matos/arch/x86/irq.c

76 lines
1.7 KiB
C
Raw Normal View History

2018-07-20 15:41:58 +02:00
#include "irq.h"
#include "idt.h"
2021-10-07 21:23:32 +02:00
#include "io.h"
#include "klibc.h"
2018-07-20 15:41:58 +02:00
#include "pic.h"
#include "stdarg.h"
2021-10-07 21:23:32 +02:00
#include "types.h"
2018-07-20 15:41:58 +02:00
int irqSetup()
{
initPic();
return 0;
2018-07-20 15:41:58 +02:00
}
2021-10-07 21:23:32 +02:00
// Assembly defined array. This is used to wrap C function than cannot:
// * get some cpu state
// * return using "iret" instead of "ret" without some compiler __attribute__
extern vaddr_t irq_handler_wrapper_array[IRQ_NUM];
irq_handler irq_handler_array[IRQ_NUM] = {
NULL,
};
2018-07-20 15:41:58 +02:00
2021-10-07 21:23:32 +02:00
void interrupt_handler_pic(int interrupt, struct interrupt_frame *frame)
{
if (0 > interrupt || IRQ_NUM <= interrupt) {
pr_err("Trying to handle unknow interrupt %d\n", interrupt);
return;
}
EOIIrq(interrupt);
if (irq_handler_array[interrupt] != NULL)
irq_handler_array[interrupt](frame);
}
2018-07-20 15:41:58 +02:00
int irqSetRoutine(int irq, irq_handler handler)
{
uint32_t flags;
if ((irq < 0) || irq >= IRQ_NUM)
return -1;
disable_IRQs(flags);
irq_handler_array[irq] = handler;
if (handler != NULL) {
int ret = idt_set_handler(IRQ_INTERRUPT_BASE_ADDRESS + irq,
(unsigned int)irq_handler_array[irq], 0);
2018-07-20 15:41:58 +02:00
if (!ret)
enableIrq(irq);
}
restore_IRQs(flags);
return 0;
}
2021-10-07 21:23:32 +02:00
int irqSetRoutineWrapped(int irq, irq_handler handler)
{
uint32_t flags;
if ((irq < 0) || irq >= IRQ_NUM)
return -1;
disable_IRQs(flags);
irq_handler_array[irq] = handler;
if (handler != NULL) {
int ret = idt_set_handler(IRQ_INTERRUPT_BASE_ADDRESS + irq,
(unsigned int)irq_handler_wrapper_array[irq], 0);
if (!ret)
enableIrq(irq);
}
restore_IRQs(flags);
return 0;
}