All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/11] Add Cortex-R52
@ 2022-07-14 14:53 Tobias Roehmel
  2022-07-14 14:53 ` [PATCH 01/11] target/arm: Add ARM_FEATURE_V8_R Tobias Roehmel
                   ` (10 more replies)
  0 siblings, 11 replies; 20+ messages in thread
From: Tobias Roehmel @ 2022-07-14 14:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Tobias Roehmel

These patches add the ARM Cortex-R52. The biggest addition is
an implementation of the armv8-r MPU.
The last patch adds a machine that combines the new core with
an UART and a GIC. This machine can run many samples of
the Zephyr OS.

All information is taken from:
- ARM Cortex-R52 TRM revision r1p3
- ARM Architecture Reference Manual Supplement
    -ARMv8 for the ARMv8-R AArch32 architecture profile Version A.c

Functionality that is not implemented:
- Changing between single and double precision floats
- Some hypervisor related functionality (HCR.T(R)VM,HADFSR,...)

Tobias Röhmel (11):
  target/arm: Add ARM_FEATURE_V8_R
  target/arm: Add ARM Cortex-R52 cpu
  target/arm: Add v8R MIDR register
  target/arm: Make RVBAR available for non AARCH64 CPUs
  target/arm: Make stage_2_format for cache attributes optional
  target/arm: Add ARMCacheAttrs to the signature of pmsav8_mpu_lookup
  target/arm: Enable TTBCR_EAE for ARM_FEATURE_V8_R
  target/arm Add PMSAv8r registers
  target/arm: Add PMSAv8r functionality
  target/arm: Make SPSR_hyp accessible for Cortex-R52
  hw/arm: Add R52 machine

 configs/devices/arm-softmmu/default.mak |   1 +
 hw/arm/Kconfig                          |   5 +
 hw/arm/meson.build                      |   1 +
 hw/arm/r52_machine.c                    | 133 +++++++++++++++
 hw/arm/r52_virt.c                       | 217 ++++++++++++++++++++++++
 include/hw/arm/r52_virt.h               |  61 +++++++
 target/arm/cpu.c                        |  10 +-
 target/arm/cpu.h                        |  11 ++
 target/arm/cpu_tcg.c                    |  54 ++++++
 target/arm/helper.c                     | 184 +++++++++++++++++++-
 target/arm/internals.h                  |  13 +-
 target/arm/m_helper.c                   |   3 +-
 target/arm/op_helper.c                  |   8 +
 target/arm/ptw.c                        | 191 ++++++++++++++++++---
 target/arm/translate.c                  |   5 +-
 15 files changed, 859 insertions(+), 38 deletions(-)
 create mode 100644 hw/arm/r52_machine.c
 create mode 100644 hw/arm/r52_virt.c
 create mode 100644 include/hw/arm/r52_virt.h

-- 
2.25.1



^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 01/11] target/arm: Add ARM_FEATURE_V8_R
  2022-07-14 14:53 [PATCH 00/11] Add Cortex-R52 Tobias Roehmel
@ 2022-07-14 14:53 ` Tobias Roehmel
  2022-07-14 15:16   ` Peter Maydell
  2022-07-14 14:53 ` [PATCH 02/11] target/arm: Add ARM Cortex-R52 cpu Tobias Roehmel
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Tobias Roehmel @ 2022-07-14 14:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel

From: Tobias Röhmel <quic_trohmel@quicinc.com>

This flag is necessary to add features for the Cortex-R52.

Signed-off-by: Tobias Röhmel <quic_trohmel@quicinc.com>
---
 target/arm/cpu.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index df677b2d5d..86e06116a9 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2287,6 +2287,7 @@ enum arm_features {
     ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
     ARM_FEATURE_M_MAIN, /* M profile Main Extension */
     ARM_FEATURE_V8_1M, /* M profile extras only in v8.1M and later */
+    ARM_FEATURE_V8_R,
 };
 
 static inline int arm_feature(CPUARMState *env, int feature)
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 02/11] target/arm: Add ARM Cortex-R52 cpu
  2022-07-14 14:53 [PATCH 00/11] Add Cortex-R52 Tobias Roehmel
  2022-07-14 14:53 ` [PATCH 01/11] target/arm: Add ARM_FEATURE_V8_R Tobias Roehmel
@ 2022-07-14 14:53 ` Tobias Roehmel
  2022-07-14 15:23   ` Peter Maydell
  2022-07-14 14:53 ` [PATCH 03/11] target/arm: Add v8R MIDR register Tobias Roehmel
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Tobias Roehmel @ 2022-07-14 14:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel

From: Tobias Röhmel <quic_trohmel@quicinc.com>

All constants are taken from the ARM Cortex-R52 Processor TRM Revision: r1p3

Signed-off-by: Tobias Röhmel <quic_trohmel@quicinc.com>
---
 target/arm/cpu_tcg.c | 54 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index b751a19c8a..49fb03c09a 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -843,6 +843,59 @@ static void cortex_r5_initfn(Object *obj)
     define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
 }
 
+static const ARMCPRegInfo cortexr52_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 },
+    { .name = "DCACHE_INVAL", .cp = 15, .opc1 = 0, .crn = 15, .crm = 5,
+      .opc2 = 0, .access = PL1_W, .type = ARM_CP_NOP },
+};
+
+static void cortex_r52_initfn(Object *obj)
+{
+    ARMCPU *cpu = ARM_CPU(obj);
+
+    set_feature(&cpu->env, ARM_FEATURE_V8);
+    set_feature(&cpu->env, ARM_FEATURE_V8_R);
+    set_feature(&cpu->env, ARM_FEATURE_EL2);
+    set_feature(&cpu->env, ARM_FEATURE_PMSA);
+    set_feature(&cpu->env, ARM_FEATURE_NEON);
+    set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
+    cpu->midr = 0x411fd133; /* r1p3 */
+    cpu->revidr = 0x00000000;
+    cpu->reset_fpsid = 0x41034023;
+    cpu->isar.mvfr0 = 0x10110222;
+    cpu->isar.mvfr1 = 0x12111111;
+    cpu->isar.mvfr2 = 0x00000043;
+    cpu->ctr = 0x8144c004;
+    cpu->reset_sctlr = 0x30c50838;
+    cpu->isar.id_pfr0 = 0x00000131;
+    cpu->isar.id_pfr1 = 0x10111001;
+    cpu->isar.id_dfr0 = 0x03010006;
+    cpu->id_afr0 = 0x00000000;
+    cpu->isar.id_mmfr0 = 0x00211040;
+    cpu->isar.id_mmfr1 = 0x40000000;
+    cpu->isar.id_mmfr2 = 0x01200000;
+    cpu->isar.id_mmfr3 = 0xf0102211;
+    cpu->isar.id_mmfr4 = 0x00000010;
+    cpu->isar.id_isar0 = 0x02101110;
+    cpu->isar.id_isar1 = 0x13112111;
+    cpu->isar.id_isar2 = 0x21232142;
+    cpu->isar.id_isar3 = 0x01112131;
+    cpu->isar.id_isar4 = 0x00010142;
+    cpu->isar.id_isar5 = 0x00010001;
+    cpu->isar.dbgdidr = 0x77168000;
+    cpu->clidr = (1 << 27) | (1 << 24) | 0x3;
+    cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
+    cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
+
+    cpu->pmsav7_dregion = 16;
+
+    define_arm_cp_regs(cpu, cortexr52_cp_reginfo);
+}
+
 static void cortex_r5f_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
@@ -1148,6 +1201,7 @@ static const ARMCPUInfo arm_tcg_cpus[] = {
     { .name = "cortex-m55",  .initfn = cortex_m55_initfn,
                              .class_init = arm_v7m_class_init },
     { .name = "cortex-r5",   .initfn = cortex_r5_initfn },
+    { .name = "cortex-r52",   .initfn = cortex_r52_initfn },
     { .name = "cortex-r5f",  .initfn = cortex_r5f_initfn },
     { .name = "ti925t",      .initfn = ti925t_initfn },
     { .name = "sa1100",      .initfn = sa1100_initfn },
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 03/11] target/arm: Add v8R MIDR register
  2022-07-14 14:53 [PATCH 00/11] Add Cortex-R52 Tobias Roehmel
  2022-07-14 14:53 ` [PATCH 01/11] target/arm: Add ARM_FEATURE_V8_R Tobias Roehmel
  2022-07-14 14:53 ` [PATCH 02/11] target/arm: Add ARM Cortex-R52 cpu Tobias Roehmel
@ 2022-07-14 14:53 ` Tobias Roehmel
  2022-07-14 15:15   ` Peter Maydell
  2022-07-14 14:53 ` [PATCH 04/11] target/arm: Make RVBAR available for non AARCH64 CPUs Tobias Roehmel
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Tobias Roehmel @ 2022-07-14 14:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel

From: Tobias Röhmel <quic_trohmel@quicinc.com>

This register is used by the ARM Cortex-R52.

Signed-off-by: Tobias Röhmel <quic_trohmel@quicinc.com>
---
 target/arm/helper.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 6457e6301c..bdf1df37d5 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8201,6 +8201,15 @@ void register_cp_regs_for_features(ARMCPU *cpu)
               .accessfn = access_aa64_tid1,
               .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
         };
