mirror of
https://github.com/FDOS/kernel.git
synced 2025-04-08 17:15:17 +02:00
New irqstack.asm: irq 2, 3, 4, 5, 6, 10, 11, 12, 14, 15 now use the IBM
interrupt sharing protocol for STACKS. Affect int 2 too, but not IRQ 7 (INT 0fh) and IRQ 9 (INT 71h) git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@1498 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
parent
0278349047
commit
3ae2e90e08
@ -30,81 +30,89 @@
|
||||
|
||||
; Code for stack switching during hardware interrupts.
|
||||
|
||||
; Format of interrupt sharing protocol interrupt handler entry point:
|
||||
; Offset Size Description (Table 02568)
|
||||
; 00h 2 BYTEs short jump to actual start of interrupt handler, immediately
|
||||
; following this data block (EBh 10h)
|
||||
; 02h DWORD address of next handler in chain
|
||||
; 06h WORD signature 424Bh
|
||||
; 08h BYTE EOI flag
|
||||
; 00h software interrupt or secondary hardware interrupt handler
|
||||
; 80h primary hardware interrupt handler (will issue EOI to
|
||||
; interrupt controller)
|
||||
; 09h 2 BYTEs short jump to hardware reset routine
|
||||
; must point at a valid FAR procedure (may be just RETF)
|
||||
; 0Bh 7 BYTEs reserved (0) by IBM for future expansion
|
||||
|
||||
; Ralf Brown documents that irq 2, 3, 4, 5, 6, 10, 11, 12, 14, 15 use the above
|
||||
; protocol..
|
||||
; MS (http://support.microsoft.com/kb/84300/)
|
||||
; documents that STACKS= implements stacks for interrupt vectors
|
||||
; 02H, 08-0EH, 70H, and 72-77H.
|
||||
; that means that we need to redirect NMI (INT 2), irq 0, 1, 8, 13 without sharing
|
||||
; irq 9 (==irq2) and irq 7 (printer) are not handled at all
|
||||
|
||||
%include "segs.inc"
|
||||
|
||||
segment _IRQTEXT
|
||||
|
||||
old_vectors times 16 dd 0
|
||||
stack_size dw 0
|
||||
stack_top dw 0
|
||||
stack_offs dw 0
|
||||
stack_seg dw 0
|
||||
|
||||
irq_0: push bx
|
||||
mov bx, 0 * 4
|
||||
jmp short general_irq_service
|
||||
%macro irq 0
|
||||
call general_irq_service
|
||||
dd 0
|
||||
%endmacro
|
||||
|
||||
irq_1: push bx
|
||||
mov bx, 1 * 4
|
||||
jmp short general_irq_service
|
||||
%macro irqshare 1
|
||||
jmp short %%1
|
||||
dd 0
|
||||
dw 424bh
|
||||
db 0
|
||||
jmp short retf%1
|
||||
times 7 db 0
|
||||
%%1: call general_irq_service_share
|
||||
%endmacro
|
||||
|
||||
irq_2: push bx
|
||||
mov bx, 2 * 4
|
||||
jmp short general_irq_service
|
||||
nmi: irq
|
||||
irq_0: irq
|
||||
irq_1: irq
|
||||
irq_08: irq
|
||||
irq_0d: irq
|
||||
|
||||
irq_3: push bx
|
||||
mov bx, 3 * 4
|
||||
jmp short general_irq_service
|
||||
retf1: retf
|
||||
irq_2: irqshare 1
|
||||
irq_3: irqshare 1
|
||||
irq_4: irqshare 1
|
||||
irq_5: irqshare 1
|
||||
irq_6: irqshare 1
|
||||
irq_0a: irqshare 2
|
||||
irq_0b: irqshare 2
|
||||
irq_0c: irqshare 2
|
||||
irq_0e: irqshare 2
|
||||
irq_0f: irqshare 2
|
||||
retf2: retf
|
||||
|
||||
irq_4: push bx
|
||||
mov bx, 4 * 4
|
||||
jmp short general_irq_service
|
||||
; align to 100h to align _LOWTEXT for interrupt vectors
|
||||
; in kernel.asm
|
||||
times (100h - ($ - stack_size)) db 0
|
||||
|
||||
irq_5: push bx
|
||||
mov bx, 5 * 4
|
||||
jmp short general_irq_service
|
||||
|
||||
irq_6: push bx
|
||||
mov bx, 6 * 4
|
||||
jmp short general_irq_service
|
||||
|
||||
irq_7: push bx
|
||||
mov bx, 7 * 4
|
||||
jmp short general_irq_service
|
||||
|
||||
irq_08: push bx
|
||||
mov bx, 8 * 4
|
||||
jmp short general_irq_service
|
||||
|
||||
irq_09: push bx
|
||||
mov bx, 9 * 4
|
||||
jmp short general_irq_service
|
||||
|
||||
irq_0a: push bx
|
||||
mov bx, 0ah * 4
|
||||
jmp short general_irq_service
|
||||
|
||||
irq_0b: push bx
|
||||
mov bx, 0bh * 4
|
||||
jmp short general_irq_service
|
||||
|
||||
irq_0c: push bx
|
||||
mov bx, 0ch * 4
|
||||
jmp short general_irq_service
|
||||
|
||||
irq_0d: push bx
|
||||
mov bx, 0dh * 4
|
||||
jmp short general_irq_service
|
||||
|
||||
irq_0e: push bx
|
||||
mov bx, 0eh * 4
|
||||
jmp short general_irq_service
|
||||
|
||||
irq_0f: push bx
|
||||
mov bx, 0fh * 4
|
||||
; jmp short general_irq_service
|
||||
segment _IO_TEXT
|
||||
|
||||
general_irq_service:
|
||||
push bx
|
||||
mov bx, sp
|
||||
mov bx, [ss:bx+2] ; return address->old ivec
|
||||
jmp common_irq
|
||||
|
||||
general_irq_service_share:
|
||||
push bx
|
||||
mov bx, sp
|
||||
mov bx, [ss:bx+2] ; return address->old ivec
|
||||
sub bx, irq_3 - irq_2 - 2
|
||||
common_irq:
|
||||
push dx
|
||||
push ax
|
||||
push ds
|
||||
@ -129,7 +137,7 @@ general_irq_service:
|
||||
sub [stack_top], ax
|
||||
|
||||
pushf
|
||||
call far word [old_vectors+bx]
|
||||
call far word [bx]
|
||||
|
||||
cli
|
||||
add [stack_top], ax
|
||||
@ -140,30 +148,26 @@ general_irq_service:
|
||||
mov ss, dx ; switch back to old stack
|
||||
mov sp, ax
|
||||
|
||||
pop ds ; restore registers and return
|
||||
return: pop ds ; restore registers and return
|
||||
pop ax
|
||||
pop dx
|
||||
pop bx
|
||||
add sp, 2
|
||||
iret
|
||||
|
||||
dont_switch: pushf
|
||||
call far word [old_vectors+bx]
|
||||
pop ds
|
||||
pop ax
|
||||
pop dx
|
||||
pop bx
|
||||
iret
|
||||
call far word [bx]
|
||||
jmp short return
|
||||
|
||||
|
||||
; align to 100h to align _LOWTEXT for interrupt vectors
|
||||
; in kernel.asm
|
||||
times (100h - ($ - old_vectors)) db 0
|
||||
|
||||
segment INIT_TEXT
|
||||
|
||||
global _init_stacks
|
||||
; VOID init_stacks(VOID FAR *stack_base, COUNT nStacks, WORD stackSize);
|
||||
|
||||
int_numbers: db 2,8,9,70h,75h
|
||||
int_numbers_share: db 0ah,0bh,0ch,0dh,0eh,72h,73h,74h,76h,77h
|
||||
|
||||
_init_stacks:
|
||||
push bp
|
||||
mov bp, sp
|
||||
@ -174,6 +178,7 @@ _init_stacks:
|
||||
|
||||
mov ax,LGROUP
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
|
||||
mov bx, [bp+4]
|
||||
mov dx, [bp+6]
|
||||
@ -186,31 +191,22 @@ _init_stacks:
|
||||
|
||||
mul cx
|
||||
add ax, bx
|
||||
mov [stack_top], ax
|
||||
; stack_top = stack_size * nStacks + stack_seg:stack_offs
|
||||
mov [stack_top], ax
|
||||
|
||||
xor ax, ax
|
||||
mov ds, ax
|
||||
|
||||
mov ax, LGROUP
|
||||
mov es, ax
|
||||
|
||||
mov di, old_vectors
|
||||
mov si, 8 * 4
|
||||
mov cx, 10h
|
||||
rep movsw
|
||||
|
||||
mov si, 70h * 4
|
||||
mov cx, 10h
|
||||
rep movsw
|
||||
|
||||
push ds
|
||||
pop es
|
||||
|
||||
mov di, 8 * 4
|
||||
mov dx, irq_0
|
||||
mov di, nmi + 3
|
||||
mov dx, nmi
|
||||
mov bx, int_numbers
|
||||
mov cx, int_numbers_share - int_numbers
|
||||
mov bp, irq_1 - irq_0
|
||||
call set_vect
|
||||
|
||||
mov di, 70h * 4
|
||||
inc dx ; skip over retf (not di: go from nmi+3 to irq_2+2)
|
||||
mov cx, _init_stacks - int_numbers_share
|
||||
mov bp, irq_3 - irq_2
|
||||
call set_vect
|
||||
|
||||
pop si
|
||||
@ -219,16 +215,32 @@ _init_stacks:
|
||||
pop bp
|
||||
ret
|
||||
|
||||
; set interrupt vectors:
|
||||
; in: es=LGROUP, ds=0
|
||||
; bx: pointer to int_numbers bytes in cs
|
||||
; cx: number of vectors to set
|
||||
; dx: pointer to es:nmi and so on (new interrupt vectors)
|
||||
; di: pointer to es:nmi+3 and so on (pointer to place of old interrupt vectors)
|
||||
; bp: difference in offset between irq structures
|
||||
; out: bx, si, di updated, cx=0, ax destroyed
|
||||
set_vect:
|
||||
mov cx, 8
|
||||
mov al, [cs:bx] ; get next int vector offset
|
||||
inc bx
|
||||
cbw
|
||||
mov si, ax
|
||||
shl si, 1
|
||||
shl si, 1 ; now ds:si -> int vector, es:di -> nmi+3, etc
|
||||
|
||||
movsw ; save old vector
|
||||
movsw
|
||||
|
||||
set_next: mov ax, dx
|
||||
cli
|
||||
stosw
|
||||
mov ax, LGROUP
|
||||
stosw
|
||||
mov [si-4], dx ; set new vector
|
||||
mov [si-2], es
|
||||
sti
|
||||
add dx, irq_1 - irq_0
|
||||
loop set_next
|
||||
|
||||
add dx, bp
|
||||
lea di, [di+bp-4] ; update di, compensating for movsw
|
||||
loop set_vect
|
||||
|
||||
ret
|
||||
|
Loading…
x
Reference in New Issue
Block a user