|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v3 14/23] xen/riscv: add very early virtual APLIC (vAPLIC) initialization support
At the current development stage, only domain vINTC init and deinit
operations are required, so implement those first.
Initialize vAPLIC's domaincfg to with the interrupt-enable bit set and
MSI delivery mode selected as the current solution is exepcted to have
always IMSIC, and initialize vintc->ops.
Other operations such as emulate_load(), emulate_store(), and is_access()
will be needed once guests are running and MMIO accesses to APLIC MMIO
range must be handled. These will be introduced separately later.
Introduce a structure to describe a virtual interrupt controller (vINTC)
and a vintc_ops structure, which provides operations to emulate load and
store accesses to interrupt controller MMIOs and to check whether a given
address falls within the MMIO range of a specific virtual interrupt
controller.
The vAPLIC implementation of these operations will be provided later
once guests can be run and these operations are actually needed.
Introduce these structures here as they are required for the implementation
of domain_vaplic_init() and domain_vaplic_alloc(). Also, introduce
vaplic_init() and init vintc_ops->vcpu_init() with it.
Co-developed-by: Romain Caritey <Romain.Caritey@xxxxxxxxxxxxx>
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
---
Changes in v3:
- Drop ASSERT() before vintc->ops->vcpu_init() in arch_vcpu_create(); a
NULL deref already produces a sufficient backtrace.
- Parenthesize macro argument in to_vaplic().
- Drop __init from domain_vaplic_init() and domain_vaplic_deinit() since
the caller domain_vintc_init() (follow-up patch) is not __init.
- Remove pointless zero-initializer for rc in vcpu_vaplic_init().
- Fix domain_vaplic_deinit() to null d->arch.vintc before freeing, making
the function idempotent.
- Drop intc_irq_nums(), (*nr_irqs)(void) hook from intc_hw_operations,
aplic_nr_irqs(), and vintc->nr_irqs field entirely.
- Rename vcpu_vaplic_init() to vaplic_init() and drop vgein_assign() and
imsic_set_guest_file_id() calls; those will be introduced/called later,
where for sure we will know on which pCPU vCPU as it is required for
proper h/w IMSIC interrupt file calculation, to have this initialization
in one place.
- Introduce vaplic_deinit().
---
Changes in v2:
- s/vcpu/v for function arguments in struct vintc_ops().
- Update the comment above is_access() and drop const for addr argument.
- Update to_vaplic() to work with 'struct domain *'.
- Drop smsiaddrcfg{h} from vaplic_regs struct as they aren't used for now.
- Drop inclusion of xen/schec.h from intc.c.
- use result of xvzalloc() as initializer in vpalic_alloc().
- Drop goto in domain_vaplic_init().
- s/XVFREE/xvfree.
- s/aplic/vintc.
- Drop __init for vcpu_vaplic_init() as it could be called for secondary CPU
bring up.
- Drop vaplic_alloc().
- Drop vintc_ops struct, embed callbacks iniside struct vintc.
- Introduce and init vintc irqs for vAPLIC.
- Introduce intc_irq_nums() to properly initialize number of vAPLIC's irqs.
---
---
xen/arch/riscv/Makefile | 1 +
xen/arch/riscv/domain.c | 11 ++---
xen/arch/riscv/include/asm/aplic.h | 1 +
xen/arch/riscv/include/asm/intc.h | 12 ++++++
xen/arch/riscv/include/asm/vaplic.h | 34 ++++++++++++++++
xen/arch/riscv/vaplic.c | 63 +++++++++++++++++++++++++++++
6 files changed, 114 insertions(+), 8 deletions(-)
create mode 100644 xen/arch/riscv/include/asm/vaplic.h
create mode 100644 xen/arch/riscv/vaplic.c
diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile
index 9df8b72b5494..9d8d21b65188 100644
--- a/xen/arch/riscv/Makefile
+++ b/xen/arch/riscv/Makefile
@@ -25,6 +25,7 @@ obj-y += smpboot.o
obj-y += stubs.o
obj-y += time.o
obj-y += traps.o
+obj-y += vaplic.o
obj-y += vmid.o
obj-y += vm_event.o
obj-y += vsbi/
diff --git a/xen/arch/riscv/domain.c b/xen/arch/riscv/domain.c
index e4a8c27ea9cb..129e775c52cb 100644
--- a/xen/arch/riscv/domain.c
+++ b/xen/arch/riscv/domain.c
@@ -11,6 +11,7 @@
#include <asm/bitops.h>
#include <asm/cpufeature.h>
#include <asm/csr.h>
+#include <asm/intc.h>
#include <asm/riscv_encoding.h>
#include <asm/vtimer.h>
@@ -155,14 +156,8 @@ int arch_vcpu_create(struct vcpu *v)
if ( (rc = vcpu_vtimer_init(v)) )
goto fail;
- /*
- * As interrupt controller (IC) is not yet implemented,
- * return an error.
- *
- * TODO: Drop this once IC is implemented.
- */
- rc = -EOPNOTSUPP;
- goto fail;
+ if ( (rc = v->domain->arch.vintc->ops->vcpu_init(v)) )
+ goto fail;
return rc;
diff --git a/xen/arch/riscv/include/asm/aplic.h
b/xen/arch/riscv/include/asm/aplic.h
index b0724fe6f360..d443faac57c4 100644
--- a/xen/arch/riscv/include/asm/aplic.h
+++ b/xen/arch/riscv/include/asm/aplic.h
@@ -15,6 +15,7 @@
#include <asm/imsic.h>
+#define APLIC_DOMAINCFG_RO80 (0x80U << 24)
#define APLIC_DOMAINCFG_IE BIT(8, U)
#define APLIC_DOMAINCFG_DM BIT(2, U)
diff --git a/xen/arch/riscv/include/asm/intc.h
b/xen/arch/riscv/include/asm/intc.h
index 9b701445179f..d3d456afe5f0 100644
--- a/xen/arch/riscv/include/asm/intc.h
+++ b/xen/arch/riscv/include/asm/intc.h
@@ -15,6 +15,7 @@ enum intc_version {
struct cpu_user_regs;
struct irq_desc;
struct kernel_info;
+struct vcpu;
struct intc_info {
enum intc_version hw_version;
@@ -38,6 +39,7 @@ struct intc_hw_operations {
/* handle external interrupt */
void (*handle_interrupt)(struct cpu_user_regs *regs);
+
};
struct intc_hw_init_ops {
@@ -51,8 +53,17 @@ struct vintc_init_ops {
int (*make_domu_dt_node)(struct kernel_info *kinfo);
};
+struct vintc_ops {
+ /* Initialize some vINTC-related stuff for a vCPU */
+ int (*vcpu_init)(struct vcpu *v);
+
+ /* Deinitialize some vINTC-related stuff for a vCPU */
+ void (*vcpu_deinit)(struct vcpu *v);
+};
+
struct vintc {
const struct vintc_init_ops *init_ops;
+ const struct vintc_ops *ops;
};
void intc_preinit(void);
@@ -65,4 +76,5 @@ void intc_route_irq_to_xen(struct irq_desc *desc, unsigned
int priority);
void intc_handle_external_irqs(struct cpu_user_regs *regs);
+
#endif /* ASM__RISCV__INTERRUPT_CONTOLLER_H */
diff --git a/xen/arch/riscv/include/asm/vaplic.h
b/xen/arch/riscv/include/asm/vaplic.h
new file mode 100644
index 000000000000..96080bfbc23b
--- /dev/null
+++ b/xen/arch/riscv/include/asm/vaplic.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * xen/arch/riscv/vaplic.c
+ *
+ * Virtual RISC-V Advanced Platform-Level Interrupt Controller support
+ *
+ * Copyright (c) Microchip.
+ */
+
+#ifndef ASM__RISCV__VAPLIC_H
+#define ASM__RISCV__VAPLIC_H
+
+#include <xen/kernel.h>
+#include <xen/types.h>
+
+#include <asm/intc.h>
+
+struct domain;
+
+#define to_vaplic(d) container_of((d)->arch.vintc, struct vaplic, vintc)
+
+struct vaplic_regs {
+ uint32_t domaincfg;
+};
+
+struct vaplic {
+ struct vintc vintc;
+ struct vaplic_regs regs;
+};
+
+int domain_vaplic_init(struct domain *d);
+void domain_vaplic_deinit(struct domain *d);
+
+#endif /* ASM__RISCV__VAPLIC_H */
diff --git a/xen/arch/riscv/vaplic.c b/xen/arch/riscv/vaplic.c
new file mode 100644
index 000000000000..8170e93701ad
--- /dev/null
+++ b/xen/arch/riscv/vaplic.c
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * xen/arch/riscv/vaplic.c
+ *
+ * Virtual RISC-V Advanced Platform-Level Interrupt Controller support
+ *
+ * Copyright (c) Microchip.
+ * Copyright (c) Vates
+ */
+
+#include <xen/errno.h>
+#include <xen/sched.h>
+#include <xen/xvmalloc.h>
+
+#include <asm/aia.h>
+#include <asm/imsic.h>
+#include <asm/intc.h>
+#include <asm/vaplic.h>
+
+#include "aplic-priv.h"
+
+static int cf_check vaplic_init(struct vcpu *v)
+{
+ return vcpu_imsic_init(v);
+}
+
+static void cf_check vaplic_deinit(struct vcpu *v)
+{
+ return vcpu_imsic_deinit(v);
+}
+
+static const struct vintc_ops vintc_ops = {
+ .vcpu_init = vaplic_init,
+ .vcpu_deinit = vaplic_deinit,
+};
+
+int domain_vaplic_init(struct domain *d)
+{
+ struct vaplic *vaplic = xvzalloc(struct vaplic);
+
+ if ( !vaplic )
+ return -ENOMEM;
+
+ d->arch.vintc = &vaplic->vintc;
+ d->arch.vintc->ops = &vintc_ops;
+
+ vaplic->regs.domaincfg = APLIC_DOMAINCFG_IE | APLIC_DOMAINCFG_DM |
+ APLIC_DOMAINCFG_RO80;
+
+ return 0;
+}
+
+void domain_vaplic_deinit(struct domain *d)
+{
+ struct vaplic *vaplic;
+
+ if ( !d->arch.vintc )
+ return;
+
+ vaplic = to_vaplic(d);
+ d->arch.vintc = NULL;
+ xvfree(vaplic);
+}
--
2.54.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |