qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v3] target-arm: add Faraday ARMv5TE processors suppo


From: Kuo-Jung Su
Subject: [Qemu-devel] [PATCH v3] target-arm: add Faraday ARMv5TE processors support
Date: Mon, 4 Feb 2013 17:56:51 +0800

From: Kuo-Jung Su <address@hidden>

Faraday processors are a series of ARMv4/ARMv5TE clone.

* ARMv4 series (FA526, FA626).

    All of them are now out-of-date, so I have no plan for them.

* ARMv5TE series (FA606TE, FA626TE, FA616TE, FA726TE)

    All the single core RISC listed above are included in this patch.
    And there are two Faraday CP15 extensions (AUX and I/D-Scratchpad)
    have been implemented as a read/write value without any extra actions.

Signed-off-by: Kuo-Jung Su <address@hidden>
Cc: Paul Brook <address@hidden>
Cc: Peter Maydell <address@hidden>
---
 Partial version of Faraday ARM cores are available here:
 
 https://docs.google.com/folder/d/0BwfiewvSmUgAalh5TkxyZWtlWEE/edit

 Changes for v3:
   - Replace Faraday i/d scratchpad with TCM, since they're compatible.
     The TCM_STATUS would be redirected to 'TCMTR' in id_cp_reginfo[],
     and it's always a 'ZERO' which indicates no TCM in QEMU model.
   - Replace Faraday auxiliary control for FA626TE with ARM AUXCR.
   - Add Faraday MPU support for FA606TE.
   - Update CPU_SAVE_VERSION from 9 to 10.
   - Update machine.c to include c15_tcm_xxxx.

 Changes for v2:
   - coding style fixes.
   - create a register cache(field) in cp15 for R/W, rather than NOP.
     thanks to Paul for the idea.

 target-arm/cpu.c     |   52 +++++++++++++++++++++++++++++++
 target-arm/cpu.h     |    6 +++-
 target-arm/helper.c  |   84 ++++++++++++++++++++++++++++++++++++++++++++++++++
 target-arm/machine.c |    4 +++
 4 files changed, 145 insertions(+), 1 deletion(-)

diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 1c6a628..d308dbe 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -233,6 +233,54 @@ static void arm926_initfn(Object *obj)
     cpu->reset_sctlr = 0x00090078;
 }
 
+static void fa606te_initfn(Object *obj)
+{
+    ARMCPU *cpu = ARM_CPU(obj);
+    set_feature(&cpu->env, ARM_FEATURE_V5);
+    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
+    set_feature(&cpu->env, ARM_FEATURE_MPU_FARADAY);
+    cpu->midr = 0x66056061; /* CR0-0 Identification Code Register (ID) */
+    cpu->ctr = 0x00000000;  /* CR0-1 Cache Type Register (CTR) */
+    cpu->reset_sctlr = 0x00000078;  /* CR1-0 Configuration Register (CFG) */
+}
+
+static void fa616te_initfn(Object *obj)
+{
+    ARMCPU *cpu = ARM_CPU(obj);
+    set_feature(&cpu->env, ARM_FEATURE_V5);
+    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
+    set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
+    set_feature(&cpu->env, ARM_FEATURE_TCM_FARADAY);
+    cpu->midr = 0x66056161; /* CR0-0 Identification Code Register (ID) */
+    cpu->ctr = 0x1d152152;  /* CR0-1 Cache Type Register (CTR) */
+    cpu->reset_sctlr = 0x00050078;  /* CR1-0 Configuration Register (CFG) */
+}
+
+static void fa626te_initfn(Object *obj)
+{
+    ARMCPU *cpu = ARM_CPU(obj);
+    set_feature(&cpu->env, ARM_FEATURE_V5);
+    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
+    set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
+    set_feature(&cpu->env, ARM_FEATURE_TCM_FARADAY);
+    set_feature(&cpu->env, ARM_FEATURE_AUXCR);
+    cpu->midr = 0x66056261; /* CR0-0 Identification Code Register (ID) */
+    cpu->ctr = 0x0f192192;  /* CR0-1 Cache Type Register (CTR) */
+    cpu->reset_sctlr = 0x00000078;  /* CR1-0 Configuration Register (CFG) */
+}
+
+static void fa726te_initfn(Object *obj)
+{
+    ARMCPU *cpu = ARM_CPU(obj);
+    set_feature(&cpu->env, ARM_FEATURE_V5);
+    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
+    set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
+    set_feature(&cpu->env, ARM_FEATURE_TCM_FARADAY);
+    cpu->midr = 0x66057261; /* CR0-0 Identification Code Register (ID) */
+    cpu->ctr = 0x1d192192;  /* CR0-1 Cache Type Register (CTR) */
+    cpu->reset_sctlr = 0x00050078;  /* CR1-0 Configuration Register (CFG) */
+}
+
 static void arm946_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
