diff options
Diffstat (limited to 'c/src/lib/libbsp/powerpc/gen83xx/start/start.S')
-rw-r--r-- | c/src/lib/libbsp/powerpc/gen83xx/start/start.S | 205 |
1 files changed, 111 insertions, 94 deletions
diff --git a/c/src/lib/libbsp/powerpc/gen83xx/start/start.S b/c/src/lib/libbsp/powerpc/gen83xx/start/start.S index a982444464..25e30c2089 100644 --- a/c/src/lib/libbsp/powerpc/gen83xx/start/start.S +++ b/c/src/lib/libbsp/powerpc/gen83xx/start/start.S @@ -18,72 +18,20 @@ \*===============================================================*/ /* $Id$ */ -#include <rtems/asm.h> +#include <libcpu/powerpc-utility.h> #include <rtems/powerpc/cache.h> -#include <rtems/powerpc/registers.h> -#include <mpc83xx/mpc83xx.h> #include <bsp.h> - -/* Macro definitions to load a register with a 32-bit address. - Both functions identically. Sometimes one mnemonic is more - appropriate than the other. - reg -> register to load - value -> value to be loaded - LA reg,value ("Load Address") - LWI reg,value ("Load Word Immediate") */ - -.macro LA reg, value - lis \reg , \value@h - ori \reg , \reg, \value@l -.endm - -.macro LWI reg, value - lis \reg , (\value)@h - ori \reg , \reg, (\value)@l -.endm +#include <mpc83xx/mpc83xx.h> .macro SET_IMM_REGW base, reg2, offset, value LA \reg2, \value stw \reg2,\offset(\base) .endm -/* Macro definitions to test, set or clear a single - bit or bit pattern in a given 32bit GPR. - reg1 -> register content to be tested - reg2 -> 2nd register only needed for computation - mask -> any bit pattern */ - -.macro TSTBITS reg1, reg2, reg3, mask /* Match is indicated by EQ=0 (CR) */ - LWI \reg3, \mask /* Unmatch is indicated by EQ=1 (CR) */ - and \reg1, \reg1, \reg3 - and \reg2, \reg2, \reg3 - cmplw \reg1, \reg2 - sync -.endm - -.macro SETBITS reg1, reg2, mask - LWI \reg2, \mask - or \reg1, \reg1, \reg2 - sync -.endm - -.macro CLRBITS reg1, reg2, mask - LWI \reg2, \mask - andc \reg1, \reg1, \reg2 - sync -.endm - #define REP8(l) l ; l; l; l; l; l; l; l; -.extern _bss_start -.extern _bss_size -.extern _data_start -.extern _data_size -.extern _text_start -.extern _text_size -/*.extern _s_got*/ .extern boot_card -.extern MBAR +.extern MBAR #if defined(RESET_CONF_WRD_L) .section ".resconf","ax" @@ -108,6 +56,32 @@ reset_vec: .section ".entry" PUBLIC_VAR (start) start: + +#ifdef HAS_UBOOT + +.extern mpc83xx_uboot_board_info +.extern mpc83xx_uboot_board_info_size + + /* Reset time base */ + li r0, 0 + mtspr TBWU, r0 + mtspr TBWL, r0 + + /* Copy board info */ + LA r6, mpc83xx_uboot_board_info + LW r5, mpc83xx_uboot_board_info_size + mtctr r5 + +copy_uboot_board_info: + + lwz r5, 0(r3) + addi r3, r3, 4 + stw r5, 0(r6) + addi r6, r6, 4 + bdnz copy_uboot_board_info + +#endif /* HAS_UBOOT */ + /* * basic CPU setup: * init MSR @@ -116,6 +90,7 @@ start: 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) @@ -165,7 +140,7 @@ rom_entry: /* * ROM startup: jump to code final ROM location */ - LA r20, ROM_START /* ROM-RAM reloc in r20 */ + 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 @@ -380,12 +355,12 @@ start_rom_skip1: * ROM or relocatable startup: copy startup code to SDRAM */ /* get start address of text section in RAM */ - LA r29, _text_start + LA r29, bsp_section_text_start /* 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, _text_start + LA r31, bsp_section_text_start sub 28,r28,r31 /* copy startup code from ROM to RAM location */ bl copy_image @@ -409,8 +384,8 @@ copy_rest_of_text: /* get start address of text section in ROM (add reloc offset) */ add r30, r20, r29 /* get size of rest of code */ - LA r28, _text_start - LA r31, _text_size + LA r28, bsp_section_text_start + 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 */ @@ -419,11 +394,11 @@ copy_rest_of_text: * ROM or relocatable startup: copy data to SDRAM */ /* get start address of data section in RAM */ - LA r29, _data_start + LA r29, bsp_section_data_start /* get start address of data section in ROM (add reloc offset) */ add r30, r20, r29 /* get size of RAM image */ - LA r28, _data_size + LA r28, bsp_section_data_size /* copy initialized data section from ROM to RAM location */ bl copy_image @@ -432,15 +407,32 @@ start_code_in_ram: /* * ROM/RAM startup: clear bss in SDRAM */ - LWI r30, _bss_start /* get start address of bss section */ - LWI r29, _bss_size /* get size of bss section */ - bl clr_mem /* Clear the bss section */ + LA r3, bsp_section_bss_start /* get start address of bss section */ + LWI r4, bsp_section_bss_size /* get size of bss section */ + bl mpc83xx_zero_4 /* Clear the bss section */ /* * call boot_card */ -/* set stack pointer (common for RAM/ROM startup) */ - LA r1, _text_start + + /* Set stack pointer (common for RAM/ROM startup) */ + LA r1, bsp_section_text_start 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_ + /* clear arguments and do further init. in C (common for RAM/ROM startup) */ xor r3, r3, r3 xor r4, r4, r4 /* Clear argc and argv */ @@ -486,33 +478,58 @@ copy_image_byte: copy_image_end: blr -clr_mem: - mr r28, r29 - srwi r29, r29, 2 - mtctr r29 /* set ctr reg */ - - - slwi r29, r29, 2 - sub r28, r28, r29 /* maybe some residual bytes */ - xor r29, r29, r29 - - -clr_mem_word: - stswi r29, r30, 0x04 /* store r29 (word) to r30 memory location */ - addi r30, r30, 0x04 /* increment r30 */ - - bdnz clr_mem_word /* dec counter and loop */ +/** + * @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, 8 + 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 - cmpwi r28, 0x00 /* clear mem. finished ? */ - beq clr_mem_end; - mtctr r28 /* reload counter for residual bytes */ -clr_mem_byte: - stswi r29, r30, 0x01 /* store r29 (byte) to r30 memory location */ - addi r30, r30, 0x01 /* update r30 */ - - bdnz clr_mem_byte /* dec counter and loop */ - -clr_mem_end: - blr /* return */ + /* Return */ + blr + end_reloc_startup: |