aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/head.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/head.S')
-rw-r--r--arch/arm/kernel/head.S135
1 files changed, 52 insertions, 83 deletions
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 742b6108a00..239703dbdf4 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -21,6 +21,7 @@
21#include <asm/memory.h> 21#include <asm/memory.h>
22#include <asm/thread_info.h> 22#include <asm/thread_info.h>
23#include <asm/system.h> 23#include <asm/system.h>
24#include <asm/pgtable.h>
24 25
25#ifdef CONFIG_DEBUG_LL 26#ifdef CONFIG_DEBUG_LL
26#include <mach/debug-macro.S> 27#include <mach/debug-macro.S>
@@ -38,11 +39,14 @@
38#error KERNEL_RAM_VADDR must start at 0xXXXX8000 39#error KERNEL_RAM_VADDR must start at 0xXXXX8000
39#endif 40#endif
40 41
42#define PG_DIR_SIZE 0x4000
43#define PMD_ORDER 2
44
41 .globl swapper_pg_dir 45 .globl swapper_pg_dir
42 .equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000 46 .equ swapper_pg_dir, KERNEL_RAM_VADDR - PG_DIR_SIZE
43 47
44 .macro pgtbl, rd, phys 48 .macro pgtbl, rd, phys
45 add \rd, \phys, #TEXT_OFFSET - 0x4000 49 add \rd, \phys, #TEXT_OFFSET - PG_DIR_SIZE
46 .endm 50 .endm
47 51
48#ifdef CONFIG_XIP_KERNEL 52#ifdef CONFIG_XIP_KERNEL
@@ -148,11 +152,11 @@ __create_page_tables:
148 pgtbl r4, r8 @ page table address 152 pgtbl r4, r8 @ page table address
149 153
150 /* 154 /*
151 * Clear the 16K level 1 swapper page table 155 * Clear the swapper page table
152 */ 156 */
153 mov r0, r4 157 mov r0, r4
154 mov r3, #0 158 mov r3, #0
155 add r6, r0, #0x4000 159 add r6, r0, #PG_DIR_SIZE
1561: str r3, [r0], #4 1601: str r3, [r0], #4
157 str r3, [r0], #4 161 str r3, [r0], #4
158 str r3, [r0], #4 162 str r3, [r0], #4
@@ -171,30 +175,30 @@ __create_page_tables:
171 sub r0, r0, r3 @ virt->phys offset 175 sub r0, r0, r3 @ virt->phys offset
172 add r5, r5, r0 @ phys __enable_mmu 176 add r5, r5, r0 @ phys __enable_mmu
173 add r6, r6, r0 @ phys __enable_mmu_end 177 add r6, r6, r0 @ phys __enable_mmu_end
174 mov r5, r5, lsr #20 178 mov r5, r5, lsr #SECTION_SHIFT
175 mov r6, r6, lsr #20 179 mov r6, r6, lsr #SECTION_SHIFT
176 180
1771: orr r3, r7, r5, lsl #20 @ flags + kernel base 1811: orr r3, r7, r5, lsl #SECTION_SHIFT @ flags + kernel base
178 str r3, [r4, r5, lsl #2] @ identity mapping 182 str r3, [r4, r5, lsl #PMD_ORDER] @ identity mapping
179 teq r5, r6 183 cmp r5, r6
180 addne r5, r5, #1 @ next section 184 addlo r5, r5, #1 @ next section
181 bne 1b 185 blo 1b
182 186
183 /* 187 /*
184 * Now setup the pagetables for our kernel direct 188 * Now setup the pagetables for our kernel direct
185 * mapped region. 189 * mapped region.
186 */ 190 */
187 mov r3, pc 191 mov r3, pc
188 mov r3, r3, lsr #20 192 mov r3, r3, lsr #SECTION_SHIFT
189 orr r3, r7, r3, lsl #20 193 orr r3, r7, r3, lsl #SECTION_SHIFT
190 add r0, r4, #(KERNEL_START & 0xff000000) >> 18 194 add r0, r4, #(KERNEL_START & 0xff000000) >> (SECTION_SHIFT - PMD_ORDER)
191 str r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]! 195 str r3, [r0, #((KERNEL_START & 0x00f00000) >> SECTION_SHIFT) << PMD_ORDER]!
192 ldr r6, =(KERNEL_END - 1) 196 ldr r6, =(KERNEL_END - 1)
193 add r0, r0, #4 197 add r0, r0, #1 << PMD_ORDER
194 add r6, r4, r6, lsr #18 198 add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
1951: cmp r0, r6 1991: cmp r0, r6
196 add r3, r3, #1 << 20 200 add r3, r3, #1 << SECTION_SHIFT
197 strls r3, [r0], #4 201 strls r3, [r0], #1 << PMD_ORDER
198 bls 1b 202 bls 1b
199 203
200#ifdef CONFIG_XIP_KERNEL 204#ifdef CONFIG_XIP_KERNEL
@@ -203,11 +207,11 @@ __create_page_tables:
203 */ 207 */
204 add r3, r8, #TEXT_OFFSET 208 add r3, r8, #TEXT_OFFSET
205 orr r3, r3, r7 209 orr r3, r3, r7
206 add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18 210 add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> (SECTION_SHIFT - PMD_ORDER)
207 str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]! 211 str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> (SECTION_SHIFT - PMD_ORDER)]!
208 ldr r6, =(_end - 1) 212 ldr r6, =(_end - 1)
209 add r0, r0, #4 213 add r0, r0, #4
210 add r6, r4, r6, lsr #18 214 add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
2111: cmp r0, r6 2151: cmp r0, r6
212 add r3, r3, #1 << 20 216 add r3, r3, #1 << 20
213 strls r3, [r0], #4 217 strls r3, [r0], #4
@@ -218,12 +222,12 @@ __create_page_tables:
218 * Then map boot params address in r2 or 222 * Then map boot params address in r2 or
219 * the first 1MB of ram if boot params address is not specified. 223 * the first 1MB of ram if boot params address is not specified.
220 */ 224 */
221 mov r0, r2, lsr #20 225 mov r0, r2, lsr #SECTION_SHIFT
222 movs r0, r0, lsl #20 226 movs r0, r0, lsl #SECTION_SHIFT
223 moveq r0, r8 227 moveq r0, r8
224 sub r3, r0, r8 228 sub r3, r0, r8
225 add r3, r3, #PAGE_OFFSET 229 add r3, r3, #PAGE_OFFSET
226 add r3, r4, r3, lsr #18 230 add r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER)
227 orr r6, r7, r0 231 orr r6, r7, r0
228 str r6, [r3] 232 str r6, [r3]
229 233
@@ -236,21 +240,21 @@ __create_page_tables:
236 */ 240 */
237 addruart r7, r3 241 addruart r7, r3
238 242
239 mov r3, r3, lsr #20 243 mov r3, r3, lsr #SECTION_SHIFT
240 mov r3, r3, lsl #2 244 mov r3, r3, lsl #PMD_ORDER
241 245
242 add r0, r4, r3 246 add r0, r4, r3
243 rsb r3, r3, #0x4000 @ PTRS_PER_PGD*sizeof(long) 247 rsb r3, r3, #0x4000 @ PTRS_PER_PGD*sizeof(long)
244 cmp r3, #0x0800 @ limit to 512MB 248 cmp r3, #0x0800 @ limit to 512MB
245 movhi r3, #0x0800 249 movhi r3, #0x0800
246 add r6, r0, r3 250 add r6, r0, r3
247 mov r3, r7, lsr #20 251 mov r3, r7, lsr #SECTION_SHIFT
248 ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags 252 ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
249 orr r3, r7, r3, lsl #20 253 orr r3, r7, r3, lsl #SECTION_SHIFT
2501: str r3, [r0], #4 2541: str r3, [r0], #4
251 add r3, r3, #1 << 20 255 add r3, r3, #1 << SECTION_SHIFT
252 teq r0, r6 256 cmp r0, r6
253 bne 1b 257 blo 1b
254 258
255#else /* CONFIG_DEBUG_ICEDCC */ 259#else /* CONFIG_DEBUG_ICEDCC */
256 /* we don't need any serial debugging mappings for ICEDCC */ 260 /* we don't need any serial debugging mappings for ICEDCC */
@@ -262,7 +266,7 @@ __create_page_tables:
262 * If we're using the NetWinder or CATS, we also need to map 266 * If we're using the NetWinder or CATS, we also need to map
263 * in the 16550-type serial port for the debug messages 267 * in the 16550-type serial port for the debug messages
264 */ 268 */
265 add r0, r4, #0xff000000 >> 18 269 add r0, r4, #0xff000000 >> (SECTION_SHIFT - PMD_ORDER)
266 orr r3, r7, #0x7c000000 270 orr r3, r7, #0x7c000000
267 str r3, [r0] 271 str r3, [r0]
268#endif 272#endif
@@ -272,10 +276,10 @@ __create_page_tables:
272 * Similar reasons here - for debug. This is 276 * Similar reasons here - for debug. This is
273 * only for Acorn RiscPC architectures. 277 * only for Acorn RiscPC architectures.
274 */ 278 */
275 add r0, r4, #0x02000000 >> 18 279 add r0, r4, #0x02000000 >> (SECTION_SHIFT - PMD_ORDER)
276 orr r3, r7, #0x02000000 280 orr r3, r7, #0x02000000
277 str r3, [r0] 281 str r3, [r0]
278 add r0, r4, #0xd8000000 >> 18 282 add r0, r4, #0xd8000000 >> (SECTION_SHIFT - PMD_ORDER)
279 str r3, [r0] 283 str r3, [r0]
280#endif 284#endif
281#endif 285#endif
@@ -488,13 +492,8 @@ __fixup_pv_table:
488 add r5, r5, r3 @ adjust table end address 492 add r5, r5, r3 @ adjust table end address
489 add r7, r7, r3 @ adjust __pv_phys_offset address 493 add r7, r7, r3 @ adjust __pv_phys_offset address
490 str r8, [r7] @ save computed PHYS_OFFSET to __pv_phys_offset 494 str r8, [r7] @ save computed PHYS_OFFSET to __pv_phys_offset
491#ifndef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
492 mov r6, r3, lsr #24 @ constant for add/sub instructions 495 mov r6, r3, lsr #24 @ constant for add/sub instructions
493 teq r3, r6, lsl #24 @ must be 16MiB aligned 496 teq r3, r6, lsl #24 @ must be 16MiB aligned
494#else
495 mov r6, r3, lsr #16 @ constant for add/sub instructions
496 teq r3, r6, lsl #16 @ must be 64kiB aligned
497#endif
498THUMB( it ne @ cross section branch ) 497THUMB( it ne @ cross section branch )
499 bne __error 498 bne __error
500 str r6, [r7, #4] @ save to __pv_offset 499 str r6, [r7, #4] @ save to __pv_offset
@@ -510,20 +509,8 @@ ENDPROC(__fixup_pv_table)
510 .text 509 .text
511__fixup_a_pv_table: 510__fixup_a_pv_table:
512#ifdef CONFIG_THUMB2_KERNEL 511#ifdef CONFIG_THUMB2_KERNEL
513#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT 512 lsls r6, #24
514 lsls r0, r6, #24 513 beq 2f
515 lsr r6, #8
516 beq 1f
517 clz r7, r0
518 lsr r0, #24
519 lsl r0, r7
520 bic r0, 0x0080
521 lsrs r7, #1
522 orrcs r0, #0x0080
523 orr r0, r0, r7, lsl #12
524#endif
5251: lsls r6, #24
526 beq 4f
527 clz r7, r6 514 clz r7, r6
528 lsr r6, #24 515 lsr r6, #24
529 lsl r6, r7 516 lsl r6, r7
@@ -532,43 +519,25 @@ __fixup_a_pv_table:
532 orrcs r6, #0x0080 519 orrcs r6, #0x0080
533 orr r6, r6, r7, lsl #12 520 orr r6, r6, r7, lsl #12
534 orr r6, #0x4000 521 orr r6, #0x4000
535 b 4f 522 b 2f
5362: @ at this point the C flag is always clear 5231: add r7, r3
537 add r7, r3 524 ldrh ip, [r7, #2]
538#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
539 ldrh ip, [r7]
540 tst ip, 0x0400 @ the i bit tells us LS or MS byte
541 beq 3f
542 cmp r0, #0 @ set C flag, and ...
543 biceq ip, 0x0400 @ immediate zero value has a special encoding
544 streqh ip, [r7] @ that requires the i bit cleared
545#endif
5463: ldrh ip, [r7, #2]
547 and ip, 0x8f00 525 and ip, 0x8f00
548 orrcc ip, r6 @ mask in offset bits 31-24 526 orr ip, r6 @ mask in offset bits 31-24
549 orrcs ip, r0 @ mask in offset bits 23-16
550 strh ip, [r7, #2] 527 strh ip, [r7, #2]
5514: cmp r4, r5 5282: cmp r4, r5
552 ldrcc r7, [r4], #4 @ use branch for delay slot 529 ldrcc r7, [r4], #4 @ use branch for delay slot
553 bcc 2b 530 bcc 1b
554 bx lr 531 bx lr
555#else 532#else
556#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT 533 b 2f
557 and r0, r6, #255 @ offset bits 23-16 5341: ldr ip, [r7, r3]
558 mov r6, r6, lsr #8 @ offset bits 31-24
559#else
560 mov r0, #0 @ just in case...
561#endif
562 b 3f
5632: ldr ip, [r7, r3]
564 bic ip, ip, #0x000000ff 535 bic ip, ip, #0x000000ff
565 tst ip, #0x400 @ rotate shift tells us LS or MS byte 536 orr ip, ip, r6 @ mask in offset bits 31-24
566 orrne ip, ip, r6 @ mask in offset bits 31-24
567 orreq ip, ip, r0 @ mask in offset bits 23-16
568 str ip, [r7, r3] 537 str ip, [r7, r3]
5693: cmp r4, r5 5382: cmp r4, r5
570 ldrcc r7, [r4], #4 @ use branch for delay slot 539 ldrcc r7, [r4], #4 @ use branch for delay slot
571 bcc 2b 540 bcc 1b
572 mov pc, lr 541 mov pc, lr
573#endif 542#endif
574ENDPROC(__fixup_a_pv_table) 543ENDPROC(__fixup_a_pv_table)