📄 locore.s
字号:
/* * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Lawrence Berkeley Laboratory. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)locore.s 8.4 (Berkeley) 12/10/93 * * from: $Header: locore.s,v 1.51 93/04/21 06:19:37 torek Exp $ */#define LOCORE#include "assym.s"#include <sparc/sparc/intreg.h>#include <sparc/sparc/timerreg.h>#ifdef notyet#include <sparc/sparc/vaddrs.h>#include <sparc/dev/zsreg.h>#endif#include <machine/ctlreg.h>#include <machine/psl.h>#include <machine/signal.h>#include <machine/trap.h>/* * GNU assembler does not understand `.empty' directive; Sun assembler * gripes about labels without it. To allow cross-compilation using * the Sun assembler, and because .empty directives are useful documentation, * we use this trick. */#ifdef SUN_AS#define EMPTY .empty#else#define EMPTY /* .empty */#endif/* use as needed to align things on longword boundaries */#define ALIGN .align 4/* * CCFSZ (C Compiler Frame SiZe) is the size of a stack frame required if * a function is to call C code. It should be just 64, but Sun defined * their frame with space to hold arguments 0 through 5 (plus some junk), * and varargs routines (such as printf) demand this, and gcc uses this * area at times anyway. */#define CCFSZ 96/* * A handy macro for maintaining instrumentation counters. * Note that this clobbers %o0 and %o1. Normal usage is * something like: * foointr: * TRAP_SETUP(...) ! makes %o registers safe * INCR(_cnt+V_FOO) ! count a foo */#define INCR(what) \ sethi %hi(what), %o0; \ ld [%o0 + %lo(what)], %o1; \ inc %o1; \ st %o1, [%o0 + %lo(what)]/* * Another handy macro: load one register window, given `base' address. * This can be either a simple register (e.g., %sp) or include an initial * offset (e.g., %g6 + PCB_RW). */#define LOADWIN(addr) \ ldd [addr], %l0; \ ldd [addr + 8], %l2; \ ldd [addr + 16], %l4; \ ldd [addr + 24], %l6; \ ldd [addr + 32], %i0; \ ldd [addr + 40], %i2; \ ldd [addr + 48], %i4; \ ldd [addr + 56], %i6/* * To return from trap we need the two-instruction sequence * `jmp %l1; rett %l2', which is defined here for convenience. */#define RETT jmp %l1; rett %l2 .data/* * The interrupt stack. * * This is the very first thing in the data segment, and therefore has * the lowest kernel stack address. We count on this in the interrupt * trap-frame setup code, since we may need to switch from the kernel * stack to the interrupt stack (iff we are not already on the interrupt * stack). One sethi+cmp is all we need since this is so carefully * arranged. */ .globl _intstack .globl _eintstack_intstack: .skip 4 * NBPG ! 16k = 128 128-byte stack frames_eintstack:/* * When a process exits and its u. area goes away, we set cpcb to point * to this `u.', leaving us with something to use for an interrupt stack, * and letting all the register save code have a pcb_uw to examine. * This is also carefully arranged (to come just before u0, so that * process 0's kernel stack can quietly overrun into it during bootup, if * we feel like doing that). */ .globl _idle_u_idle_u: .skip UPAGES * NBPG/* * Process 0's u. * * This must be aligned on an 8 byte boundary. */ .globl _u0_u0: .skip UPAGES * NBPGestack0:#ifdef KGDB/* * Another item that must be aligned, easiest to put it here. */KGDB_STACK_SIZE = 2048 .globl _kgdb_stack_kgdb_stack: .skip KGDB_STACK_SIZE ! hope this is enough#endif/* * _cpcb points to the current pcb (and hence u. area). * Initially this is the special one. */ .globl _cpcb_cpcb: .word _u0 .text/* * The first thing in the real text segment is the trap vector table, * which must be aligned on a 4096 byte boundary. The text segment * starts beyond page 0 of KERNBASE so that there is a red zone * between user and kernel space. Since the boot ROM loads us at * 0x4000, it is far easier to start at KERNBASE+0x4000 than to * buck the trend. This is four pages in; we can stuff something * into the three pages left beneath us later ... like, oh, say, the * message buffer (1 page). */ .globl _msgbufmsgbufsize = NBPG ! 1 page for msg buffer_msgbuf = KERNBASE + NBPG/* * The remaining two physical pages are currently unused. We need to * map the interrupt enable register very early on in the boot process, * so that we can handle NMIs (parity errors) halfway sensibly during * boot. We use virtual address f8002000 (`page 2') for this, wasting * 4096 bytes of physical memory. */IE_reg_addr = _msgbuf + msgbufsize ! this page not used; points to IEreg/* * Each trap has room for four instructions, of which one perforce must * be a branch. On entry the hardware has copied pc and npc to %l1 and * %l2 respectively. We use two more to read the psr into %l0, and to * put the trap type value into %l3 (with a few exceptions below). * We could read the trap type field of %tbr later in the code instead, * but there is no need, and that would require more instructions * (read+mask, vs 1 `mov' here). * * I used to generate these numbers by address arithmetic, but gas's * expression evaluator has about as much sense as your average slug * (oddly enough, the code looks about as slimy too). Thus, all the * trap numbers are given as arguments to the trap macros. This means * there is one line per trap. Sigh. * * Note that only the local registers may be used, since the trap * window is potentially the last window. Its `in' registers are * the previous window's outs (as usual), but more important, its * `out' registers may be in use as the `topmost' window's `in' registers. * The global registers are of course verboten (well, until we save * them away). * * Hardware interrupt vectors can be `linked'---the linkage is to regular * C code---or rewired to fast in-window handlers. The latter are good * for unbuffered hardware like the Zilog serial chip and the AMD audio * chip, where many interrupts can be handled trivially with pseudo-DMA or * similar. Only one `fast' interrupt can be used per level, however, and * direct and `fast' interrupts are incompatible. Routines in intr.c * handle setting these, with optional paranoia. */ /* regular vectored traps */#define VTRAP(type, label) \ mov (type), %l3; b label; mov %psr, %l0; nop /* hardware interrupts (can be linked or made `fast') */#define HARDINT(lev) \ mov (lev), %l3; b _sparc_interrupt; mov %psr, %l0; nop /* software interrupts (may not be made direct, sorry---but you should not be using them trivially anyway) */#define SOFTINT(lev, bit) \ mov (lev), %l3; mov (bit), %l4; b softintr; mov %psr, %l0 /* traps that just call trap() */#define TRAP(type) VTRAP(type, slowtrap) /* architecturally undefined traps (cause panic) */#define UTRAP(type) VTRAP(type, slowtrap) /* software undefined traps (may be replaced) */#define STRAP(type) VTRAP(type, slowtrap)/* breakpoint acts differently under kgdb */#ifdef KGDB#define BPT VTRAP(T_BREAKPOINT, bpt)#define BPT_KGDB_EXEC VTRAP(T_KGDB_EXEC, bpt)#else#define BPT TRAP(T_BREAKPOINT)#define BPT_KGDB_EXEC TRAP(T_KGDB_EXEC)#endif/* special high-speed 1-instruction-shaved-off traps (get nothing in %l3) */#ifdef COMPAT_SUNOS#define SUN_SYSCALL b sun_syscall; mov %psr, %l0; nop; nop#else#define SUN_SYSCALL TRAP(T_SUN_SYSCALL)#endif#define SYSCALL b syscall; mov %psr, %l0; nop; nop#define WINDOW_OF b window_of; mov %psr, %l0; nop; nop#define WINDOW_UF b window_uf; mov %psr, %l0; nop; nop#ifdef notyet#define ZS_INTERRUPT b zshard; mov %psr, %l0; nop; nop#else#define ZS_INTERRUPT HARDINT(12)#endif .globl start .globl _trapbasestart:_trapbase:/* trap 0 is special since we cannot receive it */ b dostart; nop; nop; nop ! 00 = reset (fake) VTRAP(T_TEXTFAULT, memfault) ! 01 = instr. fetch fault TRAP(T_ILLINST) ! 02 = illegal instruction TRAP(T_PRIVINST) ! 03 = privileged instruction TRAP(T_FPDISABLED) ! 04 = fp instr, but EF bit off in psr WINDOW_OF ! 05 = window overflow WINDOW_UF ! 06 = window underflow TRAP(T_ALIGN) ! 07 = address alignment error VTRAP(T_FPE, fp_exception) ! 08 = fp exception VTRAP(T_DATAFAULT, memfault) ! 09 = data fetch fault TRAP(T_TAGOF) ! 0a = tag overflow UTRAP(0x0b) UTRAP(0x0c) UTRAP(0x0d) UTRAP(0x0e) UTRAP(0x0f) UTRAP(0x10) SOFTINT(1, IE_L1) ! 11 = level 1 interrupt HARDINT(2) ! 12 = level 2 interrupt HARDINT(3) ! 13 = level 3 interrupt SOFTINT(4, IE_L4) ! 14 = level 4 interrupt HARDINT(5) ! 15 = level 5 interrupt SOFTINT(6, IE_L6) ! 16 = level 6 interrupt HARDINT(7) ! 17 = level 7 interrupt HARDINT(8) ! 18 = level 8 interrupt HARDINT(9) ! 19 = level 9 interrupt HARDINT(10) ! 1a = level 10 interrupt HARDINT(11) ! 1b = level 11 interrupt ZS_INTERRUPT ! 1c = level 12 (zs) interrupt HARDINT(13) ! 1d = level 13 interrupt HARDINT(14) ! 1e = level 14 interrupt VTRAP(15, nmi) ! 1f = nonmaskable interrupt UTRAP(0x20) UTRAP(0x21) UTRAP(0x22) UTRAP(0x23) UTRAP(0x24) UTRAP(0x25) UTRAP(0x26) UTRAP(0x27) UTRAP(0x28) UTRAP(0x29) UTRAP(0x2a) UTRAP(0x2b) UTRAP(0x2c) UTRAP(0x2d) UTRAP(0x2e) UTRAP(0x2f) UTRAP(0x30) UTRAP(0x31) UTRAP(0x32) UTRAP(0x33) UTRAP(0x34) UTRAP(0x35) TRAP(T_CPDISABLED) ! 36 = coprocessor instr, EC bit off in psr UTRAP(0x37) UTRAP(0x38) UTRAP(0x39) UTRAP(0x3a) UTRAP(0x3b) UTRAP(0x3c) UTRAP(0x3d) UTRAP(0x3e) UTRAP(0x3f) TRAP(T_CPEXCEPTION) ! 40 = coprocessor exception UTRAP(0x41) UTRAP(0x42) UTRAP(0x43) UTRAP(0x44) UTRAP(0x45) UTRAP(0x46) UTRAP(0x47) UTRAP(0x48) UTRAP(0x49) UTRAP(0x4a) UTRAP(0x4b) UTRAP(0x4c) UTRAP(0x4d) UTRAP(0x4e) UTRAP(0x4f) UTRAP(0x50) UTRAP(0x51) UTRAP(0x52) UTRAP(0x53) UTRAP(0x54) UTRAP(0x55) UTRAP(0x56) UTRAP(0x57) UTRAP(0x58) UTRAP(0x59) UTRAP(0x5a) UTRAP(0x5b) UTRAP(0x5c) UTRAP(0x5d) UTRAP(0x5e) UTRAP(0x5f) UTRAP(0x60) UTRAP(0x61) UTRAP(0x62) UTRAP(0x63) UTRAP(0x64) UTRAP(0x65) UTRAP(0x66) UTRAP(0x67) UTRAP(0x68) UTRAP(0x69) UTRAP(0x6a) UTRAP(0x6b) UTRAP(0x6c) UTRAP(0x6d) UTRAP(0x6e) UTRAP(0x6f) UTRAP(0x70) UTRAP(0x71) UTRAP(0x72) UTRAP(0x73) UTRAP(0x74) UTRAP(0x75) UTRAP(0x76) UTRAP(0x77) UTRAP(0x78) UTRAP(0x79) UTRAP(0x7a) UTRAP(0x7b) UTRAP(0x7c) UTRAP(0x7d) UTRAP(0x7e) UTRAP(0x7f) SUN_SYSCALL ! 80 = sun syscall BPT ! 81 = pseudo breakpoint instruction TRAP(T_DIV0) ! 82 = divide by zero TRAP(T_FLUSHWIN) ! 83 = flush windows TRAP(T_CLEANWIN) ! 84 = provide clean windows TRAP(T_RANGECHECK) ! 85 = ??? TRAP(T_FIXALIGN) ! 86 = fix up unaligned accesses TRAP(T_INTOF) ! 87 = integer overflow BPT_KGDB_EXEC ! 88 = enter kernel gdb on kernel startup SYSCALL ! 89 = bsd syscall STRAP(0x8a) STRAP(0x8b) STRAP(0x8c) STRAP(0x8d) STRAP(0x8e) STRAP(0x8f) STRAP(0x90) STRAP(0x91) STRAP(0x92) STRAP(0x93) STRAP(0x94) STRAP(0x95) STRAP(0x96) STRAP(0x97) STRAP(0x98) STRAP(0x99) STRAP(0x9a) STRAP(0x9b) STRAP(0x9c) STRAP(0x9d) STRAP(0x9e) STRAP(0x9f) STRAP(0xa0) STRAP(0xa1) STRAP(0xa2) STRAP(0xa3) STRAP(0xa4) STRAP(0xa5) STRAP(0xa6) STRAP(0xa7) STRAP(0xa8) STRAP(0xa9) STRAP(0xaa) STRAP(0xab) STRAP(0xac) STRAP(0xad) STRAP(0xae) STRAP(0xaf) STRAP(0xb0) STRAP(0xb1) STRAP(0xb2)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -