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:
1000
bsps/powerpc/gen5200/start/start.S
Normal file
1000
bsps/powerpc/gen5200/start/start.S
Normal file
File diff suppressed because it is too large
Load Diff
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:
|
||||
299
bsps/powerpc/mpc55xxevb/start/start.S
Normal file
299
bsps/powerpc/mpc55xxevb/start/start.S
Normal file
@@ -0,0 +1,299 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup mpc55xx_asm
|
||||
*
|
||||
* @brief Boot and system start code.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <bspopts.h>
|
||||
#include <bsp/linker-symbols.h>
|
||||
#include <libcpu/powerpc-utility.h>
|
||||
|
||||
#if MPC55XX_CHIP_FAMILY != 551
|
||||
#define HAS_SPE
|
||||
#endif
|
||||
|
||||
#if MPC55XX_CHIP_FAMILY == 564
|
||||
#define INIT_REGISTERS_FOR_LSM
|
||||
#endif
|
||||
|
||||
#ifdef HAS_SPE
|
||||
#define ZERO_GPR(reg) evxor reg, reg, reg
|
||||
#else
|
||||
#define ZERO_GPR(reg) xor reg, reg, reg
|
||||
#endif
|
||||
|
||||
.extern __eabi
|
||||
.extern boot_card
|
||||
.extern bsp_ram_start
|
||||
.extern mpc55xx_start_config_mmu_early
|
||||
.extern mpc55xx_start_config_mmu_early_count
|
||||
.extern mpc55xx_start_early
|
||||
|
||||
.globl _start
|
||||
.globl mpc55xx_start_load_section
|
||||
.globl mpc55xx_start_mmu_apply_config
|
||||
|
||||
#ifdef MPC55XX_BOOTFLAGS
|
||||
.globl mpc55xx_bootflag_0
|
||||
.globl mpc55xx_bootflag_1
|
||||
#endif
|
||||
|
||||
.section ".bsp_start_text", "ax"
|
||||
|
||||
/* BAM: RCHW */
|
||||
.int 0x005a0000
|
||||
|
||||
/* BAM: Address of start instruction */
|
||||
.int _start
|
||||
|
||||
#ifdef MPC55XX_BOOTFLAGS
|
||||
/*
|
||||
* We skip over the next two boot flag words to the next 64-bit
|
||||
* aligned start address. It is 64-bit aligned to play well with
|
||||
* FLASH programming. These boot flags can be set by debuggers
|
||||
* and emulators to customize boot. Currently bit0 of
|
||||
* bootflag_0 means to "skip setting up the MMU", allowing
|
||||
* external MMU setup in a debugger before branching to 0x10.
|
||||
* This can be used e.g., to map FLASH into RAM.
|
||||
*/
|
||||
mpc55xx_bootflag_0:
|
||||
.int 0xffffffff
|
||||
mpc55xx_bootflag_1:
|
||||
.int 0xffffffff
|
||||
#endif
|
||||
|
||||
_start:
|
||||
|
||||
#ifdef MPC55XX_ENABLE_START_PROLOGUE
|
||||
bl mpc55xx_start_prologue
|
||||
#endif
|
||||
|
||||
#ifdef MPC55XX_NEEDS_LOW_LEVEL_INIT
|
||||
|
||||
/* Enable SPE */
|
||||
#ifdef HAS_SPE
|
||||
mfmsr r3
|
||||
oris r3, r3, MSR_SPE >> 16
|
||||
mtmsr r3
|
||||
isync
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialization of core registers according to "e200z4 Power
|
||||
* Architecture Core Reference Manual" section 2.6 "Reset Settings"
|
||||
* table 2-16 "Reset Settings of e200 Resources". This is necessary
|
||||
* for lock step mode (LSM).
|
||||
*/
|
||||
ZERO_GPR(r0)
|
||||
#ifdef INIT_REGISTERS_FOR_LSM
|
||||
ZERO_GPR(r1)
|
||||
ZERO_GPR(r2)
|
||||
ZERO_GPR(r4)
|
||||
ZERO_GPR(r5)
|
||||
ZERO_GPR(r6)
|
||||
ZERO_GPR(r7)
|
||||
ZERO_GPR(r8)
|
||||
ZERO_GPR(r9)
|
||||
ZERO_GPR(r10)
|
||||
ZERO_GPR(r11)
|
||||
ZERO_GPR(r12)
|
||||
ZERO_GPR(r13)
|
||||
ZERO_GPR(r14)
|
||||
ZERO_GPR(r15)
|
||||
ZERO_GPR(r16)
|
||||
ZERO_GPR(r17)
|
||||
ZERO_GPR(r18)
|
||||
ZERO_GPR(r19)
|
||||
ZERO_GPR(r20)
|
||||
ZERO_GPR(r21)
|
||||
ZERO_GPR(r22)
|
||||
ZERO_GPR(r23)
|
||||
ZERO_GPR(r24)
|
||||
ZERO_GPR(r25)
|
||||
ZERO_GPR(r26)
|
||||
ZERO_GPR(r27)
|
||||
ZERO_GPR(r28)
|
||||
ZERO_GPR(r29)
|
||||
ZERO_GPR(r30)
|
||||
ZERO_GPR(r31)
|
||||
mtcrf 0xff, r0
|
||||
mtcsrr0 r0
|
||||
mtcsrr1 r0
|
||||
mtctr r0
|
||||
mtspr FSL_EIS_DBCNT, r0
|
||||
mtspr DEAR_BOOKE, r0
|
||||
mtdec r0
|
||||
mtspr BOOKE_DECAR, r0
|
||||
mtspr FSL_EIS_DSRR0, r0
|
||||
mtspr FSL_EIS_DSRR1, r0
|
||||
mtspr BOOKE_DVC1, r0
|
||||
mtspr BOOKE_DVC2, r0
|
||||
mtspr BOOKE_IVPR, r0
|
||||
mtlr r0
|
||||
mtspr FSL_EIS_MCAR, r0
|
||||
mtmcsrr0 r0
|
||||
mtmcsrr1 r0
|
||||
mtspr SPRG0, r0
|
||||
mtspr SPRG1, r0
|
||||
mtspr SPRG2, r0
|
||||
mtspr SPRG3, r0
|
||||
mtspr SPRG4, r0
|
||||
mtspr SPRG5, r0
|
||||
mtspr SPRG6, r0
|
||||
mtspr SPRG7, r0
|
||||
mtspr FSL_EIS_SPRG8, r0
|
||||
mtspr FSL_EIS_SPRG9, r0
|
||||
mtsrr0 r0
|
||||
mtsrr1 r0
|
||||
mtspr USPRG0, r0
|
||||
#ifdef HAS_SPE
|
||||
evmra r0, r0
|
||||
#endif
|
||||
#endif /* INIT_REGISTERS_FOR_LSM */
|
||||
mtspr TBWL, r0
|
||||
mtspr TBWU, r0
|
||||
|
||||
/* Enable time base */
|
||||
mfspr r3, HID0
|
||||
ori r3, r3, 0x4000
|
||||
mtspr HID0, r3
|
||||
|
||||
/*
|
||||
* Enable branch prediction.
|
||||
*
|
||||
* Errata e4396: e200z7: Erroneous Address Fetch
|
||||
*
|
||||
* The propose workaround does not work.
|
||||
*/
|
||||
#if MPC55XX_CHIP_FAMILY != 567
|
||||
LWI r3, FSL_EIS_BUCSR_BBFI | FSL_EIS_BUCSR_BALLOC_ALL | FSL_EIS_BUCSR_BPRED_NOT_TAKEN | FSL_EIS_BUCSR_BPEN
|
||||
mtspr FSL_EIS_BUCSR, r3
|
||||
#endif
|
||||
|
||||
#endif /* MPC55XX_NEEDS_LOW_LEVEL_INIT */
|
||||
|
||||
/* MMU early initialization */
|
||||
LA r3, mpc55xx_start_config_mmu_early
|
||||
LW r4, mpc55xx_start_config_mmu_early_count
|
||||
bl mpc55xx_start_mmu_apply_config
|
||||
|
||||
#ifdef MPC55XX_NEEDS_LOW_LEVEL_INIT
|
||||
|
||||
/* Initialize intermediate stack (ECC) */
|
||||
|
||||
LA r3, bsp_ram_start
|
||||
addi r4, r3, MPC55XX_EARLY_STACK_SIZE
|
||||
|
||||
zero_intermediate_stack_loop:
|
||||
|
||||
#ifdef HAS_SPE
|
||||
evstdd r0, 0(r3)
|
||||
evstdd r0, 8(r3)
|
||||
evstdd r0, 16(r3)
|
||||
evstdd r0, 24(r3)
|
||||
#else
|
||||
stw r0, 0(r3)
|
||||
stw r0, 4(r3)
|
||||
stw r0, 8(r3)
|
||||
stw r0, 12(r3)
|
||||
stw r0, 16(r3)
|
||||
stw r0, 20(r3)
|
||||
stw r0, 24(r3)
|
||||
stw r0, 28(r3)
|
||||
#endif
|
||||
addi r3, r3, 32
|
||||
cmpw cr7, r3, r4
|
||||
bne cr7, zero_intermediate_stack_loop
|
||||
subi r1, r3, 16
|
||||
|
||||
#endif /* MPC55XX_NEEDS_LOW_LEVEL_INIT */
|
||||
|
||||
/* Next steps in C */
|
||||
bl mpc55xx_start_early
|
||||
|
||||
/* Initialize start stack */
|
||||
LA r1, start_stack_end
|
||||
subi r1, r1, 16
|
||||
li r0, 0
|
||||
stw r0, 0(r1)
|
||||
|
||||
/*
|
||||
* Load sections. This must be performed after the stack switch
|
||||
* because it may overwrite the initial stack.
|
||||
*/
|
||||
LA r3, bsp_section_fast_text_begin
|
||||
LA r4, bsp_section_fast_text_load_begin
|
||||
LA r5, bsp_section_fast_text_size
|
||||
bl mpc55xx_start_load_section
|
||||
LA r3, bsp_section_fast_data_begin
|
||||
LA r4, bsp_section_fast_data_load_begin
|
||||
LA r5, bsp_section_fast_data_size
|
||||
bl mpc55xx_start_load_section
|
||||
LA r3, bsp_section_data_begin
|
||||
LA r4, bsp_section_data_load_begin
|
||||
LA r5, bsp_section_data_size
|
||||
bl mpc55xx_start_load_section
|
||||
|
||||
/* Set up EABI and SYSV environment */
|
||||
bl __eabi
|
||||
|
||||
/* Clear command line */
|
||||
li r3, 0
|
||||
|
||||
/* Start RTEMS */
|
||||
bl boot_card
|
||||
|
||||
/* Spin around */
|
||||
twiddle:
|
||||
|
||||
b twiddle
|
||||
|
||||
mpc55xx_start_mmu_apply_config:
|
||||
|
||||
cmpwi cr7, r4, r0
|
||||
beqlr cr7
|
||||
mtctr r4
|
||||
|
||||
mmu_init_loop:
|
||||
|
||||
lwz r4, 0(r3)
|
||||
lwz r5, 4(r3)
|
||||
lwz r6, 8(r3)
|
||||
lwz r7, 12(r3)
|
||||
mtspr FSL_EIS_MAS0, r4
|
||||
mtspr FSL_EIS_MAS1, r5
|
||||
mtspr FSL_EIS_MAS2, r6
|
||||
mtspr FSL_EIS_MAS3, r7
|
||||
tlbwe
|
||||
addi r3, r3, 16
|
||||
bdnz mmu_init_loop
|
||||
blr
|
||||
|
||||
mpc55xx_start_load_section:
|
||||
cmpw cr7, r3, r4
|
||||
beqlr cr7
|
||||
b memcpy
|
||||
|
||||
/* Start stack area */
|
||||
|
||||
.section ".bsp_rwextra", "aw", @nobits
|
||||
.align 4
|
||||
.space 4096
|
||||
|
||||
start_stack_end:
|
||||
168
bsps/powerpc/mpc8260ads/start/start.S
Normal file
168
bsps/powerpc/mpc8260ads/start/start.S
Normal file
@@ -0,0 +1,168 @@
|
||||
/* start.S
|
||||
*
|
||||
* Modified for the Motorola PQII ADS board by
|
||||
* Andy Dachs <a.dachs@sstl.co.uk> 23-11-00.
|
||||
* Surrey Satellite Technology Limited
|
||||
*
|
||||
* I have a proprietary bootloader programmed into the flash
|
||||
* on the board which initialises the SDRAM prior to calling
|
||||
* this function.
|
||||
*
|
||||
* This file is based on the one by Jay Monkman (jmonkman@fracsa.com)
|
||||
* which in turn was based on the dlentry.s file for the Papyrus BSP,
|
||||
* written by:
|
||||
*
|
||||
* Author: Andrew Bray <andy@i-cubed.co.uk>
|
||||
*
|
||||
* COPYRIGHT (c) 1995 by i-cubed ltd.
|
||||
*
|
||||
* To anyone who acknowledges that this file is provided "AS IS"
|
||||
* without any express or implied warranty:
|
||||
* permission to use, copy, modify, and distribute this file
|
||||
* for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice and this notice appears in all
|
||||
* copies, and that the name of i-cubed limited not be used in
|
||||
* advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
* i-cubed limited makes no representations about the suitability
|
||||
* of this software for any purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <rtems/asm.h>
|
||||
|
||||
/*
|
||||
* The initial stack is set to run BELOW the code base address.
|
||||
* (between the vectors and text sections)
|
||||
*
|
||||
* The entry veneer has to clear the BSS and copy the read only
|
||||
* version of the data segment to the correct location.
|
||||
*/
|
||||
|
||||
.section ".entry" /* This might have to be the first thing in the
|
||||
* text section. At one time, it had to be
|
||||
* first, but I don't believe it is true
|
||||
* any more. */
|
||||
PUBLIC_VAR (start)
|
||||
SYM(start):
|
||||
bl .startup
|
||||
base_addr:
|
||||
|
||||
/*
|
||||
* Parameters from linker
|
||||
*/
|
||||
toc_pointer:
|
||||
.long s.got
|
||||
bss_length:
|
||||
.long bss.size
|
||||
bss_addr:
|
||||
.long bss.start
|
||||
|
||||
PUBLIC_VAR (data_length )
|
||||
data_length:
|
||||
.long data.size
|
||||
PUBLIC_VAR (data_addr )
|
||||
data_addr:
|
||||
.long data.start
|
||||
|
||||
PUBLIC_VAR (text_addr)
|
||||
text_addr:
|
||||
.long text.start
|
||||
|
||||
PUBLIC_VAR (text_length)
|
||||
text_length:
|
||||
.long text.size
|
||||
|
||||
/*
|
||||
* Initialization code
|
||||
*/
|
||||
.startup:
|
||||
/* Get start address */
|
||||
mflr r1
|
||||
|
||||
/* --------------------------------------------------
|
||||
* Clear MSR[EE] to disable interrupts
|
||||
* Clear MSR[IP] bit to put vectors at 0x00000000
|
||||
* Set MSR[FP] to enable FPU - not on my eval board!
|
||||
* -------------------------------------------------- */
|
||||
mfmsr r5
|
||||
lis r13, 0xFFFF
|
||||
ori r13, r13, 0x7FBF
|
||||
and r5, r5, r13 /* Clear EE and IP */
|
||||
#if 1
|
||||
ori r5, r5, 0x2000 /* Enable FPU */
|
||||
#endif
|
||||
mtmsr r5
|
||||
|
||||
#ifdef ENABLE_CACHE
|
||||
/* Enable caches */
|
||||
mfspr r5, 1008
|
||||
ori r5, r5, 0x8000
|
||||
isync
|
||||
mtspr 1008, r5
|
||||
|
||||
/* Leave D-cache disabled for now */
|
||||
#if 0
|
||||
ori r5, r5, 0x4000
|
||||
sync
|
||||
mtspr 1008, r5
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------
|
||||
* Set up the power management modes
|
||||
* The 8260 has a dynamic power management mode that
|
||||
* is automatically invoked if the unit is idle.
|
||||
* We invoke the NAP mode in the RTEMS idle task.
|
||||
*-------------------------------------------------- */
|
||||
|
||||
lis r13, 0x0050 /* set nap mode and DPM */
|
||||
or r5, r5, r13
|
||||
mtspr 1008, r5
|
||||
|
||||
/*--------------------------------------------------
|
||||
*
|
||||
*-------------------------------------------------- */
|
||||
|
||||
/* clear the bss section */
|
||||
bl bssclr
|
||||
|
||||
/*
|
||||
* C_setup.
|
||||
*/
|
||||
|
||||
/* set toc */
|
||||
lwz r2, toc_pointer-base_addr(r1)
|
||||
|
||||
/* Set up stack pointer = beginning of text section - 56 */
|
||||
addi r1, r1, -56-4
|
||||
|
||||
/* Clear cmdline */
|
||||
xor r3, r3, r3
|
||||
|
||||
.extern SYM (boot_card)
|
||||
bl SYM (boot_card) /* call the first C routine */
|
||||
|
||||
/* we don't expect to return from boot_card but if we do */
|
||||
/* wait here for watchdog to kick us into hard reset */
|
||||
|
||||
twiddle:
|
||||
b twiddle
|
||||
|
||||
/*
|
||||
* bssclr - zero out bss
|
||||
*/
|
||||
bssclr:
|
||||
lwz r4, bss_addr-base_addr(r1) /* Start of bss */
|
||||
lwz r5, bss_length-base_addr(r1) /* Length of bss */
|
||||
|
||||
rlwinm. r5,r5,30,0x3FFFFFFF /* form length/4 */
|
||||
beqlr /* no bss */
|
||||
mtctr r5 /* set ctr reg */
|
||||
xor r6,r6,r6 /* r6 = 0 */
|
||||
clear_bss:
|
||||
stswi r6,r4,0x4 /* store r6 */
|
||||
addi r4,r4,0x4 /* update r2 */
|
||||
|
||||
bdnz clear_bss /* dec counter and loop */
|
||||
blr /* return */
|
||||
90
bsps/powerpc/mvme3100/start/start.S
Normal file
90
bsps/powerpc/mvme3100/start/start.S
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* start.S : RTEMS entry point
|
||||
*
|
||||
* Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Modified for mvme3100 by T. Straumann, 2007.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <rtems/asm.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
#include <rtems/powerpc/powerpc.h>
|
||||
|
||||
#include <bspopts.h>
|
||||
|
||||
#define SYNC \
|
||||
sync; \
|
||||
isync
|
||||
|
||||
#define KERNELBASE 0x0
|
||||
|
||||
/* cannot include <bsp.h> from assembly :-( */
|
||||
#ifndef BSP_8540_CCSR_BASE
|
||||
#define BSP_8540_CCSR_BASE 0xe1000000
|
||||
#endif
|
||||
|
||||
#define ERR_DISABLE_REG (BSP_8540_CCSR_BASE + 0x2e44)
|
||||
|
||||
.text
|
||||
.globl __rtems_entry_point
|
||||
.type __rtems_entry_point,@function
|
||||
__rtems_entry_point:
|
||||
mr r31,r3
|
||||
mr r30,r4
|
||||
mr r29,r5
|
||||
mr r28,r6
|
||||
mr r27,r7
|
||||
/* disable checking for memory-select errors; motload has all TLBs
|
||||
* mapping a possible larger area as memory (not-guarded, caching-enabled)
|
||||
* than actual physical memory is available.
|
||||
* In case of speculative loads this may cause 'memory-select' errors
|
||||
* which seem to raise 'core_fault_in' (found no description in
|
||||
* the manual but I experienced this problem).
|
||||
* Such errors (if HID1[RFXE] is clear) may *stall* execution
|
||||
* leading to mysterious 'hangs'.
|
||||
* Note: enabling HID1[RFXE] at this point makes no sense since
|
||||
* exceptions are not configured yet. Therefore we disable
|
||||
* memory-select errors.
|
||||
* Eventually (bspstart.c) we want to delete TLB entries for
|
||||
* which no physical memory is present.
|
||||
*/
|
||||
lis r3, ERR_DISABLE_REG@ha
|
||||
lwz r4, ERR_DISABLE_REG@l(r3)
|
||||
/* disable memory-select errors */
|
||||
ori r4, r4, 1
|
||||
stw r4, ERR_DISABLE_REG@l(r3)
|
||||
|
||||
/* Use MotLoad's TLB setup for now; caches are on already */
|
||||
bl __eabi /* setup EABI and SYSV environment */
|
||||
bl zero_bss
|
||||
/*
|
||||
* restore original args
|
||||
*/
|
||||
mr r3,r31
|
||||
mr r4,r30
|
||||
mr r5,r29
|
||||
mr r6,r28
|
||||
mr r7,r27
|
||||
bl save_boot_params
|
||||
addis r9,r0, (__stack-PPC_MINIMUM_STACK_FRAME_SIZE)@ha
|
||||
addi r9,r9, (__stack-PPC_MINIMUM_STACK_FRAME_SIZE)@l
|
||||
/* align down to 16-bytes */
|
||||
li r5, (CPU_STACK_ALIGNMENT - 1)
|
||||
andc r1, r9, r5
|
||||
|
||||
/* NULL ptr to back chain */
|
||||
li r0, 0
|
||||
stw r0, 0(r1)
|
||||
|
||||
/*
|
||||
* We are now in a environment that is totally independent from
|
||||
* bootloader setup.
|
||||
*/
|
||||
/* pass result of 'save_boot_params' to 'boot_card' in R3 */
|
||||
bl boot_card
|
||||
/* point of no return: reset board here ? */
|
||||
208
bsps/powerpc/mvme5500/start/start.S
Normal file
208
bsps/powerpc/mvme5500/start/start.S
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* start.S : RTEMS entry point
|
||||
*
|
||||
* Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
|
||||
*
|
||||
* S. Kate Feng <feng1@bnl.gov>, April 2004
|
||||
* Mapped the 2nd 256MB of RAM to support the MVME5500/MVME6100 boards
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <rtems/asm.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
#include <rtems/powerpc/powerpc.h>
|
||||
|
||||
#include <libcpu/io.h>
|
||||
#include <libcpu/bat.h>
|
||||
#include <bspopts.h>
|
||||
|
||||
#define SYNC \
|
||||
sync; \
|
||||
isync
|
||||
|
||||
#define KERNELBASE 0x0
|
||||
#define MEM256MB 0x10000000
|
||||
|
||||
#define MONITOR_ENTER \
|
||||
mfmsr r10 ; \
|
||||
ori r10,r10,MSR_IP ; \
|
||||
mtmsr r10 ; \
|
||||
li r10,0x63 ; \
|
||||
sc
|
||||
|
||||
.text
|
||||
.globl __rtems_entry_point
|
||||
.type __rtems_entry_point,@function
|
||||
__rtems_entry_point:
|
||||
#ifdef DEBUG_EARLY_START
|
||||
MONITOR_ENTER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PREP
|
||||
* This is jumped to on prep systems right after the kernel is relocated
|
||||
* to its proper place in memory by the boot loader. The expected layout
|
||||
* of the regs is:
|
||||
* r3: ptr to residual data
|
||||
* r4: initrd_start or if no initrd then 0
|
||||
* r5: initrd_end - unused if r4 is 0
|
||||
* r6: Start of command line string
|
||||
* r7: End of command line string
|
||||
*
|
||||
* The Prep boot loader insure that the MMU is currently off...
|
||||
*
|
||||
*/
|
||||
|
||||
mr r31,r3 /* save parameters */
|
||||
mr r30,r4
|
||||
mr r29,r5
|
||||
mr r28,r6
|
||||
mr r27,r7
|
||||
|
||||
#ifdef __ALTIVEC__
|
||||
/* enable altivec; gcc may use it! */
|
||||
mfmsr r0
|
||||
oris r0, r0, (1<<(31-16-6))
|
||||
mtmsr r0
|
||||
isync
|
||||
/*
|
||||
* set vscr and vrsave to known values
|
||||
*/
|
||||
li r0, 0
|
||||
mtvrsave r0
|
||||
vxor 0,0,0
|
||||
mtvscr 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make sure we have nothing in BATS and TLB
|
||||
*/
|
||||
bl CPU_clear_bats_early
|
||||
bl flush_tlbs
|
||||
/*
|
||||
* Use the first pair of BAT registers to map the 1st 256MB
|
||||
* of RAM to KERNELBASE.
|
||||
*/
|
||||
lis r11,KERNELBASE@h
|
||||
/* set up BAT registers for 604 */
|
||||
ori r11,r11,0x1ffe
|
||||
li r8,2 /* R/W access */
|
||||
isync
|
||||
mtspr DBAT0L,r8 /* N.B. 6xx (not 601) have valid */
|
||||
mtspr DBAT0U,r11 /* bit in upper BAT register */
|
||||
mtspr IBAT0L,r8
|
||||
mtspr IBAT0U,r11
|
||||
isync
|
||||
/*
|
||||
* <skf> Use the 2nd pair of BAT registers to map the 2nd 256MB
|
||||
* of RAM to 0x10000000.
|
||||
*/
|
||||
lis r11,MEM256MB@h
|
||||
ori r11,r11,0x1ffe /* set up BAT1 registers for 604+ */
|
||||
lis r8,MEM256MB@h
|
||||
ori r8,r8,2
|
||||
isync
|
||||
mtspr DBAT1L,r8 /* N.B. 6xx (not 601) have valid */
|
||||
mtspr DBAT1U,r11 /* bit in upper BAT register */
|
||||
mtspr IBAT1L,r8
|
||||
mtspr IBAT1U,r11
|
||||
isync
|
||||
|
||||
/*
|
||||
* we now have the two 256M of ram mapped with the bats. We are still
|
||||
* running on the bootloader stack and cannot switch to an RTEMS allocated
|
||||
* init stack before copying the residual data that may have been set just
|
||||
* after rtems_end address. This bug has been experienced on MVME2304. Thank
|
||||
* to Till Straumann <strauman@SLAC.Stanford.EDU> for hunting it and
|
||||
* suggesting the appropriate code.
|
||||
*/
|
||||
|
||||
enter_C_code:
|
||||
bl MMUon
|
||||
bl __eabi /* setup EABI and SYSV environment */
|
||||
bl zero_bss
|
||||
/*
|
||||
* restore prep boot params
|
||||
*/
|
||||
mr r3,r31
|
||||
mr r4,r30
|
||||
mr r5,r29
|
||||
mr r6,r28
|
||||
mr r7,r27
|
||||
bl save_boot_params
|
||||
/*
|
||||
* stack = &__rtems_end + 4096
|
||||
*/
|
||||
addis r9,r0, __stack-PPC_MINIMUM_STACK_FRAME_SIZE@ha
|
||||
addi r9,r9, __stack-PPC_MINIMUM_STACK_FRAME_SIZE@l
|
||||
/*
|
||||
* align initial stack
|
||||
* (we hope that the bootloader stack was 16-byte aligned
|
||||
* or we haven't used altivec yet...)
|
||||
*/
|
||||
li r0, (CPU_STACK_ALIGNMENT-1)
|
||||
andc r1, r9, r0
|
||||
/*
|
||||
* NULL ptr to back chain
|
||||
*/
|
||||
li r0, 0
|
||||
stw r0, 0(r1)
|
||||
|
||||
/*
|
||||
* We are now in a environment that is totally independent from
|
||||
* bootloader setup.
|
||||
*/
|
||||
/* pass result of 'save_boot_params' to 'boot_card' in R3 */
|
||||
bl boot_card
|
||||
bl _return_to_ppcbug
|
||||
|
||||
.globl MMUon
|
||||
.type MMUon,@function
|
||||
MMUon:
|
||||
mfmsr r0
|
||||
ori r0,r0, MSR_IP | MSR_RI | MSR_IR | MSR_DR | MSR_EE | MSR_FE0 | MSR_FE1 | MSR_FP
|
||||
#if (PPC_HAS_FPU == 0)
|
||||
xori r0, r0, MSR_EE | MSR_IP | MSR_FP
|
||||
#else
|
||||
xori r0, r0, MSR_EE | MSR_IP | MSR_FE0 | MSR_FE1
|
||||
#endif
|
||||
mflr r11
|
||||
mtsrr0 r11
|
||||
mtsrr1 r0
|
||||
SYNC
|
||||
rfi
|
||||
|
||||
.globl MMUoff
|
||||
.type MMUoff,@function
|
||||
MMUoff:
|
||||
mfmsr r0
|
||||
ori r0,r0,MSR_IR| MSR_DR | MSR_IP
|
||||
mflr r11
|
||||
xori r0,r0,MSR_IR|MSR_DR
|
||||
mtsrr0 r11
|
||||
mtsrr1 r0
|
||||
SYNC
|
||||
rfi
|
||||
|
||||
.globl _return_to_ppcbug
|
||||
.type _return_to_ppcbug,@function
|
||||
|
||||
_return_to_ppcbug:
|
||||
mflr r30
|
||||
bl MMUoff
|
||||
MONITOR_ENTER
|
||||
bl MMUon
|
||||
mtctr r30
|
||||
bctr
|
||||
|
||||
flush_tlbs:
|
||||
lis r20, 0x1000
|
||||
1: addic. r20, r20, -0x1000
|
||||
tlbie r20
|
||||
bgt 1b
|
||||
sync
|
||||
blr
|
||||
141
bsps/powerpc/psim/start/start.S
Normal file
141
bsps/powerpc/psim/start/start.S
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* This is based on the mvme-crt0.S file from libgloss/rs6000.
|
||||
* crt0.S -- startup file for PowerPC systems.
|
||||
*
|
||||
* Copyright (c) 1995 Cygnus Support
|
||||
*
|
||||
* The authors hereby grant permission to use, copy, modify, distribute,
|
||||
* and license this software and its documentation for any purpose, provided
|
||||
* that existing copyright notices are retained in all copies and that this
|
||||
* notice is included verbatim in any distributions. No written agreement,
|
||||
* license, or royalty fee is required for any of the authorized uses.
|
||||
* Modifications to this software may be copyrighted by their authors
|
||||
* and need not follow the licensing terms described here, provided that
|
||||
* the new terms are clearly indicated on the first page of each file where
|
||||
* they apply.
|
||||
*/
|
||||
|
||||
#include <rtems/asm.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
#include <libcpu/io.h>
|
||||
#include "ppc-asm.h"
|
||||
|
||||
.section ".got2","aw"
|
||||
.align 2
|
||||
|
||||
.LCTOC1 = .+32768
|
||||
|
||||
.extern FUNC_NAME(atexit)
|
||||
.globl FUNC_NAME(__atexit)
|
||||
.section ".sdata","aw"
|
||||
.align 2
|
||||
FUNC_NAME(__atexit): /* tell C's eabi-ctor's we have an atexit function */
|
||||
.long FUNC_NAME(atexit)@fixup /* and that it is to register __do_global_dtors */
|
||||
|
||||
.section ".fixup","aw"
|
||||
.align 2
|
||||
.long FUNC_NAME(__atexit)
|
||||
|
||||
.section ".got2","aw"
|
||||
.Ltable = .-.LCTOC1
|
||||
.long .LCTOC1 /* address we think .LCTOC1 is loaded at */
|
||||
|
||||
.Lbss_start = .-.LCTOC1
|
||||
.long bsp_section_sbss_begin
|
||||
|
||||
.Lend = .-.LCTOC1
|
||||
.long bsp_section_bss_end
|
||||
|
||||
.Lstack = .-.LCTOC1 /* stack address if set by user */
|
||||
.long __stack
|
||||
|
||||
.text
|
||||
.Lptr:
|
||||
.long .LCTOC1-.Laddr
|
||||
|
||||
.globl __rtems_entry_point
|
||||
.type __rtems_entry_point,@function
|
||||
__rtems_entry_point:
|
||||
#if 1
|
||||
.globl _start
|
||||
.type _start,@function
|
||||
_start:
|
||||
#endif
|
||||
bl .Laddr /* get current address */
|
||||
.Laddr:
|
||||
mflr r4 /* real address of .Laddr */
|
||||
lwz r5,(.Lptr-.Laddr)(r4) /* linker generated address of .LCTOC1 */
|
||||
add r5,r5,r4 /* correct to real pointer */
|
||||
lwz r4,.Ltable(r5) /* get linker's idea of where .Laddr is */
|
||||
subf r4,r4,r5 /* calculate difference between where linked and current */
|
||||
|
||||
/* clear bss */
|
||||
lwz r6,.Lbss_start(r5) /* calculate beginning of the BSS */
|
||||
lwz r7,.Lend(r5) /* calculate end of the BSS */
|
||||
add r6,r6,r4 /* adjust pointers */
|
||||
add r7,r7,r4
|
||||
|
||||
cmplw 1,r6,r7
|
||||
bc 4,4,.Ldone
|
||||
|
||||
subf r8,r6,r7 /* number of bytes to zero */
|
||||
srwi r9,r8,2 /* number of words to zero */
|
||||
mtctr r9
|
||||
li r0,0 /* zero to clear memory */
|
||||
addi r6,r6,-4 /* adjust so we can use stwu */
|
||||
.Lloop:
|
||||
stwu r0,4(r6) /* zero bss */
|
||||
bdnz .Lloop
|
||||
|
||||
.Ldone:
|
||||
|
||||
lwz r0,.Lstack(r5) /* stack address or 0 */
|
||||
cmplwi 1,r0,0 /* equal to 0? */
|
||||
bc 12,6,.Lnostack /* use default stack if == 0 */
|
||||
mr sp,r0 /* use user defined stack */
|
||||
|
||||
.Lnostack:
|
||||
#ifdef __ALTIVEC__
|
||||
/* enable altivec; this requires the ALTIVEC user
|
||||
* extension to be installed in the user extension
|
||||
* slot 0!
|
||||
*/
|
||||
mfmsr r0
|
||||
oris r0, r0, (1<<(31-16-6))
|
||||
mtmsr r0
|
||||
isync
|
||||
/*
|
||||
* set vscr and vrsave to known values
|
||||
*/
|
||||
li r0, 0
|
||||
mtvrsave r0
|
||||
vxor 0,0,0
|
||||
mtvscr 0
|
||||
#endif
|
||||
/* set up initial stack frame */
|
||||
addi sp,sp,-4 /* make sure we don't overwrite debug mem */
|
||||
/* align */
|
||||
li r3, CPU_STACK_ALIGNMENT-1
|
||||
andc sp, sp, r3
|
||||
lis r0,0
|
||||
stw r0,0(sp) /* clear back chain */
|
||||
stwu sp,-CPU_STACK_ALIGNMENT(sp) /* push another stack frame */
|
||||
bl FUNC_NAME(__eabi)
|
||||
|
||||
/* Let her rip */
|
||||
li r3, 0 /* command line */
|
||||
bl FUNC_NAME(boot_card)
|
||||
|
||||
.globl FUNC_NAME(bsp_reset)
|
||||
FUNC_NAME(bsp_reset):
|
||||
li 10,99 /* 0x63 */
|
||||
sc
|
||||
|
||||
.Lstart:
|
||||
.size _start,.Lstart-_start
|
||||
|
||||
/* Start stack area */
|
||||
.section ".bsp_rwextra", "aw", @nobits
|
||||
.align 4
|
||||
.space 4096
|
||||
__stack:
|
||||
52
bsps/powerpc/qemuppc/start/start.S
Normal file
52
bsps/powerpc/qemuppc/start/start.S
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <rtems/score/cpu.h>
|
||||
#include <rtems/powerpc/powerpc.h>
|
||||
|
||||
#include <bspopts.h>
|
||||
|
||||
.global bsp_interrupt_stack_start
|
||||
.global bsp_interrupt_stack_end
|
||||
.global _start
|
||||
|
||||
.section .bsp_start_text,"awx",@progbits
|
||||
|
||||
_start:
|
||||
lis %r1,bsp_interrupt_stack_start@h
|
||||
ori %r1,%r1,bsp_interrupt_stack_start@l
|
||||
/* Make sure stack is properly aligned */
|
||||
li %r3, CPU_STACK_ALIGNMENT - 1
|
||||
andc %r1, %r1, %r3
|
||||
/* NULL ptr to back chain */
|
||||
li %r3, 0
|
||||
stw %r3, 0(%r1)
|
||||
|
||||
li %r3,8192
|
||||
mtmsr %r3
|
||||
|
||||
/* Read-only small data */
|
||||
lis %r2, _SDA2_BASE_@h
|
||||
ori %r2, %r2,_SDA2_BASE_@l
|
||||
|
||||
/* Read-write small data */
|
||||
lis %r13, _SDA_BASE_@h
|
||||
ori %r13, %r13,_SDA_BASE_@l
|
||||
|
||||
bl cmain
|
||||
.size _start, . - _start
|
||||
|
||||
.global __eabi
|
||||
__eabi:
|
||||
blr
|
||||
.size __eabi, . - __eabi
|
||||
|
||||
.section ".reset","ax"
|
||||
_reset:
|
||||
b _start
|
||||
.size _reset, . - _reset
|
||||
|
||||
/* Start stack area */
|
||||
.section ".bsp_rwextra", "aw", @nobits
|
||||
.align 4
|
||||
.space 4096
|
||||
bsp_interrupt_stack_start:
|
||||
.space 32768
|
||||
bsp_interrupt_stack_end:
|
||||
548
bsps/powerpc/qoriq/start/start.S
Normal file
548
bsps/powerpc/qoriq/start/start.S
Normal file
@@ -0,0 +1,548 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup qoriq
|
||||
*
|
||||
* @brief BSP start.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010, 2017 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <rtems/score/percpu.h>
|
||||
|
||||
#include <bsp.h>
|
||||
|
||||
#include <libcpu/powerpc-utility.h>
|
||||
|
||||
#include <bsp/vectors.h>
|
||||
|
||||
#if (QORIQ_INITIAL_MSR & MSR_FP) != 0
|
||||
#define INITIALIZE_FPU
|
||||
#endif
|
||||
|
||||
#define FIRST_TLB 0
|
||||
#define SCRATCH_TLB QORIQ_TLB1_ENTRY_COUNT - 1
|
||||
#define INITIAL_MSR r14
|
||||
#define START_STACK r15
|
||||
#define SAVED_LINK_REGISTER r16
|
||||
#define FDT_REGISTER r17
|
||||
|
||||
.globl _start
|
||||
#ifdef RTEMS_SMP
|
||||
#if QORIQ_THREAD_COUNT > 1
|
||||
.globl _start_thread
|
||||
#endif
|
||||
.globl _start_secondary_processor
|
||||
#endif
|
||||
.globl bsp_exc_vector_base
|
||||
|
||||
.section ".bsp_start_text", "ax"
|
||||
|
||||
_start:
|
||||
mr FDT_REGISTER, r3
|
||||
bl .Linitearly
|
||||
|
||||
/* Get start stack */
|
||||
LA START_STACK, start_stack_end
|
||||
|
||||
bl .Linitmore
|
||||
|
||||
/* Copy fast text */
|
||||
LA r3, bsp_section_fast_text_begin
|
||||
LA r4, bsp_section_fast_text_load_begin
|
||||
LA r5, bsp_section_fast_text_size
|
||||
bl .Lcopy
|
||||
LA r3, bsp_section_fast_text_begin
|
||||
LA r4, bsp_section_fast_text_size
|
||||
bl rtems_cache_flush_multiple_data_lines
|
||||
PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
|
||||
/* Copy read-only data */
|
||||
LA r3, bsp_section_rodata_begin
|
||||
LA r4, bsp_section_rodata_load_begin
|
||||
LA r5, bsp_section_rodata_size
|
||||
bl .Lcopy
|
||||
|
||||
/* Copy FDT into read-only data */
|
||||
mr r3, FDT_REGISTER
|
||||
bl bsp_fdt_copy
|
||||
PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
|
||||
/* Flush read-only data */
|
||||
LA r3, bsp_section_rodata_begin
|
||||
LA r4, bsp_section_rodata_size
|
||||
bl rtems_cache_flush_multiple_data_lines
|
||||
PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
|
||||
/* Copy fast data */
|
||||
LA r3, bsp_section_fast_data_begin
|
||||
LA r4, bsp_section_fast_data_load_begin
|
||||
LA r5, bsp_section_fast_data_size
|
||||
bl .Lcopy
|
||||
|
||||
/* Copy data */
|
||||
LA r3, bsp_section_data_begin
|
||||
LA r4, bsp_section_data_load_begin
|
||||
LA r5, bsp_section_data_size
|
||||
bl .Lcopy
|
||||
|
||||
/* NULL pointer access protection (only core 0 has to do this) */
|
||||
mfspr r3, BOOKE_PIR
|
||||
cmpwi r3, 0
|
||||
bne .Lnull_area_setup_done
|
||||
LA r3, bsp_section_start_begin
|
||||
srawi r3, r3, 2
|
||||
mtctr r3
|
||||
li r3, -4
|
||||
LWI r4, 0x44000002
|
||||
.Lnull_area_setup_loop:
|
||||
stwu r4, 4(r3)
|
||||
bdnz .Lnull_area_setup_loop
|
||||
.Lnull_area_setup_done:
|
||||
|
||||
li r3, 1
|
||||
bl .Linitmmu
|
||||
|
||||
/* Clear SBSS */
|
||||
LA r3, bsp_section_sbss_begin
|
||||
LA r4, bsp_section_sbss_size
|
||||
bl bsp_start_zero
|
||||
PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
|
||||
/* Clear BSS */
|
||||
LA r3, bsp_section_bss_begin
|
||||
LA r4, bsp_section_bss_size
|
||||
bl bsp_start_zero
|
||||
PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
|
||||
#ifndef __powerpc64__
|
||||
/* Set up EABI and SYSV environment */
|
||||
bl __eabi
|
||||
#endif
|
||||
|
||||
/* Clear command line */
|
||||
li r3, 0
|
||||
|
||||
bl boot_card
|
||||
PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
|
||||
.Lcopy:
|
||||
PPC_REG_CMP r3, r4
|
||||
beqlr
|
||||
b memcpy
|
||||
PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
|
||||
.Linitearly:
|
||||
#ifdef __powerpc64__
|
||||
/* Enable 64-bit computation mode for exceptions */
|
||||
mfspr r0, BOOKE_EPCR
|
||||
oris r0, r0, BOOKE_EPCR_ICM >> 16
|
||||
mtspr BOOKE_EPCR, r0
|
||||
|
||||
/* Enable 64-bit computation mode */
|
||||
mfmsr r0
|
||||
oris r0, r0, MSR_CM >> 16
|
||||
mtmsr r0
|
||||
isync
|
||||
#endif
|
||||
|
||||
/* Disable decrementer */
|
||||
mfspr r0, BOOKE_TCR
|
||||
LWI r4, BOOKE_TCR_DIE
|
||||
andc r0, r0, r4
|
||||
mtspr BOOKE_TCR, r0
|
||||
|
||||
#ifdef QORIQ_INITIAL_SPEFSCR
|
||||
/* SPEFSCR initialization */
|
||||
LWI r0, QORIQ_INITIAL_SPEFSCR
|
||||
mtspr FSL_EIS_SPEFSCR, r0
|
||||
#endif
|
||||
|
||||
#ifdef QORIQ_INITIAL_BUCSR
|
||||
/* BUCSR initialization */
|
||||
LWI r0, QORIQ_INITIAL_BUCSR
|
||||
mtspr FSL_EIS_BUCSR, r0
|
||||
isync
|
||||
#endif
|
||||
|
||||
#if defined(QORIQ_INITIAL_HID0) && !defined(QORIQ_IS_HYPERVISOR_GUEST)
|
||||
/* HID0 initialization */
|
||||
LWI r0, QORIQ_INITIAL_HID0
|
||||
mtspr HID0, r0
|
||||
#endif
|
||||
|
||||
#ifdef __powerpc64__
|
||||
LA32 r2, .TOC.
|
||||
#else
|
||||
/* Invalidate TLS anchor */
|
||||
li r2, 0
|
||||
|
||||
/* Set small-data anchor */
|
||||
LA r13, _SDA_BASE_
|
||||
#endif
|
||||
|
||||
SET_SELF_CPU_CONTROL r4, r5
|
||||
|
||||
blr
|
||||
|
||||
.Linitmore:
|
||||
mflr SAVED_LINK_REGISTER
|
||||
|
||||
/* Invalidate all TS1 MMU entries */
|
||||
li r3, 1
|
||||
bl qoriq_tlb1_invalidate_all_by_ts
|
||||
PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
|
||||
/* Add TS1 entry for the first 4GiB of RAM */
|
||||
li r3, SCRATCH_TLB
|
||||
li r4, FSL_EIS_MAS1_TS
|
||||
li r5, FSL_EIS_MAS2_M
|
||||
li r6, FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW | FSL_EIS_MAS3_SX
|
||||
li r7, 0
|
||||
li r8, 0
|
||||
li r9, 11
|
||||
bl qoriq_tlb1_write
|
||||
PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
|
||||
/* MSR initialization and use TS1 for address translation */
|
||||
LWI INITIAL_MSR, QORIQ_INITIAL_MSR
|
||||
ori r0, INITIAL_MSR, MSR_IS | MSR_DS
|
||||
#ifdef QORIQ_IS_HYPERVISOR_GUEST
|
||||
oris r0, r0, MSR_GS >> 16
|
||||
#endif
|
||||
mtmsr r0
|
||||
isync
|
||||
|
||||
/*
|
||||
* Initialize start stack. Make sure that we do not share a cache line
|
||||
* with the heap block management, since initial stacks for the
|
||||
* secondary processors are allocated from the workspace.
|
||||
*/
|
||||
subi r1, START_STACK, 2 * PPC_DEFAULT_CACHE_LINE_SIZE
|
||||
clrrwi r1, r1, PPC_DEFAULT_CACHE_LINE_POWER
|
||||
li r0, 0
|
||||
PPC_REG_STORE r0, 0(r1)
|
||||
|
||||
#ifdef INITIALIZE_FPU
|
||||
bl .Linitfpu
|
||||
#endif
|
||||
|
||||
mtlr SAVED_LINK_REGISTER
|
||||
blr
|
||||
|
||||
.Linitmmu:
|
||||
mflr SAVED_LINK_REGISTER
|
||||
|
||||
/* Configure MMU */
|
||||
li r4, FIRST_TLB
|
||||
li r5, SCRATCH_TLB
|
||||
bl qoriq_mmu_config
|
||||
PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
mtmsr INITIAL_MSR
|
||||
isync
|
||||
li r3, SCRATCH_TLB
|
||||
bl qoriq_tlb1_invalidate
|
||||
PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
|
||||
mtlr SAVED_LINK_REGISTER
|
||||
blr
|
||||
|
||||
#ifdef INITIALIZE_FPU
|
||||
/*
|
||||
* Write a value to the FPRs to initialize the hidden tag bits. See
|
||||
* also "Core Software Initialization Requirements" of the e500mc
|
||||
* reference manual for example.
|
||||
*/
|
||||
.Linitfpu:
|
||||
li r0, 0
|
||||
stw r0, 0(r1)
|
||||
stw r0, 4(r1)
|
||||
lfd f0, 0(r1)
|
||||
fmr f1, f0
|
||||
fmr f2, f0
|
||||
fmr f3, f0
|
||||
fmr f4, f0
|
||||
fmr f5, f0
|
||||
fmr f6, f0
|
||||
fmr f7, f0
|
||||
fmr f8, f0
|
||||
fmr f9, f0
|
||||
fmr f10, f0
|
||||
fmr f11, f0
|
||||
fmr f12, f0
|
||||
fmr f13, f0
|
||||
fmr f14, f0
|
||||
fmr f15, f0
|
||||
fmr f16, f0
|
||||
fmr f17, f0
|
||||
fmr f18, f0
|
||||
fmr f19, f0
|
||||
fmr f20, f0
|
||||
fmr f21, f0
|
||||
fmr f22, f0
|
||||
fmr f23, f0
|
||||
fmr f24, f0
|
||||
fmr f25, f0
|
||||
fmr f26, f0
|
||||
fmr f27, f0
|
||||
fmr f28, f0
|
||||
fmr f29, f0
|
||||
fmr f30, f0
|
||||
fmr f31, f0
|
||||
blr
|
||||
#endif
|
||||
|
||||
#ifdef RTEMS_SMP
|
||||
#if QORIQ_THREAD_COUNT > 1
|
||||
_start_thread:
|
||||
/* Adjust PIR */
|
||||
mfspr r0, BOOKE_PIR
|
||||
srawi r0, r0, 2
|
||||
ori r0, r0, 1
|
||||
mtspr BOOKE_PIR, r0
|
||||
|
||||
bl .Linitearly
|
||||
|
||||
/* Initialize start stack */
|
||||
GET_SELF_CPU_CONTROL r3
|
||||
PPC_REG_LOAD r3, PER_CPU_INTERRUPT_STACK_HIGH(r3)
|
||||
subi r1, r3, PPC_MINIMUM_STACK_FRAME_SIZE
|
||||
clrrwi r1, r1, PPC_STACK_ALIGN_POWER
|
||||
li r0, 0
|
||||
PPC_REG_STORE r0, 0(r1)
|
||||
|
||||
#ifdef INITIALIZE_FPU
|
||||
bl .Linitfpu
|
||||
#endif
|
||||
|
||||
b qoriq_start_thread
|
||||
PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
#endif
|
||||
_start_secondary_processor:
|
||||
bl .Linitearly
|
||||
|
||||
/* Get start stack */
|
||||
mr START_STACK, r3
|
||||
|
||||
bl .Linitmore
|
||||
li r3, 0
|
||||
bl .Linitmmu
|
||||
b bsp_start_on_secondary_processor
|
||||
PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
#endif /* RTEMS_SMP */
|
||||
|
||||
#ifdef __powerpc64__
|
||||
#define START_NOP_FOR_LINKER_TOC_POINTER_RESTORE nop; nop; nop; nop
|
||||
#else
|
||||
#define START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
#endif
|
||||
|
||||
/* Exception vector prologues area */
|
||||
.section ".bsp_start_text", "ax"
|
||||
.align 4
|
||||
bsp_exc_vector_base:
|
||||
/* Critical input */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 0
|
||||
b ppc_exc_fatal_critical
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* Machine check */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 1
|
||||
b ppc_exc_fatal_machine_check
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* Data storage */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 2
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* Instruction storage */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 3
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* External input */
|
||||
PPC_REG_STORE_UPDATE r1, -PPC_EXC_INTERRUPT_FRAME_SIZE(r1)
|
||||
PPC_REG_STORE r3, PPC_EXC_GPR3_PROLOGUE_OFFSET(r1)
|
||||
li r3, 4
|
||||
b ppc_exc_interrupt
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* Alignment */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 5
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* Program */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 6
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
#ifdef __PPC_CPU_E6500__
|
||||
/* Floating-point unavailable */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 7
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
#endif
|
||||
/* System call */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 8
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
#ifdef __PPC_CPU_E6500__
|
||||
/* APU unavailable */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 9
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
#endif
|
||||
/* Decrementer */
|
||||
#ifdef QORIQ_IS_HYPERVISOR_GUEST
|
||||
PPC_REG_STORE_UPDATE r1, -PPC_EXC_INTERRUPT_FRAME_SIZE(r1)
|
||||
PPC_REG_STORE r3, PPC_EXC_GPR3_PROLOGUE_OFFSET(r1)
|
||||
li r3, 10
|
||||
b ppc_exc_interrupt
|
||||
#else
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 10
|
||||
b ppc_exc_fatal_normal
|
||||
#endif
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* Fixed-interval timer interrupt */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 11
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* Watchdog timer interrupt */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 12
|
||||
b ppc_exc_fatal_critical
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* Data TLB error */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 13
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* Instruction TLB error */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 14
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* Debug */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 15
|
||||
b ppc_exc_fatal_debug
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* SPE APU unavailable or AltiVec unavailable */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 32
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* SPE floating-point data exception or AltiVec assist */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 33
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
#ifndef __PPC_CPU_E6500__
|
||||
/* SPE floating-point round exception */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 34
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
#endif
|
||||
/* Performance monitor */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 35
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
#ifdef __PPC_CPU_E6500__
|
||||
/* Processor doorbell interrupt */
|
||||
#if defined(QORIQ_IS_HYPERVISOR_GUEST) && defined(RTEMS_SMP)
|
||||
PPC_REG_STORE_UPDATE r1, -PPC_EXC_INTERRUPT_FRAME_SIZE(r1)
|
||||
PPC_REG_STORE r3, PPC_EXC_GPR3_PROLOGUE_OFFSET(r1)
|
||||
li r3, 36
|
||||
b ppc_exc_interrupt
|
||||
#else
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 36
|
||||
b ppc_exc_fatal_normal
|
||||
#endif
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* Processor doorbell critical interrupt */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 37
|
||||
b ppc_exc_fatal_critical
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* Guest processor doorbell */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 38
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* Guest processor doorbell critical and machine check */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 39
|
||||
b ppc_exc_fatal_critical
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* Hypervisor system call */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 40
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* Hypervisor privilege */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 41
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
/* LRAT error */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 42
|
||||
b ppc_exc_fatal_normal
|
||||
START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
|
||||
#endif
|
||||
|
||||
/* Symbol provided for debugging and tracing */
|
||||
bsp_exc_vector_end:
|
||||
|
||||
/* Start stack area */
|
||||
.section ".bsp_rwextra", "aw", @nobits
|
||||
.align 4
|
||||
.space 4096
|
||||
start_stack_end:
|
||||
278
bsps/powerpc/shared/start/preload.S
Normal file
278
bsps/powerpc/shared/start/preload.S
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Mini-loader for the SVGM BSP.
|
||||
*
|
||||
* Author: Till Straumann, 10/2001 <strauman@slac.stanford.edu>
|
||||
*
|
||||
* Some ideas are borrowed from the powerpc/shared/bootloader
|
||||
* by
|
||||
* Copyright (C) 1998, 1999 Gabriel Paubert, paubert@iram.es
|
||||
* Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
|
||||
*
|
||||
* The SMON firmware is unable to load the RTEMS image below
|
||||
* 0x2000 (I believe their stack is growing below 0x1000).
|
||||
*
|
||||
* The code provided by this file is responsible for the performing
|
||||
* the following steps:
|
||||
*
|
||||
* 1) Save commandline parameters to an area that is
|
||||
* a) not covered by the downloaded image
|
||||
* b) will not be overwritten by the moved image
|
||||
* nor the final BSS segment (rtems clears BSS
|
||||
* before saving the command line).
|
||||
* 2) Move the entire image (including this very file) to
|
||||
* its final location starting at 0x0000.
|
||||
* It is important to note that _NO_STACK_ is available
|
||||
* during this step. Also, there is probably no return to
|
||||
* SMON because relocating RTEMS will destroy vital SMON
|
||||
* data (such as its stack).
|
||||
* 3) Flush the cache to make sure the relocated image is actually
|
||||
* in memory.
|
||||
* 4) setup RTEMS environment (initial register values), most
|
||||
* notably an initial STACK. The initial stack may be small and
|
||||
* is used by RTEMS only at a very early stage.
|
||||
* A safe place for the stack seems to be the 00..0x7f area.
|
||||
* NOTE: we should respect the MAILBOX area 0x80..0xff!
|
||||
* 5) switch the MMU off (because that's what RTEMS is expecting
|
||||
* it to be at startup).
|
||||
* 6) fire up rtems...
|
||||
*
|
||||
*
|
||||
* Calling convention:
|
||||
* R1: SMON SP
|
||||
* R3: command line string start
|
||||
* R4: command line string end + 1
|
||||
* R5: where SMON put the image
|
||||
* if R5 is 0, the preloader will use its entry point
|
||||
* as the image starting address.
|
||||
* See NOTE below.
|
||||
* R6: end of the image (i.e. R6-R5 is the image length)
|
||||
* if R6 is 0, _edata will be used as the image length
|
||||
* See NOTE below.
|
||||
*
|
||||
* NOTE: if the symbol DONT_USE_R5_ENTRY is defined,
|
||||
* R5/R6 are never used and the necessary parameters are
|
||||
* determined at runtime (R5) / linkage (R6) [_edata]
|
||||
*
|
||||
* ASSUMPTIONS:
|
||||
* The code RELIES on the assumption that the image will be
|
||||
* moved DOWNWARDS in memory and that the this loader is
|
||||
* prepended to the image, i.e. it is safe to do
|
||||
* codemove(codemove,0,codemove_end - codemove);
|
||||
* (*0)(codemove_end, codemove_end-codemove, __rtems_end-codemove_end);
|
||||
* where codemove(from, to, nbytes) is defined as
|
||||
* codemove(from, to, nbytes) { while (nbytes--) *(to++)=*(from++); }
|
||||
* Implicit to these assumptions is the assumption that the destination
|
||||
* address is cache block aligned.
|
||||
* Furthermore, the byte count is assumed to be a multiple
|
||||
* of four
|
||||
*
|
||||
*/
|
||||
#if 0
|
||||
#include <rtems/score/powerpc.h>
|
||||
#else
|
||||
#ifndef PPC_CACHE_ALIGNMENT
|
||||
#define PPC_CACHE_ALIGNMENT 32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <rtems/score/cpu.h>
|
||||
#include <rtems/asm.h>
|
||||
|
||||
/* Note that major modifications may be needed
|
||||
* if DESTINATION_ADDR is not 0
|
||||
*/
|
||||
#define KERNELBASE 0x0
|
||||
#define INITIAL_STACK 0x70 /* 16-byte aligned */
|
||||
#define CACHE_LINE_SIZE PPC_CACHE_ALIGNMENT /* autodetect doesn't work, see below */
|
||||
#define ASSUME_RTEMS_INSTALLS_VECTORS /* assume we need not load vectors */
|
||||
#define DONT_USE_R5_ENTRY /* always dynamically determine the address we're running from */
|
||||
|
||||
/* put this into its own section which we want to
|
||||
* be loaded at the very beginning. We should probably
|
||||
* not use more than 255 bytes.
|
||||
*/
|
||||
PUBLIC_VAR(__rtems_start)
|
||||
PUBLIC_VAR(__rtems_entry_point)
|
||||
PUBLIC_VAR(__rtems_end)
|
||||
.section .entry_point_section,"awx",@progbits
|
||||
preload:
|
||||
/* find out where we are */
|
||||
bl here
|
||||
here:
|
||||
xor r0,r0,r0
|
||||
mtmsr r0 /* clear MSR to known state */
|
||||
mflr r5
|
||||
addi r5,r5,-(here-preload)
|
||||
lis r27,_edata@h
|
||||
ori r27,r27,_edata@l
|
||||
|
||||
/* at this point the register contents are
|
||||
* R3: command line start
|
||||
* R4: R3 + command line length
|
||||
* R5: address we are running from / loaded to
|
||||
* R27: image end
|
||||
*/
|
||||
|
||||
/* save command line start */
|
||||
mr r6, r3
|
||||
/* save the command line parameters if they are to be overwritten */
|
||||
sub. r17, r4, r3 /* string length */
|
||||
ble leaveparms /* <=0 -> no parameters */
|
||||
/* copy has to be out of the way of the bss; therefore we must
|
||||
* put the string out of the way of both, the current end of
|
||||
* the image (without bss) AND the end of the loaded image
|
||||
* (including bss):
|
||||
* |......image.........| downloaded image
|
||||
* |image_bss...........| loaded image with bss appended
|
||||
*
|
||||
* ^ safe place for string
|
||||
*
|
||||
* the alternative scenario looks like this:
|
||||
* |..image.............| downloaded image
|
||||
* |image_bss...........| loaded image with bss appended
|
||||
* ^ safe place for string
|
||||
*/
|
||||
lis r18, __rtems_end+0x10000@h /* round up, save one instruction */
|
||||
add r16, r5, r27 /* image end + 1 */
|
||||
cmpw r16, r18
|
||||
bge ishighenough
|
||||
mr r16,r18 /* __rtems_end is higher than the image end
|
||||
* (without bss)
|
||||
*/
|
||||
ishighenough:
|
||||
cmpw r16, r3 /* destination start > current string start ? */
|
||||
ble leaveparms /* string already after dst, leave it */
|
||||
/* copy string from the last byte downwards */
|
||||
add r6, r16, r17 /* last byte of destination + 1 */
|
||||
mtctr r17
|
||||
1:
|
||||
lbzu r3, -1(r4)
|
||||
stbu r3, -1(r6)
|
||||
bdnz 1b
|
||||
leaveparms:
|
||||
add r7, r6, r17 /* destination + strlen */
|
||||
|
||||
#ifndef CACHE_LINE_SIZE
|
||||
/* Oh well, SMON has inhibited the cache, so this
|
||||
* nice routine doesn't work...
|
||||
*/
|
||||
/* figure out the cache line size */
|
||||
li r16, 0x80
|
||||
cmpw r5, r16 /* 'from' must be > 0x80 */
|
||||
blt panic
|
||||
|
||||
1: /* store some arbitrary, nonzero stuff in 0..0x7c */
|
||||
stwu r16,-4(r16)
|
||||
cmpwi r16,0
|
||||
bne 1b
|
||||
dcbz 0,r16 /* zero out one cache line */
|
||||
subi r16,r16,4
|
||||
2: lwzu r0,4(r16) /* search for a non-zero word */
|
||||
cmpwi r0,0
|
||||
beq 2b
|
||||
/* OK, r16 now hold the size of a cache line in bytes */
|
||||
#else
|
||||
li r16,CACHE_LINE_SIZE
|
||||
#endif
|
||||
|
||||
lis r3,preload@h
|
||||
ori r3,r3,preload@l
|
||||
mr r4,r5 /* from-addr */
|
||||
li r5,_preload_size/* this is never > 16k */
|
||||
/* now move ourselves to the link address ('preload').
|
||||
* We set up the LR, so domove() 'returns' to the
|
||||
* relocated copy
|
||||
*/
|
||||
lis r0,return_here@h
|
||||
ori r0,r0,return_here@l
|
||||
mtlr r0
|
||||
b domove /* move the preloader itself */
|
||||
return_here:
|
||||
/* now we move the entire rest of the image */
|
||||
#ifdef ASSUME_RTEMS_INSTALLS_VECTORS
|
||||
lis r3,__rtems_start@h
|
||||
ori r3,r3,__rtems_start@l
|
||||
lis r0,preload@h /* calculate/adjust from address */
|
||||
ori r0,r0,preload@l
|
||||
sub r0,r3,r0
|
||||
add r4,r4,r0
|
||||
sub r5,r27,r3
|
||||
#else
|
||||
add r3,r3,r5 /* add preloader size to destination */
|
||||
add r4,r4,r5 /* and source addresses */
|
||||
sub r5,r27,r5 /* length of the remaining rest */
|
||||
#endif
|
||||
bl domove
|
||||
/* OK, now everything should be in place.
|
||||
* we are ready to start...
|
||||
*/
|
||||
|
||||
/* setup initial stack for rtems early boot */
|
||||
li r1,INITIAL_STACK
|
||||
/* tag TOS with a NULL pointer (for stack trace) */
|
||||
li r0, 0
|
||||
stw r0, 0(r1)
|
||||
/* disable the MMU and fire up rtems */
|
||||
mfmsr r0
|
||||
ori r0,r0,MSR_IR|MSR_DR|MSR_IP|MSR_ME
|
||||
xori r0,r0,MSR_IR|MSR_DR
|
||||
mtsrr1 r0
|
||||
lis r0,__rtems_entry_point@h
|
||||
ori r0,r0,__rtems_entry_point@l
|
||||
mtsrr0 r0
|
||||
/* R6: start of command line */
|
||||
/* R7: end of command line +1 */
|
||||
rfi
|
||||
|
||||
/* domove(to, from, nbytes):
|
||||
*
|
||||
* move a R5 bytes from R4 to R3 and flush
|
||||
* the caches for the destination memory
|
||||
* region. R16 provides the cache line size.
|
||||
* DESTROYS: R0, R17, R18, CTR, CR
|
||||
*/
|
||||
domove:
|
||||
addi r0,r5,3 /* convert to word count */
|
||||
srwi. r0,r0,2
|
||||
beq 3f /* nothing to do */
|
||||
cmpw r3,r4 /* from == to ? */
|
||||
beq 3f
|
||||
mtctr r0
|
||||
la r18,-4(r4)
|
||||
la r17,-4(r3)
|
||||
1: lwzu r0,4(r18)
|
||||
stwu r0,4(r17)
|
||||
bdnz 1b /* move data */
|
||||
/* now, we must flush the destination cache region */
|
||||
#ifndef CACHE_LINE_SIZE
|
||||
cmpwi r16,0
|
||||
beq 3f /* nothing to do */
|
||||
#endif
|
||||
#if defined(CACHE_LINE_SIZE) && CACHE_LINE_SIZE > 0
|
||||
add r17,r3,r5 /* target end pointer */
|
||||
subi r0,r16,1
|
||||
add r17,r17,r0
|
||||
andc r17,r17,r0 /* cache aligned target end pointer */
|
||||
mr r18,r3
|
||||
2: cmpw r18,r17
|
||||
dcbst 0,r18 /* write out data cache line */
|
||||
icbi 0,r18 /* invalidate corresponding i-cache line */
|
||||
add r18,r18,r16
|
||||
blt 2b
|
||||
sync /* make sure data is written back */
|
||||
isync /* invalidate possibly preloaded instructions */
|
||||
#endif
|
||||
3:
|
||||
blr
|
||||
|
||||
#if !defined(CACHE_LINE_SIZE)
|
||||
panic:
|
||||
li r10,0x63
|
||||
mfmsr r0
|
||||
ori r0,r0,MSR_IP
|
||||
mtmsr r0
|
||||
sc
|
||||
#endif
|
||||
|
||||
/* DONT PUT ANY CODE BELOW HERE */
|
||||
_preload_size = . - preload
|
||||
68
bsps/powerpc/shared/start/rtems_crti.S
Normal file
68
bsps/powerpc/shared/start/rtems_crti.S
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2017 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* rtems_crti.S */
|
||||
#include <rtems/asm.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
|
||||
#if defined(__powerpc64__)
|
||||
.section ".init","ax"
|
||||
.align 2
|
||||
.globl _init
|
||||
.type _init,@function
|
||||
_init:
|
||||
mflr r0
|
||||
std r0,16(1)
|
||||
stdu r1,-96(1)
|
||||
|
||||
.section ".fini","ax"
|
||||
.align 2
|
||||
.globl _fini
|
||||
.type _fini,@function
|
||||
_fini:
|
||||
mflr r0
|
||||
std r0,16(r1)
|
||||
stdu r1,-96(r1)
|
||||
#else
|
||||
/* terminate the __init() function and create
|
||||
* a new head '_init' for use by RTEMS to
|
||||
* invoke C++ global constructors
|
||||
* NOTE: it is essential that this snippet
|
||||
* is hooked between ecrti and crtbegin
|
||||
*
|
||||
* ecrti has the following .init section:
|
||||
* __init:
|
||||
* stwu r1,-16(r1)
|
||||
* mflr r0
|
||||
* stw r0,20(r1)
|
||||
*
|
||||
* The reason for this is that we want to call
|
||||
* __eabi() at an early stage but prevent __eabi()
|
||||
* from branching to __init (C++ exception init
|
||||
* and global CTORs). Hence we make __init a no-op
|
||||
* and create a new entry point:
|
||||
*/
|
||||
.section ".init","ax"
|
||||
.align 2
|
||||
lwz r0,r20(r1)
|
||||
mtlr r0
|
||||
addi r1,r1,16
|
||||
blr
|
||||
.globl _init
|
||||
.type _init,@function
|
||||
_init:
|
||||
stwu r1,-16(r1)
|
||||
mflr r0
|
||||
stw r0,20(r1)
|
||||
#endif
|
||||
27
bsps/powerpc/shared/start/rtems_crtn.S
Normal file
27
bsps/powerpc/shared/start/rtems_crtn.S
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2017 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(__powerpc64__)
|
||||
.section ".init","ax"
|
||||
addi 1,1,96
|
||||
ld 0,16(1)
|
||||
mtlr 0
|
||||
blr
|
||||
|
||||
.section ".fini","ax"
|
||||
addi 1,1,96
|
||||
ld 0,16(1)
|
||||
mtlr 0
|
||||
blr
|
||||
#endif
|
||||
207
bsps/powerpc/shared/start/start.S
Normal file
207
bsps/powerpc/shared/start/start.S
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* start.S : RTEMS entry point
|
||||
*
|
||||
* Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <rtems/asm.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
#include <rtems/powerpc/powerpc.h>
|
||||
|
||||
#include <libcpu/io.h>
|
||||
#include <libcpu/bat.h>
|
||||
#include <bspopts.h>
|
||||
|
||||
#define SYNC \
|
||||
sync; \
|
||||
isync
|
||||
|
||||
#define KERNELBASE 0x0
|
||||
|
||||
#define MONITOR_ENTER \
|
||||
mfmsr r10 ; \
|
||||
ori r10,r10,MSR_IP ; \
|
||||
mtmsr r10 ; \
|
||||
li r10,0x63 ; \
|
||||
sc
|
||||
|
||||
.text
|
||||
.globl __rtems_entry_point
|
||||
.type __rtems_entry_point,@function
|
||||
__rtems_entry_point:
|
||||
#ifdef DEBUG_EARLY_START
|
||||
MONITOR_ENTER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PREP
|
||||
* This is jumped to on prep systems right after the kernel is relocated
|
||||
* to its proper place in memory by the boot loader. The expected layout
|
||||
* of the regs is:
|
||||
* r3: ptr to residual data
|
||||
* r4: initrd_start or if no initrd then 0
|
||||
* r5: initrd_end - unused if r4 is 0
|
||||
* r6: Start of command line string
|
||||
* r7: End of command line string
|
||||
*
|
||||
* The Prep boot loader insure that the MMU is currently off...
|
||||
*
|
||||
*/
|
||||
|
||||
mr r31,r3 /* save parameters */
|
||||
mr r30,r4
|
||||
mr r29,r5
|
||||
mr r28,r6
|
||||
mr r27,r7
|
||||
|
||||
#ifdef __ALTIVEC__
|
||||
/* enable altivec; gcc may use it! */
|
||||
mfmsr r0
|
||||
oris r0, r0, (1<<(31-16-6))
|
||||
mtmsr r0
|
||||
isync
|
||||
/*
|
||||
* set vscr and vrsave to known values
|
||||
*/
|
||||
li r0, 0
|
||||
mtvrsave r0
|
||||
vxor 0,0,0
|
||||
mtvscr 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make sure we have nothing in BATS and TLB
|
||||
*/
|
||||
bl CPU_clear_bats_early
|
||||
bl flush_tlbs
|
||||
/*
|
||||
* Use the first pair of BAT registers to map the 1st 256MB
|
||||
* of RAM to KERNELBASE.
|
||||
*/
|
||||
lis r11,KERNELBASE@h
|
||||
/* set up BAT registers for 604 */
|
||||
ori r11,r11,0x1ffe
|
||||
li r8,2 /* R/W access */
|
||||
isync
|
||||
mtspr DBAT0L,r8 /* N.B. 6xx (not 601) have valid */
|
||||
mtspr DBAT0U,r11 /* bit in upper BAT register */
|
||||
mtspr IBAT0L,r8
|
||||
mtspr IBAT0U,r11
|
||||
isync
|
||||
/* Map section where residual is located if outside
|
||||
* the first 256Mb of RAM. This is to support cases
|
||||
* where the available system memory is larger than
|
||||
* 256Mb of RAM.
|
||||
*/
|
||||
mr r9, r1 /* Get where residual was mapped */
|
||||
lis r12,0xf0000000@h
|
||||
and r9,r9,r12
|
||||
cmpi 0,1,r9, 0
|
||||
beq enter_C_code
|
||||
isync
|
||||
ori r11,r9,0x1ffe
|
||||
mtspr DBAT1L,r8 /* N.B. 6xx (not 601) have valid */
|
||||
mtspr DBAT1U,r11 /* bit in upper BAT register */
|
||||
mtspr IBAT1L,r8
|
||||
mtspr IBAT1U,r11
|
||||
isync
|
||||
|
||||
/*
|
||||
* we now have the 1st 256M of ram mapped with the bats. We are still
|
||||
* running on the bootloader stack and cannot switch to an RTEMS allocated
|
||||
* init stack before copying the residual data that may have been set just after
|
||||
* rtems_end address. This bug has been experienced on MVME2304. Thank to
|
||||
* Till Straumann <strauman@SLAC.Stanford.EDU> for hunting it and suggesting
|
||||
* the appropriate code.
|
||||
*/
|
||||
|
||||
enter_C_code:
|
||||
bl MMUon
|
||||
bl __eabi /* setup EABI and SYSV environment */
|
||||
bl zero_bss
|
||||
/*
|
||||
* restore prep boot params
|
||||
*/
|
||||
mr r3,r31
|
||||
mr r4,r30
|
||||
mr r5,r29
|
||||
mr r6,r28
|
||||
mr r7,r27
|
||||
bl save_boot_params
|
||||
/*
|
||||
* stack = &__rtems_end + 4096
|
||||
*/
|
||||
addis r9,r0, __stack-PPC_MINIMUM_STACK_FRAME_SIZE@ha
|
||||
addi r9,r9, __stack-PPC_MINIMUM_STACK_FRAME_SIZE@l
|
||||
/*
|
||||
* align initial stack
|
||||
* (we hope that the bootloader stack was 16-byte aligned
|
||||
* or we haven't used altivec yet...)
|
||||
*/
|
||||
li r0, (CPU_STACK_ALIGNMENT-1)
|
||||
andc r1, r9, r0
|
||||
/*
|
||||
* Tag TOS with a NULL (terminator for stack dump)
|
||||
*/
|
||||
li r0, 0
|
||||
stw r0, 0(r1)
|
||||
|
||||
/*
|
||||
* We are now in a environment that is totally independent from
|
||||
* bootloader setup.
|
||||
*/
|
||||
/* pass result of 'save_boot_params' to 'boot_card' in R3 */
|
||||
bl boot_card
|
||||
bl _return_to_ppcbug
|
||||
|
||||
.globl MMUon
|
||||
.type MMUon,@function
|
||||
MMUon:
|
||||
mfmsr r0
|
||||
ori r0,r0, MSR_IP | MSR_RI | MSR_IR | MSR_DR | MSR_EE | MSR_FE0 | MSR_FE1 | MSR_FP
|
||||
#if (PPC_HAS_FPU == 0)
|
||||
xori r0, r0, MSR_EE | MSR_IP | MSR_FP
|
||||
#else
|
||||
xori r0, r0, MSR_EE | MSR_IP | MSR_FE0 | MSR_FE1
|
||||
#endif
|
||||
mflr r11
|
||||
mtsrr0 r11
|
||||
mtsrr1 r0
|
||||
SYNC
|
||||
rfi
|
||||
|
||||
.globl MMUoff
|
||||
.type MMUoff,@function
|
||||
MMUoff:
|
||||
mfmsr r0
|
||||
ori r0,r0,MSR_IR| MSR_DR | MSR_IP
|
||||
mflr r11
|
||||
xori r0,r0,MSR_IR|MSR_DR
|
||||
mtsrr0 r11
|
||||
mtsrr1 r0
|
||||
SYNC
|
||||
rfi
|
||||
|
||||
.globl _return_to_ppcbug
|
||||
.type _return_to_ppcbug,@function
|
||||
|
||||
_return_to_ppcbug:
|
||||
mflr r30
|
||||
bl MMUoff
|
||||
MONITOR_ENTER
|
||||
bl MMUon
|
||||
mtctr r30
|
||||
bctr
|
||||
|
||||
flush_tlbs:
|
||||
lis r20, 0x1000
|
||||
1: addic. r20, r20, -0x1000
|
||||
tlbie r20
|
||||
bgt 1b
|
||||
sync
|
||||
blr
|
||||
22
bsps/powerpc/shared/start/vectors_entry.S
Normal file
22
bsps/powerpc/shared/start/vectors_entry.S
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* (c) 2007, Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
|
||||
*
|
||||
*
|
||||
* This file contains the entry point vector needed by some bootloaders
|
||||
* derived from "vectors.S"
|
||||
*/
|
||||
|
||||
#include <rtems/asm.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
|
||||
PUBLIC_VAR (__rtems_start)
|
||||
.section .entry_point_section,"awx",@progbits
|
||||
/*
|
||||
* Entry point information used by bootloader code
|
||||
*/
|
||||
SYM (__rtems_start):
|
||||
.long __rtems_entry_point
|
||||
|
||||
/*
|
||||
* end of special Entry point section
|
||||
*/
|
||||
411
bsps/powerpc/ss555/start/start.S
Normal file
411
bsps/powerpc/ss555/start/start.S
Normal file
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
* This file contains the entry veneer for RTEMS programs on the Intec
|
||||
* SS555 board. It jumps to the BSP which is responsible for performing
|
||||
* all remaining initialization.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is based on several others:
|
||||
*
|
||||
* (1) start360.s from the gen68360 BSP by
|
||||
* W. Eric Norum (eric@skatter.usask.ca)
|
||||
* with the following copyright and license:
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1998.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may in
|
||||
* the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*
|
||||
* (2) start.s for the eth_comm port by
|
||||
* Jay Monkman (jmonkman@fracsa.com),
|
||||
* which itself is based on the
|
||||
*
|
||||
* (3) dlentry.s for the Papyrus BSP, written by:
|
||||
* Andrew Bray <andy@i-cubed.co.uk>
|
||||
* with the following copyright and license:
|
||||
*
|
||||
* COPYRIGHT (c) 1995 by i-cubed ltd.
|
||||
*
|
||||
* (4) start860.S for the MBX821/MBX860, written by:
|
||||
* Darlene A. Stewart <darlene.stewart@iit.nrc.ca>
|
||||
* Copyright (c) 1999, National Research Council of Canada
|
||||
*
|
||||
* To anyone who acknowledges that this file is provided "AS IS"
|
||||
* without any express or implied warranty:
|
||||
* permission to use, copy, modify, and distribute this file
|
||||
* for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice and this notice appears in all
|
||||
* copies, and that the name of i-cubed limited not be used in
|
||||
* advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
* i-cubed limited makes no representations about the suitability
|
||||
* of this software for any purpose.
|
||||
*
|
||||
* (5) Modifications (for MBX8xx) of respective RTEMS files:
|
||||
* Copyright (c) 1999, National Research Council of Canada
|
||||
*
|
||||
* SS555 port sponsored by Defence Research and Development Canada - Suffield
|
||||
* Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
|
||||
*/
|
||||
|
||||
#include <rtems/asm.h>
|
||||
#include <rtems/powerpc/registers.h>
|
||||
|
||||
#include <bsp.h>
|
||||
|
||||
/*
|
||||
* The initial stack is set to the top of the internal RAM.
|
||||
*
|
||||
* All the entry veneer has to do is to clear the .bss section and copy the
|
||||
* initializers into the .data section.
|
||||
*/
|
||||
|
||||
/*
|
||||
* GDB likes to have debugging information for the entry veneer.
|
||||
* Play compiler and provide some DWARF information.
|
||||
*
|
||||
* CHANGE TO SUIT YOUR SETUP!
|
||||
*/
|
||||
|
||||
.section .entry,"ax",@progbits
|
||||
.L_text_b:
|
||||
.L_LC1:
|
||||
.previous
|
||||
|
||||
.section .debug_sfnames
|
||||
.L_sfnames_b:
|
||||
.byte "rtems/c/src/lib/libbsp/powerpc/ss555/startup/"
|
||||
.byte 0
|
||||
.L_F0:
|
||||
.byte "start.S"
|
||||
.byte 0
|
||||
.previous
|
||||
|
||||
.section .line
|
||||
.L_line_b:
|
||||
.4byte .L_line_e-.L_line_b
|
||||
.4byte .L_text_b
|
||||
.L_LE1:
|
||||
.L_line_last:
|
||||
.4byte 0x0
|
||||
.2byte 0xffff
|
||||
.4byte .L_text_e-.L_text_b
|
||||
.L_line_e:
|
||||
.previous
|
||||
|
||||
.section .debug_srcinfo
|
||||
.L_srcinfo_b:
|
||||
.4byte .L_line_b
|
||||
.4byte .L_sfnames_b
|
||||
.4byte .L_text_b
|
||||
.4byte .L_text_e
|
||||
.4byte 0xffffffff
|
||||
.4byte .L_LE1-.L_line_b
|
||||
.4byte .L_F0-.L_sfnames_b
|
||||
.4byte .L_line_last-.L_line_b
|
||||
.4byte 0xffffffff
|
||||
.previous
|
||||
|
||||
.section .debug_pubnames
|
||||
.4byte .L_debug_b
|
||||
.4byte .L_P0
|
||||
.byte "start"
|
||||
.byte 0
|
||||
.4byte 0x0
|
||||
.byte 0
|
||||
.previous
|
||||
|
||||
.section .debug_aranges
|
||||
.4byte .L_debug_b
|
||||
.4byte .L_text_b
|
||||
.4byte .L_text_e-.L_text_b
|
||||
.4byte 0
|
||||
.4byte 0
|
||||
.4byte 0
|
||||
.4byte 0
|
||||
.4byte 0
|
||||
.4byte 0
|
||||
.4byte 0x0
|
||||
.4byte 0x0
|
||||
.previous
|
||||
|
||||
.section .debug
|
||||
.L_debug_b:
|
||||
.L_D1:
|
||||
.4byte .L_D1_e-.L_D1
|
||||
.2byte 0x11 /* TAG_compile_unit */
|
||||
.2byte 0x12 /* AT_sibling */
|
||||
.4byte .L_D2
|
||||
.2byte 0x38 /* AT_name */
|
||||
.byte "start.S"
|
||||
.byte 0
|
||||
.2byte 0x258 /* AT_producer */
|
||||
.byte "GAS 2.5.2"
|
||||
.byte 0
|
||||
.2byte 0x111 /* AT_low_pc */
|
||||
.4byte .L_text_b
|
||||
.2byte 0x121 /* AT_high_pc */
|
||||
.4byte .L_text_e
|
||||
.2byte 0x106 /* AT_stmt_list */
|
||||
.4byte .L_line_b
|
||||
.2byte 0x1b8 /* AT_comp_dir */
|
||||
.byte "rtems/c/src/lib/libbsp/powerpc/ss555/startup/"
|
||||
.byte 0
|
||||
.2byte 0x8006 /* AT_sf_names */
|
||||
.4byte .L_sfnames_b
|
||||
.2byte 0x8016 /* AT_src_info */
|
||||
.4byte .L_srcinfo_b
|
||||
.L_D1_e:
|
||||
.L_P0:
|
||||
.L_D3:
|
||||
.4byte .L_D3_e-.L_D3
|
||||
.2byte 0x6 /* TAG_global_subroutine */
|
||||
.2byte 0x12 /* AT_sibling */
|
||||
.4byte .L_D4
|
||||
.2byte 0x38 /* AT_name */
|
||||
.byte "start"
|
||||
.byte 0
|
||||
.2byte 0x278 /* AT_prototyped */
|
||||
.byte 0
|
||||
.2byte 0x111 /* AT_low_pc */
|
||||
.4byte .L_text_b
|
||||
.2byte 0x121 /* AT_high_pc */
|
||||
.4byte .L_text_e
|
||||
.2byte 0x8041 /* AT_body_begin */
|
||||
.4byte .L_text_b
|
||||
.2byte 0x8051 /* AT_body_end */
|
||||
.4byte .L_text_e
|
||||
.L_D3_e:
|
||||
|
||||
.L_D4:
|
||||
.4byte .L_D4_e-.L_D4
|
||||
.align 2
|
||||
.L_D4_e:
|
||||
.L_D2:
|
||||
.previous
|
||||
|
||||
/*
|
||||
* Tell C's eabi-ctor's that we have an atexit function,
|
||||
* and that it is to register __do_global_dtors.
|
||||
*/
|
||||
EXTERN_PROC(atexit)
|
||||
PUBLIC_VAR(__atexit)
|
||||
.section ".sdata","aw"
|
||||
.align 2
|
||||
SYM(__atexit):
|
||||
EXT_PROC_REF(atexit)@fixup
|
||||
.previous
|
||||
|
||||
.section ".fixup","aw"
|
||||
.align 2
|
||||
EXT_SYM_REF(__atexit)
|
||||
.previous
|
||||
|
||||
/* That should do it */
|
||||
|
||||
/*
|
||||
* Put the entry point in its own section. That way, we can guarantee
|
||||
* to put it first in the .text section in the linker script.
|
||||
*/
|
||||
.section .entry
|
||||
|
||||
PUBLIC_VAR (start)
|
||||
SYM(start):
|
||||
bl .startup /* or bl .spin */
|
||||
base_addr:
|
||||
|
||||
/*
|
||||
* Parameters from linker
|
||||
*/
|
||||
stack_top:
|
||||
.long initStackPtr
|
||||
|
||||
toc_pointer:
|
||||
.long __GOT_START__
|
||||
|
||||
bss_length:
|
||||
.long bss.size
|
||||
bss_addr:
|
||||
.long bss.start
|
||||
|
||||
data_length:
|
||||
.long data.size
|
||||
data_addr:
|
||||
.long data.start
|
||||
contents_addr:
|
||||
.long data.contents.start
|
||||
|
||||
PUBLIC_VAR (text_addr)
|
||||
text_addr:
|
||||
.long text.start
|
||||
|
||||
PUBLIC_VAR (text_length)
|
||||
text_length:
|
||||
.long text.size
|
||||
|
||||
/*
|
||||
* Spin, if necessary, to acquire control from debugger (CodeWarrior).
|
||||
*/
|
||||
spin:
|
||||
.long 0x0001
|
||||
.spin:
|
||||
lis r3, spin@ha
|
||||
lwz r3, spin@l(r3)
|
||||
cmpwi r3, 0x1
|
||||
beq .spin
|
||||
|
||||
/*
|
||||
* Initialization code
|
||||
*/
|
||||
.startup:
|
||||
/* Capture address of linker parameters. */
|
||||
mflr r3
|
||||
|
||||
/* Set initial stack pointer to end of internal RAM - 56. */
|
||||
lwz r1, stack_top-base_addr(r3)
|
||||
addi r1, r1, -56
|
||||
|
||||
/* Initialize essential registers. */
|
||||
bl initregs
|
||||
|
||||
/* Set TOC pointer */
|
||||
lwz r2, toc_pointer-base_addr(r3)
|
||||
|
||||
/* Initialize the memory mapped MPC555 registers (done in C). */
|
||||
EXTERN_PROC (_InitSS555)
|
||||
bl PROC (_InitSS555)
|
||||
|
||||
/* Clear the .bss section. */
|
||||
bl bssclr
|
||||
|
||||
/* Copy initializers into the .data section */
|
||||
bl datacopy
|
||||
|
||||
/* Enable floating point, since gcc sometimes uses the floating
|
||||
* point registers for data moves, even if the C source code doesn't
|
||||
* include floating point operations.
|
||||
*/
|
||||
mfmsr r0
|
||||
ori r0, r0, MSR_FP
|
||||
mtmsr r0
|
||||
|
||||
/* Start system. */
|
||||
li r3, 0 /* command line */
|
||||
EXTERN_PROC (boot_card)
|
||||
bl PROC (boot_card) /* call the first C routine */
|
||||
|
||||
/* We should never return from boot_card, but in case we do ... */
|
||||
/* The next instructions are dependent on your runtime environment. */
|
||||
|
||||
stop_here:
|
||||
b stop_here
|
||||
|
||||
/*
|
||||
* datacopy - copy initializers into .data section
|
||||
*/
|
||||
datacopy:
|
||||
lis r3, base_addr@ha /* point to linker data */
|
||||
addi r3, r3, base_addr@l
|
||||
|
||||
lwz r4, contents_addr-base_addr(r3) /* .data contents in ROM */
|
||||
lwz r5, data_addr-base_addr(r3) /* .data section in RAM */
|
||||
lwz r6, data_length-base_addr(r3) /* length of .data */
|
||||
|
||||
rlwinm. r6, r6, 30, 0x3FFFFFFF /* form length / 4 */
|
||||
beqlr /* no .data - return */
|
||||
|
||||
mtctr r6 /* set ctr reg */
|
||||
dc1:
|
||||
lwz r6, 0(r4) /* get word */
|
||||
stw r6, 0(r5) /* store word */
|
||||
addi r4, r4, 0x4 /* next source */
|
||||
addi r5, r5, 0x4 /* next target */
|
||||
bdnz dc1 /* dec counter and loop */
|
||||
|
||||
blr /* return */
|
||||
|
||||
/*
|
||||
* bssclr - zero out bss
|
||||
*/
|
||||
bssclr:
|
||||
lis r3, base_addr@ha /* point to linker data */
|
||||
addi r3, r3, base_addr@l
|
||||
|
||||
lwz r4, bss_addr-base_addr(r3) /* Start of bss */
|
||||
lwz r5, bss_length-base_addr(r3) /* Length of bss */
|
||||
|
||||
rlwinm. r5, r5, 30, 0x3FFFFFFF /* form length/4 */
|
||||
beqlr /* no bss - return */
|
||||
|
||||
mtctr r5 /* set ctr reg */
|
||||
li r5, 0x0000 /* r5 = 0 */
|
||||
clear_bss:
|
||||
stw r5, 0(r4) /* store r6 */
|
||||
addi r4, r4, 0x4 /* update r4 */
|
||||
bdnz clear_bss /* dec counter and loop */
|
||||
|
||||
blr /* return */
|
||||
|
||||
/*
|
||||
* initregs
|
||||
* Initialize the MSR and basic core PowerPC registers
|
||||
*
|
||||
* Register usage:
|
||||
* r0 - scratch
|
||||
*/
|
||||
initregs:
|
||||
/*
|
||||
* Set the processor for big-endian mode, exceptions vectored to
|
||||
* 0x000n_nnnn, no execution tracing, machine check exceptions
|
||||
* enabled, floating-point not available, supervisor priviledge
|
||||
* level, external interrupts disabled, power management disabled
|
||||
* (normal operation mode).
|
||||
*/
|
||||
li r0, 0x1000 /* MSR_ME */
|
||||
mtmsr r0 /* Context-synchronizing */
|
||||
isync
|
||||
|
||||
/*
|
||||
* Clear the exception handling registers.
|
||||
*/
|
||||
li r0, 0x0000
|
||||
mtdar r0
|
||||
mtspr sprg0, r0
|
||||
mtspr sprg1, r0
|
||||
mtspr sprg2, r0
|
||||
mtspr sprg3, r0
|
||||
mtspr srr0, r0
|
||||
mtspr srr1, r0
|
||||
|
||||
mr r6, r0
|
||||
mr r7, r0
|
||||
mr r8, r0
|
||||
mr r9, r0
|
||||
mr r10, r0
|
||||
mr r11, r0
|
||||
mr r12, r0
|
||||
mr r13, r0
|
||||
mr r14, r0
|
||||
mr r15, r0
|
||||
mr r16, r0
|
||||
mr r17, r0
|
||||
mr r18, r0
|
||||
mr r19, r0
|
||||
mr r20, r0
|
||||
mr r21, r0
|
||||
mr r22, r0
|
||||
mr r23, r0
|
||||
mr r24, r0
|
||||
mr r25, r0
|
||||
mr r26, r0
|
||||
mr r27, r0
|
||||
mr r28, r0
|
||||
mr r29, r0
|
||||
mr r30, r0
|
||||
mr r31, r0
|
||||
|
||||
blr /* return */
|
||||
|
||||
.L_text_e:
|
||||
203
bsps/powerpc/t32mppc/start/start.S
Normal file
203
bsps/powerpc/t32mppc/start/start.S
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2017 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <bspopts.h>
|
||||
|
||||
#include <rtems/score/percpu.h>
|
||||
#include <libcpu/powerpc-utility.h>
|
||||
#include <bsp/vectors.h>
|
||||
|
||||
.globl _start
|
||||
.globl bsp_exc_vector_base
|
||||
|
||||
.section ".bsp_start_text", "ax"
|
||||
|
||||
/* Primitive NULL pointer protection */
|
||||
.rept 1024
|
||||
sc
|
||||
.endr
|
||||
|
||||
_start:
|
||||
/* Enable time base */
|
||||
li r0, 0x4000
|
||||
mtspr HID0, r0
|
||||
|
||||
/* Initialize start stack */
|
||||
LWI r1, start_stack_end
|
||||
subi r1, r1, 16
|
||||
li r0, 0
|
||||
stw r0, 0(r1)
|
||||
|
||||
SET_SELF_CPU_CONTROL r3, r4
|
||||
|
||||
/* Copy fast text */
|
||||
LWI r3, bsp_section_fast_text_begin
|
||||
LWI r4, bsp_section_fast_text_load_begin
|
||||
LWI r5, bsp_section_fast_text_size
|
||||
bl copy
|
||||
|
||||
/* Copy read-only data */
|
||||
LWI r3, bsp_section_rodata_begin
|
||||
LWI r4, bsp_section_rodata_load_begin
|
||||
LWI r5, bsp_section_rodata_size
|
||||
bl copy
|
||||
|
||||
/* Copy fast data */
|
||||
LWI r3, bsp_section_fast_data_begin
|
||||
LWI r4, bsp_section_fast_data_load_begin
|
||||
LWI r5, bsp_section_fast_data_size
|
||||
bl copy
|
||||
|
||||
/* Copy data */
|
||||
LWI r3, bsp_section_data_begin
|
||||
LWI r4, bsp_section_data_load_begin
|
||||
LWI r5, bsp_section_data_size
|
||||
bl copy
|
||||
|
||||
/* Clear SBSS */
|
||||
LWI r3, bsp_section_sbss_begin
|
||||
LWI r4, bsp_section_sbss_size
|
||||
bl bsp_start_zero
|
||||
|
||||
/* Clear BSS */
|
||||
LWI r3, bsp_section_bss_begin
|
||||
LWI r4, bsp_section_bss_size
|
||||
bl bsp_start_zero
|
||||
|
||||
/* Set up EABI and SYSV environment */
|
||||
bl __eabi
|
||||
|
||||
/* Clear command line */
|
||||
li r3, 0
|
||||
|
||||
bl boot_card
|
||||
|
||||
twiddle:
|
||||
b twiddle
|
||||
|
||||
copy:
|
||||
cmpw r3, r4
|
||||
beqlr
|
||||
b memcpy
|
||||
|
||||
/* Exception vector prologues area */
|
||||
.section ".bsp_start_text", "ax"
|
||||
.align 4
|
||||
bsp_exc_vector_base:
|
||||
/* Critical input */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 0
|
||||
b ppc_exc_fatal_critical
|
||||
/* Machine check */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 1
|
||||
b ppc_exc_fatal_machine_check
|
||||
/* Data storage */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 2
|
||||
b ppc_exc_fatal_normal
|
||||
/* Instruction storage */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 3
|
||||
b ppc_exc_fatal_normal
|
||||
/* External input */
|
||||
PPC_REG_STORE_UPDATE r1, -PPC_EXC_INTERRUPT_FRAME_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 4
|
||||
b ppc_exc_interrupt
|
||||
/* Alignment */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 5
|
||||
b ppc_exc_fatal_normal
|
||||
/* Program */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 6
|
||||
b ppc_exc_fatal_normal
|
||||
/* Floating-point unavailable */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 7
|
||||
b ppc_exc_fatal_normal
|
||||
/* System call */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 8
|
||||
b ppc_exc_fatal_normal
|
||||
/* APU unavailable */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 9
|
||||
b ppc_exc_fatal_normal
|
||||
/* Decrementer */
|
||||
PPC_REG_STORE_UPDATE r1, -PPC_EXC_INTERRUPT_FRAME_SIZE(r1)
|
||||
PPC_REG_STORE r3, PPC_EXC_GPR3_PROLOGUE_OFFSET(r1)
|
||||
li r3, 10
|
||||
b ppc_exc_interrupt
|
||||
/* Fixed-interval timer interrupt */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 11
|
||||
b ppc_exc_fatal_normal
|
||||
/* Watchdog timer interrupt */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 12
|
||||
b ppc_exc_fatal_critical
|
||||
/* Data TLB error */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 13
|
||||
b ppc_exc_fatal_normal
|
||||
/* Instruction TLB error */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 14
|
||||
b ppc_exc_fatal_normal
|
||||
/* Debug */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 15
|
||||
b ppc_exc_fatal_debug
|
||||
/* SPE APU unavailable or AltiVec unavailable */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 32
|
||||
b ppc_exc_fatal_normal
|
||||
/* SPE floating-point data exception or AltiVec assist */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 33
|
||||
b ppc_exc_fatal_normal
|
||||
/* SPE floating-point round exception */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 34
|
||||
b ppc_exc_fatal_normal
|
||||
/* Performance monitor */
|
||||
PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1)
|
||||
PPC_REG_STORE r3, GPR3_OFFSET(r1)
|
||||
li r3, 35
|
||||
b ppc_exc_fatal_normal
|
||||
|
||||
/* Start stack area */
|
||||
.section ".bsp_rwextra", "aw", @nobits
|
||||
.align 4
|
||||
.space 4096
|
||||
start_stack_end:
|
||||
294
bsps/powerpc/tqm8xx/start/start.S
Normal file
294
bsps/powerpc/tqm8xx/start/start.S
Normal file
@@ -0,0 +1,294 @@
|
||||
/*===============================================================*\
|
||||
| Project: RTEMS generic TQM8xx BSP |
|
||||
+-----------------------------------------------------------------+
|
||||
| Copyright (c) 2008 |
|
||||
| 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 |
|
||||
| it is based on the gen83xx BSP |
|
||||
\*===============================================================*/
|
||||
|
||||
#include <libcpu/powerpc-utility.h>
|
||||
#include <rtems/powerpc/cache.h>
|
||||
#include <bsp.h>
|
||||
#include <mpc8xx.h>
|
||||
|
||||
.extern boot_card
|
||||
|
||||
PUBLIC_VAR (_start)
|
||||
PUBLIC_VAR (bsp_interrupt_stack_start)
|
||||
PUBLIC_VAR (bsp_interrupt_stack_end)
|
||||
|
||||
.section ".bsp_start_text", "ax"
|
||||
_start:
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
/*
|
||||
* init IMMR
|
||||
*/
|
||||
LA r30,m8xx
|
||||
mtspr immr,r30
|
||||
/*
|
||||
* determine current execution address offset
|
||||
*/
|
||||
bl start_1
|
||||
start_1:
|
||||
mflr r20
|
||||
LA r30,start_1
|
||||
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 text section in RAM */
|
||||
LA r29, bsp_section_text_begin
|
||||
/* get start address of text section in ROM (add reloc offset) */
|
||||
add r30, r20, r29
|
||||
/* get size of startup code */
|
||||
LA r28, end_reloc_startup
|
||||
LA r31, bsp_section_text_begin
|
||||
sub 28,r28,r31
|
||||
/* copy startup code from ROM to RAM location */
|
||||
bl copy_image
|
||||
|
||||
/*
|
||||
* 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:
|
||||
/*
|
||||
* ROM or relocatable startup: copy rest of code to SDRAM
|
||||
*/
|
||||
/* get start address of rest of code in RAM */
|
||||
LA r29, end_reloc_startup
|
||||
/* get start address of text section in ROM (add reloc offset) */
|
||||
add r30, r20, r29
|
||||
/* get size of rest of code */
|
||||
LA r28, bsp_section_text_begin
|
||||
LA r31, bsp_section_text_size
|
||||
add r28,r28,r31
|
||||
sub r28,r28,r29
|
||||
bl copy_image /* copy text section from ROM to RAM location */
|
||||
|
||||
/*
|
||||
* ROM or relocatable startup: copy data to SDRAM
|
||||
*/
|
||||
/* get start address of data section in RAM */
|
||||
LA r29, bsp_section_data_begin
|
||||
/* get start address of data section in ROM (add reloc offset) */
|
||||
add r30, r20, r29
|
||||
/* get size of RAM image */
|
||||
LA r28, bsp_section_data_size
|
||||
/* copy initialized data section from ROM to RAM location */
|
||||
bl copy_image
|
||||
|
||||
start_code_in_ram:
|
||||
|
||||
/*
|
||||
* ROM/RAM startup: clear bss in SDRAM
|
||||
*/
|
||||
LA r3, bsp_section_bss_begin /* get start address of bss section */
|
||||
LWI r4, bsp_section_bss_size /* get size of bss section */
|
||||
bl mpc8xx_zero_4 /* Clear the bss section */
|
||||
/*
|
||||
* call boot_card
|
||||
*/
|
||||
|
||||
/* Set stack pointer (common for RAM/ROM startup) */
|
||||
LA r1, bsp_section_text_begin
|
||||
addi r1, r1, -0x10 /* Set up stack pointer = beginning of text section - 0x10 */
|
||||
|
||||
/* Create NULL */
|
||||
li r0, 0
|
||||
|
||||
/* Return address */
|
||||
stw r0, 4(r1)
|
||||
|
||||
/* Back chain */
|
||||
stw r0, 0(r1)
|
||||
|
||||
/* Read-only small data */
|
||||
LA r2, _SDA2_BASE_
|
||||
|
||||
/* Read-write small data */
|
||||
LA r13, _SDA_BASE_
|
||||
|
||||
/*
|
||||
* init some CPU stuff
|
||||
*/
|
||||
bl SYM (_InitTQM8xx)
|
||||
|
||||
/* clear arguments and do further init. in C (common for RAM/ROM startup) */
|
||||
|
||||
/* Clear cmdline */
|
||||
xor r3, r3, r3
|
||||
|
||||
bl SYM (boot_card) /* Call the first C routine */
|
||||
|
||||
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_with_watchdog:
|
||||
addi r5,r5,16
|
||||
rlwinm. r5,r5,28,4,31
|
||||
mtctr r5
|
||||
|
||||
copy_loop:
|
||||
lwz r6,0(r3)
|
||||
lwz r7,4(r3)
|
||||
lwz r8,8(r3)
|
||||
lwz r9,12(r3)
|
||||
stw r6,0(r4)
|
||||
stw r7,4(r4)
|
||||
stw r8,8(r4)
|
||||
stw r9,12(r4)
|
||||
addi r3,r3,16
|
||||
addi r4,r4,16
|
||||
sth r28,14(r30)
|
||||
sth r29,14(r30)
|
||||
bdnz+ copy_loop
|
||||
blr
|
||||
|
||||
copy_image:
|
||||
/*
|
||||
* watchdog:
|
||||
* r26 = immr
|
||||
* r25 = watchdog magic 1
|
||||
* r24 = watchdog magic 2
|
||||
*/
|
||||
mfimmr r26
|
||||
rlwinm. r26,r26,0,0,15
|
||||
li r25,0x556c
|
||||
li r24,0xffffaa39
|
||||
|
||||
mr r27, r28 /* determine number of 4word chunks */
|
||||
srwi r28, r28, 4
|
||||
mtctr r28
|
||||
|
||||
slwi r28, r28, 4
|
||||
sub r27, r27, r28 /* determine residual bytes */
|
||||
copy_image_4word:
|
||||
lwz r20, 0(r30) /* fetch data */
|
||||
lwz r21, 4(r30)
|
||||
lwz r22, 8(r30)
|
||||
lwz r23,12(r30)
|
||||
stw r20, 0(r29) /* store data */
|
||||
stw r21, 4(r29)
|
||||
stw r22, 8(r29)
|
||||
stw r23,12(r29)
|
||||
|
||||
addi r30, r30, 0x10 /* increment source pointer */
|
||||
addi r29, r29, 0x10 /* increment destination pointer */
|
||||
/*
|
||||
* trigger watchdog
|
||||
*/
|
||||
sth r25,14(r26)
|
||||
sth r24,14(r26)
|
||||
|
||||
bdnz copy_image_4word /* 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 mpc8xx_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 mpc8xx_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 mpc8xx_zero_4_more
|
||||
mtctr r9
|
||||
|
||||
mpc8xx_zero_4_head:
|
||||
|
||||
stwx r0, r3, r5
|
||||
addi r5, r5, 4
|
||||
bdnz mpc8xx_zero_4_head
|
||||
|
||||
mpc8xx_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
|
||||
|
||||
mpc8xx_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 mpc8xx_zero_4_tail
|
||||
|
||||
/* Return */
|
||||
blr
|
||||
|
||||
end_reloc_startup:
|
||||
|
||||
/* Interrupt stack */
|
||||
.section ".bsp_rwextra", "aw", @nobits
|
||||
.align 4
|
||||
bsp_interrupt_stack_start:
|
||||
.space 32768
|
||||
bsp_interrupt_stack_end:
|
||||
116
bsps/powerpc/virtex/start/start.S
Normal file
116
bsps/powerpc/virtex/start/start.S
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2013 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <rtems/asm.h>
|
||||
|
||||
#include <bspopts.h>
|
||||
|
||||
#include <libcpu/powerpc-utility.h>
|
||||
|
||||
.globl _start
|
||||
.globl virtex_exc_vector_base
|
||||
|
||||
.section ".bsp_start_text", "ax"
|
||||
|
||||
virtex_exc_vector_base:
|
||||
|
||||
b _start
|
||||
|
||||
/* Critical Input 0x0100 */
|
||||
/* Machine Check 0x0200 */
|
||||
/* Data Storage 0x0300 */
|
||||
/* Instruction Storage 0x0400 */
|
||||
/* External 0x0500 */
|
||||
/* Alignment 0x0600 */
|
||||
/* Program 0x0700 */
|
||||
/* FPU Unavailable 0x0800 */
|
||||
/* System Call 0x0C00 */
|
||||
/* APU Unavailable 0x0F20 */
|
||||
/* Programmable-Interval Timer 0x1000 */
|
||||
/* Fixed-Interval Timer 0x1010 */
|
||||
/* Watchdog Timer 0x1020 */
|
||||
/* Data TLB Miss 0x1100 */
|
||||
/* Instruction TLB Miss 0x1200 */
|
||||
/* Debug 0x2000 */
|
||||
.rept 0x2000 / 4 - 1
|
||||
b twiddle
|
||||
.endr
|
||||
|
||||
/* Start stack area */
|
||||
.rept BSP_START_STACK_SIZE / 4
|
||||
b twiddle
|
||||
.endr
|
||||
|
||||
_start:
|
||||
|
||||
/* Reset time base */
|
||||
li r0, 0
|
||||
mtspr TBWU, r0
|
||||
mtspr TBWL, r0
|
||||
|
||||
/* Initialize start stack */
|
||||
LWI r1, _start
|
||||
stwu r0, -4(r1)
|
||||
stwu r0, -4(r1)
|
||||
|
||||
/* Copy fast text */
|
||||
LWI r3, bsp_section_fast_text_begin
|
||||
LWI r4, bsp_section_fast_text_load_begin
|
||||
LWI r5, bsp_section_fast_text_size
|
||||
bl copy
|
||||
|
||||
/* Copy fast data */
|
||||
LWI r3, bsp_section_fast_data_begin
|
||||
LWI r4, bsp_section_fast_data_load_begin
|
||||
LWI r5, bsp_section_fast_data_size
|
||||
bl copy
|
||||
|
||||
/* Clear SBSS */
|
||||
LWI r3, bsp_section_sbss_begin
|
||||
LWI r4, bsp_section_sbss_size
|
||||
bl bsp_start_zero
|
||||
|
||||
/* Clear BSS */
|
||||
LWI r3, bsp_section_bss_begin
|
||||
LWI r4, bsp_section_bss_size
|
||||
bl bsp_start_zero
|
||||
|
||||
/* Set up EABI and SYSV environment */
|
||||
bl __eabi
|
||||
|
||||
/* Clear command line */
|
||||
li r3, 0
|
||||
|
||||
bl boot_card
|
||||
|
||||
twiddle:
|
||||
|
||||
bl bsp_reset
|
||||
b twiddle
|
||||
|
||||
copy:
|
||||
|
||||
cmpw r3, r4
|
||||
beqlr
|
||||
b memcpy
|
||||
|
||||
/* Reset entry */
|
||||
.section ".virtex_reset", "ax"
|
||||
|
||||
jump_to_start:
|
||||
|
||||
LWI r3, _start
|
||||
mtctr r3
|
||||
bctr
|
||||
b jump_to_start
|
||||
330
bsps/powerpc/virtex4/start/start.S
Normal file
330
bsps/powerpc/virtex4/start/start.S
Normal file
@@ -0,0 +1,330 @@
|
||||
/*!@file start.S
|
||||
*
|
||||
* @brief Initialization code to set up the CPU and call boot_card()
|
||||
*
|
||||
* This "BSP" targets the Xilinx Virtex XC4VFX60 and related parts. This
|
||||
* BSP makes no assumptions on what firmware is loaded into the FPGA.
|
||||
*
|
||||
* Provides the .entry section code. This is the first code to run in
|
||||
* the PPC after download to RAM. Excecution in this case starts at
|
||||
* 'download_entry'.
|
||||
*
|
||||
* The entrypoint 'start' is provided for the case where a bootloader has
|
||||
* initialized the CPU, and all that remains to do is to set up a C
|
||||
* environment and call boot_card.
|
||||
*
|
||||
* Derived from virtex dlentry and others.
|
||||
*
|
||||
* IBM refers to the version of the processor as PPC405F5.
|
||||
* The processor version register returns 0x20011470.
|
||||
* References:
|
||||
* PowerPC Processor Reference Guide UG011 (v1.3)
|
||||
* http://www.xilinx.com/support/documentation/user_guides/ug011.pdf
|
||||
*
|
||||
* PowerPC Block Reference Guide
|
||||
* http://www.xilinx.com/support/documentation/user_guides/ug018.pdf
|
||||
*
|
||||
* PowerPC errata
|
||||
* ftp://ftp.xilinx.com/pub/documentation/misc/ppc405f6v5_2_0.pdf
|
||||
*
|
||||
* PowerPC 405-S Embedded Processor Core User's Manual (Version 1.2)
|
||||
* https://www-01.ibm.com/chips/techlib/techlib.nsf/products/PowerPC_405_Embedded_Cores
|
||||
*
|
||||
* @author Richard Claus <claus@SLAC.Stanford.edu>
|
||||
*
|
||||
* @date March 4, 2011 -- Created
|
||||
*
|
||||
* $Revision: 674 $
|
||||
*
|
||||
* @verbatim Copyright 2011
|
||||
* by
|
||||
* The Board of Trustees of the
|
||||
* Leland Stanford Junior University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Work supported by the U.S. Department of Energy under contract
|
||||
* DE-AC03-76SF00515.
|
||||
*
|
||||
* Disclaimer Notice
|
||||
*
|
||||
* The items furnished herewith were developed under the sponsorship
|
||||
* of the U.S. Government. Neither the U.S., nor the U.S. D.O.E., nor the
|
||||
* Leland Stanford Junior University, nor their employees, makes any war-
|
||||
* ranty, express or implied, or assumes any liability or responsibility
|
||||
* for accuracy, completeness or usefulness of any information, apparatus,
|
||||
* product or process disclosed, or represents that its use will not in-
|
||||
* fringe privately-owned rights. Mention of any product, its manufactur-
|
||||
* er, or suppliers shall not, nor is it intended to, imply approval, dis-
|
||||
* approval, or fitness for any particular use. The U.S. and the Univer-
|
||||
* sity at all times retain the right to use and disseminate the furnished
|
||||
* items for any purpose whatsoever. Notice 91 02 01
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#include <rtems/asm.h>
|
||||
#include <rtems/powerpc/powerpc.h>
|
||||
|
||||
/*
|
||||
* The virtex ELF link scripts support some special sections:
|
||||
* .entry The actual entry point
|
||||
* .vectors The section containing the interrupt entry veneers.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Downloaded code loads the vectors separately to 0x00000100,
|
||||
* so .entry can be over 256 bytes.
|
||||
*
|
||||
* The other sections are linked in the following order:
|
||||
* .entry
|
||||
* .text
|
||||
* .data
|
||||
* .bss
|
||||
* see linker command file for section placement
|
||||
*
|
||||
* The initial stack is set to __stack_base.
|
||||
*
|
||||
*/
|
||||
|
||||
.section .entry
|
||||
|
||||
PUBLIC_VAR (download_entry)
|
||||
PUBLIC_VAR (__rtems_entry_point)
|
||||
SYM(download_entry):
|
||||
SYM(__rtems_entry_point):
|
||||
b startupDow /* Entry point used by xmd dow command */
|
||||
|
||||
PUBLIC_VAR (start)
|
||||
SYM(start):
|
||||
b startupBL /* Entry point used by bootLoader */
|
||||
|
||||
base_addr:
|
||||
/*-------------------------------------------------------------------
|
||||
* Parameters from linker
|
||||
*-----------------------------------------------------------------*/
|
||||
toc_pointer:
|
||||
.long __got_start
|
||||
bss_length:
|
||||
.long __bss_size
|
||||
bss_addr:
|
||||
.long __bss_start
|
||||
stack_top:
|
||||
.long __stack_base
|
||||
dccr_contents:
|
||||
.long __dccr
|
||||
iccr_contents:
|
||||
.long __iccr
|
||||
sgr_contents:
|
||||
.long __sgr
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Setup iccr, sgr, msr, cccr0, dcwr, dccr and clear bss
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
startupDow:
|
||||
/*-------------------------------------------------------------------
|
||||
* Load the parameter table base address
|
||||
*------------------------------------------------------------------*/
|
||||
lis r1, base_addr@h
|
||||
ori r1,r1,base_addr@l
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* Clear the Machine State Register's Critical and External
|
||||
* interrupt enables.
|
||||
*------------------------------------------------------------------*/
|
||||
mfmsr r3
|
||||
lis r0, 0x00028000@h
|
||||
ori r0,r0,0x00028000@l
|
||||
andc r3,r3,r0
|
||||
mtmsr r3
|
||||
sync
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* Initialize the memory system.
|
||||
*------------------------------------------------------------------*/
|
||||
li r0,0
|
||||
|
||||
/* Set the Storage Guarded Register. */
|
||||
lwz r2,sgr_contents-base_addr(r1)
|
||||
mtsgr r2
|
||||
|
||||
/* Configure endianness, compression */
|
||||
lis r0,0x00000000@h // Endianess value
|
||||
mtsler r0
|
||||
lis r0,0x00000000@h // Compression value
|
||||
mtsu0r r0
|
||||
|
||||
/* Invalidate the entire instruction cache. */
|
||||
iccci r0,r0
|
||||
|
||||
/* Set the Instruction Cache Cacheability Register. */
|
||||
lwz r2,iccr_contents-base_addr(r1)
|
||||
mticcr r2
|
||||
isync
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Tell the processor where the exception vector table will be.
|
||||
*------------------------------------------------------------------*/
|
||||
.extern SYM(__vectors)
|
||||
lis r2, __vectors@h /* set EVPR exc. vector prefix */
|
||||
mtevpr r2
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Set up the debug register to freeze timers on debug events.
|
||||
*------------------------------------------------------------------*/
|
||||
mfdbcr0 r2
|
||||
ori r2,r2,0x0001
|
||||
mtdbcr0 r2
|
||||
isync
|
||||
|
||||
/* Select whether APU, Wait Enable, interrupts/exceptions and address
|
||||
translation should be enabled when application starts */
|
||||
lis r0,0x00000000@h /* SRR1 value */
|
||||
mtsrr1 r0 /* Potentially: 0x80000000 >> 6 is APU */
|
||||
|
||||
/* Configure timer facilities */
|
||||
mttbl r0 /* Clear Timebase to prevent Fixed Interval.. */
|
||||
mttbu r0 /* ..timer and Watchdog Timer exceptions */
|
||||
mtpit r0 /* Programmable interval timer */
|
||||
li r2,-1 /* -1 to clear TSR */
|
||||
mttsr r2 /* Timer status register */
|
||||
|
||||
/* Clear out stale values in certain registers to avoid confusion */
|
||||
mtcrf 0xff,r0 /* Need for simulation */
|
||||
mtctr r0 /* Counter register */
|
||||
mtxer r0 /* Fixed-point exception register */
|
||||
mtesr r0 /* Exception syndrome register */
|
||||
mtdear r0 /* Data exception address register */
|
||||
mtmcsr r0 /* Machine check syndrome register */
|
||||
|
||||
/* Invalidate the data cache */
|
||||
li r2,0 /* Start address */
|
||||
li r3,0x100 /* Number of cache lines */
|
||||
mtctr r3 /* Transfer data cache congruence class count to CTR */
|
||||
1: dccci 0,r2 /* Invalidate this congruence class */
|
||||
addi r2,r2,0x20 /* Point to next congruence class */
|
||||
bdnz 1b /* Decrement counter and loop whilst not zero */
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* Set Core Configuration Register 0 as follows:
|
||||
* sum: 0x02700E00
|
||||
* bit 1 off: as told by ppc405 errata to avoid CPU_213 ppc bug
|
||||
* bit 3 off: as told by ppc405 errata to avoid CPU_213 ppc bug
|
||||
(Note added later: PPC405F6 is not subject to CPU_213.)
|
||||
* bit 1 on: Xilinx: CR 203746 Patch for PPC405 errata (RiC 12/8/11)
|
||||
* bit 2 on: Xilinx: CR 203746 Patch for PPC405 errata (RiC 12/8/11)
|
||||
* bit 6 on: load word as line
|
||||
* bit 7 off: load misses allocate cache line
|
||||
* bit 8 off: store misses allocate cache line
|
||||
* bit 9-11 on: default settings to do with plb priority
|
||||
* bit 20 on: prefetching for cacheable regions
|
||||
* bit 21 on: prefetching for non-cacheable regions
|
||||
* bit 22 on: request size of non-cacheable inst fetches is 8 words
|
||||
* bit 23 off: fetch misses allocate cache line
|
||||
*------------------------------------------------------------------*/
|
||||
lis r5, 0x52700E00@h
|
||||
ori r5,r5,0x52700E00@l
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* To change CCR0 we make sure the code writing to it is
|
||||
* running from the I-cache. This is needed because changing some
|
||||
* CCR0 fields will cause a hang if the processor is trying to
|
||||
* access memory at the same time.
|
||||
*------------------------------------------------------------------*/
|
||||
lis r4, 2f@h
|
||||
ori r4,r4,2f@l
|
||||
icbt r0,r4
|
||||
b 2f
|
||||
|
||||
.align 5 /* New cache line (32 bytes each) */
|
||||
2:
|
||||
icbt r0,r4 /* Put this line into the I-cache. */
|
||||
isync
|
||||
mtccr0 r5
|
||||
isync
|
||||
b 3f
|
||||
|
||||
.align 5
|
||||
3:
|
||||
/* Set the Data Cache Write-Through Register for no write-through, i.e., for write-back. */
|
||||
li r0,0
|
||||
mtdcwr r0
|
||||
|
||||
/* Set the Data Cache Cacheablility Register. */
|
||||
lwz r0,dccr_contents-base_addr(r1)
|
||||
mtdccr r0
|
||||
isync
|
||||
|
||||
/* Fall through */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* If a bootloader has run that has already performed some
|
||||
* initialization, which among other things has loaded
|
||||
* this code into memory and jumped to start above, the initialization
|
||||
* above does not need to be done. Execution thus resumes here.
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
startupBL:
|
||||
/* -------------------------------------------------------------------
|
||||
* Note that some initialization has already been performed by the
|
||||
* bootloader code in Block RAM, which among other things has loaded
|
||||
* this code into memory and jumped to start above.
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Load the parameter table base address
|
||||
*------------------------------------------------------------------*/
|
||||
lis r1, base_addr@h
|
||||
ori r1,r1,base_addr@l
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Setup stack for RTEMS and call boot_card(). From this
|
||||
* point forward registers will be used in accordance with the
|
||||
* PowerPC EABI.
|
||||
*
|
||||
* boot_card() supervises the initialization of RTEMS and the C
|
||||
* library. It calls bsp_start(), etc.
|
||||
*------------------------------------------------------------------*/
|
||||
lwz r2,toc_pointer-base_addr(r1) /* set r2 to toc */
|
||||
lwz r1,stack_top-base_addr(r1) /* set r1 to stack_top */
|
||||
|
||||
/* Align as required by ABI */
|
||||
li r3,PPC_STACK_ALIGNMENT-1
|
||||
andc r1,r1,r3
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Set up r2 and r13. Upon entry r1 must have a nonzero value
|
||||
* as it will be stored in an "init done" flag. Stupid but true.
|
||||
* r1 must also be set up as a stack pointer as __eabi() jumps
|
||||
* to __init() which has a standard function prolog.
|
||||
*------------------------------------------------------------------*/
|
||||
bl __eabi
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Zero the .bss, .sbss and .sbss2 sections.
|
||||
* Must have r2 and r13 properly set.
|
||||
*------------------------------------------------------------------*/
|
||||
bl zero_bss
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Create a minimal stack frame for this code, the caller of boot_card().
|
||||
*------------------------------------------------------------------*/
|
||||
addi r1,r1, -PPC_MINIMUM_STACK_FRAME_SIZE
|
||||
|
||||
xor r3,r3,r3
|
||||
stw r3,0(r1) /* Terminate the chain of stack frames. */
|
||||
stw r3,4(r1)
|
||||
stw r3,8(r1)
|
||||
stw r3,12(r1)
|
||||
lis r5,environ@ha
|
||||
la r5,environ@l(r5) /* environp */
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Call boot_card() with its arguments, the command-line pointer and
|
||||
* the argument count, set to NULL.
|
||||
*------------------------------------------------------------------*/
|
||||
li r4,0 /* argv */
|
||||
li r3,0 /* argc */
|
||||
.extern SYM (boot_card)
|
||||
b SYM (boot_card)
|
||||
455
bsps/powerpc/virtex5/start/start.S
Normal file
455
bsps/powerpc/virtex5/start/start.S
Normal file
@@ -0,0 +1,455 @@
|
||||
/*!@file start.S
|
||||
*
|
||||
* @brief Initialization code to set up the CPU and call boot_card()
|
||||
*
|
||||
* This "BSP" targets the Xilinx Virtex XC5VFX70T and related parts. This
|
||||
* BSP makes no assumptions on what firmware is loaded into the FPGA.
|
||||
*
|
||||
* Provides the .entry section code. This is the first code to run in
|
||||
* the PPC after download to RAM. Excecution in this case starts at
|
||||
* 'download_entry'.
|
||||
*
|
||||
* The entrypoint 'start' is provided for the case where a bootloader has
|
||||
* initialized the CPU, and all that remains to do is to set up a C
|
||||
* environment and call boot_card.
|
||||
*
|
||||
* Derived from virtex dlentry and others.
|
||||
*
|
||||
* Some portions of this code follow section 3.4 of the PPC440x5 CPU Core User's
|
||||
* Manual v7.1 from IBM. Other parts were derived from examples provided
|
||||
* by Xilinx in their ML510 Reference Designs, e.g., ml510_bsb1_design_ppc440.
|
||||
* See boot.S in standalone/, for example.
|
||||
*
|
||||
* References:
|
||||
* Embedded Processor Block in Virtex-5 FPGAs Reference Guide UG200 (v1.8)
|
||||
* http://www.xilinx.com/support/documentation/user_guides/ug200.pdf
|
||||
*
|
||||
* PowerPC 440x5 Embedded Processor Core User's Manual (Version 7.1)
|
||||
* https://www-01.ibm.com/chips/techlib/techlib.nsf/products/PowerPC_440_Embedded_Core
|
||||
*
|
||||
* @author Richard Claus <claus@SLAC.Stanford.edu>
|
||||
*
|
||||
* @date March 4, 2011 -- Created
|
||||
*
|
||||
* $Revision: 675 $
|
||||
*
|
||||
* @verbatim Copyright 2011
|
||||
* by
|
||||
* The Board of Trustees of the
|
||||
* Leland Stanford Junior University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Work supported by the U.S. Department of Energy under contract
|
||||
* DE-AC03-76SF00515.
|
||||
*
|
||||
* Disclaimer Notice
|
||||
*
|
||||
* The items furnished herewith were developed under the sponsorship
|
||||
* of the U.S. Government. Neither the U.S., nor the U.S. D.O.E., nor the
|
||||
* Leland Stanford Junior University, nor their employees, makes any war-
|
||||
* ranty, express or implied, or assumes any liability or responsibility
|
||||
* for accuracy, completeness or usefulness of any information, apparatus,
|
||||
* product or process disclosed, or represents that its use will not in-
|
||||
* fringe privately-owned rights. Mention of any product, its manufactur-
|
||||
* er, or suppliers shall not, nor is it intended to, imply approval, dis-
|
||||
* approval, or fitness for any particular use. The U.S. and the Univer-
|
||||
* sity at all times retain the right to use and disseminate the furnished
|
||||
* items for any purpose whatsoever. Notice 91 02 01
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#include <rtems/asm.h>
|
||||
#include <rtems/powerpc/powerpc.h>
|
||||
#include <rtems/powerpc/registers.h>
|
||||
|
||||
#define V_TS_SZ_I 0x0290 // V,TS=0(Inst),SIZE=9,TID=0
|
||||
#define V_TS_SZ_D 0x0390 // V,TS=1(Data),SIZE=9,TID=0
|
||||
#define WIMG_U_S_0 0x043F // !(U0-3),!W, I,!M,!G,!E,UX,UW,UR,SX,SW,SR
|
||||
#define WIMG_U_S_1 0x003F // !(U0-3),!W,!I,!M,!G,!E,UX,UW,UR,SX,SW,SR
|
||||
#define PAGE_SZ 0x10000000 // 256 MB
|
||||
|
||||
/*
|
||||
* The virtex ELF link scripts support some special sections:
|
||||
* .entry The actual entry point
|
||||
* .vectors The section containing the interrupt entry veneers.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Downloaded code loads the vectors separately to 0x00000100,
|
||||
* so .entry can be over 256 bytes.
|
||||
*
|
||||
* The other sections are linked in the following order:
|
||||
* .entry
|
||||
* .text
|
||||
* .data
|
||||
* .bss
|
||||
* see linker command file for section placement
|
||||
*
|
||||
* The initial stack is set to __stack_base
|
||||
*
|
||||
* All the entry veneer has to do is to clear the BSS.
|
||||
*/
|
||||
|
||||
.section .entry
|
||||
|
||||
PUBLIC_VAR(download_entry)
|
||||
PUBLIC_VAR(__rtems_entry_point)
|
||||
SYM(download_entry):
|
||||
SYM(__rtems_entry_point):
|
||||
b startupDL /* Entry point used by xmd dow command */
|
||||
|
||||
PUBLIC_VAR (start)
|
||||
SYM(start):
|
||||
b startupBL /* Entry point used by bootLoader */
|
||||
|
||||
base_addr:
|
||||
/*-------------------------------------------------------------------
|
||||
* Parameters from linker
|
||||
*-----------------------------------------------------------------*/
|
||||
toc_pointer:
|
||||
.long __got_start
|
||||
bss_length:
|
||||
.long __bss_size
|
||||
bss_addr:
|
||||
.long __bss_start
|
||||
stack_top:
|
||||
.long __stack_base
|
||||
|
||||
|
||||
.eject
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
* This code follows section 3.4 of the PPC440x5 CPU Core User's
|
||||
* Manual. The numbers in the comments refer to the step numbers
|
||||
* therein. Some of the implementation comes from examples provided
|
||||
* by Xilinx in their ML510 Reference Designs, e.g.,
|
||||
* ml510_bsb1_design_ppc440. See boot.S in standalone/.
|
||||
*------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------
|
||||
* This code is designed to accomodate warm restarts, in which the
|
||||
* application software triggers the restart of the system by branching
|
||||
* to the following code (either boot or boot1) without causing
|
||||
* one of the hardware resets: core, chip, system or JTAG (section
|
||||
* 3.2,3 in the Power PC 440-S Embedded Processor Core User's Manual).
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
* Setup CPU
|
||||
*-----------------------------------------------------------------*/
|
||||
first: li r0,0 // Clear r0
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
* Initialize the memory system.
|
||||
*------------------------------------------------------------------*/
|
||||
iccci r0,r0 // 2. Invalidate instruction cache
|
||||
dccci r0,r0 // 3. Invalidate data cache
|
||||
msync // 4. Force in-progress data PLB ops to complete
|
||||
|
||||
mfdbcr0 r2 // 5. Disable all debug events
|
||||
lis r3,0x8100
|
||||
and r2,r2,r3 // Ignore EDM,TRAP to allow XMD use
|
||||
mtdbcr0 r2
|
||||
li r2,-1
|
||||
mtdbsr r2 // 6. Initialize all debug event status
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
* Set Core Configuration Register 0 as follows:
|
||||
* sum: 0x00206000
|
||||
* bit 1 off Parity Recovery Enable
|
||||
* bit 4 off Cache Read Parity Enable
|
||||
* bit 10 on Disable Store Gathering
|
||||
* bit 11 off Disable APU Instruction Broadcast
|
||||
* bit 16 off Disable Trace Broadcast
|
||||
* bit 17:18 on Specifies behaviour of icbt,dcbt/dcbtst insts
|
||||
* bit 23 off Force Load/Store Alignment
|
||||
* bit 28:29 off Instruction Cache Speculative Line Count
|
||||
* bit 30:31 off Instruction Cache Speculative Line Threshold
|
||||
* NB: UG200/pg 21: Spec. prefetching must be disabled
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
lis r2, 0x00206000@h // 7. Set CCR0: DSTG
|
||||
ori r2,r2,0x00206000@l // Set CCR0: GDCBT, GICBT
|
||||
mtccr0 r2 // Configure CCR0
|
||||
|
||||
mtspr PPC440_CCR1,r0 // 8. Clear CCR1
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
* 9. Configure cache regions
|
||||
*------------------------------------------------------------------*/
|
||||
mtspr PPC440_INV0,r0
|
||||
mtspr PPC440_INV1,r0
|
||||
mtspr PPC440_INV2,r0
|
||||
mtspr PPC440_INV3,r0
|
||||
mtspr PPC440_DNV0,r0
|
||||
mtspr PPC440_DNV1,r0
|
||||
mtspr PPC440_DNV2,r0
|
||||
mtspr PPC440_DNV3,r0
|
||||
mtspr PPC440_ITV0,r0
|
||||
mtspr PPC440_ITV1,r0
|
||||
mtspr PPC440_ITV2,r0
|
||||
mtspr PPC440_ITV3,r0
|
||||
mtspr PPC440_DTV0,r0
|
||||
mtspr PPC440_DTV1,r0
|
||||
mtspr PPC440_DTV2,r0
|
||||
mtspr PPC440_DTV3,r0
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
* Cache victim limits
|
||||
* floors 0, ceiling max to use the entire cache -- nothing locked
|
||||
*------------------------------------------------------------------*/
|
||||
lis r2, 0x0001f800@h
|
||||
ori r2,r2,0x0001f800@l
|
||||
mtspr PPC440_IVLIM,r2
|
||||
mtspr PPC440_DVLIM,r2
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
* Configure instruction and data cache regions:
|
||||
* Set up register constants (r6,r7), page index (r5), address
|
||||
* variable (r4), EPN_V_TS bits (r3)
|
||||
*
|
||||
* Word 0 bits: 0xX0000290, 0xX0000390
|
||||
* Bits Field Inst Data Description
|
||||
* 0:21 EPN 0-15 0-15 Effective Page Number
|
||||
* 22 V 1 1 Valid
|
||||
* 23 TS 0 1 Translation Address Space
|
||||
* 24:27 SIZE 9 9 Page Size (9 = 256 MB)
|
||||
* 38:31 TPAR 0 0 Tag Parity
|
||||
* 32:39 TID 0 0 Translation ID (in the MMUCR)
|
||||
*
|
||||
* Word 1 bits: 0x00000000, 0x00000000
|
||||
* Bits Field Inst Data Description
|
||||
* 0:21 RPN 0 0 Real Page Number
|
||||
* 22:23 PAR1 0 0 Parity for TLB word 1
|
||||
* 28:31 ERPN 0 0 Extended Real Page Number
|
||||
*
|
||||
* Word 2 bits: 0x0000043f, 0x00000c3f
|
||||
* Bits Field Inst Data Description
|
||||
* 0: 1 PAR2 0 0 Parity for TLB word 2
|
||||
* 16 U0 0 0 User-Defineable Storage Attribute 0
|
||||
* 17 U1 0 0 User-Defineable Storage Attribute 1
|
||||
* 18 U2 0 0 User-Defineable Storage Attribute 2
|
||||
* 19 U3 0 0 User-Defineable Storage Attribute 3
|
||||
* 20 W 0 0 Write-Through
|
||||
* 21 I 1 1 Caching Inhibited
|
||||
* 22 M 0 0 Memory Coherence Required
|
||||
* 23 G 0 0 Guarded
|
||||
* 24 E 0 0 Endian
|
||||
* 26 UX 1 1 User State Execute Enable
|
||||
* 27 UW 1 1 User State Write Enable
|
||||
* 28 UR 1 1 User State Read Enable
|
||||
* 29 SX 1 1 Supervisor State Execute Enable
|
||||
* 30 SW 1 1 Supervisor State Write Enable
|
||||
* 31 SR 1 1 Supervisor State Read Enable
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
mtspr PPC440_MMUCR,r0 // 10a. Clear MMUCR
|
||||
li r7,WIMG_U_S_1 // Word 2: Pages are NOT cache inhibited
|
||||
lis r6, PAGE_SZ@h // Page size constant
|
||||
ori r6,r6,PAGE_SZ@l
|
||||
mr r5,r0 // TLB entry index
|
||||
mr r4,r0 // Initialize RPN to zero
|
||||
mflr r28 // Save return address
|
||||
bl tlbSetup // 10b. Set up the TLBs
|
||||
mtlr r28 // Restore return address
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
* Select whether Wait Enable, interrupts/exceptions and which address
|
||||
* spaces should be enabled when application starts
|
||||
*------------------------------------------------------------------*/
|
||||
lis r3, 0x00000000@h // 10d. MSR[IS]=0 MSR[DS]=0
|
||||
ori r3,r3,0x00000000@l
|
||||
mtsrr1 r3
|
||||
mtsrr0 r28 // Return address
|
||||
rfi // Context synchronize to invalidate shadow TLB contents
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Entry point used when downloaded, e.g. through XMD
|
||||
*------------------------------------------------------------------*/
|
||||
startupDL:
|
||||
/*-------------------------------------------------------------------
|
||||
* Do initialization up to the point where a context sync is required
|
||||
*------------------------------------------------------------------*/
|
||||
bl first // Do first things first
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* 11. Tell the processor where the exception vector table will be
|
||||
*------------------------------------------------------------------*/
|
||||
.extern SYM(__vectors)
|
||||
lis r1, __vectors@h /* set EVPR exc. vector prefix */
|
||||
mtspr BOOKE_IVPR,r1
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
* Set up default exception and interrupt vectors
|
||||
*------------------------------------------------------------------*/
|
||||
li r1,0
|
||||
mtivor0 r1
|
||||
addi r1,r1,0x10
|
||||
mtivor1 r1
|
||||
addi r1,r1,0x10
|
||||
mtivor2 r1
|
||||
addi r1,r1,0x10
|
||||
mtivor3 r1
|
||||
addi r1,r1,0x10
|
||||
mtivor4 r1
|
||||
addi r1,r1,0x10
|
||||
mtivor5 r1
|
||||
addi r1,r1,0x10
|
||||
mtivor6 r1
|
||||
addi r1,r1,0x10
|
||||
mtivor7 r1
|
||||
addi r1,r1,0x10
|
||||
mtivor8 r1
|
||||
addi r1,r1,0x10
|
||||
mtivor9 r1
|
||||
addi r1,r1,0x10
|
||||
mtivor10 r1
|
||||
addi r1,r1,0x10
|
||||
mtivor11 r1
|
||||
addi r1,r1,0x10
|
||||
mtivor12 r1
|
||||
addi r1,r1,0x10
|
||||
mtivor13 r1
|
||||
addi r1,r1,0x10
|
||||
mtivor14 r1
|
||||
addi r1,r1,0x10
|
||||
mtivor15 r1
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
* 12. Configure debug facilities
|
||||
*------------------------------------------------------------------*/
|
||||
mtdbcr1 r0
|
||||
mtdbcr2 r0
|
||||
mtiac1 r0
|
||||
mtiac2 r0
|
||||
mtiac3 r0
|
||||
mtiac4 r0
|
||||
mtdac1 r0
|
||||
mtdac2 r0
|
||||
mtdvc1 r0
|
||||
mtdvc2 r0
|
||||
mfdbcr0 r2 // Freeze timers on debug events
|
||||
ori r2,r2,0x0001
|
||||
mtdbcr0 r2
|
||||
isync
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* 13. Configure timer facilities
|
||||
*------------------------------------------------------------------*/
|
||||
mtdec r0 // Clear Decrementer to prevent exception
|
||||
mttbl r0 // Clear Timebase to prevent Fixed Interval..
|
||||
mttbu r0 // ..timer and Watchdog Timer exceptions
|
||||
mtpit r0 // Programmable interval timer
|
||||
li r2,-1 // -1 to clear TSR
|
||||
mttsr r2 // Timer status register
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Clear out stale values in certain registers to avoid confusion
|
||||
*------------------------------------------------------------------*/
|
||||
mtcrf 0xff,r0 // Need for simulation
|
||||
mtctr r0 // Counter register
|
||||
mtxer r0 // Fixed-point exception register
|
||||
mtesr r0 // Exception syndrome register
|
||||
mtdear r0 // Data exception address register
|
||||
mtmcsr r0 // Machine check syndrome register
|
||||
|
||||
/* Fall through */
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* If a bootloader has run that has already initialized the CPU,
|
||||
* which among other things has loaded this code into memory and
|
||||
* jumped to start above, the initialization above does not need
|
||||
* to be redone. Execution thus resumes here.
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
startupBL:
|
||||
/*-------------------------------------------------------------------
|
||||
* Load the parameter table base address
|
||||
*------------------------------------------------------------------*/
|
||||
lis r1, base_addr@h
|
||||
ori r1,r1,base_addr@l
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Setup stack for RTEMS and call boot_card(). From this
|
||||
* point forward registers will be used in accordance with the
|
||||
* PowerPC EABI.
|
||||
*
|
||||
* boot_card() supervises the initialization of RTEMS and the C
|
||||
* library. It calls bsp_start(), bsp_predriver_hook(), etc.
|
||||
*------------------------------------------------------------------*/
|
||||
lwz r2,toc_pointer-base_addr(r1) /* set r2 to toc */
|
||||
lwz r1,stack_top-base_addr(r1) /* set r1 to stack_top */
|
||||
|
||||
/* Align as required by ABI */
|
||||
li r3,PPC_STACK_ALIGNMENT-1
|
||||
andc r1,r1,r3
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Set up r2 and r13. Upon entry r1 must have a nonzero value
|
||||
* as it will be stored in an "init done" flag. Stupid but true.
|
||||
* r1 must also be set up as a stack pointer as __eabi() jumps
|
||||
* to __init() which has a standard function prolog.
|
||||
*------------------------------------------------------------------*/
|
||||
bl __eabi /* setup EABI and SYSV environment */
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Zero the .bss, .sbss and .sbss2 sections.
|
||||
* Must have r2 and r13 properly set.
|
||||
*------------------------------------------------------------------*/
|
||||
bl zero_bss /* Assume Bank regs set up..., cache etc. */
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Create a minimal stack frame for this code, the caller of boot_card().
|
||||
*------------------------------------------------------------------*/
|
||||
addi r1,r1,-PPC_MINIMUM_STACK_FRAME_SIZE
|
||||
|
||||
xor r3,r3,r3 /* Clear r3 */
|
||||
stw r3,0(r1) /* Clear stack chain */
|
||||
stw r3,4(r1)
|
||||
stw r3,8(r1)
|
||||
stw r3,12(r1)
|
||||
lis r5,environ@ha
|
||||
la r5,environ@l(r5) /* environp */
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Call boot_card() with its arguments, the command-line pointer and
|
||||
* the argument count, set to NULL.
|
||||
*------------------------------------------------------------------*/
|
||||
li r4,0 /* argv */
|
||||
li r3,0 /* argc */
|
||||
.extern SYM (boot_card)
|
||||
b SYM (boot_card) /* call the first C routine */
|
||||
|
||||
|
||||
.eject
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
* Set up TLB entries: 2 entries are needed for the same 256MB page
|
||||
* one for instruction memory and the other for data memory.
|
||||
* (TS bit=0 for instructions)
|
||||
*------------------------------------------------------------------*/
|
||||
tlbSetup:
|
||||
1: ori r3,r4,V_TS_SZ_I // Fold V_TS_SZ in with EPN=RPN
|
||||
tlbwe r3,r5,0 // Word 0: EPN_V_TS_SZ (Instructions)
|
||||
tlbwe r4,r5,1 // Word 1: RPN_ERPN
|
||||
tlbwe r7,r5,2 // Word 2: WIMG_U_S
|
||||
ori r3,r4,V_TS_SZ_D // Fold V_TS_SZ in with EPN=RPN
|
||||
addi r5,r5,1 // Next TLB entry
|
||||
tlbwe r3,r5,0 // Word 0: EPN_V_TS_SZ (Data)
|
||||
tlbwe r4,r5,1 // Word 1: RPN_ERPN
|
||||
tlbwe r7,r5,2 // Word 2: WIMG_U_S
|
||||
add r4,r4,r6 // Increment RPN to next 256MB block
|
||||
addi r5,r5,1 // Next TLB entry
|
||||
cmpwi r5,32 // Done yet?
|
||||
bne 1b
|
||||
li r0,0
|
||||
2: // Zero out index 32-63 TLB entries
|
||||
tlbwe r0,r5,0
|
||||
tlbwe r0,r5,1
|
||||
tlbwe r0,r5,2
|
||||
addi r5,r5,1
|
||||
cmpwi r5,64
|
||||
bne 2b
|
||||
|
||||
blr
|
||||
Reference in New Issue
Block a user