+        ARMCPRegInfo id_v8r_midr_cp_reginfo[] = {
+            { .name = "MIDR",
+              .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = CP_ANY,
+              .access = PL1_R, .resetvalue = cpu->midr,
+              .writefn = arm_cp_write_ignore, .raw_writefn = raw_write,
+              .readfn = midr_read,
+              .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
+              .type = ARM_CP_OVERRIDE },
+        };
         ARMCPRegInfo id_cp_reginfo[] = {
             /* These are common to v8 and pre-v8 */
             { .name = "CTR",
@@ -8264,7 +8273,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
             id_mpuir_reginfo.access = PL1_RW;
             id_tlbtr_reginfo.access = PL1_RW;
         }
-        if (arm_feature(env, ARM_FEATURE_V8)) {
+        if (arm_feature(env, ARM_FEATURE_V8_R)) {
+            define_arm_cp_regs(cpu, id_v8r_midr_cp_reginfo);
+        } else if (arm_feature(env, ARM_FEATURE_V8)) {
             define_arm_cp_regs(cpu, id_v8_midr_cp_reginfo);
         } else {
             define_arm_cp_regs(cpu, id_pre_v8_midr_cp_reginfo);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 04/11] target/arm: Make RVBAR available for non AARCH64 CPUs
  2022-07-14 14:53 [PATCH 00/11] Add Cortex-R52 Tobias Roehmel
                   ` (2 preceding siblings ...)
  2022-07-14 14:53 ` [PATCH 03/11] target/arm: Add v8R MIDR register Tobias Roehmel
@ 2022-07-14 14:53 ` Tobias Roehmel
  2022-07-14 15:28   ` Peter Maydell
  2022-07-14 14:53 ` [PATCH 05/11] target/arm: Make stage_2_format for cache attributes optional Tobias Roehmel
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Tobias Roehmel @ 2022-07-14 14:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel

From: Tobias Röhmel <quic_trohmel@quicinc.com>

The ARM Cortex-R52 is not AARCH64 but uses RVBAR.

Signed-off-by: Tobias Röhmel <quic_trohmel@quicinc.com>
---
 target/arm/cpu.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 1b5d535788..2c26a5387d 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -258,6 +258,10 @@ static void arm_cpu_reset(DeviceState *dev)
         env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
                                          CPACR, CP11, 3);
 #endif
+        if (arm_feature(env, ARM_FEATURE_V8_R)) {
+            env->cp15.rvbar = cpu->rvbar_prop;
+            env->regs[15] = cpu->rvbar_prop;
+        }
     }
 
 #if defined(CONFIG_USER_ONLY)
@@ -1273,7 +1277,8 @@ void arm_cpu_post_init(Object *obj)
         qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_hivecs_property);
     }
 
-    if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
+    if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) ||
+        arm_feature(&cpu->env, ARM_FEATURE_V8_R)) {
         object_property_add_uint64_ptr(obj, "rvbar",
                                        &cpu->rvbar_prop,
                                        OBJ_PROP_FLAG_READWRITE);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 05/11] target/arm: Make stage_2_format for cache attributes optional
  2022-07-14 14:53 [PATCH 00/11] Add Cortex-R52 Tobias Roehmel
                   ` (3 preceding siblings ...)
  2022-07-14 14:53 ` [PATCH 04/11] target/arm: Make RVBAR available for non AARCH64 CPUs Tobias Roehmel
@ 2022-07-14 14:53 ` Tobias Roehmel
  2022-07-14 14:53 ` [PATCH 06/11] target/arm: Add ARMCacheAttrs to the signature of pmsav8_mpu_lookup Tobias Roehmel
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Tobias Roehmel @ 2022-07-14 14:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel

From: Tobias Röhmel <quic_trohmel@quicinc.com>

The Cortex-R52 has a 2 stage MPU translation process but doesn't have the FEAT_S2FWB feature. This makes it neccessary to allow for the old cache attribut combination.
This is facilitated by changing the control path of combine_cacheattrs instead of failing if the second cache attributes struct is not in that format.

Signed-off-by: Tobias Röhmel <quic_trohmel@quicinc.com>
---
 target/arm/ptw.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index 4d97a24808..8b037c1f55 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -2108,7 +2108,11 @@ static uint8_t combined_attrs_nofwb(CPUARMState *env,
 {
     uint8_t s1lo, s2lo, s1hi, s2hi, s2_mair_attrs, ret_attrs;
 
-    s2_mair_attrs = convert_stage2_attrs(env, s2.attrs);
+    if (s2.is_s2_format) {
+        s2_mair_attrs = convert_stage2_attrs(env, s2.attrs);
+    } else {
+        s2_mair_attrs = s2.attrs;
+    }
 
     s1lo = extract32(s1.attrs, 0, 4);
     s2lo = extract32(s2_mair_attrs, 0, 4);
@@ -2166,6 +2170,8 @@ static uint8_t force_cacheattr_nibble_wb(uint8_t attr)
 static uint8_t combined_attrs_fwb(CPUARMState *env,
                                   ARMCacheAttrs s1, ARMCacheAttrs s2)
 {
+    assert(s2.is_s2_format && !s1.is_s2_format);
+
     switch (s2.attrs) {
     case 7:
         /* Use stage 1 attributes */
@@ -2215,7 +2221,6 @@ static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
     ARMCacheAttrs ret;
     bool tagged = false;
 
-    assert(s2.is_s2_format && !s1.is_s2_format);
     ret.is_s2_format = false;
 
     if (s1.attrs == 0xf0) {
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 06/11] target/arm: Add ARMCacheAttrs to the signature of pmsav8_mpu_lookup
  2022-07-14 14:53 [PATCH 00/11] Add Cortex-R52 Tobias Roehmel
                   ` (4 preceding siblings ...)
  2022-07-14 14:53 ` [PATCH 05/11] target/arm: Make stage_2_format for cache attributes optional Tobias Roehmel
@ 2022-07-14 14:53 ` Tobias Roehmel
  2022-07-14 14:53 ` [PATCH 07/11] target/arm: Enable TTBCR_EAE for ARM_FEATURE_V8_R Tobias Roehmel
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Tobias Roehmel @ 2022-07-14 14:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel

From: Tobias Röhmel <quic_trohmel@quicinc.com>

Add ARMCacheAttrs to the signature of pmsav8_mpu_lookup to prepare for the Cortex-R52 MPU which uses and combines cache attributes of different translation levels.

Signed-off-by: Tobias Röhmel <quic_trohmel@quicinc.com>
---
 target/arm/internals.h | 13 +++++++------
 target/arm/m_helper.c  |  3 ++-
 target/arm/ptw.c       | 11 +++++++----
 3 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 6f94f3019d..b03049d920 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1109,12 +1109,6 @@ void v8m_security_lookup(CPUARMState *env, uint32_t address,
                          MMUAccessType access_type, ARMMMUIdx mmu_idx,
                          V8M_SAttributes *sattrs);
 
-bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
-                       MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                       hwaddr *phys_ptr, MemTxAttrs *txattrs,
-                       int *prot, bool *is_subpage,
-                       ARMMMUFaultInfo *fi, uint32_t *mregion);
-
 /* Cacheability and shareability attributes for a memory access */
 typedef struct ARMCacheAttrs {
     /*
@@ -1126,6 +1120,13 @@ typedef struct ARMCacheAttrs {
     bool is_s2_format:1;
 } ARMCacheAttrs;
 
+bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
+                       MMUAccessType access_type, ARMMMUIdx mmu_idx,
+                       hwaddr *phys_ptr, MemTxAttrs *txattrs,
+                       int *prot, bool *is_subpage,
+                       ARMMMUFaultInfo *fi, uint32_t *mregion,
+                       ARMCacheAttrs *cacheattrs);
+
 bool get_phys_addr(CPUARMState *env, target_ulong address,
                    MMUAccessType access_type, ARMMMUIdx mmu_idx,
                    hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
index a740c3e160..44c80d733a 100644
--- a/target/arm/m_helper.c
+++ b/target/arm/m_helper.c
@@ -2829,10 +2829,11 @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
      * inspecting the other MPU state.
      */
     if (arm_current_el(env) != 0 || alt) {
+        ARMCacheAttrs cacheattrs = {0};
         /* We can ignore the return value as prot is always set */
         pmsav8_mpu_lookup(env, addr, MMU_DATA_LOAD, mmu_idx,
                           &phys_addr, &attrs, &prot, &is_subpage,
-                          &fi, &mregion);
+                          &fi, &mregion, &cacheattrs);
         if (mregion == -1) {
             mrvalid = false;
             mregion = 0;
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index 8b037c1f55..c4f5721012 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -1702,7 +1702,8 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
                        MMUAccessType access_type, ARMMMUIdx mmu_idx,
                        hwaddr *phys_ptr, MemTxAttrs *txattrs,
                        int *prot, bool *is_subpage,
-                       ARMMMUFaultInfo *fi, uint32_t *mregion)
+                       ARMMMUFaultInfo *fi, uint32_t *mregion,
+                       ARMCacheAttrs *cacheattrs)
 {
     /*
      * Perform a PMSAv8 MPU lookup (without also doing the SAU check
@@ -1968,7 +1969,7 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
                                  MMUAccessType access_type, ARMMMUIdx mmu_idx,
                                  hwaddr *phys_ptr, MemTxAttrs *txattrs,
                                  int *prot, target_ulong *page_size,
-                                 ARMMMUFaultInfo *fi)
+                                 ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
 {
     uint32_t secure = regime_is_secure(env, mmu_idx);
     V8M_SAttributes sattrs = {};
@@ -2036,7 +2037,8 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
     }
 
     ret = pmsav8_mpu_lookup(env, address, access_type, mmu_idx, phys_ptr,
-                            txattrs, prot, &mpu_is_subpage, fi, NULL);
+                            txattrs, prot, &mpu_is_subpage, fi,
+                            NULL, cacheattrs);
     *page_size = sattrs.subpage || mpu_is_subpage ? 1 : TARGET_PAGE_SIZE;
     return ret;
 }
@@ -2416,7 +2418,8 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
         if (arm_feature(env, ARM_FEATURE_V8)) {
             /* PMSAv8 */
             ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx,
-                                       phys_ptr, attrs, prot, page_size, fi);
+                                       phys_ptr, attrs, prot, page_size,
+                                       fi, cacheattrs);
         } else if (arm_feature(env, ARM_FEATURE_V7)) {
             /* PMSAv7 */
             ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 07/11] target/arm: Enable TTBCR_EAE for ARM_FEATURE_V8_R
  2022-07-14 14:53 [PATCH 00/11] Add Cortex-R52 Tobias Roehmel
                   ` (5 preceding siblings ...)
  2022-07-14 14:53 ` [PATCH 06/11] target/arm: Add ARMCacheAttrs to the signature of pmsav8_mpu_lookup Tobias Roehmel
@ 2022-07-14 14:53 ` Tobias Roehmel
  2022-07-14 15:34   ` Peter Maydell
  2022-07-14 14:53 ` [PATCH 08/11] target/arm Add PMSAv8r registers Tobias Roehmel
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Tobias Roehmel @ 2022-07-14 14:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel

From: Tobias Röhmel <quic_trohmel@quicinc.com>

Enable TTBCR_EAE during reset since it's always set to 1 for Cortex-R52.
See ARM Architecture Reference Manual Supplement - ARMv8, for the ARMv8-R
AArch32 architecture profile Version:A.c section C1.2.

Signed-off-by: Tobias Röhmel <quic_trohmel@quicinc.com>
---
 target/arm/cpu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 2c26a5387d..121fc2a819 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -261,6 +261,9 @@ static void arm_cpu_reset(DeviceState *dev)
         if (arm_feature(env, ARM_FEATURE_V8_R)) {
             env->cp15.rvbar = cpu->rvbar_prop;
             env->regs[15] = cpu->rvbar_prop;
+            env->cp15.tcr_el[0].raw_tcr = TTBCR_EAE;
+            env->cp15.tcr_el[1].raw_tcr = TTBCR_EAE;
+            env->cp15.tcr_el[2].raw_tcr = TTBCR_EAE;
         }
     }
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 08/11] target/arm Add PMSAv8r registers
  2022-07-14 14:53 [PATCH 00/11] Add Cortex-R52 Tobias Roehmel
                   ` (6 preceding siblings ...)
  2022-07-14 14:53 ` [PATCH 07/11] target/arm: Enable TTBCR_EAE for ARM_FEATURE_V8_R Tobias Roehmel
