Moving components modules to a more proper directory

This commit is contained in:
2023-03-30 22:40:08 -07:00
parent 044d5a75b5
commit cc1bb63e27
26 changed files with 11 additions and 148 deletions

View File

@@ -0,0 +1,170 @@
; Dispatching to our interrupt handler code from assembly because some of this is
; enourmous pain in C
; Save the register state
; call the C handler
; executes iret(expects the stack to look like struct stack_state)
; If the interrupt we need to handle doesn't produce an error code then must provide a 0
; for consistency
extern interrupt_handler
extern cpu_reg_state
extern stack_state
extern idt_ptr
extern irq_handler
global load_idt
load_idt:
lidt [idt_ptr]
ret
%macro irq 2
global irq_handler_%1
irq_handler_%1:
push dword 0
push dword %2
jmp common_irq_handler
%endmacro
%macro no_err_handler 1
global no_err_handler_%1 ; defined in interrupts.h
no_err_handler_%1:
push dword 0
push dword %1
jmp common_int_handler
%endmacro
; deals with the intterrupts that do give us an error code
%macro err_code_handler 1
global err_code_handler_%1
err_code_handler_%1:
push dword %1
jmp common_int_handler
%endmacro
extern interrupt_handler ; external handler (interrupts.c)
common_int_handler:
; save thigns before do our C-call
pushad
;push eax ecx edx ebx
;push esp ebp esi edi
push ds
push es
push fs
push gs
; load the kernel segment descriptor
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp ; pushing the stack into the next call
push eax
mov eax, interrupt_handler
call eax ; preserve the eip register past this call
; segments
pop eax
pop gs
pop fs
pop es
pop ds
popad
add esp, 8
; special instruction which lets us jump back to code
; which was previously interrupted
iret
no_err_handler 0
no_err_handler 1
no_err_handler 2
no_err_handler 3
no_err_handler 4
no_err_handler 5
no_err_handler 6
no_err_handler 7
err_code_handler 8
no_err_handler 9
err_code_handler 10
err_code_handler 11
err_code_handler 12
err_code_handler 13
err_code_handler 14
no_err_handler 15
no_err_handler 16
no_err_handler 17
no_err_handler 18
no_err_handler 19
no_err_handler 20
no_err_handler 21
no_err_handler 22
no_err_handler 23
no_err_handler 24
no_err_handler 25
no_err_handler 26
no_err_handler 27
no_err_handler 28
no_err_handler 29
no_err_handler 30
no_err_handler 31
common_irq_handler:
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, irq_handler
call eax
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8
iret
; Remapped IRQ's for the APIC
; starting from irq 0 -> 15 but remapped to 32 -> 47
irq 0, 32
irq 1, 33
irq 2, 34
irq 3, 35
irq 4, 36
irq 5, 37
irq 6, 38
irq 7, 39
irq 8, 40
irq 9, 41
irq 10, 42
irq 11, 43
irq 12, 44
irq 13, 45
irq 14, 46
irq 15, 47

View File

