aplic
struct vm_aplic_descr aplic;
bzero(&aplic, sizeof(aplic));
aplic.mem_start = mem_start;
aplic.mem_size = mem_size;
return (ioctl(ctx->fd, VM_ATTACH_APLIC, &aplic));
fdt_get_hartid(device_t dev, phandle_t aplic)
if (OF_searchencprop(aplic, "#interrupt-cells", &hartid,
"Could not find #interrupt-cells for phandle %u\n", aplic);
if (OF_searchencprop(OF_parent(aplic), "reg", (pcell_t *)&hartid,
DEFINE_CLASS_0(aplic, aplic_driver, aplic_methods, sizeof(struct aplic_softc));
EARLY_DRIVER_MODULE(aplic, simplebus, aplic_driver, 0, 0,
struct aplic *aplic;
aplic_handle_sourcecfg(struct aplic *aplic, int i, bool write, uint64_t *val)
if (i <= 0 || i > aplic->nirqs)
mtx_lock_spin(&aplic->mtx);
irq = &aplic->irqs[i];
mtx_unlock_spin(&aplic->mtx);
aplic_set_enabled(struct aplic *aplic, bool write, uint64_t *val, bool enabled)
if (i <= 0 || i > aplic->nirqs)
irq = &aplic->irqs[i];
mtx_lock_spin(&aplic->mtx);
mtx_unlock_spin(&aplic->mtx);
aplic_set_enabled_word(struct aplic *aplic, bool write, uint32_t word,
(void)aplic_set_enabled(aplic, write, &v, enabled);
aplic_handle_target(struct aplic *aplic, int i, bool write, uint64_t *val)
mtx_lock_spin(&aplic->mtx);
irq = &aplic->irqs[i];
mtx_unlock_spin(&aplic->mtx);
aplic_handle_idc_claimi(struct hyp *hyp, struct aplic *aplic, int cpu_id,
mtx_lock_spin(&aplic->mtx);
for (i = 0; i < aplic->nirqs; i++) {
irq = &aplic->irqs[i];
mtx_unlock_spin(&aplic->mtx);
aplic_handle_idc(struct hyp *hyp, struct aplic *aplic, int cpu, int reg,
error = aplic_handle_idc_claimi(hyp, aplic, cpu, write, val);
aplic_mmio_access(struct hyp *hyp, struct aplic *aplic, uint64_t reg,
(reg <= APLIC_SOURCECFG(aplic->nirqs))) {
error = aplic_handle_sourcecfg(aplic, i, write, val);
if ((reg >= APLIC_TARGET(1)) && (reg <= APLIC_TARGET(aplic->nirqs))) {
error = aplic_handle_target(aplic, i, write, val);
error = aplic_handle_idc(hyp, aplic, cpu, r, write, val);
if ((reg >= APLIC_CLRIE) && (reg < (APLIC_CLRIE + aplic->nirqs * 4))) {
aplic_set_enabled_word(aplic, write, i, val, false);
mtx_lock_spin(&aplic->mtx);
aplic->domaincfg = *val & DOMAINCFG_IE;
*val = aplic->domaincfg;
mtx_unlock_spin(&aplic->mtx);
error = aplic_set_enabled(aplic, write, val, true);
error = aplic_set_enabled(aplic, write, val, false);
struct aplic *aplic;
aplic = hyp->aplic;
if (fault_ipa < aplic->mem_start || fault_ipa + size > aplic->mem_end)
reg = fault_ipa - aplic->mem_start;
error = aplic_mmio_access(hyp, aplic, reg, false, &val);
struct aplic *aplic;
aplic = hyp->aplic;
if (fault_ipa < aplic->mem_start || fault_ipa + size > aplic->mem_end)
reg = fault_ipa - aplic->mem_start;
error = aplic_mmio_access(hyp, aplic, reg, true, &val);
struct aplic *aplic;
hyp->aplic = malloc(sizeof(*hyp->aplic), M_APLIC,
aplic = hyp->aplic;
mtx_init(&aplic->mtx, "APLIC lock", NULL, MTX_SPIN);
struct aplic *aplic;
aplic = hyp->aplic;
mtx_destroy(&aplic->mtx);
free(hyp->aplic, M_APLIC);
struct aplic *aplic;
aplic = hyp->aplic;
aplic->nirqs = APLIC_NIRQS;
aplic->mem_start = descr->mem_start;
aplic->mem_end = descr->mem_start + descr->mem_size;
aplic->irqs = malloc(sizeof(struct aplic_irq) * aplic->nirqs, M_APLIC,
struct aplic *aplic;
aplic = hyp->aplic;
free(aplic->irqs, M_APLIC);
struct aplic *aplic;
aplic = hyp->aplic;
mtx_lock_spin(&aplic->mtx);
if ((aplic->domaincfg & DOMAINCFG_IE) == 0) {
mtx_unlock_spin(&aplic->mtx);
for (i = 0; i < aplic->nirqs; i++) {
irq = &aplic->irqs[i];
mtx_unlock_spin(&aplic->mtx);
mtx_unlock_spin(&aplic->mtx);
struct aplic *aplic;
aplic = hyp->aplic;
mtx_lock_spin(&aplic->mtx);
if ((aplic->domaincfg & DOMAINCFG_IE) == 0) {
mtx_unlock_spin(&aplic->mtx);
irq = &aplic->irqs[irqid];
mtx_unlock_spin(&aplic->mtx);
mtx_unlock_spin(&aplic->mtx);
struct vm_aplic_descr *aplic;
aplic = (struct vm_aplic_descr *)data;
error = vm_attach_aplic(vm, aplic);