@ 2022-07-14 14:53 ` Tobias Roehmel
  2022-07-14 14:53 ` [PATCH 09/11] target/arm: Add PMSAv8r functionality Tobias Roehmel
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Tobias Roehmel @ 2022-07-14 14:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel

From: Tobias Röhmel <quic_trohmel@quicinc.com>

Signed-off-by: Tobias Röhmel <quic_trohmel@quicinc.com>
---
 target/arm/cpu.h    |  10 +++
 target/arm/helper.c | 171 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 181 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 86e06116a9..632d0d13c6 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -726,8 +726,18 @@ typedef struct CPUArchState {
          */
         uint32_t *rbar[M_REG_NUM_BANKS];
         uint32_t *rlar[M_REG_NUM_BANKS];
+        uint32_t prbarn[255];
+        uint32_t prlarn[255];
+        uint32_t hprbarn[255];
+        uint32_t hprlarn[255];
         uint32_t mair0[M_REG_NUM_BANKS];
         uint32_t mair1[M_REG_NUM_BANKS];
+        uint32_t prbar;
+        uint32_t prlar;
+        uint32_t prselr;
+        uint32_t hprbar;
+        uint32_t hprlar;
+        uint32_t hprselr;
     } pmsav8;
 
     /* v8M SAU */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index bdf1df37d5..adbf282d00 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7422,6 +7422,78 @@ static CPAccessResult access_joscr_jmcr(CPUARMState *env,
     return CP_ACCESS_OK;
 }
 
+static void prbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                          uint64_t value)
+{
+    env->pmsav8.prbarn[env->pmsav8.prselr] = value;
+}
+
+static void prlar_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                          uint64_t value)
+{
+    env->pmsav8.prlarn[env->pmsav8.prselr] = value;
+}
+
+static uint64_t prbar_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    return env->pmsav8.prbarn[env->pmsav8.prselr];
+}
+
+static uint64_t prlar_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    return env->pmsav8.prlarn[env->pmsav8.prselr];
+}
+
+static void hprbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                          uint64_t value)
+{
+    env->pmsav8.hprbarn[env->pmsav8.hprselr] = value;
+}
+
+static void hprlar_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                          uint64_t value)
+{
+    env->pmsav8.hprlarn[env->pmsav8.hprselr] = value;
+}
+
+static void hprenr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                          uint64_t value)
+{
+    uint32_t n;
+    ARMCPU *cpu = env_archcpu(env);
+    for (n = 0; n < (int)cpu->pmsav7_dregion; ++n) {
+        if (value & (1 << n)) {
+            env->pmsav8.hprlarn[n] |= 0x1;
+        } else {
+            env->pmsav8.hprlarn[n] &= (~0x1);
+        }
+    }
+}
+
+static uint64_t hprbar_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    return env->pmsav8.hprbarn[env->pmsav8.hprselr];
+}
+
+static uint64_t hprlar_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    return env->pmsav8.hprlarn[env->pmsav8.hprselr];
+}
+
+static uint64_t hprenr_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    uint32_t n;
+    uint32_t result = 0x0;
+    ARMCPU *cpu = env_archcpu(env);
+
+    for (n = 0; n < (int)cpu->pmsav7_dregion; ++n) {
+        if (env->pmsav8.hprlarn[n] & 0x1) {
+            result |= (0x1 << n);
+        }
+    }
+    return result;
+}
+
 static const ARMCPRegInfo jazelle_regs[] = {
     { .name = "JIDR",
       .cp = 14, .crn = 0, .crm = 0, .opc1 = 7, .opc2 = 0,
@@ -8242,6 +8314,46 @@ void register_cp_regs_for_features(ARMCPU *cpu)
               .access = PL1_R, .type = ARM_CP_CONST,
               .resetvalue = cpu->pmsav7_dregion << 8
         };
+        /* PMSAv8-R registers*/
+        ARMCPRegInfo id_pmsav8_r_reginfo[] = {
+            { .name = "HMPUIR",
+              .cp = 15, .crn = 0, .crm = 0, .opc1 = 4, .opc2 = 4,
+              .access = PL2_R, .type = ARM_CP_CONST,
+              .resetvalue = cpu->pmsav7_dregion},
+             /* PMSAv8-R registers */
+            { .name = "PRBAR",
+              .cp = 15, .opc1 = 0, .crn = 6, .crm = 3, .opc2 = 0,
+              .access = PL1_RW, .resetvalue = 0,
+              .readfn = prbar_read, .writefn = prbar_write,
+              .fieldoffset = offsetof(CPUARMState, pmsav8.prbar)},
+            { .name = "PRLAR",
+              .cp = 15, .opc1 = 0, .crn = 6, .crm = 3, .opc2 = 1,
+              .access = PL1_RW, .resetvalue = 0,
+              .readfn = prlar_read, .writefn = prlar_write,
+              .fieldoffset = offsetof(CPUARMState, pmsav8.prlar)},
+            { .name = "PRSELR", .resetvalue = 0,
+              .cp = 15, .opc1 = 0, .crn = 6, .crm = 2, .opc2 = 1,
+              .access = PL1_RW, .accessfn = access_tvm_trvm,
+              .fieldoffset = offsetof(CPUARMState, pmsav8.prselr)},
+            { .name = "HPRBAR", .resetvalue = 0,
+              .readfn = hprbar_read, .writefn = hprbar_write,
+              .cp = 15, .opc1 = 4, .crn = 6, .crm = 3, .opc2 = 0,
+              .access = PL2_RW, .resetvalue = 0,
+              .fieldoffset = offsetof(CPUARMState, pmsav8.hprbar)},
+            { .name = "HPRLAR",
+              .cp = 15, .opc1 = 4, .crn = 6, .crm = 3, .opc2 = 1,
+              .access = PL2_RW, .resetvalue = 0,
+              .readfn = hprlar_read, .writefn = hprlar_write,
+              .fieldoffset = offsetof(CPUARMState, pmsav8.hprlar)},
+            { .name = "HPRSELR", .resetvalue = 0,
+              .cp = 15, .opc1 = 4, .crn = 6, .crm = 2, .opc2 = 1,
+              .access = PL2_RW, .accessfn = access_tvm_trvm,
+              .fieldoffset = offsetof(CPUARMState, pmsav8.hprselr)},
+            { .name = "HPRENR",
+              .cp = 15, .opc1 = 4, .crn = 6, .crm = 1, .opc2 = 1,
+              .access = PL2_RW, .resetvalue = 0,
+              .readfn = hprenr_read, .writefn = hprenr_write},
+        };
         static const ARMCPRegInfo crn0_wi_reginfo = {
             .name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY,
             .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W,
@@ -8283,6 +8395,65 @@ void register_cp_regs_for_features(ARMCPU *cpu)
         define_arm_cp_regs(cpu, id_cp_reginfo);
         if (!arm_feature(env, ARM_FEATURE_PMSA)) {
             define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo);
+        } else if (arm_feature(env, ARM_FEATURE_V8_R)) {
+            uint32_t i = 0;
+            char hprbar_string[] = "HPRBAR%u";
+            char hprlar_string[] = "HPRLAR%u";
+
+            char prbar_string[] = "PRBAR%u";
+            char prlar_string[] = "PRLAR%u";
+            char tmp_string[50];
+            define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
+            define_arm_cp_regs(cpu, id_pmsav8_r_reginfo);
+            for (i = 0; i < cpu->pmsav7_dregion; ++i) {
+                uint8_t crm = 0b1000 | ((i & 0b1110) >> 1);
+                uint8_t opc2 = (i & 0x1) << 2;
+
+                sprintf(tmp_string, hprbar_string, i);
+                ARMCPRegInfo tmp_hprbarn_reginfo = {
+                    .name = tmp_string,
+                    .cp = 15, .opc1 = 4, .crn = 6, .crm = crm, .opc2 = opc2,
+                    .access = PL2_RW, .resetvalue = 0,
+                    .accessfn = access_tvm_trvm,
+                    .fieldoffset = offsetof(CPUARMState, pmsav8.hprbarn)
+                    + i * sizeof(env->pmsav8.hprbarn[0])
+                };
+                define_one_arm_cp_reg(cpu, &tmp_hprbarn_reginfo);
+
+                sprintf(tmp_string, prbar_string, i);
+                ARMCPRegInfo tmp_prbarn_reginfo = {
+                    .name = tmp_string,
+                    .cp = 15, .opc1 = 0, .crn = 6, .crm = crm, .opc2 = opc2,
+                    .access = PL1_RW, .resetvalue = 0,
+                    .accessfn = access_tvm_trvm,
+                    .fieldoffset = offsetof(CPUARMState, pmsav8.prbarn)
+                    + i * sizeof(env->pmsav8.prbarn[0])
+                };
+                define_one_arm_cp_reg(cpu, &tmp_prbarn_reginfo);
+
+                opc2 = (i & 0x1) << 2 | 0x1;
+                sprintf(tmp_string, hprlar_string, i);
+                ARMCPRegInfo tmp_hprlarn_reginfo = {
+                    .name = tmp_string,
+                    .cp = 15, .opc1 = 4, .crn = 6, .crm = crm, .opc2 = opc2,
+                    .access = PL2_RW, .resetvalue = 0,
+                    .accessfn = access_tvm_trvm,
+                    .fieldoffset = offsetof(CPUARMState, pmsav8.hprlarn)
+                    + i * sizeof(env->pmsav8.hprlarn[0])
+                };
+                define_one_arm_cp_reg(cpu, &tmp_hprlarn_reginfo);
+
+                sprintf(tmp_string, prlar_string, i);
+                ARMCPRegInfo tmp_prlarn_reginfo = {
+                    .name = tmp_string,
+                    .cp = 15, .opc1 = 0, .crn = 6, .crm = crm, .opc2 = opc2,
+                    .access = PL1_RW, .resetvalue = 0,
+                    .accessfn = access_tvm_trvm,
+                    .fieldoffset = offsetof(CPUARMState, pmsav8.prlarn)
+                    + i * sizeof(env->pmsav8.prlarn[0])
+                };
+                define_one_arm_cp_reg(cpu, &tmp_prlarn_reginfo);
+            }
         } else if (arm_feature(env, ARM_FEATURE_V7)) {
             define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
         }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 09/11] target/arm: Add PMSAv8r functionality
  2022-07-14 14:53 [PATCH 00/11] Add Cortex-R52 Tobias Roehmel
                   ` (7 preceding siblings ...)
  2022-07-14 14:53 ` [PATCH 08/11] target/arm Add PMSAv8r registers Tobias Roehmel
