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:
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#include <error/panic.h>
|
||||||
|
|
||||||
|
void panic() {
|
||||||
|
// TODO: print a message
|
||||||
|
while (1) { __asm__ volatile ("cli; hlt"); }
|
||||||
|
}
|
||||||
|
|
||||||
+3
-3
@@ -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;
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef ERROR_DEBUG_H
|
||||||
|
#define ERROR_DEBUG_H
|
||||||
|
|
||||||
|
int debugf(const char* fmt, ...);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef ERROR_PANIC_H
|
||||||
|
#define ERROR_PANIC_H
|
||||||
|
|
||||||
|
void panic();
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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 <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) {
|
||||||
|
|||||||
@@ -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/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
@@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#include <syscalls/syscalls.h>
|
||||||
|
#include <interrupt/isr.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int sys_close(intFrame_t* iframe) {
|
||||||
|
// TODO
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#include <syscalls/syscalls.h>
|
||||||
|
#include <interrupt/isr.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int sys_open(intFrame_t* iframe) {
|
||||||
|
// TODO
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#include <syscalls/syscalls.h>
|
||||||
|
#include <interrupt/isr.h>
|
||||||
|
|
||||||
|
int sys_seek(intFrame_t* iframe) {
|
||||||
|
// TODO
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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; }
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user