i386/exception.s,
Keep track of interrupt nesting level. It is normally 0 for syscalls and traps, but is fudged to 1 for their exit processing in case they metamorphose into an interrupt handler. i386/genassym.c; Remove support for the obsolete pcb_iml and pcb_cmap2. Add support for pcb_inl. i386/swtch.s: Fudge the interrupt nesting level across context switches and in the idle loop so that the work for preemptive context switches gets counted as interrupt time, the work for voluntary context switches gets counted mostly as system time (the part when curproc == 0 gets counted as interrupt time), and only truly idle time gets counted as idle time. Remove obsolete support (commented out and otherwise) for pcb_iml. Load curpcb just before curproc instead of just after so that curpcb is always valid if curproc is. A few more changes like this may fix tracing through context switches. Remove obsolete function swtch_to_inactive(). include/cpu.h: Use the new interrupt nesting level variable to implement a non-fake CLF_INTR() so that accounting for the interrupt state works. You can use top, iostat or (best) an up to date systat to see interrupt overheads. I see the expected huge interrupt overheads for ISA devices (on a 486DX/33, about 55% for an IDE drive transferring 1250K/sec and the same for a WD8013EBT network card transferring 1100K/sec). The huge interrupt overheads for serial devices are unfortunately normally invisible. include/pcb.h: Remove the obsolete pcb_iml and pcb_cmap2. Replace them by padding to preserve binary compatibility. Use part of the new padding for pcb_inl. isa/icu.s: isa/vector.s: Keep track of interrupt nesting level.
This commit is contained in:
parent
d7649fc477
commit
40161a97d9
@ -33,7 +33,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: swtch.s,v 1.16 1994/10/25 07:25:56 davidg Exp $
|
||||
* $Id: swtch.s,v 1.17 1994/10/30 20:09:13 bde Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h" /* for NNPX */
|
||||
@ -250,13 +250,19 @@ _idle:
|
||||
ALIGN_TEXT
|
||||
idle_loop:
|
||||
cli
|
||||
movb $1,_intr_nesting_level /* charge Intr if we leave */
|
||||
cmpl $0,_whichrtqs /* real-time queue */
|
||||
jne sw1a
|
||||
cmpl $0,_whichqs /* normal queue */
|
||||
jne nortqr
|
||||
cmpl $0,_whichidqs /* 'idle' queue */
|
||||
jne idqr
|
||||
movb $0,_intr_nesting_level /* charge Idle for this loop */
|
||||
#ifdef APM
|
||||
/*
|
||||
* XXX it breaks the rules to call a function while interrupts are
|
||||
* disabled. How long before apm enables them?
|
||||
*/
|
||||
call _apm_cpu_idle
|
||||
call _apm_cpu_busy
|
||||
#else
|
||||
@ -294,24 +300,24 @@ ENTRY(cpu_switch)
|
||||
movl %esi,PCB_ESI(%ecx)
|
||||
movl %edi,PCB_EDI(%ecx)
|
||||
|
||||
movb _intr_nesting_level,%al
|
||||
movb %al,PCB_INL(%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
|
||||
addl $PCB_SAVEFPU,%ecx /* h/w bugs make saving complicated */
|
||||
pushl %ecx
|
||||
call _npxsave /* do it in a big C function */
|
||||
popl %eax
|
||||
popl %ecx
|
||||
1:
|
||||
#endif /* NNPX > 0 */
|
||||
|
||||
movl $0,_curproc /* out of process */
|
||||
movb $1,_intr_nesting_level /* charge Intr, not Sys/Idle */
|
||||
|
||||
# movw _cpl,%ax
|
||||
# movw %ax,PCB_IML(%ecx) /* save ipl */
|
||||
movl $0,_curproc /* out of process */
|
||||
|
||||
/* save is done, now choose a new process or idle */
|
||||
sw1:
|
||||
@ -436,8 +442,11 @@ swtch_com:
|
||||
movl PCB_EIP(%edx),%eax
|
||||
movl %eax,(%esp)
|
||||
|
||||
movl %ecx,_curproc /* into next process */
|
||||
movl %edx,_curpcb
|
||||
movl %ecx,_curproc /* into next process */
|
||||
|
||||
movb PCB_INL(%edx),%al
|
||||
movb %al,_intr_nesting_level
|
||||
|
||||
#ifdef USER_LDT
|
||||
cmpl $0, PCB_USERLDT(%edx)
|
||||
@ -454,46 +463,12 @@ swtch_com:
|
||||
2:
|
||||
#endif
|
||||
|
||||
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
|
||||
#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(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,%esp /* temporary stack, compensated for call */
|
||||
MEXITCOUNT
|
||||
jmp %edx /* return, execute remainder of cleanup */
|
||||
|
||||
/*
|
||||
* savectx(pcb, altreturn)
|
||||
@ -502,8 +477,6 @@ ENTRY(swtch_to_inactive)
|
||||
*/
|
||||
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)
|
||||
|
@ -30,7 +30,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: exception.s,v 1.4 1994/08/13 03:49:38 wollman Exp $
|
||||
* $Id: exception.s,v 1.5 1994/09/28 03:37:49 bde Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h" /* NNPX */
|
||||
@ -130,9 +130,11 @@ IDTVEC(rsvd)
|
||||
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.
|
||||
* Handle like an interrupt (except for accounting) so that we can
|
||||
* call npxintr to clear the error. It would be better to handle
|
||||
* npx interrupts as traps. This used to be difficult for nested
|
||||
* interrupts, but now it is fairly easy - mask nested ones the
|
||||
* same as SWI_AST's.
|
||||
*/
|
||||
pushl $0 /* dumby error code */
|
||||
pushl $0 /* dumby trap type */
|
||||
@ -150,6 +152,7 @@ IDTVEC(fpu)
|
||||
orl $SWI_AST_MASK,%eax
|
||||
movl %eax,_cpl
|
||||
call _npxintr
|
||||
incb _intr_nesting_level
|
||||
MEXITCOUNT
|
||||
jmp _doreti
|
||||
#else /* NNPX > 0 */
|
||||
@ -217,6 +220,7 @@ calltrap:
|
||||
*/
|
||||
pushl %eax
|
||||
subl $4,%esp
|
||||
incb _intr_nesting_level
|
||||
MEXITCOUNT
|
||||
jmp _doreti
|
||||
|
||||
@ -265,6 +269,7 @@ IDTVEC(syscall)
|
||||
*/
|
||||
pushl $0 /* cpl to restore */
|
||||
subl $4,%esp
|
||||
movb $1,_intr_nesting_level
|
||||
MEXITCOUNT
|
||||
jmp _doreti
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: exception.s,v 1.4 1994/08/13 03:49:38 wollman Exp $
|
||||
* $Id: exception.s,v 1.5 1994/09/28 03:37:49 bde Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h" /* NNPX */
|
||||
@ -130,9 +130,11 @@ IDTVEC(rsvd)
|
||||
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.
|
||||
* Handle like an interrupt (except for accounting) so that we can
|
||||
* call npxintr to clear the error. It would be better to handle
|
||||
* npx interrupts as traps. This used to be difficult for nested
|
||||
* interrupts, but now it is fairly easy - mask nested ones the
|
||||
* same as SWI_AST's.
|
||||
*/
|
||||
pushl $0 /* dumby error code */
|
||||
pushl $0 /* dumby trap type */
|
||||
@ -150,6 +152,7 @@ IDTVEC(fpu)
|
||||
orl $SWI_AST_MASK,%eax
|
||||
movl %eax,_cpl
|
||||
call _npxintr
|
||||
incb _intr_nesting_level
|
||||
MEXITCOUNT
|
||||
jmp _doreti
|
||||
#else /* NNPX > 0 */
|
||||
@ -217,6 +220,7 @@ calltrap:
|
||||
*/
|
||||
pushl %eax
|
||||
subl $4,%esp
|
||||
incb _intr_nesting_level
|
||||
MEXITCOUNT
|
||||
jmp _doreti
|
||||
|
||||
@ -265,6 +269,7 @@ IDTVEC(syscall)
|
||||
*/
|
||||
pushl $0 /* cpl to restore */
|
||||
subl $4,%esp
|
||||
movb $1,_intr_nesting_level
|
||||
MEXITCOUNT
|
||||
jmp _doreti
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)genassym.c 5.11 (Berkeley) 5/10/91
|
||||
* $Id: genassym.c,v 1.19 1994/10/26 22:01:11 bde Exp $
|
||||
* $Id: genassym.c,v 1.20 1994/11/18 05:27:32 phk Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@ -164,8 +164,7 @@ main()
|
||||
printf("#define\tPCB_SAVEFPU %d\n", &pcb->pcb_savefpu);
|
||||
printf("#define\tFP_USESEMC %d\n", FP_USESEMC);
|
||||
printf("#define\tPCB_SAVEEMC %d\n", &pcb->pcb_saveemc);
|
||||
printf("#define\tPCB_CMAP2 %d\n", &pcb->pcb_cmap2);
|
||||
printf("#define\tPCB_IML %d\n", &pcb->pcb_iml);
|
||||
printf("#define\tPCB_INL %d\n", &pcb->pcb_inl);
|
||||
printf("#define\tPCB_ONFAULT %d\n", &pcb->pcb_onfault);
|
||||
|
||||
printf("#define\tTF_ES %d\n", &tf->tf_es);
|
||||
|
@ -33,7 +33,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: swtch.s,v 1.16 1994/10/25 07:25:56 davidg Exp $
|
||||
* $Id: swtch.s,v 1.17 1994/10/30 20:09:13 bde Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h" /* for NNPX */
|
||||
@ -250,13 +250,19 @@ _idle:
|
||||
ALIGN_TEXT
|
||||
idle_loop:
|
||||
cli
|
||||
movb $1,_intr_nesting_level /* charge Intr if we leave */
|
||||
cmpl $0,_whichrtqs /* real-time queue */
|
||||
jne sw1a
|
||||
cmpl $0,_whichqs /* normal queue */
|
||||
jne nortqr
|
||||
cmpl $0,_whichidqs /* 'idle' queue */
|
||||
jne idqr
|
||||
movb $0,_intr_nesting_level /* charge Idle for this loop */
|
||||
#ifdef APM
|
||||
/*
|
||||
* XXX it breaks the rules to call a function while interrupts are
|
||||
* disabled. How long before apm enables them?
|
||||
*/
|
||||
call _apm_cpu_idle
|
||||
call _apm_cpu_busy
|
||||
#else
|
||||
@ -294,24 +300,24 @@ ENTRY(cpu_switch)
|
||||
movl %esi,PCB_ESI(%ecx)
|
||||
movl %edi,PCB_EDI(%ecx)
|
||||
|
||||
movb _intr_nesting_level,%al
|
||||
movb %al,PCB_INL(%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
|
||||
addl $PCB_SAVEFPU,%ecx /* h/w bugs make saving complicated */
|
||||
pushl %ecx
|
||||
call _npxsave /* do it in a big C function */
|
||||
popl %eax
|
||||
popl %ecx
|
||||
1:
|
||||
#endif /* NNPX > 0 */
|
||||
|
||||
movl $0,_curproc /* out of process */
|
||||
movb $1,_intr_nesting_level /* charge Intr, not Sys/Idle */
|
||||
|
||||
# movw _cpl,%ax
|
||||
# movw %ax,PCB_IML(%ecx) /* save ipl */
|
||||
movl $0,_curproc /* out of process */
|
||||
|
||||
/* save is done, now choose a new process or idle */
|
||||
sw1:
|
||||
@ -436,8 +442,11 @@ swtch_com:
|
||||
movl PCB_EIP(%edx),%eax
|
||||
movl %eax,(%esp)
|
||||
|
||||
movl %ecx,_curproc /* into next process */
|
||||
movl %edx,_curpcb
|
||||
movl %ecx,_curproc /* into next process */
|
||||
|
||||
movb PCB_INL(%edx),%al
|
||||
movb %al,_intr_nesting_level
|
||||
|
||||
#ifdef USER_LDT
|
||||
cmpl $0, PCB_USERLDT(%edx)
|
||||
@ -454,46 +463,12 @@ swtch_com:
|
||||
2:
|
||||
#endif
|
||||
|
||||
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
|
||||
#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(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,%esp /* temporary stack, compensated for call */
|
||||
MEXITCOUNT
|
||||
jmp %edx /* return, execute remainder of cleanup */
|
||||
|
||||
/*
|
||||
* savectx(pcb, altreturn)
|
||||
@ -502,8 +477,6 @@ ENTRY(swtch_to_inactive)
|
||||
*/
|
||||
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)
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)cpu.h 5.4 (Berkeley) 5/9/91
|
||||
* $Id: cpu.h,v 1.16 1994/11/05 22:44:34 bde Exp $
|
||||
* $Id: cpu.h,v 1.17 1994/11/26 09:27:58 phk Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_CPU_H_
|
||||
@ -58,8 +58,8 @@
|
||||
#define cpu_set_init_frame(p, fp) (p)->p_md.md_regs = fp
|
||||
|
||||
#define CLKF_USERMODE(framep) (ISPL((framep)->cf_cs) == SEL_UPL)
|
||||
#define CLKF_INTR(framep) (0)
|
||||
#if 0
|
||||
#define CLKF_INTR(framep) (intr_nesting_level >= 2)
|
||||
#if 1
|
||||
/*
|
||||
* XXX splsoftclock() is very broken and barely worth fixing. It doesn't
|
||||
* turn off the clock bit in imen or in the icu. (This is not a serious
|
||||
@ -127,6 +127,7 @@ struct cpu_nameclass {
|
||||
extern int bootverbose;
|
||||
extern int cpu;
|
||||
extern int cpu_class;
|
||||
extern u_char intr_nesting_level;
|
||||
extern struct cpu_nameclass i386_cpus[];
|
||||
extern int want_resched; /* resched was called */
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)pcb.h 5.10 (Berkeley) 5/12/91
|
||||
* $Id: pcb.h,v 1.6 1994/08/13 03:49:50 wollman Exp $
|
||||
* $Id: pcb.h,v 1.7 1994/10/08 22:21:33 phk Exp $
|
||||
*/
|
||||
|
||||
#ifndef _I386_PCB_H_
|
||||
@ -73,10 +73,10 @@ struct pcb {
|
||||
#endif
|
||||
#define FP_USESEMC 0x08 /* process uses EMC memory-mapped mode */
|
||||
#define FP_SOFTFP 0x20 /* process using software fltng pnt emulator */
|
||||
short pcb_iml; /* interrupt mask level */
|
||||
u_char pcb_inl; /* intr_nesting_level at context switch */
|
||||
caddr_t pcb_onfault; /* copyin/out fault recovery */
|
||||
long pcb_sigc[8]; /* XXX signal code trampoline */
|
||||
int pcb_cmap2; /* XXX temporary PTE - will prefault instead */
|
||||
int pad2; /* XXX unused - remove it if you change struct */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* from: vector.s, 386BSD 0.1 unknown origin
|
||||
* $Id: vector.s,v 1.9 1994/09/20 21:35:49 bde Exp $
|
||||
* $Id: vector.s,v 1.10 1994/11/01 23:29:50 bde Exp $
|
||||
*/
|
||||
|
||||
#include <i386/isa/icu.h>
|
||||
@ -147,6 +147,7 @@ IDTVEC(fastintr/**/irq_num) ; \
|
||||
movl (2+8+1)*4(%esp),%eax ; /* ... cpl from thin frame */ \
|
||||
pushl %eax ; \
|
||||
subl $4,%esp ; /* junk for unit number */ \
|
||||
incb _intr_nesting_level ; \
|
||||
MEXITCOUNT ; \
|
||||
jmp _doreti
|
||||
|
||||
@ -172,7 +173,7 @@ IDTVEC(intr/**/irq_num) ; \
|
||||
movl _cpl,%eax ; \
|
||||
testb $IRQ_BIT(irq_num),%reg ; \
|
||||
jne 2f ; \
|
||||
1: ; \
|
||||
incb _intr_nesting_level ; \
|
||||
Xresume/**/irq_num: ; \
|
||||
FAKE_MCOUNT(12*4(%esp)) ; /* XXX late to avoid double count */ \
|
||||
movl _intr_countp + (irq_num) * 4,%eax ; \
|
||||
@ -254,6 +255,10 @@ imasks: /* masks for interrupt handlers */
|
||||
.space NHWI*4 /* padding; HWI masks are elsewhere */
|
||||
.long SWI_TTY_MASK, SWI_NET_MASK, 0, 0, 0, 0, 0, 0
|
||||
.long 0, 0, 0, 0, 0, 0, SWI_CLOCK_MASK, SWI_AST_MASK
|
||||
.globl _intr_nesting_level
|
||||
_intr_nesting_level:
|
||||
.byte 0
|
||||
.space 3
|
||||
|
||||
/*
|
||||
* Interrupt counters and names. The format of these and the label names
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* from: vector.s, 386BSD 0.1 unknown origin
|
||||
* $Id: vector.s,v 1.9 1994/09/20 21:35:49 bde Exp $
|
||||
* $Id: vector.s,v 1.10 1994/11/01 23:29:50 bde Exp $
|
||||
*/
|
||||
|
||||
#include <i386/isa/icu.h>
|
||||
@ -147,6 +147,7 @@ IDTVEC(fastintr/**/irq_num) ; \
|
||||
movl (2+8+1)*4(%esp),%eax ; /* ... cpl from thin frame */ \
|
||||
pushl %eax ; \
|
||||
subl $4,%esp ; /* junk for unit number */ \
|
||||
incb _intr_nesting_level ; \
|
||||
MEXITCOUNT ; \
|
||||
jmp _doreti
|
||||
|
||||
@ -172,7 +173,7 @@ IDTVEC(intr/**/irq_num) ; \
|
||||
movl _cpl,%eax ; \
|
||||
testb $IRQ_BIT(irq_num),%reg ; \
|
||||
jne 2f ; \
|
||||
1: ; \
|
||||
incb _intr_nesting_level ; \
|
||||
Xresume/**/irq_num: ; \
|
||||
FAKE_MCOUNT(12*4(%esp)) ; /* XXX late to avoid double count */ \
|
||||
movl _intr_countp + (irq_num) * 4,%eax ; \
|
||||
@ -254,6 +255,10 @@ imasks: /* masks for interrupt handlers */
|
||||
.space NHWI*4 /* padding; HWI masks are elsewhere */
|
||||
.long SWI_TTY_MASK, SWI_NET_MASK, 0, 0, 0, 0, 0, 0
|
||||
.long 0, 0, 0, 0, 0, 0, SWI_CLOCK_MASK, SWI_AST_MASK
|
||||
.globl _intr_nesting_level
|
||||
_intr_nesting_level:
|
||||
.byte 0
|
||||
.space 3
|
||||
|
||||
/*
|
||||
* Interrupt counters and names. The format of these and the label names
|
||||
|
@ -30,7 +30,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: exception.s,v 1.4 1994/08/13 03:49:38 wollman Exp $
|
||||
* $Id: exception.s,v 1.5 1994/09/28 03:37:49 bde Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h" /* NNPX */
|
||||
@ -130,9 +130,11 @@ IDTVEC(rsvd)
|
||||
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.
|
||||
* Handle like an interrupt (except for accounting) so that we can
|
||||
* call npxintr to clear the error. It would be better to handle
|
||||
* npx interrupts as traps. This used to be difficult for nested
|
||||
* interrupts, but now it is fairly easy - mask nested ones the
|
||||
* same as SWI_AST's.
|
||||
*/
|
||||
pushl $0 /* dumby error code */
|
||||
pushl $0 /* dumby trap type */
|
||||
@ -150,6 +152,7 @@ IDTVEC(fpu)
|
||||
orl $SWI_AST_MASK,%eax
|
||||
movl %eax,_cpl
|
||||
call _npxintr
|
||||
incb _intr_nesting_level
|
||||
MEXITCOUNT
|
||||
jmp _doreti
|
||||
#else /* NNPX > 0 */
|
||||
@ -217,6 +220,7 @@ calltrap:
|
||||
*/
|
||||
pushl %eax
|
||||
subl $4,%esp
|
||||
incb _intr_nesting_level
|
||||
MEXITCOUNT
|
||||
jmp _doreti
|
||||
|
||||
@ -265,6 +269,7 @@ IDTVEC(syscall)
|
||||
*/
|
||||
pushl $0 /* cpl to restore */
|
||||
subl $4,%esp
|
||||
movb $1,_intr_nesting_level
|
||||
MEXITCOUNT
|
||||
jmp _doreti
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)genassym.c 5.11 (Berkeley) 5/10/91
|
||||
* $Id: genassym.c,v 1.19 1994/10/26 22:01:11 bde Exp $
|
||||
* $Id: genassym.c,v 1.20 1994/11/18 05:27:32 phk Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@ -164,8 +164,7 @@ main()
|
||||
printf("#define\tPCB_SAVEFPU %d\n", &pcb->pcb_savefpu);
|
||||
printf("#define\tFP_USESEMC %d\n", FP_USESEMC);
|
||||
printf("#define\tPCB_SAVEEMC %d\n", &pcb->pcb_saveemc);
|
||||
printf("#define\tPCB_CMAP2 %d\n", &pcb->pcb_cmap2);
|
||||
printf("#define\tPCB_IML %d\n", &pcb->pcb_iml);
|
||||
printf("#define\tPCB_INL %d\n", &pcb->pcb_inl);
|
||||
printf("#define\tPCB_ONFAULT %d\n", &pcb->pcb_onfault);
|
||||
|
||||
printf("#define\tTF_ES %d\n", &tf->tf_es);
|
||||
|
@ -33,7 +33,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: swtch.s,v 1.16 1994/10/25 07:25:56 davidg Exp $
|
||||
* $Id: swtch.s,v 1.17 1994/10/30 20:09:13 bde Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h" /* for NNPX */
|
||||
@ -250,13 +250,19 @@ _idle:
|
||||
ALIGN_TEXT
|
||||
idle_loop:
|
||||
cli
|
||||
movb $1,_intr_nesting_level /* charge Intr if we leave */
|
||||
cmpl $0,_whichrtqs /* real-time queue */
|
||||
jne sw1a
|
||||
cmpl $0,_whichqs /* normal queue */
|
||||
jne nortqr
|
||||
cmpl $0,_whichidqs /* 'idle' queue */
|
||||
jne idqr
|
||||
movb $0,_intr_nesting_level /* charge Idle for this loop */
|
||||
#ifdef APM
|
||||
/*
|
||||
* XXX it breaks the rules to call a function while interrupts are
|
||||
* disabled. How long before apm enables them?
|
||||
*/
|
||||
call _apm_cpu_idle
|
||||
call _apm_cpu_busy
|
||||
#else
|
||||
@ -294,24 +300,24 @@ ENTRY(cpu_switch)
|
||||
movl %esi,PCB_ESI(%ecx)
|
||||
movl %edi,PCB_EDI(%ecx)
|
||||
|
||||
movb _intr_nesting_level,%al
|
||||
movb %al,PCB_INL(%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
|
||||
addl $PCB_SAVEFPU,%ecx /* h/w bugs make saving complicated */
|
||||
pushl %ecx
|
||||
call _npxsave /* do it in a big C function */
|
||||
popl %eax
|
||||
popl %ecx
|
||||
1:
|
||||
#endif /* NNPX > 0 */
|
||||
|
||||
movl $0,_curproc /* out of process */
|
||||
movb $1,_intr_nesting_level /* charge Intr, not Sys/Idle */
|
||||
|
||||
# movw _cpl,%ax
|
||||
# movw %ax,PCB_IML(%ecx) /* save ipl */
|
||||
movl $0,_curproc /* out of process */
|
||||
|
||||
/* save is done, now choose a new process or idle */
|
||||
sw1:
|
||||
@ -436,8 +442,11 @@ swtch_com:
|
||||
movl PCB_EIP(%edx),%eax
|
||||
movl %eax,(%esp)
|
||||
|
||||
movl %ecx,_curproc /* into next process */
|
||||
movl %edx,_curpcb
|
||||
movl %ecx,_curproc /* into next process */
|
||||
|
||||
movb PCB_INL(%edx),%al
|
||||
movb %al,_intr_nesting_level
|
||||
|
||||
#ifdef USER_LDT
|
||||
cmpl $0, PCB_USERLDT(%edx)
|
||||
@ -454,46 +463,12 @@ swtch_com:
|
||||
2:
|
||||
#endif
|
||||
|
||||
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
|
||||
#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(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,%esp /* temporary stack, compensated for call */
|
||||
MEXITCOUNT
|
||||
jmp %edx /* return, execute remainder of cleanup */
|
||||
|
||||
/*
|
||||
* savectx(pcb, altreturn)
|
||||
@ -502,8 +477,6 @@ ENTRY(swtch_to_inactive)
|
||||
*/
|
||||
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)
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)cpu.h 5.4 (Berkeley) 5/9/91
|
||||
* $Id: cpu.h,v 1.16 1994/11/05 22:44:34 bde Exp $
|
||||
* $Id: cpu.h,v 1.17 1994/11/26 09:27:58 phk Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_CPU_H_
|
||||
@ -58,8 +58,8 @@
|
||||
#define cpu_set_init_frame(p, fp) (p)->p_md.md_regs = fp
|
||||
|
||||
#define CLKF_USERMODE(framep) (ISPL((framep)->cf_cs) == SEL_UPL)
|
||||
#define CLKF_INTR(framep) (0)
|
||||
#if 0
|
||||
#define CLKF_INTR(framep) (intr_nesting_level >= 2)
|
||||
#if 1
|
||||
/*
|
||||
* XXX splsoftclock() is very broken and barely worth fixing. It doesn't
|
||||
* turn off the clock bit in imen or in the icu. (This is not a serious
|
||||
@ -127,6 +127,7 @@ struct cpu_nameclass {
|
||||
extern int bootverbose;
|
||||
extern int cpu;
|
||||
extern int cpu_class;
|
||||
extern u_char intr_nesting_level;
|
||||
extern struct cpu_nameclass i386_cpus[];
|
||||
extern int want_resched; /* resched was called */
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)pcb.h 5.10 (Berkeley) 5/12/91
|
||||
* $Id: pcb.h,v 1.6 1994/08/13 03:49:50 wollman Exp $
|
||||
* $Id: pcb.h,v 1.7 1994/10/08 22:21:33 phk Exp $
|
||||
*/
|
||||
|
||||
#ifndef _I386_PCB_H_
|
||||
@ -73,10 +73,10 @@ struct pcb {
|
||||
#endif
|
||||
#define FP_USESEMC 0x08 /* process uses EMC memory-mapped mode */
|
||||
#define FP_SOFTFP 0x20 /* process using software fltng pnt emulator */
|
||||
short pcb_iml; /* interrupt mask level */
|
||||
u_char pcb_inl; /* intr_nesting_level at context switch */
|
||||
caddr_t pcb_onfault; /* copyin/out fault recovery */
|
||||
long pcb_sigc[8]; /* XXX signal code trampoline */
|
||||
int pcb_cmap2; /* XXX temporary PTE - will prefault instead */
|
||||
int pad2; /* XXX unused - remove it if you change struct */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -36,7 +36,7 @@
|
||||
*
|
||||
* @(#)icu.s 7.2 (Berkeley) 5/21/91
|
||||
*
|
||||
* $Id: icu.s,v 1.14 1994/09/19 22:24:31 wollman Exp $
|
||||
* $Id: icu.s,v 1.15 1994/09/20 21:35:47 bde Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -102,6 +102,7 @@ doreti_next:
|
||||
jne doreti_unpend
|
||||
doreti_exit:
|
||||
movl %eax,_cpl
|
||||
decb _intr_nesting_level
|
||||
MEXITCOUNT
|
||||
popl %es
|
||||
popl %ds
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* from: vector.s, 386BSD 0.1 unknown origin
|
||||
* $Id: vector.s,v 1.9 1994/09/20 21:35:49 bde Exp $
|
||||
* $Id: vector.s,v 1.10 1994/11/01 23:29:50 bde Exp $
|
||||
*/
|
||||
|
||||
#include <i386/isa/icu.h>
|
||||
@ -147,6 +147,7 @@ IDTVEC(fastintr/**/irq_num) ; \
|
||||
movl (2+8+1)*4(%esp),%eax ; /* ... cpl from thin frame */ \
|
||||
pushl %eax ; \
|
||||
subl $4,%esp ; /* junk for unit number */ \
|
||||
incb _intr_nesting_level ; \
|
||||
MEXITCOUNT ; \
|
||||
jmp _doreti
|
||||
|
||||
@ -172,7 +173,7 @@ IDTVEC(intr/**/irq_num) ; \
|
||||
movl _cpl,%eax ; \
|
||||
testb $IRQ_BIT(irq_num),%reg ; \
|
||||
jne 2f ; \
|
||||
1: ; \
|
||||
incb _intr_nesting_level ; \
|
||||
Xresume/**/irq_num: ; \
|
||||
FAKE_MCOUNT(12*4(%esp)) ; /* XXX late to avoid double count */ \
|
||||
movl _intr_countp + (irq_num) * 4,%eax ; \
|
||||
@ -254,6 +255,10 @@ imasks: /* masks for interrupt handlers */
|
||||
.space NHWI*4 /* padding; HWI masks are elsewhere */
|
||||
.long SWI_TTY_MASK, SWI_NET_MASK, 0, 0, 0, 0, 0, 0
|
||||
.long 0, 0, 0, 0, 0, 0, SWI_CLOCK_MASK, SWI_AST_MASK
|
||||
.globl _intr_nesting_level
|
||||
_intr_nesting_level:
|
||||
.byte 0
|
||||
.space 3
|
||||
|
||||
/*
|
||||
* Interrupt counters and names. The format of these and the label names
|
||||
|
Loading…
Reference in New Issue
Block a user