ReactOS 0.4.17-dev-684-ga6524ef
namespace.c File Reference
Include dependency graph for namespace.c:

Go to the source code of this file.

Macros

#define UACPI_REV_VALUE   2
 
#define UACPI_OS_VALUE   "Microsoft Windows NT"
 
#define MAKE_PREDEFINED(c0, c1, c2, c3)    { .name.text = { c0, c1, c2, c3 } }
 

Enumerations

enum  action { ACTION_REACQUIRE , ACTION_PUT }
 

Functions

uacpi_status uacpi_namespace_read_lock (void)
 
uacpi_status uacpi_namespace_read_unlock (void)
 
uacpi_status uacpi_namespace_write_lock (void)
 
uacpi_status uacpi_namespace_write_unlock (void)
 
static uacpi_objectmake_object_for_predefined (enum uacpi_predefined_namespace ns)
 
static void namespace_node_detach_object (uacpi_namespace_node *node)
 
static void free_namespace_node (uacpi_handle handle)
 
uacpi_status uacpi_initialize_namespace (void)
 
void uacpi_deinitialize_namespace (void)
 
uacpi_namespace_nodeuacpi_namespace_root (void)
 
uacpi_namespace_nodeuacpi_namespace_get_predefined (enum uacpi_predefined_namespace ns)
 
uacpi_namespace_nodeuacpi_namespace_node_alloc (uacpi_object_name name)
 
void uacpi_namespace_node_unref (uacpi_namespace_node *node)
 
uacpi_status uacpi_namespace_node_install (uacpi_namespace_node *parent, uacpi_namespace_node *node)
 
uacpi_bool uacpi_namespace_node_is_alias (uacpi_namespace_node *node)
 
uacpi_bool uacpi_namespace_node_is_dangling (uacpi_namespace_node *node)
 
uacpi_bool uacpi_namespace_node_is_temporary (uacpi_namespace_node *node)
 
uacpi_bool uacpi_namespace_node_is_predefined (uacpi_namespace_node *node)
 
uacpi_status uacpi_namespace_node_uninstall (uacpi_namespace_node *node)
 
uacpi_namespace_nodeuacpi_namespace_node_find_sub_node (uacpi_namespace_node *parent, uacpi_object_name name)
 
static uacpi_object_name segment_to_name (const uacpi_char **string, uacpi_size *in_out_size)
 
uacpi_status uacpi_namespace_node_resolve (uacpi_namespace_node *parent, const uacpi_char *path, enum uacpi_should_lock should_lock, enum uacpi_may_search_above_parent may_search_above_parent, enum uacpi_permanent_only permanent_only, uacpi_namespace_node **out_node)
 
uacpi_status uacpi_namespace_node_find (uacpi_namespace_node *parent, const uacpi_char *path, uacpi_namespace_node **out_node)
 
uacpi_status uacpi_namespace_node_resolve_from_aml_namepath (uacpi_namespace_node *scope, const uacpi_char *path, uacpi_namespace_node **out_node)
 
uacpi_objectuacpi_namespace_node_get_object (const uacpi_namespace_node *node)
 
uacpi_objectuacpi_namespace_node_get_object_typed (const uacpi_namespace_node *node, uacpi_object_type_bits type_mask)
 
uacpi_status uacpi_namespace_node_acquire_object_typed (const uacpi_namespace_node *node, uacpi_object_type_bits type_mask, uacpi_object **out_obj)
 
uacpi_status uacpi_namespace_node_acquire_object (const uacpi_namespace_node *node, uacpi_object **out_obj)
 
static uacpi_status object_mutate_refcount (uacpi_object *obj, void(*cb)(uacpi_object *))
 
uacpi_status uacpi_namespace_node_reacquire_object (uacpi_object *obj)
 
uacpi_status uacpi_namespace_node_release_object (uacpi_object *obj)
 
uacpi_object_name uacpi_namespace_node_name (const uacpi_namespace_node *node)
 
uacpi_status uacpi_namespace_node_type_unlocked (const uacpi_namespace_node *node, uacpi_object_type *out_type)
 
uacpi_status uacpi_namespace_node_type (const uacpi_namespace_node *node, uacpi_object_type *out_type)
 
uacpi_status uacpi_namespace_node_is_one_of_unlocked (const uacpi_namespace_node *node, uacpi_object_type_bits type_mask, uacpi_bool *out)
 
uacpi_status uacpi_namespace_node_is_one_of (const uacpi_namespace_node *node, uacpi_object_type_bits type_mask, uacpi_bool *out)
 
uacpi_status uacpi_namespace_node_is (const uacpi_namespace_node *node, uacpi_object_type type, uacpi_bool *out)
 
uacpi_status uacpi_namespace_do_for_each_child (uacpi_namespace_node *node, uacpi_iteration_callback descending_callback, uacpi_iteration_callback ascending_callback, uacpi_object_type_bits type_mask, uacpi_u32 max_depth, enum uacpi_should_lock should_lock, enum uacpi_permanent_only permanent_only, void *user)
 
uacpi_status uacpi_namespace_for_each_child_simple (uacpi_namespace_node *parent, uacpi_iteration_callback callback, void *user)
 
uacpi_status uacpi_namespace_for_each_child (uacpi_namespace_node *parent, uacpi_iteration_callback descending_callback, uacpi_iteration_callback ascending_callback, uacpi_object_type_bits type_mask, uacpi_u32 max_depth, void *user)
 
uacpi_status uacpi_namespace_node_next_typed (uacpi_namespace_node *parent, uacpi_namespace_node **iter, uacpi_object_type_bits type_mask)
 
uacpi_status uacpi_namespace_node_next (uacpi_namespace_node *parent, uacpi_namespace_node **iter)
 
uacpi_size uacpi_namespace_node_depth (const uacpi_namespace_node *node)
 
uacpi_namespace_nodeuacpi_namespace_node_parent (uacpi_namespace_node *node)
 
const uacpi_charuacpi_namespace_node_generate_absolute_path (const uacpi_namespace_node *node)
 
void uacpi_free_absolute_path (const uacpi_char *path)
 

Variables

static uacpi_namespace_node predefined_namespaces [UACPI_PREDEFINED_NAMESPACE_MAX+1]
 
static struct uacpi_rw_lock namespace_lock
 

Macro Definition Documentation

◆ MAKE_PREDEFINED

