diff options
Diffstat (limited to 'arch/m68k/platform/coldfire/head.S')
-rw-r--r-- | arch/m68k/platform/coldfire/head.S | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/arch/m68k/platform/coldfire/head.S b/arch/m68k/platform/coldfire/head.S new file mode 100644 index 00000000000..129bff4956b --- /dev/null +++ b/arch/m68k/platform/coldfire/head.S | |||
@@ -0,0 +1,250 @@ | |||
1 | /*****************************************************************************/ | ||
2 | |||
3 | /* | ||
4 | * head.S -- common startup code for ColdFire CPUs. | ||
5 | * | ||
6 | * (C) Copyright 1999-2010, Greg Ungerer <gerg@snapgear.com>. | ||
7 | */ | ||
8 | |||
9 | /*****************************************************************************/ | ||
10 | |||
11 | #include <linux/sys.h> | ||
12 | #include <linux/linkage.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <asm/asm-offsets.h> | ||
15 | #include <asm/coldfire.h> | ||
16 | #include <asm/mcfsim.h> | ||
17 | #include <asm/thread_info.h> | ||
18 | |||
19 | /*****************************************************************************/ | ||
20 | |||
21 | /* | ||
22 | * If we don't have a fixed memory size, then lets build in code | ||
23 | * to auto detect the DRAM size. Obviously this is the prefered | ||
24 | * method, and should work for most boards. It won't work for those | ||
25 | * that do not have their RAM starting at address 0, and it only | ||
26 | * works on SDRAM (not boards fitted with SRAM). | ||
27 | */ | ||
28 | #if CONFIG_RAMSIZE != 0 | ||
29 | .macro GET_MEM_SIZE | ||
30 | movel #CONFIG_RAMSIZE,%d0 /* hard coded memory size */ | ||
31 | .endm | ||
32 | |||
33 | #elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ | ||
34 | defined(CONFIG_M5249) || defined(CONFIG_M527x) || \ | ||
35 | defined(CONFIG_M528x) || defined(CONFIG_M5307) || \ | ||
36 | defined(CONFIG_M5407) | ||
37 | /* | ||
38 | * Not all these devices have exactly the same DRAM controller, | ||
39 | * but the DCMR register is virtually identical - give or take | ||
40 | * a couple of bits. The only exception is the 5272 devices, their | ||
41 | * DRAM controller is quite different. | ||
42 | */ | ||
43 | .macro GET_MEM_SIZE | ||
44 | movel MCFSIM_DMR0,%d0 /* get mask for 1st bank */ | ||
45 | btst #0,%d0 /* check if region enabled */ | ||
46 | beq 1f | ||
47 | andl #0xfffc0000,%d0 | ||
48 | beq 1f | ||
49 | addl #0x00040000,%d0 /* convert mask to size */ | ||
50 | 1: | ||
51 | movel MCFSIM_DMR1,%d1 /* get mask for 2nd bank */ | ||
52 | btst #0,%d1 /* check if region enabled */ | ||
53 | beq 2f | ||
54 | andl #0xfffc0000,%d1 | ||
55 | beq 2f | ||
56 | addl #0x00040000,%d1 | ||
57 | addl %d1,%d0 /* total mem size in d0 */ | ||
58 | 2: | ||
59 | .endm | ||
60 | |||
61 | #elif defined(CONFIG_M5272) | ||
62 | .macro GET_MEM_SIZE | ||
63 | movel MCF_MBAR+MCFSIM_CSOR7,%d0 /* get SDRAM address mask */ | ||
64 | andil #0xfffff000,%d0 /* mask out chip select options */ | ||
65 | negl %d0 /* negate bits */ | ||
66 | .endm | ||
67 | |||
68 | #elif defined(CONFIG_M520x) | ||
69 | .macro GET_MEM_SIZE | ||
70 | clrl %d0 | ||
71 | movel MCFSIM_SDCS0, %d2 /* Get SDRAM chip select 0 config */ | ||
72 | andl #0x1f, %d2 /* Get only the chip select size */ | ||
73 | beq 3f /* Check if it is enabled */ | ||
74 | addql #1, %d2 /* Form exponent */ | ||
75 | moveql #1, %d0 | ||
76 | lsll %d2, %d0 /* 2 ^ exponent */ | ||
77 | 3: | ||
78 | movel MCFSIM_SDCS1, %d2 /* Get SDRAM chip select 1 config */ | ||
79 | andl #0x1f, %d2 /* Get only the chip select size */ | ||
80 | beq 4f /* Check if it is enabled */ | ||
81 | addql #1, %d2 /* Form exponent */ | ||
82 | moveql #1, %d1 | ||
83 | lsll %d2, %d1 /* 2 ^ exponent */ | ||
84 | addl %d1, %d0 /* Total size of SDRAM in d0 */ | ||
85 | 4: | ||
86 | .endm | ||
87 | |||
88 | #else | ||
89 | #error "ERROR: I don't know how to probe your boards memory size?" | ||
90 | #endif | ||
91 | |||
92 | /*****************************************************************************/ | ||
93 | |||
94 | /* | ||
95 | * Boards and platforms can do specific early hardware setup if | ||
96 | * they need to. Most don't need this, define away if not required. | ||
97 | */ | ||
98 | #ifndef PLATFORM_SETUP | ||
99 | #define PLATFORM_SETUP | ||
100 | #endif | ||
101 | |||
102 | /*****************************************************************************/ | ||
103 | |||
104 | .global _start | ||
105 | .global _rambase | ||
106 | .global _ramvec | ||
107 | .global _ramstart | ||
108 | .global _ramend | ||
109 | #if defined(CONFIG_UBOOT) | ||
110 | .global _init_sp | ||
111 | #endif | ||
112 | |||
113 | /*****************************************************************************/ | ||
114 | |||
115 | .data | ||
116 | |||
117 | /* | ||
118 | * During startup we store away the RAM setup. These are not in the | ||
119 | * bss, since their values are determined and written before the bss | ||
120 | * has been cleared. | ||
121 | */ | ||
122 | _rambase: | ||
123 | .long 0 | ||
124 | _ramvec: | ||
125 | .long 0 | ||
126 | _ramstart: | ||
127 | .long 0 | ||
128 | _ramend: | ||
129 | .long 0 | ||
130 | #if defined(CONFIG_UBOOT) | ||
131 | _init_sp: | ||
132 | .long 0 | ||
133 | #endif | ||
134 | |||
135 | /*****************************************************************************/ | ||
136 | |||
137 | __HEAD | ||
138 | |||
139 | /* | ||
140 | * This is the codes first entry point. This is where it all | ||
141 | * begins... | ||
142 | */ | ||
143 | |||
144 | _start: | ||
145 | nop /* filler */ | ||
146 | movew #0x2700, %sr /* no interrupts */ | ||
147 | #if defined(CONFIG_UBOOT) | ||
148 | movel %sp,_init_sp /* save initial stack pointer */ | ||
149 | #endif | ||
150 | |||
151 | /* | ||
152 | * Do any platform or board specific setup now. Most boards | ||
153 | * don't need anything. Those exceptions are define this in | ||
154 | * their board specific includes. | ||
155 | */ | ||
156 | PLATFORM_SETUP | ||
157 | |||
158 | /* | ||
159 | * Create basic memory configuration. Set VBR accordingly, | ||
160 | * and size memory. | ||
161 | */ | ||
162 | movel #CONFIG_VECTORBASE,%a7 | ||
163 | movec %a7,%VBR /* set vectors addr */ | ||
164 | movel %a7,_ramvec | ||
165 | |||
166 | movel #CONFIG_RAMBASE,%a7 /* mark the base of RAM */ | ||
167 | movel %a7,_rambase | ||
168 | |||
169 | GET_MEM_SIZE /* macro code determines size */ | ||
170 | addl %a7,%d0 | ||
171 | movel %d0,_ramend /* set end ram addr */ | ||
172 | |||
173 | /* | ||
174 | * Now that we know what the memory is, lets enable cache | ||
175 | * and get things moving. This is Coldfire CPU specific. Not | ||
176 | * all version cores have identical cache register setup. But | ||
177 | * it is very similar. Define the exact settings in the headers | ||
178 | * then the code here is the same for all. | ||
179 | */ | ||
180 | movel #CACHE_INIT,%d0 /* invalidate whole cache */ | ||
181 | movec %d0,%CACR | ||
182 | nop | ||
183 | movel #ACR0_MODE,%d0 /* set RAM region for caching */ | ||
184 | movec %d0,%ACR0 | ||
185 | movel #ACR1_MODE,%d0 /* anything else to cache? */ | ||
186 | movec %d0,%ACR1 | ||
187 | #ifdef ACR2_MODE | ||
188 | movel #ACR2_MODE,%d0 | ||
189 | movec %d0,%ACR2 | ||
190 | movel #ACR3_MODE,%d0 | ||
191 | movec %d0,%ACR3 | ||
192 | #endif | ||
193 | movel #CACHE_MODE,%d0 /* enable cache */ | ||
194 | movec %d0,%CACR | ||
195 | nop | ||
196 | |||
197 | #ifdef CONFIG_ROMFS_FS | ||
198 | /* | ||
199 | * Move ROM filesystem above bss :-) | ||
200 | */ | ||
201 | lea _sbss,%a0 /* get start of bss */ | ||
202 | lea _ebss,%a1 /* set up destination */ | ||
203 | movel %a0,%a2 /* copy of bss start */ | ||
204 | |||
205 | movel 8(%a0),%d0 /* get size of ROMFS */ | ||
206 | addql #8,%d0 /* allow for rounding */ | ||
207 | andl #0xfffffffc, %d0 /* whole words */ | ||
208 | |||
209 | addl %d0,%a0 /* copy from end */ | ||
210 | addl %d0,%a1 /* copy from end */ | ||
211 | movel %a1,_ramstart /* set start of ram */ | ||
212 | |||
213 | _copy_romfs: | ||
214 | movel -(%a0),%d0 /* copy dword */ | ||
215 | movel %d0,-(%a1) | ||
216 | cmpl %a0,%a2 /* check if at end */ | ||
217 | bne _copy_romfs | ||
218 | |||
219 | #else /* CONFIG_ROMFS_FS */ | ||
220 | lea _ebss,%a1 | ||
221 | movel %a1,_ramstart | ||
222 | #endif /* CONFIG_ROMFS_FS */ | ||
223 | |||
224 | |||
225 | /* | ||
226 | * Zero out the bss region. | ||
227 | */ | ||
228 | lea _sbss,%a0 /* get start of bss */ | ||
229 | lea _ebss,%a1 /* get end of bss */ | ||
230 | clrl %d0 /* set value */ | ||
231 | _clear_bss: | ||
232 | movel %d0,(%a0)+ /* clear each word */ | ||
233 | cmpl %a0,%a1 /* check if at end */ | ||
234 | bne _clear_bss | ||
235 | |||
236 | /* | ||
237 | * Load the current task pointer and stack. | ||
238 | */ | ||
239 | lea init_thread_union,%a0 | ||
240 | lea THREAD_SIZE(%a0),%sp | ||
241 | |||
242 | /* | ||
243 | * Assember start up done, start code proper. | ||
244 | */ | ||
245 | jsr start_kernel /* start Linux kernel */ | ||
246 | |||
247 | _exit: | ||
248 | jmp _exit /* should never get here */ | ||
249 | |||
250 | /*****************************************************************************/ | ||