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