From 3987e7bca6447d87d6c89b1d36c40f9101b54802 Mon Sep 17 00:00:00 2001 From: Matheus Date: Thu, 4 May 2023 13:52:35 -0300 Subject: [PATCH] interrupt: split setipl into raiseipl and loweripl --- kernel-src/include/kernel/interrupt.h | 10 ++++++---- kernel-src/sys/interrupt.c | 18 ++++++++++++++---- kernel-src/sys/timer.c | 8 ++++---- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/kernel-src/include/kernel/interrupt.h b/kernel-src/include/kernel/interrupt.h index 7eac1dbb..b524eea7 100644 --- a/kernel-src/include/kernel/interrupt.h +++ b/kernel-src/include/kernel/interrupt.h @@ -11,10 +11,11 @@ #error Unsupported architecture! #endif -#define IPL_MAX -1 -#define IPL_NONE 0 +#define IPL_EXCEPT -1 +#define IPL_MAX 0 #define IPL_TIMER 1 -#define IPL_BASE 1000 +#define IPL_KEYBOARD 2 +#define IPL_NORMAL 1000 struct _isr_t; typedef struct _isr_t { @@ -27,7 +28,8 @@ typedef struct _isr_t { 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); -long interrupt_setipl(long newipl); +long interrupt_loweripl(long newipl); +long interrupt_raiseipl(long ipl); bool interrupt_set(bool status); #endif diff --git a/kernel-src/sys/interrupt.c b/kernel-src/sys/interrupt.c index f6f8dc4c..fe003eb5 100644 --- a/kernel-src/sys/interrupt.c +++ b/kernel-src/sys/interrupt.c @@ -12,12 +12,12 @@ void interrupt_isr(int vec, context_t *ctx) { _panic("Unregistered interrupt", ctx); if (_cpu()->ipl > isr->priority) { - long oldipl = interrupt_setipl(isr->priority); + long oldipl = interrupt_raiseipl(isr->priority); isr->func(isr, ctx); interrupt_set(false); - interrupt_setipl(oldipl); + interrupt_loweripl(oldipl); } else { isr->pending = true; } @@ -51,10 +51,11 @@ isr_t *interrupt_allocate(void (*func)(isr_t *self, context_t *ctx), void (*eoi) return isr; } -long interrupt_setipl(long ipl) { +long interrupt_loweripl(long ipl) { bool oldintstatus = interrupt_set(false); long oldipl = _cpu()->ipl; - _cpu()->ipl = ipl; + if (oldipl > ipl) + _cpu()->ipl = ipl; interrupt_set(oldintstatus); // TODO do pending interrupts @@ -62,6 +63,15 @@ long interrupt_setipl(long ipl) { return oldipl; } +long interrupt_raiseipl(long ipl) { + bool oldintstatus = interrupt_set(false); + long oldipl = _cpu()->ipl; + if (oldipl < ipl) + _cpu()->ipl = ipl; + interrupt_set(oldintstatus); + return oldipl; +} + void arch_interrupt_disable(); void arch_interrupt_enable(); diff --git a/kernel-src/sys/timer.c b/kernel-src/sys/timer.c index 410bc2e1..231dabec 100644 --- a/kernel-src/sys/timer.c +++ b/kernel-src/sys/timer.c @@ -69,18 +69,18 @@ void timer_resume(timer_t *timer) { } void timer_stop(timer_t *timer) { - long oldipl = interrupt_setipl(IPL_TIMER); + long oldipl = interrupt_raiseipl(IPL_TIMER); spinlock_acquire(&timer->lock); timer->tickcurrent += timer->stop(timer); timer->running = false; spinlock_release(&timer->lock); - interrupt_setipl(oldipl); + interrupt_loweripl(oldipl); } void timer_insert(timer_t *timer, timerentry_t* entry, time_t us) { - long oldipl = interrupt_setipl(IPL_TIMER); + long oldipl = interrupt_raiseipl(IPL_TIMER); spinlock_acquire(&timer->lock); if (timer->running) @@ -95,7 +95,7 @@ void timer_insert(timer_t *timer, timerentry_t* entry, time_t us) { } spinlock_release(&timer->lock); - interrupt_setipl(oldipl); + interrupt_loweripl(oldipl); } timer_t *timer_new(time_t ticksperus, void (*arm)(time_t), time_t (*stop)()) {