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
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// doc : https://wiki.osdev.org/Interrupt_Descriptor_Table#IDTR
|
||||
struct idt_descriptor {
|
||||
uint16_t size;
|
||||
|
@ -2,5 +2,19 @@
|
||||
|
||||
#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 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 "utils.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#define NTMFDP 0
|
||||
|
||||
const char *faults[] = {
|
||||
"division by zero",
|
||||
@ -29,36 +29,29 @@ const char *faults[] = {
|
||||
"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;
|
||||
while (i < ARRAY_SIZE(faults)) {
|
||||
if (i == index)
|
||||
if (i == regs->int_no)
|
||||
kpanic("interrupt: %s\n", faults[i]);
|
||||
i++;
|
||||
}
|
||||
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;
|
||||
__asm__ volatile("movb %%bl, %0" ::"m"(index));
|
||||
|
||||
pic_send_eoi(index);
|
||||
if (index == -1) {
|
||||
kprintf(KERN_ERR "interrupt triggered without a code\n");
|
||||
return;
|
||||
}
|
||||
if (index == 0)
|
||||
return;
|
||||
kpanic("%d\n", index);
|
||||
interrupt_handlers[i] = handler;
|
||||
}
|
||||
|
||||
void irq_handler(struct registers *regs)
|
||||
{
|
||||
if (regs->int_no != 0) {
|
||||
isr_t handler = interrupt_handlers[regs->int_no];
|
||||
handler(regs);
|
||||
}
|
||||
pic_send_eoi(regs->int_no);
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
#include "sys/io.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -1,45 +1,137 @@
|
||||
.intel_syntax noprefix
|
||||
.extern irq_handler
|
||||
|
||||
.macro irq_common_stub nb
|
||||
irq_stub_\nb:
|
||||
mov bl, \nb
|
||||
call irq_handler
|
||||
iret
|
||||
.endm
|
||||
irq_common_stub:
|
||||
// push general purpose registers
|
||||
pusha
|
||||
|
||||
irq_common_stub 0
|
||||
irq_common_stub 1
|
||||
irq_common_stub 2
|
||||
irq_common_stub 3
|
||||
irq_common_stub 4
|
||||
irq_common_stub 5
|
||||
irq_common_stub 6
|
||||
irq_common_stub 7
|
||||
irq_common_stub 8
|
||||
irq_common_stub 9
|
||||
irq_common_stub 10
|
||||
irq_common_stub 11
|
||||
irq_common_stub 12
|
||||
irq_common_stub 13
|
||||
irq_common_stub 14
|
||||
irq_common_stub 15
|
||||
// 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 irq_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
|
||||
|
||||
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
|
||||
irq_stub_table:
|
||||
.long irq_stub_0
|
||||
.long irq_stub_1
|
||||
.long irq_stub_2
|
||||
.long irq_stub_3
|
||||
.long irq_stub_4
|
||||
.long irq_stub_5
|
||||
.long irq_stub_6
|
||||
.long irq_stub_7
|
||||
.long irq_stub_8
|
||||
.long irq_stub_9
|
||||
.long irq_stub_10
|
||||
.long irq_stub_11
|
||||
.long irq_stub_12
|
||||
.long irq_stub_13
|
||||
.long irq_stub_14
|
||||
.long irq_stub_15
|
||||
.long irq0
|
||||
.long irq1
|
||||
.long irq2
|
||||
.long irq3
|
||||
.long irq4
|
||||
.long irq5
|
||||
.long irq6
|
||||
.long irq7
|
||||
.long irq8
|
||||
.long irq9
|
||||
.long irq10
|
||||
.long irq11
|
||||
.long irq12
|
||||
.long irq13
|
||||
.long irq14
|
||||
.long irq15
|
||||
|
@ -1,84 +1,257 @@
|
||||
.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
|
||||
.endm
|
||||
|
||||
.macro isr_no_err_stub nb
|
||||
isr_stub_\nb:
|
||||
mov bl, \nb
|
||||
call exception_handler
|
||||
iret
|
||||
.endm
|
||||
// 0: Divide By Zero Exception
|
||||
isr0:
|
||||
push 0
|
||||
push 0
|
||||
jmp isr_common_stub
|
||||
|
||||
isr_no_err_stub 0
|
||||
isr_no_err_stub 1
|
||||
isr_no_err_stub 2
|
||||
isr_no_err_stub 3
|
||||
isr_no_err_stub 4
|
||||
isr_no_err_stub 5
|
||||
isr_no_err_stub 6
|
||||
isr_no_err_stub 7
|
||||
isr_err_stub 8
|
||||
isr_no_err_stub 9
|
||||
isr_err_stub 10
|
||||
isr_err_stub 11
|
||||
isr_err_stub 12
|
||||
isr_err_stub 13
|
||||
isr_err_stub 14
|
||||
isr_no_err_stub 15
|
||||
isr_no_err_stub 16
|
||||
isr_err_stub 17
|
||||
isr_no_err_stub 18
|
||||
isr_no_err_stub 19
|
||||
isr_no_err_stub 20
|
||||
isr_no_err_stub 21
|
||||
isr_no_err_stub 22
|
||||
isr_no_err_stub 23
|
||||
isr_no_err_stub 24
|
||||
isr_no_err_stub 25
|
||||
isr_no_err_stub 26
|
||||
isr_no_err_stub 27
|
||||
isr_no_err_stub 28
|
||||
isr_no_err_stub 29
|
||||
isr_err_stub 30
|
||||
isr_no_err_stub 31
|
||||
// 1: Debug Exception
|
||||
isr1:
|
||||
push 0
|
||||
push 1
|
||||
jmp isr_common_stub
|
||||
|
||||
// 2: Non Maskable Interrupt Exception
|
||||
isr2:
|
||||
push 0
|
||||
push 2
|
||||
jmp isr_common_stub
|
||||
|
||||
// 3: Int 3 Exception
|
||||
isr3:
|
||||
push 0
|
||||
push 3
|
||||
jmp isr_common_stub
|
||||
|
||||
// 4: INTO Exception
|
||||
isr4:
|
||||
push 0
|
||||
push 4
|
||||
jmp isr_common_stub
|
||||
|
||||
// 5: Out of Bounds Exception
|
||||
isr5:
|
||||
push 0
|
||||
push 5
|
||||
jmp isr_common_stub
|
||||
|
||||
// 6: Invalid Opcode Exception
|
||||
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
|
||||
isr_stub_table:
|
||||
.long isr_stub_0
|
||||
.long isr_stub_1
|
||||
.long isr_stub_2
|
||||
.long isr_stub_3
|
||||
.long isr_stub_4
|
||||
.long isr_stub_5
|
||||
.long isr_stub_6
|
||||
.long isr_stub_7
|
||||
.long isr_stub_8
|
||||
.long isr_stub_9
|
||||
.long isr_stub_10
|
||||
.long isr_stub_11
|
||||
.long isr_stub_12
|
||||
.long isr_stub_13
|
||||
.long isr_stub_14
|
||||
.long isr_stub_15
|
||||
.long isr_stub_16
|
||||
.long isr_stub_17
|
||||
.long isr_stub_18
|
||||
.long isr_stub_19
|
||||
.long isr_stub_20
|
||||
.long isr_stub_21
|
||||
.long isr_stub_22
|
||||
.long isr_stub_23
|
||||
.long isr_stub_24
|
||||
.long isr_stub_25
|
||||
.long isr_stub_26
|
||||
.long isr_stub_27
|
||||
.long isr_stub_28
|
||||
.long isr_stub_29
|
||||
.long isr_stub_30
|
||||
.long isr_stub_31
|
||||
.long isr0
|
||||
.long isr1
|
||||
.long isr2
|
||||
.long isr3
|
||||
.long isr4
|
||||
.long isr5
|
||||
.long isr6
|
||||
.long isr7
|
||||
.long isr8
|
||||
.long isr9
|
||||
.long isr10
|
||||
.long isr11
|
||||
.long isr12
|
||||
.long isr13
|
||||
.long isr14
|
||||
.long isr15
|
||||
.long isr16
|
||||
.long isr17
|
||||
.long isr18
|
||||
.long isr19
|
||||
.long isr20
|
||||
.long isr21
|
||||
.long isr22
|
||||
.long isr23
|
||||
.long isr24
|
||||
.long isr25
|
||||
.long isr26
|
||||
.long isr27
|
||||
.long isr28
|
||||
.long isr29
|
||||
.long isr30
|
||||
.long isr31
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "drivers.h"
|
||||
#include "gdt.h"
|
||||
#include "idt.h"
|
||||
#include "kprintf.h"
|
||||
@ -27,5 +28,8 @@ void kernel_main(void)
|
||||
init_gdt();
|
||||
init_idt();
|
||||
init_memory();
|
||||
/* load_drivers(); */
|
||||
/* while (42) */
|
||||
/* ; */
|
||||
shell_init();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user