diff options
Diffstat (limited to 'arch/arm/boot/compressed')
-rw-r--r-- | arch/arm/boot/compressed/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/boot/compressed/head.S | 188 | ||||
-rw-r--r-- | arch/arm/boot/compressed/ice-dcc.S | 17 | ||||
-rw-r--r-- | arch/arm/boot/compressed/misc.c | 41 |
4 files changed, 178 insertions, 72 deletions
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 35ffe0f4ece7..2adc1527e0eb 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -50,10 +50,6 @@ ifeq ($(CONFIG_ARCH_AT91RM9200),y) OBJS += head-at91rm9200.o endif -ifeq ($(CONFIG_DEBUG_ICEDCC),y) -OBJS += ice-dcc.o -endif - ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) OBJS += big-endian.o endif diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index db3389d8e027..b56f5e691d65 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -2,6 +2,7 @@ * 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 @@ -320,6 +321,62 @@ params: ldr r0, =params_phys 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 @@ -358,7 +415,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 @@ -367,24 +424,24 @@ __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 @@ -471,12 +528,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 @@ -486,16 +543,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 @@ -506,41 +575,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 0x00070000 @ ARMv6 .word 0x000f0000 - b __armv4_cache_on - b __armv4_cache_off - b __armv6_cache_flush + b __armv4_mmu_cache_on + b __armv4_mmu_cache_off + b __armv6_mmu_cache_flush .word 0 @ unrecognised type .word 0 @@ -562,7 +631,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 @@ -571,15 +658,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 @@ -601,7 +688,25 @@ cache_clean_flush: mov r3, #16 b call_cache_fn -__armv6_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 @@ -609,7 +714,7 @@ __armv6_cache_flush: mcr p15, 0, r1, c7, c10, 4 @ drain WB mov pc, lr -__armv4_cache_flush: +__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 @@ -637,7 +742,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 diff --git a/arch/arm/boot/compressed/ice-dcc.S b/arch/arm/boot/compressed/ice-dcc.S deleted file mode 100644 index 104377a199bb..000000000000 --- a/arch/arm/boot/compressed/ice-dcc.S +++ /dev/null @@ -1,17 +0,0 @@ - - - .text - - .global icedcc_putc - -icedcc_putc: - mov r2, #0x4000000 -1: - subs r2, r2, #1 - movlt pc, r14 - mrc p14, 0, r1, c0, c0, 0 - tst r1, #2 - bne 1b - - mcr p14, 0, r0, c1, c0, 0 - mov pc, r14 diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index 5ab94584baee..0af3772efcb7 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c @@ -20,24 +20,45 @@ unsigned int __machine_arch_type; #include <linux/string.h> -#include <asm/arch/uncompress.h> - #ifdef STANDALONE_DEBUG #define putstr printf -#endif +#else + +static void putstr(const char *ptr); + +#include <linux/compiler.h> +#include <asm/arch/uncompress.h> #ifdef CONFIG_DEBUG_ICEDCC -#define putstr icedcc_putstr -#define putc icedcc_putc +static void icedcc_putc(int ch) +{ + int status, i = 0x4000000; -extern void icedcc_putc(int ch); + do { + if (--i < 0) + return; -static void -icedcc_putstr(const char *ptr) + asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (status)); + } while (status & 2); + + asm("mcr p15, 0, %0, c1, c0, 0" : : "r" (ch)); +} + +#define putc(ch) icedcc_putc(ch) +#define flush() do { } while (0) +#endif + +static void putstr(const char *ptr) { - for (; *ptr != '\0'; ptr++) { - icedcc_putc(*ptr); + char c; + + while ((c = *ptr++) != '\0') { + if (c == '\n') + putc('\r'); + putc(c); } + + flush(); } #endif |