MOS Source Code
Loading...
Searching...
No Matches
ioapic.cpp
Go to the documentation of this file.
1
// SPDX-License-Identifier: GPL-3.0-or-later
2
3
#include <
mos/mm/paging/paging.hpp
>
4
#include <
mos/mm/physical/pmm.hpp
>
5
#include <
mos/platform/platform.hpp
>
6
#include <
mos/syslog/printk.hpp
>
7
#include <
mos/x86/acpi/madt.hpp
>
8
#include <
mos/x86/interrupt/apic.hpp
>
9
#include <
mos/x86/x86_interrupt.hpp
>
10
#include <
mos/x86/x86_platform.hpp
>
11
12
// +-------+ +-------+ +-------+
13
// | | | | | |
14
// | CPU 0 | | CPU 1 | | CPU 2 | ...
15
// | | | | | |
16
// +-------+ +-------+ +-------+
17
// | LAPIC | | LAPIC | | LAPIC | ...
18
// +---+---+ +---+---+ +---+---+
19
// | | |
20
// | +------+ |
21
// +---+ | +-----------------+
22
// | | |
23
// | | |
24
// +--v--v--v---+
25
// | I/O APIC | <- Interrupts are sent to this
26
// +------------+
27
28
#define IOAPIC_REG_ID 0x00
29
#define IOAPIC_REG_VERSION 0x01
30
#define IOAPIC_REG_ARB_ID 0x02
31
#define IOAPIC_REG_REDIR_TABLE(n) (0x10 + 2 * (n))
32
33
typedef
struct
34
{
35
u8
interrupt_vec
: 8;
36
u8
delivery_mode
: 3;
// 0 = Normal, 1 = Low Priority, 2 = SMI, 4 = NMI, 5 = INIT, 7 = External
37
bool
destination_mode
: 1;
// 0 = Physical, 1 = Logical
38
bool
pending
: 1;
// 1 = if this interrupt is going to be sent, but the APIC is busy
39
ioapic_polarity_t
polarity
: 1;
// 0 = Active High, 1 = Active Low
40
bool
something
: 1;
// 0 = a local APIC has sent an EOI, 1 = a local APIC has received the interrupt
41
ioapic_trigger_mode_t
trigger_mode
: 1;
// 0 = Edge, 1 = Level
42
bool
mask
: 1;
// 0 = Enabled, 1 = Disabled
43
u64
reserved
: 39;
44
struct
45
{
46
u8
target_apic_id
: 4;
47
u8
something_else
: 4;
48
}
__packed
destination;
49
}
__packed
ioapic_redirection_entry_t
;
50
51
MOS_STATIC_ASSERT
(
sizeof
(
ioapic_redirection_entry_t
) ==
sizeof
(
u64
),
"ioapic_register_1 is not 64 bits"
);
52
53
static
u32
volatile
*
ioapic
=
NULL
;
54
55
should_inline
u32
ioapic_read
(
u32
reg)
56
{
57
ioapic
[0] = reg & 0xff;
58
return
ioapic
[4];
59
}
60
61
should_inline
void
ioapic_write
(
u32
reg,
u32
value)
62
{
63
ioapic
[0] = reg & 0xff;
64
ioapic
[4] = value;
65
}
66
67
should_inline
void
ioapic_write_redirection_entry
(
u32
irq,
ioapic_redirection_entry_t
entry)
68
{
69
union
70
{
71
u64
value;
72
ioapic_redirection_entry_t
entry;
73
}
__packed
u = { .entry = entry };
74
75
ioapic_write
(
IOAPIC_REG_REDIR_TABLE
(irq), u.value & 0xffffffff);
76
ioapic_write
(
IOAPIC_REG_REDIR_TABLE
(irq) + 1, u.value >> 32);
77
}
78
79
should_inline
ioapic_redirection_entry_t
ioapic_read_redirection_entry
(
u32
irq)
80
{
81
union
82
{
83
u64
value;
84
ioapic_redirection_entry_t
entry;
85
}
__packed
u = { 0 };
86
87
u.value =
ioapic_read
(
IOAPIC_REG_REDIR_TABLE
(irq));
88
u.value |= (
u64
)
ioapic_read
(
IOAPIC_REG_REDIR_TABLE
(irq) + 1) << 32;
89
90
return
u.entry;
91
}
92
93
void
ioapic_init
(
void
)
94
{
95
MOS_ASSERT_X
(
x86_ioapic_phyaddr
!= 0,
"ioapic: no ioapic found in madt"
);
96
if
(!
pmm_find_reserved_region
(
x86_ioapic_phyaddr
))
97
{
98
pr_info
(
"reserving ioapic address"
);
99
pmm_reserve_address
(
x86_ioapic_phyaddr
);
100
}
101
102
ioapic
= (
u32
volatile
*)
pa_va
(
x86_ioapic_phyaddr
);
103
const
u32
ioapic_id =
ioapic_read
(
IOAPIC_REG_ID
) >> 24 & 0xf;
// get the 24-27 bits
104
105
const
union
106
{
107
u32
value;
108
struct
109
{
110
u32
version : 8;
// 0 - 7
111
u32
reserved : 8;
112
u32
max_entries : 8;
// 16 - 23
113
u32
reserved2 : 8;
114
}
__packed
;
115
} version = { .value =
ioapic_read
(
IOAPIC_REG_VERSION
) };
116
117
const
u32
arb_id =
ioapic_read
(
IOAPIC_REG_ARB_ID
) >> 24 & 0xf;
// get the 24-27 bits
118
119
pr_dinfo2
(x86_ioapic,
"max IRQs: %d, id: %d, version: %d, arb: %d"
, version.max_entries + 1, ioapic_id, version.version, arb_id);
120
121
for
(
int
i = 0; i < version.max_entries + 1; i++)
122
ioapic_disable
(i);
123
}
124
125
void
ioapic_enable_with_mode
(
u32
irq,
u32
lapic_id,
ioapic_trigger_mode_t
trigger_mode,
ioapic_polarity_t
polarity)
126
{
127
pr_dinfo2
(x86_ioapic,
"enable irq %d, cpu lapic-id: %d, trigger_mode %d, polarity %d"
, irq, lapic_id, trigger_mode, polarity);
128
129
ioapic_redirection_entry_t
entry = { 0 };
130
entry.
interrupt_vec
= irq +
ISR_MAX_COUNT
;
// the vector number received by the CPU
131
entry.
polarity
= polarity;
132
entry.
trigger_mode
= trigger_mode;
133
entry.
destination
.
target_apic_id
= lapic_id;
134
135
const
u32
irq_overridden =
x86_ioapic_get_irq_override
(irq);
// the irq number received by the ioapic "pin"
136
ioapic_write_redirection_entry
(irq_overridden, entry);
137
}
138
139
void
ioapic_disable
(
u32
irq)
140
{
141
ioapic_redirection_entry_t
entry = { 0 };
142
entry.
interrupt_vec
= irq +
ISR_MAX_COUNT
;
143
entry.
mask
=
true
;
144
ioapic_write_redirection_entry
(irq, entry);
145
}
apic.hpp
ioapic_polarity_t
ioapic_polarity_t
Definition
apic.hpp:60
ioapic_trigger_mode_t
ioapic_trigger_mode_t
Definition
apic.hpp:54
MOS_ASSERT_X
#define MOS_ASSERT_X(cond, msg,...)
Definition
assert.hpp:15
pa_va
#define pa_va(pa)
Definition
mm.hpp:81
pmm_find_reserved_region
pmm_region_t * pmm_find_reserved_region(ptr_t needle)
Find a region in the physical memory manager.
Definition
pmm.cpp:131
pmm_reserve_address
#define pmm_reserve_address(paddr)
Definition
pmm.hpp:109
ioapic_init
void ioapic_init(void)
Definition
ioapic.cpp:93
ioapic_enable_with_mode
void ioapic_enable_with_mode(u32 irq, u32 lapic_id, ioapic_trigger_mode_t trigger_mode, ioapic_polarity_t polarity)
Definition
ioapic.cpp:125
ioapic
static u32 volatile * ioapic
Definition
ioapic.cpp:53
ioapic_write_redirection_entry
should_inline void ioapic_write_redirection_entry(u32 irq, ioapic_redirection_entry_t entry)
Definition
ioapic.cpp:67
ioapic_read
should_inline u32 ioapic_read(u32 reg)
Definition
ioapic.cpp:55
IOAPIC_REG_ID
#define IOAPIC_REG_ID
Definition
ioapic.cpp:28
IOAPIC_REG_VERSION
#define IOAPIC_REG_VERSION
Definition
ioapic.cpp:29
IOAPIC_REG_REDIR_TABLE
#define IOAPIC_REG_REDIR_TABLE(n)
Definition
ioapic.cpp:31
ioapic_read_redirection_entry
should_inline ioapic_redirection_entry_t ioapic_read_redirection_entry(u32 irq)
Definition
ioapic.cpp:79
ioapic_disable
void ioapic_disable(u32 irq)
Definition
ioapic.cpp:139
IOAPIC_REG_ARB_ID
#define IOAPIC_REG_ARB_ID
Definition
ioapic.cpp:30
ioapic_write
should_inline void ioapic_write(u32 reg, u32 value)
Definition
ioapic.cpp:61
x86_ioapic_get_irq_override
u32 x86_ioapic_get_irq_override(u32 irq)
Definition
madt.cpp:18
x86_ioapic_phyaddr
ptr_t x86_ioapic_phyaddr
Definition
madt.cpp:12
madt.hpp
__packed
#define __packed
Definition
mos_global.h:29
should_inline
#define should_inline
Definition
mos_global.h:37
MOS_STATIC_ASSERT
#define MOS_STATIC_ASSERT
Definition
mos_global.h:14
paging.hpp
NULL
#define NULL
Definition
pb_syshdr.h:46
platform.hpp
pmm.hpp
printk.hpp
pr_info
#define pr_info(fmt,...)
Definition
printk.hpp:35
pr_dinfo2
#define pr_dinfo2(feat, fmt,...)
Definition
printk.hpp:27
ioapic_redirection_entry_t
Definition
ioapic.cpp:34
ioapic_redirection_entry_t::delivery_mode
u8 delivery_mode
Definition
ioapic.cpp:36
ioapic_redirection_entry_t::pending
bool pending
Definition
ioapic.cpp:38
ioapic_redirection_entry_t::target_apic_id
u8 target_apic_id
Definition
ioapic.cpp:46
ioapic_redirection_entry_t::something
bool something
Definition
ioapic.cpp:40
ioapic_redirection_entry_t::destination
struct ioapic_redirection_entry_t::@002345073164106336160156103234235272220133265167 destination
ioapic_redirection_entry_t::interrupt_vec
u8 interrupt_vec
Definition
ioapic.cpp:35
ioapic_redirection_entry_t::something_else
u8 something_else
Definition
ioapic.cpp:47
ioapic_redirection_entry_t::trigger_mode
ioapic_trigger_mode_t trigger_mode
Definition
ioapic.cpp:41
ioapic_redirection_entry_t::destination_mode
bool destination_mode
Definition
ioapic.cpp:37
ioapic_redirection_entry_t::mask
bool mask
Definition
ioapic.cpp:42
ioapic_redirection_entry_t::polarity
ioapic_polarity_t polarity
Definition
ioapic.cpp:39
ioapic_redirection_entry_t::reserved
u64 reserved
Definition
ioapic.cpp:43
u32
unsigned int u32
Definition
types.h:17
u64
unsigned long long u64
Definition
types.h:19
u8
unsigned char u8
Definition
types.h:15
x86_interrupt.hpp
ISR_MAX_COUNT
#define ISR_MAX_COUNT
Definition
x86_interrupt.hpp:14
x86_platform.hpp
kernel
arch
x86_64
interrupt
ioapic.cpp
Generated on Tue Feb 18 2025 16:41:40 for MOS Source Code by
1.13.2