mirror of
https://github.com/Tom-on64/kern.git
synced 2026-11-04 02:23:10 +00:00
Implemented a proper libk
This commit is contained in:
@@ -1,51 +1,6 @@
|
||||
#ifndef INTERRUPT_EXCEPTIONS_H
|
||||
#define 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);
|
||||
}
|
||||
void setupExceptions();
|
||||
|
||||
#endif
|
||||
|
||||
+2
-21
@@ -28,27 +28,8 @@ typedef struct {
|
||||
uint32_t ss;
|
||||
} __attribute__ ((packed)) intFrame_t;
|
||||
|
||||
__attribute__ ((aligned(0x10))) // For performance
|
||||
idtEntry_t idt[256] = { 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));
|
||||
}
|
||||
void idtSetGate(uint8_t i, void* handler, uint8_t flags);
|
||||
void setupIdt();
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+6
-75
@@ -1,7 +1,7 @@
|
||||
#ifndef INTERRUPT_PIC_H
|
||||
#define INTERRUPT_PIC_H
|
||||
|
||||
#include <ports/io.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// PIC I/O Ports
|
||||
#define PIC_1_CMD 0x20
|
||||
@@ -17,79 +17,10 @@
|
||||
#define PIC_EOI 0x20 // End Of Interrupt
|
||||
#define PIC_DISABLE 0xff
|
||||
|
||||
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);
|
||||
}
|
||||
void sendPicEOI(uint8_t irq);
|
||||
void disableIrqs();
|
||||
void setIrqMask(uint8_t irq);
|
||||
void unsetIrqMask(uint8_t irq);
|
||||
void remapPic();
|
||||
|
||||
#endif
|
||||
|
||||
+2
-38
@@ -1,49 +1,13 @@
|
||||
#ifndef INTERRUPT_PIT_H
|
||||
#define INTERRUPT_PIT_H
|
||||
|
||||
#include <interrupt/idt.h>
|
||||
#include <interrupt/pic.h>
|
||||
#include <terminal/terminal.h>
|
||||
#include <memory/addresses.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define CHANNEL_0 0x40 // Offset it by 1 or 2 for ch1 and ch2
|
||||
#define COMMAND 0x43
|
||||
#define INPUT_CLK 1193182
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void timerHandler(intFrame_t* iframe) {
|
||||
static uint32_t cursorTicks = 0;
|
||||
cursorTicks++;
|
||||
|
||||
if (!terminal->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) {
|
||||
if (channel > 2 || opMode > 7) { return; }
|
||||
__asm__ volatile ("cli");
|
||||
|
||||
// Send command - bits 7-6 channel, 5-4 Access mode, 3-1 operating mode, 0 - Should be zero in x86
|
||||
outb(COMMAND, ((channel << 6) | (3 << 4) | (opMode << 1)));
|
||||
|
||||
// Send frequency
|
||||
uint16_t freq = INPUT_CLK / hz; // I solved an equation to figure this out
|
||||
outb(CHANNEL_0 + channel, (uint8_t)freq);
|
||||
outb(CHANNEL_0 + channel, (uint8_t)(freq >> 8));
|
||||
|
||||
__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
|
||||
}
|
||||
void setPitPhase(uint8_t channel, uint8_t opMode, uint16_t hz);
|
||||
void setupTimer();
|
||||
|
||||
#endif
|
||||
|
||||
+6
-135
@@ -1,13 +1,8 @@
|
||||
#ifndef INTERRUPT_RTC_H
|
||||
#define INTERRUPT_RTC_H
|
||||
|
||||
#include <interrupt/pic.h>
|
||||
#include <interrupt/idt.h>
|
||||
#include <screen/text.h>
|
||||
#include <screen/gfxmode.h>
|
||||
#include <terminal/terminal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CMOS_ADDRESS 0x70
|
||||
#define CMOS_DATA 0x71
|
||||
@@ -21,134 +16,10 @@ typedef struct {
|
||||
uint16_t year;
|
||||
} __attribute__ ((packed)) datetime_t;
|
||||
|
||||
static datetime_t* datetime = (datetime_t*)DATETIME_LOC;
|
||||
|
||||
bool cmosUpdateProgress() {
|
||||
outb(CMOS_ADDRESS, 0x8a); // Read status reg A, disable NMI
|
||||
return inb(CMOS_DATA) & 0x80;
|
||||
}
|
||||
|
||||
uint8_t getRtcRegister(uint8_t reg) {
|
||||
outb(CMOS_ADDRESS, reg | 0x80); // Disable NMI when sending
|
||||
return inb(CMOS_DATA);
|
||||
}
|
||||
|
||||
void enableRtc() {
|
||||
uint8_t regB = getRtcRegister(0x0b);
|
||||
outb(CMOS_ADDRESS, 0x8b);
|
||||
outb(CMOS_DATA, regB | 0x40); // Set bit 6 - periodic int at 1024Hz
|
||||
|
||||
getRtcRegister(0x0c); // Clear pending interrupts
|
||||
}
|
||||
|
||||
void disableRtc() {
|
||||
__asm__ volatile ("cli");
|
||||
uint8_t regB = getRtcRegister(0x0b);
|
||||
outb(CMOS_ADDRESS, 0x8b);
|
||||
outb(CMOS_DATA, regB & 0xbf); // Clear bit 6
|
||||
__asm__ volatile ("sti");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt)) void rtcHandler(intFrame_t* iframe) {
|
||||
datetime_t newDatetime, oldDatetime;
|
||||
static uint16_t rtcTicks = 0;
|
||||
|
||||
__asm__ volatile ("cli");
|
||||
rtcTicks++;
|
||||
if (rtcTicks % 1024 == 0) { // 1 Second has passed
|
||||
while (cmosUpdateProgress()); // Wait
|
||||
|
||||
newDatetime.second = getRtcRegister(0);
|
||||
newDatetime.minute = getRtcRegister(2);
|
||||
newDatetime.hour = getRtcRegister(4);
|
||||
newDatetime.day = getRtcRegister(7);
|
||||
newDatetime.month = getRtcRegister(8);
|
||||
newDatetime.year = getRtcRegister(9);
|
||||
|
||||
do {
|
||||
oldDatetime = newDatetime;
|
||||
|
||||
while (cmosUpdateProgress()); // Wait
|
||||
newDatetime.second = getRtcRegister(0);
|
||||
newDatetime.minute = getRtcRegister(2);
|
||||
newDatetime.hour = getRtcRegister(4);
|
||||
newDatetime.day = getRtcRegister(7);
|
||||
newDatetime.month = getRtcRegister(8);
|
||||
newDatetime.year = getRtcRegister(9);
|
||||
|
||||
} while (
|
||||
newDatetime.second != oldDatetime.second ||
|
||||
newDatetime.minute != oldDatetime.minute ||
|
||||
newDatetime.hour != oldDatetime.hour ||
|
||||
newDatetime.day != oldDatetime.day ||
|
||||
newDatetime.month != oldDatetime.month ||
|
||||
newDatetime.year != oldDatetime.year
|
||||
);
|
||||
|
||||
uint8_t regB = getRtcRegister(0x0b);
|
||||
if (!(regB & 0x04)) {
|
||||
newDatetime.second = (newDatetime.second & 0x0f) + ((newDatetime.second >> 4) * 10);
|
||||
newDatetime.minute = (newDatetime.minute & 0x0f) + ((newDatetime.minute >> 4) * 10);
|
||||
newDatetime.hour = ((newDatetime.hour & 0x0F) + (((newDatetime.hour & 0x70) / 16) * 10)) | (newDatetime.hour & 0x80); // 12/24 Hour format bs
|
||||
newDatetime.day = (newDatetime.day & 0x0f) + ((newDatetime.day >> 4) * 10);
|
||||
newDatetime.month = (newDatetime.month & 0x0f) + ((newDatetime.month >> 4) * 10);
|
||||
newDatetime.year = (newDatetime.year & 0x0f) + ((newDatetime.year >> 4) * 10);
|
||||
}
|
||||
|
||||
// Convert 12 to 14 hour format
|
||||
if (!(regB & 0x02) && (newDatetime.hour & 0x80)) {
|
||||
newDatetime.hour = ((newDatetime.hour & 0x7f) + 12) % 24;
|
||||
}
|
||||
|
||||
newDatetime.year += 2000; // Add current century
|
||||
|
||||
//*datetime = newDatetime;
|
||||
|
||||
datetime->second = newDatetime.second;
|
||||
datetime->minute = newDatetime.minute;
|
||||
datetime->hour = newDatetime.hour;
|
||||
datetime->day = newDatetime.day;
|
||||
datetime->month = newDatetime.month;
|
||||
datetime->year = newDatetime.year;
|
||||
|
||||
if (true) { // TODO: Probably get rid of this idk
|
||||
char buf[20] = { 0 }; // "12/12 2012 12:12:12" - Max string 20 chars with null byte
|
||||
|
||||
strcat(buf, itoa(datetime->day, 10));
|
||||
strcat(buf, "/");
|
||||
strcat(buf, itoa(datetime->month, 10));
|
||||
strcat(buf, " ");
|
||||
strcat(buf, itoa(datetime->year, 10));
|
||||
strcat(buf, " ");
|
||||
if (datetime->hour < 10) strcat(buf, "0");
|
||||
strcat(buf, itoa(datetime->hour, 10));
|
||||
strcat(buf, ":");
|
||||
if (datetime->minute < 10) strcat(buf, "0");
|
||||
strcat(buf, itoa(datetime->minute, 10));
|
||||
strcat(buf, ":");
|
||||
if (datetime->second < 10) strcat(buf, "0");
|
||||
strcat(buf, itoa(datetime->second, 10));
|
||||
|
||||
// The clock is a little offset down (about 0.4 of a character) It does look nice though!
|
||||
uint8_t len = strlen(buf);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getRtcRegister(0x0c);
|
||||
sendPicEOI(8);
|
||||
|
||||
__asm__ volatile ("sti");
|
||||
}
|
||||
|
||||
void setupRtc() { // IRQ 8 - Real Time Clock
|
||||
idtSetGate(0x28, rtcHandler, INT_GATE_FLAGS);
|
||||
unsetIrqMask(8);
|
||||
enableRtc();
|
||||
}
|
||||
bool cmosUpdateProgress();
|
||||
uint8_t getRtcRegister(uint8_t reg);
|
||||
void enableRtc();
|
||||
void disableRtc();
|
||||
void setupRtc();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,21 +2,7 @@
|
||||
#define INTERRUPT_SYSCALLS_H
|
||||
|
||||
#include <interrupt/idt.h>
|
||||
#include <terminal/terminal.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 <error/bigerr.h>
|
||||
#include <syscall.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* XXX WARNING - Update MAX_SYSCALLS in the handler XXX
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint32_t esp;
|
||||
@@ -33,188 +19,6 @@ typedef struct {
|
||||
uint32_t eax;
|
||||
} __attribute__ ((packed)) sys_regs_t;
|
||||
|
||||
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) { // "stdout"
|
||||
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;
|
||||
|
||||
extern FILE* openFileTable;
|
||||
extern uint32_t openFiles;
|
||||
|
||||
// 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 = openFiles++;
|
||||
FILE* fp = 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;
|
||||
|
||||
extern FILE* openFileTable;
|
||||
extern uint32_t openFiles;
|
||||
|
||||
FILE* fp = openFileTable + fd;
|
||||
free(fp->_ptr);
|
||||
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)
|
||||
);
|
||||
}
|
||||
__attribute__ ((naked)) void syscallHandler(intFrame_t* iframe);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user