diff options
author | Paul Mundt <lethal@linux-sh.org> | 2007-12-10 15:50:28 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-01-28 13:18:59 +0900 |
commit | cd01204b82933754a7276838656420477f64d4b8 (patch) | |
tree | f9e3b11574bec04cda78c549cdc5c37c3c75c4a5 /arch/sh/kernel | |
parent | c8c0a1aba9fa8f816dc8fb477ff816a5b700f0ea (diff) | |
download | op-kernel-dev-cd01204b82933754a7276838656420477f64d4b8.zip op-kernel-dev-cd01204b82933754a7276838656420477f64d4b8.tar.gz |
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>
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r-- | arch/sh/kernel/cpu/init.c | 29 | ||||
-rw-r--r-- | arch/sh/kernel/setup.c | 3 |
2 files changed, 31 insertions, 1 deletions
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index 0f0c76a..80a3132 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -13,6 +13,7 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/mm.h> +#include <linux/log2.h> #include <asm/mmu_context.h> #include <asm/processor.h> #include <asm/uaccess.h> @@ -20,6 +21,7 @@ #include <asm/system.h> #include <asm/cacheflush.h> #include <asm/cache.h> +#include <asm/elf.h> #include <asm/io.h> #include <asm/smp.h> #ifdef CONFIG_SUPERH32 @@ -151,6 +153,27 @@ static void __uses_jump_to_uncached cache_init(void) #define cache_init() do { } while (0) #endif +#define CSHAPE(totalsize, linesize, assoc) \ + ((totalsize & ~0xff) | (linesize << 4) | assoc) + +#define CACHE_DESC_SHAPE(desc) \ + CSHAPE((desc).way_size * (desc).ways, ilog2((desc).linesz), (desc).ways) + +static void detect_cache_shape(void) +{ + l1d_cache_shape = CACHE_DESC_SHAPE(current_cpu_data.dcache); + + if (current_cpu_data.dcache.flags & SH_CACHE_COMBINED) + l1i_cache_shape = l1d_cache_shape; + else + l1i_cache_shape = CACHE_DESC_SHAPE(current_cpu_data.icache); + + if (current_cpu_data.flags & CPU_HAS_L2_CACHE) + l2_cache_shape = CACHE_DESC_SHAPE(current_cpu_data.scache); + else + l2_cache_shape = -1; /* No S-cache */ +} + #ifdef CONFIG_SH_DSP static void __init release_dsp(void) { @@ -237,11 +260,15 @@ asmlinkage void __cpuinit sh_cpu_init(void) /* Init the cache */ cache_init(); - if (raw_smp_processor_id() == 0) + if (raw_smp_processor_id() == 0) { shm_align_mask = max_t(unsigned long, current_cpu_data.dcache.way_size - 1, PAGE_SIZE - 1); + /* Boot CPU sets the cache shape */ + detect_cache_shape(); + } + /* Disable the FPU */ if (fpu_disabled) { printk("FPU Disabled\n"); diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index f48ce8e..9c105c8 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -26,6 +26,7 @@ #include <asm/uaccess.h> #include <asm/io.h> #include <asm/page.h> +#include <asm/elf.h> #include <asm/sections.h> #include <asm/irq.h> #include <asm/setup.h> @@ -78,6 +79,8 @@ EXPORT_SYMBOL(memory_start); unsigned long memory_end = 0; EXPORT_SYMBOL(memory_end); +int l1i_cache_shape, l1d_cache_shape, l2_cache_shape; + static int __init early_parse_mem(char *p) { unsigned long size; |