#define MAKE_PREDEFINED (   c0,
  c1,
  c2,
  c3 
)     { .name.text = { c0, c1, c2, c3 } }

Definition at line 17 of file namespace.c.

◆ UACPI_OS_VALUE

#define UACPI_OS_VALUE   "Microsoft Windows NT"

Definition at line 15 of file namespace.c.

◆ UACPI_REV_VALUE

#define UACPI_REV_VALUE   2

Definition at line 14 of file namespace.c.

Enumeration Type Documentation

◆ action

Enumerator
ACTION_REACQUIRE 
ACTION_PUT 

Definition at line 707 of file namespace.c.

707 {
710};
@ ACTION_REACQUIRE
Definition: namespace.c:708
@ ACTION_PUT
Definition: namespace.c:709

Function Documentation

◆ free_namespace_node()

static void free_namespace_node ( uacpi_handle  handle)
static

Definition at line 140 of file namespace.c.

141{
143
145 uacpi_free(node, sizeof(*node));
146 return;
147 }
148
149 node->flags = 0;
150 node->object = UACPI_NULL;
151 node->parent = UACPI_NULL;
152 node->child = UACPI_NULL;
154}
#define uacpi_free(mem, _)
Definition: stdlib.h:96
#define uacpi_likely(expr)
Definition: compiler.h:89
#define UACPI_NULL
Definition: types.h:33
uacpi_bool uacpi_namespace_node_is_predefined(uacpi_namespace_node *node)
Definition: namespace.c:343
Definition: dlist.c:348
void * next
Definition: dlist.c:360

Referenced by uacpi_deinitialize_namespace(), and uacpi_namespace_node_unref().

◆ make_object_for_predefined()

static uacpi_object * make_object_for_predefined ( enum uacpi_predefined_namespace  ns)
static

Definition at line 56 of file namespace.c.

59{
61
62 switch (ns) {
64 /*
65 * The real root object is stored in the global context, whereas the \
66 * node gets a placeholder uninitialized object instead. This is to
67 * protect against CopyObject(JUNK, \‍), so that all of the opregion and
68 * notify handlers are preserved if AML decides to do that.
69 */
71 if (uacpi_unlikely(g_uacpi_rt_ctx.root_object == UACPI_NULL))
72 return UACPI_NULL;
73
75 break;
76
80 return obj;
81
82 obj->buffer->text = uacpi_kernel_alloc(sizeof(UACPI_OS_VALUE));
83 if (uacpi_unlikely(obj->buffer->text == UACPI_NULL)) {
85 return UACPI_NULL;
86 }
87
88 obj->buffer->size = sizeof(UACPI_OS_VALUE);
89 uacpi_memcpy(obj->buffer->text, UACPI_OS_VALUE, obj->buffer->size);
90 break;
91
95 return obj;
96
97 obj->integer = UACPI_REV_VALUE;
98 break;
99
102 if (uacpi_likely(obj != UACPI_NULL)) {
103 uacpi_shareable_ref(obj->mutex);
104 g_uacpi_rt_ctx.global_lock_mutex = obj->mutex;
105 }
106 break;
107
111 return obj;
112
113 obj->method->native_call = UACPI_TRUE;
114 obj->method->handler = uacpi_osi;
115 obj->method->args = 1;
116 break;
117
118 default:
120 break;
121 }
122
123 return obj;
124}
struct uacpi_runtime_context g_uacpi_rt_ctx
Definition: uacpi.c:17
#define uacpi_memcpy
Definition: stdlib.h:34
uacpi_object * uacpi_create_object(uacpi_object_type type)
Definition: types.c:327
@ UACPI_PREDEFINED_NAMESPACE_REV
Definition: namespace.h:26
@ UACPI_PREDEFINED_NAMESPACE_ROOT
Definition: namespace.h:17
@ UACPI_PREDEFINED_NAMESPACE_OSI
Definition: namespace.h:25
@ UACPI_PREDEFINED_NAMESPACE_GL
Definition: namespace.h:23
@ UACPI_PREDEFINED_NAMESPACE_OS
Definition: namespace.h:24
#define uacpi_unlikely(expr)
Definition: compiler.h:88
#define UACPI_TRUE
Definition: types.h:29
@ UACPI_OBJECT_METHOD
Definition: types.h:119
@ UACPI_OBJECT_STRING
Definition: types.h:113
@ UACPI_OBJECT_DEVICE
Definition: types.h:117
@ UACPI_OBJECT_UNINITIALIZED
Definition: types.h:111
@ UACPI_OBJECT_MUTEX
Definition: types.h:120
@ UACPI_OBJECT_INTEGER
Definition: types.h:112
void uacpi_object_unref(uacpi_object *obj)
Definition: types.c:762
#define UACPI_OS_VALUE
Definition: namespace.c:15
#define UACPI_REV_VALUE
Definition: namespace.c:14
uacpi_status uacpi_osi(uacpi_handle handle, uacpi_object *retval)
Definition: interpreter.c:6237
void * uacpi_kernel_alloc(uacpi_size size)
Definition: uacpiosl.c:111
uacpi_u32 uacpi_shareable_ref(uacpi_handle)
Definition: shareable.c:31
Definition: mxnamespace.c:38

Referenced by uacpi_initialize_namespace().

◆ namespace_node_detach_object()

static void namespace_node_detach_object ( uacpi_namespace_node node)
static

Definition at line 126 of file namespace.c.

127{
129
131 if (object != UACPI_NULL) {
134
135 uacpi_object_unref(node->object);
136 node->object = UACPI_NULL;
137 }
138}
@ UACPI_OBJECT_OPERATION_REGION
Definition: types.h:121
uacpi_object * uacpi_namespace_node_get_object(const uacpi_namespace_node *node)
Definition: namespace.c:646
void uacpi_opregion_uninstall_handler(uacpi_namespace_node *node)
Definition: opregion.c:403

Referenced by uacpi_deinitialize_namespace(), and uacpi_namespace_node_uninstall().

◆ object_mutate_refcount()

static uacpi_status object_mutate_refcount ( uacpi_object obj,
void(*)(uacpi_object *)  cb 
)
static

Definition at line 712 of file namespace.c.

