1*37e4dafaSPeter Tyser/* 2*37e4dafaSPeter Tyser * (C) Copyright 2004, Psyent Corporation <www.psyent.com> 3*37e4dafaSPeter Tyser * Scott McNutt <smcnutt@psyent.com> 4*37e4dafaSPeter Tyser * 5*37e4dafaSPeter Tyser * See file CREDITS for list of people who contributed to this 6*37e4dafaSPeter Tyser * project. 7*37e4dafaSPeter Tyser * 8*37e4dafaSPeter Tyser * This program is free software; you can redistribute it and/or 9*37e4dafaSPeter Tyser * modify it under the terms of the GNU General Public License as 10*37e4dafaSPeter Tyser * published by the Free Software Foundation; either version 2 of 11*37e4dafaSPeter Tyser * the License, or (at your option) any later version. 12*37e4dafaSPeter Tyser * 13*37e4dafaSPeter Tyser * This program is distributed in the hope that it will be useful, 14*37e4dafaSPeter Tyser * but WITHOUT ANY WARRANTY; without even the implied warranty of 15*37e4dafaSPeter Tyser * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*37e4dafaSPeter Tyser * GNU General Public License for more details. 17*37e4dafaSPeter Tyser * 18*37e4dafaSPeter Tyser * You should have received a copy of the GNU General Public License 19*37e4dafaSPeter Tyser * along with this program; if not, write to the Free Software 20*37e4dafaSPeter Tyser * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21*37e4dafaSPeter Tyser * MA 02111-1307 USA 22*37e4dafaSPeter Tyser */ 23*37e4dafaSPeter Tyser 24*37e4dafaSPeter Tyser 25*37e4dafaSPeter Tyser#include <config.h> 26*37e4dafaSPeter Tyser#include <timestamp.h> 27*37e4dafaSPeter Tyser#include <version.h> 28*37e4dafaSPeter Tyser 29*37e4dafaSPeter Tyser/************************************************************************* 30*37e4dafaSPeter Tyser * RESTART 31*37e4dafaSPeter Tyser ************************************************************************/ 32*37e4dafaSPeter Tyser 33*37e4dafaSPeter Tyser .text 34*37e4dafaSPeter Tyser .global _start 35*37e4dafaSPeter Tyser 36*37e4dafaSPeter Tyser_start: 37*37e4dafaSPeter Tyser /* ICACHE INIT -- only the icache line at the reset address 38*37e4dafaSPeter Tyser * is invalidated at reset. So the init must stay within 39*37e4dafaSPeter Tyser * the cache line size (8 words). If GERMS is used, we'll 40*37e4dafaSPeter Tyser * just be invalidating the cache a second time. If cache 41*37e4dafaSPeter Tyser * is not implemented initi behaves as nop. 42*37e4dafaSPeter Tyser */ 43*37e4dafaSPeter Tyser ori r4, r0, %lo(CONFIG_SYS_ICACHELINE_SIZE) 44*37e4dafaSPeter Tyser movhi r5, %hi(CONFIG_SYS_ICACHE_SIZE) 45*37e4dafaSPeter Tyser ori r5, r5, %lo(CONFIG_SYS_ICACHE_SIZE) 46*37e4dafaSPeter Tyser mov r6, r0 47*37e4dafaSPeter Tyser0: initi r6 48*37e4dafaSPeter Tyser add r6, r6, r4 49*37e4dafaSPeter Tyser bltu r6, r5, 0b 50*37e4dafaSPeter Tyser br _except_end /* Skip the tramp */ 51*37e4dafaSPeter Tyser 52*37e4dafaSPeter Tyser /* EXCEPTION TRAMPOLINE -- the following gets copied 53*37e4dafaSPeter Tyser * to the exception address (below), but is otherwise at the 54*37e4dafaSPeter Tyser * default exception vector offset (0x0020). 55*37e4dafaSPeter Tyser */ 56*37e4dafaSPeter Tyser_except_start: 57*37e4dafaSPeter Tyser movhi et, %hi(_exception) 58*37e4dafaSPeter Tyser ori et, et, %lo(_exception) 59*37e4dafaSPeter Tyser jmp et 60*37e4dafaSPeter Tyser_except_end: 61*37e4dafaSPeter Tyser 62*37e4dafaSPeter Tyser /* INTERRUPTS -- for now, all interrupts masked and globally 63*37e4dafaSPeter Tyser * disabled. 64*37e4dafaSPeter Tyser */ 65*37e4dafaSPeter Tyser wrctl status, r0 /* Disable interrupts */ 66*37e4dafaSPeter Tyser wrctl ienable, r0 /* All disabled */ 67*37e4dafaSPeter Tyser 68*37e4dafaSPeter Tyser /* DCACHE INIT -- if dcache not implemented, initd behaves as 69*37e4dafaSPeter Tyser * nop. 70*37e4dafaSPeter Tyser */ 71*37e4dafaSPeter Tyser movhi r4, %hi(CONFIG_SYS_DCACHELINE_SIZE) 72*37e4dafaSPeter Tyser ori r4, r4, %lo(CONFIG_SYS_DCACHELINE_SIZE) 73*37e4dafaSPeter Tyser movhi r5, %hi(CONFIG_SYS_DCACHE_SIZE) 74*37e4dafaSPeter Tyser ori r5, r5, %lo(CONFIG_SYS_DCACHE_SIZE) 75*37e4dafaSPeter Tyser mov r6, r0 76*37e4dafaSPeter Tyser1: initd 0(r6) 77*37e4dafaSPeter Tyser add r6, r6, r4 78*37e4dafaSPeter Tyser bltu r6, r5, 1b 79*37e4dafaSPeter Tyser 80*37e4dafaSPeter Tyser /* RELOCATE CODE, DATA & COMMAND TABLE -- the following code 81*37e4dafaSPeter Tyser * assumes code, data and the command table are all 82*37e4dafaSPeter Tyser * contiguous. This lets us relocate everything as a single 83*37e4dafaSPeter Tyser * block. Make sure the linker script matches this ;-) 84*37e4dafaSPeter Tyser */ 85*37e4dafaSPeter Tyser nextpc r4 86*37e4dafaSPeter Tyser_cur: movhi r5, %hi(_cur - _start) 87*37e4dafaSPeter Tyser ori r5, r5, %lo(_cur - _start) 88*37e4dafaSPeter Tyser sub r4, r4, r5 /* r4 <- cur _start */ 89*37e4dafaSPeter Tyser mov r8, r4 90*37e4dafaSPeter Tyser movhi r5, %hi(_start) 91*37e4dafaSPeter Tyser ori r5, r5, %lo(_start) /* r5 <- linked _start */ 92*37e4dafaSPeter Tyser beq r4, r5, 3f 93*37e4dafaSPeter Tyser 94*37e4dafaSPeter Tyser movhi r6, %hi(_edata) 95*37e4dafaSPeter Tyser ori r6, r6, %lo(_edata) 96*37e4dafaSPeter Tyser2: ldwio r7, 0(r4) 97*37e4dafaSPeter Tyser addi r4, r4, 4 98*37e4dafaSPeter Tyser stwio r7, 0(r5) 99*37e4dafaSPeter Tyser addi r5, r5, 4 100*37e4dafaSPeter Tyser bne r5, r6, 2b 101*37e4dafaSPeter Tyser3: 102*37e4dafaSPeter Tyser 103*37e4dafaSPeter Tyser /* ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent 104*37e4dafaSPeter Tyser * and between __bss_start and _end. 105*37e4dafaSPeter Tyser */ 106*37e4dafaSPeter Tyser movhi r5, %hi(__bss_start) 107*37e4dafaSPeter Tyser ori r5, r5, %lo(__bss_start) 108*37e4dafaSPeter Tyser movhi r6, %hi(_end) 109*37e4dafaSPeter Tyser ori r6, r6, %lo(_end) 110*37e4dafaSPeter Tyser beq r5, r6, 5f 111*37e4dafaSPeter Tyser 112*37e4dafaSPeter Tyser4: stwio r0, 0(r5) 113*37e4dafaSPeter Tyser addi r5, r5, 4 114*37e4dafaSPeter Tyser bne r5, r6, 4b 115*37e4dafaSPeter Tyser5: 116*37e4dafaSPeter Tyser 117*37e4dafaSPeter Tyser /* GLOBAL POINTER -- the global pointer is used to reference 118*37e4dafaSPeter Tyser * "small data" (see -G switch). The linker script must 119*37e4dafaSPeter Tyser * provide the gp address. 120*37e4dafaSPeter Tyser */ 121*37e4dafaSPeter Tyser movhi gp, %hi(_gp) 122*37e4dafaSPeter Tyser ori gp, gp, %lo(_gp) 123*37e4dafaSPeter Tyser 124*37e4dafaSPeter Tyser /* JUMP TO RELOC ADDR */ 125*37e4dafaSPeter Tyser movhi r4, %hi(_reloc) 126*37e4dafaSPeter Tyser ori r4, r4, %lo(_reloc) 127*37e4dafaSPeter Tyser jmp r4 128*37e4dafaSPeter Tyser_reloc: 129*37e4dafaSPeter Tyser 130*37e4dafaSPeter Tyser /* COPY EXCEPTION TRAMPOLINE -- copy the tramp to the 131*37e4dafaSPeter Tyser * exception address. Define CONFIG_ROM_STUBS to prevent 132*37e4dafaSPeter Tyser * the copy (e.g. exception in flash or in other 133*37e4dafaSPeter Tyser * softare/firmware component). 134*37e4dafaSPeter Tyser */ 135*37e4dafaSPeter Tyser#if !defined(CONFIG_ROM_STUBS) 136*37e4dafaSPeter Tyser movhi r4, %hi(_except_start) 137*37e4dafaSPeter Tyser ori r4, r4, %lo(_except_start) 138*37e4dafaSPeter Tyser movhi r5, %hi(_except_end) 139*37e4dafaSPeter Tyser ori r5, r5, %lo(_except_end) 140*37e4dafaSPeter Tyser movhi r6, %hi(CONFIG_SYS_EXCEPTION_ADDR) 141*37e4dafaSPeter Tyser ori r6, r6, %lo(CONFIG_SYS_EXCEPTION_ADDR) 142*37e4dafaSPeter Tyser beq r4, r6, 7f /* Skip if at proper addr */ 143*37e4dafaSPeter Tyser 144*37e4dafaSPeter Tyser6: ldwio r7, 0(r4) 145*37e4dafaSPeter Tyser stwio r7, 0(r6) 146*37e4dafaSPeter Tyser addi r4, r4, 4 147*37e4dafaSPeter Tyser addi r6, r6, 4 148*37e4dafaSPeter Tyser bne r4, r5, 6b 149*37e4dafaSPeter Tyser7: 150*37e4dafaSPeter Tyser#endif 151*37e4dafaSPeter Tyser 152*37e4dafaSPeter Tyser /* STACK INIT -- zero top two words for call back chain. 153*37e4dafaSPeter Tyser */ 154*37e4dafaSPeter Tyser movhi sp, %hi(CONFIG_SYS_INIT_SP) 155*37e4dafaSPeter Tyser ori sp, sp, %lo(CONFIG_SYS_INIT_SP) 156*37e4dafaSPeter Tyser addi sp, sp, -8 157*37e4dafaSPeter Tyser stw r0, 0(sp) 158*37e4dafaSPeter Tyser stw r0, 4(sp) 159*37e4dafaSPeter Tyser mov fp, sp 160*37e4dafaSPeter Tyser 161*37e4dafaSPeter Tyser /* 162*37e4dafaSPeter Tyser * Call board_init -- never returns 163*37e4dafaSPeter Tyser */ 164*37e4dafaSPeter Tyser movhi r4, %hi(board_init@h) 165*37e4dafaSPeter Tyser ori r4, r4, %lo(board_init@h) 166*37e4dafaSPeter Tyser callr r4 167*37e4dafaSPeter Tyser 168*37e4dafaSPeter Tyser /* NEVER RETURNS -- but branch to the _start just 169*37e4dafaSPeter Tyser * in case ;-) 170*37e4dafaSPeter Tyser */ 171*37e4dafaSPeter Tyser br _start 172*37e4dafaSPeter Tyser 173*37e4dafaSPeter Tyser 174*37e4dafaSPeter Tyser/* 175*37e4dafaSPeter Tyser * dly_clks -- Nios2 (like Nios1) doesn't have a timebase in 176*37e4dafaSPeter Tyser * the core. For simple delay loops, we do our best by counting 177*37e4dafaSPeter Tyser * instruction cycles. 178*37e4dafaSPeter Tyser * 179*37e4dafaSPeter Tyser * Instruction performance varies based on the core. For cores 180*37e4dafaSPeter Tyser * with icache and static/dynamic branch prediction (II/f, II/s): 181*37e4dafaSPeter Tyser * 182*37e4dafaSPeter Tyser * Normal ALU (e.g. add, cmp, etc): 1 cycle 183*37e4dafaSPeter Tyser * Branch (correctly predicted, taken): 2 cycles 184*37e4dafaSPeter Tyser * Negative offset is predicted (II/s). 185*37e4dafaSPeter Tyser * 186*37e4dafaSPeter Tyser * For cores without icache and no branch prediction (II/e): 187*37e4dafaSPeter Tyser * 188*37e4dafaSPeter Tyser * Normal ALU (e.g. add, cmp, etc): 6 cycles 189*37e4dafaSPeter Tyser * Branch (no prediction): 6 cycles 190*37e4dafaSPeter Tyser * 191*37e4dafaSPeter Tyser * For simplicity, if an instruction cache is implemented we 192*37e4dafaSPeter Tyser * assume II/f or II/s. Otherwise, we use the II/e. 193*37e4dafaSPeter Tyser * 194*37e4dafaSPeter Tyser */ 195*37e4dafaSPeter Tyser .globl dly_clks 196*37e4dafaSPeter Tyser 197*37e4dafaSPeter Tyserdly_clks: 198*37e4dafaSPeter Tyser 199*37e4dafaSPeter Tyser#if (CONFIG_SYS_ICACHE_SIZE > 0) 200*37e4dafaSPeter Tyser subi r4, r4, 3 /* 3 clocks/loop */ 201*37e4dafaSPeter Tyser#else 202*37e4dafaSPeter Tyser subi r4, r4, 12 /* 12 clocks/loop */ 203*37e4dafaSPeter Tyser#endif 204*37e4dafaSPeter Tyser bge r4, r0, dly_clks 205*37e4dafaSPeter Tyser ret 206*37e4dafaSPeter Tyser 207*37e4dafaSPeter Tyser 208*37e4dafaSPeter Tyser#if !defined(CONFIG_IDENT_STRING) 209*37e4dafaSPeter Tyser#define CONFIG_IDENT_STRING "" 210*37e4dafaSPeter Tyser#endif 211*37e4dafaSPeter Tyser .data 212*37e4dafaSPeter Tyser .globl version_string 213*37e4dafaSPeter Tyser 214*37e4dafaSPeter Tyserversion_string: 215*37e4dafaSPeter Tyser .ascii U_BOOT_VERSION 216*37e4dafaSPeter Tyser .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" 217*37e4dafaSPeter Tyser .ascii CONFIG_IDENT_STRING, "\0" 218