diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-01-12 12:50:42 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-02-15 11:36:44 -0500 |
commit | 6fc31d54443bdc25a8166be15e3920a7e39d195d (patch) | |
tree | 70ae632dec09e31e7db475de53ee620c2bf1c183 | |
parent | ebf53826e105f488f4f628703a108e98940d1dc5 (diff) |
ARM: Defer lookup of machine_type to setup.c
Since the debug macros no longer depend on the machine type information,
the machine type lookup can be deferred to setup_arch() in setup.c which
simplifies the code somewhat.
We also move the __error_a functionality into setup.c for displaying a
message when a bad machine ID is passed to the kernel via the LL debug
code. We also log this into the kernel ring buffer which makes it
possible to retrieve the message via a debugger.
Original idea from Grant Likely.
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Tested-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | arch/arm/kernel/head-common.S | 90 | ||||
-rw-r--r-- | arch/arm/kernel/head-nommu.S | 3 | ||||
-rw-r--r-- | arch/arm/kernel/head.S | 9 | ||||
-rw-r--r-- | arch/arm/kernel/setup.c | 39 |
4 files changed, 40 insertions, 101 deletions
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 8f57515bbdb0..c84b57d27d07 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S | |||
@@ -25,83 +25,6 @@ | |||
25 | * machine ID for example). | 25 | * machine ID for example). |
26 | */ | 26 | */ |
27 | __HEAD | 27 | __HEAD |
28 | __error_a: | ||
29 | #ifdef CONFIG_DEBUG_LL | ||
30 | mov r4, r1 @ preserve machine ID | ||
31 | adr r0, str_a1 | ||
32 | bl printascii | ||
33 | mov r0, r4 | ||
34 | bl printhex8 | ||
35 | adr r0, str_a2 | ||
36 | bl printascii | ||
37 | adr r3, __lookup_machine_type_data | ||
38 | ldmia r3, {r4, r5, r6} @ get machine desc list | ||
39 | sub r4, r3, r4 @ get offset between virt&phys | ||
40 | add r5, r5, r4 @ convert virt addresses to | ||
41 | add r6, r6, r4 @ physical address space | ||
42 | 1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type | ||
43 | bl printhex8 | ||
44 | mov r0, #'\t' | ||
45 | bl printch | ||
46 | ldr r0, [r5, #MACHINFO_NAME] @ get machine name | ||
47 | add r0, r0, r4 | ||
48 | bl printascii | ||
49 | mov r0, #'\n' | ||
50 | bl printch | ||
51 | add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc | ||
52 | cmp r5, r6 | ||
53 | blo 1b | ||
54 | adr r0, str_a3 | ||
55 | bl printascii | ||
56 | b __error | ||
57 | ENDPROC(__error_a) | ||
58 | |||
59 | str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x" | ||
60 | str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n" | ||
61 | str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n" | ||
62 | .align | ||
63 | #else | ||
64 | b __error | ||
65 | #endif | ||
66 | |||
67 | /* | ||
68 | * Lookup machine architecture in the linker-build list of architectures. | ||
69 | * Note that we can't use the absolute addresses for the __arch_info | ||
70 | * lists since we aren't running with the MMU on (and therefore, we are | ||
71 | * not in the correct address space). We have to calculate the offset. | ||
72 | * | ||
73 | * r1 = machine architecture number | ||
74 | * Returns: | ||
75 | * r3, r4, r6 corrupted | ||
76 | * r5 = mach_info pointer in physical address space | ||
77 | */ | ||
78 | __lookup_machine_type: | ||
79 | adr r3, __lookup_machine_type_data | ||
80 | ldmia r3, {r4, r5, r6} | ||
81 | sub r3, r3, r4 @ get offset between virt&phys | ||
82 | add r5, r5, r3 @ convert virt addresses to | ||
83 | add r6, r6, r3 @ physical address space | ||
84 | 1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type | ||
85 | teq r3, r1 @ matches loader number? | ||
86 | beq 2f @ found | ||
87 | add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc | ||
88 | cmp r5, r6 | ||
89 | blo 1b | ||
90 | mov r5, #0 @ unknown machine | ||
91 | 2: mov pc, lr | ||
92 | ENDPROC(__lookup_machine_type) | ||
93 | |||
94 | /* | ||
95 | * Look in arch/arm/kernel/arch.[ch] for information about the | ||
96 | * __arch_info structures. | ||
97 | */ | ||
98 | .align 2 | ||
99 | .type __lookup_machine_type_data, %object | ||
100 | __lookup_machine_type_data: | ||
101 | .long . | ||
102 | .long __arch_info_begin | ||
103 | .long __arch_info_end | ||
104 | .size __lookup_machine_type_data, . - __lookup_machine_type_data | ||
105 | 28 | ||
106 | /* Determine validity of the r2 atags pointer. The heuristic requires | 29 | /* Determine validity of the r2 atags pointer. The heuristic requires |
107 | * that the pointer be aligned, in the first 16k of physical RAM and | 30 | * that the pointer be aligned, in the first 16k of physical RAM and |
@@ -109,8 +32,6 @@ __lookup_machine_type_data: | |||
109 | * of this function may be more lenient with the physical address and | 32 | * of this function may be more lenient with the physical address and |
110 | * may also be able to move the ATAGS block if necessary. | 33 | * may also be able to move the ATAGS block if necessary. |
111 | * | 34 | * |
112 | * r8 = machinfo | ||
113 | * | ||
114 | * Returns: | 35 | * Returns: |
115 | * r2 either valid atags pointer, or zero | 36 | * r2 either valid atags pointer, or zero |
116 | * r5, r6 corrupted | 37 | * r5, r6 corrupted |
@@ -185,17 +106,6 @@ __mmap_switched_data: | |||
185 | .size __mmap_switched_data, . - __mmap_switched_data | 106 | .size __mmap_switched_data, . - __mmap_switched_data |
186 | 107 | ||
187 | /* | 108 | /* |
188 | * This provides a C-API version of __lookup_machine_type | ||
189 | */ | ||
190 | ENTRY(lookup_machine_type) | ||
191 | stmfd sp!, {r4 - r6, lr} | ||
192 | mov r1, r0 | ||
193 | bl __lookup_machine_type | ||
194 | mov r0, r5 | ||
195 | ldmfd sp!, {r4 - r6, pc} | ||
196 | ENDPROC(lookup_machine_type) | ||
197 | |||
198 | /* | ||
199 | * This provides a C-API version of __lookup_processor_type | 109 | * This provides a C-API version of __lookup_processor_type |
200 | */ | 110 | */ |
201 | ENTRY(lookup_processor_type) | 111 | ENTRY(lookup_processor_type) |
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index 814ce1a73270..6b1e0ad9ec3b 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S | |||
@@ -44,9 +44,6 @@ ENTRY(stext) | |||
44 | bl __lookup_processor_type @ r5=procinfo r9=cpuid | 44 | bl __lookup_processor_type @ r5=procinfo r9=cpuid |
45 | movs r10, r5 @ invalid processor (r5=0)? | 45 | movs r10, r5 @ invalid processor (r5=0)? |
46 | beq __error_p @ yes, error 'p' | 46 | beq __error_p @ yes, error 'p' |
47 | bl __lookup_machine_type @ r5=machinfo | ||
48 | movs r8, r5 @ invalid machine (r5=0)? | ||
49 | beq __error_a @ yes, error 'a' | ||
50 | 47 | ||
51 | adr lr, BSYM(__after_proc_init) @ return (PIC) address | 48 | adr lr, BSYM(__after_proc_init) @ return (PIC) address |
52 | ARM( add pc, r10, #PROCINFO_INITFUNC ) | 49 | ARM( add pc, r10, #PROCINFO_INITFUNC ) |
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index c0225da3fb21..8a154b940fef 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
@@ -87,14 +87,10 @@ ENTRY(stext) | |||
87 | movs r10, r5 @ invalid processor (r5=0)? | 87 | movs r10, r5 @ invalid processor (r5=0)? |
88 | THUMB( it eq ) @ force fixup-able long branch encoding | 88 | THUMB( it eq ) @ force fixup-able long branch encoding |
89 | beq __error_p @ yes, error 'p' | 89 | beq __error_p @ yes, error 'p' |
90 | bl __lookup_machine_type @ r5=machinfo | ||
91 | movs r8, r5 @ invalid machine (r5=0)? | ||
92 | THUMB( it eq ) @ force fixup-able long branch encoding | ||
93 | beq __error_a @ yes, error 'a' | ||
94 | 90 | ||
95 | /* | 91 | /* |
96 | * r1 = machine no, r2 = atags, | 92 | * r1 = machine no, r2 = atags, |
97 | * r8 = machinfo, r9 = cpuid, r10 = procinfo | 93 | * r9 = cpuid, r10 = procinfo |
98 | */ | 94 | */ |
99 | bl __vet_atags | 95 | bl __vet_atags |
100 | #ifdef CONFIG_SMP_ON_UP | 96 | #ifdef CONFIG_SMP_ON_UP |
@@ -105,7 +101,7 @@ ENTRY(stext) | |||
105 | /* | 101 | /* |
106 | * The following calls CPU specific code in a position independent | 102 | * The following calls CPU specific code in a position independent |
107 | * manner. See arch/arm/mm/proc-*.S for details. r10 = base of | 103 | * manner. See arch/arm/mm/proc-*.S for details. r10 = base of |
108 | * xxx_proc_info structure selected by __lookup_machine_type | 104 | * xxx_proc_info structure selected by __lookup_processor_type |
109 | * above. On return, the CPU will be ready for the MMU to be | 105 | * above. On return, the CPU will be ready for the MMU to be |
110 | * turned on, and r0 will hold the CPU control register value. | 106 | * turned on, and r0 will hold the CPU control register value. |
111 | */ | 107 | */ |
@@ -124,7 +120,6 @@ ENDPROC(stext) | |||
124 | * amount which are required to get the kernel running, which | 120 | * amount which are required to get the kernel running, which |
125 | * generally means mapping in the kernel code. | 121 | * generally means mapping in the kernel code. |
126 | * | 122 | * |
127 | * r8 = machinfo | ||
128 | * r9 = cpuid | 123 | * r9 = cpuid |
129 | * r10 = procinfo | 124 | * r10 = procinfo |
130 | * | 125 | * |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 420b8d6485d6..78678b07901c 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -308,7 +308,44 @@ static void __init cacheid_init(void) | |||
308 | * already provide the required functionality. | 308 | * already provide the required functionality. |
309 | */ | 309 | */ |
310 | extern struct proc_info_list *lookup_processor_type(unsigned int); | 310 | extern struct proc_info_list *lookup_processor_type(unsigned int); |
311 | extern struct machine_desc *lookup_machine_type(unsigned int); | 311 | |
312 | static void __init early_print(const char *str, ...) | ||
313 | { | ||
314 | extern void printascii(const char *); | ||
315 | char buf[256]; | ||
316 | va_list ap; | ||
317 | |||
318 | va_start(ap, str); | ||
319 | vsnprintf(buf, sizeof(buf), str, ap); | ||
320 | va_end(ap); | ||
321 | |||
322 | #ifdef CONFIG_DEBUG_LL | ||
323 | printascii(buf); | ||
324 | #endif | ||
325 | printk("%s", buf); | ||
326 | } | ||
327 | |||
328 | static struct machine_desc * __init lookup_machine_type(unsigned int type) | ||
329 | { | ||
330 | extern struct machine_desc __arch_info_begin[], __arch_info_end[]; | ||
331 | struct machine_desc *p; | ||
332 | |||
333 | for (p = __arch_info_begin; p < __arch_info_end; p++) | ||
334 | if (type == p->nr) | ||
335 | return p; | ||
336 | |||
337 | early_print("\n" | ||
338 | "Error: unrecognized/unsupported machine ID (r1 = 0x%08x).\n\n" | ||
339 | "Available machine support:\n\nID (hex)\tNAME\n", type); | ||
340 | |||
341 | for (p = __arch_info_begin; p < __arch_info_end; p++) | ||
342 | early_print("%08x\t%s\n", p->nr, p->name); | ||
343 | |||
344 | early_print("\nPlease check your kernel config and/or bootloader.\n"); | ||
345 | |||
346 | while (true) | ||
347 | /* can't use cpu_relax() here as it may require MMU setup */; | ||
348 | } | ||
312 | 349 | ||
313 | static void __init feat_v6_fixup(void) | 350 | static void __init feat_v6_fixup(void) |
314 | { | 351 | { |