Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /*****************************************************************************/ |
2 | ||
3 | /* | |
4 | * head.S -- common startup code for ColdFire CPUs. | |
5 | * | |
6 | * (C) Copyright 1999-2004, Greg Ungerer (gerg@snapgear.com). | |
7 | */ | |
8 | ||
9 | /*****************************************************************************/ | |
10 | ||
11 | #include <linux/config.h> | |
12 | #include <linux/sys.h> | |
13 | #include <linux/linkage.h> | |
14 | #include <asm/asm-offsets.h> | |
15 | #include <asm/coldfire.h> | |
16 | #include <asm/mcfcache.h> | |
17 | #include <asm/mcfsim.h> | |
18 | ||
19 | /*****************************************************************************/ | |
20 | ||
21 | /* | |
22 | * Define fixed memory sizes. Configuration of a fixed memory size | |
23 | * overrides everything else. If the user defined a size we just | |
24 | * blindly use it (they know what they are doing right :-) | |
25 | */ | |
26 | #if defined(CONFIG_RAM32MB) | |
27 | #define MEM_SIZE 0x02000000 /* memory size 32Mb */ | |
28 | #elif defined(CONFIG_RAM16MB) | |
29 | #define MEM_SIZE 0x01000000 /* memory size 16Mb */ | |
30 | #elif defined(CONFIG_RAM8MB) | |
31 | #define MEM_SIZE 0x00800000 /* memory size 8Mb */ | |
32 | #elif defined(CONFIG_RAM4MB) | |
33 | #define MEM_SIZE 0x00400000 /* memory size 4Mb */ | |
34 | #elif defined(CONFIG_RAM1MB) | |
35 | #define MEM_SIZE 0x00100000 /* memory size 1Mb */ | |
36 | #endif | |
37 | ||
38 | /* | |
39 | * Memory size exceptions for special cases. Some boards may be set | |
40 | * for auto memory sizing, but we can't do it that way for some reason. | |
41 | * For example the 5206eLITE board has static RAM, and auto-detecting | |
42 | * the SDRAM will do you no good at all. | |
43 | */ | |
44 | #ifdef CONFIG_RAMAUTO | |
45 | #if defined(CONFIG_M5206eLITE) | |
46 | #define MEM_SIZE 0x00100000 /* 1MiB default memory */ | |
47 | #endif | |
48 | #endif /* CONFIG_RAMAUTO */ | |
49 | ||
50 | /* | |
51 | * If we don't have a fixed memory size now, then lets build in code | |
52 | * to auto detect the DRAM size. Obviously this is the prefered | |
53 | * method, and should work for most boards (it won't work for those | |
54 | * that do not have their RAM starting at address 0). | |
55 | */ | |
56 | #if defined(MEM_SIZE) | |
57 | .macro GET_MEM_SIZE | |
58 | movel #MEM_SIZE,%d0 /* hard coded memory size */ | |
59 | .endm | |
60 | ||
61 | #elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ | |
62 | defined(CONFIG_M5249) || defined(CONFIG_M527x) || \ | |
63 | defined(CONFIG_M528x) || defined(CONFIG_M5307) || \ | |
64 | defined(CONFIG_M5407) | |
65 | /* | |
66 | * Not all these devices have exactly the same DRAM controller, | |
67 | * but the DCMR register is virtually identical - give or take | |
68 | * a couple of bits. The only exception is the 5272 devices, their | |
69 | * DRAM controller is quite different. | |
70 | */ | |
71 | .macro GET_MEM_SIZE | |
72 | movel MCF_MBAR+MCFSIM_DMR0,%d0 /* get mask for 1st bank */ | |
73 | btst #0,%d0 /* check if region enabled */ | |
74 | beq 1f | |
75 | andl #0xfffc0000,%d0 | |
76 | beq 1f | |
77 | addl #0x00040000,%d0 /* convert mask to size */ | |
78 | 1: | |
79 | movel MCF_MBAR+MCFSIM_DMR1,%d1 /* get mask for 2nd bank */ | |
80 | btst #0,%d1 /* check if region enabled */ | |
81 | beq 2f | |
82 | andl #0xfffc0000, %d1 | |
83 | beq 2f | |
84 | addl #0x00040000,%d1 | |
85 | addl %d1,%d0 /* total mem size in d0 */ | |
86 | 2: | |
87 | .endm | |
88 | ||
89 | #elif defined(CONFIG_M5272) | |
90 | .macro GET_MEM_SIZE | |
91 | movel MCF_MBAR+MCFSIM_CSOR7,%d0 /* get SDRAM address mask */ | |
92 | andil #0xfffff000,%d0 /* mask out chip select options */ | |
93 | negl %d0 /* negate bits */ | |
94 | .endm | |
95 | ||
96 | #else | |
97 | #error "ERROR: I don't know how to determine your boards memory size?" | |
98 | #endif | |
99 | ||
100 | ||
101 | /* | |
102 | * Most ColdFire boards have their DRAM starting at address 0. | |
103 | * Notable exception is the 5206eLITE board. | |
104 | */ | |
105 | #if defined(CONFIG_M5206eLITE) | |
106 | #define MEM_BASE 0x30000000 | |
107 | #endif | |
108 | ||
109 | #ifndef MEM_BASE | |
110 | #define MEM_BASE 0x00000000 /* memory base at address 0 */ | |
111 | #endif | |
112 | ||
113 | /* | |
114 | * The default location for the vectors is at the base of RAM. | |
115 | * Some boards might like to use internal SRAM or something like | |
116 | * that. If no board specific header defines an alternative then | |
117 | * use the base of RAM. | |
118 | */ | |
119 | #ifndef VBR_BASE | |
120 | #define VBR_BASE MEM_BASE /* vector address */ | |
121 | #endif | |
122 | ||
123 | /*****************************************************************************/ | |
124 | ||
125 | /* | |
126 | * Boards and platforms can do specific early hardware setup if | |
127 | * they need to. Most don't need this, define away if not required. | |
128 | */ | |
129 | #ifndef PLATFORM_SETUP | |
130 | #define PLATFORM_SETUP | |
131 | #endif | |
132 | ||
133 | /*****************************************************************************/ | |
134 | ||
135 | .global _start | |
136 | .global _rambase | |
137 | .global _ramvec | |
138 | .global _ramstart | |
139 | .global _ramend | |
140 | ||
141 | /*****************************************************************************/ | |
142 | ||
143 | .data | |
144 | ||
145 | /* | |
146 | * During startup we store away the RAM setup. These are not in the | |
147 | * bss, since their values are determined and written before the bss | |
148 | * has been cleared. | |
149 | */ | |
150 | _rambase: | |
151 | .long 0 | |
152 | _ramvec: | |
153 | .long 0 | |
154 | _ramstart: | |
155 | .long 0 | |
156 | _ramend: | |
157 | .long 0 | |
158 | ||
159 | /*****************************************************************************/ | |
160 | ||
161 | .text | |
162 | ||
163 | /* | |
164 | * This is the codes first entry point. This is where it all | |
165 | * begins... | |
166 | */ | |
167 | ||
168 | _start: | |
169 | nop /* filler */ | |
170 | movew #0x2700, %sr /* no interrupts */ | |
171 | ||
172 | /* | |
173 | * Do any platform or board specific setup now. Most boards | |
174 | * don't need anything. Those exceptions are define this in | |
175 | * their board specific includes. | |
176 | */ | |
177 | PLATFORM_SETUP | |
178 | ||
179 | /* | |
180 | * Create basic memory configuration. Set VBR accordingly, | |
181 | * and size memory. | |
182 | */ | |
183 | movel #VBR_BASE,%a7 | |
184 | movec %a7,%VBR /* set vectors addr */ | |
185 | movel %a7,_ramvec | |
186 | ||
187 | movel #MEM_BASE,%a7 /* mark the base of RAM */ | |
188 | movel %a7,_rambase | |
189 | ||
190 | GET_MEM_SIZE /* macro code determines size */ | |
191 | movel %d0,_ramend /* set end ram addr */ | |
192 | ||
193 | /* | |
194 | * Now that we know what the memory is, lets enable cache | |
195 | * and get things moving. This is Coldfire CPU specific. | |
196 | */ | |
197 | CACHE_ENABLE /* enable CPU cache */ | |
198 | ||
199 | ||
200 | #ifdef CONFIG_ROMFS_FS | |
201 | /* | |
202 | * Move ROM filesystem above bss :-) | |
203 | */ | |
204 | lea _sbss,%a0 /* get start of bss */ | |
205 | lea _ebss,%a1 /* set up destination */ | |
206 | movel %a0,%a2 /* copy of bss start */ | |
207 | ||
208 | movel 8(%a0),%d0 /* get size of ROMFS */ | |
209 | addql #8,%d0 /* allow for rounding */ | |
210 | andl #0xfffffffc, %d0 /* whole words */ | |
211 | ||
212 | addl %d0,%a0 /* copy from end */ | |
213 | addl %d0,%a1 /* copy from end */ | |
214 | movel %a1,_ramstart /* set start of ram */ | |
215 | ||
216 | _copy_romfs: | |
217 | movel -(%a0),%d0 /* copy dword */ | |
218 | movel %d0,-(%a1) | |
219 | cmpl %a0,%a2 /* check if at end */ | |
220 | bne _copy_romfs | |
221 | ||
222 | #else /* CONFIG_ROMFS_FS */ | |
223 | lea _ebss,%a1 | |
224 | movel %a1,_ramstart | |
225 | #endif /* CONFIG_ROMFS_FS */ | |
226 | ||
227 | ||
228 | /* | |
229 | * Zero out the bss region. | |
230 | */ | |
231 | lea _sbss,%a0 /* get start of bss */ | |
232 | lea _ebss,%a1 /* get end of bss */ | |
233 | clrl %d0 /* set value */ | |
234 | _clear_bss: | |
235 | movel %d0,(%a0)+ /* clear each word */ | |
236 | cmpl %a0,%a1 /* check if at end */ | |
237 | bne _clear_bss | |
238 | ||
239 | /* | |
240 | * Load the current task pointer and stack. | |
241 | */ | |
242 | lea init_thread_union,%a0 | |
243 | lea THREAD_SIZE(%a0),%sp | |
244 | ||
245 | /* | |
246 | * Assember start up done, start code proper. | |
247 | */ | |
248 | jsr start_kernel /* start Linux kernel */ | |
249 | ||
250 | _exit: | |
251 | jmp _exit /* should never get here */ | |
252 | ||
253 | /*****************************************************************************/ |