715{
717
719 cb(obj);
720 return ret;
721 }
722
723 /*
724 * Reference objects must be (un)referenced under at least a read lock, as
725 * this requires walking down the entire reference chain and dropping each
726 * object ref-count by 1. This might race with the interpreter and
727 * object_replace_child in case an object in the chain is CopyObject'ed
728 * into.
729 */
732 return ret;
733
734 cb(obj);
735
737 return ret;
738}
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
#define uacpi_unlikely_error(expr)
Definition: status.h:49
uacpi_status
Definition: status.h:10
@ UACPI_STATUS_OK
Definition: status.h:11
@ UACPI_OBJECT_REFERENCE
Definition: types.h:128
uacpi_bool uacpi_object_is(uacpi_object *, uacpi_object_type)
Definition: types.c:992
return ret
Definition: mutex.c:147
uacpi_status uacpi_namespace_read_unlock(void)
Definition: namespace.c:41
uacpi_status uacpi_namespace_read_lock(void)
Definition: namespace.c:36

Referenced by uacpi_namespace_node_reacquire_object(), and uacpi_namespace_node_release_object().

◆ segment_to_name()

static uacpi_object_name segment_to_name ( const uacpi_char **  string,
uacpi_size in_out_size 
)
static

Definition at line 468 of file namespace.c.

471{
472 uacpi_object_name out_name;
473 const uacpi_char *cursor = *string;
474 uacpi_size offset, bytes_left = *in_out_size;
475
476 for (offset = 0; offset < 4; offset++) {
477 if (bytes_left < 1 || *cursor == '.') {
478 out_name.text[offset] = '_';
479 continue;
480 }
481
482 out_name.text[offset] = *cursor++;
483 bytes_left--;
484 }
485
486 *string = cursor;
487 *in_out_size = bytes_left;
488 return out_name;
489}
size_t uacpi_size
Definition: types.h:37
char uacpi_char
Definition: types.h:44
GLintptr offset
Definition: glext.h:5920
const char cursor[]
Definition: icontest.c:13
char string[160]
Definition: util.h:11
uacpi_char text[4]
Definition: types.h:24

Referenced by uacpi_namespace_node_resolve().

◆ uacpi_deinitialize_namespace()

void uacpi_deinitialize_namespace ( void  )

Definition at line 205 of file namespace.c.

206{
209 uacpi_u32 depth = 1;
210
212
214
215 while (depth) {
216 next = next == UACPI_NULL ? current->child : next->next;
217
218 /*
219 * The previous value of 'next' was the last child of this subtree,
220 * we can now remove the entire scope of 'current->child'
221 */
222 if (next == UACPI_NULL) {
223 depth--;
224
225 // Wipe the subtree
226 while (current->child != UACPI_NULL)
228
229 // Reset the pointers back as if this iteration never happened
230 next = current;
231 current = current->parent;
232
233 continue;
234 }
235
236 /*
237 * We have more nodes to process, proceed to the next one, either the
238 * child of the 'next' node, if one exists, or its peer
239 */
240 if (next->child) {
241 depth++;
242 current = next;
244 }
245
246 // This node has no children, move on to its peer
247 }
248
251
252 if (ret == UACPI_STATUS_OK)
254
256 g_uacpi_rt_ctx.root_object = UACPI_NULL;
257
258 uacpi_mutex_unref(g_uacpi_rt_ctx.global_lock_mutex);
259 g_uacpi_rt_ctx.global_lock_mutex = UACPI_NULL;
260
262}
uacpi_status uacpi_rw_lock_deinit(struct uacpi_rw_lock *lock)
Definition: mutex.c:334
void uacpi_mutex_unref(uacpi_mutex *)
Definition: types.c:495
uint32_t uacpi_u32
Definition: types.h:21
uacpi_status uacpi_namespace_write_unlock(void)
Definition: namespace.c:51
static void free_namespace_node(uacpi_handle handle)
Definition: namespace.c:140
static struct uacpi_rw_lock namespace_lock
Definition: namespace.c:34
uacpi_status uacpi_namespace_node_uninstall(uacpi_namespace_node *node)
Definition: namespace.c:349
uacpi_namespace_node * uacpi_namespace_root(void)
Definition: namespace.c:264
uacpi_status uacpi_namespace_write_lock(void)
Definition: namespace.c:46
static void namespace_node_detach_object(uacpi_namespace_node *node)
Definition: namespace.c:126
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
struct task_struct * current
Definition: linux.c:32
static unsigned __int64 next
Definition: rand_nt.c:6

Referenced by uacpi_state_reset().

◆ uacpi_free_absolute_path()

void uacpi_free_absolute_path ( const uacpi_char path)

Definition at line 1074 of file namespace.c.

1075{
1077}
void uacpi_free_dynamic_string(const uacpi_char *str)
Definition: utilities.c:1148

Referenced by exec_op().

◆ uacpi_initialize_namespace()

uacpi_status uacpi_initialize_namespace ( void  )

Definition at line 156 of file namespace.c.

157{
162
165 return ret;
166
167 for (ns = 0; ns <= UACPI_PREDEFINED_NAMESPACE_MAX; ns++) {
170
174
177 );
178 if (uacpi_unlikely(node->object == UACPI_NULL)) {
181 }
182
184 }
185
188
189 /*
190 * Skip the installation of \_OSI if it was disabled by user.
191 * We still create the object, but it's not attached to the namespace.
192 */
195 continue;
196
199 );
200 }
201
202 return UACPI_STATUS_OK;
203}
uacpi_status uacpi_rw_lock_init(struct uacpi_rw_lock *lock)
Definition: mutex.c:317
static uacpi_bool uacpi_check_flag(uacpi_u64 flag)
Definition: context.h:90
struct uacpi_object * uacpi_create_internal_reference(enum uacpi_reference_kind kind, uacpi_object *child)
Definition: types.c:1471
@ UACPI_REFERENCE_KIND_NAMED
Definition: types.h:14
uacpi_predefined_namespace
Definition: namespace.h:16
@ UACPI_PREDEFINED_NAMESPACE_GPE
Definition: namespace.h:18
@ UACPI_PREDEFINED_NAMESPACE_MAX
Definition: namespace.h:27
@ UACPI_STATUS_OUT_OF_MEMORY
Definition: status.h:13
static uacpi_object * make_object_for_predefined(enum uacpi_predefined_namespace ns)
Definition: namespace.c:56
uacpi_status uacpi_namespace_node_install(uacpi_namespace_node *parent, uacpi_namespace_node *node)
Definition: namespace.c:299
static uacpi_namespace_node predefined_namespaces[UACPI_PREDEFINED_NAMESPACE_MAX+1]
Definition: namespace.c:21
void uacpi_shareable_init(uacpi_handle)
Definition: shareable.c:9
#define UACPI_FLAG_NO_OSI
Definition: uacpi.h:100

