diff options
Diffstat (limited to 'arch/cris/boot/compressed/head_v32.S')
-rw-r--r-- | arch/cris/boot/compressed/head_v32.S | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/arch/cris/boot/compressed/head_v32.S b/arch/cris/boot/compressed/head_v32.S new file mode 100644 index 000000000000..f483005f3d48 --- /dev/null +++ b/arch/cris/boot/compressed/head_v32.S | |||
@@ -0,0 +1,145 @@ | |||
1 | /* | ||
2 | * Code that sets up the DRAM registers, calls the | ||
3 | * decompressor to unpack the piggybacked kernel, and jumps. | ||
4 | * | ||
5 | * Copyright (C) 1999 - 2006, Axis Communications AB | ||
6 | */ | ||
7 | |||
8 | #define ASSEMBLER_MACROS_ONLY | ||
9 | #include <hwregs/asm/reg_map_asm.h> | ||
10 | #include <mach/startup.inc> | ||
11 | |||
12 | #define RAM_INIT_MAGIC 0x56902387 | ||
13 | #define COMMAND_LINE_MAGIC 0x87109563 | ||
14 | |||
15 | ;; Exported symbols | ||
16 | |||
17 | .globl input_data | ||
18 | |||
19 | .text | ||
20 | start: | ||
21 | di | ||
22 | |||
23 | ;; Start clocks for used blocks. | ||
24 | START_CLOCKS | ||
25 | |||
26 | ;; Initialize the DRAM registers. | ||
27 | cmp.d RAM_INIT_MAGIC, $r8 ; Already initialized? | ||
28 | beq dram_init_finished | ||
29 | nop | ||
30 | |||
31 | #if defined CONFIG_ETRAXFS | ||
32 | #include "../../arch-v32/mach-fs/dram_init.S" | ||
33 | #elif defined CONFIG_CRIS_MACH_ARTPEC3 | ||
34 | #include "../../arch-v32/mach-a3/dram_init.S" | ||
35 | #else | ||
36 | #error Only ETRAXFS and ARTPEC-3 supported! | ||
37 | #endif | ||
38 | |||
39 | dram_init_finished: | ||
40 | |||
41 | GIO_INIT | ||
42 | ;; Setup the stack to a suitably high address. | ||
43 | ;; We assume 8 MB is the minimum DRAM and put | ||
44 | ;; the SP at the top for now. | ||
45 | |||
46 | move.d 0x40800000, $sp | ||
47 | |||
48 | ;; Figure out where the compressed piggyback image is. | ||
49 | ;; It is either in [NOR] flash (we don't want to copy it | ||
50 | ;; to DRAM before unpacking), or copied to DRAM | ||
51 | ;; by the [NAND] flash boot loader. | ||
52 | ;; The piggyback image is at _edata, but relative to where the | ||
53 | ;; image is actually located in memory, not where it is linked | ||
54 | ;; (the decompressor is linked at 0x40700000+ and runs there). | ||
55 | ;; Use (_edata - herami) as offset to the current PC. | ||
56 | |||
57 | hereami: | ||
58 | lapcq ., $r5 ; get PC | ||
59 | and.d 0x7fffffff, $r5 ; strip any non-cache bit | ||
60 | move.d $r5, $r0 ; source address of 'herami' | ||
61 | add.d _edata, $r5 | ||
62 | sub.d hereami, $r5 ; r5 = flash address of '_edata' | ||
63 | move.d hereami, $r1 ; destination | ||
64 | |||
65 | ;; Copy text+data to DRAM | ||
66 | |||
67 | move.d _edata, $r2 ; end destination | ||
68 | 1: move.w [$r0+], $r3 ; from herami+ source | ||
69 | move.w $r3, [$r1+] ; to hereami+ destination (linked address) | ||
70 | cmp.d $r2, $r1 ; finish when destination == _edata | ||
71 | bcs 1b | ||
72 | nop | ||
73 | move.d input_data, $r0 ; for the decompressor | ||
74 | move.d $r5, [$r0] ; for the decompressor | ||
75 | |||
76 | ;; Clear the decompressors BSS (between _edata and _end) | ||
77 | |||
78 | moveq 0, $r0 | ||
79 | move.d _edata, $r1 | ||
80 | move.d _end, $r2 | ||
81 | 1: move.w $r0, [$r1+] | ||
82 | cmp.d $r2, $r1 | ||
83 | bcs 1b | ||
84 | nop | ||
85 | |||
86 | ;; Save command line magic and address. | ||
87 | move.d _cmd_line_magic, $r0 | ||
88 | move.d $r10, [$r0] | ||
89 | move.d _cmd_line_addr, $r0 | ||
90 | move.d $r11, [$r0] | ||
91 | |||
92 | ;; Save boot source indicator | ||
93 | move.d _boot_source, $r0 | ||
94 | move.d $r12, [$r0] | ||
95 | |||
96 | ;; Do the decompression and save compressed size in _inptr | ||
97 | |||
98 | jsr decompress_kernel | ||
99 | nop | ||
100 | |||
101 | ;; Restore boot source indicator | ||
102 | move.d _boot_source, $r12 | ||
103 | move.d [$r12], $r12 | ||
104 | |||
105 | ;; Restore command line magic and address. | ||
106 | move.d _cmd_line_magic, $r10 | ||
107 | move.d [$r10], $r10 | ||
108 | move.d _cmd_line_addr, $r11 | ||
109 | move.d [$r11], $r11 | ||
110 | |||
111 | ;; Put start address of root partition in r9 so the kernel can use it | ||
112 | ;; when mounting from flash | ||
113 | move.d input_data, $r0 | ||
114 | move.d [$r0], $r9 ; flash address of compressed kernel | ||
115 | move.d inptr, $r0 | ||
116 | add.d [$r0], $r9 ; size of compressed kernel | ||
117 | cmp.d 0x40000000, $r9 ; image in DRAM ? | ||
118 | blo enter_kernel ; no, must be [NOR] flash, jump | ||
119 | nop ; delay slot | ||
120 | and.d 0x001fffff, $r9 ; assume compressed kernel was < 2M | ||
121 | |||
122 | enter_kernel: | ||
123 | ;; Enter the decompressed kernel | ||
124 | move.d RAM_INIT_MAGIC, $r8 ; Tell kernel that DRAM is initialized | ||
125 | jump 0x40004000 ; kernel is linked to this address | ||
126 | nop | ||
127 | |||
128 | .data | ||
129 | |||
130 | input_data: | ||
131 | .dword 0 ; used by the decompressor | ||
132 | _cmd_line_magic: | ||
133 | .dword 0 | ||
134 | _cmd_line_addr: | ||
135 | .dword 0 | ||
136 | _boot_source: | ||
137 | .dword 0 | ||
138 | |||
139 | #if defined CONFIG_ETRAXFS | ||
140 | #include "../../arch-v32/mach-fs/hw_settings.S" | ||
141 | #elif defined CONFIG_CRIS_MACH_ARTPEC3 | ||
142 | #include "../../arch-v32/mach-a3/hw_settings.S" | ||
143 | #else | ||
144 | #error Only ETRAXFS and ARTPEC-3 supported! | ||
145 | #endif | ||