Modularize interrupt handlers, split up scheduler and PIT interrupt handlers
This commit is contained in:
@ -8,6 +8,7 @@
|
||||
#include "proc/proc.h"
|
||||
#include "io/io.h"
|
||||
#include "ipc/mbus/mbus.h"
|
||||
#include "intr/intr.h"
|
||||
#include "errors.h"
|
||||
#include "hshtb.h"
|
||||
#include "kprintf.h"
|
||||
@ -155,12 +156,16 @@ int32_t ps2kb_intr(void) {
|
||||
|
||||
IpcMBus *PS2KB_MBUS;
|
||||
|
||||
void ps2kbdev_intr(void) {
|
||||
int ps2kbdev_intr(IntrStackFrame *frame) {
|
||||
(void)frame;
|
||||
|
||||
int32_t c = ps2kb_intr();
|
||||
if (c >= 0) {
|
||||
uint8_t b = c;
|
||||
ipc_mbuspublish("ps2kb", &b);
|
||||
}
|
||||
|
||||
return INTR_OK;
|
||||
}
|
||||
|
||||
void ps2kbdev_init(void) {
|
||||
|
||||
@ -19,17 +19,39 @@
|
||||
|
||||
typedef struct IntrHandler {
|
||||
struct IntrHandler *next;
|
||||
void (*fn)(void);
|
||||
int (*fn)(IntrStackFrame *frame);
|
||||
int irq;
|
||||
} IntrHandler;
|
||||
|
||||
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));
|
||||
ih->fn = fn;
|
||||
ih->irq = irq;
|
||||
spinlock_acquire(&INTR_HANDLERS_SPINLOCK);
|
||||
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 {
|
||||
@ -104,6 +126,8 @@ static const char *exceptions[] = {
|
||||
};
|
||||
|
||||
void intr_init(void) {
|
||||
spinlock_init(&INTR_HANDLERS_SPINLOCK);
|
||||
|
||||
#define MKINTR(N) \
|
||||
extern void intr_vec##N(void); \
|
||||
idt_setentry(N, (uint64_t)&intr_vec##N, 0x8E);
|
||||
@ -222,22 +246,16 @@ void intr_handleintr(IntrStackFrame *frame) {
|
||||
cpu_hang();
|
||||
}
|
||||
} else if (frame->trapnum >= 32 && frame->trapnum <= 47) {
|
||||
switch (frame->trapnum) {
|
||||
case INTR_IRQBASE+0:
|
||||
PIT_TICKS++;
|
||||
intr_pic_eoi();
|
||||
proc_sched((void *)frame);
|
||||
break;
|
||||
default:
|
||||
IntrHandler *ih, *ihtmp;
|
||||
LL_FOREACH_SAFE(INTR_HANDLERS, ih, ihtmp) {
|
||||
if ((uint64_t)ih->irq == frame->trapnum) {
|
||||
ih->fn();
|
||||
}
|
||||
bool send = true;
|
||||
IntrHandler *ih, *ihtmp;
|
||||
LL_FOREACH_SAFE(INTR_HANDLERS, ih, ihtmp) {
|
||||
if ((uint64_t)ih->irq == frame->trapnum) {
|
||||
if (ih->fn(frame) == INTR_NOEOI) {
|
||||
send = false;
|
||||
}
|
||||
intr_pic_eoi();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (send) intr_pic_eoi();
|
||||
} else if (frame->trapnum == 0x80) {
|
||||
intr_syscalldispatch(frame);
|
||||
}
|
||||
|
||||
@ -2,10 +2,14 @@
|
||||
#define INTR_INTR_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "compiler/attr.h"
|
||||
|
||||
#define INTR_IRQBASE 0x20
|
||||
|
||||
#define INTR_OK 1
|
||||
#define INTR_NOEOI 2
|
||||
|
||||
typedef struct {
|
||||
uint64_t r15;
|
||||
uint64_t r14;
|
||||
@ -34,7 +38,8 @@ typedef struct {
|
||||
uint64_t ss;
|
||||
} 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_enable(void);
|
||||
void intr_init(void);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include <stdint.h>
|
||||
#include "intr/pit.h"
|
||||
#include "io/io.h"
|
||||
#include "intr/intr.h"
|
||||
|
||||
#define PIT_COUNTER0 0x40
|
||||
#define PIT_CMD 0x43
|
||||
@ -25,15 +26,22 @@
|
||||
|
||||
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) {
|
||||
intr_attchhandler(&intr_pit_intr, INTR_IRQBASE+0);
|
||||
|
||||
uint32_t hz = 1000;
|
||||
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_COUNTER0, div & 0xFF);
|
||||
io_out8(PIT_COUNTER0, div >> 8);
|
||||
}
|
||||
|
||||
void intr_pit_wait(uint32_t ms) {
|
||||
uint32_t now = PIT_TICKS;
|
||||
while (PIT_TICKS - now < ms);
|
||||
}
|
||||
|
||||
@ -45,9 +45,9 @@ void kmain(void) {
|
||||
log_bootinfo();
|
||||
log_time();
|
||||
gdt_init();
|
||||
intr_init();
|
||||
pmm_init();
|
||||
vmm_init();
|
||||
intr_init();
|
||||
randcrypto_init();
|
||||
ipc_mbusinit();
|
||||
dev_init();
|
||||
|
||||
@ -16,8 +16,9 @@
|
||||
#include "std/string.h"
|
||||
#include "cpu/gdt.h"
|
||||
#include "intr/intr.h"
|
||||
#include "switch.h"
|
||||
#include "intr/pic.h"
|
||||
#include "vmm/vmm.h"
|
||||
#include "proc/switch.h"
|
||||
#include "elf.h"
|
||||
#include "errors.h"
|
||||
#include "kprintf.h"
|
||||
@ -252,10 +253,18 @@ void proc_killself(void) {
|
||||
proc_kill(proc);
|
||||
}
|
||||
|
||||
int proc_intr(IntrStackFrame *frame) {
|
||||
intr_pic_eoi();
|
||||
proc_sched(frame);
|
||||
return INTR_NOEOI;
|
||||
}
|
||||
|
||||
void proc_init(void) {
|
||||
spinlock_init(&PROCS.spinlock);
|
||||
PROCS.procs = NULL;
|
||||
|
||||
intr_attchhandler(&proc_intr, INTR_IRQBASE+0);
|
||||
|
||||
Proc *init = proc_spawnuser("base", "/bin/init");
|
||||
PROCS.current = init;
|
||||
proc_register(init);
|
||||
|
||||
Reference in New Issue
Block a user