Referenced by uacpi_initialize().

◆ uacpi_namespace_do_for_each_child()

uacpi_status uacpi_namespace_do_for_each_child ( uacpi_namespace_node node,
uacpi_iteration_callback  descending_callback,
uacpi_iteration_callback  ascending_callback,
uacpi_object_type_bits  type_mask,
uacpi_u32  max_depth,
enum uacpi_should_lock  should_lock,
enum uacpi_permanent_only  permanent_only,
void user 
)

Definition at line 834 of file namespace.c.

841{
846 uacpi_u32 depth = 1;
847
849
850 if (uacpi_unlikely(descending_callback == UACPI_NULL &&
851 ascending_callback == UACPI_NULL))
853
854 if (uacpi_unlikely(node == UACPI_NULL || max_depth == 0))
856
857 if (should_lock == UACPI_SHOULD_LOCK_YES) {
860 return ret;
861 }
862
863 if (node->child == UACPI_NULL)
864 goto out;
865
866 node = node->child;
867
868 while (depth) {
870 if (!matches) {
872 goto do_next;
873 }
874
875 if (permanent_only == UACPI_PERMANENT_ONLY_YES &&
878 goto do_next;
879 }
880
881 cb = walking_up ? ascending_callback : descending_callback;
882 if (cb != UACPI_NULL) {
883 if (should_lock == UACPI_SHOULD_LOCK_YES) {
886 return ret;
887 }
888
889 decision = cb(user, node, depth);
890 if (decision == UACPI_ITERATION_DECISION_BREAK)
891 return ret;
892
893 if (should_lock == UACPI_SHOULD_LOCK_YES) {
896 return ret;
897 }
898 } else {
900 }
901
902 do_next:
903 if (walking_up) {
904 if (node->next) {
905 node = node->next;
906 walking_up = UACPI_FALSE;
907 continue;
908 }
909
910 depth--;
911 node = node->parent;
912 continue;
913 }
914
915 switch (decision) {
917 if ((depth != max_depth) && (node->child != UACPI_NULL)) {
918 node = node->child;
919 depth++;
920 continue;
921 }
924 walking_up = UACPI_TRUE;
925 continue;
926 default:
928 goto out;
929 }
930 }
931
932out:
933 if (should_lock == UACPI_SHOULD_LOCK_YES)
935 return ret;
936}
void user(int argc, const char *argv[])
Definition: cmds.c:1350
#define UACPI_ENSURE_INIT_LEVEL_AT_LEAST(lvl)
Definition: context.h:127
@ UACPI_PERMANENT_ONLY_YES
Definition: namespace.h:90
@ UACPI_SHOULD_LOCK_YES
Definition: namespace.h:95
uacpi_iteration_decision(* uacpi_iteration_callback)(void *user, uacpi_namespace_node *node, uacpi_u32 node_depth)
Definition: namespace.h:98
#define UACPI_FALLTHROUGH
Definition: compiler.h:100
bool uacpi_bool
Definition: types.h:31
#define UACPI_FALSE
Definition: types.h:30
@ UACPI_STATUS_INVALID_ARGUMENT
Definition: status.h:18
uacpi_iteration_decision
Definition: types.h:28
@ UACPI_ITERATION_DECISION_BREAK
Definition: types.h:30
@ UACPI_ITERATION_DECISION_NEXT_PEER
Definition: types.h:39
@ UACPI_ITERATION_DECISION_CONTINUE
Definition: types.h:29
@ UACPI_INIT_LEVEL_SUBSYSTEM_INITIALIZED
Definition: types.h:72
uacpi_bool uacpi_namespace_node_is_temporary(uacpi_namespace_node *node)
Definition: namespace.c:338
uacpi_status uacpi_namespace_node_is_one_of_unlocked(const uacpi_namespace_node *node, uacpi_object_type_bits type_mask, uacpi_bool *out)
Definition: namespace.c:790
#define matches(FN)
Definition: match.h:70
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383

Referenced by create_gpe_block(), object_replace_child(), reg_or_unreg_all_opregions(), uacpi_events_match_post_dynamic_table_load(), uacpi_install_address_space_handler_with_flags(), uacpi_namespace_for_each_child(), uacpi_namespace_for_each_child_simple(), and uacpi_uninstall_address_space_handler().

◆ uacpi_namespace_for_each_child()

uacpi_status uacpi_namespace_for_each_child ( uacpi_namespace_node parent,
uacpi_iteration_callback  descending_callback,
uacpi_iteration_callback  ascending_callback,
uacpi_object_type_bits  type_mask,
uacpi_u32  max_depth,
void user 
)

Depth-first iterate the namespace starting at the first child of 'parent'.

'descending_callback' is invoked the first time a node is visited when walking down. 'ascending_callback' is invoked the second time a node is visited after we reach the leaf node without children and start walking up. Either of the callbacks may be NULL, but not both at the same time.

Only nodes matching 'type_mask' are passed to the callbacks.

'max_depth' is used to limit the maximum reachable depth from 'parent', where 1 is only direct children of 'parent', 2 is children of first-level children etc. Use UACPI_MAX_DEPTH_ANY or -1 to specify infinite depth.

Definition at line 948 of file namespace.c.

953{
955 parent, descending_callback, ascending_callback, type_mask, max_depth,
957 );
958}
uacpi_status uacpi_namespace_do_for_each_child(uacpi_namespace_node *node, uacpi_iteration_callback descending_callback, uacpi_iteration_callback ascending_callback, uacpi_object_type_bits type_mask, uacpi_u32 max_depth, enum uacpi_should_lock should_lock, enum uacpi_permanent_only permanent_only, void *user)
Definition: namespace.c:834
r parent
Definition: btrfs.c:3010

Referenced by uacpi_find_devices_at(), and uacpi_namespace_initialize().

◆ uacpi_namespace_for_each_child_simple()

uacpi_status uacpi_namespace_for_each_child_simple ( uacpi_namespace_node parent,
uacpi_iteration_callback  callback,
void user 
)

