1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Head.S contains the MIPS exception handler and startup code. 7 * 8 * Copyright (C) 1994, 1995 Waldorf Electronics 9 * Written by Ralf Baechle and Andreas Busse 10 * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Ralf Baechle 11 * Copyright (C) 1999 Silicon Graphics, Inc. 12 */ 13#include <linux/config.h> 14#include <linux/init.h> 15#include <asm/asm.h> 16#include <asm/regdef.h> 17#include <asm/processor.h> 18#include <asm/mipsregs.h> 19#include <asm/stackframe.h> 20#include <asm/pgtable.h> 21#include <asm/sn/addrs.h> 22#include <asm/sn/sn0/hubni.h> 23#include <asm/sn/klkernvars.h> 24 25 .macro ARC64_TWIDDLE_PC 26#if defined(CONFIG_ARC64) || defined(CONFIG_MAPPED_KERNEL) 27 /* We get launched at a XKPHYS address but the kernel is linked to 28 run at a KSEG0 address, so jump there. */ 29 PTR_LA t0, \@f 30 jr t0 31\@: 32#endif 33 .endm 34 35#ifdef CONFIG_SGI_IP27 36 /* 37 * outputs the local nasid into res. IP27 stuff. 38 */ 39 .macro GET_NASID_ASM res 40 dli \res, LOCAL_HUB_ADDR(NI_STATUS_REV_ID) 41 ld \res, (\res) 42 and \res, NSRI_NODEID_MASK 43 dsrl \res, NSRI_NODEID_SHFT 44 .endm 45#endif /* CONFIG_SGI_IP27 */ 46 47 /* 48 * inputs are the text nasid in t1, data nasid in t2. 49 */ 50 .macro MAPPED_KERNEL_SETUP_TLB 51#ifdef CONFIG_MAPPED_KERNEL 52 /* 53 * This needs to read the nasid - assume 0 for now. 54 * Drop in 0xffffffffc0000000 in tlbhi, 0+VG in tlblo_0, 55 * 0+DVG in tlblo_1. 56 */ 57 dli t0, 0xffffffffc0000000 58 dmtc0 t0, CP0_ENTRYHI 59 li t0, 0x1c000 # Offset of text into node memory 60 dsll t1, NASID_SHFT # Shift text nasid into place 61 dsll t2, NASID_SHFT # Same for data nasid 62 or t1, t1, t0 # Physical load address of kernel text 63 or t2, t2, t0 # Physical load address of kernel data 64 dsrl t1, 12 # 4K pfn 65 dsrl t2, 12 # 4K pfn 66 dsll t1, 6 # Get pfn into place 67 dsll t2, 6 # Get pfn into place 68 li t0, ((_PAGE_GLOBAL|_PAGE_VALID| _CACHE_CACHABLE_COW) >> 6) 69 or t0, t0, t1 70 mtc0 t0, CP0_ENTRYLO0 # physaddr, VG, cach exlwr 71 li t0, ((_PAGE_GLOBAL|_PAGE_VALID| _PAGE_DIRTY|_CACHE_CACHABLE_COW) >> 6) 72 or t0, t0, t2 73 mtc0 t0, CP0_ENTRYLO1 # physaddr, DVG, cach exlwr 74 li t0, 0x1ffe000 # MAPPED_KERN_TLBMASK, TLBPGMASK_16M 75 mtc0 t0, CP0_PAGEMASK 76 li t0, 0 # KMAP_INX 77 mtc0 t0, CP0_INDEX 78 li t0, 1 79 mtc0 t0, CP0_WIRED 80 tlbwi 81#else 82 mtc0 zero, CP0_WIRED 83#endif 84 .endm 85 86 .text 87 88EXPORT(stext) # used for profiling 89EXPORT(_stext) 90 91 __INIT 92 93NESTED(kernel_entry, 16, sp) # kernel entry point 94 95 ori sp, 0xf # align stack on 16 byte. 96 xori sp, 0xf 97 98#ifdef CONFIG_SGI_IP27 99 GET_NASID_ASM t1 100 move t2, t1 # text and data are here 101 MAPPED_KERNEL_SETUP_TLB 102#endif /* IP27 */ 103 104 ARC64_TWIDDLE_PC 105 106 CLI # disable interrupts 107 108 /* 109 * The firmware/bootloader passes argc/argp/envp 110 * to us as arguments. But clear bss first because 111 * the romvec and other important info is stored there 112 * by prom_init(). 113 */ 114 PTR_LA t0, _edata 115 sd zero, (t0) 116 PTR_LA t1, (_end - 8) 1171: 118 daddiu t0, 8 119 sd zero, (t0) 120 bne t0, t1, 1b 121 122 PTR_LA $28, init_task_union # init current pointer 123 daddiu sp, $28, KERNEL_STACK_SIZE-32 124 set_saved_sp sp, t0, t1 125 dsubu sp, 4*SZREG # init stack pointer 126 127 j init_arch 128 END(kernel_entry) 129 130#ifdef CONFIG_SMP 131/* 132 * SMP slave cpus entry point. Board specific code for bootstrap calls this 133 * function after setting up the stack and gp registers. 134 */ 135NESTED(smp_bootstrap, 16, sp) 136#ifdef CONFIG_SGI_IP27 137 GET_NASID_ASM t1 138 dli t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \ 139 KLDIR_OFF_POINTER + K0BASE 140 dsll t1, NASID_SHFT 141 or t0, t0, t1 142 ld t0, 0(t0) # t0 points to kern_vars struct 143 lh t1, KV_RO_NASID_OFFSET(t0) 144 lh t2, KV_RW_NASID_OFFSET(t0) 145 MAPPED_KERNEL_SETUP_TLB 146 ARC64_TWIDDLE_PC 147#endif /* CONFIG_SGI_IP27 */ 148 149 CLI 150 151 /* 152 * For the moment set ST0_KU so the CPU will not spit fire when 153 * executing 64-bit instructions. The full initialization of the 154 * CPU's status register is done later in per_cpu_trap_init(). 155 */ 156 mfc0 t0, CP0_STATUS 157 or t0, ST0_KX 158 mtc0 t0, CP0_STATUS 159 160 jal start_secondary # XXX: IP27: cboot 161 162 END(smp_bootstrap) 163#endif /* CONFIG_SMP */ 164 165 __FINIT 166 167 declare_saved_sp 168 169 .macro page name, order=0 170 .globl \name 171\name: .size \name, (_PAGE_SIZE << \order) 172 .org . + (_PAGE_SIZE << \order) 173 .type \name, @object 174 .endm 175 176 .data 177 .align 12 178 179 page swapper_pg_dir, _PGD_ORDER 180 page invalid_pmd_table, _PMD_ORDER 181 page invalid_pte_table, _PTE_ORDER 182 page kptbl, _PGD_ORDER 183 .globl ekptbl 184 page kpmdtbl, 0 185ekptbl: 186