1#pragma once
2
3#include <uacpi/types.h>
4#include <uacpi/status.h>
5
6#ifdef __cplusplus
7extern "C" {
8#endif
9
10// Forward-declared to avoid including the entire acpi.h here
11struct acpi_fadt;
12struct acpi_entry_hdr;
13struct acpi_sdt_hdr;
14
15typedef struct uacpi_table_identifiers {
16 uacpi_object_name signature;
17
18 // if oemid[0] == 0 this field is ignored
19 char oemid[6];
20
21 // if oem_table_id[0] == 0 this field is ignored
22 char oem_table_id[8];
23} uacpi_table_identifiers;
24
25typedef struct uacpi_table {
26 union {
27 uacpi_virt_addr virt_addr;
28 void *ptr;
29 struct acpi_sdt_hdr *hdr;
30 };
31
32 // Index number used to identify this table internally
33 uacpi_size index;
34} uacpi_table;
35
36/**
37 * Install a table from either a virtual or a physical address.
38 * The table is simply stored in the internal table array, and not loaded by
39 * the interpreter (see uacpi_table_load).
40 *
41 * The table is optionally returned via 'out_table'.
42 *
43 * Manual calls to uacpi_table_install are not subject to filtering via the
44 * table installation callback (if any).
45 */
46uacpi_status uacpi_table_install(
47 void*, uacpi_table *out_table
48);
49uacpi_status uacpi_table_install_physical(
50 uacpi_phys_addr, uacpi_table *out_table
51);
52
53#ifndef UACPI_BAREBONES_MODE
54/**
55 * Load a previously installed table by feeding it to the interpreter.
56 */
57uacpi_status uacpi_table_load(uacpi_size index);
58#endif // !UACPI_BAREBONES_MODE
59
60/**
61 * Helpers for finding tables.
62 *
63 * for find_by_signature:
64 * 'signature' is an array of 4 characters, a null terminator is not
65 * necessary and can be omitted (especially useful for non-C language
66 * bindings)
67 *
68 * 'out_table' is a pointer to a caller allocated uacpi_table structure that
69 * receives the table pointer & its internal index in case the call was
70 * successful.
71 *
72 * NOTE:
73 * The returned table's reference count is incremented by 1, which keeps its
74 * mapping alive forever unless uacpi_table_unref() is called for this table
75 * later on. Calling uacpi_table_find_next_with_same_signature() on a table also
76 * drops its reference count by 1, so if you want to keep it mapped you must
77 * manually call uacpi_table_ref() beforehand.
78 */
79uacpi_status uacpi_table_find_by_signature(
80 const uacpi_char *signature, uacpi_table *out_table
81);
82uacpi_status uacpi_table_find_next_with_same_signature(
83 uacpi_table *in_out_table
84);
85uacpi_status uacpi_table_find(
86 const uacpi_table_identifiers *id, uacpi_table *out_table
87);
88
89/**
90 * Increment/decrement a table's reference count.
91 * The table is unmapped when the reference count drops to 0.
92 */
93uacpi_status uacpi_table_ref(uacpi_table*);
94uacpi_status uacpi_table_unref(uacpi_table*);
95
96/**
97 * Returns the pointer to a sanitized internal version of FADT.
98 *
99 * The revision is guaranteed to be correct. All of the registers are converted
100 * to GAS format. Fields that might contain garbage are cleared.
101 */
102uacpi_status uacpi_table_fadt(struct acpi_fadt**);
103
104typedef enum uacpi_table_installation_disposition {
105 // Allow the table to be installed as-is
106 UACPI_TABLE_INSTALLATION_DISPOSITON_ALLOW = 0,
107
108 /**
109 * Deny the table from being installed completely. This is useful for
110 * debugging various problems, e.g. AML loading bad SSDTs that cause the
111 * system to hang or enter an undesired state.
112 */
113 UACPI_TABLE_INSTALLATION_DISPOSITON_DENY,
114
115 /**
116 * Override the table being installed with the table at the virtual address
117 * returned in 'out_override_address'.
118 */
119 UACPI_TABLE_INSTALLATION_DISPOSITON_VIRTUAL_OVERRIDE,
120
121 /**
122 * Override the table being installed with the table at the physical address
123 * returned in 'out_override_address'.
124 */
125 UACPI_TABLE_INSTALLATION_DISPOSITON_PHYSICAL_OVERRIDE,
126} uacpi_table_installation_disposition;
127
128typedef uacpi_table_installation_disposition (*uacpi_table_installation_handler)
129 (struct acpi_sdt_hdr *hdr, uacpi_u64 *out_override_address);
130
131/**
132 * Set a handler that is invoked for each table before it gets installed.
133 *
134 * Depending on the return value, the table is either allowed to be installed
135 * as-is, denied, or overriden with a new one.
136 */
137uacpi_status uacpi_set_table_installation_handler(
138 uacpi_table_installation_handler handler
139);
140
141typedef uacpi_iteration_decision (*uacpi_subtable_iteration_callback)
142 (uacpi_handle, struct acpi_entry_hdr*);
143
144/**
145 * Iterate every subtable of a table such as MADT or SRAT.
146 *
147 * 'hdr' is the pointer to the main table, 'hdr_size' is the number of bytes in
148 * the table before the beginning of the subtable records. 'cb' is the callback
149 * invoked for each subtable with the 'user' context pointer passed for every
150 * invocation.
151 *
152 * Example usage:
153 * uacpi_table tbl;
154 *
155 * uacpi_table_find_by_signature(ACPI_MADT_SIGNATURE, &tbl);
156 * uacpi_for_each_subtable(
157 * tbl.hdr, sizeof(struct acpi_madt), parse_madt, NULL
158 * );
159 */
160uacpi_status uacpi_for_each_subtable(
161 struct acpi_sdt_hdr *hdr, size_t hdr_size,
162 uacpi_subtable_iteration_callback cb, void *user
163);
164
165#ifdef __cplusplus
166}
167#endif
168