miniOS
x86_64 hobby kernel with SMP, VFS, and POSIX process model
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/* ------------------------------------------------------------------ */
68extern volatile uint32_t *lapic_base;
69
70/* ------------------------------------------------------------------ */
71/* Public API */
72/* ------------------------------------------------------------------ */
73
85void lapic_init(void);
86
92static inline void lapic_write(uint32_t reg, uint32_t val) {
93 lapic_base[reg / 4] = val;
94}
95
101static inline uint32_t lapic_read(uint32_t reg) {
102 return lapic_base[reg / 4];
103}
104
111static inline void lapic_eoi(void) {
113}
114
121void lapic_eoi_asm(void);
122
134void 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
164void ioapic_init(void);
165
171void ioapic_mask_irq(uint8_t irq);
172
178void 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 TLB_SHOOTDOWN_VECTOR 51 /* IDT vector: TLB-shootdown IPI broadcast */
189#define PANIC_HALT_VECTOR 52 /* IDT vector: panic-halt IPI broadcast */
190#define LAPIC_TIMER_DIVBY_16 0x3 /* DCR divide-by-16 */
191
199void lapic_timer_idt_install(void);
200
209void lapic_timer_init(void);
210extern volatile uint64_t lapic_tick_count;
211
212/* BSP-calibrated LAPIC timer ICR value (written by lapic_timer_init).
213 APs read this to start their timers without running PIT calibration again. */
215
224void lapic_timer_init_ap(void);
225
227
228#endif /* _MINIOS_ARCH_X86_64_APIC_H_ */
volatile uint64_t lapic_tick_count
Definition lapic.c:126
static void lapic_eoi(void)
Signal End-of-Interrupt to the local APIC.
Definition apic.h:111
void ioapic_init(void)
Map and initialise the I/O APIC.
Definition ioapic.c:67
#define LAPIC_EOI
Definition apic.h:44
static uint32_t lapic_read(uint32_t reg)
Read a 32-bit value from a LAPIC MMIO register.
Definition apic.h:101
void lapic_eoi_asm(void)
Non-inline wrapper for lapic_eoi(), callable from assembly.
Definition lapic.c:118
void lapic_init(void)
Detect, identity-map, and software-enable the local APIC.
Definition lapic.c:54
void lapic_timer_init(void)
Calibrate and start the BSP LAPIC timer.
Definition lapic.c:166
void lapic_send_ipi(uint8_t target_lapic_id, uint8_t vector)
Send a Fixed IPI to a remote CPU.
Definition lapic.c:284
volatile uint32_t * lapic_base
Definition lapic.c:40
static void lapic_write(uint32_t reg, uint32_t val)
Write a 32-bit value to a LAPIC MMIO register.
Definition apic.h:92
uint32_t lapic_bsp_timer_icr
Definition lapic.c:45
void ioapic_unmask_irq(uint8_t irq)
Unmask (enable) an I/O APIC redirection entry.
Definition ioapic.c:62
void lapic_timer_idt_install(void)
Install the IDT entry for LAPIC_TIMER_VECTOR (48).
Definition lapic.c:160
void lapic_timer_init_ap(void)
Start the LAPIC timer on the calling AP.
Definition lapic.c:257
void ioapic_mask_irq(uint8_t irq)
Mask (disable) an I/O APIC redirection entry.
Definition ioapic.c:57
unsigned int uint32_t
Definition types.h:34
unsigned long int uint64_t
Definition types.h:37
unsigned char uint8_t
Definition types.h:28