]> rtime.felk.cvut.cz Git - l4.git/blobdiff - kernel/fiasco/src/kern/arm/cpu-arm.cpp
update
[l4.git] / kernel / fiasco / src / kern / arm / cpu-arm.cpp
index a6b5b0dc441f606e9ff42340c908567ab22bb216..c9b83d341d826a9410fd8b3bc6a91d1a84d0b0ba 100644 (file)
@@ -29,12 +29,29 @@ public:
 
   Cpu(unsigned id) { set_id(id); }
 
+
+  struct Ids {
+    Mword _pfr[2], _dfr0, _afr0, _mmfr[4];
+  };
+  void id_init();
+
+  enum {
+    Copro_dbg_model_not_supported = 0,
+    Copro_dbg_model_v6            = 2,
+    Copro_dbg_model_v6_1          = 3,
+    Copro_dbg_model_v7            = 4,
+  };
+
+  unsigned copro_dbg_model() const { return _cpu_id._dfr0 & 0xf; }
+
 private:
   static Cpu *_boot_cpu;
 
   unsigned _phys_id;
+  Ids _cpu_id;
 };
 
+// ------------------------------------------------------------------------
 INTERFACE [arm && armv5]:
 
 EXTENSION class Cpu
@@ -91,8 +108,6 @@ public:
 
     Cp15_c1_cache_bits      = Cp15_c1_cache
                               | Cp15_c1_insn_cache,
-
-    Smp_enable              = 0x20,
   };
 };
 
@@ -104,9 +119,8 @@ public:
   enum {
     Cp15_c1_ee              = 1 << 25,
     Cp15_c1_nmfi            = 1 << 27,
-    Cp15_c1_tre             = 1 << 28,
-    Cp15_c1_afe             = 1 << 29,
     Cp15_c1_te              = 1 << 30,
+    Cp15_c1_rao_sbop        = (0xf << 3) | (1 << 16) | (1 << 18) | (1 << 22) | (1 << 23),
 
     Cp15_c1_cache_bits      = Cp15_c1_cache
                               | Cp15_c1_insn_cache,
@@ -114,6 +128,7 @@ public:
     Cp15_c1_generic         = Cp15_c1_mmu
                               | (Config::Cp15_c1_use_alignment_check ?  Cp15_c1_alignment_check : 0)
                              | Cp15_c1_branch_predict
+                              | Cp15_c1_rao_sbop
                              | Cp15_c1_high_vector,
   };
 };
@@ -128,9 +143,8 @@ public:
     Cp15_c1_ha              = 1 << 17,
     Cp15_c1_ee              = 1 << 25,
     Cp15_c1_nmfi            = 1 << 27,
-    Cp15_c1_tre             = 1 << 28,
-    Cp15_c1_afe             = 1 << 29,
     Cp15_c1_te              = 1 << 30,
+    Cp15_c1_rao_sbop        = (0xf << 3) | (1 << 16) | (1 << 18) | (1 << 22) | (1 << 23),
 
     Cp15_c1_cache_bits      = Cp15_c1_cache
                               | Cp15_c1_insn_cache,
@@ -139,9 +153,8 @@ public:
                               | (Config::Cp15_c1_use_alignment_check ?  Cp15_c1_alignment_check : 0)
                              | Cp15_c1_branch_predict
                              | Cp15_c1_high_vector
+                              | Cp15_c1_rao_sbop
                              | (Config::Cp15_c1_use_a9_swp_enable ?  Cp15_c1_sw : 0),
-
-    Smp_enable              = 0x41,
   };
 };
 
@@ -156,14 +169,52 @@ public:
   };
 };
 
+//---------------------------------------------------------------------------
+IMPLEMENTATION [arm && armv6]:
+
+PRIVATE static inline void
+Cpu::enable_smp()
+{
+  asm volatile ("mrc p15, 0, %0, c1, c0, 1   \n"
+                "orr %0, %1                  \n"
+                "mcr p15, 0, %0, c1, c0, 1   \n"
+                : : "r" (0), "i" (0x20));
+}
+
+//---------------------------------------------------------------------------
+IMPLEMENTATION [arm && armv7]:
+
+PRIVATE static inline void
+Cpu::enable_smp()
+{
+  Mword midr;
+  asm volatile ("mrc p15, 0, %0, c0, c0, 0" : "=r" (midr));
+
+  // ACTRL is implementation defined
+  if ((midr & 0xff0ffff0) != 0x410fc090)
+    return;
+
+  Mword actrl;
+  asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (actrl));
+  if (!(actrl & 0x40))
+    asm volatile ("mcr p15, 0, %0, c1, c0, 1" : : "r" (actrl | 0x41));
+}
+
 //---------------------------------------------------------------------------
 IMPLEMENTATION [arm && (mpcore || armca9)]:
 
-PUBLIC static inline void
+PRIVATE static inline void
 Cpu::early_init_platform()
 {
-  Io::write<Mword>(0xffffffff, Mem_layout::Mp_scu_map_base + 0xc);
-  Io::write<Mword>(1,          Mem_layout::Mp_scu_map_base + 0);
+  enum {
+    Scu_control      = Mem_layout::Mp_scu_map_base + 0x0,
+    Scu_config       = Mem_layout::Mp_scu_map_base + 0x4,
+    Scu_power_status = Mem_layout::Mp_scu_map_base + 0x8,
+    Scu_inv          = Mem_layout::Mp_scu_map_base + 0xc,
+  };
+
+  Io::write<Mword>(0xffffffff, Scu_inv);
+  Io::write<Mword>(Io::read<Mword>(Scu_control) | 1, Scu_control);
 
   Io::write<Mword>(Io::read<Mword>(Mem_layout::Gic_cpu_map_base + 0) | 1,
                    Mem_layout::Gic_cpu_map_base + 0);
@@ -172,17 +223,13 @@ Cpu::early_init_platform()
 
   Mem_unit::clean_dcache();
 
-  Mword tmp = 0;
-  __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1   \n"
-                       "orr %0, %1                  \n"
-                       "mcr p15, 0, %0, c1, c0, 1   \n"
-                       : : "r" (tmp), "i" (Smp_enable));
+  enable_smp();
 }
 
 //---------------------------------------------------------------------------
 IMPLEMENTATION [arm && !(mpcore || armca9)]:
 
-PUBLIC static inline void Cpu::early_init_platform()
+PRIVATE static inline void Cpu::early_init_platform()
 {}
 
 //---------------------------------------------------------------------------
@@ -228,8 +275,6 @@ void Cpu::early_init()
   early_init_platform();
 
   Mem_unit::flush_cache();
-
-  print_infos();
 }
 
 
@@ -306,6 +351,36 @@ Cpu::init(bool is_boot_cpu)
   _phys_id = Proc::cpu_id();
 
   init_tz();
+
+  id_init();
+
+  print_infos();
+}
+
+//---------------------------------------------------------------------------
+IMPLEMENTATION [arm && !armv6plus]:
+
+IMPLEMENT
+void
+Cpu::id_init()
+{
+}
+
+//---------------------------------------------------------------------------
+IMPLEMENTATION [arm && armv6plus]:
+
+IMPLEMENT
+void
+Cpu::id_init()
+{
+  __asm__("mrc p15, 0, %0, c0, c1, 0": "=r" (_cpu_id._pfr[0]));
+  __asm__("mrc p15, 0, %0, c0, c1, 1": "=r" (_cpu_id._pfr[1]));
+  __asm__("mrc p15, 0, %0, c0, c1, 2": "=r" (_cpu_id._dfr0));
+  __asm__("mrc p15, 0, %0, c0, c1, 3": "=r" (_cpu_id._afr0));
+  __asm__("mrc p15, 0, %0, c0, c1, 4": "=r" (_cpu_id._mmfr[0]));
+  __asm__("mrc p15, 0, %0, c0, c1, 5": "=r" (_cpu_id._mmfr[1]));
+  __asm__("mrc p15, 0, %0, c0, c1, 6": "=r" (_cpu_id._mmfr[2]));
+  __asm__("mrc p15, 0, %0, c0, c1, 7": "=r" (_cpu_id._mmfr[3]));
 }
 
 //---------------------------------------------------------------------------
@@ -339,9 +414,9 @@ Cpu::init_tz()
 
   // enable nonsecure access to vfp coprocessor
   asm volatile("mov r0, #0xc00;"
-               "mcr p15, 0, r0, c1, c1, 2;"
-               : : : "r0"
-               );
+               "mcr p15, 0, r0, c1, c1, 2;"
+               : : : "r0"
+              );
 
   enable_irq_ovrr();
 }
