Compare commits
2 commits
623b9e339f
...
fbef354410
| Author | SHA1 | Date | |
|---|---|---|---|
| fbef354410 | |||
| 8c51b7010e |
7 changed files with 104 additions and 15 deletions
|
|
@ -17,6 +17,7 @@ typedef struct IDTR_s {
|
||||||
|
|
||||||
extern IDTR_t idtr;
|
extern IDTR_t idtr;
|
||||||
extern InterruptDescriptor_t* idt_start;
|
extern InterruptDescriptor_t* idt_start;
|
||||||
|
extern char num_interrupts;
|
||||||
|
|
||||||
void setup_idt();
|
void setup_idt();
|
||||||
void write_descriptors();
|
void write_descriptors();
|
||||||
|
|
|
||||||
14
include/interrupt_handlers.h
Normal file
14
include/interrupt_handlers.h
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef INTERRUPTHANDLERS_H
|
||||||
|
#define INTERRUPTHANDLERS_H
|
||||||
|
#include <stdint.h>
|
||||||
|
extern void* isr_ptrs;
|
||||||
|
|
||||||
|
typedef struct StateSnapshot_s {
|
||||||
|
uint32_t eax, ecx, edx, ebx, esp, esi, edi;
|
||||||
|
uint32_t interrupt_id, error_code;
|
||||||
|
uint32_t eip, cs, eflags;
|
||||||
|
} StateSnapshot_t;
|
||||||
|
|
||||||
|
void generic_isr_handler(StateSnapshot_t* cpu_state);
|
||||||
|
|
||||||
|
#endif
|
||||||
15
src/allocidt.s
Normal file
15
src/allocidt.s
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
%define NUM_INTERRUPTS 32
|
||||||
|
global idtr, idt_start, num_interrupts
|
||||||
|
section .idtr
|
||||||
|
num_interrupts:
|
||||||
|
db NUM_INTERRUPTS
|
||||||
|
idtr:
|
||||||
|
;Normally, the size would be the size of the whole table, but i'm only defining 32 interrupts for now.
|
||||||
|
;dw idt_end - idt_start
|
||||||
|
dw NUM_INTERRUPTS * 8
|
||||||
|
dd idt_start
|
||||||
|
section .idt nobits
|
||||||
|
idt_start:
|
||||||
|
resb NUM_INTERRUPTS * 8
|
||||||
|
idt_end:
|
||||||
|
|
||||||
18
src/idt.c
Normal file
18
src/idt.c
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
#include "idt.h"
|
||||||
|
|
||||||
|
|
||||||
|
void setup_idt() {
|
||||||
|
write_descriptors();
|
||||||
|
load_idt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_descriptors() {
|
||||||
|
|
||||||
|
for(int i = 0; i < num_interrupts; i++) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_idt() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
11
src/idt.s
11
src/idt.s
|
|
@ -1,11 +0,0 @@
|
||||||
global idtr, idt_start
|
|
||||||
section .idtr
|
|
||||||
idtr:
|
|
||||||
dw idt_end - idt_start
|
|
||||||
dd idt_start
|
|
||||||
|
|
||||||
section .idt nobits
|
|
||||||
idt_start:
|
|
||||||
resb 256 * 8 ;idt technically has 256 entries by the spec, so i'm reserving that much space... even if i dont implement that many.
|
|
||||||
idt_end:
|
|
||||||
|
|
||||||
13
src/interrupt_handlers.c
Normal file
13
src/interrupt_handlers.c
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include "interrupt_handlers.h"
|
||||||
|
#include "kio.h"
|
||||||
|
|
||||||
|
void generic_isr_handler(StateSnapshot_t* cpu_state) {
|
||||||
|
//We made it to C for our interrupt! For now, let's just print our interrupt to the screen.
|
||||||
|
vga_clear();
|
||||||
|
vga_printf("INTERRUPT TRIGGERED! Info below.\n");
|
||||||
|
vga_printf("Int_ID|ERR: %X|%X\n", cpu_state->interrupt_id, cpu_state->error_code);
|
||||||
|
vga_printf("EFLAGS|CS|EIP: %X|%X|%X\n", cpu_state->eflags, cpu_state->cs,cpu_state->eip);
|
||||||
|
vga_printf("GP Registers:\neax:%X\nebx:%X\necx:%X\nedx:%X\nesp:%X\nesi:%X\nedi:%X\n");
|
||||||
|
vga_printf("HALT!");
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
@ -2,11 +2,50 @@
|
||||||
|
|
||||||
;Let's make an interrupt pointer table so C can reference it and build the IDT.
|
;Let's make an interrupt pointer table so C can reference it and build the IDT.
|
||||||
|
|
||||||
|
global isr_ptrs
|
||||||
|
extern generic_isr_handler
|
||||||
|
|
||||||
|
;By the time we get here, we actually have a rather consistent stack:
|
||||||
|
; dword [Interrupt ID]
|
||||||
|
; dword [Error code (0 if int has no error code field)]
|
||||||
|
; dword [EIP]
|
||||||
|
; dword [CS]
|
||||||
|
; dword [EFLAGS]
|
||||||
|
; We can pass this to C. First, we might want to push all of our registers or something.
|
||||||
|
isr_common:
|
||||||
|
pusha
|
||||||
|
push esp ;Throwing a pointer to ESP in there for referencing the aforementioned stuff as a struct
|
||||||
|
call generic_isr_handler
|
||||||
|
add esp,4 ;Remove that esp ref from the stack
|
||||||
|
popad ;restore our gp registers
|
||||||
|
add esp,4 ;deallocate the error code from the stack before heading out
|
||||||
|
iret
|
||||||
|
|
||||||
|
%macro ISR_ENTRY 1
|
||||||
|
isr_%1:
|
||||||
|
cli
|
||||||
|
%if %1 = 8 || %1 = 10 || %1 = 11 || %1 = 12 || %1 = 13 || %1 = 14 || %1 = 17 || %1 = 21
|
||||||
|
%else
|
||||||
|
push dword 0
|
||||||
|
%endif
|
||||||
|
push dword %1 ; saving our interrupt so C knows
|
||||||
|
jmp isr_common
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
|
||||||
isr_table:
|
%assign j 0
|
||||||
|
%rep 32
|
||||||
|
isr_ %+ j:
|
||||||
|
ISR_ENTRY j
|
||||||
|
%assign j j+1
|
||||||
|
%endrep
|
||||||
|
; Generate a table of pointers that point to each of our ISRs. This will be accessed from C to setup our IDT.
|
||||||
|
isr_ptrs:
|
||||||
%assign i 0
|
%assign i 0
|
||||||
%rep 21
|
%rep 32
|
||||||
isr_stub_ %+ i:
|
dd isr_ %+ i
|
||||||
|
%assign i i+1
|
||||||
|
%endrep
|
||||||
|
isr_ptrs_end:
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue