19 #define SIGNATURE_RSDP 0x2052545020445352ll // "RSD PTR " 20 #define SIGNATURE_MADT 0x43495041 // "APIC" 21 #define SIGNATURE_BOOT 0x544f4f42 // "BOOT" 22 #define SIGNATURE_FADT 0x50434146 // "FACP" 23 #define SIGNATURE_HPET 0x54455048 // "HPET" 24 #define SIGNATURE_MCFG 0x4746434d // "MCFG" 25 #define SIGNATURE_SRAT 0x54415253 // "SRAT" 26 #define SIGNATURE_SSDT 0x54445353 // "SSDT" 27 #define SIGNATURE_WAET 0x54454157 // "WAET" 30 #define PAGE_ALIGN_DOWN(a) ((a) & ~(PAGE_SIZE - 1)) 31 #define PAGE_ALIGN_UP(a) (((a) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) 61 uint32_t ptr_table[1];
67 uint64_t ptr_table[1];
126 uint64_t pml4te =
PML4E(addr);
127 uint64_t pdpte =
PDPTE(addr);
128 uint64_t pde =
PDE(addr);
129 uint64_t pte =
PTE(addr);
132 if (pml4t->
entry[pml4te] == 0)
136 if (pdpt->
entry[pdpte] == 0)
142 if (pdt->
entry[pde] == 0)
144 if (pdt->
entry[pde] & PF_PS)
148 return pt->
entry[pte] != 0;
165 uint64_t pml4te =
PML4E(addr);
166 uint64_t pdpte =
PDPTE(addr);
167 uint64_t pde =
PDE(addr);
168 uint64_t pte =
PTE(addr);
171 if (pml4t->
entry[pml4te] == 0)
175 if (pdpt->
entry[pdpte] == 0)
179 if (pdt->
entry[pde] == 0)
183 pt->
entry[pte] = addr | flags;
195 for (uint64_t addr = begin; addr < term; addr +=
PAGE_SIZE) {
204 uint64_t addr = (uint64_t)hdr;
212 uint64_t size = hdr->
length;
229 "[acpi] oem='%.6s' tbl='%.8s' rev=%#x creator='%.4s'",
233 int tables = (int)(xhdr->
length -
sizeof(*xhdr)) /
sizeof(uint64_t);
234 for (
int i = 0; i < tables; i++) {
251 "[acpi] oem='%.6s' tbl='%.8s' rev=%#x creator='%.4s'",
255 int tables = (int)(rhdr->
length -
sizeof(*rhdr)) /
sizeof(uint32_t);
256 for (
int i = 0; i < tables; i++) {
271 const uint64_t *ptr = (
const uint64_t *)addr;
272 const uint64_t *term = (
const uint64_t *)(addr + size);
273 for (; ptr < term; ptr += 2) {
305 logf(
LOG_INFO,
"[acpi] ACPI %d.0 RSDP table found at %#lx.",
376 const void *term = (
const uint8_t *)madt + madt->
hdr.
length;
383 ptr = (
const uint8_t *)prev +
389 if (hdr->
type == type)
391 ptr = (
const uint8_t *)hdr + hdr->
length;
431 const uint8_t *term = (
const uint8_t *)mcfg + mcfg->
hdr.
length;
432 if ((
const uint8_t *)ptr < term)
#define KMEM_BOOT_PAGETABLE
struct acpi_rsdp PACKSTRUCT
uint32_t length
Length of this table including header.
uint32_t ptr_io_apic
I/O APIC address.
Physical memory map describing usable and reserved regions of physical memory.
char oemid[6]
Supplied by the OEM.
const struct acpi_xsdt * xsdt
Header attached to the front of all ACPI tables.
union acpi_hdr::@1 signature
Advanced configuration and power interface (ACPI) tables.
String and memory operations.
uint8_t checksum_ex
Covers entire rsdp structure.
#define KMEM_BOOT_PAGETABLE_LOADED
#define KMEM_BOOT_PAGETABLE_END
uint32_t ptr_rsdt
32-bit pointer to RSDT table
uint32_t ptr_table[1]
Pointers to other ACPI tables.
uint32_t length
RSDT table length, including header.
static void create_page(btable_t *btable, uint64_t addr, uint64_t flags)
char creatorid[4]
Vendor id.
#define KMEM_EXTENDED_BIOS_SIZE
Kernel physical (and virtual) memory map.
Interrupt Source Override.
#define KMEM_EXTENDED_BIOS
uint8_t length
Length of IC structure including header.
Marked as uncacheable, usually for I/O.
static bool is_mapped(btable_t *btable, uint64_t addr)
static void map_range(btable_t *btable, uint64_t addr, uint64_t size, uint64_t flags)
const struct acpi_madt_local_apic * acpi_next_local_apic(const struct acpi_madt_local_apic *prev)
Return a pointer to the next Local APIC structure entry in the MADT table.
static void read_mcfg(const struct acpi_hdr *hdr)
uint32_t ptr_local_apic
Local APIC address.
Used for ACPI tables or code.
static void read_madt(const struct acpi_hdr *hdr)
static void map_table(btable_t *btable, const struct acpi_hdr *hdr)
MCFG entry, one or more of which appears at the tail of the acpi_mcfg struct.
static void read_rsdt(btable_t *btable)
char oemtableid[8]
Supplied by the OEM.
__forceinline void fatal()
PCI express Mapped Configuration (MCFG) table.
uint64_t ptr_xsdt
64-bit pointer to XSDT table
const struct acpi_rsdp * rsdp
const struct acpi_rsdt * rsdt
uint32_t oemrevision
Supplied by the OEM.
page_t * next_page
The next page to use when allocating.
void acpi_init()
Find and parse all available ACPI tables.
Fixed ACPI Description Table (FADT)
const struct acpi_madt * madt
#define PAGE_ALIGN_DOWN(a)
uint8_t revision
0=1.0, 1=2.0, 2=3.0
void pmap_add(uint64_t addr, uint64_t size, enum pmemtype type)
Add a region of memory to the physical memory map.
const struct acpi_mcfg_addr * acpi_next_mcfg_addr(const struct acpi_mcfg_addr *prev)
Return a pointer to the next Mapped Configuration (MCFG) address entry, used for PCIe.
uint64_t entry[PAGE_SIZE/sizeof(uint64_t)]
static const void * madt_find(enum acpi_madt_type type, const void *prev)
A structure used to track the state of the temporary page table generated by the boot loader...
void logf(loglevel_t level, const char *format,...)
Log a printf-formatted message to the kernel log buffer.
x86 CPU-specific function implementations.
uint8_t type
acpi_madt_type
MADT Interrupt Source Override (ISO) entry.
uint64_t ptr_table[1]
Pointers to other ACPI tables.
Critical error, occurs just prior to crashing.
static const struct acpi_rsdp * find_rsdp(uint64_t addr, uint64_t size)
page_t * root
The top-level (PML4) page table.
const struct acpi_madt * acpi_madt()
Return a pointer to the ACPI multiple APIC description table (MADT).
const struct acpi_madt_io_apic * acpi_next_io_apic(const struct acpi_madt_io_apic *prev)
Return a pointer to the next I/O APIC structure entry in the MADT table.
uint8_t checksum
Covers up to (and including) ptr_rsdt.
const struct acpi_mcfg * mcfg
int acpi_version()
Return the ACPI version number.
Multiple APIC description table (MADT).
const struct acpi_fadt * acpi_fadt()
Return a pointer to the ACPI fixed ACPI description table.
const struct acpi_fadt * fadt
void * memzero(void *dst, size_t num)
Fill a region of memory with zeroes.
const struct acpi_madt_iso * acpi_next_iso(const struct acpi_madt_iso *prev)
Return a pointer to the next Interrupt Source Override (ISO) structure entry in the MADT table...
static uint64_t alloc_page(btable_t *btable)
static void read_fadt(const struct acpi_hdr *hdr)
static void read_table(const struct acpi_hdr *hdr)
#define KMEM_SYSTEM_ROM_SIZE
acpi_madt_type
MADT entry types.
static void read_xsdt(btable_t *btable)
page_t * term_page
Just beyond the last available page.