@ 2022-07-14 14:53 ` Tobias Roehmel
  2022-07-14 14:53 ` [PATCH 10/11] target/arm: Make SPSR_hyp accessible for Cortex-R52 Tobias Roehmel
  2022-07-14 14:53 ` [PATCH 11/11] hw/arm: Add R52 machine Tobias Roehmel
  10 siblings, 0 replies; 20+ messages in thread
From: Tobias Roehmel @ 2022-07-14 14:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel

From: Tobias Röhmel <quic_trohmel@quicinc.com>

Add PMSAv8r translation that is used by the ARM Cortex-R52.

Signed-off-by: Tobias Röhmel <quic_trohmel@quicinc.com>
---
 target/arm/ptw.c | 171 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 150 insertions(+), 21 deletions(-)

diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index c4f5721012..c7e37c66d0 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -140,6 +140,9 @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx)
              */
             return true;
         }
+    } else if (arm_feature(env, ARM_FEATURE_V8_R)) {
+        return !(regime_sctlr(env, mmu_idx) & SCTLR_M) ||
+        (!(regime_el(env, mmu_idx) == 2) && arm_hcr_el2_eff(env) & HCR_TGE);
     }
 
     hcr_el2 = arm_hcr_el2_eff(env);
@@ -1504,6 +1507,8 @@ static bool pmsav7_use_background_region(ARMCPU *cpu, ARMMMUIdx mmu_idx,
     if (arm_feature(env, ARM_FEATURE_M)) {
         return env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)]
             & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
+    } else if (arm_feature(env, ARM_FEATURE_V8_R)) {
+        return false;
     } else {
         return regime_sctlr(env, mmu_idx) & SCTLR_BR;
     }
@@ -1698,6 +1703,77 @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
     return !(*prot & (1 << access_type));
 }
 
+static uint32_t *regime_rbar(CPUARMState *env, ARMMMUIdx mmu_idx,
+                             uint32_t secure)
+{
+    if (arm_feature(env, ARM_FEATURE_V8_R)) {
+        if (regime_el(env, mmu_idx) == 2) {
+            return env->pmsav8.hprbarn;
+        } else {
+            return env->pmsav8.prbarn;
+        }
+    } else {
+         return env->pmsav8.rbar[secure];
+    }
+}
+
+static uint32_t *regime_rlar(CPUARMState *env, ARMMMUIdx mmu_idx,
+                             uint32_t secure)
+{
+    if (arm_feature(env, ARM_FEATURE_V8_R)) {
+        if (regime_el(env, mmu_idx) == 2) {
+            return env->pmsav8.hprlarn;
+        } else {
+            return env->pmsav8.prlarn;
+        }
+    } else {
+        return env->pmsav8.rlar[secure];
+    }
+}
+
+static inline void get_phys_addr_pmsav8_default(CPUARMState *env,
+                                                ARMMMUIdx mmu_idx,
+                                                uint32_t address, int *prot)
+{
+    if (arm_feature(env, ARM_FEATURE_V8_R)) {
+        *prot = PAGE_READ | PAGE_WRITE;
+        if (address <= 0x7FFFFFFF) {
+            *prot |= PAGE_EXEC;
+        }
+        if ((regime_el(env, mmu_idx) == 2)
+            && (regime_sctlr(env, mmu_idx) & SCTLR_WXN)
+            && (regime_sctlr(env, mmu_idx) & SCTLR_M)) {
+            *prot &= ~PAGE_EXEC;
+        }
+    } else {
+        get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
+    }
+}
+
+static bool pmsav8_fault(bool hit, CPUARMState *env, ARMMMUIdx mmu_idx)
+{
+    if (arm_feature(env, ARM_FEATURE_V8_R)) {
+        if (regime_el(env, mmu_idx) == 2) {
+            if (!hit && (mmu_idx != ARMMMUIdx_E2)) {
+                return true;
+            } else if (!hit && (mmu_idx == ARMMMUIdx_E2)
+                       &&!(regime_sctlr(env, mmu_idx) & SCTLR_BR)) {
+                return true;
+            }
+        } else {
+            if (!hit && (mmu_idx != ARMMMUIdx_Stage1_E1)) {
+                return true;
+            } else if (!hit && (mmu_idx == ARMMMUIdx_Stage1_E1)
+                       &&!(regime_sctlr(env, mmu_idx) & SCTLR_BR)) {
+                return true;
+            }
+        }
+        return false;
+    } else {
+        return !hit;
+    }
+}
+
 bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
                        MMUAccessType access_type, ARMMMUIdx mmu_idx,
                        hwaddr *phys_ptr, MemTxAttrs *txattrs,
@@ -1730,6 +1806,12 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
         *mregion = -1;
     }
 
+    if (arm_feature(env, ARM_FEATURE_V8_R)) {
+        if (mmu_idx == ARMMMUIdx_Stage2) {
+            fi->stage2 = true;
+        }
+    }
+
     /*
      * Unlike the ARM ARM pseudocode, we don't need to check whether this
      * was an exception vector read from the vector table (which is always
@@ -1746,17 +1828,26 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
             hit = true;
         }
 
+        uint32_t bitmask;
+        if (arm_feature(env, ARM_FEATURE_V8_R)) {
+            bitmask = 0x3f;
+        } else {
+            bitmask = 0x1f;
+        }
+
+
         for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
             /* region search */
             /*
-             * Note that the base address is bits [31:5] from the register
-             * with bits [4:0] all zeroes, but the limit address is bits
-             * [31:5] from the register with bits [4:0] all ones.
+             * Note that the base address is bits [31:x] from the register
+             * with bits [x-1:0] all zeroes, but the limit address is bits
+             * [31:x] from the register with bits [x:0] all ones. Where x is
+             * 5 for Cortex-M and 6 for Cortex-R
              */
-            uint32_t base = env->pmsav8.rbar[secure][n] & ~0x1f;
-            uint32_t limit = env->pmsav8.rlar[secure][n] | 0x1f;
+            uint32_t base = regime_rbar(env, mmu_idx, secure)[n] & ~bitmask;
+            uint32_t limit = regime_rlar(env, mmu_idx, secure)[n] | bitmask;
 
-            if (!(env->pmsav8.rlar[secure][n] & 0x1)) {
+            if (!(regime_rlar(env, mmu_idx, secure)[n] & 0x1)) {
                 /* Region disabled */
                 continue;
             }
@@ -1799,22 +1890,25 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
         }
     }
 
-    if (!hit) {
-        /* background fault */
-        fi->type = ARMFault_Background;
+    if (pmsav8_fault(hit, env, mmu_idx)) {
+        fi->type = ARMFault_Permission;
+        fi->level = 0;
         return true;
     }
 
     if (matchregion == -1) {
         /* hit using the background region */
-        get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
+        get_phys_addr_pmsav8_default(env, mmu_idx, address, prot);
     } else {
-        uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
-        uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
+        uint32_t ap = extract32(regime_rbar(env,
+                                mmu_idx, secure)[matchregion], 1, 2);
+        uint32_t xn = extract32(regime_rbar(env,
+                                mmu_idx, secure)[matchregion], 0, 1);
         bool pxn = false;
 
         if (arm_feature(env, ARM_FEATURE_V8_1M)) {
-            pxn = extract32(env->pmsav8.rlar[secure][matchregion], 4, 1);
+            pxn = extract32(regime_rlar(env,
+                            mmu_idx, secure)[matchregion], 4, 1);
         }
 
         if (m_is_system_region(env, address)) {
@@ -1822,14 +1916,42 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
             xn = 1;
         }
 
-        *prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
+        if (arm_feature(env, ARM_FEATURE_V8_R)) {
+            if (regime_el(env, mmu_idx) == 2) {
+                *prot = simple_ap_to_rw_prot_is_user(ap,
+                                                mmu_idx != ARMMMUIdx_E2);
+            } else {
+                *prot = simple_ap_to_rw_prot_is_user(ap,
+                                                mmu_idx != ARMMMUIdx_Stage1_E1);
+            }
+
+            if (regime_sctlr(env, mmu_idx) & SCTLR_WXN
+                && (*prot & PAGE_WRITE)) {
+                xn = 0x1;
+            }
+
+            if ((regime_el(env, mmu_idx) == 1) && regime_sctlr(env, mmu_idx)
+                 & SCTLR_UWXN && (ap == 0x1)) {
+                xn = 0x1;
+            }
+
+            uint8_t attrindx = extract32(regime_rlar(env,
+                                         mmu_idx, secure)[matchregion], 1, 3);
+            uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)];
+            uint8_t sh = extract32(regime_rlar(env,
+                                   mmu_idx, secure)[matchregion], 3, 2);
+            assert(attrindx <= 4);
+            cacheattrs->is_s2_format = false;
+            cacheattrs->attrs = extract64(mair, attrindx * 8, 8);
+            cacheattrs->shareability = sh;
+        } else {
+            *prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
+        }
+
         if (*prot && !xn && !(pxn && !is_user)) {
             *prot |= PAGE_EXEC;
         }
-        /*
-         * We don't need to look the attribute up in the MAIR0/MAIR1
-         * registers because that only tells us about cacheability.
-         */
+
         if (mregion) {
             *mregion = matchregion;
         }
@@ -2342,9 +2464,16 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
             is_el0 = mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_SE10_0;
 
             /* S1 is done. Now do S2 translation.  */
-            ret = get_phys_addr_lpae(env, ipa, access_type, s2_mmu_idx, is_el0,
-                                     phys_ptr, attrs, &s2_prot,
-                                     page_size, fi, &cacheattrs2);
+            if (arm_feature(env, ARM_FEATURE_V8_R)) {
+                ret = get_phys_addr_pmsav8(env, ipa, access_type, s2_mmu_idx,
+                                       phys_ptr, attrs, &s2_prot, page_size,
+                                       fi, &cacheattrs2);
+            } else {
+                ret = get_phys_addr_lpae(env, ipa, access_type, s2_mmu_idx,
+                                      is_el0, phys_ptr, attrs, &s2_prot,
+                                      page_size, fi, &cacheattrs2);
+            }
+
             fi->s2addr = ipa;
             /* Combine the S1 and S2 perms.  */
             *prot &= s2_prot;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 10/11] target/arm: Make SPSR_hyp accessible for Cortex-R52
  2022-07-14 14:53 [PATCH 00/11] Add Cortex-R52 Tobias Roehmel
                   ` (8 preceding siblings ...)
  2022-07-14 14:53 ` [PATCH 09/11] target/arm: Add PMSAv8r functionality Tobias Roehmel
@ 2022-07-14 14:53 ` Tobias Roehmel
  2022-07-14 15:46   ` Peter Maydell
  2022-07-14 14:53 ` [PATCH 11/11] hw/arm: Add R52 machine Tobias Roehmel
  10 siblings, 1 reply; 20+ messages in thread
From: Tobias Roehmel @ 2022-07-14 14:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel

From: Tobias Röhmel <quic_trohmel@quicinc.com>

The Cortex-R52 can access SPSR_hyp from hypervisor mode
as discussed here: https://github.com/zephyrproject-rtos/zephyr/issues/47330

Signed-off-by: Tobias Röhmel <quic_trohmel@quicinc.com>
---
 target/arm/op_helper.c | 8 ++++++++
 target/arm/translate.c | 5 +++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index c5bde1cfcc..aa019bc39d 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -522,6 +522,11 @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
         return;
     }
 
+    if (curmode == ARM_CPU_MODE_HYP && tgtmode == ARM_CPU_MODE_HYP
+        && arm_feature(env, ARM_FEATURE_V8_R)) {
+        return;
+    }
+
     if (curmode == tgtmode) {
         goto undef;
     }
@@ -570,6 +575,9 @@ void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
     switch (regno) {
     case 16: /* SPSRs */
         env->banked_spsr[bank_number(tgtmode)] = value;
+        if (arm_feature(env, ARM_FEATURE_V8_R)) {
+            env->spsr = value;
+        }
         break;
     case 17: /* ELR_Hyp */
         env->elr_el[2] = value;
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 6617de775f..c097f7e417 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -2881,8 +2881,9 @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
          * can be accessed also from Hyp mode, so forbid accesses from
          * EL0 or EL1.
          */
-        if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
-            (s->current_el < 3 && *regno != 17)) {
+        if (!arm_dc_feature(s, ARM_FEATURE_V8_R)
+            && (!arm_dc_feature(s, ARM_FEATURE_EL2)
+            || s->current_el < 2 || (s->current_el < 3 && *regno != 17))) {
             goto undef;
         }
         break;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 11/11] hw/arm: Add R52 machine
  2022-07-14 14:53 [PATCH 00/11] Add Cortex-R52 Tobias Roehmel
                   ` (9 preceding siblings ...)
  2022-07-14 14:53 ` [PATCH 10/11] target/arm: Make SPSR_hyp accessible for Cortex-R52 Tobias Roehmel
@ 2022-07-14 14:53 ` Tobias Roehmel
  2022-07-14 15:53   ` Peter Maydell
  10 siblings, 1 reply; 20+ messages in thread
From: Tobias Roehmel @ 2022-07-14 14:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Tobias Röhmel

From: Tobias Röhmel <quic_trohmel@quicinc.com>

Signed-off-by: Tobias Röhmel <quic_trohmel@quicinc.com>
---
 configs/devices/arm-softmmu/default.mak |   1 +
 hw/arm/Kconfig                          |   5 +
 hw/arm/meson.build                      |   1 +
 hw/arm/r52_machine.c                    | 133 +++++++++++++++
 hw/arm/r52_virt.c                       | 217 ++++++++++++++++++++++++
 include/hw/arm/r52_virt.h               |  61 +++++++
 6 files changed, 418 insertions(+)
 create mode 100644 hw/arm/r52_machine.c
 create mode 100644 hw/arm/r52_virt.c
 create mode 100644 include/hw/arm/r52_virt.h

diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
index 6985a25377..4df0844080 100644
--- a/configs/devices/arm-softmmu/default.mak
+++ b/configs/devices/arm-softmmu/default.mak
@@ -42,3 +42,4 @@ CONFIG_FSL_IMX6UL=y
 CONFIG_SEMIHOSTING=y
 CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
 CONFIG_ALLWINNER_H3=y
+CONFIG_CORTEX_R52_VIRT=y
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 219262a8da..72ec0bb656 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -565,3 +565,8 @@ config ARMSSE
     select UNIMP
     select SSE_COUNTER
     select SSE_TIMER
+
+config CORTEX_R52_VIRT
+    bool
+    select ARM_GIC
+    select PL011
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index 2d8381339c..2a0cdb9c83 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -43,6 +43,7 @@ arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c'))
 arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c'))
 arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c'))
 arm_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp.c', 'xlnx-zcu102.c'))
+arm_ss.add(when: 'CONFIG_CORTEX_R52_VIRT', if_true: files('r52_virt.c', 'r52_machine.c'))
 arm_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal.c', 'xlnx-versal-virt.c'))
 arm_ss.add(when: 'CONFIG_FSL_IMX25', if_true: files('fsl-imx25.c', 'imx25_pdk.c'))
 arm_ss.add(when: 'CONFIG_FSL_IMX31', if_true: files('fsl-imx31.c', 'kzm.c'))
