2018-07-20 15:41:58 +02:00
|
|
|
#include "exception.h"
|
2021-10-07 23:54:46 +02:00
|
|
|
#include "cpu_context.h"
|
2018-07-20 15:41:58 +02:00
|
|
|
#include "idt.h"
|
|
|
|
#include "interrupt.h"
|
|
|
|
#include "irq.h"
|
2021-10-07 23:54:46 +02:00
|
|
|
#include "klibc.h"
|
2021-10-30 14:18:21 +02:00
|
|
|
#include "thread.h"
|
2021-10-07 23:54:46 +02:00
|
|
|
#include "vga.h"
|
2018-07-20 15:41:58 +02:00
|
|
|
|
|
|
|
exception_handler exception_handler_array[EXCEPTION_NUM] = {
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
2021-10-07 23:54:46 +02:00
|
|
|
extern vaddr_t exception_handler_wrapper_array[EXCEPTION_NUM];
|
|
|
|
|
|
|
|
void exception_handler_wrap(int intr, struct cpu_state *frame)
|
|
|
|
{
|
|
|
|
if (0 > intr || EXCEPTION_NUM <= intr) {
|
|
|
|
pr_err("Trying to handle unknow exception %d\n", intr);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (exception_handler_array[intr] != NULL)
|
|
|
|
exception_handler_array[intr](frame, intr);
|
|
|
|
}
|
|
|
|
|
2018-07-20 15:41:58 +02:00
|
|
|
int exceptionSetRoutine(int exception, exception_handler handler)
|
|
|
|
{
|
2020-04-27 00:14:37 +02:00
|
|
|
uint32_t flags;
|
|
|
|
if ((exception < 0) || exception >= EXCEPTION_NUM)
|
|
|
|
return -1;
|
2018-07-20 15:41:58 +02:00
|
|
|
|
2020-04-27 00:14:37 +02:00
|
|
|
disable_IRQs(flags);
|
2018-07-20 15:41:58 +02:00
|
|
|
|
2020-04-27 00:14:37 +02:00
|
|
|
exception_handler_array[exception] = handler;
|
2018-07-20 15:41:58 +02:00
|
|
|
|
2021-10-07 23:54:46 +02:00
|
|
|
idt_set_handler(EXCEPTION_INTERRUPT_BASE_ADDRESS + exception,
|
|
|
|
(unsigned int)exception_handler_wrapper_array[exception], 0);
|
2020-04-27 00:14:37 +02:00
|
|
|
restore_IRQs(flags);
|
|
|
|
return 0;
|
2018-07-20 15:41:58 +02:00
|
|
|
}
|
2020-04-29 23:07:01 +02:00
|
|
|
|
2021-10-07 23:54:46 +02:00
|
|
|
void print_handler(struct cpu_state *frame, ulong intr)
|
2020-04-29 23:07:01 +02:00
|
|
|
{
|
2021-10-07 23:54:46 +02:00
|
|
|
int intNbInt = intr;
|
|
|
|
VGAPrintf(RED, BLACK, 0, VGA_HEIGHT - 1, "EXCEPTION %d %d", intNbInt, intr);
|
|
|
|
printf("Exception %d (Err %d) at 0x%x\n", intr, intr,
|
|
|
|
cpu_context_get_PC(frame));
|
|
|
|
asm("hlt");
|
|
|
|
}
|
2020-04-29 23:07:01 +02:00
|
|
|
|
2021-10-07 23:54:46 +02:00
|
|
|
void pagefault_handler(struct cpu_state *frame, ulong intr)
|
|
|
|
{
|
|
|
|
|
2021-10-30 14:08:12 +02:00
|
|
|
struct thread *current = getCurrentThread();
|
2021-10-26 21:57:45 +02:00
|
|
|
printf("page fault while in thread %s code at 0x%x when trying to access 0x%x err_code 0x%x\n", current->name,
|
|
|
|
cpu_context_get_PC(frame), cpu_context_get_EX_faulting_vaddr(frame), cpu_context_get_EX_err(frame));
|
2021-11-05 23:02:23 +01:00
|
|
|
if (cpu_context_is_in_user_mode(frame)) {
|
|
|
|
printf("Killing User Thread\n");
|
|
|
|
threadExit();
|
|
|
|
}
|
2021-10-07 23:54:46 +02:00
|
|
|
VGAPrintf(RED, BLACK, 0, VGA_HEIGHT - 1, "PAGE FAULT %d", intr);
|
|
|
|
(void)intr;
|
|
|
|
for (;;)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
int exceptionSetup()
|
|
|
|
{
|
|
|
|
for (int i = 0; i < EXCEPTION_NUM; i++) {
|
|
|
|
exceptionSetRoutine(i, print_handler);
|
|
|
|
}
|
2020-04-29 23:07:01 +02:00
|
|
|
exceptionSetRoutine(EXCEPTION_PAGE_FAULT, pagefault_handler);
|
|
|
|
return 0;
|
|
|
|
}
|