PIT protected handles interrupts more correctly
This commit is contained in:
8
TODO.md
8
TODO.md
@@ -1,5 +1,8 @@
|
||||
# TODO
|
||||
|
||||
-
|
||||
http://stackoverflow.com/questions/1858640/how-can-i-create-a-sleep-function-in-16bit-masm-assembly-x86
|
||||
|
||||
- cache:
|
||||
|
||||
- http://stackoverflow.com/questions/1756825/how-can-i-do-a-cpu-cache-flush
|
||||
@@ -101,10 +104,13 @@
|
||||
|
||||
- keyboard through interrupt (high level BIOS int 16 that waits for input done)
|
||||
|
||||
Almost there! pit_protected almost works, the problem is that it only fires once: <http://board.flatassembler.net/topic.php?t=17437>
|
||||
Needs some resetting fixed it seems.
|
||||
|
||||
- happens on IRQ 1 as mentioned at: https://en.wikipedia.org/wiki/Interrupt_request_%28PC_architecture%29#Master_PIC
|
||||
- keyboard protected mode: http://stackoverflow.com/questions/219120/x86-assembly-protected-mode-keyboard-access
|
||||
- oszur does it with the i8042: http://stackoverflow.com/questions/22744624/keyboard-interrupt-handler-for-own-kernel-c
|
||||
- https://github.com/arjun024/mkeykernel contains a small example that is easy to dissect
|
||||
- happens on IRQ 1 as mentioned at: https://en.wikipedia.org/wiki/Interrupt_request_%28PC_architecture%29#Master_PIC
|
||||
|
||||
- mouse
|
||||
|
||||
|
||||
74
common.h
74
common.h
@@ -34,7 +34,7 @@ http://stackoverflow.com/questions/19776992/gas-altmacro-macro-with-a-percent-si
|
||||
|
||||
/* Helpers */
|
||||
|
||||
/* Push regiesters ax, bx, cx and dx. Lightweight `pusha`. */
|
||||
/* Push registers ax, bx, cx and dx. Lightweight `pusha`. */
|
||||
.macro PUSH_ADX
|
||||
push %ax
|
||||
push %bx
|
||||
@@ -370,6 +370,61 @@ idt_descriptor:
|
||||
pop %eax
|
||||
.endm
|
||||
|
||||
/* Shamelessly copied from James Molloy's tutorial. */
|
||||
.macro ISR_NOERRCODE i
|
||||
isr\()\i:
|
||||
cli
|
||||
push $0
|
||||
push $\i
|
||||
jmp interrupt_handler
|
||||
.endm
|
||||
|
||||
.macro ISR_ERRCODE i
|
||||
isr\()\i:
|
||||
cli
|
||||
push $\i
|
||||
jmp interrupt_handler
|
||||
.endm
|
||||
|
||||
/*
|
||||
Entries and handlers.
|
||||
48 = 32 processor built-ins + 16 PIC interrupts.
|
||||
*/
|
||||
.macro IDT_48_ENTRIES
|
||||
IDT_START
|
||||
.rept 48
|
||||
IDT_ENTRY
|
||||
.endr
|
||||
IDT_END
|
||||
|
||||
.irp i, 0, 1, 2, 3, 4, 5, 6, 7
|
||||
ISR_NOERRCODE \i
|
||||
.endr
|
||||
ISR_ERRCODE 8
|
||||
ISR_NOERRCODE 9
|
||||
.irp i, 10, 11, 12, 13, 14
|
||||
ISR_ERRCODE \i
|
||||
.endr
|
||||
.irp i, 15, 16, 17, 18, 19, \
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, \
|
||||
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, \
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48
|
||||
ISR_NOERRCODE \i
|
||||
.endr
|
||||
.endm
|
||||
|
||||
.macro IDT_SETUP_48_ISRS
|
||||
.irp i, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, \
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, \
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, \
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, \
|
||||
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, \
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48
|
||||
IDT_SETUP_ENTRY $\i, $isr\()\i
|
||||
.endr
|
||||
lidt idt_descriptor
|
||||
.endm
|
||||
|
||||
/* BIOS */
|
||||
|
||||
.macro CURSOR_POSITION x=$0, y=$0
|
||||
@@ -654,6 +709,23 @@ end:
|
||||
OUTB PIC_CMD_RESET, PORT_PIC_MASTER_CMD
|
||||
.endm
|
||||
|
||||
.macro REMAP_PIC_32
|
||||
/*
|
||||
Remap the PIC interrupts to start at 32.
|
||||
TODO understand.
|
||||
*/
|
||||
OUTB $0x11, PORT_PIC_MASTER_CMD
|
||||
OUTB $0x11, PORT_PIC_SLAVE_CMD
|
||||
OUTB $0x20, PORT_PIC_MASTER_DATA
|
||||
OUTB $0x28, PORT_PIC_SLAVE_DATA
|
||||
OUTB $0x04, PORT_PIC_MASTER_DATA
|
||||
OUTB $0x02, PORT_PIC_SLAVE_DATA
|
||||
OUTB $0x01, PORT_PIC_MASTER_DATA
|
||||
OUTB $0x01, PORT_PIC_SLAVE_DATA
|
||||
OUTB $0x00, PORT_PIC_MASTER_DATA
|
||||
OUTB $0x00, PORT_PIC_SLAVE_DATA
|
||||
.endm
|
||||
|
||||
/* PIT */
|
||||
|
||||
/*
|
||||
|
||||
@@ -19,7 +19,7 @@ BEGIN
|
||||
CLEAR
|
||||
STAGE2
|
||||
PROTECTED_MODE
|
||||
IDT_SETUP_ENTRY $14, $handler
|
||||
IDT_SETUP_ENTRY $14, $interrupt_handler
|
||||
lidt idt_descriptor
|
||||
SETUP_PAGING_4M
|
||||
|
||||
@@ -39,7 +39,7 @@ IDT_START
|
||||
IDT_SKIP 14
|
||||
IDT_ENTRY
|
||||
IDT_END
|
||||
handler:
|
||||
interrupt_handler:
|
||||
VGA_PRINT_STRING $message
|
||||
/*
|
||||
Mandatory because page faults push the error code to the stack.
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
/*
|
||||
# PIT protected mode
|
||||
|
||||
Unlike in real mode, for the protected mode to work well,
|
||||
we have to setup the IDT properly.
|
||||
TODO why? More maskable interrupts seem to be generated here by the PIC.
|
||||
|
||||
This handles all interrupts.
|
||||
This is not very generic, because we don't know which interrupt number we are handling,
|
||||
and cannot take the stack pushed error byte into account.
|
||||
But it works for a very simple example.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
@@ -16,45 +7,18 @@ BEGIN
|
||||
STAGE2
|
||||
CLEAR
|
||||
PROTECTED_MODE
|
||||
|
||||
mov $47, %ecx
|
||||
setup_idt:
|
||||
IDT_SETUP_ENTRY <%ecx>, $handler
|
||||
loop setup_idt
|
||||
|
||||
lidt idt_descriptor
|
||||
|
||||
/*
|
||||
Remap the PIC interrupts to start at 32.
|
||||
TODO understand.
|
||||
*/
|
||||
OUTB $0x11, PORT_PIC_MASTER_CMD
|
||||
OUTB $0x11, PORT_PIC_SLAVE_CMD
|
||||
OUTB $0x20, PORT_PIC_MASTER_DATA
|
||||
OUTB $0x28, PORT_PIC_SLAVE_DATA
|
||||
OUTB $0x04, PORT_PIC_MASTER_DATA
|
||||
OUTB $0x02, PORT_PIC_SLAVE_DATA
|
||||
OUTB $0x01, PORT_PIC_MASTER_DATA
|
||||
OUTB $0x01, PORT_PIC_SLAVE_DATA
|
||||
OUTB $0x00, PORT_PIC_MASTER_DATA
|
||||
OUTB $0x00, PORT_PIC_SLAVE_DATA
|
||||
|
||||
IDT_SETUP_48_ISRS
|
||||
REMAP_PIC_32
|
||||
OUTB $0b00110100, PORT_PIT_MODE
|
||||
PIT_SET_MIN_FREQ
|
||||
|
||||
sti
|
||||
jmp .
|
||||
|
||||
IDT_START
|
||||
.rept 48
|
||||
IDT_ENTRY
|
||||
.endr
|
||||
IDT_END
|
||||
handler:
|
||||
cli
|
||||
VGA_PRINT_STRING $message
|
||||
IDT_48_ENTRIES
|
||||
interrupt_handler:
|
||||
pop %eax
|
||||
VGA_PRINT_HEX_4 <%eax>
|
||||
OUTB $0x61, $0x20
|
||||
PIC_EOI
|
||||
add $4, %esp
|
||||
sti
|
||||
iret
|
||||
message:
|
||||
.asciz "interrupt"
|
||||
|
||||
Reference in New Issue
Block a user