Skip to content

Commit dd6fff7

Browse files
kfree hygene, and code comments
1 parent b3bc66d commit dd6fff7

30 files changed

+727
-357
lines changed

include/acpi.h

Lines changed: 134 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,139 +1,209 @@
11
/**
22
* @file acpi.h
33
* @author Craig Edwards (craigedwards@brainbox.cc)
4-
* @copyright Copyright (c) 2012-2025
4+
* @brief ACPI detection and enumeration header. Provides low-level interfaces
5+
* to extract CPU topology, IOAPIC mappings, and PCI IRQ routing from
6+
* ACPI tables such as RSDP, XSDT, MADT, and others.
7+
* @copyright Copyright (c) 2012–2025
58
*/
69
#pragma once
710

811
#include <kernel.h>
912

1013
/**
1114
* @brief ACPI Root System Description Pointer (RSDP)
15+
*
16+
* This structure serves as the entry point to the ACPI system description tables.
17+
* Its location is typically found by scanning the BIOS memory range. It may point
18+
* to either the RSDT (ACPI 1.0) or XSDT (ACPI 2.0+).
1219
*/
1320
typedef struct rsdp_t {
14-
char signature[8]; // "RSD PTR "
15-
uint8_t checksum;
16-
char oem_id[6]; // OEM identifier string
17-
uint8_t revision; // 0 for ACPI 1.0, >0 for ACPI 2.0 or later
18-
uint32_t rsdt_address; // Root System Description Table Address
19-
uint32_t length; // Length of Root System Description Table
20-
uint64_t xsdt_address; // Extended System Description Table Address
21-
uint8_t extended_checksum; // Extended System Description Table Checksum
22-
uint8_t reserved[3]; // Reserved
21+
char signature[8]; ///< Should contain "RSD PTR "
22+
uint8_t checksum; ///< Checksum of first 20 bytes
23+
char oem_id[6]; ///< OEM identifier string
24+
uint8_t revision; ///< Revision: 0 = ACPI 1.0, 2+ = ACPI 2.0+
25+
uint32_t rsdt_address; ///< 32-bit physical address of RSDT
26+
uint32_t length; ///< Total length of the RSDP (ACPI 2.0+)
27+
uint64_t xsdt_address; ///< 64-bit physical address of XSDT (ACPI 2.0+)
28+
uint8_t extended_checksum; ///< Checksum of entire RSDP (ACPI 2.0+)
29+
uint8_t reserved[3]; ///< Reserved bytes (must be zero)
2330
} __attribute__((packed)) rsdp_t;
2431

2532
/**
26-
* @brief System Description Table Header
33+
* @brief Generic ACPI System Description Table Header
34+
*
35+
* All ACPI tables begin with this header. It is used to identify table type,
36+
* length, version, and source information.
2737
*/
2838
typedef struct sdt_header_t {
29-
char signature[4];
30-
uint32_t length;
31-
uint8_t revision;
32-
uint8_t checksum;
33-
char oem_id[6];
34-
char oem_table_id[8];
35-
uint32_t oem_revision;
36-
uint32_t creator_id;
37-
uint32_t creator_revision;
39+
char signature[4]; ///< Table identifier (e.g. "APIC", "DSDT", etc.)
40+
uint32_t length; ///< Total length of the table, including this header
41+
uint8_t revision; ///< Table version
42+
uint8_t checksum; ///< Entire table checksum
43+
char oem_id[6]; ///< OEM identifier string
44+
char oem_table_id[8]; ///< OEM-defined table identifier
45+
uint32_t oem_revision; ///< OEM table revision
46+
uint32_t creator_id; ///< Vendor ID of utility that created the table
47+
uint32_t creator_revision; ///< Version of utility that created the table
3848
} __attribute__((packed)) sdt_header_t;
3949

4050
/**
41-
* @brief Root System Description Table
51+
* @brief Root System Description Table (RSDT)
52+
*
53+
* Points to other system description tables using 32-bit addresses.
54+
* Superseded by XSDT in ACPI 2.0+ which uses 64-bit addresses.
4255
*/
4356
typedef struct rsdt_t {
44-
sdt_header_t header; // System Description Table header
45-
uint32_t pointer_to_other_sdt[]; // 32-Bit Pointer to other table
46-
57+
sdt_header_t header; ///< Standard ACPI header
58+
uint32_t pointer_to_other_sdt[]; ///< Array of 32-bit physical addresses to other tables
4759
} __attribute__((packed)) rsdt_t;
4860

