forked from PoliEcho-holding-org/kern
Got IDT & ISRs working!
This commit is contained in:
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef _IDT_H
|
||||||
|
#define _IDT_H
|
||||||
|
|
||||||
|
#include <kernel.h>
|
||||||
|
|
||||||
|
#define IDT_ENTRIES 256
|
||||||
|
#define IDT_FLAG_TRAP 0x8f // P = 1, Priv = 00, S = 0, Type = 1111 (32-bit trap)
|
||||||
|
#define IDT_FLAG_INT 0x8e // P = 1, Priv = 00, S = 0, Type = 1110 (32-bit int)
|
||||||
|
#define IDT_FLAG_USER 0xee // P = 1, Priv = 11, S = 0, Type = 1110 (32-bit int)
|
||||||
|
|
||||||
|
struct idt_entry {
|
||||||
|
uint16_t offsetLow;
|
||||||
|
uint16_t selector;
|
||||||
|
uint8_t __unused;
|
||||||
|
uint8_t flags;
|
||||||
|
uint16_t offsetHigh;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct idt_pointer {
|
||||||
|
uint16_t limit;
|
||||||
|
uint32_t base;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
int idt_init(void);
|
||||||
|
void idt_setGate(uint8_t i, void* handler, uint8_t flags);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#ifndef _ISR_H
|
||||||
|
#define _ISR_H
|
||||||
|
|
||||||
|
#include <kernel.h>
|
||||||
|
|
||||||
|
// Interrupt frame (ie. what's on the stack on interrupt)
|
||||||
|
struct isr_intFrame {
|
||||||
|
// Pushed by OS
|
||||||
|
uint32_t esp, ebx, ecx, edx, esi, edi, ebp;
|
||||||
|
uint32_t ds, es, fs, gs, eax;
|
||||||
|
uint32_t interrupt, error;
|
||||||
|
|
||||||
|
// Pushed by CPU
|
||||||
|
uint32_t eip, cs, eflags, user_esp, user_ss;
|
||||||
|
};
|
||||||
|
typedef void (*isr_handlerPtr)(struct isr_intFrame* iframe);
|
||||||
|
|
||||||
|
int isr_init(void);
|
||||||
|
void isr_registerIRQ(uint8_t i, isr_handlerPtr handler);
|
||||||
|
int isr_handleInterrupt(struct isr_intFrame iframe);
|
||||||
|
|
||||||
|
// Assembly definitions (isr.s)
|
||||||
|
extern void* isr_redirectTable[48]; // ISR Table
|
||||||
|
extern void isr128(); // int 0x80 - syscall
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef _SYSCALL_H
|
||||||
|
#define _SYSCALL_H
|
||||||
|
|
||||||
|
#include <isr.h>
|
||||||
|
|
||||||
|
int syscallHandler(struct isr_intFrame* iframe) { return 1; }
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -6,7 +6,8 @@
|
|||||||
void cpuid(uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx);
|
void cpuid(uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx);
|
||||||
|
|
||||||
// Ports
|
// Ports
|
||||||
uint8_t inb(uint16_t port);
|
void iowait(void);
|
||||||
|
uint8_t inb(uint16_t port);
|
||||||
void outb(uint16_t port, uint8_t data);
|
void outb(uint16_t port, uint8_t data);
|
||||||
uint16_t inw(uint16_t port);
|
uint16_t inw(uint16_t port);
|
||||||
void outw(uint16_t port, uint16_t data);
|
void outw(uint16_t port, uint16_t data);
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#include <kernel.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <gdt.h>
|
||||||
|
#include <idt.h>
|
||||||
|
|
||||||
|
__align(16) // performace :fire:
|
||||||
|
static struct idt_entry idt[IDT_ENTRIES];
|
||||||
|
static struct idt_pointer idtp;
|
||||||
|
|
||||||
|
void idt_setGate(uint8_t i, void* handler, uint8_t flags) {
|
||||||
|
uint32_t offset = (uint32_t)handler;
|
||||||
|
struct idt_entry* entry = &idt[i];
|
||||||
|
|
||||||
|
entry->offsetLow = (uint16_t)offset;
|
||||||
|
entry->selector = GDT_KERNEL_CODE;
|
||||||
|
entry->flags = flags;
|
||||||
|
entry->offsetHigh = (uint16_t)(offset >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
int idt_init(void) {
|
||||||
|
memset(&idt, 0, sizeof(idt));
|
||||||
|
idtp.limit = sizeof(idt);
|
||||||
|
idtp.base = (uint32_t)&idt;
|
||||||
|
|
||||||
|
__asm__ volatile ("lidt %0" : : "m"(idtp));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
#include <syscall.h>
|
||||||
|
#include <kernel.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <system.h>
|
||||||
|
#include <idt.h>
|
||||||
|
#include <isr.h>
|
||||||
|
|
||||||
|
isr_handlerPtr irqHandlers[16];
|
||||||
|
|
||||||
|
const char* exceptions[] = {
|
||||||
|
"Division By Zero",
|
||||||
|
"Debug",
|
||||||
|
"Non Maskable Interrupt",
|
||||||
|
"Breakpoint",
|
||||||
|
"Into Detected Overflow",
|
||||||
|
"Out of Bounds",
|
||||||
|
"Invalid Opcode",
|
||||||
|
"No Coprocessor",
|
||||||
|
"Double Fault",
|
||||||
|
"Coprocessor Segment Overrun",
|
||||||
|
"Bad TSS",
|
||||||
|
"Segment Not Present",
|
||||||
|
"Stack Fault",
|
||||||
|
"General Protection Fault",
|
||||||
|
"Page Fault",
|
||||||
|
"Unknown Interrupt",
|
||||||
|
"Coprocessor Fault",
|
||||||
|
"Alignment Check",
|
||||||
|
"Machine Check",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved"
|
||||||
|
};
|
||||||
|
|
||||||
|
// I have no clue how this works or what it does, but it doesn't work without it
|
||||||
|
void isr_remapPIC(void) {
|
||||||
|
outb(0x20, 0x11); iowait();
|
||||||
|
outb(0xa0, 0x11); iowait();
|
||||||
|
outb(0x21, 0x20); iowait();
|
||||||
|
outb(0xa1, 0x28); iowait();
|
||||||
|
outb(0x21, 0x04); iowait();
|
||||||
|
outb(0xa1, 0x02); iowait();
|
||||||
|
outb(0x21, 0x01); iowait();
|
||||||
|
outb(0xa1, 0x01); iowait();
|
||||||
|
outb(0x21, 0x00); iowait();
|
||||||
|
outb(0xa1, 0x00); iowait();
|
||||||
|
}
|
||||||
|
|
||||||
|
int isr_init(void) {
|
||||||
|
idt_init();
|
||||||
|
isr_remapPIC();
|
||||||
|
|
||||||
|
for (int i = 0; i < 48; i++) {
|
||||||
|
// First 32 IRSs are exceptions (traps) and the next 16 are hardware interrupts
|
||||||
|
idt_setGate(i, isr_redirectTable[i], (i < 32) ? IDT_FLAG_TRAP : IDT_FLAG_INT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// System call (should be callable from userspace)
|
||||||
|
idt_setGate(0x80, (void*)(uint32_t)isr128, IDT_FLAG_USER);
|
||||||
|
|
||||||
|
// Let interrupts interrupt
|
||||||
|
__asm__ volatile ("sti");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void isr_registerIRQ(uint8_t i, isr_handlerPtr handler) {
|
||||||
|
irqHandlers[i] = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void isr_sendEOI(uint8_t irq) {
|
||||||
|
if (irq >= 8) {
|
||||||
|
outb(0xa0, 0x20);
|
||||||
|
}
|
||||||
|
outb(0x20, 0x20);
|
||||||
|
}
|
||||||
|
|
||||||
|
int isr_handleInterrupt(struct isr_intFrame iframe) {
|
||||||
|
if (iframe.interrupt < 32) {
|
||||||
|
// ISRs 0-31 - Exceptions
|
||||||
|
panic(exceptions[iframe.interrupt]);
|
||||||
|
} else if (iframe.interrupt >= 32 && iframe.interrupt < 48) {
|
||||||
|
// ISRs 32-47 - Hardware interrupts
|
||||||
|
uint8_t irq = iframe.interrupt - 32;
|
||||||
|
if (irqHandlers[irq]) {
|
||||||
|
irqHandlers[irq](&iframe);
|
||||||
|
isr_sendEOI(irq);
|
||||||
|
}
|
||||||
|
} else if (iframe.interrupt == 128) {
|
||||||
|
// ISR 128 - System call
|
||||||
|
return syscallHandler(&iframe);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
; ISR Assembly
|
||||||
|
[bits 32]
|
||||||
|
|
||||||
|
isr_common:
|
||||||
|
;; Push registers to the intFrame_t struct
|
||||||
|
push eax
|
||||||
|
push gs
|
||||||
|
push fs
|
||||||
|
push es
|
||||||
|
push ds
|
||||||
|
push ebp
|
||||||
|
push edi
|
||||||
|
push esi
|
||||||
|
push edx
|
||||||
|
push ecx
|
||||||
|
push ebx
|
||||||
|
push esp
|
||||||
|
|
||||||
|
[extern isr_handleInterrupt]
|
||||||
|
call isr_handleInterrupt
|
||||||
|
isr_return:
|
||||||
|
add esp, 4 ; Keep ESP
|
||||||
|
pop ebx
|
||||||
|
pop ecx
|
||||||
|
pop edx
|
||||||
|
pop esi
|
||||||
|
pop edi
|
||||||
|
pop ebp
|
||||||
|
pop ds
|
||||||
|
pop es
|
||||||
|
pop fs
|
||||||
|
pop gs
|
||||||
|
add esp, 4 ; Keep EAX
|
||||||
|
add esp, 8 ; Pop interupt number and error code
|
||||||
|
|
||||||
|
iretd ; Pop CS, EIP & EFLAGS (Also SS & ESP if it's from userspace)
|
||||||
|
|
||||||
|
%macro ISR_WITH_ERRNO 1
|
||||||
|
isr%1:
|
||||||
|
push dword %1
|
||||||
|
jmp isr_common
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro ISR_WITHOUT_ERRNO 1
|
||||||
|
isr%1:
|
||||||
|
push dword 0 ; Instead of error code
|
||||||
|
push dword %1
|
||||||
|
jmp isr_common
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
;; Exceptions
|
||||||
|
ISR_WITHOUT_ERRNO 0
|
||||||
|
ISR_WITHOUT_ERRNO 1
|
||||||
|
ISR_WITHOUT_ERRNO 2
|
||||||
|
ISR_WITHOUT_ERRNO 3
|
||||||
|
ISR_WITHOUT_ERRNO 4
|
||||||
|
ISR_WITHOUT_ERRNO 5
|
||||||
|
ISR_WITHOUT_ERRNO 6
|
||||||
|
ISR_WITHOUT_ERRNO 7
|
||||||
|
ISR_WITH_ERRNO 8
|
||||||
|
ISR_WITHOUT_ERRNO 9
|
||||||
|
ISR_WITH_ERRNO 10
|
||||||
|
ISR_WITH_ERRNO 11
|
||||||
|
ISR_WITH_ERRNO 12
|
||||||
|
ISR_WITH_ERRNO 13
|
||||||
|
ISR_WITH_ERRNO 14
|
||||||
|
ISR_WITHOUT_ERRNO 15
|
||||||
|
ISR_WITHOUT_ERRNO 16
|
||||||
|
ISR_WITHOUT_ERRNO 17
|
||||||
|
ISR_WITHOUT_ERRNO 18
|
||||||
|
ISR_WITHOUT_ERRNO 19
|
||||||
|
ISR_WITHOUT_ERRNO 20
|
||||||
|
ISR_WITHOUT_ERRNO 21
|
||||||
|
ISR_WITHOUT_ERRNO 22
|
||||||
|
ISR_WITHOUT_ERRNO 23
|
||||||
|
ISR_WITHOUT_ERRNO 24
|
||||||
|
ISR_WITHOUT_ERRNO 25
|
||||||
|
ISR_WITHOUT_ERRNO 26
|
||||||
|
ISR_WITHOUT_ERRNO 27
|
||||||
|
ISR_WITHOUT_ERRNO 28
|
||||||
|
ISR_WITHOUT_ERRNO 29
|
||||||
|
ISR_WITHOUT_ERRNO 30
|
||||||
|
ISR_WITHOUT_ERRNO 31
|
||||||
|
|
||||||
|
;; IRQs 0-15 (mapped 32-47)
|
||||||
|
ISR_WITHOUT_ERRNO 32
|
||||||
|
ISR_WITHOUT_ERRNO 33
|
||||||
|
ISR_WITHOUT_ERRNO 34
|
||||||
|
ISR_WITHOUT_ERRNO 35
|
||||||
|
ISR_WITHOUT_ERRNO 36
|
||||||
|
ISR_WITHOUT_ERRNO 37
|
||||||
|
ISR_WITHOUT_ERRNO 38
|
||||||
|
ISR_WITHOUT_ERRNO 39
|
||||||
|
ISR_WITHOUT_ERRNO 40
|
||||||
|
ISR_WITHOUT_ERRNO 41
|
||||||
|
ISR_WITHOUT_ERRNO 42
|
||||||
|
ISR_WITHOUT_ERRNO 43
|
||||||
|
ISR_WITHOUT_ERRNO 44
|
||||||
|
ISR_WITHOUT_ERRNO 45
|
||||||
|
ISR_WITHOUT_ERRNO 46
|
||||||
|
ISR_WITHOUT_ERRNO 47
|
||||||
|
|
||||||
|
;; Syscall ISR128
|
||||||
|
[global isr128]
|
||||||
|
isr128:
|
||||||
|
cli ; Prevent race condition & other issues
|
||||||
|
push dword 0
|
||||||
|
push dword 128
|
||||||
|
jmp isr_common
|
||||||
|
|
||||||
|
;; Create table of ISRs
|
||||||
|
[global isr_redirectTable]
|
||||||
|
isr_redirectTable:
|
||||||
|
%assign i 0
|
||||||
|
%rep 48
|
||||||
|
dd isr%+i
|
||||||
|
%assign i i+1
|
||||||
|
%endrep
|
||||||
|
|
||||||
+2
-1
@@ -2,6 +2,7 @@
|
|||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
#include <gdt.h>
|
#include <gdt.h>
|
||||||
|
#include <isr.h>
|
||||||
#include <tty.h>
|
#include <tty.h>
|
||||||
|
|
||||||
// TODO: Commented out stuff
|
// TODO: Commented out stuff
|
||||||
@@ -25,7 +26,7 @@ void kmain(void* ptr, uint32_t magic) {
|
|||||||
// vmm_init();
|
// vmm_init();
|
||||||
|
|
||||||
gdt_init();
|
gdt_init();
|
||||||
// isr_init();
|
isr_init();
|
||||||
// pag_init();
|
// pag_init();
|
||||||
|
|
||||||
debugf("Basic initialization complete!\n");
|
debugf("Basic initialization complete!\n");
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
#include <system.h>
|
||||||
|
|
||||||
void cpuid(uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) {
|
void cpuid(uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) {
|
||||||
__asm__ volatile ("cpuid"
|
__asm__ volatile ("cpuid"
|
||||||
@@ -7,6 +8,10 @@ void cpuid(uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) {
|
|||||||
: "memory");
|
: "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void iowait(void) {
|
||||||
|
outb(0x80, 0);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t inb(uint16_t port) {
|
uint8_t inb(uint16_t port) {
|
||||||
uint8_t r;
|
uint8_t r;
|
||||||
__asm__ volatile ("inb %1, %0" : "=a"(r) : "dN"(port));
|
__asm__ volatile ("inb %1, %0" : "=a"(r) : "dN"(port));
|
||||||
|
|||||||
Reference in New Issue
Block a user