source: rtems/bsps/powerpc/gen83xx/start/start.S @ 84e59b7c

Last change on this file since 84e59b7c was 84e59b7c, checked in by Sebastian Huber <sebastian.huber@…>, on Nov 15, 2018 at 7:47:22 PM

bsps/powerpc: Use interrupt stack for init stack

Move start.o to separate file.

Update #3459.

  • Property mode set to 100644
File size: 12.7 KB
Line 
1/*===============================================================*\
2| Project: RTEMS generic MPC83xx BSP                              |
3+-----------------------------------------------------------------+
4|                    Copyright (c) 2007                           |
5|                    Embedded Brains GmbH                         |
6|                    Obere Lagerstr. 30                           |
7|                    D-82178 Puchheim                             |
8|                    Germany                                      |
9|                    rtems@embedded-brains.de                     |
10+-----------------------------------------------------------------+
11| The license and distribution terms for this file may be         |
12| found in the file LICENSE in this distribution or at            |
13|                                                                 |
14| http://www.rtems.org/license/LICENSE.                           |
15|                                                                 |
16+-----------------------------------------------------------------+
17| this file contains the startup assembly code                    |
18\*===============================================================*/
19
20
21#include <libcpu/powerpc-utility.h>
22#include <rtems/powerpc/cache.h>
23#include <bsp.h>
24#include <mpc83xx/mpc83xx.h>
25
26.macro SET_IMM_REGW base, reg2, offset, value
27        LA \reg2, \value
28        stw \reg2,\offset(\base)
29.endm
30
31#define REP8(l) l ; l; l; l; l; l; l; l;
32
33.extern boot_card
34.extern MBAR
35
36#if defined(RESET_CONF_WRD_L)
37.section ".resconf","ax"
38PUBLIC_VAR (reset_conf_words)
39reset_conf_words:
40        REP8( .byte ((RESET_CONF_WRD_L >> 24) & 0xff))
41        REP8( .byte ((RESET_CONF_WRD_L >> 16) & 0xff))
42        REP8( .byte ((RESET_CONF_WRD_L >>  8) & 0xff))
43        REP8( .byte ((RESET_CONF_WRD_L >>  0) & 0xff))
44
45        REP8( .byte ((RESET_CONF_WRD_H >> 24) & 0xff))
46        REP8( .byte ((RESET_CONF_WRD_H >> 16) & 0xff))
47        REP8( .byte ((RESET_CONF_WRD_H >>  8) & 0xff))
48        REP8( .byte ((RESET_CONF_WRD_H >>  0) & 0xff))
49#endif
50
51.section ".vectors","ax"
52PUBLIC_VAR (reset_vec)
53reset_vec:
54        bl rom_entry
55
56.section ".bsp_start_text", "ax"
57PUBLIC_VAR (_start)
58_start:
59        /* Reset time base */
60        li      r0, 0
61        mtspr   TBWU, r0
62        mtspr   TBWL, r0
63
64#ifdef HAS_UBOOT
65        mr      r14, r3
66#endif /* HAS_UBOOT */
67
68        /*
69         * basic CPU setup:
70         * init MSR
71         */
72        mfmsr   r30
73        SETBITS r30, r29, MSR_ME|MSR_RI
74        CLRBITS r30, r29, MSR_IP|MSR_EE
75        mtmsr   r30                             /* Set RI/ME, Clr EE in MSR */
76
77        b start_rom_skip
78
79PUBLIC_VAR (rom_entry)
80rom_entry:
81        /*
82         * basic CPU setup:
83         * init MSR
84         */
85        mfmsr   r30
86        SETBITS r30, r29, MSR_ME|MSR_RI
87        CLRBITS r30, r29, MSR_IP|MSR_EE
88        mtmsr   r30                             /* Set RI/ME, Clr EE in MSR */
89
90        /*
91         * ROM startup: remap IMMR to 0xE0000000
92         * use special sequence from MPC8349EA RM Rev 1, 5.2.4.1.1 "Updating IMMRBAR"
93         */
94        LWI  r30,IMMRBAR_DEFAULT
95        LWI  r31,IMMRBAR
96        lwz  r29,0(r30)
97        stw  r31,0(r30)
98#if 0
99        lwz  r29,0(r28) /* read from ROM... */
100#endif
101        isync
102        lwz  r29,0(r31) /* read from IMMRBAR... */
103        isync
104        /*
105         * NOTE:         now r31 points to onchip registers
106        */
107        /*
108         * we start from 0x100, so ROM is currently mapped to
109         * 0x00000000..
110         * in the next step, ROM will be remapped to its final location
111         * at 0xfe000000... (using LBLAWBAR1 with LBLAWBAR0 value)
112         * and we jump to that location.
113         * then we remove the ROM mapping to zero
114         */
115#ifdef LBLAWBAR0_VAL
116        SET_IMM_REGW r31,r30,LBLAWBAR1_OFF,LBLAWBAR0_VAL
117#endif
118#ifdef LBLAWAR0_VAL
119        SET_IMM_REGW r31,r30,LBLAWAR1_OFF,LBLAWAR0_VAL
120#endif
121
122
123        /*
124         * ROM startup: jump to code final ROM location
125         */
126        LA      r20, bsp_rom_start /* ROM-RAM reloc in r20 */
127        LA      r29, start_code_in_rom /* get compile time addr of label */
128        add     r29,r20,r29    /* compute exec address */
129        mtlr    r29
130        blr                     /* now further execution in upper ROM */
131
132start_code_in_rom:
133
134#ifdef LBLAWBAR0_VAL
135        SET_IMM_REGW r31,r30,LBLAWBAR0_OFF,LBLAWBAR0_VAL
136#endif
137#ifdef LBLAWAR0_VAL
138        SET_IMM_REGW r31,r30,LBLAWAR0_OFF,LBLAWAR0_VAL
139#endif
140
141/*
142 * Local access window 1 is a special case since we used it for a temporary
143 * mapping.  If we do not use it then restore the reset value.
144 */
145#ifdef LBLAWBAR1_VAL
146        SET_IMM_REGW r31,r30,LBLAWBAR1_OFF,LBLAWBAR1_VAL
147#else
148        SET_IMM_REGW r31,r30,LBLAWBAR1_OFF,0
149#endif
150#ifdef LBLAWAR1_VAL
151        SET_IMM_REGW r31,r30,LBLAWAR1_OFF,LBLAWAR1_VAL
152#else
153        SET_IMM_REGW r31,r30,LBLAWAR1_OFF,0
154#endif
155
156#ifdef LBLAWBAR2_VAL
157        SET_IMM_REGW r31,r30,LBLAWBAR2_OFF,LBLAWBAR2_VAL
158#endif
159#ifdef LBLAWAR2_VAL
160        SET_IMM_REGW r31,r30,LBLAWAR2_OFF,LBLAWAR2_VAL
161#endif
162#ifdef LBLAWBAR3_VAL
163        SET_IMM_REGW r31,r30,LBLAWBAR3_OFF,LBLAWBAR3_VAL
164#endif
165#ifdef LBLAWAR3_VAL
166        SET_IMM_REGW r31,r30,LBLAWAR3_OFF,LBLAWAR3_VAL
167#endif
168        /*
169         * ROM startup: init bus system
170         */
171#ifdef BR0_VAL
172        SET_IMM_REGW r31,r30,BR0_OFF,BR0_VAL
173#endif
174#ifdef OR0_VAL
175        SET_IMM_REGW r31,r30,OR0_OFF,OR0_VAL
176#endif
177#ifdef BR1_VAL
178        SET_IMM_REGW r31,r30,BR1_OFF,BR1_VAL
179#endif
180#ifdef OR1_VAL
181        SET_IMM_REGW r31,r30,OR1_OFF,OR1_VAL
182#endif
183#ifdef BR2_VAL
184        SET_IMM_REGW r31,r30,BR2_OFF,BR2_VAL
185#endif
186#ifdef OR2_VAL
187        SET_IMM_REGW r31,r30,OR2_OFF,OR2_VAL
188#endif
189#ifdef BR3_VAL
190        SET_IMM_REGW r31,r30,BR3_OFF,BR3_VAL
191#endif
192#ifdef OR3_VAL
193        SET_IMM_REGW r31,r30,OR3_OFF,OR3_VAL
194#endif
195#ifdef BR4_VAL
196        SET_IMM_REGW r31,r30,BR4_OFF,BR4_VAL
197#endif
198#ifdef OR4_VAL
199        SET_IMM_REGW r31,r30,OR4_OFF,OR4_VAL
200#endif
201#ifdef BR5_VAL
202        SET_IMM_REGW r31,r30,BR5_OFF,BR5_VAL
203#endif
204#ifdef OR5_VAL
205        SET_IMM_REGW r31,r30,OR5_OFF,OR5_VAL
206#endif
207        /*
208         * ROM startup: init SDRAM access window
209         */
210#ifdef DDRLAWBAR0_VAL
211        SET_IMM_REGW r31,r30,DDRLAWBAR0_OFF,DDRLAWBAR0_VAL
212#endif
213#ifdef DDRLAWAR0_VAL
214        SET_IMM_REGW r31,r30,DDRLAWAR0_OFF,DDRLAWAR0_VAL
215#endif
216#ifdef DDRLAWBAR1_VAL
217        SET_IMM_REGW r31,r30,DDRLAWBAR1_OFF,DDRLAWBAR1_VAL
218#endif
219#ifdef DDRLAWAR1_VAL
220        SET_IMM_REGW r31,r30,DDRLAWAR1_OFF,DDRLAWAR1_VAL
221#endif
222        /*
223         * ROM startup: init refresh interval
224         */
225#ifdef MRPTR_VAL
226        SET_IMM_REGW r31,r30,MRPTR_OFF,MRPTR_VAL
227#endif
228        /*
229         * ROM startup: init SDRAM
230         */
231#ifdef LSRT_VAL
232        SET_IMM_REGW r31,r30, LSRT_OFF, LSRT_VAL
233#endif
234#ifdef LSDMR_VAL
235        SET_IMM_REGW r31,r30, LSDMR_OFF, LSDMR_VAL
236#endif
237#ifdef CS0_BNDS_VAL
238        SET_IMM_REGW r31,r30,CS0_BNDS_OFF,CS0_BNDS_VAL
239#endif
240#ifdef CS1_BNDS_VAL
241        SET_IMM_REGW r31,r30,CS1_BNDS_OFF,CS1_BNDS_VAL
242#endif
243#ifdef CS2_BNDS_VAL
244        SET_IMM_REGW r31,r30,CS2_BNDS_OFF,CS2_BNDS_VAL
245#endif
246#ifdef CS3_BNDS_VAL
247        SET_IMM_REGW r31,r30,CS3_BNDS_OFF,CS3_BNDS_VAL
248#endif
249#ifdef CS0_CONFIG_VAL
250        SET_IMM_REGW r31,r30,CS0_CONFIG_OFF,CS0_CONFIG_VAL
251#endif
252#ifdef CS1_CONFIG_VAL
253        SET_IMM_REGW r31,r30,CS1_CONFIG_OFF,CS1_CONFIG_VAL
254#endif
255#ifdef CS2_CONFIG_VAL
256        SET_IMM_REGW r31,r30,CS2_CONFIG_OFF,CS2_CONFIG_VAL
257#endif
258#ifdef CS3_CONFIG_VAL
259        SET_IMM_REGW r31,r30,CS3_CONFIG_OFF,CS3_CONFIG_VAL
260#endif
261#ifdef TIMING_CFG_3_VAL
262        SET_IMM_REGW r31,r30,TIMING_CFG_3_OFF,TIMING_CFG_3_VAL
263#endif
264#ifdef TIMING_CFG_0_VAL
265        SET_IMM_REGW r31,r30,TIMING_CFG_0_OFF,TIMING_CFG_0_VAL
266#endif
267#ifdef TIMING_CFG_1_VAL
268        SET_IMM_REGW r31,r30,TIMING_CFG_1_OFF,TIMING_CFG_1_VAL
269#endif
270#ifdef TIMING_CFG_2_VAL
271        SET_IMM_REGW r31,r30,TIMING_CFG_2_OFF,TIMING_CFG_2_VAL
272#endif
273#ifdef DDRCDR_VAL
274        SET_IMM_REGW r31,r30,DDRCDR_OFF,DDRCDR_VAL
275#endif
276#ifdef DDR_SDRAM_CFG_2_VAL
277        SET_IMM_REGW r31,r30,DDR_SDRAM_CFG_2_OFF,DDR_SDRAM_CFG_2_VAL
278#endif
279#ifdef DDR_SDRAM_MODE_VAL
280        SET_IMM_REGW r31,r30,DDR_SDRAM_MODE_OFF,DDR_SDRAM_MODE_VAL
281#endif
282#ifdef DDR_SDRAM_MODE_2_VAL
283        SET_IMM_REGW r31,r30,DDR_SDRAM_MODE_2_OFF,DDR_SDRAM_MODE_2_VAL
284#endif
285#ifdef DDR_SDRAM_MD_CNTL_VAL
286        SET_IMM_REGW r31,r30,DDR_SDRAM_MD_CNTL_OFF,DDR_SDRAM_MD_CNTL_VAL
287#endif
288#ifdef DDR_SDRAM_MD_ITVL_VAL
289        SET_IMM_REGW r31,r30,DDR_SDRAM_MD_ITVL_OFF,DDR_SDRAM_MD_ITVL_VAL
290#endif
291#ifdef DDR_SDRAM_CLK_CNTL_VAL
292        SET_IMM_REGW r31,r30,DDR_SDRAM_CLK_CNTL_OFF,DDR_SDRAM_CLK_CNTL_VAL
293#endif
294#ifdef DDR_SDRAM_CFG_2_VAL
295        SET_IMM_REGW r31,r30,DDR_SDRAM_CFG_2_OFF,DDR_SDRAM_CFG_2_VAL|DDR_SDRAM_CFG_2_D_INIT
296#endif
297
298#ifdef DDR_ERR_DISABLE_VAL
299        /*
300         * disable detect of RAM errors
301         */
302        SET_IMM_REGW r31,r30,DDR_ERR_DISABLE_OFF,DDR_ERR_DISABLE_VAL
303#endif
304#ifdef DDR_SDRAM_DATA_INIT_VAL
305        /*
306         * set this value to initialize memory
307         */
308        SET_IMM_REGW r31,r30,DDR_SDRAM_DATA_INIT_OFF,DDR_SDRAM_DATA_INIT_VAL
309#endif
310#ifdef DDR_SDRAM_INIT_ADDR_VAL
311        SET_IMM_REGW r31,r30,DDR_SDRAM_INIT_ADDR_OFF,DDR_SDRAM_INIT_ADDR_VAL
312#endif
313#ifdef DDR_SDRAM_CFG_VAL
314        /*
315         * config DDR SDRAM
316         */
317        SET_IMM_REGW r31,r30,DDR_SDRAM_CFG_OFF,DDR_SDRAM_CFG_VAL & ~DDR_SDRAM_CFG_MEM_EN
318        /*
319         * FIXME: wait 200us
320         */
321        /*
322         * enable  DDR SDRAM
323         */
324        SET_IMM_REGW r31,r30,DDR_SDRAM_CFG_OFF,DDR_SDRAM_CFG_VAL | DDR_SDRAM_CFG_MEM_EN
325        /*
326         * wait, until DDR_SDRAM_CFG_2_D_INIT is cleared
327         */
3281:      lwz r30,DDR_SDRAM_CFG_2_OFF(r31)
329        andi. r30,r30,DDR_SDRAM_CFG_2_D_INIT
330        bne 1b
331#endif
332#ifdef DDR_ERR_DISABLE_VAL2
333        /*
334         * enable detect of some RAM errors
335         */
336        SET_IMM_REGW r31,r30,DDR_ERR_DISABLE_OFF,DDR_ERR_DISABLE_VAL2
337#endif
338#ifdef DDR_SDRAM_INTERVAL_VAL
339        /*
340         * set the refresh interval
341         */
342        SET_IMM_REGW r31,r30,DDR_SDRAM_INTERVAL_OFF,DDR_SDRAM_INTERVAL_VAL
343#endif
344start_rom_skip:
345        /*
346         * determine current execution address offset
347         */
348        bl start_rom_skip1
349start_rom_skip1:
350        mflr r20
351        LA   r30,start_rom_skip1
352        sub. r20,r20,r30
353        /*
354         * execution address offset == 0?
355         * then do not relocate code and data
356         */
357        beq  start_code_in_ram
358        /*
359         * ROM or relocatable startup: copy startup code to SDRAM
360         */
361        /* get start address of start section in RAM */
362        LA      r29, bsp_section_start_begin
363        /* get start address of start section in ROM (add reloc offset) */
364        add     r30, r20, r29
365        /* get size of startup code */
366        LA      r28, bsp_section_start_end
367        sub     28,r28,r29
368        /* copy startup code from ROM to RAM location */
369        bl      copy_image
370
371        /*
372         * ROM startup: jump to code copy in  SDRAM
373         */
374        /* get compile time address of label */
375        LA      r29, copy_rest_of_text
376        mtlr    r29
377        blr                     /* now further execution RAM */
378copy_rest_of_text:
379        LWI  r31,IMMRBAR
380#ifdef LCRR_VAL
381        SET_IMM_REGW r31,r30,LCRR_OFF,LCRR_VAL
382#endif
383        /*
384         * ROM or relocatable startup: copy rest of code to SDRAM
385         */
386        /* get start address of rest of loadable sections in RAM */
387        LA      r29, bsp_section_text_begin
388        /* get start address of loadable sections in ROM (add reloc offset) */
389        add     r30, r20, r29
390        /* get size of rest of loadable sections */
391        LA      r28, bsp_section_data_end
392        sub     r28,r28,r29
393        bl      copy_image      /* copy text section from ROM to RAM location */
394
395start_code_in_ram:
396
397        /*
398         * ROM/RAM startup: clear bss in SDRAM
399         */
400        LA      r3, bsp_section_sbss_begin  /* get start address of bss section */
401        LA      r4, bsp_section_bss_end     /* get end address of bss section */
402        sub     r4, r4, r3                  /* get size of bss section */
403        bl      mpc83xx_zero_4              /* Clear the bss section */
404
405#ifdef HAS_UBOOT
406        mr      r3, r14
407        bl      bsp_uboot_copy_board_info
408#endif /* HAS_UBOOT */
409
410        /* Read-only small data */
411        LA r2, _SDA2_BASE_
412
413        /* Read-write small data */
414        LA r13, _SDA_BASE_
415
416        /* Clear cmdline */
417        li      r3, 0
418
419        /*
420         * Initialize start stack.  The stacks are statically allocated and
421         * properly aligned.
422         */
423        LA      r1, _ISR_Stack_area_end
424        subi    r1, r1, PPC_DEFAULT_CACHE_LINE_SIZE
425        stw     r3, 0(r1)
426
427        /* Call the first C routine */
428        bl      SYM (boot_card)
429
430twiddle:
431        /* We don't expect to return from boot_card but if we do */
432        /* wait here for watchdog to kick us into hard reset     */
433        b       twiddle
434
435copy_image:
436        cmpwi   r28, 0
437        beqlr
438
439        mr      r27, r28
440        srwi    r28, r28, 2
441        mtctr   r28
442
443        slwi    r28, r28, 2
444        sub     r27, r27, r28                   /* maybe some residual bytes */
445copy_image_word:
446        lswi    r28, r30, 0x04
447
448        stswi   r28, r29, 0x04                  /* do word copy ROM -> RAM */
449
450
451        addi    r30, r30, 0x04                  /* increment source pointer */
452        addi    r29, r29, 0x04                  /* increment destination pointer */
453
454        bdnz    copy_image_word                 /* decrement ctr and branch if not 0 */
455
456        cmpwi   r27, 0x00                       /* copy image finished ? */
457        beq     copy_image_end;
458        mtctr   r27                             /* reload counter for residual bytes */
459copy_image_byte:
460        lswi    r28, r30, 0x01
461
462        stswi   r28, r29, 0x01                  /* do byte copy ROM -> RAM */
463
464
465        addi    r30, r30, 0x01                  /* increment source pointer */
466        addi    r29, r29, 0x01                  /* increment destination pointer */
467
468        bdnz    copy_image_byte                 /* decrement ctr and branch if not 0 */
469
470copy_image_end:
471        blr
472
473
474/**
475 * @fn int mpc83xx_zero_4( void *dest, size_t n)
476 *
477 * @brief Zero all @a n bytes starting at @a dest with 4 byte writes.
478 *
479 * The address @a dest has to be aligned on 4 byte boundaries.  The size @a n
480 * must be evenly divisible by 4.
481 */
482GLOBAL_FUNCTION mpc83xx_zero_4
483        /* Create zero */
484        xor     r0, r0, r0
485
486        /* Set offset */
487        xor     r5, r5, r5
488
489        /* Loop counter for the first bytes up to 16 bytes */
490        rlwinm. r9, r4, 30, 30, 31
491        beq     mpc83xx_zero_4_more
492        mtctr   r9
493
494mpc83xx_zero_4_head:
495
496        stwx    r0, r3, r5
497        addi    r5, r5, 4
498        bdnz    mpc83xx_zero_4_head
499
500mpc83xx_zero_4_more:
501
502        /* More than 16 bytes? */
503        srwi.   r9, r4, 4
504        beqlr
505        mtctr   r9
506
507        /* Set offsets */
508        addi    r6, r5, 4
509        addi    r7, r5, 8
510        addi    r8, r5, 12
511
512mpc83xx_zero_4_tail:
513
514        stwx    r0, r3, r5
515        addi    r5, r5, 16
516        stwx    r0, r3, r6
517        addi    r6, r6, 16
518        stwx    r0, r3, r7
519        addi    r7, r7, 16
520        stwx    r0, r3, r8
521        addi    r8, r8, 16
522        bdnz    mpc83xx_zero_4_tail
523
524        /* Return */
525        blr
Note: See TracBrowser for help on using the repository browser.