Add M mode initial entry PC and SP properties. Signed-off-by: Alistair Francis <alist...@alistair23.me> --- target/arm/cpu.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ target/arm/cpu.h | 3 +++ 2 files changed, 50 insertions(+)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 376db154f0..1d83972ab1 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -301,6 +301,9 @@ static void arm_cpu_reset(CPUState *s) */ initial_msp = ldl_p(rom); initial_pc = ldl_p(rom + 4); + } else if (cpu->init_sp || cpu->init_entry) { + initial_msp = cpu->init_sp; + initial_pc = cpu->init_entry; } else { /* Address zero not covered by a ROM blob, or the ROM blob * is in non-modifiable memory and this is a second reset after @@ -801,6 +804,38 @@ static void arm_set_init_svtor(Object *obj, Visitor *v, const char *name, visit_type_uint32(v, name, &cpu->init_svtor, errp); } +static void arm_get_init_sp(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + ARMCPU *cpu = ARM_CPU(obj); + + visit_type_uint32(v, name, &cpu->init_sp, errp); +} + +static void arm_set_init_sp(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + ARMCPU *cpu = ARM_CPU(obj); + + visit_type_uint32(v, name, &cpu->init_sp, errp); +} + +static void arm_get_init_entry(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + ARMCPU *cpu = ARM_CPU(obj); + + visit_type_uint32(v, name, &cpu->init_entry, errp); +} + +static void arm_set_init_entry(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + ARMCPU *cpu = ARM_CPU(obj); + + visit_type_uint32(v, name, &cpu->init_entry, errp); +} + void arm_cpu_post_init(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); @@ -913,6 +948,18 @@ void arm_cpu_post_init(Object *obj) object_property_add(obj, "init-svtor", "uint32", arm_get_init_svtor, arm_set_init_svtor, NULL, NULL, &error_abort); + } else { + /* + * M profile: initial value of the SP and entry. We can't just use + * a simple DEFINE_PROP_UINT32 for this because we want to permit + * the property to be set after realize. + */ + object_property_add(obj, "init-sp", "uint32", + arm_get_init_sp, arm_set_init_sp, + NULL, NULL, &error_abort); + object_property_add(obj, "init-entry", "uint32", + arm_get_init_entry, arm_set_init_entry, + NULL, NULL, &error_abort); } qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property, diff --git a/target/arm/cpu.h b/target/arm/cpu.h index f9da672be5..290fac19d3 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -805,6 +805,9 @@ struct ARMCPU { */ uint32_t psci_conduit; + /* For M, initial value of the entry and SP */ + uint32_t init_sp, init_entry; + /* For v8M, initial value of the Secure VTOR */ uint32_t init_svtor; -- 2.11.0