Interrupt Descriptors implemented

Now just need to populate the IDT, then debug the whole thing.
This commit is contained in:
lordtet 2025-06-16 22:40:02 -04:00
parent 623b9e339f
commit 8c51b7010e
5 changed files with 92 additions and 5 deletions

View 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

View file

@ -1,7 +1,9 @@
global idtr, idt_start global idtr, idt_start
section .idtr section .idtr
idtr: idtr:
dw idt_end - idt_start ;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 32
dd idt_start dd idt_start
section .idt nobits section .idt nobits

19
src/idt.c Normal file
View file

@ -0,0 +1,19 @@
#include "idt.h"
void setup_idt() {
write_descriptors();
load_idt();
}
void write_descriptors() {
for(int i = 0; i < idtr.size; i+=(sizeof(InterruptDescriptor_t))) {
}
return;
}
void load_idt() {
return;
}

13
src/interrupt_handlers.c Normal file
View 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);
}

View file

@ -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: