PatchworkOS  966e257
A non-POSIX operating system.
Loading...
Searching...
No Matches
method.c
Go to the documentation of this file.
2
3#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_overlay_t* highestThatContainsMethod = aml_overlay_find_containing(&parentState->overlay, methodObj);
81 if (highestThatContainsMethod == NULL)
82 {
83 // Should never happen.
84 if (method->methodFlags.isSerialized)
85 {
86 aml_mutex_release(&method->mutex); // Ignore errors
87 }
88 errno = EIO;
89 return NULL;
90 }
91 aml_overlay_set_parent(&state.overlay, highestThatContainsMethod);
92
93 // "The current namespace location is assigned to the method package, and all namespace references that occur during
94 // control method execution for this package are relative to that location." - Section 19.6.85
95
96 // The method body is just a TermList.
97 if (aml_term_list_read(&state, methodObj, method->start, method->end, NULL) == ERR)
98 {
99 LOG_ERR("failed to read method body for method '%s'\n", AML_NAME_TO_STRING(method->name));
100 aml_state_deinit(&state);
101 if (method->methodFlags.isSerialized)
102 {
103 aml_mutex_release(&method->mutex); // Ignore errors
104 }
105 return NULL;
106 }
107
108 if (method->methodFlags.isSerialized)
109 {
110 if (aml_mutex_release(&method->mutex) == ERR)
111 {
112 LOG_ERR("could not release method mutex\n");
113 aml_state_deinit(&state);
114 return NULL;
115 }
116 }
117
118 aml_object_t* result = aml_state_result_get(&state);
119 aml_state_deinit(&state);
120 return result; // Transfer ownership
121}
#define CLOCKS_NEVER
Definition clock_t.h:16
#define LOG_ERR(format,...)
Definition log.h:108
#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.
#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:189
aml_object_t * aml_method_invoke(aml_state_t *parentState, aml_method_t *method, aml_object_t **args)
Invoke a method with the given arguments.
Definition method.c:11
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
aml_overlay_t * aml_overlay_find_containing(aml_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:577
void aml_overlay_set_parent(aml_overlay_t *overlay, aml_overlay_t *parent)
Set the parent of a namespace overlay.
Definition namespace.c:567
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:87
void aml_state_deinit(aml_state_t *state)
Deinitialize an AML state.
Definition state.c:68
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
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:306
aml_method_flags_t methodFlags
Definition object.h:313
aml_method_implementation_t implementation
Definition object.h:312
aml_mutex_id_t mutex
Definition object.h:316
const uint8_t * end
Definition object.h:315
const uint8_t * start
Definition object.h:314
ACPI object.
Definition object.h:447
Namespace overlay.
Definition namespace.h:87
AML State.
Definition state.h:25
aml_overlay_t overlay
Holds any named objects created during parsing.
Definition state.h:30