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 1255e2b4d4SThomas Chou/* 1355e2b4d4SThomas Chou * icache and dcache configuration used only for start.S. 1455e2b4d4SThomas Chou * the values are chosen so that it will work for all configuration. 1555e2b4d4SThomas Chou */ 1655e2b4d4SThomas Chou#define ICACHE_LINE_SIZE 32 /* fixed 32 */ 1755e2b4d4SThomas Chou#define ICACHE_SIZE_MAX 0x10000 /* 64k max */ 1855e2b4d4SThomas Chou#define DCACHE_LINE_SIZE_MIN 4 /* 4, 16, 32 */ 1955e2b4d4SThomas Chou#define DCACHE_SIZE_MAX 0x10000 /* 64k max */ 2055e2b4d4SThomas Chou 214a572fa8SThomas Chou /* RESTART */ 2237e4dafaSPeter Tyser .text 23b8112091SThomas Chou .global _start, _except_start, _except_end 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 */ 3455e2b4d4SThomas Chou ori r4, r0, %lo(ICACHE_LINE_SIZE) 3555e2b4d4SThomas Chou movhi r5, %hi(ICACHE_SIZE_MAX) 3655e2b4d4SThomas 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 */ 6355e2b4d4SThomas Chou ori r4, r0, %lo(DCACHE_LINE_SIZE_MIN) 6455e2b4d4SThomas Chou movhi r5, %hi(DCACHE_SIZE_MAX) 6555e2b4d4SThomas 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 */ 8465af9f69SThomas Chou mov sp, r5 /* initial stack below u-boot code */ 8537e4dafaSPeter Tyser beq r4, r5, 3f 8637e4dafaSPeter Tyser 87e900298eSThomas Chou movhi r6, %hi(CONFIG_SYS_MONITOR_LEN) 88e900298eSThomas Chou ori r6, r6, %lo(CONFIG_SYS_MONITOR_LEN) 89e900298eSThomas Chou add r6, r6, r5 9037e4dafaSPeter Tyser2: ldwio r7, 0(r4) 9137e4dafaSPeter Tyser addi r4, r4, 4 9237e4dafaSPeter Tyser stwio r7, 0(r5) 9337e4dafaSPeter Tyser addi r5, r5, 4 9437e4dafaSPeter Tyser bne r5, r6, 2b 9537e4dafaSPeter Tyser3: 9637e4dafaSPeter Tyser 9737e4dafaSPeter Tyser /* JUMP TO RELOC ADDR */ 9837e4dafaSPeter Tyser movhi r4, %hi(_reloc) 9937e4dafaSPeter Tyser ori r4, r4, %lo(_reloc) 10037e4dafaSPeter Tyser jmp r4 10137e4dafaSPeter Tyser_reloc: 10237e4dafaSPeter Tyser 1034a572fa8SThomas Chou /* STACK INIT -- zero top two words for call back chain. */ 10437e4dafaSPeter Tyser addi sp, sp, -8 10537e4dafaSPeter Tyser stw r0, 0(sp) 10637e4dafaSPeter Tyser stw r0, 4(sp) 10737e4dafaSPeter Tyser mov fp, sp 10837e4dafaSPeter Tyser 109*ecc30663SAlbert ARIBAUD /* Allocate and initialize reserved area, update SP */ 1103e468e68SThomas Chou mov r4, sp 111*ecc30663SAlbert ARIBAUD movhi r2, %hi(board_init_f_alloc_reserve@h) 112*ecc30663SAlbert ARIBAUD ori r2, r2, %lo(board_init_f_alloc_reserve@h) 113*ecc30663SAlbert ARIBAUD callr r2 114*ecc30663SAlbert ARIBAUD mov sp, r2 115*ecc30663SAlbert ARIBAUD mov r4, sp 116*ecc30663SAlbert ARIBAUD movhi r2, %hi(board_init_f_init_reserve@h) 117*ecc30663SAlbert ARIBAUD ori r2, r2, %lo(board_init_f_init_reserve@h) 1183e468e68SThomas Chou callr r2 1193e468e68SThomas Chou 120*ecc30663SAlbert ARIBAUD /* Update frame-pointer */ 1213e468e68SThomas Chou mov fp, sp 1223e468e68SThomas Chou 1234a572fa8SThomas Chou /* Call board_init_f -- never returns */ 1245ff10aa7SThomas Chou mov r4, r0 1255ff10aa7SThomas Chou movhi r2, %hi(board_init_f@h) 1265ff10aa7SThomas Chou ori r2, r2, %lo(board_init_f@h) 1275ff10aa7SThomas Chou callr r2 12837e4dafaSPeter Tyser 1294a572fa8SThomas Chou /* 1304a572fa8SThomas Chou * NEVER RETURNS -- but branch to the _start just 13137e4dafaSPeter Tyser * in case ;-) 13237e4dafaSPeter Tyser */ 13337e4dafaSPeter Tyser br _start 13437e4dafaSPeter Tyser 1355ff10aa7SThomas Chou /* 1365ff10aa7SThomas Chou * relocate_code -- Nios2 handles the relocation above. But 1375ff10aa7SThomas Chou * the generic board code monkeys with the heap, stack, etc. 1385ff10aa7SThomas Chou * (it makes some assumptions that may not be appropriate 1395ff10aa7SThomas Chou * for Nios). Nevertheless, we capitulate here. 1405ff10aa7SThomas Chou * 1415ff10aa7SThomas Chou * We'll call the board_init_r from here since this isn't 1425ff10aa7SThomas Chou * supposed to return. 1435ff10aa7SThomas Chou * 1445ff10aa7SThomas Chou * void relocate_code (ulong sp, gd_t *global_data, 1455ff10aa7SThomas Chou * ulong reloc_addr) 1465ff10aa7SThomas Chou * __attribute__ ((noreturn)); 1475ff10aa7SThomas Chou */ 1485ff10aa7SThomas Chou .text 1495ff10aa7SThomas Chou .global relocate_code 1505ff10aa7SThomas Chou 1515ff10aa7SThomas Chourelocate_code: 1525ff10aa7SThomas Chou mov sp, r4 /* Set the new sp */ 1535ff10aa7SThomas Chou mov r4, r5 1544192b8c3SThomas Chou 1554192b8c3SThomas Chou /* 1564192b8c3SThomas Chou * ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent 1574192b8c3SThomas Chou * and between __bss_start and __bss_end. 1584192b8c3SThomas Chou */ 1594192b8c3SThomas Chou movhi r5, %hi(__bss_start) 1604192b8c3SThomas Chou ori r5, r5, %lo(__bss_start) 1614192b8c3SThomas Chou movhi r6, %hi(__bss_end) 1624192b8c3SThomas Chou ori r6, r6, %lo(__bss_end) 1634192b8c3SThomas Chou beq r5, r6, 5f 1644192b8c3SThomas Chou 1659208d7ebSThomas Chou4: stw r0, 0(r5) 1664192b8c3SThomas Chou addi r5, r5, 4 1674192b8c3SThomas Chou bne r5, r6, 4b 1684192b8c3SThomas Chou5: 1694192b8c3SThomas Chou 1705ff10aa7SThomas Chou movhi r8, %hi(board_init_r@h) 1715ff10aa7SThomas Chou ori r8, r8, %lo(board_init_r@h) 1725ff10aa7SThomas Chou callr r8 1735ff10aa7SThomas Chou ret 174