driver/pic: IRQHandlerRaw jumped handler
This commit is contained in:
parent
193b29400a
commit
312703104d
@ -1,6 +1,9 @@
|
|||||||
format elf64
|
format elf64
|
||||||
|
|
||||||
|
include 'pic_constants.incS'
|
||||||
|
|
||||||
extrn irq_pic_IntHandler
|
extrn irq_pic_IntHandler
|
||||||
|
extrn irq_pic_IRQHandlerRaw
|
||||||
|
|
||||||
public irq_pic_IntHandler20h
|
public irq_pic_IntHandler20h
|
||||||
public irq_pic_IntHandler21h
|
public irq_pic_IntHandler21h
|
||||||
@ -23,9 +26,25 @@ public irq_pic_IntHandler2fh
|
|||||||
section '.text' executable
|
section '.text' executable
|
||||||
|
|
||||||
macro inth op1 {
|
macro inth op1 {
|
||||||
|
push rax
|
||||||
|
|
||||||
|
mov rax, [irq_pic_IRQHandlerRaw+op1*8]
|
||||||
|
test rax, rax
|
||||||
|
jz .noraw
|
||||||
|
|
||||||
|
; has raw handler
|
||||||
|
mov al, PIC_CMD_EOI
|
||||||
|
if op1 >= 8
|
||||||
|
out PIC2_COMMAND, al
|
||||||
|
end if
|
||||||
|
out PIC1_COMMAND, al
|
||||||
|
|
||||||
|
pop rax
|
||||||
|
jmp qword [irq_pic_IRQHandlerRaw+op1*8]
|
||||||
|
|
||||||
|
.noraw:
|
||||||
push rdi
|
push rdi
|
||||||
mov rdi, op1
|
mov rdi, op1
|
||||||
push rax
|
|
||||||
push rsi
|
push rsi
|
||||||
push rdx
|
push rdx
|
||||||
push rcx
|
push rcx
|
||||||
@ -41,8 +60,8 @@ macro inth op1 {
|
|||||||
pop rcx
|
pop rcx
|
||||||
pop rdx
|
pop rdx
|
||||||
pop rsi
|
pop rsi
|
||||||
pop rax
|
|
||||||
pop rdi
|
pop rdi
|
||||||
|
pop rax
|
||||||
iretq
|
iretq
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,11 @@ typedef SYSV_ABI void (*irq_pic_IRQHandlerType)();
|
|||||||
extern irq_pic_IRQHandlerType irq_pic_IRQHandler[16];
|
extern irq_pic_IRQHandlerType irq_pic_IRQHandler[16];
|
||||||
extern bool irq_pic_Enabled;
|
extern bool irq_pic_Enabled;
|
||||||
|
|
||||||
|
// If IRQHandlerRaw[irq] is not NULL, the function is jumped to (not called).
|
||||||
|
//
|
||||||
|
// So the handler should use IRET instead of RET, and save all the registers it uses.
|
||||||
|
extern void *irq_pic_IRQHandlerRaw[16];
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
|
|
||||||
irq_pic_IRQHandlerType irq_pic_IRQHandler[16];
|
irq_pic_IRQHandlerType irq_pic_IRQHandler[16];
|
||||||
|
void * irq_pic_IRQHandlerRaw[16];
|
||||||
bool irq_pic_Enabled;
|
bool irq_pic_Enabled;
|
||||||
|
|
||||||
void irq_pic_Init() {
|
void irq_pic_Init() {
|
||||||
@ -34,6 +35,7 @@ void irq_pic_Init() {
|
|||||||
outb_wait(PIC2_DATA, 0xff);
|
outb_wait(PIC2_DATA, 0xff);
|
||||||
|
|
||||||
memset(irq_pic_IRQHandler, 0, sizeof(irq_pic_IRQHandler)); // reset all IRQ handlers
|
memset(irq_pic_IRQHandler, 0, sizeof(irq_pic_IRQHandler)); // reset all IRQ handlers
|
||||||
|
memset(irq_pic_IRQHandlerRaw, 0, sizeof(irq_pic_IRQHandlerRaw));
|
||||||
|
|
||||||
// map the IRQ handlers
|
// map the IRQ handlers
|
||||||
interrupt_MapHandler(irq_pic_IntHandler20h, 0x20);
|
interrupt_MapHandler(irq_pic_IntHandler20h, 0x20);
|
||||||
|
Loading…
Reference in New Issue
Block a user