137e4dafaSPeter Tyser/* 237e4dafaSPeter Tyser * (C) Copyright 2004, Psyent Corporation <www.psyent.com> 337e4dafaSPeter Tyser * Scott McNutt <smcnutt@psyent.com> 437e4dafaSPeter Tyser * 51a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 637e4dafaSPeter Tyser */ 737e4dafaSPeter Tyser 825ddd1fbSWolfgang Denk#include <asm-offsets.h> 937e4dafaSPeter Tyser#include <config.h> 1037e4dafaSPeter Tyser#include <version.h> 1137e4dafaSPeter Tyser 12*55e2b4d4SThomas Chou/* 13*55e2b4d4SThomas Chou * icache and dcache configuration used only for start.S. 14*55e2b4d4SThomas Chou * the values are chosen so that it will work for all configuration. 15*55e2b4d4SThomas Chou */ 16*55e2b4d4SThomas Chou#define ICACHE_LINE_SIZE 32 /* fixed 32 */ 17*55e2b4d4SThomas Chou#define ICACHE_SIZE_MAX 0x10000 /* 64k max */ 18*55e2b4d4SThomas Chou#define DCACHE_LINE_SIZE_MIN 4 /* 4, 16, 32 */ 19*55e2b4d4SThomas Chou#define DCACHE_SIZE_MAX 0x10000 /* 64k max */ 20*55e2b4d4SThomas Chou 214a572fa8SThomas Chou /* RESTART */ 2237e4dafaSPeter Tyser .text 2337e4dafaSPeter Tyser .global _start 2437e4dafaSPeter Tyser 2537e4dafaSPeter Tyser_start: 26fd2712d0SThomas Chou wrctl status, r0 /* Disable interrupts */ 274a572fa8SThomas Chou /* 284a572fa8SThomas Chou * ICACHE INIT -- only the icache line at the reset address 2937e4dafaSPeter Tyser * is invalidated at reset. So the init must stay within 3037e4dafaSPeter Tyser * the cache line size (8 words). If GERMS is used, we'll 3137e4dafaSPeter Tyser * just be invalidating the cache a second time. If cache 3237e4dafaSPeter Tyser * is not implemented initi behaves as nop. 3337e4dafaSPeter Tyser */ 34*55e2b4d4SThomas Chou ori r4, r0, %lo(ICACHE_LINE_SIZE) 35*55e2b4d4SThomas Chou movhi r5, %hi(ICACHE_SIZE_MAX) 36*55e2b4d4SThomas Chou ori r5, r5, %lo(ICACHE_SIZE_MAX) 37fd2712d0SThomas Chou0: initi r5 38fd2712d0SThomas Chou sub r5, r5, r4 39fd2712d0SThomas Chou bgt r5, r0, 0b 4037e4dafaSPeter Tyser br _except_end /* Skip the tramp */ 4137e4dafaSPeter Tyser 424a572fa8SThomas Chou /* 434a572fa8SThomas Chou * EXCEPTION TRAMPOLINE -- the following gets copied 4437e4dafaSPeter Tyser * to the exception address (below), but is otherwise at the 4537e4dafaSPeter Tyser * default exception vector offset (0x0020). 4637e4dafaSPeter Tyser */ 4737e4dafaSPeter Tyser_except_start: 4837e4dafaSPeter Tyser movhi et, %hi(_exception) 4937e4dafaSPeter Tyser ori et, et, %lo(_exception) 5037e4dafaSPeter Tyser jmp et 5137e4dafaSPeter Tyser_except_end: 5237e4dafaSPeter Tyser 534a572fa8SThomas Chou /* 544a572fa8SThomas Chou * INTERRUPTS -- for now, all interrupts masked and globally 5537e4dafaSPeter Tyser * disabled. 5637e4dafaSPeter Tyser */ 5737e4dafaSPeter Tyser wrctl ienable, r0 /* All disabled */ 5837e4dafaSPeter Tyser 594a572fa8SThomas Chou /* 604a572fa8SThomas Chou * DCACHE INIT -- if dcache not implemented, initd behaves as 6137e4dafaSPeter Tyser * nop. 6237e4dafaSPeter Tyser */ 63*55e2b4d4SThomas Chou ori r4, r0, %lo(DCACHE_LINE_SIZE_MIN) 64*55e2b4d4SThomas Chou movhi r5, %hi(DCACHE_SIZE_MAX) 65*55e2b4d4SThomas Chou ori r5, r5, %lo(DCACHE_SIZE_MAX) 6637e4dafaSPeter Tyser mov r6, r0 6737e4dafaSPeter Tyser1: initd 0(r6) 6837e4dafaSPeter Tyser add r6, r6, r4 6937e4dafaSPeter Tyser bltu r6, r5, 1b 7037e4dafaSPeter Tyser 714a572fa8SThomas Chou /* 724a572fa8SThomas Chou * RELOCATE CODE, DATA & COMMAND TABLE -- the following code 7337e4dafaSPeter Tyser * assumes code, data and the command table are all 7437e4dafaSPeter Tyser * contiguous. This lets us relocate everything as a single 7537e4dafaSPeter Tyser * block. Make sure the linker script matches this ;-) 7637e4dafaSPeter Tyser */ 7737e4dafaSPeter Tyser nextpc r4 7837e4dafaSPeter Tyser_cur: movhi r5, %hi(_cur - _start) 7937e4dafaSPeter Tyser ori r5, r5, %lo(_cur - _start) 8037e4dafaSPeter Tyser sub r4, r4, r5 /* r4 <- cur _start */ 8137e4dafaSPeter Tyser mov r8, r4 8237e4dafaSPeter Tyser movhi r5, %hi(_start) 8337e4dafaSPeter Tyser ori r5, r5, %lo(_start) /* r5 <- linked _start */ 8437e4dafaSPeter Tyser beq r4, r5, 3f 8537e4dafaSPeter Tyser 86e900298eSThomas Chou movhi r6, %hi(CONFIG_SYS_MONITOR_LEN) 87e900298eSThomas Chou ori r6, r6, %lo(CONFIG_SYS_MONITOR_LEN) 88e900298eSThomas Chou add r6, r6, r5 8937e4dafaSPeter Tyser2: ldwio r7, 0(r4) 9037e4dafaSPeter Tyser addi r4, r4, 4 9137e4dafaSPeter Tyser stwio r7, 0(r5) 9237e4dafaSPeter Tyser addi r5, r5, 4 9337e4dafaSPeter Tyser bne r5, r6, 2b 9437e4dafaSPeter Tyser3: 9537e4dafaSPeter Tyser 9637e4dafaSPeter Tyser /* JUMP TO RELOC ADDR */ 9737e4dafaSPeter Tyser movhi r4, %hi(_reloc) 9837e4dafaSPeter Tyser ori r4, r4, %lo(_reloc) 9937e4dafaSPeter Tyser jmp r4 10037e4dafaSPeter Tyser_reloc: 10137e4dafaSPeter Tyser 1024a572fa8SThomas Chou /* 1034a572fa8SThomas Chou * COPY EXCEPTION TRAMPOLINE -- copy the tramp to the 10437e4dafaSPeter Tyser * exception address. Define CONFIG_ROM_STUBS to prevent 10537e4dafaSPeter Tyser * the copy (e.g. exception in flash or in other 10637e4dafaSPeter Tyser * softare/firmware component). 10737e4dafaSPeter Tyser */ 10837e4dafaSPeter Tyser#if !defined(CONFIG_ROM_STUBS) 10937e4dafaSPeter Tyser movhi r4, %hi(_except_start) 11037e4dafaSPeter Tyser ori r4, r4, %lo(_except_start) 11137e4dafaSPeter Tyser movhi r5, %hi(_except_end) 11237e4dafaSPeter Tyser ori r5, r5, %lo(_except_end) 11337e4dafaSPeter Tyser movhi r6, %hi(CONFIG_SYS_EXCEPTION_ADDR) 11437e4dafaSPeter Tyser ori r6, r6, %lo(CONFIG_SYS_EXCEPTION_ADDR) 11537e4dafaSPeter Tyser beq r4, r6, 7f /* Skip if at proper addr */ 11637e4dafaSPeter Tyser 11737e4dafaSPeter Tyser6: ldwio r7, 0(r4) 11837e4dafaSPeter Tyser stwio r7, 0(r6) 11937e4dafaSPeter Tyser addi r4, r4, 4 12037e4dafaSPeter Tyser addi r6, r6, 4 12137e4dafaSPeter Tyser bne r4, r5, 6b 12237e4dafaSPeter Tyser7: 12337e4dafaSPeter Tyser#endif 12437e4dafaSPeter Tyser 1254a572fa8SThomas Chou /* STACK INIT -- zero top two words for call back chain. */ 12637e4dafaSPeter Tyser movhi sp, %hi(CONFIG_SYS_INIT_SP) 12737e4dafaSPeter Tyser ori sp, sp, %lo(CONFIG_SYS_INIT_SP) 12837e4dafaSPeter Tyser addi sp, sp, -8 12937e4dafaSPeter Tyser stw r0, 0(sp) 13037e4dafaSPeter Tyser stw r0, 4(sp) 13137e4dafaSPeter Tyser mov fp, sp 13237e4dafaSPeter Tyser 1333e468e68SThomas Chou /* Allocate and zero GD, update SP */ 1343e468e68SThomas Chou mov r4, sp 1353e468e68SThomas Chou movhi r2, %hi(board_init_f_mem@h) 1363e468e68SThomas Chou ori r2, r2, %lo(board_init_f_mem@h) 1373e468e68SThomas Chou callr r2 1383e468e68SThomas Chou 1393e468e68SThomas Chou /* Update stack- and frame-pointers */ 1403e468e68SThomas Chou mov sp, r2 1413e468e68SThomas Chou mov fp, sp 1423e468e68SThomas Chou 1434a572fa8SThomas Chou /* Call board_init_f -- never returns */ 1445ff10aa7SThomas Chou mov r4, r0 1455ff10aa7SThomas Chou movhi r2, %hi(board_init_f@h) 1465ff10aa7SThomas Chou ori r2, r2, %lo(board_init_f@h) 1475ff10aa7SThomas Chou callr r2 14837e4dafaSPeter Tyser 1494a572fa8SThomas Chou /* 1504a572fa8SThomas Chou * NEVER RETURNS -- but branch to the _start just 15137e4dafaSPeter Tyser * in case ;-) 15237e4dafaSPeter Tyser */ 15337e4dafaSPeter Tyser br _start 15437e4dafaSPeter Tyser 1555ff10aa7SThomas Chou /* 1565ff10aa7SThomas Chou * relocate_code -- Nios2 handles the relocation above. But 1575ff10aa7SThomas Chou * the generic board code monkeys with the heap, stack, etc. 1585ff10aa7SThomas Chou * (it makes some assumptions that may not be appropriate 1595ff10aa7SThomas Chou * for Nios). Nevertheless, we capitulate here. 1605ff10aa7SThomas Chou * 1615ff10aa7SThomas Chou * We'll call the board_init_r from here since this isn't 1625ff10aa7SThomas Chou * supposed to return. 1635ff10aa7SThomas Chou * 1645ff10aa7SThomas Chou * void relocate_code (ulong sp, gd_t *global_data, 1655ff10aa7SThomas Chou * ulong reloc_addr) 1665ff10aa7SThomas Chou * __attribute__ ((noreturn)); 1675ff10aa7SThomas Chou */ 1685ff10aa7SThomas Chou .text 1695ff10aa7SThomas Chou .global relocate_code 1705ff10aa7SThomas Chou 1715ff10aa7SThomas Chourelocate_code: 1725ff10aa7SThomas Chou mov sp, r4 /* Set the new sp */ 1735ff10aa7SThomas Chou mov r4, r5 1744192b8c3SThomas Chou 1754192b8c3SThomas Chou /* 1764192b8c3SThomas Chou * ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent 1774192b8c3SThomas Chou * and between __bss_start and __bss_end. 1784192b8c3SThomas Chou */ 1794192b8c3SThomas Chou movhi r5, %hi(__bss_start) 1804192b8c3SThomas Chou ori r5, r5, %lo(__bss_start) 1814192b8c3SThomas Chou movhi r6, %hi(__bss_end) 1824192b8c3SThomas Chou ori r6, r6, %lo(__bss_end) 1834192b8c3SThomas Chou beq r5, r6, 5f 1844192b8c3SThomas Chou 1854192b8c3SThomas Chou4: stwio r0, 0(r5) 1864192b8c3SThomas Chou addi r5, r5, 4 1874192b8c3SThomas Chou bne r5, r6, 4b 1884192b8c3SThomas Chou5: 1894192b8c3SThomas Chou 1905ff10aa7SThomas Chou movhi r8, %hi(board_init_r@h) 1915ff10aa7SThomas Chou ori r8, r8, %lo(board_init_r@h) 1925ff10aa7SThomas Chou callr r8 1935ff10aa7SThomas Chou ret 194