forked from Imagelibrary/rtems
bsps: Move start files to bsps
This patch is a part of the BSP source reorganization. Update #3285.
This commit is contained in:
529
bsps/powerpc/gen83xx/start/start.S
Normal file
529
bsps/powerpc/gen83xx/start/start.S
Normal file
@@ -0,0 +1,529 @@
|
||||
/*===============================================================*\
|
||||
| Project: RTEMS generic MPC83xx BSP |
|
||||
+-----------------------------------------------------------------+
|
||||
| Copyright (c) 2007 |
|
||||
| Embedded Brains GmbH |
|
||||
| Obere Lagerstr. 30 |
|
||||
| D-82178 Puchheim |
|
||||
| Germany |
|
||||
| rtems@embedded-brains.de |
|
||||
+-----------------------------------------------------------------+
|
||||
| The license and distribution terms for this file may be |
|
||||
| found in the file LICENSE in this distribution or at |
|
||||
| |
|
||||
| http://www.rtems.org/license/LICENSE. |
|
||||
| |
|
||||
+-----------------------------------------------------------------+
|
||||
| this file contains the startup assembly code |
|
||||
\*===============================================================*/
|
||||
|
||||
|
||||
#include <libcpu/powerpc-utility.h>
|
||||
#include <rtems/powerpc/cache.h>
|
||||
#include <bsp.h>
|
||||
#include <mpc83xx/mpc83xx.h>
|
||||
|
||||
.macro SET_IMM_REGW base, reg2, offset, value
|
||||
LA \reg2, \value
|
||||
stw \reg2,\offset(\base)
|
||||
.endm
|
||||
|
||||
#define REP8(l) l ; l; l; l; l; l; l; l;
|
||||
|
||||
.extern boot_card
|
||||
.extern MBAR
|
||||
|
||||
#if defined(RESET_CONF_WRD_L)
|
||||
.section ".resconf","ax"
|
||||
PUBLIC_VAR (reset_conf_words)
|
||||
reset_conf_words:
|
||||
REP8( .byte ((RESET_CONF_WRD_L >> 24) & 0xff))
|
||||
REP8( .byte ((RESET_CONF_WRD_L >> 16) & 0xff))
|
||||
REP8( .byte ((RESET_CONF_WRD_L >> 8) & 0xff))
|
||||
REP8( .byte ((RESET_CONF_WRD_L >> 0) & 0xff))
|
||||
|
||||
REP8( .byte ((RESET_CONF_WRD_H >> 24) & 0xff))
|
||||
REP8( .byte ((RESET_CONF_WRD_H >> 16) & 0xff))
|
||||
REP8( .byte ((RESET_CONF_WRD_H >> 8) & 0xff))
|
||||
REP8( .byte ((RESET_CONF_WRD_H >> 0) & 0xff))
|
||||
#endif
|
||||
|
||||
.section ".vectors","ax"
|
||||
PUBLIC_VAR (reset_vec)
|
||||
reset_vec:
|
||||
bl rom_entry
|
||||
|
||||
.section ".bsp_start_text", "ax"
|
||||
PUBLIC_VAR (_start)
|
||||
_start:
|
||||
/* Reset time base */
|
||||
li r0, 0
|
||||
mtspr TBWU, r0
|
||||
mtspr TBWL, r0
|
||||
|
||||
#ifdef HAS_UBOOT
|
||||
mr r14, r3
|
||||
#endif /* HAS_UBOOT */
|
||||
|
||||
/*
|
||||
* basic CPU setup:
|
||||
* init MSR
|
||||
*/
|
||||
mfmsr r30
|
||||
SETBITS r30, r29, MSR_ME|MSR_RI
|
||||
CLRBITS r30, r29, MSR_IP|MSR_EE
|
||||
mtmsr r30 /* Set RI/ME, Clr EE in MSR */
|
||||
|
||||
b start_rom_skip
|
||||
|
||||
PUBLIC_VAR (rom_entry)
|
||||
rom_entry:
|
||||
/*
|
||||
* basic CPU setup:
|
||||
* init MSR
|
||||
*/
|
||||
mfmsr r30
|
||||
SETBITS r30, r29, MSR_ME|MSR_RI
|
||||
CLRBITS r30, r29, MSR_IP|MSR_EE
|
||||
mtmsr r30 /* Set RI/ME, Clr EE in MSR */
|
||||
|
||||
/*
|
||||
* ROM startup: remap IMMR to 0xE0000000
|
||||
* use special sequence from MPC8349EA RM Rev 1, 5.2.4.1.1 "Updating IMMRBAR"
|
||||
*/
|
||||
LWI r30,IMMRBAR_DEFAULT
|
||||
LWI r31,IMMRBAR
|
||||
lwz r29,0(r30)
|
||||
stw r31,0(r30)
|
||||
#if 0
|
||||
lwz r29,0(r28) /* read from ROM... */
|
||||
#endif
|
||||
isync
|
||||
lwz r29,0(r31) /* read from IMMRBAR... */
|
||||
isync
|
||||
/*
|
||||
* NOTE: now r31 points to onchip registers
|
||||
*/
|
||||
/*
|
||||
* we start from 0x100, so ROM is currently mapped to
|
||||
* 0x00000000..
|
||||
* in the next step, ROM will be remapped to its final location
|
||||
* at 0xfe000000... (using LBLAWBAR1 with LBLAWBAR0 value)
|
||||
* and we jump to that location.
|
||||
* then we remove the ROM mapping to zero
|
||||
*/
|
||||
#ifdef LBLAWBAR0_VAL
|
||||
SET_IMM_REGW r31,r30,LBLAWBAR1_OFF,LBLAWBAR0_VAL
|
||||
#endif
|
||||
#ifdef LBLAWAR0_VAL
|
||||
SET_IMM_REGW r31,r30,LBLAWAR1_OFF,LBLAWAR0_VAL
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* ROM startup: jump to code final ROM location
|
||||
*/
|
||||
LA r20, bsp_rom_start /* ROM-RAM reloc in r20 */
|
||||
LA r29, start_code_in_rom /* get compile time addr of label */
|
||||
add r29,r20,r29 /* compute exec address */
|
||||
mtlr r29
|
||||
blr /* now further execution in upper ROM */
|
||||
|
||||
start_code_in_rom:
|
||||
|
||||
#ifdef LBLAWBAR0_VAL
|
||||
SET_IMM_REGW r31,r30,LBLAWBAR0_OFF,LBLAWBAR0_VAL
|
||||
#endif
|
||||
#ifdef LBLAWAR0_VAL
|
||||
SET_IMM_REGW r31,r30,LBLAWAR0_OFF,LBLAWAR0_VAL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local access window 1 is a special case since we used it for a temporary
|
||||
* mapping. If we do not use it then restore the reset value.
|
||||
*/
|
||||
#ifdef LBLAWBAR1_VAL
|
||||
SET_IMM_REGW r31,r30,LBLAWBAR1_OFF,LBLAWBAR1_VAL
|
||||
#else
|
||||
SET_IMM_REGW r31,r30,LBLAWBAR1_OFF,0
|
||||
#endif
|
||||
#ifdef LBLAWAR1_VAL
|
||||
SET_IMM_REGW r31,r30,LBLAWAR1_OFF,LBLAWAR1_VAL
|
||||
#else
|
||||
SET_IMM_REGW r31,r30,LBLAWAR1_OFF,0
|
||||
#endif
|
||||
|
||||
#ifdef LBLAWBAR2_VAL
|
||||
SET_IMM_REGW r31,r30,LBLAWBAR2_OFF,LBLAWBAR2_VAL
|
||||
#endif
|
||||
#ifdef LBLAWAR2_VAL
|
||||
SET_IMM_REGW r31,r30,LBLAWAR2_OFF,LBLAWAR2_VAL
|
||||
#endif
|
||||
#ifdef LBLAWBAR3_VAL
|
||||
SET_IMM_REGW r31,r30,LBLAWBAR3_OFF,LBLAWBAR3_VAL
|
||||
#endif
|
||||
#ifdef LBLAWAR3_VAL
|
||||
SET_IMM_REGW r31,r30,LBLAWAR3_OFF,LBLAWAR3_VAL
|
||||
#endif
|
||||
/*
|
||||
* ROM startup: init bus system
|
||||
*/
|
||||
#ifdef BR0_VAL
|
||||
SET_IMM_REGW r31,r30,BR0_OFF,BR0_VAL
|
||||
#endif
|
||||
#ifdef OR0_VAL
|
||||
SET_IMM_REGW r31,r30,OR0_OFF,OR0_VAL
|
||||
#endif
|
||||
#ifdef BR1_VAL
|
||||
SET_IMM_REGW r31,r30,BR1_OFF,BR1_VAL
|
||||
#endif
|
||||
#ifdef OR1_VAL
|
||||
SET_IMM_REGW r31,r30,OR1_OFF,OR1_VAL
|
||||
#endif
|
||||
#ifdef BR2_VAL
|
||||
SET_IMM_REGW r31,r30,BR2_OFF,BR2_VAL
|
||||
#endif
|
||||
#ifdef OR2_VAL
|
||||
SET_IMM_REGW r31,r30,OR2_OFF,OR2_VAL
|
||||
#endif
|
||||
#ifdef BR3_VAL
|
||||
SET_IMM_REGW r31,r30,BR3_OFF,BR3_VAL
|
||||
#endif
|
||||
#ifdef OR3_VAL
|
||||
SET_IMM_REGW r31,r30,OR3_OFF,OR3_VAL
|
||||
#endif
|
||||
#ifdef BR4_VAL
|
||||
SET_IMM_REGW r31,r30,BR4_OFF,BR4_VAL
|
||||
#endif
|
||||
#ifdef OR4_VAL
|
||||
SET_IMM_REGW r31,r30,OR4_OFF,OR4_VAL
|
||||
#endif
|
||||
#ifdef BR5_VAL
|
||||
SET_IMM_REGW r31,r30,BR5_OFF,BR5_VAL
|
||||
#endif
|
||||
#ifdef OR5_VAL
|
||||
SET_IMM_REGW r31,r30,OR5_OFF,OR5_VAL
|
||||
#endif
|
||||
/*
|
||||
* ROM startup: init SDRAM access window
|
||||
*/
|
||||
#ifdef DDRLAWBAR0_VAL
|
||||
SET_IMM_REGW r31,r30,DDRLAWBAR0_OFF,DDRLAWBAR0_VAL
|
||||
#endif
|
||||
#ifdef DDRLAWAR0_VAL
|
||||
SET_IMM_REGW r31,r30,DDRLAWAR0_OFF,DDRLAWAR0_VAL
|
||||
#endif
|
||||
#ifdef DDRLAWBAR1_VAL
|
||||
SET_IMM_REGW r31,r30,DDRLAWBAR1_OFF,DDRLAWBAR1_VAL
|
||||
#endif
|
||||
#ifdef DDRLAWAR1_VAL
|
||||
SET_IMM_REGW r31,r30,DDRLAWAR1_OFF,DDRLAWAR1_VAL
|
||||
#endif
|
||||
/*
|
||||
* ROM startup: init refresh interval
|
||||
*/
|
||||
#ifdef MRPTR_VAL
|
||||
SET_IMM_REGW r31,r30,MRPTR_OFF,MRPTR_VAL
|
||||
#endif
|
||||
/*
|
||||
* ROM startup: init SDRAM
|
||||
*/
|
||||
#ifdef LSRT_VAL
|
||||
SET_IMM_REGW r31,r30, LSRT_OFF, LSRT_VAL
|
||||
#endif
|
||||
#ifdef LSDMR_VAL
|
||||
SET_IMM_REGW r31,r30, LSDMR_OFF, LSDMR_VAL
|
||||
#endif
|
||||
#ifdef CS0_BNDS_VAL
|
||||
SET_IMM_REGW r31,r30,CS0_BNDS_OFF,CS0_BNDS_VAL
|
||||
#endif
|
||||
#ifdef CS1_BNDS_VAL
|
||||
SET_IMM_REGW r31,r30,CS1_BNDS_OFF,CS1_BNDS_VAL
|
||||
#endif
|
||||
#ifdef CS2_BNDS_VAL
|
||||
SET_IMM_REGW r31,r30,CS2_BNDS_OFF,CS2_BNDS_VAL
|
||||
#endif
|
||||
#ifdef CS3_BNDS_VAL
|
||||
SET_IMM_REGW r31,r30,CS3_BNDS_OFF,CS3_BNDS_VAL
|
||||
#endif
|
||||
#ifdef CS0_CONFIG_VAL
|
||||
SET_IMM_REGW r31,r30,CS0_CONFIG_OFF,CS0_CONFIG_VAL
|
||||
#endif
|
||||
#ifdef CS1_CONFIG_VAL
|
||||
SET_IMM_REGW r31,r30,CS1_CONFIG_OFF,CS1_CONFIG_VAL
|
||||
#endif
|
||||
#ifdef CS2_CONFIG_VAL
|
||||
SET_IMM_REGW r31,r30,CS2_CONFIG_OFF,CS2_CONFIG_VAL
|
||||
#endif
|
||||
#ifdef CS3_CONFIG_VAL
|
||||
SET_IMM_REGW r31,r30,CS3_CONFIG_OFF,CS3_CONFIG_VAL
|
||||
#endif
|
||||
#ifdef TIMING_CFG_3_VAL
|
||||
SET_IMM_REGW r31,r30,TIMING_CFG_3_OFF,TIMING_CFG_3_VAL
|
||||
#endif
|
||||
#ifdef TIMING_CFG_0_VAL
|
||||
SET_IMM_REGW r31,r30,TIMING_CFG_0_OFF,TIMING_CFG_0_VAL
|
||||
#endif
|
||||
#ifdef TIMING_CFG_1_VAL
|
||||
SET_IMM_REGW r31,r30,TIMING_CFG_1_OFF,TIMING_CFG_1_VAL
|
||||
#endif
|
||||
#ifdef TIMING_CFG_2_VAL
|
||||
SET_IMM_REGW r31,r30,TIMING_CFG_2_OFF,TIMING_CFG_2_VAL
|
||||
#endif
|
||||
#ifdef DDRCDR_VAL
|
||||
SET_IMM_REGW r31,r30,DDRCDR_OFF,DDRCDR_VAL
|
||||
#endif
|
||||
#ifdef DDR_SDRAM_CFG_2_VAL
|
||||
SET_IMM_REGW r31,r30,DDR_SDRAM_CFG_2_OFF,DDR_SDRAM_CFG_2_VAL
|
||||
#endif
|
||||
#ifdef DDR_SDRAM_MODE_VAL
|
||||
SET_IMM_REGW r31,r30,DDR_SDRAM_MODE_OFF,DDR_SDRAM_MODE_VAL
|
||||
#endif
|
||||
#ifdef DDR_SDRAM_MODE_2_VAL
|
||||
SET_IMM_REGW r31,r30,DDR_SDRAM_MODE_2_OFF,DDR_SDRAM_MODE_2_VAL
|
||||
#endif
|
||||
#ifdef DDR_SDRAM_MD_CNTL_VAL
|
||||
SET_IMM_REGW r31,r30,DDR_SDRAM_MD_CNTL_OFF,DDR_SDRAM_MD_CNTL_VAL
|
||||
#endif
|
||||
#ifdef DDR_SDRAM_MD_ITVL_VAL
|
||||
SET_IMM_REGW r31,r30,DDR_SDRAM_MD_ITVL_OFF,DDR_SDRAM_MD_ITVL_VAL
|
||||
#endif
|
||||
#ifdef DDR_SDRAM_CLK_CNTL_VAL
|
||||
SET_IMM_REGW r31,r30,DDR_SDRAM_CLK_CNTL_OFF,DDR_SDRAM_CLK_CNTL_VAL
|
||||
#endif
|
||||
#ifdef DDR_SDRAM_CFG_2_VAL
|
||||
SET_IMM_REGW r31,r30,DDR_SDRAM_CFG_2_OFF,DDR_SDRAM_CFG_2_VAL|DDR_SDRAM_CFG_2_D_INIT
|
||||
#endif
|
||||
|
||||
#ifdef DDR_ERR_DISABLE_VAL
|
||||
/*
|
||||
* disable detect of RAM errors
|
||||
*/
|
||||
SET_IMM_REGW r31,r30,DDR_ERR_DISABLE_OFF,DDR_ERR_DISABLE_VAL
|
||||
#endif
|
||||
#ifdef DDR_SDRAM_DATA_INIT_VAL
|
||||
/*
|
||||
* set this value to initialize memory
|
||||
*/
|
||||
SET_IMM_REGW r31,r30,DDR_SDRAM_DATA_INIT_OFF,DDR_SDRAM_DATA_INIT_VAL
|
||||
#endif
|
||||
#ifdef DDR_SDRAM_INIT_ADDR_VAL
|
||||
SET_IMM_REGW r31,r30,DDR_SDRAM_INIT_ADDR_OFF,DDR_SDRAM_INIT_ADDR_VAL
|
||||
#endif
|
||||
#ifdef DDR_SDRAM_CFG_VAL
|
||||
/*
|
||||
* config DDR SDRAM
|
||||
*/
|
||||
SET_IMM_REGW r31,r30,DDR_SDRAM_CFG_OFF,DDR_SDRAM_CFG_VAL & ~DDR_SDRAM_CFG_MEM_EN
|
||||
/*
|
||||
* FIXME: wait 200us
|
||||
*/
|
||||
/*
|
||||
* enable DDR SDRAM
|
||||
*/
|
||||
SET_IMM_REGW r31,r30,DDR_SDRAM_CFG_OFF,DDR_SDRAM_CFG_VAL | DDR_SDRAM_CFG_MEM_EN
|
||||
/*
|
||||
* wait, until DDR_SDRAM_CFG_2_D_INIT is cleared
|
||||
*/
|
||||
1: lwz r30,DDR_SDRAM_CFG_2_OFF(r31)
|
||||
andi. r30,r30,DDR_SDRAM_CFG_2_D_INIT
|
||||
bne 1b
|
||||
#endif
|
||||
#ifdef DDR_ERR_DISABLE_VAL2
|
||||
/*
|
||||
* enable detect of some RAM errors
|
||||
*/
|
||||
SET_IMM_REGW r31,r30,DDR_ERR_DISABLE_OFF,DDR_ERR_DISABLE_VAL2
|
||||
#endif
|
||||
#ifdef DDR_SDRAM_INTERVAL_VAL
|
||||
/*
|
||||
* set the refresh interval
|
||||
*/
|
||||
SET_IMM_REGW r31,r30,DDR_SDRAM_INTERVAL_OFF,DDR_SDRAM_INTERVAL_VAL
|
||||
#endif
|
||||
start_rom_skip:
|
||||
/*
|
||||
* determine current execution address offset
|
||||
*/
|
||||
bl start_rom_skip1
|
||||
start_rom_skip1:
|
||||
mflr r20
|
||||
LA r30,start_rom_skip1
|
||||
sub. r20,r20,r30
|
||||
/*
|
||||
* execution address offset == 0?
|
||||
* then do not relocate code and data
|
||||
*/
|
||||
beq start_code_in_ram
|
||||
/*
|
||||
* ROM or relocatable startup: copy startup code to SDRAM
|
||||
*/
|
||||
/* get start address of start section in RAM */
|
||||
LA r29, bsp_section_start_begin
|
||||
/* get start address of start section in ROM (add reloc offset) */
|
||||
add r30, r20, r29
|
||||
/* get size of startup code */
|
||||
LA r28, bsp_section_start_end
|
||||
sub 28,r28,r29
|
||||
/* copy startup code from ROM to RAM location */
|
||||
bl copy_image
|
||||
|
||||
/*
|
||||
* ROM startup: jump to code copy in SDRAM
|
||||
*/
|
||||
/* get compile time address of label */
|
||||
LA r29, copy_rest_of_text
|
||||
mtlr r29
|
||||
blr /* now further execution RAM */
|
||||
copy_rest_of_text:
|
||||
LWI r31,IMMRBAR
|
||||
#ifdef LCRR_VAL
|
||||
SET_IMM_REGW r31,r30,LCRR_OFF,LCRR_VAL
|
||||
#endif
|
||||
/*
|
||||
* ROM or relocatable startup: copy rest of code to SDRAM
|
||||
*/
|
||||
/* get start address of rest of loadable sections in RAM */
|
||||
LA r29, bsp_section_text_begin
|
||||
/* get start address of loadable sections in ROM (add reloc offset) */
|
||||
add r30, r20, r29
|
||||
/* get size of rest of loadable sections */
|
||||
LA r28, bsp_section_data_end
|
||||
sub r28,r28,r29
|
||||
bl copy_image /* copy text section from ROM to RAM location */
|
||||
|
||||
start_code_in_ram:
|
||||
|
||||
/*
|
||||
* ROM/RAM startup: clear bss in SDRAM
|
||||
*/
|
||||
LA r3, bsp_section_sbss_begin /* get start address of bss section */
|
||||
LA r4, bsp_section_bss_end /* get end address of bss section */
|
||||
sub r4, r4, r3 /* get size of bss section */
|
||||
bl mpc83xx_zero_4 /* Clear the bss section */
|
||||
|
||||
#ifdef HAS_UBOOT
|
||||
mr r3, r14
|
||||
bl bsp_uboot_copy_board_info
|
||||
#endif /* HAS_UBOOT */
|
||||
|
||||
/* Read-only small data */
|
||||
LA r2, _SDA2_BASE_
|
||||
|
||||
/* Read-write small data */
|
||||
LA r13, _SDA_BASE_
|
||||
|
||||
/* Clear cmdline */
|
||||
li r3, 0
|
||||
|
||||
/* Set start stack pointer */
|
||||
LA r1, start_stack_end
|
||||
stwu r3, -4(r1)
|
||||
stwu r3, -4(r1)
|
||||
|
||||
/* Call the first C routine */
|
||||
bl SYM (boot_card)
|
||||
|
||||
twiddle:
|
||||
/* We don't expect to return from boot_card but if we do */
|
||||
/* wait here for watchdog to kick us into hard reset */
|
||||
b twiddle
|
||||
|
||||
copy_image:
|
||||
cmpwi r28, 0
|
||||
beqlr
|
||||
|
||||
mr r27, r28
|
||||
srwi r28, r28, 2
|
||||
mtctr r28
|
||||
|
||||
slwi r28, r28, 2
|
||||
sub r27, r27, r28 /* maybe some residual bytes */
|
||||
copy_image_word:
|
||||
lswi r28, r30, 0x04
|
||||
|
||||
stswi r28, r29, 0x04 /* do word copy ROM -> RAM */
|
||||
|
||||
|
||||
addi r30, r30, 0x04 /* increment source pointer */
|
||||
addi r29, r29, 0x04 /* increment destination pointer */
|
||||
|
||||
bdnz copy_image_word /* decrement ctr and branch if not 0 */
|
||||
|
||||
cmpwi r27, 0x00 /* copy image finished ? */
|
||||
beq copy_image_end;
|
||||
mtctr r27 /* reload counter for residual bytes */
|
||||
copy_image_byte:
|
||||
lswi r28, r30, 0x01
|
||||
|
||||
stswi r28, r29, 0x01 /* do byte copy ROM -> RAM */
|
||||
|
||||
|
||||
addi r30, r30, 0x01 /* increment source pointer */
|
||||
addi r29, r29, 0x01 /* increment destination pointer */
|
||||
|
||||
bdnz copy_image_byte /* decrement ctr and branch if not 0 */
|
||||
|
||||
copy_image_end:
|
||||
blr
|
||||
|
||||
|
||||
/**
|
||||
* @fn int mpc83xx_zero_4( void *dest, size_t n)
|
||||
*
|
||||
* @brief Zero all @a n bytes starting at @a dest with 4 byte writes.
|
||||
*
|
||||
* The address @a dest has to be aligned on 4 byte boundaries. The size @a n
|
||||
* must be evenly divisible by 4.
|
||||
*/
|
||||
GLOBAL_FUNCTION mpc83xx_zero_4
|
||||
/* Create zero */
|
||||
xor r0, r0, r0
|
||||
|
||||
/* Set offset */
|
||||
xor r5, r5, r5
|
||||
|
||||
/* Loop counter for the first bytes up to 16 bytes */
|
||||
rlwinm. r9, r4, 30, 30, 31
|
||||
beq mpc83xx_zero_4_more
|
||||
mtctr r9
|
||||
|
||||
mpc83xx_zero_4_head:
|
||||
|
||||
stwx r0, r3, r5
|
||||
addi r5, r5, 4
|
||||
bdnz mpc83xx_zero_4_head
|
||||
|
||||
mpc83xx_zero_4_more:
|
||||
|
||||
/* More than 16 bytes? */
|
||||
srwi. r9, r4, 4
|
||||
beqlr
|
||||
mtctr r9
|
||||
|
||||
/* Set offsets */
|
||||
addi r6, r5, 4
|
||||
addi r7, r5, 8
|
||||
addi r8, r5, 12
|
||||
|
||||
mpc83xx_zero_4_tail:
|
||||
|
||||
stwx r0, r3, r5
|
||||
addi r5, r5, 16
|
||||
stwx r0, r3, r6
|
||||
addi r6, r6, 16
|
||||
stwx r0, r3, r7
|
||||
addi r7, r7, 16
|
||||
stwx r0, r3, r8
|
||||
addi r8, r8, 16
|
||||
bdnz mpc83xx_zero_4_tail
|
||||
|
||||
/* Return */
|
||||
blr
|
||||
|
||||
.section ".bsp_rwextra", "aw", @nobits
|
||||
|
||||
/* Start stack area */
|
||||
.align 4
|
||||
.space 4096
|
||||
start_stack_end:
|
||||
Reference in New Issue
Block a user