kernel: initial interrupt abstraction implementation

This commit is contained in:
Matheus
2023-04-08 20:13:51 -03:00
parent 1555becce5
commit a9f490b431
3 changed files with 76 additions and 1 deletions
+26
View File
@@ -0,0 +1,26 @@
#ifndef _INTERRUPT_H
#define _INTERRUPT_H
#include <stdbool.h>
#ifdef __x86_64__
#define MAX_ISR_COUNT 256
#else
#error Unsupported architecture!
#endif
struct _isr_t;
typedef struct _isr_t {
void (*func)(struct _isr_t *self); // TODO pass register context as argument as well.
void (*eoi)(struct _isr_t *self);
long id;
long priority;
bool pending;
} isr_t;
void interrupt_register(int vector, void (*func)(isr_t *self), void (*eoi)(isr_t *self), long priority); // TODO pass register context as well.
isr_t *interrupt_allocate(void (*func)(isr_t *self), void (*eoi)(isr_t *self), long priority); // TODO pass register context as well.
void interrupt_raiseipl(long newipl);
void interrupt_loweripl(long newipl);
#endif
+3 -1
View File
@@ -6,11 +6,13 @@
#include <arch/msr.h>
#include <arch/ist.h>
#include <kernel/interrupt.h>
typedef struct {
uint64_t gdt[7];
ist_t ist;
int lapicid;
long id;
isr_t isr[MAX_ISR_COUNT];
} cpu_t;
static inline cpu_t *_cpu() {
+47
View File
@@ -0,0 +1,47 @@
#include <kernel/interrupt.h>
#include <logging.h>
#include <arch/cpu.h>
// TODO pass register context as well
void interrupt_isr(int vec) {
isr_t *isr = &_cpu()->isr[vec];
// TODO ipl check
isr->func(isr); // TODO pass context
if (isr->eoi)
isr->eoi(isr);
}
// TODO pass register context as well.
void interrupt_register(int vector, void (*func)(isr_t *self), void (*eoi)(isr_t *self), long priority) {
isr_t *isr = &_cpu()->isr[vector];
isr->func = func;
isr->eoi = eoi;
isr->id = _cpu()->id << 32 | vector;
isr->priority = priority;
}
// TODO pass register context as well.
isr_t *interrupt_allocate(void (*func)(isr_t *self), void (*eoi)(isr_t *self), long priority) {
isr_t *isr = NULL;
for (int i = 0; i < MAX_ISR_COUNT; ++i) {
if (_cpu()->isr[i].func == NULL) {
isr = &_cpu()->isr[i];
interrupt_register(i, func, eoi, priority);
break;
}
}
return isr;
}
// TODO ipl is thread level, write these when the scheduler is written
void interrupt_raiseipl(long newipl) {
__assert(!"Unimplemented");
}
void interrupt_loweripl(long newipl) {
__assert(!"Unimplemented");
}