summaryrefslogtreecommitdiffstats
path: root/arch/arm/boot
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/boot')
-rw-r--r--arch/arm/boot/compressed/head.S271
1 files changed, 191 insertions, 80 deletions
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 796f812ab..f60dc3564 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -6,6 +6,66 @@
#include <linux/linkage.h>
.section ".start", #alloc, #execinstr
+
+/*
+ * Debugging stuff
+ */
+ .macro kputc,val
+ mov r0, \val
+ bl putc
+ .endm
+
+ .macro kphex,val,len
+ mov r0, \val
+ mov r1, #\len
+ bl phex
+ .endm
+
+ .macro debug_reloc_start
+#ifdef DEBUG
+ kputc #'\n'
+ kphex r6, 8
+ kputc #':'
+ kphex r5, 8
+ kputc #'-'
+ kphex r8, 8
+ kputc #'>'
+ kphex r4, 8
+ kputc #'\n'
+#endif
+ .endm
+
+ .macro debug_reloc_end
+#ifdef DEBUG
+ mov r8, r0
+ kphex r5, 8
+ kputc #'-'
+ kphex r8, 8
+ kputc #'\n'
+ mov r0, r4
+ bl memdump
+#endif
+ .endm
+
+#if 0
+ .macro loadsp, rb
+ mov \rb, #0x7c000000
+ .endm
+
+ .macro writeb, rb
+ strb \rb, [r3, #0x3f8]
+ .endm
+#else
+ .macro loadsp, rb
+ mov \rb, #0x03000000
+ orr \rb, \rb, #0x00010000
+ .endm
+
+ .macro writeb, rb
+ strb \rb, [r3, #0x3f8 << 2]
+ .endm
+#endif
+
/*
* sort out different calling conventions
*/
@@ -42,6 +102,8 @@ start:
cmp r2, r3
blt 1b
+ bl cache_on
+
mov r1, sp @ malloc space above stack
add r2, sp, #0x10000 @ 64k max
@@ -77,15 +139,87 @@ start:
cmp r2, r3
blt 1b
- eor r1, r6, #0x44 << 24 @ SA-110 or SA-1100?
- eor r1, r1, #0x01 << 16
- eor r1, r1, #0xa1 << 8
- movs r1, r1, lsr #5
- mcreq p15, 0, r1, c7, c7, 0 @ flush I & D-cache
- mcreq p15, 0, r1, c7, c10, 4 @ drain WB
+ bl cache_clean_flush
add pc, r5, r0 @ call relocation code
/*
+ * Page table physical address list
+ */
+ .align 5
+ .type pgtable,#object
+pgtable: .word 0x00004000 @ 0x00
+ .word 0x10004000 @ 0x01
+ .word 0x00000000 @ 0x02
+ .word 0x40004000 @ 0x03
+ .word 0x00004000 @ 0x04
+ .word 0x00004000 @ 0x05
+ .word 0x00004000 @ 0x06
+ .word 0x80004000 @ 0x07
+ .word 0x00004000 @ 0x08
+ .word 0x00000000 @ 0x09
+ .word 0x00000000 @ 0x0a
+ .word 0x00000000 @ 0x0b
+ .word 0x00000000 @ 0x0c
+ .word 0x00000000 @ 0x0d
+ .word 0x10004000 @ 0x0e
+ .word 0x08004000 @ 0x0f
+ .word 0xc0004000 @ 0x10
+ .size pgtable,. - pgtable
+1:
+
+ .type LC0, #object
+LC0: .word __bss_start
+ .word _end
+ .word _load_addr
+ .word _start
+ .word user_stack+4096
+ .size LC0, . - LC0
+
+ .align 5
+cache_on: ldr r1, proc_sa110_type
+ eor r1, r1, r6
+ movs r1, r1, lsr #5
+ movne pc, lr
+ cmp r7, #(1b - pgtable) >> 2
+ movge pc, lr
+ adr r3, pgtable
+ ldr r3, [r3, r7, lsl #2]
+ teq r3, #0
+ moveq pc, lr
+/*
+ * Initialise the page tables
+ */
+ mov r0, r3
+ mov r8, r0, lsr #18
+ mov r8, r8, lsl #18 @ start of RAM
+ add r9, r8, #0x20000000 @ the maximum RAM size
+ mov r1, #0x12
+ orr r1, r1, #3 << 10
+ add r2, r3, #16384
+1: cmp r1, r8 @ if virt > start of RAM
+ orrge r1, r1, #0x0c @ set cacheable, bufferable
+ cmp r1, r9 @ if virt > end of RAM
+ bicge r1, r1, #0x0c @ clear cacheable, bufferable
+ str r1, [r0], #4 @ 1:1 mapping
+ add r1, r1, #1048576
+ teq r0, r2
+ bne 1b
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mcr p15, 0, r0, c8, c7 @ flush I,D TLBs
+ mcr p15, 0, r3, c2, c0 @ load page table pointer
+ mov r0, #-1
+ mcr p15, 0, r0, c3, c0 @ load domain access register
+ mrc p15, 0, r0, c1, c0
+ orr r0, r0, #0x1000 @ I-cache enable
+#ifndef DEBUG
+ orr r0, r0, #0x003d @ Write buffer, mmu
+#endif
+ mcr p15, 0, r0, c1, c0
+ mov pc, lr
+
+/*
* r0 = decompressed kernel length
* r1-r3 = unused
* r4 = kernel execution address
@@ -94,87 +228,68 @@ start:
* r7 = architecture ID
* r8-r14 = unused
*/
+ .align 5
reloc_start: add r8, r5, r0
-#if 0
- mov r0, #'\n'
- bl putc
- mov r0, r6
- mov r1, #8
- bl phex
- mov r0, #':'
- bl putc
- mov r0, r5
- mov r1, #8
- bl phex
- mov r0, #'-'
- bl putc
- mov r0, r8
- mov r1, #8
- bl phex
- mov r0, #'>'
- bl putc
- mov r0, r4
- mov r1, #8
- bl phex
- mov r0, #'\n'
- bl putc
-#endif
- mov r0, r8
+ debug_reloc_start
mov r1, r4
1:
.rept 4
- ldmia r5!, {r2, r3, r8 - r13} @ relocate kernel
- stmia r1!, {r2, r3, r8 - r13}
+ ldmia r5!, {r0, r2, r3, r9 - r13} @ relocate kernel
+ stmia r1!, {r0, r2, r3, r9 - r13}
.endr
- cmp r5, r0
+ cmp r5, r8
blt 1b
-#if 0
- mov r8, r0
- mov r0, r5
- mov r1, #8
- bl phex
- mov r0, #'-'
- bl putc
- mov r0, r8
- mov r1, #8
- bl phex
- mov r0, #'\n'
- bl putc
- mov r0, r4
- bl memdump
-#endif
- eor r0, r6, #0x44 << 24 @ SA-110 or SA-1100?
- eor r0, r0, #0x01 << 16
- eor r0, r0, #0xa1 << 8
- movs r0, r0, lsr #5
- mcreq p15, 0, r0, c7, c7, 0 @ flush I cache
- mcreq p15, 0, r1, c7, c10, 4 @ drain WB
-
-call_kernel: mov r0, #0
+ debug_reloc_end
+
+call_kernel: bl cache_clean_flush
+ bl cache_off
+ mov r0, #0
mov r1, r7 @ restore architecture number
mov pc, r4 @ call kernel
-phexbuf: .space 12
+ .type proc_sa110_type,#object
+proc_sa110_type:
+ .word 0x4401a100
+ .size proc_sa110_type, . - proc_sa110_type
-#if 0
- .macro loadsp, rb
- mov \rb, #0x7c000000
- .endm
+/*
+ * Turn off StrongARM cache and MMU
+ */
+ .align 5
+cache_off: ldr r1, proc_sa110_type
+ eor r1, r1, r6
+ movs r1, r1, lsr #5
+ movne pc, lr
+ mrc p15, 0, r0, c1, c0
+ bic r0, r0, #0x000d
+ mcr p15, 0, r0, c1, c0
+ mov pc, lr
- .macro writeb, rb
- strb \rb, [r3, #0x3f8]
- .endm
-#else
- .macro loadsp, rb
- mov \rb, #0x03000000
- orr \rb, \rb, #0x00010000
- .endm
+/*
+ * Clean and flush the cache to maintain consistency.
+ */
+ .align 5
+cache_clean_flush:
+ ldr r1, proc_sa110_type @ SA-110 or SA-1100?
+ eor r1, r1, r6
+ movs r1, r1, lsr #5
+ movne pc, lr
- .macro writeb, rb
- strb \rb, [r3, #0x3f8 << 2]
- .endm
-#endif
+ bic r1, pc, #31
+ add r2, r1, #32768
+1: ldr r12, [r1], #32
+ teq r1, r2
+ bne 1b
+
+ mcr p15, 0, r1, c7, c7, 0 @ flush I cache
+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+#ifdef DEBUG
+ .type phexbuf,#object
+phexbuf: .space 12
+ .size phexbuf, . - phexbuf
phex: adr r3, phexbuf
mov r2, #0
@@ -240,14 +355,10 @@ memdump: mov r12, r0
cmp r11, #64
blt 2b
mov pc, r10
+#endif
+
reloc_end:
-LC0: .word __bss_start
- .word _end
- .word _load_addr
- .word _start
- .word user_stack+4096
.align
-
.section ".stack"
user_stack: .space 4096