Depth-first iterate the namespace starting at the first child of 'parent'.

Definition at line 938 of file namespace.c.

941{
945 );
946}
#define UACPI_MAX_DEPTH_ANY
Definition: namespace.h:102
@ UACPI_OBJECT_ANY_BIT
Definition: types.h:152
static IPrintDialogCallback callback
Definition: printdlg.c:326

◆ uacpi_namespace_get_predefined()

uacpi_namespace_node * uacpi_namespace_get_predefined ( enum uacpi_predefined_namespace  ns)

Definition at line 269 of file namespace.c.

272{
274 uacpi_warn("requested invalid predefined namespace %d", ns);
275 return UACPI_NULL;
276 }
277
278 return &predefined_namespaces[ns];
279}
#define uacpi_warn(...)
Definition: log.h:35

Referenced by do_sta_ini(), eval_sst(), initialize_gpes(), sanitize_device_and_find_gpe(), and uacpi_namespace_initialize().

◆ uacpi_namespace_node_acquire_object()

uacpi_status uacpi_namespace_node_acquire_object ( const uacpi_namespace_node node,
uacpi_object **  out_obj 
)

Definition at line 698 of file namespace.c.

701{
703 node, UACPI_OBJECT_ANY_BIT, out_obj
704 );
705}
uacpi_status uacpi_namespace_node_acquire_object_typed(const uacpi_namespace_node *node, uacpi_object_type_bits type_mask, uacpi_object **out_obj)
Definition: namespace.c:670

◆ uacpi_namespace_node_acquire_object_typed()

uacpi_status uacpi_namespace_node_acquire_object_typed ( const uacpi_namespace_node node,
uacpi_object_type_bits  type_mask,
uacpi_object **  out_obj 
)

Definition at line 670 of file namespace.c.

674{
677
680 return ret;
681
683
684 if (uacpi_unlikely(obj == UACPI_NULL) ||
685 !uacpi_object_is_one_of(obj, type_mask)) {
687 goto out;
688 }
689
691 *out_obj = obj;
692
693out:
695 return ret;
696}
void uacpi_object_ref(uacpi_object *obj)
Definition: types.c:734
uacpi_bool uacpi_object_is_one_of(uacpi_object *, uacpi_object_type_bits type_mask)
Definition: types.c:997

Referenced by uacpi_install_notify_handler(), uacpi_namespace_node_acquire_object(), and uacpi_uninstall_notify_handler().

◆ uacpi_namespace_node_alloc()

uacpi_namespace_node * uacpi_namespace_node_alloc ( uacpi_object_name  name)

Definition at line 281 of file namespace.c.

282{
284
287 return ret;
288
290 ret->name = name;
291 return ret;
292}
#define uacpi_kernel_alloc_zeroed
Definition: stdlib.h:127
Definition: name.c:39

Referenced by resolve_name_string().

◆ uacpi_namespace_node_depth()

uacpi_size uacpi_namespace_node_depth ( const uacpi_namespace_node node)

Definition at line 1015 of file namespace.c.

1016{
1017 uacpi_size depth = 0;
1018
1019 while (node->parent) {
1020 depth++;
1021 node = node->parent;
1022 }
1023
1024 return depth;
1025}

Referenced by uacpi_namespace_node_generate_absolute_path().

◆ uacpi_namespace_node_find()

uacpi_status uacpi_namespace_node_find ( uacpi_namespace_node parent,
const uacpi_char path,
uacpi_namespace_node **  out_node 
)

Definition at line 623 of file namespace.c.

627{
631 );
632}
@ UACPI_MAY_SEARCH_ABOVE_PARENT_NO
Definition: namespace.h:84
uacpi_status uacpi_namespace_node_resolve(uacpi_namespace_node *parent, const uacpi_char *path, enum uacpi_should_lock should_lock, enum uacpi_may_search_above_parent may_search_above_parent, enum uacpi_permanent_only permanent_only, uacpi_namespace_node **out_node)
Definition: namespace.c:491

◆ uacpi_namespace_node_find_sub_node()

uacpi_namespace_node * uacpi_namespace_node_find_sub_node ( uacpi_namespace_node parent,
uacpi_object_name  name 
)

Definition at line 446 of file namespace.c.

450{
452
453 if (parent == UACPI_NULL)
455
456 node = parent->child;
457
458 while (node) {
459 if (node->name.id == name.id)
460 return node;
461
462 node = node->next;
463 }
464
465 return UACPI_NULL;
466}

Referenced by resolve_name_string(), and uacpi_namespace_node_resolve().

◆ uacpi_namespace_node_generate_absolute_path()

const uacpi_char * uacpi_namespace_node_generate_absolute_path ( const uacpi_namespace_node node)

Definition at line 1034 of file namespace.c.

1037{
1039 uacpi_size bytes_needed;
1041
1043
1044 // \ only needs 1 byte, the rest is 4 bytes
1045 bytes_needed = 1 + (depth - 1) * sizeof(uacpi_object_name);
1046
1047 // \ and the first NAME don't need a '.', every other segment does
1048 bytes_needed += depth > 2 ? depth - 2 : 0;
1049
1050 // Null terminator
1051 bytes_needed += 1;
1052
1053 path = uacpi_kernel_alloc(bytes_needed);
1055 return path;
1056
1057 path[0] = '\\';
1058
1059 offset = bytes_needed - 1;
1060 path[offset] = '\0';
1061
1062 while (node != uacpi_namespace_root()) {
1063 offset -= sizeof(uacpi_object_name);
1064 uacpi_memcpy(&path[offset], node->name.text, sizeof(uacpi_object_name));
1065
1066 node = node->parent;
1067 if (node != uacpi_namespace_root())
1068 path[--offset] = '.';
1069 }
1070
1071 return path;
1072}
uacpi_size uacpi_namespace_node_depth(const uacpi_namespace_node *node)
Definition: namespace.c:1015

Referenced by exec_op(), handle_notify(), trace_invalid_return_type(), trace_method_abort(), trace_named_object_lookup_or_creation_failure(), trace_region_io(), uacpi_dispatch_opregion_io(), uacpi_eval_dstate_method_template(), and uacpi_trace_region_error().

◆ uacpi_namespace_node_get_object()

◆ uacpi_namespace_node_get_object_typed()

◆ uacpi_namespace_node_install()

