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