AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
acpi.c File Reference

x86: ACPI's tables, and powering off. More...

#include <core/system.h>
#include <core/string.h>
#include <cpu/cpu.h>
#include <cpu/io.h>
#include <cpu/sdt.h>
#include <mm/mm.h>
#include <mm/vm.h>
#include <mm/kvmem.h>
#include <platform/misc.h>

Go to the source code of this file.

Macros

#define ACPI_WINDOW   ARCH_ACPI_BASE
#define ACPI_WINDOW_SIZE   0x00400000UL
#define FADT_DSDT   40
#define FADT_SMI_CMD   48
#define FADT_ACPI_ENABLE   52
#define FADT_PM1A_CNT   64
#define FADT_PM1B_CNT   68
#define PM1_SCI_EN   0x0001
#define PM1_SLP_EN   0x2000
#define AML_NAME   0x08
#define AML_BYTE_PREFIX   0x0A
#define AML_PACKAGE   0x12
#define ACPI_TABLES_MAX   32

Functions

static int checksum (const void *p, size_t size)
 Returns the 8-bit sum of size bytes, which is 0 for a valid table.
static void * acpi_map (uintptr_t paddr, size_t size)
 Maps a range of physical memory, read-only, in the tables' window.
static struct acpi_sdt_header * acpi_table (uintptr_t paddr)
 Maps a table, as long as its header says it is.
static struct acpi_rsdp * acpi_rsdp (void)
 Finds the RSDP, which is in the first KiB of the EBDA or in the BIOS ROM, on a 16-byte boundary.
static void acpi_tables (void)
 Maps every table that the XSDT (or the RSDT) lists, and records them in tables.
void * x86_acpi_table (const char *signature)
 Finds one of ACPI's tables, by its signature.
static int aml_int (const uint8_t **p, const uint8_t *end)
 Reads an integer element of an AML package: BytePrefix n, or ZeroOp or OneOp.
static int acpi_s5 (struct acpi_sdt_header *dsdt, int *typb)
 Finds S5's sleep types in the DSDT: Name (_S5, Package () {a, b, ...}).
static void pm1_write (uint32_t port, uint16_t val)
 Writes a PM1 control register.
static uint16_t pm1_read (uint32_t port)
 Reads a PM1 control register.
void x86_acpi_poweroff (void)
 Powers the machine off, by entering ACPI's S5 sleep state.

Variables

static uintptr_t window_next = ACPI_WINDOW
static struct acpi_sdt_header * tables [ACPI_TABLES_MAX]
static int tables_nr = -1

Detailed Description

x86: ACPI's tables, and powering off.

The firmware describes the machine in ACPI's tables, which the RSDT (or ACPI 2.0's XSDT) lists. They are mapped once, and found by their signature (x86_acpi_table()): the APIC code reads the MADT, the HPET code the HPET table.

Powering off is entering the S5 sleep state: writing its sleep type to the PM1 control registers that the FADT gives. The sleep type is in the \_S5 object of the DSDT, which is AML code; it is found by its name, without an AML interpreter.

Definition in file acpi.c.

Macro Definition Documentation

◆ ACPI_TABLES_MAX

#define ACPI_TABLES_MAX   32

Definition at line 123 of file acpi.c.

Referenced by acpi_tables().

◆ ACPI_WINDOW

#define ACPI_WINDOW   ARCH_ACPI_BASE

Definition at line 31 of file acpi.c.

Referenced by acpi_map().

◆ ACPI_WINDOW_SIZE

#define ACPI_WINDOW_SIZE   0x00400000UL

Definition at line 32 of file acpi.c.

Referenced by acpi_map(), and acpi_table().

◆ AML_BYTE_PREFIX

#define AML_BYTE_PREFIX   0x0A

Definition at line 48 of file acpi.c.

Referenced by aml_int().

◆ AML_NAME

#define AML_NAME   0x08

Definition at line 47 of file acpi.c.

Referenced by acpi_s5().

◆ AML_PACKAGE

#define AML_PACKAGE   0x12

Definition at line 49 of file acpi.c.

Referenced by acpi_s5().

◆ FADT_ACPI_ENABLE

#define FADT_ACPI_ENABLE   52

Definition at line 39 of file acpi.c.

Referenced by x86_acpi_poweroff().

◆ FADT_DSDT

#define FADT_DSDT   40

Definition at line 37 of file acpi.c.

Referenced by x86_acpi_poweroff().

◆ FADT_PM1A_CNT

#define FADT_PM1A_CNT   64

Definition at line 40 of file acpi.c.

Referenced by x86_acpi_poweroff().

◆ FADT_PM1B_CNT

#define FADT_PM1B_CNT   68

Definition at line 41 of file acpi.c.

Referenced by x86_acpi_poweroff().

◆ FADT_SMI_CMD

#define FADT_SMI_CMD   48

Definition at line 38 of file acpi.c.

Referenced by x86_acpi_poweroff().

◆ PM1_SCI_EN

#define PM1_SCI_EN   0x0001

Definition at line 43 of file acpi.c.

Referenced by x86_acpi_poweroff().

◆ PM1_SLP_EN

#define PM1_SLP_EN   0x2000

Definition at line 44 of file acpi.c.

Referenced by x86_acpi_poweroff().

Function Documentation

◆ acpi_map()

void * acpi_map ( uintptr_t paddr,
size_t size )
static

Maps a range of physical memory, read-only, in the tables' window.

Returns its kernel address, or NULL if the window is full or there's no memory.

