mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-31 22:48:21 +00:00
interrupt: basic ipl handling
This commit is contained in:
@@ -78,7 +78,7 @@ void arch_idt_reload() {
|
|||||||
|
|
||||||
// make sure to reserve the first 32 isrs for exceptions with a dummy panic isr
|
// make sure to reserve the first 32 isrs for exceptions with a dummy panic isr
|
||||||
for (int i = 0; i < 32; ++i)
|
for (int i = 0; i < 32; ++i)
|
||||||
interrupt_register(i, exceptisr, NULL, 0); // TODO assign priority
|
interrupt_register(i, exceptisr, NULL, IPL_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_interrupt_disable() {
|
void arch_interrupt_disable() {
|
||||||
|
|||||||
@@ -11,6 +11,11 @@
|
|||||||
#error Unsupported architecture!
|
#error Unsupported architecture!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define IPL_MAX -1
|
||||||
|
#define IPL_NONE 0
|
||||||
|
#define IPL_TIMER 1
|
||||||
|
#define IPL_BASE 1000
|
||||||
|
|
||||||
struct _isr_t;
|
struct _isr_t;
|
||||||
typedef struct _isr_t {
|
typedef struct _isr_t {
|
||||||
void (*func)(struct _isr_t *self, context_t *ctx);
|
void (*func)(struct _isr_t *self, context_t *ctx);
|
||||||
@@ -22,8 +27,7 @@ typedef struct _isr_t {
|
|||||||
|
|
||||||
void interrupt_register(int vector, void (*func)(isr_t *self, context_t *ctx), void (*eoi)(isr_t *self), long priority);
|
void interrupt_register(int vector, void (*func)(isr_t *self, context_t *ctx), void (*eoi)(isr_t *self), long priority);
|
||||||
isr_t *interrupt_allocate(void (*func)(isr_t *self, context_t *ctx), void (*eoi)(isr_t *self), long priority);
|
isr_t *interrupt_allocate(void (*func)(isr_t *self, context_t *ctx), void (*eoi)(isr_t *self), long priority);
|
||||||
void interrupt_raiseipl(long newipl);
|
long interrupt_setipl(long newipl);
|
||||||
void interrupt_loweripl(long newipl);
|
|
||||||
bool interrupt_set(bool status);
|
bool interrupt_set(bool status);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ typedef struct {
|
|||||||
int acpiid;
|
int acpiid;
|
||||||
timer_t *timer;
|
timer_t *timer;
|
||||||
bool intstatus;
|
bool intstatus;
|
||||||
|
long ipl;
|
||||||
} cpu_t;
|
} cpu_t;
|
||||||
|
|
||||||
static inline cpu_t *_cpu() {
|
static inline cpu_t *_cpu() {
|
||||||
|
|||||||
@@ -9,8 +9,18 @@ void interrupt_isr(int vec, context_t *ctx) {
|
|||||||
if (isr->func == NULL)
|
if (isr->func == NULL)
|
||||||
_panic("Unregistered interrupt", ctx);
|
_panic("Unregistered interrupt", ctx);
|
||||||
|
|
||||||
// TODO ipl check
|
if (_cpu()->ipl < isr->priority) {
|
||||||
isr->func(isr, ctx);
|
long oldipl = interrupt_setipl(isr->priority);
|
||||||
|
|
||||||
|
bool oldint = interrupt_set(true);
|
||||||
|
isr->func(isr, ctx);
|
||||||
|
interrupt_set(false);
|
||||||
|
|
||||||
|
_cpu()->intstatus = oldint;
|
||||||
|
interrupt_setipl(oldipl);
|
||||||
|
} else {
|
||||||
|
isr->pending = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (isr->eoi)
|
if (isr->eoi)
|
||||||
isr->eoi(isr);
|
isr->eoi(isr);
|
||||||
@@ -22,6 +32,7 @@ void interrupt_register(int vector, void (*func)(isr_t *self, context_t *ctx), v
|
|||||||
isr->eoi = eoi;
|
isr->eoi = eoi;
|
||||||
isr->id = (uint64_t)_cpu()->id << 32 | vector;
|
isr->id = (uint64_t)_cpu()->id << 32 | vector;
|
||||||
isr->priority = priority;
|
isr->priority = priority;
|
||||||
|
isr->pending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
isr_t *interrupt_allocate(void (*func)(isr_t *self, context_t *ctx), void (*eoi)(isr_t *self), long priority) {
|
isr_t *interrupt_allocate(void (*func)(isr_t *self, context_t *ctx), void (*eoi)(isr_t *self), long priority) {
|
||||||
@@ -38,14 +49,15 @@ isr_t *interrupt_allocate(void (*func)(isr_t *self, context_t *ctx), void (*eoi)
|
|||||||
return isr;
|
return isr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO ipl is thread level, write these when the scheduler is written
|
long interrupt_setipl(long ipl) {
|
||||||
|
bool oldintstatus = interrupt_set(false);
|
||||||
|
long oldipl = _cpu()->ipl;
|
||||||
|
_cpu()->ipl = ipl;
|
||||||
|
interrupt_set(oldintstatus);
|
||||||
|
|
||||||
void interrupt_raiseipl(long newipl) {
|
// TODO do pending interrupts
|
||||||
__assert(!"Unimplemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
void interrupt_loweripl(long newipl) {
|
return oldipl;
|
||||||
__assert(!"Unimplemented");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_interrupt_disable();
|
void arch_interrupt_disable();
|
||||||
|
|||||||
Reference in New Issue
Block a user