aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2007-12-10 01:50:28 -0500
committerPaul Mundt <lethal@linux-sh.org>2008-01-27 23:18:59 -0500
commitcd01204b82933754a7276838656420477f64d4b8 (patch)
treef9e3b11574bec04cda78c549cdc5c37c3c75c4a5
parentc8c0a1aba9fa8f816dc8fb477ff816a5b700f0ea (diff)
sh: Encode L1/L2 cache shape in auxvt.
This adds in the L1I/L1D/L2 cache shape support to their respective entries in the ELF auxvt, based on the Alpha implementation. We use this on the userspace libc side for calculating a tightly packed SHMLBA amongst other things. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/sh/kernel/cpu/init.c29
-rw-r--r--arch/sh/kernel/setup.c3
-rw-r--r--include/asm-sh/auxvec.h12
-rw-r--r--include/asm-sh/elf.h19
-rw-r--r--include/asm-sh/system.h2
5 files changed, 60 insertions, 5 deletions
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index 0f0c76a842e4..80a31329ead9 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -13,6 +13,7 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/mm.h> 15#include <linux/mm.h>
16#include <linux/log2.h>
16#include <asm/mmu_context.h> 17#include <asm/mmu_context.h>
17#include <asm/processor.h> 18#include <asm/processor.h>
18#include <asm/uaccess.h> 19#include <asm/uaccess.h>
@@ -20,6 +21,7 @@
20#include <asm/system.h> 21#include <asm/system.h>
21#include <asm/cacheflush.h> 22#include <asm/cacheflush.h>
22#include <asm/cache.h> 23#include <asm/cache.h>
24#include <asm/elf.h>
23#include <asm/io.h> 25#include <asm/io.h>
24#include <asm/smp.h> 26#include <asm/smp.h>
25#ifdef CONFIG_SUPERH32 27#ifdef CONFIG_SUPERH32
@@ -151,6 +153,27 @@ static void __uses_jump_to_uncached cache_init(void)
151#define cache_init() do { } while (0) 153#define cache_init() do { } while (0)
152#endif 154#endif
153 155
156#define CSHAPE(totalsize, linesize, assoc) \
157 ((totalsize & ~0xff) | (linesize << 4) | assoc)
158
159#define CACHE_DESC_SHAPE(desc) \
160 CSHAPE((desc).way_size * (desc).ways, ilog2((desc).linesz), (desc).ways)
161
162static void detect_cache_shape(void)
163{
164 l1d_cache_shape = CACHE_DESC_SHAPE(current_cpu_data.dcache);
165
166 if (current_cpu_data.dcache.flags & SH_CACHE_COMBINED)
167 l1i_cache_shape = l1d_cache_shape;
168 else
169 l1i_cache_shape = CACHE_DESC_SHAPE(current_cpu_data.icache);
170
171 if (current_cpu_data.flags & CPU_HAS_L2_CACHE)
172 l2_cache_shape = CACHE_DESC_SHAPE(current_cpu_data.scache);
173 else
174 l2_cache_shape = -1; /* No S-cache */
175}
176
154#ifdef CONFIG_SH_DSP 177#ifdef CONFIG_SH_DSP
155static void __init release_dsp(void) 178static void __init release_dsp(void)
156{ 179{
@@ -237,11 +260,15 @@ asmlinkage void __cpuinit sh_cpu_init(void)
237 /* Init the cache */ 260 /* Init the cache */
238 cache_init(); 261 cache_init();
239 262
240 if (raw_smp_processor_id() == 0) 263 if (raw_smp_processor_id() == 0) {
241 shm_align_mask = max_t(unsigned long, 264 shm_align_mask = max_t(unsigned long,
242 current_cpu_data.dcache.way_size - 1, 265 current_cpu_data.dcache.way_size - 1,
243 PAGE_SIZE - 1); 266 PAGE_SIZE - 1);
244 267
268 /* Boot CPU sets the cache shape */
269 detect_cache_shape();
270 }
271
245 /* Disable the FPU */ 272 /* Disable the FPU */
246 if (fpu_disabled) { 273 if (fpu_disabled) {
247 printk("FPU Disabled\n"); 274 printk("FPU Disabled\n");
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index f48ce8e5d0a8..9c105c827e86 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -26,6 +26,7 @@
26#include <asm/uaccess.h> 26#include <asm/uaccess.h>
27#include <asm/io.h> 27#include <asm/io.h>
28#include <asm/page.h> 28#include <asm/page.h>
29#include <asm/elf.h>
29#include <asm/sections.h> 30#include <asm/sections.h>
30#include <asm/irq.h> 31#include <asm/irq.h>
31#include <asm/setup.h> 32#include <asm/setup.h>
@@ -78,6 +79,8 @@ EXPORT_SYMBOL(memory_start);
78unsigned long memory_end = 0; 79unsigned long memory_end = 0;
79EXPORT_SYMBOL(memory_end); 80EXPORT_SYMBOL(memory_end);
80 81
82int l1i_cache_shape, l1d_cache_shape, l2_cache_shape;
83
81static int __init early_parse_mem(char *p) 84static int __init early_parse_mem(char *p)
82{ 85{
83 unsigned long size; 86 unsigned long size;
diff --git a/include/asm-sh/auxvec.h b/include/asm-sh/auxvec.h
index 1b6916e63e90..4069858f8131 100644
--- a/include/asm-sh/auxvec.h
+++ b/include/asm-sh/auxvec.h
@@ -15,4 +15,16 @@
15#define AT_SYSINFO_EHDR 33 15#define AT_SYSINFO_EHDR 33
16#endif 16#endif
17 17
18/*
19 * More complete cache descriptions than AT_[DIU]CACHEBSIZE. If the
20 * value is -1, then the cache doesn't exist. Otherwise:
21 *
22 * bit 0-3: Cache set-associativity; 0 means fully associative.
23 * bit 4-7: Log2 of cacheline size.
24 * bit 8-31: Size of the entire cache >> 8.
25 */
26#define AT_L1I_CACHESHAPE 34
27#define AT_L1D_CACHESHAPE 35
28#define AT_L2_CACHESHAPE 36
29
18#endif /* __ASM_SH_AUXVEC_H */ 30#endif /* __ASM_SH_AUXVEC_H */
diff --git a/include/asm-sh/elf.h b/include/asm-sh/elf.h
index 5a1e920f0598..61960408e6ef 100644
--- a/include/asm-sh/elf.h
+++ b/include/asm-sh/elf.h
@@ -161,12 +161,25 @@ extern void __kernel_vsyscall;
161#define VDSO_BASE ((unsigned long)current->mm->context.vdso) 161#define VDSO_BASE ((unsigned long)current->mm->context.vdso)
162#define VDSO_SYM(x) (VDSO_BASE + (unsigned long)(x)) 162#define VDSO_SYM(x) (VDSO_BASE + (unsigned long)(x))
163 163
164#define VSYSCALL_AUX_ENT \
165 if (vdso_enabled) \
166 NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE);
167#else
168#define VSYSCALL_AUX_ENT
169#endif /* CONFIG_VSYSCALL */
170
171extern int l1i_cache_shape, l1d_cache_shape, l2_cache_shape;
172
164/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ 173/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
165#define ARCH_DLINFO \ 174#define ARCH_DLINFO \
166do { \ 175do { \
167 if (vdso_enabled) \ 176 /* Optional vsyscall entry */ \
168 NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); \ 177 VSYSCALL_AUX_ENT \
178 \
179 /* Cache desc */ \
180 NEW_AUX_ENT(AT_L1I_CACHESHAPE, l1i_cache_shape); \
181 NEW_AUX_ENT(AT_L1D_CACHESHAPE, l1d_cache_shape); \
182 NEW_AUX_ENT(AT_L2_CACHESHAPE, l2_cache_shape); \
169} while (0) 183} while (0)
170#endif /* CONFIG_VSYSCALL */
171 184
172#endif /* __ASM_SH_ELF_H */ 185#endif /* __ASM_SH_ELF_H */
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h
index 9bda8d063ecf..84592555ba2a 100644
--- a/include/asm-sh/system.h
+++ b/include/asm-sh/system.h
@@ -12,7 +12,7 @@
12#include <asm/types.h> 12#include <asm/types.h>
13#include <asm/ptrace.h> 13#include <asm/ptrace.h>
14 14
15#define AT_VECTOR_SIZE_ARCH 1 /* entries in ARCH_DLINFO */ 15#define AT_VECTOR_SIZE_ARCH 4 /* entries in ARCH_DLINFO */
16 16
17#if defined(CONFIG_CPU_SH4A) || defined(CONFIG_CPU_SH5) 17#if defined(CONFIG_CPU_SH4A) || defined(CONFIG_CPU_SH5)
18#define __icbi() \ 18#define __icbi() \