Add exception handling
This commit is contained in:
parent
6d34b7eef0
commit
b4990aed80
6
Makefile
6
Makefile
@ -13,6 +13,12 @@ cobj=$(csrc:%.c=%.o)
|
|||||||
kernel:$(asmobj) $(cobj) linker.ld
|
kernel:$(asmobj) $(cobj) linker.ld
|
||||||
$(CXX) $(LDFLAGS) $(cobj) $(asmobj) -o $@ -T linker.ld
|
$(CXX) $(LDFLAGS) $(cobj) $(asmobj) -o $@ -T linker.ld
|
||||||
|
|
||||||
|
#https://gcc.gnu.org/onlinedocs/gcc/x86-Function-Attributes.html#x86-Function-Attributes
|
||||||
|
exception_handler.o:exception_handler.c
|
||||||
|
$(CC) $(CPPFLAGS) $(CFLAGS) -mgeneral-regs-only -c $<
|
||||||
|
irq_handler.o:irq_handler.c
|
||||||
|
$(CC) $(CPPFLAGS) $(CFLAGS) -mgeneral-regs-only -c $<
|
||||||
|
|
||||||
%.o:%.asm
|
%.o:%.asm
|
||||||
$(AS) $(ASFLAGS) -o $@ $<
|
$(AS) $(ASFLAGS) -o $@ $<
|
||||||
|
|
||||||
|
24
exception.c
Normal file
24
exception.c
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include "exception.h"
|
||||||
|
#include "idt.h"
|
||||||
|
#include "interrupt.h"
|
||||||
|
#include "irq.h"
|
||||||
|
|
||||||
|
exception_handler exception_handler_array[EXCEPTION_NUM] = {
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
int exceptionSetRoutine(int exception, exception_handler handler)
|
||||||
|
{
|
||||||
|
uint32_t flags;
|
||||||
|
if ((exception < 0) || exception >= EXCEPTION_NUM)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
disable_IRQs(flags);
|
||||||
|
|
||||||
|
exception_handler_array[exception] = handler;
|
||||||
|
|
||||||
|
idt_set_handler(EXCEPTION_INTERRUPT_BASE_ADDRESS + exception, (unsigned int)handler,
|
||||||
|
0);
|
||||||
|
restore_IRQs(flags);
|
||||||
|
return 0;
|
||||||
|
}
|
46
exception.h
Normal file
46
exception.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "interrupt.h"
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
#define EXCEPTION_INTERRUPT_BASE_ADDRESS 0
|
||||||
|
|
||||||
|
// list and description https://wiki.osdev.org/Exceptions
|
||||||
|
|
||||||
|
#define EXCEPTION_DIVIDE_ZERO 0
|
||||||
|
#define EXCEPTION_DEBUG 1
|
||||||
|
#define EXCEPTION_NMI 2
|
||||||
|
#define EXCEPTION_BREAKPOINT 3
|
||||||
|
#define EXCEPTION_OVERFLOW 4
|
||||||
|
#define EXCEPTION_BOUND_RANGE_EXCEEDED 5
|
||||||
|
#define EXCEPTION_INVALID_OPCODE 6
|
||||||
|
#define EXCEPTION_DEVICE_NOT_AVAILABLE 7
|
||||||
|
#define EXCEPTION_DOUBLE_FAULT 8
|
||||||
|
#define EXCEPTION_COPRO_OVERRUN 9
|
||||||
|
#define EXCEPTION_INVALID_TSS 10
|
||||||
|
#define EXCEPTION_SEGMENT_NOT_PRESENT 11
|
||||||
|
#define EXCEPTION_STACK_SEGMENT_FAULT 12
|
||||||
|
#define EXCEPTION_GENERAL_PROTECTION_FAULT 13
|
||||||
|
#define EXCEPTION_PAGE_FAULT 14
|
||||||
|
#define EXCEPTION_RESERVED_1 15
|
||||||
|
#define EXCEPTION_X87_FP_EXCEPTION 16
|
||||||
|
#define EXCEPTION_ALIGNMENT_CHECK 17
|
||||||
|
#define EXCEPTION_MACHINE_CHECK 18
|
||||||
|
#define EXCEPTION_SIMD_FP 19
|
||||||
|
#define EXCEPTION_VIRTUALIZATION 20
|
||||||
|
#define EXCEPTION_RESERVED_2 21
|
||||||
|
#define EXCEPTION_RESERVED_3 22
|
||||||
|
#define EXCEPTION_RESERVED_4 23
|
||||||
|
#define EXCEPTION_RESERVED_5 24
|
||||||
|
#define EXCEPTION_RESERVED_6 25
|
||||||
|
#define EXCEPTION_RESERVED_7 26
|
||||||
|
#define EXCEPTION_RESERVED_8 27
|
||||||
|
#define EXCEPTION_RESERVED_9 28
|
||||||
|
#define EXCEPTION_RESERVED_10 29
|
||||||
|
#define EXCEPTION_SECURITY 30
|
||||||
|
#define EXCEPTION_RESERVED_11 31
|
||||||
|
|
||||||
|
#define EXCEPTION_NUM 32
|
||||||
|
|
||||||
|
typedef void (*exception_handler) (struct interrupt_frame *frame, ulong error_code);
|
||||||
|
int exceptionSetRoutine(int exception, exception_handler handler);
|
||||||
|
|
11
exception_handler.c
Normal file
11
exception_handler.c
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#include "exception.h"
|
||||||
|
#include "vga.h"
|
||||||
|
|
||||||
|
// Need GCC > 6
|
||||||
|
__attribute__ ((interrupt))
|
||||||
|
void print_handler(struct interrupt_frame *frame, ulong error_code){
|
||||||
|
|
||||||
|
printString("EXCEPTION", RED, BLACK, 0, 6);
|
||||||
|
(void) frame;
|
||||||
|
(void) error_code;
|
||||||
|
}
|
10
interrupt.h
Normal file
10
interrupt.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
struct interrupt_frame;
|
||||||
|
|
||||||
|
//Exception
|
||||||
|
void print_handler(struct interrupt_frame *frame, ulong error_code);
|
||||||
|
|
||||||
|
//IRQ
|
||||||
|
void keyboard_handler(struct interrupt_frame *frame);
|
3
irq.h
3
irq.h
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "interrupt.h"
|
||||||
|
|
||||||
#define save_flags(flags) asm volatile("pushfl ; popl %0" : "=g"(flags)::"memory")
|
#define save_flags(flags) asm volatile("pushfl ; popl %0" : "=g"(flags)::"memory")
|
||||||
#define restore_flags(flags) asm volatile("push %0; popfl" ::"g"(flags) : "memory")
|
#define restore_flags(flags) asm volatile("push %0; popfl" ::"g"(flags) : "memory")
|
||||||
@ -34,6 +35,6 @@
|
|||||||
// An handler should finish by the iret opcode -> https://wiki.osdev.org/Interrupt_Service_Routines
|
// An handler should finish by the iret opcode -> https://wiki.osdev.org/Interrupt_Service_Routines
|
||||||
// That's why we use wrapper around them or the gcc interrupt attribut
|
// That's why we use wrapper around them or the gcc interrupt attribut
|
||||||
// __attribute__((interrupt)) void (*irq_handler)(int irq);
|
// __attribute__((interrupt)) void (*irq_handler)(int irq);
|
||||||
typedef void (*irq_handler)(int *irq);
|
typedef void (*irq_handler)(struct interrupt_frame *frame);
|
||||||
int irqSetup();
|
int irqSetup();
|
||||||
int irqSetRoutine(int irq, irq_handler handler);
|
int irqSetRoutine(int irq, irq_handler handler);
|
||||||
|
7
irq_handler.c
Normal file
7
irq_handler.c
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "interrupt.h"
|
||||||
|
|
||||||
|
// Need GCC > 6
|
||||||
|
__attribute__((interrupt)) void keyboard_handler(struct interrupt_frame *frame)
|
||||||
|
{
|
||||||
|
(void)frame;
|
||||||
|
}
|
18
main.c
18
main.c
@ -1,5 +1,7 @@
|
|||||||
|
#include "exception.h"
|
||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
|
#include "interrupt.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
@ -22,15 +24,6 @@ void cpuid(int code, uint32_t *a, uint32_t *d)
|
|||||||
asm volatile("cpuid" : "=a"(*a), "=d"(*d) : "0"(code) : "ebx", "ecx");
|
asm volatile("cpuid" : "=a"(*a), "=d"(*d) : "0"(code) : "ebx", "ecx");
|
||||||
}
|
}
|
||||||
|
|
||||||
void keyboard_handler(int *id)
|
|
||||||
{
|
|
||||||
__asm__("pushal");
|
|
||||||
(void)id;
|
|
||||||
const char *tictac = "tic tac";
|
|
||||||
const short color = RED;
|
|
||||||
printString(tictac, color, BLACK, 0, 3);
|
|
||||||
__asm__("popal; leave; iret");
|
|
||||||
}
|
|
||||||
|
|
||||||
void kmain()
|
void kmain()
|
||||||
{
|
{
|
||||||
@ -42,11 +35,16 @@ void kmain()
|
|||||||
printString("Setting up IRQ", color, BLACK, 0, 1);
|
printString("Setting up IRQ", color, BLACK, 0, 1);
|
||||||
irqSetup();
|
irqSetup();
|
||||||
|
|
||||||
|
printString("Setting up IRQ_KEYBOARD", color, BLACK, 0, 1);
|
||||||
irqSetRoutine(IRQ_KEYBOARD, keyboard_handler);
|
irqSetRoutine(IRQ_KEYBOARD, keyboard_handler);
|
||||||
|
printString("Enabling HW interrupts", color, BLACK, 0, 1);
|
||||||
|
exceptionSetRoutine(EXCEPTION_DOUBLE_FAULT, print_handler);
|
||||||
// Enabling the HW interrupts
|
// Enabling the HW interrupts
|
||||||
//asm volatile("sti\n");
|
asm volatile("sti\n");
|
||||||
|
printString("Idling", color, BLACK, 0, 2);
|
||||||
while (1) {
|
while (1) {
|
||||||
char c = getScancode();
|
char c = getScancode();
|
||||||
printChar(c, color, BLACK, 0, 5);
|
printChar(c, color, BLACK, 0, 5);
|
||||||
}
|
}
|
||||||
|
printString("exiting", color, BLACK, 0, 3);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user