diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-01-18 04:42:24 -0500 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2013-02-15 12:46:07 -0500 |
commit | af61742813aa9dde65ca796801e36d03b83fa79f (patch) | |
tree | eccf5ea5d87904d79c9aa5574b031d56961247da /arch/arc | |
parent | f46121bd26d7957866739313f1e098a682e8d3e4 (diff) |
ARC: Boot #2: Verbose Boot reporting / feature verification
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc')
-rw-r--r-- | arch/arc/Makefile | 2 | ||||
-rw-r--r-- | arch/arc/include/asm/arcregs.h | 122 | ||||
-rw-r--r-- | arch/arc/include/asm/defines.h | 56 | ||||
-rw-r--r-- | arch/arc/include/asm/setup.h | 14 | ||||
-rw-r--r-- | arch/arc/kernel/setup.c | 223 | ||||
-rw-r--r-- | arch/arc/mm/cache_arc700.c | 46 | ||||
-rw-r--r-- | arch/arc/mm/tlb.c | 38 |
7 files changed, 490 insertions, 11 deletions
diff --git a/arch/arc/Makefile b/arch/arc/Makefile index fae66bfc2bdb..9a36c04e4306 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile | |||
@@ -20,6 +20,8 @@ export PLATFORM | |||
20 | cflags-y += -Iarch/arc/plat-$(PLATFORM)/include | 20 | cflags-y += -Iarch/arc/plat-$(PLATFORM)/include |
21 | cflags-y += -mA7 -fno-common -pipe -fno-builtin -D__linux__ | 21 | cflags-y += -mA7 -fno-common -pipe -fno-builtin -D__linux__ |
22 | 22 | ||
23 | LINUXINCLUDE += -include ${src}/arch/arc/include/asm/defines.h | ||
24 | |||
23 | ifdef CONFIG_ARC_CURR_IN_REG | 25 | ifdef CONFIG_ARC_CURR_IN_REG |
24 | # For a global register defintion, make sure it gets passed to every file | 26 | # For a global register defintion, make sure it gets passed to every file |
25 | # We had a customer reported bug where some code built in kernel was NOT using | 27 | # We had a customer reported bug where some code built in kernel was NOT using |
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index 9e42611e39d3..1b907c465666 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h | |||
@@ -12,8 +12,26 @@ | |||
12 | #ifdef __KERNEL__ | 12 | #ifdef __KERNEL__ |
13 | 13 | ||
14 | /* Build Configuration Registers */ | 14 | /* Build Configuration Registers */ |
15 | #define ARC_REG_DCCMBASE_BCR 0x61 /* DCCM Base Addr */ | ||
16 | #define ARC_REG_CRC_BCR 0x62 | ||
17 | #define ARC_REG_DVFB_BCR 0x64 | ||
18 | #define ARC_REG_EXTARITH_BCR 0x65 | ||
15 | #define ARC_REG_VECBASE_BCR 0x68 | 19 | #define ARC_REG_VECBASE_BCR 0x68 |
20 | #define ARC_REG_PERIBASE_BCR 0x69 | ||
21 | #define ARC_REG_FP_BCR 0x6B /* Single-Precision FPU */ | ||
22 | #define ARC_REG_DPFP_BCR 0x6C /* Dbl Precision FPU */ | ||
16 | #define ARC_REG_MMU_BCR 0x6f | 23 | #define ARC_REG_MMU_BCR 0x6f |
24 | #define ARC_REG_DCCM_BCR 0x74 /* DCCM Present + SZ */ | ||
25 | #define ARC_REG_TIMERS_BCR 0x75 | ||
26 | #define ARC_REG_ICCM_BCR 0x78 | ||
27 | #define ARC_REG_XY_MEM_BCR 0x79 | ||
28 | #define ARC_REG_MAC_BCR 0x7a | ||
29 | #define ARC_REG_MUL_BCR 0x7b | ||
30 | #define ARC_REG_SWAP_BCR 0x7c | ||
31 | #define ARC_REG_NORM_BCR 0x7d | ||
32 | #define ARC_REG_MIXMAX_BCR 0x7e | ||
33 | #define ARC_REG_BARREL_BCR 0x7f | ||
34 | #define ARC_REG_D_UNCACH_BCR 0x6A | ||
17 | 35 | ||
18 | /* status32 Bits Positions */ | 36 | /* status32 Bits Positions */ |
19 | #define STATUS_H_BIT 0 /* CPU Halted */ | 37 | #define STATUS_H_BIT 0 /* CPU Halted */ |
@@ -88,16 +106,6 @@ | |||
88 | #define TIMER_CTRL_IE (1 << 0) /* Interupt when Count reachs limit */ | 106 | #define TIMER_CTRL_IE (1 << 0) /* Interupt when Count reachs limit */ |
89 | #define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */ | 107 | #define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */ |
90 | 108 | ||
91 | #if defined(CONFIG_ARC_MMU_V1) | ||
92 | #define CONFIG_ARC_MMU_VER 1 | ||
93 | #elif defined(CONFIG_ARC_MMU_V2) | ||
94 | #define CONFIG_ARC_MMU_VER 2 | ||
95 | #elif defined(CONFIG_ARC_MMU_V3) | ||
96 | #define CONFIG_ARC_MMU_VER 3 | ||
97 | #else | ||
98 | #error "Error: MMU ver" | ||
99 | #endif | ||
100 | |||
101 | /* MMU Management regs */ | 109 | /* MMU Management regs */ |
102 | #define ARC_REG_TLBPD0 0x405 | 110 | #define ARC_REG_TLBPD0 0x405 |
103 | #define ARC_REG_TLBPD1 0x406 | 111 | #define ARC_REG_TLBPD1 0x406 |
@@ -277,6 +285,13 @@ struct arc_fpu { | |||
277 | *************************************************************** | 285 | *************************************************************** |
278 | * Build Configuration Registers, with encoded hardware config | 286 | * Build Configuration Registers, with encoded hardware config |
279 | */ | 287 | */ |
288 | struct bcr_identity { | ||
289 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
290 | unsigned int chip_id:16, cpu_id:8, family:8; | ||
291 | #else | ||
292 | unsigned int family:8, cpu_id:8, chip_id:16; | ||
293 | #endif | ||
294 | }; | ||
280 | 295 | ||
281 | struct bcr_mmu_1_2 { | 296 | struct bcr_mmu_1_2 { |
282 | #ifdef CONFIG_CPU_BIG_ENDIAN | 297 | #ifdef CONFIG_CPU_BIG_ENDIAN |
@@ -296,6 +311,38 @@ struct bcr_mmu_3 { | |||
296 | #endif | 311 | #endif |
297 | }; | 312 | }; |
298 | 313 | ||
314 | #define EXTN_SWAP_VALID 0x1 | ||
315 | #define EXTN_NORM_VALID 0x2 | ||
316 | #define EXTN_MINMAX_VALID 0x2 | ||
317 | #define EXTN_BARREL_VALID 0x2 | ||
318 | |||
319 | struct bcr_extn { | ||
320 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
321 | unsigned int pad:20, crc:1, ext_arith:2, mul:2, barrel:2, minmax:2, | ||
322 | norm:2, swap:1; | ||
323 | #else | ||
324 | unsigned int swap:1, norm:2, minmax:2, barrel:2, mul:2, ext_arith:2, | ||
325 | crc:1, pad:20; | ||
326 | #endif | ||
327 | }; | ||
328 | |||
329 | /* DSP Options Ref Manual */ | ||
330 | struct bcr_extn_mac_mul { | ||
331 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
332 | unsigned int pad:16, type:8, ver:8; | ||
333 | #else | ||
334 | unsigned int ver:8, type:8, pad:16; | ||
335 | #endif | ||
336 | }; | ||
337 | |||
338 | struct bcr_extn_xymem { | ||
339 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
340 | unsigned int ram_org:2, num_banks:4, bank_sz:4, ver:8; | ||
341 | #else | ||
342 | unsigned int ver:8, bank_sz:4, num_banks:4, ram_org:2; | ||
343 | #endif | ||
344 | }; | ||
345 | |||
299 | struct bcr_cache { | 346 | struct bcr_cache { |
300 | #ifdef CONFIG_CPU_BIG_ENDIAN | 347 | #ifdef CONFIG_CPU_BIG_ENDIAN |
301 | unsigned int pad:12, line_len:4, sz:4, config:4, ver:8; | 348 | unsigned int pad:12, line_len:4, sz:4, config:4, ver:8; |
@@ -304,6 +351,48 @@ struct bcr_cache { | |||
304 | #endif | 351 | #endif |
305 | }; | 352 | }; |
306 | 353 | ||
354 | struct bcr_perip { | ||
355 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
356 | unsigned int start:8, pad2:8, sz:8, pad:8; | ||
357 | #else | ||
358 | unsigned int pad:8, sz:8, pad2:8, start:8; | ||
359 | #endif | ||
360 | }; | ||
361 | struct bcr_iccm { | ||
362 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
363 | unsigned int base:16, pad:5, sz:3, ver:8; | ||
364 | #else | ||
365 | unsigned int ver:8, sz:3, pad:5, base:16; | ||
366 | #endif | ||
367 | }; | ||
368 | |||
369 | /* DCCM Base Address Register: ARC_REG_DCCMBASE_BCR */ | ||
370 | struct bcr_dccm_base { | ||
371 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
372 | unsigned int addr:24, ver:8; | ||
373 | #else | ||
374 | unsigned int ver:8, addr:24; | ||
375 | #endif | ||
376 | }; | ||
377 | |||
378 | /* DCCM RAM Configuration Register: ARC_REG_DCCM_BCR */ | ||
379 | struct bcr_dccm { | ||
380 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
381 | unsigned int res:21, sz:3, ver:8; | ||
382 | #else | ||
383 | unsigned int ver:8, sz:3, res:21; | ||
384 | #endif | ||
385 | }; | ||
386 | |||
387 | /* Both SP and DP FPU BCRs have same format */ | ||
388 | struct bcr_fp { | ||
389 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
390 | unsigned int fast:1, ver:8; | ||
391 | #else | ||
392 | unsigned int ver:8, fast:1; | ||
393 | #endif | ||
394 | }; | ||
395 | |||
307 | /* | 396 | /* |
308 | ******************************************************************* | 397 | ******************************************************************* |
309 | * Generic structures to hold build configuration used at runtime | 398 | * Generic structures to hold build configuration used at runtime |
@@ -317,9 +406,22 @@ struct cpuinfo_arc_cache { | |||
317 | unsigned int has_aliasing, sz, line_len, assoc, ver; | 406 | unsigned int has_aliasing, sz, line_len, assoc, ver; |
318 | }; | 407 | }; |
319 | 408 | ||
409 | struct cpuinfo_arc_ccm { | ||
410 | unsigned int base_addr, sz; | ||
411 | }; | ||
412 | |||
320 | struct cpuinfo_arc { | 413 | struct cpuinfo_arc { |
321 | struct cpuinfo_arc_cache icache, dcache; | 414 | struct cpuinfo_arc_cache icache, dcache; |
322 | struct cpuinfo_arc_mmu mmu; | 415 | struct cpuinfo_arc_mmu mmu; |
416 | struct bcr_identity core; | ||
417 | unsigned int timers; | ||
418 | unsigned int vec_base; | ||
419 | unsigned int uncached_base; | ||
420 | struct cpuinfo_arc_ccm iccm, dccm; | ||
421 | struct bcr_extn extn; | ||
422 | struct bcr_extn_xymem extn_xymem; | ||
423 | struct bcr_extn_mac_mul extn_mac_mul; | ||
424 | struct bcr_fp fp, dpfp; | ||
323 | }; | 425 | }; |
324 | 426 | ||
325 | extern struct cpuinfo_arc cpuinfo_arc700[]; | 427 | extern struct cpuinfo_arc cpuinfo_arc700[]; |
diff --git a/arch/arc/include/asm/defines.h b/arch/arc/include/asm/defines.h new file mode 100644 index 000000000000..6097bb439cc5 --- /dev/null +++ b/arch/arc/include/asm/defines.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #ifndef __ARC_ASM_DEFINES_H__ | ||
10 | #define __ARC_ASM_DEFINES_H__ | ||
11 | |||
12 | #if defined(CONFIG_ARC_MMU_V1) | ||
13 | #define CONFIG_ARC_MMU_VER 1 | ||
14 | #elif defined(CONFIG_ARC_MMU_V2) | ||
15 | #define CONFIG_ARC_MMU_VER 2 | ||
16 | #elif defined(CONFIG_ARC_MMU_V3) | ||
17 | #define CONFIG_ARC_MMU_VER 3 | ||
18 | #endif | ||
19 | |||
20 | #ifdef CONFIG_ARC_HAS_LLSC | ||
21 | #define __CONFIG_ARC_HAS_LLSC_VAL 1 | ||
22 | #else | ||
23 | #define __CONFIG_ARC_HAS_LLSC_VAL 0 | ||
24 | #endif | ||
25 | |||
26 | #ifdef CONFIG_ARC_HAS_SWAPE | ||
27 | #define __CONFIG_ARC_HAS_SWAPE_VAL 1 | ||
28 | #else | ||
29 | #define __CONFIG_ARC_HAS_SWAPE_VAL 0 | ||
30 | #endif | ||
31 | |||
32 | #ifdef CONFIG_ARC_HAS_RTSC | ||
33 | #define __CONFIG_ARC_HAS_RTSC_VAL 1 | ||
34 | #else | ||
35 | #define __CONFIG_ARC_HAS_RTSC_VAL 0 | ||
36 | #endif | ||
37 | |||
38 | #ifdef CONFIG_ARC_MMU_SASID | ||
39 | #define __CONFIG_ARC_MMU_SASID_VAL 1 | ||
40 | #else | ||
41 | #define __CONFIG_ARC_MMU_SASID_VAL 0 | ||
42 | #endif | ||
43 | |||
44 | #ifdef CONFIG_ARC_HAS_ICACHE | ||
45 | #define __CONFIG_ARC_HAS_ICACHE 1 | ||
46 | #else | ||
47 | #define __CONFIG_ARC_HAS_ICACHE 0 | ||
48 | #endif | ||
49 | |||
50 | #ifdef CONFIG_ARC_HAS_DCACHE | ||
51 | #define __CONFIG_ARC_HAS_DCACHE 1 | ||
52 | #else | ||
53 | #define __CONFIG_ARC_HAS_DCACHE 0 | ||
54 | #endif | ||
55 | |||
56 | #endif /* __ARC_ASM_DEFINES_H__ */ | ||
diff --git a/arch/arc/include/asm/setup.h b/arch/arc/include/asm/setup.h index ab427e6a2cb5..fc97411269fe 100644 --- a/arch/arc/include/asm/setup.h +++ b/arch/arc/include/asm/setup.h | |||
@@ -13,6 +13,20 @@ | |||
13 | 13 | ||
14 | #define COMMAND_LINE_SIZE 256 | 14 | #define COMMAND_LINE_SIZE 256 |
15 | 15 | ||
16 | /* | ||
17 | * Data structure to map a ID to string | ||
18 | * Used a lot for bootup reporting of hardware diversity | ||
19 | */ | ||
20 | struct id_to_str { | ||
21 | int id; | ||
22 | const char *str; | ||
23 | }; | ||
24 | |||
25 | struct cpuinfo_data { | ||
26 | struct id_to_str info; | ||
27 | int up_range; | ||
28 | }; | ||
29 | |||
16 | extern int root_mountflags, end_mem; | 30 | extern int root_mountflags, end_mem; |
17 | extern int running_on_hw; | 31 | extern int running_on_hw; |
18 | 32 | ||
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index 6e3996cb9df9..e25538e29fe7 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <asm/arcregs.h> | 24 | #include <asm/arcregs.h> |
25 | #include <asm/prom.h> | 25 | #include <asm/prom.h> |
26 | #include <asm/unwind.h> | 26 | #include <asm/unwind.h> |
27 | #include <asm/clk.h> | ||
27 | 28 | ||
28 | #define FIX_PTR(x) __asm__ __volatile__(";" : "+r"(x)) | 29 | #define FIX_PTR(x) __asm__ __volatile__(";" : "+r"(x)) |
29 | 30 | ||
@@ -35,10 +36,205 @@ struct task_struct *_current_task[NR_CPUS]; /* For stack switching */ | |||
35 | 36 | ||
36 | struct cpuinfo_arc cpuinfo_arc700[NR_CPUS]; | 37 | struct cpuinfo_arc cpuinfo_arc700[NR_CPUS]; |
37 | 38 | ||
39 | |||
38 | void __init read_arc_build_cfg_regs(void) | 40 | void __init read_arc_build_cfg_regs(void) |
39 | { | 41 | { |
42 | struct bcr_perip uncached_space; | ||
43 | struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; | ||
44 | FIX_PTR(cpu); | ||
45 | |||
46 | READ_BCR(AUX_IDENTITY, cpu->core); | ||
47 | |||
48 | cpu->timers = read_aux_reg(ARC_REG_TIMERS_BCR); | ||
49 | |||
50 | cpu->vec_base = read_aux_reg(AUX_INTR_VEC_BASE); | ||
51 | if (cpu->vec_base == 0) | ||
52 | cpu->vec_base = (unsigned int)_int_vec_base_lds; | ||
53 | |||
54 | READ_BCR(ARC_REG_D_UNCACH_BCR, uncached_space); | ||
55 | cpu->uncached_base = uncached_space.start << 24; | ||
56 | |||
57 | cpu->extn.mul = read_aux_reg(ARC_REG_MUL_BCR); | ||
58 | cpu->extn.swap = read_aux_reg(ARC_REG_SWAP_BCR); | ||
59 | cpu->extn.norm = read_aux_reg(ARC_REG_NORM_BCR); | ||
60 | cpu->extn.minmax = read_aux_reg(ARC_REG_MIXMAX_BCR); | ||
61 | cpu->extn.barrel = read_aux_reg(ARC_REG_BARREL_BCR); | ||
62 | READ_BCR(ARC_REG_MAC_BCR, cpu->extn_mac_mul); | ||
63 | |||
64 | cpu->extn.ext_arith = read_aux_reg(ARC_REG_EXTARITH_BCR); | ||
65 | cpu->extn.crc = read_aux_reg(ARC_REG_CRC_BCR); | ||
66 | |||
67 | READ_BCR(ARC_REG_XY_MEM_BCR, cpu->extn_xymem); | ||
68 | |||
40 | read_decode_mmu_bcr(); | 69 | read_decode_mmu_bcr(); |
41 | read_decode_cache_bcr(); | 70 | read_decode_cache_bcr(); |
71 | |||
72 | READ_BCR(ARC_REG_FP_BCR, cpu->fp); | ||
73 | READ_BCR(ARC_REG_DPFP_BCR, cpu->dpfp); | ||
74 | } | ||
75 | |||
76 | static const struct cpuinfo_data arc_cpu_tbl[] = { | ||
77 | { {0x10, "ARCTangent A5"}, 0x1F}, | ||
78 | { {0x20, "ARC 600" }, 0x2F}, | ||
79 | { {0x30, "ARC 700" }, 0x33}, | ||
80 | { {0x34, "ARC 700 R4.10"}, 0x34}, | ||
81 | { {0x00, NULL } } | ||
82 | }; | ||
83 | |||
84 | char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) | ||
85 | { | ||
86 | int n = 0; | ||
87 | struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id]; | ||
88 | struct bcr_identity *core = &cpu->core; | ||
89 | const struct cpuinfo_data *tbl; | ||
90 | int be = 0; | ||
91 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
92 | be = 1; | ||
93 | #endif | ||
94 | FIX_PTR(cpu); | ||
95 | |||
96 | n += scnprintf(buf + n, len - n, | ||
97 | "\nARC IDENTITY\t: Family [%#02x]" | ||
98 | " Cpu-id [%#02x] Chip-id [%#4x]\n", | ||
99 | core->family, core->cpu_id, | ||
100 | core->chip_id); | ||
101 | |||
102 | for (tbl = &arc_cpu_tbl[0]; tbl->info.id != 0; tbl++) { | ||
103 | if ((core->family >= tbl->info.id) && | ||
104 | (core->family <= tbl->up_range)) { | ||
105 | n += scnprintf(buf + n, len - n, | ||
106 | "processor\t: %s %s\n", | ||
107 | tbl->info.str, | ||
108 | be ? "[Big Endian]" : ""); | ||
109 | break; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | if (tbl->info.id == 0) | ||
114 | n += scnprintf(buf + n, len - n, "UNKNOWN ARC Processor\n"); | ||
115 | |||
116 | n += scnprintf(buf + n, len - n, "CPU speed\t: %u.%02u Mhz\n", | ||
117 | (unsigned int)(arc_get_core_freq() / 1000000), | ||
118 | (unsigned int)(arc_get_core_freq() / 10000) % 100); | ||
119 | |||
120 | n += scnprintf(buf + n, len - n, "Timers\t\t: %s %s\n", | ||
121 | (cpu->timers & 0x200) ? "TIMER1" : "", | ||
122 | (cpu->timers & 0x100) ? "TIMER0" : ""); | ||
123 | |||
124 | n += scnprintf(buf + n, len - n, "Vect Tbl Base\t: %#x\n", | ||
125 | cpu->vec_base); | ||
126 | |||
127 | n += scnprintf(buf + n, len - n, "UNCACHED Base\t: %#x\n", | ||
128 | cpu->uncached_base); | ||
129 | |||
130 | return buf; | ||
131 | } | ||
132 | |||
133 | static const struct id_to_str mul_type_nm[] = { | ||
134 | { 0x0, "N/A"}, | ||
135 | { 0x1, "32x32 (spl Result Reg)" }, | ||
136 | { 0x2, "32x32 (ANY Result Reg)" } | ||
137 | }; | ||
138 | |||
139 | static const struct id_to_str mac_mul_nm[] = { | ||
140 | {0x0, "N/A"}, | ||
141 | {0x1, "N/A"}, | ||
142 | {0x2, "Dual 16 x 16"}, | ||
143 | {0x3, "N/A"}, | ||
144 | {0x4, "32x16"}, | ||
145 | {0x5, "N/A"}, | ||
146 | {0x6, "Dual 16x16 and 32x16"} | ||
147 | }; | ||
148 | |||
149 | char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) | ||
150 | { | ||
151 | int n = 0; | ||
152 | struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id]; | ||
153 | |||
154 | FIX_PTR(cpu); | ||
155 | #define IS_AVAIL1(var, str) ((var) ? str : "") | ||
156 | #define IS_AVAIL2(var, str) ((var == 0x2) ? str : "") | ||
157 | #define IS_USED(var) ((var) ? "(in-use)" : "(not used)") | ||
158 | |||
159 | n += scnprintf(buf + n, len - n, | ||
160 | "Extn [700-Base]\t: %s %s %s %s %s %s\n", | ||
161 | IS_AVAIL2(cpu->extn.norm, "norm,"), | ||
162 | IS_AVAIL2(cpu->extn.barrel, "barrel-shift,"), | ||
163 | IS_AVAIL1(cpu->extn.swap, "swap,"), | ||
164 | IS_AVAIL2(cpu->extn.minmax, "minmax,"), | ||
165 | IS_AVAIL1(cpu->extn.crc, "crc,"), | ||
166 | IS_AVAIL2(cpu->extn.ext_arith, "ext-arith")); | ||
167 | |||
168 | n += scnprintf(buf + n, len - n, "Extn [700-MPY]\t: %s", | ||
169 | mul_type_nm[cpu->extn.mul].str); | ||
170 | |||
171 | n += scnprintf(buf + n, len - n, " MAC MPY: %s\n", | ||
172 | mac_mul_nm[cpu->extn_mac_mul.type].str); | ||
173 | |||
174 | if (cpu->core.family == 0x34) { | ||
175 | n += scnprintf(buf + n, len - n, | ||
176 | "Extn [700-4.10]\t: LLOCK/SCOND %s, SWAPE %s, RTSC %s\n", | ||
177 | IS_USED(__CONFIG_ARC_HAS_LLSC_VAL), | ||
178 | IS_USED(__CONFIG_ARC_HAS_SWAPE_VAL), | ||
179 | IS_USED(__CONFIG_ARC_HAS_RTSC_VAL)); | ||
180 | } | ||
181 | |||
182 | n += scnprintf(buf + n, len - n, "Extn [CCM]\t: %s", | ||
183 | !(cpu->dccm.sz || cpu->iccm.sz) ? "N/A" : ""); | ||
184 | |||
185 | if (cpu->dccm.sz) | ||
186 | n += scnprintf(buf + n, len - n, "DCCM: @ %x, %d KB ", | ||
187 | cpu->dccm.base_addr, TO_KB(cpu->dccm.sz)); | ||
188 | |||
189 | if (cpu->iccm.sz) | ||
190 | n += scnprintf(buf + n, len - n, "ICCM: @ %x, %d KB", | ||
191 | cpu->iccm.base_addr, TO_KB(cpu->iccm.sz)); | ||
192 | |||
193 | n += scnprintf(buf + n, len - n, "\nExtn [FPU]\t: %s", | ||
194 | !(cpu->fp.ver || cpu->dpfp.ver) ? "N/A" : ""); | ||
195 | |||
196 | if (cpu->fp.ver) | ||
197 | n += scnprintf(buf + n, len - n, "SP [v%d] %s", | ||
198 | cpu->fp.ver, cpu->fp.fast ? "(fast)" : ""); | ||
199 | |||
200 | if (cpu->dpfp.ver) | ||
201 | n += scnprintf(buf + n, len - n, "DP [v%d] %s", | ||
202 | cpu->dpfp.ver, cpu->dpfp.fast ? "(fast)" : ""); | ||
203 | |||
204 | n += scnprintf(buf + n, len - n, "\n"); | ||
205 | |||
206 | #ifdef _ASM_GENERIC_UNISTD_H | ||
207 | n += scnprintf(buf + n, len - n, | ||
208 | "OS ABI [v2]\t: asm-generic/{unistd,stat,fcntl}\n"); | ||
209 | #endif | ||
210 | |||
211 | return buf; | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * Ensure that FP hardware and kernel config match | ||
216 | * -If hardware contains DPFP, kernel needs to save/restore FPU state | ||
217 | * across context switches | ||
218 | * -If hardware lacks DPFP, but kernel configured to save FPU state then | ||
219 | * kernel trying to access non-existant DPFP regs will crash | ||
220 | * | ||
221 | * We only check for Dbl precision Floating Point, because only DPFP | ||
222 | * hardware has dedicated regs which need to be saved/restored on ctx-sw | ||
223 | * (Single Precision uses core regs), thus kernel is kind of oblivious to it | ||
224 | */ | ||
225 | void __init arc_chk_fpu(void) | ||
226 | { | ||
227 | struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; | ||
228 | |||
229 | if (cpu->dpfp.ver) { | ||
230 | #ifndef CONFIG_ARC_FPU_SAVE_RESTORE | ||
231 | pr_warn("DPFP support broken in this kernel...\n"); | ||
232 | #endif | ||
233 | } else { | ||
234 | #ifdef CONFIG_ARC_FPU_SAVE_RESTORE | ||
235 | panic("H/w lacks DPFP support, apps won't work\n"); | ||
236 | #endif | ||
237 | } | ||
42 | } | 238 | } |
43 | 239 | ||
44 | /* | 240 | /* |
@@ -49,10 +245,25 @@ void __init read_arc_build_cfg_regs(void) | |||
49 | 245 | ||
50 | void __init setup_processor(void) | 246 | void __init setup_processor(void) |
51 | { | 247 | { |
248 | char str[512]; | ||
249 | int cpu_id = smp_processor_id(); | ||
250 | |||
52 | read_arc_build_cfg_regs(); | 251 | read_arc_build_cfg_regs(); |
53 | arc_init_IRQ(); | 252 | arc_init_IRQ(); |
253 | |||
254 | printk(arc_cpu_mumbojumbo(cpu_id, str, sizeof(str))); | ||
255 | |||
54 | arc_mmu_init(); | 256 | arc_mmu_init(); |
55 | arc_cache_init(); | 257 | arc_cache_init(); |
258 | |||
259 | |||
260 | printk(arc_extn_mumbojumbo(cpu_id, str, sizeof(str))); | ||
261 | |||
262 | #ifdef CONFIG_SMP | ||
263 | printk(arc_platform_smp_cpuinfo()); | ||
264 | #endif | ||
265 | |||
266 | arc_chk_fpu(); | ||
56 | } | 267 | } |
57 | 268 | ||
58 | void __init __attribute__((weak)) arc_platform_early_init(void) | 269 | void __init __attribute__((weak)) arc_platform_early_init(void) |
@@ -126,12 +337,22 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
126 | if (!str) | 337 | if (!str) |
127 | goto done; | 338 | goto done; |
128 | 339 | ||
129 | seq_printf(m, "ARC700 #%d\n", cpu_id); | 340 | seq_printf(m, arc_cpu_mumbojumbo(cpu_id, str, PAGE_SIZE)); |
130 | 341 | ||
131 | seq_printf(m, "Bogo MIPS : \t%lu.%02lu\n", | 342 | seq_printf(m, "Bogo MIPS : \t%lu.%02lu\n", |
132 | loops_per_jiffy / (500000 / HZ), | 343 | loops_per_jiffy / (500000 / HZ), |
133 | (loops_per_jiffy / (5000 / HZ)) % 100); | 344 | (loops_per_jiffy / (5000 / HZ)) % 100); |
134 | 345 | ||
346 | seq_printf(m, arc_mmu_mumbojumbo(cpu_id, str, PAGE_SIZE)); | ||
347 | |||
348 | seq_printf(m, arc_cache_mumbojumbo(cpu_id, str, PAGE_SIZE)); | ||
349 | |||
350 | seq_printf(m, arc_extn_mumbojumbo(cpu_id, str, PAGE_SIZE)); | ||
351 | |||
352 | #ifdef CONFIG_SMP | ||
353 | seq_printf(m, arc_platform_smp_cpuinfo()); | ||
354 | #endif | ||
355 | |||
135 | free_page((unsigned long)str); | 356 | free_page((unsigned long)str); |
136 | done: | 357 | done: |
137 | seq_printf(m, "\n\n"); | 358 | seq_printf(m, "\n\n"); |
diff --git a/arch/arc/mm/cache_arc700.c b/arch/arc/mm/cache_arc700.c index 670f65bb2ef1..c299b30924ee 100644 --- a/arch/arc/mm/cache_arc700.c +++ b/arch/arc/mm/cache_arc700.c | |||
@@ -82,6 +82,28 @@ static void __ic_line_inv_4_alias(unsigned long, int); | |||
82 | static void (*___flush_icache_rtn) (unsigned long, int); | 82 | static void (*___flush_icache_rtn) (unsigned long, int); |
83 | #endif | 83 | #endif |
84 | 84 | ||
85 | char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len) | ||
86 | { | ||
87 | int n = 0; | ||
88 | unsigned int c = smp_processor_id(); | ||
89 | |||
90 | #define PR_CACHE(p, enb, str) \ | ||
91 | { \ | ||
92 | if (!(p)->ver) \ | ||
93 | n += scnprintf(buf + n, len - n, str"\t\t: N/A\n"); \ | ||
94 | else \ | ||
95 | n += scnprintf(buf + n, len - n, \ | ||
96 | str"\t\t: (%uK) VIPT, %dway set-asc, %ub Line %s\n", \ | ||
97 | TO_KB((p)->sz), (p)->assoc, (p)->line_len, \ | ||
98 | enb ? "" : "DISABLED (kernel-build)"); \ | ||
99 | } | ||
100 | |||
101 | PR_CACHE(&cpuinfo_arc700[c].icache, __CONFIG_ARC_HAS_ICACHE, "I-Cache"); | ||
102 | PR_CACHE(&cpuinfo_arc700[c].dcache, __CONFIG_ARC_HAS_DCACHE, "D-Cache"); | ||
103 | |||
104 | return buf; | ||
105 | } | ||
106 | |||
85 | /* | 107 | /* |
86 | * Read the Cache Build Confuration Registers, Decode them and save into | 108 | * Read the Cache Build Confuration Registers, Decode them and save into |
87 | * the cpuinfo structure for later use. | 109 | * the cpuinfo structure for later use. |
@@ -132,10 +154,29 @@ void __init arc_cache_init(void) | |||
132 | struct cpuinfo_arc_cache *dc; | 154 | struct cpuinfo_arc_cache *dc; |
133 | #endif | 155 | #endif |
134 | int way_pg_ratio = way_pg_ratio; | 156 | int way_pg_ratio = way_pg_ratio; |
157 | char str[256]; | ||
158 | |||
159 | printk(arc_cache_mumbojumbo(0, str, sizeof(str))); | ||
135 | 160 | ||
136 | #ifdef CONFIG_ARC_HAS_ICACHE | 161 | #ifdef CONFIG_ARC_HAS_ICACHE |
137 | ic = &cpuinfo_arc700[cpu].icache; | 162 | ic = &cpuinfo_arc700[cpu].icache; |
138 | 163 | ||
164 | /* 1. Confirm some of I-cache params which Linux assumes */ | ||
165 | if ((ic->assoc != ARC_ICACHE_WAYS) || | ||
166 | (ic->line_len != ARC_ICACHE_LINE_LEN)) { | ||
167 | panic("Cache H/W doesn't match kernel Config"); | ||
168 | } | ||
169 | #if (CONFIG_ARC_MMU_VER > 2) | ||
170 | if (ic->ver != 3) { | ||
171 | if (running_on_hw) | ||
172 | panic("Cache ver doesn't match MMU ver\n"); | ||
173 | |||
174 | /* For ISS - suggest the toggles to use */ | ||
175 | pr_err("Use -prop=icache_version=3,-prop=dcache_version=3\n"); | ||
176 | |||
177 | } | ||
178 | #endif | ||
179 | |||
139 | /* | 180 | /* |
140 | * if Cache way size is <= page size then no aliasing exhibited | 181 | * if Cache way size is <= page size then no aliasing exhibited |
141 | * otherwise ratio determines num of aliases. | 182 | * otherwise ratio determines num of aliases. |
@@ -175,6 +216,11 @@ void __init arc_cache_init(void) | |||
175 | #ifdef CONFIG_ARC_HAS_DCACHE | 216 | #ifdef CONFIG_ARC_HAS_DCACHE |
176 | dc = &cpuinfo_arc700[cpu].dcache; | 217 | dc = &cpuinfo_arc700[cpu].dcache; |
177 | 218 | ||
219 | if ((dc->assoc != ARC_DCACHE_WAYS) || | ||
220 | (dc->line_len != ARC_DCACHE_LINE_LEN)) { | ||
221 | panic("Cache H/W doesn't match kernel Config"); | ||
222 | } | ||
223 | |||
178 | /* check for D-Cache aliasing */ | 224 | /* check for D-Cache aliasing */ |
179 | if ((dc->sz / ARC_DCACHE_WAYS) > PAGE_SIZE) | 225 | if ((dc->sz / ARC_DCACHE_WAYS) > PAGE_SIZE) |
180 | panic("D$ aliasing not handled right now\n"); | 226 | panic("D$ aliasing not handled right now\n"); |
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c index e96030c13b52..9b9ce23f4ec3 100644 --- a/arch/arc/mm/tlb.c +++ b/arch/arc/mm/tlb.c | |||
@@ -463,8 +463,46 @@ void __init read_decode_mmu_bcr(void) | |||
463 | mmu->num_tlb = mmu->sets * mmu->ways; | 463 | mmu->num_tlb = mmu->sets * mmu->ways; |
464 | } | 464 | } |
465 | 465 | ||
466 | char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len) | ||
467 | { | ||
468 | int n = 0; | ||
469 | struct cpuinfo_arc_mmu *p_mmu = &cpuinfo_arc700[smp_processor_id()].mmu; | ||
470 | |||
471 | n += scnprintf(buf + n, len - n, "ARC700 MMU [v%x]\t: %dk PAGE, ", | ||
472 | p_mmu->ver, TO_KB(p_mmu->pg_sz)); | ||
473 | |||
474 | n += scnprintf(buf + n, len - n, | ||
475 | "J-TLB %d (%dx%d), uDTLB %d, uITLB %d, %s\n", | ||
476 | p_mmu->num_tlb, p_mmu->sets, p_mmu->ways, | ||
477 | p_mmu->u_dtlb, p_mmu->u_itlb, | ||
478 | __CONFIG_ARC_MMU_SASID_VAL ? "SASID" : ""); | ||
479 | |||
480 | return buf; | ||
481 | } | ||
482 | |||
466 | void __init arc_mmu_init(void) | 483 | void __init arc_mmu_init(void) |
467 | { | 484 | { |
485 | char str[256]; | ||
486 | struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; | ||
487 | |||
488 | printk(arc_mmu_mumbojumbo(0, str, sizeof(str))); | ||
489 | |||
490 | /* For efficiency sake, kernel is compile time built for a MMU ver | ||
491 | * This must match the hardware it is running on. | ||
492 | * Linux built for MMU V2, if run on MMU V1 will break down because V1 | ||
493 | * hardware doesn't understand cmds such as WriteNI, or IVUTLB | ||
494 | * On the other hand, Linux built for V1 if run on MMU V2 will do | ||
495 | * un-needed workarounds to prevent memcpy thrashing. | ||
496 | * Similarly MMU V3 has new features which won't work on older MMU | ||
497 | */ | ||
498 | if (mmu->ver != CONFIG_ARC_MMU_VER) { | ||
499 | panic("MMU ver %d doesn't match kernel built for %d...\n", | ||
500 | mmu->ver, CONFIG_ARC_MMU_VER); | ||
501 | } | ||
502 | |||
503 | if (mmu->pg_sz != PAGE_SIZE) | ||
504 | panic("MMU pg size != PAGE_SIZE (%luk)\n", TO_KB(PAGE_SIZE)); | ||
505 | |||
468 | /* | 506 | /* |
469 | * ASID mgmt data structures are compile time init | 507 | * ASID mgmt data structures are compile time init |
470 | * asid_cache = FIRST_ASID and asid_mm_map[] all zeroes | 508 | * asid_cache = FIRST_ASID and asid_mm_map[] all zeroes |