[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 4/5] hw/intc/riscv_aclint: swi: report errors and free allocated
From: |
Damien Hedde |
Subject: |
[PATCH 4/5] hw/intc/riscv_aclint: swi: report errors and free allocated memory |
Date: |
Fri, 18 Feb 2022 17:46:45 +0100 |
Add the instance_finalize() method to free the allocated arrays
and make realize() method report errors instead of exiting.
This commit also move the 'num-harts' property check from
riscv_aclint_swi_create() to realize().
Code in realize() is re-ordered to first check for errors and leave
the object in a clean state. To achieve this, we do the following:
+ parse_hart_config and char_to_mode are refactored to return errors
instead of exiting.
+ in case of interrupt claim failure, we release the succesfully
claimed ones.
These clean-ups allow the following life-cycle use cases (happening
when user creation is allowed) to execute as expected:
+ init -> finalize
+ init -> realize-failure -> finalize
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
---
hw/intc/riscv_aclint.c | 54 +++++++++++++++++++++++++++++++-----------
1 file changed, 40 insertions(+), 14 deletions(-)
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
index f1a5d3d284..4f66eeed0b 100644
--- a/hw/intc/riscv_aclint.c
+++ b/hw/intc/riscv_aclint.c
@@ -389,22 +389,48 @@ static void riscv_aclint_swi_realize(DeviceState *dev,
Error **errp)
RISCVAclintSwiState *swi = RISCV_ACLINT_SWI(dev);
int i;
+ if (swi->num_harts > RISCV_ACLINT_MAX_HARTS) {
+ error_setg(errp, "invalid 'num-harts': max is %u",
+ RISCV_ACLINT_MAX_HARTS);
+ return;
+ }
+
+ /*
+ * Claim software interrupt bits:
+ * + sswi==false -> MSIP
+ * + sswi==true -> SSIP
+ * We don't claim mip.SSIP because it is writeable by software
+ */
+ if (!swi->sswi) {
+ for (i = 0; i < swi->num_harts; i++) {
+ RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(swi->hartid_base + i));
+ if (riscv_cpu_claim_interrupts(cpu, MIP_MSIP) < 0) {
+ error_setg(errp, "MSIP (hartid %u) already claimed",
+ (unsigned) (swi->hartid_base + i));
+ /* release interrupts we already claimed */
+ while (--i >= 0) {
+ cpu = RISCV_CPU(qemu_get_cpu(swi->hartid_base + i));
+ riscv_cpu_release_claimed_interrupts(cpu, MIP_MSIP);
+ }
+ return;
+ }
+ }
+ }
+
memory_region_init_io(&swi->mmio, OBJECT(dev), &riscv_aclint_swi_ops, swi,
TYPE_RISCV_ACLINT_SWI, RISCV_ACLINT_SWI_SIZE);
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &swi->mmio);
swi->soft_irqs = g_malloc(sizeof(qemu_irq) * swi->num_harts);
qdev_init_gpio_out(dev, swi->soft_irqs, swi->num_harts);
+}
- /* Claim software interrupt bits */
- for (i = 0; i < swi->num_harts; i++) {
- RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(swi->hartid_base + i));
- /* We don't claim mip.SSIP because it is writeable by software */
- if (riscv_cpu_claim_interrupts(cpu, swi->sswi ? 0 : MIP_MSIP) < 0) {
- error_report("MSIP already claimed");
- exit(1);
- }
- }
+static void riscv_aclint_swi_finalize(Object *obj)
+{
+ RISCVAclintSwiState *swi = RISCV_ACLINT_SWI(obj);
+
+ /* free allocated area during realize */
+ g_free(swi->soft_irqs);
}
static void riscv_aclint_swi_class_init(ObjectClass *klass, void *data)
@@ -415,10 +441,11 @@ static void riscv_aclint_swi_class_init(ObjectClass
*klass, void *data)
}
static const TypeInfo riscv_aclint_swi_info = {
- .name = TYPE_RISCV_ACLINT_SWI,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(RISCVAclintSwiState),
- .class_init = riscv_aclint_swi_class_init,
+ .name = TYPE_RISCV_ACLINT_SWI,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(RISCVAclintSwiState),
+ .class_init = riscv_aclint_swi_class_init,
+ .instance_finalize = riscv_aclint_swi_finalize,
};
/*
@@ -430,7 +457,6 @@ DeviceState *riscv_aclint_swi_create(hwaddr addr, uint32_t
hartid_base,
int i;
DeviceState *dev = qdev_new(TYPE_RISCV_ACLINT_SWI);
- assert(num_harts <= RISCV_ACLINT_MAX_HARTS);
assert(!(addr & 0x3));
qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
--
2.35.1
[PATCH 2/5] target/riscv: add riscv_cpu_release_claimed_interrupts function, Damien Hedde, 2022/02/18
[PATCH 3/5] hw/intc/sifive_plic: report errors and free allocated memory, Damien Hedde, 2022/02/18
[PATCH 4/5] hw/intc/riscv_aclint: swi: report errors and free allocated memory,
Damien Hedde <=
[PATCH 5/5] hw/intc/riscv_aclint: mtimer: report errors and free allocated memory, Damien Hedde, 2022/02/18