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 XC5VFX70T 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 | * Some portions of this code follow section 3.4 of the PPC440x5 CPU Core User's |
---|
19 | * Manual v7.1 from IBM. Other parts were derived from examples provided |
---|
20 | * by Xilinx in their ML510 Reference Designs, e.g., ml510_bsb1_design_ppc440. |
---|
21 | * See boot.S in standalone/, for example. |
---|
22 | * |
---|
23 | * References: |
---|
24 | * Embedded Processor Block in Virtex-5 FPGAs Reference Guide UG200 (v1.8) |
---|
25 | * http://www.xilinx.com/support/documentation/user_guides/ug200.pdf |
---|
26 | * |
---|
27 | * PowerPC 440x5 Embedded Processor Core User's Manual (Version 7.1) |
---|
28 | * https://www-01.ibm.com/chips/techlib/techlib.nsf/products/PowerPC_440_Embedded_Core |
---|
29 | * |
---|
30 | * @author Richard Claus <claus@SLAC.Stanford.edu> |
---|
31 | * |
---|
32 | * @date March 4, 2011 -- Created |
---|
33 | * |
---|
34 | * $Revision: 675 $ |
---|
35 | * |
---|
36 | * @verbatim Copyright 2011 |
---|
37 | * by |
---|
38 | * The Board of Trustees of the |
---|
39 | * Leland Stanford Junior University. |
---|
40 | * All rights reserved. |
---|
41 | * |
---|
42 | * Work supported by the U.S. Department of Energy under contract |
---|
43 | * DE-AC03-76SF00515. |
---|
44 | * |
---|
45 | * Disclaimer Notice |
---|
46 | * |
---|
47 | * The items furnished herewith were developed under the sponsorship |
---|
48 | * of the U.S. Government. Neither the U.S., nor the U.S. D.O.E., nor the |
---|
49 | * Leland Stanford Junior University, nor their employees, makes any war- |
---|
50 | * ranty, express or implied, or assumes any liability or responsibility |
---|
51 | * for accuracy, completeness or usefulness of any information, apparatus, |
---|
52 | * product or process disclosed, or represents that its use will not in- |
---|
53 | * fringe privately-owned rights. Mention of any product, its manufactur- |
---|
54 | * er, or suppliers shall not, nor is it intended to, imply approval, dis- |
---|
55 | * approval, or fitness for any particular use. The U.S. and the Univer- |
---|
56 | * sity at all times retain the right to use and disseminate the furnished |
---|
57 | * items for any purpose whatsoever. Notice 91 02 01 |
---|
58 | * |
---|
59 | * @endverbatim |
---|
60 | */ |
---|
61 | |
---|
62 | #include <rtems/asm.h> |
---|
63 | #include <rtems/powerpc/powerpc.h> |
---|
64 | #include <rtems/powerpc/registers.h> |
---|
65 | |
---|
66 | #define V_TS_SZ_I 0x0290 // V,TS=0(Inst),SIZE=9,TID=0 |
---|
67 | #define V_TS_SZ_D 0x0390 // V,TS=1(Data),SIZE=9,TID=0 |
---|
68 | #define WIMG_U_S_0 0x043F // !(U0-3),!W, I,!M,!G,!E,UX,UW,UR,SX,SW,SR |
---|
69 | #define WIMG_U_S_1 0x003F // !(U0-3),!W,!I,!M,!G,!E,UX,UW,UR,SX,SW,SR |
---|
70 | #define PAGE_SZ 0x10000000 // 256 MB |
---|
71 | |
---|
72 | /* |
---|
73 | * The virtex ELF link scripts support some special sections: |
---|
74 | * .entry The actual entry point |
---|
75 | * .vectors The section containing the interrupt entry veneers. |
---|
76 | */ |
---|
77 | |
---|
78 | /* |
---|
79 | * Downloaded code loads the vectors separately to 0x00000100, |
---|
80 | * so .entry can be over 256 bytes. |
---|
81 | * |
---|
82 | * The other sections are linked in the following order: |
---|
83 | * .entry |
---|
84 | * .text |
---|
85 | * .data |
---|
86 | * .bss |
---|
87 | * see linker command file for section placement |
---|
88 | * |
---|
89 | * The initial stack is set to __stack_base |
---|
90 | * |
---|
91 | * All the entry veneer has to do is to clear the BSS. |
---|
92 | */ |
---|
93 | |
---|
94 | .section .entry |
---|
95 | |
---|
96 | PUBLIC_VAR(download_entry) |
---|
97 | PUBLIC_VAR(__rtems_entry_point) |
---|
98 | SYM(download_entry): |
---|
99 | SYM(__rtems_entry_point): |
---|
100 | b startupDL /* Entry point used by xmd dow command */ |
---|
101 | |
---|
102 | PUBLIC_VAR (start) |
---|
103 | SYM(start): |
---|
104 | b startupBL /* Entry point used by bootLoader */ |
---|
105 | |
---|
106 | base_addr: |
---|
107 | /*------------------------------------------------------------------- |
---|
108 | * Parameters from linker |
---|
109 | *-----------------------------------------------------------------*/ |
---|
110 | toc_pointer: |
---|
111 | .long __got_start |
---|
112 | bss_length: |
---|
113 | .long __bss_size |
---|
114 | bss_addr: |
---|
115 | .long __bss_start |
---|
116 | stack_top: |
---|
117 | .long __stack_base |
---|
118 | |
---|
119 | |
---|
120 | .eject |
---|
121 | |
---|
122 | /*------------------------------------------------------------------ |
---|
123 | * This code follows section 3.4 of the PPC440x5 CPU Core User's |
---|
124 | * Manual. The numbers in the comments refer to the step numbers |
---|
125 | * therein. Some of the implementation comes from examples provided |
---|
126 | * by Xilinx in their ML510 Reference Designs, e.g., |
---|
127 | * ml510_bsb1_design_ppc440. See boot.S in standalone/. |
---|
128 | *------------------------------------------------------------------*/ |
---|
129 | /*------------------------------------------------------------------ |
---|
130 | * This code is designed to accomodate warm restarts, in which the |
---|
131 | * application software triggers the restart of the system by branching |
---|
132 | * to the following code (either boot or boot1) without causing |
---|
133 | * one of the hardware resets: core, chip, system or JTAG (section |
---|
134 | * 3.2,3 in the Power PC 440-S Embedded Processor Core User's Manual). |
---|
135 | *-----------------------------------------------------------------*/ |
---|
136 | |
---|
137 | /* ----------------------------------------------------------------- |
---|
138 | * Setup CPU |
---|
139 | *-----------------------------------------------------------------*/ |
---|
140 | first: li r0,0 // Clear r0 |
---|
141 | |
---|
142 | /* ----------------------------------------------------------------- |
---|
143 | * Initialize the memory system. |
---|
144 | *------------------------------------------------------------------*/ |
---|
145 | iccci r0,r0 // 2. Invalidate instruction cache |
---|
146 | dccci r0,r0 // 3. Invalidate data cache |
---|
147 | msync // 4. Force in-progress data PLB ops to complete |
---|
148 | |
---|
149 | mfdbcr0 r2 // 5. Disable all debug events |
---|
150 | lis r3,0x8100 |
---|
151 | and r2,r2,r3 // Ignore EDM,TRAP to allow XMD use |
---|
152 | mtdbcr0 r2 |
---|
153 | li r2,-1 |
---|
154 | mtdbsr r2 // 6. Initialize all debug event status |
---|
155 | |
---|
156 | /*------------------------------------------------------------------ |
---|
157 | * Set Core Configuration Register 0 as follows: |
---|
158 | * sum: 0x00206000 |
---|
159 | * bit 1 off Parity Recovery Enable |
---|
160 | * bit 4 off Cache Read Parity Enable |
---|
161 | * bit 10 on Disable Store Gathering |
---|
162 | * bit 11 off Disable APU Instruction Broadcast |
---|
163 | * bit 16 off Disable Trace Broadcast |
---|
164 | * bit 17:18 on Specifies behaviour of icbt,dcbt/dcbtst insts |
---|
165 | * bit 23 off Force Load/Store Alignment |
---|
166 | * bit 28:29 off Instruction Cache Speculative Line Count |
---|
167 | * bit 30:31 off Instruction Cache Speculative Line Threshold |
---|
168 | * NB: UG200/pg 21: Spec. prefetching must be disabled |
---|
169 | *------------------------------------------------------------------*/ |
---|
170 | |
---|
171 | lis r2, 0x00206000@h // 7. Set CCR0: DSTG |
---|
172 | ori r2,r2,0x00206000@l // Set CCR0: GDCBT, GICBT |
---|
173 | mtccr0 r2 // Configure CCR0 |
---|
174 | |
---|
175 | mtspr PPC440_CCR1,r0 // 8. Clear CCR1 |
---|
176 | |
---|
177 | /*------------------------------------------------------------------ |
---|
178 | * 9. Configure cache regions |
---|
179 | *------------------------------------------------------------------*/ |
---|
180 | mtspr PPC440_INV0,r0 |
---|
181 | mtspr PPC440_INV1,r0 |
---|
182 | mtspr PPC440_INV2,r0 |
---|
183 | mtspr PPC440_INV3,r0 |
---|
184 | mtspr PPC440_DNV0,r0 |
---|
185 | mtspr PPC440_DNV1,r0 |
---|
186 | mtspr PPC440_DNV2,r0 |
---|
187 | mtspr PPC440_DNV3,r0 |
---|
188 | mtspr PPC440_ITV0,r0 |
---|
189 | mtspr PPC440_ITV1,r0 |
---|
190 | mtspr PPC440_ITV2,r0 |
---|
191 | mtspr PPC440_ITV3,r0 |
---|
192 | mtspr PPC440_DTV0,r0 |
---|
193 | mtspr PPC440_DTV1,r0 |
---|
194 | mtspr PPC440_DTV2,r0 |
---|
195 | mtspr PPC440_DTV3,r0 |
---|
196 | |
---|
197 | /*------------------------------------------------------------------ |
---|
198 | * Cache victim limits |
---|
199 | * floors 0, ceiling max to use the entire cache -- nothing locked |
---|
200 | *------------------------------------------------------------------*/ |
---|
201 | lis r2, 0x0001f800@h |
---|
202 | ori r2,r2,0x0001f800@l |
---|
203 | mtspr PPC440_IVLIM,r2 |
---|
204 | mtspr PPC440_DVLIM,r2 |
---|
205 | |
---|
206 | /*------------------------------------------------------------------ |
---|
207 | * Configure instruction and data cache regions: |
---|
208 | * Set up register constants (r6,r7), page index (r5), address |
---|
209 | * variable (r4), EPN_V_TS bits (r3) |
---|
210 | * |
---|
211 | * Word 0 bits: 0xX0000290, 0xX0000390 |
---|
212 | * Bits Field Inst Data Description |
---|
213 | * 0:21 EPN 0-15 0-15 Effective Page Number |
---|
214 | * 22 V 1 1 Valid |
---|
215 | * 23 TS 0 1 Translation Address Space |
---|
216 | * 24:27 SIZE 9 9 Page Size (9 = 256 MB) |
---|
217 | * 38:31 TPAR 0 0 Tag Parity |
---|
218 | * 32:39 TID 0 0 Translation ID (in the MMUCR) |
---|
219 | * |
---|
220 | * Word 1 bits: 0x00000000, 0x00000000 |
---|
221 | * Bits Field Inst Data Description |
---|
222 | * 0:21 RPN 0 0 Real Page Number |
---|
223 | * 22:23 PAR1 0 0 Parity for TLB word 1 |
---|
224 | * 28:31 ERPN 0 0 Extended Real Page Number |
---|
225 | * |
---|
226 | * Word 2 bits: 0x0000043f, 0x00000c3f |
---|
227 | * Bits Field Inst Data Description |
---|
228 | * 0: 1 PAR2 0 0 Parity for TLB word 2 |
---|
229 | * 16 U0 0 0 User-Defineable Storage Attribute 0 |
---|
230 | * 17 U1 0 0 User-Defineable Storage Attribute 1 |
---|
231 | * 18 U2 0 0 User-Defineable Storage Attribute 2 |
---|
232 | * 19 U3 0 0 User-Defineable Storage Attribute 3 |
---|
233 | * 20 W 0 0 Write-Through |
---|
234 | * 21 I 1 1 Caching Inhibited |
---|
235 | * 22 M 0 0 Memory Coherence Required |
---|
236 | * 23 G 0 0 Guarded |
---|
237 | * 24 E 0 0 Endian |
---|
238 | * 26 UX 1 1 User State Execute Enable |
---|
239 | * 27 UW 1 1 User State Write Enable |
---|
240 | * 28 UR 1 1 User State Read Enable |
---|
241 | * 29 SX 1 1 Supervisor State Execute Enable |
---|
242 | * 30 SW 1 1 Supervisor State Write Enable |
---|
243 | * 31 SR 1 1 Supervisor State Read Enable |
---|
244 | *------------------------------------------------------------------*/ |
---|
245 | |
---|
246 | mtspr PPC440_MMUCR,r0 // 10a. Clear MMUCR |
---|
247 | li r7,WIMG_U_S_1 // Word 2: Pages are NOT cache inhibited |
---|
248 | lis r6, PAGE_SZ@h // Page size constant |
---|
249 | ori r6,r6,PAGE_SZ@l |
---|
250 | mr r5,r0 // TLB entry index |
---|
251 | mr r4,r0 // Initialize RPN to zero |
---|
252 | mflr r28 // Save return address |
---|
253 | bl tlbSetup // 10b. Set up the TLBs |
---|
254 | mtlr r28 // Restore return address |
---|
255 | |
---|
256 | /*------------------------------------------------------------------ |
---|
257 | * Select whether Wait Enable, interrupts/exceptions and which address |
---|
258 | * spaces should be enabled when application starts |
---|
259 | *------------------------------------------------------------------*/ |
---|
260 | lis r3, 0x00000000@h // 10d. MSR[IS]=0 MSR[DS]=0 |
---|
261 | ori r3,r3,0x00000000@l |
---|
262 | mtsrr1 r3 |
---|
263 | mtsrr0 r28 // Return address |
---|
264 | rfi // Context synchronize to invalidate shadow TLB contents |
---|
265 | |
---|
266 | |
---|
267 | /*------------------------------------------------------------------- |
---|
268 | * Entry point used when downloaded, e.g. through XMD |
---|
269 | *------------------------------------------------------------------*/ |
---|
270 | startupDL: |
---|
271 | /*------------------------------------------------------------------- |
---|
272 | * Do initialization up to the point where a context sync is required |
---|
273 | *------------------------------------------------------------------*/ |
---|
274 | bl first // Do first things first |
---|
275 | |
---|
276 | /*------------------------------------------------------------------- |
---|
277 | * 11. Tell the processor where the exception vector table will be |
---|
278 | *------------------------------------------------------------------*/ |
---|
279 | .extern SYM(__vectors) |
---|
280 | lis r1, __vectors@h /* set EVPR exc. vector prefix */ |
---|
281 | mtspr BOOKE_IVPR,r1 |
---|
282 | |
---|
283 | /*------------------------------------------------------------------ |
---|
284 | * Set up default exception and interrupt vectors |
---|
285 | *------------------------------------------------------------------*/ |
---|
286 | li r1,0 |
---|
287 | mtivor0 r1 |
---|
288 | addi r1,r1,0x10 |
---|
289 | mtivor1 r1 |
---|
290 | addi r1,r1,0x10 |
---|
291 | mtivor2 r1 |
---|
292 | addi r1,r1,0x10 |
---|
293 | mtivor3 r1 |
---|
294 | addi r1,r1,0x10 |
---|
295 | mtivor4 r1 |
---|
296 | addi r1,r1,0x10 |
---|
297 | mtivor5 r1 |
---|
298 | addi r1,r1,0x10 |
---|
299 | mtivor6 r1 |
---|
300 | addi r1,r1,0x10 |
---|
301 | mtivor7 r1 |
---|
302 | addi r1,r1,0x10 |
---|
303 | mtivor8 r1 |
---|
304 | addi r1,r1,0x10 |
---|
305 | mtivor9 r1 |
---|
306 | addi r1,r1,0x10 |
---|
307 | mtivor10 r1 |
---|
308 | addi r1,r1,0x10 |
---|
309 | mtivor11 r1 |
---|
310 | addi r1,r1,0x10 |
---|
311 | mtivor12 r1 |
---|
312 | addi r1,r1,0x10 |
---|
313 | mtivor13 r1 |
---|
314 | addi r1,r1,0x10 |
---|
315 | mtivor14 r1 |
---|
316 | addi r1,r1,0x10 |
---|
317 | mtivor15 r1 |
---|
318 | |
---|
319 | /*------------------------------------------------------------------ |
---|
320 | * 12. Configure debug facilities |
---|
321 | *------------------------------------------------------------------*/ |
---|
322 | mtdbcr1 r0 |
---|
323 | mtdbcr2 r0 |
---|
324 | mtiac1 r0 |
---|
325 | mtiac2 r0 |
---|
326 | mtiac3 r0 |
---|
327 | mtiac4 r0 |
---|
328 | mtdac1 r0 |
---|
329 | mtdac2 r0 |
---|
330 | mtdvc1 r0 |
---|
331 | mtdvc2 r0 |
---|
332 | mfdbcr0 r2 // Freeze timers on debug events |
---|
333 | ori r2,r2,0x0001 |
---|
334 | mtdbcr0 r2 |
---|
335 | isync |
---|
336 | |
---|
337 | /*------------------------------------------------------------------- |
---|
338 | * 13. Configure timer facilities |
---|
339 | *------------------------------------------------------------------*/ |
---|
340 | mtdec r0 // Clear Decrementer to prevent exception |
---|
341 | mttbl r0 // Clear Timebase to prevent Fixed Interval.. |
---|
342 | mttbu r0 // ..timer and Watchdog Timer exceptions |
---|
343 | mtpit r0 // Programmable interval timer |
---|
344 | li r2,-1 // -1 to clear TSR |
---|
345 | mttsr r2 // Timer status register |
---|
346 | |
---|
347 | /*------------------------------------------------------------------- |
---|
348 | * Clear out stale values in certain registers to avoid confusion |
---|
349 | *------------------------------------------------------------------*/ |
---|
350 | mtcrf 0xff,r0 // Need for simulation |
---|
351 | mtctr r0 // Counter register |
---|
352 | mtxer r0 // Fixed-point exception register |
---|
353 | mtesr r0 // Exception syndrome register |
---|
354 | mtdear r0 // Data exception address register |
---|
355 | mtmcsr r0 // Machine check syndrome register |
---|
356 | |
---|
357 | /* Fall through */ |
---|
358 | |
---|
359 | /* ------------------------------------------------------------------- |
---|
360 | * If a bootloader has run that has already initialized the CPU, |
---|
361 | * which among other things has loaded this code into memory and |
---|
362 | * jumped to start above, the initialization above does not need |
---|
363 | * to be redone. Execution thus resumes here. |
---|
364 | *------------------------------------------------------------------*/ |
---|
365 | |
---|
366 | startupBL: |
---|
367 | /*------------------------------------------------------------------- |
---|
368 | * Load the parameter table base address |
---|
369 | *------------------------------------------------------------------*/ |
---|
370 | lis r1, base_addr@h |
---|
371 | ori r1,r1,base_addr@l |
---|
372 | |
---|
373 | /*------------------------------------------------------------------- |
---|
374 | * Setup stack for RTEMS and call boot_card(). From this |
---|
375 | * point forward registers will be used in accordance with the |
---|
376 | * PowerPC EABI. |
---|
377 | * |
---|
378 | * boot_card() supervises the initialization of RTEMS and the C |
---|
379 | * library. It calls bsp_start(), bsp_predriver_hook(), etc. |
---|
380 | *------------------------------------------------------------------*/ |
---|
381 | lwz r2,toc_pointer-base_addr(r1) /* set r2 to toc */ |
---|
382 | lwz r1,stack_top-base_addr(r1) /* set r1 to stack_top */ |
---|
383 | |
---|
384 | /* Align as required by ABI */ |
---|
385 | li r3,PPC_STACK_ALIGNMENT-1 |
---|
386 | andc r1,r1,r3 |
---|
387 | |
---|
388 | /*------------------------------------------------------------------- |
---|
389 | * Set up r2 and r13. Upon entry r1 must have a nonzero value |
---|
390 | * as it will be stored in an "init done" flag. Stupid but true. |
---|
391 | * r1 must also be set up as a stack pointer as __eabi() jumps |
---|
392 | * to __init() which has a standard function prolog. |
---|
393 | *------------------------------------------------------------------*/ |
---|
394 | bl __eabi /* setup EABI and SYSV environment */ |
---|
395 | |
---|
396 | /*------------------------------------------------------------------- |
---|
397 | * Zero the .bss, .sbss and .sbss2 sections. |
---|
398 | * Must have r2 and r13 properly set. |
---|
399 | *------------------------------------------------------------------*/ |
---|
400 | bl zero_bss /* Assume Bank regs set up..., cache etc. */ |
---|
401 | |
---|
402 | /*------------------------------------------------------------------- |
---|
403 | * Create a minimal stack frame for this code, the caller of boot_card(). |
---|
404 | *------------------------------------------------------------------*/ |
---|
405 | addi r1,r1,-PPC_MINIMUM_STACK_FRAME_SIZE |
---|
406 | |
---|
407 | xor r3,r3,r3 /* Clear r3 */ |
---|
408 | stw r3,0(r1) /* Clear stack chain */ |
---|
409 | stw r3,4(r1) |
---|
410 | stw r3,8(r1) |
---|
411 | stw r3,12(r1) |
---|
412 | lis r5,environ@ha |
---|
413 | la r5,environ@l(r5) /* environp */ |
---|
414 | |
---|
415 | /*------------------------------------------------------------------- |
---|
416 | * Call boot_card() with its arguments, the command-line pointer and |
---|
417 | * the argument count, set to NULL. |
---|
418 | *------------------------------------------------------------------*/ |
---|
419 | li r4,0 /* argv */ |
---|
420 | li r3,0 /* argc */ |
---|
421 | .extern SYM (boot_card) |
---|
422 | b SYM (boot_card) /* call the first C routine */ |
---|
423 | |
---|
424 | |
---|
425 | .eject |
---|
426 | |
---|
427 | /*------------------------------------------------------------------ |
---|
428 | * Set up TLB entries: 2 entries are needed for the same 256MB page |
---|
429 | * one for instruction memory and the other for data memory. |
---|
430 | * (TS bit=0 for instructions) |
---|
431 | *------------------------------------------------------------------*/ |
---|
432 | tlbSetup: |
---|
433 | 1: ori r3,r4,V_TS_SZ_I // Fold V_TS_SZ in with EPN=RPN |
---|
434 | tlbwe r3,r5,0 // Word 0: EPN_V_TS_SZ (Instructions) |
---|
435 | tlbwe r4,r5,1 // Word 1: RPN_ERPN |
---|
436 | tlbwe r7,r5,2 // Word 2: WIMG_U_S |
---|
437 | ori r3,r4,V_TS_SZ_D // Fold V_TS_SZ in with EPN=RPN |
---|
438 | addi r5,r5,1 // Next TLB entry |
---|
439 | tlbwe r3,r5,0 // Word 0: EPN_V_TS_SZ (Data) |
---|
440 | tlbwe r4,r5,1 // Word 1: RPN_ERPN |
---|
441 | tlbwe r7,r5,2 // Word 2: WIMG_U_S |
---|
442 | add r4,r4,r6 // Increment RPN to next 256MB block |
---|
443 | addi r5,r5,1 // Next TLB entry |
---|
444 | cmpwi r5,32 // Done yet? |
---|
445 | bne 1b |
---|
446 | li r0,0 |
---|
447 | 2: // Zero out index 32-63 TLB entries |
---|
448 | tlbwe r0,r5,0 |
---|
449 | tlbwe r0,r5,1 |
---|
450 | tlbwe r0,r5,2 |
---|
451 | addi r5,r5,1 |
---|
452 | cmpwi r5,64 |
---|
453 | bne 2b |
---|
454 | |
---|
455 | blr |
---|