📄 locore.s
字号:
/* * Copyright (c) 1988 University of Utah. * Copyright (c) 1992 OMRON Corporation. * Copyright (c) 1980, 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * the Systems Programming Group of the University of Utah Computer * Science Department. * * 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. * * from: Utah $Hdr: locore.s 1.62 92/01/20$ * from: hp300/hp300/locore.s 8.5 (Berkeley) 11/14/93 * * @(#)locore.s 8.4 (Berkeley) 12/6/93 *//* * STACKCHECK enables two types of kernel stack checking: * 1. stack "overflow". On every clock interrupt we ensure that * the current kernel stack has not grown into the user struct * page, i.e. size exceeded UPAGES-1 pages. * 2. stack "underflow". Before every rte to user mode we ensure * that we will be exactly at the base of the stack after the * exception frame has been popped. * Both checks are performed at splclock since they operate on the * global temporary stack. *//* #define STACKCHECK */#include "assym.s"#include <luna68k/luna68k/vectors.s>/* * Temporary stack for a variety of purposes. * Try and make this the first thing is the data segment so it * is page aligned. Note that if we overflow here, we run into * our text segment. */ .data .space NBPGtmpstk: .text/* * This is where we wind up if the kernel jumps to location 0. * (i.e. a bogus PC) This is known to immediately follow the vector * table and is hence at 0x400 (see reset vector in vectors.s). */ .globl _panic pea Ljmp0panic jbsr _panic /* NOTREACHED */Ljmp0panic: .asciz "kernel jump to zero" .even/* * Do a dump. * Called by auto-restart. */ .globl _dumpsys .globl _doadump_doadump: jbsr _dumpsys jbsr _doboot /*NOTREACHED*//* * Trap/interrupt vector routines */ .globl _trap, _nofault, _longjmp_buserr: tstl _nofault | device probe? jeq Lberr | no, handle as usual movl _nofault,sp@- | yes, jbsr _longjmp | longjmp(nofault)Lberr:#if defined(LUNA2) cmpl #-2,_mmutype | 68040? jne _addrerr | no, skip clrl sp@- | stack adjust count moveml #0xFFFF,sp@- | save user registers movl usp,a0 | save the user SP movl a0,sp@(FR_SP) | in the savearea lea sp@(FR_HW),a1 | grab base of HW berr frame moveq #0,d0 movw a1@(12),d0 | grab SSW movl a1@(20),d1 | and fault VA btst #11,d0 | check for mis-aligned access jeq Lberr2 | no, skip addl #3,d1 | yes, get into next page andl #PG_FRAME,d1 | and truncateLberr2: movl d1,sp@- | push fault VA movl d0,sp@- | and padded SSW btst #10,d0 | ATC bit set? jeq Lisberr | no, must be a real bus error movc dfc,d1 | yes, get MMU fault movc d0,dfc | store faulting function code movl sp@(4),a0 | get faulting address .word 0xf568 | ptestr a0@ movc d1,dfc .long 0x4e7a0805 | movc mmusr,d0 movw d0,sp@ | save (ONLY LOW 16 BITS!) jra Lismerr#endif_addrerr: clrl sp@- | stack adjust count moveml #0xFFFF,sp@- | save user registers movl usp,a0 | save the user SP movl a0,sp@(FR_SP) | in the savearea lea sp@(FR_HW),a1 | grab base of HW berr frame#if defined(LUNA2) cmpl #-2,_mmutype | 68040? jne Lbenot040 | no, skip movl a1@(8),sp@- | yes, push fault address clrl sp@- | no SSW for address fault jra Lisaerr | go deal with itLbenot040:#endif moveq #0,d0 movw a1@(10),d0 | grab SSW for fault processing btst #12,d0 | RB set? jeq LbeX0 | no, test RC bset #14,d0 | yes, must set FB movw d0,a1@(10) | for hardware tooLbeX0: btst #13,d0 | RC set? jeq LbeX1 | no, skip bset #15,d0 | yes, must set FC movw d0,a1@(10) | for hardware tooLbeX1: btst #8,d0 | data fault? jeq Lbe0 | no, check for hard cases movl a1@(16),d1 | fault address is as given in frame jra Lbe10 | thats itLbe0: btst #4,a1@(6) | long (type B) stack frame? jne Lbe4 | yes, go handle movl a1@(2),d1 | no, can use save PC btst #14,d0 | FB set? jeq Lbe3 | no, try FC addql #4,d1 | yes, adjust address jra Lbe10 | doneLbe3: btst #15,d0 | FC set? jeq Lbe10 | no, done addql #2,d1 | yes, adjust address jra Lbe10 | doneLbe4: movl a1@(36),d1 | long format, use stage B address btst #15,d0 | FC set? jeq Lbe10 | no, all done subql #2,d1 | yes, adjust addressLbe10: movl d1,sp@- | push fault VA movl d0,sp@- | and padded SSW movw a1@(6),d0 | get frame format/vector offset andw #0x0FFF,d0 | clear out frame format cmpw #12,d0 | address error vector? jeq Lisaerr | yes, go to it movl d1,a0 | fault address ptestr #1,a0@,#7 | do a table search pmove psr,sp@ | save result btst #7,sp@ | bus error bit set? jeq Lismerr | no, must be MMU fault clrw sp@ | yes, re-clear pad word jra Lisberr | and process as normal bus errorLismerr: movl #T_MMUFLT,sp@- | show that we are an MMU fault jra Ltrapnstkadj | and deal with itLisaerr: movl #T_ADDRERR,sp@- | mark address error jra Ltrapnstkadj | and deal with itLisberr: movl #T_BUSERR,sp@- | mark bus errorLtrapnstkadj: jbsr _trap | handle the error lea sp@(12),sp | pop value args movl sp@(FR_SP),a0 | restore user SP movl a0,usp | from save area movw sp@(FR_ADJ),d0 | need to adjust stack? jne Lstkadj | yes, go to it moveml sp@+,#0x7FFF | no, restore most user regs addql #8,sp | toss SSP and stkadj jra rei | all doneLstkadj: lea sp@(FR_HW),a1 | pointer to HW frame addql #8,a1 | source pointer movl a1,a0 | source addw d0,a0 | + hole size = dest pointer movl a1@-,a0@- | copy movl a1@-,a0@- | 8 bytes movl a0,sp@(FR_SP) | new SSP moveml sp@+,#0x7FFF | restore user registers movl sp@,sp | and our SP jra rei | all done/* * FP exceptions. */_fpfline:#if defined(LUNA2) cmpw #0x202c,sp@(6) | format type 2? jne _illinst | no, not an FP emulation#ifdef HPFPLIB .globl fpsp_unimp jmp fpsp_unimp | yes, go handle it#else clrl sp@- | stack adjust count moveml #0xFFFF,sp@- | save registers moveq #T_FPEMULI,d0 | denote as FP emulation trap jra fault | do it#endif#else jra _illinst#endif_fpunsupp:#if defined(LUNA2) cmpl #-2,_mmutype | 68040? jne _illinst | no, treat as illinst#ifdef HPFPLIB .globl fpsp_unsupp jmp fpsp_unsupp | yes, go handle it#else clrl sp@- | stack adjust count moveml #0xFFFF,sp@- | save registers moveq #T_FPEMULD,d0 | denote as FP emulation trap jra fault | do it#endif#else jra _illinst#endif/* * Handles all other FP coprocessor exceptions. * Note that since some FP exceptions generate mid-instruction frames * and may cause signal delivery, we need to test for stack adjustment * after the trap call. */_fpfault:#ifdef FPCOPROC clrl sp@- | stack adjust count moveml #0xFFFF,sp@- | save user registers movl usp,a0 | and save movl a0,sp@(FR_SP) | the user stack pointer clrl sp@- | no VA arg movl _curpcb,a0 | current pcb lea a0@(PCB_FPCTX),a0 | address of FP savearea fsave a0@ | save state tstb a0@ | null state frame? jeq Lfptnull | yes, safe clrw d0 | no, need to tweak BIU movb a0@(1),d0 | get frame size bset #3,a0@(0,d0:w) | set exc_pend bit of BIULfptnull: fmovem fpsr,sp@- | push fpsr as code argument frestore a0@ | restore state movl #T_FPERR,sp@- | push type arg jra Ltrapnstkadj | call trap and deal with stack cleanup#else jra _badtrap | treat as an unexpected trap#endif#ifdef HPFPLIB/* * We wind up here from the 040 FP emulation library after * the exception has been processed. */ .globl _fault_fault: subql #4,sp | space for rts addr movl d0,sp@- | scratch register movw sp@(14),d0 | get vector offset andl #0xFFF,d0 | mask out frame type and clear high word cmpl #0x100,d0 | HP-UX style reschedule trap? jne Lfault1 | no, skip movl sp@+,d0 | restore scratch register addql #4,sp | pop space jra Lrei1 | go do ASTLfault1: cmpl #0xC0,d0 | FP exception? jlt Lfault2 | no, skip movl sp@+,d0 | yes, backoff addql #4,sp | and prepare for normal trap frame jra _fpfault | go to itLfault2: addl #Lvectab,d0 | convert to vector table offset exg d0,a0 movl a0@,sp@(4) | get exception vector and save for rts exg d0,a0 movl sp@+,d0 | scratch registers rts | return to handler from vectab#endif/* * Coprocessor and format errors can generate mid-instruction stack * frames and cause signal delivery hence we need to check for potential * stack adjustment. */_coperr: clrl sp@- | stack adjust count moveml #0xFFFF,sp@- movl usp,a0 | get and save movl a0,sp@(FR_SP) | the user stack pointer clrl sp@- | no VA arg clrl sp@- | or code arg movl #T_COPERR,sp@- | push trap type jra Ltrapnstkadj | call trap and deal with stack adjustments_fmterr: clrl sp@- | stack adjust count moveml #0xFFFF,sp@- movl usp,a0 | get and save movl a0,sp@(FR_SP) | the user stack pointer clrl sp@- | no VA arg clrl sp@- | or code arg movl #T_FMTERR,sp@- | push trap type jra Ltrapnstkadj | call trap and deal with stack adjustments/* * Other exceptions only cause four and six word stack frame and require * no post-trap stack adjustment. */_illinst: clrl sp@- moveml #0xFFFF,sp@- moveq #T_ILLINST,d0 jra fault_zerodiv: clrl sp@- moveml #0xFFFF,sp@- moveq #T_ZERODIV,d0 jra fault_chkinst: clrl sp@- moveml #0xFFFF,sp@- moveq #T_CHKINST,d0 jra fault_trapvinst: clrl sp@- moveml #0xFFFF,sp@- moveq #T_TRAPVINST,d0 jra fault_privinst: clrl sp@- moveml #0xFFFF,sp@- moveq #T_PRIVINST,d0 jra fault .globl faultfault: movl usp,a0 | get and save movl a0,sp@(FR_SP) | the user stack pointer clrl sp@- | no VA arg clrl sp@- | or code arg movl d0,sp@- | push trap type jbsr _trap | handle trap lea sp@(12),sp | pop value args movl sp@(FR_SP),a0 | restore movl a0,usp | user SP moveml sp@+,#0x7FFF | restore most user regs addql #8,sp | pop SP and stack adjust jra rei | all done .globl _straytrap_badtrap: moveml #0xC0C0,sp@- | save scratch regs movw sp@(22),sp@- | push exception vector info clrw sp@- movl sp@(22),sp@- | and PC jbsr _straytrap | report addql #8,sp | pop args moveml sp@+,#0x0303 | restore regs jra rei | all done .globl _syscall_trap0: clrl sp@- | stack adjust count moveml #0xFFFF,sp@- | save user registers movl usp,a0 | save the user SP movl a0,sp@(FR_SP) | in the savearea movl d0,sp@- | push syscall number jbsr _syscall | handle it addql #4,sp | pop syscall arg movl sp@(FR_SP),a0 | grab and restore movl a0,usp | user SP moveml sp@+,#0x7FFF | restore most registers addql #8,sp | pop SP and stack adjust jra rei | all done/* * trap1 is sigreturn and trap2 is breakpoint. */_trap1: jra sigreturn | trap1 is sigreturn_trap2: jra _trace | trap2 is breakpoint/* * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD) * cachectl(command, addr, length) * command in d0, addr in a1, length in d1 */ .globl _cachectl_trap12: movl d1,sp@- | push length movl a1,sp@- | push addr movl d0,sp@- | push command jbsr _cachectl | do it lea sp@(12),sp | pop args jra rei | all done/* * Trap 15 is used for: * - KGDB traps * - trace traps for SUN binaries (not fully supported yet) * We just pass it on and let trap() sort it all out */_trap15: clrl sp@- moveml #0xFFFF,sp@-#ifdef KGDB moveq #T_TRAP15,d0 movw sp@(FR_HW),d1 | get PSW andw #PSL_S,d1 | from user mode? jeq fault | yes, just a regular fault movl d0,sp@- .globl _kgdb_trap_glue jbsr _kgdb_trap_glue | returns if no debugger addl #4,sp#endif moveq #T_TRAP15,d0 jra fault/* * Hit a breakpoint (trap 1 or 2) instruction. * Push the code and treat as a normal fault. */_trace: clrl sp@- moveml #0xFFFF,sp@-#ifdef KGDB moveq #T_TRACE,d0 movw sp@(FR_HW),d1 | get SSW andw #PSL_S,d1 | from user mode? jeq fault | no, regular fault movl d0,sp@- jbsr _kgdb_trap_glue | returns if no debugger addl #4,sp#endif moveq #T_TRACE,d0 jra fault/* * The sigreturn() syscall comes here. It requires special handling * because we must open a hole in the stack to fill in the (possibly much * larger) original stack frame. */sigreturn: lea sp@(-84),sp | leave enough space for largest frame movl sp@(84),sp@ | move up current 8 byte frame movl sp@(88),sp@(4)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -