1/* $NetBSD: locore.S,v 1.26 2002/03/09 23:35:58 chs Exp $ */ 2 3/* 4 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 5 * Copyright (C) 1995, 1996 TooLs GmbH. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by TooLs GmbH. 19 * 4. The name of TooLs GmbH may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34#include "opt_ddb.h" 35#include "opt_ipkdb.h" 36#include "opt_lockdebug.h" 37#include "opt_multiprocessor.h" 38#include "assym.h" 39 40#include <sys/syscall.h> 41 42#include <machine/param.h> 43#include <machine/pmap.h> 44#include <machine/psl.h> 45#include <machine/trap.h> 46#include <machine/asm.h> 47 48#ifndef OLDPMAP 49#include <machine/vmparam.h> 50#endif 51 52#include <powerpc/spr.h> 53/* 54 * Some instructions gas doesn't understand (yet?) 55 */ 56#define bdneq bdnzf 2, 57 58#define INTSTK (8*1024) /* 8K interrupt stack */ 59#define SPILLSTK 1024 /* 1K spill stack */ 60 61/* 62 * Globals 63 */ 64GLOBAL(startsym) 65 .long 0 /* start of symbol table */ 66GLOBAL(endsym) 67 .long 0 /* end of symbol table */ 68GLOBAL(proc0paddr) 69 .long 0 /* proc0 p_addr */ 70 71/* 72 * File-scope for locore.S 73 */ 74 .data 75idle_u: 76 .long 0 /* fake uarea during idle after exit */ 77openfirmware_entry: 78 .long 0 /* openfirmware entry point */ 79 80/* 81 * This symbol is here for the benefit of kvm_mkdb, and is supposed to 82 * mark the start of kernel text. 83 */ 84 .text 85 .globl _C_LABEL(kernel_text) 86_C_LABEL(kernel_text): 87 88/* 89 * Startup entry. Note, this must be the first thing in the text 90 * segment! 91 */ 92 .text 93 .globl __start 94__start: 95#ifdef FIRMWORKSBUGS 96 mfmsr 0 97 andi. 0,0,PSL_IR|PSL_DR 98 beq 1f 99 100 bl _C_LABEL(ofwr_init) 1011: 102#endif 103 li 0,0 104 mtmsr 0 /* Disable FPU/MMU/exceptions */ 105 isync 106 107 /* compute end of kernel memory */ 108#ifdef DDB 109 /* skip symbol table */ 110 cmpwi 6,0 111 beq 1f 112 add 9,6,7 /* r9 = args + l */ 113 114 /* If the resulting address is misaligned, abort. */ 115 andi. 8,9,3 116 bne 1f /* misaligned */ 117 118 /* First, see if the loader even put the symbols there. */ 119 lwz 9,-12(9) 120 lis 8,0x19730224@h /* magic number */ 121 ori 8,8,0x19730224@l 122 cmplw 8,9 123 bne 1f /* nope */ 124 125 /* Okay, ssym and esym are here -- fetch them. */ 126 add 9,6,7 127 lwz 9,-8(9) 128 lis 8,_C_LABEL(startsym)@ha 129 stw 9,_C_LABEL(startsym)@l(8) 130 131 add 9,6,7 132 lwz 9,-4(9) 133 lis 8,_C_LABEL(endsym)@ha 134 stw 9,_C_LABEL(endsym)@l(8) 135 136 mr 8,9 /* r8 = end of kernel + symbols */ 137 b 2f 1381: 139 lis 8,_C_LABEL(end)@ha 140 addi 8,8,_C_LABEL(end)@l 1412: 142#else 143 lis 8,_C_LABEL(end)@ha 144 addi 8,8,_C_LABEL(end)@l 145#endif 146 li 9,PGOFSET 147 add 8,8,9 148 andc 8,8,9 149 lis 9,_C_LABEL(OF_buf)@ha 150 stw 8,_C_LABEL(OF_buf)@l(9) 151 addi 8,8,NBPG 152 lis 9,idle_u@ha 153 stw 8,idle_u@l(9) 154 addi 8,8,USPACE /* space for idle_u */ 155 lis 9,_C_LABEL(proc0paddr)@ha 156 stw 8,_C_LABEL(proc0paddr)@l(9) 157 addi 1,8,USPACE-FRAMELEN /* stackpointer for proc0 */ 158 mr 4,1 /* end of mem reserved for kernel */ 159 xor 0,0,0 160 stwu 0,-16(1) /* end of stack chain */ 161 162 lis 8,openfirmware_entry@ha 163 stw 5,openfirmware_entry@l(8) /* save client interface handler */ 164 lis 3,__start@ha 165 addi 3,3,__start@l 166 mr 5,6 /* args string */ 167 bl _C_LABEL(initppc) 168 bl _C_LABEL(main) 169 b _C_LABEL(OF_exit) 170 171/* 172 * OpenFirmware entry point 173 */ 174ENTRY(openfirmware) 175 mflr 0 /* save return address */ 176 stw 0,4(1) 177 stwu 1,-16(1) /* setup stack frame */ 178 179 mfmsr 4 /* save msr */ 180 stw 4,8(1) 181 182 lis 4,openfirmware_entry@ha /* get firmware entry point */ 183 lwz 4,openfirmware_entry@l(4) 184 mtlr 4 185 186 li 0,0 /* turn off any ints/mmu/etc. */ 187 mtmsr 0 188 isync 189 190 blrl /* call OpenFirmware */ 191 192 lwz 4,8(1) /* restore msr */ 193 mtmsr 4 194 isync 195 196 lwz 1,0(1) /* and return */ 197 lwz 0,4(1) 198 mtlr 0 199 blr 200 201/* 202 * Switch to/from OpenFirmware real mode stack 203 * 204 * Note: has to be called as the very first thing in OpenFirmware interface 205 * routines. 206 * E.g.: 207 * int 208 * OF_xxx(arg1, arg2) 209 * type arg1, arg2; 210 * { 211 * static struct { 212 * char *name; 213 * int nargs; 214 * int nreturns; 215 * char *method; 216 * int arg1; 217 * int arg2; 218 * int ret; 219 * } args = { 220 * "xxx", 221 * 2, 222 * 1, 223 * }; 224 * 225 * ofw_stack(); 226 * args.arg1 = arg1; 227 * args.arg2 = arg2; 228 * if (openfirmware(&args) < 0) 229 * return -1; 230 * return args.ret; 231 * } 232 */ 233 234 .local firmstk 235 .comm firmstk,NBPG,8 236 237ENTRY(ofw_stack) 238 mfmsr 8 /* turn off interrupts */ 239 andi. 0,8,~(PSL_EE|PSL_RI)@l 240 mtmsr 0 241 stw 8,4(1) /* abuse return address slot */ 242 243 lwz 5,0(1) /* get length of stack frame */ 244 subf 5,1,5 245 246 lis 7,firmstk+NBPG-8@ha 247 addi 7,7,firmstk+NBPG-8@l 248 lis 6,ofw_back@ha 249 addi 6,6,ofw_back@l 250 subf 4,5,7 /* make room for stack frame on 251 new stack */ 252 stw 6,-4(7) /* setup return pointer */ 253 stwu 1,-8(7) 254 255 stw 7,-8(4) 256 257 addi 3,1,8 258 addi 1,4,-8 259 subi 5,5,8 260 261 b _C_LABEL(ofbcopy) /* and copy it */ 262 263ofw_back: 264 lwz 1,0(1) /* get callers original stack pointer */ 265 266 lwz 0,4(1) /* get saved msr from abused slot */ 267 mtmsr 0 268 269 lwz 1,0(1) /* return */ 270 lwz 0,4(1) 271 mtlr 0 272 blr 273 274/* 275 * Pull in common switch / setfault code. 276 */ 277#include <powerpc/powerpc/locore_subr.S> 278 279/* 280 * Pull in common trap vector code. 281 */ 282#include <powerpc/powerpc/trap_subr.S> 283