source: rtems/c/src/lib/libbsp/powerpc/gen83xx/start/start.S @ e08dbc5

4.104.115
Last change on this file since e08dbc5 was e08dbc5, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 11/03/09 at 18:45:04

various PowerPC code maintenance

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