uacpi_status uacpi_namespace_node_install ( uacpi_namespace_node parent,
uacpi_namespace_node node 
)

Definition at line 299 of file namespace.c.

303{
304 if (parent == UACPI_NULL)
306
308 uacpi_warn("attempting to install a dangling namespace node %.4s",
309 node->name.text);
311 }
312
313 if (parent->child == UACPI_NULL) {
314 parent->child = node;
315 } else {
316 uacpi_namespace_node *prev = parent->child;
317
318 while (prev->next != UACPI_NULL)
319 prev = prev->next;
320
321 prev->next = node;
322 }
323
324 node->parent = parent;
325 return UACPI_STATUS_OK;
326}
@ UACPI_STATUS_NAMESPACE_NODE_DANGLING
Definition: status.h:24
uacpi_bool uacpi_namespace_node_is_dangling(uacpi_namespace_node *node)
Definition: namespace.c:333
struct uacpi_namespace_node * next
Definition: namespace.h:34

Referenced by do_install_node_item(), and uacpi_initialize_namespace().

◆ uacpi_namespace_node_is()

uacpi_status uacpi_namespace_node_is ( const uacpi_namespace_node node,
uacpi_object_type  type,
uacpi_bool out 
)

Returns UACPI_TRUE via 'out' if the type of the object stored at the namespace node matches the provided value, UACPI_FALSE otherwise.

NOTE: due to the existance of the CopyObject operator in AML, the return value of this function is subject to TOCTOU bugs.

Definition at line 825 of file namespace.c.

828{
830 node, 1u << type, out
831 );
832}
uacpi_status uacpi_namespace_node_is_one_of(const uacpi_namespace_node *node, uacpi_object_type_bits type_mask, uacpi_bool *out)
Definition: namespace.c:808
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545

Referenced by eval_resource_helper(), uacpi_install_gpe_block(), uacpi_setup_gpe_for_wake(), and uacpi_uninstall_gpe_block().

◆ uacpi_namespace_node_is_alias()

uacpi_bool uacpi_namespace_node_is_alias ( uacpi_namespace_node node)

Returns UACPI_TRUE if the provided 'node' is an alias.

Definition at line 328 of file namespace.c.

329{
331}
#define UACPI_NAMESPACE_NODE_FLAG_ALIAS
Definition: namespace.h:10

Referenced by do_sta_ini().

◆ uacpi_namespace_node_is_dangling()

uacpi_bool uacpi_namespace_node_is_dangling ( uacpi_namespace_node node)

Definition at line 333 of file namespace.c.

334{
336}
#define UACPI_NAMESPACE_NODE_FLAG_DANGLING
Definition: namespace.h:19

Referenced by uacpi_namespace_node_install(), uacpi_namespace_node_uninstall(), and uacpi_opregion_attach().

◆ uacpi_namespace_node_is_one_of()

uacpi_status uacpi_namespace_node_is_one_of ( const uacpi_namespace_node node,
uacpi_object_type_bits  type_mask,
uacpi_bool out 
)

Returns UACPI_TRUE via 'out' if the type of the object stored at the namespace node matches any of the type bits in the provided value, UACPI_FALSE otherwise.

NOTE: due to the existance of the CopyObject operator in AML, the return value of this function is subject to TOCTOU bugs.

Definition at line 808 of file namespace.c.

812{
814
817 return ret;
818
820
822 return ret;
823}

Referenced by uacpi_namespace_node_is().

◆ uacpi_namespace_node_is_one_of_unlocked()

uacpi_status uacpi_namespace_node_is_one_of_unlocked ( const uacpi_namespace_node node,
uacpi_object_type_bits  type_mask,
uacpi_bool out 
)

◆ uacpi_namespace_node_is_predefined()

uacpi_bool uacpi_namespace_node_is_predefined ( uacpi_namespace_node node)

Definition at line 343 of file namespace.c.

Referenced by free_namespace_node().

◆ uacpi_namespace_node_is_temporary()

uacpi_bool uacpi_namespace_node_is_temporary ( uacpi_namespace_node node)

Definition at line 338 of file namespace.c.

339{
341}
#define UACPI_NAMESPACE_NODE_FLAG_TEMPORARY
Definition: namespace.h:25

Referenced by uacpi_namespace_do_for_each_child(), uacpi_namespace_node_next_typed(), and uacpi_namespace_node_resolve().

◆ uacpi_namespace_node_name()

uacpi_object_name uacpi_namespace_node_name ( const uacpi_namespace_node node)

Definition at line 752 of file namespace.c.

753{
754 return node->name;
755}

Referenced by async_run_gpe_handler(), uacpi_eval_cid(), uacpi_eval_hid(), uacpi_eval_uid(), and uacpi_get_namespace_node_info().

◆ uacpi_namespace_node_next()

uacpi_status uacpi_namespace_node_next ( uacpi_namespace_node parent,
uacpi_namespace_node **  iter 
)

Retrieve the next peer namespace node of '*iter', or, if '*iter' is UACPI_NULL, retrieve the first child of 'parent' instead. The resulting namespace node is stored at '*iter'.

This API can be used to implement an "iterator" version of the for_each_child helpers.

Example usage: void recurse(uacpi_namespace_node *parent) { uacpi_namespace_node *iter = UACPI_NULL;

while (uacpi_namespace_node_next(parent, &iter) == UACPI_STATUS_OK) { // Do something with iter... descending_callback(iter);

// Recurse down to walk over the children of iter recurse(iter); } }

Prefer the for_each_child family of helpers if possible instead of this API as they avoid recursion and/or the need to use dynamic data structures entirely.

Definition at line 1006 of file namespace.c.

1009{
1012 );
1013}
uacpi_status uacpi_namespace_node_next_typed(uacpi_namespace_node *parent, uacpi_namespace_node **iter, uacpi_object_type_bits type_mask)
Definition: namespace.c:960

◆ uacpi_namespace_node_next_typed()

uacpi_status uacpi_namespace_node_next_typed ( uacpi_namespace_node parent,
uacpi_namespace_node **  iter,
uacpi_object_type_bits  type_mask 
)

Retrieve the next peer namespace node of '*iter', or, if '*iter' is UACPI_NULL, retrieve the first child of 'parent' instead. The resulting namespace node is stored at '*iter'. Only nodes which type matches one of the types set in 'type_mask' are returned.

See comment above 'uacpi_namespace_node_next' for usage examples.

Prefer the for_each_child family of helpers if possible instead of this API as they avoid recursion and/or the need to use dynamic data structures entirely.

Definition at line 960 of file namespace.c.

964{
968
970
971 if (uacpi_unlikely(parent == UACPI_NULL && *iter == UACPI_NULL))
973
976 return ret;
977
978 node = *iter;
979 if (node == UACPI_NULL)
980 node = parent->child;
981 else
982 node = node->next;
983
984 for (; node != UACPI_NULL; node = node->next) {
986 continue;
987
989 node, type_mask, &is_one_of
990 );
992 break;
993 if (is_one_of)
994 break;
995 }
996
998 if (node == UACPI_NULL)
1000
1002 *iter = node;
1003 return ret;
1004}
#define uacpi_likely_success(expr)
Definition: status.h:53
static uacpi_bool is_one_of(uacpi_char c, const uacpi_char *list)
Definition: stdlib.c:436

