aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm26/boot/compressed
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/arm26/boot/compressed
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/arm26/boot/compressed')
-rw-r--r--arch/arm26/boot/compressed/Makefile50
-rw-r--r--arch/arm26/boot/compressed/head.S517
-rw-r--r--arch/arm26/boot/compressed/hw-bse.c74
-rw-r--r--arch/arm26/boot/compressed/ll_char_wr.S162
-rw-r--r--arch/arm26/boot/compressed/misc.c316
-rw-r--r--arch/arm26/boot/compressed/uncompress.h110
-rw-r--r--arch/arm26/boot/compressed/vmlinux.lds.in60
7 files changed, 1289 insertions, 0 deletions
diff --git a/arch/arm26/boot/compressed/Makefile b/arch/arm26/boot/compressed/Makefile
new file mode 100644
index 000000000000..b1d9ddebbe74
--- /dev/null
+++ b/arch/arm26/boot/compressed/Makefile
@@ -0,0 +1,50 @@
1#
2# linux/arch/arm26/boot/compressed/Makefile
3#
4# create a compressed vmlinuz image from the original vmlinux
5#
6# Note! ZTEXTADDR, ZBSSADDR and ZRELADDR are now exported
7# from arch/arm26/boot/Makefile
8#
9
10HEAD = head.o
11OBJS = misc.o
12FONTC = drivers/video/console/font_acorn_8x8.c
13
14OBJS += ll_char_wr.o font.o
15CFLAGS_misc.o := -DPARAMS_PHYS=$(PARAMS_PHYS)
16
17targets := vmlinux vmlinux.lds piggy piggy.gz piggy.o font.o head.o $(OBJS)
18
19SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;s/BSS_START/$(ZBSSADDR)/
20
21EXTRA_CFLAGS := $(CFLAGS_BOOT) -fpic
22EXTRA_AFLAGS := -traditional
23
24LDFLAGS_vmlinux := -p -X \
25 $(shell $(CC) $(CFLAGS)) -T
26
27$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \
28 $(addprefix $(obj)/, $(OBJS)) FORCE
29 $(call if_changed,ld)
30 @:
31
32
33$(obj)/piggy: vmlinux FORCE
34 $(call if_changed,objcopy)
35
36$(obj)/piggy.gz: $(obj)/piggy FORCE
37 $(call if_changed,gzip)
38
39LDFLAGS_piggy.o := -r -b binary
40$(obj)/piggy.o: $(obj)/piggy.gz FORCE
41 $(call if_changed,ld)
42
43$(obj)/font.o: $(FONTC)
44 $(CC) $(CFLAGS) -Dstatic= -c $(FONTC) -o $(obj)/font.o
45
46$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in Makefile arch/arm26/boot/Makefile .config
47 @sed "$(SEDFLAGS)" < $< > $@
48
49$(obj)/misc.o: $(obj)/misc.c $(obj)/uncompress.h lib/inflate.c
50
diff --git a/arch/arm26/boot/compressed/head.S b/arch/arm26/boot/compressed/head.S
new file mode 100644
index 000000000000..0307804a6070
--- /dev/null
+++ b/arch/arm26/boot/compressed/head.S
@@ -0,0 +1,517 @@
1/*
2 * linux/arch/arm26/boot/compressed/head.S
3 *
4 * Copyright (C) 1996-2002 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/config.h>
11#include <linux/linkage.h>
12
13/*
14 * Debugging stuff
15 *
16 * Note that these macros must not contain any code which is not
17 * 100% relocatable. Any attempt to do so will result in a crash.
18 * Please select one of the following when turning on debugging.
19 */
20
21 .macro kputc,val
22 mov r0, \val
23 bl putc
24 .endm
25
26 .macro kphex,val,len
27 mov r0, \val
28 mov r1, #\len
29 bl phex
30 .endm
31
32 .macro debug_reloc_start
33 .endm
34
35 .macro debug_reloc_end
36 .endm
37
38 .section ".start", #alloc, #execinstr
39/*
40 * sort out different calling conventions
41 */
42 .align
43start:
44 .type start,#function
45 .rept 8
46 mov r0, r0
47 .endr
48
49 b 1f
50 .word 0x016f2818 @ Magic numbers to help the loader
51 .word start @ absolute load/run zImage address
52 .word _edata @ zImage end address
531: mov r7, r1 @ save architecture ID
54 mov r8, #0 @ save r0
55 teqp pc, #0x0c000003 @ turn off interrupts
56
57 .text
58 adr r0, LC0
59 ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp}
60 subs r0, r0, r1 @ calculate the delta offset
61
62 teq r0, #0 @ if delta is zero, we're
63 beq not_relocated @ running at the address we
64 @ were linked at.
65
66 add r2, r2, r0 @ different address, so we
67 add r3, r3, r0 @ need to fix up various
68 add r5, r5, r0 @ pointers.
69 add r6, r6, r0
70 add ip, ip, r0
71 add sp, sp, r0
72
731: ldr r1, [r6, #0] @ relocate entries in the GOT
74 add r1, r1, r0 @ table. This fixes up the
75 str r1, [r6], #4 @ C references.
76 cmp r6, ip
77 blo 1b
78
79not_relocated: mov r0, #0
801: str r0, [r2], #4 @ clear bss
81 str r0, [r2], #4
82 str r0, [r2], #4
83 str r0, [r2], #4
84 cmp r2, r3
85 blo 1b
86
87 bl cache_on
88
89 mov r1, sp @ malloc space above stack
90 add r2, sp, #0x10000 @ 64k max
91
92/*
93 * Check to see if we will overwrite ourselves.
94 * r4 = final kernel address
95 * r5 = start of this image
96 * r2 = end of malloc space (and therefore this image)
97 * We basically want:
98 * r4 >= r2 -> OK
99 * r4 + image length <= r5 -> OK
100 */
101 cmp r4, r2
102 bhs wont_overwrite
103 add r0, r4, #4096*1024 @ 4MB largest kernel size
104 cmp r0, r5
105 bls wont_overwrite
106
107 mov r5, r2 @ decompress after malloc space
108 mov r0, r5
109 mov r3, r7
110 bl decompress_kernel
111
112 add r0, r0, #127
113 bic r0, r0, #127 @ align the kernel length
114/*
115 * r0 = decompressed kernel length
116 * r1-r3 = unused
117 * r4 = kernel execution address
118 * r5 = decompressed kernel start
119 * r6 = processor ID
120 * r7 = architecture ID
121 * r8-r14 = unused
122 */
123 add r1, r5, r0 @ end of decompressed kernel
124 adr r2, reloc_start
125 ldr r3, LC1
126 add r3, r2, r3
1271: ldmia r2!, {r8 - r13} @ copy relocation code
128 stmia r1!, {r8 - r13}
129 ldmia r2!, {r8 - r13}
130 stmia r1!, {r8 - r13}
131 cmp r2, r3
132 blo 1b
133
134 bl cache_clean_flush
135 add pc, r5, r0 @ call relocation code
136
137/*
138 * We're not in danger of overwriting ourselves. Do this the simple way.
139 *
140 * r4 = kernel execution address
141 * r7 = architecture ID
142 */
143wont_overwrite: mov r0, r4
144 mov r3, r7
145 bl decompress_kernel
146 b call_kernel
147
148 .type LC0, #object
149LC0: .word LC0 @ r1
150 .word __bss_start @ r2
151 .word _end @ r3
152 .word _load_addr @ r4
153 .word _start @ r5
154 .word _got_start @ r6
155 .word _got_end @ ip
156 .word user_stack+4096 @ sp
157LC1: .word reloc_end - reloc_start
158 .size LC0, . - LC0
159
160/*
161 * Turn on the cache. We need to setup some page tables so that we
162 * can have both the I and D caches on.
163 *
164 * We place the page tables 16k down from the kernel execution address,
165 * and we hope that nothing else is using it. If we're using it, we
166 * will go pop!
167 *
168 * On entry,
169 * r4 = kernel execution address
170 * r6 = processor ID
171 * r7 = architecture number
172 * r8 = run-time address of "start"
173 * On exit,
174 * r1, r2, r3, r8, r9, r12 corrupted
175 * This routine must preserve:
176 * r4, r5, r6, r7
177 */
178 .align 5
179cache_on: mov r3, #8 @ cache_on function
180 b call_cache_fn
181
182__setup_mmu: sub r3, r4, #16384 @ Page directory size
183 bic r3, r3, #0xff @ Align the pointer
184 bic r3, r3, #0x3f00
185/*
186 * Initialise the page tables, turning on the cacheable and bufferable
187 * bits for the RAM area only.
188 */
189 mov r0, r3
190 mov r8, r0, lsr #18
191 mov r8, r8, lsl #18 @ start of RAM
192 add r9, r8, #0x10000000 @ a reasonable RAM size
193 mov r1, #0x12
194 orr r1, r1, #3 << 10
195 add r2, r3, #16384
1961: cmp r1, r8 @ if virt > start of RAM
197 orrhs r1, r1, #0x0c @ set cacheable, bufferable
198 cmp r1, r9 @ if virt > end of RAM
199 bichs r1, r1, #0x0c @ clear cacheable, bufferable
200 str r1, [r0], #4 @ 1:1 mapping
201 add r1, r1, #1048576
202 teq r0, r2
203 bne 1b
204/*
205 * If ever we are running from Flash, then we surely want the cache
206 * to be enabled also for our execution instance... We map 2MB of it
207 * so there is no map overlap problem for up to 1 MB compressed kernel.
208 * If the execution is in RAM then we would only be duplicating the above.
209 */
210 mov r1, #0x1e
211 orr r1, r1, #3 << 10
212 mov r2, pc, lsr #20
213 orr r1, r1, r2, lsl #20
214 add r0, r3, r2, lsl #2
215 str r1, [r0], #4
216 add r1, r1, #1048576
217 str r1, [r0]
218 mov pc, lr
219
220__armv4_cache_on:
221 mov r12, lr
222 bl __setup_mmu
223 mov r0, #0
224 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
225 mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
226 mrc p15, 0, r0, c1, c0, 0 @ read control reg
227 orr r0, r0, #0x1000 @ I-cache enable
228 orr r0, r0, #0x0030
229 b __common_cache_on
230
231__arm6_cache_on:
232 mov r12, lr
233 bl __setup_mmu
234 mov r0, #0
235 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
236 mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
237 mov r0, #0x30
238__common_cache_on:
239#ifndef DEBUG
240 orr r0, r0, #0x000d @ Write buffer, mmu
241#endif
242 mov r1, #-1
243 mcr p15, 0, r3, c2, c0, 0 @ load page table pointer
244 mcr p15, 0, r1, c3, c0, 0 @ load domain access control
245 mcr p15, 0, r0, c1, c0, 0 @ load control register
246 mov pc, r12
247
248/*
249 * All code following this line is relocatable. It is relocated by
250 * the above code to the end of the decompressed kernel image and
251 * executed there. During this time, we have no stacks.
252 *
253 * r0 = decompressed kernel length
254 * r1-r3 = unused
255 * r4 = kernel execution address
256 * r5 = decompressed kernel start
257 * r6 = processor ID
258 * r7 = architecture ID
259 * r8-r14 = unused
260 */
261 .align 5
262reloc_start: add r8, r5, r0
263 debug_reloc_start
264 mov r1, r4
2651:
266 .rept 4
267 ldmia r5!, {r0, r2, r3, r9 - r13} @ relocate kernel
268 stmia r1!, {r0, r2, r3, r9 - r13}
269 .endr
270
271 cmp r5, r8
272 blo 1b
273 debug_reloc_end
274
275call_kernel: bl cache_clean_flush
276 bl cache_off
277 mov r0, #0
278 mov r1, r7 @ restore architecture number
279 mov pc, r4 @ call kernel
280
281/*
282 * Here follow the relocatable cache support functions for the
283 * various processors. This is a generic hook for locating an
284 * entry and jumping to an instruction at the specified offset
285 * from the start of the block. Please note this is all position
286 * independent code.
287 *
288 * r1 = corrupted
289 * r2 = corrupted
290 * r3 = block offset
291 * r6 = corrupted
292 * r12 = corrupted
293 */
294
295call_cache_fn: adr r12, proc_types
296 mrc p15, 0, r6, c0, c0 @ get processor ID
2971: ldr r1, [r12, #0] @ get value
298 ldr r2, [r12, #4] @ get mask
299 eor r1, r1, r6 @ (real ^ match)
300 tst r1, r2 @ & mask
301 addeq pc, r12, r3 @ call cache function
302 add r12, r12, #4*5
303 b 1b
304
305/*
306 * Table for cache operations. This is basically:
307 * - CPU ID match
308 * - CPU ID mask
309 * - 'cache on' method instruction
310 * - 'cache off' method instruction
311 * - 'cache flush' method instruction
312 *
313 * We match an entry using: ((real_id ^ match) & mask) == 0
314 *
315 * Writethrough caches generally only need 'on' and 'off'
316 * methods. Writeback caches _must_ have the flush method
317 * defined.
318 */
319 .type proc_types,#object
320proc_types:
321 .word 0x41560600 @ ARM6/610
322 .word 0xffffffe0
323 b __arm6_cache_off @ works, but slow
324 b __arm6_cache_off
325 mov pc, lr
326@ b __arm6_cache_on @ untested
327@ b __arm6_cache_off
328@ b __armv3_cache_flush
329
330 .word 0x41007000 @ ARM7/710
331 .word 0xfff8fe00
332 b __arm7_cache_off
333 b __arm7_cache_off
334 mov pc, lr
335
336 .word 0x41807200 @ ARM720T (writethrough)
337 .word 0xffffff00
338 b __armv4_cache_on
339 b __armv4_cache_off
340 mov pc, lr
341
342 .word 0x41129200 @ ARM920T
343 .word 0xff00fff0
344 b __armv4_cache_on
345 b __armv4_cache_off
346 b __armv4_cache_flush
347
348 .word 0x4401a100 @ sa110 / sa1100
349 .word 0xffffffe0
350 b __armv4_cache_on
351 b __armv4_cache_off
352 b __armv4_cache_flush
353
354 .word 0x6901b110 @ sa1110
355 .word 0xfffffff0
356 b __armv4_cache_on
357 b __armv4_cache_off
358 b __armv4_cache_flush
359
360 .word 0x69050000 @ xscale
361 .word 0xffff0000
362 b __armv4_cache_on
363 b __armv4_cache_off
364 b __armv4_cache_flush
365
366 .word 0 @ unrecognised type
367 .word 0
368 mov pc, lr
369 mov pc, lr
370 mov pc, lr
371
372 .size proc_types, . - proc_types
373
374/*
375 * Turn off the Cache and MMU. ARMv3 does not support
376 * reading the control register, but ARMv4 does.
377 *
378 * On entry, r6 = processor ID
379 * On exit, r0, r1, r2, r3, r12 corrupted
380 * This routine must preserve: r4, r6, r7
381 */
382 .align 5
383cache_off: mov r3, #12 @ cache_off function
384 b call_cache_fn
385
386__armv4_cache_off:
387 mrc p15, 0, r0, c1, c0
388 bic r0, r0, #0x000d
389 mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
390 mov r0, #0
391 mcr p15, 0, r0, c7, c7 @ invalidate whole cache v4
392 mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4
393 mov pc, lr
394
395__arm6_cache_off:
396 mov r0, #0x00000030 @ ARM6 control reg.
397 b __armv3_cache_off
398
399__arm7_cache_off:
400 mov r0, #0x00000070 @ ARM7 control reg.
401 b __armv3_cache_off
402
403__armv3_cache_off:
404 mcr p15, 0, r0, c1, c0, 0 @ turn MMU and cache off
405 mov r0, #0
406 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
407 mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
408 mov pc, lr
409
410/*
411 * Clean and flush the cache to maintain consistency.
412 *
413 * On entry,
414 * r6 = processor ID
415 * On exit,
416 * r1, r2, r3, r12 corrupted
417 * This routine must preserve:
418 * r0, r4, r5, r6, r7
419 */
420 .align 5
421cache_clean_flush:
422 mov r3, #16
423 b call_cache_fn
424
425__armv4_cache_flush:
426 bic r1, pc, #31
427 add r2, r1, #65536 @ 2x the largest dcache size
4281: ldr r12, [r1], #32 @ s/w flush D cache
429 teq r1, r2
430 bne 1b
431
432 mcr p15, 0, r1, c7, c7, 0 @ flush I cache
433 mcr p15, 0, r1, c7, c10, 4 @ drain WB
434 mov pc, lr
435
436__armv3_cache_flush:
437 mov r1, #0
438 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
439 mov pc, lr
440
441/*
442 * Various debugging routines for printing hex characters and
443 * memory, which again must be relocatable.
444 */
445#ifdef DEBUG
446 .type phexbuf,#object
447phexbuf: .space 12
448 .size phexbuf, . - phexbuf
449
450phex: adr r3, phexbuf
451 mov r2, #0
452 strb r2, [r3, r1]
4531: subs r1, r1, #1
454 movmi r0, r3
455 bmi puts
456 and r2, r0, #15
457 mov r0, r0, lsr #4
458 cmp r2, #10
459 addge r2, r2, #7
460 add r2, r2, #'0'
461 strb r2, [r3, r1]
462 b 1b
463
464puts: loadsp r3
4651: ldrb r2, [r0], #1
466 teq r2, #0
467 moveq pc, lr
4682: writeb r2
469 mov r1, #0x00020000
4703: subs r1, r1, #1
471 bne 3b
472 teq r2, #'\n'
473 moveq r2, #'\r'
474 beq 2b
475 teq r0, #0
476 bne 1b
477 mov pc, lr
478putc:
479 mov r2, r0
480 mov r0, #0
481 loadsp r3
482 b 2b
483
484memdump: mov r12, r0
485 mov r10, lr
486 mov r11, #0
4872: mov r0, r11, lsl #2
488 add r0, r0, r12
489 mov r1, #8
490 bl phex
491 mov r0, #':'
492 bl putc
4931: mov r0, #' '
494 bl putc
495 ldr r0, [r12, r11, lsl #2]
496 mov r1, #8
497 bl phex
498 and r0, r11, #7
499 teq r0, #3
500 moveq r0, #' '
501 bleq putc
502 and r0, r11, #7
503 add r11, r11, #1
504 teq r0, #7
505 bne 1b
506 mov r0, #'\n'
507 bl putc
508 cmp r11, #64
509 blt 2b
510 mov pc, r10
511#endif
512
513reloc_end:
514
515 .align
516 .section ".stack", "aw"
517user_stack: .space 4096
diff --git a/arch/arm26/boot/compressed/hw-bse.c b/arch/arm26/boot/compressed/hw-bse.c
new file mode 100644
index 000000000000..3e8f07f8e08a
--- /dev/null
+++ b/arch/arm26/boot/compressed/hw-bse.c
@@ -0,0 +1,74 @@
1/*
2 * Bright Star Engineering Inc.
3 *
4 * code for readng parameters from the
5 * parameter blocks of the boot block
6 * flash memory
7 *
8 */
9
10static int strcmp(const char *s1, const char *s2)
11{
12 while (*s1 != '\0' && *s1 == *s2)
13 {
14 s1++;
15 s2++;
16 }
17
18 return (*(unsigned char *) s1) - (*(unsigned char *) s2);
19}
20
21struct pblk_t {
22 char type;
23 unsigned short size;
24};
25
26static char *bse_getflashparam(char *name) {
27 unsigned int esize;
28 char *q,*r;
29 unsigned char *p,*e;
30 struct pblk_t *thepb = (struct pblk_t *) 0x00004000;
31 struct pblk_t *altpb = (struct pblk_t *) 0x00006000;
32 if (thepb->type&1) {
33 if (altpb->type&1) {
34 /* no valid param block */
35 return (char*)0;
36 } else {
37 /* altpb is valid */
38 struct pblk_t *tmp;
39 tmp = thepb;
40 thepb = altpb;
41 altpb = tmp;
42 }
43 }
44 p = (char*)thepb + sizeof(struct pblk_t);
45 e = p + thepb->size;
46 while (p < e) {
47 q = p;
48 esize = *p;
49 if (esize == 0xFF) break;
50 if (esize == 0) break;
51 if (esize > 127) {
52 esize = (esize&0x7F)<<8 | p[1];
53 q++;
54 }
55 q++;
56 r=q;
57 if (*r && ((name == 0) || (!strcmp(name,r)))) {
58 while (*q++) ;
59 return q;
60 }
61 p+=esize;
62 }
63 return (char*)0;
64}
65
66void bse_setup(void) {
67 /* extract the linux cmdline from flash */
68 char *name=bse_getflashparam("linuxboot");
69 char *x = (char *)0xc0000100;
70 if (name) {
71 while (*name) *x++=*name++;
72 }
73 *x=0;
74}
diff --git a/arch/arm26/boot/compressed/ll_char_wr.S b/arch/arm26/boot/compressed/ll_char_wr.S
new file mode 100644
index 000000000000..f024c3ebdfa5
--- /dev/null
+++ b/arch/arm26/boot/compressed/ll_char_wr.S
@@ -0,0 +1,162 @@
1/*
2 * linux/arch/arm26/lib/ll_char_wr.S
3 *
4 * Copyright (C) 1995, 1996 Russell King.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Speedups & 1bpp code (C) 1996 Philip Blundell & Russell King.
11 *
12 * 10-04-96 RMK Various cleanups & reduced register usage.
13 * 08-04-98 RMK Shifts re-ordered
14 */
15
16@ Regs: [] = corruptible
17@ {} = used
18@ () = do not use
19
20#include <linux/linkage.h>
21#include <asm/assembler.h>
22 .text
23
24#define BOLD 0x01
25#define ITALIC 0x02
26#define UNDERLINE 0x04
27#define FLASH 0x08
28#define INVERSE 0x10
29
30LC0: .word bytes_per_char_h
31 .word video_size_row
32 .word acorndata_8x8
33 .word con_charconvtable
34
35ENTRY(ll_write_char)
36 stmfd sp!, {r4 - r7, lr}
37@
38@ Smashable regs: {r0 - r3}, [r4 - r7], (r8 - fp), [ip], (sp), [lr], (pc)
39@
40 eor ip, r1, #UNDERLINE << 9
41/*
42 * calculate colours
43 */
44 tst r1, #INVERSE << 9
45 moveq r2, r1, lsr #16
46 moveq r3, r1, lsr #24
47 movne r2, r1, lsr #24
48 movne r3, r1, lsr #16
49 and r3, r3, #255
50 and r2, r2, #255
51/*
52 * calculate offset into character table
53 */
54 mov r1, r1, lsl #23
55 mov r1, r1, lsr #20
56/*
57 * calculate offset required for each row [maybe I should make this an argument to this fn.
58 * Have to see what the register usage is like in the calling routines.
59 */
60 adr r4, LC0
61 ldmia r4, {r4, r5, r6, lr}
62 ldr r4, [r4]
63 ldr r5, [r5]
64/*
65 * Go to resolution-dependent routine...
66 */
67 cmp r4, #4
68 blt Lrow1bpp
69 eor r2, r3, r2 @ Create eor mask to change colour from bg
70 orr r3, r3, r3, lsl #8 @ to fg.
71 orr r3, r3, r3, lsl #16
72 add r0, r0, r5, lsl #3 @ Move to bottom of character
73 add r1, r1, #7
74 ldrb r7, [r6, r1]
75 tst ip, #UNDERLINE << 9
76 eoreq r7, r7, #255
77 teq r4, #8
78 beq Lrow8bpplp
79@
80@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
81@
82 orr r3, r3, r3, lsl #4
83Lrow4bpplp: ldr r7, [lr, r7, lsl #2]
84 mul r7, r2, r7
85 tst r1, #7 @ avoid using r7 directly after
86 eor ip, r3, r7
87 str ip, [r0, -r5]!
88 LOADREGS(eqfd, sp!, {r4 - r7, pc})
89 sub r1, r1, #1
90 ldrb r7, [r6, r1]
91 ldr r7, [lr, r7, lsl #2]
92 mul r7, r2, r7
93 tst r1, #7 @ avoid using r7 directly after
94 eor ip, r3, r7
95 str ip, [r0, -r5]!
96 subne r1, r1, #1
97 ldrneb r7, [r6, r1]
98 bne Lrow4bpplp
99 LOADREGS(fd, sp!, {r4 - r7, pc})
100
101@
102@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
103@
104Lrow8bpplp: mov ip, r7, lsr #4
105 ldr ip, [lr, ip, lsl #2]
106 mul r4, r2, ip
107 and ip, r7, #15 @ avoid r4
108 ldr ip, [lr, ip, lsl #2] @ avoid r4
109 mul ip, r2, ip @ avoid r4
110 eor r4, r3, r4 @ avoid ip
111 tst r1, #7 @ avoid ip
112 sub r0, r0, r5 @ avoid ip
113 eor ip, r3, ip
114 stmia r0, {r4, ip}
115 LOADREGS(eqfd, sp!, {r4 - r7, pc})
116 sub r1, r1, #1
117 ldrb r7, [r6, r1]
118 mov ip, r7, lsr #4
119 ldr ip, [lr, ip, lsl #2]
120 mul r4, r2, ip
121 and ip, r7, #15 @ avoid r4
122 ldr ip, [lr, ip, lsl #2] @ avoid r4
123 mul ip, r2, ip @ avoid r4
124 eor r4, r3, r4 @ avoid ip
125 tst r1, #7 @ avoid ip
126 sub r0, r0, r5 @ avoid ip
127 eor ip, r3, ip
128 stmia r0, {r4, ip}
129 subne r1, r1, #1
130 ldrneb r7, [r6, r1]
131 bne Lrow8bpplp
132 LOADREGS(fd, sp!, {r4 - r7, pc})
133
134@
135@ Smashable regs: {r0 - r3}, [r4], {r5, r6}, [r7], (r8 - fp), [ip], (sp), [lr], (pc)
136@
137Lrow1bpp: add r6, r6, r1
138 ldmia r6, {r4, r7}
139 tst ip, #INVERSE << 9
140 mvnne r4, r4
141 mvnne r7, r7
142 strb r4, [r0], r5
143 mov r4, r4, lsr #8
144 strb r4, [r0], r5
145 mov r4, r4, lsr #8
146 strb r4, [r0], r5
147 mov r4, r4, lsr #8
148 strb r4, [r0], r5
149 strb r7, [r0], r5
150 mov r7, r7, lsr #8
151 strb r7, [r0], r5
152 mov r7, r7, lsr #8
153 strb r7, [r0], r5
154 mov r7, r7, lsr #8
155 tst ip, #UNDERLINE << 9
156 mvneq r7, r7
157 strb r7, [r0], r5
158 LOADREGS(fd, sp!, {r4 - r7, pc})
159
160 .bss
161ENTRY(con_charconvtable)
162 .space 1024
diff --git a/arch/arm26/boot/compressed/misc.c b/arch/arm26/boot/compressed/misc.c
new file mode 100644
index 000000000000..f17f50e5516f
--- /dev/null
+++ b/arch/arm26/boot/compressed/misc.c
@@ -0,0 +1,316 @@
1/*
2 * misc.c
3 *
4 * This is a collection of several routines from gzip-1.0.3
5 * adapted for Linux.
6 *
7 * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
8 *
9 * Modified for ARM Linux by Russell King
10 *
11 * Nicolas Pitre <nico@visuaide.com> 1999/04/14 :
12 * For this code to run directly from Flash, all constant variables must
13 * be marked with 'const' and all other variables initialized at run-time
14 * only. This way all non constant variables will end up in the bss segment,
15 * which should point to addresses in RAM and cleared to 0 on start.
16 * This allows for a much quicker boot time.
17 */
18
19unsigned int __machine_arch_type;
20
21#include <linux/kernel.h>
22
23#include <asm/uaccess.h>
24#include "uncompress.h"
25
26#ifdef STANDALONE_DEBUG
27#define puts printf
28#endif
29
30#define __ptr_t void *
31
32/*
33 * Optimised C version of memzero for the ARM.
34 */
35void __memzero (__ptr_t s, size_t n)
36{
37 union { void *vp; unsigned long *ulp; unsigned char *ucp; } u;
38 int i;
39
40 u.vp = s;
41
42 for (i = n >> 5; i > 0; i--) {
43 *u.ulp++ = 0;
44 *u.ulp++ = 0;
45 *u.ulp++ = 0;
46 *u.ulp++ = 0;
47 *u.ulp++ = 0;
48 *u.ulp++ = 0;
49 *u.ulp++ = 0;
50 *u.ulp++ = 0;
51 }
52
53 if (n & 1 << 4) {
54 *u.ulp++ = 0;
55 *u.ulp++ = 0;
56 *u.ulp++ = 0;
57 *u.ulp++ = 0;
58 }
59
60 if (n & 1 << 3) {
61 *u.ulp++ = 0;
62 *u.ulp++ = 0;
63 }
64
65 if (n & 1 << 2)
66 *u.ulp++ = 0;
67
68 if (n & 1 << 1) {
69 *u.ucp++ = 0;
70 *u.ucp++ = 0;
71 }
72
73 if (n & 1)
74 *u.ucp++ = 0;
75}
76
77static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
78 size_t __n)
79{
80 int i = 0;
81 unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
82
83 for (i = __n >> 3; i > 0; i--) {
84 *d++ = *s++;
85 *d++ = *s++;
86 *d++ = *s++;
87 *d++ = *s++;
88 *d++ = *s++;
89 *d++ = *s++;
90 *d++ = *s++;
91 *d++ = *s++;
92 }
93
94 if (__n & 1 << 2) {
95 *d++ = *s++;
96 *d++ = *s++;
97 *d++ = *s++;
98 *d++ = *s++;
99 }
100
101 if (__n & 1 << 1) {
102 *d++ = *s++;
103 *d++ = *s++;
104 }
105
106 if (__n & 1)
107 *d++ = *s++;
108
109 return __dest;
110}
111
112/*
113 * gzip delarations
114 */
115#define OF(args) args
116#define STATIC static
117
118typedef unsigned char uch;
119typedef unsigned short ush;
120typedef unsigned long ulg;
121
122#define WSIZE 0x8000 /* Window size must be at least 32k, */
123 /* and a power of two */
124
125static uch *inbuf; /* input buffer */
126static uch window[WSIZE]; /* Sliding window buffer */
127
128static unsigned insize; /* valid bytes in inbuf */
129static unsigned inptr; /* index of next byte to be processed in inbuf */
130static unsigned outcnt; /* bytes in output buffer */
131
132/* gzip flag byte */
133#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
134#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
135#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
136#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
137#define COMMENT 0x10 /* bit 4 set: file comment present */
138#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
139#define RESERVED 0xC0 /* bit 6,7: reserved */
140
141#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
142
143/* Diagnostic functions */
144#ifdef DEBUG
145# define Assert(cond,msg) {if(!(cond)) error(msg);}
146# define Trace(x) fprintf x
147# define Tracev(x) {if (verbose) fprintf x ;}
148# define Tracevv(x) {if (verbose>1) fprintf x ;}
149# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
150# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
151#else
152# define Assert(cond,msg)
153# define Trace(x)
154# define Tracev(x)
155# define Tracevv(x)
156# define Tracec(c,x)
157# define Tracecv(c,x)
158#endif
159
160static int fill_inbuf(void);
161static void flush_window(void);
162static void error(char *m);
163static void gzip_mark(void **);
164static void gzip_release(void **);
165
166extern char input_data[];
167extern char input_data_end[];
168
169static uch *output_data;
170static ulg output_ptr;
171static ulg bytes_out;
172
173static void *malloc(int size);
174static void free(void *where);
175static void error(char *m);
176static void gzip_mark(void **);
177static void gzip_release(void **);
178
179static void puts(const char *);
180
181extern int end;
182static ulg free_mem_ptr;
183static ulg free_mem_ptr_end;
184
185#define HEAP_SIZE 0x2000
186
187#include "../../../../lib/inflate.c"
188
189#ifndef STANDALONE_DEBUG
190static void *malloc(int size)
191{
192 void *p;
193
194 if (size <0) error("Malloc error");
195 if (free_mem_ptr <= 0) error("Memory error");
196
197 free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
198
199 p = (void *)free_mem_ptr;
200 free_mem_ptr += size;
201
202 if (free_mem_ptr >= free_mem_ptr_end)
203 error("Out of memory");
204 return p;
205}
206
207static void free(void *where)
208{ /* gzip_mark & gzip_release do the free */
209}
210
211static void gzip_mark(void **ptr)
212{
213 arch_decomp_wdog();
214 *ptr = (void *) free_mem_ptr;
215}
216
217static void gzip_release(void **ptr)
218{
219 arch_decomp_wdog();
220 free_mem_ptr = (long) *ptr;
221}
222#else
223static void gzip_mark(void **ptr)
224{
225}
226
227static void gzip_release(void **ptr)
228{
229}
230#endif
231
232/* ===========================================================================
233 * Fill the input buffer. This is called only when the buffer is empty
234 * and at least one byte is really needed.
235 */
236int fill_inbuf(void)
237{
238 if (insize != 0)
239 error("ran out of input data");
240
241 inbuf = input_data;
242 insize = &input_data_end[0] - &input_data[0];
243
244 inptr = 1;
245 return inbuf[0];
246}
247
248/* ===========================================================================
249 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
250 * (Used for the decompressed data only.)
251 */
252void flush_window(void)
253{
254 ulg c = crc;
255 unsigned n;
256 uch *in, *out, ch;
257
258 in = window;
259 out = &output_data[output_ptr];
260 for (n = 0; n < outcnt; n++) {
261 ch = *out++ = *in++;
262 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
263 }
264 crc = c;
265 bytes_out += (ulg)outcnt;
266 output_ptr += (ulg)outcnt;
267 outcnt = 0;
268 puts(".");
269}
270
271static void error(char *x)
272{
273 int ptr;
274
275 puts("\n\n");
276 puts(x);
277 puts("\n\n -- System halted");
278
279 while(1); /* Halt */
280}
281
282#ifndef STANDALONE_DEBUG
283
284ulg
285decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
286 int arch_id)
287{
288 output_data = (uch *)output_start; /* Points to kernel start */
289 free_mem_ptr = free_mem_ptr_p;
290 free_mem_ptr_end = free_mem_ptr_end_p;
291 __machine_arch_type = arch_id;
292
293 arch_decomp_setup();
294
295 makecrc();
296 puts("Uncompressing Linux...");
297 gunzip();
298 puts(" done, booting the kernel.\n");
299 return output_ptr;
300}
301#else
302
303char output_buffer[1500*1024];
304
305int main()
306{
307 output_data = output_buffer;
308
309 makecrc();
310 puts("Uncompressing Linux...");
311 gunzip();
312 puts("done.\n");
313 return 0;
314}
315#endif
316
diff --git a/arch/arm26/boot/compressed/uncompress.h b/arch/arm26/boot/compressed/uncompress.h
new file mode 100644
index 000000000000..66d9b938a7a4
--- /dev/null
+++ b/arch/arm26/boot/compressed/uncompress.h
@@ -0,0 +1,110 @@
1/*
2 *
3 * Copyright (C) 1996 Russell King
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9#define VIDMEM ((char *)0x02000000)
10
11int video_num_columns, video_num_lines, video_size_row;
12int white, bytes_per_char_h;
13extern unsigned long con_charconvtable[256];
14
15struct param_struct {
16 unsigned long page_size;
17 unsigned long nr_pages;
18 unsigned long ramdisk_size;
19 unsigned long mountrootrdonly;
20 unsigned long rootdev;
21 unsigned long video_num_cols;
22 unsigned long video_num_rows;
23 unsigned long video_x;
24 unsigned long video_y;
25 unsigned long memc_control_reg;
26 unsigned char sounddefault;
27 unsigned char adfsdrives;
28 unsigned char bytes_per_char_h;
29 unsigned char bytes_per_char_v;
30 unsigned long unused[256/4-11];
31};
32
33static struct param_struct *params = (struct param_struct *)0x0207c000;
34
35/*
36 * This does not append a newline
37 */
38static void puts(const char *s)
39{
40 extern void ll_write_char(char *, unsigned long);
41 int x,y;
42 unsigned char c;
43 char *ptr;
44
45 x = params->video_x;
46 y = params->video_y;
47
48 while ( ( c = *(unsigned char *)s++ ) != '\0' ) {
49 if ( c == '\n' ) {
50 x = 0;
51 if ( ++y >= video_num_lines ) {
52 y--;
53 }
54 } else {
55 ptr = VIDMEM + ((y*video_num_columns*params->bytes_per_char_v+x)*bytes_per_char_h);
56 ll_write_char(ptr, c|(white<<16));
57 if ( ++x >= video_num_columns ) {
58 x = 0;
59 if ( ++y >= video_num_lines ) {
60 y--;
61 }
62 }
63 }
64 }
65
66 params->video_x = x;
67 params->video_y = y;
68}
69
70static void error(char *x);
71
72/*
73 * Setup for decompression
74 */
75static void arch_decomp_setup(void)
76{
77 int i;
78
79 video_num_lines = params->video_num_rows;
80 video_num_columns = params->video_num_cols;
81 bytes_per_char_h = params->bytes_per_char_h;
82 video_size_row = video_num_columns * bytes_per_char_h;
83 if (bytes_per_char_h == 4)
84 for (i = 0; i < 256; i++)
85 con_charconvtable[i] =
86 (i & 128 ? 1 << 0 : 0) |
87 (i & 64 ? 1 << 4 : 0) |
88 (i & 32 ? 1 << 8 : 0) |
89 (i & 16 ? 1 << 12 : 0) |
90 (i & 8 ? 1 << 16 : 0) |
91 (i & 4 ? 1 << 20 : 0) |
92 (i & 2 ? 1 << 24 : 0) |
93 (i & 1 ? 1 << 28 : 0);
94 else
95 for (i = 0; i < 16; i++)
96 con_charconvtable[i] =
97 (i & 8 ? 1 << 0 : 0) |
98 (i & 4 ? 1 << 8 : 0) |
99 (i & 2 ? 1 << 16 : 0) |
100 (i & 1 ? 1 << 24 : 0);
101
102 white = bytes_per_char_h == 8 ? 0xfc : 7;
103
104 if (params->nr_pages * params->page_size < 4096*1024) error("<4M of mem\n");
105}
106
107/*
108 * nothing to do
109 */
110#define arch_decomp_wdog()
diff --git a/arch/arm26/boot/compressed/vmlinux.lds.in b/arch/arm26/boot/compressed/vmlinux.lds.in
new file mode 100644
index 000000000000..86d821d5ab70
--- /dev/null
+++ b/arch/arm26/boot/compressed/vmlinux.lds.in
@@ -0,0 +1,60 @@
1/*
2 * linux/arch/arm26/boot/compressed/vmlinux.lds.in
3 *
4 * Copyright (C) 2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10OUTPUT_ARCH(arm)
11ENTRY(_start)
12SECTIONS
13{
14 . = LOAD_ADDR;
15 _load_addr = .;
16
17 . = TEXT_START;
18 _text = .;
19
20 .text : {
21 _start = .;
22 *(.start)
23 *(.text)
24 *(.fixup)
25 *(.gnu.warning)
26 *(.rodata)
27 *(.rodata.*)
28 *(.glue_7)
29 *(.glue_7t)
30 input_data = .;
31 arch/arm26/boot/compressed/piggy.o
32 input_data_end = .;
33 . = ALIGN(4);
34 }
35
36 _etext = .;
37
38 _got_start = .;
39 .got : { *(.got) }
40 _got_end = .;
41 .got.plt : { *(.got.plt) }
42 .data : { *(.data) }
43 _edata = .;
44
45 . = BSS_START;
46 __bss_start = .;
47 .bss : { *(.bss) }
48 _end = .;
49
50 .stack (NOLOAD) : { *(.stack) }
51
52 .stab 0 : { *(.stab) }
53 .stabstr 0 : { *(.stabstr) }
54 .stab.excl 0 : { *(.stab.excl) }
55 .stab.exclstr 0 : { *(.stab.exclstr) }
56 .stab.index 0 : { *(.stab.index) }
57 .stab.indexstr 0 : { *(.stab.indexstr) }
58 .comment 0 : { *(.comment) }
59}
60