From f163659f0cba282f5eb08ac2cdd14f91730d8892 Mon Sep 17 00:00:00 2001 From: Tom-on64 Date: Wed, 23 Oct 2024 14:11:22 +0200 Subject: [PATCH] Major interrupt change --- libk/error/debug.c | 13 ++ libk/error/panic.c | 7 ++ libk/fs/impl.c | 6 +- libk/include/error/debug.h | 6 + libk/include/error/panic.h | 6 + libk/include/interrupt/idt.h | 10 +- libk/include/interrupt/isr.h | 27 +++++ libk/include/interrupt/pic.h | 26 ---- libk/include/interrupt/pit.h | 3 +- libk/include/interrupt/rtc.h | 3 +- libk/include/interrupt/syscalls.h | 24 ---- libk/include/keyboard/keyboard.h | 3 +- libk/include/ports/serial.h | 2 +- libk/include/syscalls/syscalls.h | 19 +++ libk/include/tty/tty.h | 6 +- libk/interrupt/exceptions.c | 48 -------- libk/interrupt/idt.c | 4 +- libk/interrupt/isr.c | 103 ++++++++++++++++ libk/interrupt/isr.s | 116 ++++++++++++++++++ libk/interrupt/pic.c | 79 ------------ libk/interrupt/pit.c | 16 +-- libk/interrupt/rtc.c | 14 +-- libk/interrupt/syscalls.c | 194 ------------------------------ libk/keyboard/keyboard.c | 13 +- libk/makefile | 5 +- libk/ports/serial.c | 2 +- libk/screen/text.c | 14 +-- libk/syscalls/sys_close.c | 9 ++ libk/syscalls/sys_exit.c | 9 ++ libk/syscalls/sys_free.c | 10 ++ libk/syscalls/sys_malloc.c | 18 +++ libk/syscalls/sys_open.c | 9 ++ libk/syscalls/sys_read.c | 11 ++ libk/syscalls/sys_seek.c | 8 ++ libk/syscalls/sys_sleep.c | 14 +++ libk/syscalls/sys_write.c | 15 +++ libk/syscalls/syscalls.c | 28 +++++ libk/tty/tty.c | 66 +++++----- 38 files changed, 498 insertions(+), 468 deletions(-) create mode 100644 libk/error/debug.c create mode 100644 libk/error/panic.c create mode 100644 libk/include/error/debug.h create mode 100644 libk/include/error/panic.h create mode 100644 libk/include/interrupt/isr.h delete mode 100644 libk/include/interrupt/pic.h delete mode 100644 libk/include/interrupt/syscalls.h create mode 100644 libk/include/syscalls/syscalls.h delete mode 100644 libk/interrupt/exceptions.c create mode 100644 libk/interrupt/isr.c create mode 100644 libk/interrupt/isr.s delete mode 100644 libk/interrupt/pic.c delete mode 100644 libk/interrupt/syscalls.c create mode 100644 libk/syscalls/sys_close.c create mode 100644 libk/syscalls/sys_exit.c create mode 100644 libk/syscalls/sys_free.c create mode 100644 libk/syscalls/sys_malloc.c create mode 100644 libk/syscalls/sys_open.c create mode 100644 libk/syscalls/sys_read.c create mode 100644 libk/syscalls/sys_seek.c create mode 100644 libk/syscalls/sys_sleep.c create mode 100644 libk/syscalls/sys_write.c create mode 100644 libk/syscalls/syscalls.c diff --git a/libk/error/debug.c b/libk/error/debug.c new file mode 100644 index 0000000..bf1cae3 --- /dev/null +++ b/libk/error/debug.c @@ -0,0 +1,13 @@ +#include +#include +#include + +int debugf(const char* fmt, ...) { + va_list va; + va_start(va, fmt); + serialPrint(PORT_COM1, fmt); // TODO: use a printf + int res = 0; + va_end(va); + return res; +} + diff --git a/libk/error/panic.c b/libk/error/panic.c new file mode 100644 index 0000000..5c6ddb8 --- /dev/null +++ b/libk/error/panic.c @@ -0,0 +1,7 @@ +#include + +void panic() { + // TODO: print a message + while (1) { __asm__ volatile ("cli; hlt"); } +} + diff --git a/libk/fs/impl.c b/libk/fs/impl.c index a13cc5f..e83540f 100644 --- a/libk/fs/impl.c +++ b/libk/fs/impl.c @@ -47,15 +47,15 @@ void initOpenFileTable() { // offset and ptr are unused in these stdin = fsInfo->openFileTable + 0; - stdin->_file = 0; + stdin->_file = STDIN_FILENO; stdin->_flag = O_RDONLY; stdout = fsInfo->openFileTable + 1; - stdout->_file = 1; + stdout->_file = STDOUT_FILENO; stdout->_flag = O_WRONLY | O_APPEND; stderr = fsInfo->openFileTable + 2; - stderr->_file = 2; + stderr->_file = STDERR_FILENO; stderr->_flag = O_WRONLY | O_APPEND; fsInfo->openFiles = 3; diff --git a/libk/include/error/debug.h b/libk/include/error/debug.h new file mode 100644 index 0000000..1d7ae85 --- /dev/null +++ b/libk/include/error/debug.h @@ -0,0 +1,6 @@ +#ifndef ERROR_DEBUG_H +#define ERROR_DEBUG_H + +int debugf(const char* fmt, ...); + +#endif diff --git a/libk/include/error/panic.h b/libk/include/error/panic.h new file mode 100644 index 0000000..2cea8ab --- /dev/null +++ b/libk/include/error/panic.h @@ -0,0 +1,6 @@ +#ifndef ERROR_PANIC_H +#define ERROR_PANIC_H + +void panic(); + +#endif diff --git a/libk/include/interrupt/idt.h b/libk/include/interrupt/idt.h index 49c291f..8cbb013 100644 --- a/libk/include/interrupt/idt.h +++ b/libk/include/interrupt/idt.h @@ -5,7 +5,7 @@ #define TRAP_GATE_FLAGS 0x8f // P = 1, DPL = 00, S = 0, Type = 1111 (32-bit Trap gate) #define INT_GATE_FLAGS 0x8e // P = 1, DPL = 00, S = 0, Type = 1110 (32-bit Int gate) -#define USR_INT_GAME_FLAGS 0xee // P = 1, DPL = 11, S = 0, Type = 1110 (32-bit Int gate) +#define USR_INT_GATE_FLAGS 0xee // P = 1, DPL = 11, S = 0, Type = 1110 (32-bit Int gate) typedef struct { uint16_t offsetLow; @@ -20,14 +20,6 @@ typedef struct { uint32_t base; } __attribute__ ((packed)) idtp_t; -typedef struct { - uint32_t eip; - uint32_t cs; - uint32_t eflags; - uint32_t esp; - uint32_t ss; -} __attribute__ ((packed)) intFrame_t; - void idtSetGate(uint8_t i, void* handler, uint8_t flags); void setupIdt(); diff --git a/libk/include/interrupt/isr.h b/libk/include/interrupt/isr.h new file mode 100644 index 0000000..e8503ac --- /dev/null +++ b/libk/include/interrupt/isr.h @@ -0,0 +1,27 @@ +#ifndef INTERRUPT_ISR_H +#define INTERRUPT_ISR_H + +#include + +typedef struct { + // 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; +} intFrame_t; +typedef void (*HandlerPtr)(intFrame_t* iframe); + +void setupIsrs(); +int handleInterrupt(intFrame_t iframe); +void registerIrq(uint8_t id, HandlerPtr handler); + +// ISR Table +extern void* asm_isrRedirectTable[48]; + +// Int 0x80 - Syscall +extern void isr128(); + +#endif diff --git a/libk/include/interrupt/pic.h b/libk/include/interrupt/pic.h deleted file mode 100644 index 2bb4276..0000000 --- a/libk/include/interrupt/pic.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef INTERRUPT_PIC_H -#define INTERRUPT_PIC_H - -#include - -// PIC I/O Ports -#define PIC_1_CMD 0x20 -#define PIC_1_DATA 0x21 -#define PIC_2_CMD 0xA0 -#define PIC_2_DATA 0xA1 - -// IRQs -#define NEW_IRQ_0 0x20 // IRQ 0 : int 32 -#define NEW_IRQ_8 0x28 // IRQ 8 : int 40 - -// Commands -#define PIC_EOI 0x20 // End Of Interrupt -#define PIC_DISABLE 0xff - -void sendPicEOI(uint8_t irq); -void disableIrqs(); -void setIrqMask(uint8_t irq); -void unsetIrqMask(uint8_t irq); -void remapPic(); - -#endif diff --git a/libk/include/interrupt/pit.h b/libk/include/interrupt/pit.h index e210205..fd39e73 100644 --- a/libk/include/interrupt/pit.h +++ b/libk/include/interrupt/pit.h @@ -1,13 +1,14 @@ #ifndef INTERRUPT_PIT_H #define INTERRUPT_PIT_H +#include #include #define CHANNEL_0 0x40 // Offset it by 1 or 2 for ch1 and ch2 #define COMMAND 0x43 #define INPUT_CLK 1193182 +void timerHandler(intFrame_t*); void setPitPhase(uint8_t channel, uint8_t opMode, uint16_t hz); -void setupTimer(); #endif diff --git a/libk/include/interrupt/rtc.h b/libk/include/interrupt/rtc.h index e9d452f..77195e5 100644 --- a/libk/include/interrupt/rtc.h +++ b/libk/include/interrupt/rtc.h @@ -1,6 +1,7 @@ #ifndef INTERRUPT_RTC_H #define INTERRUPT_RTC_H +#include #include #include @@ -16,10 +17,10 @@ typedef struct { uint16_t year; } __attribute__ ((packed)) datetime_t; +void rtcHandler(intFrame_t*); bool cmosUpdateProgress(); uint8_t getRtcRegister(uint8_t reg); void enableRtc(); void disableRtc(); -void setupRtc(); #endif diff --git a/libk/include/interrupt/syscalls.h b/libk/include/interrupt/syscalls.h deleted file mode 100644 index 8bc7612..0000000 --- a/libk/include/interrupt/syscalls.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef INTERRUPT_SYSCALLS_H -#define INTERRUPT_SYSCALLS_H - -#include -#include - -typedef struct { - uint32_t esp; - uint32_t ebx; - uint32_t ecx; - uint32_t edx; - uint32_t esi; - uint32_t edi; - uint32_t ebp; - uint32_t ds; - uint32_t es; - uint32_t fs; - uint32_t gs; - uint32_t eax; -} __attribute__ ((packed)) sys_regs_t; - -__attribute__ ((naked)) void syscallHandler(intFrame_t* iframe); - -#endif diff --git a/libk/include/keyboard/keyboard.h b/libk/include/keyboard/keyboard.h index b312140..f688e10 100644 --- a/libk/include/keyboard/keyboard.h +++ b/libk/include/keyboard/keyboard.h @@ -1,6 +1,7 @@ #ifndef KEYBOARD_KEYBOARD_H #define KEYBOARD_KEYBOARD_H +#include #include typedef struct { @@ -8,6 +9,6 @@ typedef struct { bool shift; } keyboardState_t; -void setupKeyboard(); +void keyboardHandler(intFrame_t*); #endif diff --git a/libk/include/ports/serial.h b/libk/include/ports/serial.h index 4a59557..21d4040 100644 --- a/libk/include/ports/serial.h +++ b/libk/include/ports/serial.h @@ -18,7 +18,7 @@ int serialTransmitEmpty(uint32_t port); int serialRecieved(uint32_t port); void serialWrite(uint32_t port, char c); -void serialPrint(uint32_t port, char* s); +void serialPrint(uint32_t port, const char* s); char serialRead(uint32_t port); #endif diff --git a/libk/include/syscalls/syscalls.h b/libk/include/syscalls/syscalls.h new file mode 100644 index 0000000..615dbbe --- /dev/null +++ b/libk/include/syscalls/syscalls.h @@ -0,0 +1,19 @@ +#ifndef INTERRUPT_SYSCALLS_H +#define INTERRUPT_SYSCALLS_H + +#include + +int sys_exit (intFrame_t* iframe); +int sys_read (intFrame_t* iframe); +int sys_write (intFrame_t* iframe); +int sys_open (intFrame_t* iframe); +int sys_close (intFrame_t* iframe); +int sys_seek (intFrame_t* iframe); +int sys_malloc (intFrame_t* iframe); +int sys_free (intFrame_t* iframe); +int sys_sleep (intFrame_t* iframe); + +// Main syscall handler/dispatcher +int syscallHandler(intFrame_t* iframe); + +#endif diff --git a/libk/include/tty/tty.h b/libk/include/tty/tty.h index 559195e..0d32ed5 100644 --- a/libk/include/tty/tty.h +++ b/libk/include/tty/tty.h @@ -13,11 +13,11 @@ typedef struct { uint32_t height; // Height in characters char cursorChar; // Character to use as a cursor bool hideCursor; // Should we display the cursor -} terminal_t; +} console_t; -extern terminal_t* terminal; +extern console_t* console; -int32_t terminalWrite(const void* buf, uint32_t len); +int32_t consoleWrite(const void* buf, uint32_t len); void toggleCursor(); #endif diff --git a/libk/interrupt/exceptions.c b/libk/interrupt/exceptions.c deleted file mode 100644 index e93086d..0000000 --- a/libk/interrupt/exceptions.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include - -// 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); -} - diff --git a/libk/interrupt/idt.c b/libk/interrupt/idt.c index dc7918a..913712e 100644 --- a/libk/interrupt/idt.c +++ b/libk/interrupt/idt.c @@ -1,8 +1,10 @@ #include #include +#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) { diff --git a/libk/interrupt/isr.c b/libk/interrupt/isr.c new file mode 100644 index 0000000..67ae969 --- /dev/null +++ b/libk/interrupt/isr.c @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include +#include + +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; +} + diff --git a/libk/interrupt/isr.s b/libk/interrupt/isr.s new file mode 100644 index 0000000..b82f91a --- /dev/null +++ b/libk/interrupt/isr.s @@ -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 + diff --git a/libk/interrupt/pic.c b/libk/interrupt/pic.c deleted file mode 100644 index 4cb9357..0000000 --- a/libk/interrupt/pic.c +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#include - -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); -} - diff --git a/libk/interrupt/pit.c b/libk/interrupt/pit.c index a3470f8..f6c24cd 100644 --- a/libk/interrupt/pit.c +++ b/libk/interrupt/pit.c @@ -1,23 +1,19 @@ #include -#include -#include +#include #include #include #include #include -__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 -} - diff --git a/libk/interrupt/rtc.c b/libk/interrupt/rtc.c index d5a0b82..5c7ce64 100644 --- a/libk/interrupt/rtc.c +++ b/libk/interrupt/rtc.c @@ -1,6 +1,5 @@ #include -#include -#include +#include #include #include #include @@ -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(); -} - diff --git a/libk/interrupt/syscalls.c b/libk/interrupt/syscalls.c deleted file mode 100644 index b0f16bb..0000000 --- a/libk/interrupt/syscalls.c +++ /dev/null @@ -1,194 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * 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) - ); -} - diff --git a/libk/keyboard/keyboard.c b/libk/keyboard/keyboard.c index d013955..173afc3 100644 --- a/libk/keyboard/keyboard.c +++ b/libk/keyboard/keyboard.c @@ -1,6 +1,5 @@ #include -#include -#include +#include #include #include #include @@ -10,8 +9,7 @@ static const uint8_t US_Keyboard[2][128] = US_KEYBOARD; keyboardState_t* keyboard = (keyboardState_t*)KEYBOARD_STATE_LOC; -__attribute__ ((interrupt)) -void keyboardHandler(intFrame_t* iframe) { // TODO: Make this better and be able to read multi-byte scancode +void keyboardHandler(intFrame_t*) { // TODO: Make this better and be able to read multi-byte scancode uint8_t scancode = inb(0x60); char c = US_Keyboard[keyboard->shift][scancode]; @@ -25,12 +23,5 @@ void keyboardHandler(intFrame_t* iframe) { // TODO: Make this better and be able } else if (c != '\0') { keyboard->character = c; } - - sendPicEOI(1); -} - -void setupKeyboard() { - idtSetGate(0x21, keyboardHandler, INT_GATE_FLAGS); - unsetIrqMask(1); } diff --git a/libk/makefile b/libk/makefile index b9bd448..257bf15 100644 --- a/libk/makefile +++ b/libk/makefile @@ -4,8 +4,11 @@ include make.defaults -$(LIBK): $(LIBK_SRC) +LIBK_ASM=$(LIBK_DIR)/interrupt/isr.s + +$(LIBK): $(LIBK_SRC) $(LIBK_ASM) @echo "Building $(LIBK)..." + nasm -felf32 -o $(BIN)/libk/isr_asm.o $(LIBK_ASM) for f in $(LIBK_SRC); do\ filename=$$(basename $$f .c);\ $(CC) $(CFLAGS) -I$(LIBC_INC) -I$(LIBK_INC) -o $(BIN)/libk/$$filename.o -c $$f;\ diff --git a/libk/ports/serial.c b/libk/ports/serial.c index ce1776e..af3bf8a 100644 --- a/libk/ports/serial.c +++ b/libk/ports/serial.c @@ -32,7 +32,7 @@ void serialWrite(uint32_t port, char c) { outb(port, c); } -void serialPrint(uint32_t port, char* s) { +void serialPrint(uint32_t port, const char* s) { while (*s != '\0') { if (*s == '\n') serialWrite(port, '\r'); serialWrite(port, *s++); diff --git a/libk/screen/text.c b/libk/screen/text.c index 709df04..a7c4082 100644 --- a/libk/screen/text.c +++ b/libk/screen/text.c @@ -39,10 +39,10 @@ void drawChar(char c, uint32_t x, uint32_t y, uint32_t fgColor, uint32_t bgColor void scroll() { // TODO: Make this faster (still kinda slow, but memcpy32() helped alot) uint8_t charHeight = ((font_t*)FONT_LOC)->height; - if (terminal->y+1 < terminal->height) { return; } // Check if we should scroll + if (console->y+1 < console->height) { return; } // Check if we should scroll uint32_t bytesPerLine = charHeight * gfxMode->bytesPerScanline; - uint32_t lines = terminal->height; + uint32_t lines = console->height; uint32_t vidmem = gfxMode->physicalBasePtr; for (uint32_t i = 1; i < lines; i++) { @@ -50,7 +50,7 @@ void scroll() { // TODO: Make this faster (still kinda slow, but memcpy32() help memcpy32((char*)address, (char*)(address - bytesPerLine), bytesPerLine); } - uint32_t color = convertColor(terminal->bg); + uint32_t color = convertColor(console->bg); uint8_t* lastLine = (uint8_t*)(vidmem + (lines-1) * bytesPerLine); uint8_t bytesPerPx = (gfxMode->bpp+1) / 8; @@ -61,16 +61,16 @@ void scroll() { // TODO: Make this faster (still kinda slow, but memcpy32() help lastLine += bytesPerPx; } - terminal->y--; + console->y--; } -// TODO: Make this comply with the new terminal.h thing! +// TODO: Make this comply with the new console.h thing! void clearScreen(uint32_t bgColor) { uint8_t* vidmem = (uint8_t*)gfxMode->physicalBasePtr; uint8_t bytesPerPx = (gfxMode->bpp+1) / 8; - terminal->x = 0; - terminal->y = 0; + console->x = 0; + console->y = 0; uint32_t color = convertColor(bgColor); diff --git a/libk/syscalls/sys_close.c b/libk/syscalls/sys_close.c new file mode 100644 index 0000000..77894c9 --- /dev/null +++ b/libk/syscalls/sys_close.c @@ -0,0 +1,9 @@ +#include +#include +#include + +int sys_close(intFrame_t* iframe) { + // TODO + return -1; +} + diff --git a/libk/syscalls/sys_exit.c b/libk/syscalls/sys_exit.c new file mode 100644 index 0000000..38ec0ff --- /dev/null +++ b/libk/syscalls/sys_exit.c @@ -0,0 +1,9 @@ +#include +#include +#include + +int sys_exit(intFrame_t* iframe) { + debugf("Tried to exit with %d", iframe->eax); + return iframe->eax; +} + diff --git a/libk/syscalls/sys_free.c b/libk/syscalls/sys_free.c new file mode 100644 index 0000000..6a9ab40 --- /dev/null +++ b/libk/syscalls/sys_free.c @@ -0,0 +1,10 @@ +#include +#include +#include + +int sys_free(intFrame_t* iframe) { + void* ptr = (void*)iframe->ebx; + mallocFree(ptr); + return 0; +} + diff --git a/libk/syscalls/sys_malloc.c b/libk/syscalls/sys_malloc.c new file mode 100644 index 0000000..0178e0c --- /dev/null +++ b/libk/syscalls/sys_malloc.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +int sys_malloc(intFrame_t* iframe) { + size_t count = iframe->ebx; + + // First Malloc() + if (!mallocListHead) { + mallocInit(count); // Setup malloc linked list + } + + void* ptr = mallocNextNode(count); + mallocMergeFree(); + + return (size_t)ptr; +} diff --git a/libk/syscalls/sys_open.c b/libk/syscalls/sys_open.c new file mode 100644 index 0000000..3b7c330 --- /dev/null +++ b/libk/syscalls/sys_open.c @@ -0,0 +1,9 @@ +#include +#include +#include + +int sys_open(intFrame_t* iframe) { + // TODO + return -1; +} + diff --git a/libk/syscalls/sys_read.c b/libk/syscalls/sys_read.c new file mode 100644 index 0000000..e48214d --- /dev/null +++ b/libk/syscalls/sys_read.c @@ -0,0 +1,11 @@ +#include +#include +#include + +int sys_read(intFrame_t* iframe) { + char* s = (char*)iframe->ebx; + reads(s); + + return 0; +} + diff --git a/libk/syscalls/sys_seek.c b/libk/syscalls/sys_seek.c new file mode 100644 index 0000000..841927d --- /dev/null +++ b/libk/syscalls/sys_seek.c @@ -0,0 +1,8 @@ +#include +#include + +int sys_seek(intFrame_t* iframe) { + // TODO + return -1; +} + diff --git a/libk/syscalls/sys_sleep.c b/libk/syscalls/sys_sleep.c new file mode 100644 index 0000000..da2e16f --- /dev/null +++ b/libk/syscalls/sys_sleep.c @@ -0,0 +1,14 @@ +#include +#include +#include +#include + +int sys_sleep(intFrame_t* iframe) { + uint32_t* sleepTimerTicks = (uint32_t*)SLEEP_TIMER; + *sleepTimerTicks = iframe->ebx; + + while (*sleepTimerTicks > 0) { __asm__ volatile ("sti; hlt"); } + + return 0; +} + diff --git a/libk/syscalls/sys_write.c b/libk/syscalls/sys_write.c new file mode 100644 index 0000000..afbc52a --- /dev/null +++ b/libk/syscalls/sys_write.c @@ -0,0 +1,15 @@ +#include +#include +#include +#include + +int sys_write(intFrame_t* iframe) { + int fd = iframe->ebx; + void* buf = (void*)iframe->ecx; + size_t len = iframe->edx; + + if (fd == 1) { + return consoleWrite(buf, len); + } else { return -1; } +} + diff --git a/libk/syscalls/syscalls.c b/libk/syscalls/syscalls.c new file mode 100644 index 0000000..f539130 --- /dev/null +++ b/libk/syscalls/syscalls.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +// System call table +int (*syscalls[MAX_SYSCALLS])(intFrame_t*) = { + [SYS_EXIT] = sys_exit, + [SYS_READ] = sys_read, + [SYS_WRITE] = sys_write, + [SYS_OPEN] = sys_open, + [SYS_CLOSE] = sys_close, + [SYS_SEEK] = sys_seek, + [SYS_MALLOC] = sys_malloc, + [SYS_FREE] = sys_free, + [SYS_SLEEP] = sys_sleep, +}; + +// Syscall handler +int syscallHandler(intFrame_t* iframe) { + if (iframe->eax > MAX_SYSCALLS-1) { // Syscall doesn't exist + debugf("Error: Syscall(%d) does not exist!\n", iframe->eax); + return -1; + } + + return syscalls[iframe->eax](iframe); +} + diff --git a/libk/tty/tty.c b/libk/tty/tty.c index db56784..cce0ad8 100644 --- a/libk/tty/tty.c +++ b/libk/tty/tty.c @@ -7,11 +7,11 @@ #include #include -terminal_t* terminal = (terminal_t*)TERMINAL_INFO_LOC; +console_t* console = (console_t*)TERMINAL_INFO_LOC; -int32_t terminalWrite(const void* buf, uint32_t len) { // TODO fix font size - terminal->width = gfxMode->xRes / 8;//*(uint8_t*)(FONT_LOC); - terminal->height = gfxMode->yRes / 16;//*(uint8_t*)(FONT_LOC+1); +int32_t consoleWrite(const void* buf, uint32_t len) { // TODO fix font size + console->width = gfxMode->xRes / 8;//*(uint8_t*)(FONT_LOC); + console->height = gfxMode->yRes / 16;//*(uint8_t*)(FONT_LOC+1); char* str = (char*)buf; uint32_t i; @@ -19,18 +19,18 @@ int32_t terminalWrite(const void* buf, uint32_t len) { // TODO fix font size // Do we need to check for NULL? Can we just skip it/ignore it? for (i = 0; i < len && str[i] != '\0'; i++) { if (str[i] == '\n') { - drawChar(' ', terminal->x, terminal->y, terminal->fg, terminal->bg); - terminal->y++; - terminal->x = 0; + drawChar(' ', console->x, console->y, console->fg, console->bg); + console->y++; + console->x = 0; } else if (str[i] == '\b') { - drawChar(' ', terminal->x, terminal->y, terminal->fg, terminal->bg); - if (terminal->x == 0) { - terminal->x = terminal->width - 1; - terminal->y--; // Y could be 0? + drawChar(' ', console->x, console->y, console->fg, console->bg); + if (console->x == 0) { + console->x = console->width - 1; + console->y--; // Y could be 0? } else { - terminal->x--; + console->x--; } - drawChar(' ', terminal->x, terminal->y, terminal->fg, terminal->bg); + drawChar(' ', console->x, console->y, console->fg, console->bg); } else if (str[i] == '\x1b') { // Escape sequence if (str[++i] != '[') { // TODO: Support more types of escape sequences i--; @@ -57,33 +57,33 @@ int32_t terminalWrite(const void* buf, uint32_t len) { // TODO fix font size switch (str[i]) { // TODO: Add default values (see docs/escape.txt) case 'A': // Cursor up - terminal->y -= args[0]; + console->y -= args[0]; break; case 'B': // Cursor down - terminal->y += args[0]; + console->y += args[0]; break; case 'C': // Cursor left - terminal->x -= args[0]; + console->x -= args[0]; break; case 'D': // Cursor right - terminal->x += args[0]; + console->x += args[0]; break; case 'E': // nth row - terminal->x = args[0]; + console->x = args[0]; break; case 'F': // nth col - terminal->y = args[0]; + console->y = args[0]; break; case 'G': // show/hide cursor - terminal->hideCursor = args[0] ? false : true; + console->hideCursor = args[0] ? false : true; break; case 'H': // move cursor to (x,y) - terminal->x = args[0]; - terminal->y = args[1]; + console->x = args[0]; + console->y = args[1]; break; case 'I': // RESERVED case 'J': // Erase screen - clearScreen(terminal->bg); + clearScreen(console->bg); break; case 'K': // Erase line break; // TODO @@ -91,27 +91,27 @@ int32_t terminalWrite(const void* buf, uint32_t len) { // TODO fix font size break; // TODO case 'M': // Set FG if (args[0] < 8) { - terminal->fg = codeToColor(args[0]); + console->fg = codeToColor(args[0]); } else if (args[0] == 8) { - terminal->fg = FG_COLOR; + console->fg = FG_COLOR; } break; case 'N': // Set BG if (args[0] < 8) { - terminal->bg = codeToColor(args[0]); + console->bg = codeToColor(args[0]); } else if (args[0] == 8) { - terminal->bg = BG_COLOR; + console->bg = BG_COLOR; } break; default: break; } } else { - drawChar(str[i], terminal->x, terminal->y, terminal->fg, terminal->bg); - terminal->x++; + drawChar(str[i], console->x, console->y, console->fg, console->bg); + console->x++; - if (terminal->x >= terminal->width) { // Go to next line - terminal->y++; - terminal->x = 0; + if (console->x >= console->width) { // Go to next line + console->y++; + console->x = 0; } } } @@ -124,6 +124,6 @@ void toggleCursor() { static bool visible = false; visible = !visible; - drawChar(visible ? 127 : ' ', terminal->x, terminal->y, terminal->fg, terminal->bg); + drawChar(visible ? 127 : ' ', console->x, console->y, console->fg, console->bg); }