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