Skip to content

Helper API Documentation

thom_tl edited this page Aug 14, 2019 · 6 revisions

PCI helpers

LAI provides a few helpers for PCI access

/* PCI helpers are located in <lai/helpers/pci.h> */

/* Routes the PCI IRQ for the device at seg:bus:slot:function, and returns it in dest
 * Returns 0 on success and 1 on failure
 * This function is deprecated in favour of lai_pci_route_pin(), since this function does not take the pin number and that is required to route IRQs for devices behind bridges */
int lai_pci_route(acpi_resource_t *dest, uint16_t seg, uint8_t bus, uint8_t slot, uint8_t function);

/* Routes the PCI interrupt pin for the device at seg:bus:slot:function, and returns it in dest
 * Only routes interrupts from the root bus
 * Returns a lai_api_error_t */
lai_api_error_t lai_pci_route_pin(acpi_resource_t *dest, uint16_t seg, uint8_t bus, uint8_t slot, uint8_t function, uint8_t pin);

/* Finds a device under the bus node, with slot:function, it returns the node or NULL
 * Note: Not every PCI device has an AML node, the fact that this function returns NULL doesn't mean that the device doesn't exist */
lai_nsnode_t *lai_pci_find_device(lai_nsnode_t *bus, uint8_t slot, uint8_t function, lai_state_t *state);

/* Finds the AML node for the bridge at seg:bus and returns it or NULL if it can't find it
 * Note: Although the ACPI 6.3 Specification doesn't state that the _BBN (Base bus number) is allowed to not exist, on a lot of systems (Including QEMU) it doesn't so this function assumes 0 for a non-existant _BBN like it does for _SEG (PCIe Segment Group) */
lai_nsnode_t *lai_pci_find_bus(uint16_t seg, uint8_t bus, lai_state_t *state);

Power Management

LAI provides some help with using the ACPI power management API, although this is not finished yet.

/* Power Management helpers are found in <lai/helpers/pm.h> */

/* Puts the system in another sleeping state (S0 - S5 as defined in the ACPI 6.3 Specification Paragraph 7.4.2), returns 0 on success and anything else on failure
 * Note: Currently lai_enter_sleep only supports S5(Soft off), LAI will still comply if you send it to a different state but it wont work as expected. */
lai_api_error_t lai_enter_sleep(uint8_t sleep_state);

/* Resets the system via the system independent ACPI reset function, this is equivalent to a cold reboot
 * Returns 1 on failure, ofcourse it shouldn't return at all on success
 * Requires knowing the ACPI revision via lai_set_acpi_revision(int revision); */
lai_api_error_t lai_acpi_reset();

System Management

LAI also helps with handling SCIs and initializing the system to full ACPI mode

/* These helper functions can be found in <lai/helpers/sci.h> */

/* Initializes ACPI mode on the system, enables the SCI and selects the interrupt model used
 * The mode argument specifies the interrupt mode (ACPI 6.3 Specification 5.8.1) the system will be put in
 * Valid Values:
 *    - 0: Legacy 8259 PIC Mode
 *    - 1: APIC Mode
 *    - 2: SAPIC Mode (Note: SAPIC only exists on Itanium systems and can be ignored on all x86(_64) systems
 * Returns 0 on succes 
 * Detailed Working:
 *    - Runs \_SB_.INI() and the _INI() functions of all children
 *    - Runs \_PIC(mode) to tell firmware about the interrupt mode
 *    - Enables the Firmware SCI and enables the Power button, sleep button and wake events */
int lai_enable_acpi(uint32_t mode);

/* Sets the events on which an SCI will occur */
void lai_set_sci_event(uint16_t value);

/* Reads on which events an SCI will occur */
uint16_t lai_get_sci_event(void);

/* Evaluates the _STA() (ACPI 6.3 Specification 6.3.7) function of node
 * This function should be called instead of evaluating _STA() yourself because the spec states that if _STA doesn't exists you should assume all relevant bits are set
 * Returns the evaluated value of _STA() */
int lai_evaluate_sta(lai_nsnode_t *node);

/* Finally LAI exposes a function to call the _INI() function of all children of a parent node */
void lai_init_children(lai_nsnode_t *parent);

Resource helpers

See Resource API Documentation

Clone this wiki locally