Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * RTEMS generic TQM8xx BSP
0005  *
0006  * This file contains the startup assembly code.
0007  * It is based on the gen83xx BSP.
0008  */
0009  
0010 /*
0011  * Copyright (c) 2008 embedded brains GmbH & Co. KG
0012  *
0013  * Redistribution and use in source and binary forms, with or without
0014  * modification, are permitted provided that the following conditions
0015  * are met:
0016  * 1. Redistributions of source code must retain the above copyright
0017  *    notice, this list of conditions and the following disclaimer.
0018  * 2. Redistributions in binary form must reproduce the above copyright
0019  *    notice, this list of conditions and the following disclaimer in the
0020  *    documentation and/or other materials provided with the distribution.
0021  *
0022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0023  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0025  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0026  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0027  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0028  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0032  * POSSIBILITY OF SUCH DAMAGE.
0033  */
0034 
0035 #include <libcpu/powerpc-utility.h>
0036 #include <rtems/powerpc/cache.h>
0037 #include <bsp.h>
0038 #include <mpc8xx.h>
0039 
0040 .extern boot_card
0041 
0042 PUBLIC_VAR (_start)
0043 
0044 .section ".bsp_start_text", "ax"
0045 _start:
0046 
0047     /*
0048      * basic CPU setup:
0049      * init MSR
0050      */
0051     mfmsr   r30
0052     SETBITS r30, r29, MSR_ME|MSR_RI
0053     CLRBITS r30, r29, MSR_IP|MSR_EE
0054     mtmsr   r30                 /* Set RI/ME, Clr EE in MSR */
0055     /*
0056      * init IMMR
0057      */
0058     LA  r30,m8xx
0059     mtspr immr,r30
0060     /*
0061      * determine current execution address offset
0062      */
0063     bl start_1
0064 start_1:
0065     mflr r20
0066     LA   r30,start_1
0067     sub. r20,r20,r30
0068     /*
0069      * execution address offset == 0?
0070      * then do not relocate code and data
0071      */
0072     beq  start_code_in_ram
0073     /*
0074      * ROM or relocatable startup: copy startup code to SDRAM
0075      */
0076     /* get start address of text section in RAM */
0077     LA  r29, bsp_section_text_begin
0078     /* get start address of text section in ROM (add reloc offset) */
0079     add r30, r20, r29
0080     /* get size of startup code */
0081     LA  r28, end_reloc_startup
0082     LA  r31, bsp_section_text_begin
0083     sub 28,r28,r31
0084     /* copy startup code from ROM to RAM location */
0085     bl  copy_image
0086 
0087     /*
0088      * jump to code copy in  SDRAM
0089      */
0090     /* get compile time address of label */
0091     LA  r29, copy_rest_of_text
0092     mtlr    r29
0093     blr                     /* now further execution RAM */
0094 copy_rest_of_text:
0095     /*
0096      * ROM or relocatable startup: copy rest of code to SDRAM
0097      */
0098     /* get start address of rest of code in RAM */
0099     LA  r29, end_reloc_startup
0100     /* get start address of text section in ROM (add reloc offset) */
0101     add r30, r20, r29
0102     /* get size of rest of code */
0103     LA  r28, bsp_section_text_begin
0104     LA  r31, bsp_section_text_size
0105     add r28,r28,r31
0106     sub r28,r28,r29
0107     bl  copy_image      /* copy text section from ROM to RAM location */
0108 
0109     /*
0110      * ROM or relocatable startup: copy data to SDRAM
0111      */
0112     /* get start address of data section in RAM */
0113     LA  r29, bsp_section_data_begin
0114     /* get start address of data section in ROM (add reloc offset) */
0115     add r30, r20, r29
0116     /* get size of RAM image */
0117     LA  r28, bsp_section_data_size
0118     /* copy initialized data section from ROM to RAM location */
0119     bl  copy_image
0120 
0121 start_code_in_ram:
0122 
0123     /*
0124      * ROM/RAM startup: clear sbss/bss in SDRAM
0125      */
0126     LA  r3, bsp_section_sbss_begin
0127     LWI r4, bsp_section_sbss_size
0128     bl  mpc8xx_zero_4
0129     LA  r3, bsp_section_bss_begin
0130     LWI r4, bsp_section_bss_size
0131     bl  mpc8xx_zero_4
0132     /*
0133      * call boot_card
0134      */
0135 
0136     /* Set stack pointer (common for RAM/ROM startup) */
0137     LA  r1, _ISR_Stack_area_end
0138         addi    r1, r1, -0x10
0139 
0140     /* Create NULL */
0141     li r0, 0
0142 
0143     /* Return address */
0144     stw r0, 4(r1)
0145 
0146     /* Back chain */
0147     stw r0, 0(r1)
0148 
0149     /* Read-only small data */
0150     LA r2, _SDA2_BASE_
0151 
0152     /* Read-write small data */
0153     LA r13, _SDA_BASE_
0154 
0155     /*
0156      * init some CPU stuff
0157      */
0158     bl SYM (_InitTQM8xx)
0159 
0160 /* clear arguments and do further init. in C (common for RAM/ROM startup) */
0161 
0162         /* Clear cmdline */
0163         xor r3, r3, r3
0164 
0165         bl      SYM (boot_card)  /* Call the first C routine */
0166 
0167 twiddle:
0168     /* We don't expect to return from boot_card but if we do */
0169     /* wait here for watchdog to kick us into hard reset     */
0170     b   twiddle
0171 
0172 copy_with_watchdog:
0173      addi    r5,r5,16
0174      rlwinm. r5,r5,28,4,31
0175      mtctr   r5
0176 
0177 copy_loop:
0178      lwz     r6,0(r3)
0179      lwz     r7,4(r3)
0180      lwz     r8,8(r3)
0181      lwz     r9,12(r3)
0182      stw     r6,0(r4)
0183      stw     r7,4(r4)
0184      stw     r8,8(r4)
0185      stw     r9,12(r4)
0186      addi    r3,r3,16
0187      addi    r4,r4,16
0188      sth     r28,14(r30)
0189      sth     r29,14(r30)
0190      bdnz+   copy_loop
0191      blr
0192 
0193 copy_image:
0194     /*
0195      * watchdog:
0196      * r26 = immr
0197      * r25 = watchdog magic 1
0198      * r24 = watchdog magic 2
0199      */
0200     mfimmr  r26
0201     rlwinm. r26,r26,0,0,15
0202     li      r25,0x556c
0203     li      r24,0xffffaa39
0204 
0205     mr  r27, r28        /* determine number of 4word chunks */
0206     srwi    r28, r28, 4
0207     mtctr   r28
0208 
0209     slwi    r28, r28, 4
0210     sub     r27, r27, r28       /* determine residual bytes */
0211 copy_image_4word:
0212     lwz r20, 0(r30)     /* fetch data */
0213     lwz r21, 4(r30)
0214     lwz r22, 8(r30)
0215     lwz r23,12(r30)
0216     stw r20, 0(r29)     /* store data */
0217     stw r21, 4(r29)
0218     stw r22, 8(r29)
0219     stw r23,12(r29)
0220 
0221     addi    r30, r30, 0x10      /* increment source pointer */
0222     addi    r29, r29, 0x10      /* increment destination pointer */
0223     /*
0224      * trigger watchdog
0225      */
0226     sth     r25,14(r26)
0227     sth     r24,14(r26)
0228 
0229     bdnz    copy_image_4word    /* decrement ctr and branch if not 0 */
0230 
0231     cmpwi   r27, 0x00       /* copy image finished ? */
0232     beq copy_image_end;
0233     mtctr   r27         /* reload counter for residual bytes */
0234 copy_image_byte:
0235     lswi    r28, r30, 0x01
0236 
0237     stswi   r28, r29, 0x01      /* do byte copy ROM -> RAM */
0238 
0239 
0240     addi    r30, r30, 0x01      /* increment source pointer */
0241     addi    r29, r29, 0x01      /* increment destination pointer */
0242 
0243     bdnz    copy_image_byte     /* decrement ctr and branch if not 0 */
0244 
0245 copy_image_end:
0246     blr
0247 
0248 
0249 /**
0250  * @fn int mpc8xx_zero_4( void *dest, size_t n)
0251  *
0252  * @brief Zero all @a n bytes starting at @a dest with 4 byte writes.
0253  *
0254  * The address @a dest has to be aligned on 4 byte boundaries.  The size @a n
0255  * must be evenly divisible by 4.
0256  */
0257 GLOBAL_FUNCTION mpc8xx_zero_4
0258     /* Create zero */
0259     xor r0, r0, r0
0260 
0261     /* Set offset */
0262     xor r5, r5, r5
0263 
0264     /* Loop counter for the first bytes up to 16 bytes */
0265     rlwinm. r9, r4, 30, 30, 31
0266     beq mpc8xx_zero_4_more
0267     mtctr   r9
0268 
0269 mpc8xx_zero_4_head:
0270 
0271     stwx    r0, r3, r5
0272     addi    r5, r5, 4
0273     bdnz    mpc8xx_zero_4_head
0274 
0275 mpc8xx_zero_4_more:
0276 
0277     /* More than 16 bytes? */
0278     srwi.   r9, r4, 4
0279     beqlr
0280     mtctr   r9
0281 
0282     /* Set offsets */
0283     addi    r6, r5, 4
0284     addi    r7, r5, 8
0285     addi    r8, r5, 12
0286 
0287 mpc8xx_zero_4_tail:
0288 
0289     stwx    r0, r3, r5
0290     addi    r5, r5, 16
0291     stwx    r0, r3, r6
0292     addi    r6, r6, 16
0293     stwx    r0, r3, r7
0294     addi    r7, r7, 16
0295     stwx    r0, r3, r8
0296     addi    r8, r8, 16
0297     bdnz    mpc8xx_zero_4_tail
0298 
0299     /* Return */
0300     blr
0301 
0302 end_reloc_startup: