1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#include "mos/interrupt/interrupt.h"
4
5#include "mos/lib/structures/list.h"
6#include "mos/mm/slab_autoinit.h"
7
8#include <mos_stdlib.h>
9
10typedef struct
11{
12 as_linked_list;
13 u32 irq;
14 irq_serve_t handler;
15 void *data;
16} interrupt_handler_t;
17
18static spinlock_t irq_handlers_lock = SPINLOCK_INIT;
19static list_head irq_handlers = LIST_HEAD_INIT(irq_handlers);
20
21static slab_t *irq_handler_slab = NULL;
22SLAB_AUTOINIT("irq_handler", irq_handler_slab, interrupt_handler_t);
23
24void interrupt_entry(u32 irq)
25{
26 // spinlock_acquire(&irq_handlers_lock);
27
28 list_foreach(interrupt_handler_t, handler, irq_handlers)
29 {
30 if (handler->irq == irq)
31 if (handler->handler(irq, handler->data))
32 break; // interrupt was handled
33 }
34
35 // spinlock_release(&irq_handlers_lock);
36}
37
38void interrupt_handler_register(u32 irq, irq_serve_t handler, void *data)
39{
40 interrupt_handler_t *new_handler = kmalloc(irq_handler_slab);
41 new_handler->irq = irq;
42 new_handler->handler = handler;
43 new_handler->data = data;
44
45 spinlock_acquire(&irq_handlers_lock);
46 list_node_append(head: &irq_handlers, item: &new_handler->list_node);
47 spinlock_release(&irq_handlers_lock);
48}
49