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:
David Greenman 1993-11-13 02:25:21 +00:00
parent d05214e6b4
commit 0967373e1c
30 changed files with 6271 additions and 5471 deletions

View 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
View 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
View 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"

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

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
View 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

View File

@ -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:

View 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

View File

@ -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

View File

@ -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} $<

View File

@ -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} $<

View File

@ -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
View 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"

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

435
sys/i386/i386/swtch.s Normal file
View 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

View File

@ -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:

View 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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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: