Modularize interrupt handlers, split up scheduler and PIT interrupt handlers
This commit is contained in:
@ -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) {
|
||||||
|
|||||||
@ -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:
|
IntrHandler *ih, *ihtmp;
|
||||||
PIT_TICKS++;
|
LL_FOREACH_SAFE(INTR_HANDLERS, ih, ihtmp) {
|
||||||
intr_pic_eoi();
|
if ((uint64_t)ih->irq == frame->trapnum) {
|
||||||
proc_sched((void *)frame);
|
if (ih->fn(frame) == INTR_NOEOI) {
|
||||||
break;
|
send = false;
|
||||||
default:
|
|
||||||
IntrHandler *ih, *ihtmp;
|
|
||||||
LL_FOREACH_SAFE(INTR_HANDLERS, ih, ihtmp) {
|
|
||||||
if ((uint64_t)ih->irq == frame->trapnum) {
|
|
||||||
ih->fn();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user