]> git.sur5r.net Git - u-boot/blobdiff - arch/microblaze/cpu/start.S
SPDX: Convert all of our single license tags to Linux Kernel style
[u-boot] / arch / microblaze / cpu / start.S
index d3370c414b703f747aff8b69e4e6ed5841f38ecd..22903e3bc4e5e403975e09788e4b6f343dee700e 100644 (file)
@@ -1,27 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * (C) Copyright 2007 Michal Simek
  * (C) Copyright 2004 Atmark Techno, Inc.
  *
  * Michal  SIMEK <monstr@monstr.eu>
  * Yasushi SHOJI <yashi@atmark-techno.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
  */
 
 #include <asm-offsets.h>
        .text
        .global _start
 _start:
+       /*
+        * reserve registers:
+        * r10: Stores little/big endian offset for vectors
+        * r2: Stores imm opcode
+        * r3: Stores brai opcode
+        */
+
        mts     rmsr, r0        /* disable cache */
+
+       addi    r8, r0, __end
+       mts     rslr, r8
+       /* TODO: Redo this code to call board_init_f_*() */
+#if defined(CONFIG_SPL_BUILD)
+       addi    r1, r0, CONFIG_SPL_STACK_ADDR
+       mts     rshr, r1
+       addi    r1, r1, -4      /* Decrement SP to top of memory */
+#else
+#if CONFIG_VAL(SYS_MALLOC_F_LEN)
+       addi    r1, r0, CONFIG_SYS_INIT_SP_OFFSET - CONFIG_VAL(SYS_MALLOC_F_LEN)
+#else
        addi    r1, r0, CONFIG_SYS_INIT_SP_OFFSET
+#endif
+       mts     rshr, r1
        addi    r1, r1, -4      /* Decrement SP to top of memory */
 
        /* Find-out if u-boot is running on BIG/LITTLE endian platform
@@ -44,50 +48,34 @@ _start:
         * 4b) BIG endian - r10 contains 0x0 because 0x2 offset is on addr 0x3
         */
        addik   r6, r0, 0x2 /* BIG/LITTLE endian offset */
-       swi     r6, r0, 0
-       lbui    r10, r0, 0
-
-       /* add opcode instruction for 32bit jump - 2 instruction imm & brai*/
-       addi    r6, r0, 0xb0000000      /* hex b000 opcode imm */
-       swi     r6, r0, 0x0     /* reset address */
-       swi     r6, r0, 0x8     /* user vector exception */
-       swi     r6, r0, 0x10    /* interrupt */
-       swi     r6, r0, 0x20    /* hardware exception */
-
-       addi    r6, r0, 0xb8080000      /* hew b808 opcode brai*/
-       swi     r6, r0, 0x4     /* reset address */
-       swi     r6, r0, 0xC     /* user vector exception */
-       swi     r6, r0, 0x14    /* interrupt */
-       swi     r6, r0, 0x24    /* hardware exception */
+       lwi     r7, r0, 0x28
+       swi     r6, r0, 0x28 /* used first unused MB vector */
+       lbui    r10, r0, 0x28 /* used first unused MB vector */
+       swi     r7, r0, 0x28
+
+       /* add opcode instruction for 32bit jump - 2 instruction imm & brai */
+       addi    r2, r0, 0xb0000000      /* hex b000 opcode imm */
+       addi    r3, r0, 0xb8080000      /* hew b808 opcode brai */
 
 #ifdef CONFIG_SYS_RESET_ADDRESS
        /* reset address */
+       swi     r2, r0, 0x0     /* reset address - imm opcode */
+       swi     r3, r0, 0x4     /* reset address - brai opcode */
+
        addik   r6, r0, CONFIG_SYS_RESET_ADDRESS
        sw      r6, r1, r0
-       lhu     r7, r1, r0
-       shi     r7, r0, 0x2
-       shi     r6, r0, 0x6
-/*
- * Copy U-Boot code to CONFIG_SYS_TEXT_BASE
- * solve problem with sbrk_base
- */
-#if (CONFIG_SYS_RESET_ADDRESS != CONFIG_SYS_TEXT_BASE)
-       addi    r4, r0, __end
-       addi    r5, r0, __text_start
-       rsub    r4, r5, r4      /* size = __end - __text_start */
-       addi    r6, r0, CONFIG_SYS_RESET_ADDRESS        /* source address */
-       addi    r7, r0, 0       /* counter */
-4:
-       lw      r8, r6, r7
-       sw      r8, r5, r7
-       addi    r7, r7, 0x4
-       cmp     r8, r4, r7
-       blti    r8, 4b
-#endif
+       lhu     r7, r1, r10
+       rsubi   r8, r10, 0x2
+       sh      r7, r0, r8
+       rsubi   r8, r10, 0x6
+       sh      r6, r0, r8
 #endif
 
 #ifdef CONFIG_SYS_USR_EXCEP
        /* user_vector_exception */
+       swi     r2, r0, 0x8     /* user vector exception - imm opcode */
+       swi     r3, r0, 0xC     /* user vector exception - brai opcode */
+
        addik   r6, r0, _exception_handler
        sw      r6, r1, r0
        /*
@@ -117,8 +105,10 @@ _start:
        sh      r6, r0, r8
 #endif
 
-#ifdef CONFIG_SYS_INTC_0
        /* interrupt_handler */
+       swi     r2, r0, 0x10    /* interrupt - imm opcode */
+       swi     r3, r0, 0x14    /* interrupt - brai opcode */
+
        addik   r6, r0, _interrupt_handler
        sw      r6, r1, r0
        lhu     r7, r1, r10
@@ -126,9 +116,11 @@ _start:
        sh      r7, r0, r8
        rsubi   r8, r10, 0x16
        sh      r6, r0, r8
-#endif
 
        /* hardware exception */
+       swi     r2, r0, 0x20    /* hardware exception - imm opcode */
+       swi     r3, r0, 0x24    /* hardware exception - brai opcode */
+
        addik   r6, r0, _hw_exception_handler
        sw      r6, r1, r0
        lhu     r7, r1, r10
@@ -136,12 +128,20 @@ _start:
        sh      r7, r0, r8
        rsubi   r8, r10, 0x26
        sh      r6, r0, r8
+#endif /* CONFIG_SPL_BUILD */
+
+       /* Flush cache before enable cache */
+       addik   r5, r0, 0
+       addik   r6, r0, XILINX_DCACHE_BYTE_SIZE
+       bralid r15, flush_cache
+       nop
 
        /* enable instruction and data cache */
        mfs     r12, rmsr
-       ori     r12, r12, 0xa0
+       ori     r12, r12, 0x1a0
        mts     rmsr, r12
 
+       /* TODO: Redo this code to call board_init_f_*() */
 clear_bss:
        /* clear BSS segments */
        addi    r5, r0, __bss_start
@@ -154,9 +154,34 @@ clear_bss:
        cmp     r6, r5, r4 /* check if we have reach the end */
        bnei    r6, 2b
 3:     /* jumping to board_init */
-       brai    board_init
+#ifdef CONFIG_DEBUG_UART
+       bralid  r15, debug_uart_init
+       nop
+#endif
+#ifndef CONFIG_SPL_BUILD
+       or      r5, r0, r0      /* flags - empty */
+       addi    r31, r0, _gd
+#if CONFIG_VAL(SYS_MALLOC_F_LEN)
+       addi    r6, r0, CONFIG_SYS_INIT_SP_OFFSET
+       swi     r6, r31, GD_MALLOC_BASE
+#endif
+       brai    board_init_f
+#else
+       addi    r31, r0, _gd
+#if CONFIG_VAL(SYS_MALLOC_F_LEN)
+       addi    r6, r0, CONFIG_SPL_STACK_ADDR
+       swi     r6, r31, GD_MALLOC_BASE
+#endif
+       brai    board_init_r
+#endif
 1:     bri     1b
 
+ .section .bss
+.align 4
+_gd:
+         .space  GENERATED_GBL_DATA_SIZE
+
+#ifndef CONFIG_SPL_BUILD
 /*
  * Read 16bit little endian
  */
@@ -189,3 +214,108 @@ out16:    bslli   r3, r6, 8
        rtsd    r15, 8
        or      r0, r0, r0
        .end    out16
