miniOS
x86_64 hobby kernel with SMP, VFS, and POSIX process model
Toggle main menu visibility
Loading...
Searching...
No Matches
apic.h
Go to the documentation of this file.
1
// MIT License
2
//
3
// Copyright (c) 2026 Christian Spoo
4
//
5
// Permission is hereby granted, free of charge, to any person obtaining a copy
6
// of this software and associated documentation files (the "Software"), to deal
7
// in the Software without restriction, including without limitation the rights
8
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the Software is
10
// furnished to do so, subject to the following conditions:
11
//
12
// The above copyright notice and this permission notice shall be included in all
13
// copies or substantial portions of the Software.
14
//
15
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
// SOFTWARE.
22
34
35
#ifndef _MINIOS_ARCH_X86_64_APIC_H_
36
#define _MINIOS_ARCH_X86_64_APIC_H_
37
38
#include <
miniOS/types.h
>
39
40
/* ------------------------------------------------------------------ */
41
/* LAPIC MMIO register offsets (byte offsets from lapic_base) */
42
/* ------------------------------------------------------------------ */
43
#define LAPIC_ID 0x020
/* Local APIC ID register */
44
#define LAPIC_EOI 0x0B0
/* End-of-Interrupt register */
45
#define LAPIC_SVR 0x0F0
/* Spurious Interrupt Vector Register */
46
#define LAPIC_ICR_LOW 0x300
/* Interrupt Command Register low */
47
#define LAPIC_ICR_HIGH 0x310
/* Interrupt Command Register high */
48
#define LAPIC_TIMER_LVT 0x320
/* LVT Timer register */
49
#define LAPIC_TIMER_ICR 0x380
/* Timer Initial Count Register */
50
#define LAPIC_TIMER_CCR 0x390
/* Timer Current Count Register */
51
#define LAPIC_TIMER_DCR 0x3E0
/* Timer Divide Configuration Register*/
52
53
/* ------------------------------------------------------------------ */
54
/* SVR flags */
55
/* ------------------------------------------------------------------ */
56
#define LAPIC_SVR_ENABLE (1 << 8)
/* Software enable bit */
57
#define LAPIC_SPURIOUS_VECTOR 0xFF
/* Spurious interrupt vector */
58
59
/* ------------------------------------------------------------------ */
60
/* IA32_APIC_BASE MSR */
61
/* ------------------------------------------------------------------ */
62
#define IA32_APIC_BASE_MSR 0x1B
63
#define IA32_APIC_BASE_ENABLE (1 << 11)
/* Global enable bit */
64
65
/* ------------------------------------------------------------------ */
66
/* LAPIC base pointer (set by lapic_init) */
67
/* ------------------------------------------------------------------ */
68
extern
volatile
uint32_t
*
lapic_base
;
69
70
/* ------------------------------------------------------------------ */
71
/* Public API */
72
/* ------------------------------------------------------------------ */
73
85
void
lapic_init
(
void
);
86
92
static
inline
void
lapic_write
(
uint32_t
reg,
uint32_t
val) {
93
lapic_base
[reg / 4] = val;
94
}
95
101
static
inline
uint32_t
lapic_read
(
uint32_t
reg) {
102
return
lapic_base
[reg / 4];
103
}
104
111
static
inline
void
lapic_eoi
(
void
) {
112
lapic_write
(
LAPIC_EOI
, 0);
113
}
114
121
void
lapic_eoi_asm
(
void
);
122
134
void
lapic_send_ipi
(
uint8_t
target_lapic_id,
uint8_t
vector);
135
136
/* ------------------------------------------------------------------ */
137
/* I/O APIC MMIO base (physical). */
138
/* Identity-mapped via page_table_l2_mmio L2[502] (2MB huge page). */
139
/* ------------------------------------------------------------------ */
140
#define IOAPIC_BASE 0xFEC00000UL
141
/* I/O APIC indirect registers (byte offsets from IOAPIC_BASE) */
142
#define IOAPIC_REGSEL 0x00
/* register select */
143
#define IOAPIC_IOWIN 0x10
/* data window */
144
/* I/O APIC indirect register indices */
145
#define IOAPIC_ID 0x00
146
#define IOAPIC_VER 0x01
147
#define IOAPIC_REDTBL_LO(n) (0x10 + (n)*2)
/* low 32 bits of redirection entry n */
148
#define IOAPIC_REDTBL_HI(n) (0x10 + (n)*2 + 1)
/* high 32 bits of redirection entry n */
149
/* Redirection entry bits */
150
#define IOAPIC_RTE_MASKED (1 << 16)
/* set to mask (disable) this IRQ line */
151
#define IOAPIC_RTE_LEVEL (1 << 15)
/* 0=edge, 1=level trigger */
152
#define IOAPIC_RTE_LOPOL (1 << 13)
/* 0=active-high, 1=active-low polarity */
153
/* First IDT vector for external IRQs (vectors 0-31 are CPU exceptions) */
154
#define IRQ_VECTOR_BASE 32
155
164
void
ioapic_init
(
void
);
165
171
void
ioapic_mask_irq
(
uint8_t
irq);
172
178
void
ioapic_unmask_irq
(
uint8_t
irq);
179
180
/* ------------------------------------------------------------------ */
181
/* LAPIC timer */
182
/* ------------------------------------------------------------------ */
183
#define LAPIC_TIMER_PERIODIC (1 << 17)
/* LVT timer mode: periodic */
184
#define LAPIC_TIMER_ONESHOT (0 << 17)
/* LVT timer mode: one-shot */
185
#define LAPIC_TIMER_MASKED (1 << 16)
/* LVT: mask the timer */
186
#define LAPIC_TIMER_VECTOR 48
/* IDT vector for LAPIC timer */
187
#define SCHEDULER_KICK_VECTOR 50
/* IDT vector: scheduler-kick IPI from remote CPU */
188
#define PANIC_HALT_VECTOR 52
/* IDT vector: panic-halt IPI broadcast */
189
/* IDT vectors 53..53+MAX_CPUS-1: one dedicated TLB-shootdown IPI vector per
190
* possible INITIATOR CPU (hardcoded to 8 — must match MAX_CPUS's default in
191
* smp.h; there is no build-system plumbing to pass MAX_CPUS into the NASM
192
* assembler). Giving each initiator its own vector (and barrier slot, see
193
* ipi.h) means concurrent shootdowns started by different CPUs never share
194
* mutable state — see ipi.c for why a single shared vector/barrier isn't
195
* safe under SMP. */
196
#define TLB_SHOOTDOWN_VECTOR_BASE 53
197
#define LAPIC_TIMER_DIVBY_16 0x3
/* DCR divide-by-16 */
198
206
void
lapic_timer_idt_install
(
void
);
207
216
void
lapic_timer_init
(
void
);
217
extern
volatile
uint64_t
lapic_tick_count
;
218
219
/* BSP-calibrated LAPIC timer ICR value (written by lapic_timer_init).
220
APs read this to start their timers without running PIT calibration again. */
221
extern
uint32_t
lapic_bsp_timer_icr
;
222
231
void
lapic_timer_init_ap
(
void
);
232
234
235
#endif
/* _MINIOS_ARCH_X86_64_APIC_H_ */
lapic_tick_count
volatile uint64_t lapic_tick_count
Definition
lapic.c:147
lapic_eoi
static void lapic_eoi(void)
Signal End-of-Interrupt to the local APIC.
Definition
apic.h:111
ioapic_init
void ioapic_init(void)
Map and initialise the I/O APIC.
Definition
ioapic.c:67
LAPIC_EOI
#define LAPIC_EOI
Definition
apic.h:44
lapic_read
static uint32_t lapic_read(uint32_t reg)
Read a 32-bit value from a LAPIC MMIO register.
Definition
apic.h:101
lapic_eoi_asm
void lapic_eoi_asm(void)
Non-inline wrapper for lapic_eoi(), callable from assembly.
Definition
lapic.c:139
lapic_init
void lapic_init(void)
Detect, identity-map, and software-enable the local APIC.
Definition
lapic.c:56
lapic_timer_init
void lapic_timer_init(void)
Calibrate and start the BSP LAPIC timer.
Definition
lapic.c:187
lapic_send_ipi
void lapic_send_ipi(uint8_t target_lapic_id, uint8_t vector)
Send a Fixed IPI to a remote CPU.
Definition
lapic.c:298
lapic_base
volatile uint32_t * lapic_base
Definition
lapic.c:42
lapic_write
static void lapic_write(uint32_t reg, uint32_t val)
Write a 32-bit value to a LAPIC MMIO register.
Definition
apic.h:92
lapic_bsp_timer_icr
uint32_t lapic_bsp_timer_icr
Definition
lapic.c:47
ioapic_unmask_irq
void ioapic_unmask_irq(uint8_t irq)
Unmask (enable) an I/O APIC redirection entry.
Definition
ioapic.c:62
lapic_timer_idt_install
void lapic_timer_idt_install(void)
Install the IDT entry for LAPIC_TIMER_VECTOR (48).
Definition
lapic.c:181
lapic_timer_init_ap
void lapic_timer_init_ap(void)
Start the LAPIC timer on the calling AP.
Definition
lapic.c:271
ioapic_mask_irq
void ioapic_mask_irq(uint8_t irq)
Mask (disable) an I/O APIC redirection entry.
Definition
ioapic.c:57
types.h
uint32_t
unsigned int uint32_t
Definition
types.h:34
uint64_t
unsigned long int uint64_t
Definition
types.h:37
uint8_t
unsigned char uint8_t
Definition
types.h:28
include
miniOS
arch
x86_64
apic.h
Generated by
1.18.0