summaryrefslogtreecommitdiffstats
path: root/bsps/powerpc/virtex5/start/start.S
blob: fa6c7154a39c399d570ba05d48c3941f33b04e15 (plain) (blame)
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
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
/*!@file
*
*  @brief     Initialization code to set up the CPU and call boot_card()
*
*  This "BSP" targets the Xilinx Virtex XC5VFX70T 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.
*
*  Some portions of this code follow section 3.4 of the PPC440x5 CPU Core User's
*  Manual v7.1 from IBM.  Other parts were derived from examples provided
*  by Xilinx in their ML510 Reference Designs, e.g., ml510_bsb1_design_ppc440.
*  See boot.S in standalone/, for example.
*
*  References:
*      Embedded Processor Block in Virtex-5 FPGAs Reference Guide UG200 (v1.8)
*      http://www.xilinx.com/support/documentation/user_guides/ug200.pdf
*
*      PowerPC 440x5 Embedded Processor Core User's Manual (Version 7.1)
*      https://www-01.ibm.com/chips/techlib/techlib.nsf/products/PowerPC_440_Embedded_Core
*
*  @author    Richard Claus <claus@SLAC.Stanford.edu>
*
*  @date      March 4, 2011 -- Created
*
*  $Revision: 675 $
*
*  @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>
#include <rtems/powerpc/registers.h>

#define   V_TS_SZ_I    0x0290      // V,TS=0(Inst),SIZE=9,TID=0
#define   V_TS_SZ_D    0x0390      // V,TS=1(Data),SIZE=9,TID=0
#define   WIMG_U_S_0   0x043F      // !(U0-3),!W, I,!M,!G,!E,UX,UW,UR,SX,SW,SR
#define   WIMG_U_S_1   0x003F      // !(U0-3),!W,!I,!M,!G,!E,UX,UW,UR,SX,SW,SR
#define   PAGE_SZ      0x10000000  // 256 MB

/*
 *  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 _ISR_Stack_area_end.
 *
 *  All the entry veneer has to do is to clear the BSS.
 */

        .section .entry

        PUBLIC_VAR(download_entry)
        PUBLIC_VAR(__rtems_entry_point)
SYM(download_entry):
SYM(__rtems_entry_point):
        b       startupDL         /* 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   _ISR_Stack_area_end


        .eject

       /*------------------------------------------------------------------
        * This code follows section 3.4 of the PPC440x5 CPU Core User's
        * Manual.  The numbers in the comments refer to the step numbers
        * therein.  Some of the implementation comes from examples provided
        * by Xilinx in their ML510 Reference Designs, e.g.,
        * ml510_bsb1_design_ppc440.  See boot.S in standalone/.
        *------------------------------------------------------------------*/
       /*------------------------------------------------------------------
        * This code is designed to accomodate warm restarts, in which the
        * application software triggers the restart of the system by branching
        * to the following code (either boot or boot1) without causing
        * one of the hardware resets: core, chip, system or JTAG (section
        * 3.2,3 in the Power PC 440-S Embedded Processor Core User's Manual).
        *-----------------------------------------------------------------*/

       /* -----------------------------------------------------------------
        * Setup CPU
        *-----------------------------------------------------------------*/