@@ -0,0 +1,217 @@
#include "stlio.h"
#include "interrupts.h"
#include "serial.h"
#include "mem.h"
#include "types.h"
#include "ports.h"
#include "pit.h"
#include "kbd.h"
const char* err_msg[] = {
"Divide by zero\n",
"Debug Exception\n",
"Non Maskable Interrupt Exception\n",
"Breakpoint Exception\n",
"Into Detected Overflow Exception\n",
"Out of Bounds Exception\n",
"Invalid Opcode Exception\n",
"No Coprocessor Exception\n",
"Double Fault Exception\n",
"Coprocessor Segment Overrun Exception\n",
"Bad TSS Exception\n",
"Segment Not Present Exception\n",
"Stack Fault Exception\n",
"General Protection Fault Exception\n",
"Page Fault Exception\n",
"Unknown Interrupt Exception\n",
"Coprocessor Fault Exception\n",
"Alignment Check Exception (486+)\n",
"Machine Check Exception (Pentium/586+)\n",
"Reserved Exceptions\n", /* for 19 - 31 */
};
extern void load_idt(); // found in interrupts_entry.s
extern void no_err_handler_0();
extern void no_err_handler_1();
extern void no_err_handler_2();
extern void no_err_handler_3();
extern void no_err_handler_4();
extern void no_err_handler_5();
extern void no_err_handler_6();
extern void no_err_handler_7();
extern void err_code_handler_8();
extern void no_err_handler_9();
extern void err_code_handler_10();
extern void err_code_handler_11();
extern void err_code_handler_12();
extern void err_code_handler_13();
extern void err_code_handler_14();
extern void no_err_handler_15();
extern void no_err_handler_16();
extern void no_err_handler_17();
extern void no_err_handler_18();
extern void no_err_handler_19();
extern void no_err_handler_20();
extern void no_err_handler_21();
extern void no_err_handler_22();
extern void no_err_handler_23();
extern void no_err_handler_24();
extern void no_err_handler_25();
extern void no_err_handler_26();
extern void no_err_handler_27();
extern void no_err_handler_28();
extern void no_err_handler_29();
extern void no_err_handler_30();
extern void no_err_handler_31();
// Remapped IRQ's
extern void irq_handler_0();
extern void irq_handler_1();
extern void irq_handler_2();
extern void irq_handler_3();
extern void irq_handler_4();
extern void irq_handler_5();
extern void irq_handler_6();
extern void irq_handler_7();
extern void irq_handler_8();
extern void irq_handler_9();
extern void irq_handler_10();
extern void irq_handler_11();
extern void irq_handler_12();
extern void irq_handler_13();
extern void irq_handler_14();
extern void irq_handler_15();
void* irq_handlers[16] = {0};
void setup_idt_entry(u32 t_idx, u32 base, u16 sel, u8 type_attrs) {
// Configuring a single given entry in the IDT table
IDT[t_idx].offset_low = (base & 0xffff);
IDT[t_idx].offset_high = ((base >> 16) & 0xffff);
IDT[t_idx].type_attrs = type_attrs;
IDT[t_idx].zero = 0;
IDT[t_idx].selector = sel;
}
// Generic interrupt handler to be used later on
void interrupt_handler(struct cpu_reg_state* cpu) {
// treating things on the stack like it were a cpu_reg_state
// NOTE: dummy stuff to stop gcc from complaining atm
printf("handled exception\n");
if(cpu->int_no < 32) {
printf(err_msg[cpu->int_no]);
}
return;
}
// Pass the index into the table and the handler(strut* cpu_reg_state)
void init_irq_handler(u32 irq, void (*handler)(struct cpu_reg_state* cpu)) {
// install handle
irq_handlers[irq] = handler;
}
void irq_handler(struct cpu_reg_state* cpu) {
void (*handler)(struct cpu_reg_state* cpu);
// Dispatcher for irq's
handler = irq_handlers[cpu->int_no - 0x20];
// Handler the timer by hand because fuck this tbh
if(handler) {
handler(cpu);
}
// pretend like nothing happend for now
if(cpu->int_no >= 40) {
serialport_write_byte(0xa0, 0x20);
}
// notify master pic controller that we're done handling the interrupt
serialport_write_byte(0x20, 0x20);
}
void init_idt() {
// setup special idt pointer
idt_ptr.address = (u32)(&IDT);
idt_ptr.limit = (sizeof(struct IDT_Entry) * IDT_SIZE) - 1;
// clear table
memset((u8*)IDT, 0x00, (sizeof(struct IDT_Entry) * IDT_SIZE));
// add interrupt service routines here
setup_idt_entry(0,(u32)no_err_handler_0,0x08, 0x8e);
setup_idt_entry(1,(u32)no_err_handler_1,0x08, 0x8e);
setup_idt_entry(2,(u32)no_err_handler_2,0x08, 0x8e);
setup_idt_entry(3,(u32)no_err_handler_3,0x08, 0x8e);
setup_idt_entry(4,(u32)no_err_handler_4,0x08, 0x8e);
setup_idt_entry(5,(u32)no_err_handler_5,0x08, 0x8e);
setup_idt_entry(6,(u32)no_err_handler_6,0x08, 0x8e);
setup_idt_entry(7,(u32)no_err_handler_7,0x08, 0x8e);
setup_idt_entry(8,(u32)err_code_handler_8,0x08, 0x8e);
setup_idt_entry(9,(u32)no_err_handler_9,0x08, 0x8e);
setup_idt_entry(10,(u32)err_code_handler_10,0x08, 0x8e);
setup_idt_entry(11,(u32)err_code_handler_11,0x08, 0x8e);
setup_idt_entry(12,(u32)err_code_handler_12,0x08, 0x8e);
setup_idt_entry(13,(u32)err_code_handler_13,0x08, 0x8e);
setup_idt_entry(14,(u32)err_code_handler_14,0x08, 0x8e);
setup_idt_entry(15,(u32)no_err_handler_15,0x08, 0x8e);
setup_idt_entry(16,(u32)no_err_handler_16,0x08, 0x8e);
setup_idt_entry(17,(u32)no_err_handler_17,0x08, 0x8e);
setup_idt_entry(18,(u32)no_err_handler_18,0x08, 0x8e);
setup_idt_entry(19,(u32)no_err_handler_19,0x08, 0x8e);
setup_idt_entry(20,(u32)no_err_handler_20,0x08, 0x8e);
setup_idt_entry(21,(u32)no_err_handler_21,0x08, 0x8e);
setup_idt_entry(22,(u32)no_err_handler_22,0x08, 0x8e);
setup_idt_entry(23,(u32)no_err_handler_23,0x08, 0x8e);
setup_idt_entry(24,(u32)no_err_handler_24,0x08, 0x8e);
setup_idt_entry(25,(u32)no_err_handler_25,0x08, 0x8e);
setup_idt_entry(26,(u32)no_err_handler_26,0x08, 0x8e);
setup_idt_entry(27,(u32)no_err_handler_27,0x08, 0x8e);
setup_idt_entry(28,(u32)no_err_handler_28,0x08, 0x8e);
setup_idt_entry(29,(u32)no_err_handler_29,0x08, 0x8e);
setup_idt_entry(30,(u32)no_err_handler_30,0x08, 0x8e);
setup_idt_entry(31,(u32)no_err_handler_31,0x08, 0x8e);
// Load IDT with all the new information in place, ready to use
load_idt();
// clear table in case there's garbage in there
memset((u8*)irq_handlers, 0, sizeof(void*));
irq_handlers[0] = pit_inc_ticks; // LULW
// Remap irq's to proper location
serialport_write_byte(0x20, 0x11);
serialport_write_byte(0xA0, 0x11);
serialport_write_byte(0x21, 0x20);
serialport_write_byte(0xA1, 0x28);
serialport_write_byte(0x21, 0x04);
serialport_write_byte(0xA1, 0x02);
serialport_write_byte(0x21, 0x01);
serialport_write_byte(0xA1, 0x01);
serialport_write_byte(0x21, 0x0);
serialport_write_byte(0xA1, 0x0);
// Install handlers for irq's
setup_idt_entry(32,(u32)irq_handler_0,0x08, 0x8e);
setup_idt_entry(33,(u32)irq_handler_1,0x08, 0x8e);
setup_idt_entry(34,(u32)irq_handler_2,0x08, 0x8e);
setup_idt_entry(35,(u32)irq_handler_3,0x08, 0x8e);
setup_idt_entry(36,(u32)irq_handler_4,0x08, 0x8e);
setup_idt_entry(37,(u32)irq_handler_5,0x08, 0x8e);
setup_idt_entry(38,(u32)irq_handler_6,0x08, 0x8e);
setup_idt_entry(39,(u32)irq_handler_7,0x08, 0x8e);
setup_idt_entry(40,(u32)irq_handler_8,0x08, 0x8e);
setup_idt_entry(41,(u32)irq_handler_9,0x08, 0x8e);
setup_idt_entry(42,(u32)irq_handler_10,0x08, 0x8e);
setup_idt_entry(43,(u32)irq_handler_11,0x08, 0x8e);
setup_idt_entry(44,(u32)irq_handler_12,0x08, 0x8e);
setup_idt_entry(45,(u32)irq_handler_13,0x08, 0x8e);
setup_idt_entry(46,(u32)irq_handler_14,0x08, 0x8e);
setup_idt_entry(47,(u32)irq_handler_15,0x08, 0x8e);
// Enable interrupt flags
__asm__ __volatile__("sti");
}

