feature: start to implement keyboard handler and better isrs/irqs

This commit is contained in:
0x35c 2024-10-09 17:54:29 +02:00
parent 0812a06350
commit 4fb51d4356
11 changed files with 451 additions and 141 deletions

7
headers/drivers.h Normal file
View 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);

View File

@ -1,5 +1,7 @@
#pragma once
#include <stdint.h>
// doc : https://wiki.osdev.org/Interrupt_Descriptor_Table#IDTR
struct idt_descriptor {
uint16_t size;

View File

@ -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
View 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
View 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
View 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);
}

View File

@ -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);
}

View File

@ -1,4 +1,3 @@
#include "sys/io.h"
#include <stdbool.h>
#include <stdint.h>

View File

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

View File

@ -1,84 +1,257 @@
.intel_syntax noprefix
.extern exception_handler
.extern isr_handler
.macro isr_err_stub nb
isr_stub_\nb:
mov bl, \nb
call exception_handler
iret
.endm
isr_common_stub:
// push general purpose registers
pusha
.macro isr_no_err_stub nb
isr_stub_\nb:
mov bl, \nb
call exception_handler
iret
.endm
// push data segment selector
mov ax, ds
push eax
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
// 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
iret
// 0: Divide By Zero Exception
isr0:
push 0
push 0
jmp isr_common_stub
// 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

View File

@ -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();
}