|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 14/26] xen/riscv: add very early virtual APLIC (vAPLIC) initialization support
On 6/4/26 1:29 PM, Oleksii Kurochko wrote:
As an alternative it could be that vintc->init_ops are moved as a variable to int.c and then domain_vaplic_(de)init will be just a hook. Something like: $ git diff diff --git a/xen/arch/riscv/aplic.c b/xen/arch/riscv/aplic.c index 86d0a247ef3d..4c4f777f7e1b 100644 --- a/xen/arch/riscv/aplic.c +++ b/xen/arch/riscv/aplic.c @@ -28,6 +28,7 @@ #include <asm/imsic.h> #include <asm/intc.h> #include <asm/io.h> +#include <asm/vaplic.h> #include <asm/riscv_encoding.h> #define APLIC_DEFAULT_PRIORITY 1@@ -394,6 +395,7 @@ static int __init aplic_preinit(struct dt_device_node *node, const void *dat)
dt_irq_xlate = aplic_irq_xlate;
register_intc_ops(&aplic_init_ops);
+ register_vintc_init_ops(&vaplic_vintc_init_ops);
/* Enable supervisor external interrupt */
csr_set(CSR_SIE, BIT(IRQ_S_EXT, UL));
diff --git a/xen/arch/riscv/include/asm/intc.h
b/xen/arch/riscv/include/asm/intc.h
index 4842ca08aa54..84b97d6c56f9 100644
--- a/xen/arch/riscv/include/asm/intc.h
+++ b/xen/arch/riscv/include/asm/intc.h
@@ -56,6 +56,8 @@ struct intc_hw_init_ops {
};
struct vintc_init_ops {
+ int (*init)(struct domain *d);
+ void (*deinit)(struct domain *d);
/* Create interrupt controller node for domain */
int (*make_domu_dt_node)(struct kernel_info *kinfo);
};
@@ -79,13 +81,13 @@ struct vintc_ops {
struct vintc {
unsigned int irq_nums;
unsigned long *allocated_irqs;
- const struct vintc_init_ops *init_ops;
const struct vintc_ops *ops;
};
void intc_preinit(void);
void register_intc_ops(const struct intc_hw_init_ops *init_ops);
+void register_vintc_init_ops(const struct vintc_init_ops *ops);
void intc_init(void);
diff --git a/xen/arch/riscv/include/asm/vaplic.h
b/xen/arch/riscv/include/asm/vaplic.h
index 0fa690fcb2d7..7720e6556fcb 100644
--- a/xen/arch/riscv/include/asm/vaplic.h
+++ b/xen/arch/riscv/include/asm/vaplic.h
@@ -15,8 +15,6 @@
#include <asm/intc.h>
-struct domain;
-
#define to_vaplic(d) container_of(d->arch.vintc, struct vaplic, vintc)
struct vaplic_regs {
@@ -31,7 +29,6 @@ struct vaplic {
paddr_t regs_size;
};
-int domain_vaplic_init(struct domain *d);
-void domain_vaplic_deinit(struct domain *d);
+extern const struct vintc_init_ops vaplic_vintc_init_ops;
#endif /* ASM__RISCV__VAPLIC_H */
diff --git a/xen/arch/riscv/intc.c b/xen/arch/riscv/intc.c
index 0934bce3f2f8..304d4def7a4b 100644
--- a/xen/arch/riscv/intc.c
+++ b/xen/arch/riscv/intc.c
@@ -13,18 +13,24 @@
#include <asm/aia.h>
#include <asm/intc.h>
-#include <asm/vaplic.h>
static const struct intc_hw_operations *__ro_after_init intc_hw_ops;
static const struct intc_hw_init_ops *__initdata intc_hw_init_ops;
+static const struct vintc_init_ops *__ro_after_init vintc_init_ops;
+
void __init register_intc_ops(const struct intc_hw_init_ops *init_ops)
{
intc_hw_ops = init_ops->ops;
intc_hw_init_ops = init_ops;
}
+void __init register_vintc_init_ops(const struct vintc_init_ops *ops)
+{
+ vintc_init_ops = ops;
+}
+
void __init intc_preinit(void)
{
if ( acpi_disabled )
@@ -105,29 +111,18 @@ int intc_route_irq_to_guest(struct irq_desc *desc,
int __init make_intc_domU_node(struct kernel_info *kinfo)
{
- struct vintc *vintc = kinfo->bd.d->arch.vintc;
-
- ASSERT(vintc->init_ops && vintc->init_ops->make_domu_dt_node);
- return vintc->init_ops->make_domu_dt_node(kinfo);
+ return vintc_init_ops->make_domu_dt_node(kinfo);
}
int 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;
+ int ret;
- default:
- printk("vintc (ver:%d) isn't implemented\n", ver);
- break;
- }
+ ret = vintc_init_ops->init(d);
if ( !ret )
{
d->arch.vintc->allocated_irqs =
@@ -141,19 +136,9 @@ int domain_vintc_init(struct domain *d)
void 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;
- }
+ ASSERT(vintc_init_ops && vintc_init_ops->deinit);
+ vintc_init_ops->deinit(d);
xvfree(d->arch.vintc->allocated_irqs);
}
diff --git a/xen/arch/riscv/vaplic.c b/xen/arch/riscv/vaplic.c
index 57c3433ba03b..301078b8639e 100644
--- a/xen/arch/riscv/vaplic.c
+++ b/xen/arch/riscv/vaplic.c
@@ -397,7 +397,12 @@ static int __init cf_check
vaplic_make_domu_dt_node(struct kernel_info *kinfo)
return fdt_end_node(fdt);
}
-static const struct vintc_init_ops __initdata init_ops = {
+static int domain_vaplic_init(struct domain *d);
+static void domain_vaplic_deinit(struct domain *d);
+
+const struct vintc_init_ops vaplic_vintc_init_ops = {
+ .init = domain_vaplic_init,
+ .deinit = domain_vaplic_deinit,
.make_domu_dt_node = vaplic_make_domu_dt_node,
};
@@ -408,7 +413,7 @@ static const struct vintc_ops vintc_ops = {
.emulate_load = vaplic_emulate_load,
};
-int __init domain_vaplic_init(struct domain *d)
+static int domain_vaplic_init(struct domain *d)
{
struct vaplic *vaplic = xvzalloc(struct vaplic);
@@ -417,7 +422,6 @@ int __init domain_vaplic_init(struct domain *d)
d->arch.vintc = &vaplic->vintc;
d->arch.vintc->ops = &vintc_ops;
- d->arch.vintc->init_ops = &init_ops;
vaplic->regs.domaincfg = APLIC_DOMAINCFG_IE | APLIC_DOMAINCFG_DM |
APLIC_DOMAINCFG_RO80;
@@ -428,7 +432,7 @@ int __init domain_vaplic_init(struct domain *d)
return 0;
}
-void __init domain_vaplic_deinit(struct domain *d)
+static void domain_vaplic_deinit(struct domain *d)
{
struct vaplic *vaplic = to_vaplic(d);
The downside is that we still need register_vintc_init_ops() which will
called from real interrupt controller code.
Would it be better solution? ~ Oleksii
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |