Lines Matching +full:riscv +full:- +full:aia

1 // SPDX-License-Identifier: GPL-2.0
10 #include <linux/irqchip/riscv-aplic.h>
46 if (!irq || aplic->nr_irqs <= irq) in aplic_read_sourcecfg()
48 irqd = &aplic->irqs[irq]; in aplic_read_sourcecfg()
50 raw_spin_lock_irqsave(&irqd->lock, flags); in aplic_read_sourcecfg()
51 ret = irqd->sourcecfg; in aplic_read_sourcecfg()
52 raw_spin_unlock_irqrestore(&irqd->lock, flags); in aplic_read_sourcecfg()
62 if (!irq || aplic->nr_irqs <= irq) in aplic_write_sourcecfg()
64 irqd = &aplic->irqs[irq]; in aplic_write_sourcecfg()
71 raw_spin_lock_irqsave(&irqd->lock, flags); in aplic_write_sourcecfg()
72 irqd->sourcecfg = val; in aplic_write_sourcecfg()
73 raw_spin_unlock_irqrestore(&irqd->lock, flags); in aplic_write_sourcecfg()
82 if (!irq || aplic->nr_irqs <= irq) in aplic_read_target()
84 irqd = &aplic->irqs[irq]; in aplic_read_target()
86 raw_spin_lock_irqsave(&irqd->lock, flags); in aplic_read_target()
87 ret = irqd->target; in aplic_read_target()
88 raw_spin_unlock_irqrestore(&irqd->lock, flags); in aplic_read_target()
98 if (!irq || aplic->nr_irqs <= irq) in aplic_write_target()
100 irqd = &aplic->irqs[irq]; in aplic_write_target()
106 raw_spin_lock_irqsave(&irqd->lock, flags); in aplic_write_target()
107 irqd->target = val; in aplic_write_target()
108 raw_spin_unlock_irqrestore(&irqd->lock, flags); in aplic_write_target()
117 if (!irq || aplic->nr_irqs <= irq) in aplic_read_pending()
119 irqd = &aplic->irqs[irq]; in aplic_read_pending()
121 raw_spin_lock_irqsave(&irqd->lock, flags); in aplic_read_pending()
122 ret = (irqd->state & APLIC_IRQ_STATE_PENDING) ? true : false; in aplic_read_pending()
123 raw_spin_unlock_irqrestore(&irqd->lock, flags); in aplic_read_pending()
133 if (!irq || aplic->nr_irqs <= irq) in aplic_write_pending()
135 irqd = &aplic->irqs[irq]; in aplic_write_pending()
137 raw_spin_lock_irqsave(&irqd->lock, flags); in aplic_write_pending()
139 sm = irqd->sourcecfg & APLIC_SOURCECFG_SM_MASK; in aplic_write_pending()
147 if ((irqd->state & APLIC_IRQ_STATE_INPUT) && in aplic_write_pending()
150 if (!(irqd->state & APLIC_IRQ_STATE_INPUT) && in aplic_write_pending()
157 irqd->state |= APLIC_IRQ_STATE_PENDING; in aplic_write_pending()
159 irqd->state &= ~APLIC_IRQ_STATE_PENDING; in aplic_write_pending()
162 raw_spin_unlock_irqrestore(&irqd->lock, flags); in aplic_write_pending()
171 if (!irq || aplic->nr_irqs <= irq) in aplic_read_enabled()
173 irqd = &aplic->irqs[irq]; in aplic_read_enabled()
175 raw_spin_lock_irqsave(&irqd->lock, flags); in aplic_read_enabled()
176 ret = (irqd->state & APLIC_IRQ_STATE_ENABLED) ? true : false; in aplic_read_enabled()
177 raw_spin_unlock_irqrestore(&irqd->lock, flags); in aplic_read_enabled()
187 if (!irq || aplic->nr_irqs <= irq) in aplic_write_enabled()
189 irqd = &aplic->irqs[irq]; in aplic_write_enabled()
191 raw_spin_lock_irqsave(&irqd->lock, flags); in aplic_write_enabled()
193 irqd->state |= APLIC_IRQ_STATE_ENABLED; in aplic_write_enabled()
195 irqd->state &= ~APLIC_IRQ_STATE_ENABLED; in aplic_write_enabled()
196 raw_spin_unlock_irqrestore(&irqd->lock, flags); in aplic_write_enabled()
206 if (!irq || aplic->nr_irqs <= irq) in aplic_read_input()
208 irqd = &aplic->irqs[irq]; in aplic_read_input()
210 raw_spin_lock_irqsave(&irqd->lock, flags); in aplic_read_input()
212 sourcecfg = irqd->sourcecfg; in aplic_read_input()
220 raw_input = (irqd->state & APLIC_IRQ_STATE_INPUT) ? 1 : 0; in aplic_read_input()
226 raw_spin_unlock_irqrestore(&irqd->lock, flags); in aplic_read_input()
249 struct aplic *aplic = kvm->arch.aia.aplic_state; in aplic_update_irq_range()
251 if (!(aplic->domaincfg & APLIC_DOMAINCFG_IE)) in aplic_update_irq_range()
255 if (!irq || aplic->nr_irqs <= irq) in aplic_update_irq_range()
257 irqd = &aplic->irqs[irq]; in aplic_update_irq_range()
259 raw_spin_lock_irqsave(&irqd->lock, flags); in aplic_update_irq_range()
262 target = irqd->target; in aplic_update_irq_range()
263 if ((irqd->state & APLIC_IRQ_STATE_ENPEND) == in aplic_update_irq_range()
265 irqd->state &= ~APLIC_IRQ_STATE_PENDING; in aplic_update_irq_range()
269 raw_spin_unlock_irqrestore(&irqd->lock, flags); in aplic_update_irq_range()
282 struct aplic *aplic = kvm->arch.aia.aplic_state; in kvm_riscv_aia_aplic_inject()
284 if (!aplic || !source || (aplic->nr_irqs <= source)) in kvm_riscv_aia_aplic_inject()
285 return -ENODEV; in kvm_riscv_aia_aplic_inject()
286 irqd = &aplic->irqs[source]; in kvm_riscv_aia_aplic_inject()
287 ie = (aplic->domaincfg & APLIC_DOMAINCFG_IE) ? true : false; in kvm_riscv_aia_aplic_inject()
289 raw_spin_lock_irqsave(&irqd->lock, flags); in kvm_riscv_aia_aplic_inject()
291 if (irqd->sourcecfg & APLIC_SOURCECFG_D) in kvm_riscv_aia_aplic_inject()
294 switch (irqd->sourcecfg & APLIC_SOURCECFG_SM_MASK) { in kvm_riscv_aia_aplic_inject()
296 if (level && !(irqd->state & APLIC_IRQ_STATE_INPUT) && in kvm_riscv_aia_aplic_inject()
297 !(irqd->state & APLIC_IRQ_STATE_PENDING)) in kvm_riscv_aia_aplic_inject()
298 irqd->state |= APLIC_IRQ_STATE_PENDING; in kvm_riscv_aia_aplic_inject()
301 if (!level && (irqd->state & APLIC_IRQ_STATE_INPUT) && in kvm_riscv_aia_aplic_inject()
302 !(irqd->state & APLIC_IRQ_STATE_PENDING)) in kvm_riscv_aia_aplic_inject()
303 irqd->state |= APLIC_IRQ_STATE_PENDING; in kvm_riscv_aia_aplic_inject()
306 if (level && !(irqd->state & APLIC_IRQ_STATE_PENDING)) in kvm_riscv_aia_aplic_inject()
307 irqd->state |= APLIC_IRQ_STATE_PENDING; in kvm_riscv_aia_aplic_inject()
310 if (!level && !(irqd->state & APLIC_IRQ_STATE_PENDING)) in kvm_riscv_aia_aplic_inject()
311 irqd->state |= APLIC_IRQ_STATE_PENDING; in kvm_riscv_aia_aplic_inject()
316 irqd->state |= APLIC_IRQ_STATE_INPUT; in kvm_riscv_aia_aplic_inject()
318 irqd->state &= ~APLIC_IRQ_STATE_INPUT; in kvm_riscv_aia_aplic_inject()
320 target = irqd->target; in kvm_riscv_aia_aplic_inject()
321 if (ie && ((irqd->state & APLIC_IRQ_STATE_ENPEND) == in kvm_riscv_aia_aplic_inject()
323 irqd->state &= ~APLIC_IRQ_STATE_PENDING; in kvm_riscv_aia_aplic_inject()
328 raw_spin_unlock_irqrestore(&irqd->lock, flags); in kvm_riscv_aia_aplic_inject()
391 struct aplic *aplic = kvm->arch.aia.aplic_state; in aplic_mmio_read_offset()
394 return -EOPNOTSUPP; in aplic_mmio_read_offset()
398 aplic->domaincfg | APLIC_DOMAINCFG_DM; in aplic_mmio_read_offset()
400 (off < (APLIC_SOURCECFG_BASE + (aplic->nr_irqs - 1) * 4))) { in aplic_mmio_read_offset()
401 i = ((off - APLIC_SOURCECFG_BASE) >> 2) + 1; in aplic_mmio_read_offset()
404 (off < (APLIC_SETIP_BASE + aplic->nr_words * 4))) { in aplic_mmio_read_offset()
405 i = (off - APLIC_SETIP_BASE) >> 2; in aplic_mmio_read_offset()
410 (off < (APLIC_CLRIP_BASE + aplic->nr_words * 4))) { in aplic_mmio_read_offset()
411 i = (off - APLIC_CLRIP_BASE) >> 2; in aplic_mmio_read_offset()
416 (off < (APLIC_SETIE_BASE + aplic->nr_words * 4))) { in aplic_mmio_read_offset()
417 i = (off - APLIC_SETIE_BASE) >> 2; in aplic_mmio_read_offset()
422 (off < (APLIC_CLRIE_BASE + aplic->nr_words * 4))) { in aplic_mmio_read_offset()
431 *val32 = aplic->genmsi; in aplic_mmio_read_offset()
433 (off < (APLIC_TARGET_BASE + (aplic->nr_irqs - 1) * 4))) { in aplic_mmio_read_offset()
434 i = ((off - APLIC_TARGET_BASE) >> 2) + 1; in aplic_mmio_read_offset()
437 return -ENODEV; in aplic_mmio_read_offset()
446 return -EOPNOTSUPP; in aplic_mmio_read()
448 return aplic_mmio_read_offset(vcpu->kvm, in aplic_mmio_read()
449 addr - vcpu->kvm->arch.aia.aplic_addr, in aplic_mmio_read()
456 struct aplic *aplic = kvm->arch.aia.aplic_state; in aplic_mmio_write_offset()
459 return -EOPNOTSUPP; in aplic_mmio_write_offset()
463 aplic->domaincfg = val32 & APLIC_DOMAINCFG_IE; in aplic_mmio_write_offset()
465 (off < (APLIC_SOURCECFG_BASE + (aplic->nr_irqs - 1) * 4))) { in aplic_mmio_write_offset()
466 i = ((off - APLIC_SOURCECFG_BASE) >> 2) + 1; in aplic_mmio_write_offset()
469 (off < (APLIC_SETIP_BASE + aplic->nr_words * 4))) { in aplic_mmio_write_offset()
470 i = (off - APLIC_SETIP_BASE) >> 2; in aplic_mmio_write_offset()
475 (off < (APLIC_CLRIP_BASE + aplic->nr_words * 4))) { in aplic_mmio_write_offset()
476 i = (off - APLIC_CLRIP_BASE) >> 2; in aplic_mmio_write_offset()
481 (off < (APLIC_SETIE_BASE + aplic->nr_words * 4))) { in aplic_mmio_write_offset()
482 i = (off - APLIC_SETIE_BASE) >> 2; in aplic_mmio_write_offset()
487 (off < (APLIC_CLRIE_BASE + aplic->nr_words * 4))) { in aplic_mmio_write_offset()
488 i = (off - APLIC_CLRIE_BASE) >> 2; in aplic_mmio_write_offset()
497 aplic->genmsi = val32 & ~(APLIC_TARGET_GUEST_IDX_MASK << in aplic_mmio_write_offset()
503 (off < (APLIC_TARGET_BASE + (aplic->nr_irqs - 1) * 4))) { in aplic_mmio_write_offset()
504 i = ((off - APLIC_TARGET_BASE) >> 2) + 1; in aplic_mmio_write_offset()
507 return -ENODEV; in aplic_mmio_write_offset()
509 aplic_update_irq_range(kvm, 1, aplic->nr_irqs - 1); in aplic_mmio_write_offset()
518 return -EOPNOTSUPP; in aplic_mmio_write()
520 return aplic_mmio_write_offset(vcpu->kvm, in aplic_mmio_write()
521 addr - vcpu->kvm->arch.aia.aplic_addr, in aplic_mmio_write()
534 if (!kvm->arch.aia.aplic_state) in kvm_riscv_aia_aplic_set_attr()
535 return -ENODEV; in kvm_riscv_aia_aplic_set_attr()
548 if (!kvm->arch.aia.aplic_state) in kvm_riscv_aia_aplic_get_attr()
549 return -ENODEV; in kvm_riscv_aia_aplic_get_attr()
563 if (!kvm->arch.aia.aplic_state) in kvm_riscv_aia_aplic_has_attr()
564 return -ENODEV; in kvm_riscv_aia_aplic_has_attr()
579 if (!kvm->arch.aia.nr_sources) in kvm_riscv_aia_aplic_init()
585 return -ENOMEM; in kvm_riscv_aia_aplic_init()
586 kvm->arch.aia.aplic_state = aplic; in kvm_riscv_aia_aplic_init()
589 aplic->nr_irqs = kvm->arch.aia.nr_sources + 1; in kvm_riscv_aia_aplic_init()
590 aplic->nr_words = DIV_ROUND_UP(aplic->nr_irqs, 32); in kvm_riscv_aia_aplic_init()
591 aplic->irqs = kcalloc(aplic->nr_irqs, in kvm_riscv_aia_aplic_init()
592 sizeof(*aplic->irqs), GFP_KERNEL); in kvm_riscv_aia_aplic_init()
593 if (!aplic->irqs) { in kvm_riscv_aia_aplic_init()
594 ret = -ENOMEM; in kvm_riscv_aia_aplic_init()
597 for (i = 0; i < aplic->nr_irqs; i++) in kvm_riscv_aia_aplic_init()
598 raw_spin_lock_init(&aplic->irqs[i].lock); in kvm_riscv_aia_aplic_init()
601 kvm_iodevice_init(&aplic->iodev, &aplic_iodoev_ops); in kvm_riscv_aia_aplic_init()
602 mutex_lock(&kvm->slots_lock); in kvm_riscv_aia_aplic_init()
604 kvm->arch.aia.aplic_addr, in kvm_riscv_aia_aplic_init()
606 &aplic->iodev); in kvm_riscv_aia_aplic_init()
607 mutex_unlock(&kvm->slots_lock); in kvm_riscv_aia_aplic_init()
612 ret = kvm_riscv_setup_default_irq_routing(kvm, aplic->nr_irqs); in kvm_riscv_aia_aplic_init()
619 mutex_lock(&kvm->slots_lock); in kvm_riscv_aia_aplic_init()
620 kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &aplic->iodev); in kvm_riscv_aia_aplic_init()
621 mutex_unlock(&kvm->slots_lock); in kvm_riscv_aia_aplic_init()
623 kfree(aplic->irqs); in kvm_riscv_aia_aplic_init()
625 kvm->arch.aia.aplic_state = NULL; in kvm_riscv_aia_aplic_init()
632 struct aplic *aplic = kvm->arch.aia.aplic_state; in kvm_riscv_aia_aplic_cleanup()
637 mutex_lock(&kvm->slots_lock); in kvm_riscv_aia_aplic_cleanup()
638 kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &aplic->iodev); in kvm_riscv_aia_aplic_cleanup()
639 mutex_unlock(&kvm->slots_lock); in kvm_riscv_aia_aplic_cleanup()
641 kfree(aplic->irqs); in kvm_riscv_aia_aplic_cleanup()
643 kvm->arch.aia.aplic_state = NULL; in kvm_riscv_aia_aplic_cleanup()