137e4dafaSPeter Tyser/* 237e4dafaSPeter Tyser * (C) Copyright 2004, Psyent Corporation <www.psyent.com> 337e4dafaSPeter Tyser * Scott McNutt <smcnutt@psyent.com> 437e4dafaSPeter Tyser * 537e4dafaSPeter Tyser * See file CREDITS for list of people who contributed to this 637e4dafaSPeter Tyser * project. 737e4dafaSPeter Tyser * 837e4dafaSPeter Tyser * This program is free software; you can redistribute it and/or 937e4dafaSPeter Tyser * modify it under the terms of the GNU General Public License as 1037e4dafaSPeter Tyser * published by the Free Software Foundation; either version 2 of 1137e4dafaSPeter Tyser * the License, or (at your option) any later version. 1237e4dafaSPeter Tyser * 1337e4dafaSPeter Tyser * This program is distributed in the hope that it will be useful, 1437e4dafaSPeter Tyser * but WITHOUT ANY WARRANTY; without even the implied warranty of 1537e4dafaSPeter Tyser * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1637e4dafaSPeter Tyser * GNU General Public License for more details. 1737e4dafaSPeter Tyser * 1837e4dafaSPeter Tyser * You should have received a copy of the GNU General Public License 1937e4dafaSPeter Tyser * along with this program; if not, write to the Free Software 2037e4dafaSPeter Tyser * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 2137e4dafaSPeter Tyser * MA 02111-1307 USA 2237e4dafaSPeter Tyser */ 2337e4dafaSPeter Tyser 24*25ddd1fbSWolfgang Denk#include <asm-offsets.h> 2537e4dafaSPeter Tyser#include <config.h> 2637e4dafaSPeter Tyser#include <timestamp.h> 2737e4dafaSPeter Tyser#include <version.h> 2837e4dafaSPeter Tyser 2937e4dafaSPeter Tyser/************************************************************************* 3037e4dafaSPeter Tyser * RESTART 3137e4dafaSPeter Tyser ************************************************************************/ 3237e4dafaSPeter Tyser 3337e4dafaSPeter Tyser .text 3437e4dafaSPeter Tyser .global _start 3537e4dafaSPeter Tyser 3637e4dafaSPeter Tyser_start: 37fd2712d0SThomas Chou wrctl status, r0 /* Disable interrupts */ 3837e4dafaSPeter Tyser /* ICACHE INIT -- only the icache line at the reset address 3937e4dafaSPeter Tyser * is invalidated at reset. So the init must stay within 4037e4dafaSPeter Tyser * the cache line size (8 words). If GERMS is used, we'll 4137e4dafaSPeter Tyser * just be invalidating the cache a second time. If cache 4237e4dafaSPeter Tyser * is not implemented initi behaves as nop. 4337e4dafaSPeter Tyser */ 4437e4dafaSPeter Tyser ori r4, r0, %lo(CONFIG_SYS_ICACHELINE_SIZE) 4537e4dafaSPeter Tyser movhi r5, %hi(CONFIG_SYS_ICACHE_SIZE) 4637e4dafaSPeter Tyser ori r5, r5, %lo(CONFIG_SYS_ICACHE_SIZE) 47fd2712d0SThomas Chou0: initi r5 48fd2712d0SThomas Chou sub r5, r5, r4 49fd2712d0SThomas Chou bgt r5, r0, 0b 5037e4dafaSPeter Tyser br _except_end /* Skip the tramp */ 5137e4dafaSPeter Tyser 5237e4dafaSPeter Tyser /* EXCEPTION TRAMPOLINE -- the following gets copied 5337e4dafaSPeter Tyser * to the exception address (below), but is otherwise at the 5437e4dafaSPeter Tyser * default exception vector offset (0x0020). 5537e4dafaSPeter Tyser */ 5637e4dafaSPeter Tyser_except_start: 5737e4dafaSPeter Tyser movhi et, %hi(_exception) 5837e4dafaSPeter Tyser ori et, et, %lo(_exception) 5937e4dafaSPeter Tyser jmp et 6037e4dafaSPeter Tyser_except_end: 6137e4dafaSPeter Tyser 6237e4dafaSPeter Tyser /* INTERRUPTS -- for now, all interrupts masked and globally 6337e4dafaSPeter Tyser * disabled. 6437e4dafaSPeter Tyser */ 6537e4dafaSPeter Tyser wrctl ienable, r0 /* All disabled */ 6637e4dafaSPeter Tyser 6737e4dafaSPeter Tyser /* DCACHE INIT -- if dcache not implemented, initd behaves as 6837e4dafaSPeter Tyser * nop. 6937e4dafaSPeter Tyser */ 7037e4dafaSPeter Tyser movhi r4, %hi(CONFIG_SYS_DCACHELINE_SIZE) 7137e4dafaSPeter Tyser ori r4, r4, %lo(CONFIG_SYS_DCACHELINE_SIZE) 7237e4dafaSPeter Tyser movhi r5, %hi(CONFIG_SYS_DCACHE_SIZE) 7337e4dafaSPeter Tyser ori r5, r5, %lo(CONFIG_SYS_DCACHE_SIZE) 7437e4dafaSPeter Tyser mov r6, r0 7537e4dafaSPeter Tyser1: initd 0(r6) 7637e4dafaSPeter Tyser add r6, r6, r4 7737e4dafaSPeter Tyser bltu r6, r5, 1b 7837e4dafaSPeter Tyser 7937e4dafaSPeter Tyser /* RELOCATE CODE, DATA & COMMAND TABLE -- the following code 8037e4dafaSPeter Tyser * assumes code, data and the command table are all 8137e4dafaSPeter Tyser * contiguous. This lets us relocate everything as a single 8237e4dafaSPeter Tyser * block. Make sure the linker script matches this ;-) 8337e4dafaSPeter Tyser */ 8437e4dafaSPeter Tyser nextpc r4 8537e4dafaSPeter Tyser_cur: movhi r5, %hi(_cur - _start) 8637e4dafaSPeter Tyser ori r5, r5, %lo(_cur - _start) 8737e4dafaSPeter Tyser sub r4, r4, r5 /* r4 <- cur _start */ 8837e4dafaSPeter Tyser mov r8, r4 8937e4dafaSPeter Tyser movhi r5, %hi(_start) 9037e4dafaSPeter Tyser ori r5, r5, %lo(_start) /* r5 <- linked _start */ 9137e4dafaSPeter Tyser beq r4, r5, 3f 9237e4dafaSPeter Tyser 9337e4dafaSPeter Tyser movhi r6, %hi(_edata) 9437e4dafaSPeter Tyser ori r6, r6, %lo(_edata) 9537e4dafaSPeter Tyser2: ldwio r7, 0(r4) 9637e4dafaSPeter Tyser addi r4, r4, 4 9737e4dafaSPeter Tyser stwio r7, 0(r5) 9837e4dafaSPeter Tyser addi r5, r5, 4 9937e4dafaSPeter Tyser bne r5, r6, 2b 10037e4dafaSPeter Tyser3: 10137e4dafaSPeter Tyser 10237e4dafaSPeter Tyser /* ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent 10337e4dafaSPeter Tyser * and between __bss_start and _end. 10437e4dafaSPeter Tyser */ 10537e4dafaSPeter Tyser movhi r5, %hi(__bss_start) 10637e4dafaSPeter Tyser ori r5, r5, %lo(__bss_start) 10737e4dafaSPeter Tyser movhi r6, %hi(_end) 10837e4dafaSPeter Tyser ori r6, r6, %lo(_end) 10937e4dafaSPeter Tyser beq r5, r6, 5f 11037e4dafaSPeter Tyser 11137e4dafaSPeter Tyser4: stwio r0, 0(r5) 11237e4dafaSPeter Tyser addi r5, r5, 4 11337e4dafaSPeter Tyser bne r5, r6, 4b 11437e4dafaSPeter Tyser5: 11537e4dafaSPeter Tyser 11637e4dafaSPeter Tyser /* JUMP TO RELOC ADDR */ 11737e4dafaSPeter Tyser movhi r4, %hi(_reloc) 11837e4dafaSPeter Tyser ori r4, r4, %lo(_reloc) 11937e4dafaSPeter Tyser jmp r4 12037e4dafaSPeter Tyser_reloc: 12137e4dafaSPeter Tyser 12237e4dafaSPeter Tyser /* COPY EXCEPTION TRAMPOLINE -- copy the tramp to the 12337e4dafaSPeter Tyser * exception address. Define CONFIG_ROM_STUBS to prevent 12437e4dafaSPeter Tyser * the copy (e.g. exception in flash or in other 12537e4dafaSPeter Tyser * softare/firmware component). 12637e4dafaSPeter Tyser */ 12737e4dafaSPeter Tyser#if !defined(CONFIG_ROM_STUBS) 12837e4dafaSPeter Tyser movhi r4, %hi(_except_start) 12937e4dafaSPeter Tyser ori r4, r4, %lo(_except_start) 13037e4dafaSPeter Tyser movhi r5, %hi(_except_end) 13137e4dafaSPeter Tyser ori r5, r5, %lo(_except_end) 13237e4dafaSPeter Tyser movhi r6, %hi(CONFIG_SYS_EXCEPTION_ADDR) 13337e4dafaSPeter Tyser ori r6, r6, %lo(CONFIG_SYS_EXCEPTION_ADDR) 13437e4dafaSPeter Tyser beq r4, r6, 7f /* Skip if at proper addr */ 13537e4dafaSPeter Tyser 13637e4dafaSPeter Tyser6: ldwio r7, 0(r4) 13737e4dafaSPeter Tyser stwio r7, 0(r6) 13837e4dafaSPeter Tyser addi r4, r4, 4 13937e4dafaSPeter Tyser addi r6, r6, 4 14037e4dafaSPeter Tyser bne r4, r5, 6b 14137e4dafaSPeter Tyser7: 14237e4dafaSPeter Tyser#endif 14337e4dafaSPeter Tyser 14437e4dafaSPeter Tyser /* STACK INIT -- zero top two words for call back chain. 14537e4dafaSPeter Tyser */ 14637e4dafaSPeter Tyser movhi sp, %hi(CONFIG_SYS_INIT_SP) 14737e4dafaSPeter Tyser ori sp, sp, %lo(CONFIG_SYS_INIT_SP) 14837e4dafaSPeter Tyser addi sp, sp, -8 14937e4dafaSPeter Tyser stw r0, 0(sp) 15037e4dafaSPeter Tyser stw r0, 4(sp) 15137e4dafaSPeter Tyser mov fp, sp 15237e4dafaSPeter Tyser 15337e4dafaSPeter Tyser /* 15437e4dafaSPeter Tyser * Call board_init -- never returns 15537e4dafaSPeter Tyser */ 15637e4dafaSPeter Tyser movhi r4, %hi(board_init@h) 15737e4dafaSPeter Tyser ori r4, r4, %lo(board_init@h) 15837e4dafaSPeter Tyser callr r4 15937e4dafaSPeter Tyser 16037e4dafaSPeter Tyser /* NEVER RETURNS -- but branch to the _start just 16137e4dafaSPeter Tyser * in case ;-) 16237e4dafaSPeter Tyser */ 16337e4dafaSPeter Tyser br _start 16437e4dafaSPeter Tyser 16537e4dafaSPeter Tyser 16637e4dafaSPeter Tyser/* 16737e4dafaSPeter Tyser * dly_clks -- Nios2 (like Nios1) doesn't have a timebase in 16837e4dafaSPeter Tyser * the core. For simple delay loops, we do our best by counting 16937e4dafaSPeter Tyser * instruction cycles. 17037e4dafaSPeter Tyser * 17137e4dafaSPeter Tyser * Instruction performance varies based on the core. For cores 17237e4dafaSPeter Tyser * with icache and static/dynamic branch prediction (II/f, II/s): 17337e4dafaSPeter Tyser * 17437e4dafaSPeter Tyser * Normal ALU (e.g. add, cmp, etc): 1 cycle 17537e4dafaSPeter Tyser * Branch (correctly predicted, taken): 2 cycles 17637e4dafaSPeter Tyser * Negative offset is predicted (II/s). 17737e4dafaSPeter Tyser * 17837e4dafaSPeter Tyser * For cores without icache and no branch prediction (II/e): 17937e4dafaSPeter Tyser * 18037e4dafaSPeter Tyser * Normal ALU (e.g. add, cmp, etc): 6 cycles 18137e4dafaSPeter Tyser * Branch (no prediction): 6 cycles 18237e4dafaSPeter Tyser * 18337e4dafaSPeter Tyser * For simplicity, if an instruction cache is implemented we 18437e4dafaSPeter Tyser * assume II/f or II/s. Otherwise, we use the II/e. 18537e4dafaSPeter Tyser * 18637e4dafaSPeter Tyser */ 18737e4dafaSPeter Tyser .globl dly_clks 18837e4dafaSPeter Tyser 18937e4dafaSPeter Tyserdly_clks: 19037e4dafaSPeter Tyser 19137e4dafaSPeter Tyser#if (CONFIG_SYS_ICACHE_SIZE > 0) 19237e4dafaSPeter Tyser subi r4, r4, 3 /* 3 clocks/loop */ 19337e4dafaSPeter Tyser#else 19437e4dafaSPeter Tyser subi r4, r4, 12 /* 12 clocks/loop */ 19537e4dafaSPeter Tyser#endif 19637e4dafaSPeter Tyser bge r4, r0, dly_clks 19737e4dafaSPeter Tyser ret 19837e4dafaSPeter Tyser 19937e4dafaSPeter Tyser 20037e4dafaSPeter Tyser#if !defined(CONFIG_IDENT_STRING) 20137e4dafaSPeter Tyser#define CONFIG_IDENT_STRING "" 20237e4dafaSPeter Tyser#endif 20337e4dafaSPeter Tyser .data 20437e4dafaSPeter Tyser .globl version_string 20537e4dafaSPeter Tyser 20637e4dafaSPeter Tyserversion_string: 20737e4dafaSPeter Tyser .ascii U_BOOT_VERSION 20837e4dafaSPeter Tyser .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" 20937e4dafaSPeter Tyser .ascii CONFIG_IDENT_STRING, "\0" 210