diff --git a/.vscode/settings.json b/.vscode/settings.json index 36c0cfc..e94ea84 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,10 @@ { "files.associations": { "*.h": "c", - "type_traits": "c" + "type_traits": "c", + "array": "c", + "string_view": "c", + "initializer_list": "c", + "utility": "c" } } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 36c0cfc..e94ea84 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,10 @@ { "files.associations": { "*.h": "c", - "type_traits": "c" + "type_traits": "c", + "array": "c", + "string_view": "c", + "initializer_list": "c", + "utility": "c" } } \ No newline at end of file diff --git a/src/headers/exceptions.h b/src/headers/exceptions.h index 0e0715e..8990d35 100644 --- a/src/headers/exceptions.h +++ b/src/headers/exceptions.h @@ -3,4 +3,37 @@ extern void setupExceptions(); +extern void isrHandler0(); +extern void isrHandler1(); +extern void isrHandler2(); +extern void isrHandler3(); +extern void isrHandler4(); +extern void isrHandler5(); +extern void isrHandler6(); +extern void isrHandler7(); +extern void isrHandler8(); +extern void isrHandler9(); +extern void isrHandler10(); +extern void isrHandler11(); +extern void isrHandler12(); +extern void isrHandler13(); +extern void isrHandler14(); +extern void isrHandler15(); +extern void isrHandler16(); +extern void isrHandler17(); +extern void isrHandler18(); +extern void isrHandler19(); +extern void isrHandler20(); +extern void isrHandler21(); +extern void isrHandler22(); +extern void isrHandler23(); +extern void isrHandler24(); +extern void isrHandler25(); +extern void isrHandler26(); +extern void isrHandler27(); +extern void isrHandler28(); +extern void isrHandler29(); +extern void isrHandler30(); +extern void isrHandler31(); + #endif \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 36c0cfc..e94ea84 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,10 @@ { "files.associations": { "*.h": "c", - "type_traits": "c" + "type_traits": "c", + "array": "c", + "string_view": "c", + "initializer_list": "c", + "utility": "c" } } \ No newline at end of file diff --git a/src/headers/exceptions.h b/src/headers/exceptions.h index 0e0715e..8990d35 100644 --- a/src/headers/exceptions.h +++ b/src/headers/exceptions.h @@ -3,4 +3,37 @@ extern void setupExceptions(); +extern void isrHandler0(); +extern void isrHandler1(); +extern void isrHandler2(); +extern void isrHandler3(); +extern void isrHandler4(); +extern void isrHandler5(); +extern void isrHandler6(); +extern void isrHandler7(); +extern void isrHandler8(); +extern void isrHandler9(); +extern void isrHandler10(); +extern void isrHandler11(); +extern void isrHandler12(); +extern void isrHandler13(); +extern void isrHandler14(); +extern void isrHandler15(); +extern void isrHandler16(); +extern void isrHandler17(); +extern void isrHandler18(); +extern void isrHandler19(); +extern void isrHandler20(); +extern void isrHandler21(); +extern void isrHandler22(); +extern void isrHandler23(); +extern void isrHandler24(); +extern void isrHandler25(); +extern void isrHandler26(); +extern void isrHandler27(); +extern void isrHandler28(); +extern void isrHandler29(); +extern void isrHandler30(); +extern void isrHandler31(); + #endif \ No newline at end of file diff --git a/src/headers/interrupts.h b/src/headers/interrupts.h index 1d8a597..f8ed10a 100644 --- a/src/headers/interrupts.h +++ b/src/headers/interrupts.h @@ -16,6 +16,13 @@ uint32_t base; } __attribute__((packed)) IDTR; +typedef struct { + unsigned int gs, fs, es, ds; + unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; + unsigned int int_no, err_code; + unsigned int eip, cs, eflags, useresp, ss; +} __attribute__((packed)) regs; + extern void initInterrupts(); extern void setInterrupt(uint8_t vector, void* callback); diff --git a/.vscode/settings.json b/.vscode/settings.json index 36c0cfc..e94ea84 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,10 @@ { "files.associations": { "*.h": "c", - "type_traits": "c" + "type_traits": "c", + "array": "c", + "string_view": "c", + "initializer_list": "c", + "utility": "c" } } \ No newline at end of file diff --git a/src/headers/exceptions.h b/src/headers/exceptions.h index 0e0715e..8990d35 100644 --- a/src/headers/exceptions.h +++ b/src/headers/exceptions.h @@ -3,4 +3,37 @@ extern void setupExceptions(); +extern void isrHandler0(); +extern void isrHandler1(); +extern void isrHandler2(); +extern void isrHandler3(); +extern void isrHandler4(); +extern void isrHandler5(); +extern void isrHandler6(); +extern void isrHandler7(); +extern void isrHandler8(); +extern void isrHandler9(); +extern void isrHandler10(); +extern void isrHandler11(); +extern void isrHandler12(); +extern void isrHandler13(); +extern void isrHandler14(); +extern void isrHandler15(); +extern void isrHandler16(); +extern void isrHandler17(); +extern void isrHandler18(); +extern void isrHandler19(); +extern void isrHandler20(); +extern void isrHandler21(); +extern void isrHandler22(); +extern void isrHandler23(); +extern void isrHandler24(); +extern void isrHandler25(); +extern void isrHandler26(); +extern void isrHandler27(); +extern void isrHandler28(); +extern void isrHandler29(); +extern void isrHandler30(); +extern void isrHandler31(); + #endif \ No newline at end of file diff --git a/src/headers/interrupts.h b/src/headers/interrupts.h index 1d8a597..f8ed10a 100644 --- a/src/headers/interrupts.h +++ b/src/headers/interrupts.h @@ -16,6 +16,13 @@ uint32_t base; } __attribute__((packed)) IDTR; +typedef struct { + unsigned int gs, fs, es, ds; + unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; + unsigned int int_no, err_code; + unsigned int eip, cs, eflags, useresp, ss; +} __attribute__((packed)) regs; + extern void initInterrupts(); extern void setInterrupt(uint8_t vector, void* callback); diff --git a/src/headers/irqs.h b/src/headers/irqs.h new file mode 100644 index 0000000..c3cde17 --- /dev/null +++ b/src/headers/irqs.h @@ -0,0 +1,27 @@ +#ifndef IRQS_H +#define IRQS_H + +#include + +extern void initIRQs(); + +extern void setIRQHandler(uint8_t irqNumber, void* fun); + +extern void irqHandler0(); +extern void irqHandler1(); +extern void irqHandler2(); +extern void irqHandler3(); +extern void irqHandler4(); +extern void irqHandler5(); +extern void irqHandler6(); +extern void irqHandler7(); +extern void irqHandler8(); +extern void irqHandler9(); +extern void irqHandler10(); +extern void irqHandler11(); +extern void irqHandler12(); +extern void irqHandler13(); +extern void irqHandler14(); +extern void irqHandler15(); + +#endif \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 36c0cfc..e94ea84 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,10 @@ { "files.associations": { "*.h": "c", - "type_traits": "c" + "type_traits": "c", + "array": "c", + "string_view": "c", + "initializer_list": "c", + "utility": "c" } } \ No newline at end of file diff --git a/src/headers/exceptions.h b/src/headers/exceptions.h index 0e0715e..8990d35 100644 --- a/src/headers/exceptions.h +++ b/src/headers/exceptions.h @@ -3,4 +3,37 @@ extern void setupExceptions(); +extern void isrHandler0(); +extern void isrHandler1(); +extern void isrHandler2(); +extern void isrHandler3(); +extern void isrHandler4(); +extern void isrHandler5(); +extern void isrHandler6(); +extern void isrHandler7(); +extern void isrHandler8(); +extern void isrHandler9(); +extern void isrHandler10(); +extern void isrHandler11(); +extern void isrHandler12(); +extern void isrHandler13(); +extern void isrHandler14(); +extern void isrHandler15(); +extern void isrHandler16(); +extern void isrHandler17(); +extern void isrHandler18(); +extern void isrHandler19(); +extern void isrHandler20(); +extern void isrHandler21(); +extern void isrHandler22(); +extern void isrHandler23(); +extern void isrHandler24(); +extern void isrHandler25(); +extern void isrHandler26(); +extern void isrHandler27(); +extern void isrHandler28(); +extern void isrHandler29(); +extern void isrHandler30(); +extern void isrHandler31(); + #endif \ No newline at end of file diff --git a/src/headers/interrupts.h b/src/headers/interrupts.h index 1d8a597..f8ed10a 100644 --- a/src/headers/interrupts.h +++ b/src/headers/interrupts.h @@ -16,6 +16,13 @@ uint32_t base; } __attribute__((packed)) IDTR; +typedef struct { + unsigned int gs, fs, es, ds; + unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; + unsigned int int_no, err_code; + unsigned int eip, cs, eflags, useresp, ss; +} __attribute__((packed)) regs; + extern void initInterrupts(); extern void setInterrupt(uint8_t vector, void* callback); diff --git a/src/headers/irqs.h b/src/headers/irqs.h new file mode 100644 index 0000000..c3cde17 --- /dev/null +++ b/src/headers/irqs.h @@ -0,0 +1,27 @@ +#ifndef IRQS_H +#define IRQS_H + +#include + +extern void initIRQs(); + +extern void setIRQHandler(uint8_t irqNumber, void* fun); + +extern void irqHandler0(); +extern void irqHandler1(); +extern void irqHandler2(); +extern void irqHandler3(); +extern void irqHandler4(); +extern void irqHandler5(); +extern void irqHandler6(); +extern void irqHandler7(); +extern void irqHandler8(); +extern void irqHandler9(); +extern void irqHandler10(); +extern void irqHandler11(); +extern void irqHandler12(); +extern void irqHandler13(); +extern void irqHandler14(); +extern void irqHandler15(); + +#endif \ No newline at end of file diff --git a/src/interrupts/exceptions.asm b/src/interrupts/exceptions.asm new file mode 100644 index 0000000..9fd4f04 --- /dev/null +++ b/src/interrupts/exceptions.asm @@ -0,0 +1,74 @@ +%macro isr 1 + global isrHandler%1 + isrHandler%1: + push byte 0 + push byte %1 + jmp exceptionHandler +%endmacro + +%macro isr_error 1 + global isrHandler%1 + isrHandler%1: + push byte %1 + jmp exceptionHandler +%endmacro + +isrs: + isr 0 + isr 1 + isr 2 + isr 3 + isr 4 + isr 5 + isr 6 + isr 7 + isr_error 8 + isr 9 + isr_error 10 + isr_error 11 + isr_error 12 + isr_error 13 + isr_error 14 + isr 15 + isr 16 + isr_error 17 + isr 18 + isr 19 + isr 20 + isr 21 + isr 22 + isr 23 + isr 24 + isr 25 + isr 26 + isr 27 + isr 28 + isr 29 + isr_error 30 + isr 31 + +extern handleException + +exceptionHandler: + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp + push eax + mov eax, handleException + call eax + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 + iret \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 36c0cfc..e94ea84 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,10 @@ { "files.associations": { "*.h": "c", - "type_traits": "c" + "type_traits": "c", + "array": "c", + "string_view": "c", + "initializer_list": "c", + "utility": "c" } } \ No newline at end of file diff --git a/src/headers/exceptions.h b/src/headers/exceptions.h index 0e0715e..8990d35 100644 --- a/src/headers/exceptions.h +++ b/src/headers/exceptions.h @@ -3,4 +3,37 @@ extern void setupExceptions(); +extern void isrHandler0(); +extern void isrHandler1(); +extern void isrHandler2(); +extern void isrHandler3(); +extern void isrHandler4(); +extern void isrHandler5(); +extern void isrHandler6(); +extern void isrHandler7(); +extern void isrHandler8(); +extern void isrHandler9(); +extern void isrHandler10(); +extern void isrHandler11(); +extern void isrHandler12(); +extern void isrHandler13(); +extern void isrHandler14(); +extern void isrHandler15(); +extern void isrHandler16(); +extern void isrHandler17(); +extern void isrHandler18(); +extern void isrHandler19(); +extern void isrHandler20(); +extern void isrHandler21(); +extern void isrHandler22(); +extern void isrHandler23(); +extern void isrHandler24(); +extern void isrHandler25(); +extern void isrHandler26(); +extern void isrHandler27(); +extern void isrHandler28(); +extern void isrHandler29(); +extern void isrHandler30(); +extern void isrHandler31(); + #endif \ No newline at end of file diff --git a/src/headers/interrupts.h b/src/headers/interrupts.h index 1d8a597..f8ed10a 100644 --- a/src/headers/interrupts.h +++ b/src/headers/interrupts.h @@ -16,6 +16,13 @@ uint32_t base; } __attribute__((packed)) IDTR; +typedef struct { + unsigned int gs, fs, es, ds; + unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; + unsigned int int_no, err_code; + unsigned int eip, cs, eflags, useresp, ss; +} __attribute__((packed)) regs; + extern void initInterrupts(); extern void setInterrupt(uint8_t vector, void* callback); diff --git a/src/headers/irqs.h b/src/headers/irqs.h new file mode 100644 index 0000000..c3cde17 --- /dev/null +++ b/src/headers/irqs.h @@ -0,0 +1,27 @@ +#ifndef IRQS_H +#define IRQS_H + +#include + +extern void initIRQs(); + +extern void setIRQHandler(uint8_t irqNumber, void* fun); + +extern void irqHandler0(); +extern void irqHandler1(); +extern void irqHandler2(); +extern void irqHandler3(); +extern void irqHandler4(); +extern void irqHandler5(); +extern void irqHandler6(); +extern void irqHandler7(); +extern void irqHandler8(); +extern void irqHandler9(); +extern void irqHandler10(); +extern void irqHandler11(); +extern void irqHandler12(); +extern void irqHandler13(); +extern void irqHandler14(); +extern void irqHandler15(); + +#endif \ No newline at end of file diff --git a/src/interrupts/exceptions.asm b/src/interrupts/exceptions.asm new file mode 100644 index 0000000..9fd4f04 --- /dev/null +++ b/src/interrupts/exceptions.asm @@ -0,0 +1,74 @@ +%macro isr 1 + global isrHandler%1 + isrHandler%1: + push byte 0 + push byte %1 + jmp exceptionHandler +%endmacro + +%macro isr_error 1 + global isrHandler%1 + isrHandler%1: + push byte %1 + jmp exceptionHandler +%endmacro + +isrs: + isr 0 + isr 1 + isr 2 + isr 3 + isr 4 + isr 5 + isr 6 + isr 7 + isr_error 8 + isr 9 + isr_error 10 + isr_error 11 + isr_error 12 + isr_error 13 + isr_error 14 + isr 15 + isr 16 + isr_error 17 + isr 18 + isr 19 + isr 20 + isr 21 + isr 22 + isr 23 + isr 24 + isr 25 + isr 26 + isr 27 + isr 28 + isr 29 + isr_error 30 + isr 31 + +extern handleException + +exceptionHandler: + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp + push eax + mov eax, handleException + call eax + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 + iret \ No newline at end of file diff --git a/src/interrupts/exceptions.c b/src/interrupts/exceptions.c index 19d8819..8d82af9 100644 --- a/src/interrupts/exceptions.c +++ b/src/interrupts/exceptions.c @@ -3,51 +3,77 @@ #include #include <_stdio.h> -#define exception(exceptionNR, name) void exception##exceptionNR##Handler () {printf("exception "#name" happend!"); yields();} -#define setExceptionHandler(exceptionNR) setInterrupt(exceptionNR, &exception##exceptionNR##Handler); - -exception(0, DIVIDE_BY_ZERO); -exception(1, DEBUG); -exception(2, NON_MASKABLE_INTERRUPT); -exception(3, BREAKPOINT); -exception(4, OVERFLOW); -exception(5, BOUND_RANGE_EXCEEDED); -exception(6, INVALID_OPCODE); -exception(7, DEVIVE_NOT_AVAILABLE); -exception(8, DOUBLE_FAULT); -exception(10, INVALID_TSS); -exception(11, SEGMENT_NOT_PRESENT); -exception(12, STACK_SEGMENT_FAULT); -exception(13, GENERAL_PROTECTION_FAULT); -exception(14, PAGE_FAULT); -exception(16, X87_FLOATING_POINT_EXCEPTION); -exception(17, ALIGNMENT_CHECK); -exception(18, MACHINE_CHECK); -exception(19, SMID_FLOATING_POINT_EXCEPTION); -exception(20, VIRTUALIZATION_EXCEPTION); -exception(30, SECURITy_EXCEPTION); - +char* EXCEPTION_MESSAGES[] = { + "DIVIDE BY ZERO", + "DEBUG", + "NON-MASKABLE INTERRUPT", + "BREAKPOINT", + "OVERFLOW", + "BOUND RAGE EXCEEDED", + "INVALID OPCODE", + "DEVICE NOT AVAILABLE", + "DOUBLE FAULT", + "COPROCESSOR SEGMENT OVERRUN", + "INVALID TSS", + "SEGMENT NOT PRESENT", + "STACK SEGMENT FAULT", + "GENERAL PROTECTION FAULT", + "PAGE FAULT", + "RESERVED", + "x87 FLOATING-POINT-EXCEPTION", + "ALIGNMENT CHECK", + "MACHINE CHECK", + "SMID FLOATING-POINT-EXCEPTION", + "VIRTUALIZATION EXCEPTION", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "SECURITY EXCEPTION", + "RESERVED" +}; void setupExceptions() { printf("setting exceptions\n"); - setExceptionHandler(0); - setExceptionHandler(1); - setExceptionHandler(2); - setExceptionHandler(3); - setExceptionHandler(4); - setExceptionHandler(5); - setExceptionHandler(6); - setExceptionHandler(7); - setExceptionHandler(8); - setExceptionHandler(10); - setExceptionHandler(11); - setExceptionHandler(12); - setExceptionHandler(13); - setExceptionHandler(14); - setExceptionHandler(16); - setExceptionHandler(17); - setExceptionHandler(18); - setExceptionHandler(19); - setExceptionHandler(20); - setExceptionHandler(30); + setInterrupt(0, &isrHandler0); + setInterrupt(1, &isrHandler1); + setInterrupt(2, &isrHandler2); + setInterrupt(3, &isrHandler3); + setInterrupt(4, &isrHandler4); + setInterrupt(5, &isrHandler5); + setInterrupt(6, &isrHandler6); + setInterrupt(7, &isrHandler7); + setInterrupt(8, &isrHandler8); + setInterrupt(9, &isrHandler9); + setInterrupt(10, &isrHandler10); + setInterrupt(11, &isrHandler11); + setInterrupt(12, &isrHandler12); + setInterrupt(13, &isrHandler13); + setInterrupt(14, &isrHandler14); + setInterrupt(15, &isrHandler15); + setInterrupt(16, &isrHandler16); + setInterrupt(17, &isrHandler17); + setInterrupt(18, &isrHandler18); + setInterrupt(19, &isrHandler19); + setInterrupt(20, &isrHandler20); + setInterrupt(21, &isrHandler21); + setInterrupt(22, &isrHandler22); + setInterrupt(23, &isrHandler23); + setInterrupt(24, &isrHandler24); + setInterrupt(25, &isrHandler25); + setInterrupt(26, &isrHandler26); + setInterrupt(27, &isrHandler27); + setInterrupt(28, &isrHandler28); + setInterrupt(29, &isrHandler29); + setInterrupt(30, &isrHandler30); + setInterrupt(31, &isrHandler31); +} + +void handleException(regs* registers) { + printf("exception %s was raised with error code 0x%x!\n", EXCEPTION_MESSAGES[registers->int_no], registers->err_code); + yields(); } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 36c0cfc..e94ea84 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,10 @@ { "files.associations": { "*.h": "c", - "type_traits": "c" + "type_traits": "c", + "array": "c", + "string_view": "c", + "initializer_list": "c", + "utility": "c" } } \ No newline at end of file diff --git a/src/headers/exceptions.h b/src/headers/exceptions.h index 0e0715e..8990d35 100644 --- a/src/headers/exceptions.h +++ b/src/headers/exceptions.h @@ -3,4 +3,37 @@ extern void setupExceptions(); +extern void isrHandler0(); +extern void isrHandler1(); +extern void isrHandler2(); +extern void isrHandler3(); +extern void isrHandler4(); +extern void isrHandler5(); +extern void isrHandler6(); +extern void isrHandler7(); +extern void isrHandler8(); +extern void isrHandler9(); +extern void isrHandler10(); +extern void isrHandler11(); +extern void isrHandler12(); +extern void isrHandler13(); +extern void isrHandler14(); +extern void isrHandler15(); +extern void isrHandler16(); +extern void isrHandler17(); +extern void isrHandler18(); +extern void isrHandler19(); +extern void isrHandler20(); +extern void isrHandler21(); +extern void isrHandler22(); +extern void isrHandler23(); +extern void isrHandler24(); +extern void isrHandler25(); +extern void isrHandler26(); +extern void isrHandler27(); +extern void isrHandler28(); +extern void isrHandler29(); +extern void isrHandler30(); +extern void isrHandler31(); + #endif \ No newline at end of file diff --git a/src/headers/interrupts.h b/src/headers/interrupts.h index 1d8a597..f8ed10a 100644 --- a/src/headers/interrupts.h +++ b/src/headers/interrupts.h @@ -16,6 +16,13 @@ uint32_t base; } __attribute__((packed)) IDTR; +typedef struct { + unsigned int gs, fs, es, ds; + unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; + unsigned int int_no, err_code; + unsigned int eip, cs, eflags, useresp, ss; +} __attribute__((packed)) regs; + extern void initInterrupts(); extern void setInterrupt(uint8_t vector, void* callback); diff --git a/src/headers/irqs.h b/src/headers/irqs.h new file mode 100644 index 0000000..c3cde17 --- /dev/null +++ b/src/headers/irqs.h @@ -0,0 +1,27 @@ +#ifndef IRQS_H +#define IRQS_H + +#include + +extern void initIRQs(); + +extern void setIRQHandler(uint8_t irqNumber, void* fun); + +extern void irqHandler0(); +extern void irqHandler1(); +extern void irqHandler2(); +extern void irqHandler3(); +extern void irqHandler4(); +extern void irqHandler5(); +extern void irqHandler6(); +extern void irqHandler7(); +extern void irqHandler8(); +extern void irqHandler9(); +extern void irqHandler10(); +extern void irqHandler11(); +extern void irqHandler12(); +extern void irqHandler13(); +extern void irqHandler14(); +extern void irqHandler15(); + +#endif \ No newline at end of file diff --git a/src/interrupts/exceptions.asm b/src/interrupts/exceptions.asm new file mode 100644 index 0000000..9fd4f04 --- /dev/null +++ b/src/interrupts/exceptions.asm @@ -0,0 +1,74 @@ +%macro isr 1 + global isrHandler%1 + isrHandler%1: + push byte 0 + push byte %1 + jmp exceptionHandler +%endmacro + +%macro isr_error 1 + global isrHandler%1 + isrHandler%1: + push byte %1 + jmp exceptionHandler +%endmacro + +isrs: + isr 0 + isr 1 + isr 2 + isr 3 + isr 4 + isr 5 + isr 6 + isr 7 + isr_error 8 + isr 9 + isr_error 10 + isr_error 11 + isr_error 12 + isr_error 13 + isr_error 14 + isr 15 + isr 16 + isr_error 17 + isr 18 + isr 19 + isr 20 + isr 21 + isr 22 + isr 23 + isr 24 + isr 25 + isr 26 + isr 27 + isr 28 + isr 29 + isr_error 30 + isr 31 + +extern handleException + +exceptionHandler: + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp + push eax + mov eax, handleException + call eax + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 + iret \ No newline at end of file diff --git a/src/interrupts/exceptions.c b/src/interrupts/exceptions.c index 19d8819..8d82af9 100644 --- a/src/interrupts/exceptions.c +++ b/src/interrupts/exceptions.c @@ -3,51 +3,77 @@ #include #include <_stdio.h> -#define exception(exceptionNR, name) void exception##exceptionNR##Handler () {printf("exception "#name" happend!"); yields();} -#define setExceptionHandler(exceptionNR) setInterrupt(exceptionNR, &exception##exceptionNR##Handler); - -exception(0, DIVIDE_BY_ZERO); -exception(1, DEBUG); -exception(2, NON_MASKABLE_INTERRUPT); -exception(3, BREAKPOINT); -exception(4, OVERFLOW); -exception(5, BOUND_RANGE_EXCEEDED); -exception(6, INVALID_OPCODE); -exception(7, DEVIVE_NOT_AVAILABLE); -exception(8, DOUBLE_FAULT); -exception(10, INVALID_TSS); -exception(11, SEGMENT_NOT_PRESENT); -exception(12, STACK_SEGMENT_FAULT); -exception(13, GENERAL_PROTECTION_FAULT); -exception(14, PAGE_FAULT); -exception(16, X87_FLOATING_POINT_EXCEPTION); -exception(17, ALIGNMENT_CHECK); -exception(18, MACHINE_CHECK); -exception(19, SMID_FLOATING_POINT_EXCEPTION); -exception(20, VIRTUALIZATION_EXCEPTION); -exception(30, SECURITy_EXCEPTION); - +char* EXCEPTION_MESSAGES[] = { + "DIVIDE BY ZERO", + "DEBUG", + "NON-MASKABLE INTERRUPT", + "BREAKPOINT", + "OVERFLOW", + "BOUND RAGE EXCEEDED", + "INVALID OPCODE", + "DEVICE NOT AVAILABLE", + "DOUBLE FAULT", + "COPROCESSOR SEGMENT OVERRUN", + "INVALID TSS", + "SEGMENT NOT PRESENT", + "STACK SEGMENT FAULT", + "GENERAL PROTECTION FAULT", + "PAGE FAULT", + "RESERVED", + "x87 FLOATING-POINT-EXCEPTION", + "ALIGNMENT CHECK", + "MACHINE CHECK", + "SMID FLOATING-POINT-EXCEPTION", + "VIRTUALIZATION EXCEPTION", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "SECURITY EXCEPTION", + "RESERVED" +}; void setupExceptions() { printf("setting exceptions\n"); - setExceptionHandler(0); - setExceptionHandler(1); - setExceptionHandler(2); - setExceptionHandler(3); - setExceptionHandler(4); - setExceptionHandler(5); - setExceptionHandler(6); - setExceptionHandler(7); - setExceptionHandler(8); - setExceptionHandler(10); - setExceptionHandler(11); - setExceptionHandler(12); - setExceptionHandler(13); - setExceptionHandler(14); - setExceptionHandler(16); - setExceptionHandler(17); - setExceptionHandler(18); - setExceptionHandler(19); - setExceptionHandler(20); - setExceptionHandler(30); + setInterrupt(0, &isrHandler0); + setInterrupt(1, &isrHandler1); + setInterrupt(2, &isrHandler2); + setInterrupt(3, &isrHandler3); + setInterrupt(4, &isrHandler4); + setInterrupt(5, &isrHandler5); + setInterrupt(6, &isrHandler6); + setInterrupt(7, &isrHandler7); + setInterrupt(8, &isrHandler8); + setInterrupt(9, &isrHandler9); + setInterrupt(10, &isrHandler10); + setInterrupt(11, &isrHandler11); + setInterrupt(12, &isrHandler12); + setInterrupt(13, &isrHandler13); + setInterrupt(14, &isrHandler14); + setInterrupt(15, &isrHandler15); + setInterrupt(16, &isrHandler16); + setInterrupt(17, &isrHandler17); + setInterrupt(18, &isrHandler18); + setInterrupt(19, &isrHandler19); + setInterrupt(20, &isrHandler20); + setInterrupt(21, &isrHandler21); + setInterrupt(22, &isrHandler22); + setInterrupt(23, &isrHandler23); + setInterrupt(24, &isrHandler24); + setInterrupt(25, &isrHandler25); + setInterrupt(26, &isrHandler26); + setInterrupt(27, &isrHandler27); + setInterrupt(28, &isrHandler28); + setInterrupt(29, &isrHandler29); + setInterrupt(30, &isrHandler30); + setInterrupt(31, &isrHandler31); +} + +void handleException(regs* registers) { + printf("exception %s was raised with error code 0x%x!\n", EXCEPTION_MESSAGES[registers->int_no], registers->err_code); + yields(); } \ No newline at end of file diff --git a/src/interrupts/interrupts.c b/src/interrupts/interrupts.c index 0c9e2b1..908e4ef 100644 --- a/src/interrupts/interrupts.c +++ b/src/interrupts/interrupts.c @@ -17,47 +17,16 @@ descriptor->attributes = 0x8E; descriptor->isr_high = (uint32_t)callback >> 16; descriptor->reserved = 0; - __asm__ volatile ("lidt %0" : : "memory"(idtr)); } -uint32_t count = 0x01; - -void testInterrupt() { - printf("interrupt 0x%x!\n", count++); - yields(); -} - -#define PIC1 0x20 -#define PIC2 0xA0 -#define PIC1_COMMAND PIC1 -#define PIC1_DATA (PIC1+1) -#define PIC2_COMMAND PIC2 -#define PIC2_DATA (PIC2+1) - -void remapPIC(int offset1, int offset2) { - printf("remapping pic\n"); - outb(0x20, 0x11); - outb(0xA0, 0x11); - outb(0x21, 0x20); - outb(0xA1, offset1); - outb(0x21, offset2); - outb(0xA1, 0x02); - outb(0x21, 0x01); - outb(0xA1, 0x01); - outb(0x21, 0x0); - outb(0xA1, 0x0); -} void initInterrupts() { - remapPIC(32, 40); - buffer = malloc(sizeof(IDTEntry) * 256); - entries = (IDTEntry*) (((int) buffer + sizeof(IDTEntry)) & -1 ^ 0x0F); + buffer = malloc(sizeof(IDTEntry) * 257); + entries = (IDTEntry*) (((int) buffer + sizeof(IDTEntry) >> 3) << 3); idtr.limit = sizeof(IDTEntry) * 256 - 1; idtr.base = (uint32_t) entries; - for (int i = 0; i < 256; i++) { - setInterrupt(i, &testInterrupt); - } setupExceptions(); - // setupTimer(); + setupIRQs(); + __asm__ volatile ("lidt %0" : : "memory"(idtr)); __asm__ volatile ("sti"); } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 36c0cfc..e94ea84 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,10 @@ { "files.associations": { "*.h": "c", - "type_traits": "c" + "type_traits": "c", + "array": "c", + "string_view": "c", + "initializer_list": "c", + "utility": "c" } } \ No newline at end of file diff --git a/src/headers/exceptions.h b/src/headers/exceptions.h index 0e0715e..8990d35 100644 --- a/src/headers/exceptions.h +++ b/src/headers/exceptions.h @@ -3,4 +3,37 @@ extern void setupExceptions(); +extern void isrHandler0(); +extern void isrHandler1(); +extern void isrHandler2(); +extern void isrHandler3(); +extern void isrHandler4(); +extern void isrHandler5(); +extern void isrHandler6(); +extern void isrHandler7(); +extern void isrHandler8(); +extern void isrHandler9(); +extern void isrHandler10(); +extern void isrHandler11(); +extern void isrHandler12(); +extern void isrHandler13(); +extern void isrHandler14(); +extern void isrHandler15(); +extern void isrHandler16(); +extern void isrHandler17(); +extern void isrHandler18(); +extern void isrHandler19(); +extern void isrHandler20(); +extern void isrHandler21(); +extern void isrHandler22(); +extern void isrHandler23(); +extern void isrHandler24(); +extern void isrHandler25(); +extern void isrHandler26(); +extern void isrHandler27(); +extern void isrHandler28(); +extern void isrHandler29(); +extern void isrHandler30(); +extern void isrHandler31(); + #endif \ No newline at end of file diff --git a/src/headers/interrupts.h b/src/headers/interrupts.h index 1d8a597..f8ed10a 100644 --- a/src/headers/interrupts.h +++ b/src/headers/interrupts.h @@ -16,6 +16,13 @@ uint32_t base; } __attribute__((packed)) IDTR; +typedef struct { + unsigned int gs, fs, es, ds; + unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; + unsigned int int_no, err_code; + unsigned int eip, cs, eflags, useresp, ss; +} __attribute__((packed)) regs; + extern void initInterrupts(); extern void setInterrupt(uint8_t vector, void* callback); diff --git a/src/headers/irqs.h b/src/headers/irqs.h new file mode 100644 index 0000000..c3cde17 --- /dev/null +++ b/src/headers/irqs.h @@ -0,0 +1,27 @@ +#ifndef IRQS_H +#define IRQS_H + +#include + +extern void initIRQs(); + +extern void setIRQHandler(uint8_t irqNumber, void* fun); + +extern void irqHandler0(); +extern void irqHandler1(); +extern void irqHandler2(); +extern void irqHandler3(); +extern void irqHandler4(); +extern void irqHandler5(); +extern void irqHandler6(); +extern void irqHandler7(); +extern void irqHandler8(); +extern void irqHandler9(); +extern void irqHandler10(); +extern void irqHandler11(); +extern void irqHandler12(); +extern void irqHandler13(); +extern void irqHandler14(); +extern void irqHandler15(); + +#endif \ No newline at end of file diff --git a/src/interrupts/exceptions.asm b/src/interrupts/exceptions.asm new file mode 100644 index 0000000..9fd4f04 --- /dev/null +++ b/src/interrupts/exceptions.asm @@ -0,0 +1,74 @@ +%macro isr 1 + global isrHandler%1 + isrHandler%1: + push byte 0 + push byte %1 + jmp exceptionHandler +%endmacro + +%macro isr_error 1 + global isrHandler%1 + isrHandler%1: + push byte %1 + jmp exceptionHandler +%endmacro + +isrs: + isr 0 + isr 1 + isr 2 + isr 3 + isr 4 + isr 5 + isr 6 + isr 7 + isr_error 8 + isr 9 + isr_error 10 + isr_error 11 + isr_error 12 + isr_error 13 + isr_error 14 + isr 15 + isr 16 + isr_error 17 + isr 18 + isr 19 + isr 20 + isr 21 + isr 22 + isr 23 + isr 24 + isr 25 + isr 26 + isr 27 + isr 28 + isr 29 + isr_error 30 + isr 31 + +extern handleException + +exceptionHandler: + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp + push eax + mov eax, handleException + call eax + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 + iret \ No newline at end of file diff --git a/src/interrupts/exceptions.c b/src/interrupts/exceptions.c index 19d8819..8d82af9 100644 --- a/src/interrupts/exceptions.c +++ b/src/interrupts/exceptions.c @@ -3,51 +3,77 @@ #include #include <_stdio.h> -#define exception(exceptionNR, name) void exception##exceptionNR##Handler () {printf("exception "#name" happend!"); yields();} -#define setExceptionHandler(exceptionNR) setInterrupt(exceptionNR, &exception##exceptionNR##Handler); - -exception(0, DIVIDE_BY_ZERO); -exception(1, DEBUG); -exception(2, NON_MASKABLE_INTERRUPT); -exception(3, BREAKPOINT); -exception(4, OVERFLOW); -exception(5, BOUND_RANGE_EXCEEDED); -exception(6, INVALID_OPCODE); -exception(7, DEVIVE_NOT_AVAILABLE); -exception(8, DOUBLE_FAULT); -exception(10, INVALID_TSS); -exception(11, SEGMENT_NOT_PRESENT); -exception(12, STACK_SEGMENT_FAULT); -exception(13, GENERAL_PROTECTION_FAULT); -exception(14, PAGE_FAULT); -exception(16, X87_FLOATING_POINT_EXCEPTION); -exception(17, ALIGNMENT_CHECK); -exception(18, MACHINE_CHECK); -exception(19, SMID_FLOATING_POINT_EXCEPTION); -exception(20, VIRTUALIZATION_EXCEPTION); -exception(30, SECURITy_EXCEPTION); - +char* EXCEPTION_MESSAGES[] = { + "DIVIDE BY ZERO", + "DEBUG", + "NON-MASKABLE INTERRUPT", + "BREAKPOINT", + "OVERFLOW", + "BOUND RAGE EXCEEDED", + "INVALID OPCODE", + "DEVICE NOT AVAILABLE", + "DOUBLE FAULT", + "COPROCESSOR SEGMENT OVERRUN", + "INVALID TSS", + "SEGMENT NOT PRESENT", + "STACK SEGMENT FAULT", + "GENERAL PROTECTION FAULT", + "PAGE FAULT", + "RESERVED", + "x87 FLOATING-POINT-EXCEPTION", + "ALIGNMENT CHECK", + "MACHINE CHECK", + "SMID FLOATING-POINT-EXCEPTION", + "VIRTUALIZATION EXCEPTION", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "SECURITY EXCEPTION", + "RESERVED" +}; void setupExceptions() { printf("setting exceptions\n"); - setExceptionHandler(0); - setExceptionHandler(1); - setExceptionHandler(2); - setExceptionHandler(3); - setExceptionHandler(4); - setExceptionHandler(5); - setExceptionHandler(6); - setExceptionHandler(7); - setExceptionHandler(8); - setExceptionHandler(10); - setExceptionHandler(11); - setExceptionHandler(12); - setExceptionHandler(13); - setExceptionHandler(14); - setExceptionHandler(16); - setExceptionHandler(17); - setExceptionHandler(18); - setExceptionHandler(19); - setExceptionHandler(20); - setExceptionHandler(30); + setInterrupt(0, &isrHandler0); + setInterrupt(1, &isrHandler1); + setInterrupt(2, &isrHandler2); + setInterrupt(3, &isrHandler3); + setInterrupt(4, &isrHandler4); + setInterrupt(5, &isrHandler5); + setInterrupt(6, &isrHandler6); + setInterrupt(7, &isrHandler7); + setInterrupt(8, &isrHandler8); + setInterrupt(9, &isrHandler9); + setInterrupt(10, &isrHandler10); + setInterrupt(11, &isrHandler11); + setInterrupt(12, &isrHandler12); + setInterrupt(13, &isrHandler13); + setInterrupt(14, &isrHandler14); + setInterrupt(15, &isrHandler15); + setInterrupt(16, &isrHandler16); + setInterrupt(17, &isrHandler17); + setInterrupt(18, &isrHandler18); + setInterrupt(19, &isrHandler19); + setInterrupt(20, &isrHandler20); + setInterrupt(21, &isrHandler21); + setInterrupt(22, &isrHandler22); + setInterrupt(23, &isrHandler23); + setInterrupt(24, &isrHandler24); + setInterrupt(25, &isrHandler25); + setInterrupt(26, &isrHandler26); + setInterrupt(27, &isrHandler27); + setInterrupt(28, &isrHandler28); + setInterrupt(29, &isrHandler29); + setInterrupt(30, &isrHandler30); + setInterrupt(31, &isrHandler31); +} + +void handleException(regs* registers) { + printf("exception %s was raised with error code 0x%x!\n", EXCEPTION_MESSAGES[registers->int_no], registers->err_code); + yields(); } \ No newline at end of file diff --git a/src/interrupts/interrupts.c b/src/interrupts/interrupts.c index 0c9e2b1..908e4ef 100644 --- a/src/interrupts/interrupts.c +++ b/src/interrupts/interrupts.c @@ -17,47 +17,16 @@ descriptor->attributes = 0x8E; descriptor->isr_high = (uint32_t)callback >> 16; descriptor->reserved = 0; - __asm__ volatile ("lidt %0" : : "memory"(idtr)); } -uint32_t count = 0x01; - -void testInterrupt() { - printf("interrupt 0x%x!\n", count++); - yields(); -} - -#define PIC1 0x20 -#define PIC2 0xA0 -#define PIC1_COMMAND PIC1 -#define PIC1_DATA (PIC1+1) -#define PIC2_COMMAND PIC2 -#define PIC2_DATA (PIC2+1) - -void remapPIC(int offset1, int offset2) { - printf("remapping pic\n"); - outb(0x20, 0x11); - outb(0xA0, 0x11); - outb(0x21, 0x20); - outb(0xA1, offset1); - outb(0x21, offset2); - outb(0xA1, 0x02); - outb(0x21, 0x01); - outb(0xA1, 0x01); - outb(0x21, 0x0); - outb(0xA1, 0x0); -} void initInterrupts() { - remapPIC(32, 40); - buffer = malloc(sizeof(IDTEntry) * 256); - entries = (IDTEntry*) (((int) buffer + sizeof(IDTEntry)) & -1 ^ 0x0F); + buffer = malloc(sizeof(IDTEntry) * 257); + entries = (IDTEntry*) (((int) buffer + sizeof(IDTEntry) >> 3) << 3); idtr.limit = sizeof(IDTEntry) * 256 - 1; idtr.base = (uint32_t) entries; - for (int i = 0; i < 256; i++) { - setInterrupt(i, &testInterrupt); - } setupExceptions(); - // setupTimer(); + setupIRQs(); + __asm__ volatile ("lidt %0" : : "memory"(idtr)); __asm__ volatile ("sti"); } \ No newline at end of file diff --git a/src/interrupts/irqs.asm b/src/interrupts/irqs.asm new file mode 100644 index 0000000..3e6670b --- /dev/null +++ b/src/interrupts/irqs.asm @@ -0,0 +1,52 @@ +%macro irq 1 + global irqHandler%1 + irqHandler%1: + cli + push byte 0 + push byte %1+32 + jmp irqHandler +%endmacro + +irqs: + irq 0 + irq 1 + irq 2 + irq 3 + irq 4 + irq 5 + irq 6 + irq 7 + irq 8 + irq 9 + irq 10 + irq 11 + irq 12 + irq 13 + irq 14 + irq 15 + +extern handleIRQ + +irqHandler: + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp + push eax + mov eax, handleIRQ + call eax + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 + iret \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 36c0cfc..e94ea84 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,10 @@ { "files.associations": { "*.h": "c", - "type_traits": "c" + "type_traits": "c", + "array": "c", + "string_view": "c", + "initializer_list": "c", + "utility": "c" } } \ No newline at end of file diff --git a/src/headers/exceptions.h b/src/headers/exceptions.h index 0e0715e..8990d35 100644 --- a/src/headers/exceptions.h +++ b/src/headers/exceptions.h @@ -3,4 +3,37 @@ extern void setupExceptions(); +extern void isrHandler0(); +extern void isrHandler1(); +extern void isrHandler2(); +extern void isrHandler3(); +extern void isrHandler4(); +extern void isrHandler5(); +extern void isrHandler6(); +extern void isrHandler7(); +extern void isrHandler8(); +extern void isrHandler9(); +extern void isrHandler10(); +extern void isrHandler11(); +extern void isrHandler12(); +extern void isrHandler13(); +extern void isrHandler14(); +extern void isrHandler15(); +extern void isrHandler16(); +extern void isrHandler17(); +extern void isrHandler18(); +extern void isrHandler19(); +extern void isrHandler20(); +extern void isrHandler21(); +extern void isrHandler22(); +extern void isrHandler23(); +extern void isrHandler24(); +extern void isrHandler25(); +extern void isrHandler26(); +extern void isrHandler27(); +extern void isrHandler28(); +extern void isrHandler29(); +extern void isrHandler30(); +extern void isrHandler31(); + #endif \ No newline at end of file diff --git a/src/headers/interrupts.h b/src/headers/interrupts.h index 1d8a597..f8ed10a 100644 --- a/src/headers/interrupts.h +++ b/src/headers/interrupts.h @@ -16,6 +16,13 @@ uint32_t base; } __attribute__((packed)) IDTR; +typedef struct { + unsigned int gs, fs, es, ds; + unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; + unsigned int int_no, err_code; + unsigned int eip, cs, eflags, useresp, ss; +} __attribute__((packed)) regs; + extern void initInterrupts(); extern void setInterrupt(uint8_t vector, void* callback); diff --git a/src/headers/irqs.h b/src/headers/irqs.h new file mode 100644 index 0000000..c3cde17 --- /dev/null +++ b/src/headers/irqs.h @@ -0,0 +1,27 @@ +#ifndef IRQS_H +#define IRQS_H + +#include + +extern void initIRQs(); + +extern void setIRQHandler(uint8_t irqNumber, void* fun); + +extern void irqHandler0(); +extern void irqHandler1(); +extern void irqHandler2(); +extern void irqHandler3(); +extern void irqHandler4(); +extern void irqHandler5(); +extern void irqHandler6(); +extern void irqHandler7(); +extern void irqHandler8(); +extern void irqHandler9(); +extern void irqHandler10(); +extern void irqHandler11(); +extern void irqHandler12(); +extern void irqHandler13(); +extern void irqHandler14(); +extern void irqHandler15(); + +#endif \ No newline at end of file diff --git a/src/interrupts/exceptions.asm b/src/interrupts/exceptions.asm new file mode 100644 index 0000000..9fd4f04 --- /dev/null +++ b/src/interrupts/exceptions.asm @@ -0,0 +1,74 @@ +%macro isr 1 + global isrHandler%1 + isrHandler%1: + push byte 0 + push byte %1 + jmp exceptionHandler +%endmacro + +%macro isr_error 1 + global isrHandler%1 + isrHandler%1: + push byte %1 + jmp exceptionHandler +%endmacro + +isrs: + isr 0 + isr 1 + isr 2 + isr 3 + isr 4 + isr 5 + isr 6 + isr 7 + isr_error 8 + isr 9 + isr_error 10 + isr_error 11 + isr_error 12 + isr_error 13 + isr_error 14 + isr 15 + isr 16 + isr_error 17 + isr 18 + isr 19 + isr 20 + isr 21 + isr 22 + isr 23 + isr 24 + isr 25 + isr 26 + isr 27 + isr 28 + isr 29 + isr_error 30 + isr 31 + +extern handleException + +exceptionHandler: + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp + push eax + mov eax, handleException + call eax + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 + iret \ No newline at end of file diff --git a/src/interrupts/exceptions.c b/src/interrupts/exceptions.c index 19d8819..8d82af9 100644 --- a/src/interrupts/exceptions.c +++ b/src/interrupts/exceptions.c @@ -3,51 +3,77 @@ #include #include <_stdio.h> -#define exception(exceptionNR, name) void exception##exceptionNR##Handler () {printf("exception "#name" happend!"); yields();} -#define setExceptionHandler(exceptionNR) setInterrupt(exceptionNR, &exception##exceptionNR##Handler); - -exception(0, DIVIDE_BY_ZERO); -exception(1, DEBUG); -exception(2, NON_MASKABLE_INTERRUPT); -exception(3, BREAKPOINT); -exception(4, OVERFLOW); -exception(5, BOUND_RANGE_EXCEEDED); -exception(6, INVALID_OPCODE); -exception(7, DEVIVE_NOT_AVAILABLE); -exception(8, DOUBLE_FAULT); -exception(10, INVALID_TSS); -exception(11, SEGMENT_NOT_PRESENT); -exception(12, STACK_SEGMENT_FAULT); -exception(13, GENERAL_PROTECTION_FAULT); -exception(14, PAGE_FAULT); -exception(16, X87_FLOATING_POINT_EXCEPTION); -exception(17, ALIGNMENT_CHECK); -exception(18, MACHINE_CHECK); -exception(19, SMID_FLOATING_POINT_EXCEPTION); -exception(20, VIRTUALIZATION_EXCEPTION); -exception(30, SECURITy_EXCEPTION); - +char* EXCEPTION_MESSAGES[] = { + "DIVIDE BY ZERO", + "DEBUG", + "NON-MASKABLE INTERRUPT", + "BREAKPOINT", + "OVERFLOW", + "BOUND RAGE EXCEEDED", + "INVALID OPCODE", + "DEVICE NOT AVAILABLE", + "DOUBLE FAULT", + "COPROCESSOR SEGMENT OVERRUN", + "INVALID TSS", + "SEGMENT NOT PRESENT", + "STACK SEGMENT FAULT", + "GENERAL PROTECTION FAULT", + "PAGE FAULT", + "RESERVED", + "x87 FLOATING-POINT-EXCEPTION", + "ALIGNMENT CHECK", + "MACHINE CHECK", + "SMID FLOATING-POINT-EXCEPTION", + "VIRTUALIZATION EXCEPTION", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "SECURITY EXCEPTION", + "RESERVED" +}; void setupExceptions() { printf("setting exceptions\n"); - setExceptionHandler(0); - setExceptionHandler(1); - setExceptionHandler(2); - setExceptionHandler(3); - setExceptionHandler(4); - setExceptionHandler(5); - setExceptionHandler(6); - setExceptionHandler(7); - setExceptionHandler(8); - setExceptionHandler(10); - setExceptionHandler(11); - setExceptionHandler(12); - setExceptionHandler(13); - setExceptionHandler(14); - setExceptionHandler(16); - setExceptionHandler(17); - setExceptionHandler(18); - setExceptionHandler(19); - setExceptionHandler(20); - setExceptionHandler(30); + setInterrupt(0, &isrHandler0); + setInterrupt(1, &isrHandler1); + setInterrupt(2, &isrHandler2); + setInterrupt(3, &isrHandler3); + setInterrupt(4, &isrHandler4); + setInterrupt(5, &isrHandler5); + setInterrupt(6, &isrHandler6); + setInterrupt(7, &isrHandler7); + setInterrupt(8, &isrHandler8); + setInterrupt(9, &isrHandler9); + setInterrupt(10, &isrHandler10); + setInterrupt(11, &isrHandler11); + setInterrupt(12, &isrHandler12); + setInterrupt(13, &isrHandler13); + setInterrupt(14, &isrHandler14); + setInterrupt(15, &isrHandler15); + setInterrupt(16, &isrHandler16); + setInterrupt(17, &isrHandler17); + setInterrupt(18, &isrHandler18); + setInterrupt(19, &isrHandler19); + setInterrupt(20, &isrHandler20); + setInterrupt(21, &isrHandler21); + setInterrupt(22, &isrHandler22); + setInterrupt(23, &isrHandler23); + setInterrupt(24, &isrHandler24); + setInterrupt(25, &isrHandler25); + setInterrupt(26, &isrHandler26); + setInterrupt(27, &isrHandler27); + setInterrupt(28, &isrHandler28); + setInterrupt(29, &isrHandler29); + setInterrupt(30, &isrHandler30); + setInterrupt(31, &isrHandler31); +} + +void handleException(regs* registers) { + printf("exception %s was raised with error code 0x%x!\n", EXCEPTION_MESSAGES[registers->int_no], registers->err_code); + yields(); } \ No newline at end of file diff --git a/src/interrupts/interrupts.c b/src/interrupts/interrupts.c index 0c9e2b1..908e4ef 100644 --- a/src/interrupts/interrupts.c +++ b/src/interrupts/interrupts.c @@ -17,47 +17,16 @@ descriptor->attributes = 0x8E; descriptor->isr_high = (uint32_t)callback >> 16; descriptor->reserved = 0; - __asm__ volatile ("lidt %0" : : "memory"(idtr)); } -uint32_t count = 0x01; - -void testInterrupt() { - printf("interrupt 0x%x!\n", count++); - yields(); -} - -#define PIC1 0x20 -#define PIC2 0xA0 -#define PIC1_COMMAND PIC1 -#define PIC1_DATA (PIC1+1) -#define PIC2_COMMAND PIC2 -#define PIC2_DATA (PIC2+1) - -void remapPIC(int offset1, int offset2) { - printf("remapping pic\n"); - outb(0x20, 0x11); - outb(0xA0, 0x11); - outb(0x21, 0x20); - outb(0xA1, offset1); - outb(0x21, offset2); - outb(0xA1, 0x02); - outb(0x21, 0x01); - outb(0xA1, 0x01); - outb(0x21, 0x0); - outb(0xA1, 0x0); -} void initInterrupts() { - remapPIC(32, 40); - buffer = malloc(sizeof(IDTEntry) * 256); - entries = (IDTEntry*) (((int) buffer + sizeof(IDTEntry)) & -1 ^ 0x0F); + buffer = malloc(sizeof(IDTEntry) * 257); + entries = (IDTEntry*) (((int) buffer + sizeof(IDTEntry) >> 3) << 3); idtr.limit = sizeof(IDTEntry) * 256 - 1; idtr.base = (uint32_t) entries; - for (int i = 0; i < 256; i++) { - setInterrupt(i, &testInterrupt); - } setupExceptions(); - // setupTimer(); + setupIRQs(); + __asm__ volatile ("lidt %0" : : "memory"(idtr)); __asm__ volatile ("sti"); } \ No newline at end of file diff --git a/src/interrupts/irqs.asm b/src/interrupts/irqs.asm new file mode 100644 index 0000000..3e6670b --- /dev/null +++ b/src/interrupts/irqs.asm @@ -0,0 +1,52 @@ +%macro irq 1 + global irqHandler%1 + irqHandler%1: + cli + push byte 0 + push byte %1+32 + jmp irqHandler +%endmacro + +irqs: + irq 0 + irq 1 + irq 2 + irq 3 + irq 4 + irq 5 + irq 6 + irq 7 + irq 8 + irq 9 + irq 10 + irq 11 + irq 12 + irq 13 + irq 14 + irq 15 + +extern handleIRQ + +irqHandler: + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp + push eax + mov eax, handleIRQ + call eax + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 + iret \ No newline at end of file diff --git a/src/interrupts/irqs.c b/src/interrupts/irqs.c new file mode 100644 index 0000000..65826ac --- /dev/null +++ b/src/interrupts/irqs.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#include <_stdio.h> + +#define OFFSET_1 32 +#define OFFSET_2 40 + +void remapPIC(int offset1, int offset2) { + printf("remapping pic\n"); + outb(0x20, 0x11); + outb(0xA0, 0x11); + outb(0x21, 0x20); + outb(0xA1, offset1); + outb(0x21, offset2); + outb(0xA1, 0x02); + outb(0x21, 0x01); + outb(0xA1, 0x01); + outb(0x21, 0x0); + outb(0xA1, 0x0); +} + +void setupIRQs() { + printf("setting IRQs\n"); + setInterrupt(OFFSET_1 + 0, &irqHandler0); + setInterrupt(OFFSET_1 + 1, &irqHandler1); + setInterrupt(OFFSET_1 + 2, &irqHandler2); + setInterrupt(OFFSET_1 + 3, &irqHandler3); + setInterrupt(OFFSET_1 + 4, &irqHandler4); + setInterrupt(OFFSET_1 + 5, &irqHandler5); + setInterrupt(OFFSET_1 + 6, &irqHandler6); + setInterrupt(OFFSET_1 + 7, &irqHandler7); + setInterrupt(OFFSET_2 + 0, &irqHandler8); + setInterrupt(OFFSET_2 + 1, &irqHandler9); + setInterrupt(OFFSET_2 + 2, &irqHandler10); + setInterrupt(OFFSET_2 + 3, &irqHandler11); + setInterrupt(OFFSET_2 + 4, &irqHandler12); + setInterrupt(OFFSET_2 + 5, &irqHandler13); + setInterrupt(OFFSET_2 + 6, &irqHandler14); + setInterrupt(OFFSET_2 + 7, &irqHandler15); + remapPIC(OFFSET_1, OFFSET_2); +} + +void* irqHandlers[16]; + +void setIRQHandler(uint8_t irqNumber, void* fun) { + irqHandlers[irqNumber] = fun; +} + +void handleIRQ(regs* registers) { + if (registers->int_no >= OFFSET_2) { + outb(0xA0, 0x20); + } + outb(0x20, 0x20); + void (*handler)() = irqHandlers[registers->int_no - OFFSET_1]; + if (handler) { + handler(); + return; + } + printf("unhandeled IRQ no. 0x%x was triggered!\n", registers->int_no); + yields(); +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 36c0cfc..e94ea84 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,10 @@ { "files.associations": { "*.h": "c", - "type_traits": "c" + "type_traits": "c", + "array": "c", + "string_view": "c", + "initializer_list": "c", + "utility": "c" } } \ No newline at end of file diff --git a/src/headers/exceptions.h b/src/headers/exceptions.h index 0e0715e..8990d35 100644 --- a/src/headers/exceptions.h +++ b/src/headers/exceptions.h @@ -3,4 +3,37 @@ extern void setupExceptions(); +extern void isrHandler0(); +extern void isrHandler1(); +extern void isrHandler2(); +extern void isrHandler3(); +extern void isrHandler4(); +extern void isrHandler5(); +extern void isrHandler6(); +extern void isrHandler7(); +extern void isrHandler8(); +extern void isrHandler9(); +extern void isrHandler10(); +extern void isrHandler11(); +extern void isrHandler12(); +extern void isrHandler13(); +extern void isrHandler14(); +extern void isrHandler15(); +extern void isrHandler16(); +extern void isrHandler17(); +extern void isrHandler18(); +extern void isrHandler19(); +extern void isrHandler20(); +extern void isrHandler21(); +extern void isrHandler22(); +extern void isrHandler23(); +extern void isrHandler24(); +extern void isrHandler25(); +extern void isrHandler26(); +extern void isrHandler27(); +extern void isrHandler28(); +extern void isrHandler29(); +extern void isrHandler30(); +extern void isrHandler31(); + #endif \ No newline at end of file diff --git a/src/headers/interrupts.h b/src/headers/interrupts.h index 1d8a597..f8ed10a 100644 --- a/src/headers/interrupts.h +++ b/src/headers/interrupts.h @@ -16,6 +16,13 @@ uint32_t base; } __attribute__((packed)) IDTR; +typedef struct { + unsigned int gs, fs, es, ds; + unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; + unsigned int int_no, err_code; + unsigned int eip, cs, eflags, useresp, ss; +} __attribute__((packed)) regs; + extern void initInterrupts(); extern void setInterrupt(uint8_t vector, void* callback); diff --git a/src/headers/irqs.h b/src/headers/irqs.h new file mode 100644 index 0000000..c3cde17 --- /dev/null +++ b/src/headers/irqs.h @@ -0,0 +1,27 @@ +#ifndef IRQS_H +#define IRQS_H + +#include + +extern void initIRQs(); + +extern void setIRQHandler(uint8_t irqNumber, void* fun); + +extern void irqHandler0(); +extern void irqHandler1(); +extern void irqHandler2(); +extern void irqHandler3(); +extern void irqHandler4(); +extern void irqHandler5(); +extern void irqHandler6(); +extern void irqHandler7(); +extern void irqHandler8(); +extern void irqHandler9(); +extern void irqHandler10(); +extern void irqHandler11(); +extern void irqHandler12(); +extern void irqHandler13(); +extern void irqHandler14(); +extern void irqHandler15(); + +#endif \ No newline at end of file diff --git a/src/interrupts/exceptions.asm b/src/interrupts/exceptions.asm new file mode 100644 index 0000000..9fd4f04 --- /dev/null +++ b/src/interrupts/exceptions.asm @@ -0,0 +1,74 @@ +%macro isr 1 + global isrHandler%1 + isrHandler%1: + push byte 0 + push byte %1 + jmp exceptionHandler +%endmacro + +%macro isr_error 1 + global isrHandler%1 + isrHandler%1: + push byte %1 + jmp exceptionHandler +%endmacro + +isrs: + isr 0 + isr 1 + isr 2 + isr 3 + isr 4 + isr 5 + isr 6 + isr 7 + isr_error 8 + isr 9 + isr_error 10 + isr_error 11 + isr_error 12 + isr_error 13 + isr_error 14 + isr 15 + isr 16 + isr_error 17 + isr 18 + isr 19 + isr 20 + isr 21 + isr 22 + isr 23 + isr 24 + isr 25 + isr 26 + isr 27 + isr 28 + isr 29 + isr_error 30 + isr 31 + +extern handleException + +exceptionHandler: + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp + push eax + mov eax, handleException + call eax + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 + iret \ No newline at end of file diff --git a/src/interrupts/exceptions.c b/src/interrupts/exceptions.c index 19d8819..8d82af9 100644 --- a/src/interrupts/exceptions.c +++ b/src/interrupts/exceptions.c @@ -3,51 +3,77 @@ #include #include <_stdio.h> -#define exception(exceptionNR, name) void exception##exceptionNR##Handler () {printf("exception "#name" happend!"); yields();} -#define setExceptionHandler(exceptionNR) setInterrupt(exceptionNR, &exception##exceptionNR##Handler); - -exception(0, DIVIDE_BY_ZERO); -exception(1, DEBUG); -exception(2, NON_MASKABLE_INTERRUPT); -exception(3, BREAKPOINT); -exception(4, OVERFLOW); -exception(5, BOUND_RANGE_EXCEEDED); -exception(6, INVALID_OPCODE); -exception(7, DEVIVE_NOT_AVAILABLE); -exception(8, DOUBLE_FAULT); -exception(10, INVALID_TSS); -exception(11, SEGMENT_NOT_PRESENT); -exception(12, STACK_SEGMENT_FAULT); -exception(13, GENERAL_PROTECTION_FAULT); -exception(14, PAGE_FAULT); -exception(16, X87_FLOATING_POINT_EXCEPTION); -exception(17, ALIGNMENT_CHECK); -exception(18, MACHINE_CHECK); -exception(19, SMID_FLOATING_POINT_EXCEPTION); -exception(20, VIRTUALIZATION_EXCEPTION); -exception(30, SECURITy_EXCEPTION); - +char* EXCEPTION_MESSAGES[] = { + "DIVIDE BY ZERO", + "DEBUG", + "NON-MASKABLE INTERRUPT", + "BREAKPOINT", + "OVERFLOW", + "BOUND RAGE EXCEEDED", + "INVALID OPCODE", + "DEVICE NOT AVAILABLE", + "DOUBLE FAULT", + "COPROCESSOR SEGMENT OVERRUN", + "INVALID TSS", + "SEGMENT NOT PRESENT", + "STACK SEGMENT FAULT", + "GENERAL PROTECTION FAULT", + "PAGE FAULT", + "RESERVED", + "x87 FLOATING-POINT-EXCEPTION", + "ALIGNMENT CHECK", + "MACHINE CHECK", + "SMID FLOATING-POINT-EXCEPTION", + "VIRTUALIZATION EXCEPTION", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "SECURITY EXCEPTION", + "RESERVED" +}; void setupExceptions() { printf("setting exceptions\n"); - setExceptionHandler(0); - setExceptionHandler(1); - setExceptionHandler(2); - setExceptionHandler(3); - setExceptionHandler(4); - setExceptionHandler(5); - setExceptionHandler(6); - setExceptionHandler(7); - setExceptionHandler(8); - setExceptionHandler(10); - setExceptionHandler(11); - setExceptionHandler(12); - setExceptionHandler(13); - setExceptionHandler(14); - setExceptionHandler(16); - setExceptionHandler(17); - setExceptionHandler(18); - setExceptionHandler(19); - setExceptionHandler(20); - setExceptionHandler(30); + setInterrupt(0, &isrHandler0); + setInterrupt(1, &isrHandler1); + setInterrupt(2, &isrHandler2); + setInterrupt(3, &isrHandler3); + setInterrupt(4, &isrHandler4); + setInterrupt(5, &isrHandler5); + setInterrupt(6, &isrHandler6); + setInterrupt(7, &isrHandler7); + setInterrupt(8, &isrHandler8); + setInterrupt(9, &isrHandler9); + setInterrupt(10, &isrHandler10); + setInterrupt(11, &isrHandler11); + setInterrupt(12, &isrHandler12); + setInterrupt(13, &isrHandler13); + setInterrupt(14, &isrHandler14); + setInterrupt(15, &isrHandler15); + setInterrupt(16, &isrHandler16); + setInterrupt(17, &isrHandler17); + setInterrupt(18, &isrHandler18); + setInterrupt(19, &isrHandler19); + setInterrupt(20, &isrHandler20); + setInterrupt(21, &isrHandler21); + setInterrupt(22, &isrHandler22); + setInterrupt(23, &isrHandler23); + setInterrupt(24, &isrHandler24); + setInterrupt(25, &isrHandler25); + setInterrupt(26, &isrHandler26); + setInterrupt(27, &isrHandler27); + setInterrupt(28, &isrHandler28); + setInterrupt(29, &isrHandler29); + setInterrupt(30, &isrHandler30); + setInterrupt(31, &isrHandler31); +} + +void handleException(regs* registers) { + printf("exception %s was raised with error code 0x%x!\n", EXCEPTION_MESSAGES[registers->int_no], registers->err_code); + yields(); } \ No newline at end of file diff --git a/src/interrupts/interrupts.c b/src/interrupts/interrupts.c index 0c9e2b1..908e4ef 100644 --- a/src/interrupts/interrupts.c +++ b/src/interrupts/interrupts.c @@ -17,47 +17,16 @@ descriptor->attributes = 0x8E; descriptor->isr_high = (uint32_t)callback >> 16; descriptor->reserved = 0; - __asm__ volatile ("lidt %0" : : "memory"(idtr)); } -uint32_t count = 0x01; - -void testInterrupt() { - printf("interrupt 0x%x!\n", count++); - yields(); -} - -#define PIC1 0x20 -#define PIC2 0xA0 -#define PIC1_COMMAND PIC1 -#define PIC1_DATA (PIC1+1) -#define PIC2_COMMAND PIC2 -#define PIC2_DATA (PIC2+1) - -void remapPIC(int offset1, int offset2) { - printf("remapping pic\n"); - outb(0x20, 0x11); - outb(0xA0, 0x11); - outb(0x21, 0x20); - outb(0xA1, offset1); - outb(0x21, offset2); - outb(0xA1, 0x02); - outb(0x21, 0x01); - outb(0xA1, 0x01); - outb(0x21, 0x0); - outb(0xA1, 0x0); -} void initInterrupts() { - remapPIC(32, 40); - buffer = malloc(sizeof(IDTEntry) * 256); - entries = (IDTEntry*) (((int) buffer + sizeof(IDTEntry)) & -1 ^ 0x0F); + buffer = malloc(sizeof(IDTEntry) * 257); + entries = (IDTEntry*) (((int) buffer + sizeof(IDTEntry) >> 3) << 3); idtr.limit = sizeof(IDTEntry) * 256 - 1; idtr.base = (uint32_t) entries; - for (int i = 0; i < 256; i++) { - setInterrupt(i, &testInterrupt); - } setupExceptions(); - // setupTimer(); + setupIRQs(); + __asm__ volatile ("lidt %0" : : "memory"(idtr)); __asm__ volatile ("sti"); } \ No newline at end of file diff --git a/src/interrupts/irqs.asm b/src/interrupts/irqs.asm new file mode 100644 index 0000000..3e6670b --- /dev/null +++ b/src/interrupts/irqs.asm @@ -0,0 +1,52 @@ +%macro irq 1 + global irqHandler%1 + irqHandler%1: + cli + push byte 0 + push byte %1+32 + jmp irqHandler +%endmacro + +irqs: + irq 0 + irq 1 + irq 2 + irq 3 + irq 4 + irq 5 + irq 6 + irq 7 + irq 8 + irq 9 + irq 10 + irq 11 + irq 12 + irq 13 + irq 14 + irq 15 + +extern handleIRQ + +irqHandler: + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp + push eax + mov eax, handleIRQ + call eax + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 + iret \ No newline at end of file diff --git a/src/interrupts/irqs.c b/src/interrupts/irqs.c new file mode 100644 index 0000000..65826ac --- /dev/null +++ b/src/interrupts/irqs.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#include <_stdio.h> + +#define OFFSET_1 32 +#define OFFSET_2 40 + +void remapPIC(int offset1, int offset2) { + printf("remapping pic\n"); + outb(0x20, 0x11); + outb(0xA0, 0x11); + outb(0x21, 0x20); + outb(0xA1, offset1); + outb(0x21, offset2); + outb(0xA1, 0x02); + outb(0x21, 0x01); + outb(0xA1, 0x01); + outb(0x21, 0x0); + outb(0xA1, 0x0); +} + +void setupIRQs() { + printf("setting IRQs\n"); + setInterrupt(OFFSET_1 + 0, &irqHandler0); + setInterrupt(OFFSET_1 + 1, &irqHandler1); + setInterrupt(OFFSET_1 + 2, &irqHandler2); + setInterrupt(OFFSET_1 + 3, &irqHandler3); + setInterrupt(OFFSET_1 + 4, &irqHandler4); + setInterrupt(OFFSET_1 + 5, &irqHandler5); + setInterrupt(OFFSET_1 + 6, &irqHandler6); + setInterrupt(OFFSET_1 + 7, &irqHandler7); + setInterrupt(OFFSET_2 + 0, &irqHandler8); + setInterrupt(OFFSET_2 + 1, &irqHandler9); + setInterrupt(OFFSET_2 + 2, &irqHandler10); + setInterrupt(OFFSET_2 + 3, &irqHandler11); + setInterrupt(OFFSET_2 + 4, &irqHandler12); + setInterrupt(OFFSET_2 + 5, &irqHandler13); + setInterrupt(OFFSET_2 + 6, &irqHandler14); + setInterrupt(OFFSET_2 + 7, &irqHandler15); + remapPIC(OFFSET_1, OFFSET_2); +} + +void* irqHandlers[16]; + +void setIRQHandler(uint8_t irqNumber, void* fun) { + irqHandlers[irqNumber] = fun; +} + +void handleIRQ(regs* registers) { + if (registers->int_no >= OFFSET_2) { + outb(0xA0, 0x20); + } + outb(0x20, 0x20); + void (*handler)() = irqHandlers[registers->int_no - OFFSET_1]; + if (handler) { + handler(); + return; + } + printf("unhandeled IRQ no. 0x%x was triggered!\n", registers->int_no); + yields(); +} \ No newline at end of file diff --git a/src/interrupts/timer/timer.c b/src/interrupts/timer/timer.c new file mode 100644 index 0000000..440118a --- /dev/null +++ b/src/interrupts/timer/timer.c @@ -0,0 +1,49 @@ +#include +#include <_stdio.h> +#include +#include +#include +#include + + +#define PIT_A 0x40 +#define PIT_CONTROL 0x43 + +#define PIT_MASK 0xFF +#define PIT_SCALE 1193180 +#define PIT_SET 0x36 + +#define CMD_BINARY 0x00 + +#define CMD_MODE0 0x00 +#define CMD_MODE1 0x02 +#define CMD_MODE2 0x04 +#define CMD_MODE3 0x06 +#define CMD_MODE4 0x08 +#define CMD_MODE5 0x0a + +#define CMD_RW_BOTH 0x30 + +#define CMD_COUNTER0 0x00 +#define CMD_COUNTER2 0x80 + +void setTimerFreq(uint32_t hz) { + int divisor = PIT_SCALE / hz; + outb(PIT_CONTROL, 0x36);// CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); + outb(PIT_A, (uint8_t) divisor); + outb(PIT_A, (uint8_t) (divisor >> 8)); +} + +uint32_t timer_ticks = 0; + +void timerHandler() { + printf("timer 0x%x\n", timer_ticks); + timer_ticks++; + yields(); +} + +void setupTimer() { + printf("setting timer frequency to 100Hz\n"); + setTimerFreq(20); + setIRQHandler(0, &timerHandler); +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 36c0cfc..e94ea84 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,10 @@ { "files.associations": { "*.h": "c", - "type_traits": "c" + "type_traits": "c", + "array": "c", + "string_view": "c", + "initializer_list": "c", + "utility": "c" } } \ No newline at end of file diff --git a/src/headers/exceptions.h b/src/headers/exceptions.h index 0e0715e..8990d35 100644 --- a/src/headers/exceptions.h +++ b/src/headers/exceptions.h @@ -3,4 +3,37 @@ extern void setupExceptions(); +extern void isrHandler0(); +extern void isrHandler1(); +extern void isrHandler2(); +extern void isrHandler3(); +extern void isrHandler4(); +extern void isrHandler5(); +extern void isrHandler6(); +extern void isrHandler7(); +extern void isrHandler8(); +extern void isrHandler9(); +extern void isrHandler10(); +extern void isrHandler11(); +extern void isrHandler12(); +extern void isrHandler13(); +extern void isrHandler14(); +extern void isrHandler15(); +extern void isrHandler16(); +extern void isrHandler17(); +extern void isrHandler18(); +extern void isrHandler19(); +extern void isrHandler20(); +extern void isrHandler21(); +extern void isrHandler22(); +extern void isrHandler23(); +extern void isrHandler24(); +extern void isrHandler25(); +extern void isrHandler26(); +extern void isrHandler27(); +extern void isrHandler28(); +extern void isrHandler29(); +extern void isrHandler30(); +extern void isrHandler31(); + #endif \ No newline at end of file diff --git a/src/headers/interrupts.h b/src/headers/interrupts.h index 1d8a597..f8ed10a 100644 --- a/src/headers/interrupts.h +++ b/src/headers/interrupts.h @@ -16,6 +16,13 @@ uint32_t base; } __attribute__((packed)) IDTR; +typedef struct { + unsigned int gs, fs, es, ds; + unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; + unsigned int int_no, err_code; + unsigned int eip, cs, eflags, useresp, ss; +} __attribute__((packed)) regs; + extern void initInterrupts(); extern void setInterrupt(uint8_t vector, void* callback); diff --git a/src/headers/irqs.h b/src/headers/irqs.h new file mode 100644 index 0000000..c3cde17 --- /dev/null +++ b/src/headers/irqs.h @@ -0,0 +1,27 @@ +#ifndef IRQS_H +#define IRQS_H + +#include + +extern void initIRQs(); + +extern void setIRQHandler(uint8_t irqNumber, void* fun); + +extern void irqHandler0(); +extern void irqHandler1(); +extern void irqHandler2(); +extern void irqHandler3(); +extern void irqHandler4(); +extern void irqHandler5(); +extern void irqHandler6(); +extern void irqHandler7(); +extern void irqHandler8(); +extern void irqHandler9(); +extern void irqHandler10(); +extern void irqHandler11(); +extern void irqHandler12(); +extern void irqHandler13(); +extern void irqHandler14(); +extern void irqHandler15(); + +#endif \ No newline at end of file diff --git a/src/interrupts/exceptions.asm b/src/interrupts/exceptions.asm new file mode 100644 index 0000000..9fd4f04 --- /dev/null +++ b/src/interrupts/exceptions.asm @@ -0,0 +1,74 @@ +%macro isr 1 + global isrHandler%1 + isrHandler%1: + push byte 0 + push byte %1 + jmp exceptionHandler +%endmacro + +%macro isr_error 1 + global isrHandler%1 + isrHandler%1: + push byte %1 + jmp exceptionHandler +%endmacro + +isrs: + isr 0 + isr 1 + isr 2 + isr 3 + isr 4 + isr 5 + isr 6 + isr 7 + isr_error 8 + isr 9 + isr_error 10 + isr_error 11 + isr_error 12 + isr_error 13 + isr_error 14 + isr 15 + isr 16 + isr_error 17 + isr 18 + isr 19 + isr 20 + isr 21 + isr 22 + isr 23 + isr 24 + isr 25 + isr 26 + isr 27 + isr 28 + isr 29 + isr_error 30 + isr 31 + +extern handleException + +exceptionHandler: + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp + push eax + mov eax, handleException + call eax + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 + iret \ No newline at end of file diff --git a/src/interrupts/exceptions.c b/src/interrupts/exceptions.c index 19d8819..8d82af9 100644 --- a/src/interrupts/exceptions.c +++ b/src/interrupts/exceptions.c @@ -3,51 +3,77 @@ #include #include <_stdio.h> -#define exception(exceptionNR, name) void exception##exceptionNR##Handler () {printf("exception "#name" happend!"); yields();} -#define setExceptionHandler(exceptionNR) setInterrupt(exceptionNR, &exception##exceptionNR##Handler); - -exception(0, DIVIDE_BY_ZERO); -exception(1, DEBUG); -exception(2, NON_MASKABLE_INTERRUPT); -exception(3, BREAKPOINT); -exception(4, OVERFLOW); -exception(5, BOUND_RANGE_EXCEEDED); -exception(6, INVALID_OPCODE); -exception(7, DEVIVE_NOT_AVAILABLE); -exception(8, DOUBLE_FAULT); -exception(10, INVALID_TSS); -exception(11, SEGMENT_NOT_PRESENT); -exception(12, STACK_SEGMENT_FAULT); -exception(13, GENERAL_PROTECTION_FAULT); -exception(14, PAGE_FAULT); -exception(16, X87_FLOATING_POINT_EXCEPTION); -exception(17, ALIGNMENT_CHECK); -exception(18, MACHINE_CHECK); -exception(19, SMID_FLOATING_POINT_EXCEPTION); -exception(20, VIRTUALIZATION_EXCEPTION); -exception(30, SECURITy_EXCEPTION); - +char* EXCEPTION_MESSAGES[] = { + "DIVIDE BY ZERO", + "DEBUG", + "NON-MASKABLE INTERRUPT", + "BREAKPOINT", + "OVERFLOW", + "BOUND RAGE EXCEEDED", + "INVALID OPCODE", + "DEVICE NOT AVAILABLE", + "DOUBLE FAULT", + "COPROCESSOR SEGMENT OVERRUN", + "INVALID TSS", + "SEGMENT NOT PRESENT", + "STACK SEGMENT FAULT", + "GENERAL PROTECTION FAULT", + "PAGE FAULT", + "RESERVED", + "x87 FLOATING-POINT-EXCEPTION", + "ALIGNMENT CHECK", + "MACHINE CHECK", + "SMID FLOATING-POINT-EXCEPTION", + "VIRTUALIZATION EXCEPTION", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "SECURITY EXCEPTION", + "RESERVED" +}; void setupExceptions() { printf("setting exceptions\n"); - setExceptionHandler(0); - setExceptionHandler(1); - setExceptionHandler(2); - setExceptionHandler(3); - setExceptionHandler(4); - setExceptionHandler(5); - setExceptionHandler(6); - setExceptionHandler(7); - setExceptionHandler(8); - setExceptionHandler(10); - setExceptionHandler(11); - setExceptionHandler(12); - setExceptionHandler(13); - setExceptionHandler(14); - setExceptionHandler(16); - setExceptionHandler(17); - setExceptionHandler(18); - setExceptionHandler(19); - setExceptionHandler(20); - setExceptionHandler(30); + setInterrupt(0, &isrHandler0); + setInterrupt(1, &isrHandler1); + setInterrupt(2, &isrHandler2); + setInterrupt(3, &isrHandler3); + setInterrupt(4, &isrHandler4); + setInterrupt(5, &isrHandler5); + setInterrupt(6, &isrHandler6); + setInterrupt(7, &isrHandler7); + setInterrupt(8, &isrHandler8); + setInterrupt(9, &isrHandler9); + setInterrupt(10, &isrHandler10); + setInterrupt(11, &isrHandler11); + setInterrupt(12, &isrHandler12); + setInterrupt(13, &isrHandler13); + setInterrupt(14, &isrHandler14); + setInterrupt(15, &isrHandler15); + setInterrupt(16, &isrHandler16); + setInterrupt(17, &isrHandler17); + setInterrupt(18, &isrHandler18); + setInterrupt(19, &isrHandler19); + setInterrupt(20, &isrHandler20); + setInterrupt(21, &isrHandler21); + setInterrupt(22, &isrHandler22); + setInterrupt(23, &isrHandler23); + setInterrupt(24, &isrHandler24); + setInterrupt(25, &isrHandler25); + setInterrupt(26, &isrHandler26); + setInterrupt(27, &isrHandler27); + setInterrupt(28, &isrHandler28); + setInterrupt(29, &isrHandler29); + setInterrupt(30, &isrHandler30); + setInterrupt(31, &isrHandler31); +} + +void handleException(regs* registers) { + printf("exception %s was raised with error code 0x%x!\n", EXCEPTION_MESSAGES[registers->int_no], registers->err_code); + yields(); } \ No newline at end of file diff --git a/src/interrupts/interrupts.c b/src/interrupts/interrupts.c index 0c9e2b1..908e4ef 100644 --- a/src/interrupts/interrupts.c +++ b/src/interrupts/interrupts.c @@ -17,47 +17,16 @@ descriptor->attributes = 0x8E; descriptor->isr_high = (uint32_t)callback >> 16; descriptor->reserved = 0; - __asm__ volatile ("lidt %0" : : "memory"(idtr)); } -uint32_t count = 0x01; - -void testInterrupt() { - printf("interrupt 0x%x!\n", count++); - yields(); -} - -#define PIC1 0x20 -#define PIC2 0xA0 -#define PIC1_COMMAND PIC1 -#define PIC1_DATA (PIC1+1) -#define PIC2_COMMAND PIC2 -#define PIC2_DATA (PIC2+1) - -void remapPIC(int offset1, int offset2) { - printf("remapping pic\n"); - outb(0x20, 0x11); - outb(0xA0, 0x11); - outb(0x21, 0x20); - outb(0xA1, offset1); - outb(0x21, offset2); - outb(0xA1, 0x02); - outb(0x21, 0x01); - outb(0xA1, 0x01); - outb(0x21, 0x0); - outb(0xA1, 0x0); -} void initInterrupts() { - remapPIC(32, 40); - buffer = malloc(sizeof(IDTEntry) * 256); - entries = (IDTEntry*) (((int) buffer + sizeof(IDTEntry)) & -1 ^ 0x0F); + buffer = malloc(sizeof(IDTEntry) * 257); + entries = (IDTEntry*) (((int) buffer + sizeof(IDTEntry) >> 3) << 3); idtr.limit = sizeof(IDTEntry) * 256 - 1; idtr.base = (uint32_t) entries; - for (int i = 0; i < 256; i++) { - setInterrupt(i, &testInterrupt); - } setupExceptions(); - // setupTimer(); + setupIRQs(); + __asm__ volatile ("lidt %0" : : "memory"(idtr)); __asm__ volatile ("sti"); } \ No newline at end of file diff --git a/src/interrupts/irqs.asm b/src/interrupts/irqs.asm new file mode 100644 index 0000000..3e6670b --- /dev/null +++ b/src/interrupts/irqs.asm @@ -0,0 +1,52 @@ +%macro irq 1 + global irqHandler%1 + irqHandler%1: + cli + push byte 0 + push byte %1+32 + jmp irqHandler +%endmacro + +irqs: + irq 0 + irq 1 + irq 2 + irq 3 + irq 4 + irq 5 + irq 6 + irq 7 + irq 8 + irq 9 + irq 10 + irq 11 + irq 12 + irq 13 + irq 14 + irq 15 + +extern handleIRQ + +irqHandler: + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp + push eax + mov eax, handleIRQ + call eax + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 + iret \ No newline at end of file diff --git a/src/interrupts/irqs.c b/src/interrupts/irqs.c new file mode 100644 index 0000000..65826ac --- /dev/null +++ b/src/interrupts/irqs.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#include <_stdio.h> + +#define OFFSET_1 32 +#define OFFSET_2 40 + +void remapPIC(int offset1, int offset2) { + printf("remapping pic\n"); + outb(0x20, 0x11); + outb(0xA0, 0x11); + outb(0x21, 0x20); + outb(0xA1, offset1); + outb(0x21, offset2); + outb(0xA1, 0x02); + outb(0x21, 0x01); + outb(0xA1, 0x01); + outb(0x21, 0x0); + outb(0xA1, 0x0); +} + +void setupIRQs() { + printf("setting IRQs\n"); + setInterrupt(OFFSET_1 + 0, &irqHandler0); + setInterrupt(OFFSET_1 + 1, &irqHandler1); + setInterrupt(OFFSET_1 + 2, &irqHandler2); + setInterrupt(OFFSET_1 + 3, &irqHandler3); + setInterrupt(OFFSET_1 + 4, &irqHandler4); + setInterrupt(OFFSET_1 + 5, &irqHandler5); + setInterrupt(OFFSET_1 + 6, &irqHandler6); + setInterrupt(OFFSET_1 + 7, &irqHandler7); + setInterrupt(OFFSET_2 + 0, &irqHandler8); + setInterrupt(OFFSET_2 + 1, &irqHandler9); + setInterrupt(OFFSET_2 + 2, &irqHandler10); + setInterrupt(OFFSET_2 + 3, &irqHandler11); + setInterrupt(OFFSET_2 + 4, &irqHandler12); + setInterrupt(OFFSET_2 + 5, &irqHandler13); + setInterrupt(OFFSET_2 + 6, &irqHandler14); + setInterrupt(OFFSET_2 + 7, &irqHandler15); + remapPIC(OFFSET_1, OFFSET_2); +} + +void* irqHandlers[16]; + +void setIRQHandler(uint8_t irqNumber, void* fun) { + irqHandlers[irqNumber] = fun; +} + +void handleIRQ(regs* registers) { + if (registers->int_no >= OFFSET_2) { + outb(0xA0, 0x20); + } + outb(0x20, 0x20); + void (*handler)() = irqHandlers[registers->int_no - OFFSET_1]; + if (handler) { + handler(); + return; + } + printf("unhandeled IRQ no. 0x%x was triggered!\n", registers->int_no); + yields(); +} \ No newline at end of file diff --git a/src/interrupts/timer/timer.c b/src/interrupts/timer/timer.c new file mode 100644 index 0000000..440118a --- /dev/null +++ b/src/interrupts/timer/timer.c @@ -0,0 +1,49 @@ +#include +#include <_stdio.h> +#include +#include +#include +#include + + +#define PIT_A 0x40 +#define PIT_CONTROL 0x43 + +#define PIT_MASK 0xFF +#define PIT_SCALE 1193180 +#define PIT_SET 0x36 + +#define CMD_BINARY 0x00 + +#define CMD_MODE0 0x00 +#define CMD_MODE1 0x02 +#define CMD_MODE2 0x04 +#define CMD_MODE3 0x06 +#define CMD_MODE4 0x08 +#define CMD_MODE5 0x0a + +#define CMD_RW_BOTH 0x30 + +#define CMD_COUNTER0 0x00 +#define CMD_COUNTER2 0x80 + +void setTimerFreq(uint32_t hz) { + int divisor = PIT_SCALE / hz; + outb(PIT_CONTROL, 0x36);// CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); + outb(PIT_A, (uint8_t) divisor); + outb(PIT_A, (uint8_t) (divisor >> 8)); +} + +uint32_t timer_ticks = 0; + +void timerHandler() { + printf("timer 0x%x\n", timer_ticks); + timer_ticks++; + yields(); +} + +void setupTimer() { + printf("setting timer frequency to 100Hz\n"); + setTimerFreq(20); + setIRQHandler(0, &timerHandler); +} diff --git a/src/kernel/drivers/timer/timer.c b/src/kernel/drivers/timer/timer.c deleted file mode 100644 index c386a7d..0000000 --- a/src/kernel/drivers/timer/timer.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include <_stdio.h> -#include -#include -#include - - -#define PIT_A 0x40 -#define PIT_CONTROL 0x43 - -#define PIT_MASK 0xFF -#define PIT_SCALE 1193180 -#define PIT_SET 0x36 - -#define CMD_BINARY 0x00 - -#define CMD_MODE0 0x00 -#define CMD_MODE1 0x02 -#define CMD_MODE2 0x04 -#define CMD_MODE3 0x06 -#define CMD_MODE4 0x08 -#define CMD_MODE5 0x0a - -#define CMD_RW_BOTH 0x30 - -#define CMD_COUNTER0 0x00 -#define CMD_COUNTER2 0x80 - -void setTimerFreq(uint32_t hz) { - int divisor = PIT_SCALE / hz; - outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); - outb(PIT_A, (uint8_t) divisor); - outb(PIT_A, (uint8_t) (divisor >> 8)); -} - -uint64_t timer_ticks = 0; -uint8_t timer_subticks = 0; - -void timerHandler() { - printf("timer\n"); - yields(); - outb(0x20, 0x20); - __asm__ volatile ("iret"); -} - -void setupTimer() { - printf("setting timer frequency to 100Hz\n"); - setTimerFreq(100); - setInterrupt(32, &timerHandler); -} - diff --git a/.vscode/settings.json b/.vscode/settings.json index 36c0cfc..e94ea84 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,10 @@ { "files.associations": { "*.h": "c", - "type_traits": "c" + "type_traits": "c", + "array": "c", + "string_view": "c", + "initializer_list": "c", + "utility": "c" } } \ No newline at end of file diff --git a/src/headers/exceptions.h b/src/headers/exceptions.h index 0e0715e..8990d35 100644 --- a/src/headers/exceptions.h +++ b/src/headers/exceptions.h @@ -3,4 +3,37 @@ extern void setupExceptions(); +extern void isrHandler0(); +extern void isrHandler1(); +extern void isrHandler2(); +extern void isrHandler3(); +extern void isrHandler4(); +extern void isrHandler5(); +extern void isrHandler6(); +extern void isrHandler7(); +extern void isrHandler8(); +extern void isrHandler9(); +extern void isrHandler10(); +extern void isrHandler11(); +extern void isrHandler12(); +extern void isrHandler13(); +extern void isrHandler14(); +extern void isrHandler15(); +extern void isrHandler16(); +extern void isrHandler17(); +extern void isrHandler18(); +extern void isrHandler19(); +extern void isrHandler20(); +extern void isrHandler21(); +extern void isrHandler22(); +extern void isrHandler23(); +extern void isrHandler24(); +extern void isrHandler25(); +extern void isrHandler26(); +extern void isrHandler27(); +extern void isrHandler28(); +extern void isrHandler29(); +extern void isrHandler30(); +extern void isrHandler31(); + #endif \ No newline at end of file diff --git a/src/headers/interrupts.h b/src/headers/interrupts.h index 1d8a597..f8ed10a 100644 --- a/src/headers/interrupts.h +++ b/src/headers/interrupts.h @@ -16,6 +16,13 @@ uint32_t base; } __attribute__((packed)) IDTR; +typedef struct { + unsigned int gs, fs, es, ds; + unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; + unsigned int int_no, err_code; + unsigned int eip, cs, eflags, useresp, ss; +} __attribute__((packed)) regs; + extern void initInterrupts(); extern void setInterrupt(uint8_t vector, void* callback); diff --git a/src/headers/irqs.h b/src/headers/irqs.h new file mode 100644 index 0000000..c3cde17 --- /dev/null +++ b/src/headers/irqs.h @@ -0,0 +1,27 @@ +#ifndef IRQS_H +#define IRQS_H + +#include + +extern void initIRQs(); + +extern void setIRQHandler(uint8_t irqNumber, void* fun); + +extern void irqHandler0(); +extern void irqHandler1(); +extern void irqHandler2(); +extern void irqHandler3(); +extern void irqHandler4(); +extern void irqHandler5(); +extern void irqHandler6(); +extern void irqHandler7(); +extern void irqHandler8(); +extern void irqHandler9(); +extern void irqHandler10(); +extern void irqHandler11(); +extern void irqHandler12(); +extern void irqHandler13(); +extern void irqHandler14(); +extern void irqHandler15(); + +#endif \ No newline at end of file diff --git a/src/interrupts/exceptions.asm b/src/interrupts/exceptions.asm new file mode 100644 index 0000000..9fd4f04 --- /dev/null +++ b/src/interrupts/exceptions.asm @@ -0,0 +1,74 @@ +%macro isr 1 + global isrHandler%1 + isrHandler%1: + push byte 0 + push byte %1 + jmp exceptionHandler +%endmacro + +%macro isr_error 1 + global isrHandler%1 + isrHandler%1: + push byte %1 + jmp exceptionHandler +%endmacro + +isrs: + isr 0 + isr 1 + isr 2 + isr 3 + isr 4 + isr 5 + isr 6 + isr 7 + isr_error 8 + isr 9 + isr_error 10 + isr_error 11 + isr_error 12 + isr_error 13 + isr_error 14 + isr 15 + isr 16 + isr_error 17 + isr 18 + isr 19 + isr 20 + isr 21 + isr 22 + isr 23 + isr 24 + isr 25 + isr 26 + isr 27 + isr 28 + isr 29 + isr_error 30 + isr 31 + +extern handleException + +exceptionHandler: + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp + push eax + mov eax, handleException + call eax + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 + iret \ No newline at end of file diff --git a/src/interrupts/exceptions.c b/src/interrupts/exceptions.c index 19d8819..8d82af9 100644 --- a/src/interrupts/exceptions.c +++ b/src/interrupts/exceptions.c @@ -3,51 +3,77 @@ #include #include <_stdio.h> -#define exception(exceptionNR, name) void exception##exceptionNR##Handler () {printf("exception "#name" happend!"); yields();} -#define setExceptionHandler(exceptionNR) setInterrupt(exceptionNR, &exception##exceptionNR##Handler); - -exception(0, DIVIDE_BY_ZERO); -exception(1, DEBUG); -exception(2, NON_MASKABLE_INTERRUPT); -exception(3, BREAKPOINT); -exception(4, OVERFLOW); -exception(5, BOUND_RANGE_EXCEEDED); -exception(6, INVALID_OPCODE); -exception(7, DEVIVE_NOT_AVAILABLE); -exception(8, DOUBLE_FAULT); -exception(10, INVALID_TSS); -exception(11, SEGMENT_NOT_PRESENT); -exception(12, STACK_SEGMENT_FAULT); -exception(13, GENERAL_PROTECTION_FAULT); -exception(14, PAGE_FAULT); -exception(16, X87_FLOATING_POINT_EXCEPTION); -exception(17, ALIGNMENT_CHECK); -exception(18, MACHINE_CHECK); -exception(19, SMID_FLOATING_POINT_EXCEPTION); -exception(20, VIRTUALIZATION_EXCEPTION); -exception(30, SECURITy_EXCEPTION); - +char* EXCEPTION_MESSAGES[] = { + "DIVIDE BY ZERO", + "DEBUG", + "NON-MASKABLE INTERRUPT", + "BREAKPOINT", + "OVERFLOW", + "BOUND RAGE EXCEEDED", + "INVALID OPCODE", + "DEVICE NOT AVAILABLE", + "DOUBLE FAULT", + "COPROCESSOR SEGMENT OVERRUN", + "INVALID TSS", + "SEGMENT NOT PRESENT", + "STACK SEGMENT FAULT", + "GENERAL PROTECTION FAULT", + "PAGE FAULT", + "RESERVED", + "x87 FLOATING-POINT-EXCEPTION", + "ALIGNMENT CHECK", + "MACHINE CHECK", + "SMID FLOATING-POINT-EXCEPTION", + "VIRTUALIZATION EXCEPTION", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "SECURITY EXCEPTION", + "RESERVED" +}; void setupExceptions() { printf("setting exceptions\n"); - setExceptionHandler(0); - setExceptionHandler(1); - setExceptionHandler(2); - setExceptionHandler(3); - setExceptionHandler(4); - setExceptionHandler(5); - setExceptionHandler(6); - setExceptionHandler(7); - setExceptionHandler(8); - setExceptionHandler(10); - setExceptionHandler(11); - setExceptionHandler(12); - setExceptionHandler(13); - setExceptionHandler(14); - setExceptionHandler(16); - setExceptionHandler(17); - setExceptionHandler(18); - setExceptionHandler(19); - setExceptionHandler(20); - setExceptionHandler(30); + setInterrupt(0, &isrHandler0); + setInterrupt(1, &isrHandler1); + setInterrupt(2, &isrHandler2); + setInterrupt(3, &isrHandler3); + setInterrupt(4, &isrHandler4); + setInterrupt(5, &isrHandler5); + setInterrupt(6, &isrHandler6); + setInterrupt(7, &isrHandler7); + setInterrupt(8, &isrHandler8); + setInterrupt(9, &isrHandler9); + setInterrupt(10, &isrHandler10); + setInterrupt(11, &isrHandler11); + setInterrupt(12, &isrHandler12); + setInterrupt(13, &isrHandler13); + setInterrupt(14, &isrHandler14); + setInterrupt(15, &isrHandler15); + setInterrupt(16, &isrHandler16); + setInterrupt(17, &isrHandler17); + setInterrupt(18, &isrHandler18); + setInterrupt(19, &isrHandler19); + setInterrupt(20, &isrHandler20); + setInterrupt(21, &isrHandler21); + setInterrupt(22, &isrHandler22); + setInterrupt(23, &isrHandler23); + setInterrupt(24, &isrHandler24); + setInterrupt(25, &isrHandler25); + setInterrupt(26, &isrHandler26); + setInterrupt(27, &isrHandler27); + setInterrupt(28, &isrHandler28); + setInterrupt(29, &isrHandler29); + setInterrupt(30, &isrHandler30); + setInterrupt(31, &isrHandler31); +} + +void handleException(regs* registers) { + printf("exception %s was raised with error code 0x%x!\n", EXCEPTION_MESSAGES[registers->int_no], registers->err_code); + yields(); } \ No newline at end of file diff --git a/src/interrupts/interrupts.c b/src/interrupts/interrupts.c index 0c9e2b1..908e4ef 100644 --- a/src/interrupts/interrupts.c +++ b/src/interrupts/interrupts.c @@ -17,47 +17,16 @@ descriptor->attributes = 0x8E; descriptor->isr_high = (uint32_t)callback >> 16; descriptor->reserved = 0; - __asm__ volatile ("lidt %0" : : "memory"(idtr)); } -uint32_t count = 0x01; - -void testInterrupt() { - printf("interrupt 0x%x!\n", count++); - yields(); -} - -#define PIC1 0x20 -#define PIC2 0xA0 -#define PIC1_COMMAND PIC1 -#define PIC1_DATA (PIC1+1) -#define PIC2_COMMAND PIC2 -#define PIC2_DATA (PIC2+1) - -void remapPIC(int offset1, int offset2) { - printf("remapping pic\n"); - outb(0x20, 0x11); - outb(0xA0, 0x11); - outb(0x21, 0x20); - outb(0xA1, offset1); - outb(0x21, offset2); - outb(0xA1, 0x02); - outb(0x21, 0x01); - outb(0xA1, 0x01); - outb(0x21, 0x0); - outb(0xA1, 0x0); -} void initInterrupts() { - remapPIC(32, 40); - buffer = malloc(sizeof(IDTEntry) * 256); - entries = (IDTEntry*) (((int) buffer + sizeof(IDTEntry)) & -1 ^ 0x0F); + buffer = malloc(sizeof(IDTEntry) * 257); + entries = (IDTEntry*) (((int) buffer + sizeof(IDTEntry) >> 3) << 3); idtr.limit = sizeof(IDTEntry) * 256 - 1; idtr.base = (uint32_t) entries; - for (int i = 0; i < 256; i++) { - setInterrupt(i, &testInterrupt); - } setupExceptions(); - // setupTimer(); + setupIRQs(); + __asm__ volatile ("lidt %0" : : "memory"(idtr)); __asm__ volatile ("sti"); } \ No newline at end of file diff --git a/src/interrupts/irqs.asm b/src/interrupts/irqs.asm new file mode 100644 index 0000000..3e6670b --- /dev/null +++ b/src/interrupts/irqs.asm @@ -0,0 +1,52 @@ +%macro irq 1 + global irqHandler%1 + irqHandler%1: + cli + push byte 0 + push byte %1+32 + jmp irqHandler +%endmacro + +irqs: + irq 0 + irq 1 + irq 2 + irq 3 + irq 4 + irq 5 + irq 6 + irq 7 + irq 8 + irq 9 + irq 10 + irq 11 + irq 12 + irq 13 + irq 14 + irq 15 + +extern handleIRQ + +irqHandler: + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp + push eax + mov eax, handleIRQ + call eax + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 + iret \ No newline at end of file diff --git a/src/interrupts/irqs.c b/src/interrupts/irqs.c new file mode 100644 index 0000000..65826ac --- /dev/null +++ b/src/interrupts/irqs.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#include <_stdio.h> + +#define OFFSET_1 32 +#define OFFSET_2 40 + +void remapPIC(int offset1, int offset2) { + printf("remapping pic\n"); + outb(0x20, 0x11); + outb(0xA0, 0x11); + outb(0x21, 0x20); + outb(0xA1, offset1); + outb(0x21, offset2); + outb(0xA1, 0x02); + outb(0x21, 0x01); + outb(0xA1, 0x01); + outb(0x21, 0x0); + outb(0xA1, 0x0); +} + +void setupIRQs() { + printf("setting IRQs\n"); + setInterrupt(OFFSET_1 + 0, &irqHandler0); + setInterrupt(OFFSET_1 + 1, &irqHandler1); + setInterrupt(OFFSET_1 + 2, &irqHandler2); + setInterrupt(OFFSET_1 + 3, &irqHandler3); + setInterrupt(OFFSET_1 + 4, &irqHandler4); + setInterrupt(OFFSET_1 + 5, &irqHandler5); + setInterrupt(OFFSET_1 + 6, &irqHandler6); + setInterrupt(OFFSET_1 + 7, &irqHandler7); + setInterrupt(OFFSET_2 + 0, &irqHandler8); + setInterrupt(OFFSET_2 + 1, &irqHandler9); + setInterrupt(OFFSET_2 + 2, &irqHandler10); + setInterrupt(OFFSET_2 + 3, &irqHandler11); + setInterrupt(OFFSET_2 + 4, &irqHandler12); + setInterrupt(OFFSET_2 + 5, &irqHandler13); + setInterrupt(OFFSET_2 + 6, &irqHandler14); + setInterrupt(OFFSET_2 + 7, &irqHandler15); + remapPIC(OFFSET_1, OFFSET_2); +} + +void* irqHandlers[16]; + +void setIRQHandler(uint8_t irqNumber, void* fun) { + irqHandlers[irqNumber] = fun; +} + +void handleIRQ(regs* registers) { + if (registers->int_no >= OFFSET_2) { + outb(0xA0, 0x20); + } + outb(0x20, 0x20); + void (*handler)() = irqHandlers[registers->int_no - OFFSET_1]; + if (handler) { + handler(); + return; + } + printf("unhandeled IRQ no. 0x%x was triggered!\n", registers->int_no); + yields(); +} \ No newline at end of file diff --git a/src/interrupts/timer/timer.c b/src/interrupts/timer/timer.c new file mode 100644 index 0000000..440118a --- /dev/null +++ b/src/interrupts/timer/timer.c @@ -0,0 +1,49 @@ +#include +#include <_stdio.h> +#include +#include +#include +#include + + +#define PIT_A 0x40 +#define PIT_CONTROL 0x43 + +#define PIT_MASK 0xFF +#define PIT_SCALE 1193180 +#define PIT_SET 0x36 + +#define CMD_BINARY 0x00 + +#define CMD_MODE0 0x00 +#define CMD_MODE1 0x02 +#define CMD_MODE2 0x04 +#define CMD_MODE3 0x06 +#define CMD_MODE4 0x08 +#define CMD_MODE5 0x0a + +#define CMD_RW_BOTH 0x30 + +#define CMD_COUNTER0 0x00 +#define CMD_COUNTER2 0x80 + +void setTimerFreq(uint32_t hz) { + int divisor = PIT_SCALE / hz; + outb(PIT_CONTROL, 0x36);// CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); + outb(PIT_A, (uint8_t) divisor); + outb(PIT_A, (uint8_t) (divisor >> 8)); +} + +uint32_t timer_ticks = 0; + +void timerHandler() { + printf("timer 0x%x\n", timer_ticks); + timer_ticks++; + yields(); +} + +void setupTimer() { + printf("setting timer frequency to 100Hz\n"); + setTimerFreq(20); + setIRQHandler(0, &timerHandler); +} diff --git a/src/kernel/drivers/timer/timer.c b/src/kernel/drivers/timer/timer.c deleted file mode 100644 index c386a7d..0000000 --- a/src/kernel/drivers/timer/timer.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include <_stdio.h> -#include -#include -#include - - -#define PIT_A 0x40 -#define PIT_CONTROL 0x43 - -#define PIT_MASK 0xFF -#define PIT_SCALE 1193180 -#define PIT_SET 0x36 - -#define CMD_BINARY 0x00 - -#define CMD_MODE0 0x00 -#define CMD_MODE1 0x02 -#define CMD_MODE2 0x04 -#define CMD_MODE3 0x06 -#define CMD_MODE4 0x08 -#define CMD_MODE5 0x0a - -#define CMD_RW_BOTH 0x30 - -#define CMD_COUNTER0 0x00 -#define CMD_COUNTER2 0x80 - -void setTimerFreq(uint32_t hz) { - int divisor = PIT_SCALE / hz; - outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); - outb(PIT_A, (uint8_t) divisor); - outb(PIT_A, (uint8_t) (divisor >> 8)); -} - -uint64_t timer_ticks = 0; -uint8_t timer_subticks = 0; - -void timerHandler() { - printf("timer\n"); - yields(); - outb(0x20, 0x20); - __asm__ volatile ("iret"); -} - -void setupTimer() { - printf("setting timer frequency to 100Hz\n"); - setTimerFreq(100); - setInterrupt(32, &timerHandler); -} - diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index e52b7f9..75f4624 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -6,6 +6,7 @@ #include #include #include +#include extern uint32_t _kernel_end; @@ -15,7 +16,8 @@ drawLogo(); printf("initializing interrupts\n"); initInterrupts(); - 1/0; yields(); + setupTimer(); while(1); + yield(); } \ No newline at end of file