+
+/*
+ * Relocate u-boot
+ */
+       .text
+       .global relocate_code
+       .ent    relocate_code
+       .align  2
+relocate_code:
+       /*
+        * r5 - start_addr_sp
+        * r6 - new_gd
+        * r7 - reloc_addr
+        */
+       addi    r1, r5, 0 /* Start to use new SP */
+       addi    r31, r6, 0 /* Start to use new GD */
+
+       add     r23, r0, r7 /* Move reloc addr to r23 */
+       /* Relocate text and data - r12 temp value */
+       addi    r21, r0, _start
+       addi    r22, r0, __end - 4 /* Include BSS too */
+
+       rsub    r6, r21, r22
+       or      r5, r0, r0
+1:     lw      r12, r21, r5 /* Load u-boot data */
+       sw      r12, r23, r5 /* Write zero to loc */
+       cmp     r12, r5, r6 /* Check if we have reach the end */
+       bneid   r12, 1b
+       addi    r5, r5, 4 /* Increment to next loc - relocate code */
+
+       /* R23 points to the base address. */
+       add     r23, r0, r7 /* Move reloc addr to r23 */
+       addi    r24, r0, CONFIG_SYS_TEXT_BASE /* Get reloc offset */
+       rsub    r23, r24, r23 /* keep - this is already here gd->reloc_off */
+
+       addik   r6, r0, 0x2 /* BIG/LITTLE endian offset */
+       lwi     r7, r0, 0x28
+       swi     r6, r0, 0x28 /* used first unused MB vector */
+       lbui    r10, r0, 0x28 /* used first unused MB vector */
+       swi     r7, r0, 0x28
+
+#ifdef CONFIG_SYS_USR_EXCEP
+       addik   r6, r0, _exception_handler
+       addk    r6, r6, r23 /* add offset */
+       sw      r6, r1, r0
+       lhu     r7, r1, r10
+       rsubi   r8, r10, 0xa
+       sh      r7, r0, r8
+       rsubi   r8, r10, 0xe
+       sh      r6, r0, r8
+#endif
+       addik   r6, r0, _hw_exception_handler
+       addk    r6, r6, r23 /* add offset */
+       sw      r6, r1, r0
+       lhu     r7, r1, r10
+       rsubi   r8, r10, 0x22
+       sh      r7, r0, r8
+       rsubi   r8, r10, 0x26
+       sh      r6, r0, r8
+
+       addik   r6, r0, _interrupt_handler
+       addk    r6, r6, r23 /* add offset */
+       sw      r6, r1, r0
+       lhu     r7, r1, r10
+       rsubi   r8, r10, 0x12
+       sh      r7, r0, r8
+       rsubi   r8, r10, 0x16
+       sh      r6, r0, r8
+
+       /* Check if GOT exist */
+       addik   r21, r23, _got_start
+       addik   r22, r23, _got_end
+       cmpu    r12, r21, r22
+       beqi    r12, 2f /* No GOT table - jump over */
+
+       /* Skip last 3 entries plus 1 because of loop boundary below */
+       addik   r22, r22, -0x10
+
+        /* Relocate the GOT. */
+3:     lw      r12, r21, r0 /* Load entry */
+       addk    r12, r12, r23 /* Add reloc offset */
+       sw      r12, r21, r0 /* Save entry back */
+
+       cmpu    r12, r21, r22 /* Check if this cross boundary */
+       bneid   r12, 3b
+       addik   r21. r21, 4
+
+       /* Update pointer to GOT */
+       mfs     r20, rpc
+       addik   r20, r20, _GLOBAL_OFFSET_TABLE_ + 8
+       addk    r20, r20, r23
+
+       /* Flush caches to ensure consistency */
+       addik   r5, r0, 0
+       addik   r6, r0, XILINX_DCACHE_BYTE_SIZE
+       bralid  r15, flush_cache
+       nop
+
+2:     addi    r5, r31, 0 /* gd is initialized in board_r.c */
+       addi    r6, r0, CONFIG_SYS_TEXT_BASE
+       addi    r12, r23, board_init_r
+       bra     r12 /* Jump to relocated code */
+
+       .end    relocate_code
+#endif