diff --git a/hw/arm/r52_machine.c b/hw/arm/r52_machine.c
new file mode 100644
index 0000000000..33e9764793
--- /dev/null
+++ b/hw/arm/r52_machine.c
@@ -0,0 +1,133 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/arm/r52_virt.h"
+#include "hw/boards.h"
+#include "qemu/error-report.h"
+#include "qemu/log.h"
+#include "qom/object.h"
+
+struct r52MachineState {
+    MachineState parent_obj;
+
+    ArmR52VirtState soc;
+
+    bool secure;
+    bool virt;
+
+    struct arm_boot_info binfo;
+};
+
+#define TYPE_R52_MACHINE   MACHINE_TYPE_NAME("r52")
+OBJECT_DECLARE_SIMPLE_TYPE(r52MachineState, R52_MACHINE)
+
+
+static bool r52_get_secure(Object *obj, Error **errp)
+{
+    r52MachineState *s = R52_MACHINE(obj);
+
+    return s->secure;
+}
+
+static void r52_set_secure(Object *obj, bool value, Error **errp)
+{
+    r52MachineState *s = R52_MACHINE(obj);
+
+    s->secure = value;
+}
+
+static bool r52_get_virt(Object *obj, Error **errp)
+{
+    r52MachineState *s = R52_MACHINE(obj);
+
+    return s->virt;
+}
+
+static void r52_set_virt(Object *obj, bool value, Error **errp)
+{
+    r52MachineState *s = R52_MACHINE(obj);
+
+    s->virt = value;
+}
+
+static void r52_init(MachineState *machine)
+{
+    r52MachineState *s = R52_MACHINE(machine);
+    uint64_t ram_size = machine->ram_size;
+
+    object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_ARMR52VIRT);
+
+    object_property_set_bool(OBJECT(&s->soc), "secure", s->secure,
+                             &error_fatal);
+    object_property_set_bool(OBJECT(&s->soc), "virtualization", s->virt,
+                             &error_fatal);
+
+    qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
+
+    s->binfo.ram_size = ram_size;
+    s->binfo.loader_start = 0;
+    s->binfo.psci_conduit = QEMU_PSCI_CONDUIT_SMC;
+    arm_load_kernel(s->soc.boot_cpu_ptr, machine, &s->binfo);
+}
+
+static void r52_machine_instance_init(Object *obj)
+{
+    r52MachineState *s = R52_MACHINE(obj);
+
+    /* Default to secure mode being disabled */
+    s->secure = false;
+    /* Default to virt (EL2) being enabled */
+    s->virt = true;
+}
+
+static void r52_machine_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+
+    mc->desc = "Cortex-R52 platform";
+    mc->init = r52_init;
+    mc->block_default_type = IF_IDE;
+    mc->units_per_default_bus = 1;
+    mc->ignore_memory_transaction_failures = true;
+    mc->max_cpus = ARMR52_VIRT_NUM_APU_CPUS;
+    mc->default_cpus = ARMR52_VIRT_NUM_APU_CPUS;
+
+    object_class_property_add_bool(oc, "secure", r52_get_secure,
+                                   r52_set_secure);
+    object_class_property_set_description(oc, "secure",
+                                          "Set on/off to enable/disable the ARM "
+                                          "Security Extensions (TrustZone)");
+
+    object_class_property_add_bool(oc, "virtualization", r52_get_virt,
+                                   r52_set_virt);
+    object_class_property_set_description(oc, "virtualization",
+                                          "Set on/off to enable/disable emulating a "
+                                          "guest CPU which implements the ARM "
+                                          "Virtualization Extensions");
+}
+
+static const TypeInfo r52_machine_init_typeinfo = {
+    .name       = TYPE_R52_MACHINE,
+    .parent     = TYPE_MACHINE,
+    .class_init = r52_machine_class_init,
+    .instance_init = r52_machine_instance_init,
+    .instance_size = sizeof(r52MachineState),
+};
+
+static void r52_machine_init_register_types(void)
+{
+    type_register_static(&r52_machine_init_typeinfo);
+}
+
+type_init(r52_machine_init_register_types)
diff --git a/hw/arm/r52_virt.c b/hw/arm/r52_virt.c
new file mode 100644
index 0000000000..edf3dadb0e
--- /dev/null
+++ b/hw/arm/r52_virt.c
@@ -0,0 +1,217 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "hw/arm/r52_virt.h"
+#include "hw/intc/arm_gic_common.h"
+#include "hw/misc/unimp.h"
+#include "hw/boards.h"
+#include "sysemu/kvm.h"
+#include "sysemu/sysemu.h"
+#include "kvm_arm.h"
+
+#define GIC_NUM_SPI_INTR 160
+
+#define ARM_PHYS_TIMER_PPI  30
+#define ARM_VIRT_TIMER_PPI  27
+#define ARM_HYP_TIMER_PPI   26
+#define ARM_SEC_TIMER_PPI   29
+#define GIC_MAINTENANCE_PPI 25
+
+#define GIC_BASE_ADDR       0xaf000000
+#define GIC_REDIST_ADDR       0xaf100000
+
+static const uint64_t uart_addr[ARMR52_VIRT_NUM_UARTS] = {
+    0x9c090000,
+};
+
+static const int uart_intr[ARMR52_VIRT_NUM_UARTS] = {
+    5,
+};
+
+static inline int arm_gic_ppi_index(int cpu_nr, int ppi_index)
+{
+    return GIC_NUM_SPI_INTR + cpu_nr * GIC_INTERNAL + ppi_index;
+}
+
+static void armr52_virt_init(Object *obj)
+{
+    MachineState *ms = MACHINE(qdev_get_machine());
+    ArmR52VirtState *s = ARMR52VIRT(obj);
+    int i;
+    int num_apus = MIN(ms->smp.cpus, ARMR52_VIRT_NUM_APU_CPUS);
+
+    object_initialize_child(obj, "apu-cluster", &s->apu_cluster,
+                            TYPE_CPU_CLUSTER);
+    qdev_prop_set_uint32(DEVICE(&s->apu_cluster), "cluster-id", 0);
+
+    for (i = 0; i < num_apus; i++) {
+        object_initialize_child(OBJECT(&s->apu_cluster), "apu-cpu[*]",
+                                &s->apu_cpu[i],
+                                ARM_CPU_TYPE_NAME("cortex-r52"));
+    }
+
+    object_initialize_child(obj, "gic", &s->gic, gicv3_class_name());
+
+
+    for (i = 0; i < ARMR52_VIRT_NUM_UARTS; i++) {
+        object_initialize_child(obj, "uart[*]", &s->uart[i],
+                                TYPE_PL011);
+    }
+}
+
+static void armr52_virt_realize(DeviceState *dev, Error **errp)
+{
+    MachineState *ms = MACHINE(qdev_get_machine());
+    ArmR52VirtState *s = ARMR52VIRT(dev);
+    uint8_t i;
+    int num_apus = MIN(ms->smp.cpus, ARMR52_VIRT_NUM_APU_CPUS);
+    const char *boot_cpu = s->boot_cpu ? s->boot_cpu : "apu-cpu[0]";
+    qemu_irq gic_spi[GIC_NUM_SPI_INTR];
+    Error *err = NULL;
+
+    memory_region_init_ram(&s->ddr_ram, NULL, "armr52virt.dram", 0x04000000,
+                           &error_fatal);
+    memory_region_add_subregion(get_system_memory(), 0, &s->ddr_ram);
+
+    qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", NUM_IRQS + 32);
+    qdev_prop_set_uint32(DEVICE(&s->gic), "revision", 3);
+    qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", num_apus);
+    qdev_prop_set_bit(DEVICE(&s->gic), "has-security-extensions", false);
+    qdev_prop_set_uint32(DEVICE(&s->gic), "len-redist-region-count", 1);
+    qdev_prop_set_uint32(DEVICE(&s->gic), "redist-region-count[0]", num_apus);
+
+    qdev_realize(DEVICE(&s->apu_cluster), NULL, &error_fatal);
+
+    for (i = 0; i < num_apus; i++) {
+        const char *name;
+
+        name = object_get_canonical_path_component(OBJECT(&s->apu_cpu[i]));
+        if (strcmp(name, boot_cpu)) {
+            /*
+             * Secondary CPUs start in powered-down state.
+             */
+            object_property_set_bool(OBJECT(&s->apu_cpu[i]),
+                                     "start-powered-off", true, &error_abort);
+        } else {
+            s->boot_cpu_ptr = &s->apu_cpu[i];
+        }
+
+        object_property_set_bool(OBJECT(&s->apu_cpu[i]), "has_el3", s->secure,
+                                 NULL);
+        object_property_set_bool(OBJECT(&s->apu_cpu[i]), "has_el2", s->virt,
+                                 NULL);
+        object_property_set_int(OBJECT(&s->apu_cpu[i]), "core-count",
+                                num_apus, &error_abort);
+        if (!qdev_realize(DEVICE(&s->apu_cpu[i]), NULL, errp)) {
+            return;
+        }
+    }
+
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->gic), errp)) {
+        return;
+    }
+
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 0, GIC_BASE_ADDR);
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 1, GIC_REDIST_ADDR);
+
+    for (i = 0; i < num_apus; i++) {
+
+        int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
+        int irq;
+        /*
+         * Mapping from the output timer irq lines from the CPU to the
+         * GIC PPI inputs we use for the virt board.
+         */
+        const int timer_irq[] = {
+            [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
+            [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
+            [GTIMER_HYP]  = ARCH_TIMER_NS_EL2_IRQ,
+            [GTIMER_SEC]  = ARCH_TIMER_S_EL1_IRQ,
+        };
+
+        for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
+            qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), irq,
+                                  qdev_get_gpio_in(DEVICE(&s->gic),
+                                                   ppibase + timer_irq[irq]));
+        }
+
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i,
+                           qdev_get_gpio_in(DEVICE(&s->apu_cpu[i]),
+                                            ARM_CPU_IRQ));
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + num_apus,
+                           qdev_get_gpio_in(DEVICE(&s->apu_cpu[i]),
+                                            ARM_CPU_FIQ));
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + num_apus * 2,
+                           qdev_get_gpio_in(DEVICE(&s->apu_cpu[i]),
+                                            ARM_CPU_VIRQ));
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + num_apus * 3,
+                           qdev_get_gpio_in(DEVICE(&s->apu_cpu[i]),
+                                            ARM_CPU_VFIQ));
+    }
+
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    if (!s->boot_cpu_ptr) {
+        error_setg(errp, "Boot cpu %s not found", boot_cpu);
+        return;
+    }
+
+    for (i = 0; i < GIC_NUM_SPI_INTR; i++) {
+        gic_spi[i] = qdev_get_gpio_in(DEVICE(&s->gic), i);
+    }
+
+    for (i = 0; i < ARMR52_VIRT_NUM_UARTS; i++) {
+        qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hd(i));
+        if (!sysbus_realize(SYS_BUS_DEVICE(&s->uart[i]), errp)) {
+            return;
+        }
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, uart_addr[i]);
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
+                           gic_spi[uart_intr[i]]);
+    }
+
+}
+
+static Property armr52_virt_props[] = {
+    DEFINE_PROP_STRING("boot-cpu", ArmR52VirtState, boot_cpu),
+    DEFINE_PROP_BOOL("secure", ArmR52VirtState, secure, false),
+    DEFINE_PROP_BOOL("virtualization", ArmR52VirtState, virt, false),
+};
+
+static void armr52_virt_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    device_class_set_props(dc, armr52_virt_props);
+    dc->realize = armr52_virt_realize;
+}
+
+static const TypeInfo armr52_virt_type_info = {
+    .name = TYPE_ARMR52VIRT,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(ArmR52VirtState),
+    .instance_init = armr52_virt_init,
+    .class_init = armr52_virt_class_init,
+};
+
+static void armr52_virt_register_types(void)
+{
+    type_register_static(&armr52_virt_type_info);
+}
+
+type_init(armr52_virt_register_types)
diff --git a/include/hw/arm/r52_virt.h b/include/hw/arm/r52_virt.h
new file mode 100644
index 0000000000..0f26745535
--- /dev/null
+++ b/include/hw/arm/r52_virt.h
@@ -0,0 +1,61 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef ARMR52VIRT_H
+#define ARMR52VIRT_H
+
+#include "hw/arm/boot.h"
+#include "hw/intc/arm_gic.h"
+#include "hw/char/pl011.h"
+#include "include/exec/address-spaces.h"
+#include "hw/cpu/cluster.h"
+#include "target/arm/cpu.h"
+#include "qom/object.h"
+#include "hw/intc/arm_gicv3_common.h"
+
+#define TYPE_ARMR52VIRT "armr52virt"
+OBJECT_DECLARE_SIMPLE_TYPE(ArmR52VirtState, ARMR52VIRT)
+
+#define ARMR52_VIRT_NUM_APU_CPUS 4
+#define ARMR52_VIRT_NUM_UARTS 1
+#define ARMR52_VIRT_GIC_REGIONS 6
+
+#define ARCH_TIMER_VIRT_IRQ   11
+#define ARCH_TIMER_S_EL1_IRQ  13
+#define ARCH_TIMER_NS_EL1_IRQ 14
+#define ARCH_TIMER_NS_EL2_IRQ 10
+#define NUM_IRQS 256
+
+struct ArmR52VirtState {
+    /*< private >*/
+    DeviceState parent_obj;
+
+    /*< public >*/
+    CPUClusterState apu_cluster;
+    ARMCPU apu_cpu[ARMR52_VIRT_NUM_APU_CPUS];
+    GICv3State gic;
+
+    MemoryRegion ddr_ram;
+
+    PL011State uart[ARMR52_VIRT_NUM_UARTS];
+
+    char *boot_cpu;
+    ARMCPU *boot_cpu_ptr;
+
+    /* Has the ARM Security extensions?  */
+    bool secure;
+    /* Has the ARM Virtualization extensions?  */
+    bool virt;
+
+};
+
+#endif
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH 03/11] target/arm: Add v8R MIDR register
  2022-07-14 14:53 ` [PATCH 03/11] target/arm: Add v8R MIDR register Tobias Roehmel
@ 2022-07-14 15:15   ` Peter Maydell
  0 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2022-07-14 15:15 UTC (permalink / raw)
  To: Tobias Roehmel; +Cc: qemu-devel

