1 /* 1 /* 2 * Copyright (C) 2009 Wind River Systems Inc << 3 * Implemented by fredrik.markstrom@gmail.co << 4 * Copyright (C) 2004 Microtronix Datacom Ltd << 5 * Copyright (C) 2001 Vic Phillips, Microtroni << 6 * << 7 * Based on head.S for Altera's Excalibur deve << 8 * << 9 * Based on the following from the Excalibur s << 10 * NA_MemoryMap.s, NR_JumpToStart.s, NR_S << 11 * << 12 * This file is subject to the terms and condi 2 * This file is subject to the terms and conditions of the GNU General Public 13 * License. See the file "COPYING" in the main !! 3 * License. See the file "COPYING" in the main directory of this archive 14 * for more details. 4 * for more details. >> 5 * >> 6 * Copyright (C) 1994, 1995 Waldorf Electronics >> 7 * Written by Ralf Baechle and Andreas Busse >> 8 * Copyright (C) 1994 - 99, 2003, 06 Ralf Baechle >> 9 * Copyright (C) 1996 Paul M. Antoine >> 10 * Modified for DECStation and hence R3000 support by Paul M. Antoine >> 11 * Further modifications by David S. Miller and Harald Koerfgen >> 12 * Copyright (C) 1999 Silicon Graphics, Inc. >> 13 * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com >> 14 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. 15 */ 15 */ 16 << 17 #include <linux/init.h> 16 #include <linux/init.h> 18 #include <linux/linkage.h> !! 17 #include <linux/threads.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 18 26 /* !! 19 #include <asm/addrspace.h> 27 * ZERO_PAGE is a special page that is used fo !! 20 #include <asm/asm.h> 28 * data and COW. !! 21 #include <asm/asmmacro.h> 29 */ !! 22 #include <asm/irqflags.h> 30 .data !! 23 #include <asm/regdef.h> 31 .global empty_zero_page !! 24 #include <asm/mipsregs.h> 32 .align 12 !! 25 #include <asm/stackframe.h> 33 empty_zero_page: << 34 .space PAGE_SIZE << 35 26 36 /* !! 27 #include <kernel-entry-init.h> 37 * This global variable is used as an extensio << 38 * STATUS register to emulate a user/superviso << 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 informat << 50 * r5 - Optional pointer to the physical sta << 51 * disk. << 52 * r6 - Optional pointer to the physical end << 53 * disk. << 54 * r7 - Optional pointer to the physical sta << 55 * command-line parameters. << 56 */ << 57 28 58 /* !! 29 /* 59 * First executable code - detected and jumped !! 30 * For the moment disable interrupts, mark the kernel mode and 60 * if the code resides in flash (looks for "Ni !! 31 * set ST0_KX so that the CPU does not spit fire when using 61 * the potential executable image). !! 32 * 64-bit addresses. A full initialization of the CPU's status 62 */ !! 33 * register is done later in per_cpu_trap_init(). 63 __HEAD !! 34 */ 64 ENTRY(_start) !! 35 .macro setup_c0_status set clr 65 wrctl status, r0 /* Dis !! 36 .set push 66 !! 37 mfc0 t0, CP0_STATUS 67 /* Initialize all cache lines within t !! 38 or t0, ST0_KERNEL_CUMASK|\set|0x1f|\clr 68 movia r1, NIOS2_ICACHE_SIZE !! 39 xor t0, 0x1f|\clr 69 movui r2, NIOS2_ICACHE_LINE_SIZE !! 40 mtc0 t0, CP0_STATUS 70 !! 41 .set noreorder 71 icache_init: !! 42 sll zero,3 # ehb 72 initi r1 !! 43 .set pop 73 sub r1, r1, r2 !! 44 .endm 74 bgt r1, r0, icache_init !! 45 75 br 1f !! 46 .macro setup_c0_status_pri >> 47 #ifdef CONFIG_64BIT >> 48 setup_c0_status ST0_KX 0 >> 49 #else >> 50 setup_c0_status 0 0 >> 51 #endif >> 52 .endm >> 53 >> 54 .macro setup_c0_status_sec >> 55 #ifdef CONFIG_64BIT >> 56 setup_c0_status ST0_KX ST0_BEV >> 57 #else >> 58 setup_c0_status 0 ST0_BEV >> 59 #endif >> 60 .endm 76 61 >> 62 #ifndef CONFIG_NO_EXCEPT_FILL 77 /* 63 /* 78 * This is the default location for th !! 64 * Reserved space for exception handlers. 79 * to our handler !! 65 * Necessary for machines which link their kernels at KSEG0. 80 */ 66 */ 81 ENTRY(exception_handler_hook) !! 67 .fill 0x400 82 movia r24, inthandler !! 68 #endif 83 jmp r24 << 84 << 85 ENTRY(fast_handler) << 86 nextpc et << 87 helper: << 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 << 105 helper2: << 106 ldw r3, r3save - helper2(et) << 107 subi ea, ea, 4 << 108 eret << 109 r3save: << 110 .word 0x0 << 111 ENTRY(fast_handler_end) << 112 69 113 1: !! 70 EXPORT(_stext) >> 71 >> 72 #ifdef CONFIG_BOOT_RAW 114 /* 73 /* 115 * After the instruction cache is init !! 74 * Give us a fighting chance of running if execution beings at the 116 * also be initialized. !! 75 * kernel load address. This is needed because this platform does >> 76 * not have a ELF loader yet. 117 */ 77 */ 118 movia r1, NIOS2_DCACHE_SIZE !! 78 FEXPORT(__kernel_entry) 119 movui r2, NIOS2_DCACHE_LINE_SIZE !! 79 j kernel_entry >> 80 #endif /* CONFIG_BOOT_RAW */ 120 81 121 dcache_init: !! 82 __REF 122 initd 0(r1) !! 83 123 sub r1, r1, r2 !! 84 NESTED(kernel_entry, 16, sp) # kernel entry point 124 bgt r1, r0, dcache_init << 125 << 126 nextpc r1 /* Fin << 127 chkadr: << 128 movia r2, chkadr << 129 beq r1, r2,finish_move /* We << 130 addi r1, r1,(_start - chkadr) << 131 movia r2, _start /* Des << 132 movia r3, __bss_start /* End << 133 << 134 loop_move: /* r1: << 135 ldw r8, 0(r1) /* loa << 136 stw r8, 0(r2) /* sto << 137 flushd 0(r2) /* Flu << 138 addi r1, r1, 4 /* inc << 139 addi r2, r2, 4 /* inc << 140 blt r2, r3, loop_move << 141 << 142 movia r1, finish_move /* VMA << 143 jmp r1 /* jmp << 144 << 145 finish_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 << 153 1: << 154 stb r0, 0(r2) << 155 addi r2, r2, 1 << 156 bne r1, r2, 1b << 157 << 158 movia r1, init_thread_union /* set << 159 addi sp, r1, THREAD_SIZE << 160 movia r2, _current_thread /* Rem << 161 stw r1, 0(r2) << 162 85 163 movia r1, nios2_boot_init /* sav !! 86 kernel_entry_setup # cpu specific setup 164 callr r1 << 165 87 166 movia r1, start_kernel /* cal !! 88 setup_c0_status_pri 167 callr r1 << 168 89 169 /* If we return from start_kernel, bre !! 90 /* We might not get launched at the address the kernel is linked to, 170 * buggered we are. !! 91 so we jump there. */ >> 92 PTR_LA t0, 0f >> 93 jr t0 >> 94 0: >> 95 >> 96 PTR_LA t0, __bss_start # clear .bss >> 97 LONG_S zero, (t0) >> 98 PTR_LA t1, __bss_stop - LONGSIZE >> 99 1: >> 100 PTR_ADDIU t0, LONGSIZE >> 101 LONG_S zero, (t0) >> 102 bne t0, t1, 1b >> 103 >> 104 LONG_S a0, fw_arg0 # firmware arguments >> 105 LONG_S a1, fw_arg1 >> 106 LONG_S a2, fw_arg2 >> 107 LONG_S a3, fw_arg3 >> 108 >> 109 MTC0 zero, CP0_CONTEXT # clear context register >> 110 #ifdef CONFIG_64BIT >> 111 MTC0 zero, CP0_XCONTEXT >> 112 #endif >> 113 PTR_LA $28, init_thread_union >> 114 /* Set the SP after an empty pt_regs. */ >> 115 PTR_LI sp, _THREAD_SIZE - 32 - PT_SIZE >> 116 PTR_ADDU sp, $28 >> 117 back_to_back_c0_hazard >> 118 set_saved_sp sp, t0, t1 >> 119 PTR_SUBU sp, 4 * SZREG # init stack pointer >> 120 >> 121 #ifdef CONFIG_RELOCATABLE >> 122 /* Copy kernel and apply the relocations */ >> 123 jal relocate_kernel >> 124 >> 125 /* Repoint the sp into the new kernel image */ >> 126 PTR_LI sp, _THREAD_SIZE - 32 - PT_SIZE >> 127 PTR_ADDU sp, $28 >> 128 set_saved_sp sp, t0, t1 >> 129 PTR_SUBU sp, 4 * SZREG # init stack pointer >> 130 >> 131 /* >> 132 * relocate_kernel returns the entry point either >> 133 * in the relocated kernel or the original if for >> 134 * some reason relocation failed - jump there now >> 135 * with instruction hazard barrier because of the >> 136 * newly sync'd icache. 171 */ 137 */ 172 break !! 138 jr.hb v0 >> 139 #else /* !CONFIG_RELOCATABLE */ >> 140 j start_kernel >> 141 #endif /* !CONFIG_RELOCATABLE */ >> 142 END(kernel_entry) 173 143 174 /* End of startup code */ !! 144 #ifdef CONFIG_SMP 175 .set at !! 145 /* >> 146 * SMP slave cpus entry point. Board specific code for bootstrap calls this >> 147 * function after setting up the stack and gp registers. >> 148 */ >> 149 NESTED(smp_bootstrap, 16, sp) >> 150 smp_slave_setup >> 151 setup_c0_status_sec >> 152 j start_secondary >> 153 END(smp_bootstrap) >> 154 #endif /* CONFIG_SMP */
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.