2025-06-13 19:53:54 -05:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <drivers/ps2_keyboard.h>
|
2025-06-17 15:50:07 -05:00
|
|
|
#include <drivers/pit.h>
|
2025-10-20 21:57:30 -05:00
|
|
|
#include <port_io.h>
|
2025-06-13 18:03:39 -05:00
|
|
|
|
2026-03-20 16:57:08 -05:00
|
|
|
/* TEMP DEBUG */
|
|
|
|
|
#include <tty.h>
|
|
|
|
|
|
|
|
|
|
#include <kernel/syscall.h>
|
|
|
|
|
|
2025-06-13 18:03:39 -05:00
|
|
|
#include <drivers/irq.h>
|
|
|
|
|
|
2026-03-20 16:57:08 -05:00
|
|
|
#define MAX_IRQ_HANDLERS 128 /* the maximum number of irq handlers */
|
2025-07-03 20:30:21 -05:00
|
|
|
|
|
|
|
|
|
2026-03-20 16:57:08 -05:00
|
|
|
typedef struct {
|
|
|
|
|
uint32_t irq_no;
|
|
|
|
|
irq_func_t func;
|
|
|
|
|
} irq_handler_t;
|
2025-07-04 14:23:29 -05:00
|
|
|
|
2026-03-20 16:57:08 -05:00
|
|
|
uint32_t num_irq_handlers = 0;
|
|
|
|
|
irq_handler_t handler_list[MAX_IRQ_HANDLERS];
|
2025-07-04 14:23:29 -05:00
|
|
|
|
2026-03-20 16:57:08 -05:00
|
|
|
volatile uint32_t num_irqs_missed = 0;
|
2025-07-01 20:39:38 -05:00
|
|
|
|
|
|
|
|
void irq_init(void)
|
|
|
|
|
{
|
2026-03-20 16:57:08 -05:00
|
|
|
for (int i = 0; i < MAX_IRQ_HANDLERS; i++)
|
2025-10-20 21:57:30 -05:00
|
|
|
{
|
2026-03-20 16:57:08 -05:00
|
|
|
handler_list[i].irq_no = 0;
|
|
|
|
|
handler_list[i].func = NULL;
|
2025-10-20 21:57:30 -05:00
|
|
|
}
|
2026-03-20 16:57:08 -05:00
|
|
|
set_irq_handler(0, (irq_func_t) pit_handler);
|
|
|
|
|
//set_irq_handler(1, (irq_func_t) ps2_keyboard_handler);
|
2025-07-01 20:39:38 -05:00
|
|
|
}
|
2025-06-13 18:03:39 -05:00
|
|
|
|
2026-03-20 16:57:08 -05:00
|
|
|
registers_t* irq_handler(uint32_t irq, registers_t* regs)
|
2025-06-13 18:03:39 -05:00
|
|
|
{
|
2026-03-20 16:57:08 -05:00
|
|
|
uint8_t funcs_called = 0;
|
|
|
|
|
|
|
|
|
|
if (num_irq_handlers > 0)
|
|
|
|
|
{
|
|
|
|
|
for (unsigned int i = 0; i < MAX_IRQ_HANDLERS; i++)
|
2025-07-03 20:30:21 -05:00
|
|
|
{
|
2026-03-20 16:57:08 -05:00
|
|
|
if (handler_list[i].irq_no == irq && handler_list[i].func != NULL)
|
|
|
|
|
{
|
|
|
|
|
regs = handler_list[i].func(regs);
|
|
|
|
|
funcs_called++;
|
|
|
|
|
/* PIC IRQ acknowledgement happens in idt.c */
|
|
|
|
|
}
|
2025-07-03 20:30:21 -05:00
|
|
|
}
|
2025-07-01 20:39:38 -05:00
|
|
|
}
|
2026-03-20 16:57:08 -05:00
|
|
|
|
|
|
|
|
if (funcs_called == 0)
|
|
|
|
|
{
|
|
|
|
|
num_irqs_missed++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return regs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t get_interrupts_missed(void)
|
|
|
|
|
{
|
|
|
|
|
return num_irqs_missed;
|
2025-07-01 20:39:38 -05:00
|
|
|
}
|
|
|
|
|
|
2026-03-20 16:57:08 -05:00
|
|
|
void set_irq_handler(uint32_t num, irq_func_t handler)
|
2025-07-01 20:39:38 -05:00
|
|
|
{
|
2026-03-20 16:57:08 -05:00
|
|
|
if (num < MAX_IRQ_HANDLERS)
|
2025-07-03 20:30:21 -05:00
|
|
|
{
|
2026-03-20 16:57:08 -05:00
|
|
|
handler_list[num].irq_no = num;
|
|
|
|
|
handler_list[num].func = handler;
|
|
|
|
|
|
|
|
|
|
num_irq_handlers++;
|
2025-07-03 20:30:21 -05:00
|
|
|
}
|
|
|
|
|
}
|