Referenced by uacpi_namespace_node_next().

◆ uacpi_namespace_node_parent()

uacpi_namespace_node * uacpi_namespace_node_parent ( uacpi_namespace_node node)

Definition at line 1027 of file namespace.c.

1030{
1031 return node->parent;
1032}

◆ uacpi_namespace_node_reacquire_object()

uacpi_status uacpi_namespace_node_reacquire_object ( uacpi_object obj)

Definition at line 740 of file namespace.c.

743{
745}
static uacpi_status object_mutate_refcount(uacpi_object *obj, void(*cb)(uacpi_object *))
Definition: namespace.c:712

◆ uacpi_namespace_node_release_object()

uacpi_status uacpi_namespace_node_release_object ( uacpi_object obj)

Definition at line 747 of file namespace.c.

Referenced by free_notification_ctx().

◆ uacpi_namespace_node_resolve()

uacpi_status uacpi_namespace_node_resolve ( uacpi_namespace_node parent,
const uacpi_char path,
enum uacpi_should_lock  should_lock,
enum uacpi_may_search_above_parent  may_search_above_parent,
enum uacpi_permanent_only  permanent_only,
uacpi_namespace_node **  out_node 
)

Definition at line 491 of file namespace.c.

498{
499 uacpi_namespace_node *cur_node = parent;
501 const uacpi_char *cursor = path;
502 uacpi_size bytes_left;
503 uacpi_char prev_char = 0;
504 uacpi_bool single_nameseg = UACPI_TRUE;
505
506 if (cur_node == UACPI_NULL)
507 cur_node = uacpi_namespace_root();
508
509 bytes_left = uacpi_strlen(path);
510
511 if (should_lock == UACPI_SHOULD_LOCK_YES) {
514 return ret;
515 }
516
517 for (;;) {
518 if (bytes_left == 0)
519 goto out;
520
521 switch (*cursor) {
522 case '\\':
523 single_nameseg = UACPI_FALSE;
524
525 if (prev_char == '^') {
527 goto out;
528 }
529
530 cur_node = uacpi_namespace_root();
531 break;
532 case '^':
533 single_nameseg = UACPI_FALSE;
534
535 // Tried to go behind root
536 if (uacpi_unlikely(cur_node == uacpi_namespace_root())) {
538 goto out;
539 }
540
541 cur_node = cur_node->parent;
542 break;
543 default:
544 break;
545 }
546
547 prev_char = *cursor;
548
549 switch (prev_char) {
550 case '^':
551 case '\\':
552 cursor++;
553 bytes_left--;
554 break;
555 default:
556 break;
557 }
558
559 if (prev_char != '^')
560 break;
561 }
562
563 while (bytes_left != 0) {
564 uacpi_object_name nameseg;
565
566 if (*cursor == '.') {
567 cursor++;
568 bytes_left--;
569 }
570
571 nameseg = segment_to_name(&cursor, &bytes_left);
572 if (bytes_left != 0 && single_nameseg)
573 single_nameseg = UACPI_FALSE;
574
575 cur_node = uacpi_namespace_node_find_sub_node(cur_node, nameseg);
576 if (cur_node == UACPI_NULL) {
577 if (may_search_above_parent == UACPI_MAY_SEARCH_ABOVE_PARENT_NO ||
578 !single_nameseg)
579 goto out;
580
581 parent = parent->parent;
582
583 while (parent) {
584 cur_node = uacpi_namespace_node_find_sub_node(parent, nameseg);
585 if (cur_node != UACPI_NULL)
586 goto out;
587
588 parent = parent->parent;
589 }
590
591 goto out;
592 }
593 }
594
595out:
597 uacpi_warn("invalid path '%s'", path);
598 goto out_read_unlock;
599 }
600
601 if (cur_node == UACPI_NULL) {
603 goto out_read_unlock;
604 }
605
606 if (uacpi_namespace_node_is_temporary(cur_node) &&
607 permanent_only == UACPI_PERMANENT_ONLY_YES) {
608 uacpi_warn("denying access to temporary namespace node '%.4s'",
609 cur_node->name.text);
611 goto out_read_unlock;
612 }
613
614 if (out_node != UACPI_NULL)
615 *out_node = cur_node;
616
617out_read_unlock:
618 if (should_lock == UACPI_SHOULD_LOCK_YES)
620 return ret;
621}
uacpi_size uacpi_strlen(const uacpi_char *str)
Definition: stdlib.c:72
@ UACPI_STATUS_DENIED
Definition: status.h:31
static uacpi_object_name segment_to_name(const uacpi_char **string, uacpi_size *in_out_size)
Definition: namespace.c:468
uacpi_namespace_node * uacpi_namespace_node_find_sub_node(uacpi_namespace_node *parent, uacpi_object_name name)
Definition: namespace.c:446
uacpi_object_name name
Definition: namespace.h:29
struct uacpi_namespace_node * parent
Definition: namespace.h:32

Referenced by handle_load_table(), region_run_reg(), uacpi_eval(), uacpi_namespace_node_find(), and uacpi_namespace_node_resolve_from_aml_namepath().

◆ uacpi_namespace_node_resolve_from_aml_namepath()

uacpi_status uacpi_namespace_node_resolve_from_aml_namepath ( uacpi_namespace_node scope,
const uacpi_char path,
uacpi_namespace_node **  out_node 
)

Same as uacpi_namespace_node_find, except the search recurses upwards when the namepath consists of only a single nameseg. Usually, this behavior is only desired if resolving a namepath specified in an aml-provided object, such as a package element.

Definition at line 634 of file namespace.c.

639{
643 );
644}
@ UACPI_MAY_SEARCH_ABOVE_PARENT_YES
Definition: namespace.h:85

Referenced by uacpi_object_resolve_as_aml_namepath().

◆ uacpi_namespace_node_type()

uacpi_status uacpi_namespace_node_type ( const uacpi_namespace_node node,
uacpi_object_type out_type 
)

Returns the type of object stored at the namespace node.

NOTE: due to the existance of the CopyObject operator in AML, the return value of this function is subject to TOCTOU bugs.

Definition at line 774 of file namespace.c.

777{
779
782 return ret;
783
785
787 return ret;
788}
uacpi_status uacpi_namespace_node_type_unlocked(const uacpi_namespace_node *node, uacpi_object_type *out_type)
Definition: namespace.c:757

Referenced by do_sta_ini(), and pci_region_attach().

◆ uacpi_namespace_node_type_unlocked()

uacpi_status uacpi_namespace_node_type_unlocked ( const uacpi_namespace_node node,
uacpi_object_type out_type 
)

Definition at line 757 of file namespace.c.

760{
762
765
769
770 *out_type = obj->type;
771 return UACPI_STATUS_OK;
772}

Referenced by uacpi_namespace_node_type().

◆ uacpi_namespace_node_uninstall()

uacpi_status uacpi_namespace_node_uninstall ( uacpi_namespace_node node)

Definition at line 349 of file namespace.c.

350{
352
354 uacpi_warn("attempting to uninstall a dangling namespace node %.4s",
355 node->name.text);
357 }
358
359 /*
360 * The way to trigger this is as follows:
361 *
362 * Method (FOO) {
363 * // Temporary device, will be deleted upon returning from FOO
364 * Device (\BAR) {
365 * }
366 *
367 * //
368 * // Load TBL where TBL is:
369 * // Scope (\BAR) {
370 * // Name (TEST, 123)
371 * // }
372 * //
373 * Load(TBL)
374 * }
375 *
376 * In the above example, TEST is a permanent node attached by bad AML to a
377 * temporary node created inside the FOO method at \BAR. The cleanup code
378 * will attempt to remove the \BAR device upon exit from FOO, but that is
379 * no longer possible as there's now a permanent child attached to it.
380 */
381 if (uacpi_unlikely(node->child != UACPI_NULL)) {
383 "refusing to uninstall node %.4s with a child (%.4s)",
384 node->name.text, node->child->name.text
385 );
386 return UACPI_STATUS_DENIED;
387 }
388
389 /*
390 * Even though namespace_node is reference-counted it still has an 'invalid'
391 * state that is entered after it is uninstalled from the global namespace.
392 *
393 * Reference counting is only needed to combat dangling pointer issues
394 * whereas bad AML might try to prolong a local object lifetime by
395 * returning it from a method, or CopyObject it somewhere. In that case the
396 * namespace node object itself is still alive, but no longer has a valid
397 * object associated with it.
398 *
399 * Example:
400 * Method (BAD) {
401 * OperationRegion(REG, SystemMemory, 0xDEADBEEF, 4)
402 * Field (REG, AnyAcc, NoLock) {
403 * FILD, 8,
404 * }
405 *
406 * Return (RefOf(FILD))
407 * }
408 *
409 * // Local0 is now the sole owner of the 'FILD' object that under the
410 * // hood is still referencing the 'REG' operation region object from
411 * // the 'BAD' method.
412 * Local0 = DerefOf(BAD())
413 *
414 * This is done to prevent potential very deep recursion where an object
415 * frees a namespace node that frees an attached object that frees a
416 * namespace node as well as potential infinite cycles between a namespace
417 * node and an object.
418 */
420
421 prev = node->parent ? node->parent->child : UACPI_NULL;
422
423 if (prev == node) {
424 node->parent->child = node->next;
425 } else {
426 while (uacpi_likely(prev != UACPI_NULL) && prev->next != node)
427 prev = prev->next;
428
429 if (uacpi_unlikely(prev == UACPI_NULL)) {
431 "trying to uninstall a node %.4s (%p) not linked to any peer",
432 node->name.text, node
433 );
435 }
436
437 prev->next = node->next;
438 }
439
442
443 return UACPI_STATUS_OK;
444}
@ UACPI_STATUS_INTERNAL_ERROR
Definition: status.h:21
void uacpi_namespace_node_unref(uacpi_namespace_node *node)
Definition: namespace.c:294

Referenced by call_frame_clear(), and uacpi_deinitialize_namespace().

◆ uacpi_namespace_node_unref()

void uacpi_namespace_node_unref ( uacpi_namespace_node node)

Definition at line 294 of file namespace.c.

295{
297}
void uacpi_shareable_unref_and_delete_if_last(uacpi_handle, void(*do_free)(uacpi_handle))
Definition: shareable.c:51

Referenced by free_field_unit(), free_notification_ctx(), pop_item(), region_uninstall_handler(), and uacpi_namespace_node_uninstall().

◆ uacpi_namespace_read_lock()

◆ uacpi_namespace_read_unlock()

◆ uacpi_namespace_root()

◆ uacpi_namespace_write_lock()

◆ uacpi_namespace_write_unlock()

Variable Documentation

◆ namespace_lock

◆ predefined_namespaces

uacpi_namespace_node predefined_namespaces[UACPI_PREDEFINED_NAMESPACE_MAX+1]
static
Initial value:
= {
}
@ UACPI_PREDEFINED_NAMESPACE_PR
Definition: namespace.h:19
@ UACPI_PREDEFINED_NAMESPACE_SB
Definition: namespace.h:20
@ UACPI_PREDEFINED_NAMESPACE_SI
Definition: namespace.h:21
@ UACPI_PREDEFINED_NAMESPACE_TZ
Definition: namespace.h:22
#define MAKE_PREDEFINED(c0, c1, c2, c3)
Definition: namespace.c:17

Definition at line 21 of file namespace.c.

Referenced by uacpi_initialize_namespace(), uacpi_namespace_get_predefined(), uacpi_namespace_node_is_predefined(), and uacpi_namespace_root().