mirror of
https://github.com/Tom-on64/kern.git
synced 2026-11-03 18:22:22 +00:00
Major interrupt change
This commit is contained in:
@@ -1,48 +0,0 @@
|
||||
#include <interrupt/exceptions.h>
|
||||
#include <interrupt/idt.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Exception handlers
|
||||
__attribute__ ((interrupt))
|
||||
void excp_divideErr(intFrame_t* iframe) { // ISR 0
|
||||
printf("\x1b[1M[ Division Error ]\n\x1b[8M");
|
||||
iframe->eip++;
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_doubleFault(intFrame_t* iframe, uint32_t errCode) { // ISR 8
|
||||
printf("\x1b[1M[ Double Fault ]\n\x1b[8M"); // Error code should be 0 (TODO: Maybe check if it's != 0?)
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_pageFault(intFrame_t* iframe, uint32_t errCode) { // ISR 14
|
||||
uint32_t badAddress = 0;
|
||||
|
||||
// cr2 should contain invalid address
|
||||
__asm__ volatile("movl %%cr2, %0" : "=r"(badAddress));
|
||||
|
||||
printf("\x1b[1M[ Page Fault : 0x%x ] - Tried to access 0x%x.\n\x1b[8M", errCode, badAddress);
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_reserved(intFrame_t* iframe) { // ISR 15
|
||||
print("\x1b[1M[ Unknown Exception ]\n\x1b[8M");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
// TODO: Add more (because there's always more)
|
||||
|
||||
// Repetative isr definitions
|
||||
void setupExceptions() {
|
||||
for (uint8_t i = 0; i < 32; i++) {
|
||||
idtSetGate(i, excp_reserved, TRAP_GATE_FLAGS); // Doesn't account for err codes, will just halt anyways
|
||||
}
|
||||
|
||||
idtSetGate(0, excp_divideErr, TRAP_GATE_FLAGS);
|
||||
idtSetGate(8, excp_doubleFault, TRAP_GATE_FLAGS);
|
||||
idtSetGate(14, excp_pageFault, TRAP_GATE_FLAGS);
|
||||
idtSetGate(15, excp_reserved, TRAP_GATE_FLAGS);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#include <interrupt/idt.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define IDT_ENTRIES 256
|
||||
|
||||
__attribute__ ((aligned(0x10))) // For performance
|
||||
idtEntry_t idt[256] = { 0 };
|
||||
idtEntry_t idt[IDT_ENTRIES] = { 0 };
|
||||
idtp_t idtp;
|
||||
|
||||
void idtSetGate(uint8_t i, void* handler, uint8_t flags) {
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
#include <interrupt/isr.h>
|
||||
#include <interrupt/idt.h>
|
||||
#include <syscalls/syscalls.h>
|
||||
#include <error/panic.h>
|
||||
#include <error/debug.h>
|
||||
#include <ports/io.h>
|
||||
|
||||
const char* format = "\x1b[31mPanic: %s!\n";
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
#include <interrupt/pic.h>
|
||||
#include <ports/io.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void sendPicEOI(uint8_t irq) {
|
||||
if (irq >= 8) {
|
||||
outb(PIC_2_CMD, PIC_EOI);
|
||||
}
|
||||
outb(PIC_1_CMD, PIC_EOI);
|
||||
}
|
||||
|
||||
void disableIrqs() {
|
||||
outb(PIC_2_DATA, PIC_DISABLE);
|
||||
outb(PIC_1_DATA, PIC_DISABLE);
|
||||
}
|
||||
|
||||
void setIrqMask(uint8_t irq) {
|
||||
uint16_t port;
|
||||
uint8_t value;
|
||||
|
||||
if (irq < 8) {
|
||||
port = PIC_1_DATA;
|
||||
} else {
|
||||
irq -= 8;
|
||||
port = PIC_2_DATA;
|
||||
}
|
||||
|
||||
value = inb(port) | (1 << irq);
|
||||
outb(port, value);
|
||||
}
|
||||
|
||||
void unsetIrqMask(uint8_t irq) {
|
||||
uint16_t port;
|
||||
uint8_t value;
|
||||
|
||||
if (irq < 8) {
|
||||
port = PIC_1_DATA;
|
||||
} else {
|
||||
irq -= 8;
|
||||
port = PIC_2_DATA;
|
||||
}
|
||||
|
||||
value = inb(port) & ~(1 << irq);
|
||||
outb(port, value);
|
||||
}
|
||||
|
||||
void remapPic() {
|
||||
uint8_t pic1Mask = inb(PIC_1_DATA);
|
||||
uint8_t pic2Mask = inb(PIC_2_DATA);
|
||||
|
||||
// Send Init Control Word 1-4 to both PICs
|
||||
// ICW 1: bit 0 - send up to 4 ICWs, bit 4 - Init PIC
|
||||
outb(PIC_1_CMD, 0x11);
|
||||
ioWait(); // For slower machines
|
||||
outb(PIC_2_CMD, 0x11);
|
||||
ioWait();
|
||||
|
||||
// ICW 2: Where to map IRW bases in IDT
|
||||
outb(PIC_1_DATA, NEW_IRQ_0);
|
||||
ioWait();
|
||||
outb(PIC_2_DATA, NEW_IRQ_8);
|
||||
ioWait();
|
||||
|
||||
// ICW 3: Which IRQ in PIC1 is PIC2; Mapping PIC2 to IRQ 2
|
||||
outb(PIC_1_DATA, 0x04);
|
||||
ioWait();
|
||||
outb(PIC_2_DATA, 0x02);
|
||||
ioWait();
|
||||
|
||||
// ICW 4 - Set x86 mode
|
||||
outb(PIC_1_DATA, 0x01);
|
||||
ioWait();
|
||||
outb(PIC_2_DATA, 0x01);
|
||||
ioWait();
|
||||
|
||||
outb(PIC_1_DATA, pic1Mask);
|
||||
outb(PIC_2_DATA, pic2Mask);
|
||||
}
|
||||
|
||||
+3
-13
@@ -1,23 +1,19 @@
|
||||
#include <interrupt/pit.h>
|
||||
#include <interrupt/idt.h>
|
||||
#include <interrupt/pic.h>
|
||||
#include <interrupt/isr.h>
|
||||
#include <tty/tty.h>
|
||||
#include <memory/addresses.h>
|
||||
#include <ports/io.h>
|
||||
#include <stdint.h>
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void timerHandler(intFrame_t* iframe) {
|
||||
void timerHandler(intFrame_t*) {
|
||||
static uint32_t cursorTicks = 0;
|
||||
cursorTicks++;
|
||||
|
||||
if (!terminal->hideCursor) { // TODO: Make a better cursor drawing thing
|
||||
if (!console->hideCursor) { // TODO: Make a better cursor drawing thing
|
||||
if (cursorTicks % 500 == 0) toggleCursor();
|
||||
}
|
||||
|
||||
if (*(uint32_t*)SLEEP_TIMER > 0) { --(*(uint32_t*)SLEEP_TIMER); }
|
||||
|
||||
sendPicEOI(0);
|
||||
}
|
||||
|
||||
void setPitPhase(uint8_t channel, uint8_t opMode, uint16_t hz) {
|
||||
@@ -35,9 +31,3 @@ void setPitPhase(uint8_t channel, uint8_t opMode, uint16_t hz) {
|
||||
__asm__ volatile ("sti");
|
||||
}
|
||||
|
||||
void setupTimer() { // Sets up IRQ 0 - PIT
|
||||
idtSetGate(0x20, timerHandler, INT_GATE_FLAGS);
|
||||
unsetIrqMask(0);
|
||||
setPitPhase(0, 2, 1000); // Default setup: 1000Hz - 1 tick per 1ms
|
||||
}
|
||||
|
||||
|
||||
+3
-11
@@ -1,6 +1,5 @@
|
||||
#include <interrupt/rtc.h>
|
||||
#include <interrupt/pic.h>
|
||||
#include <interrupt/idt.h>
|
||||
#include <interrupt/isr.h>
|
||||
#include <screen/text.h>
|
||||
#include <screen/gfxmode.h>
|
||||
#include <tty/tty.h>
|
||||
@@ -36,7 +35,7 @@ void disableRtc() {
|
||||
__asm__ volatile ("sti");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt)) void rtcHandler(intFrame_t* iframe) {
|
||||
void rtcHandler(intFrame_t* iframe) {
|
||||
datetime_t newDatetime, oldDatetime;
|
||||
static uint16_t rtcTicks = 0;
|
||||
|
||||
@@ -121,20 +120,13 @@ __attribute__ ((interrupt)) void rtcHandler(intFrame_t* iframe) {
|
||||
uint32_t x = gfxMode->xRes - len - 1;
|
||||
char* str = &buf[0];
|
||||
for (uint8_t i = 0; i != len; i++, x++) {
|
||||
drawChar(str[i], x, 0, terminal->fg, terminal->bg);
|
||||
drawChar(str[i], x, 0, console->fg, console->bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getRtcRegister(0x0c);
|
||||
sendPicEOI(8);
|
||||
|
||||
__asm__ volatile ("sti");
|
||||
}
|
||||
|
||||
void setupRtc() { // IRQ 8 - Real Time Clock
|
||||
idtSetGate(0x28, rtcHandler, INT_GATE_FLAGS);
|
||||
unsetIrqMask(8);
|
||||
enableRtc();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,194 +0,0 @@
|
||||
#include <interrupt/syscalls.h>
|
||||
#include <interrupt/idt.h>
|
||||
#include <tty/tty.h>
|
||||
#include <keyboard/keyboard.h>
|
||||
#include <memory/malloc.h>
|
||||
#include <memory/addresses.h>
|
||||
#include <memory/physical.h>
|
||||
#include <fs/fs.h>
|
||||
#include <fs/impl.h>
|
||||
#include <stdio.h>
|
||||
#include <syscall.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* XXX WARNING - Update MAX_SYSCALLS in the handler XXX
|
||||
*/
|
||||
|
||||
int sys_reserved(sys_regs_t) {
|
||||
printf("\e[1N\e[6M Illegal use of Reserved() system call! \e[8M\e[8N\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Args: ebx - number of miliseconds
|
||||
int sys_sleep(sys_regs_t regs) {
|
||||
uint32_t* sleepTimerTicks = (uint32_t*)SLEEP_TIMER;
|
||||
*sleepTimerTicks = regs.ebx;
|
||||
|
||||
while (*sleepTimerTicks > 0) { // Wait...
|
||||
__asm__ volatile ("sti;hlt;cli;");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Args: ebx - int fd
|
||||
// ecx - void* buf
|
||||
// edx - uint32_t len
|
||||
// Rets: Number of bytes written
|
||||
int sys_write(sys_regs_t regs) {
|
||||
int32_t fd = regs.ebx;
|
||||
void* buf = (void*)regs.ecx;
|
||||
uint32_t len = regs.edx;
|
||||
|
||||
// TODO: Open fd table?
|
||||
if (fd == 1) {
|
||||
return terminalWrite(buf, len); // Call a terminal print function
|
||||
} else { return -1; }
|
||||
}
|
||||
|
||||
// TODO: Use a Read() sycall and read from stdin
|
||||
// Args: ebx - char* buffer
|
||||
int sys_read(sys_regs_t regs) {
|
||||
char* s = (char*)regs.ebx;
|
||||
reads(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Args: ebx - size_t count
|
||||
// Rets: Pointer to malloc-ed memory
|
||||
int sys_malloc(sys_regs_t regs) {
|
||||
uint32_t count = regs.ebx;
|
||||
|
||||
// First Malloc()
|
||||
if (!mallocListHead) {
|
||||
mallocInit(count); // Setup malloc linked list
|
||||
}
|
||||
|
||||
void* ptr = mallocNextNode(count);
|
||||
mallocMergeFree();
|
||||
|
||||
return (uint32_t)ptr;
|
||||
}
|
||||
|
||||
// Args: ebx - void* ptr
|
||||
int sys_free(sys_regs_t regs) {
|
||||
void* ptr = (void*)regs.ebx;
|
||||
mallocFree(ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Args: ebx - path,
|
||||
// ecx - oflag
|
||||
// Rets: Opened file descriptor
|
||||
int sys_open(sys_regs_t regs) {
|
||||
int fd = 0;
|
||||
char* path = (char*)regs.ebx;
|
||||
uint32_t oflag = regs.ecx;
|
||||
|
||||
// TODO: better file finding
|
||||
inode_t* root = (inode_t*)impl_superblock->rootInodePtr;
|
||||
loadFile(root, (void*)SCRATCH_BLOCK_LOC);
|
||||
|
||||
inode_t* inode = getInode(path, (dirEntry_t*)SCRATCH_BLOCK_LOC);
|
||||
if (inode == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO: check if max open files have'nt been reached
|
||||
fd = fsInfo->openFiles++;
|
||||
FILE* fp = fsInfo->openFileTable + fd;
|
||||
fp->_ptr = (void*)0xd000;
|
||||
fp->_offset = 0;
|
||||
fp->_size = inode->sizeBytes;
|
||||
fp->_flag = oflag;
|
||||
fp->_file = fd;
|
||||
|
||||
loadFile(inode, fp->_ptr);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
// Args: ebx - int fd
|
||||
// Rets: status
|
||||
int sys_close(sys_regs_t regs) {
|
||||
int fd = regs.ebx;
|
||||
|
||||
FILE* fp = fsInfo->openFileTable + fd;
|
||||
free(fp->_ptr);
|
||||
fsInfo->openFiles--;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO
|
||||
int sys_seek(sys_regs_t regs) { return -1; }
|
||||
|
||||
// System call table
|
||||
int (*syscalls[MAX_SYSCALLS])(sys_regs_t) = {
|
||||
[SYS_RESERVED] = sys_reserved,
|
||||
[SYS_SLEEP] = sys_sleep,
|
||||
[SYS_WRITE] = sys_write,
|
||||
[SYS_READ] = sys_read,
|
||||
[SYS_MALLOC] = sys_malloc,
|
||||
[SYS_FREE] = sys_free,
|
||||
[SYS_OPEN] = sys_open,
|
||||
[SYS_CLOSE] = sys_close,
|
||||
[SYS_SEEK] = sys_seek,
|
||||
};
|
||||
|
||||
// int 0x80 - Syscall interrupt, handled by this function
|
||||
// eax : Syscall number
|
||||
__attribute__ ((naked)) // No prologue or epilogue, just assembly
|
||||
void syscallHandler(intFrame_t* iframe) {
|
||||
// Interrupt - Stack should contain: ss, esp, eflags, cs, eip
|
||||
// We should also push these regs: ax, gs, fs, es, ds, bp, di, si, dx, cx, bx
|
||||
__asm__ volatile (
|
||||
".intel_syntax noprefix\n" // We use intel syntax
|
||||
".equ MAX_SYSCALLS, 9\n" // Define MAX_SYSCALLS again TODO: I don't want to have to do this
|
||||
|
||||
// Check if syscall exists
|
||||
"cmp eax, MAX_SYSCALLS - 1\n"
|
||||
"ja invalidSyscall\n"
|
||||
|
||||
// Call the syscall
|
||||
"push eax\n"
|
||||
"push gs\n"
|
||||
"push fs\n"
|
||||
"push es\n"
|
||||
"push ds\n"
|
||||
"push ebp\n"
|
||||
"push edi\n"
|
||||
"push esi\n"
|
||||
"push edx\n"
|
||||
"push ecx\n"
|
||||
"push ebx\n"
|
||||
"push esp\n" // Push stack pointer again (for variables and such idk)
|
||||
|
||||
"call [syscalls + eax * 4]\n" // Call syscall from table. Syscall number should be in eax
|
||||
"add esp, 4\n" // Do not override ESP
|
||||
"pop ebx\n"
|
||||
"pop ecx\n"
|
||||
"add esp, 4\n" // Do not override EDX, some syscalls use it
|
||||
|
||||
"pop esi\n"
|
||||
"pop edi\n"
|
||||
"pop ebp\n"
|
||||
"pop ds\n"
|
||||
"pop es\n"
|
||||
"pop fs\n"
|
||||
"pop gs\n"
|
||||
"add esp, 4\n" // Save eax value
|
||||
"iretd\n" // Return from interrupt (32 bit)
|
||||
|
||||
// TODO: Send an error or something here
|
||||
"invalidSyscall:\n"
|
||||
"mov eax, -1\n" // Current error thing
|
||||
"iretd\n"
|
||||
|
||||
".att_syntax" // Switch back to AT&T Syntax (Just in case)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user