pc kernel: make syscall() return thru forkret() to handle exceptions

forkret() labels the instructions that can raise exceptions
so they can be handled in trap(). this can happen when
segment descriptors get invalidated.
This commit is contained in:
cinap_lenrek 2013-09-27 19:24:45 +02:00
parent 64f44612f2
commit c9bbe34bf6
3 changed files with 44 additions and 109 deletions

View file

@ -17,6 +17,8 @@
#define INVLPG BYTE $0x0F; BYTE $0x01; BYTE $0x39 /* INVLPG (%ecx) */
#define WBINVD BYTE $0x0F; BYTE $0x09
#define VectorSYSCALL 0x40
/*
* Macros for calculating offsets within the page directory base
* and page tables. Note that these are assembler-specific hence
@ -279,61 +281,6 @@ TEXT load_gs(SB), $0
MOVW AX, GS
RET
/*
* Save registers.
*/
TEXT saveregs(SB), $0
/* appease 8l */
SUBL $32, SP
POPL AX
POPL AX
POPL AX
POPL AX
POPL AX
POPL AX
POPL AX
POPL AX
PUSHL AX
PUSHL BX
PUSHL CX
PUSHL DX
PUSHL BP
PUSHL DI
PUSHL SI
PUSHFL
XCHGL 32(SP), AX /* swap return PC and saved flags */
XCHGL 0(SP), AX
XCHGL 32(SP), AX
RET
TEXT restoreregs(SB), $0
/* appease 8l */
PUSHL AX
PUSHL AX
PUSHL AX
PUSHL AX
PUSHL AX
PUSHL AX
PUSHL AX
PUSHL AX
ADDL $32, SP
XCHGL 32(SP), AX /* swap return PC and saved flags */
XCHGL 0(SP), AX
XCHGL 32(SP), AX
POPFL
POPL SI
POPL DI
POPL BP
POPL DX
POPL CX
POPL BX
POPL AX
RET
/*
* BIOS32.
*/
@ -926,6 +873,25 @@ _rndbytes:
_rnddone:
RET
/*
* Used to get to the first process:
* set up an interrupt return frame and IRET to user level.
*/
TEXT touser(SB), $0
PUSHL $(UDSEL) /* old ss */
MOVL sp+0(FP), AX /* old sp */
PUSHL AX
MOVL $0x200, AX /* interrupt enable flag */
PUSHL AX /* old flags */
PUSHL $(UESEL) /* old cs */
PUSHL $(UTZERO+32) /* old pc */
MOVL $(UDSEL), AX
MOVW AX, DS
MOVW AX, ES
MOVW AX, GS
MOVW AX, FS
IRETL
/*
* Interrupt/exception handling.
* Each entry in the vector table calls either _strayintr or _strayintrx depending
@ -975,6 +941,28 @@ TEXT _forkretpopds(SB), $0
TEXT _forkretiret(SB), $0
IRETL
/*
* This is merely _strayintr optimised to vector
* to syscall() without going through trap().
*/
TEXT _syscallintr(SB), $0
PUSHL $VectorSYSCALL /* trap type */
PUSHL DS
PUSHL ES
PUSHL FS
PUSHL GS
PUSHAL
MOVL $(KDSEL), AX
MOVW AX, DS
MOVW AX, ES
MOVL $syscall(SB), AX
PUSHL SP /* Ureg* argument to syscall */
PUSHL $forkret(SB) /* return pc */
JMP *AX
TEXT vectortable(SB), $0
CALL _strayintr(SB); BYTE $0x00 /* divide error */
CALL _strayintr(SB); BYTE $0x01 /* debug exception */

View file

@ -45,7 +45,6 @@ PORT=\
OBJ=\
l.$O\
plan9l.$O\
cga.$O\
i8253.$O\
i8259.$O\

View file

@ -1,52 +0,0 @@
#include "mem.h"
/*
* This must match io.h.
*/
#define VectorSYSCALL 0x40
/*
* Used to get to the first process:
* set up an interrupt return frame and IRET to user level.
*/
TEXT touser(SB), $0
PUSHL $(UDSEL) /* old ss */
MOVL sp+0(FP), AX /* old sp */
PUSHL AX
MOVL $0x200, AX /* interrupt enable flag */
PUSHL AX /* old flags */
PUSHL $(UESEL) /* old cs */
PUSHL $(UTZERO+32) /* old pc */
MOVL $(UDSEL), AX
MOVW AX, DS
MOVW AX, ES
MOVW AX, GS
MOVW AX, FS
IRETL
/*
* This is merely _strayintr from l.s optimised to vector
* to syscall() without going through trap().
*/
TEXT _syscallintr(SB), $0
PUSHL $VectorSYSCALL /* trap type */
PUSHL DS
PUSHL ES
PUSHL FS
PUSHL GS
PUSHAL
MOVL $(KDSEL), AX
MOVW AX, DS
MOVW AX, ES
PUSHL SP
CALL syscall(SB)
POPL AX
POPAL
POPL GS
POPL FS
POPL ES
POPL DS
ADDL $8, SP /* pop error code and trap type */
IRETL