ReactOS 0.4.16-dev-1494-gd054f63
interpreter.c
Go to the documentation of this file.
11#include <uacpi/kernel_api.h>
14#include <uacpi/internal/io.h>
19#include <uacpi/internal/osi.h>
20
21#ifndef UACPI_BAREBONES_MODE
22
30};
31
35};
36
37struct item {
39 union {
46 };
47};
48
49DYNAMIC_ARRAY_WITH_INLINE_STORAGE(item_array, struct item, 8)
51
55
56 /*
57 * == 0 -> none
58 * >= 1 -> item[idx - 1]
59 */
61
63
64 const struct uacpi_op_spec *op;
65 struct item_array items;
66};
67
68DYNAMIC_ARRAY_WITH_INLINE_STORAGE(op_context_array, struct op_context, 8)
70 op_context_array, struct op_context, static
71)
72
73static struct op_context *op_context_array_one_before_last(
74 struct op_context_array *arr
75)
76{
78
79 size = op_context_array_size(arr);
80
81 if (size < 2)
82 return UACPI_NULL;
83
84 return op_context_array_at(arr, size - 2);
85}
86
92};
93
94struct code_block {
97 union {
100 };
101};
102
103DYNAMIC_ARRAY_WITH_INLINE_STORAGE(code_block_array, struct code_block, 8)
105 code_block_array, struct code_block, static
106)
107
108DYNAMIC_ARRAY_WITH_INLINE_STORAGE(held_mutexes_array, uacpi_mutex*, 8)
110 held_mutexes_array, uacpi_mutex*, static
111)
112
113static uacpi_status held_mutexes_array_push(
114 struct held_mutexes_array *arr, uacpi_mutex *mutex
115)
116{
118
119 slot = held_mutexes_array_alloc(arr);
122
123 *slot = mutex;
125 return UACPI_STATUS_OK;
126}
127
129 struct held_mutexes_array *arr, uacpi_size i
130)
131{
133
134 size = held_mutexes_array_inline_capacity(arr);
135
136 // Only the dynamic array part is affected
137 if (i >= size) {
138 i -= size;
139 size = arr->size_including_inline - size;
140 size -= i + 1;
141
143 &arr->dynamic_storage[i], &arr->dynamic_storage[i + 1],
144 size * sizeof(arr->inline_storage[0])
145 );
146
147 held_mutexes_array_pop(arr);
148 return;
149 }
150
151 size = UACPI_MIN(held_mutexes_array_inline_capacity(arr),
152 arr->size_including_inline);
153 size -= i + 1;
155 &arr->inline_storage[i], &arr->inline_storage[i + 1],
156 size * sizeof(arr->inline_storage[0])
157 );
158
159 size = held_mutexes_array_size(arr);
160 i = held_mutexes_array_inline_capacity(arr);
161
162 /*
163 * This array has dynamic storage as well, now we have to take the first
164 * dynamic item, move it to the top of inline storage, and then shift all
165 * dynamic items backward by 1 as well.
166 */
167 if (size > i) {
168 arr->inline_storage[i - 1] = arr->dynamic_storage[0];
169 size -= i + 1;
170
172 &arr->dynamic_storage[0], &arr->dynamic_storage[1],
173 size * sizeof(arr->inline_storage[0])
174 );
175 }
176
177 held_mutexes_array_pop(arr);
178}
179
183};
184
186 struct held_mutexes_array *arr, uacpi_mutex *mutex,
187 enum force_release force
188)
189{
192
193 if (uacpi_unlikely(held_mutexes_array_size(arr) == 0))
195
196 item = *held_mutexes_array_last(arr);
197
198 if (uacpi_unlikely(item->sync_level != mutex->sync_level &&
199 force != FORCE_RELEASE_YES)) {
201 "ignoring mutex @%p release due to sync level mismatch: %d vs %d\n",
202 mutex, mutex->sync_level, item->sync_level
203 );
204
205 // We still return OK because we don't want to abort because of this
206 return UACPI_STATUS_OK;
207 }
208
209 if (mutex->depth > 1 && force == FORCE_RELEASE_NO) {
211 return UACPI_STATUS_OK;
212 }
213
214 // Fast path for well-behaved AML that releases mutexes in descending order
215 if (uacpi_likely(item == mutex)) {
216 held_mutexes_array_pop(arr);
217 goto do_release;
218 }
219
220 /*
221 * The mutex being released is not the last one acquired, although we did
222 * verify that at least it has the same sync level. Anyway, now we have
223 * to search for it and then remove it from the array while shifting
224 * everything backwards.
225 */
226 i = held_mutexes_array_size(arr);
227 for (;;) {
228 item = *held_mutexes_array_at(arr, --i);
229 if (item == mutex)
230 break;
231
232 if (uacpi_unlikely(i == 0))
234 }
235
237
238do_release:
239 // This is either a force release, or depth was already 1 to begin with
240 mutex->depth = 1;
242
244 return UACPI_STATUS_OK;
245}
246
248 temp_namespace_node_array, uacpi_namespace_node*, 8)
250 temp_namespace_node_array, uacpi_namespace_node*, static
251)
252
253static uacpi_status temp_namespace_node_array_push(
254 struct temp_namespace_node_array *arr, uacpi_namespace_node *node
255)
256{
258
259 slot = temp_namespace_node_array_alloc(arr);
262
263 *slot = node;
264 return UACPI_STATUS_OK;
265}
266
269
272
273 struct op_context_array pending_ops;
274 struct code_block_array code_blocks;
275 struct temp_namespace_node_array temp_nodes;
279
281
283
284 // Only used if the method is serialized
286};
287
288static void *call_frame_cursor(struct call_frame *frame)
289{
290 return frame->method->code + frame->code_offset;
291}
292
294{
295 return frame->method->size - frame->code_offset;
296}
297
299{
300 return call_frame_code_bytes_left(frame) > 0;
301}
302
303DYNAMIC_ARRAY_WITH_INLINE_STORAGE(call_frame_array, struct call_frame, 4)
305 call_frame_array, struct call_frame, static
306)
307
308static struct call_frame *call_frame_array_one_before_last(
309 struct call_frame_array *arr
310)
311{
313
314 size = call_frame_array_size(arr);
315
316 if (size < 2)
317 return UACPI_NULL;
318
319 return call_frame_array_at(arr, size - 2);
320}
321
322// NOTE: Try to keep size under 2 pages
325 struct call_frame_array call_stack;
326 struct held_mutexes_array held_mutexes;
327
330 const struct uacpi_op_spec *cur_op;
333
335};
336
337#define AML_READ(ptr, offset) (*(((uacpi_u8*)(ptr)) + offset))
338
340 uacpi_object_name *out_name)
341{
344
345 uacpi_memcpy(&out_name->id, cursor, 4);
346 return UACPI_STATUS_OK;
347}
348
349/*
350 * -------------------------------------------------------------
351 * RootChar := ‘\’
352 * ParentPrefixChar := ‘^’
353 * ‘\’ := 0x5C
354 * ‘^’ := 0x5E
355 * ------------------------------------------------------------
356 * NameSeg := <leadnamechar namechar namechar namechar>
357 * NameString := <rootchar namepath> | <prefixpath namepath>
358 * PrefixPath := Nothing | <’^’ prefixpath>
359 * NamePath := NameSeg | DualNamePath | MultiNamePath | NullName
360 * DualNamePath := DualNamePrefix NameSeg NameSeg
361 * MultiNamePath := MultiNamePrefix SegCount NameSeg(SegCount)
362 */
363
365 struct call_frame *frame, uacpi_size offset,
366 uacpi_char **out_string, uacpi_size *out_size
367)
368{
369 uacpi_size bytes_left, prefix_bytes, nameseg_bytes = 0, namesegs;
370 uacpi_char *base_cursor, *cursor;
371 uacpi_char prev_char;
372
373 bytes_left = frame->method->size - offset;
374 cursor = (uacpi_char*)frame->method->code + offset;
375 base_cursor = cursor;
376 namesegs = 0;
377
378 prefix_bytes = 0;
379 for (;;) {
380 if (uacpi_unlikely(bytes_left == 0))
382
383 prev_char = *cursor;
384
385 switch (prev_char) {
386 case '^':
387 case '\\':
388 prefix_bytes++;
389 cursor++;
390 bytes_left--;
391 break;
392 default:
393 break;
394 }
395
396 if (prev_char != '^')
397 break;
398 }
399
400 // At least a NullName byte is expected here
401 if (uacpi_unlikely(bytes_left == 0))
403
404 namesegs = 0;
405 bytes_left--;
406 switch (*cursor++)
407 {
409 namesegs = 2;
410 break;
412 if (uacpi_unlikely(bytes_left == 0))
414
415 namesegs = *(uacpi_u8*)cursor;
416 if (uacpi_unlikely(namesegs == 0)) {
417 uacpi_error("MultiNamePrefix but SegCount is 0\n");
419 }
420
421 cursor++;
422 bytes_left--;
423 break;
424 case UACPI_NULL_NAME:
425 break;
426 default:
427 /*
428 * Might be an invalid byte, but assume single nameseg for now,
429 * the code below will validate it for us.
430 */
431 cursor--;
432 bytes_left++;
433 namesegs = 1;
434 break;
435 }
436
437 if (uacpi_unlikely((namesegs * 4) > bytes_left))
439
440 if (namesegs) {
441 // 4 chars per nameseg
442 nameseg_bytes = namesegs * 4;
443
444 // dot separator for every nameseg
445 nameseg_bytes += namesegs - 1;
446 }
447
448 *out_size = nameseg_bytes + prefix_bytes + 1;
449
450 *out_string = uacpi_kernel_alloc(*out_size);
451 if (*out_string == UACPI_NULL)
453
454 uacpi_memcpy(*out_string, base_cursor, prefix_bytes);
455
456 base_cursor = *out_string;
457 base_cursor += prefix_bytes;
458
459 while (namesegs-- > 0) {
460 uacpi_memcpy(base_cursor, cursor, 4);
461 cursor += 4;
462 base_cursor += 4;
463
464 if (namesegs)
465 *base_cursor++ = '.';
466 }
467
468 *base_cursor = '\0';
469 return UACPI_STATUS_OK;
470}
471
475};
476
478 struct call_frame *frame,
479 enum resolve_behavior behavior,
480 struct uacpi_namespace_node **out_node
481)
482{
485 uacpi_size bytes_left, namesegs = 0;
486 struct uacpi_namespace_node *parent, *cur_node = frame->cur_scope;
487 uacpi_char prev_char = 0;
488 uacpi_bool just_one_nameseg = UACPI_TRUE;
489
490 bytes_left = call_frame_code_bytes_left(frame);
491 cursor = call_frame_cursor(frame);
492
493 for (;;) {
494 if (uacpi_unlikely(bytes_left == 0))
496
497 switch (*cursor) {
498 case '\\':
499 if (prev_char == '^')
501
502 cur_node = uacpi_namespace_root();
503 break;
504 case '^':
505 // Tried to go behind root
506 if (uacpi_unlikely(cur_node == uacpi_namespace_root()))
508
509 cur_node = cur_node->parent;
510 break;
511 default:
512 break;
513 }
514
515 prev_char = *cursor;
516
517 switch (prev_char) {
518 case '^':
519 case '\\':
520 just_one_nameseg = UACPI_FALSE;
521 cursor++;
522 bytes_left--;
523 break;
524 default:
525 break;
526 }
527
528 if (prev_char != '^')
529 break;
530 }
531
532 // At least a NullName byte is expected here
533 if (uacpi_unlikely(bytes_left == 0))
535
536 bytes_left--;
537 switch (*cursor++)
538 {
540 namesegs = 2;
541 just_one_nameseg = UACPI_FALSE;
542 break;
544 if (uacpi_unlikely(bytes_left == 0))
546
547 namesegs = *cursor;
548 if (uacpi_unlikely(namesegs == 0)) {
549 uacpi_error("MultiNamePrefix but SegCount is 0\n");
551 }
552
553 cursor++;
554 bytes_left--;
555 just_one_nameseg = UACPI_FALSE;
556 break;
557 case UACPI_NULL_NAME:
559 just_one_nameseg)
561
562 goto out;
563 default:
564 /*
565 * Might be an invalid byte, but assume single nameseg for now,
566 * the code below will validate it for us.
567 */
568 cursor--;
569 bytes_left++;
570 namesegs = 1;
571 break;
572 }
573
574 if (uacpi_unlikely((namesegs * 4) > bytes_left))
576
577 for (; namesegs; cursor += 4, namesegs--) {
579
582 return ret;
583
584 parent = cur_node;
586
587 switch (behavior) {
589 if (namesegs == 1) {
590 if (cur_node) {
591 cur_node = UACPI_NULL;
593 goto out;
594 }
595
596 // Create the node and link to parent but don't install YET
598 if (uacpi_unlikely(cur_node == UACPI_NULL)) {
600 goto out;
601 }
602
603 cur_node->parent = parent;
604 }
605 break;
607 if (just_one_nameseg) {
608 while (!cur_node && parent != uacpi_namespace_root()) {
609 cur_node = parent;
610 parent = cur_node->parent;
611
613 }
614 }
615 break;
616 default:
618 }
619
620 if (cur_node == UACPI_NULL) {
622 break;
623 }
624 }
625
626out:
627 cursor += namesegs * 4;
628 frame->code_offset = cursor - frame->method->code;
629
631 uacpi_shareable_ref(cur_node);
632
633 *out_node = cur_node;
634 return ret;
635}
636
638 struct item *item)
639{
641
644 return ret;
645
646 if (!frame->method->named_objects_persist)
647 ret = temp_namespace_node_array_push(&frame->temp_nodes, item->node);
648
651
652 return ret;
653}
654
655static uacpi_u8 peek_next_op(struct call_frame *frame, uacpi_aml_op *out_op)
656{
658 uacpi_size bytes_left;
659 uacpi_u8 length = 0;
661 struct code_block *block;
662
663 block = code_block_array_last(&frame->code_blocks);
664 bytes_left = block->end - frame->code_offset;
665 if (bytes_left == 0)
666 return 0;
667
668 cursor = call_frame_cursor(frame);
669
670 op = AML_READ(cursor, length++);
671 if (op == UACPI_EXT_PREFIX) {
672 if (uacpi_unlikely(bytes_left < 2))
673 return 0;
674
675 op <<= 8;
676 op |= AML_READ(cursor, length++);
677 }
678
679 *out_op = op;
680 return length;
681}
682
684{
687
688 length = peek_next_op(ctx->cur_frame, &op);
689 if (uacpi_unlikely(length == 0))
691
692 ctx->cur_frame->code_offset += length;
693 g_uacpi_rt_ctx.opcodes_executed++;
694
695 ctx->cur_op = uacpi_get_op_spec(op);
696 if (uacpi_unlikely(ctx->cur_op->properties & UACPI_OP_PROPERTY_RESERVED)) {
698 "invalid opcode '%s' encountered in bytestream\n",
699 ctx->cur_op->name
700 );
702 }
703
704 return UACPI_STATUS_OK;
705}
706
708{
709 struct package_length *pkg;
710 uacpi_u8 *src;
711 uacpi_object *dst, *declared_size;
712 uacpi_u32 buffer_size, init_size, aml_offset;
713 struct op_context *op_ctx = ctx->cur_op_ctx;
714
715 aml_offset = item_array_at(&op_ctx->items, 2)->immediate;
716 src = ctx->cur_frame->method->code;
717 src += aml_offset;
718
719 pkg = &item_array_at(&op_ctx->items, 0)->pkg;
720 init_size = pkg->end - aml_offset;
721
722 // TODO: do package bounds checking at parse time
723 if (uacpi_unlikely(pkg->end > ctx->cur_frame->method->size))
725
726 declared_size = item_array_at(&op_ctx->items, 1)->obj;
727
728 if (uacpi_unlikely(declared_size->integer > 0xE0000000)) {
730 "buffer is too large (%"UACPI_PRIu64"), assuming corrupted "
731 "bytestream\n", UACPI_FMT64(declared_size->integer)
732 );
734 }
735
736 if (uacpi_unlikely(declared_size->integer == 0)) {
737 uacpi_error("attempted to create an empty buffer\n");
739 }
740
741 buffer_size = declared_size->integer;
742 if (uacpi_unlikely(init_size > buffer_size)) {
744 "too many buffer initializers: %u (size is %u)\n",
745 init_size, buffer_size
746 );
748 }
749
750 dst = item_array_at(&op_ctx->items, 3)->obj;
751 dst->buffer->data = uacpi_kernel_alloc(buffer_size);
752 if (uacpi_unlikely(dst->buffer->data == UACPI_NULL))
754 dst->buffer->size = buffer_size;
755
756 uacpi_memcpy_zerout(dst->buffer->data, src, buffer_size, init_size);
757 return UACPI_STATUS_OK;
758}
759
761{
762 struct call_frame *frame = ctx->cur_frame;
764
766 uacpi_size length, max_bytes;
767
768 obj = item_array_last(&ctx->cur_op_ctx->items)->obj;
769 string = call_frame_cursor(frame);
770
771 // TODO: sanitize string for valid UTF-8
772 max_bytes = call_frame_code_bytes_left(frame);
773 length = uacpi_strnlen(string, max_bytes);
774
775 if (uacpi_unlikely((length == max_bytes) || (string[length++] != 0x00)))
777
778 obj->buffer->text = uacpi_kernel_alloc(length);
779 if (uacpi_unlikely(obj->buffer->text == UACPI_NULL))
781
782 uacpi_memcpy(obj->buffer->text, string, length);
783 obj->buffer->size = length;
784 frame->code_offset += length;
785 return UACPI_STATUS_OK;
786}
787
789{
790 struct op_context *op_ctx = ctx->cur_op_ctx;
791 uacpi_package *package;
792 uacpi_u32 num_elements, num_defined_elements, i;
793
794 /*
795 * Layout of items here:
796 * [0] -> Package length, not interesting
797 * [1] -> Immediate or integer object, depending on PackageOp/VarPackageOp
798 * [2..N-2] -> AML pc+Package element pairs
799 * [N-1] -> The resulting package object that we're constructing
800 */
801 package = item_array_last(&op_ctx->items)->obj->package;
802
803 // 1. Detect how many elements we have, do sanity checking
804 if (op_ctx->op->code == UACPI_AML_OP_VarPackageOp) {
805 uacpi_object *var_num_elements;
806
807 var_num_elements = item_array_at(&op_ctx->items, 1)->obj;
808 if (uacpi_unlikely(var_num_elements->integer > 0xE0000000)) {
810 "package is too large (%"UACPI_PRIu64"), assuming "
811 "corrupted bytestream\n", UACPI_FMT64(var_num_elements->integer)
812 );
814 }
815 num_elements = var_num_elements->integer;
816 } else {
817 num_elements = item_array_at(&op_ctx->items, 1)->immediate;
818 }
819
820 num_defined_elements = (item_array_size(&op_ctx->items) - 3) / 2;
821 if (uacpi_unlikely(num_defined_elements > num_elements)) {
823 "too many package initializers: %u, truncating to %u\n",
824 num_defined_elements, num_elements
825 );
826
827 num_defined_elements = num_elements;
828 }
829
830 // 2. Create every object in the package, start as uninitialized
831 if (uacpi_unlikely(!uacpi_package_fill(package, num_elements,
834
835 // 3. Go through every defined object and copy it into the package
836 for (i = 0; i < num_defined_elements; ++i) {
837 uacpi_size base_pkg_index;
839 struct item *item;
841
842 base_pkg_index = (i * 2) + 2;
843 item = item_array_at(&op_ctx->items, base_pkg_index + 1);
844 obj = item->obj;
845
846 if (obj != UACPI_NULL && obj->type == UACPI_OBJECT_REFERENCE) {
847 /*
848 * For named objects we don't actually need the object itself, but
849 * simply the path to it. Often times objects referenced by the
850 * package are not defined until later so it's not possible to
851 * resolve them. For uniformity and to follow the behavior of NT,
852 * simply convert the name string to a path string object to be
853 * resolved later when actually needed.
854 */
855 if (obj->flags == UACPI_REFERENCE_KIND_NAMED) {
858 obj = UACPI_NULL;
859 } else {
861 }
862 }
863
864 if (obj == UACPI_NULL) {
867
871
873 ctx->cur_frame,
874 item_array_at(&op_ctx->items, base_pkg_index)->immediate,
875 &path, &length
876 );
878 return ret;
879
881 obj->buffer->text = path;
882 obj->buffer->size = length;
883
884 item->obj = obj;
886 }
887
888 ret = uacpi_object_assign(package->objects[i], obj,
891 return ret;
892 }
893
894 return UACPI_STATUS_OK;
895}
896
898{
899 return g_uacpi_rt_ctx.is_rev1 ? 4 : 8;
900}
901
903 uacpi_object *obj, uacpi_data_view *out_buf, uacpi_bool include_null
904)
905{
906 switch (obj->type) {
908 out_buf->length = sizeof_int();
909 out_buf->data = &obj->integer;
910 break;
912 out_buf->length = obj->buffer->size;
913 if (out_buf->length && !include_null)
914 out_buf->length--;
915
916 out_buf->text = obj->buffer->text;
917 break;
919 if (obj->buffer->size == 0) {
920 out_buf->bytes = UACPI_NULL;
921 out_buf->length = 0;
922 break;
923 }
924
925 out_buf->length = obj->buffer->size;
926 out_buf->bytes = obj->buffer->data;
927 break;
930 default:
932 }
933
934 return UACPI_STATUS_OK;
935}
936
938{
939 uacpi_u8 *out_cursor;
940
941 out_cursor = buf_idx->buffer->data;
942 out_cursor += buf_idx->idx;
943
944 return out_cursor;
945}
946
948 uacpi_data_view *src_buf)
949{
951 1, src_buf->length);
952}
953
954/*
955 * The word "implicit cast" here is only because it's called that in
956 * the specification. In reality, we just copy one buffer to another
957 * because that's what NT does.
958 */
961)
962{
964 uacpi_data_view src_buf;
965
968 goto out_bad_cast;
969
970 switch (dst->type) {
973 case UACPI_OBJECT_BUFFER: {
974 uacpi_data_view dst_buf;
975
978 goto out_bad_cast;
979
981 dst_buf.bytes, src_buf.bytes, dst_buf.length, src_buf.length
982 );
983 break;
984 }
985
988 &dst->buffer_field, src_buf.bytes, src_buf.length
989 );
990 break;
991
994 dst->field_unit, src_buf.bytes, src_buf.length,
995 wtr_response
996 );
997
999 write_buffer_index(&dst->buffer_index, &src_buf);
1000 break;
1001
1002 default:
1004 goto out_bad_cast;
1005 }
1006
1007 return ret;
1008
1009out_bad_cast:
1011 "attempted to perform an invalid implicit cast (%s -> %s)\n",
1014 );
1015 return ret;
1016}
1017
1021};
1022
1024 struct execution_context *ctx,
1026)
1027{
1028 uacpi_object **src;
1029 struct item *dst;
1030 enum uacpi_reference_kind kind;
1031
1032 if (type == ARGX) {
1033 src = &ctx->cur_frame->args[idx];
1035 } else {
1036 src = &ctx->cur_frame->locals[idx];
1038 }
1039
1040 if (*src == UACPI_NULL) {
1041 uacpi_object *default_value;
1042
1044 if (uacpi_unlikely(default_value == UACPI_NULL))
1046
1047 *src = uacpi_create_internal_reference(kind, default_value);
1048 if (uacpi_unlikely(*src == UACPI_NULL))
1050
1051 uacpi_object_unref(default_value);
1052 }
1053
1054 dst = item_array_last(&ctx->cur_op_ctx->items);
1055 dst->obj = *src;
1056 dst->type = ITEM_OBJECT;
1057 uacpi_object_ref(dst->obj);
1058
1059 return UACPI_STATUS_OK;
1060}
1061
1063{
1065 struct op_context *op_ctx = ctx->cur_op_ctx;
1066
1067 idx = op_ctx->op->code - UACPI_AML_OP_Local0Op;
1069}
1070
1072{
1074 struct op_context *op_ctx = ctx->cur_op_ctx;
1075
1076 idx = op_ctx->op->code - UACPI_AML_OP_Arg0Op;
1077 return handle_arg_or_local(ctx, idx, ARGX);
1078}
1079
1081{
1082 struct uacpi_namespace_node *src;
1083 struct item *dst;
1084
1085 src = item_array_at(&ctx->cur_op_ctx->items, 0)->node;
1086 dst = item_array_at(&ctx->cur_op_ctx->items, 1);
1087
1088 dst->obj = src->object;
1089 dst->type = ITEM_OBJECT;
1090 uacpi_object_ref(dst->obj);
1091
1092 return UACPI_STATUS_OK;
1093}
1094
1096{
1098
1099 src = item_array_at(&ctx->cur_op_ctx->items, 0)->node;
1100 dst = item_array_at(&ctx->cur_op_ctx->items, 1)->node;
1101
1102 dst->object = src->object;
1104 uacpi_object_ref(dst->object);
1105
1106 return UACPI_STATUS_OK;
1107}
1108
1110{
1113 uacpi_operation_region *op_region;
1114 uacpi_u64 region_end;
1115
1116 node = item_array_at(&ctx->cur_op_ctx->items, 0)->node;
1117 obj = item_array_at(&ctx->cur_op_ctx->items, 4)->obj;
1118 op_region = obj->op_region;
1119
1120 op_region->space = item_array_at(&ctx->cur_op_ctx->items, 1)->immediate;
1121 op_region->offset = item_array_at(&ctx->cur_op_ctx->items, 2)->obj->integer;
1122 op_region->length = item_array_at(&ctx->cur_op_ctx->items, 3)->obj->integer;
1123 region_end = op_region->offset + op_region->length;
1124
1125 if (uacpi_unlikely(op_region->length == 0)) {
1126 // Don't abort here, as long as it's never accessed we don't care
1127 uacpi_warn("unusable/empty operation region %.4s\n", node->name.text);
1128 } else if (uacpi_unlikely(op_region->offset > region_end)) {
1130 "invalid operation region %.4s bounds: offset=0x%"UACPI_PRIX64
1131 " length=0x%"UACPI_PRIX64"\n", node->name.text,
1132 UACPI_FMT64(op_region->offset), UACPI_FMT64(op_region->length)
1133 );
1135 }
1136
1137 if (op_region->space == UACPI_ADDRESS_SPACE_PCC && op_region->offset > 255) {
1138 uacpi_warn(
1139 "invalid PCC operation region %.4s subspace %"UACPI_PRIX64"\n",
1140 node->name.text, UACPI_FMT64(op_region->offset)
1141 );
1142 }
1143
1146 );
1147 if (uacpi_unlikely(node->object == UACPI_NULL))
1149
1151 return UACPI_STATUS_OK;
1152}
1153
1155 const uacpi_char *opcode, const uacpi_char *arg,
1157)
1158{
1159 uacpi_error("%s: invalid %s '%s'\n", opcode, arg, str->text);
1161}
1162
1164 const uacpi_char *opcode, struct uacpi_table_identifiers *id,
1166)
1167{
1169 "%s: unable to find table '%.4s' (OEM ID '%.6s', "
1170 "OEM Table ID '%.8s'): %s\n",
1171 opcode, id->signature.text, id->oemid, id->oem_table_id,
1173 );
1174}
1175
1177 const uacpi_char *opcode,
1178 struct uacpi_table_identifiers *out_id,
1180 uacpi_buffer *oem_table_id
1181)
1182{
1183 if (uacpi_unlikely(signature->size != (sizeof(uacpi_object_name) + 1)))
1184 return table_id_error(opcode, "SignatureString", signature);
1185
1186 uacpi_memcpy(out_id->signature.text, signature->text,
1187 sizeof(uacpi_object_name));
1188
1189 if (uacpi_unlikely(oem_id->size > (sizeof(out_id->oemid) + 1)))
1190 return table_id_error(opcode, "OemIDString", oem_id);
1191
1193 out_id->oemid, oem_id->text,
1194 sizeof(out_id->oemid), oem_id->size ? oem_id->size - 1 : 0
1195 );
1196
1197 if (uacpi_unlikely(oem_table_id->size > (sizeof(out_id->oem_table_id) + 1)))
1198 return table_id_error(opcode, "OemTableIDString", oem_table_id);
1199
1201 out_id->oem_table_id, oem_table_id->text,
1202 sizeof(out_id->oem_table_id),
1203 oem_table_id->size ? oem_table_id->size - 1 : 0
1204 );
1205
1206 return UACPI_STATUS_OK;
1207}
1208
1210{
1212 struct item_array *items = &ctx->cur_op_ctx->items;
1213 struct uacpi_table_identifiers table_id;
1217 uacpi_operation_region *op_region;
1218
1219 node = item_array_at(items, 0)->node;
1220
1222 "DataTableRegion", &table_id,
1223 item_array_at(items, 1)->obj->buffer,
1224 item_array_at(items, 2)->obj->buffer,
1225 item_array_at(items, 3)->obj->buffer
1226 );
1228 return ret;
1229
1230 ret = uacpi_table_find(&table_id, &table);
1232 report_table_id_find_error("DataTableRegion", &table_id, ret);
1233 return ret;
1234 }
1235
1236 obj = item_array_at(items, 4)->obj;
1237 op_region = obj->op_region;
1239 op_region->offset = table.virt_addr;
1240 op_region->length = table.hdr->length;
1241 op_region->table_idx = table.index;
1242
1245 );
1246 if (uacpi_unlikely(node->object == UACPI_NULL))
1248
1250 return UACPI_STATUS_OK;
1251}
1252
1254{
1255 return cause != UACPI_TABLE_LOAD_CAUSE_INIT;
1256}
1257
1259 void *ptr, enum uacpi_table_load_cause cause, uacpi_control_method *in_method
1260)
1261{
1262 struct acpi_dsdt *dsdt = ptr;
1263 enum uacpi_log_level log_level = UACPI_LOG_TRACE;
1264 const uacpi_char *log_prefix = "load of";
1265
1266 if (is_dynamic_table_load(cause)) {
1267 log_prefix = cause == UACPI_TABLE_LOAD_CAUSE_HOST ?
1268 "host-invoked load of" : "dynamic load of";
1269 log_level = UACPI_LOG_INFO;
1270 }
1271
1273 log_level, "%s "UACPI_PRI_TBL_HDR"\n",
1274 log_prefix, UACPI_FMT_TBL_HDR(&dsdt->hdr)
1275 );
1276
1277 in_method->code = dsdt->definition_block;
1278 in_method->size = dsdt->hdr.length - sizeof(dsdt->hdr);
1279 in_method->named_objects_persist = UACPI_TRUE;
1280}
1281
1283 uacpi_namespace_node *parent, struct acpi_sdt_hdr *tbl,
1284 enum uacpi_table_load_cause cause
1285)
1286{
1287 struct uacpi_control_method method = { 0 };
1289
1290 prepare_table_load(tbl, cause, &method);
1291
1294 return ret;
1295
1296 if (is_dynamic_table_load(cause))
1298
1299 return ret;
1300}
1301
1303{
1305 struct item_array *items = &ctx->cur_op_ctx->items;
1306 struct item *root_node_item;
1307 struct uacpi_table_identifiers table_id;
1309 uacpi_buffer *root_path, *param_path;
1311 uacpi_namespace_node *root_node, *param_node = UACPI_NULL;
1312
1313 /*
1314 * If we already have the last true/false object loaded, this is a second
1315 * invocation of this handler. For the second invocation we want to detect
1316 * new AML GPE handlers that might've been loaded, as well as potentially
1317 * remove the target.
1318 */
1319 if (item_array_size(items) == 12) {
1321
1322 idx = item_array_at(items, 2)->immediate;
1323 uacpi_table_unref(&(struct uacpi_table) { .index = idx });
1324
1325 /*
1326 * If this load failed, remove the target that was provided via
1327 * ParameterPathString so that it doesn't get stored to.
1328 */
1329 if (uacpi_unlikely(item_array_at(items, 11)->obj->integer == 0)) {
1331
1332 target = item_array_at(items, 3)->obj;
1333 if (target != UACPI_NULL) {
1335 item_array_at(items, 3)->obj = UACPI_NULL;
1336 }
1337
1338 return UACPI_STATUS_OK;
1339 }
1340
1342 return UACPI_STATUS_OK;
1343 }
1344
1346 "LoadTable", &table_id,
1347 item_array_at(items, 5)->obj->buffer,
1348 item_array_at(items, 6)->obj->buffer,
1349 item_array_at(items, 7)->obj->buffer
1350 );
1352 return ret;
1353
1354 root_path = item_array_at(items, 8)->obj->buffer;
1355 param_path = item_array_at(items, 9)->obj->buffer;
1356 root_node_item = item_array_at(items, 0);
1357
1358 if (root_path->size > 1) {
1360 ctx->cur_frame->cur_scope, root_path->text, UACPI_SHOULD_LOCK_NO,
1362 &root_node
1363 );
1365 table_id_error("LoadTable", "RootPathString", root_path);
1368 return ret;
1369 }
1370 } else {
1371 root_node = uacpi_namespace_root();
1372 }
1373
1374 root_node_item->node = root_node;
1375 root_node_item->type = ITEM_NAMESPACE_NODE;
1376 uacpi_shareable_ref(root_node);
1377
1378 if (param_path->size > 1) {
1379 struct item *param_item;
1380
1382 root_node, param_path->text, UACPI_SHOULD_LOCK_NO,
1384 &param_node
1385 );
1387 table_id_error("LoadTable", "ParameterPathString", root_path);
1390 return ret;
1391 }
1392
1393 param_item = item_array_at(items, 3);
1394 param_item->obj = param_node->object;
1395 uacpi_object_ref(param_item->obj);
1396 param_item->type = ITEM_OBJECT;
1397 }
1398
1399 ret = uacpi_table_find(&table_id, &table);
1401 report_table_id_find_error("LoadTable", &table_id, ret);
1402 return ret;
1403 }
1405
1406 item_array_at(items, 2)->immediate = table.index;
1407 method = item_array_at(items, 1)->obj->method;
1409
1410 return UACPI_STATUS_OK;
1411}
1412
1414{
1416 struct item_array *items = &ctx->cur_op_ctx->items;
1420 struct acpi_sdt_hdr *src_table = UACPI_NULL;
1421 void *table_buffer;
1422 uacpi_size declared_size;
1423 uacpi_bool unmap_src = UACPI_FALSE;
1424
1425 /*
1426 * If we already have the last true/false object loaded, this is a second
1427 * invocation of this handler. For the second invocation we simply want to
1428 * detect new AML GPE handlers that might've been loaded.
1429 * We do this only if table load was successful though.
1430 */
1431 if (item_array_size(items) == 5) {
1432 if (item_array_at(items, 4)->obj->integer != 0)
1434 return UACPI_STATUS_OK;
1435 }
1436
1437 src = item_array_at(items, 2)->obj;
1438
1439 switch (src->type) {
1441 uacpi_operation_region *op_region;
1442
1443 op_region = src->op_region;
1444 if (uacpi_unlikely(
1446 )) {
1447 uacpi_error("Load: operation region is not SystemMemory\n");
1448 goto error_out;
1449 }
1450
1451 if (uacpi_unlikely(op_region->length < sizeof(struct acpi_sdt_hdr))) {
1453 "Load: operation region is too small: %"UACPI_PRIu64"\n",
1454 UACPI_FMT64(op_region->length)
1455 );
1456 goto error_out;
1457 }
1458
1459 src_table = uacpi_kernel_map(op_region->offset, op_region->length);
1460 if (uacpi_unlikely(src_table == UACPI_NULL)) {
1462 "Load: failed to map operation region "
1463 "0x%016"UACPI_PRIX64" -> 0x%016"UACPI_PRIX64"\n",
1464 UACPI_FMT64(op_region->offset),
1465 UACPI_FMT64(op_region->offset + op_region->length)
1466 );
1467 goto error_out;
1468 }
1469
1470 unmap_src = UACPI_TRUE;
1471 declared_size = op_region->length;
1472 break;
1473 }
1474
1475 case UACPI_OBJECT_BUFFER: {
1477
1478 buffer = src->buffer;
1479 if (buffer->size < sizeof(struct acpi_sdt_hdr)) {
1481 "Load: buffer is too small: %zu\n",
1482 buffer->size
1483 );
1484 goto error_out;
1485 }
1486
1487 src_table = buffer->data;
1488 declared_size = buffer->size;
1489 break;
1490 }
1491
1492 default:
1494 "Load: invalid argument '%s', expected "
1495 "Buffer/Field/OperationRegion\n",
1497 );
1498 goto error_out;
1499 }
1500
1501 if (uacpi_unlikely(src_table->length > declared_size)) {
1503 "Load: table size %u is larger than the declared size %zu\n",
1504 src_table->length, declared_size
1505 );
1506 goto error_out;
1507 }
1508
1509 if (uacpi_unlikely(src_table->length < sizeof(struct acpi_sdt_hdr))) {
1510 uacpi_error("Load: table size %u is too small\n", src_table->length);
1511 goto error_out;
1512 }
1513
1514 table_buffer = uacpi_kernel_alloc(src_table->length);
1515 if (uacpi_unlikely(table_buffer == UACPI_NULL))
1516 goto error_out;
1517
1518 uacpi_memcpy(table_buffer, src_table, src_table->length);
1519
1520 if (unmap_src) {
1521 uacpi_kernel_unmap(src_table, declared_size);
1522 unmap_src = UACPI_FALSE;
1523 }
1524
1527 );
1529 uacpi_free(table_buffer, src_table->length);
1530
1532 goto error_out;
1533 }
1535
1536 item_array_at(items, 0)->node = uacpi_namespace_root();
1537
1538 method = item_array_at(items, 1)->obj->method;
1540
1541 return UACPI_STATUS_OK;
1542
1543error_out:
1544 if (unmap_src && src_table)
1545 uacpi_kernel_unmap(src_table, declared_size);
1546 return UACPI_STATUS_OK;
1547}
1548
1550{
1552
1555 return ret;
1556
1557 ret = do_load_table(uacpi_namespace_root(), tbl, cause);
1558
1560 return ret;
1561}
1562
1564{
1565 struct package_length *pkg = &item->pkg;
1566 return pkg->end - pkg->begin;
1567}
1568
1574};
1575
1577 uacpi_field_unit **out_field)
1578{
1580
1582 if (obj->type != UACPI_OBJECT_FIELD_UNIT) {
1584 "invalid argument: '%.4s' is not a field unit (%s)\n",
1585 node->name.text, uacpi_object_type_to_string(obj->type)
1586 );
1588 }
1589
1590 *out_field = obj->field_unit;
1591 return UACPI_STATUS_OK;
1592}
1593
1595 uacpi_namespace_node **out_node)
1596{
1598
1600 if (obj->type != UACPI_OBJECT_OPERATION_REGION) {
1602 "invalid argument: '%.4s' is not an operation region (%s)\n",
1603 node->name.text, uacpi_object_type_to_string(obj->type)
1604 );
1606 }
1607
1608 *out_node = node;
1609 return UACPI_STATUS_OK;
1610}
1611
1613{
1615 struct op_context *op_ctx = ctx->cur_op_ctx;
1617 uacpi_object *obj, *connection_obj = UACPI_NULL;
1618 struct field_specific_data field_data = { 0 };
1619 uacpi_size i = 1, bit_offset = 0;
1620 uacpi_u32 length, pin_offset = 0;
1621
1622 uacpi_u8 raw_value, access_type, lock_rule, update_rule;
1623 uacpi_u8 access_attrib = 0, access_length = 0;
1624
1625 switch (op_ctx->op->code) {
1626 case UACPI_AML_OP_FieldOp:
1627 node = item_array_at(&op_ctx->items, i++)->node;
1628 ret = ensure_is_an_op_region(node, &field_data.region);
1630 return ret;
1631 break;
1632
1633 case UACPI_AML_OP_BankFieldOp:
1634 node = item_array_at(&op_ctx->items, i++)->node;
1635 ret = ensure_is_an_op_region(node, &field_data.region);
1637 return ret;
1638
1639 node = item_array_at(&op_ctx->items, i++)->node;
1640 ret = ensure_is_a_field_unit(node, &field_data.field0);
1642 return ret;
1643
1644 field_data.value = item_array_at(&op_ctx->items, i++)->obj->integer;
1645 break;
1646
1647 case UACPI_AML_OP_IndexFieldOp:
1648 node = item_array_at(&op_ctx->items, i++)->node;
1649 ret = ensure_is_a_field_unit(node, &field_data.field0);
1651 return ret;
1652
1653 node = item_array_at(&op_ctx->items, i++)->node;
1654 ret = ensure_is_a_field_unit(node, &field_data.field1);
1656 return ret;
1657 break;
1658
1659 default:
1661 }
1662
1663 /*
1664 * ByteData
1665 * bit 0-3: AccessType
1666 * 0 AnyAcc
1667 * 1 ByteAcc
1668 * 2 WordAcc
1669 * 3 DWordAcc
1670 * 4 QWordAcc
1671 * 5 BufferAcc
1672 * 6 Reserved
1673 * 7-15 Reserved
1674 * bit 4: LockRule
1675 * 0 NoLock
1676 * 1 Lock
1677 * bit 5-6: UpdateRule
1678 * 0 Preserve
1679 * 1 WriteAsOnes
1680 * 2 WriteAsZeros
1681 * bit 7: Reserved (must be 0)
1682 */
1683 raw_value = item_array_at(&op_ctx->items, i++)->immediate;
1684 access_type = (raw_value >> 0) & 0b1111;
1685 lock_rule = (raw_value >> 4) & 0b1;
1686 update_rule = (raw_value >> 5) & 0b11;
1687
1688 while (i < item_array_size(&op_ctx->items)) {
1689 struct item *item;
1690 item = item_array_at(&op_ctx->items, i++);
1691
1692 // An actual field object
1693 if (item->type == ITEM_NAMESPACE_NODE) {
1695
1696 length = get_field_length(item_array_at(&op_ctx->items, i++));
1697 node = item->node;
1698
1699 obj = item_array_at(&op_ctx->items, i++)->obj;
1700 field = obj->field_unit;
1701
1702 field->update_rule = update_rule;
1703 field->lock_rule = lock_rule;
1704 field->attributes = access_attrib;
1705 field->access_length = access_length;
1706
1707 /*
1708 * 0 AnyAcc
1709 * 1 ByteAcc
1710 * 2 WordAcc
1711 * 3 DWordAcc
1712 * 4 QWordAcc
1713 * 5 BufferAcc
1714 * 6 Reserved
1715 * 7-15 Reserved
1716 */
1717 switch (access_type) {
1718 case 0:
1719 // TODO: optimize to calculate best access strategy
1721 case 1:
1722 case 5:
1723 field->access_width_bytes = 1;
1724 break;
1725 case 2:
1726 field->access_width_bytes = 2;
1727 break;
1728 case 3:
1729 field->access_width_bytes = 4;
1730 break;
1731 case 4:
1732 field->access_width_bytes = 8;
1733 break;
1734 default:
1735 uacpi_error("invalid field '%.4s' access type %d\n",
1736 node->name.text, access_type);
1738 }
1739
1740 field->bit_length = length;
1741 field->pin_offset = pin_offset;
1742
1743 // FIXME: overflow, OOB, etc checks
1744 field->byte_offset = UACPI_ALIGN_DOWN(
1745 bit_offset / 8,
1746 field->access_width_bytes,
1747 uacpi_u32
1748 );
1749
1750 field->bit_offset_within_first_byte = bit_offset;
1751 field->bit_offset_within_first_byte =
1752 bit_offset & ((field->access_width_bytes * 8) - 1);
1753
1754 switch (op_ctx->op->code) {
1755 case UACPI_AML_OP_FieldOp:
1756 field->region = field_data.region;
1757 uacpi_shareable_ref(field->region);
1758
1760 break;
1761
1762 case UACPI_AML_OP_BankFieldOp:
1763 field->bank_region = field_data.region;
1764 uacpi_shareable_ref(field->bank_region);
1765
1766 field->bank_selection = field_data.field0;
1767 uacpi_shareable_ref(field->bank_selection);
1768
1769 field->bank_value = field_data.value;
1771 break;
1772
1773 case UACPI_AML_OP_IndexFieldOp:
1774 field->index = field_data.field0;
1775 uacpi_shareable_ref(field->index);
1776
1777 field->data = field_data.field1;
1779
1781 break;
1782
1783 default:
1785 }
1786
1787 field->connection = connection_obj;
1788 if (field->connection)
1789 uacpi_object_ref(field->connection);
1790
1793 );
1794 if (uacpi_unlikely(node->object == UACPI_NULL))
1796
1797 ret = do_install_node_item(ctx->cur_frame, item);
1799 return ret;
1800
1801 bit_offset += length;
1802 pin_offset += length;
1803 continue;
1804 }
1805
1806 // All other stuff
1807 switch (item->immediate) {
1808 // ReservedField := 0x00 PkgLength
1809 case 0x00:
1810 length = get_field_length(item_array_at(&op_ctx->items, i++));
1811 bit_offset += length;
1812 pin_offset += length;
1813 break;
1814
1815 // AccessField := 0x01 AccessType AccessAttrib
1816 // ExtendedAccessField := 0x03 AccessType ExtendedAccessAttrib AccessLength
1817 case 0x01:
1818 case 0x03:
1819 raw_value = item_array_at(&op_ctx->items, i++)->immediate;
1820
1821 access_type = raw_value & 0b1111;
1822 access_attrib = (raw_value >> 6) & 0b11;
1823
1824 raw_value = item_array_at(&op_ctx->items, i++)->immediate;
1825
1826 /*
1827 * Bits 7:6
1828 * 0 = AccessAttrib = Normal Access Attributes
1829 * 1 = AccessAttrib = AttribBytes (x)
1830 * 2 = AccessAttrib = AttribRawBytes (x)
1831 * 3 = AccessAttrib = AttribRawProcessBytes (x)
1832 * x is encoded as bits 0:7 of the AccessAttrib byte.
1833 */
1834 if (access_attrib) {
1835 switch (access_attrib) {
1836 case 1:
1837 access_attrib = UACPI_ACCESS_ATTRIBUTE_BYTES;
1838 break;
1839 case 2:
1840 access_attrib = UACPI_ACCESS_ATTRIBUTE_RAW_BYTES;
1841 break;
1842 case 3:
1844 break;
1845 }
1846
1847 access_length = raw_value;
1848 } else { // Normal access attributes
1849 access_attrib = raw_value;
1850 }
1851
1852 if (item->immediate == 3)
1853 access_length = item_array_at(&op_ctx->items, i++)->immediate;
1854 break;
1855
1856 // ConnectField := <0x02 NameString> | <0x02 BufferData>
1857 case 0x02:
1858 connection_obj = item_array_at(&op_ctx->items, i++)->obj;
1859 pin_offset = 0;
1860 break;
1861
1862 default:
1864 }
1865 }
1866
1867 return UACPI_STATUS_OK;
1868}
1869
1871{
1872 if (!g_uacpi_rt_ctx.is_rev1)
1873 return;
1874
1875 obj->integer &= 0xFFFFFFFF;
1876}
1877
1878static uacpi_u64 ones(void)
1879{
1880 return g_uacpi_rt_ctx.is_rev1 ? 0xFFFFFFFF : 0xFFFFFFFFFFFFFFFF;
1881}
1882
1884 uacpi_object **out_operand)
1885{
1887
1888 // Check if we're targeting the previous call frame
1889 depth = call_frame_array_size(&ctx->call_stack);
1890 if (depth > 1) {
1891 struct op_context *op_ctx;
1892 struct call_frame *frame;
1893
1894 frame = call_frame_array_at(&ctx->call_stack, depth - 2);
1895 depth = op_context_array_size(&frame->pending_ops);
1896
1897 // Ok, no one wants the return value at call site. Discard it.
1898 if (!depth) {
1899 *out_operand = UACPI_NULL;
1900 return UACPI_STATUS_OK;
1901 }
1902
1903 op_ctx = op_context_array_at(&frame->pending_ops, depth - 1);
1904
1905 /*
1906 * Prevent the table being dynamically loaded from attempting to return
1907 * a value to the caller. This is unlikely to be ever encountered in the
1908 * wild, but we should still guard against the possibility.
1909 */
1910 if (uacpi_unlikely(op_ctx->op->code == UACPI_AML_OP_LoadOp ||
1911 op_ctx->op->code == UACPI_AML_OP_LoadTableOp)) {
1912 *out_operand = UACPI_NULL;
1913 return UACPI_STATUS_OK;
1914 }
1915
1916 *out_operand = item_array_last(&op_ctx->items)->obj;
1917 return UACPI_STATUS_OK;
1918 }
1919
1921}
1922
1924 uacpi_object **out_obj)
1925{
1927
1928 ret = method_get_ret_target(ctx, out_obj);
1929 if (ret == UACPI_STATUS_NOT_FOUND) {
1930 *out_obj = ctx->ret;
1931 return UACPI_STATUS_OK;
1932 }
1933 if (ret != UACPI_STATUS_OK || *out_obj == UACPI_NULL)
1934 return ret;
1935
1936 *out_obj = uacpi_unwrap_internal_reference(*out_obj);
1937 return UACPI_STATUS_OK;
1938}
1939
1940static struct code_block *find_last_block(struct code_block_array *blocks,
1941 enum code_block_type type)
1942{
1943 uacpi_size i;
1944
1945 i = code_block_array_size(blocks);
1946 while (i-- > 0) {
1947 struct code_block *block;
1948
1949 block = code_block_array_at(blocks, i);
1950 if (block->type == type)
1951 return block;
1952 }
1953
1954 return UACPI_NULL;
1955}
1956
1957static void update_scope(struct call_frame *frame)
1958{
1959 struct code_block *block;
1960
1962 if (block == UACPI_NULL) {
1964 return;
1965 }
1966
1967 frame->cur_scope = block->node;
1968}
1969
1971{
1972 struct call_frame *cur_frame = ctx->cur_frame;
1973 struct op_context *op_ctx = ctx->cur_op_ctx;
1974 struct package_length *pkg;
1975 struct code_block *block;
1976
1977 block = code_block_array_alloc(&cur_frame->code_blocks);
1980
1981 pkg = &item_array_at(&op_ctx->items, 0)->pkg;
1982
1983 // Disarm the tracked package so that we don't skip the Scope
1984 op_ctx->tracked_pkg_idx = 0;
1985
1986 switch (op_ctx->op->code) {
1987 case UACPI_AML_OP_IfOp:
1988 block->type = CODE_BLOCK_IF;
1989 break;
1990 case UACPI_AML_OP_ElseOp:
1991 block->type = CODE_BLOCK_ELSE;
1992 break;
1993 case UACPI_AML_OP_WhileOp:
1994 block->type = CODE_BLOCK_WHILE;
1995
1996 if (pkg->begin == cur_frame->prev_while_code_offset) {
1997 uacpi_u64 cur_ticks;
1998
2000
2001 if (uacpi_unlikely(cur_ticks > block->expiration_point)) {
2002 uacpi_error("loop time out after running for %u seconds\n",
2003 g_uacpi_rt_ctx.loop_timeout_seconds);
2004 code_block_array_pop(&cur_frame->code_blocks);
2006 }
2007
2008 block->expiration_point = cur_frame->prev_while_expiration;
2009 } else {
2010 /*
2011 * Calculate the expiration point for this loop.
2012 * If a loop is executed past this point, it will get aborted.
2013 */
2014 block->expiration_point = uacpi_kernel_get_nanoseconds_since_boot();
2015 block->expiration_point +=
2016 g_uacpi_rt_ctx.loop_timeout_seconds * UACPI_NANOSECONDS_PER_SEC;
2017 }
2018 break;
2019 case UACPI_AML_OP_ScopeOp:
2020 case UACPI_AML_OP_DeviceOp:
2021 case UACPI_AML_OP_ProcessorOp:
2022 case UACPI_AML_OP_PowerResOp:
2023 case UACPI_AML_OP_ThermalZoneOp:
2024 block->type = CODE_BLOCK_SCOPE;
2025 block->node = item_array_at(&op_ctx->items, 1)->node;
2026 break;
2027 default:
2028 code_block_array_pop(&cur_frame->code_blocks);
2030 }
2031
2032 // -1 because we want to re-evaluate at the start of the op next time
2033 block->begin = pkg->begin - 1;
2034 block->end = pkg->end;
2035 ctx->cur_block = block;
2036
2037 cur_frame->last_while = find_last_block(&cur_frame->code_blocks,
2039 update_scope(cur_frame);
2040 return UACPI_STATUS_OK;
2041}
2042
2044 enum code_block_type type)
2045{
2046 struct call_frame *frame = ctx->cur_frame;
2047
2048 if (type == CODE_BLOCK_WHILE) {
2049 struct code_block *block = ctx->cur_block;
2050
2051 // + 1 here to skip the WhileOp and get to the PkgLength
2052 frame->prev_while_code_offset = block->begin + 1;
2053 frame->prev_while_expiration = block->expiration_point;
2054 }
2055
2056 code_block_array_pop(&frame->code_blocks);
2057 ctx->cur_block = code_block_array_last(&frame->code_blocks);
2058
2059 if (type == CODE_BLOCK_WHILE) {
2060 frame->last_while = find_last_block(&frame->code_blocks, type);
2061 } else if (type == CODE_BLOCK_SCOPE) {
2062 update_scope(frame);
2063 }
2064}
2065
2067{
2068 switch (src->type) {
2070 uacpi_trace("%s Uninitialized\n", prefix);
2071 break;
2073 uacpi_trace("%s String => \"%s\"\n", prefix, src->buffer->text);
2074 break;
2076 if (g_uacpi_rt_ctx.is_rev1) {
2078 "%s Integer => 0x%08X\n", prefix, (uacpi_u32)src->integer
2079 );
2080 } else {
2082 "%s Integer => 0x%016"UACPI_PRIX64"\n", prefix,
2083 UACPI_FMT64(src->integer)
2084 );
2085 }
2086 break;
2088 uacpi_trace("%s Reference @%p => %p\n", prefix, src, src->inner_object);
2089 break;
2092 "%s Package @%p (%p) (%zu elements)\n",
2093 prefix, src, src->package, src->package->count
2094 );
2095 break;
2098 "%s Buffer @%p (%p) (%zu bytes)\n",
2099 prefix, src, src->buffer, src->buffer->size
2100 );
2101 break;
2104 "%s OperationRegion (ASID %d) 0x%016"UACPI_PRIX64
2105 " -> 0x%016"UACPI_PRIX64"\n", prefix,
2106 src->op_region->space, UACPI_FMT64(src->op_region->offset),
2107 UACPI_FMT64(src->op_region->offset + src->op_region->length)
2108 );
2109 break;
2112 "%s Power Resource %d %d\n",
2113 prefix, src->power_resource.system_level,
2114 src->power_resource.resource_order
2115 );
2116 break;
2119 "%s Processor[%d] 0x%08X (%d)\n",
2120 prefix, src->processor->id, src->processor->block_address,
2121 src->processor->block_length
2122 );
2123 break;
2126 "%s Buffer Index %p[%zu] => 0x%02X\n",
2127 prefix, src->buffer_index.buffer->data, src->buffer_index.idx,
2128 *buffer_index_cursor(&src->buffer_index)
2129 );
2130 break;
2131 case UACPI_OBJECT_MUTEX:
2133 "%s Mutex @%p (%p => %p) sync level %d\n",
2134 prefix, src, src->mutex, src->mutex->handle,
2135 src->mutex->sync_level
2136 );
2137 break;
2139 uacpi_trace("%s Method @%p (%p)\n", prefix, src, src->method);
2140 break;
2141 default:
2143 "%s %s @%p\n",
2145 );
2146 }
2147}
2148
2150{
2151 /*
2152 * Don't bother running the body if current log level is not set to trace.
2153 * All DebugOp logging is done as TRACE exclusively.
2154 */
2156 return UACPI_STATUS_OK;
2157
2159
2160 debug_store_no_recurse("[AML DEBUG]", src);
2161
2162 if (src->type == UACPI_OBJECT_PACKAGE) {
2163 uacpi_package *pkg = src->package;
2164 uacpi_size i;
2165
2166 for (i = 0; i < pkg->count; ++i) {
2167 uacpi_object *obj = pkg->objects[i];
2168 if (obj->type == UACPI_OBJECT_REFERENCE &&
2170 obj = obj->inner_object;
2171
2172 debug_store_no_recurse("Element:", obj);
2173 }
2174 }
2175
2176 return UACPI_STATUS_OK;
2177}
2178
2179/*
2180 * NOTE: this function returns the parent object
2181 */
2183{
2185
2186 while (obj) {
2187 if (obj->type != UACPI_OBJECT_REFERENCE)
2188 return parent;
2189
2190 parent = obj;
2191 obj = parent->inner_object;
2192 }
2193
2194 // This should be unreachable
2195 return UACPI_NULL;
2196}
2197
2199 void *user, uacpi_namespace_node *node, uacpi_u32 node_depth
2200)
2201{
2202 uacpi_object *target_object = user;
2203 UACPI_UNUSED(node_depth);
2204
2205 if (node->object == target_object) {
2208 }
2209
2211}
2212
2214{
2215 if (parent->flags == UACPI_REFERENCE_KIND_NAMED &&
2217
2218 /*
2219 * We're doing a CopyObject or similar to a namespace node that is an
2220 * operation region. Try to find the parent node and manually detach
2221 * the handler.
2222 */
2228 );
2229 }
2230
2233}
2234
2235/*
2236 * Breakdown of what happens here:
2237 *
2238 * CopyObject(..., Obj) where Obj is:
2239 * 1. LocalX -> Overwrite LocalX.
2240 * 2. NAME -> Overwrite NAME.
2241 * 3. ArgX -> Overwrite ArgX unless ArgX is a reference, in that case
2242 * overwrite the referenced object.
2243 * 4. RefOf -> Not allowed here.
2244 * 5. Index -> Overwrite Object stored at the index.
2245 */
2248{
2250 uacpi_object *src_obj, *new_obj;
2251
2252 switch (dst->flags) {
2254 uacpi_object *referenced_obj;
2255
2256 referenced_obj = uacpi_unwrap_internal_reference(dst);
2257 if (referenced_obj->type == UACPI_OBJECT_REFERENCE) {
2258 dst = reference_unwind(referenced_obj);
2259 break;
2260 }
2261
2263 }
2267 break;
2268 default:
2270 }
2271
2273
2275 if (uacpi_unlikely(new_obj == UACPI_NULL))
2277
2278 ret = uacpi_object_assign(new_obj, src_obj,
2281 return ret;
2282
2283 object_replace_child(dst, new_obj);
2284 uacpi_object_unref(new_obj);
2285
2286 return UACPI_STATUS_OK;
2287}
2288
2289/*
2290 * if Store(..., Obj) where Obj is:
2291 * 1. LocalX/Index -> OVERWRITE unless the object is a reference, in that
2292 * case store to the referenced object _with_ implicit
2293 * cast.
2294 * 2. ArgX -> OVERWRITE unless the object is a reference, in that
2295 * case OVERWRITE the referenced object.
2296 * 3. NAME -> Store with implicit cast.
2297 * 4. RefOf -> Not allowed here.
2298 */
2301)
2302{
2303 uacpi_object *src_obj;
2304 uacpi_bool overwrite = UACPI_FALSE;
2305
2306 switch (dst->flags) {
2310 uacpi_object *referenced_obj;
2311
2312 if (dst->flags == UACPI_REFERENCE_KIND_PKG_INDEX)
2313 referenced_obj = dst->inner_object;
2314 else
2315 referenced_obj = uacpi_unwrap_internal_reference(dst);
2316
2317 if (referenced_obj->type == UACPI_OBJECT_REFERENCE) {
2318 overwrite = dst->flags == UACPI_REFERENCE_KIND_ARG;
2319 dst = reference_unwind(referenced_obj);
2320 break;
2321 }
2322
2323 overwrite = UACPI_TRUE;
2324 break;
2325 }
2328 break;
2329 default:
2331 }
2332
2334 overwrite |= dst->inner_object->type == UACPI_OBJECT_UNINITIALIZED;
2335
2336 if (overwrite) {
2338 uacpi_object *new_obj;
2339
2341 if (uacpi_unlikely(new_obj == UACPI_NULL))
2343
2344 ret = uacpi_object_assign(new_obj, src_obj,
2347 uacpi_object_unref(new_obj);
2348 return ret;
2349 }
2350
2351 object_replace_child(dst, new_obj);
2352 uacpi_object_unref(new_obj);
2353 return UACPI_STATUS_OK;
2354 }
2355
2357 dst->inner_object, src_obj, wtr_response
2358 );
2359}
2360
2362{
2363 struct op_context *op_ctx = ctx->cur_op_ctx;
2364 uacpi_object *dst, *src;
2365
2366 src = item_array_at(&op_ctx->items, 0)->obj;
2367
2368 if (op_ctx->op->code == UACPI_AML_OP_CondRefOfOp)
2369 dst = item_array_at(&op_ctx->items, 2)->obj;
2370 else
2371 dst = item_array_at(&op_ctx->items, 1)->obj;
2372
2373 if (op_ctx->op->code == UACPI_AML_OP_DerefOfOp) {
2374 uacpi_bool was_a_reference = UACPI_FALSE;
2375
2376 if (src->type == UACPI_OBJECT_REFERENCE) {
2377 was_a_reference = UACPI_TRUE;
2378
2379 /*
2380 * Explicit dereferencing [DerefOf] behavior:
2381 * Simply grabs the bottom-most object that is not a reference.
2382 * This mimics the behavior of NT Acpi.sys: any DerfOf fetches
2383 * the bottom-most reference. Note that this is different from
2384 * ACPICA where DerefOf dereferences one level.
2385 */
2387 }
2388
2389 if (src->type == UACPI_OBJECT_BUFFER_INDEX) {
2390 uacpi_buffer_index *buf_idx = &src->buffer_index;
2391
2392 dst->type = UACPI_OBJECT_INTEGER;
2394 &dst->integer, buffer_index_cursor(buf_idx),
2395 sizeof(dst->integer), 1
2396 );
2397 return UACPI_STATUS_OK;
2398 }
2399
2400 if (!was_a_reference) {
2402 "invalid DerefOf argument: %s, expected a reference\n",
2404 );
2406 }
2407
2408 return uacpi_object_assign(dst, src,
2410 }
2411
2413 dst->inner_object = src;
2415 return UACPI_STATUS_OK;
2416}
2417
2420 uacpi_object *tgt0, uacpi_object *tgt1,
2422)
2423{
2424 uacpi_u64 lhs, rhs, res;
2425 uacpi_bool should_negate = UACPI_FALSE;
2426
2427 lhs = arg0->integer;
2428 rhs = arg1->integer;
2429
2430 switch (op)
2431 {
2432 case UACPI_AML_OP_AddOp:
2433 res = lhs + rhs;
2434 break;
2435 case UACPI_AML_OP_SubtractOp:
2436 res = lhs - rhs;
2437 break;
2438 case UACPI_AML_OP_MultiplyOp:
2439 res = lhs * rhs;
2440 break;
2441 case UACPI_AML_OP_ShiftLeftOp:
2442 case UACPI_AML_OP_ShiftRightOp:
2443 if (rhs <= (g_uacpi_rt_ctx.is_rev1 ? 31 : 63)) {
2444 if (op == UACPI_AML_OP_ShiftLeftOp)
2445 res = lhs << rhs;
2446 else
2447 res = lhs >> rhs;
2448 } else {
2449 res = 0;
2450 }
2451 break;
2452 case UACPI_AML_OP_NandOp:
2453 should_negate = UACPI_TRUE;
2455 case UACPI_AML_OP_AndOp:
2456 res = rhs & lhs;
2457 break;
2458 case UACPI_AML_OP_NorOp:
2459 should_negate = UACPI_TRUE;
2461 case UACPI_AML_OP_OrOp:
2462 res = rhs | lhs;
2463 break;
2464 case UACPI_AML_OP_XorOp:
2465 res = rhs ^ lhs;
2466 break;
2467 case UACPI_AML_OP_DivideOp:
2468 if (uacpi_unlikely(rhs == 0)) {
2469 uacpi_error("attempted to divide by zero\n");
2471 }
2472 tgt1->integer = lhs / rhs;
2473 res = lhs % rhs;
2474 break;
2475 case UACPI_AML_OP_ModOp:
2476 if (uacpi_unlikely(rhs == 0)) {
2477 uacpi_error("attempted to calculate modulo of zero\n");
2479 }
2480 res = lhs % rhs;
2481 break;
2482 default:
2484 }
2485
2486 if (should_negate)
2487 res = ~res;
2488
2489 tgt0->integer = res;
2490 return UACPI_STATUS_OK;
2491}
2492
2494{
2495 uacpi_object *arg0, *arg1, *tgt0, *tgt1;
2496 struct item_array *items = &ctx->cur_op_ctx->items;
2497 uacpi_aml_op op = ctx->cur_op_ctx->op->code;
2498
2499 arg0 = item_array_at(items, 0)->obj;
2500 arg1 = item_array_at(items, 1)->obj;
2501
2502 if (op == UACPI_AML_OP_DivideOp) {
2503 tgt0 = item_array_at(items, 4)->obj;
2504 tgt1 = item_array_at(items, 5)->obj;
2505 } else {
2506 tgt0 = item_array_at(items, 3)->obj;
2507 tgt1 = UACPI_NULL;
2508 }
2509
2510 return do_binary_math(arg0, arg1, tgt0, tgt1, op);
2511}
2512
2514{
2515 uacpi_object *arg, *tgt;
2516 struct item_array *items = &ctx->cur_op_ctx->items;
2517 uacpi_aml_op op = ctx->cur_op_ctx->op->code;
2518
2519 arg = item_array_at(items, 0)->obj;
2520 tgt = item_array_at(items, 2)->obj;
2521
2522 switch (op) {
2523 case UACPI_AML_OP_NotOp:
2524 tgt->integer = ~arg->integer;
2526 break;
2527 case UACPI_AML_OP_FindSetRightBitOp:
2528 tgt->integer = uacpi_bit_scan_forward(arg->integer);
2529 break;
2530 case UACPI_AML_OP_FindSetLeftBitOp:
2531 tgt->integer = uacpi_bit_scan_backward(arg->integer);
2532 break;
2533 default:
2535 }
2536
2537 return UACPI_STATUS_OK;
2538}
2539
2541 uacpi_size src_size)
2542{
2543 if (uacpi_likely(idx < src_size))
2544 return UACPI_STATUS_OK;
2545
2547 "invalid index %zu, %s@%p has %zu elements\n",
2548 idx, uacpi_object_type_to_string(obj->type), obj, src_size
2549 );
2551}
2552
2554{
2556 struct op_context *op_ctx = ctx->cur_op_ctx;
2558 struct item *dst;
2560
2561 src = item_array_at(&op_ctx->items, 0)->obj;
2562 idx = item_array_at(&op_ctx->items, 1)->obj->integer;
2563 dst = item_array_at(&op_ctx->items, 3);
2564
2565 switch (src->type) {
2567 case UACPI_OBJECT_STRING: {
2568 uacpi_buffer_index *buf_idx;
2571
2572 ret = ensure_valid_idx(src, idx, buf.length);
2574 return ret;
2575
2576 dst->type = ITEM_OBJECT;
2578 if (uacpi_unlikely(dst->obj == UACPI_NULL))
2580
2581 buf_idx = &dst->obj->buffer_index;
2582 buf_idx->idx = idx;
2583 buf_idx->buffer = src->buffer;
2584 uacpi_shareable_ref(buf_idx->buffer);
2585
2586 break;
2587 }
2588 case UACPI_OBJECT_PACKAGE: {
2589 uacpi_package *pkg = src->package;
2591
2592 ret = ensure_valid_idx(src, idx, pkg->count);
2594 return ret;
2595
2596 /*
2597 * Lazily transform the package element into an internal reference
2598 * to itself of type PKG_INDEX. This is needed to support stuff like
2599 * CopyObject(..., Index(pkg, X)) where the new object must be
2600 * propagated to anyone else with a currently alive index object.
2601 *
2602 * Sidenote: Yes, IndexOp is not a SimpleName, so technically it is
2603 * illegal to CopyObject to it. However, yet again we fall
2604 * victim to the NT ACPI driver implementation, which allows
2605 * it just fine.
2606 */
2607 obj = pkg->objects[idx];
2608 if (obj->type != UACPI_OBJECT_REFERENCE ||
2610
2613 );
2616
2617 pkg->objects[idx] = obj;
2618 uacpi_object_unref(obj->inner_object);
2619 }
2620
2621 dst->obj = obj;
2622 dst->type = ITEM_OBJECT;
2623 uacpi_object_ref(dst->obj);
2624 break;
2625 }
2626 default:
2628 "invalid argument for Index: %s, "
2629 "expected String/Buffer/Package\n",
2631 );
2633 }
2634
2635 return UACPI_STATUS_OK;
2636}
2637
2639 uacpi_size max_buffer_bytes)
2640{
2641 uacpi_u64 dst;
2642
2643 switch (obj->type) {
2645 dst = obj->integer;
2646 break;
2647 case UACPI_OBJECT_BUFFER: {
2649 bytes = UACPI_MIN(max_buffer_bytes, obj->buffer->size);
2650 uacpi_memcpy_zerout(&dst, obj->buffer->data, sizeof(dst), bytes);
2651 break;
2652 }
2655 obj->buffer->text, obj->buffer->size, UACPI_BASE_AUTO, &dst
2656 );
2657 break;
2658 default:
2659 dst = 0;
2660 break;
2661 }
2662
2663 return dst;
2664}
2665
2668)
2669{
2670 int repr_len;
2671 uacpi_char int_buf[21];
2672 uacpi_size final_size;
2673
2674 repr_len = uacpi_snprintf(
2675 int_buf, sizeof(int_buf),
2677 UACPI_FMT64(integer)
2678 );
2679 if (uacpi_unlikely(repr_len < 0))
2681
2682 // 0x prefix + repr + \0
2683 final_size = (is_hex ? 2 : 0) + repr_len + 1;
2684
2685 str->data = uacpi_kernel_alloc(final_size);
2686 if (uacpi_unlikely(str->data == UACPI_NULL))
2688
2689 if (is_hex) {
2690 str->text[0] = '0';
2691 str->text[1] = 'x';
2692 }
2693 uacpi_memcpy(str->text + (is_hex ? 2 : 0), int_buf, repr_len + 1);
2694 str->size = final_size;
2695
2696 return UACPI_STATUS_OK;
2697}
2698
2701)
2702{
2703 int repr_len;
2704 uacpi_char int_buf[5];
2705 uacpi_size i, final_size;
2707
2708 if (is_hex) {
2709 final_size = 4 * buf->size;
2710 } else {
2711 final_size = 0;
2712
2713 for (i = 0; i < buf->size; ++i) {
2714 uacpi_u8 value = ((uacpi_u8*)buf->data)[i];
2715
2716 if (value < 10)
2717 final_size += 1;
2718 else if (value < 100)
2719 final_size += 2;
2720 else
2721 final_size += 3;
2722 }
2723 }
2724
2725 // Comma for every value but one
2726 final_size += buf->size - 1;
2727
2728 // Null terminator
2729 final_size += 1;
2730
2731 str->data = uacpi_kernel_alloc(final_size);
2732 if (uacpi_unlikely(str->data == UACPI_NULL))
2734
2735 cursor = str->data;
2736
2737 for (i = 0; i < buf->size; ++i) {
2738 repr_len = uacpi_snprintf(
2739 int_buf, sizeof(int_buf),
2740 is_hex ? "0x%02X" : "%d",
2741 ((uacpi_u8*)buf->data)[i]
2742 );
2743 if (uacpi_unlikely(repr_len < 0)) {
2744 uacpi_free(str->data, final_size);
2745 str->data = UACPI_NULL;
2747 }
2748
2749 uacpi_memcpy(cursor, int_buf, repr_len + 1);
2750 cursor += repr_len;
2751
2752 if (i != buf->size - 1)
2753 *cursor++ = ',';
2754 }
2755
2756 str->size = final_size;
2757 return UACPI_STATUS_OK;
2758}
2759
2762{
2763 buf->text = uacpi_kernel_alloc_zeroed(sizeof(uacpi_char));
2764 if (uacpi_unlikely(buf->text == UACPI_NULL))
2766
2767 if (is_string)
2768 buf->size = sizeof(uacpi_char);
2769
2770 return UACPI_STATUS_OK;
2771}
2772
2774{
2776}
2777
2779{
2780 /*
2781 * Allocate at least 1 byte just to be safe,
2782 * even for empty buffers. We still set the
2783 * size to 0 though.
2784 */
2786}
2787
2789{
2791 struct op_context *op_ctx = ctx->cur_op_ctx;
2792 uacpi_object *src, *dst;
2793
2794 src = item_array_at(&op_ctx->items, 0)->obj;
2795 dst = item_array_at(&op_ctx->items, 2)->obj;
2796
2797 switch (op_ctx->op->code) {
2798 case UACPI_AML_OP_ToIntegerOp:
2799 // NT always takes the first 8 bytes, even for revision 1
2800 dst->integer = object_to_integer(src, 8);
2801 break;
2802
2803 case UACPI_AML_OP_ToHexStringOp:
2804 case UACPI_AML_OP_ToDecimalStringOp: {
2805 uacpi_bool is_hex = op_ctx->op->code == UACPI_AML_OP_ToHexStringOp;
2806
2807 if (src->type == UACPI_OBJECT_INTEGER) {
2808 ret = integer_to_string(src->integer, dst->buffer, is_hex);
2809 break;
2810 } else if (src->type == UACPI_OBJECT_BUFFER) {
2811 if (uacpi_unlikely(src->buffer->size == 0))
2812 return make_null_string(dst->buffer);
2813
2814 ret = buffer_to_string(src->buffer, dst->buffer, is_hex);
2815 break;
2816 }
2818 }
2819 case UACPI_AML_OP_ToBufferOp: {
2821 uacpi_u8 *dst_buf;
2822
2825 return ret;
2826
2827 if (uacpi_unlikely(buf.length == 0))
2828 return make_null_buffer(dst->buffer);
2829
2830 dst_buf = uacpi_kernel_alloc(buf.length);
2831 if (uacpi_unlikely(dst_buf == UACPI_NULL))
2833
2834 uacpi_memcpy(dst_buf, buf.bytes, buf.length);
2835 dst->buffer->data = dst_buf;
2836 dst->buffer->size = buf.length;
2837 break;
2838 }
2839
2840 default:
2842 }
2843
2844 return ret;
2845}
2846
2848{
2849 struct op_context *op_ctx = ctx->cur_op_ctx;
2850 uacpi_buffer *src_buf, *dst_buf;
2851 uacpi_size req_len, len;
2852
2853 src_buf = item_array_at(&op_ctx->items, 0)->obj->buffer;
2854 req_len = item_array_at(&op_ctx->items, 1)->obj->integer;
2855 dst_buf = item_array_at(&op_ctx->items, 3)->obj->buffer;
2856
2857 len = UACPI_MIN(req_len, src_buf->size);
2858 if (uacpi_unlikely(len == 0))
2859 return make_null_string(dst_buf);
2860
2861 len = uacpi_strnlen(src_buf->text, len);
2862
2863 dst_buf->text = uacpi_kernel_alloc(len + 1);
2864 if (uacpi_unlikely(dst_buf->text == UACPI_NULL))
2866
2867 uacpi_memcpy(dst_buf->text, src_buf->data, len);
2868 dst_buf->text[len] = '\0';
2869 dst_buf->size = len + 1;
2870
2871 return UACPI_STATUS_OK;
2872}
2873
2875{
2876 struct op_context *op_ctx = ctx->cur_op_ctx;
2877 uacpi_object *src, *dst;
2878 uacpi_data_view src_buf;
2879 uacpi_buffer *dst_buf;
2882
2883 src = item_array_at(&op_ctx->items, 0)->obj;
2884 if (uacpi_unlikely(src->type != UACPI_OBJECT_STRING &&
2885 src->type != UACPI_OBJECT_BUFFER)) {
2887 "invalid argument for Mid: %s, expected String/Buffer\n",
2889 );
2891 }
2892
2893 idx = item_array_at(&op_ctx->items, 1)->obj->integer;
2894 len = item_array_at(&op_ctx->items, 2)->obj->integer;
2895 dst = item_array_at(&op_ctx->items, 4)->obj;
2896 dst_buf = dst->buffer;
2897
2900
2901 if (uacpi_unlikely(src_buf.length == 0 || idx >= src_buf.length ||
2902 len == 0)) {
2903 if (src->type == UACPI_OBJECT_STRING) {
2904 dst->type = UACPI_OBJECT_STRING;
2905 return make_null_string(dst_buf);
2906 }
2907
2908 return make_null_buffer(dst_buf);
2909 }
2910
2911 // Guaranteed to be at least 1 here
2912 len = UACPI_MIN(len, src_buf.length - idx);
2913
2914 dst_buf->data = uacpi_kernel_alloc(len + is_string);
2915 if (uacpi_unlikely(dst_buf->data == UACPI_NULL))
2917
2918 uacpi_memcpy(dst_buf->data, (uacpi_u8*)src_buf.bytes + idx, len);
2919 dst_buf->size = len;
2920
2921 if (is_string) {
2922 dst_buf->text[dst_buf->size++] = '\0';
2923 dst->type = UACPI_OBJECT_STRING;
2924 }
2925
2926 return UACPI_STATUS_OK;
2927}
2928
2930{
2932 struct op_context *op_ctx = ctx->cur_op_ctx;
2933 uacpi_object *arg0, *arg1, *dst;
2934 uacpi_u8 *dst_buf;
2935 uacpi_size buf_size = 0;
2936
2937 arg0 = item_array_at(&op_ctx->items, 0)->obj;
2938 arg1 = item_array_at(&op_ctx->items, 1)->obj;
2939 dst = item_array_at(&op_ctx->items, 3)->obj;
2940
2941 switch (arg0->type) {
2942 case UACPI_OBJECT_INTEGER: {
2943 uacpi_u64 arg1_as_int;
2944 uacpi_size int_size;
2945
2946 int_size = sizeof_int();
2947 buf_size = int_size * 2;
2948
2949 dst_buf = uacpi_kernel_alloc(buf_size);
2950 if (uacpi_unlikely(dst_buf == UACPI_NULL))
2952
2953 arg1_as_int = object_to_integer(arg1, 8);
2954
2955 uacpi_memcpy(dst_buf, &arg0->integer, int_size);
2956 uacpi_memcpy(dst_buf+ int_size, &arg1_as_int, int_size);
2957 break;
2958 }
2959 case UACPI_OBJECT_BUFFER: {
2960 uacpi_buffer *arg0_buf = arg0->buffer;
2961 uacpi_data_view arg1_buf = { 0 };
2962
2963 get_object_storage(arg1, &arg1_buf, UACPI_TRUE);
2964 buf_size = arg0_buf->size + arg1_buf.length;
2965
2966 dst_buf = uacpi_kernel_alloc(buf_size);
2967 if (uacpi_unlikely(dst_buf == UACPI_NULL))
2969
2970 uacpi_memcpy(dst_buf, arg0_buf->data, arg0_buf->size);
2971 uacpi_memcpy(dst_buf + arg0_buf->size, arg1_buf.bytes, arg1_buf.length);
2972 break;
2973 }
2974 case UACPI_OBJECT_STRING: {
2975 uacpi_char int_buf[17];
2976 void *arg1_ptr;
2977 uacpi_size arg0_size, arg1_size;
2978 uacpi_buffer *arg0_buf = arg0->buffer;
2979
2980 switch (arg1->type) {
2981 case UACPI_OBJECT_INTEGER: {
2982 int size;
2983 size = uacpi_snprintf(int_buf, sizeof(int_buf), "%"UACPI_PRIx64,
2984 UACPI_FMT64(arg1->integer));
2985 if (size < 0)
2987
2988 arg1_ptr = int_buf;
2989 arg1_size = size + 1;
2990 break;
2991 }
2993 arg1_ptr = arg1->buffer->data;
2994 arg1_size = arg1->buffer->size;
2995 break;
2996 case UACPI_OBJECT_BUFFER: {
2997 uacpi_buffer tmp_buf;
2998
2999 ret = buffer_to_string(arg1->buffer, &tmp_buf, UACPI_TRUE);
3001 return ret;
3002
3003 arg1_ptr = tmp_buf.data;
3004 arg1_size = tmp_buf.size;
3005 break;
3006 }
3007 default:
3009 }
3010
3011 arg0_size = arg0_buf->size ? arg0_buf->size - 1 : arg0_buf->size;
3012 buf_size = arg0_size + arg1_size;
3013
3014 dst_buf = uacpi_kernel_alloc(buf_size);
3015 if (uacpi_unlikely(dst_buf == UACPI_NULL)) {
3017 goto cleanup;
3018 }
3019
3020 uacpi_memcpy(dst_buf, arg0_buf->data, arg0_size);
3021 uacpi_memcpy(dst_buf + arg0_size, arg1_ptr, arg1_size);
3022 dst->type = UACPI_OBJECT_STRING;
3023
3024 cleanup:
3025 if (arg1->type == UACPI_OBJECT_BUFFER)
3026 uacpi_free(arg1_ptr, arg1_size);
3027 break;
3028 }
3029 default:
3031 }
3032
3034 dst->buffer->data = dst_buf;
3035 dst->buffer->size = buf_size;
3036 }
3037 return ret;
3038}
3039
3041{
3043 struct op_context *op_ctx = ctx->cur_op_ctx;
3045 uacpi_object *arg0, *arg1, *dst;
3046 uacpi_u8 *dst_buf;
3047 uacpi_size dst_size, arg0_size, arg1_size;
3048
3049 arg0 = item_array_at(&op_ctx->items, 0)->obj;
3050 arg1 = item_array_at(&op_ctx->items, 1)->obj;
3051 dst = item_array_at(&op_ctx->items, 3)->obj;
3052
3056 return ret;
3057
3058 uacpi_buffer_to_view(arg1->buffer, &buffer);
3061 return ret;
3062
3063 dst_size = arg0_size + arg1_size + sizeof(struct acpi_resource_end_tag);
3064
3065 dst_buf = uacpi_kernel_alloc(dst_size);
3066 if (uacpi_unlikely(dst_buf == UACPI_NULL))
3068
3069 dst->buffer->data = dst_buf;
3070 dst->buffer->size = dst_size;
3071
3072 uacpi_memcpy(dst_buf, arg0->buffer->data, arg0_size);
3073 uacpi_memcpy(dst_buf + arg0_size, arg1->buffer->data, arg1_size);
3074
3075 /*
3076 * Small item (0), End Tag (0x0F), length 1
3077 * Leave the checksum as 0
3078 */
3079 dst_buf[dst_size - 2] =
3081 (sizeof(struct acpi_resource_end_tag) - 1);
3082 dst_buf[dst_size - 1] = 0;
3083
3084 return UACPI_STATUS_OK;
3085}
3086
3088{
3089 struct op_context *op_ctx = ctx->cur_op_ctx;
3090 uacpi_object *src, *dst;
3091
3092 src = item_array_at(&op_ctx->items, 0)->obj;
3093 dst = item_array_at(&op_ctx->items, 1)->obj;
3094
3097
3098 switch (src->type) {
3100 case UACPI_OBJECT_BUFFER: {
3103
3104 dst->integer = buf.length;
3105 break;
3106 }
3107
3109 dst->integer = src->package->count;
3110 break;
3111
3112 default:
3114 "invalid argument for Sizeof: %s, "
3115 "expected String/Buffer/Package\n",
3117 );
3119 }
3120
3121 return UACPI_STATUS_OK;
3122}
3123
3125{
3126 struct op_context *op_ctx = ctx->cur_op_ctx;
3127 uacpi_object *src, *dst;
3128
3129 src = item_array_at(&op_ctx->items, 0)->obj;
3130 dst = item_array_at(&op_ctx->items, 1)->obj;
3131
3134
3135 dst->integer = src->type;
3136 if (dst->integer == UACPI_OBJECT_BUFFER_INDEX)
3137 dst->integer = UACPI_OBJECT_BUFFER_FIELD;
3138
3139 return UACPI_STATUS_OK;
3140}
3141
3143{
3144 struct op_context *op_ctx = ctx->cur_op_ctx;
3146
3147 dst = item_array_at(&op_ctx->items, 0)->obj;
3149
3150 return UACPI_STATUS_OK;
3151}
3152
3154{
3155 struct op_context *op_ctx = ctx->cur_op_ctx;
3157
3158 time = item_array_at(&op_ctx->items, 0)->obj->integer;
3159
3160 if (op_ctx->op->code == UACPI_AML_OP_SleepOp) {
3161 /*
3162 * ACPICA doesn't allow sleeps longer than 2 seconds,
3163 * so we shouldn't either.
3164 */
3165 if (time > 2000)
3166 time = 2000;
3167
3171 } else {
3172 // Spec says this must evaluate to a ByteData
3173 if (time > 0xFF)
3174 time = 0xFF;
3176 }
3177
3178 return UACPI_STATUS_OK;
3179}
3180
3182{
3183 struct op_context *op_ctx = ctx->cur_op_ctx;
3184 uacpi_u64 src, dst = 0;
3185 uacpi_size i;
3186 uacpi_object *dst_obj;
3187
3188 src = item_array_at(&op_ctx->items, 0)->obj->integer;
3189 dst_obj = item_array_at(&op_ctx->items, 2)->obj;
3190 i = 64;
3191
3192 /*
3193 * NOTE: ACPICA just errors out for invalid BCD, but NT allows it just fine.
3194 * FromBCD matches NT behavior 1:1 even for invalid BCD, but ToBCD
3195 * produces different results when the input is too large.
3196 */
3197 if (op_ctx->op->code == UACPI_AML_OP_FromBCDOp) {
3198 do {
3199 i -= 4;
3200 dst *= 10;
3201 dst += (src >> i) & 0b1111;
3202 } while (i);
3203 } else {
3204 while (src != 0) {
3205 dst >>= 4;
3206 i -= 4;
3207 dst |= (src % 10) << 60;
3208 src /= 10;
3209 }
3210
3211 dst >>= (i % 64);
3212 }
3213
3214 dst_obj->integer = dst;
3215 return UACPI_STATUS_OK;
3216}
3217
3219{
3221
3222 /*
3223 * Technically this doesn't exist in the wild, from the dumps that I have
3224 * the only user of the Unload opcode is the Surface Pro 3, which triggers
3225 * an unload of some I2C-related table as a response to some event.
3226 *
3227 * This op has been long deprecated by the specification exactly because
3228 * it hasn't really been used by anyone and the fact that it introduces
3229 * an enormous layer of complexity, which no driver is really prepared to
3230 * deal with (aka namespace nodes disappearing under its feet).
3231 *
3232 * Just pretend we have actually unloaded whatever the AML asked for, if it
3233 * ever tries to re-load this table that will just skip opcodes that create
3234 * already existing objects, which should be good enough and mostly
3235 * transparent to the AML.
3236 */
3237 uacpi_warn("refusing to unload a table from AML\n");
3238 return UACPI_STATUS_OK;
3239}
3240
3242{
3243 struct op_context *op_ctx = ctx->cur_op_ctx;
3244 uacpi_object *src, *dst;
3245
3246 src = item_array_at(&op_ctx->items, 0)->obj;
3247 dst = item_array_at(&op_ctx->items, 1)->obj;
3248
3249 dst->type = UACPI_OBJECT_INTEGER;
3250 dst->integer = src->integer ? 0 : ones();
3251
3252 return UACPI_STATUS_OK;
3253}
3254
3256{
3258
3259 if (lhs->type == UACPI_OBJECT_STRING || lhs->type == UACPI_OBJECT_BUFFER) {
3260 res = lhs->buffer->size == rhs->buffer->size;
3261
3262 if (res && lhs->buffer->size) {
3263 res = uacpi_memcmp(
3264 lhs->buffer->data,
3265 rhs->buffer->data,
3266 lhs->buffer->size
3267 ) == 0;
3268 }
3269 } else if (lhs->type == UACPI_OBJECT_INTEGER) {
3270 res = lhs->integer == rhs->integer;
3271 }
3272
3273 return res;
3274}
3275
3278)
3279{
3280 if (lhs->type == UACPI_OBJECT_STRING || lhs->type == UACPI_OBJECT_BUFFER) {
3281 int res;
3282 uacpi_buffer *lhs_buf, *rhs_buf;
3283
3284 lhs_buf = lhs->buffer;
3285 rhs_buf = rhs->buffer;
3286
3287 res = uacpi_memcmp(lhs_buf->data, rhs_buf->data,
3288 UACPI_MIN(lhs_buf->size, rhs_buf->size));
3289 if (res == 0) {
3290 if (lhs_buf->size < rhs_buf->size)
3291 res = -1;
3292 else if (lhs_buf->size > rhs_buf->size)
3293 res = 1;
3294 }
3295
3296 if (op == UACPI_AML_OP_LLessOp)
3297 return res < 0;
3298
3299 return res > 0;
3300 }
3301
3302 if (op == UACPI_AML_OP_LLessOp)
3303 return lhs->integer < rhs->integer;
3304
3305 return lhs->integer > rhs->integer;
3306}
3307
3309{
3310 struct op_context *op_ctx = ctx->cur_op_ctx;
3311 uacpi_aml_op op = op_ctx->op->code;
3312 uacpi_object *lhs, *rhs, *dst;
3314
3315 lhs = item_array_at(&op_ctx->items, 0)->obj;
3316 rhs = item_array_at(&op_ctx->items, 1)->obj;
3317 dst = item_array_at(&op_ctx->items, 2)->obj;
3318
3319 switch (op) {
3320 case UACPI_AML_OP_LEqualOp:
3321 case UACPI_AML_OP_LLessOp:
3322 case UACPI_AML_OP_LGreaterOp:
3323 // TODO: typecheck at parse time
3324 if (lhs->type != rhs->type) {
3326 "don't know how to do a logical comparison of '%s' and '%s'\n",
3329 );
3331 }
3332
3333 if (op == UACPI_AML_OP_LEqualOp)
3334 res = handle_logical_equality(lhs, rhs);
3335 else
3337 break;
3338 default: {
3339 uacpi_u64 lhs_int, rhs_int;
3340
3341 // NT only looks at the first 4 bytes of a buffer
3342 lhs_int = object_to_integer(lhs, 4);
3343 rhs_int = object_to_integer(rhs, 4);
3344
3345 if (op == UACPI_AML_OP_LandOp)
3346 res = lhs_int && rhs_int;
3347 else
3348 res = lhs_int || rhs_int;
3349 break;
3350 }
3351 }
3352
3353 dst->integer = res ? ones() : 0;
3354 return UACPI_STATUS_OK;
3355}
3356
3358 MTR = 0,
3359 MEQ = 1,
3360 MLE = 2,
3361 MLT = 3,
3362 MGE = 4,
3363 MGT = 5,
3364};
3365
3367{
3368 switch (op) {
3369 case MTR:
3370 return UACPI_TRUE;
3371 case MEQ:
3372 return lhs == rhs;
3373 case MLE:
3374 return lhs <= rhs;
3375 case MLT:
3376 return lhs < rhs;
3377 case MGE:
3378 return lhs >= rhs;
3379 case MGT:
3380 return lhs > rhs;
3381 default:
3382 return UACPI_FALSE;
3383 }
3384}
3385
3387{
3388 struct op_context *op_ctx = ctx->cur_op_ctx;
3389 uacpi_package *pkg;
3390 uacpi_u64 operand0, operand1, start_idx, i;
3391 enum match_op mop0, mop1;
3393
3394 pkg = item_array_at(&op_ctx->items, 0)->obj->package;
3395 mop0 = item_array_at(&op_ctx->items, 1)->immediate;
3396 operand0 = item_array_at(&op_ctx->items, 2)->obj->integer;
3397 mop1 = item_array_at(&op_ctx->items, 3)->immediate;
3398 operand1 = item_array_at(&op_ctx->items, 4)->obj->integer;
3399 start_idx = item_array_at(&op_ctx->items, 5)->obj->integer;
3400 dst = item_array_at(&op_ctx->items, 6)->obj;
3401
3402 for (i = start_idx; i < pkg->count; ++i) {
3403 uacpi_object *obj = pkg->objects[i];
3404
3405 if (obj->type != UACPI_OBJECT_INTEGER)
3406 continue;
3407
3408 if (match_one(mop0, obj->integer, operand0) &&
3409 match_one(mop1, obj->integer, operand1))
3410 break;
3411 }
3412
3413 if (i < pkg->count)
3414 dst->integer = i;
3415 else
3416 dst->integer = ones();
3417
3418 return UACPI_STATUS_OK;
3419}
3420
3421/*
3422 * PkgLength :=
3423 * PkgLeadByte |
3424 * <pkgleadbyte bytedata> |
3425 * <pkgleadbyte bytedata bytedata> | <pkgleadbyte bytedata bytedata bytedata>
3426 * PkgLeadByte :=
3427 * <bit 7-6: bytedata count that follows (0-3)>
3428 * <bit 5-4: only used if pkglength < 63>
3429 * <bit 3-0: least significant package length nybble>
3430 */
3432 struct package_length *out_pkg)
3433{
3435 uacpi_u8 *data, marker_length;
3436
3437 out_pkg->begin = frame->code_offset;
3438 marker_length = 1;
3439
3441 if (uacpi_unlikely(left < 1))
3443
3444 data = call_frame_cursor(frame);
3445 marker_length += *data >> 6;
3446
3447 if (uacpi_unlikely(left < marker_length))
3449
3450 switch (marker_length) {
3451 case 1:
3452 size = *data & 0b111111;
3453 break;
3454 case 2:
3455 case 3:
3456 case 4: {
3457 uacpi_u32 temp_byte = 0;
3458
3459 size = *data & 0b1111;
3460 uacpi_memcpy(&temp_byte, data + 1, marker_length - 1);
3461
3462 // marker_length - 1 is at most 3, so this shift is safe
3463 size |= temp_byte << 4;
3464 break;
3465 }
3466 }
3467
3468 frame->code_offset += marker_length;
3469
3470 out_pkg->end = out_pkg->begin + size;
3471 if (uacpi_unlikely(out_pkg->end < out_pkg->begin)) {
3473 "PkgLength overflow: start=%u, size=%u\n", out_pkg->begin, size
3474 );
3476 }
3477
3478 return UACPI_STATUS_OK;
3479}
3480
3481/*
3482 * ByteData
3483 * // bit 0-2: ArgCount (0-7)
3484 * // bit 3: SerializeFlag
3485 * // 0 NotSerialized
3486 * // 1 Serialized
3487 * // bit 4-7: SyncLevel (0x00-0x0f)
3488 */
3490{
3491 method->args = flags_byte & 0b111;
3492 method->is_serialized = (flags_byte >> 3) & 1;
3493 method->sync_level = flags_byte >> 4;
3494}
3495
3497{
3498 struct op_context *op_ctx = ctx->cur_op_ctx;
3499 struct uacpi_control_method *this_method, *method;
3500 struct package_length *pkg;
3501 struct uacpi_namespace_node *node;
3502 struct uacpi_object *dst;
3503 uacpi_u32 method_begin_offset, method_size;
3504
3505 this_method = ctx->cur_frame->method;
3506 pkg = &item_array_at(&op_ctx->items, 0)->pkg;
3507 node = item_array_at(&op_ctx->items, 1)->node;
3508 method_begin_offset = item_array_at(&op_ctx->items, 3)->immediate;
3509
3510 if (uacpi_unlikely(pkg->end < pkg->begin ||
3511 pkg->end < method_begin_offset ||
3512 pkg->end > this_method->size)) {
3514 "invalid method %.4s bounds [%u..%u] (parent size is %u)\n",
3515 node->name.text, method_begin_offset, pkg->end, this_method->size
3516 );
3518 }
3519
3520 dst = item_array_at(&op_ctx->items, 4)->obj;
3521
3522 method = dst->method;
3523 method_size = pkg->end - method_begin_offset;
3524
3525 if (method_size) {
3526 method->code = uacpi_kernel_alloc(method_size);
3527 if (uacpi_unlikely(method->code == UACPI_NULL))
3529
3531 method->code,
3532 ctx->cur_frame->method->code + method_begin_offset,
3533 method_size
3534 );
3535 method->size = method_size;
3536 method->owns_code = 1;
3537 }
3538
3539 init_method_flags(method, item_array_at(&op_ctx->items, 2)->immediate);
3540
3542 dst);
3543 if (uacpi_unlikely(node->object == UACPI_NULL))
3545
3546 return UACPI_STATUS_OK;
3547}
3548
3550{
3551 struct op_context *op_ctx = ctx->cur_op_ctx;
3554
3555 node = item_array_at(&op_ctx->items, 0)->node;
3556
3557 if (op_ctx->op->code == UACPI_AML_OP_MutexOp) {
3558 dst = item_array_at(&op_ctx->items, 2)->obj;
3559
3560 // bits 0-3: SyncLevel (0x00-0x0f), bits 4-7: Reserved (must be 0)
3561 dst->mutex->sync_level = item_array_at(&op_ctx->items, 1)->immediate;
3562 dst->mutex->sync_level &= 0b1111;
3563 } else {
3564 dst = item_array_at(&op_ctx->items, 1)->obj;
3565 }
3566
3569 dst
3570 );
3571 if (uacpi_unlikely(node->object == UACPI_NULL))
3573
3574 return UACPI_STATUS_OK;
3575}
3576
3578{
3579 struct op_context *op_ctx = ctx->cur_op_ctx;
3581
3583 item_array_at(&op_ctx->items, 0)->obj
3584 );
3585 if (uacpi_unlikely(obj->type != UACPI_OBJECT_EVENT)) {
3587 "%s: invalid argument '%s', expected an Event object\n",
3588 op_ctx->op->name, uacpi_object_type_to_string(obj->type)
3589 );
3591 }
3592
3593 switch (op_ctx->op->code)
3594 {
3595 case UACPI_AML_OP_SignalOp:
3596 uacpi_kernel_signal_event(obj->event->handle);
3597 break;
3598 case UACPI_AML_OP_ResetOp:
3599 uacpi_kernel_reset_event(obj->event->handle);
3600 break;
3601 case UACPI_AML_OP_WaitOp: {
3604
3605 timeout = item_array_at(&op_ctx->items, 1)->obj->integer;
3606 if (timeout > 0xFFFF)
3607 timeout = 0xFFFF;
3608
3610 ret = uacpi_kernel_wait_for_event(obj->event->handle, timeout);
3612
3613 /*
3614 * The return value here is inverted, we return 0 for success and Ones
3615 * for timeout and everything else.
3616 */
3617 if (ret)
3618 item_array_at(&op_ctx->items, 2)->obj->integer = 0;
3619 break;
3620 }
3621 default:
3623 }
3624
3625 return UACPI_STATUS_OK;
3626}
3627
3629{
3630 struct op_context *op_ctx = ctx->cur_op_ctx;
3632
3634 item_array_at(&op_ctx->items, 0)->obj
3635 );
3636 if (uacpi_unlikely(obj->type != UACPI_OBJECT_MUTEX)) {
3638 "%s: invalid argument '%s', expected a Mutex object\n",
3639 op_ctx->op->name, uacpi_object_type_to_string(obj->type)
3640 );
3642 }
3643
3644 switch (op_ctx->op->code)
3645 {
3646 case UACPI_AML_OP_AcquireOp: {
3648 uacpi_u64 *return_value;
3650
3651 return_value = &item_array_at(&op_ctx->items, 2)->obj->integer;
3652
3653 if (uacpi_unlikely(ctx->sync_level > obj->mutex->sync_level)) {
3654 uacpi_warn(
3655 "ignoring attempt to acquire mutex @%p with a lower sync level "
3656 "(%d < %d)\n", obj->mutex, obj->mutex->sync_level,
3657 ctx->sync_level
3658 );
3659 break;
3660 }
3661
3662 timeout = item_array_at(&op_ctx->items, 1)->immediate;
3663 if (timeout > 0xFFFF)
3664 timeout = 0xFFFF;
3665
3669 *return_value = 0;
3670 break;
3671 }
3672
3675 break;
3676
3677 ret = held_mutexes_array_push(&ctx->held_mutexes, obj->mutex);
3680 return ret;
3681 }
3682
3683 ctx->sync_level = obj->mutex->sync_level;
3684 *return_value = 0;
3685 break;
3686 }
3687
3688 case UACPI_AML_OP_ReleaseOp: {
3690
3692 uacpi_warn(
3693 "attempted to release not-previously-acquired mutex object "
3694 "@%p (%p)\n", obj->mutex, obj->mutex->handle
3695 );
3696 break;
3697 }
3698
3700 &ctx->held_mutexes, obj->mutex,
3702 );
3704 uacpi_mutex **last_mutex;
3705
3706 last_mutex = held_mutexes_array_last(&ctx->held_mutexes);
3707 if (last_mutex == UACPI_NULL) {
3708 ctx->sync_level = 0;
3709 break;
3710 }
3711
3712 ctx->sync_level = (*last_mutex)->sync_level;
3713 }
3714 break;
3715 }
3716
3717 default:
3719 }
3720
3721 return UACPI_STATUS_OK;
3722}
3723
3725{
3727 struct op_context *op_ctx = ctx->cur_op_ctx;
3728 struct uacpi_namespace_node *node;
3730
3731 node = item_array_at(&op_ctx->items, 0)->node;
3732 value = item_array_at(&op_ctx->items, 1)->obj->integer;
3733
3736 return ret;
3737
3739 const uacpi_char *path;
3740
3742 uacpi_warn(
3743 "ignoring firmware Notify(%s, 0x%"UACPI_PRIX64") request, "
3744 "no listeners\n", path, UACPI_FMT64(value)
3745 );
3747
3748 return UACPI_STATUS_OK;
3749 }
3750
3752 uacpi_error("Notify() called on an invalid object %.4s\n",
3753 node->name.text);
3755 }
3756
3757 return ret;
3758}
3759
3761{
3762 struct op_context *op_ctx = ctx->cur_op_ctx;
3763 uacpi_firmware_request req = { 0 };
3764
3765 switch (op_ctx->op->code) {
3766 case UACPI_AML_OP_BreakPointOp:
3768 req.breakpoint.ctx = ctx;
3769 break;
3770 case UACPI_AML_OP_FatalOp:
3772 req.fatal.type = item_array_at(&op_ctx->items, 0)->immediate;
3773 req.fatal.code = item_array_at(&op_ctx->items, 1)->immediate;
3774 req.fatal.arg = item_array_at(&op_ctx->items, 2)->obj->integer;
3775 break;
3776 default:
3778 }
3779
3783
3784 return UACPI_STATUS_OK;
3785}
3786
3788{
3789 struct op_context *op_ctx = ctx->cur_op_ctx;
3790 struct uacpi_namespace_node *node;
3792
3793 node = item_array_at(&op_ctx->items, 0)->node;
3794 src = item_array_at(&op_ctx->items, 1)->obj;
3795
3797 src);
3798 if (uacpi_unlikely(node->object == UACPI_NULL))
3800
3801 return UACPI_STATUS_OK;
3802}
3803
3806)
3807{
3808 if (field->bit_length > (g_uacpi_rt_ctx.is_rev1 ? 32u : 64u) ||
3809 field->force_buffer)
3810 return UACPI_OBJECT_BUFFER;
3811
3812 return UACPI_OBJECT_INTEGER;
3813}
3814
3817)
3818{
3819 if (obj->type == UACPI_OBJECT_BUFFER_FIELD) {
3820 *out_type = buffer_field_get_read_type(&obj->buffer_field);
3821 return UACPI_STATUS_OK;
3822 }
3823
3824 return uacpi_field_unit_get_read_type(obj->field_unit, out_type);
3825}
3826
3829)
3830{
3831 uacpi_size bit_length;
3832
3833 if (obj->type == UACPI_OBJECT_BUFFER_FIELD) {
3834 bit_length = obj->buffer_field.bit_length;
3835 } else {
3837
3838 ret = uacpi_field_unit_get_bit_length(obj->field_unit, &bit_length);
3840 return ret;
3841 }
3842
3844 return UACPI_STATUS_OK;
3845}
3846
3848{
3850 struct op_context *op_ctx = ctx->cur_op_ctx;
3851 struct uacpi_namespace_node *node;
3852 uacpi_object *src_obj, *dst_obj;
3853 uacpi_size dst_size;
3854 void *dst = UACPI_NULL;
3855 uacpi_data_view wtr_response = { 0 };
3856
3857 node = item_array_at(&op_ctx->items, 0)->node;
3859 dst_obj = item_array_at(&op_ctx->items, 1)->obj;
3860
3861 if (op_ctx->op->code == UACPI_AML_OP_InternalOpReadFieldAsBuffer) {
3863
3864 ret = field_byte_size(src_obj, &dst_size);
3866 return ret;
3867
3868 if (dst_size != 0) {
3869 buf = dst_obj->buffer;
3870
3871 dst = uacpi_kernel_alloc_zeroed(dst_size);
3872 if (dst == UACPI_NULL)
3874
3875 buf->data = dst;
3876 buf->size = dst_size;
3877 }
3878 } else {
3879 dst = &dst_obj->integer;
3880 dst_size = sizeof(uacpi_u64);
3881 }
3882
3883 if (src_obj->type == UACPI_OBJECT_BUFFER_FIELD) {
3885 return UACPI_STATUS_OK;
3886 }
3887
3889 src_obj->field_unit, dst, dst_size, &wtr_response
3890 );
3892 return ret;
3893
3894 if (wtr_response.data != UACPI_NULL) {
3896
3897 buf = dst_obj->buffer;
3898 buf->data = wtr_response.data;
3899 buf->size = wtr_response.length;
3900 }
3901
3902 return ret;
3903}
3904
3906{
3907 struct op_context *op_ctx = ctx->cur_op_ctx;
3908 struct uacpi_namespace_node *node;
3909 uacpi_buffer *src_buf;
3910 uacpi_object *field_obj;
3912
3913 /*
3914 * Layout of items here:
3915 * [0] -> Type checked source buffer object
3916 * [1] -> Byte/bit index integer object
3917 * [2] ( if CreateField) -> bit length integer object
3918 * [3] (2 if not CreateField) -> the new namespace node
3919 * [4] (3 if not CreateField) -> the buffer field object we're creating here
3920 */
3921 src_buf = item_array_at(&op_ctx->items, 0)->obj->buffer;
3922
3923 if (op_ctx->op->code == UACPI_AML_OP_CreateFieldOp) {
3924 uacpi_object *idx_obj, *len_obj;
3925
3926 idx_obj = item_array_at(&op_ctx->items, 1)->obj;
3927 len_obj = item_array_at(&op_ctx->items, 2)->obj;
3928 node = item_array_at(&op_ctx->items, 3)->node;
3929 field_obj = item_array_at(&op_ctx->items, 4)->obj;
3930 field = &field_obj->buffer_field;
3931
3932 field->bit_index = idx_obj->integer;
3933
3934 if (uacpi_unlikely(!len_obj->integer ||
3935 len_obj->integer > 0xFFFFFFFF)) {
3936 uacpi_error("invalid bit field length (%u)\n", field->bit_length);
3938 }
3939
3940 field->bit_length = len_obj->integer;
3941 field->force_buffer = UACPI_TRUE;
3942 } else {
3943 uacpi_object *idx_obj;
3944
3945 idx_obj = item_array_at(&op_ctx->items, 1)->obj;
3946 node = item_array_at(&op_ctx->items, 2)->node;
3947 field_obj = item_array_at(&op_ctx->items, 3)->obj;
3948 field = &field_obj->buffer_field;
3949
3950 field->bit_index = idx_obj->integer;
3951 switch (op_ctx->op->code) {
3952 case UACPI_AML_OP_CreateBitFieldOp:
3953 field->bit_length = 1;
3954 break;
3955 case UACPI_AML_OP_CreateByteFieldOp:
3956 field->bit_length = 8;
3957 break;
3958 case UACPI_AML_OP_CreateWordFieldOp:
3959 field->bit_length = 16;
3960 break;
3961 case UACPI_AML_OP_CreateDWordFieldOp:
3962 field->bit_length = 32;
3963 break;
3964 case UACPI_AML_OP_CreateQWordFieldOp:
3965 field->bit_length = 64;
3966 break;
3967 default:
3969 }
3970
3971 if (op_ctx->op->code != UACPI_AML_OP_CreateBitFieldOp)
3972 field->bit_index *= 8;
3973 }
3974
3975 if (uacpi_unlikely((field->bit_index + field->bit_length) >
3976 src_buf->size * 8)) {
3978 "invalid buffer field: bits [%zu..%zu], buffer size is %zu bytes\n",
3979 field->bit_index, field->bit_index + field->bit_length,
3980 src_buf->size
3981 );
3983 }
3984
3985 field->backing = src_buf;
3986 uacpi_shareable_ref(field->backing);
3988 field_obj);
3989 if (uacpi_unlikely(node->object == UACPI_NULL))
3991
3992 return UACPI_STATUS_OK;
3993}
3994
3996{
3997 struct call_frame *frame = ctx->cur_frame;
3998 struct op_context *op_ctx = ctx->cur_op_ctx;
3999
4000 if (uacpi_unlikely(frame->last_while == UACPI_NULL)) {
4002 "attempting to %s outside of a While block\n",
4003 op_ctx->op->code == UACPI_AML_OP_BreakOp ? "Break" : "Continue"
4004 );
4006 }
4007
4008 for (;;) {
4009 if (ctx->cur_block != frame->last_while) {
4010 frame_reset_post_end_block(ctx, ctx->cur_block->type);
4011 continue;
4012 }
4013
4014 if (op_ctx->op->code == UACPI_AML_OP_BreakOp)
4015 frame->code_offset = ctx->cur_block->end;
4016 else
4017 frame->code_offset = ctx->cur_block->begin;
4018 frame_reset_post_end_block(ctx, ctx->cur_block->type);
4019 break;
4020 }
4021
4022 return UACPI_STATUS_OK;
4023}
4024
4026{
4029
4030 node = item_array_at(&op_ctx->items, 1)->node;
4031 obj = item_array_last(&op_ctx->items)->obj;
4032
4033 switch (op_ctx->op->code) {
4034 case UACPI_AML_OP_ProcessorOp: {
4035 uacpi_processor *proc = obj->processor;
4036 proc->id = item_array_at(&op_ctx->items, 2)->immediate;
4037 proc->block_address = item_array_at(&op_ctx->items, 3)->immediate;
4038 proc->block_length = item_array_at(&op_ctx->items, 4)->immediate;
4039 break;
4040 }
4041
4042 case UACPI_AML_OP_PowerResOp: {
4043 uacpi_power_resource *power_res = &obj->power_resource;
4044 power_res->system_level = item_array_at(&op_ctx->items, 2)->immediate;
4045 power_res->resource_order = item_array_at(&op_ctx->items, 3)->immediate;
4046 break;
4047 }
4048
4049 default:
4050 break;
4051 }
4052
4054 obj);
4055 if (uacpi_unlikely(node->object == UACPI_NULL))
4057
4058 return UACPI_STATUS_OK;
4059}
4060
4062{
4063 struct op_context *op_ctx = ctx->cur_op_ctx;
4064
4065 switch (op_ctx->op->code) {
4066 case UACPI_AML_OP_ProcessorOp:
4067 case UACPI_AML_OP_PowerResOp:
4068 case UACPI_AML_OP_ThermalZoneOp:
4069 case UACPI_AML_OP_DeviceOp: {
4071
4072 ret = create_named_scope(op_ctx);
4074 return ret;
4075
4077 }
4078 case UACPI_AML_OP_ScopeOp:
4079 case UACPI_AML_OP_IfOp:
4080 case UACPI_AML_OP_ElseOp:
4081 case UACPI_AML_OP_WhileOp: {
4082 break;
4083 }
4084 default:
4086 }
4087
4088 return begin_block_execution(ctx);
4089}
4090
4092{
4095
4096 ctx->cur_frame->code_offset = ctx->cur_frame->method->size;
4098
4100 return ret;
4101 if (dst == UACPI_NULL)
4102 return UACPI_STATUS_OK;
4103
4104 /*
4105 * Should be possible to move here if method returns a literal
4106 * like Return(Buffer { ... }), otherwise we have to copy just to
4107 * be safe.
4108 */
4109 return uacpi_object_assign(
4110 dst,
4111 item_array_at(&ctx->cur_op_ctx->items, 0)->obj,
4113 );
4114}
4115
4117{
4118 struct call_frame *frame = ctx->cur_frame;
4119
4120 if (frame == UACPI_NULL) {
4121 ctx->cur_op_ctx = UACPI_NULL;
4122 ctx->prev_op_ctx = UACPI_NULL;
4123 ctx->cur_block = UACPI_NULL;
4124 return;
4125 }
4126
4127 ctx->cur_op_ctx = op_context_array_last(&frame->pending_ops);
4128 ctx->prev_op_ctx = op_context_array_one_before_last(&frame->pending_ops);
4129 ctx->cur_block = code_block_array_last(&frame->code_blocks);
4130}
4131
4133{
4134 return ctx->cur_op_ctx && !ctx->cur_op_ctx->preempted;
4135}
4136
4141};
4142
4143static const uacpi_char *const op_trace_action_types[3] = {
4144 [OP_TRACE_ACTION_BEGIN] = "BEGIN",
4145 [OP_TRACE_ACTION_RESUME] = "RESUME",
4146 [OP_TRACE_ACTION_END] = "END",
4147};
4148
4149static inline void trace_op(
4150 const struct uacpi_op_spec *op, enum op_trace_action_type action
4151)
4152{
4154 "%s OP '%s' (0x%04X)\n",
4155 op_trace_action_types[action], op->name, op->code
4156 );
4157}
4158
4159static inline void trace_pop(uacpi_u8 pop)
4160{
4161 uacpi_debug(" pOP: %s (0x%02X)\n", uacpi_parse_op_to_string(pop), pop);
4162}
4163
4165 struct op_context *op_ctx)
4166{
4167 uacpi_size i;
4168
4169 /*
4170 * MethodCall items:
4171 * items[0] -> method namespace node
4172 * items[1] -> immediate that was used for parsing the arguments
4173 * items[2...nargs-1] -> method arguments
4174 * items[-1] -> return value object
4175 *
4176 * Here we only care about the arguments though.
4177 */
4178 for (i = 2; i < item_array_size(&op_ctx->items) - 1; i++) {
4179 uacpi_object *src, *dst;
4180
4181 src = item_array_at(&op_ctx->items, i)->obj;
4182
4186
4187 frame->args[i - 2] = dst;
4188 }
4189
4190 return UACPI_STATUS_OK;
4191}
4192
4194 uacpi_namespace_node *scope,
4196{
4197 struct code_block *block;
4198
4199 block = code_block_array_alloc(&frame->code_blocks);
4202
4203 block->type = CODE_BLOCK_SCOPE;
4204 block->node = scope;
4205 block->begin = 0;
4206 block->end = method->size;
4207 frame->method = method;
4208 frame->cur_scope = scope;
4209 return UACPI_STATUS_OK;
4210}
4211
4213 struct call_frame **out_frame)
4214{
4215 struct call_frame_array *call_stack = &ctx->call_stack;
4216 struct call_frame *prev_frame;
4217
4218 *out_frame = call_frame_array_calloc(call_stack);
4219 if (uacpi_unlikely(*out_frame == UACPI_NULL))
4221
4222 /*
4223 * Allocating a new frame might have reallocated the dynamic buffer so our
4224 * execution_context members might now be pointing to freed memory.
4225 * Refresh them here.
4226 */
4227 prev_frame = call_frame_array_one_before_last(call_stack);
4228 ctx->cur_frame = prev_frame;
4230
4231 return UACPI_STATUS_OK;
4232}
4233
4235{
4236 struct code_block *block = ctx->cur_block;
4237 struct call_frame *cur_frame = ctx->cur_frame;
4238
4239 if (!block)
4240 return UACPI_FALSE;
4241 if (cur_frame->code_offset != block->end)
4242 return UACPI_FALSE;
4243
4244 if (block->type == CODE_BLOCK_WHILE)
4245 cur_frame->code_offset = block->begin;
4246
4248 return UACPI_TRUE;
4249}
4250
4253)
4254{
4256
4257 switch (dst->type) {
4258 case UACPI_OBJECT_DEBUG:
4259 ret = debug_store(src);
4260 break;
4262 ret = store_to_reference(dst, src, wtr_response);
4263 break;
4264
4267 ret = object_assign_with_implicit_cast(dst, src, wtr_response);
4268 break;
4269
4271 // NULL target
4272 if (dst->integer == 0) {
4274 break;
4275 }
4277 default:
4278 uacpi_error("attempted to store to an invalid target: %s\n",
4281 }
4282
4283 return ret;
4284}
4285
4287{
4288 uacpi_object *src, *dst;
4289 struct op_context *op_ctx = ctx->cur_op_ctx;
4290
4291 src = item_array_at(&op_ctx->items, 0)->obj;
4292 dst = item_array_at(&op_ctx->items, 1)->obj;
4293
4294 if (op_ctx->op->code == UACPI_AML_OP_StoreOp) {
4296 uacpi_data_view wtr_response = { 0 };
4297
4298 ret = store_to_target(dst, src, &wtr_response);
4300 return ret;
4301
4302 /*
4303 * This was a write-then-read field access since we got a response
4304 * buffer back from this store. Now we have to return this buffer
4305 * as a prvalue from the StoreOp so that it can be used by AML to
4306 * retrieve the response.
4307 */
4308 if (wtr_response.data != UACPI_NULL) {
4309 uacpi_object *wtr_response_obj;
4310
4311 wtr_response_obj = uacpi_create_object(UACPI_OBJECT_BUFFER);
4312 if (uacpi_unlikely(wtr_response_obj == UACPI_NULL)) {
4313 uacpi_free(wtr_response.data, wtr_response.length);
4315 }
4316
4317 wtr_response_obj->buffer->data = wtr_response.data;
4318 wtr_response_obj->buffer->size = wtr_response.length;
4319
4321 item_array_at(&op_ctx->items, 0)->obj = wtr_response_obj;
4322 }
4323
4324 return ret;
4325 }
4326
4327 if (dst->type != UACPI_OBJECT_REFERENCE)
4329
4331}
4332
4334{
4335 uacpi_object *src, *dst;
4336 struct op_context *op_ctx = ctx->cur_op_ctx;
4337 uacpi_bool field_allowed = UACPI_FALSE;
4338 uacpi_object_type true_src_type;
4340
4341 src = item_array_at(&op_ctx->items, 0)->obj;
4342 dst = item_array_at(&op_ctx->items, 1)->obj;
4343
4344 if (src->type == UACPI_OBJECT_REFERENCE) {
4345 /*
4346 * Increment/Decrement are the only two operators that modify the value
4347 * in-place, thus we need very specific dereference rules here.
4348 *
4349 * Reading buffer fields & field units is only allowed if we were passed
4350 * a namestring directly as opposed to some nested reference chain
4351 * containing a field at the bottom.
4352 */
4353 if (src->flags == UACPI_REFERENCE_KIND_NAMED)
4354 field_allowed = src->inner_object->type != UACPI_OBJECT_REFERENCE;
4355
4357 } // else buffer index
4358
4359 true_src_type = src->type;
4360
4361 switch (true_src_type) {
4363 dst->integer = src->integer;
4364 break;
4367 if (uacpi_unlikely(!field_allowed))
4368 goto out_bad_type;
4369
4370 ret = field_get_read_type(src, &true_src_type);
4372 goto out_bad_type;
4373 if (true_src_type != UACPI_OBJECT_INTEGER)
4374 goto out_bad_type;
4375
4376 if (src->type == UACPI_OBJECT_FIELD_UNIT) {
4378 src->field_unit, &dst->integer, sizeof_int(),
4380 );
4382 return ret;
4383 } else {
4384 uacpi_read_buffer_field(&src->buffer_field, &dst->integer);
4385 }
4386 break;
4388 dst->integer = *buffer_index_cursor(&src->buffer_index);
4389 break;
4390 default:
4391 goto out_bad_type;
4392 }
4393
4394 if (op_ctx->op->code == UACPI_AML_OP_IncrementOp)
4395 dst->integer++;
4396 else
4397 dst->integer--;
4398
4399 return UACPI_STATUS_OK;
4400
4401out_bad_type:
4402 uacpi_error("Increment/Decrement: invalid object type '%s'\n",
4403 uacpi_object_type_to_string(true_src_type));
4405}
4406
4408 struct execution_context *ctx, struct call_frame *new_frame,
4410)
4411{
4413
4415
4416 if (!method->is_serialized)
4417 return ret;
4418
4419 if (uacpi_unlikely(ctx->sync_level > method->sync_level)) {
4421 "cannot invoke method @%p, sync level %d is too low "
4422 "(current is %d)\n",
4423 method, method->sync_level, ctx->sync_level
4424 );
4426 }
4427
4428 if (method->mutex == UACPI_NULL) {
4429 method->mutex = uacpi_create_mutex();
4430 if (uacpi_unlikely(method->mutex == UACPI_NULL))
4432 method->mutex->sync_level = method->sync_level;
4433 }
4434
4436 ret = uacpi_acquire_aml_mutex(method->mutex, 0xFFFF);
4438 return ret;
4439
4440 ret = held_mutexes_array_push(&ctx->held_mutexes, method->mutex);
4443 return ret;
4444 }
4445 }
4446
4447 new_frame->prev_sync_level = ctx->sync_level;
4448 ctx->sync_level = method->sync_level;
4449 return UACPI_STATUS_OK;
4450}
4451
4453{
4454 struct call_frame *frame = ctx->cur_frame;
4455 struct op_context *op_ctx;
4456
4457 op_ctx = op_context_array_calloc(&frame->pending_ops);
4458 if (op_ctx == UACPI_NULL)
4460
4461 op_ctx->op = ctx->cur_op;
4463 return UACPI_STATUS_OK;
4464}
4465
4466static uacpi_bool pop_item(struct op_context *op_ctx)
4467{
4468 struct item *item;
4469
4470 if (item_array_size(&op_ctx->items) == 0)
4471 return UACPI_FALSE;
4472
4473 item = item_array_last(&op_ctx->items);
4474
4475 if (item->type == ITEM_OBJECT)
4477
4480
4481 item_array_pop(&op_ctx->items);
4482 return UACPI_TRUE;
4483}
4484
4485static void pop_op(struct execution_context *ctx)
4486{
4487 struct call_frame *frame = ctx->cur_frame;
4488 struct op_context *cur_op_ctx = ctx->cur_op_ctx;
4489
4490 while (pop_item(cur_op_ctx));
4491
4492 item_array_clear(&cur_op_ctx->items);
4493 op_context_array_pop(&frame->pending_ops);
4495}
4496
4497static void call_frame_clear(struct call_frame *frame)
4498{
4499 uacpi_size i;
4500 op_context_array_clear(&frame->pending_ops);
4501 code_block_array_clear(&frame->code_blocks);
4502
4503 while (temp_namespace_node_array_size(&frame->temp_nodes) != 0) {
4505
4506 node = *temp_namespace_node_array_last(&frame->temp_nodes);
4508 temp_namespace_node_array_pop(&frame->temp_nodes);
4509 }
4510 temp_namespace_node_array_clear(&frame->temp_nodes);
4511
4512 for (i = 0; i < 7; ++i)
4513 uacpi_object_unref(frame->args[i]);
4514 for (i = 0; i < 8; ++i)
4515 uacpi_object_unref(frame->locals[i]);
4516
4517 uacpi_method_unref(frame->method);
4518}
4519
4552};
4553
4554static const uacpi_u8 *op_decode_cursor(const struct op_context *ctx)
4555{
4556 const struct uacpi_op_spec *spec = ctx->op;
4557
4559 return &spec->indirect_decode_ops[ctx->pc];
4560
4561 return &spec->decode_ops[ctx->pc];
4562}
4563
4565{
4566 uacpi_u8 byte;
4567
4568 byte = *op_decode_cursor(ctx);
4569 ctx->pc++;
4570
4571 return byte;
4572}
4573
4575{
4576 uacpi_aml_op op = 0;
4577
4578 op |= op_decode_byte(op_ctx);
4579 op |= op_decode_byte(op_ctx) << 8;
4580
4581 return op;
4582}
4583
4584// MSVC doesn't support __VA_OPT__ so we do this weirdness
4585#define EXEC_OP_DO_LVL(lvl, reason, ...) \
4586 uacpi_##lvl("Op 0x%04X ('%s'): "reason"\n", \
4587 op_ctx->op->code, op_ctx->op->name __VA_ARGS__)
4588
4589#define EXEC_OP_DO_ERR(reason, ...) EXEC_OP_DO_LVL(error, reason, __VA_ARGS__)
4590#define EXEC_OP_DO_WARN(reason, ...) EXEC_OP_DO_LVL(warn, reason, __VA_ARGS__)
4591
4592#define EXEC_OP_ERR_2(reason, arg0, arg1) EXEC_OP_DO_ERR(reason, ,arg0, arg1)
4593#define EXEC_OP_ERR_1(reason, arg0) EXEC_OP_DO_ERR(reason, ,arg0)
4594#define EXEC_OP_ERR(reason) EXEC_OP_DO_ERR(reason)
4595
4596#define EXEC_OP_WARN(reason) EXEC_OP_DO_WARN(reason)
4597
4598#define SPEC_SIMPLE_NAME "SimpleName := NameString | ArgObj | LocalObj"
4599#define SPEC_SUPER_NAME \
4600 "SuperName := SimpleName | DebugObj | ReferenceTypeOpcode"
4601#define SPEC_TERM_ARG \
4602 "TermArg := ExpressionOpcode | DataObject | ArgObj | LocalObj"
4603#define SPEC_OPERAND "Operand := TermArg => Integer"
4604#define SPEC_STRING "String := TermArg => String"
4605#define SPEC_TARGET "Target := SuperName | NullName"
4606
4607#define SPEC_COMPUTATIONAL_DATA \
4608 "ComputationalData := ByteConst | WordConst | DWordConst | QWordConst " \
4609 "| String | ConstObj | RevisionOp | DefBuffer"
4610
4612{
4613 switch (op) {
4618 return UACPI_TRUE;
4619 default:
4620 return UACPI_FALSE;
4621 }
4622}
4623
4625{
4626 switch (op) {
4632 return UACPI_TRUE;
4633 default:
4634 return UACPI_FALSE;
4635 }
4636}
4637
4639{
4640 switch (op) {
4644 return UACPI_TRUE;
4645 default:
4646 return UACPI_FALSE;
4647 }
4648}
4649
4651{
4652 switch (op) {
4655 return UACPI_TRUE;
4656 default:
4657 return UACPI_FALSE;
4658 }
4659}
4660
4661static uacpi_status op_typecheck(const struct op_context *op_ctx,
4662 const struct op_context *cur_op_ctx)
4663{
4664 const uacpi_char *expected_type_str;
4665 uacpi_u8 ok_mask = 0;
4666 uacpi_u8 props = cur_op_ctx->op->properties;
4667
4668 switch (*op_decode_cursor(op_ctx)) {
4669 // SimpleName := NameString | ArgObj | LocalObj
4671 expected_type_str = SPEC_SIMPLE_NAME;
4673 break;
4674
4675 // Target := SuperName | NullName
4677 expected_type_str = SPEC_TARGET;
4679 break;
4680
4681 // SuperName := SimpleName | DebugObj | ReferenceTypeOpcode
4684 expected_type_str = SPEC_SUPER_NAME;
4685 ok_mask |= UACPI_OP_PROPERTY_SUPERNAME;
4686 break;
4687
4688 // TermArg := ExpressionOpcode | DataObject | ArgObj | LocalObj
4696 expected_type_str = SPEC_TERM_ARG;
4697 ok_mask |= UACPI_OP_PROPERTY_TERM_ARG;
4698 break;
4699 default:
4701 }
4702
4703 if (!(props & ok_mask)) {
4704 EXEC_OP_ERR_2("invalid argument: '%s', expected a %s",
4705 cur_op_ctx->op->name, expected_type_str);
4707 }
4708
4709 return UACPI_STATUS_OK;
4710}
4711
4713 const struct op_context *op_ctx,
4714 const uacpi_object *obj,
4715 enum uacpi_object_type expected_type,
4716 const uacpi_char *spec_desc
4717)
4718{
4719 if (uacpi_likely(obj->type == expected_type))
4720 return UACPI_STATUS_OK;
4721
4722 EXEC_OP_ERR_2("invalid argument type: %s, expected a %s",
4723 uacpi_object_type_to_string(obj->type), spec_desc);
4725}
4726
4728 const struct op_context *op_ctx,
4729 const uacpi_object *obj
4730)
4731{
4733}
4734
4736 const struct op_context *op_ctx,
4737 const uacpi_object *obj
4738)
4739{
4741}
4742
4744 const struct op_context *op_ctx,
4745 const uacpi_object *obj
4746)
4747{
4748 switch (obj->type) {
4752 return UACPI_STATUS_OK;
4753 default:
4755 "invalid argument type: %s, expected a %s",
4758 );
4760 }
4761}
4762
4763static void emit_op_skip_warn(const struct op_context *op_ctx)
4764{
4765 EXEC_OP_WARN("skipping due to previous errors");
4766}
4767
4769 struct call_frame *frame, uacpi_size offset, enum uacpi_parse_op op,
4771)
4772{
4773 static const uacpi_char *oom_prefix = "<...>";
4774 static const uacpi_char *empty_string = "";
4775 static const uacpi_char *unknown_path = "<unknown-path>";
4776 static const uacpi_char *invalid_path = "<invalid-path>";
4777
4778 uacpi_status conv_ret;
4779 const uacpi_char *action;
4780 const uacpi_char *requested_path_to_print;
4781 const uacpi_char *middle_part = UACPI_NULL;
4782 const uacpi_char *prefix_path = UACPI_NULL;
4783 uacpi_char *requested_path = UACPI_NULL;
4785 uacpi_bool is_create;
4786
4787 is_create = op == UACPI_PARSE_OP_CREATE_NAMESTRING ||
4789
4790 if (is_create)
4791 action = "create";
4792 else
4793 action = "lookup";
4794
4795 conv_ret = name_string_to_path(
4796 frame, offset, &requested_path, &length
4797 );
4798 if (uacpi_unlikely_error(conv_ret)) {
4799 if (conv_ret == UACPI_STATUS_OUT_OF_MEMORY)
4800 requested_path_to_print = unknown_path;
4801 else
4802 requested_path_to_print = invalid_path;
4803 } else {
4804 requested_path_to_print = requested_path;
4805 }
4806
4807 if (requested_path && requested_path[0] != '\\') {
4809 frame->cur_scope
4810 );
4811 if (uacpi_unlikely(prefix_path == UACPI_NULL))
4812 prefix_path = oom_prefix;
4813
4814 if (prefix_path[1] != '\0')
4815 middle_part = ".";
4816 } else {
4817 prefix_path = empty_string;
4818 }
4819
4820 if (middle_part == UACPI_NULL)
4821 middle_part = empty_string;
4822
4823 if (length == 5 && !is_create) {
4825 level,
4826 "unable to %s named object '%s' within (or above) "
4827 "scope '%s': %s\n", action, requested_path_to_print,
4828 prefix_path, uacpi_status_to_string(ret)
4829 );
4830 } else {
4832 level,
4833 "unable to %s named object '%s%s%s': %s\n",
4834 action, prefix_path, middle_part,
4835 requested_path_to_print, uacpi_status_to_string(ret)
4836 );
4837 }
4838
4839 uacpi_free(requested_path, length);
4840 if (prefix_path != oom_prefix && prefix_path != empty_string)
4841 uacpi_free_dynamic_string(prefix_path);
4842}
4843
4845{
4846 struct op_context *op_ctx = ctx->cur_op_ctx;
4847
4848 EXEC_OP_ERR("no dedicated handler installed");
4850}
4851
4898};
4899
4901 /*
4902 * All OPs that don't have a handler dispatch to here if
4903 * UACPI_PARSE_OP_INVOKE_HANDLER is reached.
4904 */
4950};
4951
4953 [UACPI_AML_OP_Local0Op] = OP_HANDLER_LOCAL,
4954 [UACPI_AML_OP_Local1Op] = OP_HANDLER_LOCAL,
4955 [UACPI_AML_OP_Local2Op] = OP_HANDLER_LOCAL,
4956 [UACPI_AML_OP_Local3Op] = OP_HANDLER_LOCAL,
4957 [UACPI_AML_OP_Local4Op] = OP_HANDLER_LOCAL,
4958 [UACPI_AML_OP_Local5Op] = OP_HANDLER_LOCAL,
4959 [UACPI_AML_OP_Local6Op] = OP_HANDLER_LOCAL,
4960 [UACPI_AML_OP_Local7Op] = OP_HANDLER_LOCAL,
4961
4962 [UACPI_AML_OP_Arg0Op] = OP_HANDLER_ARG,
4963 [UACPI_AML_OP_Arg1Op] = OP_HANDLER_ARG,
4964 [UACPI_AML_OP_Arg2Op] = OP_HANDLER_ARG,
4965 [UACPI_AML_OP_Arg3Op] = OP_HANDLER_ARG,
4966 [UACPI_AML_OP_Arg4Op] = OP_HANDLER_ARG,
4967 [UACPI_AML_OP_Arg5Op] = OP_HANDLER_ARG,
4968 [UACPI_AML_OP_Arg6Op] = OP_HANDLER_ARG,
4969
4970 [UACPI_AML_OP_StringPrefix] = OP_HANDLER_STRING,
4971
4972 [UACPI_AML_OP_AddOp] = OP_HANDLER_BINARY_MATH,
4973 [UACPI_AML_OP_SubtractOp] = OP_HANDLER_BINARY_MATH,
4974 [UACPI_AML_OP_MultiplyOp] = OP_HANDLER_BINARY_MATH,
4975 [UACPI_AML_OP_DivideOp] = OP_HANDLER_BINARY_MATH,
4976 [UACPI_AML_OP_ShiftLeftOp] = OP_HANDLER_BINARY_MATH,
4977 [UACPI_AML_OP_ShiftRightOp] = OP_HANDLER_BINARY_MATH,
4978 [UACPI_AML_OP_AndOp] = OP_HANDLER_BINARY_MATH,
4979 [UACPI_AML_OP_NandOp] = OP_HANDLER_BINARY_MATH,
4980 [UACPI_AML_OP_OrOp] = OP_HANDLER_BINARY_MATH,
4981 [UACPI_AML_OP_NorOp] = OP_HANDLER_BINARY_MATH,
4982 [UACPI_AML_OP_XorOp] = OP_HANDLER_BINARY_MATH,
4983 [UACPI_AML_OP_ModOp] = OP_HANDLER_BINARY_MATH,
4984
4985 [UACPI_AML_OP_IfOp] = OP_HANDLER_CODE_BLOCK,
4986 [UACPI_AML_OP_ElseOp] = OP_HANDLER_CODE_BLOCK,
4987 [UACPI_AML_OP_WhileOp] = OP_HANDLER_CODE_BLOCK,
4988 [UACPI_AML_OP_ScopeOp] = OP_HANDLER_CODE_BLOCK,
4989
4990 [UACPI_AML_OP_ContinueOp] = OP_HANDLER_CONTROL_FLOW,
4991 [UACPI_AML_OP_BreakOp] = OP_HANDLER_CONTROL_FLOW,
4992
4993 [UACPI_AML_OP_ReturnOp] = OP_HANDLER_RETURN,
4994
4995 [UACPI_AML_OP_MethodOp] = OP_HANDLER_CREATE_METHOD,
4996
4997 [UACPI_AML_OP_StoreOp] = OP_HANDLER_COPY_OBJECT_OR_STORE,
4998 [UACPI_AML_OP_CopyObjectOp] = OP_HANDLER_COPY_OBJECT_OR_STORE,
4999
5000 [UACPI_AML_OP_IncrementOp] = OP_HANDLER_INC_DEC,
5001 [UACPI_AML_OP_DecrementOp] = OP_HANDLER_INC_DEC,
5002
5003 [UACPI_AML_OP_RefOfOp] = OP_HANDLER_REF_OR_DEREF_OF,
5004 [UACPI_AML_OP_DerefOfOp] = OP_HANDLER_REF_OR_DEREF_OF,
5005
5006 [UACPI_AML_OP_LnotOp] = OP_HANDLER_LOGICAL_NOT,
5007
5008 [UACPI_AML_OP_LEqualOp] = OP_HANDLER_BINARY_LOGIC,
5009 [UACPI_AML_OP_LandOp] = OP_HANDLER_BINARY_LOGIC,
5010 [UACPI_AML_OP_LorOp] = OP_HANDLER_BINARY_LOGIC,
5011 [UACPI_AML_OP_LGreaterOp] = OP_HANDLER_BINARY_LOGIC,
5012 [UACPI_AML_OP_LLessOp] = OP_HANDLER_BINARY_LOGIC,
5013
5014 [UACPI_AML_OP_InternalOpNamedObject] = OP_HANDLER_NAMED_OBJECT,
5015
5016 [UACPI_AML_OP_BufferOp] = OP_HANDLER_BUFFER,
5017
5018 [UACPI_AML_OP_PackageOp] = OP_HANDLER_PACKAGE,
5019 [UACPI_AML_OP_VarPackageOp] = OP_HANDLER_PACKAGE,
5020
5021 [UACPI_AML_OP_NameOp] = OP_HANDLER_CREATE_NAMED,
5022
5023 [UACPI_AML_OP_CreateBitFieldOp] = OP_HANDLER_CREATE_BUFFER_FIELD,
5024 [UACPI_AML_OP_CreateByteFieldOp] = OP_HANDLER_CREATE_BUFFER_FIELD,
5025 [UACPI_AML_OP_CreateWordFieldOp] = OP_HANDLER_CREATE_BUFFER_FIELD,
5026 [UACPI_AML_OP_CreateDWordFieldOp] = OP_HANDLER_CREATE_BUFFER_FIELD,
5027 [UACPI_AML_OP_CreateQWordFieldOp] = OP_HANDLER_CREATE_BUFFER_FIELD,
5028
5029 [UACPI_AML_OP_InternalOpReadFieldAsBuffer] = OP_HANDLER_READ_FIELD,
5030 [UACPI_AML_OP_InternalOpReadFieldAsInteger] = OP_HANDLER_READ_FIELD,
5031
5032 [UACPI_AML_OP_ToIntegerOp] = OP_HANDLER_TO,
5033 [UACPI_AML_OP_ToBufferOp] = OP_HANDLER_TO,
5034 [UACPI_AML_OP_ToDecimalStringOp] = OP_HANDLER_TO,
5035 [UACPI_AML_OP_ToHexStringOp] = OP_HANDLER_TO,
5036 [UACPI_AML_OP_ToStringOp] = OP_HANDLER_TO_STRING,
5037
5038 [UACPI_AML_OP_AliasOp] = OP_HANDLER_ALIAS,
5039
5040 [UACPI_AML_OP_ConcatOp] = OP_HANDLER_CONCATENATE,
5041 [UACPI_AML_OP_ConcatResOp] = OP_HANDLER_CONCATENATE_RES,
5042
5043 [UACPI_AML_OP_SizeOfOp] = OP_HANDLER_SIZEOF,
5044
5045 [UACPI_AML_OP_NotOp] = OP_HANDLER_UNARY_MATH,
5046 [UACPI_AML_OP_FindSetLeftBitOp] = OP_HANDLER_UNARY_MATH,
5047 [UACPI_AML_OP_FindSetRightBitOp] = OP_HANDLER_UNARY_MATH,
5048
5049 [UACPI_AML_OP_IndexOp] = OP_HANDLER_INDEX,
5050
5051 [UACPI_AML_OP_ObjectTypeOp] = OP_HANDLER_OBJECT_TYPE,
5052
5053 [UACPI_AML_OP_MidOp] = OP_HANDLER_MID,
5054
5055 [UACPI_AML_OP_MatchOp] = OP_HANDLER_MATCH,
5056
5057 [UACPI_AML_OP_NotifyOp] = OP_HANDLER_NOTIFY,
5058
5059 [UACPI_AML_OP_BreakPointOp] = OP_HANDLER_FIRMWARE_REQUEST,
5060};
5061
5062#define EXT_OP_IDX(op) (op & 0xFF)
5063
5065 [EXT_OP_IDX(UACPI_AML_OP_CreateFieldOp)] = OP_HANDLER_CREATE_BUFFER_FIELD,
5066 [EXT_OP_IDX(UACPI_AML_OP_CondRefOfOp)] = OP_HANDLER_REF_OR_DEREF_OF,
5067 [EXT_OP_IDX(UACPI_AML_OP_OpRegionOp)] = OP_HANDLER_CREATE_OP_REGION,
5068 [EXT_OP_IDX(UACPI_AML_OP_DeviceOp)] = OP_HANDLER_CODE_BLOCK,
5069 [EXT_OP_IDX(UACPI_AML_OP_ProcessorOp)] = OP_HANDLER_CODE_BLOCK,
5070 [EXT_OP_IDX(UACPI_AML_OP_PowerResOp)] = OP_HANDLER_CODE_BLOCK,
5071 [EXT_OP_IDX(UACPI_AML_OP_ThermalZoneOp)] = OP_HANDLER_CODE_BLOCK,
5072 [EXT_OP_IDX(UACPI_AML_OP_TimerOp)] = OP_HANDLER_TIMER,
5073 [EXT_OP_IDX(UACPI_AML_OP_MutexOp)] = OP_HANDLER_CREATE_MUTEX_OR_EVENT,
5074 [EXT_OP_IDX(UACPI_AML_OP_EventOp)] = OP_HANDLER_CREATE_MUTEX_OR_EVENT,
5075
5076 [EXT_OP_IDX(UACPI_AML_OP_FieldOp)] = OP_HANDLER_CREATE_FIELD,
5077 [EXT_OP_IDX(UACPI_AML_OP_IndexFieldOp)] = OP_HANDLER_CREATE_FIELD,
5078 [EXT_OP_IDX(UACPI_AML_OP_BankFieldOp)] = OP_HANDLER_CREATE_FIELD,
5079
5080 [EXT_OP_IDX(UACPI_AML_OP_FromBCDOp)] = OP_HANDLER_BCD,
5081 [EXT_OP_IDX(UACPI_AML_OP_ToBCDOp)] = OP_HANDLER_BCD,
5082
5083 [EXT_OP_IDX(UACPI_AML_OP_DataRegionOp)] = OP_HANDLER_CREATE_DATA_REGION,
5084
5085 [EXT_OP_IDX(UACPI_AML_OP_LoadTableOp)] = OP_HANDLER_LOAD_TABLE,
5086 [EXT_OP_IDX(UACPI_AML_OP_LoadOp)] = OP_HANDLER_LOAD,
5087 [EXT_OP_IDX(UACPI_AML_OP_UnloadOp)] = OP_HANDLER_UNLOAD,
5088
5089 [EXT_OP_IDX(UACPI_AML_OP_StallOp)] = OP_HANDLER_STALL_OR_SLEEP,
5090 [EXT_OP_IDX(UACPI_AML_OP_SleepOp)] = OP_HANDLER_STALL_OR_SLEEP,
5091
5092 [EXT_OP_IDX(UACPI_AML_OP_SignalOp)] = OP_HANDLER_EVENT_CTL,
5093 [EXT_OP_IDX(UACPI_AML_OP_ResetOp)] = OP_HANDLER_EVENT_CTL,
5094 [EXT_OP_IDX(UACPI_AML_OP_WaitOp)] = OP_HANDLER_EVENT_CTL,
5095
5096 [EXT_OP_IDX(UACPI_AML_OP_AcquireOp)] = OP_HANDLER_MUTEX_CTL,
5097 [EXT_OP_IDX(UACPI_AML_OP_ReleaseOp)] = OP_HANDLER_MUTEX_CTL,
5098
5099 [EXT_OP_IDX(UACPI_AML_OP_FatalOp)] = OP_HANDLER_FIRMWARE_REQUEST,
5100};
5101
5106};
5107
5112)
5113{
5115 struct call_frame *frame;
5116
5117 if (uacpi_unlikely(call_frame_array_size(&ctx->call_stack) >=
5118 g_uacpi_rt_ctx.max_call_stack_depth))
5120
5121 ret = push_new_frame(ctx, &frame);
5123 return ret;
5124
5125 ret = enter_method(ctx, frame, method);
5127 goto method_dispatch_error;
5128
5129 if (type == METHOD_CALL_NATIVE) {
5130 uacpi_u8 arg_count;
5131
5132 arg_count = args ? args->count : 0;
5133 if (uacpi_unlikely(arg_count != method->args)) {
5135 "invalid number of arguments %zu to call %.4s, expected %d\n",
5136 args ? args->count : 0, node->name.text, method->args
5137 );
5138
5140 goto method_dispatch_error;
5141 }
5142
5143 if (args != UACPI_NULL) {
5144 uacpi_u8 i;
5145
5146 for (i = 0; i < method->args; ++i) {
5147 frame->args[i] = args->objects[i];
5148 uacpi_object_ref(args->objects[i]);
5149 }
5150 }
5151 } else if (type == METHOD_CALL_AML) {
5152 ret = frame_push_args(frame, ctx->cur_op_ctx);
5154 goto method_dispatch_error;
5155 }
5156
5159 goto method_dispatch_error;
5160
5161 ctx->cur_frame = frame;
5162 ctx->cur_op_ctx = UACPI_NULL;
5163 ctx->prev_op_ctx = UACPI_NULL;
5164 ctx->cur_block = code_block_array_last(&ctx->cur_frame->code_blocks);
5165
5166 if (method->native_call) {
5168
5171 goto method_dispatch_error;
5172
5173 return method->handler(ctx, retval);
5174 }
5175
5176 return UACPI_STATUS_OK;
5177
5178method_dispatch_error:
5179 call_frame_clear(frame);
5180 call_frame_array_pop(&ctx->call_stack);
5181 return ret;
5182}
5183
5185 struct call_frame *frame, struct op_context *op_ctx
5186)
5187{
5188 struct item *item;
5189
5190 if (op_ctx->tracked_pkg_idx == 0)
5191 return;
5192
5193 item = item_array_at(&op_ctx->items, op_ctx->tracked_pkg_idx - 1);
5194 frame->code_offset = item->pkg.end;
5195}
5196
5198{
5200 struct call_frame *frame = ctx->cur_frame;
5201 struct op_context *op_ctx;
5202 struct item *item = UACPI_NULL;
5203 enum uacpi_parse_op prev_op = 0, op;
5204
5205 /*
5206 * Allocate a new op context if previous is preempted (looking for a
5207 * dynamic argument), or doesn't exist at all.
5208 */
5210 ret = push_op(ctx);
5212 return ret;
5213 } else {
5214 trace_op(ctx->cur_op_ctx->op, OP_TRACE_ACTION_RESUME);
5215 }
5216
5217 if (ctx->prev_op_ctx)
5218 prev_op = *op_decode_cursor(ctx->prev_op_ctx);
5219
5220 for (;;) {
5222 return ret;
5223
5224 op_ctx = ctx->cur_op_ctx;
5225 frame = ctx->cur_frame;
5226
5227 if (op_ctx->pc == 0 && ctx->prev_op_ctx) {
5228 /*
5229 * Type check the current arg type against what is expected by the
5230 * preempted op. This check is able to catch most type violations
5231 * with the only exception being Operand as we only know whether
5232 * that evaluates to an integer after the fact.
5233 */
5234 ret = op_typecheck(ctx->prev_op_ctx, ctx->cur_op_ctx);
5236 return ret;
5237 }
5238
5239 op = op_decode_byte(op_ctx);
5240 trace_pop(op);
5241
5243 item = item_array_alloc(&op_ctx->items);
5246
5248 if (item->type == ITEM_OBJECT) {
5250
5252 type = op_decode_byte(op_ctx);
5253
5257 } else {
5259 }
5260 } else if (item == UACPI_NULL) {
5261 item = item_array_last(&op_ctx->items);
5262 }
5263
5264 switch (op) {
5265 case UACPI_PARSE_OP_END:
5267 trace_op(ctx->cur_op_ctx->op, OP_TRACE_ACTION_END);
5268
5270 uacpi_u8 idx;
5271
5272 idx = op_decode_byte(op_ctx);
5273 if (item_array_at(&op_ctx->items, idx)->handle != UACPI_NULL)
5274 break;
5275
5276 emit_op_skip_warn(op_ctx);
5277 }
5278
5279 apply_tracked_pkg(frame, op_ctx);
5280
5281 pop_op(ctx);
5282 if (ctx->cur_op_ctx) {
5283 ctx->cur_op_ctx->preempted = UACPI_FALSE;
5284 ctx->cur_op_ctx->pc++;
5285 }
5286
5287 return UACPI_STATUS_OK;
5288 }
5289
5291 emit_op_skip_warn(op_ctx);
5292 break;
5293
5305 /*
5306 * Preempt this op parsing for now as we wait for the dynamic arg
5307 * to be parsed.
5308 */
5309 op_ctx->preempted = UACPI_TRUE;
5310 op_ctx->pc--;
5311 return UACPI_STATUS_OK;
5312
5314 op_ctx->tracked_pkg_idx = item_array_size(&op_ctx->items);
5317 ret = parse_package_length(frame, &item->pkg);
5318 break;
5319
5322 void *dst;
5323 uacpi_u8 src_width;
5324
5327 dst = &item->obj->integer;
5328 src_width = 8;
5329 } else {
5330 dst = &item->immediate;
5331 src_width = op_decode_byte(op_ctx);
5332 }
5333
5335 dst, op_decode_cursor(op_ctx),
5336 sizeof(uacpi_u64), src_width
5337 );
5338 op_ctx->pc += src_width;
5339 break;
5340 }
5341
5343 break;
5344
5348 void *dst;
5349
5350 width = op_decode_byte(op_ctx);
5353
5356 item->obj->integer = 0;
5357 dst = &item->obj->integer;
5358 } else {
5360 }
5361
5363 frame->code_offset += width;
5364 break;
5365 }
5366
5370 obj->type = UACPI_OBJECT_INTEGER;
5371 obj->integer = op == UACPI_PARSE_OP_LOAD_FALSE_OBJECT ? 0 : ones();
5372 break;
5373 }
5374
5376 item->immediate = frame->code_offset;
5377 break;
5378
5381 break;
5382
5384 enum uacpi_object_type expected_type;
5385
5386 expected_type = op_decode_byte(op_ctx);
5387
5388 if (uacpi_unlikely(item->obj->type != expected_type)) {
5389 EXEC_OP_ERR_2("bad object type: expected %s, got %s!",
5390 uacpi_object_type_to_string(expected_type),
5393 }
5394
5395 break;
5396 }
5397
5400 EXEC_OP_ERR("invalid/unexpected opcode");
5402 break;
5403
5405 frame->code_offset--;
5406 break;
5407
5409 item_array_at(&op_ctx->items, op_decode_byte(op_ctx))->immediate--;
5410 break;
5411
5413 pop_item(op_ctx);
5414 item = item_array_last(&op_ctx->items);
5415 break;
5416
5418 uacpi_size pkg_idx = op_ctx->tracked_pkg_idx - 1;
5419 struct package_length *pkg;
5420 uacpi_u8 bytes_skip;
5421
5422 bytes_skip = op_decode_byte(op_ctx);
5423 pkg = &item_array_at(&op_ctx->items, pkg_idx)->pkg;
5424
5425 if (frame->code_offset >= pkg->end)
5426 op_ctx->pc += bytes_skip;
5427
5428 break;
5429 }
5430
5435 uacpi_u8 idx, bytes_skip;
5436 uacpi_bool is_null, skip_if_null;
5437
5441 } else {
5442 idx = op_decode_byte(op_ctx);
5443 is_null = item_array_at(&op_ctx->items, idx)->handle == UACPI_NULL;
5444 }
5445
5446 bytes_skip = op_decode_byte(op_ctx);
5447 skip_if_null = op == UACPI_PARSE_OP_IF_NOT_NULL ||
5449
5450 if (is_null == skip_if_null)
5451 op_ctx->pc += bytes_skip;
5452
5453 break;
5454 }
5455
5457 uacpi_u8 value, bytes_skip;
5458
5459 value = op_decode_byte(op_ctx);
5460 bytes_skip = op_decode_byte(op_ctx);
5461
5462 if (item->immediate != value)
5463 op_ctx->pc += bytes_skip;
5464
5465 break;
5466 }
5467
5470 uacpi_u8 bytes_skip;
5471 uacpi_bool is_false, skip_if_false;
5472
5473 bytes_skip = op_decode_byte(op_ctx);
5474 is_false = item->obj->integer == 0;
5475 skip_if_false = op == UACPI_PARSE_OP_IF_LAST_TRUE;
5476
5477 if (is_false == skip_if_false)
5478 op_ctx->pc += bytes_skip;
5479
5480 break;
5481 }
5482
5483 case UACPI_PARSE_OP_JMP: {
5484 op_ctx->pc = op_decode_byte(op_ctx);
5485 break;
5486 }
5487
5493 uacpi_size offset = frame->code_offset;
5494 enum resolve_behavior behavior;
5495
5499 else
5501
5502 ret = resolve_name_string(frame, behavior, &item->node);
5503
5504 if (ret == UACPI_STATUS_NOT_FOUND) {
5505 uacpi_bool is_ok;
5506
5507 if (prev_op) {
5508 is_ok = op_allows_unresolved(prev_op);
5509 is_ok &= op_allows_unresolved(op);
5510 } else {
5511 // This is the only standalone op where we allow unresolved
5512 is_ok = op_ctx->op->code == UACPI_AML_OP_ExternalOp;
5513 }
5514
5515 if (is_ok)
5517 }
5518
5521 uacpi_status trace_ret = ret;
5522 uacpi_bool abort_whileif = UACPI_FALSE;
5523
5524 if (frame->method->named_objects_persist &&
5527 struct op_context *first_ctx;
5528
5529 first_ctx = op_context_array_at(&frame->pending_ops, 0);
5530 abort_whileif = first_ctx->op->code == UACPI_AML_OP_WhileOp ||
5531 first_ctx->op->code == UACPI_AML_OP_IfOp;
5532
5533 if (op_allows_unresolved_if_load(op) || abort_whileif) {
5534 lvl = UACPI_LOG_WARN;
5536 }
5537 }
5538
5540 frame, offset, op, trace_ret, lvl
5541 );
5542
5543 if (abort_whileif) {
5544 while (op_context_array_size(&frame->pending_ops) != 1)
5545 pop_op(ctx);
5546
5547 op_ctx = op_context_array_at(&frame->pending_ops, 0);
5548 op_ctx->pc++;
5549 op_ctx->preempted = UACPI_FALSE;
5550 break;
5551 }
5552
5555 }
5556
5558 !frame->method->named_objects_persist)
5560
5561 break;
5562 }
5563
5565 uacpi_aml_op code = op_ctx->op->code;
5566 uacpi_u8 idx;
5567
5568 if (code <= 0xFF)
5570 else
5572
5573 ret = op_handlers[idx](ctx);
5574 break;
5575 }
5576
5578 item = item_array_at(&op_ctx->items, op_decode_byte(op_ctx));
5579 ret = do_install_node_item(frame, item);
5580 break;
5581
5585 struct item *dst;
5586
5587 if (!ctx->prev_op_ctx)
5588 break;
5589
5590 switch (prev_op) {
5596
5597 if (prev_op == UACPI_PARSE_OP_OPERAND)
5598 ret = typecheck_operand(ctx->prev_op_ctx, src);
5599 else if (prev_op == UACPI_PARSE_OP_STRING)
5600 ret = typecheck_string(ctx->prev_op_ctx, src);
5601 else if (prev_op == UACPI_PARSE_OP_COMPUTATIONAL_DATA)
5602 ret = typecheck_computational_data(ctx->prev_op_ctx, src);
5603
5604 break;
5607 src = item->obj;
5608 break;
5609
5615 src = item->obj;
5616 break;
5617
5618 default:
5619 EXEC_OP_ERR_1("don't know how to copy/transfer object to %d",
5620 prev_op);
5622 break;
5623 }
5624
5626 dst = item_array_last(&ctx->prev_op_ctx->items);
5627 dst->type = ITEM_OBJECT;
5628
5630 dst->obj = src;
5631 uacpi_object_ref(dst->obj);
5632 } else {
5634 if (uacpi_unlikely(dst->obj == UACPI_NULL)) {
5636 break;
5637 }
5638
5641 }
5642 }
5643 break;
5644 }
5645
5648 uacpi_object *dst, *src;
5649
5650 dst = item_array_at(&op_ctx->items, op_decode_byte(op_ctx))->obj;
5651
5653 src = item_array_at(&op_ctx->items,
5654 op_decode_byte(op_ctx))->obj;
5655 } else {
5656 src = item->obj;
5657 }
5658
5660 break;
5661 }
5662
5663 // Nothing to do here, object is allocated automatically
5667 break;
5668
5672 enum uacpi_assign_behavior behavior;
5673
5674 item_array_pop(&op_ctx->items);
5675 item = item_array_last(&op_ctx->items);
5676
5679 else
5681
5682 ret = uacpi_object_assign(temp, item->obj, behavior);
5684 break;
5685
5687 item->obj = temp;
5688 break;
5689 }
5690
5692 struct uacpi_namespace_node *node;
5694
5695 node = item_array_at(&op_ctx->items, 0)->node;
5697
5700 );
5701 return ret;
5702 }
5703
5705 struct uacpi_namespace_node *node;
5707
5708 node = item_array_at(&op_ctx->items, 0)->node;
5709 method = item_array_at(&op_ctx->items, 1)->obj->method;
5710
5713 );
5714 return ret;
5715 }
5716
5718 uacpi_aml_op new_op = UACPI_AML_OP_InternalOpNamedObject;
5720
5721 if (item->node == UACPI_NULL) {
5722 if (!op_allows_unresolved(prev_op))
5724 break;
5725 }
5726
5728
5729 switch (obj->type) {
5730 case UACPI_OBJECT_METHOD: {
5731 uacpi_bool should_invoke;
5732
5733 switch (prev_op) {
5736 should_invoke = UACPI_FALSE;
5737 break;
5738 default:
5739 should_invoke = !op_wants_supername(prev_op);
5740 }
5741
5742 if (!should_invoke)
5743 break;
5744
5745 new_op = UACPI_AML_OP_InternalOpMethodCall0Args;
5746 new_op += obj->method->args;
5747 break;
5748 }
5749
5753
5754 if (!op_wants_term_arg_or_operand(prev_op))
5755 break;
5756
5759 const uacpi_char *field_path;
5760
5762 item->node
5763 );
5764
5766 "unable to perform a read from field %s: "
5767 "parent opregion gone\n", field_path
5768 );
5769 uacpi_free_absolute_path(field_path);
5770 }
5771
5772 switch (type) {
5774 new_op = UACPI_AML_OP_InternalOpReadFieldAsBuffer;
5775 break;
5777 new_op = UACPI_AML_OP_InternalOpReadFieldAsInteger;
5778 break;
5779 default:
5781 continue;
5782 }
5783 break;
5784 }
5785 default:
5786 break;
5787 }
5788
5789 op_ctx->pc = 0;
5790 op_ctx->op = uacpi_get_op_spec(new_op);
5791 break;
5792 }
5793
5795 uacpi_aml_op op, target_op;
5796 uacpi_u32 cur_offset;
5797 uacpi_u8 op_length;
5798
5799 cur_offset = frame->code_offset;
5800 apply_tracked_pkg(frame, op_ctx);
5801 op_length = peek_next_op(frame, &op);
5802
5803 target_op = op_decode_aml_op(op_ctx);
5804 if (op_length == 0 || op != target_op) {
5805 // Revert tracked package
5806 frame->code_offset = cur_offset;
5807 break;
5808 }
5809
5810 frame->code_offset += op_length;
5811 op_ctx->switched_from = op_ctx->op->code;
5812 op_ctx->op = uacpi_get_op_spec(target_op);
5813 op_ctx->pc = 0;
5814 break;
5815 }
5816
5818 uacpi_aml_op target_op;
5819 uacpi_u8 skip_bytes;
5820
5821 target_op = op_decode_aml_op(op_ctx);
5822 skip_bytes = op_decode_byte(op_ctx);
5823
5824 if (op_ctx->switched_from != target_op)
5825 op_ctx->pc += skip_bytes;
5826 break;
5827 }
5828
5829 default:
5830 EXEC_OP_ERR_1("unhandled parser op '%d'", op);
5832 break;
5833 }
5834 }
5835}
5836
5838{
5839 uacpi_control_method *method = ctx->cur_frame->method;
5840
5841 if (method->is_serialized) {
5843 &ctx->held_mutexes, method->mutex, FORCE_RELEASE_YES
5844 );
5845 ctx->sync_level = ctx->cur_frame->prev_sync_level;
5846 }
5847
5848 call_frame_clear(ctx->cur_frame);
5849 call_frame_array_pop(&ctx->call_stack);
5850
5851 ctx->cur_frame = call_frame_array_last(&ctx->call_stack);
5853}
5854
5856{
5857 static const uacpi_char *unknown_path = "<unknown>";
5858 uacpi_char oom_absolute_path[9] = "<?>.";
5859
5860 const uacpi_char *absolute_path;
5861
5862 if (block != UACPI_NULL && block->type == CODE_BLOCK_SCOPE) {
5864 if (uacpi_unlikely(absolute_path == UACPI_NULL))
5865 uacpi_memcpy(oom_absolute_path + 4, block->node->name.text, 4);
5866 } else {
5867 absolute_path = unknown_path;
5868 }
5869
5870 uacpi_error(" #%zu in %s()\n", depth, absolute_path);
5871
5872 if (absolute_path != oom_absolute_path && absolute_path != unknown_path)
5873 uacpi_free_dynamic_string(absolute_path);
5874}
5875
5877{
5879 uacpi_bool should_stop;
5880
5881 /*
5882 * Non-empty call stack here means the execution was aborted at some point,
5883 * probably due to a bytecode error.
5884 */
5885 depth = call_frame_array_size(&ctx->call_stack);
5886
5887 if (depth != 0) {
5888 uacpi_size idx = 0;
5889 uacpi_bool table_level_code;
5890
5891 do {
5892 table_level_code = ctx->cur_frame->method->named_objects_persist;
5893
5894 if (table_level_code && idx != 0)
5895 /*
5896 * This isn't the first frame that we are aborting.
5897 * If this is table-level code, we have just unwound a call
5898 * chain that had triggered an abort. Stop here, no need to
5899 * abort table load because of it.
5900 */
5901 break;
5902
5903 while (op_context_array_size(&ctx->cur_frame->pending_ops) != 0)
5904 pop_op(ctx);
5905
5907 code_block_array_at(&ctx->cur_frame->code_blocks, 0), idx
5908 );
5909
5910 should_stop = idx++ == 0 && table_level_code;
5912 } while (--depth && !should_stop);
5913 }
5914}
5915
5917{
5918 if (ctx->ret)
5919 uacpi_object_unref(ctx->ret);
5920
5921 while (held_mutexes_array_size(&ctx->held_mutexes) != 0) {
5923 &ctx->held_mutexes,
5924 *held_mutexes_array_last(&ctx->held_mutexes),
5926 );
5927 }
5928
5929 call_frame_array_clear(&ctx->call_stack);
5930 held_mutexes_array_clear(&ctx->held_mutexes);
5931 uacpi_free(ctx, sizeof(*ctx));
5932}
5933
5936 const uacpi_object_array *args, uacpi_object **out_obj
5937)
5938{
5940 struct execution_context *ctx;
5941
5942 ctx = uacpi_kernel_alloc_zeroed(sizeof(*ctx));
5945
5946 if (out_obj != UACPI_NULL) {
5948 if (uacpi_unlikely(ctx->ret == UACPI_NULL)) {
5950 goto out;
5951 }
5952 }
5953
5956 goto out;
5957
5958 for (;;) {
5960 if (ctx->cur_frame == UACPI_NULL)
5961 break;
5962
5963 if (maybe_end_block(ctx))
5964 continue;
5965
5966 if (!call_frame_has_code(ctx->cur_frame)) {
5968 continue;
5969 }
5970
5971 ret = get_op(ctx);
5973 goto handle_method_abort;
5974
5976 }
5977
5978 ret = exec_op(ctx);
5980 goto handle_method_abort;
5981
5982 continue;
5983
5984 handle_method_abort:
5985 uacpi_error("aborting %s due to previous error: %s\n",
5986 ctx->cur_frame->method->named_objects_persist ?
5987 "table load" : "method invocation",
5990
5991 /*
5992 * Having a frame here implies that we just aborted a dynamic table
5993 * load. Signal to the caller that it failed by setting the return
5994 * value to false.
5995 */
5996 if (ctx->cur_frame) {
5997 struct item *it;
5998
5999 it = item_array_last(&ctx->cur_op_ctx->items);
6000 if (it != UACPI_NULL && it->obj != UACPI_NULL)
6001 it->obj->integer = 0;
6002 }
6003 }
6004
6005out:
6006 if (ctx->ret != UACPI_NULL) {
6007 uacpi_object *ret_obj = UACPI_NULL;
6008
6009 if (ctx->ret->type != UACPI_OBJECT_UNINITIALIZED) {
6010 ret_obj = ctx->ret;
6011 uacpi_object_ref(ret_obj);
6012 }
6013
6014 *out_obj = ret_obj;
6015 }
6016
6018 return ret;
6019}
6020
6022{
6023 struct execution_context *ctx = handle;
6024 uacpi_bool is_supported;
6027
6028 arg = uacpi_unwrap_internal_reference(ctx->cur_frame->args[0]);
6029 if (arg->type != UACPI_OBJECT_STRING) {
6030 uacpi_error("_OSI: invalid argument type %s, expected a String\n",
6033 }
6034
6035 if (retval == UACPI_NULL)
6036 return UACPI_STATUS_OK;
6037
6039
6040 ret = uacpi_handle_osi(arg->buffer->text, &is_supported);
6042 return ret;
6043
6044 retval->integer = is_supported ? ones() : 0;
6045
6046 uacpi_trace("_OSI(%s) => reporting as %ssupported\n",
6047 arg->buffer->text, is_supported ? "" : "un");
6048 return UACPI_STATUS_OK;
6049}
6050
6051#endif // !UACPI_BAREBONES_MODE
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
void user(int argc, const char *argv[])
Definition: cmds.c:1350
uacpi_status uacpi_acquire_aml_mutex(uacpi_mutex *, uacpi_u16 timeout)
Definition: mutex.c:201
uacpi_status uacpi_release_aml_mutex(uacpi_mutex *)
Definition: mutex.c:241
uacpi_bool uacpi_this_thread_owns_aml_mutex(uacpi_mutex *)
Definition: mutex.c:193
UINT op
Definition: effect.c:236
unsigned int idx
Definition: utils.c:41
static void cleanup(void)
Definition: main.c:1335
#define byte(x, n)
Definition: tomcrypt.h:118
method
Definition: dragdrop.c:54
#define ACPI_SMALL_ITEM_NAME_IDX
Definition: acpi.h:1072
struct uacpi_runtime_context g_uacpi_rt_ctx
Definition: uacpi.c:17
static uacpi_bool uacpi_should_log(enum uacpi_log_level lvl)
Definition: context.h:95
#define UACPI_UNUSED(x)
Definition: helpers.h:7
uacpi_size uacpi_round_up_bits_to_bytes(uacpi_size bit_length)
Definition: io.c:11
void uacpi_write_buffer_field(uacpi_buffer_field *field, const void *src, uacpi_size size)
Definition: io.c:149
uacpi_status uacpi_field_unit_get_bit_length(struct uacpi_field_unit *field, uacpi_size *out_length)
Definition: io.c:626
void uacpi_read_buffer_field(const uacpi_buffer_field *field, void *dst)
Definition: io.c:114
uacpi_status uacpi_field_unit_get_read_type(struct uacpi_field_unit *field, uacpi_object_type *out_type)
Definition: io.c:597
uacpi_status uacpi_read_field_unit(uacpi_field_unit *field, void *dst, uacpi_size size, uacpi_data_view *wtr_response)
Definition: io.c:459
uacpi_status uacpi_write_field_unit(uacpi_field_unit *field, const void *src, uacpi_size size, uacpi_data_view *wtr_response)
Definition: io.c:576
#define uacpi_trace(...)
Definition: log.h:18
#define uacpi_error(...)
Definition: log.h:21
#define uacpi_warn(...)
Definition: log.h:20
#define uacpi_log_lvl(lvl,...)
Definition: log.h:14
#define uacpi_debug(...)
Definition: log.h:17
void uacpi_namespace_node_unref(uacpi_namespace_node *node)
Definition: namespace.c:297
uacpi_status uacpi_namespace_do_for_each_child(uacpi_namespace_node *parent, uacpi_iteration_callback descending_callback, uacpi_iteration_callback ascending_callback, uacpi_object_type_bits, uacpi_u32 max_depth, enum uacpi_should_lock, enum uacpi_permanent_only, void *user)
Definition: namespace.c:834
uacpi_status uacpi_namespace_write_unlock(void)
Definition: namespace.c:54
#define UACPI_NAMESPACE_NODE_FLAG_TEMPORARY
Definition: namespace.h:25
@ UACPI_PERMANENT_ONLY_NO
Definition: namespace.h:91
uacpi_namespace_node * uacpi_namespace_node_find_sub_node(uacpi_namespace_node *parent, uacpi_object_name name)
Definition: namespace.c:448
#define UACPI_NAMESPACE_NODE_FLAG_ALIAS
Definition: namespace.h:10
uacpi_object * uacpi_namespace_node_get_object(const uacpi_namespace_node *node)
Definition: namespace.c:646
uacpi_namespace_node * uacpi_namespace_node_alloc(uacpi_object_name name)
Definition: namespace.c:284
uacpi_status uacpi_namespace_node_install(uacpi_namespace_node *parent, uacpi_namespace_node *node)
Definition: namespace.c:302
uacpi_status uacpi_namespace_node_uninstall(uacpi_namespace_node *node)
Definition: namespace.c:351
@ UACPI_SHOULD_LOCK_NO
Definition: namespace.h:96
uacpi_status uacpi_namespace_write_lock(void)
Definition: namespace.c:49
@ UACPI_MAY_SEARCH_ABOVE_PARENT_YES
Definition: namespace.h:87
uacpi_status uacpi_namespace_node_resolve(uacpi_namespace_node *scope, const uacpi_char *path, enum uacpi_should_lock, enum uacpi_may_search_above_parent, enum uacpi_permanent_only, uacpi_namespace_node **out_node)
Definition: namespace.c:491
#define UACPI_DUAL_NAME_PREFIX
Definition: opcodes.h:10
#define UACPI_MULTI_NAME_PREFIX
Definition: opcodes.h:11
const uacpi_char * uacpi_parse_op_to_string(enum uacpi_parse_op op)
Definition: opcodes.c:260
uacpi_parse_op
Definition: opcodes.h:18
@ UACPI_PARSE_OP_OPERAND
Definition: opcodes.h:55
@ UACPI_PARSE_OP_COMPUTATIONAL_DATA
Definition: opcodes.h:64
@ UACPI_PARSE_OP_OBJECT_CONVERT_TO_DEEP_COPY
Definition: opcodes.h:119
@ UACPI_PARSE_OP_EXISTING_NAMESTRING_OR_NULL_IF_LOAD
Definition: opcodes.h:107
@ UACPI_PARSE_OP_END
Definition: opcodes.h:19
@ UACPI_PARSE_OP_BAD_OPCODE
Definition: opcodes.h:186
@ UACPI_PARSE_OP_STORE_TO_TARGET_INDIRECT
Definition: opcodes.h:176
@ UACPI_PARSE_OP_TERM_ARG
Definition: opcodes.h:39
@ UACPI_PARSE_OP_CREATE_NAMESTRING
Definition: opcodes.h:83
@ UACPI_PARSE_OP_TRACKED_PKGLEN
Definition: opcodes.h:77
@ UACPI_PARSE_OP_CONVERT_NAMESTRING
Definition: opcodes.h:211
@ UACPI_PARSE_OP_INSTALL_NAMESPACE_NODE
Definition: opcodes.h:156
@ UACPI_PARSE_OP_IF_LAST_NULL
Definition: opcodes.h:230
@ UACPI_PARSE_OP_AML_PC_DECREMENT
Definition: opcodes.h:189
@ UACPI_PARSE_OP_OBJECT_COPY_TO_PREV
Definition: opcodes.h:167
@ UACPI_PARSE_OP_EXISTING_NAMESTRING_OR_NULL
Definition: opcodes.h:101
@ UACPI_PARSE_OP_LOAD_TRUE_OBJECT
Definition: opcodes.h:147
@ UACPI_PARSE_OP_PKGLEN
Definition: opcodes.h:70
@ UACPI_PARSE_OP_EXISTING_NAMESTRING
Definition: opcodes.h:95
@ UACPI_PARSE_OP_TERM_ARG_OR_NAMED_OBJECT
Definition: opcodes.h:46
@ UACPI_PARSE_OP_IF_LAST_NOT_NULL
Definition: opcodes.h:236
@ UACPI_PARSE_OP_INVOKE_HANDLER
Definition: opcodes.h:110
@ UACPI_PARSE_OP_IF_HAS_DATA
Definition: opcodes.h:217
@ UACPI_PARSE_OP_DISPATCH_TABLE_LOAD
Definition: opcodes.h:205
@ UACPI_PARSE_OP_TERM_ARG_UNWRAP_INTERNAL
Definition: opcodes.h:40
@ UACPI_PARSE_OP_TYPECHECK
Definition: opcodes.h:153
@ UACPI_PARSE_OP_SIMPLE_NAME
Definition: opcodes.h:31
@ UACPI_PARSE_OP_IF_LAST_FALSE
Definition: opcodes.h:248
@ UACPI_PARSE_OP_JMP
Definition: opcodes.h:271
@ UACPI_PARSE_OP_ITEM_POP
Definition: opcodes.h:195
@ UACPI_PARSE_OP_SWITCH_TO_NEXT_IF_EQUALS
Definition: opcodes.h:259
@ UACPI_PARSE_OP_SUPERNAME_OR_UNRESOLVED
Definition: opcodes.h:36
@ UACPI_PARSE_OP_RECORD_AML_PC
Definition: opcodes.h:128
@ UACPI_PARSE_OP_DISPATCH_METHOD_CALL
Definition: opcodes.h:198
@ UACPI_PARSE_OP_SUPERNAME
Definition: opcodes.h:34
@ UACPI_PARSE_OP_OBJECT_ALLOC
Definition: opcodes.h:113
@ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV
Definition: opcodes.h:159
@ UACPI_PARSE_OP_UNREACHABLE
Definition: opcodes.h:183
@ UACPI_PARSE_OP_IF_LAST_TRUE
Definition: opcodes.h:251
@ UACPI_PARSE_OP_IF_NULL
Definition: opcodes.h:224
@ UACPI_PARSE_OP_LOAD_INLINE_IMM_AS_OBJECT
Definition: opcodes.h:131
@ UACPI_PARSE_OP_STRING
Definition: opcodes.h:58
@ UACPI_PARSE_OP_LOAD_IMM
Definition: opcodes.h:140
@ UACPI_PARSE_OP_STORE_TO_TARGET
Definition: opcodes.h:170
@ UACPI_PARSE_OP_SKIP_WITH_WARN_IF_NULL
Definition: opcodes.h:25
@ UACPI_PARSE_OP_CREATE_NAMESTRING_OR_NULL_IF_LOAD
Definition: opcodes.h:89
@ UACPI_PARSE_OP_EMPTY_OBJECT_ALLOC
Definition: opcodes.h:115
@ UACPI_PARSE_OP_LOAD_IMM_AS_OBJECT
Definition: opcodes.h:143
@ UACPI_PARSE_OP_OBJECT_CONVERT_TO_SHALLOW_COPY
Definition: opcodes.h:118
@ UACPI_PARSE_OP_TARGET
Definition: opcodes.h:67
@ UACPI_PARSE_OP_TERM_ARG_OR_NAMED_OBJECT_OR_UNRESOLVED
Definition: opcodes.h:52
@ UACPI_PARSE_OP_IF_LAST_EQUALS
Definition: opcodes.h:242
@ UACPI_PARSE_OP_IF_NOT_NULL
Definition: opcodes.h:233
@ UACPI_PARSE_OP_LOAD_FALSE_OBJECT
Definition: opcodes.h:146
@ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED
Definition: opcodes.h:125
@ UACPI_PARSE_OP_EMIT_SKIP_WARN
Definition: opcodes.h:28
@ UACPI_PARSE_OP_LOAD_ZERO_IMM
Definition: opcodes.h:137
@ UACPI_PARSE_OP_IF_SWITCHED_FROM
Definition: opcodes.h:266
@ UACPI_PARSE_OP_TRUNCATE_NUMBER
Definition: opcodes.h:150
@ UACPI_PARSE_OP_IMM_DECREMENT
Definition: opcodes.h:192
@ UACPI_PARSE_OP_LOAD_INLINE_IMM
Definition: opcodes.h:134
#define UACPI_NULL_NAME
Definition: opcodes.h:12
const struct uacpi_op_spec * uacpi_get_op_spec(uacpi_aml_op)
Definition: opcodes.c:44
@ UACPI_OP_PROPERTY_SIMPLE_NAME
Definition: opcodes.h:288
@ UACPI_OP_PROPERTY_TERM_ARG
Definition: opcodes.h:286
@ UACPI_OP_PROPERTY_SUPERNAME
Definition: opcodes.h:287
@ UACPI_OP_PROPERTY_OUT_OF_LINE
Definition: opcodes.h:292
@ UACPI_OP_PROPERTY_RESERVED
Definition: opcodes.h:295
@ UACPI_OP_PROPERTY_TARGET
Definition: opcodes.h:289
#define UACPI_EXT_PREFIX
Definition: opcodes.h:7
uacpi_aml_op
Definition: opcodes.h:1383
uacpi_status uacpi_find_aml_resource_end_tag(uacpi_data_view, uacpi_size *out_offset)
Definition: resources.c:1526
uacpi_u8 uacpi_bit_scan_forward(uacpi_u64)
Definition: stdlib.c:124
uacpi_i32 uacpi_snprintf(uacpi_char *buffer, uacpi_size capacity, const uacpi_char *fmt,...)
Definition: stdlib.c:661
#define uacpi_memzero(ptr, size)
Definition: stdlib.h:99
#define uacpi_kernel_alloc_zeroed
Definition: stdlib.h:127
#define uacpi_memcmp
Definition: stdlib.h:61
#define uacpi_memcpy
Definition: stdlib.h:34
uacpi_size uacpi_strnlen(const uacpi_char *str, uacpi_size max)
Definition: stdlib.c:85
#define UACPI_ALIGN_DOWN(x, val, type)
Definition: stdlib.h:109
#define uacpi_free(mem, _)
Definition: stdlib.h:96
uacpi_u8 uacpi_bit_scan_backward(uacpi_u64)
Definition: stdlib.c:154
void uacpi_memcpy_zerout(void *dst, const void *src, uacpi_size dst_size, uacpi_size src_size)
Definition: stdlib.c:112
#define uacpi_memmove
Definition: stdlib.h:43
#define UACPI_MIN(x, y)
Definition: stdlib.h:102
struct uacpi_object * uacpi_create_internal_reference(enum uacpi_reference_kind kind, uacpi_object *child)
Definition: types.c:1453
@ UACPI_PREALLOC_OBJECTS_YES
Definition: types.h:293
uacpi_object * uacpi_create_object(uacpi_object_type type)
Definition: types.c:327
void uacpi_object_detach_child(uacpi_object *parent)
Definition: types.c:959
uacpi_bool uacpi_package_fill(uacpi_package *pkg, uacpi_size num_elements, enum uacpi_prealloc_objects prealloc_objects)
Definition: types.c:124
void uacpi_buffer_to_view(uacpi_buffer *, uacpi_data_view *)
Definition: types.c:1034
uacpi_reference_kind
Definition: types.h:10
@ UACPI_REFERENCE_KIND_LOCAL
Definition: types.h:12
@ UACPI_REFERENCE_KIND_ARG
Definition: types.h:13
@ UACPI_REFERENCE_KIND_PKG_INDEX
Definition: types.h:15
@ UACPI_REFERENCE_KIND_NAMED
Definition: types.h:14
@ UACPI_FIELD_UNIT_KIND_NORMAL
Definition: types.h:204
@ UACPI_FIELD_UNIT_KIND_BANK
Definition: types.h:206
@ UACPI_FIELD_UNIT_KIND_INDEX
Definition: types.h:205
uacpi_mutex * uacpi_create_mutex(void)
Definition: types.c:181
void uacpi_object_attach_child(uacpi_object *parent, uacpi_object *child)
Definition: types.c:943
uacpi_status uacpi_object_assign(uacpi_object *dst, uacpi_object *src, enum uacpi_assign_behavior)
Definition: types.c:1360
void uacpi_method_unref(uacpi_control_method *)
Definition: types.c:648
uacpi_assign_behavior
Definition: types.h:275
@ UACPI_ASSIGN_BEHAVIOR_DEEP_COPY
Definition: types.h:276
@ UACPI_ASSIGN_BEHAVIOR_SHALLOW_COPY
Definition: types.h:277
void uacpi_mutex_unref(uacpi_mutex *)
Definition: types.c:492
@ UACPI_STRING_KIND_PATH
Definition: types.h:21
uacpi_object * uacpi_unwrap_internal_reference(uacpi_object *object)
Definition: types.c:1468
uacpi_log_level
Definition: log.h:7
@ UACPI_LOG_INFO
Definition: log.h:24
@ UACPI_LOG_TRACE
Definition: log.h:18
@ UACPI_LOG_ERROR
Definition: log.h:35
@ UACPI_LOG_WARN
Definition: log.h:29
void uacpi_free_absolute_path(const uacpi_char *path)
Definition: namespace.c:1074
#define UACPI_MAX_DEPTH_ANY
Definition: namespace.h:102
const uacpi_char * uacpi_namespace_node_generate_absolute_path(const uacpi_namespace_node *node)
Definition: namespace.c:1034
uacpi_namespace_node * uacpi_namespace_root(void)
Definition: namespace.c:267
#define UACPI_FALLTHROUGH
Definition: compiler.h:70
#define uacpi_likely(expr)
Definition: compiler.h:59
#define uacpi_unlikely(expr)
Definition: compiler.h:58
#define UACPI_PRIX64
Definition: types.h:61
size_t uacpi_size
Definition: types.h:37
uint32_t uacpi_u32
Definition: types.h:21
bool uacpi_bool
Definition: types.h:31
#define UACPI_FALSE
Definition: types.h:30
uint64_t uacpi_u64
Definition: types.h:22
char uacpi_char
Definition: types.h:44
#define UACPI_NULL
Definition: types.h:33
uint8_t uacpi_u8
Definition: types.h:19
#define UACPI_FMT64(val)
Definition: types.h:62
#define UACPI_PRIx64
Definition: types.h:60
#define UACPI_TRUE
Definition: types.h:29
#define UACPI_PRIu64
Definition: types.h:59
#define uacpi_likely_success(expr)
Definition: status.h:53
#define uacpi_unlikely_error(expr)
Definition: status.h:49
uacpi_status
Definition: status.h:10
@ UACPI_STATUS_INVALID_ARGUMENT
Definition: status.h:18
@ UACPI_STATUS_AML_OBJECT_ALREADY_EXISTS
Definition: status.h:36
@ UACPI_STATUS_AML_OUT_OF_BOUNDS_INDEX
Definition: status.h:40
@ UACPI_STATUS_NOT_FOUND
Definition: status.h:17
@ UACPI_STATUS_UNIMPLEMENTED
Definition: status.h:19
@ UACPI_STATUS_OUT_OF_MEMORY
Definition: status.h:13
@ UACPI_STATUS_OVERRIDDEN
Definition: status.h:30
@ UACPI_STATUS_AML_INCOMPATIBLE_OBJECT_TYPE
Definition: status.h:38
@ UACPI_STATUS_AML_UNDEFINED_REFERENCE
Definition: status.h:34
@ UACPI_STATUS_AML_LOOP_TIMEOUT
Definition: status.h:43
@ UACPI_STATUS_AML_BAD_ENCODING
Definition: status.h:39
@ UACPI_STATUS_AML_INVALID_OPCODE
Definition: status.h:37
@ UACPI_STATUS_OK
Definition: status.h:11
@ UACPI_STATUS_AML_INVALID_NAMESTRING
Definition: status.h:35
@ UACPI_STATUS_AML_CALL_STACK_DEPTH_LIMIT
Definition: status.h:44
@ UACPI_STATUS_AML_SYNC_LEVEL_TOO_HIGH
Definition: status.h:41
@ UACPI_STATUS_NO_HANDLER
Definition: status.h:25
const uacpi_char * uacpi_status_to_string(uacpi_status)
Definition: uacpi.c:50
void uacpi_object_ref(uacpi_object *obj)
Definition: types.c:727
uacpi_iteration_decision
Definition: types.h:28
@ UACPI_ITERATION_DECISION_BREAK
Definition: types.h:30
@ UACPI_ITERATION_DECISION_CONTINUE
Definition: types.h:29
@ UACPI_OBJECT_OPERATION_REGION_BIT
Definition: types.h:138
@ UACPI_ACCESS_ATTRIBUTE_RAW_BYTES
Definition: types.h:477
@ UACPI_ACCESS_ATTRIBUTE_RAW_PROCESS_BYTES
Definition: types.h:478
@ UACPI_ACCESS_ATTRIBUTE_BYTES
Definition: types.h:474
const uacpi_char * uacpi_object_type_to_string(uacpi_object_type)
Definition: types.c:51
uacpi_object_type
Definition: types.h:104
@ UACPI_OBJECT_EVENT
Definition: types.h:112
@ UACPI_OBJECT_METHOD
Definition: types.h:113
@ UACPI_OBJECT_BUFFER
Definition: types.h:108
@ UACPI_OBJECT_STRING
Definition: types.h:107
@ UACPI_OBJECT_PROCESSOR
Definition: types.h:117
@ UACPI_OBJECT_PACKAGE
Definition: types.h:109
@ UACPI_OBJECT_POWER_RESOURCE
Definition: types.h:116
@ UACPI_OBJECT_UNINITIALIZED
Definition: types.h:105
@ UACPI_OBJECT_REFERENCE
Definition: types.h:122
@ UACPI_OBJECT_MUTEX
Definition: types.h:114
@ UACPI_OBJECT_DEBUG
Definition: types.h:120
@ UACPI_OBJECT_INTEGER
Definition: types.h:106
@ UACPI_OBJECT_BUFFER_FIELD
Definition: types.h:119
@ UACPI_OBJECT_OPERATION_REGION
Definition: types.h:115
@ UACPI_OBJECT_FIELD_UNIT
Definition: types.h:110
@ UACPI_OBJECT_BUFFER_INDEX
Definition: types.h:123
@ UACPI_FIRMWARE_REQUEST_TYPE_FATAL
Definition: types.h:512
@ UACPI_FIRMWARE_REQUEST_TYPE_BREAKPOINT
Definition: types.h:511
uacpi_bool uacpi_object_is(uacpi_object *, uacpi_object_type)
Definition: types.c:985
@ UACPI_ADDRESS_SPACE_SYSTEM_MEMORY
Definition: types.h:37
@ UACPI_ADDRESS_SPACE_TABLE_DATA
Definition: types.h:52
@ UACPI_ADDRESS_SPACE_PCC
Definition: types.h:47
void uacpi_object_unref(uacpi_object *obj)
Definition: types.c:755
void uacpi_events_match_post_dynamic_table_load(void)
Definition: event.c:968
static uacpi_status field_byte_size(uacpi_object *obj, uacpi_size *out_size)
Definition: interpreter.c:3827
static uacpi_status handle_arg(struct execution_context *ctx)
Definition: interpreter.c:1071
static uacpi_status handle_control_flow(struct execution_context *ctx)
Definition: interpreter.c:3995
static uacpi_status handle_create_field(struct execution_context *ctx)
Definition: interpreter.c:1612
static uacpi_status table_id_error(const uacpi_char *opcode, const uacpi_char *arg, uacpi_buffer *str)
Definition: interpreter.c:1154
static struct code_block * find_last_block(struct code_block_array *blocks, enum code_block_type type)
Definition: interpreter.c:1940
static uacpi_status handle_concatenate(struct execution_context *ctx)
Definition: interpreter.c:2929
static uacpi_status handle_unload(struct execution_context *ctx)
Definition: interpreter.c:3218
#define AML_READ(ptr, offset)
Definition: interpreter.c:337
static const uacpi_char *const op_trace_action_types[3]
Definition: interpreter.c:4143
static uacpi_status handle_field_read(struct execution_context *ctx)
Definition: interpreter.c:3847
match_op
Definition: interpreter.c:3357
@ MGE
Definition: interpreter.c:3362
@ MLT
Definition: interpreter.c:3361
@ MGT
Definition: interpreter.c:3363
@ MLE
Definition: interpreter.c:3360
@ MEQ
Definition: interpreter.c:3359
@ MTR
Definition: interpreter.c:3358
static uacpi_status frame_setup_base_scope(struct call_frame *frame, uacpi_namespace_node *scope, uacpi_control_method *method)
Definition: interpreter.c:4193
static uacpi_status typecheck_operand(const struct op_context *op_ctx, const uacpi_object *obj)
Definition: interpreter.c:4727
static uacpi_status do_load_table(uacpi_namespace_node *parent, struct acpi_sdt_hdr *tbl, enum uacpi_table_load_cause cause)
Definition: interpreter.c:1282
static uacpi_status method_get_ret_target(struct execution_context *ctx, uacpi_object **out_operand)
Definition: interpreter.c:1883
static uacpi_status store_to_target(uacpi_object *dst, uacpi_object *src, uacpi_data_view *wtr_response)
Definition: interpreter.c:4251
static void apply_tracked_pkg(struct call_frame *frame, struct op_context *op_ctx)
Definition: interpreter.c:5184
static uacpi_status prepare_method_call(struct execution_context *ctx, uacpi_namespace_node *node, uacpi_control_method *method, enum method_call_type type, const uacpi_object_array *args)
Definition: interpreter.c:5108
static uacpi_bool op_allows_unresolved_if_load(enum uacpi_parse_op op)
Definition: interpreter.c:4650
static uacpi_status handle_ref_or_deref_of(struct execution_context *ctx)
Definition: interpreter.c:2361
item_type
Definition: interpreter.c:23
@ ITEM_OBJECT
Definition: interpreter.c:26
@ ITEM_EMPTY_OBJECT
Definition: interpreter.c:27
@ ITEM_IMMEDIATE
Definition: interpreter.c:29
@ ITEM_NONE
Definition: interpreter.c:24
@ ITEM_PACKAGE_LENGTH
Definition: interpreter.c:28
@ ITEM_NAMESPACE_NODE
Definition: interpreter.c:25
#define SPEC_TERM_ARG
Definition: interpreter.c:4601
static uacpi_status handle_code_block(struct execution_context *ctx)
Definition: interpreter.c:4061
resolve_behavior
Definition: interpreter.c:472
@ RESOLVE_FAIL_IF_DOESNT_EXIST
Definition: interpreter.c:474
@ RESOLVE_CREATE_LAST_NAMESEG_FAIL_IF_EXISTS
Definition: interpreter.c:473
static void truncate_number_if_needed(uacpi_object *obj)
Definition: interpreter.c:1870
static uacpi_status handle_event_ctl(struct execution_context *ctx)
Definition: interpreter.c:3577
op_handler
Definition: interpreter.c:4852
@ OP_HANDLER_REF_OR_DEREF_OF
Definition: interpreter.c:4864
@ OP_HANDLER_LOGICAL_NOT
Definition: interpreter.c:4865
@ OP_HANDLER_INDEX
Definition: interpreter.c:4878
@ OP_HANDLER_CREATE_METHOD
Definition: interpreter.c:4861
@ OP_HANDLER_MUTEX_CTL
Definition: interpreter.c:4895
@ OP_HANDLER_STALL_OR_SLEEP
Definition: interpreter.c:4893
@ OP_HANDLER_BINARY_MATH
Definition: interpreter.c:4857
@ OP_HANDLER_INC_DEC
Definition: interpreter.c:4863
@ OP_HANDLER_CREATE_DATA_REGION
Definition: interpreter.c:4881
@ OP_HANDLER_BINARY_LOGIC
Definition: interpreter.c:4866
@ OP_HANDLER_NOTIFY
Definition: interpreter.c:4896
@ OP_HANDLER_LOCAL
Definition: interpreter.c:4854
@ OP_HANDLER_LOAD_TABLE
Definition: interpreter.c:4891
@ OP_HANDLER_ALIAS
Definition: interpreter.c:4873
@ OP_HANDLER_OBJECT_TYPE
Definition: interpreter.c:4879
@ OP_HANDLER_UNLOAD
Definition: interpreter.c:4890
@ OP_HANDLER_STRING
Definition: interpreter.c:4856
@ OP_HANDLER_BUFFER
Definition: interpreter.c:4868
@ OP_HANDLER_UNARY_MATH
Definition: interpreter.c:4877
@ OP_HANDLER_CREATE_MUTEX_OR_EVENT
Definition: interpreter.c:4888
@ OP_HANDLER_PACKAGE
Definition: interpreter.c:4869
@ OP_HANDLER_MID
Definition: interpreter.c:4886
@ OP_HANDLER_CREATE_FIELD
Definition: interpreter.c:4882
@ OP_HANDLER_COPY_OBJECT_OR_STORE
Definition: interpreter.c:4862
@ OP_HANDLER_BCD
Definition: interpreter.c:4889
@ OP_HANDLER_CODE_BLOCK
Definition: interpreter.c:4859
@ OP_HANDLER_TO_STRING
Definition: interpreter.c:4884
@ OP_HANDLER_SIZEOF
Definition: interpreter.c:4876
@ OP_HANDLER_NAMED_OBJECT
Definition: interpreter.c:4867
@ OP_HANDLER_LOAD
Definition: interpreter.c:4892
@ OP_HANDLER_CONCATENATE_RES
Definition: interpreter.c:4875
@ OP_HANDLER_READ_FIELD
Definition: interpreter.c:4872
@ OP_HANDLER_CONCATENATE
Definition: interpreter.c:4874
@ OP_HANDLER_EVENT_CTL
Definition: interpreter.c:4894
@ OP_HANDLER_CONTROL_FLOW
Definition: interpreter.c:4858
@ OP_HANDLER_MATCH
Definition: interpreter.c:4887
@ OP_HANDLER_RETURN
Definition: interpreter.c:4860
@ OP_HANDLER_FIRMWARE_REQUEST
Definition: interpreter.c:4897
@ OP_HANDLER_CREATE_BUFFER_FIELD
Definition: interpreter.c:4871
@ OP_HANDLER_TIMER
Definition: interpreter.c:4885
@ OP_HANDLER_ARG
Definition: interpreter.c:4855
@ OP_HANDLER_CREATE_NAMED
Definition: interpreter.c:4870
@ OP_HANDLER_UNINSTALLED
Definition: interpreter.c:4853
@ OP_HANDLER_CREATE_OP_REGION
Definition: interpreter.c:4880
@ OP_HANDLER_TO
Definition: interpreter.c:4883
static uacpi_status debug_store(uacpi_object *src)
Definition: interpreter.c:2149
static uacpi_status field_get_read_type(uacpi_object *obj, uacpi_object_type *out_type)
Definition: interpreter.c:3815
static uacpi_status handle_create_named(struct execution_context *ctx)
Definition: interpreter.c:3787
static uacpi_status object_assign_with_implicit_cast(uacpi_object *dst, uacpi_object *src, uacpi_data_view *wtr_response)
Definition: interpreter.c:959
static uacpi_status ensure_valid_idx(uacpi_object *obj, uacpi_size idx, uacpi_size src_size)
Definition: interpreter.c:2540
#define SPEC_SUPER_NAME
Definition: interpreter.c:4599
static uacpi_status method_get_ret_object(struct execution_context *ctx, uacpi_object **out_obj)
Definition: interpreter.c:1923
static uacpi_status handle_to(struct execution_context *ctx)
Definition: interpreter.c:2788
static uacpi_u8 parse_op_generates_item[0x100]
Definition: interpreter.c:4520
static uacpi_status handle_return(struct execution_context *ctx)
Definition: interpreter.c:4091
static uacpi_bool maybe_end_block(struct execution_context *ctx)
Definition: interpreter.c:4234
static void init_method_flags(uacpi_control_method *method, uacpi_u8 flags_byte)
Definition: interpreter.c:3489
static uacpi_status handle_create_method(struct execution_context *ctx)
Definition: interpreter.c:3496
static uacpi_status handle_buffer(struct execution_context *ctx)
Definition: interpreter.c:707
static uacpi_status handle_mid(struct execution_context *ctx)
Definition: interpreter.c:2874
static uacpi_u64 ones(void)
Definition: interpreter.c:1878
static uacpi_object_type buffer_field_get_read_type(struct uacpi_buffer_field *field)
Definition: interpreter.c:3804
static void trace_pop(uacpi_u8 pop)
Definition: interpreter.c:4159
static uacpi_status do_binary_math(uacpi_object *arg0, uacpi_object *arg1, uacpi_object *tgt0, uacpi_object *tgt1, uacpi_aml_op op)
Definition: interpreter.c:2418
static uacpi_status name_string_to_path(struct call_frame *frame, uacpi_size offset, uacpi_char **out_string, uacpi_size *out_size)
Definition: interpreter.c:364
static uacpi_status handle_create_mutex_or_event(struct execution_context *ctx)
Definition: interpreter.c:3549
static uacpi_status handle_inc_dec(struct execution_context *ctx)
Definition: interpreter.c:4333
static uacpi_status handle_unary_math(struct execution_context *ctx)
Definition: interpreter.c:2513
static uacpi_status handle_object_type(struct execution_context *ctx)
Definition: interpreter.c:3124
static void report_table_id_find_error(const uacpi_char *opcode, struct uacpi_table_identifiers *id, uacpi_status ret)
Definition: interpreter.c:1163
static uacpi_status handle_bcd(struct execution_context *ctx)
Definition: interpreter.c:3181
static void pop_op(struct execution_context *ctx)
Definition: interpreter.c:4485
static void trace_named_object_lookup_or_creation_failure(struct call_frame *frame, uacpi_size offset, enum uacpi_parse_op op, uacpi_status ret, enum uacpi_log_level level)
Definition: interpreter.c:4768
static uacpi_bool pop_item(struct op_context *op_ctx)
Definition: interpreter.c:4466
static uacpi_status held_mutexes_array_remove_and_release(struct held_mutexes_array *arr, uacpi_mutex *mutex, enum force_release force)
Definition: interpreter.c:185
static uacpi_status handle_create_buffer_field(struct execution_context *ctx)
Definition: interpreter.c:3905
#define SPEC_STRING
Definition: interpreter.c:4604
static uacpi_status build_table_id(const uacpi_char *opcode, struct uacpi_table_identifiers *out_id, uacpi_buffer *signature, uacpi_buffer *oem_id, uacpi_buffer *oem_table_id)
Definition: interpreter.c:1176
static uacpi_u8 handler_idx_of_ext_op[0x100]
Definition: interpreter.c:5064
static uacpi_status handle_match(struct execution_context *ctx)
Definition: interpreter.c:3386
static void emit_op_skip_warn(const struct op_context *op_ctx)
Definition: interpreter.c:4763
static uacpi_status handle_stall_or_sleep(struct execution_context *ctx)
Definition: interpreter.c:3153
static uacpi_status handle_notify(struct execution_context *ctx)
Definition: interpreter.c:3724
argx_or_localx
Definition: interpreter.c:1018
@ LOCALX
Definition: interpreter.c:1020
@ ARGX
Definition: interpreter.c:1019
static uacpi_bool op_wants_supername(enum uacpi_parse_op op)
Definition: interpreter.c:4611
static uacpi_status do_make_empty_object(uacpi_buffer *buf, uacpi_bool is_string)
Definition: interpreter.c:2760
static void write_buffer_index(uacpi_buffer_index *buf_idx, uacpi_data_view *src_buf)
Definition: interpreter.c:947
static uacpi_status push_op(struct execution_context *ctx)
Definition: interpreter.c:4452
static uacpi_status parse_package_length(struct call_frame *frame, struct package_length *out_pkg)
Definition: interpreter.c:3431
static uacpi_status handle_to_string(struct execution_context *ctx)
Definition: interpreter.c:2847
static void * call_frame_cursor(struct call_frame *frame)
Definition: interpreter.c:288
static uacpi_u8 peek_next_op(struct call_frame *frame, uacpi_aml_op *out_op)
Definition: interpreter.c:655
static uacpi_status handle_copy_object_or_store(struct execution_context *ctx)
Definition: interpreter.c:4286
static uacpi_status handle_string(struct execution_context *ctx)
Definition: interpreter.c:760
static uacpi_status handle_arg_or_local(struct execution_context *ctx, uacpi_size idx, enum argx_or_localx type)
Definition: interpreter.c:1023
static uacpi_status handle_timer(struct execution_context *ctx)
Definition: interpreter.c:3142
static uacpi_u8 op_decode_byte(struct op_context *ctx)
Definition: interpreter.c:4564
static void stack_unwind(struct execution_context *ctx)
Definition: interpreter.c:5876
static void update_scope(struct call_frame *frame)
Definition: interpreter.c:1957
static uacpi_bool op_wants_term_arg_or_operand(enum uacpi_parse_op op)
Definition: interpreter.c:4624
#define SPEC_TARGET
Definition: interpreter.c:4605
static uacpi_status create_named_scope(struct op_context *op_ctx)
Definition: interpreter.c:4025
static void debug_store_no_recurse(const uacpi_char *prefix, uacpi_object *src)
Definition: interpreter.c:2066
static uacpi_status exec_op(struct execution_context *ctx)
Definition: interpreter.c:5197
static uacpi_status begin_block_execution(struct execution_context *ctx)
Definition: interpreter.c:1970
static uacpi_u8 handler_idx_of_op[0x100]
Definition: interpreter.c:4952
static uacpi_object * reference_unwind(uacpi_object *obj)
Definition: interpreter.c:2182
uacpi_status uacpi_execute_table(void *tbl, enum uacpi_table_load_cause cause)
Definition: interpreter.c:1549
static uacpi_status get_op(struct execution_context *ctx)
Definition: interpreter.c:683
static uacpi_iteration_decision opregion_try_detach_from_parent(void *user, uacpi_namespace_node *node, uacpi_u32 node_depth)
Definition: interpreter.c:2198
static void object_replace_child(uacpi_object *parent, uacpi_object *new_child)
Definition: interpreter.c:2213
static void execution_context_release(struct execution_context *ctx)
Definition: interpreter.c:5916
static void prepare_table_load(void *ptr, enum uacpi_table_load_cause cause, uacpi_control_method *in_method)
Definition: interpreter.c:1258
static uacpi_status make_null_string(uacpi_buffer *buf)
Definition: interpreter.c:2773
static uacpi_bool op_allows_unresolved(enum uacpi_parse_op op)
Definition: interpreter.c:4638
static uacpi_status copy_object_to_reference(uacpi_object *dst, uacpi_object *src)
Definition: interpreter.c:2246
static uacpi_status handle_create_alias(struct execution_context *ctx)
Definition: interpreter.c:1095
static void trace_op(const struct uacpi_op_spec *op, enum op_trace_action_type action)
Definition: interpreter.c:4149
static uacpi_status typecheck_string(const struct op_context *op_ctx, const uacpi_object *obj)
Definition: interpreter.c:4735
#define EXEC_OP_ERR(reason)
Definition: interpreter.c:4594
static uacpi_status handle_load_table(struct execution_context *ctx)
Definition: interpreter.c:1302
force_release
Definition: interpreter.c:180
@ FORCE_RELEASE_NO
Definition: interpreter.c:181
@ FORCE_RELEASE_YES
Definition: interpreter.c:182
static void frame_reset_post_end_block(struct execution_context *ctx, enum code_block_type type)
Definition: interpreter.c:2043
static uacpi_size sizeof_int(void)
Definition: interpreter.c:897
static uacpi_status handle_local(struct execution_context *ctx)
Definition: interpreter.c:1062
static uacpi_status(* op_handlers[])(struct execution_context *ctx)
Definition: interpreter.c:4900
static uacpi_size call_frame_code_bytes_left(struct call_frame *frame)
Definition: interpreter.c:293
op_trace_action_type
Definition: interpreter.c:4137
@ OP_TRACE_ACTION_RESUME
Definition: interpreter.c:4139
@ OP_TRACE_ACTION_BEGIN
Definition: interpreter.c:4138
@ OP_TRACE_ACTION_END
Definition: interpreter.c:4140
static uacpi_aml_op op_decode_aml_op(struct op_context *op_ctx)
Definition: interpreter.c:4574
static uacpi_status handle_create_op_region(struct execution_context *ctx)
Definition: interpreter.c:1109
#define SPEC_SIMPLE_NAME
Definition: interpreter.c:4598
static void call_frame_clear(struct call_frame *frame)
Definition: interpreter.c:4497
method_call_type
Definition: interpreter.c:5102
@ METHOD_CALL_AML
Definition: interpreter.c:5104
@ METHOD_CALL_TABLE_LOAD
Definition: interpreter.c:5105
@ METHOD_CALL_NATIVE
Definition: interpreter.c:5103
static uacpi_status do_install_node_item(struct call_frame *frame, struct item *item)
Definition: interpreter.c:637
static uacpi_status handle_sizeof(struct execution_context *ctx)
Definition: interpreter.c:3087
static uacpi_status handle_load(struct execution_context *ctx)
Definition: interpreter.c:1413
#define SPEC_COMPUTATIONAL_DATA
Definition: interpreter.c:4607
static uacpi_status resolve_name_string(struct call_frame *frame, enum resolve_behavior behavior, struct uacpi_namespace_node **out_node)
Definition: interpreter.c:477
static uacpi_status handle_firmware_request(struct execution_context *ctx)
Definition: interpreter.c:3760
static void held_mutexes_array_remove_idx(struct held_mutexes_array *arr, uacpi_size i)
Definition: interpreter.c:128
uacpi_status uacpi_execute_control_method(uacpi_namespace_node *scope, uacpi_control_method *method, const uacpi_object_array *args, uacpi_object **out_obj)
Definition: interpreter.c:5934
static uacpi_status handle_package(struct execution_context *ctx)
Definition: interpreter.c:788
#define EXEC_OP_ERR_1(reason, arg0)
Definition: interpreter.c:4593
static void refresh_ctx_pointers(struct execution_context *ctx)
Definition: interpreter.c:4116
static uacpi_bool is_dynamic_table_load(enum uacpi_table_load_cause cause)
Definition: interpreter.c:1253
#define EXEC_OP_ERR_2(reason, arg0, arg1)
Definition: interpreter.c:4592
static uacpi_u64 object_to_integer(const uacpi_object *obj, uacpi_size max_buffer_bytes)
Definition: interpreter.c:2638
static uacpi_status handle_logical_not(struct execution_context *ctx)
Definition: interpreter.c:3241
static uacpi_status make_null_buffer(uacpi_buffer *buf)
Definition: interpreter.c:2778
static uacpi_bool call_frame_has_code(struct call_frame *frame)
Definition: interpreter.c:298
static uacpi_u8 * buffer_index_cursor(uacpi_buffer_index *buf_idx)
Definition: interpreter.c:937
static uacpi_bool match_one(enum match_op op, uacpi_u64 lhs, uacpi_u64 rhs)
Definition: interpreter.c:3366
static uacpi_status get_object_storage(uacpi_object *obj, uacpi_data_view *out_buf, uacpi_bool include_null)
Definition: interpreter.c:902
static uacpi_status enter_method(struct execution_context *ctx, struct call_frame *new_frame, uacpi_control_method *method)
Definition: interpreter.c:4407
static void ctx_reload_post_ret(struct execution_context *ctx)
Definition: interpreter.c:5837
#define EXT_OP_IDX(op)
Definition: interpreter.c:5062
static uacpi_status ensure_is_a_field_unit(uacpi_namespace_node *node, uacpi_field_unit **out_field)
Definition: interpreter.c:1576
static uacpi_status handle_mutex_ctl(struct execution_context *ctx)
Definition: interpreter.c:3628
static void trace_method_abort(struct code_block *block, uacpi_size depth)
Definition: interpreter.c:5855
code_block_type
Definition: interpreter.c:87
@ CODE_BLOCK_ELSE
Definition: interpreter.c:89
@ CODE_BLOCK_IF
Definition: interpreter.c:88
@ CODE_BLOCK_WHILE
Definition: interpreter.c:90
@ CODE_BLOCK_SCOPE
Definition: interpreter.c:91
static uacpi_bool ctx_has_non_preempted_op(struct execution_context *ctx)
Definition: interpreter.c:4132
static uacpi_status typecheck_computational_data(const struct op_context *op_ctx, const uacpi_object *obj)
Definition: interpreter.c:4743
static uacpi_u32 get_field_length(struct item *item)
Definition: interpreter.c:1563
static uacpi_status store_to_reference(uacpi_object *dst, uacpi_object *src, uacpi_data_view *wtr_response)
Definition: interpreter.c:2299
static uacpi_status push_new_frame(struct execution_context *ctx, struct call_frame **out_frame)
Definition: interpreter.c:4212
static uacpi_status handle_concatenate_res(struct execution_context *ctx)
Definition: interpreter.c:3040
static uacpi_bool handle_logical_equality(uacpi_object *lhs, uacpi_object *rhs)
Definition: interpreter.c:3255
static uacpi_status ensure_is_an_op_region(uacpi_namespace_node *node, uacpi_namespace_node **out_node)
Definition: interpreter.c:1594
static uacpi_status handle_binary_math(struct execution_context *ctx)
Definition: interpreter.c:2493
static uacpi_status buffer_to_string(uacpi_buffer *buf, uacpi_buffer *str, uacpi_bool is_hex)
Definition: interpreter.c:2699
static uacpi_status handle_binary_logic(struct execution_context *ctx)
Definition: interpreter.c:3308
static uacpi_status handle_named_object(struct execution_context *ctx)
Definition: interpreter.c:1080
#define SPEC_OPERAND
Definition: interpreter.c:4603
static uacpi_status integer_to_string(uacpi_u64 integer, uacpi_buffer *str, uacpi_bool is_hex)
Definition: interpreter.c:2666
static uacpi_status frame_push_args(struct call_frame *frame, struct op_context *op_ctx)
Definition: interpreter.c:4164
static uacpi_status uninstalled_op_handler(struct execution_context *ctx)
Definition: interpreter.c:4844
static uacpi_status parse_nameseg(uacpi_u8 *cursor, uacpi_object_name *out_name)
Definition: interpreter.c:339
static uacpi_status typecheck_obj(const struct op_context *op_ctx, const uacpi_object *obj, enum uacpi_object_type expected_type, const uacpi_char *spec_desc)
Definition: interpreter.c:4712
static uacpi_bool handle_logical_less_or_greater(uacpi_aml_op op, uacpi_object *lhs, uacpi_object *rhs)
Definition: interpreter.c:3276
static uacpi_status handle_create_data_region(struct execution_context *ctx)
Definition: interpreter.c:1209
static uacpi_status op_typecheck(const struct op_context *op_ctx, const struct op_context *cur_op_ctx)
Definition: interpreter.c:4661
#define EXEC_OP_WARN(reason)
Definition: interpreter.c:4596
uacpi_status uacpi_osi(uacpi_handle handle, uacpi_object *retval)
Definition: interpreter.c:6021
static const uacpi_u8 * op_decode_cursor(const struct op_context *ctx)
Definition: interpreter.c:4554
static uacpi_status handle_index(struct execution_context *ctx)
Definition: interpreter.c:2553
return ret
Definition: mutex.c:146
action
Definition: namespace.c:707
r parent
Definition: btrfs.c:3010
#define is_hex(c)
Definition: registry.c:430
#define DYNAMIC_ARRAY_WITH_INLINE_STORAGE_IMPL(name, type, prefix)
#define DYNAMIC_ARRAY_WITH_INLINE_STORAGE(name, type, inline_capacity)
Definition: dynamic_array.h:7
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLint level
Definition: gl.h:1546
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei width
Definition: gl.h:1546
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLint left
Definition: glext.h:7726
GLenum GLenum dst
Definition: glext.h:6340
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
GLenum target
Definition: glext.h:7315
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const char cursor[]
Definition: icontest.c:13
uacpi_status uacpi_notify_all(uacpi_namespace_node *node, uacpi_u64 value)
Definition: notify.c:69
void uacpi_opregion_uninstall_handler(uacpi_namespace_node *node)
Definition: opregion.c:398
uacpi_status uacpi_initialize_opregion_node(uacpi_namespace_node *node)
Definition: opregion.c:783
uacpi_status uacpi_handle_osi(const uacpi_char *string, uacpi_bool *out_value)
Definition: osi.c:362
#define UACPI_PRI_TBL_HDR
Definition: tables.h:69
uacpi_status uacpi_table_install_with_origin(void *virt, enum uacpi_table_origin origin, uacpi_table *out_table)
Definition: tables.c:796
void uacpi_table_mark_as_loaded(uacpi_size idx)
Definition: tables.c:1143
#define UACPI_FMT_TBL_HDR(hdr)
Definition: tables.h:70
@ UACPI_TABLE_ORIGIN_FIRMWARE_VIRTUAL
Definition: tables.h:11
#define UACPI_NANOSECONDS_PER_SEC
Definition: utilities.h:45
uacpi_status uacpi_string_to_integer(const uacpi_char *str, uacpi_size max_chars, enum uacpi_base base, uacpi_u64 *out_value)
Definition: utilities.c:233
uacpi_bool uacpi_is_valid_nameseg(uacpi_u8 *nameseg)
Definition: utilities.c:315
@ UACPI_BASE_AUTO
Definition: utilities.h:31
void uacpi_free_dynamic_string(const uacpi_char *str)
Definition: utilities.c:1135
uacpi_table_load_cause
Definition: interpreter.h:9
@ UACPI_TABLE_LOAD_CAUSE_HOST
Definition: interpreter.h:13
@ UACPI_TABLE_LOAD_CAUSE_INIT
Definition: interpreter.h:12
@ UACPI_TABLE_LOAD_CAUSE_LOAD_OP
Definition: interpreter.h:10
@ UACPI_TABLE_LOAD_CAUSE_LOAD_TABLE_OP
Definition: interpreter.h:11
static BOOL is_null(jsval_t v)
Definition: jsval.h:176
uacpi_bool uacpi_kernel_wait_for_event(uacpi_handle, uacpi_u16)
Definition: uacpiosl.c:66
void * uacpi_kernel_alloc(uacpi_size size)
Definition: uacpiosl.c:111
void uacpi_kernel_reset_event(uacpi_handle)
Definition: uacpiosl.c:79
void uacpi_kernel_stall(uacpi_u8 usec)
Definition: uacpiosl.c:42
void uacpi_kernel_sleep(uacpi_u64 msec)
Definition: uacpiosl.c:47
uacpi_u64 uacpi_kernel_get_nanoseconds_since_boot(void)
Definition: uacpiosl.c:35
uacpi_status uacpi_kernel_handle_firmware_request(uacpi_firmware_request *)
Definition: uacpiosl.c:177
void uacpi_kernel_unmap(void *addr, uacpi_size len)
Definition: uacpiosl.c:198
void * uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len)
Definition: uacpiosl.c:191
void uacpi_kernel_signal_event(uacpi_handle)
Definition: uacpiosl.c:73
__u16 time
Definition: mkdosfs.c:8
static int blocks
Definition: mkdosfs.c:527
#define for
Definition: utility.h:88
char string[160]
Definition: util.h:11
static PVOID ptr
Definition: dispmode.c:27
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID ULONG out_size
Definition: file.c:100
static TCHAR * items[]
Definition: page1.c:45
static BOOL is_string(parse_buffer *buf)
Definition: parsing.c:600
static HANDLE proc()
Definition: pdb.c:34
const WCHAR * str
static calc_node_t * pop(void)
Definition: rpn_ieee.c:90
static calc_node_t temp
Definition: rpn_ieee.c:38
uacpi_u32 uacpi_shareable_ref(uacpi_handle)
Definition: shareable.c:31
wchar_t const *const size_t const buffer_size
Definition: stat.cpp:95
Definition: vfat.h:185
Definition: match.c:390
uacpi_u32 prev_while_code_offset
Definition: interpreter.c:278
struct uacpi_namespace_node * cur_scope
Definition: interpreter.c:282
struct code_block * last_while
Definition: interpreter.c:276
uacpi_object * locals[8]
Definition: interpreter.c:271
struct temp_namespace_node_array temp_nodes
Definition: interpreter.c:275
struct op_context_array pending_ops
Definition: interpreter.c:273
uacpi_u32 code_offset
Definition: interpreter.c:280
uacpi_object * args[7]
Definition: interpreter.c:270
struct uacpi_control_method * method
Definition: interpreter.c:268
struct code_block_array code_blocks
Definition: interpreter.c:274
uacpi_u64 prev_while_expiration
Definition: interpreter.c:277
uacpi_u8 prev_sync_level
Definition: interpreter.c:285
uacpi_u32 end
Definition: interpreter.c:96
enum code_block_type type
Definition: interpreter.c:95
uacpi_u32 begin
Definition: interpreter.c:96
struct uacpi_namespace_node * node
Definition: interpreter.c:98
uacpi_u64 expiration_point
Definition: interpreter.c:99
Definition: inflate.c:139
uacpi_u8 sync_level
Definition: interpreter.c:334
struct op_context * prev_op_ctx
Definition: interpreter.c:331
struct code_block * cur_block
Definition: interpreter.c:329
struct held_mutexes_array held_mutexes
Definition: interpreter.c:326
struct call_frame * cur_frame
Definition: interpreter.c:328
struct call_frame_array call_stack
Definition: interpreter.c:325
struct op_context * cur_op_ctx
Definition: interpreter.c:332
uacpi_object * ret
Definition: interpreter.c:324
const struct uacpi_op_spec * cur_op
Definition: interpreter.c:330
struct uacpi_field_unit * field1
Definition: interpreter.c:1572
struct uacpi_field_unit * field0
Definition: interpreter.c:1571
uacpi_namespace_node * region
Definition: interpreter.c:1570
Definition: parser.c:44
uacpi_u64 immediate
Definition: interpreter.c:44
uacpi_u8 type
Definition: interpreter.c:38
struct uacpi_namespace_node * node
Definition: interpreter.c:42
uacpi_object * obj
Definition: interpreter.c:41
uacpi_handle handle
Definition: interpreter.c:40
struct package_length pkg
Definition: interpreter.c:43
uacpi_u8 immediate_bytes[8]
Definition: interpreter.c:45
Definition: module.h:456
Definition: name.c:39
uacpi_u8 tracked_pkg_idx
Definition: interpreter.c:60
uacpi_bool preempted
Definition: interpreter.c:54
const struct uacpi_op_spec * op
Definition: interpreter.c:64
struct item_array items
Definition: interpreter.c:65
uacpi_u8 pc
Definition: interpreter.c:53
uacpi_aml_op switched_from
Definition: interpreter.c:62
uacpi_u32 begin
Definition: interpreter.c:33
uacpi_u32 end
Definition: interpreter.c:34
Definition: dhcpd.h:245
uacpi_buffer * buffer
Definition: types.h:49
uacpi_size idx
Definition: types.h:48
uacpi_size size
Definition: types.h:31
uacpi_char * text
Definition: types.h:29
void * data
Definition: types.h:27
uacpi_u8 named_objects_persist
Definition: types.h:178
uacpi_u8 * code
Definition: types.h:170
uacpi_u32 size
Definition: types.h:174
uacpi_char * text
Definition: types.h:93
uacpi_size length
Definition: types.h:99
void * data
Definition: types.h:96
uacpi_u8 * bytes
Definition: types.h:90
struct uacpi_firmware_request::@731::@734 fatal
struct uacpi_firmware_request::@731::@733 breakpoint
uacpi_object_name name
Definition: namespace.h:31
uacpi_object * object
Definition: namespace.h:33
struct uacpi_namespace_node * parent
Definition: namespace.h:34
uacpi_control_method * method
Definition: types.h:257
uacpi_u8 type
Definition: types.h:249
uacpi_field_unit * field_unit
Definition: types.h:269
uacpi_buffer_field buffer_field
Definition: types.h:255
uacpi_u64 integer
Definition: types.h:253
uacpi_object * inner_object
Definition: types.h:256
uacpi_buffer * buffer
Definition: types.h:258
uacpi_u8 * indirect_decode_ops
Definition: opcodes.h:302
uacpi_u8 properties
Definition: opcodes.h:304
uacpi_u8 decode_ops[16]
Definition: opcodes.h:301
uacpi_u64 offset
Definition: types.h:122
uacpi_u64 table_idx
Definition: types.h:127
uacpi_u16 space
Definition: types.h:120
uacpi_u64 length
Definition: types.h:123
uacpi_object ** objects
Definition: types.h:36
uacpi_size count
Definition: types.h:37
uacpi_u8 system_level
Definition: types.h:159
uacpi_u16 resource_order
Definition: types.h:160
uacpi_object_name signature
Definition: tables.h:14
char oem_table_id[8]
Definition: tables.h:20
uacpi_status uacpi_table_find(const uacpi_table_identifiers *id, uacpi_table *out_table)
Definition: tables.c:1013
uacpi_status uacpi_table_unref(uacpi_table *)
Definition: tables.c:1158
Character const *const prefix
Definition: tempnam.cpp:195
Definition: dlist.c:348
uacpi_u32 id
Definition: types.h:25
uacpi_char text[4]
Definition: types.h:24
Definition: pdh_main.c:96
struct _slot slot
Definition: vfat.h:196
static const WCHAR props[]
Definition: wbemdisp.c:288
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
int retval
Definition: wcstombs.cpp:91
void * arg
Definition: msvc.h:10
static unsigned int block
Definition: xmlmemory.c:101