PIT protected handles interrupts more correctly

This commit is contained in:
Ciro Santilli
2015-11-10 16:52:46 +01:00
parent 881300bd22
commit 1e87cda4c0
4 changed files with 90 additions and 48 deletions

View File

@@ -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

View File

@@ -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 */
/* /*

View File

@@ -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.

View File

@@ -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"