PatchworkOS
Loading...
Searching...
No Matches
method.c
Go to the documentation of this file.
2
7#include <kernel/log/log.h>
8
9#include <errno.h>
10
12{
13 if (method == NULL || parentState == NULL)
14 {
15 errno = EINVAL;
16 return NULL;
17 }
18
19 uint8_t argCount = 0;
20 if (args != NULL)
21 {
22 while (argCount < AML_MAX_ARGS + 1 && args[argCount] != NULL)
23 {
24 argCount++;
25 }
26
27 if (argCount == AML_MAX_ARGS + 1)
28 {
29 LOG_ERR("too many arguments, max is %u\n", AML_MAX_ARGS);
30 errno = E2BIG;
31 return NULL;
32 }
33 }
34
35 if (argCount != method->methodFlags.argCount)
36 {
37 LOG_ERR("method '%s' expects %u arguments, got %u\n", AML_NAME_TO_STRING(method->name),
38 method->methodFlags.argCount, argCount);
39 errno = EINVAL;
40 return NULL;
41 }
42
43 if (method->methodFlags.isSerialized)
44 {
46 {
47 LOG_ERR("could not acquire method mutex\n");
48 return NULL;
49 }
50 }
51
52 if (method->implementation != NULL)
53 {
54 aml_object_t* temp = method->implementation(method, args, argCount);
55 if (method->methodFlags.isSerialized)
56 {
57 if (aml_mutex_release(&method->mutex) == ERR)
58 {
59 LOG_ERR("could not release method mutex\n");
60 return NULL;
61 }
62 }
63 return temp;
64 }
65
66 aml_state_t state;
67 if (aml_state_init(&state, args) == ERR)
68 {
69 LOG_ERR("could not initialize AML state\n");
70 if (method->methodFlags.isSerialized)
71 {
72 aml_mutex_release(&method->mutex); // Ignore errors
73 }
74 return NULL;
75 }
76
77 aml_object_t* methodObj = CONTAINER_OF(method, aml_object_t, method);
78
79 // This shit is a mess. Just check namespace.h for details.
80 aml_namespace_overlay_t* highestThatContainsMethod =
82 if (highestThatContainsMethod == NULL)
83 {
84 // Should never happen.
85 if (method->methodFlags.isSerialized)
86 {
87 aml_mutex_release(&method->mutex); // Ignore errors
88 }
89 errno = EIO;
90 return NULL;
91 }
92 aml_namespace_overlay_set_parent(&state.overlay, highestThatContainsMethod);
93
94 // "The current namespace location is assigned to the method package, and all namespace references that occur during
95 // control method execution for this package are relative to that location." - Section 19.6.85
96
97 // The method body is just a TermList.
98 if (aml_term_list_read(&state, methodObj, method->start, method->end, NULL) == ERR)
99 {
100 LOG_ERR("failed to read method body for method '%s'\n", AML_NAME_TO_STRING(method->name));
101 aml_state_deinit(&state);
102 if (method->methodFlags.isSerialized)
103 {
104 aml_mutex_release(&method->mutex); // Ignore errors
105 }
106 return NULL;
107 }
108
109 if (method->methodFlags.isSerialized)
110 {
111 if (aml_mutex_release(&method->mutex) == ERR)
112 {
113 LOG_ERR("could not release method mutex\n");
114 aml_state_deinit(&state);
115 return NULL;
116 }
117 }
118
119 aml_object_t* result = aml_state_result_get(&state);
120 aml_state_deinit(&state);
121 return result; // Transfer ownership
122}
123
125{
126 if (object == NULL || out == NULL)
127 {
128 errno = EINVAL;
129 return ERR;
130 }
131
132 aml_type_t type = object->type;
133 if (type == AML_INTEGER)
134 {
135 *out = object->integer.value;
136 return 0;
137 }
138
139 if (type != AML_METHOD)
140 {
141 LOG_ERR("object is a '%s', not a method or integer\n", aml_type_to_string(type));
142 errno = EINVAL;
143 return ERR;
144 }
145
146 aml_object_t* result = aml_method_evaluate(parentState, &object->method, NULL);
147 if (result == NULL)
148 {
149 return ERR;
150 }
151 DEREF_DEFER(result);
152
153 if (result->type != AML_INTEGER)
154 {
155 LOG_ERR("method did not return an Integer, returned '%s' instead\n", aml_type_to_string(result->type));
156 return ERR;
157 }
158
159 if (out != NULL)
160 {
161 *out = result->integer.value;
162 }
163 return 0;
164}
#define CLOCKS_NEVER
Definition clock_t.h:16
#define AML_MAX_ARGS
Maximum number of arguments that can be passed to a method.
Definition arg.h:19
uint64_t aml_term_list_read(aml_state_t *state, aml_object_t *scope, const uint8_t *start, const uint8_t *end, aml_term_list_ctx_t *parentCtx)
Reads a TermList structure from the AML byte stream.
Definition term.c:216
uint64_t aml_integer_t
AML Integer type.
Definition integer.h:20
aml_object_t * aml_method_evaluate(aml_state_t *parentState, aml_method_obj_t *method, aml_object_t **args)
Evaluate a method with the given arguments.
Definition method.c:11
uint64_t aml_method_evaluate_integer(aml_state_t *parentState, aml_object_t *object, aml_integer_t *out)
Wrapper around aml_method_evaluate for zero argument methods that return an integer or nothing and fo...
Definition method.c:124
uint64_t aml_mutex_release(aml_mutex_id_t *mutex)
Release a mutex.
Definition mutex.c:114
uint64_t aml_mutex_acquire(aml_mutex_id_t *mutex, aml_sync_level_t syncLevel, clock_t timeout)
Acquire a mutex, blocking until it is available or the timeout is reached.
Definition mutex.c:94
#define AML_NAME_TO_STRING(name)
Macro to convert an aml_name_t to a stack allocated string.
Definition namespace.h:129
void aml_namespace_overlay_set_parent(aml_namespace_overlay_t *overlay, aml_namespace_overlay_t *parent)
Set the parent of a namespace overlay.
Definition namespace.c:509
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.
Definition namespace.c:519
aml_type_t
ACPI data types.
Definition object.h:57
@ AML_METHOD
Definition object.h:75
@ AML_INTEGER
Definition object.h:65
uint64_t aml_state_init(aml_state_t *state, aml_object_t **args)
Initialize an AML state.
Definition state.c:8
aml_object_t * aml_state_result_get(aml_state_t *state)
Get the result object of the state.
Definition state.c:98
void aml_state_deinit(aml_state_t *state)
Deinitialize an AML state.
Definition state.c:79
const char * aml_type_to_string(aml_type_t type)
Convert an aml data type to a string.
Definition to_string.c:5
#define LOG_ERR(format,...)
Definition log.h:89
#define DEREF_DEFER(ptr)
RAII-style cleanup for scoped references.
Definition ref.h:54
#define EINVAL
Invalid argument.
Definition errno.h:142
#define EIO
I/O error.
Definition errno.h:57
#define errno
Error number variable.
Definition errno.h:27
#define E2BIG
Argument list too long.
Definition errno.h:67
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
#define CONTAINER_OF(ptr, type, member)
Container of macro.
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
aml_integer_t value
Definition object.h:266
bool isSerialized
true if method is serialized, false if not
Definition named.h:144
uint8_t argCount
Amount of arguments (0-7)
Definition named.h:143
aml_sync_level_t syncLevel
Synchronization level (0-15)
Definition named.h:145
Data for a method object.
Definition object.h:284
aml_method_implementation_t implementation
Definition object.h:290
aml_method_flags_t methodFlags
Definition object.h:291
const uint8_t * end
Definition object.h:293
aml_mutex_id_t mutex
Definition object.h:294
const uint8_t * start
Definition object.h:292
Namespace overlay.
Definition namespace.h:87
ACPI object.
Definition object.h:425
aml_integer_obj_t integer
Definition object.h:435
aml_method_obj_t method
Definition object.h:437
AML State.
Definition state.h:25
aml_namespace_overlay_t overlay
Holds any named objects created during parsing.
Definition state.h:30