diff options
author | Paul Mundt <lethal@linux-sh.org> | 2007-12-10 01:50:28 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-01-27 23:18:59 -0500 |
commit | cd01204b82933754a7276838656420477f64d4b8 (patch) | |
tree | f9e3b11574bec04cda78c549cdc5c37c3c75c4a5 | |
parent | c8c0a1aba9fa8f816dc8fb477ff816a5b700f0ea (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.c | 29 | ||||
-rw-r--r-- | arch/sh/kernel/setup.c | 3 | ||||
-rw-r--r-- | include/asm-sh/auxvec.h | 12 | ||||
-rw-r--r-- | include/asm-sh/elf.h | 19 | ||||
-rw-r--r-- | include/asm-sh/system.h | 2 |
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 | |||
162 | static 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 |
155 | static void __init release_dsp(void) | 178 | static 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); | |||
78 | unsigned long memory_end = 0; | 79 | unsigned long memory_end = 0; |
79 | EXPORT_SYMBOL(memory_end); | 80 | EXPORT_SYMBOL(memory_end); |
80 | 81 | ||
82 | int l1i_cache_shape, l1d_cache_shape, l2_cache_shape; | ||
83 | |||
81 | static int __init early_parse_mem(char *p) | 84 | static 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 | |||
171 | extern 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 \ |
166 | do { \ | 175 | do { \ |
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() \ |