diff --git a/src/kernel/arch/i686/basicdri.asm b/src/kernel/arch/i686/basicfunc.asm similarity index 69% rename from src/kernel/arch/i686/basicdri.asm rename to src/kernel/arch/i686/basicfunc.asm index c7f2c90..aa00457 100644 --- a/src/kernel/arch/i686/basicdri.asm +++ b/src/kernel/arch/i686/basicfunc.asm @@ -1,11 +1,11 @@ [bits 32] -global reboot -reboot: +global i686_reboot +i686_reboot: XOR AL, AL IN AL, 0x64 TEST AL, 0x02 - JNZ reboot + JNZ i686_reboot MOV AL, 0xFC OUT 0x64, AL diff --git a/src/kernel/arch/i686/basicdri.c b/src/kernel/arch/i686/basicfunc.c similarity index 82% rename from src/kernel/arch/i686/basicdri.c rename to src/kernel/arch/i686/basicfunc.c index 57b7677..2234de9 100644 --- a/src/kernel/arch/i686/basicdri.c +++ b/src/kernel/arch/i686/basicfunc.c @@ -3,4 +3,4 @@ |Copyright (C) 2024| |Tyler McGurrin | \*----------------*/ -#include "basicdri.h" \ No newline at end of file +#include "basicfunc.h" \ No newline at end of file diff --git a/src/kernel/arch/i686/basicdri.h b/src/kernel/arch/i686/basicfunc.h similarity index 73% rename from src/kernel/arch/i686/basicdri.h rename to src/kernel/arch/i686/basicfunc.h index 4da40ec..c517d99 100644 --- a/src/kernel/arch/i686/basicdri.h +++ b/src/kernel/arch/i686/basicfunc.h @@ -5,4 +5,4 @@ \*----------------*/ #pragma once -void __attribute__((cdecl)) reboot(); +void __attribute__((cdecl)) i686_reboot(); diff --git a/src/kernel/arch/i686/io.asm b/src/kernel/arch/i686/io.asm index d875e0c..27f6bfc 100644 --- a/src/kernel/arch/i686/io.asm +++ b/src/kernel/arch/i686/io.asm @@ -4,16 +4,16 @@ ;Tyler McGurrin ; ;/////////////////////; -global outb -outb: +global i686_outb +i686_outb: [bits 32] mov dx, [esp + 4] mov al, [esp + 8] out dx, al ret -global inb -inb: +global i686_inb +i686_inb: [bits 32] mov dx, [esp + 4] xor eax, eax @@ -24,3 +24,13 @@ global i686_panic i686_panic: cli hlt + +global i686_EnableInterrupts +i686_EnableInterrupts: + sti + ret + +global i686_DisableInterrupts +i686_DisableInterrupts: + cli + ret diff --git a/src/kernel/arch/i686/io.c b/src/kernel/arch/i686/io.c index ec047f2..e76d949 100644 --- a/src/kernel/arch/i686/io.c +++ b/src/kernel/arch/i686/io.c @@ -2,4 +2,12 @@ |Nanite OS | |Copyright (C) 2024| |Tyler McGurrin | -\*----------------*/ \ No newline at end of file +\*----------------*/ +#include "io.h" + +#define UNUSED_PORT 0x80 + +void i686_iowait() +{ + i686_outb(UNUSED_PORT, 0); +} \ No newline at end of file diff --git a/src/kernel/arch/i686/io.h b/src/kernel/arch/i686/io.h index 0303d56..db5cb49 100644 --- a/src/kernel/arch/i686/io.h +++ b/src/kernel/arch/i686/io.h @@ -7,8 +7,10 @@ #include #include -void __attribute__((cdecl)) outb(uint16_t port, uint8_t value); -uint8_t __attribute__((cdecl)) inb(uint16_t port); +void __attribute__((cdecl)) i686_outb(uint16_t port, uint8_t value); +uint8_t __attribute__((cdecl)) i686_inb(uint16_t port); +uint8_t __attribute__((cdecl)) i686_EnableInterrupts(); +uint8_t __attribute__((cdecl)) i686_DisableInterrupts(); void i686_iowait(); void __attribute__((cdecl)) i686_panic(); diff --git a/src/kernel/arch/i686/irq.c b/src/kernel/arch/i686/irq.c new file mode 100644 index 0000000..41a7cea --- /dev/null +++ b/src/kernel/arch/i686/irq.c @@ -0,0 +1,48 @@ +/*----------------*\ +|Nanite OS | +|Copyright (C) 2024| +|Tyler McGurrin | +\*----------------*/ +#include "irq.h" +#include "pic.h" +#include "io.h" +#include +#include + +#define PIC_REMAP_OFFSET 0x20 + +IRQHandler g_IRQHandlers[16]; + +void i686_IRQ_Handler(Registers* regs) +{ + int irq = regs->interrupt - PIC_REMAP_OFFSET; + + if (g_IRQHandlers[irq] != NULL) + { + // handle IRQ + g_IRQHandlers[irq](regs); + } + else + { + printf("Unhandled IRQ %d...\n", irq); + } + + i686_PIC_SendEndOfInterrupt(irq); +} + +void i686_IRQ_Initialize() +{ + i686_PIC_Configure(PIC_REMAP_OFFSET, PIC_REMAP_OFFSET + 8); + + // register ISR handlers for each of the 16 IRQ lines + for (int i = 0; i < 16; i++) + i686_ISR_RegisterHandler(PIC_REMAP_OFFSET + i, i686_IRQ_Handler); + + // enable interrupts + i686_EnableInterrupts(); +} + +void i686_IRQ_RegisterHandler(int irq, IRQHandler handler) +{ + g_IRQHandlers[irq] = handler; +} \ No newline at end of file diff --git a/src/kernel/arch/i686/irq.h b/src/kernel/arch/i686/irq.h new file mode 100644 index 0000000..ac473da --- /dev/null +++ b/src/kernel/arch/i686/irq.h @@ -0,0 +1,12 @@ +/*----------------*\ +|Nanite OS | +|Copyright (C) 2024| +|Tyler McGurrin | +\*----------------*/ +#pragma once +#include "isr.h" + +typedef void (*IRQHandler)(Registers* regs); + +void i686_IRQ_Initialize(); +void i686_IRQ_RegisterHandler(int irq, IRQHandler handler); \ No newline at end of file diff --git a/src/kernel/arch/i686/isr.c b/src/kernel/arch/i686/isr.c index beb151e..dfd6f88 100644 --- a/src/kernel/arch/i686/isr.c +++ b/src/kernel/arch/i686/isr.c @@ -72,4 +72,9 @@ void __attribute__((cdecl)) i686_ISR_Handler(Registers* regs) { i686_panic(); } +} +void i686_ISR_RegisterHandler(int interrupt, ISRHandler handler) +{ + g_ISRHandlers[interrupt] = handler; + i686_IDT_EnableGate(interrupt); } \ No newline at end of file diff --git a/src/kernel/arch/i686/isr.h b/src/kernel/arch/i686/isr.h index e27820b..9c52b63 100644 --- a/src/kernel/arch/i686/isr.h +++ b/src/kernel/arch/i686/isr.h @@ -19,4 +19,4 @@ typedef struct typedef void (*ISRHandler)(Registers* regs); void i686_ISR_Initialize(); -void i686_ISR_RegisterHandler(int interrupt); \ No newline at end of file +void i686_ISR_RegisterHandler(int interrupt, ISRHandler handler); \ No newline at end of file diff --git a/src/kernel/arch/i686/pic.c b/src/kernel/arch/i686/pic.c new file mode 100644 index 0000000..d6f16b6 --- /dev/null +++ b/src/kernel/arch/i686/pic.c @@ -0,0 +1,131 @@ +/*----------------*\ +|Nanite OS | +|Copyright (C) 2024| +|Tyler McGurrin | +\*----------------*/ +#include "pic.h" +#include "io.h" + +#define PIC1_COMMAND_PORT 0x20 +#define PIC2_COMMAND_PORT 0xA0 +#define PIC1_DATA_PORT 0x21 +#define PIC2_DATA_PORT 0xA1 + +enum { + PIC_ICW1_ICW4 = 0x01, + PIC_ICW1_SINGLE = 0x02, + PIC_ICW1_INTERVAL4 = 0x02, + PIC_ICW1_LEVEL = 0x08, + PIC_ICW1_INITITALIZE = 0x10 +} PIC_ICW1; + +enum { + PIC_ICW4_8086 = 0x1, + PIC_ICW4_AUTO_EDI = 0x2, + PIC_ICW4_BUFFER_MASTER = 0x4, + PIC_ICW4_BUFFER_SLAVE = 0x0, + PIC_ICW4_BUFFERRED = 0x8, + PIC_ICW4_SFNM = 0x10 +} PIC_ICW4; + +enum { + PIC_CMD_END_OF_INTERRUPT = 0x20, + PIC_CMD_READ_IRR = 0x0A, + PIC_CMD_READ_ISR = 0x0B +} PIC_CMD; + +void i686_PIC_Configure(uint8_t offsetPic1, uint8_t offsetPic2) +{ + // init control word 1 + i686_outb(PIC1_COMMAND_PORT, PIC_ICW1_ICW4 | PIC_ICW1_INITITALIZE); + i686_iowait(); + i686_outb(PIC2_COMMAND_PORT, PIC_ICW1_ICW4 | PIC_ICW1_INITITALIZE); + i686_iowait(); + + // init control word 2 + i686_outb(PIC1_DATA_PORT, offsetPic1); + i686_iowait(); + i686_outb(PIC2_DATA_PORT, offsetPic2); + i686_iowait(); + + // init control word 3 + i686_outb(PIC1_DATA_PORT, PIC_ICW4_BUFFER_MASTER); // tell PIC 1 it has slave at IRQ 2 + i686_iowait(); + i686_outb(PIC2_DATA_PORT, PIC_ICW4_BUFFER_SLAVE); // tell PIC 2 its cascade ID + i686_iowait(); + + // init control word 4 + i686_outb(PIC1_DATA_PORT, PIC_ICW4_8086); + i686_iowait(); + i686_outb(PIC2_DATA_PORT, PIC_ICW4_8086); + i686_iowait(); + + // clear data registers + i686_outb(PIC1_DATA_PORT, 0); + i686_iowait(); + i686_outb(PIC2_DATA_PORT, 0); + i686_iowait(); +} + +void i686_PIC_Mask(int irq) +{ + uint8_t port; + + if (irq < 8) + { + port = PIC1_DATA_PORT; + } + else + { + irq -=8; + port = PIC2_DATA_PORT; + } + uint8_t mask = i686_inb(port); + i686_outb(port, mask | (1 << irq)); +} + +void i686_PIC_Unmask(int irq) +{ + uint8_t port; + + if (irq < 8) + { + port = PIC1_DATA_PORT; + } + else + { + irq -=8; + port = PIC2_DATA_PORT; + } + uint8_t mask = i686_inb(port); + i686_outb(port, mask & ~(1 << irq)); +} + +void i686_PIC_Disable() +{ + i686_outb(PIC1_DATA_PORT, 0xFF); + i686_iowait(); + i686_outb(PIC2_DATA_PORT, 0xFF); + i686_iowait(); +} + +void i686_PIC_SendEndOfInterrupt(int irq) +{ + if (irq >= 8) + i686_outb(PIC2_COMMAND_PORT, PIC_CMD_END_OF_INTERRUPT); + i686_outb(PIC1_COMMAND_PORT, PIC_CMD_END_OF_INTERRUPT); +} + +uint16_t i686_PIC_ReadIRQRequestRegister() +{ + i686_outb(PIC1_COMMAND_PORT, PIC_CMD_READ_IRR); + i686_outb(PIC2_COMMAND_PORT, PIC_CMD_READ_IRR); + return i686_inb(PIC2_COMMAND_PORT) | (i686_inb(PIC2_COMMAND_PORT) << 8); +} + +uint16_t i686_PIC_ReadInServiceRegister() +{ + i686_outb(PIC1_COMMAND_PORT, PIC_CMD_READ_ISR); + i686_outb(PIC2_COMMAND_PORT, PIC_CMD_READ_ISR); + return i686_inb(PIC2_COMMAND_PORT) | (i686_inb(PIC2_COMMAND_PORT) << 8); +} \ No newline at end of file diff --git a/src/kernel/arch/i686/pic.h b/src/kernel/arch/i686/pic.h new file mode 100644 index 0000000..70d287f --- /dev/null +++ b/src/kernel/arch/i686/pic.h @@ -0,0 +1,15 @@ +/*----------------*\ +|Nanite OS | +|Copyright (C) 2024| +|Tyler McGurrin | +\*----------------*/ +#pragma once + +#include +void i686_PIC_Configure(uint8_t offsetPic1, uint8_t offsetPic2); +void i686_PIC_SendEndOfInterrupt(int irq); +void i686_PIC_Disable(); +void i686_PIC_Mask(int irq); +void i686_PIC_Unmask(int irq); +uint16_t i686_PIC_ReadIRQRequestRegister(); +uint16_t i686_PIC_ReadInServiceRegister(); \ No newline at end of file diff --git a/src/kernel/hal/hal.c b/src/kernel/hal/hal.c index 6da7bfa..149ddd0 100644 --- a/src/kernel/hal/hal.c +++ b/src/kernel/hal/hal.c @@ -7,6 +7,7 @@ #include #include #include +#include #include void HAL_Initialize() { @@ -22,5 +23,9 @@ void HAL_Initialize() { printf("> Initializing ISR..."); i686_ISR_Initialize(); printf("Done!\n"); + // init IRQ + printf("> Initializing IRQ Handling..."); + i686_IRQ_Initialize(); + printf("Done!\n"); } \ No newline at end of file diff --git a/src/kernel/hal/isrs.h b/src/kernel/hal/isrs.h new file mode 100644 index 0000000..e69de29 diff --git a/src/kernel/main.c b/src/kernel/main.c index 4002842..cc9d467 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -8,13 +8,19 @@ #include #include #include -#include +#include +#include #include "../version.h" extern uint8_t __bss_start; extern uint8_t __end; - void __attribute__((section(".entry"))) start(uint16_t bootDrive) { +void timer(Registers* regs) +{ + printf("."); +} + +void __attribute__((section(".entry"))) start(uint16_t bootDrive) { // print logo clrscr(); @@ -26,9 +32,9 @@ extern uint8_t __end; printf("Initializing HAL...\n"); HAL_Initialize(); movecursorpos(19, 8); - printf("Done!\n\n\n\n"); - + printf("Done!\n\n\n\n\n"); + i686_IRQ_RegisterHandler(0, timer); end: diff --git a/src/kernel/stdio.c b/src/kernel/stdio.c index 8850e41..6ee5718 100644 --- a/src/kernel/stdio.c +++ b/src/kernel/stdio.c @@ -51,10 +51,10 @@ void setcursor(int x, int y) { int pos = y * SCREEN_WIDTH + x; - outb(0x3D4, 0x0F); - outb(0x3D5, (uint8_t)(pos & 0xFF)); - outb(0x3D4, 0x0E); - outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF)); + i686_outb(0x3D4, 0x0F); + i686_outb(0x3D5, (uint8_t)(pos & 0xFF)); + i686_outb(0x3D4, 0x0E); + i686_outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF)); } void clrscr()