first:  li      r0,0              // Clear r0

       /* -----------------------------------------------------------------
        * Initialize the memory system.
        *------------------------------------------------------------------*/
        iccci   r0,r0             // 2. Invalidate instruction cache
        dccci   r0,r0             // 3. Invalidate data cache
        msync                     // 4. Force in-progress data PLB ops to complete

        mfdbcr0 r2                // 5. Disable all debug events
        lis     r3,0x8100
        and     r2,r2,r3          // Ignore EDM,TRAP to allow XMD use
        mtdbcr0 r2
        li      r2,-1
        mtdbsr  r2                // 6. Initialize all debug event status

       /*------------------------------------------------------------------
        * Set Core Configuration Register 0 as follows:
        * sum: 0x00206000
        * bit  1    off  Parity Recovery Enable
        * bit  4    off  Cache Read Parity Enable
        * bit 10    on   Disable Store Gathering
        * bit 11    off  Disable APU Instruction Broadcast
        * bit 16    off  Disable Trace Broadcast
        * bit 17:18 on   Specifies behaviour of icbt,dcbt/dcbtst insts
        * bit 23    off  Force Load/Store Alignment
        * bit 28:29 off  Instruction Cache Speculative Line Count
        * bit 30:31 off  Instruction Cache Speculative Line Threshold
        *            NB: UG200/pg 21: Spec. prefetching must be disabled
        *------------------------------------------------------------------*/

        lis     r2,   0x00206000@h // 7. Set CCR0: DSTG
        ori     r2,r2,0x00206000@l //    Set CCR0: GDCBT, GICBT
        mtccr0  r2                 // Configure CCR0

        mtspr   PPC440_CCR1,r0     // 8. Clear CCR1

       /*------------------------------------------------------------------
	* 9. Configure cache regions
        *------------------------------------------------------------------*/
	mtspr   PPC440_INV0,r0
	mtspr   PPC440_INV1,r0
	mtspr   PPC440_INV2,r0
	mtspr   PPC440_INV3,r0
	mtspr   PPC440_DNV0,r0
	mtspr   PPC440_DNV1,r0
	mtspr   PPC440_DNV2,r0
	mtspr   PPC440_DNV3,r0
	mtspr   PPC440_ITV0,r0
	mtspr   PPC440_ITV1,r0
	mtspr   PPC440_ITV2,r0
	mtspr   PPC440_ITV3,r0
	mtspr   PPC440_DTV0,r0
	mtspr   PPC440_DTV1,r0
	mtspr   PPC440_DTV2,r0
	mtspr   PPC440_DTV3,r0

       /*------------------------------------------------------------------
	* Cache victim limits
	* floors 0, ceiling max to use the entire cache -- nothing locked
        *------------------------------------------------------------------*/
	lis	r2,   0x0001f800@h
	ori	r2,r2,0x0001f800@l
	mtspr   PPC440_IVLIM,r2
	mtspr   PPC440_DVLIM,r2

       /*------------------------------------------------------------------
        * Configure instruction and data cache regions:
        * Set up register constants (r6,r7), page index (r5), address
        * variable (r4), EPN_V_TS bits (r3)
        *
        * Word 0 bits:  0xX0000290, 0xX0000390
        * Bits  Field  Inst  Data  Description
        *  0:21  EPN   0-15  0-15  Effective Page Number
        *    22  V     1     1     Valid
        *    23  TS    0     1     Translation Address Space
        * 24:27  SIZE  9     9     Page Size (9 = 256 MB)
        * 38:31  TPAR  0     0     Tag Parity
        * 32:39  TID   0     0     Translation ID (in the MMUCR)
        *
        * Word 1 bits:  0x00000000, 0x00000000
        * Bits  Field  Inst  Data  Description
        *  0:21  RPN   0     0     Real Page Number
        * 22:23  PAR1  0     0     Parity for TLB word 1
        * 28:31  ERPN  0     0     Extended Real Page Number
        *
        * Word 2 bits:  0x0000043f, 0x00000c3f
        * Bits  Field  Inst  Data  Description
        *  0: 1  PAR2  0     0     Parity for TLB word 2
        *    16  U0    0     0     User-Defineable Storage Attribute 0
        *    17  U1    0     0     User-Defineable Storage Attribute 1
        *    18  U2    0     0     User-Defineable Storage Attribute 2
        *    19  U3    0     0     User-Defineable Storage Attribute 3
        *    20  W     0     0     Write-Through
        *    21  I     1     1     Caching Inhibited
        *    22  M     0     0     Memory Coherence Required
        *    23  G     0     0     Guarded
        *    24  E     0     0     Endian
        *    26  UX    1     1     User State Execute Enable
        *    27  UW    1     1     User State Write Enable
        *    28  UR    1     1     User State Read Enable
        *    29  SX    1     1     Supervisor State Execute Enable
        *    30  SW    1     1     Supervisor State Write Enable
        *    31  SR    1     1     Supervisor State Read Enable
        *------------------------------------------------------------------*/

        mtspr   PPC440_MMUCR,r0   // 10a. Clear MMUCR
        li      r7,WIMG_U_S_1     // Word 2: Pages are NOT cache inhibited
        lis     r6,   PAGE_SZ@h   // Page size constant
        ori     r6,r6,PAGE_SZ@l
        mr      r5,r0             // TLB entry index
        mr      r4,r0             // Initialize RPN to zero
        mflr    r28               // Save return address
        bl      tlbSetup          // 10b. Set up the TLBs
        mtlr    r28               // Restore return address

       /*------------------------------------------------------------------
        * Select whether Wait Enable, interrupts/exceptions and which address
        * spaces should be enabled when application starts
        *------------------------------------------------------------------*/
        lis     r3,   0x00000000@h // 10d. MSR[IS]=0 MSR[DS]=0
        ori     r3,r3,0x00000000@l
        mtsrr1  r3
        mtsrr0  r28               // Return address
        rfi                       // Context synchronize to invalidate shadow TLB contents


       /*-------------------------------------------------------------------
        * Entry point used when downloaded, e.g. through XMD
        *------------------------------------------------------------------*/