4961
/**
50-
* @brief Definition of an IOAPIC
62+
* @brief Describes a detected IOAPIC from the MADT table.
5163
*/
5264
typedef struct ioapic_t {
53-
uint8_t id; // The IO APIC id.
54-
uint64_t paddr; // The physical address of the MMIO region.
55-
uint32_t gsi_base; // The GSI base.
56-
uint8_t gsi_count; // The interrupt count.
65+
uint8_t id; ///< IOAPIC ID as reported by MADT
66+
uint64_t paddr; ///< Physical address of the IOAPIC's MMIO region
67+
uint32_t gsi_base; ///< Global System Interrupt (GSI) base for this IOAPIC
68+
uint8_t gsi_count; ///< Number of GSIs this IOAPIC handles
5769
} ioapic_t;
5870

71+
/**
72+
* @brief Describes an IRQ override from the MADT table.
73+
*
74+
* Used to override the default IRQ to GSI mapping, and specify trigger mode and polarity.
75+
*/
5976
typedef struct {
60-
uint8_t type;
61-
uint8_t length;
62-
uint8_t bus_source;
63-
uint8_t irq_source;
64-
uint32_t gsi;
65-
uint16_t flags;
77+
uint8_t type; ///< Entry type (always 2 for overrides)
78+
uint8_t length; ///< Length of this entry
79+
uint8_t bus_source; ///< Typically 0 (ISA bus)
80+
uint8_t irq_source; ///< Original IRQ number
81+
uint32_t gsi; ///< New GSI mapping
82+
uint16_t flags; ///< Bitmask defining polarity and trigger mode
6683
} __attribute__((packed)) madt_override_t;
6784

68-
#define IRQ_DEFAULT_POLARITY 0 // active high
69-
#define IRQ_DEFAULT_TRIGGER 0 // edge
85+
/**
86+
* @brief Default polarity: active high
87+
*/
88+
#define IRQ_DEFAULT_POLARITY 0
89+
90+
/**
91+
* @brief Default trigger mode: edge-triggered
92+
*/
93+
#define IRQ_DEFAULT_TRIGGER 0
7094

95+
/**
96+
* @brief Indicates the source of a PCI IRQ route.
97+
*/
7198
typedef enum detected_from {
72-
FROM_MADT,
73-
FROM_PRT,
74-
FROM_FALLBACK,
99+
FROM_MADT, ///< IRQ derived from MADT (ACPI interrupt overrides)
100+
FROM_PRT, ///< IRQ derived from PCI Routing Table (_PRT)
101+
FROM_FALLBACK, ///< No override detected, fallback to default IRQ mapping
75102
} detected_from_t;
76103

104+
/**
105+
* @brief A mapping of PCI interrupt pin to global system interrupt (GSI).
106+
*
107+
* Used for routing PCI IRQs through ACPI, based on _PRT or MADT.
108+
*/
77109
typedef struct pci_irq_route {
78-
bool exists;
79-
uint8_t int_pin;
80-
uint32_t gsi;
81-
int polarity; // 0 = high, 1 = low
82-
int trigger; // 0 = edge, 1 = level
83-
detected_from_t detected_from;
110+
bool exists; ///< True if this route is defined
111+
uint8_t int_pin; ///< PCI interrupt pin (INTA–INTD)
112+
uint32_t gsi; ///< Global System Interrupt (GSI) to which the pin maps
113+
int polarity; ///< Interrupt polarity (0 = high, 1 = low)
114+
int trigger; ///< Trigger mode (0 = edge, 1 = level)
115+
detected_from_t detected_from; ///< Source of route (MADT, PRT, or fallback)
84116
} pci_irq_route_t;
85117

86-
#define MAX_PCI_ROUTES 256
118+
#define MAX_PCI_ROUTES 256 ///< Maximum number of PCI IRQ routes supported
87119

88120
/**
89-
* @brief Detect SMP cores, IOAPICs, Local APICs
121+
* @brief Detect SMP CPU cores and APICs (Local and IOAPIC).
122+
*
123+
* This function parses the MADT (APIC table) and sets up CPU topology and IOAPIC data.
90124
*/
91125
void init_cores();
92126

93127
/**
94-
* @brief Get the local apic ids
95-
*
96-
* @return uint8_t*
128+
* @brief Get an array of Local APIC IDs.
129+
*
130+
* @return Pointer to array of LAPIC IDs (size = get_cpu_count()).
97131
*/
98132
uint8_t* get_lapic_ids();
99133

100134
/**
101-
* @brief Get the cpu count
102-
*
103-
* @return uint16_t
135+
* @brief Get total number of CPUs detected via ACPI.
136+
*
137+
* @return Number of CPUs detected.
104138
*/
105139
uint16_t get_cpu_count();
106140

107141
/**
108-
* @brief Get the local apic
109-
*
110-
* @return uint64_t
142+
* @brief Retrieve the physical address of the Local APIC MMIO.
143+
*
144+
* @return 64-bit physical address of LAPIC base.
111145
*/
112146
uint64_t get_local_apic();
113147

