1 | /*!@file start.S |
---|
2 | * |
---|
3 | * @brief Initialization code to set up the CPU and call boot_card() |
---|
4 | * |
---|
5 | * This "BSP" targets the Xilinx Virtex XC4VFX60 and related parts. This |
---|
6 | * BSP makes no assumptions on what firmware is loaded into the FPGA. |
---|
7 | * |
---|
8 | * Provides the .entry section code. This is the first code to run in |
---|
9 | * the PPC after download to RAM. Excecution in this case starts at |
---|
10 | * 'download_entry'. |
---|
11 | * |
---|
12 | * The entrypoint 'start' is provided for the case where a bootloader has |
---|
13 | * initialized the CPU, and all that remains to do is to set up a C |
---|
14 | * environment and call boot_card. |
---|
15 | * |
---|
16 | * Derived from virtex dlentry and others. |
---|
17 | * |
---|
18 | * IBM refers to the version of the processor as PPC405F5. |
---|
19 | * The processor version register returns 0x20011470. |
---|
20 | * References: |
---|
21 | * PowerPC Processor Reference Guide UG011 (v1.3) |
---|
22 | * http://www.xilinx.com/support/documentation/user_guides/ug011.pdf |
---|
23 | * |
---|
24 | * PowerPC Block Reference Guide |
---|
25 | * http://www.xilinx.com/support/documentation/user_guides/ug018.pdf |
---|
26 | * |
---|
27 | * PowerPC errata |
---|
28 | * ftp://ftp.xilinx.com/pub/documentation/misc/ppc405f6v5_2_0.pdf |
---|
29 | * |
---|
30 | * PowerPC 405-S Embedded Processor Core User's Manual (Version 1.2) |
---|
31 | * https://www-01.ibm.com/chips/techlib/techlib.nsf/products/PowerPC_405_Embedded_Cores |
---|
32 | * |
---|
33 | * @author Richard Claus <claus@SLAC.Stanford.edu> |
---|
34 | * |
---|
35 | * @date March 4, 2011 -- Created |
---|
36 | * |
---|
37 | * $Revision: 674 $ |
---|
38 | * |
---|
39 | * @verbatim Copyright 2011 |
---|
40 | * by |
---|
41 | * The Board of Trustees of the |
---|
42 | * Leland Stanford Junior University. |
---|
43 | * All rights reserved. |
---|
44 | * |
---|
45 | * Work supported by the U.S. Department of Energy under contract |
---|
46 | * DE-AC03-76SF00515. |
---|
47 | * |
---|
48 | * Disclaimer Notice |
---|
49 | * |
---|
50 | * The items furnished herewith were developed under the sponsorship |
---|
51 | * of the U.S. Government. Neither the U.S., nor the U.S. D.O.E., nor the |
---|
52 | * Leland Stanford Junior University, nor their employees, makes any war- |
---|
53 | * ranty, express or implied, or assumes any liability or responsibility |
---|
54 | * for accuracy, completeness or usefulness of any information, apparatus, |
---|
55 | * product or process disclosed, or represents that its use will not in- |
---|
56 | * fringe privately-owned rights. Mention of any product, its manufactur- |
---|
57 | * er, or suppliers shall not, nor is it intended to, imply approval, dis- |
---|
58 | * approval, or fitness for any particular use. The U.S. and the Univer- |
---|
59 | * sity at all times retain the right to use and disseminate the furnished |
---|
60 | * items for any purpose whatsoever. Notice 91 02 01 |
---|
61 | * |
---|
62 | * @endverbatim |
---|
63 | */ |
---|
64 | |
---|
65 | #include <rtems/asm.h> |
---|
66 | #include <rtems/powerpc/powerpc.h> |
---|
67 | |
---|
68 | /* |
---|
69 | * The virtex ELF link scripts support some special sections: |
---|
70 | * .entry The actual entry point |
---|
71 | * .vectors The section containing the interrupt entry veneers. |
---|
72 | */ |
---|
73 | |
---|
74 | /* |
---|
75 | * Downloaded code loads the vectors separately to 0x00000100, |
---|
76 | * so .entry can be over 256 bytes. |
---|
77 | * |
---|
78 | * The other sections are linked in the following order: |
---|
79 | * .entry |
---|
80 | * .text |
---|
81 | * .data |
---|
82 | * .bss |
---|
83 | * see linker command file for section placement |
---|
84 | * |
---|
85 | * The initial stack is set to _ISR_Stack_area_end. |
---|
86 | * |
---|
87 | */ |
---|
88 | |
---|
89 | .section .entry |
---|
90 | |
---|
91 | PUBLIC_VAR (download_entry) |
---|
92 | PUBLIC_VAR (__rtems_entry_point) |
---|
93 | SYM(download_entry): |
---|
94 | SYM(__rtems_entry_point): |
---|
95 | b startupDow /* Entry point used by xmd dow command */ |
---|
96 | |
---|
97 | PUBLIC_VAR (start) |
---|
98 | SYM(start): |
---|
99 | b startupBL /* Entry point used by bootLoader */ |
---|
100 | |
---|
101 | base_addr: |
---|
102 | /*------------------------------------------------------------------- |
---|
103 | * Parameters from linker |
---|
104 | *-----------------------------------------------------------------*/ |
---|
105 | toc_pointer: |
---|
106 | .long __got_start |
---|
107 | bss_length: |
---|
108 | .long __bss_size |
---|
109 | bss_addr: |
---|
110 | .long __bss_start |
---|
111 | stack_top: |
---|
112 | .long _ISR_Stack_area_end |
---|
113 | dccr_contents: |
---|
114 | .long __dccr |
---|
115 | iccr_contents: |
---|
116 | .long __iccr |
---|
117 | sgr_contents: |
---|
118 | .long __sgr |
---|
119 | |
---|
120 | /*------------------------------------------------------------------- |
---|
121 | * Setup iccr, sgr, msr, cccr0, dcwr, dccr and clear bss |
---|
122 | *-----------------------------------------------------------------*/ |
---|
123 | |
---|
124 | startupDow: |
---|
125 | /*------------------------------------------------------------------- |
---|
126 | * Load the parameter table base address |
---|
127 | *------------------------------------------------------------------*/ |
---|
128 | lis r1, base_addr@h |
---|
129 | ori r1,r1,base_addr@l |
---|
130 | |
---|
131 | /* ------------------------------------------------------------------- |
---|
132 | * Clear the Machine State Register's Critical and External |
---|
133 | * interrupt enables. |
---|
134 | *------------------------------------------------------------------*/ |
---|
135 | mfmsr r3 |
---|
136 | lis r0, 0x00028000@h |
---|
137 | ori r0,r0,0x00028000@l |
---|
138 | andc r3,r3,r0 |
---|
139 | mtmsr r3 |
---|
140 | sync |
---|
141 | |
---|
142 | /* ------------------------------------------------------------------- |
---|
143 | * Initialize the memory system. |
---|
144 | *------------------------------------------------------------------*/ |
---|
145 | li r0,0 |
---|
146 | |
---|
147 | /* Set the Storage Guarded Register. */ |
---|
148 | lwz r2,sgr_contents-base_addr(r1) |
---|
149 | mtsgr r2 |
---|
150 | |
---|
151 | /* Configure endianness, compression */ |
---|
152 | lis r0,0x00000000@h // Endianess value |
---|
153 | mtsler r0 |
---|
154 | lis r0,0x00000000@h // Compression value |
---|
155 | mtsu0r r0 |
---|
156 | |
---|
157 | /* Invalidate the entire instruction cache. */ |
---|
158 | iccci r0,r0 |
---|
159 | |
---|
160 | /* Set the Instruction Cache Cacheability Register. */ |
---|
161 | lwz r2,iccr_contents-base_addr(r1) |
---|
162 | mticcr r2 |
---|
163 | isync |
---|
164 | |
---|
165 | /*------------------------------------------------------------------- |
---|
166 | * Tell the processor where the exception vector table will be. |
---|
167 | *------------------------------------------------------------------*/ |
---|
168 | .extern SYM(__vectors) |
---|
169 | lis r2, __vectors@h /* set EVPR exc. vector prefix */ |
---|
170 | mtevpr r2 |
---|
171 | |
---|
172 | /*------------------------------------------------------------------- |
---|
173 | * Set up the debug register to freeze timers on debug events. |
---|
174 | *------------------------------------------------------------------*/ |
---|
175 | mfdbcr0 r2 |
---|
176 | ori r2,r2,0x0001 |
---|
177 | mtdbcr0 r2 |
---|
178 | isync |
---|
179 | |
---|
180 | /* Select whether APU, Wait Enable, interrupts/exceptions and address |
---|
181 | translation should be enabled when application starts */ |
---|
182 | lis r0,0x00000000@h /* SRR1 value */ |
---|
183 | mtsrr1 r0 /* Potentially: 0x80000000 >> 6 is APU */ |
---|
184 | |
---|
185 | /* Configure timer facilities */ |
---|
186 | mttbl r0 /* Clear Timebase to prevent Fixed Interval.. */ |
---|
187 | mttbu r0 /* ..timer and Watchdog Timer exceptions */ |
---|
188 | mtpit r0 /* Programmable interval timer */ |
---|
189 | li r2,-1 /* -1 to clear TSR */ |
---|
190 | mttsr r2 /* Timer status register */ |
---|
191 | |
---|
192 | /* Clear out stale values in certain registers to avoid confusion */ |
---|
193 | mtcrf 0xff,r0 /* Need for simulation */ |
---|
194 | mtctr r0 /* Counter register */ |
---|
195 | mtxer r0 /* Fixed-point exception register */ |
---|
196 | mtesr r0 /* Exception syndrome register */ |
---|
197 | mtdear r0 /* Data exception address register */ |
---|
198 | mtmcsr r0 /* Machine check syndrome register */ |
---|
199 | |
---|
200 | /* Invalidate the data cache */ |
---|
201 | li r2,0 /* Start address */ |
---|
202 | li r3,0x100 /* Number of cache lines */ |
---|
203 | mtctr r3 /* Transfer data cache congruence class count to CTR */ |
---|
204 | 1: dccci 0,r2 /* Invalidate this congruence class */ |
---|
205 | addi r2,r2,0x20 /* Point to next congruence class */ |
---|
206 | bdnz 1b /* Decrement counter and loop whilst not zero */ |
---|
207 | |
---|
208 | /* ------------------------------------------------------------------- |
---|
209 | * Set Core Configuration Register 0 as follows: |
---|
210 | * sum: 0x02700E00 |
---|
211 | * bit 1 off: as told by ppc405 errata to avoid CPU_213 ppc bug |
---|
212 | * bit 3 off: as told by ppc405 errata to avoid CPU_213 ppc bug |
---|
213 | (Note added later: PPC405F6 is not subject to CPU_213.) |
---|
214 | * bit 1 on: Xilinx: CR 203746 Patch for PPC405 errata (RiC 12/8/11) |
---|
215 | * bit 2 on: Xilinx: CR 203746 Patch for PPC405 errata (RiC 12/8/11) |
---|
216 | * bit 6 on: load word as line |
---|
217 | * bit 7 off: load misses allocate cache line |
---|
218 | * bit 8 off: store misses allocate cache line |
---|
219 | * bit 9-11 on: default settings to do with plb priority |
---|
220 | * bit 20 on: prefetching for cacheable regions |
---|
221 | * bit 21 on: prefetching for non-cacheable regions |
---|
222 | * bit 22 on: request size of non-cacheable inst fetches is 8 words |
---|
223 | * bit 23 off: fetch misses allocate cache line |
---|
224 | *------------------------------------------------------------------*/ |
---|
225 | lis r5, 0x52700E00@h |
---|
226 | ori r5,r5,0x52700E00@l |
---|
227 | |
---|
228 | /* ------------------------------------------------------------------- |
---|
229 | * To change CCR0 we make sure the code writing to it is |
---|
230 | * running from the I-cache. This is needed because changing some |
---|
231 | * CCR0 fields will cause a hang if the processor is trying to |
---|
232 | * access memory at the same time. |
---|
233 | *------------------------------------------------------------------*/ |
---|
234 | lis r4, 2f@h |
---|
235 | ori r4,r4,2f@l |
---|
236 | icbt r0,r4 |
---|
237 | b 2f |
---|
238 | |
---|
239 | .align 5 /* New cache line (32 bytes each) */ |
---|
240 | 2: |
---|
241 | icbt r0,r4 /* Put this line into the I-cache. */ |
---|
242 | isync |
---|
243 | mtccr0 r5 |
---|
244 | isync |
---|
245 | b 3f |
---|
246 | |
---|
247 | .align 5 |
---|
248 | 3: |
---|
249 | /* Set the Data Cache Write-Through Register for no write-through, i.e., for write-back. */ |
---|
250 | li r0,0 |
---|
251 | mtdcwr r0 |
---|
252 | |
---|
253 | /* Set the Data Cache Cacheablility Register. */ |
---|
254 | lwz r0,dccr_contents-base_addr(r1) |
---|
255 | mtdccr r0 |
---|
256 | isync |
---|
257 | |
---|
258 | /* Fall through */ |
---|
259 | |
---|
260 | |
---|
261 | /* ------------------------------------------------------------------- |
---|
262 | * If a bootloader has run that has already performed some |
---|
263 | * initialization, which among other things has loaded |
---|
264 | * this code into memory and jumped to start above, the initialization |
---|
265 | * above does not need to be done. Execution thus resumes here. |
---|
266 | *------------------------------------------------------------------*/ |
---|
267 | |
---|
268 | startupBL: |
---|
269 | /* ------------------------------------------------------------------- |
---|
270 | * Note that some initialization has already been performed by the |
---|
271 | * bootloader code in Block RAM, which among other things has loaded |
---|
272 | * this code into memory and jumped to start above. |
---|
273 | *------------------------------------------------------------------*/ |
---|
274 | |
---|
275 | /*------------------------------------------------------------------- |
---|
276 | * Load the parameter table base address |
---|
277 | *------------------------------------------------------------------*/ |
---|
278 | lis r1, base_addr@h |
---|
279 | ori r1,r1,base_addr@l |
---|
280 | |
---|
281 | /*------------------------------------------------------------------- |
---|
282 | * Setup stack for RTEMS and call boot_card(). From this |
---|
283 | * point forward registers will be used in accordance with the |
---|
284 | * PowerPC EABI. |
---|
285 | * |
---|
286 | * boot_card() supervises the initialization of RTEMS and the C |
---|
287 | * library. It calls bsp_start(), etc. |
---|
288 | *------------------------------------------------------------------*/ |
---|
289 | lwz r2,toc_pointer-base_addr(r1) /* set r2 to toc */ |
---|
290 | lwz r1,stack_top-base_addr(r1) /* set r1 to stack_top */ |
---|
291 | |
---|
292 | /* Align as required by ABI */ |
---|
293 | li r3,PPC_STACK_ALIGNMENT-1 |
---|
294 | andc r1,r1,r3 |
---|
295 | |
---|
296 | /*------------------------------------------------------------------- |
---|
297 | * Set up r2 and r13. Upon entry r1 must have a nonzero value |
---|
298 | * as it will be stored in an "init done" flag. Stupid but true. |
---|
299 | * r1 must also be set up as a stack pointer as __eabi() jumps |
---|
300 | * to __init() which has a standard function prolog. |
---|
301 | *------------------------------------------------------------------*/ |
---|
302 | bl __eabi |
---|
303 | |
---|
304 | /*------------------------------------------------------------------- |
---|
305 | * Zero the .bss, .sbss and .sbss2 sections. |
---|
306 | * Must have r2 and r13 properly set. |
---|
307 | *------------------------------------------------------------------*/ |
---|
308 | bl zero_bss |
---|
309 | |
---|
310 | /*------------------------------------------------------------------- |
---|
311 | * Create a minimal stack frame for this code, the caller of boot_card(). |
---|
312 | *------------------------------------------------------------------*/ |
---|
313 | addi r1,r1, -PPC_MINIMUM_STACK_FRAME_SIZE |
---|
314 | |
---|
315 | xor r3,r3,r3 |
---|
316 | stw r3,0(r1) /* Terminate the chain of stack frames. */ |
---|
317 | stw r3,4(r1) |
---|
318 | stw r3,8(r1) |
---|
319 | stw r3,12(r1) |
---|
320 | lis r5,environ@ha |
---|
321 | la r5,environ@l(r5) /* environp */ |
---|
322 | |
---|
323 | /*------------------------------------------------------------------- |
---|
324 | * Call boot_card() with its arguments, the command-line pointer and |
---|
325 | * the argument count, set to NULL. |
---|
326 | *------------------------------------------------------------------*/ |
---|
327 | li r4,0 /* argv */ |
---|
328 | li r3,0 /* argc */ |
---|
329 | .extern SYM (boot_card) |
---|
330 | b SYM (boot_card) |
---|