@@ -745,6 +793,10 @@ typedef struct ARMCPUInfo {
 
 static const ARMCPUInfo arm_cpus[] = {
     { .name = "arm926",      .initfn = arm926_initfn },
+    { .name = "fa606te",     .initfn = fa606te_initfn },
+    { .name = "fa616te",     .initfn = fa616te_initfn },
+    { .name = "fa626te",     .initfn = fa626te_initfn },
+    { .name = "fa726te",     .initfn = fa726te_initfn },
     { .name = "arm946",      .initfn = arm946_initfn },
     { .name = "arm1026",     .initfn = arm1026_initfn },
     /* What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index ffddfcb..e0b0a78 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -152,6 +152,8 @@ typedef struct CPUARMState {
         uint32_t c15_diagnostic; /* diagnostic register */
         uint32_t c15_power_diagnostic;
         uint32_t c15_power_control; /* power control */
+        uint32_t c15_tcm_data;      /* Data TCM region register */
+        uint32_t c15_tcm_inst;      /* Instruction TCM region register */
     } cp15;
 
     struct {
@@ -391,6 +393,8 @@ enum arm_features {
     ARM_FEATURE_MPIDR, /* has cp15 MPIDR */
     ARM_FEATURE_PXN, /* has Privileged Execute Never bit */
     ARM_FEATURE_LPAE, /* has Large Physical Address Extension */
+    ARM_FEATURE_TCM_FARADAY, /* Faraday Scratchpad(TCM) */
+    ARM_FEATURE_MPU_FARADAY, /* Faraday MPU */
 };
 
 static inline int arm_feature(CPUARMState *env, int feature)
@@ -639,7 +643,7 @@ static inline CPUARMState *cpu_init(const char *cpu_model)
 #define cpu_signal_handler cpu_arm_signal_handler
 #define cpu_list arm_cpu_list
 
-#define CPU_SAVE_VERSION 9
+#define CPU_SAVE_VERSION 10
 
 /* MMU modes definitions */
 #define MMU_MODE0_SUFFIX _kernel
diff --git a/target-arm/helper.c b/target-arm/helper.c
index eb7b291..48d7119 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1015,6 +1015,84 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
+static int faraday_pmsav5_ircfg_read(CPUARMState *env,
+                                     const ARMCPRegInfo *ri,
+                                     uint64_t *value)
+{
+    if (ri->crm >= 4) {
+        return EXCP_UDEF;
+    }
+    *value = env->cp15.c6_region[ri->crm];
+    return 0;
+}
+
+static int faraday_pmsav5_ircfg_write(CPUARMState *env,
+                                      const ARMCPRegInfo *ri,
+                                      uint64_t value)
+{
+    if (ri->crm >= 4) {
+        return EXCP_UDEF;
+    }
+    env->cp15.c6_region[ri->crm] = value;
+    return 0;
+}
+
+static int faraday_pmsav5_drcfg_read(CPUARMState *env,
+                                     const ARMCPRegInfo *ri,
+                                     uint64_t *value)
+{
+    if (ri->crm >= 4) {
+        return EXCP_UDEF;
+    }
+    *value = env->cp15.c6_region[ri->crm + 4];
+    return 0;
+}
+
+static int faraday_pmsav5_drcfg_write(CPUARMState *env,
+                                      const ARMCPRegInfo *ri,
+                                      uint64_t value)
+{
+    if (ri->crm >= 4) {
+        return EXCP_UDEF;
+    }
+    env->cp15.c6_region[ri->crm + 4] = value;
+    return 0;
+}
+
+static const ARMCPRegInfo faraday_pmsav5_cp_reginfo[] = {
+    /* Data region access permission */
+    { .name = "DATA_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
+      .access = PL1_RW,
+      .fieldoffset = offsetof(CPUARMState, cp15.c5_data), .resetvalue = 0,
+      .readfn = pmsav5_data_ap_read, .writefn = pmsav5_data_ap_write, },
+    /* Instruction region access permission */
+    { .name = "INSN_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1,
+      .access = PL1_RW,
+      .fieldoffset = offsetof(CPUARMState, cp15.c5_insn), .resetvalue = 0,
+      .readfn = pmsav5_insn_ap_read, .writefn = pmsav5_insn_ap_write, },
+    /* Data region base and size registers */
+    { .name = "DR_CFG", .cp = 15, .crn = 6, .crm = CP_ANY,
+      .opc1 = 0, .opc2 = 0, .access = PL1_RW,
+      .readfn = faraday_pmsav5_drcfg_read,
+      .writefn = faraday_pmsav5_drcfg_write, },
+    /* Instruction region base and size registers */
+    { .name = "IR_CFG", .cp = 15, .crn = 6, .crm = CP_ANY,
+      .opc1 = 0, .opc2 = 1, .access = PL1_RW,
+      .readfn = faraday_pmsav5_ircfg_read,
+      .writefn = faraday_pmsav5_ircfg_write, },
+    REGINFO_SENTINEL
+};
+
+static const ARMCPRegInfo faraday_tcm_cp_reginfo[] = {
+    { .name = "DTCMRR", .cp = 15, .crn = 9, .crm = 1,
+      .opc1 = 0, .opc2 = 0, .access = PL1_RW, .resetvalue = 0x0,
+      .fieldoffset = offsetof(CPUARMState, cp15.c15_tcm_data) },
+    { .name = "ITCMRR", .cp = 15, .crn = 9, .crm = 1,
+      .opc1 = 0, .opc2 = 1, .access = PL1_RW, .resetvalue = 0x0,
+      .fieldoffset = offsetof(CPUARMState, cp15.c15_tcm_inst) },
+    REGINFO_SENTINEL
+};
+
 static int sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t 
value)
 {
     env->cp15.c1_sys = value;
@@ -1163,6 +1241,12 @@ void register_cp_regs_for_features(ARMCPU *cpu)
     if (arm_feature(env, ARM_FEATURE_LPAE)) {
         define_arm_cp_regs(cpu, lpae_cp_reginfo);
     }
+    if (arm_feature(env, ARM_FEATURE_TCM_FARADAY)) {
+        define_arm_cp_regs(cpu, faraday_tcm_cp_reginfo);
+    }
+    if (arm_feature(env, ARM_FEATURE_MPU_FARADAY)) {
+        define_arm_cp_regs(cpu, faraday_pmsav5_cp_reginfo);
+    }
     /* Slightly awkwardly, the OMAP and StrongARM cores need all of
      * cp15 crn=0 to be writes-ignored, whereas for other cores they should
      * be read-only (ie write causes UNDEF exception).
diff --git a/target-arm/machine.c b/target-arm/machine.c
index 68dca7f..ed63614 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -62,6 +62,8 @@ void cpu_save(QEMUFile *f, void *opaque)
     qemu_put_be32(f, env->cp15.c15_power_control);
     qemu_put_be32(f, env->cp15.c15_diagnostic);
     qemu_put_be32(f, env->cp15.c15_power_diagnostic);
+    qemu_put_be32(f, env->cp15.c15_tcm_data);
+    qemu_put_be32(f, env->cp15.c15_tcm_inst);
 
     qemu_put_be64(f, env->features);
 
@@ -182,6 +184,8 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     env->cp15.c15_power_control = qemu_get_be32(f);
     env->cp15.c15_diagnostic = qemu_get_be32(f);
     env->cp15.c15_power_diagnostic = qemu_get_be32(f);
+    env->cp15.c15_tcm_data = qemu_get_be32(f);
+    env->cp15.c15_tcm_inst = qemu_get_be32(f);
 
     env->features = qemu_get_be64(f);
 
-- 
1.7.9.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]