Interrupt Dispatch and Handling (for first common vectors)
This commit is contained in:
@@ -40,6 +40,7 @@ interrupt_stub:
|
|||||||
push rdx
|
push rdx
|
||||||
push rsi
|
push rsi
|
||||||
push rdi
|
push rdi
|
||||||
|
push rsp
|
||||||
push rbp
|
push rbp
|
||||||
push r8
|
push r8
|
||||||
push r9
|
push r9
|
||||||
@@ -65,6 +66,7 @@ interrupt_stub:
|
|||||||
pop r9
|
pop r9
|
||||||
pop r8
|
pop r8
|
||||||
pop rbp
|
pop rbp
|
||||||
|
pop rsp
|
||||||
pop rdi
|
pop rdi
|
||||||
pop rsi
|
pop rsi
|
||||||
pop rdx
|
pop rdx
|
||||||
|
|||||||
@@ -44,13 +44,14 @@ void idt_init()
|
|||||||
// Each vector handler is 16-byte aligned, so <vector_no>*16 = address of that handler
|
// Each vector handler is 16-byte aligned, so <vector_no>*16 = address of that handler
|
||||||
idt_set_entry(i, vector_0_handler + (i*16), 0);
|
idt_set_entry(i, vector_0_handler + (i*16), 0);
|
||||||
}
|
}
|
||||||
|
idt_load(&idt);
|
||||||
|
serial_kputs("kernel: idt: Initialized IDT!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
|
struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
|
||||||
{
|
{
|
||||||
switch(context->vector_number)
|
switch(context->vector_number)
|
||||||
{
|
{
|
||||||
// TODO: add serial logs for all interrupts
|
|
||||||
case 0:
|
case 0:
|
||||||
serial_kputs("kernel: idt: Divide Error!\n");
|
serial_kputs("kernel: idt: Divide Error!\n");
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void idt_init();
|
||||||
|
|
||||||
struct interrupt_descriptor
|
struct interrupt_descriptor
|
||||||
{
|
{
|
||||||
uint16_t address_low;
|
uint16_t address_low;
|
||||||
@@ -34,6 +36,7 @@ struct cpu_status_t
|
|||||||
uint64_t r9;
|
uint64_t r9;
|
||||||
uint64_t r8;
|
uint64_t r8;
|
||||||
uint64_t rbp;
|
uint64_t rbp;
|
||||||
|
uint64_t rsp;
|
||||||
uint64_t rdi;
|
uint64_t rdi;
|
||||||
uint64_t rsi;
|
uint64_t rsi;
|
||||||
uint64_t rdx;
|
uint64_t rdx;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "../kernel.h"
|
#include "../kernel.h"
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
void outb(int port, unsigned char data)
|
void outb(int port, unsigned char data)
|
||||||
{
|
{
|
||||||
@@ -34,6 +35,8 @@ int serial_init()
|
|||||||
|
|
||||||
// Set normal operation mode
|
// Set normal operation mode
|
||||||
outb(PORT + 4, 0x0F);
|
outb(PORT + 4, 0x0F);
|
||||||
|
|
||||||
|
serial_kputs("\n\nkernel: serial: Serial initialization OK!\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
20
src/kmain.c
20
src/kmain.c
@@ -6,6 +6,7 @@
|
|||||||
#include "io/serial.h"
|
#include "io/serial.h"
|
||||||
#include "mem/gdt.h"
|
#include "mem/gdt.h"
|
||||||
#include "mem/utils.h"
|
#include "mem/utils.h"
|
||||||
|
#include "idt/idt.h"
|
||||||
|
|
||||||
// Limine version used
|
// Limine version used
|
||||||
__attribute__((used, section(".limine_requests")))
|
__attribute__((used, section(".limine_requests")))
|
||||||
@@ -35,6 +36,20 @@ static void hcf()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void trigger_div0(void)
|
||||||
|
{
|
||||||
|
asm volatile (
|
||||||
|
"mov $1, %%rax\n"
|
||||||
|
"xor %%rdx, %%rdx\n"
|
||||||
|
"xor %%rcx, %%rcx\n" // divisor = 0
|
||||||
|
"idiv %%rcx\n"
|
||||||
|
:
|
||||||
|
:
|
||||||
|
: "rax", "rcx", "rdx"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// This is our entry point
|
// This is our entry point
|
||||||
void kmain()
|
void kmain()
|
||||||
{
|
{
|
||||||
@@ -48,13 +63,12 @@ void kmain()
|
|||||||
|
|
||||||
if (serial_init()) kputs("kernel: serial: error: Cannot init serial communication!");
|
if (serial_init()) kputs("kernel: serial: error: Cannot init serial communication!");
|
||||||
|
|
||||||
serial_kputs("\n\nkernel: serial: Hello, world from serial!\n");
|
|
||||||
|
|
||||||
gdt_init();
|
gdt_init();
|
||||||
serial_kputs("kernel: gdt: Initialized GDT!");
|
idt_init();
|
||||||
|
|
||||||
// Draw something
|
// Draw something
|
||||||
printf("%s, %s!", "Hello", "world");
|
printf("%s, %s!", "Hello", "world");
|
||||||
|
|
||||||
|
trigger_div0();
|
||||||
hcf();
|
hcf();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "../io/serial.h"
|
||||||
|
|
||||||
// Descriptors are 8-byte wide (64bits)
|
// Descriptors are 8-byte wide (64bits)
|
||||||
// So the selectors will be (in bytes): 0x0, 0x8, 0x10, 0x18, etc..
|
// So the selectors will be (in bytes): 0x0, 0x8, 0x10, 0x18, etc..
|
||||||
@@ -76,4 +77,6 @@ void gdt_init()
|
|||||||
// Load the GDT we created, flush the old one
|
// Load the GDT we created, flush the old one
|
||||||
gdt_load();
|
gdt_load();
|
||||||
gdt_flush();
|
gdt_flush();
|
||||||
|
|
||||||
|
serial_kputs("kernel: gdt: Initialized GDT!\n");
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user