Add exception handling

This commit is contained in:
Mathieu Maret 2018-06-30 01:03:40 +02:00
parent 6d34b7eef0
commit b4990aed80
8 changed files with 114 additions and 11 deletions

View File

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

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

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