Major interrupt change

This commit is contained in:
2024-10-23 14:11:22 +02:00
parent 11feab5014
commit f163659f0c
38 changed files with 498 additions and 468 deletions
+13
View File
@@ -0,0 +1,13 @@
#include <error/debug.h>
#include <ports/serial.h>
#include <stdarg.h>
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;
}
+7
View File
@@ -0,0 +1,7 @@
#include <error/panic.h>
void panic() {
// TODO: print a message
while (1) { __asm__ volatile ("cli; hlt"); }
}
+3 -3
View File
@@ -47,15 +47,15 @@ void initOpenFileTable() {
// offset and ptr are unused in these // offset and ptr are unused in these
stdin = fsInfo->openFileTable + 0; stdin = fsInfo->openFileTable + 0;
stdin->_file = 0; stdin->_file = STDIN_FILENO;
stdin->_flag = O_RDONLY; stdin->_flag = O_RDONLY;
stdout = fsInfo->openFileTable + 1; stdout = fsInfo->openFileTable + 1;
stdout->_file = 1; stdout->_file = STDOUT_FILENO;
stdout->_flag = O_WRONLY | O_APPEND; stdout->_flag = O_WRONLY | O_APPEND;
stderr = fsInfo->openFileTable + 2; stderr = fsInfo->openFileTable + 2;
stderr->_file = 2; stderr->_file = STDERR_FILENO;
stderr->_flag = O_WRONLY | O_APPEND; stderr->_flag = O_WRONLY | O_APPEND;
fsInfo->openFiles = 3; fsInfo->openFiles = 3;
+6
View File
@@ -0,0 +1,6 @@
#ifndef ERROR_DEBUG_H
#define ERROR_DEBUG_H
int debugf(const char* fmt, ...);
#endif
+6
View File
@@ -0,0 +1,6 @@
#ifndef ERROR_PANIC_H
#define ERROR_PANIC_H
void panic();
#endif
+1 -9
View File
@@ -5,7 +5,7 @@
#define TRAP_GATE_FLAGS 0x8f // P = 1, DPL = 00, S = 0, Type = 1111 (32-bit Trap gate) #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 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 { typedef struct {
uint16_t offsetLow; uint16_t offsetLow;
@@ -20,14 +20,6 @@ typedef struct {
uint32_t base; uint32_t base;
} __attribute__ ((packed)) idtp_t; } __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 idtSetGate(uint8_t i, void* handler, uint8_t flags);
void setupIdt(); void setupIdt();
+27
View File
@@ -0,0 +1,27 @@
#ifndef INTERRUPT_ISR_H
#define INTERRUPT_ISR_H
#include <stdint.h>
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
-26
View File
@@ -1,26 +0,0 @@
#ifndef INTERRUPT_PIC_H
#define INTERRUPT_PIC_H
#include <stdint.h>
// 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
+2 -1
View File
@@ -1,13 +1,14 @@
#ifndef INTERRUPT_PIT_H #ifndef INTERRUPT_PIT_H
#define INTERRUPT_PIT_H #define INTERRUPT_PIT_H
#include <interrupt/isr.h>
#include <stdint.h> #include <stdint.h>
#define CHANNEL_0 0x40 // Offset it by 1 or 2 for ch1 and ch2 #define CHANNEL_0 0x40 // Offset it by 1 or 2 for ch1 and ch2
#define COMMAND 0x43 #define COMMAND 0x43
#define INPUT_CLK 1193182 #define INPUT_CLK 1193182
void timerHandler(intFrame_t*);
void setPitPhase(uint8_t channel, uint8_t opMode, uint16_t hz); void setPitPhase(uint8_t channel, uint8_t opMode, uint16_t hz);
void setupTimer();
#endif #endif
+2 -1
View File
@@ -1,6 +1,7 @@
#ifndef INTERRUPT_RTC_H #ifndef INTERRUPT_RTC_H
#define INTERRUPT_RTC_H #define INTERRUPT_RTC_H
#include <interrupt/isr.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
@@ -16,10 +17,10 @@ typedef struct {
uint16_t year; uint16_t year;
} __attribute__ ((packed)) datetime_t; } __attribute__ ((packed)) datetime_t;
void rtcHandler(intFrame_t*);
bool cmosUpdateProgress(); bool cmosUpdateProgress();
uint8_t getRtcRegister(uint8_t reg); uint8_t getRtcRegister(uint8_t reg);
void enableRtc(); void enableRtc();
void disableRtc(); void disableRtc();
void setupRtc();
#endif #endif
-24
View File
@@ -1,24 +0,0 @@
#ifndef INTERRUPT_SYSCALLS_H
#define INTERRUPT_SYSCALLS_H
#include <interrupt/idt.h>
#include <stdint.h>
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
+2 -1
View File
@@ -1,6 +1,7 @@
#ifndef KEYBOARD_KEYBOARD_H #ifndef KEYBOARD_KEYBOARD_H
#define KEYBOARD_KEYBOARD_H #define KEYBOARD_KEYBOARD_H
#include <interrupt/isr.h>
#include <stdbool.h> #include <stdbool.h>
typedef struct { typedef struct {
@@ -8,6 +9,6 @@ typedef struct {
bool shift; bool shift;
} keyboardState_t; } keyboardState_t;
void setupKeyboard(); void keyboardHandler(intFrame_t*);
#endif #endif
+1 -1
View File
@@ -18,7 +18,7 @@ int serialTransmitEmpty(uint32_t port);
int serialRecieved(uint32_t port); int serialRecieved(uint32_t port);
void serialWrite(uint32_t port, char c); 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); char serialRead(uint32_t port);
#endif #endif
+19
View File
@@ -0,0 +1,19 @@
#ifndef INTERRUPT_SYSCALLS_H
#define INTERRUPT_SYSCALLS_H
#include <interrupt/isr.h>
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
+3 -3
View File
@@ -13,11 +13,11 @@ typedef struct {
uint32_t height; // Height in characters uint32_t height; // Height in characters
char cursorChar; // Character to use as a cursor char cursorChar; // Character to use as a cursor
bool hideCursor; // Should we display the 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(); void toggleCursor();
#endif #endif
-48
View File
@@ -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);
}
+3 -1
View File
@@ -1,8 +1,10 @@
#include <interrupt/idt.h> #include <interrupt/idt.h>
#include <stdint.h> #include <stdint.h>
#define IDT_ENTRIES 256
__attribute__ ((aligned(0x10))) // For performance __attribute__ ((aligned(0x10))) // For performance
idtEntry_t idt[256] = { 0 }; idtEntry_t idt[IDT_ENTRIES] = { 0 };
idtp_t idtp; idtp_t idtp;
void idtSetGate(uint8_t i, void* handler, uint8_t flags) { void idtSetGate(uint8_t i, void* handler, uint8_t flags) {
+103
View File
@@ -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;
}
+116
View File
@@ -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
-79
View File
@@ -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
View File
@@ -1,23 +1,19 @@
#include <interrupt/pit.h> #include <interrupt/pit.h>
#include <interrupt/idt.h> #include <interrupt/isr.h>
#include <interrupt/pic.h>
#include <tty/tty.h> #include <tty/tty.h>
#include <memory/addresses.h> #include <memory/addresses.h>
#include <ports/io.h> #include <ports/io.h>
#include <stdint.h> #include <stdint.h>
__attribute__ ((interrupt)) void timerHandler(intFrame_t*) {
void timerHandler(intFrame_t* iframe) {
static uint32_t cursorTicks = 0; static uint32_t cursorTicks = 0;
cursorTicks++; 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 (cursorTicks % 500 == 0) toggleCursor();
} }
if (*(uint32_t*)SLEEP_TIMER > 0) { --(*(uint32_t*)SLEEP_TIMER); } if (*(uint32_t*)SLEEP_TIMER > 0) { --(*(uint32_t*)SLEEP_TIMER); }
sendPicEOI(0);
} }
void setPitPhase(uint8_t channel, uint8_t opMode, uint16_t hz) { 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"); __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
View File
@@ -1,6 +1,5 @@
#include <interrupt/rtc.h> #include <interrupt/rtc.h>
#include <interrupt/pic.h> #include <interrupt/isr.h>
#include <interrupt/idt.h>
#include <screen/text.h> #include <screen/text.h>
#include <screen/gfxmode.h> #include <screen/gfxmode.h>
#include <tty/tty.h> #include <tty/tty.h>
@@ -36,7 +35,7 @@ void disableRtc() {
__asm__ volatile ("sti"); __asm__ volatile ("sti");
} }
__attribute__ ((interrupt)) void rtcHandler(intFrame_t* iframe) { void rtcHandler(intFrame_t* iframe) {
datetime_t newDatetime, oldDatetime; datetime_t newDatetime, oldDatetime;
static uint16_t rtcTicks = 0; static uint16_t rtcTicks = 0;
@@ -121,20 +120,13 @@ __attribute__ ((interrupt)) void rtcHandler(intFrame_t* iframe) {
uint32_t x = gfxMode->xRes - len - 1; uint32_t x = gfxMode->xRes - len - 1;
char* str = &buf[0]; char* str = &buf[0];
for (uint8_t i = 0; i != len; i++, x++) { 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); getRtcRegister(0x0c);
sendPicEOI(8);
__asm__ volatile ("sti"); __asm__ volatile ("sti");
} }
void setupRtc() { // IRQ 8 - Real Time Clock
idtSetGate(0x28, rtcHandler, INT_GATE_FLAGS);
unsetIrqMask(8);
enableRtc();
}
-194
View File
@@ -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)
);
}
+2 -11
View File
@@ -1,6 +1,5 @@
#include <keyboard/keyboard.h> #include <keyboard/keyboard.h>
#include <interrupt/idt.h> #include <interrupt/isr.h>
#include <interrupt/pic.h>
#include <keyboard/keys.h> #include <keyboard/keys.h>
#include <memory/addresses.h> #include <memory/addresses.h>
#include <ports/io.h> #include <ports/io.h>
@@ -10,8 +9,7 @@
static const uint8_t US_Keyboard[2][128] = US_KEYBOARD; static const uint8_t US_Keyboard[2][128] = US_KEYBOARD;
keyboardState_t* keyboard = (keyboardState_t*)KEYBOARD_STATE_LOC; keyboardState_t* keyboard = (keyboardState_t*)KEYBOARD_STATE_LOC;
__attribute__ ((interrupt)) void keyboardHandler(intFrame_t*) { // TODO: Make this better and be able to read multi-byte scancode
void keyboardHandler(intFrame_t* iframe) { // TODO: Make this better and be able to read multi-byte scancode
uint8_t scancode = inb(0x60); uint8_t scancode = inb(0x60);
char c = US_Keyboard[keyboard->shift][scancode]; 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') { } else if (c != '\0') {
keyboard->character = c; keyboard->character = c;
} }
sendPicEOI(1);
}
void setupKeyboard() {
idtSetGate(0x21, keyboardHandler, INT_GATE_FLAGS);
unsetIrqMask(1);
} }
+4 -1
View File
@@ -4,8 +4,11 @@
include make.defaults include make.defaults
$(LIBK): $(LIBK_SRC) LIBK_ASM=$(LIBK_DIR)/interrupt/isr.s
$(LIBK): $(LIBK_SRC) $(LIBK_ASM)
@echo "Building $(LIBK)..." @echo "Building $(LIBK)..."
nasm -felf32 -o $(BIN)/libk/isr_asm.o $(LIBK_ASM)
for f in $(LIBK_SRC); do\ for f in $(LIBK_SRC); do\
filename=$$(basename $$f .c);\ filename=$$(basename $$f .c);\
$(CC) $(CFLAGS) -I$(LIBC_INC) -I$(LIBK_INC) -o $(BIN)/libk/$$filename.o -c $$f;\ $(CC) $(CFLAGS) -I$(LIBC_INC) -I$(LIBK_INC) -o $(BIN)/libk/$$filename.o -c $$f;\
+1 -1
View File
@@ -32,7 +32,7 @@ void serialWrite(uint32_t port, char c) {
outb(port, c); outb(port, c);
} }
void serialPrint(uint32_t port, char* s) { void serialPrint(uint32_t port, const char* s) {
while (*s != '\0') { while (*s != '\0') {
if (*s == '\n') serialWrite(port, '\r'); if (*s == '\n') serialWrite(port, '\r');
serialWrite(port, *s++); serialWrite(port, *s++);
+7 -7
View File
@@ -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) void scroll() { // TODO: Make this faster (still kinda slow, but memcpy32() helped alot)
uint8_t charHeight = ((font_t*)FONT_LOC)->height; 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 bytesPerLine = charHeight * gfxMode->bytesPerScanline;
uint32_t lines = terminal->height; uint32_t lines = console->height;
uint32_t vidmem = gfxMode->physicalBasePtr; uint32_t vidmem = gfxMode->physicalBasePtr;
for (uint32_t i = 1; i < lines; i++) { 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); 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* lastLine = (uint8_t*)(vidmem + (lines-1) * bytesPerLine);
uint8_t bytesPerPx = (gfxMode->bpp+1) / 8; 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; 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) { void clearScreen(uint32_t bgColor) {
uint8_t* vidmem = (uint8_t*)gfxMode->physicalBasePtr; uint8_t* vidmem = (uint8_t*)gfxMode->physicalBasePtr;
uint8_t bytesPerPx = (gfxMode->bpp+1) / 8; uint8_t bytesPerPx = (gfxMode->bpp+1) / 8;
terminal->x = 0; console->x = 0;
terminal->y = 0; console->y = 0;
uint32_t color = convertColor(bgColor); uint32_t color = convertColor(bgColor);
+9
View File
@@ -0,0 +1,9 @@
#include <syscalls/syscalls.h>
#include <interrupt/isr.h>
#include <stdio.h>
int sys_close(intFrame_t* iframe) {
// TODO
return -1;
}
+9
View File
@@ -0,0 +1,9 @@
#include <syscalls/syscalls.h>
#include <interrupt/isr.h>
#include <error/debug.h>
int sys_exit(intFrame_t* iframe) {
debugf("Tried to exit with %d", iframe->eax);
return iframe->eax;
}
+10
View File
@@ -0,0 +1,10 @@
#include <syscalls/syscalls.h>
#include <interrupt/isr.h>
#include <memory/malloc.h>
int sys_free(intFrame_t* iframe) {
void* ptr = (void*)iframe->ebx;
mallocFree(ptr);
return 0;
}
+18
View File
@@ -0,0 +1,18 @@
#include <syscalls/syscalls.h>
#include <interrupt/isr.h>
#include <memory/malloc.h>
#include <stddef.h>
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;
}
+9
View File
@@ -0,0 +1,9 @@
#include <syscalls/syscalls.h>
#include <interrupt/isr.h>
#include <stdio.h>
int sys_open(intFrame_t* iframe) {
// TODO
return -1;
}
+11
View File
@@ -0,0 +1,11 @@
#include <syscalls/syscalls.h>
#include <interrupt/isr.h>
#include <stdio.h>
int sys_read(intFrame_t* iframe) {
char* s = (char*)iframe->ebx;
reads(s);
return 0;
}
+8
View File
@@ -0,0 +1,8 @@
#include <syscalls/syscalls.h>
#include <interrupt/isr.h>
int sys_seek(intFrame_t* iframe) {
// TODO
return -1;
}
+14
View File
@@ -0,0 +1,14 @@
#include <syscalls/syscalls.h>
#include <interrupt/isr.h>
#include <memory/addresses.h>
#include <stdint.h>
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;
}
+15
View File
@@ -0,0 +1,15 @@
#include <syscalls/syscalls.h>
#include <tty/tty.h>
#include <interrupt/isr.h>
#include <stddef.h>
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; }
}
+28
View File
@@ -0,0 +1,28 @@
#include <syscalls/syscalls.h>
#include <interrupt/isr.h>
#include <error/debug.h>
#include <syscall.h>
// 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);
}
+33 -33
View File
@@ -7,11 +7,11 @@
#include <stdbool.h> #include <stdbool.h>
#include <sys/gfx.h> #include <sys/gfx.h>
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 int32_t consoleWrite(const void* buf, uint32_t len) { // TODO fix font size
terminal->width = gfxMode->xRes / 8;//*(uint8_t*)(FONT_LOC); console->width = gfxMode->xRes / 8;//*(uint8_t*)(FONT_LOC);
terminal->height = gfxMode->yRes / 16;//*(uint8_t*)(FONT_LOC+1); console->height = gfxMode->yRes / 16;//*(uint8_t*)(FONT_LOC+1);
char* str = (char*)buf; char* str = (char*)buf;
uint32_t i; 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? // Do we need to check for NULL? Can we just skip it/ignore it?
for (i = 0; i < len && str[i] != '\0'; i++) { for (i = 0; i < len && str[i] != '\0'; i++) {
if (str[i] == '\n') { if (str[i] == '\n') {
drawChar(' ', terminal->x, terminal->y, terminal->fg, terminal->bg); drawChar(' ', console->x, console->y, console->fg, console->bg);
terminal->y++; console->y++;
terminal->x = 0; console->x = 0;
} else if (str[i] == '\b') { } else if (str[i] == '\b') {
drawChar(' ', terminal->x, terminal->y, terminal->fg, terminal->bg); drawChar(' ', console->x, console->y, console->fg, console->bg);
if (terminal->x == 0) { if (console->x == 0) {
terminal->x = terminal->width - 1; console->x = console->width - 1;
terminal->y--; // Y could be 0? console->y--; // Y could be 0?
} else { } 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 } else if (str[i] == '\x1b') { // Escape sequence
if (str[++i] != '[') { // TODO: Support more types of escape sequences if (str[++i] != '[') { // TODO: Support more types of escape sequences
i--; 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) switch (str[i]) { // TODO: Add default values (see docs/escape.txt)
case 'A': // Cursor up case 'A': // Cursor up
terminal->y -= args[0]; console->y -= args[0];
break; break;
case 'B': // Cursor down case 'B': // Cursor down
terminal->y += args[0]; console->y += args[0];
break; break;
case 'C': // Cursor left case 'C': // Cursor left
terminal->x -= args[0]; console->x -= args[0];
break; break;
case 'D': // Cursor right case 'D': // Cursor right
terminal->x += args[0]; console->x += args[0];
break; break;
case 'E': // nth row case 'E': // nth row
terminal->x = args[0]; console->x = args[0];
break; break;
case 'F': // nth col case 'F': // nth col
terminal->y = args[0]; console->y = args[0];
break; break;
case 'G': // show/hide cursor case 'G': // show/hide cursor
terminal->hideCursor = args[0] ? false : true; console->hideCursor = args[0] ? false : true;
break; break;
case 'H': // move cursor to (x,y) case 'H': // move cursor to (x,y)
terminal->x = args[0]; console->x = args[0];
terminal->y = args[1]; console->y = args[1];
break; break;
case 'I': // RESERVED case 'I': // RESERVED
case 'J': // Erase screen case 'J': // Erase screen
clearScreen(terminal->bg); clearScreen(console->bg);
break; break;
case 'K': // Erase line case 'K': // Erase line
break; // TODO break; // TODO
@@ -91,27 +91,27 @@ int32_t terminalWrite(const void* buf, uint32_t len) { // TODO fix font size
break; // TODO break; // TODO
case 'M': // Set FG case 'M': // Set FG
if (args[0] < 8) { if (args[0] < 8) {
terminal->fg = codeToColor(args[0]); console->fg = codeToColor(args[0]);
} else if (args[0] == 8) { } else if (args[0] == 8) {
terminal->fg = FG_COLOR; console->fg = FG_COLOR;
} }
break; break;
case 'N': // Set BG case 'N': // Set BG
if (args[0] < 8) { if (args[0] < 8) {
terminal->bg = codeToColor(args[0]); console->bg = codeToColor(args[0]);
} else if (args[0] == 8) { } else if (args[0] == 8) {
terminal->bg = BG_COLOR; console->bg = BG_COLOR;
} }
break; break;
default: break; default: break;
} }
} else { } else {
drawChar(str[i], terminal->x, terminal->y, terminal->fg, terminal->bg); drawChar(str[i], console->x, console->y, console->fg, console->bg);
terminal->x++; console->x++;
if (terminal->x >= terminal->width) { // Go to next line if (console->x >= console->width) { // Go to next line
terminal->y++; console->y++;
terminal->x = 0; console->x = 0;
} }
} }
} }
@@ -124,6 +124,6 @@ void toggleCursor() {
static bool visible = false; static bool visible = false;
visible = !visible; visible = !visible;
drawChar(visible ? 127 : ' ', terminal->x, terminal->y, terminal->fg, terminal->bg); drawChar(visible ? 127 : ' ', console->x, console->y, console->fg, console->bg);
} }