Lines Matching full:aplic
10 #include <linux/irqchip/riscv-aplic.h>
29 struct aplic { struct
40 static u32 aplic_read_sourcecfg(struct aplic *aplic, u32 irq) in aplic_read_sourcecfg() argument
46 if (!irq || aplic->nr_irqs <= irq) in aplic_read_sourcecfg()
48 irqd = &aplic->irqs[irq]; in aplic_read_sourcecfg()
57 static void aplic_write_sourcecfg(struct aplic *aplic, u32 irq, u32 val) in aplic_write_sourcecfg() argument
62 if (!irq || aplic->nr_irqs <= irq) in aplic_write_sourcecfg()
64 irqd = &aplic->irqs[irq]; in aplic_write_sourcecfg()
76 static u32 aplic_read_target(struct aplic *aplic, u32 irq) in aplic_read_target() argument
82 if (!irq || aplic->nr_irqs <= irq) in aplic_read_target()
84 irqd = &aplic->irqs[irq]; in aplic_read_target()
93 static void aplic_write_target(struct aplic *aplic, u32 irq, u32 val) in aplic_write_target() argument
98 if (!irq || aplic->nr_irqs <= irq) in aplic_write_target()
100 irqd = &aplic->irqs[irq]; in aplic_write_target()
111 static bool aplic_read_pending(struct aplic *aplic, u32 irq) in aplic_read_pending() argument
117 if (!irq || aplic->nr_irqs <= irq) in aplic_read_pending()
119 irqd = &aplic->irqs[irq]; in aplic_read_pending()
128 static void aplic_write_pending(struct aplic *aplic, u32 irq, bool pending) in aplic_write_pending() argument
133 if (!irq || aplic->nr_irqs <= irq) in aplic_write_pending()
135 irqd = &aplic->irqs[irq]; in aplic_write_pending()
164 static bool aplic_read_enabled(struct aplic *aplic, u32 irq) in aplic_read_enabled() argument
170 if (!irq || aplic->nr_irqs <= irq) in aplic_read_enabled()
172 irqd = &aplic->irqs[irq]; in aplic_read_enabled()
181 static void aplic_write_enabled(struct aplic *aplic, u32 irq, bool enabled) in aplic_write_enabled() argument
186 if (!irq || aplic->nr_irqs <= irq) in aplic_write_enabled()
188 irqd = &aplic->irqs[irq]; in aplic_write_enabled()
198 static bool aplic_read_input(struct aplic *aplic, u32 irq) in aplic_read_input() argument
205 if (!irq || aplic->nr_irqs <= irq) in aplic_read_input()
207 irqd = &aplic->irqs[irq]; in aplic_read_input()
248 struct aplic *aplic = kvm->arch.aia.aplic_state; in aplic_update_irq_range() local
250 if (!(aplic->domaincfg & APLIC_DOMAINCFG_IE)) in aplic_update_irq_range()
254 if (!irq || aplic->nr_irqs <= irq) in aplic_update_irq_range()
256 irqd = &aplic->irqs[irq]; in aplic_update_irq_range()
281 struct aplic *aplic = kvm->arch.aia.aplic_state; in kvm_riscv_aia_aplic_inject() local
283 if (!aplic || !source || (aplic->nr_irqs <= source)) in kvm_riscv_aia_aplic_inject()
285 irqd = &aplic->irqs[source]; in kvm_riscv_aia_aplic_inject()
286 ie = (aplic->domaincfg & APLIC_DOMAINCFG_IE) ? true : false; in kvm_riscv_aia_aplic_inject()
335 static u32 aplic_read_input_word(struct aplic *aplic, u32 word) in aplic_read_input_word() argument
340 ret |= aplic_read_input(aplic, word * 32 + i) ? BIT(i) : 0; in aplic_read_input_word()
345 static u32 aplic_read_pending_word(struct aplic *aplic, u32 word) in aplic_read_pending_word() argument
350 ret |= aplic_read_pending(aplic, word * 32 + i) ? BIT(i) : 0; in aplic_read_pending_word()
355 static void aplic_write_pending_word(struct aplic *aplic, u32 word, in aplic_write_pending_word() argument
362 aplic_write_pending(aplic, word * 32 + i, pending); in aplic_write_pending_word()
366 static u32 aplic_read_enabled_word(struct aplic *aplic, u32 word) in aplic_read_enabled_word() argument
371 ret |= aplic_read_enabled(aplic, word * 32 + i) ? BIT(i) : 0; in aplic_read_enabled_word()
376 static void aplic_write_enabled_word(struct aplic *aplic, u32 word, in aplic_write_enabled_word() argument
383 aplic_write_enabled(aplic, word * 32 + i, enabled); in aplic_write_enabled_word()
390 struct aplic *aplic = kvm->arch.aia.aplic_state; in aplic_mmio_read_offset() local
397 aplic->domaincfg | APLIC_DOMAINCFG_DM; in aplic_mmio_read_offset()
399 (off < (APLIC_SOURCECFG_BASE + (aplic->nr_irqs - 1) * 4))) { in aplic_mmio_read_offset()
401 *val32 = aplic_read_sourcecfg(aplic, i); in aplic_mmio_read_offset()
403 (off < (APLIC_SETIP_BASE + aplic->nr_words * 4))) { in aplic_mmio_read_offset()
405 *val32 = aplic_read_pending_word(aplic, i); in aplic_mmio_read_offset()
409 (off < (APLIC_CLRIP_BASE + aplic->nr_words * 4))) { in aplic_mmio_read_offset()
411 *val32 = aplic_read_input_word(aplic, i); in aplic_mmio_read_offset()
415 (off < (APLIC_SETIE_BASE + aplic->nr_words * 4))) { in aplic_mmio_read_offset()
417 *val32 = aplic_read_enabled_word(aplic, i); in aplic_mmio_read_offset()
421 (off < (APLIC_CLRIE_BASE + aplic->nr_words * 4))) { in aplic_mmio_read_offset()
430 *val32 = aplic->genmsi; in aplic_mmio_read_offset()
432 (off < (APLIC_TARGET_BASE + (aplic->nr_irqs - 1) * 4))) { in aplic_mmio_read_offset()
434 *val32 = aplic_read_target(aplic, i); in aplic_mmio_read_offset()
455 struct aplic *aplic = kvm->arch.aia.aplic_state; in aplic_mmio_write_offset() local
462 aplic->domaincfg = val32 & APLIC_DOMAINCFG_IE; in aplic_mmio_write_offset()
464 (off < (APLIC_SOURCECFG_BASE + (aplic->nr_irqs - 1) * 4))) { in aplic_mmio_write_offset()
466 aplic_write_sourcecfg(aplic, i, val32); in aplic_mmio_write_offset()
468 (off < (APLIC_SETIP_BASE + aplic->nr_words * 4))) { in aplic_mmio_write_offset()
470 aplic_write_pending_word(aplic, i, val32, true); in aplic_mmio_write_offset()
472 aplic_write_pending(aplic, val32, true); in aplic_mmio_write_offset()
474 (off < (APLIC_CLRIP_BASE + aplic->nr_words * 4))) { in aplic_mmio_write_offset()
476 aplic_write_pending_word(aplic, i, val32, false); in aplic_mmio_write_offset()
478 aplic_write_pending(aplic, val32, false); in aplic_mmio_write_offset()
480 (off < (APLIC_SETIE_BASE + aplic->nr_words * 4))) { in aplic_mmio_write_offset()
482 aplic_write_enabled_word(aplic, i, val32, true); in aplic_mmio_write_offset()
484 aplic_write_enabled(aplic, val32, true); in aplic_mmio_write_offset()
486 (off < (APLIC_CLRIE_BASE + aplic->nr_words * 4))) { in aplic_mmio_write_offset()
488 aplic_write_enabled_word(aplic, i, val32, false); in aplic_mmio_write_offset()
490 aplic_write_enabled(aplic, val32, false); in aplic_mmio_write_offset()
492 aplic_write_pending(aplic, val32, true); in aplic_mmio_write_offset()
494 aplic_write_pending(aplic, __swab32(val32), true); in aplic_mmio_write_offset()
496 aplic->genmsi = val32 & ~(APLIC_TARGET_GUEST_IDX_MASK << in aplic_mmio_write_offset()
502 (off < (APLIC_TARGET_BASE + (aplic->nr_irqs - 1) * 4))) { in aplic_mmio_write_offset()
504 aplic_write_target(aplic, i, val32); in aplic_mmio_write_offset()
508 aplic_update_irq_range(kvm, 1, aplic->nr_irqs - 1); in aplic_mmio_write_offset()
575 struct aplic *aplic; in kvm_riscv_aia_aplic_init() local
581 /* Allocate APLIC global state */ in kvm_riscv_aia_aplic_init()
582 aplic = kzalloc(sizeof(*aplic), GFP_KERNEL); in kvm_riscv_aia_aplic_init()
583 if (!aplic) in kvm_riscv_aia_aplic_init()
585 kvm->arch.aia.aplic_state = aplic; in kvm_riscv_aia_aplic_init()
587 /* Setup APLIC IRQs */ in kvm_riscv_aia_aplic_init()
588 aplic->nr_irqs = kvm->arch.aia.nr_sources + 1; in kvm_riscv_aia_aplic_init()
589 aplic->nr_words = DIV_ROUND_UP(aplic->nr_irqs, 32); in kvm_riscv_aia_aplic_init()
590 aplic->irqs = kcalloc(aplic->nr_irqs, in kvm_riscv_aia_aplic_init()
591 sizeof(*aplic->irqs), GFP_KERNEL); in kvm_riscv_aia_aplic_init()
592 if (!aplic->irqs) { in kvm_riscv_aia_aplic_init()
596 for (i = 0; i < aplic->nr_irqs; i++) in kvm_riscv_aia_aplic_init()
597 raw_spin_lock_init(&aplic->irqs[i].lock); in kvm_riscv_aia_aplic_init()
600 kvm_iodevice_init(&aplic->iodev, &aplic_iodoev_ops); in kvm_riscv_aia_aplic_init()
605 &aplic->iodev); in kvm_riscv_aia_aplic_init()
611 ret = kvm_riscv_setup_default_irq_routing(kvm, aplic->nr_irqs); in kvm_riscv_aia_aplic_init()
619 kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &aplic->iodev); in kvm_riscv_aia_aplic_init()
622 kfree(aplic->irqs); in kvm_riscv_aia_aplic_init()
625 kfree(aplic); in kvm_riscv_aia_aplic_init()
631 struct aplic *aplic = kvm->arch.aia.aplic_state; in kvm_riscv_aia_aplic_cleanup() local
633 if (!aplic) in kvm_riscv_aia_aplic_cleanup()
637 kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &aplic->iodev); in kvm_riscv_aia_aplic_cleanup()
640 kfree(aplic->irqs); in kvm_riscv_aia_aplic_cleanup()
643 kfree(aplic); in kvm_riscv_aia_aplic_cleanup()