PatchworkOS
Loading...
Searching...
No Matches
Namespace

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_taml_namespace_get_root (void)
 Get the root object of the namespace heirarchy.
 
aml_object_taml_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_taml_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_taml_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_taml_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_taml_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.
 

Detailed Description

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.

Name (GLOB, 0) // Creates global GLOB with value 0
Method (FUNA, 0, NotSerialized)
{
Store(30, GLOB) // Updates global GLOB to 10
// Store(0, _VAR) // Error, _VAR does not exist
}
Method (FUNB, 0, NotSerialized)
{
Name (_VAR, GLOB) // Creates _VAR and stores GLOB's value in it
If (IsEqual(_VAR, 20)) // On the second call this will be true as GLOB was updated to 20 by FUNB
{
Return
}
Method (FUNC, 0, NotSerialized)
{
Store(0, _VAR) // Updates _VAR to 0
Store(10, GLOB) // Updates global GLOB to 10
}
FUNC() // Calls inner FUNC
Store(20, GLOB) // Updates global GLOB to 20
FUNB() // Calls itself, will se its own _VAR which will contain the value in GLOB which is now 20
FUNA() // Calls a outer method, cannot see _VAR and would error if it tried to access it
// Method exists here, _VAR is removed
}

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.

See also
Section 5.3 of the ACPI specification for more details.

Macro Definition Documentation

◆ AML_NAME

#define AML_NAME (   a,
  b,
  c,
 
)
Value:
((aml_name_t)((((aml_name_t)(a) & 0xFF)) | (((aml_name_t)(b) & 0xFF) << 8) | (((aml_name_t)(c) & 0xFF) << 16) | \
(((aml_name_t)(d) & 0xFF) << 24)))
uint32_t aml_name_t
Name type.
Definition namespace.h:101

Macro to create an aml_name_t from 4 characters.

Parameters
aFirst character.
bSecond character.
cThird character.
dFourth character.
Returns
The aml_name_t value.

Definition at line 112 of file namespace.h.

◆ AML_NAME_TO_STRING

#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.

Parameters
nameThe aml_name_t value.
Returns
A stack allocated string representation of the name.

Definition at line 129 of file namespace.h.

◆ AML_NAME_UNDEFINED

#define AML_NAME_UNDEFINED   AML_NAME('x', 'x', 'x', 'x')

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.

Typedef Documentation

◆ aml_name_t

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.

Function Documentation

◆ aml_namespace_add_by_name_string()

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.

Parameters
overlayThe overlay to add the object to, if NULL the object is added to the global overlay.
startThe scope to start searching from to resolve the name string, if NULL the search starts from the root object.
nameStringThe name string to use to find the parent scope and name of the object.
objectThe object to add to the namespace.
Returns
On success, 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().

◆ aml_namespace_add_child()

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.

Parameters
overlayThe overlay to add the object to, if NULL the object is added to the global overlay.
parentThe parent scope to add the object to, if NULL the object is added to the root object.
nameThe name to give the object.
objectThe object to add to the namespace.
Returns
On success, 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().

◆ aml_namespace_commit()

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.

Parameters
overlayThe overlay to commit.
Returns
On success, 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().

◆ aml_namespace_expose()

uint64_t aml_namespace_expose ( void  )

Expose the entire namespace heirarchy to sysfs.

Returns
On success, 0. On failure, ERR and errno is set.

Definition at line 80 of file namespace.c.

Referenced by aml_init(), and init_finalize().

◆ aml_namespace_find()

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:

aml_namespace_find(NULL, parent, 2, AML_NAME('A', 'B', 'C', 'D'), AML_NAME('E', 'F', 'G', 'H'));
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.
Definition namespace.c:129
#define AML_NAME(a, b, c, d)
Macro to create an aml_name_t from 4 characters.
Definition namespace.h:112
#define NULL
Pointer error value.
Definition NULL.h:23
Parameters
overlayThe overlay to search in, if NULL only the global overlay is searched.
startThe scope to start searching from, if NULL the search starts from the root object.
nameCountThe number of name segments following.
...The name segments of the object to find.
Returns
The object reference or 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_namespace_find_by_name_string()

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:

  • If the NameString starts with a root character (\), the search starts from the root object.
  • If the NameString starts with one or more parent prefix characters (^), the search starts from the parent of the start object, moving up one level for each ^.
  • If the NameString does not start with a root or parent prefix character, the search starts from the start object. If start is NULL, the search starts from the root object.
  • Attempt to find a matching name in the current namespace scope (the start object and its children).
  • If there are no prefixes, only one name segment in the NameString and no match is found in the current scope, recursively search the parent scope, and so on.
  • If there are multiple name segments, then recursively searching parent scopes is not allowed. And we just continue searching the next segment in the current scope.
Parameters
overlayThe overlay to search in, if NULL only the global overlay is searched.
startThe scope to start searching from, if NULL the search starts from the root object.
nameStringThe name string of the object to find.
Returns
The object reference or 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_namespace_find_by_path()

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.

Parameters
overlayThe overlay to search in, if NULL only the global overlay is searched.
startThe scope to start searching from, if NULL the search starts from the root object.
pathThe path string of the object to find.
Returns
The object reference or 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_namespace_find_child()

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.

Parameters
overlayThe overlay to search in, if NULL only the global overlay is searched.
parentThe parent scope to search in.
nameThe name of the child object to find.
Returns
The object reference or 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_namespace_get_root()

aml_object_t * aml_namespace_get_root ( void  )

Get the root object of the namespace heirarchy.

Returns
The root object.

Definition at line 86 of file namespace.c.

References namespaceRoot, and REF.

Referenced by aml_method_find(), and aml_parse().

◆ aml_namespace_init()

uint64_t aml_namespace_init ( aml_object_t root)

Initialize the namespace heirarchy.

Parameters
rootThe object to use as the root of the namespace heirarchy.
Returns
On success, 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().

◆ aml_namespace_overlay_deinit()

void aml_namespace_overlay_deinit ( aml_namespace_overlay_t overlay)

Deinitialize a namespace overlay.

Parameters
overlayThe 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_get_highest_that_contains()

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.

Parameters
overlayThe overlay to check.
objectThe object to check for.
Returns
On success, the highest overlay that contains the object. On failure, 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().

◆ aml_namespace_overlay_init()

uint64_t aml_namespace_overlay_init ( aml_namespace_overlay_t overlay)

Initialize a namespace overlay.

Its parent is set to the global overlay.

Parameters
overlayThe overlay to initialize.
Returns
On success, 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().

◆ aml_namespace_overlay_set_parent()

void aml_namespace_overlay_set_parent ( aml_namespace_overlay_t overlay,
aml_namespace_overlay_t parent 
)

Set the parent of a namespace overlay.

Parameters
overlayThe overlay to set the parent of.
parentThe 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().

◆ aml_namespace_remove()

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.

Parameters
objectThe 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().