-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathinterrupts.c
100 lines (86 loc) · 3.11 KB
/
interrupts.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include "interrupts.h"
#include "assembly_interface.h"
#include "data_structures/page_table.h"
#include "data_structures/symbol_table.h"
#include "drivers/keyboard.h"
#include "drivers/pic.h"
#include "loader.h"
#include "memory.h"
#include "kernel_stdio.h"
#include "kernel_syscalls.h"
void log_stack_trace_line(uint32_t eip) {
char * symbol_name = address_to_symbol_name(eip);
fprintf(LOG, "%x : %s\n", eip, symbol_name);
}
void log_interrupt_details(char* int_name, uint32_t error_code, uint32_t eip, struct cpu_state* cpu) {
if(cpu->ebp){}
fprintf(LOG, "--------------------\n");
fprintf(LOG, "Interrupt: %s\n", int_name);
fprintf(LOG, "error_code: %x\n", error_code);
fprintf(LOG, "\nStack trace:\n");
eip -= 4; // eip actually points one past the instruction that triggered interrupt
log_stack_trace_line(eip);
uint32_t ebp = cpu->ebp;
uint32_t kernel_stack_highest_address = ((uint32_t) &kernel_stack_lowest_address + KERNEL_STACK_SIZE - 4);
while (ebp <= kernel_stack_highest_address && ebp >= ((uint32_t) &kernel_stack_lowest_address)) {
eip = ((uint32_t*) ebp)[1];
log_stack_trace_line(eip);
ebp = *((uint32_t*)ebp);
}
fprintf(LOG, "--------------------\n");
}
uint32_t interrupt_handler(struct cpu_state cpu, uint32_t interrupt_number, uint32_t error_code, uint32_t eip) {
switch(interrupt_number) {
case(INT_KEYBOARD):
keyboard_interrupt_handler();
break;
case(INT_PAGE_FAULT):
if ((error_code & 0b1) == 0) {
// Caused by page-not-present
page_in((void*) cpu.cr2);
break;
}
log_interrupt_details("INT_PAGE_FAULT", error_code, eip, &cpu);
fprintf(LOG, "Interrupt was a page fault. Here's what I know:\n");
fprintf(LOG, "- Tried to access virtual address %x\n", cpu.cr2);
if (error_code & 0b1) {
fprintf(LOG, "- Couldn't complete because of page-protection violation\n");
} else {
fprintf(LOG, "- Couldn't complete because page was not present\n");
}
if (error_code & 0b10) {
fprintf(LOG, "- This was an attempt to WRITE to this address.\n");
} else {
fprintf(LOG, "- This was an attempt to READ from this address.\n");
}
if (error_code & 0b100) {
fprintf(LOG, "- Memory access came from user.\n");
} else {
fprintf(LOG, "- Memory access came from kernel.\n");
}
if (error_code & 0b1000) {
fprintf(LOG, "- caused by reading a 1 in a reserved field.\n");
}
if (error_code & 0b10000) {
fprintf(LOG, "- caused by an instruction fetch.\n");
}
while(1){}
break;
case(INT_SOFTWARE):
log_interrupt_details("INT_SOFTWARE", error_code, eip, &cpu);
break;
case(INT_SYSCALL):
return handle_syscall(&cpu);
case(INT_OUT_OF_MEMORY):
log_interrupt_details("INT_OUT_OF_MEMORY", error_code, eip, &cpu);
while(true){}
break;
default:
fprintf(LOG, "ERROR: Unable to handle interrupt: %x\n", interrupt_number);
log_interrupt_details("INT_UNKNOWN", error_code, eip, &cpu);
while(1){}
break;
}
pic_acknowledge();
return 0;
}