mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
cpu: add irq depth counting
Add a way of checking if a cpu is in the middle of handling an irq and how deep it is into it. This will allow for future code to conditionally run only in/outside interrupts.
This commit is contained in:
@@ -147,6 +147,8 @@ void arch_nmi_isr(context_t *ctx) {
|
|||||||
uint64_t old_gsbase = rdmsr(MSR_GSBASE);
|
uint64_t old_gsbase = rdmsr(MSR_GSBASE);
|
||||||
wrmsr(MSR_GSBASE, *(uint64_t *)(ctx + 1));
|
wrmsr(MSR_GSBASE, *(uint64_t *)(ctx + 1));
|
||||||
|
|
||||||
|
__atomic_fetch_add(¤t_cpu()->irq_depth, 1, __ATOMIC_RELAXED);
|
||||||
|
|
||||||
bool handled = false;
|
bool handled = false;
|
||||||
|
|
||||||
#ifdef ENABLE_PROFILING
|
#ifdef ENABLE_PROFILING
|
||||||
@@ -157,6 +159,8 @@ void arch_nmi_isr(context_t *ctx) {
|
|||||||
if (!handled)
|
if (!handled)
|
||||||
_panic("Unhandled NMI", ctx);
|
_panic("Unhandled NMI", ctx);
|
||||||
|
|
||||||
|
__atomic_fetch_sub(¤t_cpu()->irq_depth, 1, __ATOMIC_RELAXED);
|
||||||
|
|
||||||
// restore the old gsbase
|
// restore the old gsbase
|
||||||
wrmsr(MSR_GSBASE, old_gsbase);
|
wrmsr(MSR_GSBASE, old_gsbase);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ typedef struct cpu_t {
|
|||||||
|
|
||||||
uint64_t scratch; // expected to be here by other code
|
uint64_t scratch; // expected to be here by other code
|
||||||
|
|
||||||
|
unsigned long irq_depth; // expected to be here by other code
|
||||||
|
|
||||||
timekeeper_source_t *timekeeper_source;
|
timekeeper_source_t *timekeeper_source;
|
||||||
timekeeper_source_info_t *timekeeper_source_info;
|
timekeeper_source_info_t *timekeeper_source_info;
|
||||||
time_t timekeeper_source_base_ticks;
|
time_t timekeeper_source_base_ticks;
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ static void dopending(context_t *ctx, void *) {
|
|||||||
arch_interrupt_disable();
|
arch_interrupt_disable();
|
||||||
bool entrystatus = current_cpu()->intstatus;
|
bool entrystatus = current_cpu()->intstatus;
|
||||||
current_cpu()->intstatus = false;
|
current_cpu()->intstatus = false;
|
||||||
|
__atomic_fetch_add(¤t_cpu()->irq_depth, 1, __ATOMIC_RELAXED);
|
||||||
|
|
||||||
isr_t *list = NULL;
|
isr_t *list = NULL;
|
||||||
isr_t *iterator = current_cpu()->isrqueue;
|
isr_t *iterator = current_cpu()->isrqueue;
|
||||||
@@ -87,18 +88,25 @@ static void dopending(context_t *ctx, void *) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
__atomic_fetch_sub(¤t_cpu()->irq_depth, 1, __ATOMIC_RELAXED);
|
||||||
if (entrystatus) {
|
if (entrystatus) {
|
||||||
current_cpu()->intstatus = true;
|
current_cpu()->intstatus = true;
|
||||||
arch_interrupt_enable();
|
arch_interrupt_enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((no_caller_saved_registers)) void sched_userspacecheck(context_t *context, bool syscall, uint64_t syscallret, uint64_t syscallerrno);
|
__attribute__((no_caller_saved_registers)) void sched_userspacecheck(context_t *context,
|
||||||
|
bool syscall,
|
||||||
|
uint64_t syscallret,
|
||||||
|
uint64_t syscallerrno);
|
||||||
|
|
||||||
void interrupt_isr(int vec, context_t *ctx) {
|
void interrupt_isr(int vec, context_t *ctx) {
|
||||||
isr_t *isr = ¤t_cpu()->isr[vec];
|
isr_t *isr = ¤t_cpu()->isr[vec];
|
||||||
current_cpu()->intstatus = false;
|
current_cpu()->intstatus = false;
|
||||||
|
|
||||||
|
if (isr->priority != IPL_IGNORE)
|
||||||
|
__atomic_fetch_add(¤t_cpu()->irq_depth, 1, __ATOMIC_RELAXED);
|
||||||
|
|
||||||
if (isr->func == NULL) {
|
if (isr->func == NULL) {
|
||||||
char oops[64];
|
char oops[64];
|
||||||
snprintf(oops, 64, "Unregistered interrupt %d\n", vec);
|
snprintf(oops, 64, "Unregistered interrupt %d\n", vec);
|
||||||
@@ -116,6 +124,9 @@ void interrupt_isr(int vec, context_t *ctx) {
|
|||||||
if (isr->eoi)
|
if (isr->eoi)
|
||||||
isr->eoi(isr);
|
isr->eoi(isr);
|
||||||
|
|
||||||
|
if (isr->priority != IPL_IGNORE)
|
||||||
|
__atomic_fetch_sub(¤t_cpu()->irq_depth, 1, __ATOMIC_RELAXED);
|
||||||
|
|
||||||
if (ARCH_CONTEXT_ISUSER(ctx))
|
if (ARCH_CONTEXT_ISUSER(ctx))
|
||||||
sched_userspacecheck(ctx, false, 0, 0);
|
sched_userspacecheck(ctx, false, 0, 0);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user