-
-
Notifications
You must be signed in to change notification settings - Fork 31
Core API Documentation
In the following, we give an overview over LAI's core data types. All of those types are opaque structs.
A Note on Opaque Structs. Users are expected to employ API methods
to manipulate opaque structs. That includes
calling the correct functions to "destruct" the objects - failure to do
so will lead to memory leaks.
Note that
explicitly modifying members of opaque structs or manipulating them
in any other way (e.g., through memcpy
) is explicitly not supported.
Represents a node in the ACPI namespace. Users only
ever deal with pointers to this type. Most API functions expect
ACPI namespace paths to be resolved to lai_nsnode_t *
handles.
Represents a variable in AML; specifically, it stores
an AML object. Users need to use lai_variable_t
to pass arguments to
control methods and to inspect their results.
/* Destructs an object of type lai_variable_t. */
void lai_var_finalize(lai_variable_t *var);
/* Assigns the value of an AML variable to another variable.
* LAI passes AML objects by pointer, hence the result of
* lai_var_assign() points to the same AML object as the source. */
void lai_var_assign(lai_variable_t *dest, lai_variable_t *src);
/* Moves the value of an AML variable to another variable.
* This operation is slightly cheaper than lai_var_assign(),
* but it resets the source to an empty variable. */
void lai_var_move(lai_variable_t *dest, lai_variable_t *src);
Encapsulates the AML interpreter state. Users do not need to directly interact with it, but most core functions take a pointer to this struct.
/* Initializes an object of type lai_state_t. */
void lai_init_state(lai_state_t *state);
/* Destructs an object of type lai_state_t. */
void lai_finalize_state(lai_state_t *state);
/* __attribute__((cleanup)) magic to automatically call
* lai_finalize_state() at the end of the current scope. */
#define LAI_CLEANUP_STATE /* [...] */
LAI_CLEANUP_STATE
is the preferred way to ensure that a given lai_state_t
object is
destructed properly. This idiom renders it unnecessary to explicitly call lai_finalize_state
.
Usage example:
LAI_CLEANUP_STATE lai_state_t state;
lai_init_state(&state);
/* [...] */
Contains an error in the LAI API
typedef enum lai_api_error {
LAI_ERROR_NONE,
LAI_ERROR_TYPE_MISMATCH,
LAI_ERROR_NO_SUCH_NODE,
LAI_ERROR_OUT_OF_BOUNDS,
LAI_ERROR_EXECUTION_FAILURE,
LAI_ERROR_ILLEGAL_ARGUMENTS,
/* Evaluating external inputs (e.g., nodes of the ACPI namespace) returned an unexpected result.
* Unlike LAI_ERROR_EXECUTION_FAILURE, this error does not indicate that
* execution of AML failed; instead, the resulting object fails to satisfy some
* expectation (e.g., it is of the wrong type, has an unexpected size, or consists of
* unexpected contents) */
LAI_ERROR_UNEXPECTED_RESULT,
// Error given when end of iterator is reached, nothing to worry about
LAI_ERROR_END_REACHED,
} lai_api_error_t;
A function is provided to convert a lai_api_error_t
into a human readable string
const char *lai_api_error_to_string(lai_api_error_t);
LAI provides various functions to resolve ACPI paths to lai_nsnode_t *
handles:
/* Resolve a path in the ACPI namespace.
* The path may be absolute or relative. Absolute paths start with a
* backslash (\). Relative paths may start with zero or more carets (^) to
* indicate that resolution should start at a parent of the context node.
*
* Note that unlike in ASL, single segument paths are not special cases
* for lai_resolve_path(); in particular, parent scopes are not searched
* recursively for those paths. Use lai_resolve_search() if you want this
* behavior.
*
* If ctx_handle is NULL, the path is resolved relative to the root node. */
lai_nsnode_t *lai_resolve_path(lai_nsnode_t *ctx_handle, const char *path);
/* Recursively search for a single segment name in all parent scopes. */
lai_nsnode_t *lai_resolve_search(lai_nsnode_t *ctx_handle, const char *name);
To iterate over the entire ACPI namespace, LAI provides the following API:
/* Returns the root node of the ACPI namespace. */
lai_nsnode_t *lai_ns_get_root();
/* Returns the parent node of a given ACPI namespace node. */
lai_nsnode_t *lai_ns_get_parent(lai_nsnode_t *node);
/* Returns a child node of a given ACPI namespace node. */
lai_nsnode_t *lai_ns_get_child(lai_nsnode_t *node,
const char *name);
/* Helper struct that allows a single iteration over the entire
* ACPI namespace. */
struct lai_ns_iterator; // Opaque struct.
/* Expands to a designated initializer for struct lai_ns_iterator. */
#define LAI_NS_ITERATOR_INITIALIZER /* [...] */
/* Returns a handle to the next ACPI namespace node or NULL if all
* nodes have been returned already. */
lai_nsnode_t *lai_ns_iterate(struct lai_ns_iterator *iterator);
/* Helper struct that allows a single iteration over the all
* children of a namespace node. */
struct lai_ns_child_iterator; // Opaque struct.
/* Expands to a designated initializer for struct lai_ns_child_iterator. */
#define LAI_NS_CHILD_ITERATOR_INITIALIZER(parent) /* [...] */
/* Returns a handle to the next child node or NULL if all
* nodes have been returned already. */
lai_nsnode_t *lai_ns_child_iterate(struct lai_ns_child_iterator *iterator);
enum lai_object_type {
LAI_TYPE_NONE,
LAI_TYPE_INTEGER,
LAI_TYPE_STRING,
LAI_TYPE_BUFFER,
LAI_TYPE_PACKAGE,
LAI_TYPE_DEVICE,
};
/* Return the type of an AML object.
* Unlike the AML ObjectType() operator, this function does not transparently dereference
* object references (e.g. those returned by Index() or RefOf()). */
enum lai_object_type lai_obj_get_type(lai_variable_t *object);
/* Get an integer out of an AML variable. */
lai_api_error_t lai_obj_get_integer(lai_variable_t *object, uint64_t *out);
/* Get an element of an AML package. */
lai_api_error_t lai_obj_get_pkg(lai_variable_t *object, size_t i, lai_variable_t *out);
/* Get a handle out of an AML variable. */
lai_api_error_t lai_obj_get_handle(lai_variable_t *object, lai_nsnode_t **out);
/* Make a clone (i.e., a deep copy) of an object.
* This function clones strings, buffers and packages.
* Packages are cloned recursively. */
void lai_clone_object(lai_variable_t *clone, lai_variable_t *object);
/* Evaluate an ACPI namespace node with a given handle. */
void lai_eval_args(lai_variable_t *result, lai_nsnode_t *handle, lai_state_t *state,
int argc, lai_variable_t *argv);
/* Like lai_eval_args() but takes the arguments using varargs.
* Each argument must be given as a lai_variable_t *. The list is terminated by NULL. */
void lai_eval_largs(lai_variable_t *result, lai_nsnode_t *handle, lai_state_t *state,
...);
/* Like lai_eval_largs() but takes a va_list. */
void lai_eval_vargs(lai_variable_t *result, lai_nsnode_t *handle, lai_state_t *state,
va_list vl);
/* Equivalent to lai_eval_args(result, handle, state, 0, NULL). */
void lai_eval(lai_variable_t *result, lai_nsnode_t *handle, lai_state_t *state);