mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 23:18:21 +00:00
interrupts: interrupt_raise
This commit is contained in:
@@ -33,5 +33,6 @@ isr_t *interrupt_allocate(void (*func)(isr_t *self, context_t *ctx), void (*eoi)
|
|||||||
long interrupt_loweripl(long newipl);
|
long interrupt_loweripl(long newipl);
|
||||||
long interrupt_raiseipl(long ipl);
|
long interrupt_raiseipl(long ipl);
|
||||||
bool interrupt_set(bool status);
|
bool interrupt_set(bool status);
|
||||||
|
void interrupt_raise(isr_t *isr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+24
-13
@@ -29,6 +29,15 @@ static void insertinqueue(isr_t *isr) {
|
|||||||
_cpu()->isrqueue = isr;
|
_cpu()->isrqueue = isr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void runisr(isr_t *isr, context_t *ctx) {
|
||||||
|
long oldipl = interrupt_raiseipl(isr->priority);
|
||||||
|
|
||||||
|
isr->func(isr, ctx);
|
||||||
|
interrupt_set(false);
|
||||||
|
|
||||||
|
interrupt_loweripl(oldipl);
|
||||||
|
}
|
||||||
|
|
||||||
static void dopending(context_t *ctx) {
|
static void dopending(context_t *ctx) {
|
||||||
bool entrystatus = _cpu()->intstatus;
|
bool entrystatus = _cpu()->intstatus;
|
||||||
if (entrystatus) {
|
if (entrystatus) {
|
||||||
@@ -40,7 +49,6 @@ static void dopending(context_t *ctx) {
|
|||||||
isr_t *iterator = _cpu()->isrqueue;
|
isr_t *iterator = _cpu()->isrqueue;
|
||||||
|
|
||||||
// build a list of pending ISRs and remove them from the main queue
|
// build a list of pending ISRs and remove them from the main queue
|
||||||
|
|
||||||
while (iterator) {
|
while (iterator) {
|
||||||
isr_t *next = iterator->next;
|
isr_t *next = iterator->next;
|
||||||
if (_cpu()->ipl > iterator->priority) {
|
if (_cpu()->ipl > iterator->priority) {
|
||||||
@@ -70,12 +78,7 @@ static void dopending(context_t *ctx) {
|
|||||||
list->prev = NULL;
|
list->prev = NULL;
|
||||||
isr->pending = false;
|
isr->pending = false;
|
||||||
|
|
||||||
long oldipl = interrupt_raiseipl(isr->priority);
|
runisr(isr, ctx);
|
||||||
|
|
||||||
isr->func(isr, ctx);
|
|
||||||
interrupt_set(false);
|
|
||||||
|
|
||||||
interrupt_loweripl(oldipl);
|
|
||||||
|
|
||||||
// if any new interrupts are pending, they will be taken care of here
|
// if any new interrupts are pending, they will be taken care of here
|
||||||
// XXX this is kinda hacky could be very very bad if there are a lot of interrupts
|
// XXX this is kinda hacky could be very very bad if there are a lot of interrupts
|
||||||
@@ -98,12 +101,7 @@ void interrupt_isr(int vec, context_t *ctx) {
|
|||||||
_panic("Unregistered interrupt", ctx);
|
_panic("Unregistered interrupt", ctx);
|
||||||
|
|
||||||
if (_cpu()->ipl > isr->priority) {
|
if (_cpu()->ipl > isr->priority) {
|
||||||
long oldipl = interrupt_raiseipl(isr->priority);
|
runisr(isr, ctx);
|
||||||
|
|
||||||
isr->func(isr, ctx);
|
|
||||||
interrupt_set(false);
|
|
||||||
|
|
||||||
interrupt_loweripl(oldipl);
|
|
||||||
dopending(ctx);
|
dopending(ctx);
|
||||||
} else {
|
} else {
|
||||||
insertinqueue(isr);
|
insertinqueue(isr);
|
||||||
@@ -116,6 +114,19 @@ void interrupt_isr(int vec, context_t *ctx) {
|
|||||||
_cpu()->intstatus = ARCH_CONTEXT_INTSTATUS(ctx);
|
_cpu()->intstatus = ARCH_CONTEXT_INTSTATUS(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void interrupt_raise(isr_t *isr) {
|
||||||
|
bool entrystate = interrupt_set(false);
|
||||||
|
|
||||||
|
if (isr->pending)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
insertinqueue(isr);
|
||||||
|
isr->pending = true;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
interrupt_set(entrystate);
|
||||||
|
}
|
||||||
|
|
||||||
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 *isr = &_cpu()->isr[vector];
|
isr_t *isr = &_cpu()->isr[vector];
|
||||||
isr->func = func;
|
isr->func = func;
|
||||||
|
|||||||
Reference in New Issue
Block a user