bsps: Move start files to bsps

This patch is a part of the BSP source reorganization.

Update #3285.
This commit is contained in:
Sebastian Huber
2018-04-20 10:19:28 +02:00
parent d7d66d7d45
commit fbcd7c8fa6
152 changed files with 112 additions and 112 deletions

File diff suppressed because it is too large Load Diff

View 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:

View 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:

View 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 */

View 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 ? */

View 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

View 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:

View 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:

View 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:

View 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

View 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

View 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

View 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

View 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
*/

View 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:

View 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:

View 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:

View 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

View 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)

View 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