startupDL:
       /*-------------------------------------------------------------------
        * Do initialization up to the point where a context sync is required
        *------------------------------------------------------------------*/
        bl      first             // Do first things first

       /*-------------------------------------------------------------------
        * 11. Tell the processor where the exception vector table will be
        *------------------------------------------------------------------*/
        .extern SYM(__vectors)
        lis     r1, __vectors@h     /* set EVPR exc. vector prefix */
        mtspr   BOOKE_IVPR,r1

       /*------------------------------------------------------------------
        * Set up default exception and interrupt vectors
        *------------------------------------------------------------------*/
        li       r1,0
        mtivor0  r1
        addi     r1,r1,0x10
        mtivor1  r1
        addi     r1,r1,0x10
        mtivor2  r1
        addi     r1,r1,0x10
        mtivor3  r1
        addi     r1,r1,0x10
        mtivor4  r1
        addi     r1,r1,0x10
        mtivor5  r1
        addi     r1,r1,0x10
        mtivor6  r1
        addi     r1,r1,0x10
        mtivor7  r1
        addi     r1,r1,0x10
        mtivor8  r1
        addi     r1,r1,0x10
        mtivor9  r1
        addi     r1,r1,0x10
        mtivor10 r1
        addi     r1,r1,0x10
        mtivor11 r1
        addi     r1,r1,0x10
        mtivor12 r1
        addi     r1,r1,0x10
        mtivor13 r1
        addi     r1,r1,0x10
        mtivor14 r1
        addi     r1,r1,0x10
        mtivor15 r1

       /*------------------------------------------------------------------
        * 12. Configure debug facilities
        *------------------------------------------------------------------*/
        mtdbcr1 r0
        mtdbcr2 r0
        mtiac1  r0
        mtiac2  r0
        mtiac3  r0
        mtiac4  r0
        mtdac1  r0
        mtdac2  r0
        mtdvc1  r0
        mtdvc2  r0
        mfdbcr0 r2                // Freeze timers on debug events
        ori     r2,r2,0x0001
        mtdbcr0 r2
        isync

       /*-------------------------------------------------------------------
        * 13. Configure timer facilities
        *------------------------------------------------------------------*/
        mtdec   r0                // Clear Decrementer to prevent exception
        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

       /* Fall through */

       /* -------------------------------------------------------------------
        * If a bootloader has run that has already initialized the CPU,
        * which among other things has loaded this code into memory and
        * jumped to start above, the initialization above does not need
        * to be redone.  Execution thus resumes here.
        *------------------------------------------------------------------*/

startupBL:
       /*-------------------------------------------------------------------
        * 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(), bsp_predriver_hook(), 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              /* setup EABI and SYSV environment */

       /*-------------------------------------------------------------------
        * Zero the .bss, .sbss and .sbss2 sections.
        * Must have r2 and r13 properly set.
        *------------------------------------------------------------------*/
        bl      zero_bss            /* Assume Bank regs set up..., cache etc. */

       /*-------------------------------------------------------------------
        * 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            /* Clear r3 */
        stw     r3,0(r1)            /* Clear stack chain */
        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)     /* call the first C routine */


        .eject

       /*------------------------------------------------------------------
        * Set up TLB entries: 2 entries are needed for the same 256MB page
        * one for instruction memory and the other for data memory.
        * (TS bit=0 for instructions)
        *------------------------------------------------------------------*/
tlbSetup:
1:      ori     r3,r4,V_TS_SZ_I   // Fold V_TS_SZ in with EPN=RPN
        tlbwe   r3,r5,0           // Word 0: EPN_V_TS_SZ (Instructions)
        tlbwe   r4,r5,1           // Word 1: RPN_ERPN
        tlbwe   r7,r5,2           // Word 2: WIMG_U_S
        ori     r3,r4,V_TS_SZ_D   // Fold V_TS_SZ in with EPN=RPN
        addi    r5,r5,1           // Next TLB entry
        tlbwe   r3,r5,0           // Word 0: EPN_V_TS_SZ (Data)
        tlbwe   r4,r5,1           // Word 1: RPN_ERPN
        tlbwe   r7,r5,2           // Word 2: WIMG_U_S
        add     r4,r4,r6          // Increment RPN to next 256MB block
        addi    r5,r5,1           // Next TLB entry
        cmpwi   r5,32             // Done yet?
        bne     1b
        li      r0,0
2:                                // Zero out index 32-63 TLB entries
        tlbwe   r0,r5,0
        tlbwe   r0,r5,1
        tlbwe   r0,r5,2
        addi    r5,r5,1
        cmpwi   r5,64
        bne     2b

        blr