PIT protected handles interrupts more correctly
This commit is contained in:
8
TODO.md
8
TODO.md
@@ -1,5 +1,8 @@
|
|||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
|
-
|
||||||
|
http://stackoverflow.com/questions/1858640/how-can-i-create-a-sleep-function-in-16bit-masm-assembly-x86
|
||||||
|
|
||||||
- cache:
|
- cache:
|
||||||
|
|
||||||
- http://stackoverflow.com/questions/1756825/how-can-i-do-a-cpu-cache-flush
|
- 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)
|
- 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
|
- 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
|
- 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
|
- 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
|
- mouse
|
||||||
|
|
||||||
|
|||||||
74
common.h
74
common.h
@@ -34,7 +34,7 @@ http://stackoverflow.com/questions/19776992/gas-altmacro-macro-with-a-percent-si
|
|||||||
|
|
||||||
/* Helpers */
|
/* Helpers */
|
||||||
|
|
||||||
/* Push regiesters ax, bx, cx and dx. Lightweight `pusha`. */
|
/* Push registers ax, bx, cx and dx. Lightweight `pusha`. */
|
||||||
.macro PUSH_ADX
|
.macro PUSH_ADX
|
||||||
push %ax
|
push %ax
|
||||||
push %bx
|
push %bx
|
||||||
@@ -370,6 +370,61 @@ idt_descriptor:
|
|||||||
pop %eax
|
pop %eax
|
||||||
.endm
|
.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 */
|
/* BIOS */
|
||||||
|
|
||||||
.macro CURSOR_POSITION x=$0, y=$0
|
.macro CURSOR_POSITION x=$0, y=$0
|
||||||
@@ -654,6 +709,23 @@ end:
|
|||||||
OUTB PIC_CMD_RESET, PORT_PIC_MASTER_CMD
|
OUTB PIC_CMD_RESET, PORT_PIC_MASTER_CMD
|
||||||
.endm
|
.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 */
|
/* PIT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ BEGIN
|
|||||||
CLEAR
|
CLEAR
|
||||||
STAGE2
|
STAGE2
|
||||||
PROTECTED_MODE
|
PROTECTED_MODE
|
||||||
IDT_SETUP_ENTRY $14, $handler
|
IDT_SETUP_ENTRY $14, $interrupt_handler
|
||||||
lidt idt_descriptor
|
lidt idt_descriptor
|
||||||
SETUP_PAGING_4M
|
SETUP_PAGING_4M
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ IDT_START
|
|||||||
IDT_SKIP 14
|
IDT_SKIP 14
|
||||||
IDT_ENTRY
|
IDT_ENTRY
|
||||||
IDT_END
|
IDT_END
|
||||||
handler:
|
interrupt_handler:
|
||||||
VGA_PRINT_STRING $message
|
VGA_PRINT_STRING $message
|
||||||
/*
|
/*
|
||||||
Mandatory because page faults push the error code to the stack.
|
Mandatory because page faults push the error code to the stack.
|
||||||
|
|||||||
@@ -1,14 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
# PIT protected mode
|
# 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"
|
#include "common.h"
|
||||||
@@ -16,45 +7,18 @@ BEGIN
|
|||||||
STAGE2
|
STAGE2
|
||||||
CLEAR
|
CLEAR
|
||||||
PROTECTED_MODE
|
PROTECTED_MODE
|
||||||
|
IDT_SETUP_48_ISRS
|
||||||
mov $47, %ecx
|
REMAP_PIC_32
|
||||||
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
|
|
||||||
|
|
||||||
OUTB $0b00110100, PORT_PIT_MODE
|
OUTB $0b00110100, PORT_PIT_MODE
|
||||||
PIT_SET_MIN_FREQ
|
PIT_SET_MIN_FREQ
|
||||||
|
|
||||||
sti
|
sti
|
||||||
jmp .
|
jmp .
|
||||||
|
IDT_48_ENTRIES
|
||||||
IDT_START
|
interrupt_handler:
|
||||||
.rept 48
|
pop %eax
|
||||||
IDT_ENTRY
|
VGA_PRINT_HEX_4 <%eax>
|
||||||
.endr
|
OUTB $0x61, $0x20
|
||||||
IDT_END
|
|
||||||
handler:
|
|
||||||
cli
|
|
||||||
VGA_PRINT_STRING $message
|
|
||||||
PIC_EOI
|
PIC_EOI
|
||||||
|
add $4, %esp
|
||||||
sti
|
sti
|
||||||
iret
|
iret
|
||||||
message:
|
|
||||||
.asciz "interrupt"
|
|
||||||
|
|||||||
Reference in New Issue
Block a user