PatchworkOS
Loading...
Searching...
No Matches
data.c
Go to the documentation of this file.
2
11#include <kernel/log/log.h>
12
13#include <errno.h>
14#include <stdint.h>
15
17{
18 if (ctx->end - ctx->current < 1)
19 {
20 AML_DEBUG_ERROR(ctx, "Not enough data to read ByteData");
21 errno = ENODATA;
22 return ERR;
23 }
24
25 *out = *ctx->current;
26 ctx->current += 1;
27 return 0;
28}
29
31{
32 uint8_t byte1, byte2;
33 if (aml_byte_data_read(ctx, &byte1) == ERR || aml_byte_data_read(ctx, &byte2) == ERR)
34 {
35 AML_DEBUG_ERROR(ctx, "Failed to read word data");
36 return ERR;
37 }
38 *out = ((uint16_t)byte1) | (((uint16_t)byte2) << 8);
39 return 0;
40}
41
43{
44 uint16_t word1, word2;
45 if (aml_word_data_read(ctx, &word1) == ERR || aml_word_data_read(ctx, &word2) == ERR)
46 {
47 AML_DEBUG_ERROR(ctx, "Failed to read dword data");
48 return ERR;
49 }
50 *out = ((uint32_t)word1) | (((uint32_t)word2) << 16);
51 return 0;
52}
53
55{
56 uint32_t dword1, dword2;
57 if (aml_dword_data_read(ctx, &dword1) == ERR || aml_dword_data_read(ctx, &dword2) == ERR)
58 {
59 AML_DEBUG_ERROR(ctx, "Failed to read qword data");
60 return ERR;
61 }
62 *out = ((uint64_t)dword1) | (((uint64_t)dword2) << 32);
63 return 0;
64}
65
67{
69 {
70 AML_DEBUG_ERROR(ctx, "Failed to read byte prefix");
71 return ERR;
72 }
73
74 return aml_byte_data_read(ctx, out);
75}
76
78{
80 {
81 AML_DEBUG_ERROR(ctx, "Failed to read word prefix");
82 return ERR;
83 }
84
85 return aml_word_data_read(ctx, out);
86}
87
89{
91 {
92 AML_DEBUG_ERROR(ctx, "Failed to read dword prefix");
93 return ERR;
94 }
95
96 return aml_dword_data_read(ctx, out);
97}
98
100{
102 {
103 AML_DEBUG_ERROR(ctx, "Failed to read qword prefix");
104 return ERR;
105 }
106
107 return aml_qword_data_read(ctx, out);
108}
109
111{
112 aml_token_t token;
113 aml_token_read(ctx, &token);
114
115 switch (token.num)
116 {
117 case AML_ZERO_OP:
118 if (aml_integer_set(out, 0) == ERR)
119 {
120 return ERR;
121 }
122 break;
123 case AML_ONE_OP:
124 if (aml_integer_set(out, 1) == ERR)
125 {
126 return ERR;
127 }
128 break;
129 case AML_ONES_OP:
130 if (aml_integer_set(out, aml_integer_ones()) == ERR)
131 {
132 return ERR;
133 }
134 break;
135 default:
136 AML_DEBUG_ERROR(ctx, "Invalid ConstObj token '0x%x'", token.num);
137 errno = EILSEQ;
138 return ERR;
139 }
140
141 return 0;
142}
143
145{
147 {
148 AML_DEBUG_ERROR(ctx, "Failed to read StringPrefix");
149 return ERR;
150 }
151
152 const char* start = (const char*)ctx->current;
153 while (1)
154 {
155 uint8_t c;
156 if (aml_byte_data_read(ctx, &c) == ERR)
157 {
158 AML_DEBUG_ERROR(ctx, "Failed to read byte in string");
159 return ERR;
160 }
161
162 if (c == 0x00)
163 {
164 break;
165 }
166
167 if (c < 0x01 || c > 0x7F)
168 {
169 AML_DEBUG_ERROR(ctx, "Invalid ASCII character '0x%x' in string", c);
170 errno = EILSEQ;
171 return ERR;
172 }
173 }
174
175 if (aml_string_set(out, start) == ERR)
176 {
177 return ERR;
178 }
179
180 return 0;
181}
182
184{
186 {
187 AML_DEBUG_ERROR(ctx, "Failed to read RevisionOp");
188 return ERR;
189 }
190
192 {
193 return ERR;
194 }
195
196 return 0;
197}
198
200{
201 aml_token_t token;
202 aml_token_peek(ctx, &token);
203
204 uint64_t result = 0;
205 switch (token.num)
206 {
207 case AML_BYTE_PREFIX:
208 {
209 uint8_t byte;
210 if (aml_byte_const_read(ctx, &byte) == ERR)
211 {
212 AML_DEBUG_ERROR(ctx, "Failed to read ByteConst");
213 return ERR;
214 }
215
216 if (aml_integer_set(out, byte) == ERR)
217 {
218 return ERR;
219 }
220 return 0;
221 }
222 case AML_WORD_PREFIX:
223 {
224 uint16_t word;
225 if (aml_word_const_read(ctx, &word) == ERR)
226 {
227 AML_DEBUG_ERROR(ctx, "Failed to read WordConst");
228 return ERR;
229 }
230
231 if (aml_integer_set(out, word) == ERR)
232 {
233 return ERR;
234 }
235 return 0;
236 }
237 case AML_DWORD_PREFIX:
238 {
239 uint32_t dword;
240 if (aml_dword_const_read(ctx, &dword) == ERR)
241 {
242 AML_DEBUG_ERROR(ctx, "Failed to read DWordConst");
243 return ERR;
244 }
245
246 if (aml_integer_set(out, dword) == ERR)
247 {
248 return ERR;
249 }
250 return 0;
251 }
252 case AML_QWORD_PREFIX:
253 {
254 uint64_t qword;
255 if (aml_qword_const_read(ctx, &qword) == ERR)
256 {
257 AML_DEBUG_ERROR(ctx, "Failed to read QWordConst");
258 return ERR;
259 }
260
261 if (aml_integer_set(out, qword) == ERR)
262 {
263 return ERR;
264 }
265 return 0;
266 }
268 if (aml_string_read(ctx, out) == ERR)
269 {
270 AML_DEBUG_ERROR(ctx, "Failed to read String");
271 return ERR;
272 }
273 return 0;
274 case AML_ZERO_OP:
275 case AML_ONE_OP:
276 case AML_ONES_OP:
277 if (aml_const_obj_read(ctx, out) == ERR)
278 {
279 AML_DEBUG_ERROR(ctx, "Failed to read ConstObj");
280 return ERR;
281 }
282 return 0;
283 case AML_BUFFER_OP:
284 if (aml_def_buffer_read(ctx, out) == ERR)
285 {
286 AML_DEBUG_ERROR(ctx, "Failed to read Buffer");
287 return ERR;
288 }
289 return 0;
290 case AML_REVISION_OP:
291 if (aml_revision_op_read(ctx, out) == ERR)
292 {
293 AML_DEBUG_ERROR(ctx, "Failed to read RevisionOp");
294 return ERR;
295 }
296 return 0;
297 default:
298 AML_DEBUG_ERROR(ctx, "Invalid ComputationalData '%s' (0x%x)", token.props->name, token.num);
299 errno = EILSEQ;
300 return ERR;
301 }
302}
303
305{
306 if (aml_byte_data_read(ctx, out) == ERR)
307 {
308 AML_DEBUG_ERROR(ctx, "Failed to read NumElements");
309 return ERR;
310 }
311
312 return 0;
313}
314
320{
321 if (in->type &
323 AML_PACKAGE)) // "... resolved to actual data by the AML interpreter"
324 {
325 // Unsure what the spec means by "actual data" but converting to DataObject seems to be the most sensible
326 // interpretation.
327 if (aml_convert_source(state, in, &out, AML_DATA_OBJECTS) == ERR)
328 {
329 LOG_ERR("failed to convert to data object in aml_package_element_handle_name()\n");
330 return ERR;
331 }
332 return 0;
333 }
334 else // "... returned in the package as references"
335 {
336 if (aml_object_reference_set(out, in) == ERR)
337 {
338 LOG_ERR("failed to init ObjectReference in aml_package_element_handle_name()\n");
339 return ERR;
340 }
341 return 0;
342 }
343}
344
346{
347 aml_token_t token;
348 aml_token_peek(ctx, &token);
349
350 if (token.props->type == AML_TOKEN_TYPE_NAME)
351 {
352 aml_name_string_t nameString;
353 if (aml_name_string_read(ctx, &nameString) == ERR)
354 {
355 AML_DEBUG_ERROR(ctx, "Failed to read NameString");
356 return ERR;
357 }
358
359 aml_object_t* object = aml_namespace_find_by_name_string(&ctx->state->overlay, ctx->scope, &nameString);
360 if (object == NULL)
361 {
362 if (aml_unresolved_set(out, &nameString, ctx->scope, aml_package_element_handle_name) == ERR)
363 {
364 return ERR;
365 }
366 return 0;
367 }
368
369 if (aml_package_element_handle_name(ctx->state, object, out) == ERR)
370 {
371 AML_DEBUG_ERROR(ctx, "Failed to handle name in PackageElement");
372 return ERR;
373 }
374
375 return 0;
376 }
377
378 if (aml_data_ref_object_read(ctx, out) == ERR)
379 {
380 AML_DEBUG_ERROR(ctx, "Failed to read DataRefObject");
381 return ERR;
382 }
383
384 return 0;
385}
386
388{
389 uint64_t i = 0;
390 while (ctx->current < end && i < package->length)
391 {
392 if (aml_package_element_read(ctx, package->elements[i]) == ERR)
393 {
394 for (uint64_t j = 0; j < i; j++)
395 {
396 aml_object_clear(package->elements[j]);
397 }
398 AML_DEBUG_ERROR(ctx, "Failed to read PackageElement %llu", i);
399 return ERR;
400 }
401 i++;
402 }
403
404 return 0;
405}
406
408{
410 {
411 AML_DEBUG_ERROR(ctx, "Failed to read PackageOp");
412 return ERR;
413 }
414
415 const uint8_t* start = ctx->current;
416
417 // PkgLength specifies how many elements in the package are defined, others are left uninitialized.
418 aml_pkg_length_t pkgLength;
419 if (aml_pkg_length_read(ctx, &pkgLength) == ERR)
420 {
421 AML_DEBUG_ERROR(ctx, "Failed to read PkgLength");
422 return ERR;
423 }
424
425 const uint8_t* end = start + pkgLength;
426
427 // NumElements specifies the capacity of the package.
428 uint8_t numElements;
429 if (aml_num_elements_read(ctx, &numElements) == ERR)
430 {
431 return ERR;
432 }
433
434 if (aml_package_set(out, numElements) == ERR)
435 {
436 return ERR;
437 }
438
439 if (aml_package_element_list_read(ctx, &out->package, end) == ERR)
440 {
441 aml_object_clear(out);
442 AML_DEBUG_ERROR(ctx, "Failed to read PackageElementList");
443 return ERR;
444 }
445
446 return 0;
447}
448
450{
451 if (aml_term_arg_read_integer(ctx, out) == ERR)
452 {
453 AML_DEBUG_ERROR(ctx, "Failed to read TermArg for VarNumElements");
454 return ERR;
455 }
456
457 return 0;
458}
459
461{
463 {
464 AML_DEBUG_ERROR(ctx, "Failed to read VarPackageOp");
465 return ERR;
466 }
467
468 const uint8_t* start = ctx->current;
469
470 aml_pkg_length_t pkgLength;
471 if (aml_pkg_length_read(ctx, &pkgLength) == ERR)
472 {
473 AML_DEBUG_ERROR(ctx, "Failed to read PkgLength");
474 return ERR;
475 }
476
477 const uint8_t* end = start + pkgLength;
478
479 uint64_t numElements;
480 if (aml_def_var_num_elements_read(ctx, &numElements) == ERR)
481 {
482 AML_DEBUG_ERROR(ctx, "Failed to read VarNumElements");
483 return ERR;
484 }
485
486 if (aml_package_set(out, numElements) == ERR)
487 {
488 return ERR;
489 }
490
491 if (aml_package_element_list_read(ctx, &out->package, end) == ERR)
492 {
493 aml_object_clear(out);
494 AML_DEBUG_ERROR(ctx, "Failed to read PackageElementList");
495 return ERR;
496 }
497
498 return 0;
499}
500
502{
503 aml_token_t token;
504 aml_token_peek(ctx, &token);
505
506 uint64_t result = 0;
507 switch (token.num)
508 {
509 case AML_PACKAGE_OP:
510 result = aml_def_package_read(ctx, out);
511 break;
513 result = aml_def_var_package_read(ctx, out);
514 break;
515 default:
516 result = aml_computational_data_read(ctx, out);
517 break;
518 }
519
520 if (result == ERR)
521 {
522 AML_DEBUG_ERROR(ctx, "Failed to read %s", token.props->name);
523 return ERR;
524 }
525
526 return 0;
527}
528
530{
531 // TODO: Implement ObjectReference handling... somehow. I honestly have no clue what the spec wants you to do here.
532
533 if (aml_data_object_read(ctx, out) == ERR)
534 {
535 AML_DEBUG_ERROR(ctx, "Failed to read DataObject");
536 return ERR;
537 }
538
539 return 0;
540}
static uint64_t aml_package_element_handle_name(aml_state_t *state, aml_object_t *in, aml_object_t *out)
Definition data.c:319
uint64_t aml_convert_source(aml_state_t *state, aml_object_t *src, aml_object_t **dest, aml_type_t allowedTypes)
Performs a "Implicit Source Operand Conversion" acording to the rules in section 19....
Definition convert.c:541
#define AML_DEBUG_ERROR(ctx, format,...)
Macro to simplify calling aml_debug_error() with the current function name.
Definition debug.h:30
uint64_t aml_package_element_read(aml_term_list_ctx_t *ctx, aml_object_t *out)
Read a PackageElement structure from the AML stream.
Definition data.c:345
uint64_t aml_def_package_read(aml_term_list_ctx_t *ctx, aml_object_t *out)
Reads a DefPackage structure from the AML byte stream.
Definition data.c:407
uint64_t aml_byte_data_read(aml_term_list_ctx_t *ctx, uint8_t *out)
Read a ByteData structure from the AML stream.
Definition data.c:16
uint64_t aml_data_ref_object_read(aml_term_list_ctx_t *ctx, aml_object_t *out)
Read a DataRefObject structure from the AML stream.
Definition data.c:529
uint64_t aml_qword_data_read(aml_term_list_ctx_t *ctx, uint64_t *out)
Read a QWordData structure from the AML stream.
Definition data.c:54
uint64_t aml_dword_data_read(aml_term_list_ctx_t *ctx, uint32_t *out)
Read a DWordData structure from the AML stream.
Definition data.c:42
uint64_t aml_word_data_read(aml_term_list_ctx_t *ctx, uint16_t *out)
Read a WordData structure from the AML stream.
Definition data.c:30
uint64_t aml_def_var_package_read(aml_term_list_ctx_t *ctx, aml_object_t *out)
Reads a DefVarPackage structure from the AML byte stream.
Definition data.c:460
uint64_t aml_dword_const_read(aml_term_list_ctx_t *ctx, uint32_t *out)
Read a DWordConst structure from the AML stream.
Definition data.c:88
uint64_t aml_byte_const_read(aml_term_list_ctx_t *ctx, uint8_t *out)
Read a ByteConst structure from the AML stream.
Definition data.c:66
uint64_t aml_data_object_read(aml_term_list_ctx_t *ctx, aml_object_t *out)
Read a DataObject structure from the AML stream.
Definition data.c:501
uint64_t aml_word_const_read(aml_term_list_ctx_t *ctx, uint16_t *out)
Read a WordConst structure from the AML stream.
Definition data.c:77
uint64_t aml_num_elements_read(aml_term_list_ctx_t *ctx, uint8_t *out)
Read a NumElements structure from the AML stream.
Definition data.c:304
uint64_t aml_def_var_num_elements_read(aml_term_list_ctx_t *ctx, aml_integer_t *out)
Read a VarNumElements structure from the AML stream.
Definition data.c:449
uint64_t aml_package_element_list_read(aml_term_list_ctx_t *ctx, aml_package_obj_t *package, const uint8_t *end)
Read a PackageElementList structure from the AML stream.
Definition data.c:387
uint64_t aml_const_obj_read(aml_term_list_ctx_t *ctx, aml_object_t *out)
Read a ConstObj structure from the AML stream.
Definition data.c:110
uint64_t aml_string_read(aml_term_list_ctx_t *ctx, aml_object_t *out)
Read a String structure from the AML stream.
Definition data.c:144
uint64_t aml_qword_const_read(aml_term_list_ctx_t *ctx, uint64_t *out)
Read a QWordConst structure from the AML stream.
Definition data.c:99
uint64_t aml_revision_op_read(aml_term_list_ctx_t *ctx, aml_object_t *out)
Read a RevisionOp structure from the AML stream.
Definition data.c:183
uint64_t aml_computational_data_read(aml_term_list_ctx_t *ctx, aml_object_t *out)
Read a ComputationalData structure from the AML stream.
Definition data.c:199
uint64_t aml_def_buffer_read(aml_term_list_ctx_t *ctx, aml_object_t *out)
Reads a DefBuffer structure from the AML byte stream.
Definition expression.c:296
uint64_t aml_name_string_read(aml_term_list_ctx_t *ctx, aml_name_string_t *out)
Reads the next data as a NameString structure from the AML bytecode stream.
Definition name.c:189
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_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_integer_t
AML Integer type.
Definition integer.h:20
aml_integer_t aml_integer_ones(void) PURE_FUNC
Get a mask with all bits set for the current AML integer size.
Definition integer.c:32
aml_object_t * aml_namespace_find_by_name_string(aml_namespace_overlay_t *overlay, aml_object_t *start, const aml_name_string_t *nameString)
Find an object in the namespace heirarchy by a name string.
Definition namespace.c:174
uint64_t aml_object_reference_set(aml_object_t *object, aml_object_t *target)
Set a object as an ObjectReference to the given target object.
Definition object.c:831
uint64_t aml_package_set(aml_object_t *object, uint64_t length)
Set a object as a package with the given number of elements.
Definition object.c:869
uint64_t aml_integer_set(aml_object_t *object, aml_integer_t value)
Set a object as an integer with the given value and bit width.
Definition object.c:708
uint64_t aml_string_set(aml_object_t *object, const char *str)
Set a object as a string with the given value.
Definition object.c:988
void aml_object_clear(aml_object_t *object)
Clear the data of a object, setting its type to AML_UNINITIALIZED.
Definition object.c:87
uint64_t aml_unresolved_set(aml_object_t *object, const aml_name_string_t *nameString, aml_object_t *from, aml_patch_up_resolve_callback_t callback)
Set a object as an unresolved reference with the given namestring and starting point.
Definition object.c:1135
@ AML_BUFFER_FIELD
Definition object.h:60
@ AML_PACKAGE
Definition object.h:79
@ AML_STRING
Definition object.h:83
@ AML_FIELD_UNIT
Definition object.h:64
@ AML_DATA_OBJECTS
Definition object.h:99
@ AML_INTEGER
Definition object.h:65
@ AML_BUFFER
Definition object.h:59
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_read(aml_term_list_ctx_t *ctx, aml_token_t *out)
Attempt to read a token from the AML stream.
Definition token.h:340
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_ONES_OP
Definition token.h:163
@ AML_WORD_PREFIX
Definition token.h:43
@ AML_STRING_PREFIX
Definition token.h:45
@ AML_ZERO_OP
Definition token.h:38
@ AML_BYTE_PREFIX
Definition token.h:42
@ AML_ONE_OP
Definition token.h:39
@ AML_PACKAGE_OP
Definition token.h:49
@ AML_BUFFER_OP
Definition token.h:48
@ AML_QWORD_PREFIX
Definition token.h:46
@ AML_DWORD_PREFIX
Definition token.h:44
@ AML_REVISION_OP
Definition token.h:183
@ AML_VAR_PACKAGE_OP
Definition token.h:50
@ AML_TOKEN_TYPE_NAME
Is a Name Object (section 20.2.2).
Definition token.h:226
#define AML_CURRENT_REVISION
The current revision of the AML subsystem.
Definition aml.h:46
#define LOG_ERR(format,...)
Definition log.h:89
#define ENODATA
No data available.
Definition errno.h:332
#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
__UINT32_TYPE__ uint32_t
Definition stdint.h:15
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
__UINT16_TYPE__ uint16_t
Definition stdint.h:13
A NameString structure.
Definition name.h:87
ACPI object.
Definition object.h:425
aml_package_obj_t package
Definition object.h:441
Data for a package object.
Definition object.h:337
aml_object_t ** elements
Definition object.h:339
AML State.
Definition state.h:25
aml_namespace_overlay_t overlay
Holds any named objects created during parsing.
Definition state.h:30
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 * end
Definition term.h:41
const uint8_t * current
Definition term.h:42
const char * name
Definition token.h:243
aml_token_type_t type
Definition token.h:245
Token.
Definition token.h:253
const aml_token_props_t * props
Definition token.h:256
aml_token_num_t num
Definition token.h:254