On Thu, 14 Jul 2022 at 15:54, Tobias Roehmel <quic_trohmel@quicinc.com> wrote:
>
> From: Tobias Röhmel <quic_trohmel@quicinc.com>
>
> This register is used by the ARM Cortex-R52.
>
> Signed-off-by: Tobias Röhmel <quic_trohmel@quicinc.com>
> ---
>  target/arm/helper.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index 6457e6301c..bdf1df37d5 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -8201,6 +8201,15 @@ void register_cp_regs_for_features(ARMCPU *cpu)
>                .accessfn = access_aa64_tid1,
>                .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
>          };
> +        ARMCPRegInfo id_v8r_midr_cp_reginfo[] = {
> +            { .name = "MIDR",
> +              .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = CP_ANY,
> +              .access = PL1_R, .resetvalue = cpu->midr,
> +              .writefn = arm_cp_write_ignore, .raw_writefn = raw_write,
> +              .readfn = midr_read,
> +              .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
> +              .type = ARM_CP_OVERRIDE },

Why do we need this specially for v8R ? The v8R Supplement lists
MIDR and REVIDR as "unchanged" between v8A and v8R, so the
existing id_v8_midr_cp_reginfo[] should be fine.

thanks
-- PMM


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 01/11] target/arm: Add ARM_FEATURE_V8_R
  2022-07-14 14:53 ` [PATCH 01/11] target/arm: Add ARM_FEATURE_V8_R Tobias Roehmel
@ 2022-07-14 15:16   ` Peter Maydell
  0 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2022-07-14 15:16 UTC (permalink / raw)
  To: Tobias Roehmel; +Cc: qemu-devel

On Thu, 14 Jul 2022 at 15:54, Tobias Roehmel <quic_trohmel@quicinc.com> wrote:
>
> From: Tobias Röhmel <quic_trohmel@quicinc.com>
>
> This flag is necessary to add features for the Cortex-R52.

Is it? Generally we try to avoid adding new ARM_FEATURE_*
flags unless there is no way to get the equivalent information
from some combination of the existing flags and the CPU ID registers.

-- PMM


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 02/11] target/arm: Add ARM Cortex-R52 cpu
  2022-07-14 14:53 ` [PATCH 02/11] target/arm: Add ARM Cortex-R52 cpu Tobias Roehmel
@ 2022-07-14 15:23   ` Peter Maydell
  0 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2022-07-14 15:23 UTC (permalink / raw)
  To: Tobias Roehmel; +Cc: qemu-devel

On Thu, 14 Jul 2022 at 15:54, Tobias Roehmel <quic_trohmel@quicinc.com> wrote:
>
> From: Tobias Röhmel <quic_trohmel@quicinc.com>
>
> All constants are taken from the ARM Cortex-R52 Processor TRM Revision: r1p3

This should be the last patch in the patchset, so that we only
add the new CPU when all the code changes necessary to make it work
are present.

> Signed-off-by: Tobias Röhmel <quic_trohmel@quicinc.com>
> ---
>  target/arm/cpu_tcg.c | 54 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 54 insertions(+)
>
> diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
> index b751a19c8a..49fb03c09a 100644
> --- a/target/arm/cpu_tcg.c
> +++ b/target/arm/cpu_tcg.c
> @@ -843,6 +843,59 @@ static void cortex_r5_initfn(Object *obj)
>      define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
>  }
>
> +static const ARMCPRegInfo cortexr52_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 },
> +    { .name = "DCACHE_INVAL", .cp = 15, .opc1 = 0, .crn = 15, .crm = 5,
> +      .opc2 = 0, .access = PL1_W, .type = ARM_CP_NOP },
> +};

This is just a copy of the Cortex-R5 impdef register set.
The R52 doesn't have the DCACHE_INVAL. Although it does have
registers in the ATCM and BTCM encodings, it also has a
third CTCM, because it has three TCM regions.

You should implement the IMPDEF registers that the CPU
actually has, assuming that guest software cares about them.

> +static void cortex_r52_initfn(Object *obj)
> +{
> +    ARMCPU *cpu = ARM_CPU(obj);
> +
> +    set_feature(&cpu->env, ARM_FEATURE_V8);
> +    set_feature(&cpu->env, ARM_FEATURE_V8_R);
> +    set_feature(&cpu->env, ARM_FEATURE_EL2);
> +    set_feature(&cpu->env, ARM_FEATURE_PMSA);
> +    set_feature(&cpu->env, ARM_FEATURE_NEON);
> +    set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
> +    cpu->midr = 0x411fd133; /* r1p3 */
> +    cpu->revidr = 0x00000000;
> +    cpu->reset_fpsid = 0x41034023;
> +    cpu->isar.mvfr0 = 0x10110222;
> +    cpu->isar.mvfr1 = 0x12111111;
> +    cpu->isar.mvfr2 = 0x00000043;
> +    cpu->ctr = 0x8144c004;
> +    cpu->reset_sctlr = 0x30c50838;
> +    cpu->isar.id_pfr0 = 0x00000131;
> +    cpu->isar.id_pfr1 = 0x10111001;
> +    cpu->isar.id_dfr0 = 0x03010006;
> +    cpu->id_afr0 = 0x00000000;
> +    cpu->isar.id_mmfr0 = 0x00211040;
> +    cpu->isar.id_mmfr1 = 0x40000000;
> +    cpu->isar.id_mmfr2 = 0x01200000;
> +    cpu->isar.id_mmfr3 = 0xf0102211;
> +    cpu->isar.id_mmfr4 = 0x00000010;
> +    cpu->isar.id_isar0 = 0x02101110;
> +    cpu->isar.id_isar1 = 0x13112111;
> +    cpu->isar.id_isar2 = 0x21232142;
> +    cpu->isar.id_isar3 = 0x01112131;
> +    cpu->isar.id_isar4 = 0x00010142;
> +    cpu->isar.id_isar5 = 0x00010001;
> +    cpu->isar.dbgdidr = 0x77168000;
> +    cpu->clidr = (1 << 27) | (1 << 24) | 0x3;
> +    cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
> +    cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
> +
> +    cpu->pmsav7_dregion = 16;
> +
> +    define_arm_cp_regs(cpu, cortexr52_cp_reginfo);
> +}
> +
>  static void cortex_r5f_initfn(Object *obj)
>  {
>      ARMCPU *cpu = ARM_CPU(obj);
> @@ -1148,6 +1201,7 @@ static const ARMCPUInfo arm_tcg_cpus[] = {
>      { .name = "cortex-m55",  .initfn = cortex_m55_initfn,
>                               .class_init = arm_v7m_class_init },
>      { .name = "cortex-r5",   .initfn = cortex_r5_initfn },
> +    { .name = "cortex-r52",   .initfn = cortex_r52_initfn },
>      { .name = "cortex-r5f",  .initfn = cortex_r5f_initfn },

List it below cortex-r5f, so that the two different flavours of R5
stay together.

>      { .name = "ti925t",      .initfn = ti925t_initfn },
>      { .name = "sa1100",      .initfn = sa1100_initfn },
> --
> 2.25.1
>

thanks
-- PMM


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 04/11] target/arm: Make RVBAR available for non AARCH64 CPUs
  2022-07-14 14:53 ` [PATCH 04/11] target/arm: Make RVBAR available for non AARCH64 CPUs Tobias Roehmel
@ 2022-07-14 15:28   ` Peter Maydell
  0 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2022-07-14 15:28 UTC (permalink / raw)
  To: Tobias Roehmel; +Cc: qemu-devel

On Thu, 14 Jul 2022 at 15:54, Tobias Roehmel <quic_trohmel@quicinc.com> wrote:
>
> From: Tobias Röhmel <quic_trohmel@quicinc.com>
>
> The ARM Cortex-R52 is not AARCH64 but uses RVBAR.
>
> Signed-off-by: Tobias Röhmel <quic_trohmel@quicinc.com>
> ---
>  target/arm/cpu.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index 1b5d535788..2c26a5387d 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -258,6 +258,10 @@ static void arm_cpu_reset(DeviceState *dev)
>          env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
>                                           CPACR, CP11, 3);
>  #endif
> +        if (arm_feature(env, ARM_FEATURE_V8_R)) {
> +            env->cp15.rvbar = cpu->rvbar_prop;
> +            env->regs[15] = cpu->rvbar_prop;
> +        }
>      }
>
>  #if defined(CONFIG_USER_ONLY)
> @@ -1273,7 +1277,8 @@ void arm_cpu_post_init(Object *obj)
>          qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_hivecs_property);
>      }
>
> -    if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
> +    if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) ||
> +        arm_feature(&cpu->env, ARM_FEATURE_V8_R)) {

Rather than doing this, we should correct the feature bit
being tested -- the RVBAR register itself is present on all
v8 CPUs, so we should correspondingly provide the property on
all v8 CPUs, by checking ARM_FEATURE_V8 (ie the same check we
use for whether to add the RVBAR register definition).

>          object_property_add_uint64_ptr(obj, "rvbar",
>                                         &cpu->rvbar_prop,
>                                         OBJ_PROP_FLAG_READWRITE);
> --

thanks
-- PMM


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 07/11] target/arm: Enable TTBCR_EAE for ARM_FEATURE_V8_R
  2022-07-14 14:53 ` [PATCH 07/11] target/arm: Enable TTBCR_EAE for ARM_FEATURE_V8_R Tobias Roehmel
@ 2022-07-14 15:34   ` Peter Maydell
  0 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2022-07-14 15:34 UTC (permalink / raw)
  To: Tobias Roehmel; +Cc: qemu-devel

