uhm pretty much fully implemented IRQ stuff, just need to implement proper handlers but will do later (maybe)

This commit is contained in:
Tyler McGurrin 2025-02-27 02:06:04 -05:00
parent 55995a37db
commit a40ab1c13a
16 changed files with 263 additions and 21 deletions

View File

@ -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

View File

@ -3,4 +3,4 @@
|Copyright (C) 2024|
|Tyler McGurrin |
\*----------------*/
#include "basicdri.h"
#include "basicfunc.h"

View File

@ -5,4 +5,4 @@
\*----------------*/
#pragma once
void __attribute__((cdecl)) reboot();
void __attribute__((cdecl)) i686_reboot();

View File

@ -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

View File

@ -2,4 +2,12 @@
|Nanite OS |
|Copyright (C) 2024|
|Tyler McGurrin |
\*----------------*/
\*----------------*/
#include "io.h"
#define UNUSED_PORT 0x80
void i686_iowait()
{
i686_outb(UNUSED_PORT, 0);
}

View File

@ -7,8 +7,10 @@
#include <stdint.h>
#include <stdbool.h>
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();

View File

@ -0,0 +1,48 @@
/*----------------*\
|Nanite OS |
|Copyright (C) 2024|
|Tyler McGurrin |
\*----------------*/
#include "irq.h"
#include "pic.h"
#include "io.h"
#include <stddef.h>
#include <stdio.h>
#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;
}

View File

@ -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);

View File

@ -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);
}

View File

@ -19,4 +19,4 @@ typedef struct
typedef void (*ISRHandler)(Registers* regs);
void i686_ISR_Initialize();
void i686_ISR_RegisterHandler(int interrupt);
void i686_ISR_RegisterHandler(int interrupt, ISRHandler handler);

131
src/kernel/arch/i686/pic.c Normal file
View File

@ -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);
}

View File

@ -0,0 +1,15 @@
/*----------------*\
|Nanite OS |
|Copyright (C) 2024|
|Tyler McGurrin |
\*----------------*/
#pragma once
#include <stdint.h>
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();

View File

@ -7,6 +7,7 @@
#include <arch/i686/gdt.h>
#include <arch/i686/idt.h>
#include <arch/i686/isr.h>
#include <arch/i686/irq.h>
#include <stdio.h>
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");
}

0
src/kernel/hal/isrs.h Normal file
View File

View File

@ -8,13 +8,19 @@
#include <memory.h>
#include <hal/hal.h>
#include <arch/i686/io.h>
#include <arch/i686/basicdri.h>
#include <arch/i686/irq.h>
#include <arch/i686/basicfunc.h>
#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:

View File

@ -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()