114148
/**
115-
* @brief Get the ioapic
116-
*
117-
* @param index IOAPIC index
118-
* @return ioapic_t
149+
* @brief Retrieve the IOAPIC structure by index.
150+
*
151+
* @param index IOAPIC index in internal array
152+
* @return ioapic_t structure containing details of the IOAPIC
119153
*/
120154
ioapic_t get_ioapic(uint16_t index);
121155

122156
/**
123-
* @brief Get the ioapic count
124-
*
125-
* @return uint16_t total number of IOAPICs
157+
* @brief Get the total number of IOAPICs detected in the system.
158+
*
159+
* @return Number of IOAPICs.
126160
*/
127161
uint16_t get_ioapic_count();
128162

163+
/**
164+
* @brief Translate a legacy IRQ number (0–15) into a GSI using overrides.
165+
*
166+
* @param irq Legacy IRQ number
167+
* @return Global System Interrupt (GSI) for the IRQ
168+
*/
129169
uint32_t irq_to_gsi(uint8_t irq);
130170

171+
/**
172+
* @brief Determine the interrupt polarity of a given IRQ.
173+
*
174+
* @param irq IRQ number
175+
* @return 0 for active high, 1 for active low
176+
*/
131177
uint8_t get_irq_polarity(uint8_t irq);
132178

179+
/**
180+
* @brief Determine the trigger mode of a given IRQ.
181+
*
182+
* @param irq IRQ number
183+
* @return 0 for edge-triggered, 1 for level-triggered
184+
*/
133185
uint8_t get_irq_trigger_mode(uint8_t irq);
134186

187+
/**
188+
* @brief Return human-readable string for trigger mode.
189+
*
190+
* @param trig Trigger mode value
191+
* @return "edge" or "level"
192+
*/
135193
const char *triggering_str(uint8_t trig);
136194

195+
/**
196+
* @brief Return human-readable string for polarity.
197+
*
198+
* @param pol Polarity value
199+
* @return "high" or "low"
200+
*/
137201
const char *polarity_str(uint8_t pol);
138202

203+
/**
204+
* @brief Return human-readable string for IRQ sharing model.
205+
*
206+
* @param share Sharing type
207+
* @return Descriptive string of the IRQ sharing status
208+
*/
139209
const char *sharing_str(uint8_t share);

include/apic.h

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,61 @@
22
* @file apic.h
33
* @author Craig Edwards (craigedwards@brainbox.cc)
44
* @copyright Copyright (c) 2012-2025
5+
* @brief Local APIC (Advanced Programmable Interrupt Controller) interface
6+
*
7+
* This header provides low-level routines and register definitions to interface with
8+
* the Local APIC (LAPIC) on x86_64 systems. It allows for reading and writing LAPIC registers,
9+
* detecting the current CPU's LAPIC ID, and querying the LAPIC base address.
10+
*
11+
* This interface is used during system initialisation to configure per-core interrupt handling,
12+
* timer setup, and inter-processor signalling on SMP systems.
513
*/
6-
#ifndef __APIC_H__
7-
#define __APIC_H__
814

15+
#pragma once
16+
17+
/** Default virtual memory mapping address for the Local APIC (used by the kernel) */
918
#define APIC_ADDRESS 0x4000
19+
20+
/** Model Specific Register for the LAPIC base address */
1021
#define APIC_BASE_MSR 0x1B
22+
23+
/** Bitmask to enable the LAPIC via the APIC_BASE_MSR */
1124
#define APIC_BASE_MSR_ENABLE 0x800
1225

13-
// All of these values are offset from the APIC base address
14-
#define APIC_ID 0x0020
15-
#define APIC_VERSION 0x0030
26+
/* LAPIC register offsets (relative to the LAPIC base address) */
27+
#define APIC_ID 0x0020 /**< LAPIC ID Register (read-only) */
28+
#define APIC_VERSION 0x0030 /**< LAPIC Version Register (read-only) */
1629

30+
/**
31+
* @brief Read a 32-bit value from a LAPIC register
32+
*
33+
* @param reg Register offset from LAPIC base
34+
* @return uint32_t The value read from the register
35+
*/
1736
uint32_t apic_read(uint64_t reg);
37+
38+
/**
39+
* @brief Write a 32-bit value to a LAPIC register
40+
*
41+
* @param reg Register offset from LAPIC base
42+
* @param value The value to write
43+
*/
1844
void apic_write(uint64_t reg, uint32_t value);
45+
46+
/**
47+
* @brief Get the Local APIC ID of the current CPU
48+
*
49+
* @return uint8_t APIC ID read from the LAPIC ID register.
50+
* This value uniquely identifies the core in an SMP system and
51+
* may be non-contiguous or BIOS-assigned.
52+
*/
1953
uint8_t cpu_id();
54+
55+
56+
/**
57+
* @brief Get the physical address of the Local APIC
58+
*
59+
* @return uint64_t Physical address of the LAPIC MMIO region
60+
*/
2061
uint64_t get_lapic_address();
2162

22-
#endif

0 commit comments

Comments
 (0)