Lines Matching +full:riscv +full:- +full:aia
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
45 #include <riscv/vmm/riscv.h>
46 #include <riscv/vmm/vmm_aplic.h>
51 MALLOC_DEFINE(M_APLIC, "RISC-V VMM APLIC", "RISC-V AIA APLIC");
56 #define DOMAINCFG_BE (1 << 0) /* Big-Endian. */
57 #define APLIC_SOURCECFG(x) (0x0004 + ((x) - 1) * 4)
58 #define SOURCECFG_D (1 << 10) /* D - Delegate. */
78 #define APLIC_TARGET(x) (0x3004 + ((x) - 1) * 4)
117 if (i <= 0 || i > aplic->nirqs) in aplic_handle_sourcecfg()
120 mtx_lock_spin(&aplic->mtx); in aplic_handle_sourcecfg()
121 irq = &aplic->irqs[i]; in aplic_handle_sourcecfg()
123 irq->sourcecfg = *val; in aplic_handle_sourcecfg()
125 *val = irq->sourcecfg; in aplic_handle_sourcecfg()
126 mtx_unlock_spin(&aplic->mtx); in aplic_handle_sourcecfg()
143 if (i <= 0 || i > aplic->nirqs) in aplic_set_enabled()
144 return (-1); in aplic_set_enabled()
146 irq = &aplic->irqs[i]; in aplic_set_enabled()
148 mtx_lock_spin(&aplic->mtx); in aplic_set_enabled()
150 irq->state |= APLIC_IRQ_STATE_ENABLED; in aplic_set_enabled()
152 irq->state &= ~APLIC_IRQ_STATE_ENABLED; in aplic_set_enabled()
153 mtx_unlock_spin(&aplic->mtx); in aplic_set_enabled()
163 mtx_lock_spin(&aplic->mtx); in aplic_handle_target()
164 irq = &aplic->irqs[i]; in aplic_handle_target()
166 irq->target = *val; in aplic_handle_target()
167 irq->target_hart = (irq->target >> TARGET_HART_S); in aplic_handle_target()
169 *val = irq->target; in aplic_handle_target()
170 mtx_unlock_spin(&aplic->mtx); in aplic_handle_target()
185 return (-1); in aplic_handle_idc_claimi()
189 mtx_lock_spin(&aplic->mtx); in aplic_handle_idc_claimi()
190 for (i = 0; i < aplic->nirqs; i++) { in aplic_handle_idc_claimi()
191 irq = &aplic->irqs[i]; in aplic_handle_idc_claimi()
192 if (irq->target_hart != cpu_id) in aplic_handle_idc_claimi()
194 if (irq->state & APLIC_IRQ_STATE_PENDING) { in aplic_handle_idc_claimi()
196 irq->state &= ~APLIC_IRQ_STATE_PENDING; in aplic_handle_idc_claimi()
201 mtx_unlock_spin(&aplic->mtx); in aplic_handle_idc_claimi()
242 (reg <= APLIC_SOURCECFG(aplic->nirqs))) { in aplic_mmio_access()
243 i = ((reg - APLIC_SOURCECFG(1)) >> 2) + 1; in aplic_mmio_access()
248 if ((reg >= APLIC_TARGET(1)) && (reg <= APLIC_TARGET(aplic->nirqs))) { in aplic_mmio_access()
249 i = ((reg - APLIC_TARGET(1)) >> 2) + 1; in aplic_mmio_access()
255 cpu = (reg - APLIC_IDC(0)) >> 5; in aplic_mmio_access()
256 r = (reg - APLIC_IDC(0)) % 32; in aplic_mmio_access()
263 aplic->domaincfg = *val & DOMAINCFG_IE; in aplic_mmio_access()
293 hyp = hypctx->hyp; in mem_read()
294 aplic = hyp->aplic; in mem_read()
298 if (fault_ipa < aplic->mem_start || fault_ipa + size > aplic->mem_end) in mem_read()
301 reg = fault_ipa - aplic->mem_start; in mem_read()
322 hyp = hypctx->hyp; in mem_write()
323 aplic = hyp->aplic; in mem_write()
328 if (fault_ipa < aplic->mem_start || fault_ipa + size > aplic->mem_end) in mem_write()
331 reg = fault_ipa - aplic->mem_start; in mem_write()
345 hyp->aplic = malloc(sizeof(*hyp->aplic), M_APLIC, in aplic_vminit()
347 aplic = hyp->aplic; in aplic_vminit()
349 mtx_init(&aplic->mtx, "APLIC lock", NULL, MTX_SPIN); in aplic_vminit()
357 aplic = hyp->aplic; in aplic_vmcleanup()
359 mtx_destroy(&aplic->mtx); in aplic_vmcleanup()
361 free(hyp->aplic, M_APLIC); in aplic_vmcleanup()
370 vm = hyp->vm; in aplic_attach_to_vm()
374 vm_register_inst_handler(vm, descr->mem_start, descr->mem_size, in aplic_attach_to_vm()
377 aplic = hyp->aplic; in aplic_attach_to_vm()
378 aplic->nirqs = APLIC_NIRQS; in aplic_attach_to_vm()
379 aplic->mem_start = descr->mem_start; in aplic_attach_to_vm()
380 aplic->mem_end = descr->mem_start + descr->mem_size; in aplic_attach_to_vm()
381 aplic->irqs = malloc(sizeof(struct aplic_irq) * aplic->nirqs, M_APLIC, in aplic_attach_to_vm()
384 hyp->aplic_attached = true; in aplic_attach_to_vm()
394 aplic = hyp->aplic; in aplic_detach_from_vm()
398 if (hyp->aplic_attached) { in aplic_detach_from_vm()
399 hyp->aplic_attached = false; in aplic_detach_from_vm()
400 free(aplic->irqs, M_APLIC); in aplic_detach_from_vm()
412 hyp = hypctx->hyp; in aplic_check_pending()
413 aplic = hyp->aplic; in aplic_check_pending()
415 mtx_lock_spin(&aplic->mtx); in aplic_check_pending()
416 if ((aplic->domaincfg & DOMAINCFG_IE) == 0) { in aplic_check_pending()
417 mtx_unlock_spin(&aplic->mtx); in aplic_check_pending()
421 for (i = 0; i < aplic->nirqs; i++) { in aplic_check_pending()
422 irq = &aplic->irqs[i]; in aplic_check_pending()
423 if (irq->target_hart != hypctx->cpu_id) in aplic_check_pending()
425 if ((irq->state & APLIC_IRQ_STATE_ENABLED) && in aplic_check_pending()
426 (irq->state & APLIC_IRQ_STATE_PENDING)) { in aplic_check_pending()
427 mtx_unlock_spin(&aplic->mtx); in aplic_check_pending()
432 mtx_unlock_spin(&aplic->mtx); in aplic_check_pending()
445 aplic = hyp->aplic; in aplic_inject_irq()
449 mtx_lock_spin(&aplic->mtx); in aplic_inject_irq()
450 if ((aplic->domaincfg & DOMAINCFG_IE) == 0) { in aplic_inject_irq()
451 mtx_unlock_spin(&aplic->mtx); in aplic_inject_irq()
455 irq = &aplic->irqs[irqid]; in aplic_inject_irq()
456 if (irq->sourcecfg & SOURCECFG_D) { in aplic_inject_irq()
457 mtx_unlock_spin(&aplic->mtx); in aplic_inject_irq()
462 switch (irq->sourcecfg & SOURCECFG_SM_M) { in aplic_inject_irq()
465 irq->state |= APLIC_IRQ_STATE_PENDING; in aplic_inject_irq()
466 if (irq->state & APLIC_IRQ_STATE_ENABLED) in aplic_inject_irq()
469 irq->state &= ~APLIC_IRQ_STATE_PENDING; in aplic_inject_irq()
475 dprintf("sourcecfg %d\n", irq->sourcecfg & SOURCECFG_SM_M); in aplic_inject_irq()
479 mtx_unlock_spin(&aplic->mtx); in aplic_inject_irq()
482 vcpu_notify_event(vm_vcpu(hyp->vm, irq->target_hart)); in aplic_inject_irq()
525 max_count = vm_get_maxcpus(hyp->vm); in aplic_max_cpu_count()