1/* 2 * Copyright (C) 2009 Wind River Systems Inc 3 * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com 4 * Copyright (C) 2004 Microtronix Datacom Ltd 5 * Copyright (C) 2001 Vic Phillips, Microtronix Datacom Ltd. 6 * 7 * Based on head.S for Altera's Excalibur development board with nios processor 8 * 9 * Based on the following from the Excalibur sdk distribution: 10 * NA_MemoryMap.s, NR_JumpToStart.s, NR_Setup.s, NR_CWPManager.s 11 * 12 * This file is subject to the terms and conditions of the GNU General Public 13 * License. See the file "COPYING" in the main directory of this archive 14 * for more details. 15 */ 16 17#include <linux/init.h> 18#include <linux/linkage.h> 19#include <asm/thread_info.h> 20#include <asm/processor.h> 21#include <asm/cache.h> 22#include <asm/page.h> 23#include <asm/asm-offsets.h> 24#include <asm/asm-macros.h> 25 26/* 27 * ZERO_PAGE is a special page that is used for zero-initialized 28 * data and COW. 29 */ 30.data 31.global empty_zero_page 32.align 12 33empty_zero_page: 34 .space PAGE_SIZE 35 36/* 37 * This global variable is used as an extension to the nios' 38 * STATUS register to emulate a user/supervisor mode. 39 */ 40 .data 41 .align 2 42 .set noat 43 44 .global _current_thread 45_current_thread: 46 .long 0 47/* 48 * Input(s): passed from u-boot 49 * r4 - Optional pointer to a board information structure. 50 * r5 - Optional pointer to the physical starting address of the init RAM 51 * disk. 52 * r6 - Optional pointer to the physical ending address of the init RAM 53 * disk. 54 * r7 - Optional pointer to the physical starting address of any kernel 55 * command-line parameters. 56 */ 57 58/* 59 * First executable code - detected and jumped to by the ROM bootstrap 60 * if the code resides in flash (looks for "Nios" at offset 0x0c from 61 * the potential executable image). 62 */ 63 __HEAD 64ENTRY(_start) 65 wrctl status, r0 /* Disable interrupts */ 66 67 /* Initialize all cache lines within the instruction cache */ 68 movia r1, NIOS2_ICACHE_SIZE 69 movui r2, NIOS2_ICACHE_LINE_SIZE 70 71icache_init: 72 initi r1 73 sub r1, r1, r2 74 bgt r1, r0, icache_init 75 br 1f 76 77 /* 78 * This is the default location for the exception handler. Code in jump 79 * to our handler 80 */ 81ENTRY(exception_handler_hook) 82 movia r24, inthandler 83 jmp r24 84 85ENTRY(fast_handler) 86 nextpc et 87helper: 88 stw r3, r3save - helper(et) 89 90 rdctl r3 , pteaddr 91 srli r3, r3, 12 92 slli r3, r3, 2 93 movia et, pgd_current 94 95 ldw et, 0(et) 96 add r3, et, r3 97 ldw et, 0(r3) 98 99 rdctl r3, pteaddr 100 andi r3, r3, 0xfff 101 add et, r3, et 102 ldw et, 0(et) 103 wrctl tlbacc, et 104 nextpc et 105helper2: 106 ldw r3, r3save - helper2(et) 107 subi ea, ea, 4 108 eret 109r3save: 110 .word 0x0 111ENTRY(fast_handler_end) 112 1131: 114 /* 115 * After the instruction cache is initialized, the data cache must 116 * also be initialized. 117 */ 118 movia r1, NIOS2_DCACHE_SIZE 119 movui r2, NIOS2_DCACHE_LINE_SIZE 120 121dcache_init: 122 initd 0(r1) 123 sub r1, r1, r2 124 bgt r1, r0, dcache_init 125 126 nextpc r1 /* Find out where we are */ 127chkadr: 128 movia r2, chkadr 129 beq r1, r2,finish_move /* We are running in RAM done */ 130 addi r1, r1,(_start - chkadr) /* Source */ 131 movia r2, _start /* Destination */ 132 movia r3, __bss_start /* End of copy */ 133 134loop_move: /* r1: src, r2: dest, r3: last dest */ 135 ldw r8, 0(r1) /* load a word from [r1] */ 136 stw r8, 0(r2) /* store a word to dest [r2] */ 137 flushd 0(r2) /* Flush cache for safety */ 138 addi r1, r1, 4 /* inc the src addr */ 139 addi r2, r2, 4 /* inc the dest addr */ 140 blt r2, r3, loop_move 141 142 movia r1, finish_move /* VMA(_start)->l1 */ 143 jmp r1 /* jmp to _start */ 144 145finish_move: 146 147 /* Mask off all possible interrupts */ 148 wrctl ienable, r0 149 150 /* Clear .bss */ 151 movia r2, __bss_start 152 movia r1, __bss_stop 1531: 154 stb r0, 0(r2) 155 addi r2, r2, 1 156 bne r1, r2, 1b 157 158 movia r1, init_thread_union /* set stack at top of the task union */ 159 addi sp, r1, THREAD_SIZE 160 movia r2, _current_thread /* Remember current thread */ 161 stw r1, 0(r2) 162 163 movia r1, nios2_boot_init /* save args r4-r7 passed from u-boot */ 164 callr r1 165 166 movia r1, start_kernel /* call start_kernel as a subroutine */ 167 callr r1 168 169 /* If we return from start_kernel, break to the oci debugger and 170 * buggered we are. 171 */ 172 break 173 174 /* End of startup code */ 175.set at 176