X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Farm%2Fboot%2Fcompressed%2Fhead.S;h=2568d311be215a7301bc752f4813a9e64e866999;hb=refs%2Fheads%2Fvserver;hp=4803446067b8f8adcb54fd26ca5663f4b590781d;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 480344606..2568d311b 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -2,12 +2,12 @@ * linux/arch/arm/boot/compressed/head.S * * Copyright (C) 1996-2002 Russell King + * Copyright (C) 2004 Hyok S. Choi (MPU support) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#include #include /* @@ -18,90 +18,50 @@ * Please select one of the following when turning on debugging. */ #ifdef DEBUG -#if defined(CONFIG_DEBUG_DC21285_PORT) - .macro loadsp, rb - mov \rb, #0x42000000 - .endm - .macro writeb, rb - str \rb, [r3, #0x160] - .endm -#elif defined(CONFIG_DEBUG_ICEDCC) + +#if defined(CONFIG_DEBUG_ICEDCC) + +#ifdef CONFIG_CPU_V6 .macro loadsp, rb .endm - .macro writeb, rb - mcr p14, 0, \rb, c0, c1, 0 - .endm -#elif defined(CONFIG_FOOTBRIDGE) - .macro loadsp, rb - mov \rb, #0x7c000000 - .endm - .macro writeb, rb - strb \rb, [r3, #0x3f8] - .endm -#elif defined(CONFIG_ARCH_RPC) - .macro loadsp, rb - mov \rb, #0x03000000 - orr \rb, \rb, #0x00010000 - .endm - .macro writeb, rb - strb \rb, [r3, #0x3f8 << 2] + .macro writeb, ch, rb + mcr p14, 0, \ch, c0, c5, 0 .endm -#elif defined(CONFIG_ARCH_INTEGRATOR) +#else .macro loadsp, rb - mov \rb, #0x16000000 - .endm - .macro writeb, rb - strb \rb, [r3, #0] .endm -#elif defined(CONFIG_ARCH_PXA) /* Xscale-type */ - .macro loadsp, rb - mov \rb, #0x40000000 - orr \rb, \rb, #0x00100000 + .macro writeb, ch, rb + mcr p14, 0, \ch, c0, c1, 0 .endm - .macro writeb, rb - strb \rb, [r3, #0] +#endif + +#else + +#include + + .macro writeb, ch, rb + senduart \ch, \rb .endm -#elif defined(CONFIG_ARCH_SA1100) + +#if defined(CONFIG_ARCH_SA1100) .macro loadsp, rb mov \rb, #0x80000000 @ physical base address -# if defined(CONFIG_DEBUG_LL_SER3) +#ifdef CONFIG_DEBUG_LL_SER3 add \rb, \rb, #0x00050000 @ Ser3 -# else +#else add \rb, \rb, #0x00010000 @ Ser1 -# endif - .endm - .macro writeb, rb - str \rb, [r3, #0x14] @ UTDR - .endm -#elif defined(CONFIG_ARCH_IXP4XX) - .macro loadsp, rb - mov \rb, #0xc8000000 - .endm - .macro writeb, rb - str \rb, [r3, #0] -#elif defined(CONFIG_ARCH_LH7A40X) - .macro loadsp, rb - ldr \rb, =0x80000700 @ UART2 UARTBASE - .endm - .macro writeb, rb - strb \rb, [r3, #0] - .endm -#elif defined(CONFIG_ARCH_OMAP) - .macro loadsp, rb - mov \rb, #0xff000000 @ physical base address - add \rb, \rb, #0x00fb0000 -#if defined(CONFIG_OMAP_LL_DEBUG_UART2) || defined(CONFIG_OMAP_LL_DEBUG_UART3) - add \rb, \rb, #0x00000800 -#endif -#ifdef CONFIG_OMAP_LL_DEBUG_UART3 - add \rb, \rb, #0x00009000 #endif .endm - .macro writeb, rb - strb \rb, [r3] +#elif defined(CONFIG_ARCH_S3C2410) + .macro loadsp, rb + mov \rb, #0x50000000 + add \rb, \rb, #0x4000 * CONFIG_S3C2410_LOWLEVEL_UART_PORT .endm #else -#error no serial architecture defined + .macro loadsp, rb + addruart \rb + .endm +#endif #endif #endif @@ -122,13 +82,15 @@ kphex r6, 8 /* processor id */ kputc #':' kphex r7, 8 /* architecture id */ +#ifdef CONFIG_CPU_CP15 kputc #':' mrc p15, 0, r0, c1, c0 kphex r0, 8 /* control reg */ +#endif kputc #'\n' kphex r5, 8 /* decompressed kernel start */ kputc #'-' - kphex r8, 8 /* decompressed kernel end */ + kphex r9, 8 /* decompressed kernel end */ kputc #'>' kphex r4, 8 /* kernel execution address */ kputc #'\n' @@ -160,7 +122,7 @@ start: .word start @ absolute load/run zImage address .word _edata @ zImage end address 1: mov r7, r1 @ save architecture ID - mov r8, #0 @ save r0 + mov r8, r2 @ save atags pointer #ifndef __ARM_ARCH_2__ /* @@ -188,7 +150,7 @@ not_angel: /* * some architecture specific code can be inserted - * by the linker here, but it should preserve r7 and r8. + * by the linker here, but it should preserve r7, r8, and r9. */ .text @@ -275,7 +237,8 @@ not_relocated: mov r0, #0 */ cmp r4, r2 bhs wont_overwrite - add r0, r4, #4096*1024 @ 4MB largest kernel size + sub r3, sp, r5 @ > compressed kernel size + add r0, r4, r3, lsl #2 @ allow for 4x expansion cmp r0, r5 bls wont_overwrite @@ -293,16 +256,17 @@ not_relocated: mov r0, #0 * r5 = decompressed kernel start * r6 = processor ID * r7 = architecture ID - * r8-r14 = unused + * r8 = atags pointer + * r9-r14 = corrupted */ add r1, r5, r0 @ end of decompressed kernel adr r2, reloc_start ldr r3, LC1 add r3, r2, r3 -1: ldmia r2!, {r8 - r13} @ copy relocation code - stmia r1!, {r8 - r13} - ldmia r2!, {r8 - r13} - stmia r1!, {r8 - r13} +1: ldmia r2!, {r9 - r14} @ copy relocation code + stmia r1!, {r9 - r14} + ldmia r2!, {r9 - r14} + stmia r1!, {r9 - r14} cmp r2, r3 blo 1b @@ -324,7 +288,7 @@ wont_overwrite: mov r0, r4 LC0: .word LC0 @ r1 .word __bss_start @ r2 .word _end @ r3 - .word _load_addr @ r4 + .word zreladdr @ r4 .word _start @ r5 .word _got_start @ r6 .word _got_end @ ip @@ -332,6 +296,14 @@ LC0: .word LC0 @ r1 LC1: .word reloc_end - reloc_start .size LC0, . - LC0 +#ifdef CONFIG_ARCH_RPC + .globl params +params: ldr r0, =params_phys + mov pc, lr + .ltorg + .align +#endif + /* * Turn on the cache. We need to setup some page tables so that we * can have both the I and D caches on. @@ -344,16 +316,73 @@ LC1: .word reloc_end - reloc_start * r4 = kernel execution address * r6 = processor ID * r7 = architecture number - * r8 = run-time address of "start" + * r8 = atags pointer + * r9 = run-time address of "start" (???) * On exit, - * r1, r2, r3, r8, r9, r12 corrupted + * r1, r2, r3, r9, r10, r12 corrupted * This routine must preserve: - * r4, r5, r6, r7 + * r4, r5, r6, r7, r8 */ .align 5 cache_on: mov r3, #8 @ cache_on function b call_cache_fn +/* + * Initialize the highest priority protection region, PR7 + * to cover all 32bit address and cacheable and bufferable. + */ +__armv4_mpu_cache_on: + mov r0, #0x3f @ 4G, the whole + mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting + mcr p15, 0, r0, c6, c7, 1 + + mov r0, #0x80 @ PR7 + mcr p15, 0, r0, c2, c0, 0 @ D-cache on + mcr p15, 0, r0, c2, c0, 1 @ I-cache on + mcr p15, 0, r0, c3, c0, 0 @ write-buffer on + + mov r0, #0xc000 + mcr p15, 0, r0, c5, c0, 1 @ I-access permission + mcr p15, 0, r0, c5, c0, 0 @ D-access permission + + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer + mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache + mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache + mrc p15, 0, r0, c1, c0, 0 @ read control reg + @ ...I .... ..D. WC.M + orr r0, r0, #0x002d @ .... .... ..1. 11.1 + orr r0, r0, #0x1000 @ ...1 .... .... .... + + mcr p15, 0, r0, c1, c0, 0 @ write control reg + + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache + mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache + mov pc, lr + +__armv3_mpu_cache_on: + mov r0, #0x3f @ 4G, the whole + mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting + + mov r0, #0x80 @ PR7 + mcr p15, 0, r0, c2, c0, 0 @ cache on + mcr p15, 0, r0, c3, c0, 0 @ write-buffer on + + mov r0, #0xc000 + mcr p15, 0, r0, c5, c0, 0 @ access permission + + mov r0, #0 + mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 + mrc p15, 0, r0, c1, c0, 0 @ read control reg + @ .... .... .... WC.M + orr r0, r0, #0x000d @ .... .... .... 11.1 + mov r0, #0 + mcr p15, 0, r0, c1, c0, 0 @ write control reg + + mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 + mov pc, lr + __setup_mmu: sub r3, r4, #16384 @ Page directory size bic r3, r3, #0xff @ Align the pointer bic r3, r3, #0x3f00 @@ -362,15 +391,15 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size * bits for the RAM area only. */ mov r0, r3 - mov r8, r0, lsr #18 - mov r8, r8, lsl #18 @ start of RAM - add r9, r8, #0x10000000 @ a reasonable RAM size + mov r9, r0, lsr #18 + mov r9, r9, lsl #18 @ start of RAM + add r10, r9, #0x10000000 @ a reasonable RAM size mov r1, #0x12 orr r1, r1, #3 << 10 add r2, r3, #16384 -1: cmp r1, r8 @ if virt > start of RAM +1: cmp r1, r9 @ if virt > start of RAM orrhs r1, r1, #0x0c @ set cacheable, bufferable - cmp r1, r9 @ if virt > end of RAM + cmp r1, r10 @ if virt > end of RAM bichs r1, r1, #0x0c @ clear cacheable, bufferable str r1, [r0], #4 @ 1:1 mapping add r1, r1, #1048576 @@ -392,7 +421,7 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size str r1, [r0] mov pc, lr -__armv4_cache_on: +__armv4_mmu_cache_on: mov r12, lr bl __setup_mmu mov r0, #0 @@ -401,32 +430,35 @@ __armv4_cache_on: mrc p15, 0, r0, c1, c0, 0 @ read control reg orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement orr r0, r0, #0x0030 - bl __common_cache_on + bl __common_mmu_cache_on mov r0, #0 mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs mov pc, r12 -__arm6_cache_on: +__arm6_mmu_cache_on: mov r12, lr bl __setup_mmu mov r0, #0 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3 mov r0, #0x30 - bl __common_cache_on + bl __common_mmu_cache_on mov r0, #0 mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3 mov pc, r12 -__common_cache_on: +__common_mmu_cache_on: #ifndef DEBUG orr r0, r0, #0x000d @ Write buffer, mmu #endif mov r1, #-1 mcr p15, 0, r3, c2, c0, 0 @ load page table pointer mcr p15, 0, r1, c3, c0, 0 @ load domain access control - mcr p15, 0, r0, c1, c0, 0 @ load control register - mov pc, lr + b 1f + .align 5 @ cache line aligned +1: mcr p15, 0, r0, c1, c0, 0 @ load control register + mrc p15, 0, r0, c1, c0, 0 @ and read it back to + sub pc, lr, r0, lsr #32 @ properly flush pipeline /* * All code following this line is relocatable. It is relocated by @@ -439,26 +471,28 @@ __common_cache_on: * r5 = decompressed kernel start * r6 = processor ID * r7 = architecture ID - * r8-r14 = unused + * r8 = atags pointer + * r9-r14 = corrupted */ .align 5 -reloc_start: add r8, r5, r0 +reloc_start: add r9, r5, r0 debug_reloc_start mov r1, r4 1: .rept 4 - ldmia r5!, {r0, r2, r3, r9 - r13} @ relocate kernel - stmia r1!, {r0, r2, r3, r9 - r13} + ldmia r5!, {r0, r2, r3, r10 - r14} @ relocate kernel + stmia r1!, {r0, r2, r3, r10 - r14} .endr - cmp r5, r8 + cmp r5, r9 blo 1b debug_reloc_end call_kernel: bl cache_clean_flush bl cache_off - mov r0, #0 + mov r0, #0 @ must be zero mov r1, r7 @ restore architecture number + mov r2, r8 @ restore atags pointer mov pc, r4 @ call kernel /* @@ -476,7 +510,11 @@ call_kernel: bl cache_clean_flush */ call_cache_fn: adr r12, proc_types +#ifdef CONFIG_CPU_CP15 mrc p15, 0, r6, c0, c0 @ get processor ID +#else + ldr r6, =CONFIG_PROCESSOR_ID +#endif 1: ldr r1, [r12, #0] @ get value ldr r2, [r12, #4] @ get mask eor r1, r1, r6 @ (real ^ match) @@ -503,12 +541,12 @@ call_cache_fn: adr r12, proc_types proc_types: .word 0x41560600 @ ARM6/610 .word 0xffffffe0 - b __arm6_cache_off @ works, but slow - b __arm6_cache_off + b __arm6_mmu_cache_off @ works, but slow + b __arm6_mmu_cache_off mov pc, lr -@ b __arm6_cache_on @ untested -@ b __arm6_cache_off -@ b __armv3_cache_flush +@ b __arm6_mmu_cache_on @ untested +@ b __arm6_mmu_cache_off +@ b __armv3_mmu_cache_flush .word 0x00000000 @ old ARM ID .word 0x0000f000 @@ -518,16 +556,28 @@ proc_types: .word 0x41007000 @ ARM7/710 .word 0xfff8fe00 - b __arm7_cache_off - b __arm7_cache_off + b __arm7_mmu_cache_off + b __arm7_mmu_cache_off mov pc, lr .word 0x41807200 @ ARM720T (writethrough) .word 0xffffff00 - b __armv4_cache_on - b __armv4_cache_off + b __armv4_mmu_cache_on + b __armv4_mmu_cache_off mov pc, lr + .word 0x41007400 @ ARM74x + .word 0xff00ff00 + b __armv3_mpu_cache_on + b __armv3_mpu_cache_off + b __armv3_mpu_cache_flush + + .word 0x41009400 @ ARM94x + .word 0xff00ff00 + b __armv4_mpu_cache_on + b __armv4_mpu_cache_off + b __armv4_mpu_cache_flush + .word 0x00007000 @ ARM7 IDs .word 0x0000f000 mov pc, lr @@ -538,35 +588,41 @@ proc_types: .word 0x4401a100 @ sa110 / sa1100 .word 0xffffffe0 - b __armv4_cache_on - b __armv4_cache_off - b __armv4_cache_flush + b __armv4_mmu_cache_on + b __armv4_mmu_cache_off + b __armv4_mmu_cache_flush .word 0x6901b110 @ sa1110 .word 0xfffffff0 - b __armv4_cache_on - b __armv4_cache_off - b __armv4_cache_flush + b __armv4_mmu_cache_on + b __armv4_mmu_cache_off + b __armv4_mmu_cache_flush @ These match on the architecture ID .word 0x00020000 @ ARMv4T .word 0x000f0000 - b __armv4_cache_on - b __armv4_cache_off - b __armv4_cache_flush + b __armv4_mmu_cache_on + b __armv4_mmu_cache_off + b __armv4_mmu_cache_flush .word 0x00050000 @ ARMv5TE .word 0x000f0000 - b __armv4_cache_on - b __armv4_cache_off - b __armv4_cache_flush + b __armv4_mmu_cache_on + b __armv4_mmu_cache_off + b __armv4_mmu_cache_flush .word 0x00060000 @ ARMv5TEJ .word 0x000f0000 - b __armv4_cache_on - b __armv4_cache_off - b __armv4_cache_flush + b __armv4_mmu_cache_on + b __armv4_mmu_cache_off + b __armv4_mmu_cache_flush + + .word 0x0007b000 @ ARMv6 + .word 0x0007f000 + b __armv4_mmu_cache_on + b __armv4_mmu_cache_off + b __armv6_mmu_cache_flush .word 0 @ unrecognised type .word 0 @@ -588,7 +644,25 @@ proc_types: cache_off: mov r3, #12 @ cache_off function b call_cache_fn -__armv4_cache_off: +__armv4_mpu_cache_off: + mrc p15, 0, r0, c1, c0 + bic r0, r0, #0x000d + mcr p15, 0, r0, c1, c0 @ turn MPU and cache off + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer + mcr p15, 0, r0, c7, c6, 0 @ flush D-Cache + mcr p15, 0, r0, c7, c5, 0 @ flush I-Cache + mov pc, lr + +__armv3_mpu_cache_off: + mrc p15, 0, r0, c1, c0 + bic r0, r0, #0x000d + mcr p15, 0, r0, c1, c0, 0 @ turn MPU and cache off + mov r0, #0 + mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 + mov pc, lr + +__armv4_mmu_cache_off: mrc p15, 0, r0, c1, c0 bic r0, r0, #0x000d mcr p15, 0, r0, c1, c0 @ turn MMU and cache off @@ -597,15 +671,15 @@ __armv4_cache_off: mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4 mov pc, lr -__arm6_cache_off: +__arm6_mmu_cache_off: mov r0, #0x00000030 @ ARM6 control reg. - b __armv3_cache_off + b __armv3_mmu_cache_off -__arm7_cache_off: +__arm7_mmu_cache_off: mov r0, #0x00000070 @ ARM7 control reg. - b __armv3_cache_off + b __armv3_mmu_cache_off -__armv3_cache_off: +__armv3_mmu_cache_off: mcr p15, 0, r0, c1, c0, 0 @ turn MMU and cache off mov r0, #0 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 @@ -627,7 +701,33 @@ cache_clean_flush: mov r3, #16 b call_cache_fn -__armv4_cache_flush: +__armv4_mpu_cache_flush: + mov r2, #1 + mov r3, #0 + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache + mov r1, #7 << 5 @ 8 segments +1: orr r3, r1, #63 << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 5 + bcs 1b @ segments 7 to 0 + + teq r2, #0 + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + + +__armv6_mmu_cache_flush: + mov r1, #0 + mcr p15, 0, r1, c7, c14, 0 @ clean+invalidate D + mcr p15, 0, r1, c7, c5, 0 @ invalidate I+BTB + mcr p15, 0, r1, c7, c15, 0 @ clean+invalidate unified + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mov pc, lr + +__armv4_mmu_cache_flush: mov r2, #64*1024 @ default: 32K dcache size (*2) mov r11, #32 @ default: 32 byte line size mrc p15, 0, r3, c0, c0, 1 @ read cache type @@ -655,7 +755,8 @@ no_cache_id: mcr p15, 0, r1, c7, c10, 4 @ drain WB mov pc, lr -__armv3_cache_flush: +__armv3_mmu_cache_flush: +__armv3_mpu_cache_flush: mov r1, #0 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 mov pc, lr @@ -687,7 +788,7 @@ puts: loadsp r3 1: ldrb r2, [r0], #1 teq r2, #0 moveq pc, lr -2: writeb r2 +2: writeb r2, r3 mov r1, #0x00020000 3: subs r1, r1, #1 bne 3b