@@ -353,23 +428,23 @@ Cpu::tz_switch_to_ns(Mword *nonsecure_state)
   volatile register Mword r0 asm("r0") = (Mword)nonsecure_state;
   extern char go_nonsecure;
 
-  asm volatile(        "stmdb sp!, {fp}        \n"
-               "stmdb sp!, {r0}        \n"
-               "mov    r2, sp          \n" // copy sp_svc to sp_mon
-               "cps    #0x16           \n" // switch to monitor mode
-               "mov    sp, r2          \n"
-               "adr    r3, 1f          \n" // save return eip
-               "mrs    r4, cpsr        \n" // save return psr
-               "mov    pc, r1          \n" // go nonsecure!
-               "1:                     \n"
-               "mov    r0, sp          \n" // copy sp_mon to sp_svc
-               "cps    #0x13           \n" // switch to svc mode
-               "mov    sp, r0          \n"
-               "ldmia  sp!, {r0}       \n"
-               "ldmia  sp!, {fp}       \n"
-               : : "r" (r0), "r" (&go_nonsecure)
-               : "r2", "r3", "r4", "r5", "r6", "r7",
-                         "r8", "r9", "r10", "r12", "r14", "memory");
+  asm volatile("stmdb sp!, {fp}   \n"
+               "stmdb sp!, {r0}   \n"
+               "mov    r2, sp     \n" // copy sp_svc to sp_mon
+               "cps    #0x16      \n" // switch to monitor mode
+               "mov    sp, r2     \n"
+               "adr    r3, 1f     \n" // save return eip
+               "mrs    r4, cpsr   \n" // save return psr
+               "mov    pc, r1     \n" // go nonsecure!
+               "1:                \n"
+               "mov    r0, sp     \n" // copy sp_mon to sp_svc
+               "cps    #0x13      \n" // switch to svc mode
+               "mov    sp, r0     \n"
+               "ldmia  sp!, {r0}  \n"
+               "ldmia  sp!, {fp}  \n"
+               : : "r" (r0), "r" (&go_nonsecure)
+               : "r2", "r3", "r4", "r5", "r6", "r7",
+                 "r8", "r9", "r10", "r12", "r14", "memory");
 }
 
 PUBLIC static inline
@@ -412,9 +487,9 @@ void
 Cpu::enable_irq_ovrr()
 {
   // set IRQ/FIQ/Abort override bits
-  asm volatile("mov r0, #0x1c0;            \n"
-              "mcr p15, 0, r0, c1, c1, 3; \n"
-               : : : "r0");
+  asm volatile("mov r0, #0x1c0            \n"
+               "mcr p15, 0, r0, c1, c1, 3 \n"
+               : : : "r0");
 }
 
 IMPLEMENTATION [!tz || !armca9]:
@@ -432,12 +507,39 @@ void
 Cpu::print_infos()
 {}
 
+// ------------------------------------------------------------------------
+IMPLEMENTATION [debug && armv6plus]:
+
+PRIVATE
+void
+Cpu::id_print_infos()
+{
+  printf("ID_PFR0:  %08lx\n", _cpu_id._pfr[0]);
+  printf("ID_PFR1:  %08lx\n", _cpu_id._pfr[1]);
+  printf("ID_DFR0:  %08lx\n", _cpu_id._dfr0);
+  printf("ID_AFR0:  %08lx\n", _cpu_id._afr0);
+  printf("ID_MMFR0: %08lx\n", _cpu_id._mmfr[0]);
+  printf("ID_MMFR1: %08lx\n", _cpu_id._mmfr[1]);
+  printf("ID_MMFR2: %08lx\n", _cpu_id._mmfr[2]);
+  printf("ID_MMFR3: %08lx\n", _cpu_id._mmfr[3]);
+}
+
+// ------------------------------------------------------------------------
+IMPLEMENTATION [debug && !armv6plus]:
+
+PRIVATE
+void
+Cpu::id_print_infos()
+{
+}
+
 // ------------------------------------------------------------------------
 IMPLEMENTATION [debug]:
 
-PRIVATE static
+PRIVATE
 void
 Cpu::print_infos()
 {
   printf("Cache config: %s\n", Config::cache_enabled ? "ON" : "OFF");
+  id_print_infos();
 }