ARM Cortex R5 Support
v3 cover ARM Cortex R5 Support
Hi Peter and all,
This patch series adds ARM Cortex R5 processor support. The PMSAv7 MPU is implemented. Two R5s are added to the Xilinx ZynqMP SoC.
Changed since v2:
Rebased (early patches merged)
Added boot CPU selection.
Addressed PMM review (see indiv. patches)
Changed since v1:
Addressed PMM and Alistair reviews (see indiv. patches) Adding prepatory refactorings to target-arm (new patches)
- TLBTR VMSA conditional (1)
- V7MP CP regs VMSA conditional (2)
- Refactor get_phys_addr FSR return path (4)
- Add MPUIR.U config (5)
- Improved cpu configurability around MPUs (6-7)
Regards,
Peter
Peter Crosthwaite (7):
target-arm/helper.c: define MPUIR register
target-arm: Add registers for PMSAv7
target-arm: Implement PMSAv7 MPU
target-arm: Add support for Cortex-R5
arm: xlnx-zynqmp: Preface CPU variables with "apu"
arm: xlnx-zynqmp: Add boot-cpu property
arm: xlnx-zynqmp: Add 2xCortexR5 CPUs
hw/arm/xlnx-ep108.c | 2 +- hw/arm/xlnx-zynqmp.c | 79 +++++++++++-- include/hw/arm/xlnx-zynqmp.h | 9 +- target-arm/cpu-qom.h | 2 + target-arm/cpu.c | 62 ++++++++++ target-arm/cpu.h | 11 ++ target-arm/helper.c | 274 +++++++++++++++++++++++++++++++++++++++++-- target-arm/machine.c | 34 ++++++ 8 files changed, 449 insertions(+), 24 deletions(-)
Signature · 1 line
2.4.3.3.g905f831
PATCH v3 1/7 target-arm/helper.c: define MPUIR register
Define the MPUIR register for MPU supporting ARMv6 and onwards. Currently we only support unified MPU.
The size of the unified MPU is defined via the number of "dregions". So just a single config is added to specify this size. (When split MPU is implemented we will add an extra iregions config).
---
changed since v2 (PMM review):
Fix commit message wording issues.
change assertion to realize error.
allow 0 regions.
raise error of >255 memory regions.
changed since v1:
Add #regions configuration
conditionalize MPUIR existence
target-arm/cpu-qom.h | 2 ++ target-arm/cpu.c | 18 ++++++++++++++++++ target-arm/helper.c | 10 ++++++++++ 3 files changed, 30 insertions(+)
target-arm/cpu-qom.h +2 -0
@@ -105,6 +105,8 @@ typedef struct ARMCPU {/* CPU has memory protection unit */ bool has_mpu; +/* PMSAv7 MPU number of supported regions */ +uint32_t pmsav7_dregion;/* PSCI conduit used to invoke PSCI methods * 0 - disabled, 1 - smc, 2 - hvc
target-arm/cpu.c +18 -0
@@ -457,6 +457,9 @@ static Property arm_cpu_has_el3_property =static Property arm_cpu_has_mpu_property =DEFINE_PROP_BOOL ("has-mpu" ,ARMCPU , has_mpu, true); +static Property arm_cpu_pmsav7_dregion_property = +DEFINE_PROP_UINT32 ("pmsav7-dregion" ,ARMCPU , pmsav7_dregion,16 ); +static void arm_cpu_post_init (Object *obj) {ARMCPU *cpu =ARM_CPU (obj);
@@ -488,6 +491,11 @@ static void arm_cpu_post_init(Object *obj)if (arm_feature (&cpu->env,ARM_FEATURE_MPU )) {qdev_property_add_static (DEVICE (obj), &arm_cpu_has_mpu_property, &error_abort); +if (arm_feature (&cpu->env,ARM_FEATURE_V7 )) { +qdev_property_add_static (DEVICE (obj), + &arm_cpu_pmsav7_dregion_property, + &error_abort); + } } }
@@ -580,6 +588,16 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)unset_feature (env,ARM_FEATURE_MPU ); } +if (arm_feature (env,ARM_FEATURE_MPU ) && +arm_feature (env,ARM_FEATURE_V7 )) { +uint32_t nr = cpu->pmsav7_dregion; + +if (nr >0xff ) { +error_setg (errp,"PMSAv7 MPU #regions invalid %" PRIu32"\n" , nr); +return ; + } + } +register_cp_regs_for_features (cpu);arm_cpu_register_gdb_regs_for_features (cpu);
target-arm/helper.c +10 -0
@@ -3465,6 +3465,13 @@ void register_cp_regs_for_features(ARMCPU *cpu) .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 3, .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0, }; +/* MPUIR is specific to PMSA V6+ */ +ARMCPRegInfo id_mpuir_reginfo = { + .name ="MPUIR" , + .cp =15 , .crn =0 , .crm =0 , .opc1 =0 , .opc2 =4 , + .access =PL1_R , .type =ARM_CP_CONST , + .resetvalue = cpu->pmsav7_dregion <<8 + };ARMCPRegInfo crn0_wi_reginfo = { .name ="CRN0_WI" , .cp =15 , .crn =0 , .crm =CP_ANY , .opc1 =CP_ANY , .opc2 =CP_ANY , .access =PL1_W ,
@@ -3487,6 +3494,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) r->access =PL1_RW ; } id_tlbtr_reginfo.access =PL1_RW ; + id_tlbtr_reginfo.access =PL1_RW ; }if (arm_feature (env,ARM_FEATURE_V8 )) {define_arm_cp_regs (cpu, id_v8_midr_cp_reginfo);
@@ -3496,6 +3504,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)define_arm_cp_regs (cpu, id_cp_reginfo);if (!arm_feature (env,ARM_FEATURE_MPU )) {define_one_arm_cp_reg (cpu, &id_tlbtr_reginfo); + }else if (arm_feature (env,ARM_FEATURE_V7 )) { +define_one_arm_cp_reg (cpu, &id_mpuir_reginfo); } }
Signature · 1 line
2.4.3.3.g905f831
PATCH v3 2/7 target-arm: Add registers for PMSAv7
In reply to Peter CrosthwaiteDefine the arm CP registers for PMSAv7 and their accessor functions. RGNR serves as a shared index that indexes into arrays storing the DRBAR, DRSR and DRACR registers. DRBAR and friends have to be VMSDd separately from the CP interface using a new PMSA specific VMSD subsection.
---
changed since v2 (PMM review):
conditionalise pointer allocation on non-zero regions Handle 0 regions in CP accessors
Tweak RGNR GUEST_ERROR message with s/>/>= Resolve conflict with VSMD subsection.needed refactor changed since v1 (PMM review):
Use raw_ptr
Implement reset as memset
Implement VMSD support
Add out-of-bounds guard or rgnr_write Dynamically allocate registers
Move arrays out of cp15 struct into dedicated substruct
target-arm/cpu.c | 6 ++++ target-arm/cpu.h | 10 ++++++ target-arm/helper.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++---- target-arm/machine.c | 34 ++++++++++++++++++++ 4 files changed, 133 insertions(+), 7 deletions(-)
target-arm/cpu.c +6 -0
@@ -596,6 +596,12 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)error_setg (errp,"PMSAv7 MPU #regions invalid %" PRIu32"\n" , nr);return ; } + +if (nr) { + env->pmsav7.drbar =g_new0 (uint32_t, nr); + env->pmsav7.drsr =g_new0 (uint32_t, nr); + env->pmsav7.dracr =g_new0 (uint32_t, nr); + } }register_cp_regs_for_features (cpu);
target-arm/cpu.h +10 -0
@@ -284,6 +284,9 @@ typedef struct CPUARMState { };uint64_t par_el[4 ]; }; + +uint32_t c6_rgnr; +uint32_t c9_insn;/* Cache lockdown registers. */ uint32_t c9_data;uint64_t c9_pmcr;/* performance monitor control register */
@@ -482,6 +485,13 @@ typedef struct CPUARMState {/* Internal CPU feature flags. */ uint64_t features; +/* PMSAv7 MPU */ +struct { +uint32_t *drbar; +uint32_t *drsr; +uint32_t *dracr; + } pmsav7; +void *nvic;const struct arm_boot_info *boot_info; } CPUARMState;
target-arm/helper.c +83 -7
102 lines not on this page · raw message
target-arm/machine.c +34 -0
@@ -125,6 +125,39 @@ static const VMStateDescription vmstate_thumb2ee = { } }; +static bool pmsav7_needed (void *opaque) +{ +ARMCPU *cpu = opaque; +CPUARMState *env = &cpu->env; + +return arm_feature (env,ARM_FEATURE_MPU ) && +arm_feature (env,ARM_FEATURE_V7 ); +} + +static bool pmsav7_rgnr_vmstate_validate (void *opaque,int version_id) +{ +ARMCPU *cpu = opaque; + +return cpu->env.cp15.c6_rgnr < cpu->pmsav7_dregion; +} + +static const VMStateDescription vmstate_pmsav7 = { + .name ="cpu/pmsav7" , + .version_id =1 , + .minimum_version_id =1 , + .needed = pmsav7_needed, + .fields = (VMStateField []) { +VMSTATE_VARRAY_UINT32 (env.pmsav7.drbar,ARMCPU , pmsav7_dregion,0 , + vmstate_info_uint32, uint32_t), +VMSTATE_VARRAY_UINT32 (env.pmsav7.drsr,ARMCPU , pmsav7_dregion,0 , + vmstate_info_uint32, uint32_t), +VMSTATE_VARRAY_UINT32 (env.pmsav7.dracr,ARMCPU , pmsav7_dregion,0 , + vmstate_info_uint32, uint32_t), +VMSTATE_VALIDATE ("rgnr is valid" , pmsav7_rgnr_vmstate_validate), +VMSTATE_END_OF_LIST () + } +}; +static int get_cpsr (QEMUFile *f,void *opaque,size_t size) {ARMCPU *cpu = opaque;
@@ -291,6 +324,7 @@ const VMStateDescription vmstate_arm_cpu = { &vmstate_iwmmxt, &vmstate_m, &vmstate_thumb2ee, + &vmstate_pmsav7, NULL } };
Signature · 1 line
2.4.3.3.g905f831
PATCH v3 3/7 target-arm: Implement PMSAv7 MPU
In reply to Peter CrosthwaiteUnified MPU only. Uses ARM architecture major revision to switch between PMSAv5 and v7 when ARM_FEATURE_MPU is set. PMSA v6 remains unsupported and is asserted against.
---
changed since v2
Add missing -1 on initialiser
Use default if dregions == 0
Drop unneeded else
changed since v1 (PMM review):
Add comment about PMSAv6 non-support
Fix case where MPU is completely disabled Ignore regions with 0 size.GUEST_ERROR invalid base address alignments UNIMP regions that are smaller than TARGET_PAGE_SIZE use extract32 to get SR disable bits
Fixed up DRACR AP bit error message.
Correct bullet point about MPU FSR format Rebased against new FSR return system removed *prot switch-case
target-arm/cpu.h | 1 + target-arm/helper.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 174 insertions(+), 1 deletion(-)
target-arm/cpu.h +1 -0
@@ -560,6 +560,7 @@ void pmccntr_sync(CPUARMState *env);#define SCTLR_DT (1U << 16)/* up to ??, RAO in v6 and v7 */ #define SCTLR_nTWI (1U << 16)/* v8 onward */ #define SCTLR_HA (1U << 17) +#define SCTLR_BR (1U << 17)/* PMSA only */ #define SCTLR_IT (1U << 18)/* up to ??, RAO in v6 and v7 */ #define SCTLR_nTWE (1U << 18)/* v8 onward */ #define SCTLR_WXN (1U << 19)
target-arm/helper.c +173 -1
198 lines not on this page · raw message
Signature · 1 line
2.4.3.3.g905f831
PATCH v3 4/7 target-arm: Add support for Cortex-R5
In reply to Peter CrosthwaiteIntroduce a CPU model for the Cortex R5 processor. ARMv7 with MPU, and both thumb and ARM div instructions.
Also implement dummy ATCM and BTCM. These CPs are defined for R5 but don't have a lot of meaning in QEMU yet. Raz them so the guest can proceed if they are read. The TCM registers will return a size of 0, indicating no TCM.
---
Based loosely on an old patch of Andreas' for the cortex-r4. changed since v1:
Squashed in R5 specific CP regs patch
Reordered to be after supporting patches
set mp_is_up
target-arm/cpu.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+)
target-arm/cpu.c +38 -0
@@ -847,6 +847,43 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data) cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt; } +static const ARMCPRegInfo cortexr5_cp_reginfo[] = { +/* Dummy the TCM region regs for the moment */ + { .name ="ATCM" , .cp =15 , .opc1 =0 , .crn =9 , .crm =1 , .opc2 =0 , + .access =PL1_RW , .type =ARM_CP_CONST }, + { .name ="BTCM" , .cp =15 , .opc1 =0 , .crn =9 , .crm =1 , .opc2 =1 , + .access =PL1_RW , .type =ARM_CP_CONST }, +REGINFO_SENTINEL +}; + +static void cortex_r5_initfn (Object *obj) +{ +ARMCPU *cpu =ARM_CPU (obj); + +set_feature (&cpu->env,ARM_FEATURE_V7 ); +set_feature (&cpu->env,ARM_FEATURE_THUMB_DIV ); +set_feature (&cpu->env,ARM_FEATURE_ARM_DIV ); +set_feature (&cpu->env,ARM_FEATURE_V7MP ); +set_feature (&cpu->env,ARM_FEATURE_MPU ); + cpu->midr =0x411fc153 ;/* r1p3 */ + cpu->id_pfr0 =0x0131 ; + cpu->id_pfr1 =0x001 ; + cpu->id_dfr0 =0x010400 ; + cpu->id_afr0 =0x0 ; + cpu->id_mmfr0 =0x0210030 ; + cpu->id_mmfr1 =0x00000000 ; + cpu->id_mmfr2 =0x01200000 ; + cpu->id_mmfr3 =0x0211 ; + cpu->id_isar0 =0x2101111 ; + cpu->id_isar1 =0x13112111 ; + cpu->id_isar2 =0x21232141 ; + cpu->id_isar3 =0x01112131 ; + cpu->id_isar4 =0x0010142 ; + cpu->id_isar5 =0x0 ; + cpu->mp_is_up = true; +define_arm_cp_regs (cpu, cortexr5_cp_reginfo); +} +static const ARMCPRegInfo cortexa8_cp_reginfo[] = { { .name ="L2LOCKDOWN" , .cp =15 , .crn =9 , .crm =0 , .opc1 =1 , .opc2 =0 , .access =PL1_RW , .type =ARM_CP_CONST , .resetvalue =0 },
@@ -1238,6 +1275,7 @@ static const ARMCPUInfo arm_cpus[] = { { .name = "arm11mpcore", .initfn = arm11mpcore_initfn }, { .name = "cortex-m3", .initfn = cortex_m3_initfn, .class_init = arm_v7m_class_init }, + { .name = "cortex-r5", .initfn = cortex_r5_initfn }, { .name = "cortex-a8", .initfn = cortex_a8_initfn }, { .name = "cortex-a9", .initfn = cortex_a9_initfn }, { .name = "cortex-a15", .initfn = cortex_a15_initfn },
Signature · 1 line
2.4.3.3.g905f831
Re: [Qemu-devel] [PATCH target-arm v3 4/7] target-arm: Add support for Cortex-R5
Quoted 9 lines · Peter Crosthwaite
Introduce a CPU model for the Cortex R5 processor. ARMv7 with MPU, and both thumb and ARM div instructions.
Also implement dummy ATCM and BTCM. These CPs are defined for R5 but don't have a lot of meaning in QEMU yet. Raz them so the guest can proceed if they are read. The TCM registers will return a size of 0, indicating no TCM.
Reviewed-by Peter Maydell <[email protected]>
Quoted 70 lines
Signed-off-by Peter Crosthwaite <[email protected]>---
Based loosely on an old patch of Andreas' for the cortex-r4. changed since v1:
Squashed in R5 specific CP regs patch
Reordered to be after supporting patches
setmp_is_uptarget-arm/cpu.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+)target-arm/cpu.c +38
-0@@ -847,6 +847,43 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data) cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt; } +static const ARMCPRegInfo cortexr5_cp_reginfo[] = { +/* Dummy the TCM region regs for the moment */ + { .name ="ATCM" , .cp =15 , .opc1 =0 , .crn =9 , .crm =1 , .opc2 =0 , + .access =PL1_RW , .type =ARM_CP_CONST }, + { .name ="BTCM" , .cp =15 , .opc1 =0 , .crn =9 , .crm =1 , .opc2 =1 , + .access =PL1_RW , .type =ARM_CP_CONST }, +REGINFO_SENTINEL +}; + +static void cortex_r5_initfn (Object *obj) +{ +ARMCPU *cpu =ARM_CPU (obj); + +set_feature (&cpu->env,ARM_FEATURE_V7 ); +set_feature (&cpu->env,ARM_FEATURE_THUMB_DIV ); +set_feature (&cpu->env,ARM_FEATURE_ARM_DIV ); +set_feature (&cpu->env,ARM_FEATURE_V7MP ); +set_feature (&cpu->env,ARM_FEATURE_MPU ); + cpu->midr =0x411fc153 ;/* r1p3 */ + cpu->id_pfr0 =0x0131 ; + cpu->id_pfr1 =0x001 ; + cpu->id_dfr0 =0x010400 ; + cpu->id_afr0 =0x0 ; + cpu->id_mmfr0 =0x0210030 ; + cpu->id_mmfr1 =0x00000000 ; + cpu->id_mmfr2 =0x01200000 ; + cpu->id_mmfr3 =0x0211 ; + cpu->id_isar0 =0x2101111 ; + cpu->id_isar1 =0x13112111 ; + cpu->id_isar2 =0x21232141 ; + cpu->id_isar3 =0x01112131 ; + cpu->id_isar4 =0x0010142 ; + cpu->id_isar5 =0x0 ; + cpu->mp_is_up = true; +define_arm_cp_regs (cpu, cortexr5_cp_reginfo); +} +static const ARMCPRegInfo cortexa8_cp_reginfo[] = { { .name ="L2LOCKDOWN" , .cp =15 , .crn =9 , .crm =0 , .opc1 =1 , .opc2 =0 , .access =PL1_RW , .type =ARM_CP_CONST , .resetvalue =0 },@@ -1238,6 +1275,7 @@ static const ARMCPUInfo arm_cpus[] = { { .name = "arm11mpcore", .initfn = arm11mpcore_initfn }, { .name = "cortex-m3", .initfn = cortex_m3_initfn, .class_init = arm_v7m_class_init }, + { .name = "cortex-r5", .initfn = cortex_r5_initfn }, { .name = "cortex-a8", .initfn = cortex_a8_initfn }, { .name = "cortex-a9", .initfn = cortex_a9_initfn }, { .name = "cortex-a15", .initfn = cortex_a15_initfn },Signature · 1 line
2.4.3.3.g905f831
PATCH v3 5/7 arm: xlnx-zynqmp: Preface CPU variables with "apu"
In reply to Peter CrosthwaiteThe CPUs currently supported by zynqmp are the APU (application processing unit) CPUs. There are other CPUs in Zynqmp so unqualified "cpus" in ambiguous. Preface the variables with "APU" accordingly, to prepare support adding the RPU (realtime processing unit) processors.
---
changed since v1:
s/acpu/apu-cpu/
hw/arm/xlnx-ep108.c | 2 +- hw/arm/xlnx-zynqmp.c | 26 ++++++++++++++------------ include/hw/arm/xlnx-zynqmp.h | 4 ++-- 3 files changed, 17 insertions(+), 15 deletions(-)
hw/arm/xlnx-ep108.c +1 -1
@@ -65,7 +65,7 @@ static void xlnx_ep108_init(MachineState *machine) xlnx_ep108_binfo.kernel_cmdline = machine->kernel_cmdline; xlnx_ep108_binfo.initrd_filename = machine->initrd_filename; xlnx_ep108_binfo.loader_start =0 ; -arm_load_kernel (&s->soc.cpu[0 ], &xlnx_ep108_binfo); +arm_load_kernel (&s->soc.apu_cpu[0 ], &xlnx_ep108_binfo); }static QEMUMachine xlnx_ep108_machine = {
hw/arm/xlnx-zynqmp.c +14 -12
@@ -64,10 +64,10 @@ static void xlnx_zynqmp_init(Object *obj)XlnxZynqMPState *s =XLNX_ZYNQMP (obj);int i; -for (i =0 ; i <XLNX_ZYNQMP_NUM_CPUS ; i++) { -object_initialize (&s->cpu[i],sizeof (s->cpu[i]), +for (i =0 ; i <XLNX_ZYNQMP_NUM_APU_CPUS ; i++) { +object_initialize (&s->apu_cpu[i],sizeof (s->apu_cpu[i]),"cortex-a53-" TYPE_ARM_CPU ); -object_property_add_child (obj,"cpu[*]" ,OBJECT (&s->cpu[i]), +object_property_add_child (obj,"apu-cpu[*]" ,OBJECT (&s->apu_cpu[i]), &error_abort); }
@@ -95,7 +95,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)qdev_prop_set_uint32 (DEVICE (&s->gic),"num-irq" ,GIC_NUM_SPI_INTR +32 );qdev_prop_set_uint32 (DEVICE (&s->gic),"revision" ,2 ); -qdev_prop_set_uint32 (DEVICE (&s->gic),"num-cpu" ,XLNX_ZYNQMP_NUM_CPUS ); +qdev_prop_set_uint32 (DEVICE (&s->gic),"num-cpu" ,XLNX_ZYNQMP_NUM_APU_CPUS );object_property_set_bool (OBJECT (&s->gic), true,"realized" , &err);if (err) {error_propagate ((errp), (err));
@@ -121,38 +121,40 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) } } -for (i =0 ; i <XLNX_ZYNQMP_NUM_CPUS ; i++) { +for (i =0 ; i <XLNX_ZYNQMP_NUM_APU_CPUS ; i++) {qemu_irq irq; -object_property_set_int (OBJECT (&s->cpu[i]),QEMU_PSCI_CONDUIT_SMC , +object_property_set_int (OBJECT (&s->apu_cpu[i]),QEMU_PSCI_CONDUIT_SMC ,"psci-conduit" , &error_abort);if (i >0 ) {/* Secondary CPUs start in PSCI powered-down state */ -object_property_set_bool (OBJECT (&s->cpu[i]), true, +object_property_set_bool (OBJECT (&s->apu_cpu[i]), true,"start-powered-off" , &error_abort); } -object_property_set_int (OBJECT (&s->cpu[i]),GIC_BASE_ADDR , +object_property_set_int (OBJECT (&s->apu_cpu[i]),GIC_BASE_ADDR ,"reset-cbar" , &err);if (err) {error_propagate ((errp), (err));return ; } -object_property_set_bool (OBJECT (&s->cpu[i]), true,"realized" , &err); +object_property_set_bool (OBJECT (&s->apu_cpu[i]), true,"realized" , + &err);if (err) {error_propagate ((errp), (err));return ; }sysbus_connect_irq (SYS_BUS_DEVICE (&s->gic), i, -qdev_get_gpio_in (DEVICE (&s->cpu[i]),ARM_CPU_IRQ )); +qdev_get_gpio_in (DEVICE (&s->apu_cpu[i]), +ARM_CPU_IRQ )); irq =qdev_get_gpio_in (DEVICE (&s->gic),arm_gic_ppi_index (i,ARM_PHYS_TIMER_PPI )); -qdev_connect_gpio_out (DEVICE (&s->cpu[i]),0 , irq); +qdev_connect_gpio_out (DEVICE (&s->apu_cpu[i]),0 , irq); irq =qdev_get_gpio_in (DEVICE (&s->gic),arm_gic_ppi_index (i,ARM_VIRT_TIMER_PPI )); -qdev_connect_gpio_out (DEVICE (&s->cpu[i]),1 , irq); +qdev_connect_gpio_out (DEVICE (&s->apu_cpu[i]),1 , irq); }for (i =0 ; i <GIC_NUM_SPI_INTR ; i++) {
include/hw/arm/xlnx-zynqmp.h +2 -2
@@ -27,7 +27,7 @@#define XLNX_ZYNQMP (obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \ TYPE_XLNX_ZYNQMP) -#define XLNX_ZYNQMP_NUM_CPUS 4 +#define XLNX_ZYNQMP_NUM_APU_CPUS 4#define XLNX_ZYNQMP_NUM_GEMS 4#define XLNX_ZYNQMP_NUM_UARTS 2
@@ -47,7 +47,7 @@ typedef struct XlnxZynqMPState {DeviceState parent_obj;/*< public >*/ -ARMCPU cpu[XLNX_ZYNQMP_NUM_CPUS ]; +ARMCPU apu_cpu[XLNX_ZYNQMP_NUM_APU_CPUS ];GICState gic;MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS ][XLNX_ZYNQMP_GIC_ALIASES ];CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS ];
Signature · 1 line
2.4.3.3.g905f831
Re: [Qemu-devel] [PATCH target-arm v3 5/7] arm: xlnx-zynqmp: Preface CPU variables with "apu"
Quoted 5 lines · Peter Crosthwaite
The CPUs currently supported by zynqmp are the APU (application processing unit) CPUs. There are other CPUs in Zynqmp so unqualified "cpus" in ambiguous. Preface the variables with "APU" accordingly, to prepare support adding the RPU (realtime processing unit) processors.
Quoted 124 lines
Signed-off-by Peter Crosthwaite <[email protected]>---
changed since v1:
s/acpu/apu-cpu/hw/arm/xlnx-ep108.c | 2 +- hw/arm/xlnx-zynqmp.c | 26 ++++++++++++++------------ include/hw/arm/xlnx-zynqmp.h | 4 ++-- 3 files changed, 17 insertions(+), 15 deletions(-)hw/arm/xlnx-ep108.c +1
-1@@ -65,7 +65,7 @@ static void xlnx_ep108_init(MachineState *machine) xlnx_ep108_binfo.kernel_cmdline = machine->kernel_cmdline; xlnx_ep108_binfo.initrd_filename = machine->initrd_filename; xlnx_ep108_binfo.loader_start =0 ; -arm_load_kernel (&s->soc.cpu[0 ], &xlnx_ep108_binfo); +arm_load_kernel (&s->soc.apu_cpu[0 ], &xlnx_ep108_binfo); }static QEMUMachine xlnx_ep108_machine = {hw/arm/xlnx-zynqmp.c +14
-12@@ -64,10 +64,10 @@ static void xlnx_zynqmp_init(Object *obj)XlnxZynqMPState *s =XLNX_ZYNQMP (obj);int i; -for (i =0 ; i <XLNX_ZYNQMP_NUM_CPUS ; i++) { -object_initialize (&s->cpu[i],sizeof (s->cpu[i]), +for (i =0 ; i <XLNX_ZYNQMP_NUM_APU_CPUS ; i++) { +object_initialize (&s->apu_cpu[i],sizeof (s->apu_cpu[i]),"cortex-a53-" TYPE_ARM_CPU ); -object_property_add_child (obj,"cpu[*]" ,OBJECT (&s->cpu[i]), +object_property_add_child (obj,"apu-cpu[*]" ,OBJECT (&s->apu_cpu[i]), &error_abort); }@@ -95,7 +95,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)qdev_prop_set_uint32 (DEVICE (&s->gic),"num-irq" ,GIC_NUM_SPI_INTR +32 );qdev_prop_set_uint32 (DEVICE (&s->gic),"revision" ,2 ); -qdev_prop_set_uint32 (DEVICE (&s->gic),"num-cpu" ,XLNX_ZYNQMP_NUM_CPUS ); +qdev_prop_set_uint32 (DEVICE (&s->gic),"num-cpu" ,XLNX_ZYNQMP_NUM_APU_CPUS );object_property_set_bool (OBJECT (&s->gic), true,"realized" , &err);if (err) {error_propagate ((errp), (err));@@ -121,38 +121,40 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) } } -for (i =0 ; i <XLNX_ZYNQMP_NUM_CPUS ; i++) { +for (i =0 ; i <XLNX_ZYNQMP_NUM_APU_CPUS ; i++) {qemu_irq irq; -object_property_set_int (OBJECT (&s->cpu[i]),QEMU_PSCI_CONDUIT_SMC , +object_property_set_int (OBJECT (&s->apu_cpu[i]),QEMU_PSCI_CONDUIT_SMC ,"psci-conduit" , &error_abort);if (i >0 ) {/* Secondary CPUs start in PSCI powered-down state */ -object_property_set_bool (OBJECT (&s->cpu[i]), true, +object_property_set_bool (OBJECT (&s->apu_cpu[i]), true,"start-powered-off" , &error_abort); } -object_property_set_int (OBJECT (&s->cpu[i]),GIC_BASE_ADDR , +object_property_set_int (OBJECT (&s->apu_cpu[i]),GIC_BASE_ADDR ,"reset-cbar" , &err);if (err) {error_propagate ((errp), (err));return ; } -object_property_set_bool (OBJECT (&s->cpu[i]), true,"realized" , &err); +object_property_set_bool (OBJECT (&s->apu_cpu[i]), true,"realized" , + &err);if (err) {error_propagate ((errp), (err));return ; }sysbus_connect_irq (SYS_BUS_DEVICE (&s->gic), i, -qdev_get_gpio_in (DEVICE (&s->cpu[i]),ARM_CPU_IRQ )); +qdev_get_gpio_in (DEVICE (&s->apu_cpu[i]), +ARM_CPU_IRQ )); irq =qdev_get_gpio_in (DEVICE (&s->gic),arm_gic_ppi_index (i,ARM_PHYS_TIMER_PPI )); -qdev_connect_gpio_out (DEVICE (&s->cpu[i]),0 , irq); +qdev_connect_gpio_out (DEVICE (&s->apu_cpu[i]),0 , irq); irq =qdev_get_gpio_in (DEVICE (&s->gic),arm_gic_ppi_index (i,ARM_VIRT_TIMER_PPI )); -qdev_connect_gpio_out (DEVICE (&s->cpu[i]),1 , irq); +qdev_connect_gpio_out (DEVICE (&s->apu_cpu[i]),1 , irq); }for (i =0 ; i <GIC_NUM_SPI_INTR ; i++) {include/hw/arm/xlnx-zynqmp.h +2
-2@@ -27,7 +27,7 @@#define XLNX_ZYNQMP (obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \ TYPE_XLNX_ZYNQMP) -#define XLNX_ZYNQMP_NUM_CPUS 4 +#define XLNX_ZYNQMP_NUM_APU_CPUS 4#define XLNX_ZYNQMP_NUM_GEMS 4#define XLNX_ZYNQMP_NUM_UARTS 2@@ -47,7 +47,7 @@ typedef struct XlnxZynqMPState {DeviceState parent_obj;/*< public >*/ -ARMCPU cpu[XLNX_ZYNQMP_NUM_CPUS ]; +ARMCPU apu_cpu[XLNX_ZYNQMP_NUM_APU_CPUS ];GICState gic;MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS ][XLNX_ZYNQMP_GIC_ALIASES ];CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS ];Signature · 1 line
2.4.3.3.g905f831
PATCH v3 6/7 arm: xlnx-zynqmp: Add boot-cpu property
In reply to Peter CrosthwaiteAdd a string property that specifies the primary boot cpu. All CPUs except the one selected will start-powered-off. This allows for elf boots on any CPU, which prepares support for booting R5 elfs directly on the R5 processors.
--- hw/arm/xlnx-ep108.c | 2 +- hw/arm/xlnx-zynqmp.c | 19 ++++++++++++++++++- include/hw/arm/xlnx-zynqmp.h | 3 +++ 3 files changed, 22 insertions(+), 2 deletions(-)
hw/arm/xlnx-ep108.c +1 -1
@@ -65,7 +65,7 @@ static void xlnx_ep108_init(MachineState *machine) xlnx_ep108_binfo.kernel_cmdline = machine->kernel_cmdline; xlnx_ep108_binfo.initrd_filename = machine->initrd_filename; xlnx_ep108_binfo.loader_start =0 ; -arm_load_kernel (&s->soc.apu_cpu[0 ], &xlnx_ep108_binfo); +arm_load_kernel (s->soc.boot_cpu_ptr, &xlnx_ep108_binfo); }static QEMUMachine xlnx_ep108_machine = {
hw/arm/xlnx-zynqmp.c +18 -1
@@ -90,6 +90,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)XlnxZynqMPState *s =XLNX_ZYNQMP (dev);MemoryRegion *system_memory =get_system_memory ();uint8_t i; +const char *boot_cpu = s->boot_cpu ? s->boot_cpu :"apu-cpu[0]" ;qemu_irq gic_spi[GIC_NUM_SPI_INTR ];Error *err =NULL ;
@@ -123,13 +124,18 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)for (i =0 ; i <XLNX_ZYNQMP_NUM_APU_CPUS ; i++) {qemu_irq irq; +char *name;object_property_set_int (OBJECT (&s->apu_cpu[i]),QEMU_PSCI_CONDUIT_SMC ,"psci-conduit" , &error_abort); -if (i >0 ) { + + name =object_get_canonical_path_component (OBJECT (&s->apu_cpu[i])); +if (strcmp (name, boot_cpu)) {/* Secondary CPUs start in PSCI powered-down state */ object_property_set_bool (OBJECT (&s->apu_cpu[i]), true,"start-powered-off" , &error_abort); + }else { + s->boot_cpu_ptr = &s->apu_cpu[i]; } object_property_set_int(OBJECT(&s->apu_cpu[i]), GIC_BASE_ADDR,
@@ -157,6 +163,11 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)qdev_connect_gpio_out (DEVICE (&s->apu_cpu[i]),1 , irq); } +if (!s->boot_cpu_ptr) { +error_setg (errp,"ZynqMP Boot cpu %s not found\n" , boot_cpu); +return ; + } +for (i =0 ; i <GIC_NUM_SPI_INTR ; i++) { gic_spi[i] =qdev_get_gpio_in (DEVICE (&s->gic), i); }
@@ -190,10 +201,16 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) } } +static Property xlnx_zynqmp_props[] = { +DEFINE_PROP_STRING ("boot-cpu" , XlnxZynqMPState, boot_cpu), +DEFINE_PROP_END_OF_LIST () +}; +static void xlnx_zynqmp_class_init (ObjectClass *oc,void *data) {DeviceClass *dc =DEVICE_CLASS (oc); + dc->props = xlnx_zynqmp_props; dc->realize = xlnx_zynqmp_realize; }
include/hw/arm/xlnx-zynqmp.h +3 -0
@@ -52,6 +52,9 @@ typedef struct XlnxZynqMPState {MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS ][XLNX_ZYNQMP_GIC_ALIASES ];CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS ];CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS ]; + +char *boot_cpu; +ARMCPU *boot_cpu_ptr; } XlnxZynqMPState;#define XLNX_ZYNQMP_H
Signature · 1 line
2.4.3.3.g905f831
PATCH v3 7/7 arm: xlnx-zynqmp: Add 2xCortexR5 CPUs
In reply to Peter CrosthwaiteAdd the 2xCortexR5 CPUs to zynqmp board. They are powered off on reset (this is true of real hardware) by default or selectable as the boot processor.
---
changed since v2:
Add boot-cpu start-powered-off conditional
changed since v1:
s/rcpu/rpu-cpu/
hw/arm/xlnx-zynqmp.c | 34 ++++++++++++++++++++++++++++++++++ include/hw/arm/xlnx-zynqmp.h | 2 ++ 2 files changed, 36 insertions(+)
hw/arm/xlnx-zynqmp.c +34 -0
@@ -71,6 +71,13 @@ static void xlnx_zynqmp_init(Object *obj) &error_abort); } +for (i =0 ; i <XLNX_ZYNQMP_NUM_RPU_CPUS ; i++) { +object_initialize (&s->rpu_cpu[i],sizeof (s->rpu_cpu[i]), +"cortex-r5-" TYPE_ARM_CPU ); +object_property_add_child (obj,"rpu-cpu[*]" ,OBJECT (&s->rpu_cpu[i]), + &error_abort); + } +object_initialize (&s->gic,sizeof (s->gic),TYPE_ARM_GIC );qdev_set_parent_bus (DEVICE (&s->gic),sysbus_get_default ());
@@ -163,6 +170,33 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)qdev_connect_gpio_out (DEVICE (&s->apu_cpu[i]),1 , irq); } +for (i =0 ; i <XLNX_ZYNQMP_NUM_RPU_CPUS ; i++) { +char *name; + + name =object_get_canonical_path_component (OBJECT (&s->rpu_cpu[i])); +if (strcmp (name, boot_cpu)) { +/* Secondary CPUs start in PSCI powered-down state */ +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true, +"start-powered-off" , &error_abort); + }else { + s->boot_cpu_ptr = &s->rpu_cpu[i]; + } + +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true,"reset-hivecs" , + &err); +if (err !=NULL ) { +error_propagate (errp, err); +return ; + } + +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true,"realized" , + &err); +if (err) { +error_propagate ((errp), (err)); +return ; + } + } +if (!s->boot_cpu_ptr) {error_setg (errp,"ZynqMP Boot cpu %s not found\n" , boot_cpu);return ;
include/hw/arm/xlnx-zynqmp.h +2 -0
@@ -28,6 +28,7 @@ TYPE_XLNX_ZYNQMP)#define XLNX_ZYNQMP_NUM_APU_CPUS 4 +#define XLNX_ZYNQMP_NUM_RPU_CPUS 2#define XLNX_ZYNQMP_NUM_GEMS 4#define XLNX_ZYNQMP_NUM_UARTS 2
@@ -48,6 +49,7 @@ typedef struct XlnxZynqMPState {/*< public >*/ ARMCPU apu_cpu[XLNX_ZYNQMP_NUM_APU_CPUS ]; +ARMCPU rpu_cpu[XLNX_ZYNQMP_NUM_RPU_CPUS ];GICState gic;MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS ][XLNX_ZYNQMP_GIC_ALIASES ];CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS ];
Signature · 1 line
2.4.3.3.g905f831
Re: [Qemu-devel] [PATCH target-arm v3 7/7] arm: xlnx-zynqmp: Add 2xCortexR5 CPUs
Quoted 3 lines · Peter Crosthwaite
Add the 2xCortexR5 CPUs to zynqmp board. They are powered off on reset (this is true of real hardware) by default or selectable as the boot processor.
Hi Peter,
I think it would be good if you could model at least a minimal way to release the R5s from reset the "real" way. The R5s are not covered by PSCI in real code and not all code uses PSCI, in particular not any R5 code.
How would the R5s be useful with upstream with this version? Maybe I'm missing something.
Cheers,
Edgar
Quoted 87 lines
Signed-off-by Peter Crosthwaite <[email protected]>---
changed since v2:
Add boot-cpu start-powered-off conditional
changed since v1:
s/rcpu/rpu-cpu/hw/arm/xlnx-zynqmp.c | 34 ++++++++++++++++++++++++++++++++++ include/hw/arm/xlnx-zynqmp.h | 2 ++ 2 files changed, 36 insertions(+)hw/arm/xlnx-zynqmp.c +34
-0@@ -71,6 +71,13 @@ static void xlnx_zynqmp_init(Object *obj) &error_abort); } +for (i =0 ; i <XLNX_ZYNQMP_NUM_RPU_CPUS ; i++) { +object_initialize (&s->rpu_cpu[i],sizeof (s->rpu_cpu[i]), +"cortex-r5-" TYPE_ARM_CPU ); +object_property_add_child (obj,"rpu-cpu[*]" ,OBJECT (&s->rpu_cpu[i]), + &error_abort); + } +object_initialize (&s->gic,sizeof (s->gic),TYPE_ARM_GIC );qdev_set_parent_bus (DEVICE (&s->gic),sysbus_get_default ());@@ -163,6 +170,33 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)qdev_connect_gpio_out (DEVICE (&s->apu_cpu[i]),1 , irq); } +for (i =0 ; i <XLNX_ZYNQMP_NUM_RPU_CPUS ; i++) { +char *name; + + name =object_get_canonical_path_component (OBJECT (&s->rpu_cpu[i])); +if (strcmp (name, boot_cpu)) { +/* Secondary CPUs start in PSCI powered-down state */ +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true, +"start-powered-off" , &error_abort); + }else { + s->boot_cpu_ptr = &s->rpu_cpu[i]; + } + +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true,"reset-hivecs" , + &err); +if (err !=NULL ) { +error_propagate (errp, err); +return ; + } + +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true,"realized" , + &err); +if (err) { +error_propagate ((errp), (err)); +return ; + } + } +if (!s->boot_cpu_ptr) {error_setg (errp,"ZynqMP Boot cpu %s not found\n" , boot_cpu);return ;include/hw/arm/xlnx-zynqmp.h +2
-0@@ -28,6 +28,7 @@ TYPE_XLNX_ZYNQMP)#define XLNX_ZYNQMP_NUM_APU_CPUS 4 +#define XLNX_ZYNQMP_NUM_RPU_CPUS 2#define XLNX_ZYNQMP_NUM_GEMS 4#define XLNX_ZYNQMP_NUM_UARTS 2@@ -48,6 +49,7 @@ typedef struct XlnxZynqMPState {/*< public >*/ ARMCPU apu_cpu[XLNX_ZYNQMP_NUM_APU_CPUS ]; +ARMCPU rpu_cpu[XLNX_ZYNQMP_NUM_RPU_CPUS ];GICState gic;MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS ][XLNX_ZYNQMP_GIC_ALIASES ];CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS ];Signature · 1 line
2.4.3.3.g905f831
Re: [Qemu-devel] [PATCH target-arm v3 7/7] arm: xlnx-zynqmp: Add 2xCortexR5 CPUs
Quoted 7 lines · Edgar E. Iglesias
Quoted 3 lines · Peter Crosthwaite
Add the 2xCortexR5 CPUs to zynqmp board. They are powered off on reset (this is true of real hardware) by default or selectable as the boot processor.
Hi Peter,
Quoted 8 lines
I think it would be good if you could model at least a minimal way to release the R5s from reset the "real" way. The R5s are not covered by PSCI in real code and not all code uses PSCI, in particular not any R5 code.
How would the R5s be useful with upstream with this version? Maybe I'm missing something.
You can nominate an R5 instead of A53 as the one non-powered-off cpu by setting the zynqmp boot-cpu property with -global:
$ qemu-system-aarch64 -M xlnx-ep108 -m 2048 -nographic -kernel ./r5_image.elf -global xlnx,zynqmp.boot-cpu="rpu-cpu[0]"
This works with elf boots.
Regards,
Peter
Quoted 92 lines
Cheers,
EdgarQuoted 87 lines
Signed-off-by Peter Crosthwaite <[email protected]>---
changed since v2:
Add boot-cpu start-powered-off conditional
changed since v1:
s/rcpu/rpu-cpu/hw/arm/xlnx-zynqmp.c | 34 ++++++++++++++++++++++++++++++++++ include/hw/arm/xlnx-zynqmp.h | 2 ++ 2 files changed, 36 insertions(+)hw/arm/xlnx-zynqmp.c +34
-0@@ -71,6 +71,13 @@ static void xlnx_zynqmp_init(Object *obj) &error_abort); } +for (i =0 ; i <XLNX_ZYNQMP_NUM_RPU_CPUS ; i++) { +object_initialize (&s->rpu_cpu[i],sizeof (s->rpu_cpu[i]), +"cortex-r5-" TYPE_ARM_CPU ); +object_property_add_child (obj,"rpu-cpu[*]" ,OBJECT (&s->rpu_cpu[i]), + &error_abort); + } +object_initialize (&s->gic,sizeof (s->gic),TYPE_ARM_GIC );qdev_set_parent_bus (DEVICE (&s->gic),sysbus_get_default ());@@ -163,6 +170,33 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)qdev_connect_gpio_out (DEVICE (&s->apu_cpu[i]),1 , irq); } +for (i =0 ; i <XLNX_ZYNQMP_NUM_RPU_CPUS ; i++) { +char *name; + + name =object_get_canonical_path_component (OBJECT (&s->rpu_cpu[i])); +if (strcmp (name, boot_cpu)) { +/* Secondary CPUs start in PSCI powered-down state */ +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true, +"start-powered-off" , &error_abort); + }else { + s->boot_cpu_ptr = &s->rpu_cpu[i]; + } + +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true,"reset-hivecs" , + &err); +if (err !=NULL ) { +error_propagate (errp, err); +return ; + } + +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true,"realized" , + &err); +if (err) { +error_propagate ((errp), (err)); +return ; + } + } +if (!s->boot_cpu_ptr) {error_setg (errp,"ZynqMP Boot cpu %s not found\n" , boot_cpu);return ;include/hw/arm/xlnx-zynqmp.h +2
-1@@ -28,6 +28,7 @@ TYPE_XLNX_ZYNQMP)#define XLNX_ZYNQMP_NUM_APU_CPUS 4 +#define XLNX_ZYNQMP_NUM_RPU_CPUS 2#define XLNX_ZYNQMP_NUM_GEMS 4#define XLNX_ZYNQMP_NUM_UARTS 2@@ -48,6 +49,7 @@ typedef struct XlnxZynqMPState {/*< public >*/ ARMCPU apu_cpu[XLNX_ZYNQMP_NUM_APU_CPUS ]; +ARMCPU rpu_cpu[XLNX_ZYNQMP_NUM_RPU_CPUS ];GICState gic;MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS ][XLNX_ZYNQMP_GIC_ALIASES ];CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS ]; --2.4.3.3.g905f831
Re: [Qemu-devel] [PATCH target-arm v3 7/7] arm: xlnx-zynqmp: Add 2xCortexR5 CPUs
Quoted 18 lines · Peter Crosthwaite
Quoted 7 lines · Edgar E. Iglesias
Quoted 3 lines · Peter Crosthwaite
Add the 2xCortexR5 CPUs to zynqmp board. They are powered off on reset (this is true of real hardware) by default or selectable as the boot processor.
Hi Peter,
Quoted 8 lines
I think it would be good if you could model at least a minimal way to release the R5s from reset the "real" way. The R5s are not covered by PSCI in real code and not all code uses PSCI, in particular not any R5 code.
How would the R5s be useful with upstream with this version? Maybe I'm missing something.
Quoted 7 lines
You can nominate an R5 instead of A53 as the one non-powered-off cpu by setting the zynqmp boot-cpu property with -global:
$ qemu-system-aarch64 -M xlnx-ep108 -m 2048 -nographic -kernel ./r5_image.elf -global xlnx,zynqmp.boot-cpu="rpu-cpu[0]"This works with elf boots.
In that mode, how do I release the A53s (or the other R5)? Will it be either one R5 or the A53s?
Cheers,
Edgar
Quoted 96 lines
Regards,
PeterQuoted 92 lines
Cheers,
EdgarQuoted 87 lines
Signed-off-by Peter Crosthwaite <[email protected]>---
changed since v2:
Add boot-cpu start-powered-off conditional
changed since v1:
s/rcpu/rpu-cpu/hw/arm/xlnx-zynqmp.c | 34 ++++++++++++++++++++++++++++++++++ include/hw/arm/xlnx-zynqmp.h | 2 ++ 2 files changed, 36 insertions(+)hw/arm/xlnx-zynqmp.c +34
-0@@ -71,6 +71,13 @@ static void xlnx_zynqmp_init(Object *obj) &error_abort); } +for (i =0 ; i <XLNX_ZYNQMP_NUM_RPU_CPUS ; i++) { +object_initialize (&s->rpu_cpu[i],sizeof (s->rpu_cpu[i]), +"cortex-r5-" TYPE_ARM_CPU ); +object_property_add_child (obj,"rpu-cpu[*]" ,OBJECT (&s->rpu_cpu[i]), + &error_abort); + } +object_initialize (&s->gic,sizeof (s->gic),TYPE_ARM_GIC );qdev_set_parent_bus (DEVICE (&s->gic),sysbus_get_default ());@@ -163,6 +170,33 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)qdev_connect_gpio_out (DEVICE (&s->apu_cpu[i]),1 , irq); } +for (i =0 ; i <XLNX_ZYNQMP_NUM_RPU_CPUS ; i++) { +char *name; + + name =object_get_canonical_path_component (OBJECT (&s->rpu_cpu[i])); +if (strcmp (name, boot_cpu)) { +/* Secondary CPUs start in PSCI powered-down state */ +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true, +"start-powered-off" , &error_abort); + }else { + s->boot_cpu_ptr = &s->rpu_cpu[i]; + } + +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true,"reset-hivecs" , + &err); +if (err !=NULL ) { +error_propagate (errp, err); +return ; + } + +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true,"realized" , + &err); +if (err) { +error_propagate ((errp), (err)); +return ; + } + } +if (!s->boot_cpu_ptr) {error_setg (errp,"ZynqMP Boot cpu %s not found\n" , boot_cpu);return ;include/hw/arm/xlnx-zynqmp.h +2
-1@@ -28,6 +28,7 @@ TYPE_XLNX_ZYNQMP)#define XLNX_ZYNQMP_NUM_APU_CPUS 4 +#define XLNX_ZYNQMP_NUM_RPU_CPUS 2#define XLNX_ZYNQMP_NUM_GEMS 4#define XLNX_ZYNQMP_NUM_UARTS 2@@ -48,6 +49,7 @@ typedef struct XlnxZynqMPState {/*< public >*/ ARMCPU apu_cpu[XLNX_ZYNQMP_NUM_APU_CPUS ]; +ARMCPU rpu_cpu[XLNX_ZYNQMP_NUM_RPU_CPUS ];GICState gic;MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS ][XLNX_ZYNQMP_GIC_ALIASES ];CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS ]; --2.4.3.3.g905f831
Re: [Qemu-devel] [PATCH target-arm v3 7/7] arm: xlnx-zynqmp: Add 2xCortexR5 CPUs
Quoted 22 lines · Edgar E. Iglesias
Quoted 21 lines · Peter Crosthwaite
Quoted 7 lines · Edgar E. Iglesias
Quoted 3 lines · Peter Crosthwaite
Add the 2xCortexR5 CPUs to zynqmp board. They are powered off on reset (this is true of real hardware) by default or selectable as the boot processor.
Hi Peter,
Quoted 8 lines
I think it would be good if you could model at least a minimal way to release the R5s from reset the "real" way. The R5s are not covered by PSCI in real code and not all code uses PSCI, in particular not any R5 code.
How would the R5s be useful with upstream with this version? Maybe I'm missing something.
You can nominate an R5 instead of A53 as the one non-powered-off cpu by setting the zynqmp boot-cpu property with -global:
Quoted 8 lines
Quoted 4 lines
$ qemu-system-aarch64 -M xlnx-ep108 -m 2048 -nographic -kernel ./r5_image.elf -global xlnx,zynqmp.boot-cpu="rpu-cpu[0]"This works with elf boots.
In that mode, how do I release the A53s (or the other R5)? Will it be either one R5 or the A53s?
Just one or the other so far unless you do a backdoor PSCI release from SW. Loading multiple softwares needs either a more dynamic bootloader process or the reset controller model, both of which I want to follow up later with.
Regards,
Peter
Quoted 101 lines
Cheers,
EdgarQuoted 96 lines
Regards,
PeterQuoted 92 lines
Cheers,
EdgarQuoted 87 lines
Signed-off-by Peter Crosthwaite <[email protected]>---
changed since v2:
Add boot-cpu start-powered-off conditional
changed since v1:
s/rcpu/rpu-cpu/hw/arm/xlnx-zynqmp.c | 34 ++++++++++++++++++++++++++++++++++ include/hw/arm/xlnx-zynqmp.h | 2 ++ 2 files changed, 36 insertions(+)hw/arm/xlnx-zynqmp.c +34
-0@@ -71,6 +71,13 @@ static void xlnx_zynqmp_init(Object *obj) &error_abort); } +for (i =0 ; i <XLNX_ZYNQMP_NUM_RPU_CPUS ; i++) { +object_initialize (&s->rpu_cpu[i],sizeof (s->rpu_cpu[i]), +"cortex-r5-" TYPE_ARM_CPU ); +object_property_add_child (obj,"rpu-cpu[*]" ,OBJECT (&s->rpu_cpu[i]), + &error_abort); + } +object_initialize (&s->gic,sizeof (s->gic),TYPE_ARM_GIC );qdev_set_parent_bus (DEVICE (&s->gic),sysbus_get_default ());@@ -163,6 +170,33 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)qdev_connect_gpio_out (DEVICE (&s->apu_cpu[i]),1 , irq); } +for (i =0 ; i <XLNX_ZYNQMP_NUM_RPU_CPUS ; i++) { +char *name; + + name =object_get_canonical_path_component (OBJECT (&s->rpu_cpu[i])); +if (strcmp (name, boot_cpu)) { +/* Secondary CPUs start in PSCI powered-down state */ +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true, +"start-powered-off" , &error_abort); + }else { + s->boot_cpu_ptr = &s->rpu_cpu[i]; + } + +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true,"reset-hivecs" , + &err); +if (err !=NULL ) { +error_propagate (errp, err); +return ; + } + +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true,"realized" , + &err); +if (err) { +error_propagate ((errp), (err)); +return ; + } + } +if (!s->boot_cpu_ptr) {error_setg (errp,"ZynqMP Boot cpu %s not found\n" , boot_cpu);return ;include/hw/arm/xlnx-zynqmp.h +2
-1@@ -28,6 +28,7 @@ TYPE_XLNX_ZYNQMP)#define XLNX_ZYNQMP_NUM_APU_CPUS 4 +#define XLNX_ZYNQMP_NUM_RPU_CPUS 2#define XLNX_ZYNQMP_NUM_GEMS 4#define XLNX_ZYNQMP_NUM_UARTS 2@@ -48,6 +49,7 @@ typedef struct XlnxZynqMPState {/*< public >*/ ARMCPU apu_cpu[XLNX_ZYNQMP_NUM_APU_CPUS ]; +ARMCPU rpu_cpu[XLNX_ZYNQMP_NUM_RPU_CPUS ];GICState gic;MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS ][XLNX_ZYNQMP_GIC_ALIASES ];CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS ]; --2.4.3.3.g905f831
Re: [Qemu-devel] [PATCH target-arm v3 7/7] arm: xlnx-zynqmp: Add 2xCortexR5 CPUs
Quoted 27 lines · Peter Crosthwaite
Quoted 25 lines · Edgar E. Iglesias
Quoted 24 lines · Peter Crosthwaite
Quoted 7 lines · Edgar E. Iglesias
Quoted 3 lines · Peter Crosthwaite
Add the 2xCortexR5 CPUs to zynqmp board. They are powered off on reset (this is true of real hardware) by default or selectable as the boot processor.
Hi Peter,
Quoted 8 lines
I think it would be good if you could model at least a minimal way to release the R5s from reset the "real" way. The R5s are not covered by PSCI in real code and not all code uses PSCI, in particular not any R5 code.
How would the R5s be useful with upstream with this version? Maybe I'm missing something.
You can nominate an R5 instead of A53 as the one non-powered-off cpu by setting the zynqmp boot-cpu property with -global:
$ qemu-system-aarch64 -M xlnx-ep108 -m 2048 -nographic -kernel ./r5_image.elf -global xlnx,zynqmp.boot-cpu="rpu-cpu[0]"
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
This works with elf boots.
In that mode, how do I release the A53s (or the other R5)? Will it be either one R5 or the A53s?
Just one or the other so far unless you do a backdoor PSCI release from SW. Loading multiple softwares needs either a more dynamic
Note that you can't do PSCI from the R5s. The A53s could wake the R5s with PSCI in this QEMU but not on real SW stack which is a little confusing...
Quoted 2 lines
bootloader process or the reset controller model, both of which I want to follow up later with.
OK, it's quite limited ATM but I guess it's a step forward...
Thanks,
Edgar
Quoted 105 lines
Regards,
PeterQuoted 101 lines
Cheers,
EdgarQuoted 96 lines
Regards,
PeterQuoted 92 lines
Cheers,
EdgarQuoted 87 lines
Signed-off-by Peter Crosthwaite <[email protected]>---
changed since v2:
Add boot-cpu start-powered-off conditional
changed since v1:
s/rcpu/rpu-cpu/hw/arm/xlnx-zynqmp.c | 34 ++++++++++++++++++++++++++++++++++ include/hw/arm/xlnx-zynqmp.h | 2 ++ 2 files changed, 36 insertions(+)hw/arm/xlnx-zynqmp.c +34
-0@@ -71,6 +71,13 @@ static void xlnx_zynqmp_init(Object *obj) &error_abort); } +for (i =0 ; i <XLNX_ZYNQMP_NUM_RPU_CPUS ; i++) { +object_initialize (&s->rpu_cpu[i],sizeof (s->rpu_cpu[i]), +"cortex-r5-" TYPE_ARM_CPU ); +object_property_add_child (obj,"rpu-cpu[*]" ,OBJECT (&s->rpu_cpu[i]), + &error_abort); + } +object_initialize (&s->gic,sizeof (s->gic),TYPE_ARM_GIC );qdev_set_parent_bus (DEVICE (&s->gic),sysbus_get_default ());@@ -163,6 +170,33 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)qdev_connect_gpio_out (DEVICE (&s->apu_cpu[i]),1 , irq); } +for (i =0 ; i <XLNX_ZYNQMP_NUM_RPU_CPUS ; i++) { +char *name; + + name =object_get_canonical_path_component (OBJECT (&s->rpu_cpu[i])); +if (strcmp (name, boot_cpu)) { +/* Secondary CPUs start in PSCI powered-down state */ +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true, +"start-powered-off" , &error_abort); + }else { + s->boot_cpu_ptr = &s->rpu_cpu[i]; + } + +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true,"reset-hivecs" , + &err); +if (err !=NULL ) { +error_propagate (errp, err); +return ; + } + +object_property_set_bool (OBJECT (&s->rpu_cpu[i]), true,"realized" , + &err); +if (err) { +error_propagate ((errp), (err)); +return ; + } + } +if (!s->boot_cpu_ptr) {error_setg (errp,"ZynqMP Boot cpu %s not found\n" , boot_cpu);return ;include/hw/arm/xlnx-zynqmp.h +2
-1@@ -28,6 +28,7 @@ TYPE_XLNX_ZYNQMP)#define XLNX_ZYNQMP_NUM_APU_CPUS 4 +#define XLNX_ZYNQMP_NUM_RPU_CPUS 2#define XLNX_ZYNQMP_NUM_GEMS 4#define XLNX_ZYNQMP_NUM_UARTS 2@@ -48,6 +49,7 @@ typedef struct XlnxZynqMPState {/*< public >*/ ARMCPU apu_cpu[XLNX_ZYNQMP_NUM_APU_CPUS ]; +ARMCPU rpu_cpu[XLNX_ZYNQMP_NUM_RPU_CPUS ];GICState gic;MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS ][XLNX_ZYNQMP_GIC_ALIASES ];CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS ]; --2.4.3.3.g905f831
Peter Maydell
AppliedQuoted 4 lines · Peter Crosthwaite
Hi Peter and all,
This patch series adds ARM Cortex R5 processor support. The PMSAv7 MPU is implemented. Two R5s are added to the Xilinx ZynqMP SoC.
Thanks, applied to target-arm.next. (This is by a few days post-softfreeze but the patches were on the list well before the deadline.)
-- PMM