diff mbox series

[v2] target/hppa: Add CPU reset method

Message ID ZylIIkk7k69QIBmn@p100 (mailing list archive)
State New
Headers show
Series [v2] target/hppa: Add CPU reset method | expand

Commit Message

Helge Deller Nov. 4, 2024, 10:18 p.m. UTC
Add the CPU reset method, which resets all CPU registers and the TLB to
zero. Then the CPU will switch to 32-bit mode (PSW_W bit is not set) and
start execution at address 0xf0000004.
Although we currently want to zero out all values in the CPUHPPAState
struct, add the end_reset_fields marker in case the state structs gets
extended with other variables later on which should not be reset.

Signed-off-by: Helge Deller <deller@gmx.de>

V2: (based on feedback by Peter Maydell)
- Add end_reset_fields marker
- call reset function in hppa_cpu_initfn()

Comments

Peter Maydell Nov. 7, 2024, 11:20 a.m. UTC | #1
On Mon, 4 Nov 2024 at 22:18, Helge Deller <deller@kernel.org> wrote:
>
> Add the CPU reset method, which resets all CPU registers and the TLB to
> zero. Then the CPU will switch to 32-bit mode (PSW_W bit is not set) and
> start execution at address 0xf0000004.
> Although we currently want to zero out all values in the CPUHPPAState
> struct, add the end_reset_fields marker in case the state structs gets
> extended with other variables later on which should not be reset.
>
> Signed-off-by: Helge Deller <deller@gmx.de>
>
> V2: (based on feedback by Peter Maydell)
> - Add end_reset_fields marker
> - call reset function in hppa_cpu_initfn()
>
> diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
> index c38439c180..d12bf65021 100644
> --- a/target/hppa/cpu.c
> +++ b/target/hppa/cpu.c
> @@ -194,13 +194,8 @@ static void hppa_cpu_realizefn(DeviceState *dev, Error **errp)
>
>  static void hppa_cpu_initfn(Object *obj)
>  {
> -    CPUState *cs = CPU(obj);
> -    HPPACPU *cpu = HPPA_CPU(obj);
> -    CPUHPPAState *env = &cpu->env;
> -
> -    cs->exception_index = -1;
> -    cpu_hppa_loaded_fr0(env);
> -    cpu_hppa_put_psw(env, PSW_W);
> +    /* inital values loaded via reset in hppa_cpu_reset_hold() */
> +    resettable_reset(obj, RESET_TYPE_COLD);

You can't call reset from the CPU initfn (among other
things, the CPU object isn't fully constructed until
its realize method has been called).

CPU reset is rather awkward at the moment because it
doesn't happen automatically (because CPUs are not
subtypes of Device). So generally the way it works at
the moment is that the machine model code arranges to
reset the CPU object "manually". For Arm we do this
as part of setting up the CPU for however we're booting
the kernel in hw/arm/boot.c. It looks to me like for
HPPA the best place would be to call cpu_reset() in
hppa_machine_reset(), in the loop just before doing
the other CPU setup like calling cpu_set_pc().

>  }


Otherwise this looks good.

thanks
-- PMM
diff mbox series

Patch

diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index c38439c180..d12bf65021 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -194,13 +194,8 @@  static void hppa_cpu_realizefn(DeviceState *dev, Error **errp)
 
 static void hppa_cpu_initfn(Object *obj)
 {
-    CPUState *cs = CPU(obj);
-    HPPACPU *cpu = HPPA_CPU(obj);
-    CPUHPPAState *env = &cpu->env;
-
-    cs->exception_index = -1;
-    cpu_hppa_loaded_fr0(env);
-    cpu_hppa_put_psw(env, PSW_W);
+    /* inital values loaded via reset in hppa_cpu_reset_hold() */
+    resettable_reset(obj, RESET_TYPE_COLD);
 }
 
 static ObjectClass *hppa_cpu_class_by_name(const char *cpu_model)
@@ -235,15 +230,39 @@  static const TCGCPUOps hppa_tcg_ops = {
 #endif /* !CONFIG_USER_ONLY */
 };
 
+static void hppa_cpu_reset_hold(Object *obj, ResetType type)
+{
+    HPPACPU *cpu = HPPA_CPU(obj);
+    HPPACPUClass *scc = HPPA_CPU_GET_CLASS(cpu);
+    CPUHPPAState *env = &cpu->env;
+    CPUState *cs = CPU(cpu);
+
+    if (scc->parent_phases.hold) {
+        scc->parent_phases.hold(obj, type);
+    }
+
+    memset(env, 0, offsetof(CPUHPPAState, end_reset_fields));
+    cpu_set_pc(cs, 0xf0000004);
+    cpu_hppa_put_psw(env, hppa_is_pa20(env) ? PSW_W : 0);
+    cpu_hppa_loaded_fr0(env);
+
+    cs->exception_index = -1;
+    cs->halted = 0;
+}
+
 static void hppa_cpu_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
     CPUClass *cc = CPU_CLASS(oc);
     HPPACPUClass *acc = HPPA_CPU_CLASS(oc);
+    ResettableClass *rc = RESETTABLE_CLASS(oc);
 
     device_class_set_parent_realize(dc, hppa_cpu_realizefn,
                                     &acc->parent_realize);
 
+    resettable_class_set_parent_phases(rc, NULL, hppa_cpu_reset_hold, NULL,
+                                       &acc->parent_phases);
+
     cc->class_by_name = hppa_cpu_class_by_name;
     cc->has_work = hppa_cpu_has_work;
     cc->mmu_index = hppa_cpu_mmu_index;
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index e45ba50a59..32a674a8b8 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -263,6 +263,9 @@  typedef struct CPUArchState {
     IntervalTreeRoot tlb_root;
 
     HPPATLBEntry tlb[HPPA_TLB_ENTRIES];
+
+    /* Fields up to this point are cleared by a CPU reset */
+    struct {} end_reset_fields;
 } CPUHPPAState;
 
 /**
@@ -281,6 +284,7 @@  struct ArchCPU {
 /**
  * HPPACPUClass:
  * @parent_realize: The parent class' realize handler.
+ * @parent_phases: The parent class' reset phase handlers.
  *
  * An HPPA CPU model.
  */
@@ -288,6 +292,7 @@  struct HPPACPUClass {
     CPUClass parent_class;
 
     DeviceRealize parent_realize;
+    ResettablePhases parent_phases;
 };
 
 #include "exec/cpu-all.h"