summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/gen83xx/start/start.S
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/powerpc/gen83xx/start/start.S')
-rw-r--r--c/src/lib/libbsp/powerpc/gen83xx/start/start.S205
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: