|
PatchworkOS
|
Namespace and Namespace Overlays. More...
Data Structures | |
| struct | aml_namespace_overlay_t |
| Namespace overlay. More... | |
Macros | |
| #define | AML_NAME(a, b, c, d) |
Macro to create an aml_name_t from 4 characters. | |
| #define | AML_NAME_UNDEFINED AML_NAME('x', 'x', 'x', 'x') |
| Macro for an undefined name. | |
| #define | AML_NAME_TO_STRING(name) (char[]){((name)) & 0xFF, ((name) >> 8) & 0xFF, ((name) >> 16) & 0xFF, ((name) >> 24) & 0xFF, '\0'} |
Macro to convert an aml_name_t to a stack allocated string. | |
Typedefs | |
| typedef uint32_t | aml_name_t |
| Name type. | |
Functions | |
| uint64_t | aml_namespace_init (aml_object_t *root) |
| Initialize the namespace heirarchy. | |
| uint64_t | aml_namespace_expose (void) |
| Expose the entire namespace heirarchy to sysfs. | |
| aml_object_t * | aml_namespace_get_root (void) |
| Get the root object of the namespace heirarchy. | |
| aml_object_t * | aml_namespace_find_child (aml_namespace_overlay_t *overlay, aml_object_t *parent, aml_name_t name) |
| Find a child object directly under a parent object in the namespace heirarchy. | |
| aml_object_t * | aml_namespace_find (aml_namespace_overlay_t *overlay, aml_object_t *start, uint64_t nameCount,...) |
| Find an object in the namespace heirarchy by name segments. | |
| aml_object_t * | aml_namespace_find_by_name_string (aml_namespace_overlay_t *overlay, aml_object_t *start, const aml_name_string_t *nameString) |
| Find an object in the namespace heirarchy by a name string. | |
| aml_object_t * | aml_namespace_find_by_path (aml_namespace_overlay_t *overlay, aml_object_t *start, const char *path) |
| Find an object in the namespace heirarchy by a path string. | |
| uint64_t | aml_namespace_add_child (aml_namespace_overlay_t *overlay, aml_object_t *parent, aml_name_t name, aml_object_t *object) |
| Add an child to a parent in the namespace heirarchy. | |
| uint64_t | aml_namespace_add_by_name_string (aml_namespace_overlay_t *overlay, aml_object_t *start, const aml_name_string_t *nameString, aml_object_t *object) |
| Add an object to the namespace heirarchy using a name string. | |
| void | aml_namespace_remove (aml_object_t *object) |
| Remove an object from the namespace heirarchy it was added to. | |
| uint64_t | aml_namespace_commit (aml_namespace_overlay_t *overlay) |
| Commit all names in a namespace overlay to the global namespace heirarchy. | |
| uint64_t | aml_namespace_overlay_init (aml_namespace_overlay_t *overlay) |
| Initialize a namespace overlay. | |
| void | aml_namespace_overlay_deinit (aml_namespace_overlay_t *overlay) |
| Deinitialize a namespace overlay. | |
| void | aml_namespace_overlay_set_parent (aml_namespace_overlay_t *overlay, aml_namespace_overlay_t *parent) |
| Set the parent of a namespace overlay. | |
| aml_namespace_overlay_t * | aml_namespace_overlay_get_highest_that_contains (aml_namespace_overlay_t *overlay, aml_object_t *object) |
| Search a overlay and its parents for the first overlay that contains the given object. | |
Namespace and Namespace Overlays.
We need this slightly complex system as when a method runs it can create named objects that should not be visible outside of the method, and when the method finishes these objects need to be removed. Additionally, if the method calls itself, the new invocation should not see the objects created by the previous invocation. Note that "outside of the method" means that if a inner method is defined inside another method the inner method will see the objects created by the outer method.
This is complex enough to need a example, good luck.
This example does not include the edge case where a inner function calls the functions its defined inside of, but it works the same way as calling a outer function.
As far as i can tell, this does NOT apply to If, While, or other statements, only methods. So if you create a named object inside an If statement it will be visible outside of the If statement.
To solve this we give the aml_state_t a aml_namespace_overlay_t where it can create its named objects. When looking up names we first look in the overlay of the current state and then in the parent overlay and so on until we reach a NULL overlay. The last overlay will always be the "global" overlay. When invoking a method it will be given its own aml_state_t and its own overlay, the parent of this overlay will be the "highest" overlay that contains the invoked method, so if a inner method is invoked its parent overlay will be the overlay of the outer method. If a outer method is invoked we move up the overlay chain until we find the overlay that contains the method and use that as the parent overlay.
Its important to note that overlays are not directories they are maps that map a parents id and a childs name to the child object and that when combined form the complete heirarchy. Think of it like this, each overlay defines a incomplete heirarchy of named objects, for example one overlay might define an object \_FOO._BAR but the parent object _FOO is actually defined in the parent overlay.
We also need the ability to commit any names created in a overlay to be globally visible if we are not executing a method but instead parsing a DSDT or SSDT table. This is done using aml_namespace_overlay_commit() which moves all the overlays objects to its parent overlay, which is usually the global overlay.
Note that the term "namespace" in the ACPI specification does not refer to the entire "hierarchy" of named objects but instead to an object that contains named objects, for example a Device object. Yes this is confusing.
| #define AML_NAME | ( | a, | |
| b, | |||
| c, | |||
| d | |||
| ) |
Macro to create an aml_name_t from 4 characters.
| a | First character. |
| b | Second character. |
| c | Third character. |
| d | Fourth character. |
Definition at line 112 of file namespace.h.
| #define AML_NAME_TO_STRING | ( | name | ) | (char[]){((name)) & 0xFF, ((name) >> 8) & 0xFF, ((name) >> 16) & 0xFF, ((name) >> 24) & 0xFF, '\0'} |
Macro to convert an aml_name_t to a stack allocated string.
| name | The aml_name_t value. |
Definition at line 129 of file namespace.h.
Macro for an undefined name.
Real AML never uses lower case letters in names, so we can use 'x' to represent an undefined name.
Definition at line 121 of file namespace.h.
Name type.
In AML names are just 32-bit values, it just happens that each byte in this value is an ASCII character. So we can optimize things a bit by just treating this as a integer instead of pretending its a string, unless you want to print it for debugging purposes.
Definition at line 101 of file namespace.h.
| uint64_t aml_namespace_add_by_name_string | ( | aml_namespace_overlay_t * | overlay, |
| aml_object_t * | start, | ||
| const aml_name_string_t * | nameString, | ||
| aml_object_t * | object | ||
| ) |
Add an object to the namespace heirarchy using a name string.
| overlay | The overlay to add the object to, if NULL the object is added to the global overlay. |
| start | The scope to start searching from to resolve the name string, if NULL the search starts from the root object. |
| nameString | The name string to use to find the parent scope and name of the object. |
| object | The object to add to the namespace. |
0. On failure, ERR and errno is set. Definition at line 381 of file namespace.c.
References aml_namespace_add_child(), aml_namespace_find_by_name_string(), aml_namespace_traverse_parents(), aml_prefix_path_t::depth, DEREF, DEREF_DEFER, EINVAL, ENOENT, ERR, errno, aml_name_string_t::namePath, namespaceRoot, NULL, aml_name_string_t::prefixPath, aml_root_char_t::present, REF, aml_name_string_t::rootChar, aml_name_path_t::segmentCount, aml_name_path_t::segments, and start().
Referenced by aml_def_alias_read(), aml_def_create_bit_field_read(), aml_def_create_field_read(), aml_def_create_field_read_helper(), aml_def_data_region_read(), aml_def_device_read(), aml_def_event_read(), aml_def_method_read(), aml_def_mutex_read(), aml_def_name_read(), aml_def_opregion_read(), aml_def_power_res_read(), aml_def_processor_read(), and aml_def_thermal_zone_read().
| uint64_t aml_namespace_add_child | ( | aml_namespace_overlay_t * | overlay, |
| aml_object_t * | parent, | ||
| aml_name_t | name, | ||
| aml_object_t * | object | ||
| ) |
Add an child to a parent in the namespace heirarchy.
| overlay | The overlay to add the object to, if NULL the object is added to the global overlay. |
| parent | The parent scope to add the object to, if NULL the object is added to the root object. |
| name | The name to give the object. |
| object | The object to add to the namespace. |
0. On failure, ERR and errno is set. Definition at line 332 of file namespace.c.
References aml_object_map_key(), AML_OBJECT_NAMED, EEXIST, EINVAL, ERR, errno, globalOverlay, list_push(), aml_namespace_overlay_t::map, map_get(), map_insert(), namespaceRoot, NULL, aml_namespace_overlay_t::objects, aml_namespace_overlay_t::parent, and REF.
Referenced by aml_create_predefined_scope(), aml_name_field_read(), aml_namespace_add_by_name_string(), and aml_predefined_init().
| uint64_t aml_namespace_commit | ( | aml_namespace_overlay_t * | overlay | ) |
Commit all names in a namespace overlay to the global namespace heirarchy.
After this call the overlay will be empty.
| overlay | The overlay to commit. |
0. On failure, ERR and errno is set. Definition at line 443 of file namespace.c.
References AML_OBJECT_ID_NONE, aml_object_map_key(), assert, EINVAL, ERR, errno, LIST_FOR_EACH_SAFE, list_is_empty(), list_push(), list_remove(), aml_namespace_overlay_t::map, map_insert(), map_is_empty(), map_remove(), NULL, aml_namespace_overlay_t::objects, and aml_namespace_overlay_t::parent.
Referenced by aml_parse().
| uint64_t aml_namespace_expose | ( | void | ) |
Expose the entire namespace heirarchy to sysfs.
0. On failure, ERR and errno is set. Definition at line 80 of file namespace.c.
Referenced by aml_init(), and init_finalize().
| aml_object_t * aml_namespace_find | ( | aml_namespace_overlay_t * | overlay, |
| aml_object_t * | start, | ||
| uint64_t | nameCount, | ||
| ... | |||
| ) |
Find an object in the namespace heirarchy by name segments.
Will always traverse aliases.
If there is exactly one name segment, then additional search rules apply meaning that if the object is not found is the parent scope, then we recursively search the parent scope's parent, and so on until we reach the root or find the object.
Example:
| overlay | The overlay to search in, if NULL only the global overlay is searched. |
| start | The scope to start searching from, if NULL the search starts from the root object. |
| nameCount | The number of name segments following. |
| ... | The name segments of the object to find. |
NULL if it could not be found. Definition at line 129 of file namespace.c.
References aml_namespace_find_child(), aml_namespace_search_single_name(), AML_OBJECT_NAMED, DEREF, namespaceRoot, next, NULL, REF, start(), va_arg, va_end, and va_start.
Referenced by acpi_devices_init(), acpi_devices_init_children(), acpi_sta_get_flags(), and aml_pci_get_params().
| aml_object_t * aml_namespace_find_by_name_string | ( | aml_namespace_overlay_t * | overlay, |
| aml_object_t * | start, | ||
| const aml_name_string_t * | nameString | ||
| ) |
Find an object in the namespace heirarchy by a name string.
Will always traverse aliases.
A search through the ACPI namespace follows these rules:
\), the search starts from the root object.^), the search starts from the parent of the start object, moving up one level for each ^.start object. If start is NULL, the search starts from the root object.start object and its children).| overlay | The overlay to search in, if NULL only the global overlay is searched. |
| start | The scope to start searching from, if NULL the search starts from the root object. |
| nameString | The name string of the object to find. |
NULL if it could not be found. Definition at line 174 of file namespace.c.
References aml_namespace_find_child(), aml_namespace_search_single_name(), aml_namespace_traverse_parents(), AML_OBJECT_NAMED, aml_prefix_path_t::depth, DEREF, aml_name_string_t::namePath, namespaceRoot, next, NULL, aml_name_string_t::prefixPath, aml_root_char_t::present, REF, aml_name_string_t::rootChar, aml_name_path_t::segmentCount, aml_name_path_t::segments, and start().
Referenced by aml_name_string_read_and_resolve(), aml_namespace_add_by_name_string(), aml_package_element_read(), and aml_patch_up_resolve_all().
| aml_object_t * aml_namespace_find_by_path | ( | aml_namespace_overlay_t * | overlay, |
| aml_object_t * | start, | ||
| const char * | path | ||
| ) |
Find an object in the namespace heirarchy by a path string.
Will always traverse aliases.
The path string is a dot separated list of names, for example "ABCD.EFGH.IJKL". Additionally the path can start with a "\" to indicate that the search should start from the root object, or one or more "^" characters to indicate that the
search should start from the parent of the <tt>start</tt> object, moving up one level for each "^".
If the path does not start with a "" or "^", the search starts from the start object. If start is NULL, the search starts from the root object.
If there is exactly one name segment, then additional search rules apply meaning that if the object is not found is the parent scope, then we recursively search the parent scope's parent, and so on until we reach the root or find the object.
| overlay | The overlay to search in, if NULL only the global overlay is searched. |
| start | The scope to start searching from, if NULL the search starts from the root object. |
| path | The path string of the object to find. |
NULL if it could not be found. Definition at line 225 of file namespace.c.
References aml_namespace_find_child(), aml_namespace_traverse_parents(), AML_OBJECT_NAMED, DEREF, EINVAL, errno, namespaceRoot, next, NULL, REF, and start().
Referenced by aml_obj_reference_read().
| aml_object_t * aml_namespace_find_child | ( | aml_namespace_overlay_t * | overlay, |
| aml_object_t * | parent, | ||
| aml_name_t | name | ||
| ) |
Find a child object directly under a parent object in the namespace heirarchy.
Will always traverse aliases.
| overlay | The overlay to search in, if NULL only the global overlay is searched. |
| parent | The parent scope to search in. |
| name | The name of the child object to find. |
NULL if it could not be found. Definition at line 91 of file namespace.c.
References aml_object_t::alias, AML_ALIAS, aml_alias_obj_traverse(), aml_object_map_key(), AML_OBJECT_NAMED, CONTAINER_OF_SAFE, globalOverlay, aml_namespace_overlay_t::map, map_get(), NULL, aml_namespace_overlay_t::parent, and REF.
Referenced by acpi_devices_init(), aml_namespace_find(), aml_namespace_find_by_name_string(), aml_namespace_find_by_path(), and aml_namespace_search_single_name().
| aml_object_t * aml_namespace_get_root | ( | void | ) |
Get the root object of the namespace heirarchy.
Definition at line 86 of file namespace.c.
References namespaceRoot, and REF.
Referenced by aml_method_find(), and aml_parse().
| uint64_t aml_namespace_init | ( | aml_object_t * | root | ) |
Initialize the namespace heirarchy.
| root | The object to use as the root of the namespace heirarchy. |
0. On failure, ERR and errno is set. Definition at line 68 of file namespace.c.
References AML_NAME, aml_namespace_overlay_init(), AML_OBJECT_NAMED, AML_OBJECT_ROOT, ERR, globalOverlay, namespaceRoot, and REF.
Referenced by aml_init().
| void aml_namespace_overlay_deinit | ( | aml_namespace_overlay_t * | overlay | ) |
Deinitialize a namespace overlay.
| overlay | The overlay to deinitialize. |
Definition at line 493 of file namespace.c.
References aml_namespace_remove(), LIST_FOR_EACH_SAFE, aml_namespace_overlay_t::map, map_deinit(), NULL, and aml_namespace_overlay_t::objects.
Referenced by aml_state_deinit().
| aml_namespace_overlay_t * aml_namespace_overlay_get_highest_that_contains | ( | aml_namespace_overlay_t * | overlay, |
| aml_object_t * | object | ||
| ) |
Search a overlay and its parents for the first overlay that contains the given object.
| overlay | The overlay to check. |
| object | The object to check for. |
NULL. Definition at line 520 of file namespace.c.
References AML_OBJECT_ID_NONE, aml_object_map_key(), aml_namespace_overlay_t::map, map_get(), NULL, and aml_namespace_overlay_t::parent.
Referenced by aml_method_evaluate().
| uint64_t aml_namespace_overlay_init | ( | aml_namespace_overlay_t * | overlay | ) |
Initialize a namespace overlay.
Its parent is set to the global overlay.
| overlay | The overlay to initialize. |
0. On failure, ERR and errno is set. Definition at line 476 of file namespace.c.
References EINVAL, ERR, errno, globalOverlay, list_init(), aml_namespace_overlay_t::map, map_init(), NULL, aml_namespace_overlay_t::objects, and aml_namespace_overlay_t::parent.
Referenced by aml_namespace_init(), and aml_state_init().
| void aml_namespace_overlay_set_parent | ( | aml_namespace_overlay_t * | overlay, |
| aml_namespace_overlay_t * | parent | ||
| ) |
Set the parent of a namespace overlay.
| overlay | The overlay to set the parent of. |
| parent | The new parent overlay, or NULL to set no parent. |
Definition at line 510 of file namespace.c.
References NULL, and aml_namespace_overlay_t::parent.
Referenced by aml_method_evaluate().
| void aml_namespace_remove | ( | aml_object_t * | object | ) |
Remove an object from the namespace heirarchy it was added to.
If the object is not found in the specified overlay or the global namespace heirarchy, nothing happens.
The object is dereferenced, so if there are no other references to it, it will be freed.
| object | The object to remove from the namespace. |
Definition at line 421 of file namespace.c.
References AML_NAME_UNDEFINED, AML_OBJECT_ID_NONE, aml_object_map_key(), AML_OBJECT_NAMED, DEREF, list_remove(), map_remove(), and NULL.
Referenced by aml_namespace_overlay_deinit(), and aml_object_clear().