]> rtime.felk.cvut.cz Git - l4.git/blobdiff - kernel/fiasco/src/kern/arm/perf_cnt-arm.cpp
update
[l4.git] / kernel / fiasco / src / kern / arm / perf_cnt-arm.cpp
index f6e2396fbaa668e901579d9ad0cb5cce883ff4bc..c18280f02fb22ca0dbe49ff0d63db635011e845a 100644 (file)
@@ -32,10 +32,10 @@ EXTENSION class Perf_cnt
 {
 private:
   enum {
-    CPU_CONTROL = Mem_layout::Mp_scu_map_base + 0x00,
-    CONFIG      = Mem_layout::Mp_scu_map_base + 0x04,
-    CPU_STATUS  = Mem_layout::Mp_scu_map_base + 0x08,
-    MON_CONTROL = Mem_layout::Mp_scu_map_base + 0x10,
+    CPU_CONTROL = 0x00,
+    CONFIG      = 0x04,
+    CPU_STATUS  = 0x08,
+    MON_CONTROL = 0x10,
 
     MON_CONTROL_ENABLE = 1,
     MON_CONTROL_RESET  = 2,
@@ -74,10 +74,10 @@ private:
   };
 
   static Address mon_event_type_addr(int nr)
-  { return Mem_layout::Mp_scu_map_base + 0x14 + nr; }
+  { return 0x14 + nr; }
 
   static Address mon_counter(int nr)
-  { return Mem_layout::Mp_scu_map_base + 0x1c + nr * 4; }
+  { return 0x1c + nr * 4; }
 };
 
 // ------------------------------------------------------------------------
@@ -86,10 +86,10 @@ INTERFACE [arm && perf_cnt && (armca8 || armca9)]:
 EXTENSION class Perf_cnt
 {
 private:
-  static void pmnc(Mword val)
+  static void pmcr(Mword val)
   { asm volatile ("mcr p15, 0, %0, c9, c12, 0" : : "r" (val)); }
 
-  static Mword pmnc()
+  static Mword pmcr()
   { Mword val; asm volatile ("mrc p15, 0, %0, c9, c12, 0" : "=r" (val)); return val;}
 
 
@@ -209,7 +209,7 @@ Perf_cnt::init_cpu()
 {}
 
 PUBLIC static inline
-Mword
+Unsigned64
 Perf_cnt::read_cycle_cnt()
 { return 0; }
 
@@ -231,27 +231,29 @@ Perf_cnt::set_event_type(int, int)
 // ------------------------------------------------------------------------
 IMPLEMENTATION [arm && perf_cnt && mpcore]:
 
-#include "io.h"
+#include "cpu.h"
 
 char const *Perf_cnt::perf_type_str = "MP-C";
 
 PRIVATE static
 void
 Perf_cnt::set_event_type(int counter_nr, int event)
-{ Io::write<unsigned char>(event, mon_event_type_addr(counter_nr)); }
+{ Cpu::scu->write<unsigned char>(event, mon_event_type_addr(counter_nr)); }
 
 PUBLIC static
 unsigned long
 Perf_cnt::read_counter(int counter_nr)
-{ return Io::read<Mword>(mon_counter(counter_nr)); }
+{ return Cpu::scu->read<Mword>(mon_counter(counter_nr)); }
 
 PUBLIC static FIASCO_INIT_CPU
 void
 Perf_cnt::init_cpu()
 {
-  Io::write<Mword>(0xff << 16 // clear overflow flags
-                   | MON_CONTROL_RESET | MON_CONTROL_ENABLE,
-                   MON_CONTROL);
+  static_assert(Scu::Available, "No SCU available in this configuration");
+
+  Cpu::scu->write<Mword>(0xff << 16 // clear overflow flags
+                        | MON_CONTROL_RESET | MON_CONTROL_ENABLE,
+                        MON_CONTROL);
 
   // static config for now...
   set_event_type(7, EVENT_CYCLE_COUNT);
@@ -274,33 +276,52 @@ Perf_cnt::init_cpu()
 }
 
 PUBLIC static
-Mword
+Unsigned64
 Perf_cnt::read_cycle_cnt()
 { return read_counter(7); }
 
 PUBLIC static
 unsigned
 Perf_cnt::mon_event_type(int nr)
-{ return Io::read<unsigned char>(mon_event_type_addr(nr)); }
+{ return Cpu::scu->read<unsigned char>(mon_event_type_addr(nr)); }
 
 // ------------------------------------------------------------------------
 IMPLEMENTATION [arm && perf_cnt && (armca8 || armca9)]:
 
+#include "cpu.h"
+
 char const *Perf_cnt::perf_type_str = "ACor";
 int Perf_cnt::_nr_counters;
 
+PRIVATE static
+bool
+Perf_cnt::is_avail()
+{
+  switch (Cpu::boot_cpu()->copro_dbg_model())
+    {
+      case Cpu::Copro_dbg_model_v7:
+      case Cpu::Copro_dbg_model_v7_1: return true;
+      default: return false;
+    }
+}
+
 PRIVATE static
 void
 Perf_cnt::set_event_type(int counter_nr, int event)
 {
+  if (!is_avail())
+    return;
+
   pmnxsel(counter_nr);
   evtsel(event);
 }
 
 PUBLIC static
-Mword
+Unsigned64
 Perf_cnt::read_cycle_cnt()
 {
+  if (!is_avail())
+    return 0;
   return ccnt();
 }
 
@@ -308,17 +329,21 @@ PUBLIC static
 unsigned long
 Perf_cnt::read_counter(int counter_nr)
 {
+  if (!is_avail())
+    return 0;
   if (counter_nr >= _nr_counters)
     return ccnt();
   pmnxsel(counter_nr);
   return pmcnt();
 }
 
-
 PUBLIC static
 unsigned
 Perf_cnt::mon_event_type(int nr)
 {
+  if (!is_avail())
+    return 0;
+
   if (nr >= _nr_counters)
     return 0xff;
   pmnxsel(nr);
@@ -329,9 +354,12 @@ PUBLIC static FIASCO_INIT_CPU
 void
 Perf_cnt::init_cpu()
 {
-  _nr_counters = (pmnc() >> 11) & 0x1f;
+  if (!is_avail())
+    return;
 
-  pmnc(PMNC_ENABLE | PMNC_PERF_RESET | PMNC_CNT_RESET);
+  _nr_counters = (pmcr() >> 11) & 0x1f;
+
+  pmcr(PMNC_ENABLE | PMNC_PERF_RESET | PMNC_CNT_RESET);
 
   cntens((1 << 31) | ((1 << _nr_counters) - 1));
 
@@ -341,8 +369,6 @@ Perf_cnt::init_cpu()
   useren(1);
 }
 
-
-
 // ------------------------------------------------------------------------
 IMPLEMENTATION [arm && perf_cnt]:
 
@@ -392,7 +418,7 @@ Perf_cnt::get_perf_event(Mword nr, unsigned *evntsel,
   _name[sizeof(_name) - 1] = 0;
 
   snprintf(_desc, sizeof(_desc), "Check manual for description of event %lx", nr);
-  _name[sizeof(_desc) - 1] = 0;
+  _desc[sizeof(_desc) - 1] = 0;
 
   *name = (const char *)&_name;
   *desc = (const char *)&_desc;
@@ -437,7 +463,8 @@ Perf_cnt::init()
   Tb_entry::set_cycle_read_func(read_cycle_cnt);
 }
 
-PUBLIC static inline void
+PUBLIC static inline FIASCO_INIT_CPU
+void
 Perf_cnt::init_ap()
 {
   init_cpu();