Files
net/platform/x86.c
2025-12-20 18:49:21 -08:00

104 lines
2.7 KiB
C

#include <stddef.h>
#include <stdint.h>
#include <exec/hal.h>
#include <exec/task.h>
#include <exec/irq.h>
#pragma pack(push, 1)
struct Idtr {
uint16_t limit;
uintptr_t base;
};
struct IdtEntry {
uint16_t offset_low;
uint16_t selector;
uint8_t zero;
uint8_t type_attr;
uint16_t offset_high;
};
struct InitialContext {
uint32_t eflags; /* PUSHF / POPF */
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; /* PUSHA / POPA */
uint32_t eip, final_eip;
};
struct IRQFrame {
uint32_t irq, eflags, cs, eip;
};
#pragma pack(pop)
struct Idtr idtr;
struct IdtEntry idt[256];
extern void irq0(void);
extern void irq1(void);
extern void irq2(void);
extern void irq3(void);
extern void irq4(void);
extern void irq5(void);
extern void irq6(void);
extern void irq7(void);
extern void irq8(void);
extern void irq9(void);
extern void irq10(void);
extern void irq11(void);
extern void irq12(void);
extern void irq13(void);
extern void irq14(void);
extern void irq15(void);
void IDT32_SetEntry(int vector, uintptr_t handler) {
idt[vector].offset_low = handler & 0xFFFF;
idt[vector].selector = 0x08; // Code segment selector
idt[vector].zero = 0;
idt[vector].type_attr = 0x8E; // Interrupt gate, present
idt[vector].offset_high = (handler >> 16) & 0xFFFF;
}
void IDT32_Initialize(void) {
idtr.base = (uintptr_t)&idt;
idtr.limit = sizeof(idt) - 1;
IDT32_SetEntry(32, (uintptr_t)&irq0);
IDT32_SetEntry(33, (uintptr_t)&irq1);
IDT32_SetEntry(34, (uintptr_t)&irq2);
IDT32_SetEntry(35, (uintptr_t)&irq3);
IDT32_SetEntry(36, (uintptr_t)&irq4);
IDT32_SetEntry(37, (uintptr_t)&irq5);
IDT32_SetEntry(38, (uintptr_t)&irq6);
IDT32_SetEntry(39, (uintptr_t)&irq7);
IDT32_SetEntry(40, (uintptr_t)&irq8);
IDT32_SetEntry(41, (uintptr_t)&irq9);
IDT32_SetEntry(42, (uintptr_t)&irq10);
IDT32_SetEntry(43, (uintptr_t)&irq11);
IDT32_SetEntry(44, (uintptr_t)&irq12);
IDT32_SetEntry(45, (uintptr_t)&irq13);
IDT32_SetEntry(45, (uintptr_t)&irq14);
IDT32_SetEntry(45, (uintptr_t)&irq15);
asm("lidt %0" : : "m"(idtr));
}
__attribute__((interrupt))
void X86_CommonIRQHandler(struct IRQFrame *frame, int irq) {
if (irq) {
InterruptDispatch(irq);
HalAcknowledgeInterrupt(irq);
} else {
/* PIT */
execTicks++;
HalAcknowledgeInterrupt(irq);
Yield();
}
}
void X86_SetupTask(struct Task *task, uintptr_t initial_pc, uintptr_t final_pc) {
struct InitialContext *ictx;
task->sp -= sizeof(struct InitialContext);
ictx = (struct InitialContext *)task->sp;
ictx->eip = initial_pc;
ictx->final_eip = final_pc;
ictx->eflags = 0x202;
}