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


Reply via email to