First steps in rewriting locore.s, and making info useful
when the machine panics. i386/i386/locore.s: 1) got rid of most .set directives that were being used like #define's, and replaced them with appropriate #define's in the appropriate header files (accessed via genassym). 2) added comments to header inclusions and global definitions, and global variables 3) replaced some hardcoded constants with cpp defines (such as PDESIZE and others) 4) aligned all comments to the same column to make them easier to read 5) moved macro definitions for ENTRY, ALIGN, NOP, etc. to /sys/i386/include/asmacros.h 6) added #ifdef BDE_DEBUGGER around all of Bruce's debugger code 7) added new global '_KERNend' to store last location+1 of kernel 8) cleaned up zeroing of bss so that only bss is zeroed 9) fix zeroing of page tables so that it really does zero them all - not just if they follow the bss. 10) rewrote page table initialization code so that 1) works correctly and 2) write protects the kernel text by default 11) properly initialize the kernel page directory, upages, p0stack PT, and page tables. The previous scheme was more than a bit screwy. 12) change allocation of virtual area of IO hole so that it is fixed at KERNBASE + 0xa0000. The previous scheme put it right after the kernel page tables and then later expected it to be at KERNBASE +0xa0000 13) change multiple bogus settings of user read/write of various areas of kernel VM - including the IO hole; we should never be accessing the IO hole in user mode through the kernel page tables 14) split kernel support routines such as bcopy, bzero, copyin, copyout, etc. into a seperate file 'support.s' 15) split swtch and related routines into a seperate 'swtch.s' 16) split routines related to traps, syscalls, and interrupts into a seperate file 'exception.s' 17) remove some unused global variables from locore that got inserted by Garrett when he pulled them out of some .h files. i386/isa/icu.s: 1) clean up global variable declarations 2) move in declaration of astpending and netisr i386/i386/pmap.c: 1) fix calculation of virtual_avail. It previously was calculated to be right in the middle of the kernel page tables - not a good place to start allocating kernel VM. 2) properly allocate kernel page dir/tables etc out of kernel map - previously only took out 2 pages. i386/i386/machdep.c: 1) modify boot() to print a warning that the system will reboot in PANIC_REBOOT_WAIT_TIME amount of seconds, and let the user abort with a key on the console. The machine will wait for ever if a key is typed before the reboot. The default is 15 seconds, but can be set to 0 to mean don't wait at all, -1 to mean wait forever, or any positive value to wait for that many seconds. 2) print "Rebooting..." just before doing it. kern/subr_prf.c: 1) remove PANICWAIT as it is deprecated by the change to machdep.c i386/i386/trap.c: 1) add table of trap type strings and use it to print a real trap/ panic message rather than just a number. Lot's of work to be done here, but this is the first step. Symbolic traceback is in the TODO. i386/i386/Makefile.i386: 1) add support in to build support.s, exception.s and swtch.s ...and various changes to various header files to make all of the above happen.
This commit is contained in:
parent
d05214e6b4
commit
0967373e1c
435
sys/amd64/amd64/cpu_switch.S
Normal file
435
sys/amd64/amd64/cpu_switch.S
Normal file
@ -0,0 +1,435 @@
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* William Jolitz.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "npx.h" /* for NNPX */
|
||||
#include "assym.s" /* for preprocessor defines */
|
||||
#include "errno.h" /* for error codes */
|
||||
|
||||
#include "i386/isa/debug.h" /* for SHOW macros */
|
||||
#include "machine/asmacros.h" /* for miscellaneous assembly macros */
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Scheduling */
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* The following primitives manipulate the run queues.
|
||||
* _whichqs tells which of the 32 queues _qs
|
||||
* have processes in them. Setrq puts processes into queues, Remrq
|
||||
* removes them from queues. The running process is on no queue,
|
||||
* other processes are on a queue related to p->p_pri, divided by 4
|
||||
* actually to shrink the 0-127 range of priorities into the 32 available
|
||||
* queues.
|
||||
*/
|
||||
.data
|
||||
.globl _curpcb, _whichqs
|
||||
_curpcb: .long 0 /* pointer to curproc's PCB area */
|
||||
_whichqs: .long 0 /* which run queues have data */
|
||||
|
||||
.globl _qs,_cnt,_panic
|
||||
.comm _noproc,4
|
||||
.comm _runrun,4
|
||||
|
||||
.globl _want_resched
|
||||
_want_resched: .long 0 /* we need to re-run the scheduler */
|
||||
|
||||
.text
|
||||
/*
|
||||
* Setrq(p)
|
||||
*
|
||||
* Call should be made at spl6(), and p->p_stat should be SRUN
|
||||
*/
|
||||
ENTRY(setrq)
|
||||
movl 4(%esp),%eax
|
||||
cmpl $0,P_RLINK(%eax) /* should not be on q already */
|
||||
je set1
|
||||
pushl $set2
|
||||
call _panic
|
||||
set1:
|
||||
movzbl P_PRI(%eax),%edx
|
||||
shrl $2,%edx
|
||||
btsl %edx,_whichqs /* set q full bit */
|
||||
shll $3,%edx
|
||||
addl $_qs,%edx /* locate q hdr */
|
||||
movl %edx,P_LINK(%eax) /* link process on tail of q */
|
||||
movl P_RLINK(%edx),%ecx
|
||||
movl %ecx,P_RLINK(%eax)
|
||||
movl %eax,P_RLINK(%edx)
|
||||
movl %eax,P_LINK(%ecx)
|
||||
ret
|
||||
|
||||
set2: .asciz "setrq"
|
||||
|
||||
/*
|
||||
* Remrq(p)
|
||||
*
|
||||
* Call should be made at spl6().
|
||||
*/
|
||||
ENTRY(remrq)
|
||||
movl 4(%esp),%eax
|
||||
movzbl P_PRI(%eax),%edx
|
||||
shrl $2,%edx
|
||||
btrl %edx,_whichqs /* clear full bit, panic if clear already */
|
||||
jb rem1
|
||||
pushl $rem3
|
||||
call _panic
|
||||
rem1:
|
||||
pushl %edx
|
||||
movl P_LINK(%eax),%ecx /* unlink process */
|
||||
movl P_RLINK(%eax),%edx
|
||||
movl %edx,P_RLINK(%ecx)
|
||||
movl P_RLINK(%eax),%ecx
|
||||
movl P_LINK(%eax),%edx
|
||||
movl %edx,P_LINK(%ecx)
|
||||
popl %edx
|
||||
movl $_qs,%ecx
|
||||
shll $3,%edx
|
||||
addl %edx,%ecx
|
||||
cmpl P_LINK(%ecx),%ecx /* q still has something? */
|
||||
je rem2
|
||||
shrl $3,%edx /* yes, set bit as still full */
|
||||
btsl %edx,_whichqs
|
||||
rem2:
|
||||
movl $0,P_RLINK(%eax) /* zap reverse link to indicate off list */
|
||||
ret
|
||||
|
||||
rem3: .asciz "remrq"
|
||||
sw0: .asciz "swtch"
|
||||
|
||||
/*
|
||||
* When no processes are on the runq, Swtch branches to idle
|
||||
* to wait for something to come ready.
|
||||
*/
|
||||
ALIGN_TEXT
|
||||
Idle:
|
||||
sti
|
||||
SHOW_STI
|
||||
|
||||
ALIGN_TEXT
|
||||
idle_loop:
|
||||
call _spl0
|
||||
cmpl $0,_whichqs
|
||||
jne sw1
|
||||
hlt /* wait for interrupt */
|
||||
jmp idle_loop
|
||||
|
||||
badsw:
|
||||
pushl $sw0
|
||||
call _panic
|
||||
/*NOTREACHED*/
|
||||
|
||||
/*
|
||||
* Swtch()
|
||||
*/
|
||||
SUPERALIGN_TEXT /* so profiling doesn't lump Idle with swtch().. */
|
||||
ENTRY(swtch)
|
||||
|
||||
incl _cnt+V_SWTCH
|
||||
|
||||
/* switch to new process. first, save context as needed */
|
||||
|
||||
movl _curproc,%ecx
|
||||
|
||||
/* if no process to save, don't bother */
|
||||
testl %ecx,%ecx
|
||||
je sw1
|
||||
|
||||
movl P_ADDR(%ecx),%ecx
|
||||
|
||||
movl (%esp),%eax /* Hardware registers */
|
||||
movl %eax,PCB_EIP(%ecx)
|
||||
movl %ebx,PCB_EBX(%ecx)
|
||||
movl %esp,PCB_ESP(%ecx)
|
||||
movl %ebp,PCB_EBP(%ecx)
|
||||
movl %esi,PCB_ESI(%ecx)
|
||||
movl %edi,PCB_EDI(%ecx)
|
||||
|
||||
#if NNPX > 0
|
||||
/* have we used fp, and need a save? */
|
||||
mov _curproc,%eax
|
||||
cmp %eax,_npxproc
|
||||
jne 1f
|
||||
pushl %ecx /* h/w bugs make saving complicated */
|
||||
leal PCB_SAVEFPU(%ecx),%eax
|
||||
pushl %eax
|
||||
call _npxsave /* do it in a big C function */
|
||||
popl %eax
|
||||
popl %ecx
|
||||
1:
|
||||
#endif /* NNPX > 0 */
|
||||
|
||||
movl _CMAP2,%eax /* save temporary map PTE */
|
||||
movl %eax,PCB_CMAP2(%ecx) /* in our context */
|
||||
movl $0,_curproc /* out of process */
|
||||
|
||||
# movw _cpl,%ax
|
||||
# movw %ax,PCB_IML(%ecx) /* save ipl */
|
||||
|
||||
/* save is done, now choose a new process or idle */
|
||||
sw1:
|
||||
cli
|
||||
SHOW_CLI
|
||||
movl _whichqs,%edi
|
||||
2:
|
||||
/* XXX - bsf is sloow */
|
||||
bsfl %edi,%eax /* find a full q */
|
||||
je Idle /* if none, idle */
|
||||
/* XX update whichqs? */
|
||||
swfnd:
|
||||
btrl %eax,%edi /* clear q full status */
|
||||
jnb 2b /* if it was clear, look for another */
|
||||
movl %eax,%ebx /* save which one we are using */
|
||||
|
||||
shll $3,%eax
|
||||
addl $_qs,%eax /* select q */
|
||||
movl %eax,%esi
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
cmpl P_LINK(%eax),%eax /* linked to self? (e.g. not on list) */
|
||||
je badsw /* not possible */
|
||||
#endif
|
||||
|
||||
movl P_LINK(%eax),%ecx /* unlink from front of process q */
|
||||
movl P_LINK(%ecx),%edx
|
||||
movl %edx,P_LINK(%eax)
|
||||
movl P_RLINK(%ecx),%eax
|
||||
movl %eax,P_RLINK(%edx)
|
||||
|
||||
cmpl P_LINK(%ecx),%esi /* q empty */
|
||||
je 3f
|
||||
btsl %ebx,%edi /* nope, set to indicate full */
|
||||
3:
|
||||
movl %edi,_whichqs /* update q status */
|
||||
|
||||
movl $0,%eax
|
||||
movl %eax,_want_resched
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
cmpl %eax,P_WCHAN(%ecx)
|
||||
jne badsw
|
||||
cmpb $SRUN,P_STAT(%ecx)
|
||||
jne badsw
|
||||
#endif
|
||||
|
||||
movl %eax,P_RLINK(%ecx) /* isolate process to run */
|
||||
movl P_ADDR(%ecx),%edx
|
||||
movl PCB_CR3(%edx),%ebx
|
||||
|
||||
/* switch address space */
|
||||
movl %ebx,%cr3
|
||||
|
||||
/* restore context */
|
||||
movl PCB_EBX(%edx),%ebx
|
||||
movl PCB_ESP(%edx),%esp
|
||||
movl PCB_EBP(%edx),%ebp
|
||||
movl PCB_ESI(%edx),%esi
|
||||
movl PCB_EDI(%edx),%edi
|
||||
movl PCB_EIP(%edx),%eax
|
||||
movl %eax,(%esp)
|
||||
|
||||
movl PCB_CMAP2(%edx),%eax /* get temporary map */
|
||||
movl %eax,_CMAP2 /* reload temporary map PTE */
|
||||
|
||||
movl %ecx,_curproc /* into next process */
|
||||
movl %edx,_curpcb
|
||||
|
||||
pushl %edx /* save p to return */
|
||||
/*
|
||||
* XXX - 0.0 forgot to save it - is that why this was commented out in 0.1?
|
||||
* I think restoring the cpl is unnecessary, but we must turn off the cli
|
||||
* now that spl*() don't do it as a side affect.
|
||||
*/
|
||||
pushl PCB_IML(%edx)
|
||||
sti
|
||||
SHOW_STI
|
||||
#if 0
|
||||
call _splx
|
||||
#endif
|
||||
addl $4,%esp
|
||||
/*
|
||||
* XXX - 0.0 gets here via swtch_to_inactive(). I think 0.1 gets here in the
|
||||
* same way. Better return a value.
|
||||
*/
|
||||
popl %eax /* return(p); */
|
||||
ret
|
||||
|
||||
ENTRY(mvesp)
|
||||
movl %esp,%eax
|
||||
ret
|
||||
/*
|
||||
* struct proc *swtch_to_inactive(p) ; struct proc *p;
|
||||
*
|
||||
* At exit of a process, move off the address space of the
|
||||
* process and onto a "safe" one. Then, on a temporary stack
|
||||
* return and run code that disposes of the old state.
|
||||
* Since this code requires a parameter from the "old" stack,
|
||||
* pass it back as a return value.
|
||||
*/
|
||||
ENTRY(swtch_to_inactive)
|
||||
popl %edx /* old pc */
|
||||
popl %eax /* arg, our return value */
|
||||
movl _IdlePTD,%ecx
|
||||
movl %ecx,%cr3 /* good bye address space */
|
||||
#write buffer?
|
||||
movl $tmpstk-4,%esp /* temporary stack, compensated for call */
|
||||
jmp %edx /* return, execute remainder of cleanup */
|
||||
|
||||
/*
|
||||
* savectx(pcb, altreturn)
|
||||
* Update pcb, saving current processor state and arranging
|
||||
* for alternate return ala longjmp in swtch if altreturn is true.
|
||||
*/
|
||||
ENTRY(savectx)
|
||||
movl 4(%esp),%ecx
|
||||
movw _cpl,%ax
|
||||
movw %ax,PCB_IML(%ecx)
|
||||
movl (%esp),%eax
|
||||
movl %eax,PCB_EIP(%ecx)
|
||||
movl %ebx,PCB_EBX(%ecx)
|
||||
movl %esp,PCB_ESP(%ecx)
|
||||
movl %ebp,PCB_EBP(%ecx)
|
||||
movl %esi,PCB_ESI(%ecx)
|
||||
movl %edi,PCB_EDI(%ecx)
|
||||
|
||||
#if NNPX > 0
|
||||
/*
|
||||
* If npxproc == NULL, then the npx h/w state is irrelevant and the
|
||||
* state had better already be in the pcb. This is true for forks
|
||||
* but not for dumps (the old book-keeping with FP flags in the pcb
|
||||
* always lost for dumps because the dump pcb has 0 flags).
|
||||
*
|
||||
* If npxproc != NULL, then we have to save the npx h/w state to
|
||||
* npxproc's pcb and copy it to the requested pcb, or save to the
|
||||
* requested pcb and reload. Copying is easier because we would
|
||||
* have to handle h/w bugs for reloading. We used to lose the
|
||||
* parent's npx state for forks by forgetting to reload.
|
||||
*/
|
||||
mov _npxproc,%eax
|
||||
testl %eax,%eax
|
||||
je 1f
|
||||
|
||||
pushl %ecx
|
||||
movl P_ADDR(%eax),%eax
|
||||
leal PCB_SAVEFPU(%eax),%eax
|
||||
pushl %eax
|
||||
pushl %eax
|
||||
call _npxsave
|
||||
popl %eax
|
||||
popl %eax
|
||||
popl %ecx
|
||||
|
||||
pushl %ecx
|
||||
pushl $108+8*2 /* XXX h/w state size + padding */
|
||||
leal PCB_SAVEFPU(%ecx),%ecx
|
||||
pushl %ecx
|
||||
pushl %eax
|
||||
call _bcopy
|
||||
addl $12,%esp
|
||||
popl %ecx
|
||||
1:
|
||||
#endif /* NNPX > 0 */
|
||||
|
||||
movl _CMAP2,%edx /* save temporary map PTE */
|
||||
movl %edx,PCB_CMAP2(%ecx) /* in our context */
|
||||
|
||||
cmpl $0,8(%esp)
|
||||
je 1f
|
||||
movl %esp,%edx /* relocate current sp relative to pcb */
|
||||
subl $_kstack,%edx /* (sp is relative to kstack): */
|
||||
addl %edx,%ecx /* pcb += sp - kstack; */
|
||||
movl %eax,(%ecx) /* write return pc at (relocated) sp@ */
|
||||
|
||||
/* this mess deals with replicating register state gcc hides */
|
||||
movl 12(%esp),%eax
|
||||
movl %eax,12(%ecx)
|
||||
movl 16(%esp),%eax
|
||||
movl %eax,16(%ecx)
|
||||
movl 20(%esp),%eax
|
||||
movl %eax,20(%ecx)
|
||||
movl 24(%esp),%eax
|
||||
movl %eax,24(%ecx)
|
||||
1:
|
||||
xorl %eax,%eax /* return 0 */
|
||||
ret
|
||||
|
||||
/*
|
||||
* addupc(int pc, struct uprof *up, int ticks):
|
||||
* update profiling information for the user process.
|
||||
*/
|
||||
ENTRY(addupc)
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
movl 12(%ebp),%edx /* up */
|
||||
movl 8(%ebp),%eax /* pc */
|
||||
|
||||
subl PR_OFF(%edx),%eax /* pc -= up->pr_off */
|
||||
jl L1 /* if (pc < 0) return */
|
||||
|
||||
shrl $1,%eax /* praddr = pc >> 1 */
|
||||
imull PR_SCALE(%edx),%eax /* praddr *= up->pr_scale */
|
||||
shrl $15,%eax /* praddr = praddr << 15 */
|
||||
andl $-2,%eax /* praddr &= ~1 */
|
||||
|
||||
cmpl PR_SIZE(%edx),%eax /* if (praddr > up->pr_size) return */
|
||||
ja L1
|
||||
|
||||
/* addl %eax,%eax /* praddr -> word offset */
|
||||
addl PR_BASE(%edx),%eax /* praddr += up-> pr_base */
|
||||
movl 16(%ebp),%ecx /* ticks */
|
||||
|
||||
movl _curpcb,%edx
|
||||
movl $proffault,PCB_ONFAULT(%edx)
|
||||
addl %ecx,(%eax) /* storage location += ticks */
|
||||
movl $0,PCB_ONFAULT(%edx)
|
||||
L1:
|
||||
leave
|
||||
ret
|
||||
|
||||
ALIGN_TEXT
|
||||
proffault:
|
||||
/* if we get a fault, then kill profiling all together */
|
||||
movl $0,PCB_ONFAULT(%edx) /* squish the fault handler */
|
||||
movl 12(%ebp),%ecx
|
||||
movl $0,PR_SCALE(%ecx) /* up->pr_scale = 0 */
|
||||
leave
|
||||
ret
|
||||
|
||||
/* To be done: */
|
||||
ENTRY(astoff)
|
||||
ret
|
||||
|
289
sys/amd64/amd64/exception.S
Normal file
289
sys/amd64/amd64/exception.S
Normal file
@ -0,0 +1,289 @@
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "npx.h" /* NNPX */
|
||||
|
||||
#include "assym.s" /* system defines */
|
||||
|
||||
#include "errno.h" /* error return codes */
|
||||
|
||||
#include "i386/isa/debug.h" /* BDE debugging macros */
|
||||
|
||||
#include "machine/trap.h" /* trap codes */
|
||||
#include "syscall.h" /* syscall numbers */
|
||||
|
||||
#include "machine/asmacros.h" /* miscellaneous macros */
|
||||
|
||||
#define KDSEL 0x10 /* kernel data selector */
|
||||
#define SEL_RPL_MASK 0x0003
|
||||
#define TRAPF_CS_OFF (13 * 4)
|
||||
|
||||
.text
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Trap handling */
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* Trap and fault vector routines
|
||||
*
|
||||
* XXX - debugger traps are now interrupt gates so at least bdb doesn't lose
|
||||
* control. The sti's give the standard losing behaviour for ddb and kgdb.
|
||||
*/
|
||||
#define IDTVEC(name) ALIGN_TEXT; .globl _X/**/name; _X/**/name:
|
||||
#define TRAP(a) pushl $(a) ; jmp alltraps
|
||||
#ifdef KGDB
|
||||
# define BPTTRAP(a) sti; pushl $(a) ; jmp bpttraps
|
||||
#else
|
||||
# define BPTTRAP(a) sti; TRAP(a)
|
||||
#endif
|
||||
|
||||
IDTVEC(div)
|
||||
pushl $0; TRAP(T_DIVIDE)
|
||||
IDTVEC(dbg)
|
||||
#if defined(BDE_DEBUGGER) && defined(BDBTRAP)
|
||||
BDBTRAP(dbg)
|
||||
#endif
|
||||
pushl $0; BPTTRAP(T_TRCTRAP)
|
||||
IDTVEC(nmi)
|
||||
pushl $0; TRAP(T_NMI)
|
||||
IDTVEC(bpt)
|
||||
#if defined(BDE_DEBUGGER) && defined(BDBTRAP)
|
||||
BDBTRAP(bpt)
|
||||
#endif
|
||||
pushl $0; BPTTRAP(T_BPTFLT)
|
||||
IDTVEC(ofl)
|
||||
pushl $0; TRAP(T_OFLOW)
|
||||
IDTVEC(bnd)
|
||||
pushl $0; TRAP(T_BOUND)
|
||||
IDTVEC(ill)
|
||||
pushl $0; TRAP(T_PRIVINFLT)
|
||||
IDTVEC(dna)
|
||||
pushl $0; TRAP(T_DNA)
|
||||
IDTVEC(dble)
|
||||
TRAP(T_DOUBLEFLT)
|
||||
IDTVEC(fpusegm)
|
||||
pushl $0; TRAP(T_FPOPFLT)
|
||||
IDTVEC(tss)
|
||||
TRAP(T_TSSFLT)
|
||||
IDTVEC(missing)
|
||||
TRAP(T_SEGNPFLT)
|
||||
IDTVEC(stk)
|
||||
TRAP(T_STKFLT)
|
||||
IDTVEC(prot)
|
||||
TRAP(T_PROTFLT)
|
||||
IDTVEC(page)
|
||||
TRAP(T_PAGEFLT)
|
||||
IDTVEC(rsvd)
|
||||
pushl $0; TRAP(T_RESERVED)
|
||||
IDTVEC(fpu)
|
||||
#if NNPX > 0
|
||||
/*
|
||||
* Handle like an interrupt so that we can call npxintr to clear the
|
||||
* error. It would be better to handle npx interrupts as traps but
|
||||
* this is difficult for nested interrupts.
|
||||
*/
|
||||
pushl $0 /* dummy error code */
|
||||
pushl $T_ASTFLT
|
||||
pushal
|
||||
nop /* silly, the bug is for popal and it only
|
||||
* bites when the next instruction has a
|
||||
* complicated address mode */
|
||||
pushl %ds
|
||||
pushl %es /* now the stack frame is a trap frame */
|
||||
movl $KDSEL,%eax
|
||||
movl %ax,%ds
|
||||
movl %ax,%es
|
||||
pushl _cpl
|
||||
pushl $0 /* dummy unit to finish building intr frame */
|
||||
incl _cnt+V_TRAP
|
||||
call _npxintr
|
||||
jmp doreti
|
||||
#else /* NNPX > 0 */
|
||||
pushl $0; TRAP(T_ARITHTRAP)
|
||||
#endif /* NNPX > 0 */
|
||||
/* 17 - 31 reserved for future exp */
|
||||
IDTVEC(rsvd0)
|
||||
pushl $0; TRAP(17)
|
||||
IDTVEC(rsvd1)
|
||||
pushl $0; TRAP(18)
|
||||
IDTVEC(rsvd2)
|
||||
pushl $0; TRAP(19)
|
||||
IDTVEC(rsvd3)
|
||||
pushl $0; TRAP(20)
|
||||
IDTVEC(rsvd4)
|
||||
pushl $0; TRAP(21)
|
||||
IDTVEC(rsvd5)
|
||||
pushl $0; TRAP(22)
|
||||
IDTVEC(rsvd6)
|
||||
pushl $0; TRAP(23)
|
||||
IDTVEC(rsvd7)
|
||||
pushl $0; TRAP(24)
|
||||
IDTVEC(rsvd8)
|
||||
pushl $0; TRAP(25)
|
||||
IDTVEC(rsvd9)
|
||||
pushl $0; TRAP(26)
|
||||
IDTVEC(rsvd10)
|
||||
pushl $0; TRAP(27)
|
||||
IDTVEC(rsvd11)
|
||||
pushl $0; TRAP(28)
|
||||
IDTVEC(rsvd12)
|
||||
pushl $0; TRAP(29)
|
||||
IDTVEC(rsvd13)
|
||||
pushl $0; TRAP(30)
|
||||
IDTVEC(rsvd14)
|
||||
pushl $0; TRAP(31)
|
||||
|
||||
SUPERALIGN_TEXT
|
||||
alltraps:
|
||||
pushal
|
||||
nop
|
||||
pushl %ds
|
||||
pushl %es
|
||||
movl $KDSEL,%eax
|
||||
movl %ax,%ds
|
||||
movl %ax,%es
|
||||
calltrap:
|
||||
incl _cnt+V_TRAP
|
||||
call _trap
|
||||
/*
|
||||
* Return through doreti to handle ASTs. Have to change trap frame
|
||||
* to interrupt frame.
|
||||
*/
|
||||
movl $T_ASTFLT,4+4+32(%esp) /* new trap type (err code not used) */
|
||||
pushl _cpl
|
||||
pushl $0 /* dummy unit */
|
||||
jmp doreti
|
||||
|
||||
#ifdef KGDB
|
||||
/*
|
||||
* This code checks for a kgdb trap, then falls through
|
||||
* to the regular trap code.
|
||||
*/
|
||||
SUPERALIGN_TEXT
|
||||
bpttraps:
|
||||
pushal
|
||||
nop
|
||||
pushl %es
|
||||
pushl %ds
|
||||
movl $KDSEL,%eax
|
||||
movl %ax,%ds
|
||||
movl %ax,%es
|
||||
testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp) /* non-kernel mode? */
|
||||
jne calltrap /* yes */
|
||||
call _kgdb_trap_glue
|
||||
jmp calltrap
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Call gate entry for syscall
|
||||
*/
|
||||
SUPERALIGN_TEXT
|
||||
IDTVEC(syscall)
|
||||
pushfl /* only for stupid carry bit and more stupid wait3 cc kludge */
|
||||
/* XXX - also for direction flag (bzero, etc. clear it) */
|
||||
pushal /* only need eax,ecx,edx - trap resaves others */
|
||||
nop
|
||||
movl $KDSEL,%eax /* switch to kernel segments */
|
||||
movl %ax,%ds
|
||||
movl %ax,%es
|
||||
incl _cnt+V_SYSCALL
|
||||
call _syscall
|
||||
/*
|
||||
* Return through doreti to handle ASTs. Have to change syscall frame
|
||||
* to interrupt frame.
|
||||
*
|
||||
* XXX - we should have set up the frame earlier to avoid the
|
||||
* following popal/pushal (not much can be done to avoid shuffling
|
||||
* the flags). Consistent frames would simplify things all over.
|
||||
*/
|
||||
movl 32+0(%esp),%eax /* old flags, shuffle to above cs:eip */
|
||||
movl 32+4(%esp),%ebx /* `int' frame should have been ef, eip, cs */
|
||||
movl 32+8(%esp),%ecx
|
||||
movl %ebx,32+0(%esp)
|
||||
movl %ecx,32+4(%esp)
|
||||
movl %eax,32+8(%esp)
|
||||
popal
|
||||
nop
|
||||
pushl $0 /* dummy error code */
|
||||
pushl $T_ASTFLT
|
||||
pushal
|
||||
nop
|
||||
movl __udatasel,%eax /* switch back to user segments */
|
||||
pushl %eax /* XXX - better to preserve originals? */
|
||||
pushl %eax
|
||||
pushl _cpl
|
||||
pushl $0
|
||||
jmp doreti
|
||||
|
||||
#ifdef SHOW_A_LOT
|
||||
/*
|
||||
* 'show_bits' was too big when defined as a macro. The line length for some
|
||||
* enclosing macro was too big for gas. Perhaps the code would have blown
|
||||
* the cache anyway.
|
||||
*/
|
||||
ALIGN_TEXT
|
||||
show_bits:
|
||||
pushl %eax
|
||||
SHOW_BIT(0)
|
||||
SHOW_BIT(1)
|
||||
SHOW_BIT(2)
|
||||
SHOW_BIT(3)
|
||||
SHOW_BIT(4)
|
||||
SHOW_BIT(5)
|
||||
SHOW_BIT(6)
|
||||
SHOW_BIT(7)
|
||||
SHOW_BIT(8)
|
||||
SHOW_BIT(9)
|
||||
SHOW_BIT(10)
|
||||
SHOW_BIT(11)
|
||||
SHOW_BIT(12)
|
||||
SHOW_BIT(13)
|
||||
SHOW_BIT(14)
|
||||
SHOW_BIT(15)
|
||||
popl %eax
|
||||
ret
|
||||
|
||||
.data
|
||||
bit_colors:
|
||||
.byte GREEN,RED,0,0
|
||||
.text
|
||||
|
||||
#endif /* SHOW_A_LOT */
|
||||
|
||||
/*
|
||||
* include generated interrupt vectors and ISA intr code
|
||||
*/
|
||||
#include "i386/isa/vector.s"
|
||||
#include "i386/isa/icu.s"
|
289
sys/amd64/amd64/exception.s
Normal file
289
sys/amd64/amd64/exception.s
Normal file
@ -0,0 +1,289 @@
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "npx.h" /* NNPX */
|
||||
|
||||
#include "assym.s" /* system defines */
|
||||
|
||||
#include "errno.h" /* error return codes */
|
||||
|
||||
#include "i386/isa/debug.h" /* BDE debugging macros */
|
||||
|
||||
#include "machine/trap.h" /* trap codes */
|
||||
#include "syscall.h" /* syscall numbers */
|
||||
|
||||
#include "machine/asmacros.h" /* miscellaneous macros */
|
||||
|
||||
#define KDSEL 0x10 /* kernel data selector */
|
||||
#define SEL_RPL_MASK 0x0003
|
||||
#define TRAPF_CS_OFF (13 * 4)
|
||||
|
||||
.text
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Trap handling */
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* Trap and fault vector routines
|
||||
*
|
||||
* XXX - debugger traps are now interrupt gates so at least bdb doesn't lose
|
||||
* control. The sti's give the standard losing behaviour for ddb and kgdb.
|
||||
*/
|
||||
#define IDTVEC(name) ALIGN_TEXT; .globl _X/**/name; _X/**/name:
|
||||
#define TRAP(a) pushl $(a) ; jmp alltraps
|
||||
#ifdef KGDB
|
||||
# define BPTTRAP(a) sti; pushl $(a) ; jmp bpttraps
|
||||
#else
|
||||
# define BPTTRAP(a) sti; TRAP(a)
|
||||
#endif
|
||||
|
||||
IDTVEC(div)
|
||||
pushl $0; TRAP(T_DIVIDE)
|
||||
IDTVEC(dbg)
|
||||
#if defined(BDE_DEBUGGER) && defined(BDBTRAP)
|
||||
BDBTRAP(dbg)
|
||||
#endif
|
||||
pushl $0; BPTTRAP(T_TRCTRAP)
|
||||
IDTVEC(nmi)
|
||||
pushl $0; TRAP(T_NMI)
|
||||
IDTVEC(bpt)
|
||||
#if defined(BDE_DEBUGGER) && defined(BDBTRAP)
|
||||
BDBTRAP(bpt)
|
||||
#endif
|
||||
pushl $0; BPTTRAP(T_BPTFLT)
|
||||
IDTVEC(ofl)
|
||||
pushl $0; TRAP(T_OFLOW)
|
||||
IDTVEC(bnd)
|
||||
pushl $0; TRAP(T_BOUND)
|
||||
IDTVEC(ill)
|
||||
pushl $0; TRAP(T_PRIVINFLT)
|
||||
IDTVEC(dna)
|
||||
pushl $0; TRAP(T_DNA)
|
||||
IDTVEC(dble)
|
||||
TRAP(T_DOUBLEFLT)
|
||||
IDTVEC(fpusegm)
|
||||
pushl $0; TRAP(T_FPOPFLT)
|
||||
IDTVEC(tss)
|
||||
TRAP(T_TSSFLT)
|
||||
IDTVEC(missing)
|
||||
TRAP(T_SEGNPFLT)
|
||||
IDTVEC(stk)
|
||||
TRAP(T_STKFLT)
|
||||
IDTVEC(prot)
|
||||
TRAP(T_PROTFLT)
|
||||
IDTVEC(page)
|
||||
TRAP(T_PAGEFLT)
|
||||
IDTVEC(rsvd)
|
||||
pushl $0; TRAP(T_RESERVED)
|
||||
IDTVEC(fpu)
|
||||
#if NNPX > 0
|
||||
/*
|
||||
* Handle like an interrupt so that we can call npxintr to clear the
|
||||
* error. It would be better to handle npx interrupts as traps but
|
||||
* this is difficult for nested interrupts.
|
||||
*/
|
||||
pushl $0 /* dummy error code */
|
||||
pushl $T_ASTFLT
|
||||
pushal
|
||||
nop /* silly, the bug is for popal and it only
|
||||
* bites when the next instruction has a
|
||||
* complicated address mode */
|
||||
pushl %ds
|
||||
pushl %es /* now the stack frame is a trap frame */
|
||||
movl $KDSEL,%eax
|
||||
movl %ax,%ds
|
||||
movl %ax,%es
|
||||
pushl _cpl
|
||||
pushl $0 /* dummy unit to finish building intr frame */
|
||||
incl _cnt+V_TRAP
|
||||
call _npxintr
|
||||
jmp doreti
|
||||
#else /* NNPX > 0 */
|
||||
pushl $0; TRAP(T_ARITHTRAP)
|
||||
#endif /* NNPX > 0 */
|
||||
/* 17 - 31 reserved for future exp */
|
||||
IDTVEC(rsvd0)
|
||||
pushl $0; TRAP(17)
|
||||
IDTVEC(rsvd1)
|
||||
pushl $0; TRAP(18)
|
||||
IDTVEC(rsvd2)
|
||||
pushl $0; TRAP(19)
|
||||
IDTVEC(rsvd3)
|
||||
pushl $0; TRAP(20)
|
||||
IDTVEC(rsvd4)
|
||||
pushl $0; TRAP(21)
|
||||
IDTVEC(rsvd5)
|
||||
pushl $0; TRAP(22)
|
||||
IDTVEC(rsvd6)
|
||||
pushl $0; TRAP(23)
|
||||
IDTVEC(rsvd7)
|
||||
pushl $0; TRAP(24)
|
||||
IDTVEC(rsvd8)
|
||||
pushl $0; TRAP(25)
|
||||
IDTVEC(rsvd9)
|
||||
pushl $0; TRAP(26)
|
||||
IDTVEC(rsvd10)
|
||||
pushl $0; TRAP(27)
|
||||
IDTVEC(rsvd11)
|
||||
pushl $0; TRAP(28)
|
||||
IDTVEC(rsvd12)
|
||||
pushl $0; TRAP(29)
|
||||
IDTVEC(rsvd13)
|
||||
pushl $0; TRAP(30)
|
||||
IDTVEC(rsvd14)
|
||||
pushl $0; TRAP(31)
|
||||
|
||||
SUPERALIGN_TEXT
|
||||
alltraps:
|
||||
pushal
|
||||
nop
|
||||
pushl %ds
|
||||
pushl %es
|
||||
movl $KDSEL,%eax
|
||||
movl %ax,%ds
|
||||
movl %ax,%es
|
||||
calltrap:
|
||||
incl _cnt+V_TRAP
|
||||
call _trap
|
||||
/*
|
||||
* Return through doreti to handle ASTs. Have to change trap frame
|
||||
* to interrupt frame.
|
||||
*/
|
||||
movl $T_ASTFLT,4+4+32(%esp) /* new trap type (err code not used) */
|
||||
pushl _cpl
|
||||
pushl $0 /* dummy unit */
|
||||
jmp doreti
|
||||
|
||||
#ifdef KGDB
|
||||
/*
|
||||
* This code checks for a kgdb trap, then falls through
|
||||
* to the regular trap code.
|
||||
*/
|
||||
SUPERALIGN_TEXT
|
||||
bpttraps:
|
||||
pushal
|
||||
nop
|
||||
pushl %es
|
||||
pushl %ds
|
||||
movl $KDSEL,%eax
|
||||
movl %ax,%ds
|
||||
movl %ax,%es
|
||||
testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp) /* non-kernel mode? */
|
||||
jne calltrap /* yes */
|
||||
call _kgdb_trap_glue
|
||||
jmp calltrap
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Call gate entry for syscall
|
||||
*/
|
||||
SUPERALIGN_TEXT
|
||||
IDTVEC(syscall)
|
||||
pushfl /* only for stupid carry bit and more stupid wait3 cc kludge */
|
||||
/* XXX - also for direction flag (bzero, etc. clear it) */
|
||||
pushal /* only need eax,ecx,edx - trap resaves others */
|
||||
nop
|
||||
movl $KDSEL,%eax /* switch to kernel segments */
|
||||
movl %ax,%ds
|
||||
movl %ax,%es
|
||||
incl _cnt+V_SYSCALL
|
||||
call _syscall
|
||||
/*
|
||||
* Return through doreti to handle ASTs. Have to change syscall frame
|
||||
* to interrupt frame.
|
||||
*
|
||||
* XXX - we should have set up the frame earlier to avoid the
|
||||
* following popal/pushal (not much can be done to avoid shuffling
|
||||
* the flags). Consistent frames would simplify things all over.
|
||||
*/
|
||||
movl 32+0(%esp),%eax /* old flags, shuffle to above cs:eip */
|
||||
movl 32+4(%esp),%ebx /* `int' frame should have been ef, eip, cs */
|
||||
movl 32+8(%esp),%ecx
|
||||
movl %ebx,32+0(%esp)
|
||||
movl %ecx,32+4(%esp)
|
||||
movl %eax,32+8(%esp)
|
||||
popal
|
||||
nop
|
||||
pushl $0 /* dummy error code */
|
||||
pushl $T_ASTFLT
|
||||
pushal
|
||||
nop
|
||||
movl __udatasel,%eax /* switch back to user segments */
|
||||
pushl %eax /* XXX - better to preserve originals? */
|
||||
pushl %eax
|
||||
pushl _cpl
|
||||
pushl $0
|
||||
jmp doreti
|
||||
|
||||
#ifdef SHOW_A_LOT
|
||||
/*
|
||||
* 'show_bits' was too big when defined as a macro. The line length for some
|
||||
* enclosing macro was too big for gas. Perhaps the code would have blown
|
||||
* the cache anyway.
|
||||
*/
|
||||
ALIGN_TEXT
|
||||
show_bits:
|
||||
pushl %eax
|
||||
SHOW_BIT(0)
|
||||
SHOW_BIT(1)
|
||||
SHOW_BIT(2)
|
||||
SHOW_BIT(3)
|
||||
SHOW_BIT(4)
|
||||
SHOW_BIT(5)
|
||||
SHOW_BIT(6)
|
||||
SHOW_BIT(7)
|
||||
SHOW_BIT(8)
|
||||
SHOW_BIT(9)
|
||||
SHOW_BIT(10)
|
||||
SHOW_BIT(11)
|
||||
SHOW_BIT(12)
|
||||
SHOW_BIT(13)
|
||||
SHOW_BIT(14)
|
||||
SHOW_BIT(15)
|
||||
popl %eax
|
||||
ret
|
||||
|
||||
.data
|
||||
bit_colors:
|
||||
.byte GREEN,RED,0,0
|
||||
.text
|
||||
|
||||
#endif /* SHOW_A_LOT */
|
||||
|
||||
/*
|
||||
* include generated interrupt vectors and ISA intr code
|
||||
*/
|
||||
#include "i386/isa/vector.s"
|
||||
#include "i386/isa/icu.s"
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)genassym.c 5.11 (Berkeley) 5/10/91
|
||||
* $Id: genassym.c,v 1.4 1993/10/12 15:33:18 rgrimes Exp $
|
||||
* $Id: genassym.c,v 1.5 1993/10/15 10:34:17 rgrimes Exp $
|
||||
*/
|
||||
|
||||
#include "sys/param.h"
|
||||
@ -96,10 +96,14 @@ main()
|
||||
printf("#define\tCLSIZE %d\n", CLSIZE);
|
||||
printf("#define\tNBPG %d\n", NBPG);
|
||||
printf("#define\tNPTEPG %d\n", NPTEPG);
|
||||
printf("#define\tPDESIZE %d\n", PDESIZE);
|
||||
printf("#define\tPTESIZE %d\n", PTESIZE);
|
||||
printf("#define\tNKPDE %d\n", NKPDE);
|
||||
printf("#define\tKPTDI %d\n", KPTDI);
|
||||
printf("#define\tPTDPTDI %d\n", PTDPTDI);
|
||||
printf("#define\tAPTDPTDI %d\n", APTDPTDI);
|
||||
printf("#define\tKPTDI 0x%x\n", KPTDI);
|
||||
printf("#define\tKSTKPTDI 0x%x\n", KSTKPTDI);
|
||||
printf("#define\tKSTKPTEOFF 0x%x\n", KSTKPTEOFF);
|
||||
printf("#define\tPTDPTDI 0x%x\n", PTDPTDI);
|
||||
printf("#define\tAPTDPTDI 0x%x\n", APTDPTDI);
|
||||
printf("#define\tPGSHIFT %d\n", PGSHIFT);
|
||||
printf("#define\tPDRSHIFT %d\n", PDRSHIFT);
|
||||
printf("#define\tSYSPTSIZE %d\n", SYSPTSIZE);
|
||||
@ -108,9 +112,8 @@ main()
|
||||
#ifdef SYSVSHM
|
||||
printf("#define\tSHMMAXPGS %d\n", SHMMAXPGS);
|
||||
#endif
|
||||
printf("#define\tUSRSTACK %d\n", USRSTACK);
|
||||
printf("#define\tKERNBASE %d\n", KERNBASE);
|
||||
printf("#define\tKERNSIZE %d\n", KERNSIZE);
|
||||
printf("#define\tUSRSTACK 0x%x\n", USRSTACK);
|
||||
printf("#define\tKERNBASE 0x%x\n", KERNBASE);
|
||||
printf("#define\tMSGBUFPTECNT %d\n", btoc(sizeof (struct msgbuf)));
|
||||
printf("#define\tNMBCLUSTERS %d\n", NMBCLUSTERS);
|
||||
printf("#define\tMCLBYTES %d\n", MCLBYTES);
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -35,7 +35,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
|
||||
* $Id: machdep.c,v 1.14 1993/10/29 09:06:56 davidg Exp $
|
||||
* $Id: machdep.c,v 1.15 1993/11/07 21:47:00 wollman Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h"
|
||||
@ -93,6 +93,10 @@ static unsigned int avail_remaining;
|
||||
#define EXPECT_BASEMEM 640 /* The expected base memory*/
|
||||
#define INFORM_WAIT 1 /* Set to pause berfore crash in weird cases*/
|
||||
|
||||
#ifndef PANIC_REBOOT_WAIT_TIME
|
||||
#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Declare these as initialized data so we can patch them.
|
||||
*/
|
||||
@ -625,13 +629,34 @@ boot(arghowto)
|
||||
savectx(&dumppcb, 0);
|
||||
dumppcb.pcb_ptd = rcr3();
|
||||
dumpsys();
|
||||
/*NOTREACHED*/
|
||||
|
||||
if (PANIC_REBOOT_WAIT_TIME != 0) {
|
||||
if (PANIC_REBOOT_WAIT_TIME != -1) {
|
||||
int loop;
|
||||
printf("Automatic reboot in %d seconds - press a key on the console to abort\n",
|
||||
PANIC_REBOOT_WAIT_TIME);
|
||||
for (loop = PANIC_REBOOT_WAIT_TIME; loop > 0; --loop) {
|
||||
DELAY(1000 * 1000); /* one second */
|
||||
if (sgetc(1)) /* Did user type a key? */
|
||||
break;
|
||||
}
|
||||
if (!loop)
|
||||
goto die;
|
||||
}
|
||||
} else { /* zero time specified - reboot NOW */
|
||||
goto die;
|
||||
}
|
||||
printf("--> Press a key on the console to reboot <--\n");
|
||||
cngetc();
|
||||
}
|
||||
}
|
||||
#ifdef lint
|
||||
dummy = 0; dummy = dummy;
|
||||
printf("howto %d, devtype %d\n", arghowto, devtype);
|
||||
#endif
|
||||
die:
|
||||
printf("Rebooting...\n");
|
||||
DELAY (100000); /* wait 100ms for printf's to complete */
|
||||
cpu_reset();
|
||||
for(;;) ;
|
||||
/*NOTREACHED*/
|
||||
@ -681,8 +706,6 @@ dumpsys()
|
||||
printf("succeeded\n");
|
||||
break;
|
||||
}
|
||||
printf("\n\n");
|
||||
DELAY(1000);
|
||||
}
|
||||
|
||||
#ifdef HZ
|
||||
|
@ -35,7 +35,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)pmap.c 7.7 (Berkeley) 5/12/91
|
||||
* $Id: pmap.c,v 1.6 1993/10/12 15:09:37 rgrimes Exp $
|
||||
* $Id: pmap.c,v 1.7 1993/10/15 10:34:25 rgrimes Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -229,7 +229,7 @@ extern int IdlePTD;
|
||||
avail_end -= i386_round_page(sizeof(struct msgbuf));
|
||||
|
||||
mem_size = physmem << PG_SHIFT;
|
||||
virtual_avail = (vm_offset_t)atdevbase + 0x100000 - 0xa0000 + 10*NBPG;
|
||||
virtual_avail = (vm_offset_t)KERNBASE + avail_start;
|
||||
virtual_end = VM_MAX_KERNEL_ADDRESS;
|
||||
i386pagesperpage = PAGE_SIZE / NBPG;
|
||||
|
||||
@ -332,10 +332,10 @@ pmap_init(phys_start, phys_end)
|
||||
(void) vm_map_find(kernel_map, NULL, (vm_offset_t) 0,
|
||||
&addr, (0x100000-0xa0000), FALSE);
|
||||
|
||||
addr = (vm_offset_t) KERNBASE + KPTphys/* *NBPG */;
|
||||
addr = (vm_offset_t) KERNBASE + IdlePTD;
|
||||
vm_object_reference(kernel_object);
|
||||
(void) vm_map_find(kernel_map, kernel_object, addr,
|
||||
&addr, 2*NBPG, FALSE);
|
||||
&addr, (NKPDE+4)*NBPG, FALSE);
|
||||
|
||||
/*
|
||||
* Allocate memory for random pmap data structures. Includes the
|
||||
|
1031
sys/amd64/amd64/support.S
Normal file
1031
sys/amd64/amd64/support.S
Normal file
File diff suppressed because it is too large
Load Diff
1031
sys/amd64/amd64/support.s
Normal file
1031
sys/amd64/amd64/support.s
Normal file
File diff suppressed because it is too large
Load Diff
435
sys/amd64/amd64/swtch.s
Normal file
435
sys/amd64/amd64/swtch.s
Normal file
@ -0,0 +1,435 @@
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* William Jolitz.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "npx.h" /* for NNPX */
|
||||
#include "assym.s" /* for preprocessor defines */
|
||||
#include "errno.h" /* for error codes */
|
||||
|
||||
#include "i386/isa/debug.h" /* for SHOW macros */
|
||||
#include "machine/asmacros.h" /* for miscellaneous assembly macros */
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Scheduling */
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* The following primitives manipulate the run queues.
|
||||
* _whichqs tells which of the 32 queues _qs
|
||||
* have processes in them. Setrq puts processes into queues, Remrq
|
||||
* removes them from queues. The running process is on no queue,
|
||||
* other processes are on a queue related to p->p_pri, divided by 4
|
||||
* actually to shrink the 0-127 range of priorities into the 32 available
|
||||
* queues.
|
||||
*/
|
||||
.data
|
||||
.globl _curpcb, _whichqs
|
||||
_curpcb: .long 0 /* pointer to curproc's PCB area */
|
||||
_whichqs: .long 0 /* which run queues have data */
|
||||
|
||||
.globl _qs,_cnt,_panic
|
||||
.comm _noproc,4
|
||||
.comm _runrun,4
|
||||
|
||||
.globl _want_resched
|
||||
_want_resched: .long 0 /* we need to re-run the scheduler */
|
||||
|
||||
.text
|
||||
/*
|
||||
* Setrq(p)
|
||||
*
|
||||
* Call should be made at spl6(), and p->p_stat should be SRUN
|
||||
*/
|
||||
ENTRY(setrq)
|
||||
movl 4(%esp),%eax
|
||||
cmpl $0,P_RLINK(%eax) /* should not be on q already */
|
||||
je set1
|
||||
pushl $set2
|
||||
call _panic
|
||||
set1:
|
||||
movzbl P_PRI(%eax),%edx
|
||||
shrl $2,%edx
|
||||
btsl %edx,_whichqs /* set q full bit */
|
||||
shll $3,%edx
|
||||
addl $_qs,%edx /* locate q hdr */
|
||||
movl %edx,P_LINK(%eax) /* link process on tail of q */
|
||||
movl P_RLINK(%edx),%ecx
|
||||
movl %ecx,P_RLINK(%eax)
|
||||
movl %eax,P_RLINK(%edx)
|
||||
movl %eax,P_LINK(%ecx)
|
||||
ret
|
||||
|
||||
set2: .asciz "setrq"
|
||||
|
||||
/*
|
||||
* Remrq(p)
|
||||
*
|
||||
* Call should be made at spl6().
|
||||
*/
|
||||
ENTRY(remrq)
|
||||
movl 4(%esp),%eax
|
||||
movzbl P_PRI(%eax),%edx
|
||||
shrl $2,%edx
|
||||
btrl %edx,_whichqs /* clear full bit, panic if clear already */
|
||||
jb rem1
|
||||
pushl $rem3
|
||||
call _panic
|
||||
rem1:
|
||||
pushl %edx
|
||||
movl P_LINK(%eax),%ecx /* unlink process */
|
||||
movl P_RLINK(%eax),%edx
|
||||
movl %edx,P_RLINK(%ecx)
|
||||
movl P_RLINK(%eax),%ecx
|
||||
movl P_LINK(%eax),%edx
|
||||
movl %edx,P_LINK(%ecx)
|
||||
popl %edx
|
||||
movl $_qs,%ecx
|
||||
shll $3,%edx
|
||||
addl %edx,%ecx
|
||||
cmpl P_LINK(%ecx),%ecx /* q still has something? */
|
||||
je rem2
|
||||
shrl $3,%edx /* yes, set bit as still full */
|
||||
btsl %edx,_whichqs
|
||||
rem2:
|
||||
movl $0,P_RLINK(%eax) /* zap reverse link to indicate off list */
|
||||
ret
|
||||
|
||||
rem3: .asciz "remrq"
|
||||
sw0: .asciz "swtch"
|
||||
|
||||
/*
|
||||
* When no processes are on the runq, Swtch branches to idle
|
||||
* to wait for something to come ready.
|
||||
*/
|
||||
ALIGN_TEXT
|
||||
Idle:
|
||||
sti
|
||||
SHOW_STI
|
||||
|
||||
ALIGN_TEXT
|
||||
idle_loop:
|
||||
call _spl0
|
||||
cmpl $0,_whichqs
|
||||
jne sw1
|
||||
hlt /* wait for interrupt */
|
||||
jmp idle_loop
|
||||
|
||||
badsw:
|
||||
pushl $sw0
|
||||
call _panic
|
||||
/*NOTREACHED*/
|
||||
|
||||
/*
|
||||
* Swtch()
|
||||
*/
|
||||
SUPERALIGN_TEXT /* so profiling doesn't lump Idle with swtch().. */
|
||||
ENTRY(swtch)
|
||||
|
||||
incl _cnt+V_SWTCH
|
||||
|
||||
/* switch to new process. first, save context as needed */
|
||||
|
||||
movl _curproc,%ecx
|
||||
|
||||
/* if no process to save, don't bother */
|
||||
testl %ecx,%ecx
|
||||
je sw1
|
||||
|
||||
movl P_ADDR(%ecx),%ecx
|
||||
|
||||
movl (%esp),%eax /* Hardware registers */
|
||||
movl %eax,PCB_EIP(%ecx)
|
||||
movl %ebx,PCB_EBX(%ecx)
|
||||
movl %esp,PCB_ESP(%ecx)
|
||||
movl %ebp,PCB_EBP(%ecx)
|
||||
movl %esi,PCB_ESI(%ecx)
|
||||
movl %edi,PCB_EDI(%ecx)
|
||||
|
||||
#if NNPX > 0
|
||||
/* have we used fp, and need a save? */
|
||||
mov _curproc,%eax
|
||||
cmp %eax,_npxproc
|
||||
jne 1f
|
||||
pushl %ecx /* h/w bugs make saving complicated */
|
||||
leal PCB_SAVEFPU(%ecx),%eax
|
||||
pushl %eax
|
||||
call _npxsave /* do it in a big C function */
|
||||
popl %eax
|
||||
popl %ecx
|
||||
1:
|
||||
#endif /* NNPX > 0 */
|
||||
|
||||
movl _CMAP2,%eax /* save temporary map PTE */
|
||||
movl %eax,PCB_CMAP2(%ecx) /* in our context */
|
||||
movl $0,_curproc /* out of process */
|
||||
|
||||
# movw _cpl,%ax
|
||||
# movw %ax,PCB_IML(%ecx) /* save ipl */
|
||||
|
||||
/* save is done, now choose a new process or idle */
|
||||
sw1:
|
||||
cli
|
||||
SHOW_CLI
|
||||
movl _whichqs,%edi
|
||||
2:
|
||||
/* XXX - bsf is sloow */
|
||||
bsfl %edi,%eax /* find a full q */
|
||||
je Idle /* if none, idle */
|
||||
/* XX update whichqs? */
|
||||
swfnd:
|
||||
btrl %eax,%edi /* clear q full status */
|
||||
jnb 2b /* if it was clear, look for another */
|
||||
movl %eax,%ebx /* save which one we are using */
|
||||
|
||||
shll $3,%eax
|
||||
addl $_qs,%eax /* select q */
|
||||
movl %eax,%esi
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
cmpl P_LINK(%eax),%eax /* linked to self? (e.g. not on list) */
|
||||
je badsw /* not possible */
|
||||
#endif
|
||||
|
||||
movl P_LINK(%eax),%ecx /* unlink from front of process q */
|
||||
movl P_LINK(%ecx),%edx
|
||||
movl %edx,P_LINK(%eax)
|
||||
movl P_RLINK(%ecx),%eax
|
||||
movl %eax,P_RLINK(%edx)
|
||||
|
||||
cmpl P_LINK(%ecx),%esi /* q empty */
|
||||
je 3f
|
||||
btsl %ebx,%edi /* nope, set to indicate full */
|
||||
3:
|
||||
movl %edi,_whichqs /* update q status */
|
||||
|
||||
movl $0,%eax
|
||||
movl %eax,_want_resched
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
cmpl %eax,P_WCHAN(%ecx)
|
||||
jne badsw
|
||||
cmpb $SRUN,P_STAT(%ecx)
|
||||
jne badsw
|
||||
#endif
|
||||
|
||||
movl %eax,P_RLINK(%ecx) /* isolate process to run */
|
||||
movl P_ADDR(%ecx),%edx
|
||||
movl PCB_CR3(%edx),%ebx
|
||||
|
||||
/* switch address space */
|
||||
movl %ebx,%cr3
|
||||
|
||||
/* restore context */
|
||||
movl PCB_EBX(%edx),%ebx
|
||||
movl PCB_ESP(%edx),%esp
|
||||
movl PCB_EBP(%edx),%ebp
|
||||
movl PCB_ESI(%edx),%esi
|
||||
movl PCB_EDI(%edx),%edi
|
||||
movl PCB_EIP(%edx),%eax
|
||||
movl %eax,(%esp)
|
||||
|
||||
movl PCB_CMAP2(%edx),%eax /* get temporary map */
|
||||
movl %eax,_CMAP2 /* reload temporary map PTE */
|
||||
|
||||
movl %ecx,_curproc /* into next process */
|
||||
movl %edx,_curpcb
|
||||
|
||||
pushl %edx /* save p to return */
|
||||
/*
|
||||
* XXX - 0.0 forgot to save it - is that why this was commented out in 0.1?
|
||||
* I think restoring the cpl is unnecessary, but we must turn off the cli
|
||||
* now that spl*() don't do it as a side affect.
|
||||
*/
|
||||
pushl PCB_IML(%edx)
|
||||
sti
|
||||
SHOW_STI
|
||||
#if 0
|
||||
call _splx
|
||||
#endif
|
||||
addl $4,%esp
|
||||
/*
|
||||
* XXX - 0.0 gets here via swtch_to_inactive(). I think 0.1 gets here in the
|
||||
* same way. Better return a value.
|
||||
*/
|
||||
popl %eax /* return(p); */
|
||||
ret
|
||||
|
||||
ENTRY(mvesp)
|
||||
movl %esp,%eax
|
||||
ret
|
||||
/*
|
||||
* struct proc *swtch_to_inactive(p) ; struct proc *p;
|
||||
*
|
||||
* At exit of a process, move off the address space of the
|
||||
* process and onto a "safe" one. Then, on a temporary stack
|
||||
* return and run code that disposes of the old state.
|
||||
* Since this code requires a parameter from the "old" stack,
|
||||
* pass it back as a return value.
|
||||
*/
|
||||
ENTRY(swtch_to_inactive)
|
||||
popl %edx /* old pc */
|
||||
popl %eax /* arg, our return value */
|
||||
movl _IdlePTD,%ecx
|
||||
movl %ecx,%cr3 /* good bye address space */
|
||||
#write buffer?
|
||||
movl $tmpstk-4,%esp /* temporary stack, compensated for call */
|
||||
jmp %edx /* return, execute remainder of cleanup */
|
||||
|
||||
/*
|
||||
* savectx(pcb, altreturn)
|
||||
* Update pcb, saving current processor state and arranging
|
||||
* for alternate return ala longjmp in swtch if altreturn is true.
|
||||
*/
|
||||
ENTRY(savectx)
|
||||
movl 4(%esp),%ecx
|
||||
movw _cpl,%ax
|
||||
movw %ax,PCB_IML(%ecx)
|
||||
movl (%esp),%eax
|
||||
movl %eax,PCB_EIP(%ecx)
|
||||
movl %ebx,PCB_EBX(%ecx)
|
||||
movl %esp,PCB_ESP(%ecx)
|
||||
movl %ebp,PCB_EBP(%ecx)
|
||||
movl %esi,PCB_ESI(%ecx)
|
||||
movl %edi,PCB_EDI(%ecx)
|
||||
|
||||
#if NNPX > 0
|
||||
/*
|
||||
* If npxproc == NULL, then the npx h/w state is irrelevant and the
|
||||
* state had better already be in the pcb. This is true for forks
|
||||
* but not for dumps (the old book-keeping with FP flags in the pcb
|
||||
* always lost for dumps because the dump pcb has 0 flags).
|
||||
*
|
||||
* If npxproc != NULL, then we have to save the npx h/w state to
|
||||
* npxproc's pcb and copy it to the requested pcb, or save to the
|
||||
* requested pcb and reload. Copying is easier because we would
|
||||
* have to handle h/w bugs for reloading. We used to lose the
|
||||
* parent's npx state for forks by forgetting to reload.
|
||||
*/
|
||||
mov _npxproc,%eax
|
||||
testl %eax,%eax
|
||||
je 1f
|
||||
|
||||
pushl %ecx
|
||||
movl P_ADDR(%eax),%eax
|
||||
leal PCB_SAVEFPU(%eax),%eax
|
||||
pushl %eax
|
||||
pushl %eax
|
||||
call _npxsave
|
||||
popl %eax
|
||||
popl %eax
|
||||
popl %ecx
|
||||
|
||||
pushl %ecx
|
||||
pushl $108+8*2 /* XXX h/w state size + padding */
|
||||
leal PCB_SAVEFPU(%ecx),%ecx
|
||||
pushl %ecx
|
||||
pushl %eax
|
||||
call _bcopy
|
||||
addl $12,%esp
|
||||
popl %ecx
|
||||
1:
|
||||
#endif /* NNPX > 0 */
|
||||
|
||||
movl _CMAP2,%edx /* save temporary map PTE */
|
||||
movl %edx,PCB_CMAP2(%ecx) /* in our context */
|
||||
|
||||
cmpl $0,8(%esp)
|
||||
je 1f
|
||||
movl %esp,%edx /* relocate current sp relative to pcb */
|
||||
subl $_kstack,%edx /* (sp is relative to kstack): */
|
||||
addl %edx,%ecx /* pcb += sp - kstack; */
|
||||
movl %eax,(%ecx) /* write return pc at (relocated) sp@ */
|
||||
|
||||
/* this mess deals with replicating register state gcc hides */
|
||||
movl 12(%esp),%eax
|
||||
movl %eax,12(%ecx)
|
||||
movl 16(%esp),%eax
|
||||
movl %eax,16(%ecx)
|
||||
movl 20(%esp),%eax
|
||||
movl %eax,20(%ecx)
|
||||
movl 24(%esp),%eax
|
||||
movl %eax,24(%ecx)
|
||||
1:
|
||||
xorl %eax,%eax /* return 0 */
|
||||
ret
|
||||
|
||||
/*
|
||||
* addupc(int pc, struct uprof *up, int ticks):
|
||||
* update profiling information for the user process.
|
||||
*/
|
||||
ENTRY(addupc)
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
movl 12(%ebp),%edx /* up */
|
||||
movl 8(%ebp),%eax /* pc */
|
||||
|
||||
subl PR_OFF(%edx),%eax /* pc -= up->pr_off */
|
||||
jl L1 /* if (pc < 0) return */
|
||||
|
||||
shrl $1,%eax /* praddr = pc >> 1 */
|
||||
imull PR_SCALE(%edx),%eax /* praddr *= up->pr_scale */
|
||||
shrl $15,%eax /* praddr = praddr << 15 */
|
||||
andl $-2,%eax /* praddr &= ~1 */
|
||||
|
||||
cmpl PR_SIZE(%edx),%eax /* if (praddr > up->pr_size) return */
|
||||
ja L1
|
||||
|
||||
/* addl %eax,%eax /* praddr -> word offset */
|
||||
addl PR_BASE(%edx),%eax /* praddr += up-> pr_base */
|
||||
movl 16(%ebp),%ecx /* ticks */
|
||||
|
||||
movl _curpcb,%edx
|
||||
movl $proffault,PCB_ONFAULT(%edx)
|
||||
addl %ecx,(%eax) /* storage location += ticks */
|
||||
movl $0,PCB_ONFAULT(%edx)
|
||||
L1:
|
||||
leave
|
||||
ret
|
||||
|
||||
ALIGN_TEXT
|
||||
proffault:
|
||||
/* if we get a fault, then kill profiling all together */
|
||||
movl $0,PCB_ONFAULT(%edx) /* squish the fault handler */
|
||||
movl 12(%ebp),%ecx
|
||||
movl $0,PR_SCALE(%ecx) /* up->pr_scale = 0 */
|
||||
leave
|
||||
ret
|
||||
|
||||
/* To be done: */
|
||||
ENTRY(astoff)
|
||||
ret
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)trap.c 7.4 (Berkeley) 5/13/91
|
||||
* $Id: trap.c,v 1.5 1993/11/01 11:51:29 chmr Exp $
|
||||
* $Id: trap.c,v 1.6 1993/11/04 15:05:41 davidg Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -85,6 +85,38 @@ int dostacklimits;
|
||||
unsigned rcr2();
|
||||
extern short cpl;
|
||||
|
||||
#define MAX_TRAP_MSG 27
|
||||
char *trap_msg[] = {
|
||||
"reserved addressing fault", /* 0 T_RESADFLT */
|
||||
"privileged instruction fault", /* 1 T_PRIVINFLT */
|
||||
"reserved operand fault", /* 2 T_RESOPFLT */
|
||||
"breakpoint instruction fault", /* 3 T_BPTFLT */
|
||||
"", /* 4 unused */
|
||||
"system call trap", /* 5 T_SYSCALL */
|
||||
"arithmetic trap", /* 6 T_ARITHTRAP */
|
||||
"system forced exception", /* 7 T_ASTFLT */
|
||||
"segmentation (limit) fault", /* 8 T_SEGFLT */
|
||||
"protection fault", /* 9 T_PROTFLT */
|
||||
"trace trap", /* 10 T_TRCTRAP */
|
||||
"", /* 11 unused */
|
||||
"page fault", /* 12 T_PAGEFLT */
|
||||
"page table fault", /* 13 T_TABLEFLT */
|
||||
"alignment fault", /* 14 T_ALIGNFLT */
|
||||
"kernel stack pointer not valid", /* 15 T_KSPNOTVAL */
|
||||
"bus error", /* 16 T_BUSERR */
|
||||
"kernel debugger fault", /* 17 T_KDBTRAP */
|
||||
"integer divide fault", /* 18 T_DIVIDE */
|
||||
"non-maskable interrupt trap", /* 19 T_NMI */
|
||||
"overflow trap", /* 20 T_OFLOW */
|
||||
"FPU bounds check fault", /* 21 T_BOUND */
|
||||
"FPU device not available", /* 22 T_DNA */
|
||||
"double fault", /* 23 T_DOUBLEFLT */
|
||||
"FPU operand fetch fault", /* 24 T_FPOPFLT */
|
||||
"invalid TSS fault", /* 25 T_TSSFLT */
|
||||
"segment not present fault", /* 26 T_SEGNPFLT */
|
||||
"stack fault", /* 27 T_STKFLT */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* trap(frame):
|
||||
@ -165,13 +197,23 @@ if(curpcb == 0 || curproc == 0) goto we_re_toast;
|
||||
return;
|
||||
#endif
|
||||
|
||||
printf("trap type %d code = %x eip = %x cs = %x eflags = %x ",
|
||||
if ((type & ~T_USER) <= MAX_TRAP_MSG)
|
||||
printf("\n\nFatal trap %d: %s while in %s mode\n",
|
||||
type & ~T_USER, trap_msg[type & ~T_USER],
|
||||
(type & T_USER) ? "user" : "kernel");
|
||||
|
||||
printf("trap type = %d, code = %x\n eip = %x, cs = %x, eflags = %x, ",
|
||||
frame.tf_trapno, frame.tf_err, frame.tf_eip,
|
||||
frame.tf_cs, frame.tf_eflags);
|
||||
eva = rcr2();
|
||||
printf("cr2 %x cpl %x\n", eva, cpl);
|
||||
/* type &= ~T_USER; */ /* XXX what the hell is this */
|
||||
panic("trap");
|
||||
eva = rcr2();
|
||||
printf("cr2 = %x, current priority = %x\n", eva, cpl);
|
||||
|
||||
type &= ~T_USER;
|
||||
if (type <= MAX_TRAP_MSG)
|
||||
panic(trap_msg[type]);
|
||||
else
|
||||
panic("unknown/reserved trap");
|
||||
|
||||
/*NOTREACHED*/
|
||||
|
||||
case T_SEGNPFLT|T_USER:
|
||||
|
43
sys/amd64/include/asmacros.h
Normal file
43
sys/amd64/include/asmacros.h
Normal file
@ -0,0 +1,43 @@
|
||||
#define ALIGN_DATA .align 2 /* 4 byte alignment, zero filled */
|
||||
#define ALIGN_TEXT .align 2,0x90 /* 4-byte alignment, nop filled */
|
||||
#define SUPERALIGN_TEXT .align 4,0x90 /* 16-byte alignment (better for 486), nop filled */
|
||||
|
||||
#define GEN_ENTRY(name) ALIGN_TEXT; .globl name; name:
|
||||
#define NON_GPROF_ENTRY(name) GEN_ENTRY(_/**/name)
|
||||
|
||||
#ifdef GPROF
|
||||
/*
|
||||
* ALTENTRY() must be before a corresponding ENTRY() so that it can jump
|
||||
* over the mcounting.
|
||||
*/
|
||||
#define ALTENTRY(name) GEN_ENTRY(_/**/name); MCOUNT; jmp 2f
|
||||
#define ENTRY(name) GEN_ENTRY(_/**/name); MCOUNT; 2:
|
||||
/*
|
||||
* The call to mcount supports the usual (bad) conventions. We allocate
|
||||
* some data and pass a pointer to it although the FreeBSD doesn't use
|
||||
* the data. We set up a frame before calling mcount because that is
|
||||
* the standard convention although it makes work for both mcount and
|
||||
* callers.
|
||||
*/
|
||||
#define MCOUNT .data; ALIGN_DATA; 1:; .long 0; .text; \
|
||||
pushl %ebp; movl %esp,%ebp; \
|
||||
movl $1b,%eax; call mcount; popl %ebp
|
||||
#else
|
||||
/*
|
||||
* ALTENTRY() has to align because it is before a corresponding ENTRY().
|
||||
* ENTRY() has to align to because there may be no ALTENTRY() before it.
|
||||
* If there is a previous ALTENTRY() then the alignment code is empty.
|
||||
*/
|
||||
#define ALTENTRY(name) GEN_ENTRY(_/**/name)
|
||||
#define ENTRY(name) GEN_ENTRY(_/**/name)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef DUMMY_NOPS /* this will break some older machines */
|
||||
#define FASTER_NOP
|
||||
#define NOP
|
||||
#else
|
||||
#define FASTER_NOP pushl %eax ; inb $0x84,%al ; popl %eax
|
||||
#define NOP pushl %eax ; inb $0x84,%al ; inb $0x84,%al ; popl %eax
|
||||
#endif
|
||||
|
@ -42,7 +42,7 @@
|
||||
*
|
||||
* from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90
|
||||
* from: @(#)pmap.h 7.4 (Berkeley) 5/12/91
|
||||
* $Id: pmap.h,v 1.4 1993/10/15 10:07:44 rgrimes Exp $
|
||||
* $Id: pmap.h,v 1.5 1993/11/07 17:43:02 wollman Exp $
|
||||
*/
|
||||
|
||||
#ifndef _PMAP_MACHINE_
|
||||
@ -118,11 +118,11 @@ typedef struct pde pd_entry_t; /* page directory entry */
|
||||
typedef struct pte pt_entry_t; /* Mach page table entry */
|
||||
|
||||
/*
|
||||
* NKPDE controls the virtual space of the kernel, what ever is left is
|
||||
* given to the user (NUPDE)
|
||||
* NKPDE controls the virtual space of the kernel, what ever is left, minus
|
||||
* the alternate page table area is given to the user (NUPDE)
|
||||
*/
|
||||
#define NKPDE 7 /* number of kernel pde's */
|
||||
#define NUPDE (NPTEPG-NKPDE) /* number of user pde's */
|
||||
#define NUPDE (NPTEPG-NKPDE-1)/* number of user pde's */
|
||||
/*
|
||||
* The *PTDI values control the layout of virtual memory
|
||||
*
|
||||
@ -132,7 +132,11 @@ typedef struct pte pt_entry_t; /* Mach page table entry */
|
||||
#define APTDPTDI (NPTEPG-1) /* alt ptd entry that points to APTD */
|
||||
#define KPTDI (APTDPTDI-NKPDE)/* start of kernel virtual pde's */
|
||||
#define PTDPTDI (KPTDI-1) /* ptd entry that points to ptd! */
|
||||
#define UPTDI (PTDPTDI-1) /* ptd entry for u./kernel&user stack */
|
||||
#define KSTKPTDI (PTDPTDI-1) /* ptd entry for u./kernel&user stack */
|
||||
#define KSTKPTEOFF (NBPG/sizeof(struct pde)-UPAGES) /* pte entry for kernel stack */
|
||||
|
||||
#define PDESIZE sizeof(struct pde) /* for assembly files */
|
||||
#define PTESIZE sizeof(struct pte) /* for assembly files */
|
||||
|
||||
/*
|
||||
* Address of current and alternate address space page table maps
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Copyright 1990 W. Jolitz
|
||||
# from: @(#)Makefile.i386 7.1 5/10/91
|
||||
# $Id: Makefile.i386,v 1.11 1993/11/07 04:41:11 wollman Exp $
|
||||
# $Id: Makefile.i386,v 1.12 1993/11/07 16:46:33 wollman Exp $
|
||||
#
|
||||
# Makefile for FreeBSD
|
||||
#
|
||||
@ -43,7 +43,8 @@ NORMAL_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
|
||||
NORMAL_S= ${CPP} -I. -DLOCORE ${COPTS} $< | ${AS} ${ASFLAGS} -o $*.o
|
||||
DRIVER_C= ${CC} -c ${CFLAGS} ${PROF} $<
|
||||
DRIVER_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
|
||||
SYSTEM_OBJS=locore.o ${OBJS} param.o ioconf.o conf.o machdep.o
|
||||
SYSTEM_OBJS=locore.o exception.o swtch.o support.o ${OBJS} param.o \
|
||||
ioconf.o conf.o machdep.o
|
||||
SYSTEM_DEP=Makefile symbols.sort ${SYSTEM_OBJS}
|
||||
SYSTEM_LD_HEAD= @echo loading $@; rm -f $@
|
||||
SYSTEM_LD= @${LD} -z -T ${LOAD_ADDRESS} -o $@ -X vers.o ${SYSTEM_OBJS}
|
||||
@ -82,10 +83,28 @@ symbols.sort: ${I386}/i386/symbols.raw
|
||||
locore.o: assym.s ${I386}/i386/locore.s machine/trap.h machine/psl.h \
|
||||
machine/pte.h ${I386}/isa/vector.s ${I386}/isa/icu.s \
|
||||
$S/sys/errno.h machine/specialreg.h ${I386}/isa/debug.h \
|
||||
${I386}/isa/icu.h ${I386}/isa/isa.h vector.h $S/net/netisr.h
|
||||
${I386}/isa/icu.h ${I386}/isa/isa.h vector.h $S/net/netisr.h \
|
||||
machine/asmacros.h
|
||||
${CPP} -I. -DLOCORE ${COPTS} ${I386}/i386/locore.s | \
|
||||
${AS} ${ASFLAGS} -o locore.o
|
||||
|
||||
exception.o: assym.s ${I386}/i386/exception.s machine/trap.h \
|
||||
${I386}/isa/vector.s ${I386}/isa/icu.s \
|
||||
$S/sys/errno.h ${I386}/isa/icu.h ${I386}/isa/isa.h vector.h \
|
||||
$S/net/netisr.h machine/asmacros.h
|
||||
${CPP} -I. -DLOCORE ${COPTS} ${I386}/i386/exception.s | \
|
||||
${AS} ${ASFLAGS} -o exception.o
|
||||
|
||||
swtch.o: assym.s ${I386}/i386/swtch.s \
|
||||
$S/sys/errno.h ${I386}/isa/debug.h machine/asmacros.h
|
||||
${CPP} -I. ${COPTS} ${I386}/i386/swtch.s | \
|
||||
${AS} ${ASFLAGS} -o swtch.o
|
||||
|
||||
support.o: assym.s ${I386}/i386/support.s \
|
||||
$S/sys/errno.h machine/asmacros.h
|
||||
${CPP} -I. ${COPTS} ${I386}/i386/support.s | \
|
||||
${AS} ${ASFLAGS} -o support.o
|
||||
|
||||
machdep.o: ${I386}/i386/machdep.c Makefile
|
||||
${CC} -c ${CFLAGS} -DLOAD_ADDRESS=0x${LOAD_ADDRESS} ${PROF} $<
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Copyright 1990 W. Jolitz
|
||||
# from: @(#)Makefile.i386 7.1 5/10/91
|
||||
# $Id: Makefile.i386,v 1.11 1993/11/07 04:41:11 wollman Exp $
|
||||
# $Id: Makefile.i386,v 1.12 1993/11/07 16:46:33 wollman Exp $
|
||||
#
|
||||
# Makefile for FreeBSD
|
||||
#
|
||||
@ -43,7 +43,8 @@ NORMAL_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
|
||||
NORMAL_S= ${CPP} -I. -DLOCORE ${COPTS} $< | ${AS} ${ASFLAGS} -o $*.o
|
||||
DRIVER_C= ${CC} -c ${CFLAGS} ${PROF} $<
|
||||
DRIVER_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
|
||||
SYSTEM_OBJS=locore.o ${OBJS} param.o ioconf.o conf.o machdep.o
|
||||
SYSTEM_OBJS=locore.o exception.o swtch.o support.o ${OBJS} param.o \
|
||||
ioconf.o conf.o machdep.o
|
||||
SYSTEM_DEP=Makefile symbols.sort ${SYSTEM_OBJS}
|
||||
SYSTEM_LD_HEAD= @echo loading $@; rm -f $@
|
||||
SYSTEM_LD= @${LD} -z -T ${LOAD_ADDRESS} -o $@ -X vers.o ${SYSTEM_OBJS}
|
||||
@ -82,10 +83,28 @@ symbols.sort: ${I386}/i386/symbols.raw
|
||||
locore.o: assym.s ${I386}/i386/locore.s machine/trap.h machine/psl.h \
|
||||
machine/pte.h ${I386}/isa/vector.s ${I386}/isa/icu.s \
|
||||
$S/sys/errno.h machine/specialreg.h ${I386}/isa/debug.h \
|
||||
${I386}/isa/icu.h ${I386}/isa/isa.h vector.h $S/net/netisr.h
|
||||
${I386}/isa/icu.h ${I386}/isa/isa.h vector.h $S/net/netisr.h \
|
||||
machine/asmacros.h
|
||||
${CPP} -I. -DLOCORE ${COPTS} ${I386}/i386/locore.s | \
|
||||
${AS} ${ASFLAGS} -o locore.o
|
||||
|
||||
exception.o: assym.s ${I386}/i386/exception.s machine/trap.h \
|
||||
${I386}/isa/vector.s ${I386}/isa/icu.s \
|
||||
$S/sys/errno.h ${I386}/isa/icu.h ${I386}/isa/isa.h vector.h \
|
||||
$S/net/netisr.h machine/asmacros.h
|
||||
${CPP} -I. -DLOCORE ${COPTS} ${I386}/i386/exception.s | \
|
||||
${AS} ${ASFLAGS} -o exception.o
|
||||
|
||||
swtch.o: assym.s ${I386}/i386/swtch.s \
|
||||
$S/sys/errno.h ${I386}/isa/debug.h machine/asmacros.h
|
||||
${CPP} -I. ${COPTS} ${I386}/i386/swtch.s | \
|
||||
${AS} ${ASFLAGS} -o swtch.o
|
||||
|
||||
support.o: assym.s ${I386}/i386/support.s \
|
||||
$S/sys/errno.h machine/asmacros.h
|
||||
${CPP} -I. ${COPTS} ${I386}/i386/support.s | \
|
||||
${AS} ${ASFLAGS} -o support.o
|
||||
|
||||
machdep.o: ${I386}/i386/machdep.c Makefile
|
||||
${CC} -c ${CFLAGS} -DLOAD_ADDRESS=0x${LOAD_ADDRESS} ${PROF} $<
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Copyright 1990 W. Jolitz
|
||||
# from: @(#)Makefile.i386 7.1 5/10/91
|
||||
# $Id: Makefile.i386,v 1.11 1993/11/07 04:41:11 wollman Exp $
|
||||
# $Id: Makefile.i386,v 1.12 1993/11/07 16:46:33 wollman Exp $
|
||||
#
|
||||
# Makefile for FreeBSD
|
||||
#
|
||||
@ -43,7 +43,8 @@ NORMAL_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
|
||||
NORMAL_S= ${CPP} -I. -DLOCORE ${COPTS} $< | ${AS} ${ASFLAGS} -o $*.o
|
||||
DRIVER_C= ${CC} -c ${CFLAGS} ${PROF} $<
|
||||
DRIVER_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
|
||||
SYSTEM_OBJS=locore.o ${OBJS} param.o ioconf.o conf.o machdep.o
|
||||
SYSTEM_OBJS=locore.o exception.o swtch.o support.o ${OBJS} param.o \
|
||||
ioconf.o conf.o machdep.o
|
||||
SYSTEM_DEP=Makefile symbols.sort ${SYSTEM_OBJS}
|
||||
SYSTEM_LD_HEAD= @echo loading $@; rm -f $@
|
||||
SYSTEM_LD= @${LD} -z -T ${LOAD_ADDRESS} -o $@ -X vers.o ${SYSTEM_OBJS}
|
||||
@ -82,10 +83,28 @@ symbols.sort: ${I386}/i386/symbols.raw
|
||||
locore.o: assym.s ${I386}/i386/locore.s machine/trap.h machine/psl.h \
|
||||
machine/pte.h ${I386}/isa/vector.s ${I386}/isa/icu.s \
|
||||
$S/sys/errno.h machine/specialreg.h ${I386}/isa/debug.h \
|
||||
${I386}/isa/icu.h ${I386}/isa/isa.h vector.h $S/net/netisr.h
|
||||
${I386}/isa/icu.h ${I386}/isa/isa.h vector.h $S/net/netisr.h \
|
||||
machine/asmacros.h
|
||||
${CPP} -I. -DLOCORE ${COPTS} ${I386}/i386/locore.s | \
|
||||
${AS} ${ASFLAGS} -o locore.o
|
||||
|
||||
exception.o: assym.s ${I386}/i386/exception.s machine/trap.h \
|
||||
${I386}/isa/vector.s ${I386}/isa/icu.s \
|
||||
$S/sys/errno.h ${I386}/isa/icu.h ${I386}/isa/isa.h vector.h \
|
||||
$S/net/netisr.h machine/asmacros.h
|
||||
${CPP} -I. -DLOCORE ${COPTS} ${I386}/i386/exception.s | \
|
||||
${AS} ${ASFLAGS} -o exception.o
|
||||
|
||||
swtch.o: assym.s ${I386}/i386/swtch.s \
|
||||
$S/sys/errno.h ${I386}/isa/debug.h machine/asmacros.h
|
||||
${CPP} -I. ${COPTS} ${I386}/i386/swtch.s | \
|
||||
${AS} ${ASFLAGS} -o swtch.o
|
||||
|
||||
support.o: assym.s ${I386}/i386/support.s \
|
||||
$S/sys/errno.h machine/asmacros.h
|
||||
${CPP} -I. ${COPTS} ${I386}/i386/support.s | \
|
||||
${AS} ${ASFLAGS} -o support.o
|
||||
|
||||
machdep.o: ${I386}/i386/machdep.c Makefile
|
||||
${CC} -c ${CFLAGS} -DLOAD_ADDRESS=0x${LOAD_ADDRESS} ${PROF} $<
|
||||
|
||||
|
289
sys/i386/i386/exception.s
Normal file
289
sys/i386/i386/exception.s
Normal file
@ -0,0 +1,289 @@
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "npx.h" /* NNPX */
|
||||
|
||||
#include "assym.s" /* system defines */
|
||||
|
||||
#include "errno.h" /* error return codes */
|
||||
|
||||
#include "i386/isa/debug.h" /* BDE debugging macros */
|
||||
|
||||
#include "machine/trap.h" /* trap codes */
|
||||
#include "syscall.h" /* syscall numbers */
|
||||
|
||||
#include "machine/asmacros.h" /* miscellaneous macros */
|
||||
|
||||
#define KDSEL 0x10 /* kernel data selector */
|
||||
#define SEL_RPL_MASK 0x0003
|
||||
#define TRAPF_CS_OFF (13 * 4)
|
||||
|
||||
.text
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Trap handling */
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* Trap and fault vector routines
|
||||
*
|
||||
* XXX - debugger traps are now interrupt gates so at least bdb doesn't lose
|
||||
* control. The sti's give the standard losing behaviour for ddb and kgdb.
|
||||
*/
|
||||
#define IDTVEC(name) ALIGN_TEXT; .globl _X/**/name; _X/**/name:
|
||||
#define TRAP(a) pushl $(a) ; jmp alltraps
|
||||
#ifdef KGDB
|
||||
# define BPTTRAP(a) sti; pushl $(a) ; jmp bpttraps
|
||||
#else
|
||||
# define BPTTRAP(a) sti; TRAP(a)
|
||||
#endif
|
||||
|
||||
IDTVEC(div)
|
||||
pushl $0; TRAP(T_DIVIDE)
|
||||
IDTVEC(dbg)
|
||||
#if defined(BDE_DEBUGGER) && defined(BDBTRAP)
|
||||
BDBTRAP(dbg)
|
||||
#endif
|
||||
pushl $0; BPTTRAP(T_TRCTRAP)
|
||||
IDTVEC(nmi)
|
||||
pushl $0; TRAP(T_NMI)
|
||||
IDTVEC(bpt)
|
||||
#if defined(BDE_DEBUGGER) && defined(BDBTRAP)
|
||||
BDBTRAP(bpt)
|
||||
#endif
|
||||
pushl $0; BPTTRAP(T_BPTFLT)
|
||||
IDTVEC(ofl)
|
||||
pushl $0; TRAP(T_OFLOW)
|
||||
IDTVEC(bnd)
|
||||
pushl $0; TRAP(T_BOUND)
|
||||
IDTVEC(ill)
|
||||
pushl $0; TRAP(T_PRIVINFLT)
|
||||
IDTVEC(dna)
|
||||
pushl $0; TRAP(T_DNA)
|
||||
IDTVEC(dble)
|
||||
TRAP(T_DOUBLEFLT)
|
||||
IDTVEC(fpusegm)
|
||||
pushl $0; TRAP(T_FPOPFLT)
|
||||
IDTVEC(tss)
|
||||
TRAP(T_TSSFLT)
|
||||
IDTVEC(missing)
|
||||
TRAP(T_SEGNPFLT)
|
||||
IDTVEC(stk)
|
||||
TRAP(T_STKFLT)
|
||||
IDTVEC(prot)
|
||||
TRAP(T_PROTFLT)
|
||||
IDTVEC(page)
|
||||
TRAP(T_PAGEFLT)
|
||||
IDTVEC(rsvd)
|
||||
pushl $0; TRAP(T_RESERVED)
|
||||
IDTVEC(fpu)
|
||||
#if NNPX > 0
|
||||
/*
|
||||
* Handle like an interrupt so that we can call npxintr to clear the
|
||||
* error. It would be better to handle npx interrupts as traps but
|
||||
* this is difficult for nested interrupts.
|
||||
*/
|
||||
pushl $0 /* dummy error code */
|
||||
pushl $T_ASTFLT
|
||||
pushal
|
||||
nop /* silly, the bug is for popal and it only
|
||||
* bites when the next instruction has a
|
||||
* complicated address mode */
|
||||
pushl %ds
|
||||
pushl %es /* now the stack frame is a trap frame */
|
||||
movl $KDSEL,%eax
|
||||
movl %ax,%ds
|
||||
movl %ax,%es
|
||||
pushl _cpl
|
||||
pushl $0 /* dummy unit to finish building intr frame */
|
||||
incl _cnt+V_TRAP
|
||||
call _npxintr
|
||||
jmp doreti
|
||||
#else /* NNPX > 0 */
|
||||
pushl $0; TRAP(T_ARITHTRAP)
|
||||
#endif /* NNPX > 0 */
|
||||
/* 17 - 31 reserved for future exp */
|
||||
IDTVEC(rsvd0)
|
||||
pushl $0; TRAP(17)
|
||||
IDTVEC(rsvd1)
|
||||
pushl $0; TRAP(18)
|
||||
IDTVEC(rsvd2)
|
||||
pushl $0; TRAP(19)
|
||||
IDTVEC(rsvd3)
|
||||
pushl $0; TRAP(20)
|
||||
IDTVEC(rsvd4)
|
||||
pushl $0; TRAP(21)
|
||||
IDTVEC(rsvd5)
|
||||
pushl $0; TRAP(22)
|
||||
IDTVEC(rsvd6)
|
||||
pushl $0; TRAP(23)
|
||||
IDTVEC(rsvd7)
|
||||
pushl $0; TRAP(24)
|
||||
IDTVEC(rsvd8)
|
||||
pushl $0; TRAP(25)
|
||||
IDTVEC(rsvd9)
|
||||
pushl $0; TRAP(26)
|
||||
IDTVEC(rsvd10)
|
||||
pushl $0; TRAP(27)
|
||||
IDTVEC(rsvd11)
|
||||
pushl $0; TRAP(28)
|
||||
IDTVEC(rsvd12)
|
||||
pushl $0; TRAP(29)
|
||||
IDTVEC(rsvd13)
|
||||
pushl $0; TRAP(30)
|
||||
IDTVEC(rsvd14)
|
||||
pushl $0; TRAP(31)
|
||||
|
||||
SUPERALIGN_TEXT
|
||||
alltraps:
|
||||
pushal
|
||||
nop
|
||||
pushl %ds
|
||||
pushl %es
|
||||
movl $KDSEL,%eax
|
||||
movl %ax,%ds
|
||||
movl %ax,%es
|
||||
calltrap:
|
||||
incl _cnt+V_TRAP
|
||||
call _trap
|
||||
/*
|
||||
* Return through doreti to handle ASTs. Have to change trap frame
|
||||
* to interrupt frame.
|
||||
*/
|
||||
movl $T_ASTFLT,4+4+32(%esp) /* new trap type (err code not used) */
|
||||
pushl _cpl
|
||||
pushl $0 /* dummy unit */
|
||||
jmp doreti
|
||||
|
||||
#ifdef KGDB
|
||||
/*
|
||||
* This code checks for a kgdb trap, then falls through
|
||||
* to the regular trap code.
|
||||
*/
|
||||
SUPERALIGN_TEXT
|
||||
bpttraps:
|
||||
pushal
|
||||
nop
|
||||
pushl %es
|
||||
pushl %ds
|
||||
movl $KDSEL,%eax
|
||||
movl %ax,%ds
|
||||
movl %ax,%es
|
||||
testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp) /* non-kernel mode? */
|
||||
jne calltrap /* yes */
|
||||
call _kgdb_trap_glue
|
||||
jmp calltrap
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Call gate entry for syscall
|
||||
*/
|
||||
SUPERALIGN_TEXT
|
||||
IDTVEC(syscall)
|
||||
pushfl /* only for stupid carry bit and more stupid wait3 cc kludge */
|
||||
/* XXX - also for direction flag (bzero, etc. clear it) */
|
||||
pushal /* only need eax,ecx,edx - trap resaves others */
|
||||
nop
|
||||
movl $KDSEL,%eax /* switch to kernel segments */
|
||||
movl %ax,%ds
|
||||
movl %ax,%es
|
||||
incl _cnt+V_SYSCALL
|
||||
call _syscall
|
||||
/*
|
||||
* Return through doreti to handle ASTs. Have to change syscall frame
|
||||
* to interrupt frame.
|
||||
*
|
||||
* XXX - we should have set up the frame earlier to avoid the
|
||||
* following popal/pushal (not much can be done to avoid shuffling
|
||||
* the flags). Consistent frames would simplify things all over.
|
||||
*/
|
||||
movl 32+0(%esp),%eax /* old flags, shuffle to above cs:eip */
|
||||
movl 32+4(%esp),%ebx /* `int' frame should have been ef, eip, cs */
|
||||
movl 32+8(%esp),%ecx
|
||||
movl %ebx,32+0(%esp)
|
||||
movl %ecx,32+4(%esp)
|
||||
movl %eax,32+8(%esp)
|
||||
popal
|
||||
nop
|
||||
pushl $0 /* dummy error code */
|
||||
pushl $T_ASTFLT
|
||||
pushal
|
||||
nop
|
||||
movl __udatasel,%eax /* switch back to user segments */
|
||||
pushl %eax /* XXX - better to preserve originals? */
|
||||
pushl %eax
|
||||
pushl _cpl
|
||||
pushl $0
|
||||
jmp doreti
|
||||
|
||||
#ifdef SHOW_A_LOT
|
||||
/*
|
||||
* 'show_bits' was too big when defined as a macro. The line length for some
|
||||
* enclosing macro was too big for gas. Perhaps the code would have blown
|
||||
* the cache anyway.
|
||||
*/
|
||||
ALIGN_TEXT
|
||||
show_bits:
|
||||
pushl %eax
|
||||
SHOW_BIT(0)
|
||||
SHOW_BIT(1)
|
||||
SHOW_BIT(2)
|
||||
SHOW_BIT(3)
|
||||
SHOW_BIT(4)
|
||||
SHOW_BIT(5)
|
||||
SHOW_BIT(6)
|
||||
SHOW_BIT(7)
|
||||
SHOW_BIT(8)
|
||||
SHOW_BIT(9)
|
||||
SHOW_BIT(10)
|
||||
SHOW_BIT(11)
|
||||
SHOW_BIT(12)
|
||||
SHOW_BIT(13)
|
||||
SHOW_BIT(14)
|
||||
SHOW_BIT(15)
|
||||
popl %eax
|
||||
ret
|
||||
|
||||
.data
|
||||
bit_colors:
|
||||
.byte GREEN,RED,0,0
|
||||
.text
|
||||
|
||||
#endif /* SHOW_A_LOT */
|
||||
|
||||
/*
|
||||
* include generated interrupt vectors and ISA intr code
|
||||
*/
|
||||
#include "i386/isa/vector.s"
|
||||
#include "i386/isa/icu.s"
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)genassym.c 5.11 (Berkeley) 5/10/91
|
||||
* $Id: genassym.c,v 1.4 1993/10/12 15:33:18 rgrimes Exp $
|
||||
* $Id: genassym.c,v 1.5 1993/10/15 10:34:17 rgrimes Exp $
|
||||
*/
|
||||
|
||||
#include "sys/param.h"
|
||||
@ -96,10 +96,14 @@ main()
|
||||
printf("#define\tCLSIZE %d\n", CLSIZE);
|
||||
printf("#define\tNBPG %d\n", NBPG);
|
||||
printf("#define\tNPTEPG %d\n", NPTEPG);
|
||||
printf("#define\tPDESIZE %d\n", PDESIZE);
|
||||
printf("#define\tPTESIZE %d\n", PTESIZE);
|
||||
printf("#define\tNKPDE %d\n", NKPDE);
|
||||
printf("#define\tKPTDI %d\n", KPTDI);
|
||||
printf("#define\tPTDPTDI %d\n", PTDPTDI);
|
||||
printf("#define\tAPTDPTDI %d\n", APTDPTDI);
|
||||
printf("#define\tKPTDI 0x%x\n", KPTDI);
|
||||
printf("#define\tKSTKPTDI 0x%x\n", KSTKPTDI);
|
||||
printf("#define\tKSTKPTEOFF 0x%x\n", KSTKPTEOFF);
|
||||
printf("#define\tPTDPTDI 0x%x\n", PTDPTDI);
|
||||
printf("#define\tAPTDPTDI 0x%x\n", APTDPTDI);
|
||||
printf("#define\tPGSHIFT %d\n", PGSHIFT);
|
||||
printf("#define\tPDRSHIFT %d\n", PDRSHIFT);
|
||||
printf("#define\tSYSPTSIZE %d\n", SYSPTSIZE);
|
||||
@ -108,9 +112,8 @@ main()
|
||||
#ifdef SYSVSHM
|
||||
printf("#define\tSHMMAXPGS %d\n", SHMMAXPGS);
|
||||
#endif
|
||||
printf("#define\tUSRSTACK %d\n", USRSTACK);
|
||||
printf("#define\tKERNBASE %d\n", KERNBASE);
|
||||
printf("#define\tKERNSIZE %d\n", KERNSIZE);
|
||||
printf("#define\tUSRSTACK 0x%x\n", USRSTACK);
|
||||
printf("#define\tKERNBASE 0x%x\n", KERNBASE);
|
||||
printf("#define\tMSGBUFPTECNT %d\n", btoc(sizeof (struct msgbuf)));
|
||||
printf("#define\tNMBCLUSTERS %d\n", NMBCLUSTERS);
|
||||
printf("#define\tMCLBYTES %d\n", MCLBYTES);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -35,7 +35,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
|
||||
* $Id: machdep.c,v 1.14 1993/10/29 09:06:56 davidg Exp $
|
||||
* $Id: machdep.c,v 1.15 1993/11/07 21:47:00 wollman Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h"
|
||||
@ -93,6 +93,10 @@ static unsigned int avail_remaining;
|
||||
#define EXPECT_BASEMEM 640 /* The expected base memory*/
|
||||
#define INFORM_WAIT 1 /* Set to pause berfore crash in weird cases*/
|
||||
|
||||
#ifndef PANIC_REBOOT_WAIT_TIME
|
||||
#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Declare these as initialized data so we can patch them.
|
||||
*/
|
||||
@ -625,13 +629,34 @@ boot(arghowto)
|
||||
savectx(&dumppcb, 0);
|
||||
dumppcb.pcb_ptd = rcr3();
|
||||
dumpsys();
|
||||
/*NOTREACHED*/
|
||||
|
||||
if (PANIC_REBOOT_WAIT_TIME != 0) {
|
||||
if (PANIC_REBOOT_WAIT_TIME != -1) {
|
||||
int loop;
|
||||
printf("Automatic reboot in %d seconds - press a key on the console to abort\n",
|
||||
PANIC_REBOOT_WAIT_TIME);
|
||||
for (loop = PANIC_REBOOT_WAIT_TIME; loop > 0; --loop) {
|
||||
DELAY(1000 * 1000); /* one second */
|
||||
if (sgetc(1)) /* Did user type a key? */
|
||||
break;
|
||||
}
|
||||
if (!loop)
|
||||
goto die;
|
||||
}
|
||||
} else { /* zero time specified - reboot NOW */
|
||||
goto die;
|
||||
}
|
||||
printf("--> Press a key on the console to reboot <--\n");
|
||||
cngetc();
|
||||
}
|
||||
}
|
||||
#ifdef lint
|
||||
dummy = 0; dummy = dummy;
|
||||
printf("howto %d, devtype %d\n", arghowto, devtype);
|
||||
#endif
|
||||
die:
|
||||
printf("Rebooting...\n");
|
||||
DELAY (100000); /* wait 100ms for printf's to complete */
|
||||
cpu_reset();
|
||||
for(;;) ;
|
||||
/*NOTREACHED*/
|
||||
@ -681,8 +706,6 @@ dumpsys()
|
||||
printf("succeeded\n");
|
||||
break;
|
||||
}
|
||||
printf("\n\n");
|
||||
DELAY(1000);
|
||||
}
|
||||
|
||||
#ifdef HZ
|
||||
|
@ -35,7 +35,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)pmap.c 7.7 (Berkeley) 5/12/91
|
||||
* $Id: pmap.c,v 1.6 1993/10/12 15:09:37 rgrimes Exp $
|
||||
* $Id: pmap.c,v 1.7 1993/10/15 10:34:25 rgrimes Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -229,7 +229,7 @@ extern int IdlePTD;
|
||||
avail_end -= i386_round_page(sizeof(struct msgbuf));
|
||||
|
||||
mem_size = physmem << PG_SHIFT;
|
||||
virtual_avail = (vm_offset_t)atdevbase + 0x100000 - 0xa0000 + 10*NBPG;
|
||||
virtual_avail = (vm_offset_t)KERNBASE + avail_start;
|
||||
virtual_end = VM_MAX_KERNEL_ADDRESS;
|
||||
i386pagesperpage = PAGE_SIZE / NBPG;
|
||||
|
||||
@ -332,10 +332,10 @@ pmap_init(phys_start, phys_end)
|
||||
(void) vm_map_find(kernel_map, NULL, (vm_offset_t) 0,
|
||||
&addr, (0x100000-0xa0000), FALSE);
|
||||
|
||||
addr = (vm_offset_t) KERNBASE + KPTphys/* *NBPG */;
|
||||
addr = (vm_offset_t) KERNBASE + IdlePTD;
|
||||
vm_object_reference(kernel_object);
|
||||
(void) vm_map_find(kernel_map, kernel_object, addr,
|
||||
&addr, 2*NBPG, FALSE);
|
||||
&addr, (NKPDE+4)*NBPG, FALSE);
|
||||
|
||||
/*
|
||||
* Allocate memory for random pmap data structures. Includes the
|
||||
|
1031
sys/i386/i386/support.s
Normal file
1031
sys/i386/i386/support.s
Normal file
File diff suppressed because it is too large
Load Diff
435
sys/i386/i386/swtch.s
Normal file
435
sys/i386/i386/swtch.s
Normal file
@ -0,0 +1,435 @@
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* William Jolitz.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "npx.h" /* for NNPX */
|
||||
#include "assym.s" /* for preprocessor defines */
|
||||
#include "errno.h" /* for error codes */
|
||||
|
||||
#include "i386/isa/debug.h" /* for SHOW macros */
|
||||
#include "machine/asmacros.h" /* for miscellaneous assembly macros */
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Scheduling */
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* The following primitives manipulate the run queues.
|
||||
* _whichqs tells which of the 32 queues _qs
|
||||
* have processes in them. Setrq puts processes into queues, Remrq
|
||||
* removes them from queues. The running process is on no queue,
|
||||
* other processes are on a queue related to p->p_pri, divided by 4
|
||||
* actually to shrink the 0-127 range of priorities into the 32 available
|
||||
* queues.
|
||||
*/
|
||||
.data
|
||||
.globl _curpcb, _whichqs
|
||||
_curpcb: .long 0 /* pointer to curproc's PCB area */
|
||||
_whichqs: .long 0 /* which run queues have data */
|
||||
|
||||
.globl _qs,_cnt,_panic
|
||||
.comm _noproc,4
|
||||
.comm _runrun,4
|
||||
|
||||
.globl _want_resched
|
||||
_want_resched: .long 0 /* we need to re-run the scheduler */
|
||||
|
||||
.text
|
||||
/*
|
||||
* Setrq(p)
|
||||
*
|
||||
* Call should be made at spl6(), and p->p_stat should be SRUN
|
||||
*/
|
||||
ENTRY(setrq)
|
||||
movl 4(%esp),%eax
|
||||
cmpl $0,P_RLINK(%eax) /* should not be on q already */
|
||||
je set1
|
||||
pushl $set2
|
||||
call _panic
|
||||
set1:
|
||||
movzbl P_PRI(%eax),%edx
|
||||
shrl $2,%edx
|
||||
btsl %edx,_whichqs /* set q full bit */
|
||||
shll $3,%edx
|
||||
addl $_qs,%edx /* locate q hdr */
|
||||
movl %edx,P_LINK(%eax) /* link process on tail of q */
|
||||
movl P_RLINK(%edx),%ecx
|
||||
movl %ecx,P_RLINK(%eax)
|
||||
movl %eax,P_RLINK(%edx)
|
||||
movl %eax,P_LINK(%ecx)
|
||||
ret
|
||||
|
||||
set2: .asciz "setrq"
|
||||
|
||||
/*
|
||||
* Remrq(p)
|
||||
*
|
||||
* Call should be made at spl6().
|
||||
*/
|
||||
ENTRY(remrq)
|
||||
movl 4(%esp),%eax
|
||||
movzbl P_PRI(%eax),%edx
|
||||
shrl $2,%edx
|
||||
btrl %edx,_whichqs /* clear full bit, panic if clear already */
|
||||
jb rem1
|
||||
pushl $rem3
|
||||
call _panic
|
||||
rem1:
|
||||
pushl %edx
|
||||
movl P_LINK(%eax),%ecx /* unlink process */
|
||||
movl P_RLINK(%eax),%edx
|
||||
movl %edx,P_RLINK(%ecx)
|
||||
movl P_RLINK(%eax),%ecx
|
||||
movl P_LINK(%eax),%edx
|
||||
movl %edx,P_LINK(%ecx)
|
||||
popl %edx
|
||||
movl $_qs,%ecx
|
||||
shll $3,%edx
|
||||
addl %edx,%ecx
|
||||
cmpl P_LINK(%ecx),%ecx /* q still has something? */
|
||||
je rem2
|
||||
shrl $3,%edx /* yes, set bit as still full */
|
||||
btsl %edx,_whichqs
|
||||
rem2:
|
||||
movl $0,P_RLINK(%eax) /* zap reverse link to indicate off list */
|
||||
ret
|
||||
|
||||
rem3: .asciz "remrq"
|
||||
sw0: .asciz "swtch"
|
||||
|
||||
/*
|
||||
* When no processes are on the runq, Swtch branches to idle
|
||||
* to wait for something to come ready.
|
||||
*/
|
||||
ALIGN_TEXT
|
||||
Idle:
|
||||
sti
|
||||
SHOW_STI
|
||||
|
||||
ALIGN_TEXT
|
||||
idle_loop:
|
||||
call _spl0
|
||||
cmpl $0,_whichqs
|
||||
jne sw1
|
||||
hlt /* wait for interrupt */
|
||||
jmp idle_loop
|
||||
|
||||
badsw:
|
||||
pushl $sw0
|
||||
call _panic
|
||||
/*NOTREACHED*/
|
||||
|
||||
/*
|
||||
* Swtch()
|
||||
*/
|
||||
SUPERALIGN_TEXT /* so profiling doesn't lump Idle with swtch().. */
|
||||
ENTRY(swtch)
|
||||
|
||||
incl _cnt+V_SWTCH
|
||||
|
||||
/* switch to new process. first, save context as needed */
|
||||
|
||||
movl _curproc,%ecx
|
||||
|
||||
/* if no process to save, don't bother */
|
||||
testl %ecx,%ecx
|
||||
je sw1
|
||||
|
||||
movl P_ADDR(%ecx),%ecx
|
||||
|
||||
movl (%esp),%eax /* Hardware registers */
|
||||
movl %eax,PCB_EIP(%ecx)
|
||||
movl %ebx,PCB_EBX(%ecx)
|
||||
movl %esp,PCB_ESP(%ecx)
|
||||
movl %ebp,PCB_EBP(%ecx)
|
||||
movl %esi,PCB_ESI(%ecx)
|
||||
movl %edi,PCB_EDI(%ecx)
|
||||
|
||||
#if NNPX > 0
|
||||
/* have we used fp, and need a save? */
|
||||
mov _curproc,%eax
|
||||
cmp %eax,_npxproc
|
||||
jne 1f
|
||||
pushl %ecx /* h/w bugs make saving complicated */
|
||||
leal PCB_SAVEFPU(%ecx),%eax
|
||||
pushl %eax
|
||||
call _npxsave /* do it in a big C function */
|
||||
popl %eax
|
||||
popl %ecx
|
||||
1:
|
||||
#endif /* NNPX > 0 */
|
||||
|
||||
movl _CMAP2,%eax /* save temporary map PTE */
|
||||
movl %eax,PCB_CMAP2(%ecx) /* in our context */
|
||||
movl $0,_curproc /* out of process */
|
||||
|
||||
# movw _cpl,%ax
|
||||
# movw %ax,PCB_IML(%ecx) /* save ipl */
|
||||
|
||||
/* save is done, now choose a new process or idle */
|
||||
sw1:
|
||||
cli
|
||||
SHOW_CLI
|
||||
movl _whichqs,%edi
|
||||
2:
|
||||
/* XXX - bsf is sloow */
|
||||
bsfl %edi,%eax /* find a full q */
|
||||
je Idle /* if none, idle */
|
||||
/* XX update whichqs? */
|
||||
swfnd:
|
||||
btrl %eax,%edi /* clear q full status */
|
||||
jnb 2b /* if it was clear, look for another */
|
||||
movl %eax,%ebx /* save which one we are using */
|
||||
|
||||
shll $3,%eax
|
||||
addl $_qs,%eax /* select q */
|
||||
movl %eax,%esi
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
cmpl P_LINK(%eax),%eax /* linked to self? (e.g. not on list) */
|
||||
je badsw /* not possible */
|
||||
#endif
|
||||
|
||||
movl P_LINK(%eax),%ecx /* unlink from front of process q */
|
||||
movl P_LINK(%ecx),%edx
|
||||
movl %edx,P_LINK(%eax)
|
||||
movl P_RLINK(%ecx),%eax
|
||||
movl %eax,P_RLINK(%edx)
|
||||
|
||||
cmpl P_LINK(%ecx),%esi /* q empty */
|
||||
je 3f
|
||||
btsl %ebx,%edi /* nope, set to indicate full */
|
||||
3:
|
||||
movl %edi,_whichqs /* update q status */
|
||||
|
||||
movl $0,%eax
|
||||
movl %eax,_want_resched
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
cmpl %eax,P_WCHAN(%ecx)
|
||||
jne badsw
|
||||
cmpb $SRUN,P_STAT(%ecx)
|
||||
jne badsw
|
||||
#endif
|
||||
|
||||
movl %eax,P_RLINK(%ecx) /* isolate process to run */
|
||||
movl P_ADDR(%ecx),%edx
|
||||
movl PCB_CR3(%edx),%ebx
|
||||
|
||||
/* switch address space */
|
||||
movl %ebx,%cr3
|
||||
|
||||
/* restore context */
|
||||
movl PCB_EBX(%edx),%ebx
|
||||
movl PCB_ESP(%edx),%esp
|
||||
movl PCB_EBP(%edx),%ebp
|
||||
movl PCB_ESI(%edx),%esi
|
||||
movl PCB_EDI(%edx),%edi
|
||||
movl PCB_EIP(%edx),%eax
|
||||
movl %eax,(%esp)
|
||||
|
||||
movl PCB_CMAP2(%edx),%eax /* get temporary map */
|
||||
movl %eax,_CMAP2 /* reload temporary map PTE */
|
||||
|
||||
movl %ecx,_curproc /* into next process */
|
||||
movl %edx,_curpcb
|
||||
|
||||
pushl %edx /* save p to return */
|
||||
/*
|
||||
* XXX - 0.0 forgot to save it - is that why this was commented out in 0.1?
|
||||
* I think restoring the cpl is unnecessary, but we must turn off the cli
|
||||
* now that spl*() don't do it as a side affect.
|
||||
*/
|
||||
pushl PCB_IML(%edx)
|
||||
sti
|
||||
SHOW_STI
|
||||
#if 0
|
||||
call _splx
|
||||
#endif
|
||||
addl $4,%esp
|
||||
/*
|
||||
* XXX - 0.0 gets here via swtch_to_inactive(). I think 0.1 gets here in the
|
||||
* same way. Better return a value.
|
||||
*/
|
||||
popl %eax /* return(p); */
|
||||
ret
|
||||
|
||||
ENTRY(mvesp)
|
||||
movl %esp,%eax
|
||||
ret
|
||||
/*
|
||||
* struct proc *swtch_to_inactive(p) ; struct proc *p;
|
||||
*
|
||||
* At exit of a process, move off the address space of the
|
||||
* process and onto a "safe" one. Then, on a temporary stack
|
||||
* return and run code that disposes of the old state.
|
||||
* Since this code requires a parameter from the "old" stack,
|
||||
* pass it back as a return value.
|
||||
*/
|
||||
ENTRY(swtch_to_inactive)
|
||||
popl %edx /* old pc */
|
||||
popl %eax /* arg, our return value */
|
||||
movl _IdlePTD,%ecx
|
||||
movl %ecx,%cr3 /* good bye address space */
|
||||
#write buffer?
|
||||
movl $tmpstk-4,%esp /* temporary stack, compensated for call */
|
||||
jmp %edx /* return, execute remainder of cleanup */
|
||||
|
||||
/*
|
||||
* savectx(pcb, altreturn)
|
||||
* Update pcb, saving current processor state and arranging
|
||||
* for alternate return ala longjmp in swtch if altreturn is true.
|
||||
*/
|
||||
ENTRY(savectx)
|
||||
movl 4(%esp),%ecx
|
||||
movw _cpl,%ax
|
||||
movw %ax,PCB_IML(%ecx)
|
||||
movl (%esp),%eax
|
||||
movl %eax,PCB_EIP(%ecx)
|
||||
movl %ebx,PCB_EBX(%ecx)
|
||||
movl %esp,PCB_ESP(%ecx)
|
||||
movl %ebp,PCB_EBP(%ecx)
|
||||
movl %esi,PCB_ESI(%ecx)
|
||||
movl %edi,PCB_EDI(%ecx)
|
||||
|
||||
#if NNPX > 0
|
||||
/*
|
||||
* If npxproc == NULL, then the npx h/w state is irrelevant and the
|
||||
* state had better already be in the pcb. This is true for forks
|
||||
* but not for dumps (the old book-keeping with FP flags in the pcb
|
||||
* always lost for dumps because the dump pcb has 0 flags).
|
||||
*
|
||||
* If npxproc != NULL, then we have to save the npx h/w state to
|
||||
* npxproc's pcb and copy it to the requested pcb, or save to the
|
||||
* requested pcb and reload. Copying is easier because we would
|
||||
* have to handle h/w bugs for reloading. We used to lose the
|
||||
* parent's npx state for forks by forgetting to reload.
|
||||
*/
|
||||
mov _npxproc,%eax
|
||||
testl %eax,%eax
|
||||
je 1f
|
||||
|
||||
pushl %ecx
|
||||
movl P_ADDR(%eax),%eax
|
||||
leal PCB_SAVEFPU(%eax),%eax
|
||||
pushl %eax
|
||||
pushl %eax
|
||||
call _npxsave
|
||||
popl %eax
|
||||
popl %eax
|
||||
popl %ecx
|
||||
|
||||
pushl %ecx
|
||||
pushl $108+8*2 /* XXX h/w state size + padding */
|
||||
leal PCB_SAVEFPU(%ecx),%ecx
|
||||
pushl %ecx
|
||||
pushl %eax
|
||||
call _bcopy
|
||||
addl $12,%esp
|
||||
popl %ecx
|
||||
1:
|
||||
#endif /* NNPX > 0 */
|
||||
|
||||
movl _CMAP2,%edx /* save temporary map PTE */
|
||||
movl %edx,PCB_CMAP2(%ecx) /* in our context */
|
||||
|
||||
cmpl $0,8(%esp)
|
||||
je 1f
|
||||
movl %esp,%edx /* relocate current sp relative to pcb */
|
||||
subl $_kstack,%edx /* (sp is relative to kstack): */
|
||||
addl %edx,%ecx /* pcb += sp - kstack; */
|
||||
movl %eax,(%ecx) /* write return pc at (relocated) sp@ */
|
||||
|
||||
/* this mess deals with replicating register state gcc hides */
|
||||
movl 12(%esp),%eax
|
||||
movl %eax,12(%ecx)
|
||||
movl 16(%esp),%eax
|
||||
movl %eax,16(%ecx)
|
||||
movl 20(%esp),%eax
|
||||
movl %eax,20(%ecx)
|
||||
movl 24(%esp),%eax
|
||||
movl %eax,24(%ecx)
|
||||
1:
|
||||
xorl %eax,%eax /* return 0 */
|
||||
ret
|
||||
|
||||
/*
|
||||
* addupc(int pc, struct uprof *up, int ticks):
|
||||
* update profiling information for the user process.
|
||||
*/
|
||||
ENTRY(addupc)
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
movl 12(%ebp),%edx /* up */
|
||||
movl 8(%ebp),%eax /* pc */
|
||||
|
||||
subl PR_OFF(%edx),%eax /* pc -= up->pr_off */
|
||||
jl L1 /* if (pc < 0) return */
|
||||
|
||||
shrl $1,%eax /* praddr = pc >> 1 */
|
||||
imull PR_SCALE(%edx),%eax /* praddr *= up->pr_scale */
|
||||
shrl $15,%eax /* praddr = praddr << 15 */
|
||||
andl $-2,%eax /* praddr &= ~1 */
|
||||
|
||||
cmpl PR_SIZE(%edx),%eax /* if (praddr > up->pr_size) return */
|
||||
ja L1
|
||||
|
||||
/* addl %eax,%eax /* praddr -> word offset */
|
||||
addl PR_BASE(%edx),%eax /* praddr += up-> pr_base */
|
||||
movl 16(%ebp),%ecx /* ticks */
|
||||
|
||||
movl _curpcb,%edx
|
||||
movl $proffault,PCB_ONFAULT(%edx)
|
||||
addl %ecx,(%eax) /* storage location += ticks */
|
||||
movl $0,PCB_ONFAULT(%edx)
|
||||
L1:
|
||||
leave
|
||||
ret
|
||||
|
||||
ALIGN_TEXT
|
||||
proffault:
|
||||
/* if we get a fault, then kill profiling all together */
|
||||
movl $0,PCB_ONFAULT(%edx) /* squish the fault handler */
|
||||
movl 12(%ebp),%ecx
|
||||
movl $0,PR_SCALE(%ecx) /* up->pr_scale = 0 */
|
||||
leave
|
||||
ret
|
||||
|
||||
/* To be done: */
|
||||
ENTRY(astoff)
|
||||
ret
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)trap.c 7.4 (Berkeley) 5/13/91
|
||||
* $Id: trap.c,v 1.5 1993/11/01 11:51:29 chmr Exp $
|
||||
* $Id: trap.c,v 1.6 1993/11/04 15:05:41 davidg Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -85,6 +85,38 @@ int dostacklimits;
|
||||
unsigned rcr2();
|
||||
extern short cpl;
|
||||
|
||||
#define MAX_TRAP_MSG 27
|
||||
char *trap_msg[] = {
|
||||
"reserved addressing fault", /* 0 T_RESADFLT */
|
||||
"privileged instruction fault", /* 1 T_PRIVINFLT */
|
||||
"reserved operand fault", /* 2 T_RESOPFLT */
|
||||
"breakpoint instruction fault", /* 3 T_BPTFLT */
|
||||
"", /* 4 unused */
|
||||
"system call trap", /* 5 T_SYSCALL */
|
||||
"arithmetic trap", /* 6 T_ARITHTRAP */
|
||||
"system forced exception", /* 7 T_ASTFLT */
|
||||
"segmentation (limit) fault", /* 8 T_SEGFLT */
|
||||
"protection fault", /* 9 T_PROTFLT */
|
||||
"trace trap", /* 10 T_TRCTRAP */
|
||||
"", /* 11 unused */
|
||||
"page fault", /* 12 T_PAGEFLT */
|
||||
"page table fault", /* 13 T_TABLEFLT */
|
||||
"alignment fault", /* 14 T_ALIGNFLT */
|
||||
"kernel stack pointer not valid", /* 15 T_KSPNOTVAL */
|
||||
"bus error", /* 16 T_BUSERR */
|
||||
"kernel debugger fault", /* 17 T_KDBTRAP */
|
||||
"integer divide fault", /* 18 T_DIVIDE */
|
||||
"non-maskable interrupt trap", /* 19 T_NMI */
|
||||
"overflow trap", /* 20 T_OFLOW */
|
||||
"FPU bounds check fault", /* 21 T_BOUND */
|
||||
"FPU device not available", /* 22 T_DNA */
|
||||
"double fault", /* 23 T_DOUBLEFLT */
|
||||
"FPU operand fetch fault", /* 24 T_FPOPFLT */
|
||||
"invalid TSS fault", /* 25 T_TSSFLT */
|
||||
"segment not present fault", /* 26 T_SEGNPFLT */
|
||||
"stack fault", /* 27 T_STKFLT */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* trap(frame):
|
||||
@ -165,13 +197,23 @@ if(curpcb == 0 || curproc == 0) goto we_re_toast;
|
||||
return;
|
||||
#endif
|
||||
|
||||
printf("trap type %d code = %x eip = %x cs = %x eflags = %x ",
|
||||
if ((type & ~T_USER) <= MAX_TRAP_MSG)
|
||||
printf("\n\nFatal trap %d: %s while in %s mode\n",
|
||||
type & ~T_USER, trap_msg[type & ~T_USER],
|
||||
(type & T_USER) ? "user" : "kernel");
|
||||
|
||||
printf("trap type = %d, code = %x\n eip = %x, cs = %x, eflags = %x, ",
|
||||
frame.tf_trapno, frame.tf_err, frame.tf_eip,
|
||||
frame.tf_cs, frame.tf_eflags);
|
||||
eva = rcr2();
|
||||
printf("cr2 %x cpl %x\n", eva, cpl);
|
||||
/* type &= ~T_USER; */ /* XXX what the hell is this */
|
||||
panic("trap");
|
||||
eva = rcr2();
|
||||
printf("cr2 = %x, current priority = %x\n", eva, cpl);
|
||||
|
||||
type &= ~T_USER;
|
||||
if (type <= MAX_TRAP_MSG)
|
||||
panic(trap_msg[type]);
|
||||
else
|
||||
panic("unknown/reserved trap");
|
||||
|
||||
/*NOTREACHED*/
|
||||
|
||||
case T_SEGNPFLT|T_USER:
|
||||
|
43
sys/i386/include/asmacros.h
Normal file
43
sys/i386/include/asmacros.h
Normal file
@ -0,0 +1,43 @@
|
||||
#define ALIGN_DATA .align 2 /* 4 byte alignment, zero filled */
|
||||
#define ALIGN_TEXT .align 2,0x90 /* 4-byte alignment, nop filled */
|
||||
#define SUPERALIGN_TEXT .align 4,0x90 /* 16-byte alignment (better for 486), nop filled */
|
||||
|
||||
#define GEN_ENTRY(name) ALIGN_TEXT; .globl name; name:
|
||||
#define NON_GPROF_ENTRY(name) GEN_ENTRY(_/**/name)
|
||||
|
||||
#ifdef GPROF
|
||||
/*
|
||||
* ALTENTRY() must be before a corresponding ENTRY() so that it can jump
|
||||
* over the mcounting.
|
||||
*/
|
||||
#define ALTENTRY(name) GEN_ENTRY(_/**/name); MCOUNT; jmp 2f
|
||||
#define ENTRY(name) GEN_ENTRY(_/**/name); MCOUNT; 2:
|
||||
/*
|
||||
* The call to mcount supports the usual (bad) conventions. We allocate
|
||||
* some data and pass a pointer to it although the FreeBSD doesn't use
|
||||
* the data. We set up a frame before calling mcount because that is
|
||||
* the standard convention although it makes work for both mcount and
|
||||
* callers.
|
||||
*/
|
||||
#define MCOUNT .data; ALIGN_DATA; 1:; .long 0; .text; \
|
||||
pushl %ebp; movl %esp,%ebp; \
|
||||
movl $1b,%eax; call mcount; popl %ebp
|
||||
#else
|
||||
/*
|
||||
* ALTENTRY() has to align because it is before a corresponding ENTRY().
|
||||
* ENTRY() has to align to because there may be no ALTENTRY() before it.
|
||||
* If there is a previous ALTENTRY() then the alignment code is empty.
|
||||
*/
|
||||
#define ALTENTRY(name) GEN_ENTRY(_/**/name)
|
||||
#define ENTRY(name) GEN_ENTRY(_/**/name)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef DUMMY_NOPS /* this will break some older machines */
|
||||
#define FASTER_NOP
|
||||
#define NOP
|
||||
#else
|
||||
#define FASTER_NOP pushl %eax ; inb $0x84,%al ; popl %eax
|
||||
#define NOP pushl %eax ; inb $0x84,%al ; inb $0x84,%al ; popl %eax
|
||||
#endif
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)param.h 5.8 (Berkeley) 6/28/91
|
||||
* $Id: param.h,v 1.7 1993/10/15 10:07:43 rgrimes Exp $
|
||||
* $Id: param.h,v 1.8 1993/11/07 17:42:58 wollman Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_PARAM_H_
|
||||
@ -74,8 +74,6 @@
|
||||
#define KERNBASE 0xFE000000 /* start of kernel virtual */
|
||||
#define BTOPKERNBASE ((u_long)KERNBASE >> PGSHIFT)
|
||||
|
||||
#define KERNSIZE 0x00C00000 /* size of kernel virtual */
|
||||
|
||||
#define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */
|
||||
#define DEV_BSIZE (1 << DEV_BSHIFT)
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
*
|
||||
* from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90
|
||||
* from: @(#)pmap.h 7.4 (Berkeley) 5/12/91
|
||||
* $Id: pmap.h,v 1.4 1993/10/15 10:07:44 rgrimes Exp $
|
||||
* $Id: pmap.h,v 1.5 1993/11/07 17:43:02 wollman Exp $
|
||||
*/
|
||||
|
||||
#ifndef _PMAP_MACHINE_
|
||||
@ -118,11 +118,11 @@ typedef struct pde pd_entry_t; /* page directory entry */
|
||||
typedef struct pte pt_entry_t; /* Mach page table entry */
|
||||
|
||||
/*
|
||||
* NKPDE controls the virtual space of the kernel, what ever is left is
|
||||
* given to the user (NUPDE)
|
||||
* NKPDE controls the virtual space of the kernel, what ever is left, minus
|
||||
* the alternate page table area is given to the user (NUPDE)
|
||||
*/
|
||||
#define NKPDE 7 /* number of kernel pde's */
|
||||
#define NUPDE (NPTEPG-NKPDE) /* number of user pde's */
|
||||
#define NUPDE (NPTEPG-NKPDE-1)/* number of user pde's */
|
||||
/*
|
||||
* The *PTDI values control the layout of virtual memory
|
||||
*
|
||||
@ -132,7 +132,11 @@ typedef struct pte pt_entry_t; /* Mach page table entry */
|
||||
#define APTDPTDI (NPTEPG-1) /* alt ptd entry that points to APTD */
|
||||
#define KPTDI (APTDPTDI-NKPDE)/* start of kernel virtual pde's */
|
||||
#define PTDPTDI (KPTDI-1) /* ptd entry that points to ptd! */
|
||||
#define UPTDI (PTDPTDI-1) /* ptd entry for u./kernel&user stack */
|
||||
#define KSTKPTDI (PTDPTDI-1) /* ptd entry for u./kernel&user stack */
|
||||
#define KSTKPTEOFF (NBPG/sizeof(struct pde)-UPAGES) /* pte entry for kernel stack */
|
||||
|
||||
#define PDESIZE sizeof(struct pde) /* for assembly files */
|
||||
#define PTESIZE sizeof(struct pte) /* for assembly files */
|
||||
|
||||
/*
|
||||
* Address of current and alternate address space page table maps
|
||||
|
@ -36,7 +36,7 @@
|
||||
*
|
||||
* @(#)icu.s 7.2 (Berkeley) 5/21/91
|
||||
*
|
||||
* $Id$
|
||||
* $Id: icu.s,v 1.3 1993/09/06 16:12:03 rgrimes Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -55,20 +55,28 @@
|
||||
#define SOFTCLOCKMASK 0x8000
|
||||
|
||||
.data
|
||||
|
||||
.globl _cpl
|
||||
_cpl: .long 0xffff # current priority (all off)
|
||||
_cpl: .long 0xffff /* current priority (all off) */
|
||||
|
||||
.globl _imen
|
||||
_imen: .long 0xffff # interrupt mask enable (all off)
|
||||
_imen: .long 0xffff /* interrupt mask enable (all off) */
|
||||
|
||||
/* .globl _highmask */
|
||||
_highmask: .long HIGHMASK
|
||||
.globl _ttymask
|
||||
|
||||
.globl _ttymask, _biomask, _netmask
|
||||
_ttymask: .long 0
|
||||
.globl _biomask
|
||||
_biomask: .long 0
|
||||
.globl _netmask
|
||||
_netmask: .long 0
|
||||
.globl _ipending
|
||||
|
||||
.globl _ipending, _astpending
|
||||
_ipending: .long 0
|
||||
_astpending: .long 0 /* tells us an AST needs to be taken */
|
||||
|
||||
.globl _netisr
|
||||
_netisr: .long 0 /* set with bits for which queue to service */
|
||||
|
||||
vec:
|
||||
.long vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7
|
||||
.long vec8, vec9, vec10, vec11, vec12, vec13, vec14, vec15
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)trap.c 7.4 (Berkeley) 5/13/91
|
||||
* $Id: trap.c,v 1.5 1993/11/01 11:51:29 chmr Exp $
|
||||
* $Id: trap.c,v 1.6 1993/11/04 15:05:41 davidg Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -85,6 +85,38 @@ int dostacklimits;
|
||||
unsigned rcr2();
|
||||
extern short cpl;
|
||||
|
||||
#define MAX_TRAP_MSG 27
|
||||
char *trap_msg[] = {
|
||||
"reserved addressing fault", /* 0 T_RESADFLT */
|
||||
"privileged instruction fault", /* 1 T_PRIVINFLT */
|
||||
"reserved operand fault", /* 2 T_RESOPFLT */
|
||||
"breakpoint instruction fault", /* 3 T_BPTFLT */
|
||||
"", /* 4 unused */
|
||||
"system call trap", /* 5 T_SYSCALL */
|
||||
"arithmetic trap", /* 6 T_ARITHTRAP */
|
||||
"system forced exception", /* 7 T_ASTFLT */
|
||||
"segmentation (limit) fault", /* 8 T_SEGFLT */
|
||||
"protection fault", /* 9 T_PROTFLT */
|
||||
"trace trap", /* 10 T_TRCTRAP */
|
||||
"", /* 11 unused */
|
||||
"page fault", /* 12 T_PAGEFLT */
|
||||
"page table fault", /* 13 T_TABLEFLT */
|
||||
"alignment fault", /* 14 T_ALIGNFLT */
|
||||
"kernel stack pointer not valid", /* 15 T_KSPNOTVAL */
|
||||
"bus error", /* 16 T_BUSERR */
|
||||
"kernel debugger fault", /* 17 T_KDBTRAP */
|
||||
"integer divide fault", /* 18 T_DIVIDE */
|
||||
"non-maskable interrupt trap", /* 19 T_NMI */
|
||||
"overflow trap", /* 20 T_OFLOW */
|
||||
"FPU bounds check fault", /* 21 T_BOUND */
|
||||
"FPU device not available", /* 22 T_DNA */
|
||||
"double fault", /* 23 T_DOUBLEFLT */
|
||||
"FPU operand fetch fault", /* 24 T_FPOPFLT */
|
||||
"invalid TSS fault", /* 25 T_TSSFLT */
|
||||
"segment not present fault", /* 26 T_SEGNPFLT */
|
||||
"stack fault", /* 27 T_STKFLT */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* trap(frame):
|
||||
@ -165,13 +197,23 @@ if(curpcb == 0 || curproc == 0) goto we_re_toast;
|
||||
return;
|
||||
#endif
|
||||
|
||||
printf("trap type %d code = %x eip = %x cs = %x eflags = %x ",
|
||||
if ((type & ~T_USER) <= MAX_TRAP_MSG)
|
||||
printf("\n\nFatal trap %d: %s while in %s mode\n",
|
||||
type & ~T_USER, trap_msg[type & ~T_USER],
|
||||
(type & T_USER) ? "user" : "kernel");
|
||||
|
||||
printf("trap type = %d, code = %x\n eip = %x, cs = %x, eflags = %x, ",
|
||||
frame.tf_trapno, frame.tf_err, frame.tf_eip,
|
||||
frame.tf_cs, frame.tf_eflags);
|
||||
eva = rcr2();
|
||||
printf("cr2 %x cpl %x\n", eva, cpl);
|
||||
/* type &= ~T_USER; */ /* XXX what the hell is this */
|
||||
panic("trap");
|
||||
eva = rcr2();
|
||||
printf("cr2 = %x, current priority = %x\n", eva, cpl);
|
||||
|
||||
type &= ~T_USER;
|
||||
if (type <= MAX_TRAP_MSG)
|
||||
panic(trap_msg[type]);
|
||||
else
|
||||
panic("unknown/reserved trap");
|
||||
|
||||
/*NOTREACHED*/
|
||||
|
||||
case T_SEGNPFLT|T_USER:
|
||||
|
Loading…
Reference in New Issue
Block a user