feature: start to implement keyboard handler and better isrs/irqs
This commit is contained in:
parent
0812a06350
commit
4fb51d4356
7
headers/drivers.h
Normal file
7
headers/drivers.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "interrupts.h"
|
||||||
|
|
||||||
|
void load_drivers(void);
|
||||||
|
void keyboard_handler(struct registers *regs);
|
||||||
|
void clock_handler(struct registers *regs);
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
// doc : https://wiki.osdev.org/Interrupt_Descriptor_Table#IDTR
|
// doc : https://wiki.osdev.org/Interrupt_Descriptor_Table#IDTR
|
||||||
struct idt_descriptor {
|
struct idt_descriptor {
|
||||||
uint16_t size;
|
uint16_t size;
|
||||||
|
@ -2,5 +2,19 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
void exception_handler(void);
|
struct registers {
|
||||||
|
// data segment selector
|
||||||
|
uint32_t ds;
|
||||||
|
// general purpose registers pushed by pusha
|
||||||
|
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
|
||||||
|
// pushed by isr procedure
|
||||||
|
uint32_t int_no, err_code;
|
||||||
|
// pushed by CPU automatically
|
||||||
|
uint32_t eip, cs, eflags, useresp, ss;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*isr_t)(struct registers *);
|
||||||
|
|
||||||
|
void isr_handler(struct registers *regs);
|
||||||
void pic_send_eoi(uint8_t irq);
|
void pic_send_eoi(uint8_t irq);
|
||||||
|
void register_interrupt_handler(int index, isr_t handler);
|
||||||
|
8
src/drivers/clock.c
Normal file
8
src/drivers/clock.c
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include "interrupts.h"
|
||||||
|
#include "kprintf.h"
|
||||||
|
|
||||||
|
void clock_handler(struct registers *regs)
|
||||||
|
{
|
||||||
|
(void)regs;
|
||||||
|
kprintf("test\n");
|
||||||
|
}
|
8
src/drivers/drivers.c
Normal file
8
src/drivers/drivers.c
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include "drivers.h"
|
||||||
|
#include "interrupts.h"
|
||||||
|
|
||||||
|
void load_drivers(void)
|
||||||
|
{
|
||||||
|
register_interrupt_handler(1, keyboard_handler);
|
||||||
|
register_interrupt_handler(0, clock_handler);
|
||||||
|
}
|
10
src/drivers/keyboard.c
Normal file
10
src/drivers/keyboard.c
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "interrupts.h"
|
||||||
|
#include "kprintf.h"
|
||||||
|
#include "terminal.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void keyboard_handler(struct registers *regs)
|
||||||
|
{
|
||||||
|
(void)regs;
|
||||||
|
terminal_putchar(terminal_getkey().c);
|
||||||
|
}
|
@ -3,8 +3,8 @@
|
|||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#define NTMFDP 0
|
|
||||||
|
|
||||||
const char *faults[] = {
|
const char *faults[] = {
|
||||||
"division by zero",
|
"division by zero",
|
||||||
@ -29,36 +29,29 @@ const char *faults[] = {
|
|||||||
"SIMD floating point exception",
|
"SIMD floating point exception",
|
||||||
};
|
};
|
||||||
|
|
||||||
void exception_handler(void)
|
static isr_t interrupt_handlers[16];
|
||||||
|
|
||||||
|
void isr_handler(struct registers *regs)
|
||||||
{
|
{
|
||||||
int8_t index = -1;
|
|
||||||
__asm__ volatile("movb %%bl, %0" ::"m"(index));
|
|
||||||
|
|
||||||
if (index == -1) {
|
|
||||||
kprintf(KERN_ERR "interrupt triggered without a code\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
while (i < ARRAY_SIZE(faults)) {
|
while (i < ARRAY_SIZE(faults)) {
|
||||||
if (i == index)
|
if (i == regs->int_no)
|
||||||
kpanic("interrupt: %s\n", faults[i]);
|
kpanic("interrupt: %s\n", faults[i]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
kprintf(KERN_ERR "interrupt triggered with no matching code\n");
|
kprintf(KERN_ERR "interrupt triggered with no matching code\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void irq_handler(void)
|
void register_interrupt_handler(int i, isr_t handler)
|
||||||
{
|
{
|
||||||
int8_t index = -1;
|
interrupt_handlers[i] = handler;
|
||||||
__asm__ volatile("movb %%bl, %0" ::"m"(index));
|
}
|
||||||
|
|
||||||
pic_send_eoi(index);
|
void irq_handler(struct registers *regs)
|
||||||
if (index == -1) {
|
{
|
||||||
kprintf(KERN_ERR "interrupt triggered without a code\n");
|
if (regs->int_no != 0) {
|
||||||
return;
|
isr_t handler = interrupt_handlers[regs->int_no];
|
||||||
|
handler(regs);
|
||||||
}
|
}
|
||||||
if (index == 0)
|
pic_send_eoi(regs->int_no);
|
||||||
return;
|
|
||||||
kpanic("%d\n", index);
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#include "sys/io.h"
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
@ -1,45 +1,137 @@
|
|||||||
.intel_syntax noprefix
|
.intel_syntax noprefix
|
||||||
.extern irq_handler
|
.extern irq_handler
|
||||||
|
|
||||||
.macro irq_common_stub nb
|
irq_common_stub:
|
||||||
irq_stub_\nb:
|
// push general purpose registers
|
||||||
mov bl, \nb
|
pusha
|
||||||
call irq_handler
|
|
||||||
iret
|
|
||||||
.endm
|
|
||||||
|
|
||||||
irq_common_stub 0
|
// push data segment selector
|
||||||
irq_common_stub 1
|
mov ax, ds
|
||||||
irq_common_stub 2
|
push eax
|
||||||
irq_common_stub 3
|
|
||||||
irq_common_stub 4
|
// use kernel data segment
|
||||||
irq_common_stub 5
|
mov ax, 0x10
|
||||||
irq_common_stub 6
|
mov ds, ax
|
||||||
irq_common_stub 7
|
mov es, ax
|
||||||
irq_common_stub 8
|
mov fs, ax
|
||||||
irq_common_stub 9
|
mov gs, ax
|
||||||
irq_common_stub 10
|
// hand over stack to C function
|
||||||
irq_common_stub 11
|
push esp
|
||||||
irq_common_stub 12
|
// and call it
|
||||||
irq_common_stub 13
|
call irq_handler
|
||||||
irq_common_stub 14
|
// pop stack pointer again
|
||||||
irq_common_stub 15
|
pop eax
|
||||||
|
|
||||||
|
// restore original segment pointers segment
|
||||||
|
pop eax
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
|
||||||
|
// restore registers
|
||||||
|
popa
|
||||||
|
|
||||||
|
// remove int_no and err_code from stack
|
||||||
|
add esp, 8
|
||||||
|
|
||||||
|
iret
|
||||||
|
|
||||||
|
irq0:
|
||||||
|
push 0
|
||||||
|
push 32
|
||||||
|
jmp irq_common_stub
|
||||||
|
|
||||||
|
irq1:
|
||||||
|
push 1
|
||||||
|
push 33
|
||||||
|
jmp irq_common_stub
|
||||||
|
|
||||||
|
irq2:
|
||||||
|
push 2
|
||||||
|
push 34
|
||||||
|
jmp irq_common_stub
|
||||||
|
|
||||||
|
irq3:
|
||||||
|
push 3
|
||||||
|
push 35
|
||||||
|
jmp irq_common_stub
|
||||||
|
|
||||||
|
irq4:
|
||||||
|
push 4
|
||||||
|
push 36
|
||||||
|
jmp irq_common_stub
|
||||||
|
|
||||||
|
irq5:
|
||||||
|
push 5
|
||||||
|
push 37
|
||||||
|
jmp irq_common_stub
|
||||||
|
|
||||||
|
irq6:
|
||||||
|
push 6
|
||||||
|
push 38
|
||||||
|
jmp irq_common_stub
|
||||||
|
|
||||||
|
irq7:
|
||||||
|
push 7
|
||||||
|
push 39
|
||||||
|
jmp irq_common_stub
|
||||||
|
|
||||||
|
irq8:
|
||||||
|
push 8
|
||||||
|
push 40
|
||||||
|
jmp irq_common_stub
|
||||||
|
|
||||||
|
irq9:
|
||||||
|
push 9
|
||||||
|
push 41
|
||||||
|
jmp irq_common_stub
|
||||||
|
|
||||||
|
irq10:
|
||||||
|
push 10
|
||||||
|
push 42
|
||||||
|
jmp irq_common_stub
|
||||||
|
|
||||||
|
irq11:
|
||||||
|
push 11
|
||||||
|
push 43
|
||||||
|
jmp irq_common_stub
|
||||||
|
|
||||||
|
irq12:
|
||||||
|
push 12
|
||||||
|
push 44
|
||||||
|
jmp irq_common_stub
|
||||||
|
|
||||||
|
irq13:
|
||||||
|
push 13
|
||||||
|
push 45
|
||||||
|
jmp irq_common_stub
|
||||||
|
|
||||||
|
irq14:
|
||||||
|
push 14
|
||||||
|
push 46
|
||||||
|
jmp irq_common_stub
|
||||||
|
|
||||||
|
irq15:
|
||||||
|
push 15
|
||||||
|
push 47
|
||||||
|
jmp irq_common_stub
|
||||||
|
|
||||||
.global irq_stub_table
|
.global irq_stub_table
|
||||||
irq_stub_table:
|
irq_stub_table:
|
||||||
.long irq_stub_0
|
.long irq0
|
||||||
.long irq_stub_1
|
.long irq1
|
||||||
.long irq_stub_2
|
.long irq2
|
||||||
.long irq_stub_3
|
.long irq3
|
||||||
.long irq_stub_4
|
.long irq4
|
||||||
.long irq_stub_5
|
.long irq5
|
||||||
.long irq_stub_6
|
.long irq6
|
||||||
.long irq_stub_7
|
.long irq7
|
||||||
.long irq_stub_8
|
.long irq8
|
||||||
.long irq_stub_9
|
.long irq9
|
||||||
.long irq_stub_10
|
.long irq10
|
||||||
.long irq_stub_11
|
.long irq11
|
||||||
.long irq_stub_12
|
.long irq12
|
||||||
.long irq_stub_13
|
.long irq13
|
||||||
.long irq_stub_14
|
.long irq14
|
||||||
.long irq_stub_15
|
.long irq15
|
||||||
|
@ -1,84 +1,257 @@
|
|||||||
.intel_syntax noprefix
|
.intel_syntax noprefix
|
||||||
.extern exception_handler
|
.extern isr_handler
|
||||||
|
|
||||||
|
isr_common_stub:
|
||||||
|
// push general purpose registers
|
||||||
|
pusha
|
||||||
|
|
||||||
|
// push data segment selector
|
||||||
|
mov ax, ds
|
||||||
|
push eax
|
||||||
|
|
||||||
|
// use kernel data segment
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
// hand over stack to C function
|
||||||
|
push esp
|
||||||
|
// and call it
|
||||||
|
call isr_handler
|
||||||
|
// pop stack pointer again
|
||||||
|
pop eax
|
||||||
|
|
||||||
|
// restore original segment pointers segment
|
||||||
|
pop eax
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
|
||||||
|
// restore registers
|
||||||
|
popa
|
||||||
|
|
||||||
|
// remove int_no and err_code from stack
|
||||||
|
add esp, 8
|
||||||
|
|
||||||
.macro isr_err_stub nb
|
|
||||||
isr_stub_\nb:
|
|
||||||
mov bl, \nb
|
|
||||||
call exception_handler
|
|
||||||
iret
|
iret
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro isr_no_err_stub nb
|
// 0: Divide By Zero Exception
|
||||||
isr_stub_\nb:
|
isr0:
|
||||||
mov bl, \nb
|
push 0
|
||||||
call exception_handler
|
push 0
|
||||||
iret
|
jmp isr_common_stub
|
||||||
.endm
|
|
||||||
|
|
||||||
isr_no_err_stub 0
|
// 1: Debug Exception
|
||||||
isr_no_err_stub 1
|
isr1:
|
||||||
isr_no_err_stub 2
|
push 0
|
||||||
isr_no_err_stub 3
|
push 1
|
||||||
isr_no_err_stub 4
|
jmp isr_common_stub
|
||||||
isr_no_err_stub 5
|
|
||||||
isr_no_err_stub 6
|
// 2: Non Maskable Interrupt Exception
|
||||||
isr_no_err_stub 7
|
isr2:
|
||||||
isr_err_stub 8
|
push 0
|
||||||
isr_no_err_stub 9
|
push 2
|
||||||
isr_err_stub 10
|
jmp isr_common_stub
|
||||||
isr_err_stub 11
|
|
||||||
isr_err_stub 12
|
// 3: Int 3 Exception
|
||||||
isr_err_stub 13
|
isr3:
|
||||||
isr_err_stub 14
|
push 0
|
||||||
isr_no_err_stub 15
|
push 3
|
||||||
isr_no_err_stub 16
|
jmp isr_common_stub
|
||||||
isr_err_stub 17
|
|
||||||
isr_no_err_stub 18
|
// 4: INTO Exception
|
||||||
isr_no_err_stub 19
|
isr4:
|
||||||
isr_no_err_stub 20
|
push 0
|
||||||
isr_no_err_stub 21
|
push 4
|
||||||
isr_no_err_stub 22
|
jmp isr_common_stub
|
||||||
isr_no_err_stub 23
|
|
||||||
isr_no_err_stub 24
|
// 5: Out of Bounds Exception
|
||||||
isr_no_err_stub 25
|
isr5:
|
||||||
isr_no_err_stub 26
|
push 0
|
||||||
isr_no_err_stub 27
|
push 5
|
||||||
isr_no_err_stub 28
|
jmp isr_common_stub
|
||||||
isr_no_err_stub 29
|
|
||||||
isr_err_stub 30
|
// 6: Invalid Opcode Exception
|
||||||
isr_no_err_stub 31
|
isr6:
|
||||||
|
push 0
|
||||||
|
push 6
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 7: Coprocessor Not Available Exception
|
||||||
|
isr7:
|
||||||
|
push 0
|
||||||
|
push 7
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 8: Double Fault Exception (With Error Code!)
|
||||||
|
isr8:
|
||||||
|
push 8
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 9: Coprocessor Segment Overrun Exception
|
||||||
|
isr9:
|
||||||
|
push 0
|
||||||
|
push 9
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 10: Bad TSS Exception (With Error Code!)
|
||||||
|
isr10:
|
||||||
|
push 10
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 11: Segment Not Present Exception (With Error Code!)
|
||||||
|
isr11:
|
||||||
|
push 11
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 12: Stack Fault Exception (With Error Code!)
|
||||||
|
isr12:
|
||||||
|
push 12
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 13: General Protection Fault Exception (With Error Code!)
|
||||||
|
isr13:
|
||||||
|
push 13
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 14: Page Fault Exception (With Error Code!)
|
||||||
|
isr14:
|
||||||
|
push 14
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 15: Reserved Exception
|
||||||
|
isr15:
|
||||||
|
push 0
|
||||||
|
push 15
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 16: Floating Point Exception
|
||||||
|
isr16:
|
||||||
|
push 0
|
||||||
|
push 16
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 17: Alignment Check Exception
|
||||||
|
isr17:
|
||||||
|
push 17
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 18: Machine Check Exception
|
||||||
|
isr18:
|
||||||
|
push 0
|
||||||
|
push 18
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 19: Reserved
|
||||||
|
isr19:
|
||||||
|
push 0
|
||||||
|
push 19
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 20: Reserved
|
||||||
|
isr20:
|
||||||
|
push 0
|
||||||
|
push 20
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 21: Reserved
|
||||||
|
isr21:
|
||||||
|
push 21
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 22: Reserved
|
||||||
|
isr22:
|
||||||
|
push 0
|
||||||
|
push 22
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 23: Reserved
|
||||||
|
isr23:
|
||||||
|
push 0
|
||||||
|
push 23
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 24: Reserved
|
||||||
|
isr24:
|
||||||
|
push 0
|
||||||
|
push 24
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 25: Reserved
|
||||||
|
isr25:
|
||||||
|
push 0
|
||||||
|
push 25
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 26: Reserved
|
||||||
|
isr26:
|
||||||
|
push 0
|
||||||
|
push 26
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 27: Reserved
|
||||||
|
isr27:
|
||||||
|
push 0
|
||||||
|
push 27
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 28: Reserved
|
||||||
|
isr28:
|
||||||
|
push 0
|
||||||
|
push 28
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 29: Reserved
|
||||||
|
isr29:
|
||||||
|
push 0
|
||||||
|
push 29
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 30: Reserved
|
||||||
|
isr30:
|
||||||
|
push 0
|
||||||
|
push 30
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
// 31: Reserved
|
||||||
|
isr31:
|
||||||
|
push 0
|
||||||
|
push 31
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
.global isr_stub_table
|
.global isr_stub_table
|
||||||
isr_stub_table:
|
isr_stub_table:
|
||||||
.long isr_stub_0
|
.long isr0
|
||||||
.long isr_stub_1
|
.long isr1
|
||||||
.long isr_stub_2
|
.long isr2
|
||||||
.long isr_stub_3
|
.long isr3
|
||||||
.long isr_stub_4
|
.long isr4
|
||||||
.long isr_stub_5
|
.long isr5
|
||||||
.long isr_stub_6
|
.long isr6
|
||||||
.long isr_stub_7
|
.long isr7
|
||||||
.long isr_stub_8
|
.long isr8
|
||||||
.long isr_stub_9
|
.long isr9
|
||||||
.long isr_stub_10
|
.long isr10
|
||||||
.long isr_stub_11
|
.long isr11
|
||||||
.long isr_stub_12
|
.long isr12
|
||||||
.long isr_stub_13
|
.long isr13
|
||||||
.long isr_stub_14
|
.long isr14
|
||||||
.long isr_stub_15
|
.long isr15
|
||||||
.long isr_stub_16
|
.long isr16
|
||||||
.long isr_stub_17
|
.long isr17
|
||||||
.long isr_stub_18
|
.long isr18
|
||||||
.long isr_stub_19
|
.long isr19
|
||||||
.long isr_stub_20
|
.long isr20
|
||||||
.long isr_stub_21
|
.long isr21
|
||||||
.long isr_stub_22
|
.long isr22
|
||||||
.long isr_stub_23
|
.long isr23
|
||||||
.long isr_stub_24
|
.long isr24
|
||||||
.long isr_stub_25
|
.long isr25
|
||||||
.long isr_stub_26
|
.long isr26
|
||||||
.long isr_stub_27
|
.long isr27
|
||||||
.long isr_stub_28
|
.long isr28
|
||||||
.long isr_stub_29
|
.long isr29
|
||||||
.long isr_stub_30
|
.long isr30
|
||||||
.long isr_stub_31
|
.long isr31
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "drivers.h"
|
||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
@ -27,5 +28,8 @@ void kernel_main(void)
|
|||||||
init_gdt();
|
init_gdt();
|
||||||
init_idt();
|
init_idt();
|
||||||
init_memory();
|
init_memory();
|
||||||
|
/* load_drivers(); */
|
||||||
|
/* while (42) */
|
||||||
|
/* ; */
|
||||||
shell_init();
|
shell_init();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user