Definition at line 65 of file acpi.c.

References acpi_map(), ACPI_WINDOW, ACPI_WINDOW_SIZE, vm_entry::base, vm_entry::flags, kfree(), kmalloc(), kvm_space, M_ZERO, NULL, vm_entry::paddr, PAGE_ALIGN, PAGE_ROUND, vm_entry::size, VM_KR, vm_map(), and window_next.

Referenced by acpi_map(), and acpi_table().

◆ acpi_rsdp()

struct acpi_rsdp * acpi_rsdp ( void )
static

Finds the RSDP, which is in the first KiB of the EBDA or in the BIOS ROM, on a 16-byte boundary.

Returns NULL if there's none.

Definition at line 106 of file acpi.c.

References checksum(), memcmp(), NULL, acpi_rsdp::signature, and VMA.

◆ acpi_s5()

int acpi_s5 ( struct acpi_sdt_header * dsdt,
int * typb )
static

Finds S5's sleep types in the DSDT: Name (_S5, Package () {a, b, ...}).

Returns the first one (for PM1a), sets *typb to the second (for PM1b), or returns -1 if there's no \_S5 object.

Definition at line 218 of file acpi.c.

References acpi_s5(), aml_int(), AML_NAME, AML_PACKAGE, acpi_sdt_header::length, and memcmp().

Referenced by acpi_s5(), and x86_acpi_poweroff().

◆ acpi_table()

struct acpi_sdt_header * acpi_table ( uintptr_t paddr)
static

Maps a table, as long as its header says it is.

Returns it, or NULL if it can't be mapped or its checksum is wrong.

Definition at line 92 of file acpi.c.

References acpi_map(), acpi_table(), ACPI_WINDOW_SIZE, checksum(), acpi_sdt_header::length, and NULL.

Referenced by acpi_table(), acpi_tables(), and x86_acpi_poweroff().

◆ acpi_tables()

void acpi_tables ( void )
static

Maps every table that the XSDT (or the RSDT) lists, and records them in tables.

Definition at line 130 of file acpi.c.

References acpi_table(), acpi_tables(), ACPI_TABLES_MAX, checksum(), acpi_rsdt::header, acpi_xsdt::header, acpi_sdt_header::length, printk(), acpi_rsdp::rev, acpi_rsdp::rsdt, acpi_rsdt::sdt, acpi_xsdt::sdt, tables, tables_nr, and acpi_rsdp2::xsdt.

Referenced by acpi_tables(), and x86_acpi_table().

◆ aml_int()

int aml_int ( const uint8_t ** p,
const uint8_t * end )
static

Reads an integer element of an AML package: BytePrefix n, or ZeroOp or OneOp.

Returns it, or -1 for anything else.

Definition at line 197 of file acpi.c.

References AML_BYTE_PREFIX, and aml_int().

Referenced by acpi_s5(), and aml_int().

◆ checksum()

int checksum ( const void * p,
size_t size )
static

Returns the 8-bit sum of size bytes, which is 0 for a valid table.

Definition at line 52 of file acpi.c.

References checksum().

Referenced by acpi_rsdp(), acpi_table(), acpi_tables(), and checksum().

◆ pm1_read()

uint16_t pm1_read ( uint32_t port)
static

Reads a PM1 control register.

Definition at line 255 of file acpi.c.

References io_in16(), IOADDR_PORT, and pm1_read().

Referenced by pm1_read(), and x86_acpi_poweroff().

◆ pm1_write()

void pm1_write ( uint32_t port,
uint16_t val )
static

Writes a PM1 control register.

Definition at line 248 of file acpi.c.

References io_out16(), IOADDR_PORT, and pm1_write().

Referenced by pm1_write(), and x86_acpi_poweroff().

◆ x86_acpi_poweroff()

void x86_acpi_poweroff ( void )

Powers the machine off, by entering ACPI's S5 sleep state.

It returns only if it couldn't.

Definition at line 265 of file acpi.c.

References acpi_s5(), acpi_table(), FADT_ACPI_ENABLE, FADT_DSDT, FADT_PM1A_CNT, FADT_PM1B_CNT, FADT_SMI_CMD, io_out8(), IOADDR_PORT, pm1_read(), PM1_SCI_EN, PM1_SLP_EN, pm1_write(), printk(), x86_acpi_poweroff(), and x86_acpi_table().

Referenced by arch_poweroff(), and x86_acpi_poweroff().

◆ x86_acpi_table()

void * x86_acpi_table ( const char * signature)

Finds one of ACPI's tables, by its signature.

The tables are mapped the first time.

Parameters
signaturethe table's signature, 4 characters ("APIC", "HPET")
Returns
the table, or NULL if there's none

Definition at line 183 of file acpi.c.

References acpi_tables(), memcmp(), NULL, acpi_sdt_header::signature, tables, tables_nr, and x86_acpi_table().

Referenced by x86_acpi_poweroff(), x86_acpi_table(), x86_apic_setup(), and x86_hpet_init().

Variable Documentation

◆ tables

struct acpi_sdt_header* tables[ACPI_TABLES_MAX]
static

Definition at line 125 of file acpi.c.

Referenced by acpi_tables(), and x86_acpi_table().

◆ tables_nr

int tables_nr = -1
static

Definition at line 126 of file acpi.c.

Referenced by acpi_tables(), and x86_acpi_table().

◆ window_next

uintptr_t window_next = ACPI_WINDOW
static

Definition at line 34 of file acpi.c.

Referenced by acpi_map().