AquilaOS documentation
How it works, and its code
Toggle main menu visibility
Loading...
Searching...
No Matches
irq.c
Go to the documentation of this file.
1
8
9
#include <
core/system.h
>
10
#include <
core/string.h
>
11
#include <
mm/mm.h
>
12
#include <
dev/irq.h
>
13
#include <
platform/virt.h
>
14
#include <aquila/errno.h>
15
16
MALLOC_DEFINE
(M_IRQ,
"irq"
,
"IRQ handler"
);
17
19
struct
handler
{
20
irq_handler_t
fn
;
21
void
*
arg
;
22
struct
handler
*
next
;
23
};
24
25
/* Each interrupt's handlers, and how many times it came. */
26
static
struct
handler
*
handlers
[
IRQ_NR
];
27
static
uint64_t
counts
[
IRQ_NR
];
28
29
/*
30
* Installs a handler for an interrupt.
31
*/
32
int
irq_install
(
unsigned
irq,
irq_handler_t
fn
,
void
*
arg
)
33
{
34
if
(irq >=
IRQ_NR
)
35
return
-EINVAL;
36
37
struct
handler
*h =
kmalloc
(
sizeof
(*h), &M_IRQ,
M_ZERO
);
38
39
if
(!h)
40
return
-ENOMEM;
41
42
h->
fn
=
fn
;
43
h->
arg
=
arg
;
44
45
int
first = !
handlers
[irq];
46
struct
handler
**p = &
handlers
[irq];
47
48
while
(*p)
49
p = &(*p)->
next
;
50
51
*p = h;
52
53
if
(first)
54
gic_enable
(irq);
55
56
return
0;
57
}
58
59
/*
60
* Uninstalls a handler that irq_install() installed.
61
*/
62
void
irq_uninstall
(
unsigned
irq,
irq_handler_t
fn
,
void
*
arg
)
63
{
64
if
(irq >=
IRQ_NR
)
65
return
;
66
67
for
(
struct
handler
**p = &
handlers
[irq]; *p; p = &(*p)->
next
) {
68
struct
handler
*h = *p;
69
70
if
(h->
fn
==
fn
&& h->
arg
==
arg
) {
71
*p = h->
next
;
72
kfree
(h);
73
break
;
74
}
75
}
76
77
if
(!
handlers
[irq])
78
gic_disable
(irq);
79
}
80
84
void
irq_handle
(
void
)
85
{
86
unsigned
irq =
gic_ack
();
87
88
if
(irq >= 1020)
/* a spurious interrupt: there's none */
89
return
;
90
91
if
(irq <
IRQ_NR
) {
92
counts
[irq]++;
93
94
for
(
struct
handler
*h =
handlers
[irq]; h; h = h->
next
)
95
h->fn(h->arg);
96
}
97
98
gic_eoi
(irq);
99
}
100
101
/*
102
* Writes `/proc/interrupts`: the controller, and how many times each
103
* interrupt came.
104
*/
105
int
arch_interrupts_info
(
char
*buf,
size_t
size)
106
{
107
int
sz =
snprintf
(buf, size,
"controller: gicv2\n"
);
108
109
for
(
unsigned
i = 0; i <
IRQ_NR
&& (
size_t
) sz < size; ++i)
110
if
(
counts
[i])
111
sz +=
snprintf
(buf + sz, size - sz,
"%d: %ld\n"
, i,
counts
[i]);
112
113
return
sz;
114
}
irq_uninstall
void irq_uninstall(unsigned irq, irq_handler_t fn, void *arg)
Removes a handler that irq_install() installed.
Definition
irq.c:62
counts
static uint64_t counts[IRQ_NR]
Definition
irq.c:27
arch_interrupts_info
int arch_interrupts_info(char *buf, size_t size)
Definition
irq.c:105
irq_install
int irq_install(unsigned irq, irq_handler_t fn, void *arg)
Installs a handler for an IRQ.
Definition
irq.c:32
handlers
static struct handler * handlers[IRQ_NR]
Definition
irq.c:26
gic_eoi
void gic_eoi(unsigned irq)
Tells the GIC that an interrupt has been handled (end of interrupt).
Definition
gic.c:95
gic_ack
unsigned gic_ack(void)
Acknowledges the interrupt that came.
Definition
gic.c:85
gic_disable
void gic_disable(unsigned irq)
Disables (masks) an interrupt.
Definition
gic.c:75
gic_enable
void gic_enable(unsigned irq)
Enables (unmasks) an interrupt.
Definition
gic.c:65
system.h
mm.h
irq.h
irq_handler_t
void(*) irq_handler_t(void *arg)
Definition
irq.h:21
MALLOC_DEFINE
#define MALLOC_DEFINE(type, _name, _desc)
Definition
kvmem.h:30
kmalloc
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
Definition
kvmem.c:123
M_ZERO
#define M_ZERO
Definition
kvmem.h:26
kfree
void kfree(void *)
Frees an object that kmalloc() gave.
Definition
kvmem.c:146
snprintf
int snprintf(char *s, size_t n, const char *fmt,...)
Formats a string into a buffer.
Definition
snprintf.c:226
size_t
__SIZE_TYPE__ size_t
Definition
stddef.h:7
uint64_t
unsigned long long int uint64_t
Definition
stddef.h:23
string.h
handler
An installed handler, on its interrupt's list.
Definition
irq.c:19
handler::arg
void * arg
Definition
irq.c:21
handler::next
struct handler * next
Definition
irq.c:22
handler::fn
irq_handler_t fn
Definition
irq.c:20
virt.h
irq_handle
void irq_handle(void)
Runs the handlers of the interrupt that came, then tells the GIC it's done, before any thread switch,...
Definition
irq.c:84
IRQ_NR
#define IRQ_NR
Definition
virt.h:43
kernel
arch
aarch64
platform
virt
irq.c
Generated by
1.18.0