diff options
author | Paul Mundt <lethal@linux-sh.org> | 2007-11-20 04:27:20 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-01-27 23:18:50 -0500 |
commit | d1839136098e281ece46520200599ef94edca612 (patch) | |
tree | 77352e7de98dccea141287e418c5868165152e83 /arch/sh | |
parent | 92b59258b8e854dd223bbb196f0c18b8cb7e6c6e (diff) |
sh: Plug in simple SH-5 subtype probing.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r-- | arch/sh/kernel/cpu/sh5/Makefile | 4 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh5/probe.c | 76 |
2 files changed, 78 insertions, 2 deletions
diff --git a/arch/sh/kernel/cpu/sh5/Makefile b/arch/sh/kernel/cpu/sh5/Makefile index 6d388e8d8991..c7a9873c8d57 100644 --- a/arch/sh/kernel/cpu/sh5/Makefile +++ b/arch/sh/kernel/cpu/sh5/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-y := entry.o switchto.o | 1 | obj-y := entry.o probe.o switchto.o |
2 | 2 | ||
3 | obj-$(CONFIG_KALLSYMS) += unwind.o | ||
4 | obj-$(CONFIG_SH_FPU) += fpu.o | 3 | obj-$(CONFIG_SH_FPU) += fpu.o |
4 | obj-$(CONFIG_KALLSYMS) += unwind.o | ||
diff --git a/arch/sh/kernel/cpu/sh5/probe.c b/arch/sh/kernel/cpu/sh5/probe.c new file mode 100644 index 000000000000..15d167fd0ae7 --- /dev/null +++ b/arch/sh/kernel/cpu/sh5/probe.c | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/cpu/sh5/probe.c | ||
3 | * | ||
4 | * CPU Subtype Probing for SH-5. | ||
5 | * | ||
6 | * Copyright (C) 2000, 2001 Paolo Alberelli | ||
7 | * Copyright (C) 2003 - 2007 Paul Mundt | ||
8 | * | ||
9 | * This file is subject to the terms and conditions of the GNU General Public | ||
10 | * License. See the file "COPYING" in the main directory of this archive | ||
11 | * for more details. | ||
12 | */ | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/string.h> | ||
16 | #include <asm/processor.h> | ||
17 | #include <asm/cache.h> | ||
18 | |||
19 | int __init detect_cpu_and_cache_system(void) | ||
20 | { | ||
21 | unsigned long long cir; | ||
22 | |||
23 | /* Do peeks in real mode to avoid having to set up a mapping for the | ||
24 | WPC registers. On SH5-101 cut2, such a mapping would be exposed to | ||
25 | an address translation erratum which would make it hard to set up | ||
26 | correctly. */ | ||
27 | cir = peek_real_address_q(0x0d000008); | ||
28 | if ((cir & 0xffff) == 0x5103) { | ||
29 | boot_cpu_data.type = CPU_SH5_103; | ||
30 | } else if (((cir >> 32) & 0xffff) == 0x51e2) { | ||
31 | /* CPU.VCR aliased at CIR address on SH5-101 */ | ||
32 | boot_cpu_data.type = CPU_SH5_101; | ||
33 | } else { | ||
34 | boot_cpu_data.type = CPU_SH_NONE; | ||
35 | } | ||
36 | |||
37 | /* | ||
38 | * First, setup some sane values for the I-cache. | ||
39 | */ | ||
40 | boot_cpu_data.icache.ways = 4; | ||
41 | boot_cpu_data.icache.sets = 256; | ||
42 | boot_cpu_data.icache.linesz = L1_CACHE_BYTES; | ||
43 | |||
44 | #if 0 | ||
45 | /* | ||
46 | * FIXME: This can probably be cleaned up a bit as well.. for example, | ||
47 | * do we really need the way shift _and_ the way_step_shift ?? Judging | ||
48 | * by the existing code, I would guess no.. is there any valid reason | ||
49 | * why we need to be tracking this around? | ||
50 | */ | ||
51 | boot_cpu_data.icache.way_shift = 13; | ||
52 | boot_cpu_data.icache.entry_shift = 5; | ||
53 | boot_cpu_data.icache.set_shift = 4; | ||
54 | boot_cpu_data.icache.way_step_shift = 16; | ||
55 | boot_cpu_data.icache.asid_shift = 2; | ||
56 | |||
57 | /* | ||
58 | * way offset = cache size / associativity, so just don't factor in | ||
59 | * associativity in the first place.. | ||
60 | */ | ||
61 | boot_cpu_data.icache.way_ofs = boot_cpu_data.icache.sets * | ||
62 | boot_cpu_data.icache.linesz; | ||
63 | |||
64 | boot_cpu_data.icache.asid_mask = 0x3fc; | ||
65 | boot_cpu_data.icache.idx_mask = 0x1fe0; | ||
66 | boot_cpu_data.icache.epn_mask = 0xffffe000; | ||
67 | #endif | ||
68 | |||
69 | boot_cpu_data.icache.flags = 0; | ||
70 | |||
71 | /* A trivial starting point.. */ | ||
72 | memcpy(&boot_cpu_data.dcache, | ||
73 | &boot_cpu_data.icache, sizeof(struct cache_info)); | ||
74 | |||
75 | return 0; | ||
76 | } | ||