Use the IDT handler stub
This commit is contained in:
42
common.h
42
common.h
@@ -374,29 +374,38 @@ idt_descriptor:
|
||||
.macro ISR_NOERRCODE i
|
||||
isr\()\i:
|
||||
cli
|
||||
/*
|
||||
Push a dummy 0 for interrupts that don't push any code.
|
||||
http://stackoverflow.com/questions/10581224/why-does-iret-from-a-page-fault-handler-generate-interrupt-13-general-protectio/33398064#33398064
|
||||
*/
|
||||
push $0
|
||||
push $\i
|
||||
jmp interrupt_handler
|
||||
jmp interrupt_handler_stub
|
||||
.endm
|
||||
|
||||
.macro ISR_ERRCODE i
|
||||
isr\()\i:
|
||||
cli
|
||||
push $\i
|
||||
jmp interrupt_handler
|
||||
jmp interrupt_handler_stub
|
||||
.endm
|
||||
|
||||
/*
|
||||
Entries and handlers.
|
||||
48 = 32 processor built-ins + 16 PIC interrupts.
|
||||
In addition to including this, you should also call
|
||||
- call IDT_SETUP_48_ISRS to setup the handler addreses.
|
||||
- define an `interrupt_handler(uint32 number, uint32 error)` function
|
||||
*/
|
||||
.macro IDT_48_ENTRIES
|
||||
/* IDT. */
|
||||
IDT_START
|
||||
.rept 48
|
||||
IDT_ENTRY
|
||||
.endr
|
||||
IDT_END
|
||||
|
||||
/* ISRs */
|
||||
.irp i, 0, 1, 2, 3, 4, 5, 6, 7
|
||||
ISR_NOERRCODE \i
|
||||
.endr
|
||||
@@ -411,6 +420,19 @@ Entries and handlers.
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48
|
||||
ISR_NOERRCODE \i
|
||||
.endr
|
||||
|
||||
/* Factor out things which we will want to do in every handler. */
|
||||
interrupt_handler_stub:
|
||||
cli
|
||||
call interrupt_handler
|
||||
/* If we are a PIC interrupt (>=32), do an EOI. */
|
||||
cmp $0x20, (%esp)
|
||||
jb interrupt_handler_stub.noeoi
|
||||
PIC_EOI
|
||||
interrupt_handler_stub.noeoi:
|
||||
add $8, %esp
|
||||
sti
|
||||
iret
|
||||
.endm
|
||||
|
||||
.macro IDT_SETUP_48_ISRS
|
||||
@@ -614,11 +636,11 @@ Expected output on screen:
|
||||
|
||||
12345678
|
||||
*/
|
||||
.macro VGA_PRINT_HEX_4 reg=<%eax>
|
||||
.macro VGA_PRINT_HEX_4 in=<%eax>
|
||||
LOCAL loop
|
||||
PUSH_EADX
|
||||
/* Null terminator. */
|
||||
mov \reg, %ecx
|
||||
mov \in, %ecx
|
||||
|
||||
/* Write ASCII representation to memory. */
|
||||
push $0
|
||||
@@ -739,6 +761,18 @@ but you don't have to wait much for each one.
|
||||
out %al, PORT_PIT_CHANNEL0
|
||||
.endm
|
||||
|
||||
/*
|
||||
Define the properties of the wave:
|
||||
|
||||
- Channel: 0
|
||||
- access mode: lobyte/hibyte
|
||||
- operating mode: rate generator
|
||||
- BCD/binary: binary
|
||||
*/
|
||||
.macro PIT_GENERATE_FREQUENCY
|
||||
OUTB $0b00110100, PORT_PIT_MODE
|
||||
.endm
|
||||
|
||||
/* IVT */
|
||||
|
||||
#define IVT_PIT 8
|
||||
|
||||
10
pit.S
10
pit.S
@@ -65,15 +65,7 @@ TODO learn to turn off the PIT after some iterations
|
||||
BEGIN
|
||||
IVT_PIT_SETUP
|
||||
|
||||
/*
|
||||
Define the properties of the wave:
|
||||
|
||||
- Channel: 0
|
||||
- access mode: lobyte/hibyte
|
||||
- operating mode: rate generator
|
||||
- BCD/binary: binary
|
||||
*/
|
||||
OUTB $0b00110100, PORT_PIT_MODE
|
||||
PIT_GENERATE_FREQUENCY
|
||||
|
||||
/*
|
||||
Set frequency of Channel 0.
|
||||
|
||||
@@ -9,16 +9,12 @@ BEGIN
|
||||
PROTECTED_MODE
|
||||
IDT_SETUP_48_ISRS
|
||||
REMAP_PIC_32
|
||||
OUTB $0b00110100, PORT_PIT_MODE
|
||||
PIT_GENERATE_FREQUENCY
|
||||
PIT_SET_MIN_FREQ
|
||||
sti
|
||||
jmp .
|
||||
IDT_48_ENTRIES
|
||||
interrupt_handler:
|
||||
pop %eax
|
||||
mov 4(%esp), %eax
|
||||
VGA_PRINT_HEX_4 <%eax>
|
||||
OUTB $0x61, $0x20
|
||||
PIC_EOI
|
||||
add $4, %esp
|
||||
sti
|
||||
iret
|
||||
ret
|
||||
|
||||
Reference in New Issue
Block a user