1/* SPDX-License-Identifier: GPL-2.0+ */ 2/* 3 * (C) Copyright 2004, Psyent Corporation <www.psyent.com> 4 * Scott McNutt <smcnutt@psyent.com> 5 */ 6 7#include <asm-offsets.h> 8#include <config.h> 9#include <version.h> 10 11/* 12 * icache and dcache configuration used only for start.S. 13 * the values are chosen so that it will work for all configuration. 14 */ 15#define ICACHE_LINE_SIZE 32 /* fixed 32 */ 16#define ICACHE_SIZE_MAX 0x10000 /* 64k max */ 17#define DCACHE_LINE_SIZE_MIN 4 /* 4, 16, 32 */ 18#define DCACHE_SIZE_MAX 0x10000 /* 64k max */ 19 20 /* RESTART */ 21 .text 22 .global _start, _except_start, _except_end 23 24_start: 25 wrctl status, r0 /* Disable interrupts */ 26 /* 27 * ICACHE INIT -- only the icache line at the reset address 28 * is invalidated at reset. So the init must stay within 29 * the cache line size (8 words). If GERMS is used, we'll 30 * just be invalidating the cache a second time. If cache 31 * is not implemented initi behaves as nop. 32 */ 33 ori r4, r0, %lo(ICACHE_LINE_SIZE) 34 movhi r5, %hi(ICACHE_SIZE_MAX) 35 ori r5, r5, %lo(ICACHE_SIZE_MAX) 360: initi r5 37 sub r5, r5, r4 38 bgt r5, r0, 0b 39 br _except_end /* Skip the tramp */ 40 41 /* 42 * EXCEPTION TRAMPOLINE -- the following gets copied 43 * to the exception address (below), but is otherwise at the 44 * default exception vector offset (0x0020). 45 */ 46_except_start: 47 movhi et, %hi(_exception) 48 ori et, et, %lo(_exception) 49 jmp et 50_except_end: 51 52 /* 53 * INTERRUPTS -- for now, all interrupts masked and globally 54 * disabled. 55 */ 56 wrctl ienable, r0 /* All disabled */ 57 58 /* 59 * DCACHE INIT -- if dcache not implemented, initd behaves as 60 * nop. 61 */ 62 ori r4, r0, %lo(DCACHE_LINE_SIZE_MIN) 63 movhi r5, %hi(DCACHE_SIZE_MAX) 64 ori r5, r5, %lo(DCACHE_SIZE_MAX) 65 mov r6, r0 661: initd 0(r6) 67 add r6, r6, r4 68 bltu r6, r5, 1b 69 70 /* 71 * RELOCATE CODE, DATA & COMMAND TABLE -- the following code 72 * assumes code, data and the command table are all 73 * contiguous. This lets us relocate everything as a single 74 * block. Make sure the linker script matches this ;-) 75 */ 76 nextpc r4 77_cur: movhi r5, %hi(_cur - _start) 78 ori r5, r5, %lo(_cur - _start) 79 sub r4, r4, r5 /* r4 <- cur _start */ 80 mov r8, r4 81 movhi r5, %hi(_start) 82 ori r5, r5, %lo(_start) /* r5 <- linked _start */ 83 mov sp, r5 /* initial stack below u-boot code */ 84 beq r4, r5, 3f 85 86 movhi r6, %hi(CONFIG_SYS_MONITOR_LEN) 87 ori r6, r6, %lo(CONFIG_SYS_MONITOR_LEN) 88 add r6, r6, r5 892: ldwio r7, 0(r4) 90 addi r4, r4, 4 91 stwio r7, 0(r5) 92 addi r5, r5, 4 93 bne r5, r6, 2b 943: 95 96 /* JUMP TO RELOC ADDR */ 97 movhi r4, %hi(_reloc) 98 ori r4, r4, %lo(_reloc) 99 jmp r4 100_reloc: 101 102 /* STACK INIT -- zero top two words for call back chain. */ 103 addi sp, sp, -8 104 stw r0, 0(sp) 105 stw r0, 4(sp) 106 mov fp, sp 107 108#ifdef CONFIG_DEBUG_UART 109 /* Set up the debug UART */ 110 movhi r2, %hi(debug_uart_init@h) 111 ori r2, r2, %lo(debug_uart_init@h) 112 callr r2 113#endif 114 115 /* Allocate and initialize reserved area, update SP */ 116 mov r4, sp 117 movhi r2, %hi(board_init_f_alloc_reserve@h) 118 ori r2, r2, %lo(board_init_f_alloc_reserve@h) 119 callr r2 120 mov sp, r2 121 mov r4, sp 122 movhi r2, %hi(board_init_f_init_reserve@h) 123 ori r2, r2, %lo(board_init_f_init_reserve@h) 124 callr r2 125 126 /* Update frame-pointer */ 127 mov fp, sp 128 129 /* Call board_init_f -- never returns */ 130 mov r4, r0 131 movhi r2, %hi(board_init_f@h) 132 ori r2, r2, %lo(board_init_f@h) 133 callr r2 134 135 /* 136 * NEVER RETURNS -- but branch to the _start just 137 * in case ;-) 138 */ 139 br _start 140 141 /* 142 * relocate_code -- Nios2 handles the relocation above. But 143 * the generic board code monkeys with the heap, stack, etc. 144 * (it makes some assumptions that may not be appropriate 145 * for Nios). Nevertheless, we capitulate here. 146 * 147 * We'll call the board_init_r from here since this isn't 148 * supposed to return. 149 * 150 * void relocate_code (ulong sp, gd_t *global_data, 151 * ulong reloc_addr) 152 * __attribute__ ((noreturn)); 153 */ 154 .text 155 .global relocate_code 156 157relocate_code: 158 mov sp, r4 /* Set the new sp */ 159 mov r4, r5 160 161 /* 162 * ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent 163 * and between __bss_start and __bss_end. 164 */ 165 movhi r5, %hi(__bss_start) 166 ori r5, r5, %lo(__bss_start) 167 movhi r6, %hi(__bss_end) 168 ori r6, r6, %lo(__bss_end) 169 beq r5, r6, 5f 170 1714: stw r0, 0(r5) 172 addi r5, r5, 4 173 bne r5, r6, 4b 1745: 175 176 movhi r8, %hi(board_init_r@h) 177 ori r8, r8, %lo(board_init_r@h) 178 callr r8 179 ret 180