aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/boot
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/boot')
-rw-r--r--arch/arm/boot/bootp/init.S2
-rw-r--r--arch/arm/boot/compressed/Makefile40
-rw-r--r--arch/arm/boot/compressed/decompress.c46
-rw-r--r--arch/arm/boot/compressed/head.S96
-rw-r--r--arch/arm/boot/compressed/misc.c213
-rw-r--r--arch/arm/boot/compressed/piggy.gzip.S6
-rw-r--r--arch/arm/boot/compressed/piggy.lzo.S (renamed from arch/arm/boot/compressed/piggy.S)2
-rw-r--r--arch/arm/boot/compressed/vmlinux.lds.in11
8 files changed, 185 insertions, 231 deletions
diff --git a/arch/arm/boot/bootp/init.S b/arch/arm/boot/bootp/init.S
index df7bc7068d0f..8b0de41c3dcb 100644
--- a/arch/arm/boot/bootp/init.S
+++ b/arch/arm/boot/bootp/init.S
@@ -49,7 +49,7 @@ _start: add lr, pc, #-0x8 @ lr = current load addr
49/* 49/*
50 * find the end of the tag list, and then add an INITRD tag on the end. 50 * find the end of the tag list, and then add an INITRD tag on the end.
51 * If there is already an INITRD tag, then we ignore it; the last INITRD 51 * If there is already an INITRD tag, then we ignore it; the last INITRD
52 * tag takes precidence. 52 * tag takes precedence.
53 */ 53 */
54taglist: ldr r10, [r9, #0] @ tag length 54taglist: ldr r10, [r9, #0] @ tag length
55 teq r10, #0 @ last tag (zero length)? 55 teq r10, #0 @ last tag (zero length)?
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index ce39dc540085..97c89e7de7d3 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -5,7 +5,7 @@
5# 5#
6 6
7HEAD = head.o 7HEAD = head.o
8OBJS = misc.o 8OBJS = misc.o decompress.o
9FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c 9FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c
10 10
11# 11#
@@ -63,8 +63,12 @@ endif
63 63
64SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ 64SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
65 65
66targets := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c \ 66suffix_$(CONFIG_KERNEL_GZIP) = gzip
67 head.o misc.o $(OBJS) 67suffix_$(CONFIG_KERNEL_LZO) = lzo
68
69targets := vmlinux vmlinux.lds \
70 piggy.$(suffix_y) piggy.$(suffix_y).o \
71 font.o font.c head.o misc.o $(OBJS)
68 72
69ifeq ($(CONFIG_FUNCTION_TRACER),y) 73ifeq ($(CONFIG_FUNCTION_TRACER),y)
70ORIG_CFLAGS := $(KBUILD_CFLAGS) 74ORIG_CFLAGS := $(KBUILD_CFLAGS)
@@ -87,22 +91,30 @@ endif
87ifneq ($(PARAMS_PHYS),) 91ifneq ($(PARAMS_PHYS),)
88LDFLAGS_vmlinux += --defsym params_phys=$(PARAMS_PHYS) 92LDFLAGS_vmlinux += --defsym params_phys=$(PARAMS_PHYS)
89endif 93endif
90LDFLAGS_vmlinux += -p --no-undefined -X \ 94# ?
91 $(shell $(CC) $(KBUILD_CFLAGS) --print-libgcc-file-name) -T 95LDFLAGS_vmlinux += -p
92 96# Report unresolved symbol references
93# Don't allow any static data in misc.o, which 97LDFLAGS_vmlinux += --no-undefined
94# would otherwise mess up our GOT table 98# Delete all temporary local symbols
95CFLAGS_misc.o := -Dstatic= 99LDFLAGS_vmlinux += -X
100# Next argument is a linker script
101LDFLAGS_vmlinux += -T
102
103# For __aeabi_uidivmod
104lib1funcs = $(obj)/lib1funcs.o
105
106$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE
107 $(call cmd,shipped)
96 108
97$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \ 109$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
98 $(addprefix $(obj)/, $(OBJS)) FORCE 110 $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE
99 $(call if_changed,ld) 111 $(call if_changed,ld)
100 @: 112 @:
101 113
102$(obj)/piggy.gz: $(obj)/../Image FORCE 114$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE
103 $(call if_changed,gzip) 115 $(call if_changed,$(suffix_y))
104 116
105$(obj)/piggy.o: $(obj)/piggy.gz FORCE 117$(obj)/piggy.$(suffix_y).o: $(obj)/piggy.$(suffix_y) FORCE
106 118
107CFLAGS_font.o := -Dstatic= 119CFLAGS_font.o := -Dstatic=
108 120
diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c
new file mode 100644
index 000000000000..9c097073ce4c
--- /dev/null
+++ b/arch/arm/boot/compressed/decompress.c
@@ -0,0 +1,46 @@
1#define _LINUX_STRING_H_
2
3#include <linux/compiler.h> /* for inline */
4#include <linux/types.h> /* for size_t */
5#include <linux/stddef.h> /* for NULL */
6#include <linux/linkage.h>
7#include <asm/string.h>
8
9extern unsigned long free_mem_ptr;
10extern unsigned long free_mem_end_ptr;
11extern void error(char *);
12
13#define STATIC static
14#define STATIC_RW_DATA /* non-static please */
15
16#define ARCH_HAS_DECOMP_WDOG
17
18/* Diagnostic functions */
19#ifdef DEBUG
20# define Assert(cond,msg) {if(!(cond)) error(msg);}
21# define Trace(x) fprintf x
22# define Tracev(x) {if (verbose) fprintf x ;}
23# define Tracevv(x) {if (verbose>1) fprintf x ;}
24# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
25# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
26#else
27# define Assert(cond,msg)
28# define Trace(x)
29# define Tracev(x)
30# define Tracevv(x)
31# define Tracec(c,x)
32# define Tracecv(c,x)
33#endif
34
35#ifdef CONFIG_KERNEL_GZIP
36#include "../../../../lib/decompress_inflate.c"
37#endif
38
39#ifdef CONFIG_KERNEL_LZO
40#include "../../../../lib/decompress_unlzo.c"
41#endif
42
43void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
44{
45 decompress(input, len, NULL, NULL, output, NULL, error);
46}
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index fa6fbf45cf3b..c5191b1532e8 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -22,19 +22,27 @@
22#if defined(CONFIG_DEBUG_ICEDCC) 22#if defined(CONFIG_DEBUG_ICEDCC)
23 23
24#ifdef CONFIG_CPU_V6 24#ifdef CONFIG_CPU_V6
25 .macro loadsp, rb 25 .macro loadsp, rb, tmp
26 .endm 26 .endm
27 .macro writeb, ch, rb 27 .macro writeb, ch, rb
28 mcr p14, 0, \ch, c0, c5, 0 28 mcr p14, 0, \ch, c0, c5, 0
29 .endm 29 .endm
30#elif defined(CONFIG_CPU_V7)
31 .macro loadsp, rb, tmp
32 .endm
33 .macro writeb, ch, rb
34wait: mrc p14, 0, pc, c0, c1, 0
35 bcs wait
36 mcr p14, 0, \ch, c0, c5, 0
37 .endm
30#elif defined(CONFIG_CPU_XSCALE) 38#elif defined(CONFIG_CPU_XSCALE)
31 .macro loadsp, rb 39 .macro loadsp, rb, tmp
32 .endm 40 .endm
33 .macro writeb, ch, rb 41 .macro writeb, ch, rb
34 mcr p14, 0, \ch, c8, c0, 0 42 mcr p14, 0, \ch, c8, c0, 0
35 .endm 43 .endm
36#else 44#else
37 .macro loadsp, rb 45 .macro loadsp, rb, tmp
38 .endm 46 .endm
39 .macro writeb, ch, rb 47 .macro writeb, ch, rb
40 mcr p14, 0, \ch, c1, c0, 0 48 mcr p14, 0, \ch, c1, c0, 0
@@ -50,7 +58,7 @@
50 .endm 58 .endm
51 59
52#if defined(CONFIG_ARCH_SA1100) 60#if defined(CONFIG_ARCH_SA1100)
53 .macro loadsp, rb 61 .macro loadsp, rb, tmp
54 mov \rb, #0x80000000 @ physical base address 62 mov \rb, #0x80000000 @ physical base address
55#ifdef CONFIG_DEBUG_LL_SER3 63#ifdef CONFIG_DEBUG_LL_SER3
56 add \rb, \rb, #0x00050000 @ Ser3 64 add \rb, \rb, #0x00050000 @ Ser3
@@ -59,13 +67,13 @@
59#endif 67#endif
60 .endm 68 .endm
61#elif defined(CONFIG_ARCH_S3C2410) 69#elif defined(CONFIG_ARCH_S3C2410)
62 .macro loadsp, rb 70 .macro loadsp, rb, tmp
63 mov \rb, #0x50000000 71 mov \rb, #0x50000000
64 add \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT 72 add \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
65 .endm 73 .endm
66#else 74#else
67 .macro loadsp, rb 75 .macro loadsp, rb, tmp
68 addruart \rb 76 addruart \rb, \tmp
69 .endm 77 .endm
70#endif 78#endif
71#endif 79#endif
@@ -162,9 +170,9 @@ not_angel:
162 170
163 .text 171 .text
164 adr r0, LC0 172 adr r0, LC0
165 ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp} ) 173 ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp})
166 THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, ip} ) 174 THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip} )
167 THUMB( ldr sp, [r0, #28] ) 175 THUMB( ldr sp, [r0, #32] )
168 subs r0, r0, r1 @ calculate the delta offset 176 subs r0, r0, r1 @ calculate the delta offset
169 177
170 @ if delta is zero, we are 178 @ if delta is zero, we are
@@ -174,12 +182,13 @@ not_angel:
174 /* 182 /*
175 * We're running at a different address. We need to fix 183 * We're running at a different address. We need to fix
176 * up various pointers: 184 * up various pointers:
177 * r5 - zImage base address 185 * r5 - zImage base address (_start)
178 * r6 - GOT start 186 * r6 - size of decompressed image
187 * r11 - GOT start
179 * ip - GOT end 188 * ip - GOT end
180 */ 189 */
181 add r5, r5, r0 190 add r5, r5, r0
182 add r6, r6, r0 191 add r11, r11, r0
183 add ip, ip, r0 192 add ip, ip, r0
184 193
185#ifndef CONFIG_ZBOOT_ROM 194#ifndef CONFIG_ZBOOT_ROM
@@ -197,10 +206,10 @@ not_angel:
197 /* 206 /*
198 * Relocate all entries in the GOT table. 207 * Relocate all entries in the GOT table.
199 */ 208 */
2001: ldr r1, [r6, #0] @ relocate entries in the GOT 2091: ldr r1, [r11, #0] @ relocate entries in the GOT
201 add r1, r1, r0 @ table. This fixes up the 210 add r1, r1, r0 @ table. This fixes up the
202 str r1, [r6], #4 @ C references. 211 str r1, [r11], #4 @ C references.
203 cmp r6, ip 212 cmp r11, ip
204 blo 1b 213 blo 1b
205#else 214#else
206 215
@@ -208,12 +217,12 @@ not_angel:
208 * Relocate entries in the GOT table. We only relocate 217 * Relocate entries in the GOT table. We only relocate
209 * the entries that are outside the (relocated) BSS region. 218 * the entries that are outside the (relocated) BSS region.
210 */ 219 */
2111: ldr r1, [r6, #0] @ relocate entries in the GOT 2201: ldr r1, [r11, #0] @ relocate entries in the GOT
212 cmp r1, r2 @ entry < bss_start || 221 cmp r1, r2 @ entry < bss_start ||
213 cmphs r3, r1 @ _end < entry 222 cmphs r3, r1 @ _end < entry
214 addlo r1, r1, r0 @ table. This fixes up the 223 addlo r1, r1, r0 @ table. This fixes up the
215 str r1, [r6], #4 @ C references. 224 str r1, [r11], #4 @ C references.
216 cmp r6, ip 225 cmp r11, ip
217 blo 1b 226 blo 1b
218#endif 227#endif
219 228
@@ -239,6 +248,7 @@ not_relocated: mov r0, #0
239 * Check to see if we will overwrite ourselves. 248 * Check to see if we will overwrite ourselves.
240 * r4 = final kernel address 249 * r4 = final kernel address
241 * r5 = start of this image 250 * r5 = start of this image
251 * r6 = size of decompressed image
242 * r2 = end of malloc space (and therefore this image) 252 * r2 = end of malloc space (and therefore this image)
243 * We basically want: 253 * We basically want:
244 * r4 >= r2 -> OK 254 * r4 >= r2 -> OK
@@ -246,8 +256,7 @@ not_relocated: mov r0, #0
246 */ 256 */
247 cmp r4, r2 257 cmp r4, r2
248 bhs wont_overwrite 258 bhs wont_overwrite
249 sub r3, sp, r5 @ > compressed kernel size 259 add r0, r4, r6
250 add r0, r4, r3, lsl #2 @ allow for 4x expansion
251 cmp r0, r5 260 cmp r0, r5
252 bls wont_overwrite 261 bls wont_overwrite
253 262
@@ -263,7 +272,6 @@ not_relocated: mov r0, #0
263 * r1-r3 = unused 272 * r1-r3 = unused
264 * r4 = kernel execution address 273 * r4 = kernel execution address
265 * r5 = decompressed kernel start 274 * r5 = decompressed kernel start
266 * r6 = processor ID
267 * r7 = architecture ID 275 * r7 = architecture ID
268 * r8 = atags pointer 276 * r8 = atags pointer
269 * r9-r12,r14 = corrupted 277 * r9-r12,r14 = corrupted
@@ -304,7 +312,8 @@ LC0: .word LC0 @ r1
304 .word _end @ r3 312 .word _end @ r3
305 .word zreladdr @ r4 313 .word zreladdr @ r4
306 .word _start @ r5 314 .word _start @ r5
307 .word _got_start @ r6 315 .word _image_size @ r6
316 .word _got_start @ r11
308 .word _got_end @ ip 317 .word _got_end @ ip
309 .word user_stack+4096 @ sp 318 .word user_stack+4096 @ sp
310LC1: .word reloc_end - reloc_start 319LC1: .word reloc_end - reloc_start
@@ -328,7 +337,6 @@ params: ldr r0, =params_phys
328 * 337 *
329 * On entry, 338 * On entry,
330 * r4 = kernel execution address 339 * r4 = kernel execution address
331 * r6 = processor ID
332 * r7 = architecture number 340 * r7 = architecture number
333 * r8 = atags pointer 341 * r8 = atags pointer
334 * r9 = run-time address of "start" (???) 342 * r9 = run-time address of "start" (???)
@@ -534,7 +542,6 @@ __common_mmu_cache_on:
534 * r1-r3 = unused 542 * r1-r3 = unused
535 * r4 = kernel execution address 543 * r4 = kernel execution address
536 * r5 = decompressed kernel start 544 * r5 = decompressed kernel start
537 * r6 = processor ID
538 * r7 = architecture ID 545 * r7 = architecture ID
539 * r8 = atags pointer 546 * r8 = atags pointer
540 * r9-r12,r14 = corrupted 547 * r9-r12,r14 = corrupted
@@ -573,19 +580,19 @@ call_kernel: bl cache_clean_flush
573 * r1 = corrupted 580 * r1 = corrupted
574 * r2 = corrupted 581 * r2 = corrupted
575 * r3 = block offset 582 * r3 = block offset
576 * r6 = corrupted 583 * r9 = corrupted
577 * r12 = corrupted 584 * r12 = corrupted
578 */ 585 */
579 586
580call_cache_fn: adr r12, proc_types 587call_cache_fn: adr r12, proc_types
581#ifdef CONFIG_CPU_CP15 588#ifdef CONFIG_CPU_CP15
582 mrc p15, 0, r6, c0, c0 @ get processor ID 589 mrc p15, 0, r9, c0, c0 @ get processor ID
583#else 590#else
584 ldr r6, =CONFIG_PROCESSOR_ID 591 ldr r9, =CONFIG_PROCESSOR_ID
585#endif 592#endif
5861: ldr r1, [r12, #0] @ get value 5931: ldr r1, [r12, #0] @ get value
587 ldr r2, [r12, #4] @ get mask 594 ldr r2, [r12, #4] @ get mask
588 eor r1, r1, r6 @ (real ^ match) 595 eor r1, r1, r9 @ (real ^ match)
589 tst r1, r2 @ & mask 596 tst r1, r2 @ & mask
590 ARM( addeq pc, r12, r3 ) @ call cache function 597 ARM( addeq pc, r12, r3 ) @ call cache function
591 THUMB( addeq r12, r3 ) 598 THUMB( addeq r12, r3 )
@@ -678,8 +685,8 @@ proc_types:
678 W(b) __armv4_mmu_cache_off 685 W(b) __armv4_mmu_cache_off
679 W(b) __armv4_mmu_cache_flush 686 W(b) __armv4_mmu_cache_flush
680 687
681 .word 0x56056930 688 .word 0x56056900
682 .word 0xff0ffff0 @ PXA935 689 .word 0xffffff00 @ PXA9xx
683 W(b) __armv4_mmu_cache_on 690 W(b) __armv4_mmu_cache_on
684 W(b) __armv4_mmu_cache_off 691 W(b) __armv4_mmu_cache_off
685 W(b) __armv4_mmu_cache_flush 692 W(b) __armv4_mmu_cache_flush
@@ -690,12 +697,6 @@ proc_types:
690 W(b) __armv4_mmu_cache_off 697 W(b) __armv4_mmu_cache_off
691 W(b) __armv5tej_mmu_cache_flush 698 W(b) __armv5tej_mmu_cache_flush
692 699
693 .word 0x56056930
694 .word 0xff0ffff0 @ PXA935
695 W(b) __armv4_mmu_cache_on
696 W(b) __armv4_mmu_cache_off
697 W(b) __armv4_mmu_cache_flush
698
699 .word 0x56050000 @ Feroceon 700 .word 0x56050000 @ Feroceon
700 .word 0xff0f0000 701 .word 0xff0f0000
701 W(b) __armv4_mmu_cache_on 702 W(b) __armv4_mmu_cache_on
@@ -735,7 +736,7 @@ proc_types:
735 .word 0x000f0000 736 .word 0x000f0000
736 W(b) __armv4_mmu_cache_on 737 W(b) __armv4_mmu_cache_on
737 W(b) __armv4_mmu_cache_off 738 W(b) __armv4_mmu_cache_off
738 W(b) __armv4_mmu_cache_flush 739 W(b) __armv5tej_mmu_cache_flush
739 740
740 .word 0x0007b000 @ ARMv6 741 .word 0x0007b000 @ ARMv6
741 .word 0x000ff000 742 .word 0x000ff000
@@ -743,6 +744,12 @@ proc_types:
743 W(b) __armv4_mmu_cache_off 744 W(b) __armv4_mmu_cache_off
744 W(b) __armv6_mmu_cache_flush 745 W(b) __armv6_mmu_cache_flush
745 746
747 .word 0x560f5810 @ Marvell PJ4 ARMv6
748 .word 0xff0ffff0
749 W(b) __armv4_mmu_cache_on
750 W(b) __armv4_mmu_cache_off
751 W(b) __armv6_mmu_cache_flush
752
746 .word 0x000f0000 @ new CPU Id 753 .word 0x000f0000 @ new CPU Id
747 .word 0x000f0000 754 .word 0x000f0000
748 W(b) __armv7_mmu_cache_on 755 W(b) __armv7_mmu_cache_on
@@ -764,8 +771,7 @@ proc_types:
764 * Turn off the Cache and MMU. ARMv3 does not support 771 * Turn off the Cache and MMU. ARMv3 does not support
765 * reading the control register, but ARMv4 does. 772 * reading the control register, but ARMv4 does.
766 * 773 *
767 * On entry, r6 = processor ID 774 * On exit, r0, r1, r2, r3, r9, r12 corrupted
768 * On exit, r0, r1, r2, r3, r12 corrupted
769 * This routine must preserve: r4, r6, r7 775 * This routine must preserve: r4, r6, r7
770 */ 776 */
771 .align 5 777 .align 5
@@ -838,10 +844,8 @@ __armv3_mmu_cache_off:
838/* 844/*
839 * Clean and flush the cache to maintain consistency. 845 * Clean and flush the cache to maintain consistency.
840 * 846 *
841 * On entry,
842 * r6 = processor ID
843 * On exit, 847 * On exit,
844 * r1, r2, r3, r11, r12 corrupted 848 * r1, r2, r3, r9, r11, r12 corrupted
845 * This routine must preserve: 849 * This routine must preserve:
846 * r0, r4, r5, r6, r7 850 * r0, r4, r5, r6, r7
847 */ 851 */
@@ -953,7 +957,7 @@ __armv4_mmu_cache_flush:
953 mov r2, #64*1024 @ default: 32K dcache size (*2) 957 mov r2, #64*1024 @ default: 32K dcache size (*2)
954 mov r11, #32 @ default: 32 byte line size 958 mov r11, #32 @ default: 32 byte line size
955 mrc p15, 0, r3, c0, c0, 1 @ read cache type 959 mrc p15, 0, r3, c0, c0, 1 @ read cache type
956 teq r3, r6 @ cache ID register present? 960 teq r3, r9 @ cache ID register present?
957 beq no_cache_id 961 beq no_cache_id
958 mov r1, r3, lsr #18 962 mov r1, r3, lsr #18
959 and r1, r1, #7 963 and r1, r1, #7
@@ -1011,7 +1015,7 @@ phex: adr r3, phexbuf
1011 strb r2, [r3, r1] 1015 strb r2, [r3, r1]
1012 b 1b 1016 b 1b
1013 1017
1014puts: loadsp r3 1018puts: loadsp r3, r1
10151: ldrb r2, [r0], #1 10191: ldrb r2, [r0], #1
1016 teq r2, #0 1020 teq r2, #0
1017 moveq pc, lr 1021 moveq pc, lr
@@ -1028,7 +1032,7 @@ puts: loadsp r3
1028putc: 1032putc:
1029 mov r2, r0 1033 mov r2, r0
1030 mov r0, #0 1034 mov r0, #0
1031 loadsp r3 1035 loadsp r3, r1
1032 b 2b 1036 b 2b
1033 1037
1034memdump: mov r12, r0 1038memdump: mov r12, r0
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index 17153b54613b..d2b2ef41cd4f 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -18,16 +18,22 @@
18 18
19unsigned int __machine_arch_type; 19unsigned int __machine_arch_type;
20 20
21#define _LINUX_STRING_H_
22
21#include <linux/compiler.h> /* for inline */ 23#include <linux/compiler.h> /* for inline */
22#include <linux/types.h> /* for size_t */ 24#include <linux/types.h> /* for size_t */
23#include <linux/stddef.h> /* for NULL */ 25#include <linux/stddef.h> /* for NULL */
26#include <linux/linkage.h>
24#include <asm/string.h> 27#include <asm/string.h>
25 28
29#include <asm/unaligned.h>
30
26#ifdef STANDALONE_DEBUG 31#ifdef STANDALONE_DEBUG
27#define putstr printf 32#define putstr printf
28#else 33#else
29 34
30static void putstr(const char *ptr); 35static void putstr(const char *ptr);
36extern void error(char *x);
31 37
32#include <mach/uncompress.h> 38#include <mach/uncompress.h>
33 39
@@ -48,6 +54,18 @@ static void icedcc_putc(int ch)
48 54
49 asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch)); 55 asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch));
50} 56}
57
58#elif defined(CONFIG_CPU_V7)
59
60static void icedcc_putc(int ch)
61{
62 asm(
63 "wait: mrc p14, 0, pc, c0, c1, 0 \n\
64 bcs wait \n\
65 mcr p14, 0, %0, c0, c5, 0 "
66 : : "r" (ch));
67}
68
51#elif defined(CONFIG_CPU_XSCALE) 69#elif defined(CONFIG_CPU_XSCALE)
52 70
53static void icedcc_putc(int ch) 71static void icedcc_putc(int ch)
@@ -83,7 +101,6 @@ static void icedcc_putc(int ch)
83#endif 101#endif
84 102
85#define putc(ch) icedcc_putc(ch) 103#define putc(ch) icedcc_putc(ch)
86#define flush() do { } while (0)
87#endif 104#endif
88 105
89static void putstr(const char *ptr) 106static void putstr(const char *ptr)
@@ -101,57 +118,7 @@ static void putstr(const char *ptr)
101 118
102#endif 119#endif
103 120
104#define __ptr_t void * 121void *memcpy(void *__dest, __const void *__src, size_t __n)
105
106#define memzero(s,n) __memzero(s,n)
107
108/*
109 * Optimised C version of memzero for the ARM.
110 */
111void __memzero (__ptr_t s, size_t n)
112{
113 union { void *vp; unsigned long *ulp; unsigned char *ucp; } u;
114 int i;
115
116 u.vp = s;
117
118 for (i = n >> 5; i > 0; i--) {
119 *u.ulp++ = 0;
120 *u.ulp++ = 0;
121 *u.ulp++ = 0;
122 *u.ulp++ = 0;
123 *u.ulp++ = 0;
124 *u.ulp++ = 0;
125 *u.ulp++ = 0;
126 *u.ulp++ = 0;
127 }
128
129 if (n & 1 << 4) {
130 *u.ulp++ = 0;
131 *u.ulp++ = 0;
132 *u.ulp++ = 0;
133 *u.ulp++ = 0;
134 }
135
136 if (n & 1 << 3) {
137 *u.ulp++ = 0;
138 *u.ulp++ = 0;
139 }
140
141 if (n & 1 << 2)
142 *u.ulp++ = 0;
143
144 if (n & 1 << 1) {
145 *u.ucp++ = 0;
146 *u.ucp++ = 0;
147 }
148
149 if (n & 1)
150 *u.ucp++ = 0;
151}
152
153static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
154 size_t __n)
155{ 122{
156 int i = 0; 123 int i = 0;
157 unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src; 124 unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
@@ -188,122 +155,20 @@ static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
188/* 155/*
189 * gzip delarations 156 * gzip delarations
190 */ 157 */
191#define OF(args) args
192#define STATIC static
193
194typedef unsigned char uch;
195typedef unsigned short ush;
196typedef unsigned long ulg;
197
198#define WSIZE 0x8000 /* Window size must be at least 32k, */
199 /* and a power of two */
200
201static uch *inbuf; /* input buffer */
202static uch window[WSIZE]; /* Sliding window buffer */
203
204static unsigned insize; /* valid bytes in inbuf */
205static unsigned inptr; /* index of next byte to be processed in inbuf */
206static unsigned outcnt; /* bytes in output buffer */
207
208/* gzip flag byte */
209#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
210#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
211#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
212#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
213#define COMMENT 0x10 /* bit 4 set: file comment present */
214#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
215#define RESERVED 0xC0 /* bit 6,7: reserved */
216
217#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
218
219/* Diagnostic functions */
220#ifdef DEBUG
221# define Assert(cond,msg) {if(!(cond)) error(msg);}
222# define Trace(x) fprintf x
223# define Tracev(x) {if (verbose) fprintf x ;}
224# define Tracevv(x) {if (verbose>1) fprintf x ;}
225# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
226# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
227#else
228# define Assert(cond,msg)
229# define Trace(x)
230# define Tracev(x)
231# define Tracevv(x)
232# define Tracec(c,x)
233# define Tracecv(c,x)
234#endif
235
236static int fill_inbuf(void);
237static void flush_window(void);
238static void error(char *m);
239
240extern char input_data[]; 158extern char input_data[];
241extern char input_data_end[]; 159extern char input_data_end[];
242 160
243static uch *output_data; 161unsigned char *output_data;
244static ulg output_ptr; 162unsigned long output_ptr;
245static ulg bytes_out;
246
247static void error(char *m);
248
249static void putstr(const char *);
250
251extern int end;
252static ulg free_mem_ptr;
253static ulg free_mem_end_ptr;
254
255#ifdef STANDALONE_DEBUG
256#define NO_INFLATE_MALLOC
257#endif
258
259#define ARCH_HAS_DECOMP_WDOG
260
261#include "../../../../lib/inflate.c"
262
263/* ===========================================================================
264 * Fill the input buffer. This is called only when the buffer is empty
265 * and at least one byte is really needed.
266 */
267int fill_inbuf(void)
268{
269 if (insize != 0)
270 error("ran out of input data");
271
272 inbuf = input_data;
273 insize = &input_data_end[0] - &input_data[0];
274
275 inptr = 1;
276 return inbuf[0];
277}
278 163
279/* =========================================================================== 164unsigned long free_mem_ptr;
280 * Write the output window window[0..outcnt-1] and update crc and bytes_out. 165unsigned long free_mem_end_ptr;
281 * (Used for the decompressed data only.)
282 */
283void flush_window(void)
284{
285 ulg c = crc;
286 unsigned n;
287 uch *in, *out, ch;
288
289 in = window;
290 out = &output_data[output_ptr];
291 for (n = 0; n < outcnt; n++) {
292 ch = *out++ = *in++;
293 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
294 }
295 crc = c;
296 bytes_out += (ulg)outcnt;
297 output_ptr += (ulg)outcnt;
298 outcnt = 0;
299 putstr(".");
300}
301 166
302#ifndef arch_error 167#ifndef arch_error
303#define arch_error(x) 168#define arch_error(x)
304#endif 169#endif
305 170
306static void error(char *x) 171void error(char *x)
307{ 172{
308 arch_error(x); 173 arch_error(x);
309 174
@@ -314,22 +179,35 @@ static void error(char *x)
314 while(1); /* Halt */ 179 while(1); /* Halt */
315} 180}
316 181
182asmlinkage void __div0(void)
183{
184 error("Attempting division by 0!");
185}
186
187extern void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
188
317#ifndef STANDALONE_DEBUG 189#ifndef STANDALONE_DEBUG
318 190
319ulg 191unsigned long
320decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p, 192decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
321 int arch_id) 193 unsigned long free_mem_ptr_end_p,
194 int arch_id)
322{ 195{
323 output_data = (uch *)output_start; /* Points to kernel start */ 196 unsigned char *tmp;
197
198 output_data = (unsigned char *)output_start;
324 free_mem_ptr = free_mem_ptr_p; 199 free_mem_ptr = free_mem_ptr_p;
325 free_mem_end_ptr = free_mem_ptr_end_p; 200 free_mem_end_ptr = free_mem_ptr_end_p;
326 __machine_arch_type = arch_id; 201 __machine_arch_type = arch_id;
327 202
328 arch_decomp_setup(); 203 arch_decomp_setup();
329 204
330 makecrc(); 205 tmp = (unsigned char *) (((unsigned long)input_data_end) - 4);
206 output_ptr = get_unaligned_le32(tmp);
207
331 putstr("Uncompressing Linux..."); 208 putstr("Uncompressing Linux...");
332 gunzip(); 209 do_decompress(input_data, input_data_end - input_data,
210 output_data, error);
333 putstr(" done, booting the kernel.\n"); 211 putstr(" done, booting the kernel.\n");
334 return output_ptr; 212 return output_ptr;
335} 213}
@@ -341,11 +219,10 @@ int main()
341{ 219{
342 output_data = output_buffer; 220 output_data = output_buffer;
343 221
344 makecrc();
345 putstr("Uncompressing Linux..."); 222 putstr("Uncompressing Linux...");
346 gunzip(); 223 decompress(input_data, input_data_end - input_data,
224 NULL, NULL, output_data, NULL, error);
347 putstr("done.\n"); 225 putstr("done.\n");
348 return 0; 226 return 0;
349} 227}
350#endif 228#endif
351
diff --git a/arch/arm/boot/compressed/piggy.gzip.S b/arch/arm/boot/compressed/piggy.gzip.S
new file mode 100644
index 000000000000..a68adf91a165
--- /dev/null
+++ b/arch/arm/boot/compressed/piggy.gzip.S
@@ -0,0 +1,6 @@
1 .section .piggydata,#alloc
2 .globl input_data
3input_data:
4 .incbin "arch/arm/boot/compressed/piggy.gzip"
5 .globl input_data_end
6input_data_end:
diff --git a/arch/arm/boot/compressed/piggy.S b/arch/arm/boot/compressed/piggy.lzo.S
index 54c951800ebd..a425ad95959a 100644
--- a/arch/arm/boot/compressed/piggy.S
+++ b/arch/arm/boot/compressed/piggy.lzo.S
@@ -1,6 +1,6 @@
1 .section .piggydata,#alloc 1 .section .piggydata,#alloc
2 .globl input_data 2 .globl input_data
3input_data: 3input_data:
4 .incbin "arch/arm/boot/compressed/piggy.gz" 4 .incbin "arch/arm/boot/compressed/piggy.lzo"
5 .globl input_data_end 5 .globl input_data_end
6input_data_end: 6input_data_end:
diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in
index a5924b9b88bd..d08168941bd6 100644
--- a/arch/arm/boot/compressed/vmlinux.lds.in
+++ b/arch/arm/boot/compressed/vmlinux.lds.in
@@ -14,6 +14,13 @@ SECTIONS
14 /DISCARD/ : { 14 /DISCARD/ : {
15 *(.ARM.exidx*) 15 *(.ARM.exidx*)
16 *(.ARM.extab*) 16 *(.ARM.extab*)
17 /*
18 * Discard any r/w data - this produces a link error if we have any,
19 * which is required for PIC decompression. Local data generates
20 * GOTOFF relocations, which prevents it being relocated independently
21 * of the text/got segments.
22 */
23 *(.data)
17 } 24 }
18 25
19 . = TEXT_START; 26 . = TEXT_START;
@@ -36,11 +43,13 @@ SECTIONS
36 43
37 _etext = .; 44 _etext = .;
38 45
46 /* Assume size of decompressed image is 4x the compressed image */
47 _image_size = (_etext - _text) * 4;
48
39 _got_start = .; 49 _got_start = .;
40 .got : { *(.got) } 50 .got : { *(.got) }
41 _got_end = .; 51 _got_end = .;
42 .got.plt : { *(.got.plt) } 52 .got.plt : { *(.got.plt) }
43 .data : { *(.data) }
44 _edata = .; 53 _edata = .;
45 54
46 . = BSS_START; 55 . = BSS_START;