Re: [PATCH v3 4/4] hw/intc: riscv_aclint: Add reset function of ACLINT devices

2022-04-20 Thread Alistair Francis
On Tue, Apr 19, 2022 at 7:29 PM  wrote:
>
> From: Jim Shu 
>
> This commit implements reset function of all ACLINT devices.
> ACLINT device reset will clear MTIME and MSIP register to 0.
>
> Depend on RISC-V ACLINT spec v1.0-rc4:
> https://github.com/riscv/riscv-aclint/blob/v1.0-rc4/riscv-aclint.adoc
>
> Signed-off-by: Jim Shu 
> Reviewed-by: Frank Chang 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/intc/riscv_aclint.c | 39 +++
>  1 file changed, 39 insertions(+)
>
> diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
> index ad7ccf96cd..67a07bb5b9 100644
> --- a/hw/intc/riscv_aclint.c
> +++ b/hw/intc/riscv_aclint.c
> @@ -293,11 +293,29 @@ static void riscv_aclint_mtimer_realize(DeviceState 
> *dev, Error **errp)
>  }
>  }
>
> +static void riscv_aclint_mtimer_reset_enter(Object *obj, ResetType type)
> +{
> +/*
> + * According to RISC-V ACLINT spec:
> + *   - On MTIMER device reset, the MTIME register is cleared to zero.
> + *   - On MTIMER device reset, the MTIMECMP registers are in unknown 
> state.
> + */
> +RISCVAclintMTimerState *mtimer = RISCV_ACLINT_MTIMER(obj);
> +
> +/*
> + * Clear mtime register by writing to 0 it.
> + * Pending mtime interrupts will also be cleared at the same time.
> + */
> +riscv_aclint_mtimer_write(mtimer, mtimer->time_base, 0, 8);
> +}
> +
>  static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data)
>  {
>  DeviceClass *dc = DEVICE_CLASS(klass);
>  dc->realize = riscv_aclint_mtimer_realize;
>  device_class_set_props(dc, riscv_aclint_mtimer_properties);
> +ResettableClass *rc = RESETTABLE_CLASS(klass);
> +rc->phases.enter = riscv_aclint_mtimer_reset_enter;
>  }
>
>  static const TypeInfo riscv_aclint_mtimer_info = {
> @@ -452,11 +470,32 @@ static void riscv_aclint_swi_realize(DeviceState *dev, 
> Error **errp)
>  }
>  }
>
> +static void riscv_aclint_swi_reset_enter(Object *obj, ResetType type)
> +{
> +/*
> + * According to RISC-V ACLINT spec:
> + *   - On MSWI device reset, each MSIP register is cleared to zero.
> + *
> + * p.s. SSWI device reset does nothing since SETSIP register always 
> reads 0.
> + */
> +RISCVAclintSwiState *swi = RISCV_ACLINT_SWI(obj);
> +int i;
> +
> +if (!swi->sswi) {
> +for (i = 0; i < swi->num_harts; i++) {
> +/* Clear MSIP registers by lowering software interrupts. */
> +qemu_irq_lower(swi->soft_irqs[i]);
> +}
> +}
> +}
> +
>  static void riscv_aclint_swi_class_init(ObjectClass *klass, void *data)
>  {
>  DeviceClass *dc = DEVICE_CLASS(klass);
>  dc->realize = riscv_aclint_swi_realize;
>  device_class_set_props(dc, riscv_aclint_swi_properties);
> +ResettableClass *rc = RESETTABLE_CLASS(klass);
> +rc->phases.enter = riscv_aclint_swi_reset_enter;
>  }
>
>  static const TypeInfo riscv_aclint_swi_info = {
> --
> 2.35.1
>
>



[PATCH v3 4/4] hw/intc: riscv_aclint: Add reset function of ACLINT devices

2022-04-19 Thread frank . chang
From: Jim Shu 

This commit implements reset function of all ACLINT devices.
ACLINT device reset will clear MTIME and MSIP register to 0.

Depend on RISC-V ACLINT spec v1.0-rc4:
https://github.com/riscv/riscv-aclint/blob/v1.0-rc4/riscv-aclint.adoc

Signed-off-by: Jim Shu 
Reviewed-by: Frank Chang 
---
 hw/intc/riscv_aclint.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
index ad7ccf96cd..67a07bb5b9 100644
--- a/hw/intc/riscv_aclint.c
+++ b/hw/intc/riscv_aclint.c
@@ -293,11 +293,29 @@ static void riscv_aclint_mtimer_realize(DeviceState *dev, 
Error **errp)
 }
 }
 
+static void riscv_aclint_mtimer_reset_enter(Object *obj, ResetType type)
+{
+/*
+ * According to RISC-V ACLINT spec:
+ *   - On MTIMER device reset, the MTIME register is cleared to zero.
+ *   - On MTIMER device reset, the MTIMECMP registers are in unknown state.
+ */
+RISCVAclintMTimerState *mtimer = RISCV_ACLINT_MTIMER(obj);
+
+/*
+ * Clear mtime register by writing to 0 it.
+ * Pending mtime interrupts will also be cleared at the same time.
+ */
+riscv_aclint_mtimer_write(mtimer, mtimer->time_base, 0, 8);
+}
+
 static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 dc->realize = riscv_aclint_mtimer_realize;
 device_class_set_props(dc, riscv_aclint_mtimer_properties);
+ResettableClass *rc = RESETTABLE_CLASS(klass);
+rc->phases.enter = riscv_aclint_mtimer_reset_enter;
 }
 
 static const TypeInfo riscv_aclint_mtimer_info = {
@@ -452,11 +470,32 @@ static void riscv_aclint_swi_realize(DeviceState *dev, 
Error **errp)
 }
 }
 
+static void riscv_aclint_swi_reset_enter(Object *obj, ResetType type)
+{
+/*
+ * According to RISC-V ACLINT spec:
+ *   - On MSWI device reset, each MSIP register is cleared to zero.
+ *
+ * p.s. SSWI device reset does nothing since SETSIP register always reads 
0.
+ */
+RISCVAclintSwiState *swi = RISCV_ACLINT_SWI(obj);
+int i;
+
+if (!swi->sswi) {
+for (i = 0; i < swi->num_harts; i++) {
+/* Clear MSIP registers by lowering software interrupts. */
+qemu_irq_lower(swi->soft_irqs[i]);
+}
+}
+}
+
 static void riscv_aclint_swi_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 dc->realize = riscv_aclint_swi_realize;
 device_class_set_props(dc, riscv_aclint_swi_properties);
+ResettableClass *rc = RESETTABLE_CLASS(klass);
+rc->phases.enter = riscv_aclint_swi_reset_enter;
 }
 
 static const TypeInfo riscv_aclint_swi_info = {
-- 
2.35.1