PatchworkOS
Loading...
Searching...
No Matches
statement.c
Go to the documentation of this file.
2
8#include <kernel/log/log.h>
9
10#include <errno.h>
11
13{
14 if (aml_term_arg_read_integer(ctx, out) == ERR)
15 {
16 AML_DEBUG_ERROR(ctx, "Failed to read TermArg");
17 return ERR;
18 }
19 return 0;
20}
21
23{
24 if (aml_token_expect(ctx, AML_ELSE_OP) == ERR)
25 {
26 AML_DEBUG_ERROR(ctx, "Failed to read ElseOp");
27 return ERR;
28 }
29
30 const uint8_t* start = ctx->current;
31
32 aml_pkg_length_t pkgLength;
33 if (aml_pkg_length_read(ctx, &pkgLength) == ERR)
34 {
35 AML_DEBUG_ERROR(ctx, "Failed to read PkgLength");
36 return ERR;
37 }
38
39 const uint8_t* end = start + pkgLength;
40
41 if (shouldExecute)
42 {
43 // Execute the TermList in the same scope
44 if (aml_term_list_read(ctx->state, ctx->scope, ctx->current, end, ctx) == ERR)
45 {
46 AML_DEBUG_ERROR(ctx, "Failed to read TermList");
47 return ERR;
48 }
49 }
50
51 ctx->current = end;
52
53 return 0;
54}
55
57{
58 if (aml_token_expect(ctx, AML_IF_OP) == ERR)
59 {
60 AML_DEBUG_ERROR(ctx, "Failed to read IfOp");
61 return ERR;
62 }
63
64 const uint8_t* start = ctx->current;
65
66 aml_pkg_length_t pkgLength;
67 if (aml_pkg_length_read(ctx, &pkgLength) == ERR)
68 {
69 AML_DEBUG_ERROR(ctx, "Failed to read PkgLength");
70 return ERR;
71 }
72
73 // The end of the If statement, the "Else" part is not included in this length, see section 5.4.1 figure 5.17 of
74 // the ACPI spec.
75 const uint8_t* end = start + pkgLength;
76
77 aml_integer_t predicate;
78 if (aml_predicate_read(ctx, &predicate) == ERR)
79 {
80 AML_DEBUG_ERROR(ctx, "Failed to read Predicate");
81 return ERR;
82 }
83
84 bool isTrue = predicate != AML_FALSE;
85 if (isTrue)
86 {
87 // Execute the TermList in the same scope
88 if (aml_term_list_read(ctx->state, ctx->scope, ctx->current, end, ctx) == ERR)
89 {
90 AML_DEBUG_ERROR(ctx, "Failed to read TermList");
91 return ERR;
92 }
93 }
94
96 {
97 return 0;
98 }
99
100 ctx->current = end;
101
102 aml_token_t elseOp;
103 aml_token_peek(ctx, &elseOp);
104
105 if (elseOp.num == AML_ELSE_OP) // Optional
106 {
107 if (aml_def_else_read(ctx, !isTrue) == ERR)
108 {
109 AML_DEBUG_ERROR(ctx, "Failed to read ElseOp");
110 return ERR;
111 }
112 }
113
114 return 0;
115}
116
118{
119 if (aml_token_expect(ctx, AML_NOOP_OP) == ERR)
120 {
121 AML_DEBUG_ERROR(ctx, "Failed to read NoopOp");
122 return ERR;
123 }
124
125 return 0;
126}
127
129{
131 if (result == NULL)
132 {
133 AML_DEBUG_ERROR(ctx, "Failed to read TermArg");
134 return NULL;
135 }
136
137 return result; // Transfer ownership
138}
139
141{
143 {
144 AML_DEBUG_ERROR(ctx, "Failed to read ReturnOp");
145 return ERR;
146 }
147
148 aml_object_t* argObject = aml_arg_object_read(ctx);
149 if (argObject == NULL)
150 {
151 AML_DEBUG_ERROR(ctx, "Failed to read ArgObject");
152 return ERR;
153 }
154 DEREF_DEFER(argObject);
155
157 aml_state_result_set(ctx->state, argObject);
158
159 return 0;
160}
161
163{
165 {
166 AML_DEBUG_ERROR(ctx, "Failed to read ReleaseOp");
167 return ERR;
168 }
169
170 aml_object_t* mutexObject = aml_mutex_object_read(ctx);
171 if (mutexObject == NULL)
172 {
173 AML_DEBUG_ERROR(ctx, "Failed to read MutexObject");
174 return ERR;
175 }
176 DEREF_DEFER(mutexObject);
177
178 assert(mutexObject->type == AML_MUTEX);
179
180 if (aml_mutex_release(&mutexObject->mutex.mutex) == ERR)
181 {
182 AML_DEBUG_ERROR(ctx, "Failed to release mutex");
183 return ERR;
184 }
185
186 return 0;
187}
188
190{
191 if (aml_token_expect(ctx, AML_BREAK_OP) == ERR)
192 {
193 AML_DEBUG_ERROR(ctx, "Failed to read BreakOp");
194 return ERR;
195 }
196
198 return 0;
199}
200
202{
204 {
205 AML_DEBUG_ERROR(ctx, "Failed to read ContinueOp");
206 return ERR;
207 }
208
210 return 0;
211}
212
214{
215 if (aml_token_expect(ctx, AML_WHILE_OP) == ERR)
216 {
217 AML_DEBUG_ERROR(ctx, "Failed to read WhileOp");
218 return ERR;
219 }
220
221 const uint8_t* start = ctx->current;
222
223 aml_pkg_length_t pkgLength;
224 if (aml_pkg_length_read(ctx, &pkgLength) == ERR)
225 {
226 AML_DEBUG_ERROR(ctx, "Failed to read PkgLength");
227 return ERR;
228 }
229
230 const uint8_t* end = start + pkgLength;
231
232 const uint8_t* loopStart = ctx->current;
233 while (true)
234 {
235 ctx->current = loopStart;
236
237 aml_integer_t predicate;
238 if (aml_predicate_read(ctx, &predicate) == ERR)
239 {
240 AML_DEBUG_ERROR(ctx, "Failed to read Predicate");
241 return ERR;
242 }
243
244 if (predicate == AML_FALSE)
245 {
246 break;
247 }
248
249 // Execute the TermList in the same scope, might change flow control
250 if (aml_term_list_read(ctx->state, ctx->scope, ctx->current, end, ctx) == ERR)
251 {
252 AML_DEBUG_ERROR(ctx, "Failed to read TermList");
253 return ERR;
254 }
255
257 {
258 continue;
259 }
260 else if (ctx->stopReason == AML_STOP_REASON_RETURN)
261 {
262 break;
263 }
264 else if (ctx->stopReason == AML_STOP_REASON_BREAK)
265 {
267 break;
268 }
269 else if (ctx->stopReason == AML_STOP_REASON_CONTINUE)
270 {
272 }
273 else
274 {
275 AML_DEBUG_ERROR(ctx, "Invalid flow control state in while loop");
276 errno = EILSEQ;
277 return ERR;
278 }
279 }
280
281 ctx->current = end;
282 return 0;
283}
284
286{
287 aml_token_t op;
288 aml_token_peek(ctx, &op);
289
290 uint64_t result = 0;
291 switch (op.num)
292 {
293 case AML_IF_OP:
294 result = aml_def_if_else_read(ctx);
295 break;
296 case AML_NOOP_OP:
297 result = aml_def_noop_read(ctx);
298 break;
299 case AML_RETURN_OP:
300 result = aml_def_return_read(ctx);
301 break;
302 case AML_RELEASE_OP:
303 result = aml_def_release_read(ctx);
304 break;
305 case AML_WHILE_OP:
306 result = aml_def_while_read(ctx);
307 break;
308 case AML_BREAK_OP:
309 result = aml_def_break_read(ctx);
310 break;
311 case AML_CONTINUE_OP:
312 result = aml_def_continue_read(ctx);
313 break;
314 default:
315 AML_DEBUG_ERROR(ctx, "Unknown StatementOpcode '%s' (0x%x)", op.props->name, op.num);
316 errno = ENOSYS;
317 return ERR;
318 }
319
320 if (result == ERR)
321 {
322 AML_DEBUG_ERROR(ctx, "Failed to read StatementOpcode '%s' (0x%x)", op.props->name, op.num);
323 return ERR;
324 }
325
326 return 0;
327}
#define assert(expression)
Definition assert.h:29
#define AML_DEBUG_ERROR(ctx, format,...)
Macro to simplify calling aml_debug_error() with the current function name.
Definition debug.h:30
aml_object_t * aml_mutex_object_read(aml_term_list_ctx_t *ctx)
Reads a MutexObject structure from the AML byte stream.
uint32_t aml_pkg_length_t
PkgLength structure.
uint64_t aml_pkg_length_read(aml_term_list_ctx_t *ctx, aml_pkg_length_t *out)
Reads a PkgLength structure from the AML byte stream.
uint64_t aml_def_continue_read(aml_term_list_ctx_t *ctx)
Reads a DefContinue structure from the AML byte stream.
Definition statement.c:201
uint64_t aml_predicate_read(aml_term_list_ctx_t *ctx, aml_integer_t *out)
Reads a Predicate structure from the AML byte stream.
Definition statement.c:12
uint64_t aml_def_break_read(aml_term_list_ctx_t *ctx)
Reads a DefBreak structure from the AML byte stream.
Definition statement.c:189
uint64_t aml_def_noop_read(aml_term_list_ctx_t *ctx)
Reads a DefNoop structure from the AML byte stream.
Definition statement.c:117
aml_object_t * aml_arg_object_read(aml_term_list_ctx_t *ctx)
Reads an ArgObject structure from the AML byte stream.
Definition statement.c:128
uint64_t aml_statement_opcode_read(aml_term_list_ctx_t *ctx)
Reads an StatementOpcode structure from the AML byte stream.
Definition statement.c:285
uint64_t aml_def_if_else_read(aml_term_list_ctx_t *ctx)
Reads an DefIfElse structure from the AML byte stream.
Definition statement.c:56
uint64_t aml_def_return_read(aml_term_list_ctx_t *ctx)
Reads a DefReturn structure from the AML byte stream.
Definition statement.c:140
uint64_t aml_def_else_read(aml_term_list_ctx_t *ctx, bool shouldExecute)
Reads a DefElse structure from the AML byte stream.
Definition statement.c:22
uint64_t aml_def_release_read(aml_term_list_ctx_t *ctx)
Reads a DefRelease structure from the AML byte stream.
Definition statement.c:162
uint64_t aml_def_while_read(aml_term_list_ctx_t *ctx)
Reads a DefWhile structure from the AML byte stream.
Definition statement.c:213
aml_object_t * aml_term_arg_read(aml_term_list_ctx_t *ctx, aml_type_t allowedTypes)
Reads an TermArg structure from the AML byte stream.
Definition term.c:20
uint64_t aml_term_arg_read_integer(aml_term_list_ctx_t *ctx, aml_integer_t *out)
Wrapper around aml_term_arg_read() that converts the result to an integer.
Definition term.c:89
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
@ AML_STOP_REASON_BREAK
A Break statement was hit.
Definition term.h:27
@ AML_STOP_REASON_CONTINUE
A Continue statement was hit.
Definition term.h:28
@ AML_STOP_REASON_RETURN
A Return statement was hit.
Definition term.h:26
@ AML_STOP_REASON_NONE
No stop reason, continue execution or has reached the end of the TermList.
Definition term.h:25
uint64_t aml_integer_t
AML Integer type.
Definition integer.h:20
#define AML_FALSE
AML Boolean false value.
Definition integer.h:30
uint64_t aml_mutex_release(aml_mutex_id_t *mutex)
Release a mutex.
Definition mutex.c:114
@ AML_DATA_REF_OBJECTS
Definition object.h:103
@ AML_MUTEX
Definition object.h:76
void aml_state_result_set(aml_state_t *state, aml_object_t *result)
Set the result object of the state.
Definition state.c:131
static uint64_t aml_token_expect(aml_term_list_ctx_t *ctx, aml_token_num_t expected)
Reads a token from the AML stream and verifies it matches the expected token.
Definition token.h:353
static void aml_token_peek(aml_term_list_ctx_t *ctx, aml_token_t *out)
Attempt to read a token from the AML stream, without advancing the instruction pointer.
Definition token.h:301
@ AML_BREAK_OP
Definition token.h:161
@ AML_IF_OP
Definition token.h:156
@ AML_NOOP_OP
Definition token.h:159
@ AML_RETURN_OP
Definition token.h:160
@ AML_ELSE_OP
Definition token.h:157
@ AML_WHILE_OP
Definition token.h:158
@ AML_RELEASE_OP
Definition token.h:179
@ AML_CONTINUE_OP
Definition token.h:155
#define DEREF_DEFER(ptr)
RAII-style cleanup for scoped references.
Definition ref.h:54
#define ENOSYS
Function not implemented.
Definition errno.h:222
#define errno
Error number variable.
Definition errno.h:27
#define EILSEQ
Illegal byte sequence.
Definition errno.h:447
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
static void start()
Definition main.c:542
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
aml_mutex_id_t mutex
Definition object.h:305
ACPI object.
Definition object.h:425
aml_mutex_obj_t mutex
Definition object.h:438
Context for reading a TermList.
Definition term.h:37
aml_object_t * scope
Definition term.h:39
aml_state_t * state
Definition term.h:38
const uint8_t * current
Definition term.h:42
aml_stop_reason_t stopReason
Definition term.h:43
const char * name
Definition token.h:243
Token.
Definition token.h:253
const aml_token_props_t * props
Definition token.h:256
aml_token_num_t num
Definition token.h:254