Modularize interrupt handlers, split up scheduler and PIT interrupt handlers
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user