linux-omap2 git: enhance /proc/cpuinfo cache info. RMK doesn't like it, but who cares?
authorKoen Kooi <koen@openembedded.org>
Fri, 11 Jul 2008 18:00:30 +0000 (18:00 +0000)
committerKoen Kooi <koen@openembedded.org>
Fri, 11 Jul 2008 18:00:30 +0000 (18:00 +0000)
packages/linux/linux-omap2-git/beagleboard/cache-display-fix.patch [new file with mode: 0644]
packages/linux/linux-omap2_git.bb

diff --git a/packages/linux/linux-omap2-git/beagleboard/cache-display-fix.patch b/packages/linux/linux-omap2-git/beagleboard/cache-display-fix.patch
new file mode 100644 (file)
index 0000000..c96b95f
--- /dev/null
@@ -0,0 +1,238 @@
+On Tue, 2008-07-01 at 06:23 +0100, Dirk Behme wrote:
+> Catalin Marinas wrote:
+> > But, anyway, if you want a patch, Harry is updating it to a recent
+> > kernel.
+> 
+> Any news on this? I think there are some people wanting a patch ;)
+
+See below for a preliminary patch updated to 2.6.26-rc8. Note that I
+don't plan to submit it in its current form but clean it up a bit first.
+
+
+Show the cache type of ARMv7 CPUs
+
+From: Catalin Marinas <catalin.marinas@arm.com>
+
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+---
+
+ arch/arm/kernel/setup.c  |  137 +++++++++++++++++++++++++++++++++++++++++++++-
+ include/asm-arm/system.h |   18 ++++++
+ 2 files changed, 153 insertions(+), 2 deletions(-)
+
+
+diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
+index 5ae0eb2..0cd238d 100644
+--- a/arch/arm/kernel/setup.c
++++ b/arch/arm/kernel/setup.c
+@@ -256,6 +256,24 @@ static const char *proc_arch[] = {
+       "?(17)",
+ };
++static const char *v7_cache_policy[4] = {
++      "reserved",
++      "AVIVT",
++      "VIPT",
++      "PIPT",
++};
++
++static const char *v7_cache_type[8] = {
++      "none",
++      "instruction only",
++      "data only",
++      "separate instruction and data",
++      "unified",
++      "unknown type",
++      "unknown type",
++      "unknown type",
++};
++
+ #define CACHE_TYPE(x) (((x) >> 25) & 15)
+ #define CACHE_S(x)    ((x) & (1 << 24))
+ #define CACHE_DSIZE(x)        (((x) >> 12) & 4095)    /* only if S=1 */
+@@ -266,6 +284,22 @@ static const char *proc_arch[] = {
+ #define CACHE_M(y)    ((y) & (1 << 2))
+ #define CACHE_LINE(y) ((y) & 3)
++#define CACHE_TYPE_V7(x)      (((x) >> 14) & 3)
++#define CACHE_UNIFIED(x)      ((((x) >> 27) & 7)+1)
++#define CACHE_COHERENT(x)     ((((x) >> 24) & 7)+1)
++
++#define CACHE_ID_LEVEL_MASK   7
++#define CACHE_ID_LEVEL_BITS   3
++
++#define CACHE_LINE_V7(v)      ((1 << (((v) & 7)+4)))
++#define CACHE_ASSOC_V7(v)     ((((v) >> 3) & ((1<<10)-1))+1)
++#define CACHE_SETS_V7(v)      ((((v) >> 13) & ((1<<15)-1))+1)
++#define CACHE_SIZE_V7(v)      (CACHE_LINE_V7(v)*CACHE_ASSOC_V7(v)*CACHE_SETS_V7(v))
++#define CACHE_WA_V7(v)                (((v) & (1<<28)) != 0)
++#define CACHE_RA_V7(v)                (((v) & (1<<29)) != 0)
++#define CACHE_WB_V7(v)                (((v) & (1<<30)) != 0)
++#define CACHE_WT_V7(v)                (((v) & (1<<31)) != 0)
++
+ static inline void dump_cache(const char *prefix, int cpu, unsigned int cache)
+ {
+       unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0);
+@@ -279,11 +313,57 @@ static inline void dump_cache(const char *prefix, int cpu, unsigned int cache)
+                       CACHE_LINE(cache)));
+ }
++static void dump_v7_cache(const char *type, int cpu, unsigned int level)
++{
++      unsigned int cachesize;
++                    
++      write_extended_cpuid(2,0,0,0,level);  /* Set the cache size selection register */
++      write_extended_cpuid(0,7,5,4,0);      /* Prefetch flush to wait for above */
++      cachesize = read_extended_cpuid(1,0,0,0);
++
++      printk("CPU%u: %s cache: %d bytes, associativity %d, %d byte lines, %d sets,\n      supports%s%s%s%s\n",
++             cpu, type,
++             CACHE_SIZE_V7(cachesize),CACHE_ASSOC_V7(cachesize),
++             CACHE_LINE_V7(cachesize),CACHE_SETS_V7(cachesize),
++             CACHE_WA_V7(cachesize) ? " WA" : "",
++             CACHE_RA_V7(cachesize) ? " RA" : "",
++             CACHE_WB_V7(cachesize) ? " WB" : "",
++             CACHE_WT_V7(cachesize) ? " WT" : "");
++}
++
+ static void __init dump_cpu_info(int cpu)
+ {
+       unsigned int info = read_cpuid(CPUID_CACHETYPE);
+-      if (info != processor_id) {
++      if (info != processor_id && (info & (1 << 31))) {
++              /* ARMv7 style of cache info register */
++              unsigned int id = read_extended_cpuid(1,0,0,1);
++              unsigned int level = 0;
++              printk("CPU%u: L1 I %s cache. Caches unified at level %u, coherent at level %u\n",
++                     cpu,
++                     v7_cache_policy[CACHE_TYPE_V7(info)],
++                     CACHE_UNIFIED(id),
++                     CACHE_COHERENT(id));
++
++              while (id & CACHE_ID_LEVEL_MASK) {
++                      printk("CPU%u: Level %u cache is %s\n",
++                             cpu, (level >> 1)+1, v7_cache_type[id & CACHE_ID_LEVEL_MASK]);
++
++                      if (id & 1) {
++                              /* Dump I at this level */
++                              dump_v7_cache("I", cpu, level | 1);
++                      }
++
++                      if (id & (4 | 2)) {
++                              /* Dump D or unified at this level */
++                              dump_v7_cache((id & 4) ? "unified" : "D", cpu, level);
++                      }
++
++                      /* Next level out */
++                      level += 2;
++                      id >>= CACHE_ID_LEVEL_BITS;
++              }
++      } else if (info != processor_id) {
+               printk("CPU%u: D %s %s cache\n", cpu, cache_is_vivt() ? "VIVT" : "VIPT",
+                      cache_types[CACHE_TYPE(info)]);
+               if (CACHE_S(info)) {
+@@ -916,6 +996,30 @@ c_show_cache(struct seq_file *m, const char *type, unsigned int cache)
+                           CACHE_LINE(cache)));
+ }
++static void c_show_v7_cache(struct seq_file *m, const char *type, unsigned int levelselect)
++{
++      unsigned int cachesize;
++      unsigned int level = (levelselect >> 1) + 1;
++                    
++      write_extended_cpuid(2,0,0,0,levelselect);  /* Set the cache size selection register */
++      write_extended_cpuid(0,7,5,4,0);      /* Prefetch flush to wait for above */
++      cachesize = read_extended_cpuid(1,0,0,0);
++
++      seq_printf(m, "L%u %s size\t\t: %d bytes\n"
++                 "L%u %s assoc\t\t: %d\n"
++                 "L%u %s line length\t: %d\n"
++                 "L%u %s sets\t\t: %d\n"
++                 "L%u %s supports\t\t:%s%s%s%s\n",
++                 level, type, CACHE_SIZE_V7(cachesize),
++                 level, type, CACHE_ASSOC_V7(cachesize),
++                 level, type, CACHE_LINE_V7(cachesize),
++                 level, type, CACHE_SETS_V7(cachesize),
++                 level, type, CACHE_WA_V7(cachesize) ? " WA" : "",
++                 CACHE_RA_V7(cachesize) ? " RA" : "",
++                 CACHE_WB_V7(cachesize) ? " WB" : "",
++                 CACHE_WT_V7(cachesize) ? " WT" : "");
++}
++
+ static int c_show(struct seq_file *m, void *v)
+ {
+       int i;
+@@ -971,7 +1075,36 @@ static int c_show(struct seq_file *m, void *v)
+       {
+               unsigned int cache_info = read_cpuid(CPUID_CACHETYPE);
+-              if (cache_info != processor_id) {
++              if (cache_info != processor_id && (cache_info & (1<<31))) {
++                      /* V7 style of cache info register */
++                      unsigned int id = read_extended_cpuid(1,0,0,1);
++                      unsigned int levelselect = 0;
++                      seq_printf(m, "L1 I cache\t:%s\n"
++                                 "Cache unification level\t: %u\n"
++                                 "Cache coherency level\t: %u\n",
++                                 v7_cache_policy[CACHE_TYPE_V7(cache_info)],
++                                 CACHE_UNIFIED(id),
++                                 CACHE_COHERENT(id));
++
++                      while (id & CACHE_ID_LEVEL_MASK) {
++                              seq_printf(m, "Level %u cache\t\t: %s\n",
++                                         (levelselect >> 1)+1, v7_cache_type[id & CACHE_ID_LEVEL_MASK]);
++
++                              if (id & 1) {
++                                      /* Dump I at this level */
++                                      c_show_v7_cache(m, "I", levelselect | 1);
++                              }
++
++                              if (id & (4 | 2)) {
++                                      /* Dump D or unified at this level */
++                                      c_show_v7_cache(m, (id & 4) ? "cache" : "D", levelselect);
++                              }
++
++                              /* Next level out */
++                              levelselect += 2;
++                              id >>= CACHE_ID_LEVEL_BITS;
++                      }
++              } else if (cache_info != processor_id) {
+                       seq_printf(m, "Cache type\t: %s\n"
+                                     "Cache clean\t: %s\n"
+                                     "Cache lockdown\t: %s\n"
+diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
+index 514af79..704738e 100644
+--- a/include/asm-arm/system.h
++++ b/include/asm-arm/system.h
+@@ -74,6 +74,24 @@
+                   : "cc");                                            \
+               __val;                                                  \
+       })
++#define read_extended_cpuid(op1,op2,op3,op4)          \
++      ({                                                              \
++              unsigned int __val;                                     \
++              asm("mrc p15," __stringify(op1) ",%0,c" __stringify(op2)",c" __stringify(op3)"," __stringify(op4)       \
++                  : "=r" (__val)                                      \
++                  :                                                   \
++                  : "cc");                                            \
++              __val;                                                  \
++      })
++
++#define write_extended_cpuid(op1,op2,op3,op4,v)               \
++      ({                                                              \
++              unsigned int __val = v;                                 \
++              asm("mcr p15," __stringify(op1) ",%0,c" __stringify(op2)",c" __stringify(op3)"," __stringify(op4)       \
++                  :                                                   \
++                  : "r" (__val)                                       \
++                  : "cc");                                            \
++      })
+ #else
+ extern unsigned int processor_id;
+ #define read_cpuid(reg) (processor_id)
+
+
+-- 
+Catalin
+
+
index 0b3155a..69d3415 100644 (file)
@@ -5,7 +5,7 @@ FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/linux-omap2-git/${MA
 SRCREV = "7786cd7a00ae0b18923185789380a88052f4eee7"
 
 PV = "2.6.25+2.6.26-rc9+${PR}+git${SRCREV}"
-PR = "r42"
+PR = "r43"
 
 SRC_URI = "git://source.mvista.com/git/linux-omap-2.6.git;protocol=git \
           file://defconfig"
@@ -28,6 +28,7 @@ SRC_URI_append_beagleboard = " file://no-harry-potter.diff;patch=1 \
            file://05-fix-display-panning.diff;patch=1 \
            file://06-ensure-fclk.diff;patch=1 \
            file://07-set-burst-size.diff;patch=1 \
+           file://cache-display-fix.patch;patch=1 \
 "
 
 SRC_URI_append_omap3evm = " file://no-harry-potter.diff;patch=1 \