On Thu, 14 Jul 2022 at 15:54, Tobias Roehmel <quic_trohmel@quicinc.com> wrote:
>
> From: Tobias Röhmel <quic_trohmel@quicinc.com>
>
> Enable TTBCR_EAE during reset since it's always set to 1 for Cortex-R52.
> See ARM Architecture Reference Manual Supplement - ARMv8, for the ARMv8-R
> AArch32 architecture profile Version:A.c section C1.2.
>
> Signed-off-by: Tobias Röhmel <quic_trohmel@quicinc.com>
> ---
>  target/arm/cpu.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index 2c26a5387d..121fc2a819 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -261,6 +261,9 @@ static void arm_cpu_reset(DeviceState *dev)
>          if (arm_feature(env, ARM_FEATURE_V8_R)) {
>              env->cp15.rvbar = cpu->rvbar_prop;
>              env->regs[15] = cpu->rvbar_prop;
> +            env->cp15.tcr_el[0].raw_tcr = TTBCR_EAE;
> +            env->cp15.tcr_el[1].raw_tcr = TTBCR_EAE;
> +            env->cp15.tcr_el[2].raw_tcr = TTBCR_EAE;
>          }
>      }

R-profile doesn't have a TTBCR, so I'm not sure this is the right way
to handle this behaviour requirement... Probably extended_addresses_enabled()
and similar places should just return true for v8 PMSA.

-- PMM


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 10/11] target/arm: Make SPSR_hyp accessible for Cortex-R52
  2022-07-14 14:53 ` [PATCH 10/11] target/arm: Make SPSR_hyp accessible for Cortex-R52 Tobias Roehmel
@ 2022-07-14 15:46   ` Peter Maydell
  2022-07-14 16:52     ` Peter Maydell
  0 siblings, 1 reply; 20+ messages in thread
From: Peter Maydell @ 2022-07-14 15:46 UTC (permalink / raw)
  To: Tobias Roehmel; +Cc: qemu-devel

On Thu, 14 Jul 2022 at 15:54, Tobias Roehmel <quic_trohmel@quicinc.com> wrote:
>
> From: Tobias Röhmel <quic_trohmel@quicinc.com>
>
> The Cortex-R52 can access SPSR_hyp from hypervisor mode
> as discussed here: https://github.com/zephyrproject-rtos/zephyr/issues/47330

The v8R Supplement pseudocode aarch32/functions/system/SPSRaccessValid
says this is UNPREDICTABLE:

when '11110' // SPSR_hyp
    if !HaveEL(EL2) || mode != M32_Monitor then UNPREDICTABLE;

so unless that's incorrect then I think QEMU is within its rights
to UNDEF this (and real hardware may choose to UNDEF or not).

I will enquire about whether there is a bug in the sample R52
startup code.

thanks
-- PMM


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 11/11] hw/arm: Add R52 machine
  2022-07-14 14:53 ` [PATCH 11/11] hw/arm: Add R52 machine Tobias Roehmel
@ 2022-07-14 15:53   ` Peter Maydell
  0 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2022-07-14 15:53 UTC (permalink / raw)
  To: Tobias Roehmel; +Cc: qemu-devel

On Thu, 14 Jul 2022 at 15:54, Tobias Roehmel <quic_trohmel@quicinc.com> wrote:
>
> From: Tobias Röhmel <quic_trohmel@quicinc.com>
>
> Signed-off-by: Tobias Röhmel <quic_trohmel@quicinc.com>
> ---
>  configs/devices/arm-softmmu/default.mak |   1 +
>  hw/arm/Kconfig                          |   5 +
>  hw/arm/meson.build                      |   1 +
>  hw/arm/r52_machine.c                    | 133 +++++++++++++++
>  hw/arm/r52_virt.c                       | 217 ++++++++++++++++++++++++
>  include/hw/arm/r52_virt.h               |  61 +++++++

This needs justification about whether it's the right thing to do.
What's the purpose of the new machine? Would it be better as
part of the existing "virt" board? Is there a real physical
Cortex-R52 based machine that it would make more sense to model?
If we do need a new virtual R-profile board, should it really
be R52-specific?

I am generally not a fan of creating new entirely-QEMU-specific
machines if we can avoid it.

thanks
-- PMM


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 10/11] target/arm: Make SPSR_hyp accessible for Cortex-R52
  2022-07-14 15:46   ` Peter Maydell
@ 2022-07-14 16:52     ` Peter Maydell
  0 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2022-07-14 16:52 UTC (permalink / raw)
  To: Tobias Roehmel; +Cc: qemu-devel

On Thu, 14 Jul 2022 at 16:46, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Thu, 14 Jul 2022 at 15:54, Tobias Roehmel <quic_trohmel@quicinc.com> wrote:
> >
> > From: Tobias Röhmel <quic_trohmel@quicinc.com>
> >
> > The Cortex-R52 can access SPSR_hyp from hypervisor mode
> > as discussed here: https://github.com/zephyrproject-rtos/zephyr/issues/47330
>
> The v8R Supplement pseudocode aarch32/functions/system/SPSRaccessValid
> says this is UNPREDICTABLE:
>
> when '11110' // SPSR_hyp
>     if !HaveEL(EL2) || mode != M32_Monitor then UNPREDICTABLE;
>
> so unless that's incorrect then I think QEMU is within its rights
> to UNDEF this (and real hardware may choose to UNDEF or not).
>
> I will enquire about whether there is a bug in the sample R52
> startup code.

The author of the startup code example agrees it's a bug that went
unnoticed because the FVP happens to permit this UNPREDICTABLE case,
so we don't need this QEMU patch.

-- PMM


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2022-07-14 17:05 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-14 14:53 [PATCH 00/11] Add Cortex-R52 Tobias Roehmel
2022-07-14 14:53 ` [PATCH 01/11] target/arm: Add ARM_FEATURE_V8_R Tobias Roehmel
2022-07-14 15:16   ` Peter Maydell
2022-07-14 14:53 ` [PATCH 02/11] target/arm: Add ARM Cortex-R52 cpu Tobias Roehmel
2022-07-14 15:23   ` Peter Maydell
2022-07-14 14:53 ` [PATCH 03/11] target/arm: Add v8R MIDR register Tobias Roehmel
2022-07-14 15:15   ` Peter Maydell
2022-07-14 14:53 ` [PATCH 04/11] target/arm: Make RVBAR available for non AARCH64 CPUs Tobias Roehmel
2022-07-14 15:28   ` Peter Maydell
2022-07-14 14:53 ` [PATCH 05/11] target/arm: Make stage_2_format for cache attributes optional Tobias Roehmel
2022-07-14 14:53 ` [PATCH 06/11] target/arm: Add ARMCacheAttrs to the signature of pmsav8_mpu_lookup Tobias Roehmel
2022-07-14 14:53 ` [PATCH 07/11] target/arm: Enable TTBCR_EAE for ARM_FEATURE_V8_R Tobias Roehmel
2022-07-14 15:34   ` Peter Maydell
2022-07-14 14:53 ` [PATCH 08/11] target/arm Add PMSAv8r registers Tobias Roehmel
2022-07-14 14:53 ` [PATCH 09/11] target/arm: Add PMSAv8r functionality Tobias Roehmel
2022-07-14 14:53 ` [PATCH 10/11] target/arm: Make SPSR_hyp accessible for Cortex-R52 Tobias Roehmel
2022-07-14 15:46   ` Peter Maydell
2022-07-14 16:52     ` Peter Maydell
2022-07-14 14:53 ` [PATCH 11/11] hw/arm: Add R52 machine Tobias Roehmel
2022-07-14 15:53   ` Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.