ReactOS 0.4.16-dev-1505-g12fa72a
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)
 

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 
)
Value:
{ \
.name.text = { c0, c1, c2, c3 }, \
}
#define UACPI_NAMESPACE_NODE_PREDEFINED
Definition: namespace.h:27

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 143 of file namespace.c.

144{
146
148 uacpi_free(node, sizeof(*node));
149 return;
150 }
151
153 node->object = UACPI_NULL;
154 node->parent = UACPI_NULL;
155 node->child = UACPI_NULL;
157}
#define uacpi_free(mem, _)
Definition: stdlib.h:96
#define uacpi_likely(expr)
Definition: compiler.h:59
#define UACPI_NULL
Definition: types.h:33
uacpi_bool uacpi_namespace_node_is_predefined(uacpi_namespace_node *node)
Definition: namespace.c:346
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 59 of file namespace.c.

62{
64
65 switch (ns) {
67 /*
68 * The real root object is stored in the global context, whereas the \
69 * node gets a placeholder uninitialized object instead. This is to
70 * protect against CopyObject(JUNK, \‍), so that all of the opregion and
71 * notify handlers are preserved if AML decides to do that.
72 */
74 if (uacpi_unlikely(g_uacpi_rt_ctx.root_object == UACPI_NULL))
75 return UACPI_NULL;
76
78 break;
79
83 return obj;
84
85 obj->buffer->text = uacpi_kernel_alloc(sizeof(UACPI_OS_VALUE));
86 if (uacpi_unlikely(obj->buffer->text == UACPI_NULL)) {
88 return UACPI_NULL;
89 }
90
91 obj->buffer->size = sizeof(UACPI_OS_VALUE);
92 uacpi_memcpy(obj->buffer->text, UACPI_OS_VALUE, obj->buffer->size);
93 break;
94
98 return obj;
99
100 obj->integer = UACPI_REV_VALUE;
101 break;
102
105 if (uacpi_likely(obj != UACPI_NULL)) {
106 uacpi_shareable_ref(obj->mutex);
107 g_uacpi_rt_ctx.global_lock_mutex = obj->mutex;
108 }
109 break;
110
114 return obj;
115
116 obj->method->native_call = UACPI_TRUE;
117 obj->method->handler = uacpi_osi;
118 obj->method->args = 1;
119 break;
120
121 default:
123 break;
124 }
125
126 return obj;
127}
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:58
#define UACPI_TRUE
Definition: types.h:29
@ UACPI_OBJECT_METHOD
Definition: types.h:113
@ UACPI_OBJECT_STRING
Definition: types.h:107
@ UACPI_OBJECT_DEVICE
Definition: types.h:111
@ UACPI_OBJECT_UNINITIALIZED
Definition: types.h:105
@ UACPI_OBJECT_MUTEX
Definition: types.h:114
@ UACPI_OBJECT_INTEGER
Definition: types.h:106
void uacpi_object_unref(uacpi_object *obj)
Definition: types.c:755
#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:6021
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:45

Referenced by uacpi_initialize_namespace().

◆ namespace_node_detach_object()

static void namespace_node_detach_object ( uacpi_namespace_node node)
static

Definition at line 129 of file namespace.c.

130{
132
134 if (object != UACPI_NULL) {
137
138 uacpi_object_unref(node->object);
139 node->object = UACPI_NULL;
140 }
141}
@ UACPI_OBJECT_OPERATION_REGION
Definition: types.h:115
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:398

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}
#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:122
uacpi_bool uacpi_object_is(uacpi_object *, uacpi_object_type)
Definition: types.c:985
return ret
Definition: mutex.c:146
uacpi_status uacpi_namespace_read_unlock(void)
Definition: namespace.c:44
uacpi_status uacpi_namespace_read_lock(void)
Definition: namespace.c:39
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33

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 208 of file namespace.c.

