forked from PoliEcho-holding-org/kern
Major libk restructuring, also rewrote drivers/serial.h
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
#include <cpu/idt.h>
|
||||
#include <stdint.h>
|
||||
|
||||
__attribute__ ((aligned(0x10))) // For performance
|
||||
idtEntry_t idt[IDT_ENTRIES] = { 0 };
|
||||
idtp_t idtp;
|
||||
|
||||
void idtSetGate(uint8_t i, void* handler, uint8_t flags) {
|
||||
uint32_t offset = (uint32_t)handler;
|
||||
idtEntry_t* entry = &idt[i];
|
||||
|
||||
entry->offsetLow = (uint16_t)offset;
|
||||
entry->selector = 0x08;
|
||||
entry->zero = 0;
|
||||
entry->typeAttr = flags;
|
||||
entry->offsetHigh = (uint16_t)(offset >> 16);
|
||||
}
|
||||
|
||||
void setupIdt() {
|
||||
idtp.limit = sizeof(idtEntry_t) * 256;
|
||||
idtp.base = (uint32_t)&idt;
|
||||
|
||||
__asm__ volatile ("lidt %0" : : "m"(idtp));
|
||||
}
|
||||
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
#include <syscalls/syscalls.h>
|
||||
#include <drivers/serial.h>
|
||||
#include <cpu/system.h>
|
||||
#include <cpu/idt.h>
|
||||
#include <cpu/isr.h>
|
||||
|
||||
const char* format = "\x1b[31m[kernel] %s!\n\x1b[0m";
|
||||
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"
|
||||
};
|
||||
|
||||
void remapPic() {
|
||||
outb(0x20, 0x11);
|
||||
outb(0xa0, 0x11);
|
||||
outb(0x21, 0x20);
|
||||
outb(0xa1, 0x28);
|
||||
outb(0x21, 0x04);
|
||||
outb(0xa1, 0x02);
|
||||
outb(0x21, 0x01);
|
||||
outb(0xa1, 0x01);
|
||||
outb(0x21, 0x00);
|
||||
outb(0xa1, 0x00);
|
||||
}
|
||||
|
||||
HandlerPtr irqHandlers[16] = { 0 }; // IRQ 0-15
|
||||
|
||||
void setupIsrs() {
|
||||
setupIdt();
|
||||
remapPic(); // Remap IRQs 0-15 -> 32-48
|
||||
|
||||
for (int i = 0; i < 48; i++) {
|
||||
idtSetGate(i, asm_isrRedirectTable[i], TRAP_GATE_FLAGS);
|
||||
}
|
||||
|
||||
// System call
|
||||
idtSetGate(0x80, isr128, USR_INT_GATE_FLAGS);
|
||||
|
||||
__asm__ volatile ("sti");
|
||||
}
|
||||
|
||||
void registerIrq(uint8_t id, HandlerPtr handler) {
|
||||
irqHandlers[id] = handler;
|
||||
}
|
||||
|
||||
void sendPicEOI(uint8_t irq) {
|
||||
if (irq >= 8) {
|
||||
outb(0xA0, 0x20); // PIC2 Command
|
||||
}
|
||||
outb(0x20, 0x20); // PIC1 Command
|
||||
}
|
||||
|
||||
int handleInterrupt(intFrame_t iframe) {
|
||||
if (iframe.interrupt < 32) {
|
||||
// ISRs 0-31 - Exceptions
|
||||
debugf(format, exceptions[iframe.interrupt]);
|
||||
panic();
|
||||
} 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);
|
||||
sendPicEOI(irq);
|
||||
}
|
||||
} else if (iframe.interrupt == 128) {
|
||||
// ISR 128 - System call
|
||||
return syscallHandler(&iframe);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
; ISR Assembly
|
||||
[bits 32]
|
||||
|
||||
isrCommon:
|
||||
;; 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 handleInterrupt]
|
||||
call handleInterrupt
|
||||
isrReturn:
|
||||
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 isrCommon
|
||||
%endmacro
|
||||
|
||||
%macro ISR_WITHOUT_ERRNO 1
|
||||
isr%1:
|
||||
push dword 0 ; Instead of error code
|
||||
push dword %1
|
||||
jmp isrCommon
|
||||
%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]
|
||||
ISR_WITHOUT_ERRNO 128
|
||||
|
||||
;; Create table of ISRs
|
||||
[global asm_isrRedirectTable]
|
||||
asm_isrRedirectTable:
|
||||
%assign i 0
|
||||
%rep 48
|
||||
dd isr%+i
|
||||
%assign i i+1
|
||||
%endrep
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
#include <cpu/system.h>
|
||||
#include <drivers/serial.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void cpuid(uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) {
|
||||
__asm__ volatile (
|
||||
"cpuid"
|
||||
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
|
||||
: "a"(*eax)
|
||||
);
|
||||
}
|
||||
|
||||
uint8_t inb(uint16_t port) {
|
||||
uint8_t result;
|
||||
__asm__ volatile("inb %1, %0" : "=a"(result) : "Nd"(port));
|
||||
return result;
|
||||
}
|
||||
void outb(uint16_t port, uint8_t data) {
|
||||
__asm__ volatile("outb %0, %1" :: "a"(data), "Nd"(port));
|
||||
}
|
||||
|
||||
uint16_t inw(uint16_t port) {
|
||||
uint16_t result;
|
||||
__asm__ volatile("inw %1, %0" : "=a"(result) : "Nd"(port));
|
||||
return result;
|
||||
}
|
||||
void outw(uint16_t port, uint16_t data) {
|
||||
__asm__ volatile("outw %0, %1" :: "a"(data), "Nd"(port));
|
||||
}
|
||||
|
||||
uint32_t inl(uint16_t port) {
|
||||
uint32_t result;
|
||||
__asm__ volatile("inl %1, %0" : "=a"(result) : "Nd"(port));
|
||||
return result;
|
||||
}
|
||||
void outl(uint16_t port, uint32_t data) {
|
||||
__asm__ volatile("outl %0, %1" :: "a"(data), "Nd"(port));
|
||||
}
|
||||
|
||||
void ioWait() {
|
||||
// Waits ~1 I/O Cycle (Linux uses this so it should be good)
|
||||
__asm__ volatile("outb %%al, $0x80" : : "a"(0));
|
||||
}
|
||||
|
||||
void panic() {
|
||||
debugf("\x1b[31m[kernel] Kern panic!\x1b[0m\n");
|
||||
while (1) { __asm__ volatile ("cli; hlt"); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user