Modularize interrupt handlers, split up scheduler and PIT interrupt handlers

This commit is contained in:
2025-11-17 01:08:23 +01:00
parent f2b7c5da57
commit 77b5a4a153
6 changed files with 70 additions and 25 deletions

View File

@ -8,6 +8,7 @@
#include "proc/proc.h" #include "proc/proc.h"
#include "io/io.h" #include "io/io.h"
#include "ipc/mbus/mbus.h" #include "ipc/mbus/mbus.h"
#include "intr/intr.h"
#include "errors.h" #include "errors.h"
#include "hshtb.h" #include "hshtb.h"
#include "kprintf.h" #include "kprintf.h"
@ -155,12 +156,16 @@ int32_t ps2kb_intr(void) {
IpcMBus *PS2KB_MBUS; IpcMBus *PS2KB_MBUS;
void ps2kbdev_intr(void) { int ps2kbdev_intr(IntrStackFrame *frame) {
(void)frame;
int32_t c = ps2kb_intr(); int32_t c = ps2kb_intr();
if (c >= 0) { if (c >= 0) {
uint8_t b = c; uint8_t b = c;
ipc_mbuspublish("ps2kb", &b); ipc_mbuspublish("ps2kb", &b);
} }
return INTR_OK;
} }
void ps2kbdev_init(void) { void ps2kbdev_init(void) {

View File

@ -19,17 +19,39 @@
typedef struct IntrHandler { typedef struct IntrHandler {
struct IntrHandler *next; struct IntrHandler *next;
void (*fn)(void); int (*fn)(IntrStackFrame *frame);
int irq; int irq;
} IntrHandler; } IntrHandler;
IntrHandler *INTR_HANDLERS = NULL; IntrHandler *INTR_HANDLERS = NULL;
SpinLock INTR_HANDLERS_SPINLOCK;
void intr_attchhandler(void (*fn)(void), int irq) { void intr_attchhandler(int (*fn)(IntrStackFrame *frame), int irq) {
IntrHandler *ih = dlmalloc(sizeof(*ih)); IntrHandler *ih = dlmalloc(sizeof(*ih));
ih->fn = fn; ih->fn = fn;
ih->irq = irq; ih->irq = irq;
spinlock_acquire(&INTR_HANDLERS_SPINLOCK);
LL_APPEND(INTR_HANDLERS, ih); LL_APPEND(INTR_HANDLERS, ih);
spinlock_release(&INTR_HANDLERS_SPINLOCK);
}
int32_t intr_dttchhandler(int irq) {
IntrHandler *ih = NULL;
spinlock_acquire(&INTR_HANDLERS_SPINLOCK);
LL_FINDPROP(INTR_HANDLERS, ih, irq, irq);
if (ih == NULL) {
spinlock_release(&INTR_HANDLERS_SPINLOCK);
return E_NOENTRY;
}
LL_REMOVE(INTR_HANDLERS, ih);
spinlock_release(&INTR_HANDLERS_SPINLOCK);
dlfree(ih);
return E_OK;
} }
typedef struct BackTraceFrame { typedef struct BackTraceFrame {
@ -104,6 +126,8 @@ static const char *exceptions[] = {
}; };
void intr_init(void) { void intr_init(void) {
spinlock_init(&INTR_HANDLERS_SPINLOCK);
#define MKINTR(N) \ #define MKINTR(N) \
extern void intr_vec##N(void); \ extern void intr_vec##N(void); \
idt_setentry(N, (uint64_t)&intr_vec##N, 0x8E); idt_setentry(N, (uint64_t)&intr_vec##N, 0x8E);
@ -222,22 +246,16 @@ void intr_handleintr(IntrStackFrame *frame) {
cpu_hang(); cpu_hang();
} }
} else if (frame->trapnum >= 32 && frame->trapnum <= 47) { } else if (frame->trapnum >= 32 && frame->trapnum <= 47) {
switch (frame->trapnum) { bool send = true;
case INTR_IRQBASE+0:
PIT_TICKS++;
intr_pic_eoi();
proc_sched((void *)frame);
break;
default:
IntrHandler *ih, *ihtmp; IntrHandler *ih, *ihtmp;
LL_FOREACH_SAFE(INTR_HANDLERS, ih, ihtmp) { LL_FOREACH_SAFE(INTR_HANDLERS, ih, ihtmp) {
if ((uint64_t)ih->irq == frame->trapnum) { if ((uint64_t)ih->irq == frame->trapnum) {
ih->fn(); if (ih->fn(frame) == INTR_NOEOI) {
send = false;
} }
} }
intr_pic_eoi();
break;
} }
if (send) intr_pic_eoi();
} else if (frame->trapnum == 0x80) { } else if (frame->trapnum == 0x80) {
intr_syscalldispatch(frame); intr_syscalldispatch(frame);
} }

View File

@ -2,10 +2,14 @@
#define INTR_INTR_H_ #define INTR_INTR_H_
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#include "compiler/attr.h" #include "compiler/attr.h"
#define INTR_IRQBASE 0x20 #define INTR_IRQBASE 0x20
#define INTR_OK 1
#define INTR_NOEOI 2
typedef struct { typedef struct {
uint64_t r15; uint64_t r15;
uint64_t r14; uint64_t r14;
@ -34,7 +38,8 @@ typedef struct {
uint64_t ss; uint64_t ss;
} PACKED IntrStackFrame; } PACKED IntrStackFrame;
void intr_attchhandler(void (*fn)(void), int irq); void intr_attchhandler(int (*fn)(IntrStackFrame *frame), int irq);
int32_t intr_dttchhandler(int irq);
void intr_disable(void); void intr_disable(void);
void intr_enable(void); void intr_enable(void);
void intr_init(void); void intr_init(void);

View File

@ -1,6 +1,7 @@
#include <stdint.h> #include <stdint.h>
#include "intr/pit.h" #include "intr/pit.h"
#include "io/io.h" #include "io/io.h"
#include "intr/intr.h"
#define PIT_COUNTER0 0x40 #define PIT_COUNTER0 0x40
#define PIT_CMD 0x43 #define PIT_CMD 0x43
@ -25,15 +26,22 @@
volatile uint32_t PIT_TICKS; volatile uint32_t PIT_TICKS;
void intr_pit_wait(uint32_t ms) {
uint32_t now = PIT_TICKS;
while (PIT_TICKS - now < ms);
}
int intr_pit_intr(IntrStackFrame *frame) {
PIT_TICKS++;
return INTR_OK;
}
void intr_pit_init(void) { void intr_pit_init(void) {
intr_attchhandler(&intr_pit_intr, INTR_IRQBASE+0);
uint32_t hz = 1000; uint32_t hz = 1000;
uint32_t div = PIT_FREQ / hz; uint32_t div = PIT_FREQ / hz;
io_out8(PIT_CMD, PIT_CMD_BINARY | PIT_CMD_MODE3 | PIT_CMD_RW_BOTH | PIT_CMD_COUNTER0); io_out8(PIT_CMD, PIT_CMD_BINARY | PIT_CMD_MODE3 | PIT_CMD_RW_BOTH | PIT_CMD_COUNTER0);
io_out8(PIT_COUNTER0, div & 0xFF); io_out8(PIT_COUNTER0, div & 0xFF);
io_out8(PIT_COUNTER0, div >> 8); io_out8(PIT_COUNTER0, div >> 8);
} }
void intr_pit_wait(uint32_t ms) {
uint32_t now = PIT_TICKS;
while (PIT_TICKS - now < ms);
}

View File

@ -45,9 +45,9 @@ void kmain(void) {
log_bootinfo(); log_bootinfo();
log_time(); log_time();
gdt_init(); gdt_init();
intr_init();
pmm_init(); pmm_init();
vmm_init(); vmm_init();
intr_init();
randcrypto_init(); randcrypto_init();
ipc_mbusinit(); ipc_mbusinit();
dev_init(); dev_init();

View File

@ -16,8 +16,9 @@
#include "std/string.h" #include "std/string.h"
#include "cpu/gdt.h" #include "cpu/gdt.h"
#include "intr/intr.h" #include "intr/intr.h"
#include "switch.h" #include "intr/pic.h"
#include "vmm/vmm.h" #include "vmm/vmm.h"
#include "proc/switch.h"
#include "elf.h" #include "elf.h"
#include "errors.h" #include "errors.h"
#include "kprintf.h" #include "kprintf.h"
@ -252,10 +253,18 @@ void proc_killself(void) {
proc_kill(proc); proc_kill(proc);
} }
int proc_intr(IntrStackFrame *frame) {
intr_pic_eoi();
proc_sched(frame);
return INTR_NOEOI;
}
void proc_init(void) { void proc_init(void) {
spinlock_init(&PROCS.spinlock); spinlock_init(&PROCS.spinlock);
PROCS.procs = NULL; PROCS.procs = NULL;
intr_attchhandler(&proc_intr, INTR_IRQBASE+0);
Proc *init = proc_spawnuser("base", "/bin/init"); Proc *init = proc_spawnuser("base", "/bin/init");
PROCS.current = init; PROCS.current = init;
proc_register(init); proc_register(init);