aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2006-03-28 16:05:10 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-03-28 16:05:10 -0500
commitae574a5d7aa1d80469dfcbaa757db2bea536ee66 (patch)
tree6cfa7750df998359295227b76256d488f6d39d19
parentc4713074375c61f939310b04e92090afe29810dc (diff)
parentc760fc1997e8156ebc4134c42c18f68137c689f9 (diff)
Merge nommu tree
-rw-r--r--arch/arm/Kconfig8
-rw-r--r--arch/arm/Kconfig-nommu44
-rw-r--r--arch/arm/Makefile9
-rw-r--r--arch/arm/boot/compressed/head.S106
-rw-r--r--arch/arm/kernel/head-common.S217
-rw-r--r--arch/arm/kernel/head-nommu.S83
-rw-r--r--arch/arm/kernel/head.S207
-rw-r--r--arch/arm/kernel/signal.h2
-rw-r--r--arch/arm/kernel/traps.c9
9 files changed, 472 insertions, 213 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 427c72140110..1077c671256f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -72,6 +72,14 @@ config FIQ
72config ARCH_MTD_XIP 72config ARCH_MTD_XIP
73 bool 73 bool
74 74
75config VECTORS_BASE
76 hex
77 default 0xffff0000 if MMU
78 default DRAM_BASE if REMAP_VECTORS_TO_RAM
79 default 0x00000000
80 help
81 The base address of exception vectors.
82
75source "init/Kconfig" 83source "init/Kconfig"
76 84
77menu "System Type" 85menu "System Type"
diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu
new file mode 100644
index 000000000000..e1574be2ded6
--- /dev/null
+++ b/arch/arm/Kconfig-nommu
@@ -0,0 +1,44 @@
1#
2# Kconfig for uClinux(non-paged MM) depend configurations
3# Hyok S. Choi <hyok.choi@samsung.com>
4#
5
6config SET_MEM_PARAM
7 bool "Set flash/sdram size and base addr"
8 help
9 Say Y to manually set the base addresses and sizes.
10 otherwise, the default values are assigned.
11
12config DRAM_BASE
13 hex '(S)DRAM Base Address' if SET_MEM_PARAM
14 default 0x00800000
15
16config DRAM_SIZE
17 hex '(S)DRAM SIZE' if SET_MEM_PARAM
18 default 0x00800000
19
20config FLASH_MEM_BASE
21 hex 'FLASH Base Address' if SET_MEM_PARAM
22 default 0x00400000
23
24config FLASH_SIZE
25 hex 'FLASH Size' if SET_MEM_PARAM
26 default 0x00400000
27
28config REMAP_VECTORS_TO_RAM
29 bool 'Install vectors to the begining of RAM' if DRAM_BASE
30 depends on DRAM_BASE
31 help
32 The kernel needs to change the hardware exception vectors.
33 In nommu mode, the hardware exception vectors are normally
34 placed at address 0x00000000. However, this region may be
35 occupied by read-only memory depending on H/W design.
36
37 If the region contains read-write memory, say 'n' here.
38
39 If your CPU provides a remap facility which allows the exception
40 vectors to be mapped to writable memory, say 'n' here.
41
42 Otherwise, say 'y' here. In this case, the kernel will require
43 external support to redirect the hardware exception vectors to
44 the writable versions located at DRAM_BASE.
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index ce3e804ea0f3..95a96275f88a 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -20,6 +20,11 @@ GZFLAGS :=-9
20# Select a platform tht is kept up-to-date 20# Select a platform tht is kept up-to-date
21KBUILD_DEFCONFIG := versatile_defconfig 21KBUILD_DEFCONFIG := versatile_defconfig
22 22
23# defines filename extension depending memory manement type.
24ifeq ($(CONFIG_MMU),)
25MMUEXT := -nommu
26endif
27
23ifeq ($(CONFIG_FRAME_POINTER),y) 28ifeq ($(CONFIG_FRAME_POINTER),y)
24CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog 29CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
25endif 30endif
@@ -73,7 +78,7 @@ AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float
73CHECKFLAGS += -D__arm__ 78CHECKFLAGS += -D__arm__
74 79
75#Default value 80#Default value
76head-y := arch/arm/kernel/head.o arch/arm/kernel/init_task.o 81head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
77textofs-y := 0x00008000 82textofs-y := 0x00008000
78 83
79 machine-$(CONFIG_ARCH_RPC) := rpc 84 machine-$(CONFIG_ARCH_RPC) := rpc
@@ -133,7 +138,7 @@ else
133MACHINE := 138MACHINE :=
134endif 139endif
135 140
136export TEXT_OFFSET GZFLAGS 141export TEXT_OFFSET GZFLAGS MMUEXT
137 142
138# Do we have FASTFPE? 143# Do we have FASTFPE?
139FASTFPE :=arch/arm/fastfpe 144FASTFPE :=arch/arm/fastfpe
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 491c7e4c9ac6..b56f5e691d65 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -2,6 +2,7 @@
2 * linux/arch/arm/boot/compressed/head.S 2 * linux/arch/arm/boot/compressed/head.S
3 * 3 *
4 * Copyright (C) 1996-2002 Russell King 4 * Copyright (C) 1996-2002 Russell King
5 * Copyright (C) 2004 Hyok S. Choi (MPU support)
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -320,6 +321,62 @@ params: ldr r0, =params_phys
320cache_on: mov r3, #8 @ cache_on function 321cache_on: mov r3, #8 @ cache_on function
321 b call_cache_fn 322 b call_cache_fn
322 323
324/*
325 * Initialize the highest priority protection region, PR7
326 * to cover all 32bit address and cacheable and bufferable.
327 */
328__armv4_mpu_cache_on:
329 mov r0, #0x3f @ 4G, the whole
330 mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting
331 mcr p15, 0, r0, c6, c7, 1
332
333 mov r0, #0x80 @ PR7
334 mcr p15, 0, r0, c2, c0, 0 @ D-cache on
335 mcr p15, 0, r0, c2, c0, 1 @ I-cache on
336 mcr p15, 0, r0, c3, c0, 0 @ write-buffer on
337
338 mov r0, #0xc000
339 mcr p15, 0, r0, c5, c0, 1 @ I-access permission
340 mcr p15, 0, r0, c5, c0, 0 @ D-access permission
341
342 mov r0, #0
343 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
344 mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache
345 mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache
346 mrc p15, 0, r0, c1, c0, 0 @ read control reg
347 @ ...I .... ..D. WC.M
348 orr r0, r0, #0x002d @ .... .... ..1. 11.1
349 orr r0, r0, #0x1000 @ ...1 .... .... ....
350
351 mcr p15, 0, r0, c1, c0, 0 @ write control reg
352
353 mov r0, #0
354 mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache
355 mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache
356 mov pc, lr
357
358__armv3_mpu_cache_on:
359 mov r0, #0x3f @ 4G, the whole
360 mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting
361
362 mov r0, #0x80 @ PR7
363 mcr p15, 0, r0, c2, c0, 0 @ cache on
364 mcr p15, 0, r0, c3, c0, 0 @ write-buffer on
365
366 mov r0, #0xc000
367 mcr p15, 0, r0, c5, c0, 0 @ access permission
368
369 mov r0, #0
370 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
371 mrc p15, 0, r0, c1, c0, 0 @ read control reg
372 @ .... .... .... WC.M
373 orr r0, r0, #0x000d @ .... .... .... 11.1
374 mov r0, #0
375 mcr p15, 0, r0, c1, c0, 0 @ write control reg
376
377 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
378 mov pc, lr
379
323__setup_mmu: sub r3, r4, #16384 @ Page directory size 380__setup_mmu: sub r3, r4, #16384 @ Page directory size
324 bic r3, r3, #0xff @ Align the pointer 381 bic r3, r3, #0xff @ Align the pointer
325 bic r3, r3, #0x3f00 382 bic r3, r3, #0x3f00
@@ -496,6 +553,18 @@ proc_types:
496 b __armv4_mmu_cache_off 553 b __armv4_mmu_cache_off
497 mov pc, lr 554 mov pc, lr
498 555
556 .word 0x41007400 @ ARM74x
557 .word 0xff00ff00
558 b __armv3_mpu_cache_on
559 b __armv3_mpu_cache_off
560 b __armv3_mpu_cache_flush
561
562 .word 0x41009400 @ ARM94x
563 .word 0xff00ff00
564 b __armv4_mpu_cache_on
565 b __armv4_mpu_cache_off
566 b __armv4_mpu_cache_flush
567
499 .word 0x00007000 @ ARM7 IDs 568 .word 0x00007000 @ ARM7 IDs
500 .word 0x0000f000 569 .word 0x0000f000
501 mov pc, lr 570 mov pc, lr
@@ -562,6 +631,24 @@ proc_types:
562cache_off: mov r3, #12 @ cache_off function 631cache_off: mov r3, #12 @ cache_off function
563 b call_cache_fn 632 b call_cache_fn
564 633
634__armv4_mpu_cache_off:
635 mrc p15, 0, r0, c1, c0
636 bic r0, r0, #0x000d
637 mcr p15, 0, r0, c1, c0 @ turn MPU and cache off
638 mov r0, #0
639 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
640 mcr p15, 0, r0, c7, c6, 0 @ flush D-Cache
641 mcr p15, 0, r0, c7, c5, 0 @ flush I-Cache
642 mov pc, lr
643
644__armv3_mpu_cache_off:
645 mrc p15, 0, r0, c1, c0
646 bic r0, r0, #0x000d
647 mcr p15, 0, r0, c1, c0, 0 @ turn MPU and cache off
648 mov r0, #0
649 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
650 mov pc, lr
651
565__armv4_mmu_cache_off: 652__armv4_mmu_cache_off:
566 mrc p15, 0, r0, c1, c0 653 mrc p15, 0, r0, c1, c0
567 bic r0, r0, #0x000d 654 bic r0, r0, #0x000d
@@ -601,6 +688,24 @@ cache_clean_flush:
601 mov r3, #16 688 mov r3, #16
602 b call_cache_fn 689 b call_cache_fn
603 690
691__armv4_mpu_cache_flush:
692 mov r2, #1
693 mov r3, #0
694 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
695 mov r1, #7 << 5 @ 8 segments
6961: orr r3, r1, #63 << 26 @ 64 entries
6972: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index
698 subs r3, r3, #1 << 26
699 bcs 2b @ entries 63 to 0
700 subs r1, r1, #1 << 5
701 bcs 1b @ segments 7 to 0
702
703 teq r2, #0
704 mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
705 mcr p15, 0, ip, c7, c10, 4 @ drain WB
706 mov pc, lr
707
708
604__armv6_mmu_cache_flush: 709__armv6_mmu_cache_flush:
605 mov r1, #0 710 mov r1, #0
606 mcr p15, 0, r1, c7, c14, 0 @ clean+invalidate D 711 mcr p15, 0, r1, c7, c14, 0 @ clean+invalidate D
@@ -638,6 +743,7 @@ no_cache_id:
638 mov pc, lr 743 mov pc, lr
639 744
640__armv3_mmu_cache_flush: 745__armv3_mmu_cache_flush:
746__armv3_mpu_cache_flush:
641 mov r1, #0 747 mov r1, #0
642 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 748 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
643 mov pc, lr 749 mov pc, lr
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
new file mode 100644
index 000000000000..a52da0ddb43d
--- /dev/null
+++ b/arch/arm/kernel/head-common.S
@@ -0,0 +1,217 @@
1/*
2 * linux/arch/arm/kernel/head-common.S
3 *
4 * Copyright (C) 1994-2002 Russell King
5 * Copyright (c) 2003 ARM Limited
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14 .type __switch_data, %object
15__switch_data:
16 .long __mmap_switched
17 .long __data_loc @ r4
18 .long __data_start @ r5
19 .long __bss_start @ r6
20 .long _end @ r7
21 .long processor_id @ r4
22 .long __machine_arch_type @ r5
23 .long cr_alignment @ r6
24 .long init_thread_union + THREAD_START_SP @ sp
25
26/*
27 * The following fragment of code is executed with the MMU on in MMU mode,
28 * and uses absolute addresses; this is not position independent.
29 *
30 * r0 = cp#15 control register
31 * r1 = machine ID
32 * r9 = processor ID
33 */
34 .type __mmap_switched, %function
35__mmap_switched:
36 adr r3, __switch_data + 4
37
38 ldmia r3!, {r4, r5, r6, r7}
39 cmp r4, r5 @ Copy data segment if needed
401: cmpne r5, r6
41 ldrne fp, [r4], #4
42 strne fp, [r5], #4
43 bne 1b
44
45 mov fp, #0 @ Clear BSS (and zero fp)
461: cmp r6, r7
47 strcc fp, [r6],#4
48 bcc 1b
49
50 ldmia r3, {r4, r5, r6, sp}
51 str r9, [r4] @ Save processor ID
52 str r1, [r5] @ Save machine type
53 bic r4, r0, #CR_A @ Clear 'A' bit
54 stmia r6, {r0, r4} @ Save control register values
55 b start_kernel
56
57/*
58 * Exception handling. Something went wrong and we can't proceed. We
59 * ought to tell the user, but since we don't have any guarantee that
60 * we're even running on the right architecture, we do virtually nothing.
61 *
62 * If CONFIG_DEBUG_LL is set we try to print out something about the error
63 * and hope for the best (useful if bootloader fails to pass a proper
64 * machine ID for example).
65 */
66
67 .type __error_p, %function
68__error_p:
69#ifdef CONFIG_DEBUG_LL
70 adr r0, str_p1
71 bl printascii
72 b __error
73str_p1: .asciz "\nError: unrecognized/unsupported processor variant.\n"
74 .align
75#endif
76
77 .type __error_a, %function
78__error_a:
79#ifdef CONFIG_DEBUG_LL
80 mov r4, r1 @ preserve machine ID
81 adr r0, str_a1
82 bl printascii
83 mov r0, r4
84 bl printhex8
85 adr r0, str_a2
86 bl printascii
87 adr r3, 3f
88 ldmia r3, {r4, r5, r6} @ get machine desc list
89 sub r4, r3, r4 @ get offset between virt&phys
90 add r5, r5, r4 @ convert virt addresses to
91 add r6, r6, r4 @ physical address space
921: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type
93 bl printhex8
94 mov r0, #'\t'
95 bl printch
96 ldr r0, [r5, #MACHINFO_NAME] @ get machine name
97 add r0, r0, r4
98 bl printascii
99 mov r0, #'\n'
100 bl printch
101 add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
102 cmp r5, r6
103 blo 1b
104 adr r0, str_a3
105 bl printascii
106 b __error
107str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x"
108str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n"
109str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n"
110 .align
111#endif
112
113 .type __error, %function
114__error:
115#ifdef CONFIG_ARCH_RPC
116/*
117 * Turn the screen red on a error - RiscPC only.
118 */
119 mov r0, #0x02000000
120 mov r3, #0x11
121 orr r3, r3, r3, lsl #8
122 orr r3, r3, r3, lsl #16
123 str r3, [r0], #4
124 str r3, [r0], #4
125 str r3, [r0], #4
126 str r3, [r0], #4
127#endif
1281: mov r0, r0
129 b 1b
130
131
132/*
133 * Read processor ID register (CP#15, CR0), and look up in the linker-built
134 * supported processor list. Note that we can't use the absolute addresses
135 * for the __proc_info lists since we aren't running with the MMU on
136 * (and therefore, we are not in the correct address space). We have to
137 * calculate the offset.
138 *
139 * r9 = cpuid
140 * Returns:
141 * r3, r4, r6 corrupted
142 * r5 = proc_info pointer in physical address space
143 * r9 = cpuid (preserved)
144 */
145 .type __lookup_processor_type, %function
146__lookup_processor_type:
147 adr r3, 3f
148 ldmda r3, {r5 - r7}
149 sub r3, r3, r7 @ get offset between virt&phys
150 add r5, r5, r3 @ convert virt addresses to
151 add r6, r6, r3 @ physical address space
1521: ldmia r5, {r3, r4} @ value, mask
153 and r4, r4, r9 @ mask wanted bits
154 teq r3, r4
155 beq 2f
156 add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
157 cmp r5, r6
158 blo 1b
159 mov r5, #0 @ unknown processor
1602: mov pc, lr
161
162/*
163 * This provides a C-API version of the above function.
164 */
165ENTRY(lookup_processor_type)
166 stmfd sp!, {r4 - r7, r9, lr}
167 mov r9, r0
168 bl __lookup_processor_type
169 mov r0, r5
170 ldmfd sp!, {r4 - r7, r9, pc}
171
172/*
173 * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
174 * more information about the __proc_info and __arch_info structures.
175 */
176 .long __proc_info_begin
177 .long __proc_info_end
1783: .long .
179 .long __arch_info_begin
180 .long __arch_info_end
181
182/*
183 * Lookup machine architecture in the linker-build list of architectures.
184 * Note that we can't use the absolute addresses for the __arch_info
185 * lists since we aren't running with the MMU on (and therefore, we are
186 * not in the correct address space). We have to calculate the offset.
187 *
188 * r1 = machine architecture number
189 * Returns:
190 * r3, r4, r6 corrupted
191 * r5 = mach_info pointer in physical address space
192 */
193 .type __lookup_machine_type, %function
194__lookup_machine_type:
195 adr r3, 3b
196 ldmia r3, {r4, r5, r6}
197 sub r3, r3, r4 @ get offset between virt&phys
198 add r5, r5, r3 @ convert virt addresses to
199 add r6, r6, r3 @ physical address space
2001: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type
201 teq r3, r1 @ matches loader number?
202 beq 2f @ found
203 add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
204 cmp r5, r6
205 blo 1b
206 mov r5, #0 @ unknown machine
2072: mov pc, lr
208
209/*
210 * This provides a C-API version of the above function.
211 */
212ENTRY(lookup_machine_type)
213 stmfd sp!, {r4 - r6, lr}
214 mov r1, r0
215 bl __lookup_machine_type
216 mov r0, r5
217 ldmfd sp!, {r4 - r6, pc}
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
new file mode 100644
index 000000000000..b093ab8738b5
--- /dev/null
+++ b/arch/arm/kernel/head-nommu.S
@@ -0,0 +1,83 @@
1/*
2 * linux/arch/arm/kernel/head-nommu.S
3 *
4 * Copyright (C) 1994-2002 Russell King
5 * Copyright (C) 2003-2006 Hyok S. Choi
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Common kernel startup code (non-paged MM)
12 * for 32-bit CPUs which has a process ID register(CP15).
13 *
14 */
15#include <linux/config.h>
16#include <linux/linkage.h>
17#include <linux/init.h>
18
19#include <asm/assembler.h>
20#include <asm/mach-types.h>
21#include <asm/procinfo.h>
22#include <asm/ptrace.h>
23#include <asm/constants.h>
24#include <asm/system.h>
25
26#define PROCINFO_INITFUNC 12
27
28/*
29 * Kernel startup entry point.
30 * ---------------------------
31 *
32 * This is normally called from the decompressor code. The requirements
33 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
34 * r1 = machine nr.
35 *
36 * See linux/arch/arm/tools/mach-types for the complete list of machine
37 * numbers for r1.
38 *
39 */
40 __INIT
41 .type stext, %function
42ENTRY(stext)
43 msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode
44 @ and irqs disabled
45 mrc p15, 0, r9, c0, c0 @ get processor id
46 bl __lookup_processor_type @ r5=procinfo r9=cpuid
47 movs r10, r5 @ invalid processor (r5=0)?
48 beq __error_p @ yes, error 'p'
49 bl __lookup_machine_type @ r5=machinfo
50 movs r8, r5 @ invalid machine (r5=0)?
51 beq __error_a @ yes, error 'a'
52
53 ldr r13, __switch_data @ address to jump to after
54 @ the initialization is done
55 adr lr, __after_proc_init @ return (PIC) address
56 add pc, r10, #PROCINFO_INITFUNC
57
58/*
59 * Set the Control Register and Read the process ID.
60 */
61 .type __after_proc_init, %function
62__after_proc_init:
63 mrc p15, 0, r0, c1, c0, 0 @ read control reg
64#ifdef CONFIG_ALIGNMENT_TRAP
65 orr r0, r0, #CR_A
66#else
67 bic r0, r0, #CR_A
68#endif
69#ifdef CONFIG_CPU_DCACHE_DISABLE
70 bic r0, r0, #CR_C
71#endif
72#ifdef CONFIG_CPU_BPREDICT_DISABLE
73 bic r0, r0, #CR_Z
74#endif
75#ifdef CONFIG_CPU_ICACHE_DISABLE
76 bic r0, r0, #CR_I
77#endif
78 mcr p15, 0, r0, c1, c0, 0 @ write control reg
79
80 mov pc, r13 @ clear the BSS and jump
81 @ to start_kernel
82
83#include "head-common.S"
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 53b6901f70a6..04b66a9328ef 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -102,49 +102,6 @@ ENTRY(stext)
102 adr lr, __enable_mmu @ return (PIC) address 102 adr lr, __enable_mmu @ return (PIC) address
103 add pc, r10, #PROCINFO_INITFUNC 103 add pc, r10, #PROCINFO_INITFUNC
104 104
105 .type __switch_data, %object
106__switch_data:
107 .long __mmap_switched
108 .long __data_loc @ r4
109 .long __data_start @ r5
110 .long __bss_start @ r6
111 .long _end @ r7
112 .long processor_id @ r4
113 .long __machine_arch_type @ r5
114 .long cr_alignment @ r6
115 .long init_thread_union + THREAD_START_SP @ sp
116
117/*
118 * The following fragment of code is executed with the MMU on, and uses
119 * absolute addresses; this is not position independent.
120 *
121 * r0 = cp#15 control register
122 * r1 = machine ID
123 * r9 = processor ID
124 */
125 .type __mmap_switched, %function
126__mmap_switched:
127 adr r3, __switch_data + 4
128
129 ldmia r3!, {r4, r5, r6, r7}
130 cmp r4, r5 @ Copy data segment if needed
1311: cmpne r5, r6
132 ldrne fp, [r4], #4
133 strne fp, [r5], #4
134 bne 1b
135
136 mov fp, #0 @ Clear BSS (and zero fp)
1371: cmp r6, r7
138 strcc fp, [r6],#4
139 bcc 1b
140
141 ldmia r3, {r4, r5, r6, sp}
142 str r9, [r4] @ Save processor ID
143 str r1, [r5] @ Save machine type
144 bic r4, r0, #CR_A @ Clear 'A' bit
145 stmia r6, {r0, r4} @ Save control register values
146 b start_kernel
147
148#if defined(CONFIG_SMP) 105#if defined(CONFIG_SMP)
149 .type secondary_startup, #function 106 .type secondary_startup, #function
150ENTRY(secondary_startup) 107ENTRY(secondary_startup)
@@ -367,166 +324,4 @@ __create_page_tables:
367 mov pc, lr 324 mov pc, lr
368 .ltorg 325 .ltorg
369 326
370 327#include "head-common.S"
371
372/*
373 * Exception handling. Something went wrong and we can't proceed. We
374 * ought to tell the user, but since we don't have any guarantee that
375 * we're even running on the right architecture, we do virtually nothing.
376 *
377 * If CONFIG_DEBUG_LL is set we try to print out something about the error
378 * and hope for the best (useful if bootloader fails to pass a proper
379 * machine ID for example).
380 */
381
382 .type __error_p, %function
383__error_p:
384#ifdef CONFIG_DEBUG_LL
385 adr r0, str_p1
386 bl printascii
387 b __error
388str_p1: .asciz "\nError: unrecognized/unsupported processor variant.\n"
389 .align
390#endif
391
392 .type __error_a, %function
393__error_a:
394#ifdef CONFIG_DEBUG_LL
395 mov r4, r1 @ preserve machine ID
396 adr r0, str_a1
397 bl printascii
398 mov r0, r4
399 bl printhex8
400 adr r0, str_a2
401 bl printascii
402 adr r3, 3f
403 ldmia r3, {r4, r5, r6} @ get machine desc list
404 sub r4, r3, r4 @ get offset between virt&phys
405 add r5, r5, r4 @ convert virt addresses to
406 add r6, r6, r4 @ physical address space
4071: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type
408 bl printhex8
409 mov r0, #'\t'
410 bl printch
411 ldr r0, [r5, #MACHINFO_NAME] @ get machine name
412 add r0, r0, r4
413 bl printascii
414 mov r0, #'\n'
415 bl printch
416 add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
417 cmp r5, r6
418 blo 1b
419 adr r0, str_a3
420 bl printascii
421 b __error
422str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x"
423str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n"
424str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n"
425 .align
426#endif
427
428 .type __error, %function
429__error:
430#ifdef CONFIG_ARCH_RPC
431/*
432 * Turn the screen red on a error - RiscPC only.
433 */
434 mov r0, #0x02000000
435 mov r3, #0x11
436 orr r3, r3, r3, lsl #8
437 orr r3, r3, r3, lsl #16
438 str r3, [r0], #4
439 str r3, [r0], #4
440 str r3, [r0], #4
441 str r3, [r0], #4
442#endif
4431: mov r0, r0
444 b 1b
445
446
447/*
448 * Read processor ID register (CP#15, CR0), and look up in the linker-built
449 * supported processor list. Note that we can't use the absolute addresses
450 * for the __proc_info lists since we aren't running with the MMU on
451 * (and therefore, we are not in the correct address space). We have to
452 * calculate the offset.
453 *
454 * r9 = cpuid
455 * Returns:
456 * r3, r4, r6 corrupted
457 * r5 = proc_info pointer in physical address space
458 * r9 = cpuid (preserved)
459 */
460 .type __lookup_processor_type, %function
461__lookup_processor_type:
462 adr r3, 3f
463 ldmda r3, {r5 - r7}
464 sub r3, r3, r7 @ get offset between virt&phys
465 add r5, r5, r3 @ convert virt addresses to
466 add r6, r6, r3 @ physical address space
4671: ldmia r5, {r3, r4} @ value, mask
468 and r4, r4, r9 @ mask wanted bits
469 teq r3, r4
470 beq 2f
471 add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
472 cmp r5, r6
473 blo 1b
474 mov r5, #0 @ unknown processor
4752: mov pc, lr
476
477/*
478 * This provides a C-API version of the above function.
479 */
480ENTRY(lookup_processor_type)
481 stmfd sp!, {r4 - r7, r9, lr}
482 mov r9, r0
483 bl __lookup_processor_type
484 mov r0, r5
485 ldmfd sp!, {r4 - r7, r9, pc}
486
487/*
488 * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
489 * more information about the __proc_info and __arch_info structures.
490 */
491 .long __proc_info_begin
492 .long __proc_info_end
4933: .long .
494 .long __arch_info_begin
495 .long __arch_info_end
496
497/*
498 * Lookup machine architecture in the linker-build list of architectures.
499 * Note that we can't use the absolute addresses for the __arch_info
500 * lists since we aren't running with the MMU on (and therefore, we are
501 * not in the correct address space). We have to calculate the offset.
502 *
503 * r1 = machine architecture number
504 * Returns:
505 * r3, r4, r6 corrupted
506 * r5 = mach_info pointer in physical address space
507 */
508 .type __lookup_machine_type, %function
509__lookup_machine_type:
510 adr r3, 3b
511 ldmia r3, {r4, r5, r6}
512 sub r3, r3, r4 @ get offset between virt&phys
513 add r5, r5, r3 @ convert virt addresses to
514 add r6, r6, r3 @ physical address space
5151: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type
516 teq r3, r1 @ matches loader number?
517 beq 2f @ found
518 add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
519 cmp r5, r6
520 blo 1b
521 mov r5, #0 @ unknown machine
5222: mov pc, lr
523
524/*
525 * This provides a C-API version of the above function.
526 */
527ENTRY(lookup_machine_type)
528 stmfd sp!, {r4 - r6, lr}
529 mov r1, r0
530 bl __lookup_machine_type
531 mov r0, r5
532 ldmfd sp!, {r4 - r6, pc}
diff --git a/arch/arm/kernel/signal.h b/arch/arm/kernel/signal.h
index 9991049c522d..27beece15502 100644
--- a/arch/arm/kernel/signal.h
+++ b/arch/arm/kernel/signal.h
@@ -7,6 +7,6 @@
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10#define KERN_SIGRETURN_CODE 0xffff0500 10#define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500)
11 11
12extern const unsigned long sigreturn_codes[7]; 12extern const unsigned long sigreturn_codes[7];
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index d566d5f4574d..35230a060108 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -688,6 +688,7 @@ EXPORT_SYMBOL(abort);
688 688
689void __init trap_init(void) 689void __init trap_init(void)
690{ 690{
691 unsigned long vectors = CONFIG_VECTORS_BASE;
691 extern char __stubs_start[], __stubs_end[]; 692 extern char __stubs_start[], __stubs_end[];
692 extern char __vectors_start[], __vectors_end[]; 693 extern char __vectors_start[], __vectors_end[];
693 extern char __kuser_helper_start[], __kuser_helper_end[]; 694 extern char __kuser_helper_start[], __kuser_helper_end[];
@@ -698,9 +699,9 @@ void __init trap_init(void)
698 * into the vector page, mapped at 0xffff0000, and ensure these 699 * into the vector page, mapped at 0xffff0000, and ensure these
699 * are visible to the instruction stream. 700 * are visible to the instruction stream.
700 */ 701 */
701 memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start); 702 memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
702 memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start); 703 memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);
703 memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz); 704 memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
704 705
705 /* 706 /*
706 * Copy signal return handlers into the vector page, and 707 * Copy signal return handlers into the vector page, and
@@ -709,6 +710,6 @@ void __init trap_init(void)
709 memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes, 710 memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
710 sizeof(sigreturn_codes)); 711 sizeof(sigreturn_codes));
711 712
712 flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE); 713 flush_icache_range(vectors, vectors + PAGE_SIZE);
713 modify_domain(DOMAIN_USER, DOMAIN_CLIENT); 714 modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
714} 715}