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
|
||||
$(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
|
||||
$(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
|
||||
#include "interrupt.h"
|
||||
|
||||
#define save_flags(flags) asm volatile("pushfl ; popl %0" : "=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
|
||||
// That's why we use wrapper around them or the gcc interrupt attribut
|
||||
// __attribute__((interrupt)) void (*irq_handler)(int irq);
|
||||
typedef void (*irq_handler)(int *irq);
|
||||
typedef void (*irq_handler)(struct interrupt_frame *frame);
|
||||
int irqSetup();
|
||||
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 "idt.h"
|
||||
#include "interrupt.h"
|
||||
#include "io.h"
|
||||
#include "irq.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");
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
@ -42,11 +35,16 @@ void kmain()
|
||||
printString("Setting up IRQ", color, BLACK, 0, 1);
|
||||
irqSetup();
|
||||
|
||||
printString("Setting up IRQ_KEYBOARD", color, BLACK, 0, 1);
|
||||
irqSetRoutine(IRQ_KEYBOARD, keyboard_handler);
|
||||
printString("Enabling HW interrupts", color, BLACK, 0, 1);
|
||||
exceptionSetRoutine(EXCEPTION_DOUBLE_FAULT, print_handler);
|
||||
// Enabling the HW interrupts
|
||||
//asm volatile("sti\n");
|
||||
asm volatile("sti\n");
|
||||
printString("Idling", color, BLACK, 0, 2);
|
||||
while (1) {
|
||||
char c = getScancode();
|
||||
printChar(c, color, BLACK, 0, 5);
|
||||
}
|
||||
printString("exiting", color, BLACK, 0, 3);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user