View File

@@ -0,0 +1,55 @@
#ifndef INTERRUPTS_H
#define INTERRUPTS_H
#include "types.h"
// There are more interrupts but tbh i doubt we're going to need them
#define i_Timer 0
#define i_Keyboard 1
#define i_PIC2 2
#define i_COM2 3
#define i_COM1 4
#define i_LPT2 5
struct cpu_reg_state {
u32 gs, fs, es, ds; // segment registers
u32 edi, esi, ebp, esp; // generaal purupose via pushad
u32 ebx, edx, ecx, eax;
u32 int_no, err_code; // pushed by each interrupt dispatcher
u32 eip, cs, eflags, useresp, ss; // processor pushes this automatically
}__attribute__((packed)); // we shouldn't need packing since everythign is dwords here
#define IDT_SIZE 256
struct IDT_Entry {
u16 offset_low; // offset bits 0..15
u16 selector; // code segment in either gdt or ldt
u8 zero; // not used always 0
/* 7 0
* +---+---+---+---+---+---+---+---+
* | P | DPL | S | GateType |
* +---+---+---+---+---+---+---+---+
*/
u8 type_attrs; // format specified above
u16 offset_high;// offset bits 16..31
}__attribute__((packed));
struct IDT_PTR {
u16 limit;
u32 address;
}__attribute__((packed));
struct IDT_Entry IDT[IDT_SIZE];
struct IDT_PTR idt_ptr;
void init_idt();
void setup_idt_entry(u32 t_idx, u32 base, u16 sel, u8 type_attrs);
void int_keyboard(struct cpu_reg_state*);
void interrupt_handler(struct cpu_reg_state*);
// IRQ specifi functions
void init_irq_handler(u32 irq, void (*handler)(struct cpu_reg_state* cpu));
void irq_handler(struct cpu_reg_state* cpu);
#endif