209{
212 uacpi_u32 depth = 1;
213
215
217
218 while (depth) {
219 next = next == UACPI_NULL ? current->child : next->next;
220
221 /*
222 * The previous value of 'next' was the last child of this subtree,
223 * we can now remove the entire scope of 'current->child'
224 */
225 if (next == UACPI_NULL) {
226 depth--;
227
228 // Wipe the subtree
229 while (current->child != UACPI_NULL)
231
232 // Reset the pointers back as if this iteration never happened
233 next = current;
234 current = current->parent;
235
236 continue;
237 }
238
239 /*
240 * We have more nodes to process, proceed to the next one, either the
241 * child of the 'next' node, if one exists, or its peer
242 */
243 if (next->child) {
244 depth++;
245 current = next;
247 }
248
249 // This node has no children, move on to its peer
250 }
251
254
255 if (ret == UACPI_STATUS_OK)
257
259 g_uacpi_rt_ctx.root_object = UACPI_NULL;
260
261 uacpi_mutex_unref(g_uacpi_rt_ctx.global_lock_mutex);
262 g_uacpi_rt_ctx.global_lock_mutex = UACPI_NULL;
263
265}
uacpi_status uacpi_rw_lock_deinit(struct uacpi_rw_lock *lock)
Definition: mutex.c:333
void uacpi_mutex_unref(uacpi_mutex *)
Definition: types.c:492
uint32_t uacpi_u32
Definition: types.h:21
uacpi_status uacpi_namespace_write_unlock(void)
Definition: namespace.c:54
static void free_namespace_node(uacpi_handle handle)
Definition: namespace.c:143
static struct uacpi_rw_lock namespace_lock
Definition: namespace.c:37
uacpi_status uacpi_namespace_node_uninstall(uacpi_namespace_node *node)
Definition: namespace.c:351
uacpi_namespace_node * uacpi_namespace_root(void)
Definition: namespace.c:267
uacpi_status uacpi_namespace_write_lock(void)
Definition: namespace.c:49
static void namespace_node_detach_object(uacpi_namespace_node *node)
Definition: namespace.c:129
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:1135

Referenced by exec_op().

◆ uacpi_initialize_namespace()

uacpi_status uacpi_initialize_namespace ( void  )

Definition at line 159 of file namespace.c.

160{
165
168 return ret;
169
170 for (ns = 0; ns <= UACPI_PREDEFINED_NAMESPACE_MAX; ns++) {
173
177
180 );
181 if (uacpi_unlikely(node->object == UACPI_NULL)) {
184 }
185
187 }
188
191
192 /*
193 * Skip the installation of \_OSI if it was disabled by user.
194 * We still create the object, but it's not attached to the namespace.
195 */
198 continue;
199
202 );
203 }
204
205 return UACPI_STATUS_OK;
206}
uacpi_status uacpi_rw_lock_init(struct uacpi_rw_lock *lock)
Definition: mutex.c:316
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:1453
@ 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:59
uacpi_status uacpi_namespace_node_install(uacpi_namespace_node *parent, uacpi_namespace_node *node)
Definition: namespace.c:302
static uacpi_namespace_node predefined_namespaces[UACPI_PREDEFINED_NAMESPACE_MAX+1]
Definition: namespace.c:24
void uacpi_shareable_init(uacpi_handle)
Definition: shareable.c:9
#define UACPI_FLAG_NO_OSI
Definition: uacpi.h:89

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:92
@ UACPI_SHOULD_LOCK_YES
Definition: namespace.h:97
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:70
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:33
@ UACPI_ITERATION_DECISION_CONTINUE
Definition: types.h:29
@ UACPI_INIT_LEVEL_SUBSYSTEM_INITIALIZED
Definition: types.h:66
uacpi_bool uacpi_namespace_node_is_temporary(uacpi_namespace_node *node)
Definition: namespace.c:341
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 
)

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 
)

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:146
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 272 of file namespace.c.

275{
277 uacpi_warn("requested invalid predefined namespace %d\n", ns);
278 return UACPI_NULL;
279 }
280
281 return &predefined_namespaces[ns];
282}
#define uacpi_warn(...)
Definition: log.h:20

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:727
uacpi_bool uacpi_object_is_one_of(uacpi_object *, uacpi_object_type_bits type_mask)
Definition: types.c:990

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 284 of file namespace.c.

285{
287
290 return ret;
291
293 ret->name = name;
294 return ret;
295}
#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:86
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 448 of file namespace.c.

452{
453 if (parent == UACPI_NULL)
455
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 302 of file namespace.c.

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

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 
)

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)

Definition at line 331 of file namespace.c.

332{
334}
#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 336 of file namespace.c.

337{
339}
#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 
)

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 346 of file namespace.c.

347{
349}

Referenced by free_namespace_node().

◆ uacpi_namespace_node_is_temporary()

uacpi_bool uacpi_namespace_node_is_temporary ( uacpi_namespace_node node)

Definition at line 341 of file namespace.c.

342{
344}
#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 
)

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 
)

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:412

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'\n", 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'\n",
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:448
uacpi_object_name name
Definition: namespace.h:31
struct uacpi_namespace_node * parent
Definition: namespace.h:34

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 
)

Definition at line 634 of file namespace.c.

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

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 
)

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 351 of file namespace.c.

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

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 297 of file namespace.c.

298{
300}
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 24 of file namespace.c.

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