diff mbox

[10/12] Add Cortex-A15 CPU definition

Message ID 1326487969-12462-11-git-send-email-peter.maydell@linaro.org
State Superseded
Headers show

Commit Message

Peter Maydell Jan. 13, 2012, 8:52 p.m. UTC
Add a definition of a Cortex-A15 CPU. Note that for the moment we do
not implement any of:
 * Large Physical Address Extensions (LPAE)
 * Virtualization Extensions
 * Generic Timer
 * TrustZone (this is also true of our existing Cortex-A9 model, etc)

This CPU model is sufficient to boot a Linux kernel which has been
compiled for an A15 without LPAE enabled.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu.h    |    1 +
 target-arm/helper.c |   56 ++++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 52 insertions(+), 5 deletions(-)

Comments

Peter Maydell Jan. 23, 2012, 6:12 p.m. UTC | #1
Ping. Unless anybody has any review comments on this or patch 9 (generic
timer dummy implementation) I plan to put them into my target-arm.next
queue and send out a pullreq later this week.

-- PMM

On 13 January 2012 20:52, Peter Maydell <peter.maydell@linaro.org> wrote:
> Add a definition of a Cortex-A15 CPU. Note that for the moment we do
> not implement any of:
>  * Large Physical Address Extensions (LPAE)
>  * Virtualization Extensions
>  * Generic Timer
>  * TrustZone (this is also true of our existing Cortex-A9 model, etc)
>
> This CPU model is sufficient to boot a Linux kernel which has been
> compiled for an A15 without LPAE enabled.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target-arm/cpu.h    |    1 +
>  target-arm/helper.c |   56 ++++++++++++++++++++++++++++++++++++++++++++++----
>  2 files changed, 52 insertions(+), 5 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index d5403ea..4b8d680 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -433,6 +433,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
>  #define ARM_CPUID_CORTEXA8    0x410fc080
>  #define ARM_CPUID_CORTEXA9    0x410fc090
>  #define ARM_CPUID_CORTEXM3    0x410fc231
> +#define ARM_CPUID_CORTEXA15   0x412fc0f1
>  #define ARM_CPUID_ANY         0xffffffff
>
>  #if defined(CONFIG_USER_ONLY)
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index de4a50f..a68dc5c 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -10,6 +10,16 @@
>  #if !defined(CONFIG_USER_ONLY)
>  #include "hw/loader.h"
>  #endif
> +#include "sysemu.h"
> +
> +static uint32_t cortexa15_cp15_c0_c1[8] = {
> +    0x00001131, 0x00011011, 0x02010555, 0x00000000,
> +    0x10201105, 0x20000000, 0x01240000, 0x02102211
> +};
> +
> +static uint32_t cortexa15_cp15_c0_c2[8] = {
> +    0x02101110, 0x13112111, 0x21232041, 0x11112131, 0x10011142, 0, 0, 0
> +};
>
>  static uint32_t cortexa9_cp15_c0_c1[8] =
>  { 0x1031, 0x11, 0x000, 0, 0x00100103, 0x20000000, 0x01230000, 0x00002111 };
> @@ -158,6 +168,27 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
>         env->cp15.c0_ccsid[1] = 0x200fe015; /* 16k L1 icache. */
>         env->cp15.c1_sys = 0x00c50078;
>         break;
> +    case ARM_CPUID_CORTEXA15:
> +        set_feature(env, ARM_FEATURE_V7);
> +        set_feature(env, ARM_FEATURE_VFP4);
> +        set_feature(env, ARM_FEATURE_VFP_FP16);
> +        set_feature(env, ARM_FEATURE_NEON);
> +        set_feature(env, ARM_FEATURE_THUMB2EE);
> +        set_feature(env, ARM_FEATURE_ARM_DIV);
> +        set_feature(env, ARM_FEATURE_V7MP);
> +        set_feature(env, ARM_FEATURE_GENERICTIMER);
> +        env->vfp.xregs[ARM_VFP_FPSID] = 0x410430f0;
> +        env->vfp.xregs[ARM_VFP_MVFR0] = 0x10110222;
> +        env->vfp.xregs[ARM_VFP_MVFR1] = 0x11111111;
> +        memcpy(env->cp15.c0_c1, cortexa15_cp15_c0_c1, 8 * sizeof(uint32_t));
> +        memcpy(env->cp15.c0_c2, cortexa15_cp15_c0_c2, 8 * sizeof(uint32_t));
> +        env->cp15.c0_cachetype = 0x8444c004;
> +        env->cp15.c0_clid = 0x0a200023;
> +        env->cp15.c0_ccsid[0] = 0x701fe00a; /* 32K L1 dcache */
> +        env->cp15.c0_ccsid[1] = 0x201fe00a; /* 32K L1 icache */
> +        env->cp15.c0_ccsid[2] = 0x711fe07a; /* 4096K L2 unified cache */
> +        env->cp15.c1_sys = 0x00c50078;
> +        break;
>     case ARM_CPUID_CORTEXM3:
>         set_feature(env, ARM_FEATURE_V7);
>         set_feature(env, ARM_FEATURE_M);
> @@ -413,6 +444,7 @@ static const struct arm_cpu_t arm_cpu_names[] = {
>     { ARM_CPUID_CORTEXM3, "cortex-m3"},
>     { ARM_CPUID_CORTEXA8, "cortex-a8"},
>     { ARM_CPUID_CORTEXA9, "cortex-a9"},
> +    { ARM_CPUID_CORTEXA15, "cortex-a15"},
>     { ARM_CPUID_TI925T, "ti925t" },
>     { ARM_CPUID_PXA250, "pxa250" },
>     { ARM_CPUID_SA1100,    "sa1100" },
> @@ -667,8 +699,6 @@ uint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
>
>  #else
>
> -extern int semihosting_enabled;
> -
>  /* Map CPU modes onto saved register banks.  */
>  static inline int bank_number(CPUState *env, int mode)
>  {
> @@ -1934,6 +1964,7 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
>             case ARM_CPUID_CORTEXA8:
>                 return 2;
>             case ARM_CPUID_CORTEXA9:
> +            case ARM_CPUID_CORTEXA15:
>                 return 0;
>             default:
>                 goto bad_reg;
> @@ -2054,11 +2085,26 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
>                     goto bad_reg;
>                 }
>             case 1: /* L2 cache */
> -                if (crm != 0) {
> +                /* L2 Lockdown and Auxiliary control.  */
> +                switch (op2) {
> +                case 0:
> +                    /* L2 cache lockdown (A8 only) */
> +                    return 0;
> +                case 2:
> +                    /* L2 cache auxiliary control (A8) or control (A15) */
> +                    if (ARM_CPUID(env) == ARM_CPUID_CORTEXA15) {
> +                        /* Linux wants the number of processors from here.
> +                         * Might as well set the interrupt-controller bit too.
> +                         */
> +                        return ((smp_cpus - 1) << 24) | (1 << 23);
> +                    }
> +                    return 0;
> +                case 3:
> +                    /* L2 cache extended control (A15) */
> +                    return 0;
> +                default:
>                     goto bad_reg;
>                 }
> -                /* L2 Lockdown and Auxiliary control.  */
> -                return 0;
>             default:
>                 goto bad_reg;
>             }
> --
> 1.7.1
>
> _______________________________________________
> Android-virt mailing list
> Android-virt@lists.cs.columbia.edu
> https://lists.cs.columbia.edu/cucslists/listinfo/android-virt
Andreas Färber Jan. 24, 2012, 7:59 a.m. UTC | #2
Am 13.01.2012 21:52, schrieb Peter Maydell:
> Add a definition of a Cortex-A15 CPU. Note that for the moment we do
> not implement any of:
>  * Large Physical Address Extensions (LPAE)
>  * Virtualization Extensions
>  * Generic Timer
>  * TrustZone (this is also true of our existing Cortex-A9 model, etc)
> 
> This CPU model is sufficient to boot a Linux kernel which has been
> compiled for an A15 without LPAE enabled.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target-arm/cpu.h    |    1 +
>  target-arm/helper.c |   56 ++++++++++++++++++++++++++++++++++++++++++++++----
>  2 files changed, 52 insertions(+), 5 deletions(-)
> 
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index d5403ea..4b8d680 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -433,6 +433,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
>  #define ARM_CPUID_CORTEXA8    0x410fc080
>  #define ARM_CPUID_CORTEXA9    0x410fc090
>  #define ARM_CPUID_CORTEXM3    0x410fc231
> +#define ARM_CPUID_CORTEXA15   0x412fc0f1

Reminder of our rnpn topic...

We don't seem to have a clear ordering system but I'd suggest to move
A15 one line up, to group the As and Ms in ascending order respectively.

>  #define ARM_CPUID_ANY         0xffffffff
>  
>  #if defined(CONFIG_USER_ONLY)
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index de4a50f..a68dc5c 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -10,6 +10,16 @@
>  #if !defined(CONFIG_USER_ONLY)
>  #include "hw/loader.h"
>  #endif
> +#include "sysemu.h"
> +
> +static uint32_t cortexa15_cp15_c0_c1[8] = {
> +    0x00001131, 0x00011011, 0x02010555, 0x00000000,
> +    0x10201105, 0x20000000, 0x01240000, 0x02102211
> +};
> +
> +static uint32_t cortexa15_cp15_c0_c2[8] = {
> +    0x02101110, 0x13112111, 0x21232041, 0x11112131, 0x10011142, 0, 0, 0
> +};
>  
>  static uint32_t cortexa9_cp15_c0_c1[8] =
>  { 0x1031, 0x11, 0x000, 0, 0x00100103, 0x20000000, 0x01230000, 0x00002111 };
> @@ -158,6 +168,27 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
>          env->cp15.c0_ccsid[1] = 0x200fe015; /* 16k L1 icache. */
>          env->cp15.c1_sys = 0x00c50078;
>          break;
> +    case ARM_CPUID_CORTEXA15:
> +        set_feature(env, ARM_FEATURE_V7);
> +        set_feature(env, ARM_FEATURE_VFP4);
> +        set_feature(env, ARM_FEATURE_VFP_FP16);
> +        set_feature(env, ARM_FEATURE_NEON);
> +        set_feature(env, ARM_FEATURE_THUMB2EE);
> +        set_feature(env, ARM_FEATURE_ARM_DIV);
> +        set_feature(env, ARM_FEATURE_V7MP);
> +        set_feature(env, ARM_FEATURE_GENERICTIMER);

Features look sane.

> @@ -413,6 +444,7 @@ static const struct arm_cpu_t arm_cpu_names[] = {
>      { ARM_CPUID_CORTEXM3, "cortex-m3"},
>      { ARM_CPUID_CORTEXA8, "cortex-a8"},
>      { ARM_CPUID_CORTEXA9, "cortex-a9"},
> +    { ARM_CPUID_CORTEXA15, "cortex-a15"},

Space please.

>      { ARM_CPUID_TI925T, "ti925t" },
>      { ARM_CPUID_PXA250, "pxa250" },
>      { ARM_CPUID_SA1100,    "sa1100" },
> @@ -667,8 +699,6 @@ uint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
>  
>  #else
>  
> -extern int semihosting_enabled;
> -
>  /* Map CPU modes onto saved register banks.  */
>  static inline int bank_number(CPUState *env, int mode)
>  {
> @@ -1934,6 +1964,7 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
>              case ARM_CPUID_CORTEXA8:
>                  return 2;
>              case ARM_CPUID_CORTEXA9:
> +            case ARM_CPUID_CORTEXA15:
>                  return 0;
>              default:
>                  goto bad_reg;
> @@ -2054,11 +2085,26 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
>                      goto bad_reg;
>                  }
>              case 1: /* L2 cache */
> -                if (crm != 0) {
> +                /* L2 Lockdown and Auxiliary control.  */
> +                switch (op2) {
> +                case 0:
> +                    /* L2 cache lockdown (A8 only) */
> +                    return 0;
> +                case 2:
> +                    /* L2 cache auxiliary control (A8) or control (A15) */
> +                    if (ARM_CPUID(env) == ARM_CPUID_CORTEXA15) {

Change of mind? You opposed uses of ARM_CPUID() for Cortex-R4F.

Andreas

> +                        /* Linux wants the number of processors from here.
> +                         * Might as well set the interrupt-controller bit too.
> +                         */
> +                        return ((smp_cpus - 1) << 24) | (1 << 23);
> +                    }
> +                    return 0;
> +                case 3:
> +                    /* L2 cache extended control (A15) */
> +                    return 0;
> +                default:
>                      goto bad_reg;
>                  }
> -                /* L2 Lockdown and Auxiliary control.  */
> -                return 0;
>              default:
>                  goto bad_reg;
>              }
Peter Maydell Jan. 24, 2012, 8:33 a.m. UTC | #3
On 24 January 2012 07:59, Andreas Färber <afaerber@suse.de> wrote:
> Am 13.01.2012 21:52, schrieb Peter Maydell:
>> @@ -433,6 +433,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
>>  #define ARM_CPUID_CORTEXA8    0x410fc080
>>  #define ARM_CPUID_CORTEXA9    0x410fc090
>>  #define ARM_CPUID_CORTEXM3    0x410fc231
>> +#define ARM_CPUID_CORTEXA15   0x412fc0f1
>
> Reminder of our rnpn topic...

Yeah. I have a cp15-rework series brewing that might assist here.

> We don't seem to have a clear ordering system but I'd suggest to move
> A15 one line up, to group the As and Ms in ascending order respectively.

Good idea.

>> @@ -413,6 +444,7 @@ static const struct arm_cpu_t arm_cpu_names[] = {
>>      { ARM_CPUID_CORTEXM3, "cortex-m3"},
>>      { ARM_CPUID_CORTEXA8, "cortex-a8"},
>>      { ARM_CPUID_CORTEXA9, "cortex-a9"},
>> +    { ARM_CPUID_CORTEXA15, "cortex-a15"},
>
> Space please.

OK. (I just copy-pasted the a9 line, as you've probably guessed.)

>> +                case 2:
>> +                    /* L2 cache auxiliary control (A8) or control (A15) */
>> +                    if (ARM_CPUID(env) == ARM_CPUID_CORTEXA15) {
>
> Change of mind? You opposed uses of ARM_CPUID() for Cortex-R4F.

I kind of view this as a small interim bodge. My aim with my
cp15 rework is that instead of all these switches we will
just set up the cp15 registers for the CPU at cpu_init
time, so A15 will set up one thing, A8 something else and
A9 et al set up nothing at all [and so get the default UNDEF
behaviour].

If you can fish the particular mail of mine you have in mind
out of the archives I can reread it and see if I disagree
with myself :-)

-- PMM
diff mbox

Patch

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index d5403ea..4b8d680 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -433,6 +433,7 @@  void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
 #define ARM_CPUID_CORTEXA8    0x410fc080
 #define ARM_CPUID_CORTEXA9    0x410fc090
 #define ARM_CPUID_CORTEXM3    0x410fc231
+#define ARM_CPUID_CORTEXA15   0x412fc0f1
 #define ARM_CPUID_ANY         0xffffffff
 
 #if defined(CONFIG_USER_ONLY)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index de4a50f..a68dc5c 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -10,6 +10,16 @@ 
 #if !defined(CONFIG_USER_ONLY)
 #include "hw/loader.h"
 #endif
+#include "sysemu.h"
+
+static uint32_t cortexa15_cp15_c0_c1[8] = {
+    0x00001131, 0x00011011, 0x02010555, 0x00000000,
+    0x10201105, 0x20000000, 0x01240000, 0x02102211
+};
+
+static uint32_t cortexa15_cp15_c0_c2[8] = {
+    0x02101110, 0x13112111, 0x21232041, 0x11112131, 0x10011142, 0, 0, 0
+};
 
 static uint32_t cortexa9_cp15_c0_c1[8] =
 { 0x1031, 0x11, 0x000, 0, 0x00100103, 0x20000000, 0x01230000, 0x00002111 };
@@ -158,6 +168,27 @@  static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
         env->cp15.c0_ccsid[1] = 0x200fe015; /* 16k L1 icache. */
         env->cp15.c1_sys = 0x00c50078;
         break;
+    case ARM_CPUID_CORTEXA15:
+        set_feature(env, ARM_FEATURE_V7);
+        set_feature(env, ARM_FEATURE_VFP4);
+        set_feature(env, ARM_FEATURE_VFP_FP16);
+        set_feature(env, ARM_FEATURE_NEON);
+        set_feature(env, ARM_FEATURE_THUMB2EE);
+        set_feature(env, ARM_FEATURE_ARM_DIV);
+        set_feature(env, ARM_FEATURE_V7MP);
+        set_feature(env, ARM_FEATURE_GENERICTIMER);
+        env->vfp.xregs[ARM_VFP_FPSID] = 0x410430f0;
+        env->vfp.xregs[ARM_VFP_MVFR0] = 0x10110222;
+        env->vfp.xregs[ARM_VFP_MVFR1] = 0x11111111;
+        memcpy(env->cp15.c0_c1, cortexa15_cp15_c0_c1, 8 * sizeof(uint32_t));
+        memcpy(env->cp15.c0_c2, cortexa15_cp15_c0_c2, 8 * sizeof(uint32_t));
+        env->cp15.c0_cachetype = 0x8444c004;
+        env->cp15.c0_clid = 0x0a200023;
+        env->cp15.c0_ccsid[0] = 0x701fe00a; /* 32K L1 dcache */
+        env->cp15.c0_ccsid[1] = 0x201fe00a; /* 32K L1 icache */
+        env->cp15.c0_ccsid[2] = 0x711fe07a; /* 4096K L2 unified cache */
+        env->cp15.c1_sys = 0x00c50078;
+        break;
     case ARM_CPUID_CORTEXM3:
         set_feature(env, ARM_FEATURE_V7);
         set_feature(env, ARM_FEATURE_M);
@@ -413,6 +444,7 @@  static const struct arm_cpu_t arm_cpu_names[] = {
     { ARM_CPUID_CORTEXM3, "cortex-m3"},
     { ARM_CPUID_CORTEXA8, "cortex-a8"},
     { ARM_CPUID_CORTEXA9, "cortex-a9"},
+    { ARM_CPUID_CORTEXA15, "cortex-a15"},
     { ARM_CPUID_TI925T, "ti925t" },
     { ARM_CPUID_PXA250, "pxa250" },
     { ARM_CPUID_SA1100,    "sa1100" },
@@ -667,8 +699,6 @@  uint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
 
 #else
 
-extern int semihosting_enabled;
-
 /* Map CPU modes onto saved register banks.  */
 static inline int bank_number(CPUState *env, int mode)
 {
@@ -1934,6 +1964,7 @@  uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
             case ARM_CPUID_CORTEXA8:
                 return 2;
             case ARM_CPUID_CORTEXA9:
+            case ARM_CPUID_CORTEXA15:
                 return 0;
             default:
                 goto bad_reg;
@@ -2054,11 +2085,26 @@  uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
                     goto bad_reg;
                 }
             case 1: /* L2 cache */
-                if (crm != 0) {
+                /* L2 Lockdown and Auxiliary control.  */
+                switch (op2) {
+                case 0:
+                    /* L2 cache lockdown (A8 only) */
+                    return 0;
+                case 2:
+                    /* L2 cache auxiliary control (A8) or control (A15) */
+                    if (ARM_CPUID(env) == ARM_CPUID_CORTEXA15) {
+                        /* Linux wants the number of processors from here.
+                         * Might as well set the interrupt-controller bit too.
+                         */
+                        return ((smp_cpus - 1) << 24) | (1 << 23);
+                    }
+                    return 0;
+                case 3:
+                    /* L2 cache extended control (A15) */
+                    return 0;
+                default:
                     goto bad_reg;
                 }
-                /* L2 Lockdown and Auxiliary control.  */
-                return 0;
             default:
                 goto bad_reg;
             }