Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:53

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * RTEMS generic MPC83xx BSP
0005  *
0006  * This file contains the startup assembly code.
0007  */
0008 
0009 /*
0010  * Copyright (c) 2007 embedded brains GmbH & Co. KG
0011  *
0012  * Redistribution and use in source and binary forms, with or without
0013  * modification, are permitted provided that the following conditions
0014  * are met:
0015  * 1. Redistributions of source code must retain the above copyright
0016  *    notice, this list of conditions and the following disclaimer.
0017  * 2. Redistributions in binary form must reproduce the above copyright
0018  *    notice, this list of conditions and the following disclaimer in the
0019  *    documentation and/or other materials provided with the distribution.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0025  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0026  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0027  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0030  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0031  * POSSIBILITY OF SUCH DAMAGE.
0032  */
0033 
0034 #include <libcpu/powerpc-utility.h>
0035 #include <rtems/powerpc/cache.h>
0036 #include <bsp.h>
0037 #include <mpc83xx/mpc83xx.h>
0038 
0039 .macro SET_IMM_REGW base, reg2, offset, value
0040     LA \reg2, \value
0041     stw \reg2,\offset(\base)
0042 .endm
0043 
0044 #define REP8(l) l ; l; l; l; l; l; l; l;
0045 
0046 .extern boot_card
0047 .extern MBAR
0048 
0049 #if defined(RESET_CONF_WRD_L)
0050 .section ".resconf","ax"
0051 PUBLIC_VAR (reset_conf_words)
0052 reset_conf_words:
0053     REP8( .byte ((RESET_CONF_WRD_L >> 24) & 0xff))
0054     REP8( .byte ((RESET_CONF_WRD_L >> 16) & 0xff))
0055     REP8( .byte ((RESET_CONF_WRD_L >>  8) & 0xff))
0056     REP8( .byte ((RESET_CONF_WRD_L >>  0) & 0xff))
0057 
0058     REP8( .byte ((RESET_CONF_WRD_H >> 24) & 0xff))
0059     REP8( .byte ((RESET_CONF_WRD_H >> 16) & 0xff))
0060     REP8( .byte ((RESET_CONF_WRD_H >>  8) & 0xff))
0061     REP8( .byte ((RESET_CONF_WRD_H >>  0) & 0xff))
0062 #endif
0063 
0064 .section ".vectors","ax"
0065 PUBLIC_VAR (reset_vec)
0066 reset_vec:
0067     bl rom_entry
0068 
0069 .section ".bsp_start_text", "ax"
0070 PUBLIC_VAR (_start)
0071 _start:
0072     /* Reset time base */
0073     li  r0, 0
0074     mtspr   TBWU, r0
0075     mtspr   TBWL, r0
0076 
0077 #ifdef HAS_UBOOT
0078     mr  r14, r3
0079 #endif /* HAS_UBOOT */
0080 
0081     /*
0082      * basic CPU setup:
0083      * init MSR
0084      */
0085     mfmsr   r30
0086     SETBITS r30, r29, MSR_ME|MSR_RI
0087     CLRBITS r30, r29, MSR_IP|MSR_EE
0088     mtmsr   r30                 /* Set RI/ME, Clr EE in MSR */
0089 
0090     b start_rom_skip
0091 
0092 PUBLIC_VAR (rom_entry)
0093 rom_entry:
0094     /*
0095      * basic CPU setup:
0096      * init MSR
0097      */
0098     mfmsr   r30
0099     SETBITS r30, r29, MSR_ME|MSR_RI
0100     CLRBITS r30, r29, MSR_IP|MSR_EE
0101     mtmsr   r30                 /* Set RI/ME, Clr EE in MSR */
0102 
0103     /*
0104      * ROM startup: remap IMMR to 0xE0000000
0105      * use special sequence from MPC8349EA RM Rev 1, 5.2.4.1.1 "Updating IMMRBAR"
0106      */
0107     LWI  r30,IMMRBAR_DEFAULT
0108     LWI  r31,IMMRBAR
0109     lwz  r29,0(r30)
0110     stw  r31,0(r30)
0111 #if 0
0112     lwz  r29,0(r28) /* read from ROM... */
0113 #endif
0114     isync
0115     lwz  r29,0(r31) /* read from IMMRBAR... */
0116     isync
0117     /*
0118      * NOTE:     now r31 points to onchip registers
0119     */
0120     /*
0121      * we start from 0x100, so ROM is currently mapped to
0122      * 0x00000000..
0123      * in the next step, ROM will be remapped to its final location
0124      * at 0xfe000000... (using LBLAWBAR1 with LBLAWBAR0 value)
0125      * and we jump to that location.
0126      * then we remove the ROM mapping to zero
0127      */
0128 #ifdef LBLAWBAR0_VAL
0129     SET_IMM_REGW r31,r30,LBLAWBAR1_OFF,LBLAWBAR0_VAL
0130 #endif
0131 #ifdef LBLAWAR0_VAL
0132     SET_IMM_REGW r31,r30,LBLAWAR1_OFF,LBLAWAR0_VAL
0133 #endif
0134 
0135 
0136     /*
0137      * ROM startup: jump to code final ROM location
0138      */
0139     LA  r20, bsp_rom_start /* ROM-RAM reloc in r20 */
0140     LA  r29, start_code_in_rom /* get compile time addr of label */
0141     add r29,r20,r29    /* compute exec address */
0142     mtlr    r29
0143     blr                     /* now further execution in upper ROM */
0144 
0145 start_code_in_rom:
0146 
0147 #ifdef LBLAWBAR0_VAL
0148     SET_IMM_REGW r31,r30,LBLAWBAR0_OFF,LBLAWBAR0_VAL
0149 #endif
0150 #ifdef LBLAWAR0_VAL
0151     SET_IMM_REGW r31,r30,LBLAWAR0_OFF,LBLAWAR0_VAL
0152 #endif
0153 
0154 /*
0155  * Local access window 1 is a special case since we used it for a temporary
0156  * mapping.  If we do not use it then restore the reset value.
0157  */
0158 #ifdef LBLAWBAR1_VAL
0159     SET_IMM_REGW r31,r30,LBLAWBAR1_OFF,LBLAWBAR1_VAL
0160 #else
0161     SET_IMM_REGW r31,r30,LBLAWBAR1_OFF,0
0162 #endif
0163 #ifdef LBLAWAR1_VAL
0164     SET_IMM_REGW r31,r30,LBLAWAR1_OFF,LBLAWAR1_VAL
0165 #else
0166     SET_IMM_REGW r31,r30,LBLAWAR1_OFF,0
0167 #endif
0168 
0169 #ifdef LBLAWBAR2_VAL
0170     SET_IMM_REGW r31,r30,LBLAWBAR2_OFF,LBLAWBAR2_VAL
0171 #endif
0172 #ifdef LBLAWAR2_VAL
0173     SET_IMM_REGW r31,r30,LBLAWAR2_OFF,LBLAWAR2_VAL
0174 #endif
0175 #ifdef LBLAWBAR3_VAL
0176     SET_IMM_REGW r31,r30,LBLAWBAR3_OFF,LBLAWBAR3_VAL
0177 #endif
0178 #ifdef LBLAWAR3_VAL
0179     SET_IMM_REGW r31,r30,LBLAWAR3_OFF,LBLAWAR3_VAL
0180 #endif
0181     /*
0182      * ROM startup: init bus system
0183      */
0184 #ifdef BR0_VAL
0185     SET_IMM_REGW r31,r30,BR0_OFF,BR0_VAL
0186 #endif
0187 #ifdef OR0_VAL
0188     SET_IMM_REGW r31,r30,OR0_OFF,OR0_VAL
0189 #endif
0190 #ifdef BR1_VAL
0191     SET_IMM_REGW r31,r30,BR1_OFF,BR1_VAL
0192 #endif
0193 #ifdef OR1_VAL
0194     SET_IMM_REGW r31,r30,OR1_OFF,OR1_VAL
0195 #endif
0196 #ifdef BR2_VAL
0197     SET_IMM_REGW r31,r30,BR2_OFF,BR2_VAL
0198 #endif
0199 #ifdef OR2_VAL
0200     SET_IMM_REGW r31,r30,OR2_OFF,OR2_VAL
0201 #endif
0202 #ifdef BR3_VAL
0203     SET_IMM_REGW r31,r30,BR3_OFF,BR3_VAL
0204 #endif
0205 #ifdef OR3_VAL
0206     SET_IMM_REGW r31,r30,OR3_OFF,OR3_VAL
0207 #endif
0208 #ifdef BR4_VAL
0209     SET_IMM_REGW r31,r30,BR4_OFF,BR4_VAL
0210 #endif
0211 #ifdef OR4_VAL
0212     SET_IMM_REGW r31,r30,OR4_OFF,OR4_VAL
0213 #endif
0214 #ifdef BR5_VAL
0215     SET_IMM_REGW r31,r30,BR5_OFF,BR5_VAL
0216 #endif
0217 #ifdef OR5_VAL
0218     SET_IMM_REGW r31,r30,OR5_OFF,OR5_VAL
0219 #endif
0220     /*
0221      * ROM startup: init SDRAM access window
0222      */
0223 #ifdef DDRLAWBAR0_VAL
0224     SET_IMM_REGW r31,r30,DDRLAWBAR0_OFF,DDRLAWBAR0_VAL
0225 #endif
0226 #ifdef DDRLAWAR0_VAL
0227     SET_IMM_REGW r31,r30,DDRLAWAR0_OFF,DDRLAWAR0_VAL
0228 #endif
0229 #ifdef DDRLAWBAR1_VAL
0230     SET_IMM_REGW r31,r30,DDRLAWBAR1_OFF,DDRLAWBAR1_VAL
0231 #endif
0232 #ifdef DDRLAWAR1_VAL
0233     SET_IMM_REGW r31,r30,DDRLAWAR1_OFF,DDRLAWAR1_VAL
0234 #endif
0235     /*
0236      * ROM startup: init refresh interval
0237      */
0238 #ifdef MRPTR_VAL
0239     SET_IMM_REGW r31,r30,MRPTR_OFF,MRPTR_VAL
0240 #endif
0241     /*
0242      * ROM startup: init SDRAM
0243      */
0244 #ifdef LSRT_VAL
0245     SET_IMM_REGW r31,r30, LSRT_OFF, LSRT_VAL
0246 #endif
0247 #ifdef LSDMR_VAL
0248     SET_IMM_REGW r31,r30, LSDMR_OFF, LSDMR_VAL
0249 #endif
0250 #ifdef CS0_BNDS_VAL
0251     SET_IMM_REGW r31,r30,CS0_BNDS_OFF,CS0_BNDS_VAL
0252 #endif
0253 #ifdef CS1_BNDS_VAL
0254     SET_IMM_REGW r31,r30,CS1_BNDS_OFF,CS1_BNDS_VAL
0255 #endif
0256 #ifdef CS2_BNDS_VAL
0257     SET_IMM_REGW r31,r30,CS2_BNDS_OFF,CS2_BNDS_VAL
0258 #endif
0259 #ifdef CS3_BNDS_VAL
0260     SET_IMM_REGW r31,r30,CS3_BNDS_OFF,CS3_BNDS_VAL
0261 #endif
0262 #ifdef CS0_CONFIG_VAL
0263     SET_IMM_REGW r31,r30,CS0_CONFIG_OFF,CS0_CONFIG_VAL
0264 #endif
0265 #ifdef CS1_CONFIG_VAL
0266     SET_IMM_REGW r31,r30,CS1_CONFIG_OFF,CS1_CONFIG_VAL
0267 #endif
0268 #ifdef CS2_CONFIG_VAL
0269     SET_IMM_REGW r31,r30,CS2_CONFIG_OFF,CS2_CONFIG_VAL
0270 #endif
0271 #ifdef CS3_CONFIG_VAL
0272     SET_IMM_REGW r31,r30,CS3_CONFIG_OFF,CS3_CONFIG_VAL
0273 #endif
0274 #ifdef TIMING_CFG_3_VAL
0275     SET_IMM_REGW r31,r30,TIMING_CFG_3_OFF,TIMING_CFG_3_VAL
0276 #endif
0277 #ifdef TIMING_CFG_0_VAL
0278     SET_IMM_REGW r31,r30,TIMING_CFG_0_OFF,TIMING_CFG_0_VAL
0279 #endif
0280 #ifdef TIMING_CFG_1_VAL
0281     SET_IMM_REGW r31,r30,TIMING_CFG_1_OFF,TIMING_CFG_1_VAL
0282 #endif
0283 #ifdef TIMING_CFG_2_VAL
0284     SET_IMM_REGW r31,r30,TIMING_CFG_2_OFF,TIMING_CFG_2_VAL
0285 #endif
0286 #ifdef DDRCDR_VAL
0287     SET_IMM_REGW r31,r30,DDRCDR_OFF,DDRCDR_VAL
0288 #endif
0289 #ifdef DDR_SDRAM_CFG_2_VAL
0290     SET_IMM_REGW r31,r30,DDR_SDRAM_CFG_2_OFF,DDR_SDRAM_CFG_2_VAL
0291 #endif
0292 #ifdef DDR_SDRAM_MODE_VAL
0293     SET_IMM_REGW r31,r30,DDR_SDRAM_MODE_OFF,DDR_SDRAM_MODE_VAL
0294 #endif
0295 #ifdef DDR_SDRAM_MODE_2_VAL
0296     SET_IMM_REGW r31,r30,DDR_SDRAM_MODE_2_OFF,DDR_SDRAM_MODE_2_VAL
0297 #endif
0298 #ifdef DDR_SDRAM_MD_CNTL_VAL
0299     SET_IMM_REGW r31,r30,DDR_SDRAM_MD_CNTL_OFF,DDR_SDRAM_MD_CNTL_VAL
0300 #endif
0301 #ifdef DDR_SDRAM_MD_ITVL_VAL
0302     SET_IMM_REGW r31,r30,DDR_SDRAM_MD_ITVL_OFF,DDR_SDRAM_MD_ITVL_VAL
0303 #endif
0304 #ifdef DDR_SDRAM_CLK_CNTL_VAL
0305     SET_IMM_REGW r31,r30,DDR_SDRAM_CLK_CNTL_OFF,DDR_SDRAM_CLK_CNTL_VAL
0306 #endif
0307 #ifdef DDR_SDRAM_CFG_2_VAL
0308     SET_IMM_REGW r31,r30,DDR_SDRAM_CFG_2_OFF,DDR_SDRAM_CFG_2_VAL|DDR_SDRAM_CFG_2_D_INIT
0309 #endif
0310 
0311 #ifdef DDR_ERR_DISABLE_VAL
0312     /*
0313      * disable detect of RAM errors
0314      */
0315     SET_IMM_REGW r31,r30,DDR_ERR_DISABLE_OFF,DDR_ERR_DISABLE_VAL
0316 #endif
0317 #ifdef DDR_SDRAM_DATA_INIT_VAL
0318     /*
0319      * set this value to initialize memory
0320      */
0321     SET_IMM_REGW r31,r30,DDR_SDRAM_DATA_INIT_OFF,DDR_SDRAM_DATA_INIT_VAL
0322 #endif
0323 #ifdef DDR_SDRAM_INIT_ADDR_VAL
0324     SET_IMM_REGW r31,r30,DDR_SDRAM_INIT_ADDR_OFF,DDR_SDRAM_INIT_ADDR_VAL
0325 #endif
0326 #ifdef DDR_SDRAM_CFG_VAL
0327     /*
0328      * config DDR SDRAM
0329      */
0330     SET_IMM_REGW r31,r30,DDR_SDRAM_CFG_OFF,DDR_SDRAM_CFG_VAL & ~DDR_SDRAM_CFG_MEM_EN
0331     /*
0332      * FIXME: wait 200us
0333      */
0334     /*
0335      * enable  DDR SDRAM
0336      */
0337     SET_IMM_REGW r31,r30,DDR_SDRAM_CFG_OFF,DDR_SDRAM_CFG_VAL | DDR_SDRAM_CFG_MEM_EN
0338     /*
0339      * wait, until DDR_SDRAM_CFG_2_D_INIT is cleared
0340      */
0341 1:  lwz r30,DDR_SDRAM_CFG_2_OFF(r31)
0342     andi. r30,r30,DDR_SDRAM_CFG_2_D_INIT
0343     bne 1b
0344 #endif
0345 #ifdef DDR_ERR_DISABLE_VAL2
0346     /*
0347      * enable detect of some RAM errors
0348      */
0349     SET_IMM_REGW r31,r30,DDR_ERR_DISABLE_OFF,DDR_ERR_DISABLE_VAL2
0350 #endif
0351 #ifdef DDR_SDRAM_INTERVAL_VAL
0352     /*
0353      * set the refresh interval
0354      */
0355     SET_IMM_REGW r31,r30,DDR_SDRAM_INTERVAL_OFF,DDR_SDRAM_INTERVAL_VAL
0356 #endif
0357 start_rom_skip:
0358     /*
0359      * determine current execution address offset
0360      */
0361     bl start_rom_skip1
0362 start_rom_skip1:
0363     mflr r20
0364     LA   r30,start_rom_skip1
0365     sub. r20,r20,r30
0366     /*
0367      * execution address offset == 0?
0368      * then do not relocate code and data
0369      */
0370     beq  start_code_in_ram
0371     /*
0372      * ROM or relocatable startup: copy startup code to SDRAM
0373      */
0374     /* get start address of start section in RAM */
0375     LA  r29, bsp_section_start_begin
0376     /* get start address of start section in ROM (add reloc offset) */
0377     add r30, r20, r29
0378     /* get size of startup code */
0379     LA  r28, bsp_section_start_end
0380     sub 28,r28,r29
0381     /* copy startup code from ROM to RAM location */
0382     bl  copy_image
0383 
0384     /*
0385      * ROM startup: jump to code copy in  SDRAM
0386      */
0387     /* get compile time address of label */
0388     LA  r29, copy_rest_of_text
0389     mtlr    r29
0390     blr                     /* now further execution RAM */
0391 copy_rest_of_text:
0392     LWI  r31,IMMRBAR
0393 #ifdef LCRR_VAL
0394     SET_IMM_REGW r31,r30,LCRR_OFF,LCRR_VAL
0395 #endif
0396     /*
0397      * ROM or relocatable startup: copy rest of code to SDRAM
0398      */
0399     /* get start address of rest of loadable sections in RAM */
0400     LA  r29, bsp_section_text_begin
0401     /* get start address of loadable sections in ROM (add reloc offset) */
0402     add r30, r20, r29
0403     /* get size of rest of loadable sections */
0404     LA  r28, bsp_section_data_end
0405     sub r28,r28,r29
0406     bl  copy_image      /* copy text section from ROM to RAM location */
0407 
0408 start_code_in_ram:
0409 
0410     /*
0411      * ROM/RAM startup: clear bss in SDRAM
0412      */
0413     LA  r3, bsp_section_sbss_begin  /* get start address of bss section */
0414     LA  r4, bsp_section_bss_end     /* get end address of bss section */
0415     sub r4, r4, r3                  /* get size of bss section */
0416     bl  mpc83xx_zero_4              /* Clear the bss section */
0417 
0418 #ifdef HAS_UBOOT
0419     mr  r3, r14
0420     bl  bsp_uboot_copy_board_info
0421 #endif /* HAS_UBOOT */
0422 
0423     /* Read-only small data */
0424     LA r2, _SDA2_BASE_
0425 
0426     /* Read-write small data */
0427     LA r13, _SDA_BASE_
0428 
0429     /* Clear cmdline */
0430     li  r3, 0
0431 
0432     /*
0433      * Initialize start stack.  The stacks are statically allocated and
0434      * properly aligned.
0435      */
0436     LA  r1, _ISR_Stack_area_end
0437     subi    r1, r1, PPC_DEFAULT_CACHE_LINE_SIZE
0438     stw r3, 0(r1)
0439 
0440     /* Call the first C routine */
0441         bl      SYM (boot_card)
0442 
0443 twiddle:
0444     /* We don't expect to return from boot_card but if we do */
0445     /* wait here for watchdog to kick us into hard reset     */
0446     b   twiddle
0447 
0448 copy_image:
0449     cmpwi   r28, 0
0450     beqlr
0451 
0452     mr  r27, r28
0453     srwi    r28, r28, 2
0454     mtctr   r28
0455 
0456     slwi    r28, r28, 2
0457     sub     r27, r27, r28           /* maybe some residual bytes */
0458 copy_image_word:
0459     lswi    r28, r30, 0x04
0460 
0461     stswi   r28, r29, 0x04          /* do word copy ROM -> RAM */
0462 
0463 
0464     addi    r30, r30, 0x04          /* increment source pointer */
0465     addi    r29, r29, 0x04          /* increment destination pointer */
0466 
0467     bdnz    copy_image_word         /* decrement ctr and branch if not 0 */
0468 
0469     cmpwi   r27, 0x00           /* copy image finished ? */
0470     beq copy_image_end;
0471     mtctr   r27             /* reload counter for residual bytes */
0472 copy_image_byte:
0473     lswi    r28, r30, 0x01
0474 
0475     stswi   r28, r29, 0x01          /* do byte copy ROM -> RAM */
0476 
0477 
0478     addi    r30, r30, 0x01          /* increment source pointer */
0479     addi    r29, r29, 0x01          /* increment destination pointer */
0480 
0481     bdnz    copy_image_byte         /* decrement ctr and branch if not 0 */
0482 
0483 copy_image_end:
0484     blr
0485 
0486 
0487 /**
0488  * @fn int mpc83xx_zero_4( void *dest, size_t n)
0489  *
0490  * @brief Zero all @a n bytes starting at @a dest with 4 byte writes.
0491  *
0492  * The address @a dest has to be aligned on 4 byte boundaries.  The size @a n
0493  * must be evenly divisible by 4.
0494  */
0495 GLOBAL_FUNCTION mpc83xx_zero_4
0496     /* Create zero */
0497     xor r0, r0, r0
0498 
0499     /* Set offset */
0500     xor r5, r5, r5
0501 
0502     /* Loop counter for the first bytes up to 16 bytes */
0503     rlwinm. r9, r4, 30, 30, 31
0504     beq mpc83xx_zero_4_more
0505     mtctr   r9
0506 
0507 mpc83xx_zero_4_head:
0508 
0509     stwx    r0, r3, r5
0510     addi    r5, r5, 4
0511     bdnz    mpc83xx_zero_4_head
0512 
0513 mpc83xx_zero_4_more:
0514 
0515     /* More than 16 bytes? */
0516     srwi.   r9, r4, 4
0517     beqlr
0518     mtctr   r9
0519 
0520     /* Set offsets */
0521     addi    r6, r5, 4
0522     addi    r7, r5, 8
0523     addi    r8, r5, 12
0524 
0525 mpc83xx_zero_4_tail:
0526 
0527     stwx    r0, r3, r5
0528     addi    r5, r5, 16
0529     stwx    r0, r3, r6
0530     addi    r6, r6, 16
0531     stwx    r0, r3, r7
0532     addi    r7, r7, 16
0533     stwx    r0, r3, r8
0534     addi    r8, r8, 16
0535     bdnz    mpc83xx_zero_4_tail
0536 
0537     /* Return */
0538     blr