Add common helpers domain_vintc_init() and domain_vintc_deinit() to allocate and deallocate a virtual interrupt controller (vINTC) structure and initialize basic virtual interrupt controller registers.
Signed-off-by: Oleksii Kurochko <[email protected]> --- xen/arch/riscv/domain.c | 3 +++ xen/arch/riscv/include/asm/intc.h | 4 ++++ xen/arch/riscv/intc.c | 40 +++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/xen/arch/riscv/domain.c b/xen/arch/riscv/domain.c index 560b21b16ffb..1c08ba7396ea 100644 --- a/xen/arch/riscv/domain.c +++ b/xen/arch/riscv/domain.c @@ -300,6 +300,9 @@ int arch_domain_create(struct domain *d, if ( (rc = p2m_init(d)) != 0) goto fail; + if ( (rc = domain_vintc_init(d)) ) + goto fail; + d->arch.next_phandle = GUEST_PHANDLE_LAST + 1; return rc; diff --git a/xen/arch/riscv/include/asm/intc.h b/xen/arch/riscv/include/asm/intc.h index 45d41e191e30..fb4188b96a75 100644 --- a/xen/arch/riscv/include/asm/intc.h +++ b/xen/arch/riscv/include/asm/intc.h @@ -13,6 +13,7 @@ enum intc_version { }; struct cpu_user_regs; +struct domain; struct dt_device_node; struct irq_desc; struct kernel_info; @@ -96,4 +97,7 @@ void intc_handle_external_irqs(struct cpu_user_regs *regs); int intc_make_domu_dt_node(const struct kernel_info *kinfo); +int domain_vintc_init(struct domain *d); +void domain_vintc_deinit(struct domain *d); + #endif /* ASM__RISCV__INTERRUPT_CONTOLLER_H */ diff --git a/xen/arch/riscv/intc.c b/xen/arch/riscv/intc.c index a91dbc5e997c..88ce658a4de0 100644 --- a/xen/arch/riscv/intc.c +++ b/xen/arch/riscv/intc.c @@ -11,6 +11,7 @@ #include <asm/aia.h> #include <asm/intc.h> +#include <asm/vaplic.h> static const struct intc_hw_operations *__ro_after_init intc_hw_ops; @@ -87,3 +88,42 @@ int map_device_irqs_to_domain(struct domain *d, struct dt_device_node *dev, return d->arch.vintc->ops->map_device_irqs_to_domain(d, dev, need_mapping, irq_ranges); } + +int __init domain_vintc_init(struct domain *d) +{ + int ret = -EOPNOTSUPP; + const enum intc_version ver = intc_hw_ops->info->hw_version; + + switch ( ver ) + { + case INTC_APLIC: + ret = domain_vaplic_init(d); + break; + + default: + printk("vintc (ver:%d) isn't implemented\n", ver); + break; + } + + if ( !ret ) + d->arch.vintc->info = intc_hw_ops->info; + + return ret; +} + +void __init domain_vintc_deinit(struct domain *d) +{ + const enum intc_version ver = intc_hw_ops->info->hw_version; + + switch ( ver ) + { + case INTC_APLIC: + domain_vaplic_deinit(d); + break; + + default: + printk("vintc (ver:%d) isn't implemented\n", ver); + break; + } + +} -- 2.53.0
