mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
kernel: initial interrupt abstraction implementation
This commit is contained in:
@@ -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
|
||||||
@@ -6,11 +6,13 @@
|
|||||||
|
|
||||||
#include <arch/msr.h>
|
#include <arch/msr.h>
|
||||||
#include <arch/ist.h>
|
#include <arch/ist.h>
|
||||||
|
#include <kernel/interrupt.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint64_t gdt[7];
|
uint64_t gdt[7];
|
||||||
ist_t ist;
|
ist_t ist;
|
||||||
int lapicid;
|
long id;
|
||||||
|
isr_t isr[MAX_ISR_COUNT];
|
||||||
} cpu_t;
|
} cpu_t;
|
||||||
|
|
||||||
static inline cpu_t *_cpu() {
|
static inline cpu_t *_cpu() {
|
||||||
|
|||||||
@@ -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");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user