PatchworkOS
Loading...
Searching...
No Matches
object.c
Go to the documentation of this file.
2
3#include <kernel/acpi/acpi.h>
8#include <kernel/log/log.h>
9#include <kernel/log/panic.h>
10
11#include <errno.h>
12#include <stddef.h>
13#include <stdlib.h>
14#include <sys/math.h>
15
16// Used to check for memory leaks
18
19// Cache for aml_object_t to avoid frequent allocations
21
23
28
29static void aml_object_free(aml_object_t* object)
30{
31 if (object == NULL)
32 {
33 return;
34 }
35
36 // Named objects should never be able to be freed while still being named as the parent would still have a reference
37 // to them, unless the object is root.
38 assert(!(object->flags & AML_OBJECT_NAMED) || (object->flags & AML_OBJECT_ROOT));
39
40 aml_object_clear(object);
41
43 {
44 list_push(&objectsCache, &object->listEntry);
45 }
46 else
47 {
48 free(object);
49 }
50
52}
53
55{
56 aml_object_t* object = NULL;
58 {
60 }
61
62 if (object == NULL)
63 {
64 object = calloc(1, sizeof(aml_object_t));
65 if (object == NULL)
66 {
67 return NULL;
68 }
69 }
70
71 ref_init(&object->ref, aml_object_free);
72 object->id = newObjectId++;
73 object->name = AML_NAME_UNDEFINED;
74 map_entry_init(&object->mapEntry);
75 list_entry_init(&object->listEntry);
76 object->overlay = NULL;
77 list_init(&object->children);
78 list_entry_init(&object->siblingsEntry);
79 object->parent = NULL;
80 object->flags = AML_OBJECT_NONE;
81 object->type = AML_UNINITIALIZED;
82
84 return object;
85}
86
88{
89 if (object == NULL)
90 {
91 return;
92 }
93
94 if (object->type == AML_UNINITIALIZED)
95 {
96 return;
97 }
98
99 if (object->type & AML_NAMESPACES)
100 {
101 aml_object_t* child;
102 aml_object_t* temp;
103 LIST_FOR_EACH_SAFE(child, temp, &object->children, siblingsEntry)
104 {
106 }
107 }
108
109 switch (object->type)
110 {
111 case AML_BUFFER:
112 if (object->buffer.content != NULL && object->buffer.length > AML_SMALL_BUFFER_SIZE)
113 {
114 free(object->buffer.content);
115 }
116 object->buffer.content = NULL;
117 object->buffer.length = 0;
118 break;
119 case AML_BUFFER_FIELD:
120 if (object->bufferField.target != NULL)
121 {
122 DEREF(object->bufferField.target);
123 }
124 object->bufferField.target = NULL;
125 object->bufferField.bitOffset = 0;
126 object->bufferField.bitSize = 0;
127 break;
128 case AML_DEBUG_OBJECT:
129 break;
130 case AML_DEVICE:
131 break;
132 case AML_EVENT:
133 break;
134 case AML_FIELD_UNIT:
135 switch (object->fieldUnit.fieldType)
136 {
138 DEREF(object->fieldUnit.index);
139 object->fieldUnit.index = NULL;
140 DEREF(object->fieldUnit.data);
141 object->fieldUnit.data = NULL;
142 break;
144 DEREF(object->fieldUnit.bank);
145 object->fieldUnit.bank = NULL;
146 DEREF(object->fieldUnit.bankValue);
147 object->fieldUnit.bankValue = NULL;
148 DEREF(object->fieldUnit.opregion);
149 object->fieldUnit.opregion = NULL;
150 break;
152 DEREF(object->fieldUnit.opregion);
153 object->fieldUnit.opregion = NULL;
154 break;
155 default:
156 break;
157 }
158 object->fieldUnit.fieldType = 0;
159 object->fieldUnit.bitOffset = 0;
160 object->fieldUnit.bitSize = 0;
161 break;
162 case AML_INTEGER:
163 object->integer.value = 0;
164 break;
165 case AML_METHOD:
166 object->method.implementation = NULL;
167 object->method.methodFlags = (aml_method_flags_t){0};
168 object->method.start = NULL;
169 object->method.end = NULL;
171 break;
172 case AML_MUTEX:
173 object->mutex.syncLevel = 0;
175 break;
177 if (object->objectReference.target != NULL)
178 {
180 }
181 object->objectReference.target = NULL;
182 break;
184 object->opregion.space = 0;
185 object->opregion.offset = 0;
186 object->opregion.length = 0;
187 break;
188 case AML_PACKAGE:
189 if (object->package.elements != NULL)
190 {
191 for (uint64_t i = 0; i < object->package.length; i++)
192 {
193 DEREF(object->package.elements[i]);
194 object->package.elements[i] = NULL;
195 }
197 {
198 free(object->package.elements);
199 }
200 }
201 object->package.elements = NULL;
202 object->package.length = 0;
203 break;
205 object->powerResource.systemLevel = 0;
206 object->powerResource.resourceOrder = 0;
207 break;
208 case AML_PROCESSOR:
209 object->processor.procId = 0;
210 object->processor.pblkAddr = 0;
211 object->processor.pblkLen = 0;
212 break;
213 case AML_STRING:
214 if (object->string.content != NULL && object->string.length > AML_SMALL_STRING_SIZE)
215 {
216 free(object->string.content);
217 }
218 object->string.content = NULL;
219 object->string.length = 0;
220 break;
221 case AML_THERMAL_ZONE:
222 break;
223 case AML_ALIAS:
224 if (object->alias.target != NULL)
225 {
226 DEREF(object->alias.target);
227 }
228 object->alias.target = NULL;
229 break;
230 case AML_UNRESOLVED:
232 if (object->unresolved.from != NULL)
233 {
234 DEREF(object->unresolved.from);
235 }
236 object->unresolved.from = NULL;
237 object->unresolved.nameString = (aml_name_string_t){0};
238 object->unresolved.callback = NULL;
239 break;
241 break;
242 case AML_LOCAL:
243 if (object->local.value != NULL)
244 {
245 DEREF(object->local.value);
246 }
247 object->local.value = NULL;
248 break;
249 case AML_ARG:
250 if (object->arg.value != NULL)
251 {
252 DEREF(object->arg.value);
253 }
254 object->arg.value = NULL;
255 break;
256 default:
257 panic(NULL, "Unknown AML data type %u", object->type);
258 break;
259 }
260
261 object->type = AML_UNINITIALIZED;
262}
263
265{
266 if (parent == NULL)
267 {
268 return 0;
269 }
270
271 uint64_t count = 0;
272
273 if (parent->type & AML_NAMESPACES)
274 {
275 aml_object_t* child = NULL;
276 LIST_FOR_EACH(child, &parent->children, siblingsEntry)
277 {
278 count++;
280 }
281
282 return count;
283 }
284
285 switch (parent->type)
286 {
287 case AML_PACKAGE:
288 for (uint64_t i = 0; i < parent->package.length; i++)
289 {
290 aml_object_t* element = parent->package.elements[i];
291 if (element != NULL)
292 {
293 count++;
295 }
296 }
297 break;
298 case AML_FIELD_UNIT:
299 if (parent->fieldUnit.bankValue != NULL)
300 {
301 count++;
302 }
303 break;
304 default:
305 break;
306 }
307
308 return count;
309}
310
311static inline void aml_copy_bits(uint8_t* dst, uint64_t dstOffset, const uint8_t* src, uint64_t srcOffset,
312 uint64_t bitCount)
313{
314 while (bitCount > 0)
315 {
316 uint64_t dstByte = dstOffset / 8;
317 uint64_t dstBit = dstOffset % 8;
318 uint64_t srcByte = srcOffset / 8;
319 uint64_t srcBit = srcOffset % 8;
320
321 uint64_t bitsInDstByte = 8 - dstBit;
322 uint64_t bitsInSrcByte = 8 - srcBit;
323 uint64_t bitsToCopy = (bitsInDstByte < bitsInSrcByte) ? bitsInDstByte : bitsInSrcByte;
324 bitsToCopy = (bitsToCopy < bitCount) ? bitsToCopy : bitCount;
325
326 uint8_t srcMask = ((1 << bitsToCopy) - 1) << srcBit;
327 uint8_t bits = (src[srcByte] & srcMask) >> srcBit;
328
329 uint8_t dstMask = ((1 << bitsToCopy) - 1) << dstBit;
330 dst[dstByte] = (dst[dstByte] & ~dstMask) | (bits << dstBit);
331
332 dstOffset += bitsToCopy;
333 srcOffset += bitsToCopy;
334 bitCount -= bitsToCopy;
335 }
336}
337
339{
340 if (object == NULL || data == NULL || bitSize == 0)
341 {
342 errno = EINVAL;
343 return ERR;
344 }
345
346 switch (object->type)
347 {
348 case AML_INTEGER:
349 {
350 uint64_t value = 0;
351 for (uint64_t i = 0; i < (bitSize + 7) / 8; i++)
352 {
353 value |= ((uint64_t)data[i]) << (i * 8);
354 }
355
356 uint64_t effectiveBitSize = bitSize;
357 if (bitOffset >= aml_integer_bit_size())
358 {
359 return 0;
360 }
361 if (bitOffset + bitSize > aml_integer_bit_size())
362 {
363 effectiveBitSize = aml_integer_bit_size() - bitOffset;
364 }
365
366 uint64_t mask = (effectiveBitSize >= aml_integer_bit_size()) ? aml_integer_ones()
367 : ((1ULL << effectiveBitSize) - 1) << bitOffset;
368
369 object->integer.value = (object->integer.value & ~mask) | ((value << bitOffset) & mask);
370 break;
371 }
372 case AML_BUFFER:
373 case AML_STRING:
374 {
375 uint64_t length = object->type == AML_BUFFER ? object->buffer.length : object->string.length;
376 uint8_t* content = object->type == AML_BUFFER ? object->buffer.content : (uint8_t*)object->string.content;
377 uint64_t totalBits = length * 8;
378
379 if (bitOffset >= totalBits)
380 {
381 return 0;
382 }
383 if (bitOffset + bitSize > totalBits)
384 {
385 bitSize = totalBits - bitOffset;
386 }
387
388 aml_copy_bits(content, bitOffset, data, 0, bitSize);
389 break;
390 }
391 default:
392 errno = EINVAL;
393 return ERR;
394 }
395
396 return 0;
397}
398
400{
401 if (object == NULL || out == NULL || bitSize == 0)
402 {
403 errno = EINVAL;
404 return ERR;
405 }
406
407 memset(out, 0, (bitSize + 7) / 8);
408
409 switch (object->type)
410 {
411 case AML_INTEGER:
412 {
413 if (bitOffset >= aml_integer_bit_size())
414 {
415 return 0;
416 }
417
418 uint64_t effectiveBitSize = bitSize;
419 if (bitOffset + bitSize > aml_integer_bit_size())
420 {
421 effectiveBitSize = aml_integer_bit_size() - bitOffset;
422 }
423
424 uint64_t mask =
425 (effectiveBitSize >= aml_integer_bit_size()) ? aml_integer_ones() : ((1ULL << effectiveBitSize) - 1);
426 uint64_t value = (object->integer.value >> bitOffset) & mask;
427
428 for (uint64_t i = 0; i < (effectiveBitSize + 7) / 8; i++)
429 {
430 out[i] = (value >> (i * 8)) & 0xFF;
431 }
432 break;
433 }
434 case AML_BUFFER:
435 case AML_STRING:
436 {
437 uint64_t length = object->type == AML_BUFFER ? object->buffer.length : object->string.length;
438 uint8_t* content = object->type == AML_BUFFER ? object->buffer.content : (uint8_t*)object->string.content;
439 uint64_t totalBits = length * 8;
440
441 if (bitOffset >= totalBits)
442 {
443 return 0;
444 }
445 if (bitOffset + bitSize > totalBits)
446 {
447 bitSize = totalBits - bitOffset;
448 }
449
450 aml_copy_bits(out, 0, content, bitOffset, bitSize);
451 break;
452 }
453 default:
454 errno = EINVAL;
455 return ERR;
456 }
457
458 return 0;
459}
460
462{
463 if (object->flags & AML_OBJECT_EXCEPTION_ON_USE)
464 {
465 AML_EXCEPTION_RAISE(state, AML_PARSE); // Not fatal.
466 object->flags &= ~AML_OBJECT_EXCEPTION_ON_USE;
467 // We can still use the object, so continue.
468 }
469}
470
472{
473 if (object == NULL)
474 {
475 errno = EINVAL;
476 return ERR;
477 }
478
479 if (object->type != AML_UNINITIALIZED)
480 {
481 aml_object_clear(object);
482 }
483
484 return 0;
485}
486
488{
489 if (object == NULL)
490 {
491 errno = EINVAL;
492 return ERR;
493 }
494
495 if (aml_object_check_clear(object) == ERR)
496 {
497 return ERR;
498 }
499
500 if (length <= AML_SMALL_BUFFER_SIZE)
501 {
502 object->buffer.content = object->buffer.smallBuffer;
503 memset(object->buffer.content, 0, length);
504 object->buffer.length = length;
505 object->type = AML_BUFFER;
506 return 0;
507 }
508
509 object->buffer.content = malloc(length);
510 if (object->buffer.content == NULL)
511 {
512 return ERR;
513 }
514 memset(object->buffer.content, 0, length);
515 object->buffer.length = length;
516 object->type = AML_BUFFER;
517 return 0;
518}
519
521{
522 if (object == NULL || buffer == NULL || bytesToCopy > length)
523 {
524 errno = EINVAL;
525 return ERR;
526 }
527
528 if (aml_buffer_set_empty(object, length) == ERR)
529 {
530 return ERR;
531 }
532
533 memcpy(object->buffer.content, buffer, bytesToCopy);
534 return 0;
535}
536
538 aml_bit_size_t bitSize)
539{
540 if (object == NULL || target == NULL || bitSize == 0)
541 {
542 errno = EINVAL;
543 return ERR;
544 }
545
546 if (target->type != AML_BUFFER && target->type != AML_STRING)
547 {
548 errno = EINVAL;
549 return ERR;
550 }
551
552 if (aml_object_check_clear(object) == ERR)
553 {
554 return ERR;
555 }
556
557 object->bufferField.target = REF(target);
558 object->bufferField.bitOffset = bitOffset;
559 object->bufferField.bitSize = bitSize;
560 object->type = AML_BUFFER_FIELD;
561 return 0;
562}
563
565{
566 if (object == NULL)
567 {
568 errno = EINVAL;
569 return ERR;
570 }
571
572 if (aml_object_check_clear(object) == ERR)
573 {
574 return ERR;
575 }
576
577 object->type = AML_DEBUG_OBJECT;
578 return 0;
579}
580
582{
583 if (object == NULL)
584 {
585 errno = EINVAL;
586 return ERR;
587 }
588
589 if (aml_object_check_clear(object) == ERR)
590 {
591 return ERR;
592 }
593
594 object->type = AML_DEVICE;
595 return 0;
596}
597
599{
600 if (object == NULL)
601 {
602 errno = EINVAL;
603 return ERR;
604 }
605
606 if (aml_object_check_clear(object) == ERR)
607 {
608 return ERR;
609 }
610
611 object->type = AML_EVENT;
612 return 0;
613}
614
616 aml_bit_size_t bitOffset, aml_bit_size_t bitSize)
617{
618 if (object == NULL || opregion == NULL || bitSize == 0)
619 {
620 errno = EINVAL;
621 return ERR;
622 }
623
624 if (aml_object_check_clear(object) == ERR)
625 {
626 return ERR;
627 }
628
629 object->fieldUnit.fieldType = AML_FIELD_UNIT_FIELD;
630 object->fieldUnit.index = NULL;
631 object->fieldUnit.data = NULL;
632 object->fieldUnit.bankValue = NULL;
633 object->fieldUnit.bank = NULL;
634 object->fieldUnit.opregion = REF(opregion);
635 object->fieldUnit.fieldFlags = flags;
636 object->fieldUnit.bitOffset = bitOffset;
637 object->fieldUnit.bitSize = bitSize;
638 object->type = AML_FIELD_UNIT;
639 return 0;
640}
641
643 aml_field_flags_t flags, aml_bit_size_t bitOffset, aml_bit_size_t bitSize)
644{
645 if (object == NULL || index == NULL || data == NULL || bitSize == 0)
646 {
647 errno = EINVAL;
648 return ERR;
649 }
650
651 if (aml_object_check_clear(object) == ERR)
652 {
653 return ERR;
654 }
655
656 object->fieldUnit.fieldType = AML_FIELD_UNIT_INDEX_FIELD;
657 object->fieldUnit.index = REF(index);
658 object->fieldUnit.data = REF(data);
659 object->fieldUnit.bankValue = NULL;
660 object->fieldUnit.bank = NULL;
661 object->fieldUnit.opregion = NULL;
662 object->fieldUnit.fieldFlags = flags;
663 object->fieldUnit.bitOffset = bitOffset;
664 object->fieldUnit.bitSize = bitSize;
665 object->type = AML_FIELD_UNIT;
666 return 0;
667}
668
670 uint64_t bankValue, aml_field_flags_t flags, aml_bit_size_t bitOffset, aml_bit_size_t bitSize)
671{
672 if (object == NULL || opregion == NULL || bank == NULL || bitSize == 0)
673 {
674 errno = EINVAL;
675 return ERR;
676 }
677
678 if (aml_object_check_clear(object) == ERR)
679 {
680 return ERR;
681 }
682
683 object->fieldUnit.fieldType = AML_FIELD_UNIT_BANK_FIELD;
684 object->fieldUnit.index = NULL;
685 object->fieldUnit.data = NULL;
686
687 aml_object_t* bankValueObj = aml_object_new();
688 if (bankValueObj == NULL)
689 {
690 return ERR;
691 }
692 if (aml_integer_set(bankValueObj, bankValue) == ERR)
693 {
694 DEREF(bankValueObj);
695 return ERR;
696 }
697 object->fieldUnit.bankValue = bankValueObj;
698
699 object->fieldUnit.bank = REF(bank);
700 object->fieldUnit.opregion = REF(opregion);
701 object->fieldUnit.fieldFlags = flags;
702 object->fieldUnit.bitOffset = bitOffset;
703 object->fieldUnit.bitSize = bitSize;
704 object->type = AML_FIELD_UNIT;
705 return 0;
706}
707
709{
710 if (object == NULL)
711 {
712 errno = EINVAL;
713 return ERR;
714 }
715
716 if (object->type == AML_INTEGER)
717 {
718 object->integer.value = value & aml_integer_ones();
719 return 0;
720 }
721
722 if (aml_object_check_clear(object) == ERR)
723 {
724 return ERR;
725 }
726
727 object->integer.value = value & aml_integer_ones();
728 object->type = AML_INTEGER;
729 return 0;
730}
731
733 aml_method_implementation_t implementation)
734{
735 if (object == NULL || ((start == 0 || end == 0 || start > end) && implementation == NULL))
736 {
737 errno = EINVAL;
738 return ERR;
739 }
740
741 if (aml_object_check_clear(object) == ERR)
742 {
743 return ERR;
744 }
745
746 object->method.implementation = implementation;
747 object->method.methodFlags = flags;
748 object->method.start = start;
749 object->method.end = end;
751 object->type = AML_METHOD;
752 return 0;
753}
754
756{
757 if (current == NULL || addr == NULL)
758 {
759 return NULL;
760 }
761
762 if (current->type == AML_METHOD)
763 {
764 if (addr >= current->method.start && addr < current->method.end)
765 {
766 return REF(&current->method);
767 }
768 }
769
770 if (current->type & AML_NAMESPACES)
771 {
772 aml_object_t* child = NULL;
773 LIST_FOR_EACH(child, &current->children, siblingsEntry)
774 {
775 aml_method_obj_t* result = aml_method_find_recursive(child, addr);
776 if (result != NULL)
777 {
778 // Check for methods in methods
779 aml_method_obj_t* methodInMethod =
781 if (methodInMethod != NULL)
782 {
783 DEREF(result);
784 return methodInMethod; // Transfer ownership
785 }
786 return result; // Transfer ownership
787 }
788 }
789 }
790
791 return NULL;
792}
793
795{
796 if (addr == NULL)
797 {
798 errno = EINVAL;
799 return NULL;
800 }
801
803 if (root == NULL)
804 {
805 return NULL;
806 }
807 DEREF_DEFER(root);
808
809 return aml_method_find_recursive(root, addr); // Transfer ownership
810}
811
813{
814 if (object == NULL || syncLevel > 15)
815 {
816 errno = EINVAL;
817 return ERR;
818 }
819
820 if (aml_object_check_clear(object) == ERR)
821 {
822 return ERR;
823 }
824
825 object->mutex.syncLevel = syncLevel;
826 aml_mutex_id_init(&object->mutex.mutex);
827 object->type = AML_MUTEX;
828 return 0;
829}
830
832{
833 if (object == NULL || target == NULL)
834 {
835 errno = EINVAL;
836 return ERR;
837 }
838
839 if (aml_object_check_clear(object) == ERR)
840 {
841 return ERR;
842 }
843
844 object->objectReference.target = REF(target);
845 object->type = AML_OBJECT_REFERENCE;
846 return 0;
847}
848
850{
851 if (object == NULL || length == 0)
852 {
853 errno = EINVAL;
854 return ERR;
855 }
856
857 if (aml_object_check_clear(object) == ERR)
858 {
859 return ERR;
860 }
861
862 object->opregion.space = space;
863 object->opregion.offset = offset;
864 object->opregion.length = length;
865 object->type = AML_OPERATION_REGION;
866 return 0;
867}
868
870{
871 if (object == NULL)
872 {
873 errno = EINVAL;
874 return ERR;
875 }
876
877 if (aml_object_check_clear(object) == ERR)
878 {
879 return ERR;
880 }
881
882 if (length <= AML_SMALL_PACKAGE_SIZE)
883 {
884 object->package.elements = object->package.smallElements;
885 }
886 else
887 {
888 object->package.elements = malloc(sizeof(aml_object_t*) * length);
889 if (object->package.elements == NULL)
890 {
891 return ERR;
892 }
893 }
894 memset(object->package.elements, 0, sizeof(aml_object_t*) * length);
895
896 for (uint64_t i = 0; i < length; i++)
897 {
898 object->package.elements[i] = aml_object_new();
899 if (object->package.elements[i] == NULL)
900 {
901 for (uint64_t j = 0; j < i; j++)
902 {
903 DEREF(object->package.elements[j]);
904 }
905 free(object->package.elements);
906 object->package.elements = NULL;
907 return ERR;
908 }
909 }
910 object->package.length = length;
911 object->type = AML_PACKAGE;
912 return 0;
913}
914
916 aml_resource_order_t resourceOrder)
917{
918 if (object == NULL)
919 {
920 errno = EINVAL;
921 return ERR;
922 }
923
924 if (aml_object_check_clear(object) == ERR)
925 {
926 return ERR;
927 }
928
929 object->powerResource.systemLevel = systemLevel;
930 object->powerResource.resourceOrder = resourceOrder;
931 object->type = AML_POWER_RESOURCE;
932 return 0;
933}
934
936{
937 if (object == NULL)
938 {
939 errno = EINVAL;
940 return ERR;
941 }
942
943 if (aml_object_check_clear(object) == ERR)
944 {
945 return ERR;
946 }
947
948 object->processor.procId = procId;
949 object->processor.pblkAddr = pblkAddr;
950 object->processor.pblkLen = pblkLen;
951 object->type = AML_PROCESSOR;
952 return 0;
953}
954
956{
957 if (object == NULL)
958 {
959 errno = EINVAL;
960 return ERR;
961 }
962
963 if (aml_object_check_clear(object) == ERR)
964 {
965 return ERR;
966 }
967
968 if (length <= AML_SMALL_STRING_SIZE)
969 {
970 object->string.content = object->string.smallString;
971 memset(object->string.content, 0, length + 1);
972 object->string.length = length;
973 object->type = AML_STRING;
974 return 0;
975 }
976
977 object->string.content = malloc(length + 1);
978 if (object->string.content == NULL)
979 {
980 return ERR;
981 }
982 memset(object->string.content, 0, length + 1);
983 object->string.length = length;
984 object->type = AML_STRING;
985 return 0;
986}
987
988uint64_t aml_string_set(aml_object_t* object, const char* str)
989{
990 if (object == NULL || str == NULL)
991 {
992 errno = EINVAL;
993 return ERR;
994 }
995
996 size_t length = strlen(str);
997 if (aml_string_set_empty(object, length) == ERR)
998 {
999 return ERR;
1000 }
1001 memcpy(object->string.content, str, length);
1002 return 0;
1003}
1004
1006{
1007 if (string == NULL || newLength == 0)
1008 {
1009 errno = EINVAL;
1010 return ERR;
1011 }
1012
1013 if (newLength == string->length)
1014 {
1015 return 0;
1016 }
1017
1018 if (newLength <= AML_SMALL_STRING_SIZE && string->length <= AML_SMALL_STRING_SIZE)
1019 {
1020 if (newLength > string->length)
1021 {
1022 memset(string->content + string->length, 0, newLength - string->length);
1023 }
1024 string->content[newLength] = '\0';
1025 string->length = newLength;
1026 return 0;
1027 }
1028
1029 if (newLength <= AML_SMALL_STRING_SIZE && string->length > AML_SMALL_STRING_SIZE)
1030 {
1031 memcpy(string->smallString, string->content, newLength);
1032 string->smallString[newLength] = '\0';
1033 free(string->content);
1034 string->content = string->smallString;
1035 string->length = newLength;
1036 return 0;
1037 }
1038
1039 if (newLength > AML_SMALL_STRING_SIZE && string->length <= AML_SMALL_STRING_SIZE)
1040 {
1041 char* newBuffer = malloc(newLength + 1);
1042 if (newBuffer == NULL)
1043 {
1044 return ERR;
1045 }
1046 memcpy(newBuffer, string->content, string->length);
1047 memset(newBuffer + string->length, 0, newLength - string->length);
1048 newBuffer[newLength] = '\0';
1049 string->content = newBuffer;
1050 string->length = newLength;
1051 return 0;
1052 }
1053
1054 if (newLength > AML_SMALL_STRING_SIZE && string->length > AML_SMALL_STRING_SIZE)
1055 {
1056 char* newBuffer = malloc(newLength + 1);
1057 if (newBuffer == NULL)
1058 {
1059 return ERR;
1060 }
1061 size_t copyLen = (newLength < string->length ? newLength : string->length);
1062 memcpy(newBuffer, string->content, copyLen);
1063 if (newLength > string->length)
1064 {
1065 memset(newBuffer + string->length, 0, newLength - string->length);
1066 }
1067 newBuffer[newLength] = '\0';
1068 free(string->content);
1069 string->content = newBuffer;
1070 string->length = newLength;
1071 return 0;
1072 }
1073
1074 // Should never reach here
1075 errno = EINVAL;
1076 return ERR;
1077}
1078
1080{
1081 if (object == NULL)
1082 {
1083 errno = EINVAL;
1084 return ERR;
1085 }
1086
1087 if (aml_object_check_clear(object) == ERR)
1088 {
1089 return ERR;
1090 }
1091
1092 object->type = AML_THERMAL_ZONE;
1093 return 0;
1094}
1095
1097{
1098 if (object == NULL || target == NULL)
1099 {
1100 errno = EINVAL;
1101 return ERR;
1102 }
1103
1104 if (aml_object_check_clear(object) == ERR)
1105 {
1106 return ERR;
1107 }
1108
1109 object->alias.target = REF(target);
1110 object->type = AML_ALIAS;
1111 return 0;
1112}
1113
1115{
1116 if (alias == NULL)
1117 {
1118 return NULL;
1119 }
1120
1121 aml_object_t* current = REF(CONTAINER_OF(alias, aml_object_t, alias));
1122 while (current != NULL && current->type == AML_ALIAS)
1123 {
1124 aml_object_t* next = REF(current->alias.target);
1125 if (next == NULL)
1126 {
1127 return NULL;
1128 }
1129 DEREF(current);
1130 current = next;
1131 }
1132 return current;
1133}
1134
1137{
1138 if (object == NULL || nameString == NULL || callback == NULL)
1139 {
1140 errno = EINVAL;
1141 return ERR;
1142 }
1143
1144 if (aml_object_check_clear(object) == ERR)
1145 {
1146 return ERR;
1147 }
1148
1149 object->unresolved.nameString = *nameString;
1150 object->unresolved.from = REF(from);
1151 object->unresolved.callback = callback;
1152 object->type = AML_UNRESOLVED;
1153
1155 {
1156 object->type = AML_UNINITIALIZED;
1157 return ERR;
1158 }
1159 return 0;
1160}
1161
1163{
1164 if (object == NULL)
1165 {
1166 errno = EINVAL;
1167 return ERR;
1168 }
1169
1170 if (aml_object_check_clear(object) == ERR)
1171 {
1172 return ERR;
1173 }
1174
1175 object->type = AML_PREDEFINED_SCOPE;
1176 return 0;
1177}
1178
1180{
1181 if (object == NULL)
1182 {
1183 errno = EINVAL;
1184 return ERR;
1185 }
1186
1187 if (aml_object_check_clear(object) == ERR)
1188 {
1189 return ERR;
1190 }
1191
1192 if (value == NULL)
1193 {
1194 object->arg.value = NULL;
1195 object->type = AML_ARG;
1196 return 0;
1197 }
1198
1199 object->arg.value = REF(value);
1200 object->type = AML_ARG;
1201 return 0;
1202}
1203
1205{
1206 if (object == NULL)
1207 {
1208 errno = EINVAL;
1209 return ERR;
1210 }
1211
1212 if (aml_object_check_clear(object) == ERR)
1213 {
1214 return ERR;
1215 }
1216
1217 object->local.value = aml_object_new();
1218 if (object->local.value == NULL)
1219 {
1220 return ERR;
1221 }
1222 object->type = AML_LOCAL;
1223 return 0;
1224}
#define assert(expression)
Definition assert.h:29
static fd_t data
Definition dwm.c:21
uint64_t aml_bit_size_t
Represents a size in bits within an opregion.
uint8_t aml_proc_id_t
ProcID structure, deprecated in version 6.4 of the ACPI specification.
Definition named.h:151
uint32_t aml_pblk_addr_t
PblkAddr structure, deprecated in version 6.4 of the ACPI specification.
Definition named.h:156
uint8_t aml_system_level_t
SystemLevel structure.
Definition named.h:166
uint8_t aml_pblk_len_t
PblkLen structure, deprecated in version 6.4 of the ACPI specification.
Definition named.h:161
uint8_t aml_sync_level_t
Definition named.h:135
aml_region_space_t
Region Space Encoding.
Definition named.h:30
uint16_t aml_resource_order_t
ResourceOrder structure.
Definition named.h:171
#define AML_EXCEPTION_RAISE(state, code)
Macro to raise an AML exception with the current function name.
Definition exception.h:113
@ AML_PARSE
Definition exception.h:31
uint8_t aml_integer_bit_size(void) PURE_FUNC
Get the bit size of an AML integer.
Definition integer.c:27
uint64_t aml_integer_t
AML Integer type.
Definition integer.h:20
aml_integer_t aml_integer_ones(void) PURE_FUNC
Get a mask with all bits set for the current AML integer size.
Definition integer.c:32
void aml_mutex_id_init(aml_mutex_id_t *mutex)
Create a new mutex and return its id.
Definition mutex.c:84
void aml_mutex_id_deinit(aml_mutex_id_t *mutex)
Destroy the mutex with the given id.
Definition mutex.c:89
#define AML_NAME_UNDEFINED
Macro for an undefined name.
Definition namespace.h:121
void aml_namespace_remove(aml_object_t *object)
Remove an object from the namespace heirarchy it was added to.
Definition namespace.c:421
aml_object_t * aml_namespace_get_root(void)
Get the root object of the namespace heirarchy.
Definition namespace.c:86
uint64_t aml_object_reference_set(aml_object_t *object, aml_object_t *target)
Set a object as an ObjectReference to the given target object.
Definition object.c:831
void aml_object_exception_check(aml_object_t *object, aml_state_t *state)
Check if a object has the AML_OBJECT_EXCEPTION_ON_USE flag set and raise an exception if it is.
Definition object.c:461
uint64_t aml_field_unit_field_set(aml_object_t *object, aml_opregion_obj_t *opregion, aml_field_flags_t flags, aml_bit_size_t bitOffset, aml_bit_size_t bitSize)
Set a object as a field unit of type Field.
Definition object.c:615
uint64_t aml_string_resize(aml_string_obj_t *string, uint64_t newLength)
Resize a string object to the new length.
Definition object.c:1005
uint64_t aml_method_set(aml_object_t *object, aml_method_flags_t flags, const uint8_t *start, const uint8_t *end, aml_method_implementation_t implementation)
Set a object as a method with the given flags and address range.
Definition object.c:732
uint64_t aml_local_set(aml_object_t *object)
Set a object as a empty local variable.
Definition object.c:1204
uint64_t aml_event_set(aml_object_t *object)
Set a object as an event.
Definition object.c:598
uint64_t aml_device_set(aml_object_t *object)
Set a object as a device or bus.
Definition object.c:581
uint64_t aml_mutex_set(aml_object_t *object, aml_sync_level_t syncLevel)
Set a object as a mutex with the given synchronization level.
Definition object.c:812
uint64_t aml_power_resource_set(aml_object_t *object, aml_system_level_t systemLevel, aml_resource_order_t resourceOrder)
Set a object as a power resource with the given system level and resource order.
Definition object.c:915
uint64_t aml_package_set(aml_object_t *object, uint64_t length)
Set a object as a package with the given number of elements.
Definition object.c:869
uint64_t aml_integer_set(aml_object_t *object, aml_integer_t value)
Set a object as an integer with the given value and bit width.
Definition object.c:708
aml_method_obj_t * aml_method_find(const uint8_t *addr)
Find the method which contains the provided address in its AML bytecode range.
Definition object.c:794
#define AML_SMALL_STRING_SIZE
Size of string buffers used for small objects optimization, not including the null terminator.
Definition object.h:35
uint64_t aml_object_count_children(aml_object_t *parent)
Recursively count how many children an object has.
Definition object.c:264
uint64_t aml_thermal_zone_set(aml_object_t *object)
Set a object as a thermal zone.
Definition object.c:1079
aml_object_t * aml_object_new(void)
Allocate a new ACPI object.
Definition object.c:54
uint64_t aml_string_set(aml_object_t *object, const char *str)
Set a object as a string with the given value.
Definition object.c:988
uint64_t aml_field_unit_index_field_set(aml_object_t *object, aml_field_unit_obj_t *index, aml_field_unit_obj_t *data, aml_field_flags_t flags, aml_bit_size_t bitOffset, aml_bit_size_t bitSize)
Set a object as a field unit of type IndexField.
Definition object.c:642
uint64_t aml_object_set_bits_at(aml_object_t *object, aml_bit_size_t bitOffset, aml_bit_size_t bitSize, uint8_t *data)
Store bits into a object at the specified bit offset and size.
Definition object.c:338
uint64_t aml_alias_set(aml_object_t *object, aml_object_t *target)
Set a object as an alias to the given target object.
Definition object.c:1096
uint64_t aml_arg_set(aml_object_t *object, aml_object_t *value)
Set a object as an argument with the given target object.
Definition object.c:1179
aml_object_t * aml_alias_obj_traverse(aml_alias_obj_t *alias)
Traverse an alias object to get the target object.
Definition object.c:1114
uint64_t aml_predefined_scope_set(aml_object_t *object)
Set a object as a predefined scope with the given name.
Definition object.c:1162
uint64_t aml_buffer_set_empty(aml_object_t *object, uint64_t length)
Set a object as an empty buffer with the given length.
Definition object.c:487
aml_object_t *(* aml_method_implementation_t)(aml_method_obj_t *method, aml_object_t **args, uint64_t argCount)
Method Implementation function type.
Definition object.h:173
uint64_t aml_buffer_field_set(aml_object_t *object, aml_object_t *target, aml_bit_size_t bitOffset, aml_bit_size_t bitSize)
Set a object as a buffer field with the given buffer, bit offset and bit size.
Definition object.c:537
uint64_t aml_string_set_empty(aml_object_t *object, uint64_t length)
Set a object as an empty string with the given length.
Definition object.c:955
uint64_t aml_debug_object_set(aml_object_t *object)
Set a object as a debug object.
Definition object.c:564
#define AML_OBJECT_ID_NONE
Value for an invalid object id.
Definition object.h:151
void aml_object_clear(aml_object_t *object)
Clear the data of a object, setting its type to AML_UNINITIALIZED.
Definition object.c:87
uint64_t aml_object_get_bits_at(aml_object_t *object, aml_bit_size_t bitOffset, aml_bit_size_t bitSize, uint8_t *out)
Retrieve bits from a object at the specified bit offset and size.
Definition object.c:399
uint64_t aml_object_id_t
Object id type.
Definition object.h:146
uint64_t aml_processor_set(aml_object_t *object, aml_proc_id_t procId, aml_pblk_addr_t pblkAddr, aml_pblk_len_t pblkLen)
Set a object as a processor with the given ProcID, PblkAddr, and PblkLen.
Definition object.c:935
#define AML_SMALL_BUFFER_SIZE
Size of buffers used for small objects optimization.
Definition object.h:30
uint64_t aml_object_get_total_count(void)
Get the total amount of allocated ACPI objects.
Definition object.c:24
uint64_t aml_operation_region_set(aml_object_t *object, aml_region_space_t space, uintptr_t offset, uint32_t length)
Set a object as an operation region with the given space, offset, and length.
Definition object.c:849
uint64_t aml_unresolved_set(aml_object_t *object, const aml_name_string_t *nameString, aml_object_t *from, aml_patch_up_resolve_callback_t callback)
Set a object as an unresolved reference with the given namestring and starting point.
Definition object.c:1135
uint64_t aml_buffer_set(aml_object_t *object, const uint8_t *buffer, uint64_t bytesToCopy, uint64_t length)
Set a object as a buffer with the given content.
Definition object.c:520
uint64_t aml_field_unit_bank_field_set(aml_object_t *object, aml_opregion_obj_t *opregion, aml_field_unit_obj_t *bank, uint64_t bankValue, aml_field_flags_t flags, aml_bit_size_t bitOffset, aml_bit_size_t bitSize)
Set a object as a field unit of type BankField.
Definition object.c:669
#define AML_OBJECT_CACHE_SIZE
Amount of objects to store in the cache before freeing them instead.
Definition object.h:45
#define AML_SMALL_PACKAGE_SIZE
Size of package element arrays used for small objects optimization.
Definition object.h:40
@ AML_UNRESOLVED
Not in the spec, used internally to represent unresolved references.
Definition object.h:86
@ AML_METHOD
Definition object.h:75
@ AML_BUFFER_FIELD
Definition object.h:60
@ AML_PROCESSOR
Definition object.h:81
@ AML_PACKAGE
Definition object.h:79
@ AML_OBJECT_REFERENCE
Definition object.h:77
@ AML_OPERATION_REGION
Definition object.h:78
@ AML_DEBUG_OBJECT
Definition object.h:61
@ AML_STRING
Definition object.h:83
@ AML_ALIAS
Not in the spec, used internally to represent Aliases.
Definition object.h:85
@ AML_ARG
Not in the spec, used internally to represent method arguments.
Definition object.h:88
@ AML_THERMAL_ZONE
Definition object.h:84
@ AML_FIELD_UNIT
Definition object.h:64
@ AML_POWER_RESOURCE
Definition object.h:80
@ AML_EVENT
Definition object.h:63
@ AML_DEVICE
Definition object.h:62
@ AML_NAMESPACES
Definition object.h:107
@ AML_MUTEX
Definition object.h:76
@ AML_LOCAL
Not in the spec, used internally to represent method local variables.
Definition object.h:89
@ AML_INTEGER
Definition object.h:65
@ AML_PREDEFINED_SCOPE
Not in the spec, used internally to represent _SB, _GPE, etc.
Definition object.h:87
@ AML_UNINITIALIZED
Definition object.h:58
@ AML_BUFFER
Definition object.h:59
@ AML_FIELD_UNIT_BANK_FIELD
Definition object.h:166
@ AML_FIELD_UNIT_FIELD
Definition object.h:164
@ AML_FIELD_UNIT_INDEX_FIELD
Definition object.h:165
@ AML_OBJECT_ROOT
Is the root object.
Definition object.h:125
@ AML_OBJECT_EXCEPTION_ON_USE
Definition object.h:133
@ AML_OBJECT_NAMED
Appears in the namespace tree. Will be set in aml_object_add().
Definition object.h:126
@ AML_OBJECT_NONE
No flags.
Definition object.h:124
void aml_patch_up_remove_unresolved(aml_unresolved_obj_t *unresolved)
Removes an unresolved reference from the global list.
Definition patch_up.c:41
uint64_t aml_patch_up_add_unresolved(aml_unresolved_obj_t *unresolved)
Adds a unresolved reference to the global list.
Definition patch_up.c:21
uint64_t(* aml_patch_up_resolve_callback_t)(aml_state_t *state, aml_object_t *match, aml_object_t *unresolved)
Callback type for resolving a forward reference.
Definition patch_up.h:25
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
Definition panic.c:362
void map_entry_init(map_entry_t *entry)
Initialize a map entry.
Definition map.c:71
#define DEREF_DEFER(ptr)
RAII-style cleanup for scoped references.
Definition ref.h:54
static void ref_init(ref_t *ref, void *free)
Initialize a reference counter.
Definition ref.h:92
#define REF(ptr)
Increment reference count.
Definition ref.h:65
#define DEREF(ptr)
Decrement reference count.
Definition ref.h:80
#define EINVAL
Invalid argument.
Definition errno.h:142
#define errno
Error number variable.
Definition errno.h:27
#define LIST_FOR_EACH(elem, list, member)
Iterates over a list.
Definition list.h:65
static uint64_t list_length(list_t *list)
Gets the length of the list.
Definition list.h:248
#define LIST_CREATE(name)
Creates a list initializer.
Definition list.h:176
#define LIST_FOR_EACH_SAFE(elem, temp, list, member)
Safely iterates over a list, allowing for element removal during iteration.
Definition list.h:81
static void list_push(list_t *list, list_entry_t *entry)
Pushes an entry to the end of the list.
Definition list.h:345
static bool list_is_empty(list_t *list)
Checks if a list is empty.
Definition list.h:229
static void list_entry_init(list_entry_t *entry)
Initializes a list entry.
Definition list.h:184
static void list_init(list_t *list)
Initializes a list.
Definition list.h:198
static list_entry_t * list_pop(list_t *list)
Pops the first entry from the list.
Definition list.h:361
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
#define CONTAINER_OF(ptr, type, member)
Container of macro.
#define CONTAINER_OF_SAFE(ptr, type, member)
Safe container of macro.
EFI_PHYSICAL_ADDRESS buffer
Definition mem.c:15
static aml_object_id_t newObjectId
Definition object.c:22
static uint64_t totalObjects
Definition object.c:17
static uint64_t aml_object_check_clear(aml_object_t *object)
Definition object.c:471
static aml_method_obj_t * aml_method_find_recursive(aml_object_t *current, const uint8_t *addr)
Definition object.c:755
static void aml_copy_bits(uint8_t *dst, uint64_t dstOffset, const uint8_t *src, uint64_t srcOffset, uint64_t bitCount)
Definition object.c:311
static list_t objectsCache
Definition object.c:20
static void aml_object_free(aml_object_t *object)
Definition object.c:29
static void start()
Definition main.c:542
static atomic_long next
Definition main.c:10
static atomic_long count
Definition main.c:9
__UINT32_TYPE__ uint32_t
Definition stdint.h:15
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:43
_PUBLIC void * calloc(size_t nmemb, size_t size)
Definition calloc.c:6
_PUBLIC void * malloc(size_t size)
Definition malloc.c:5
_PUBLIC void free(void *ptr)
Definition free.c:11
_PUBLIC void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
Definition memcpy.c:4
_PUBLIC size_t strlen(const char *s)
Definition strlen.c:3
_PUBLIC void * memset(void *s, int c, size_t n)
Definition memset.c:4
Data for an alias object.
Definition object.h:380
aml_object_t * target
Definition object.h:382
aml_object_t * value
The object that was passed as the argument.
Definition object.h:407
aml_object_t * target
Definition object.h:225
uint64_t length
Definition object.h:214
uint8_t * content
Definition object.h:213
FieldFlags structure.
Definition named.h:86
Data for a field unit object.
Definition object.h:246
aml_field_unit_obj_type_t fieldType
The type of field unit.
Definition object.h:248
aml_field_unit_obj_t * bank
Used for BankField.
Definition object.h:252
aml_field_unit_obj_t * index
Used for IndexField.
Definition object.h:249
aml_field_unit_obj_t * data
Used for IndexField.
Definition object.h:250
aml_opregion_obj_t * opregion
Used for Field and BankField.
Definition object.h:253
aml_object_t * bankValue
Used for BankField.
Definition object.h:251
aml_object_t * value
The value of the local variable.
Definition object.h:417
MethodFlags structure.
Definition named.h:142
Data for a method object.
Definition object.h:284
aml_mutex_id_t mutex
Definition object.h:294
const uint8_t * start
Definition object.h:292
aml_mutex_id_t mutex
Definition object.h:305
A NameString structure.
Definition name.h:87
aml_object_t * target
Definition object.h:315
ACPI object.
Definition object.h:425
aml_buffer_obj_t buffer
Definition object.h:431
aml_buffer_field_obj_t bufferField
Definition object.h:432
aml_local_obj_t local
Definition object.h:449
aml_mutex_obj_t mutex
Definition object.h:438
aml_object_reference_obj_t objectReference
Definition object.h:439
aml_field_unit_obj_t fieldUnit
Definition object.h:434
aml_package_obj_t package
Definition object.h:441
aml_alias_obj_t alias
Definition object.h:446
aml_unresolved_obj_t unresolved
Definition object.h:447
aml_string_obj_t string
Definition object.h:444
aml_method_obj_t method
Definition object.h:437
aml_arg_obj_t arg
Definition object.h:448
Data for an operation region object.
Definition object.h:323
uint64_t length
Definition object.h:340
aml_object_t ** elements
Definition object.h:339
AML State.
Definition state.h:25
Data for a string object.
Definition object.h:368
char smallString[AML_SMALL_STRING_SIZE+1]
Used for small object optimization.
Definition object.h:372
char * content
Definition object.h:370
uint64_t length
Definition object.h:371
aml_name_string_t nameString
The NameString representing the path to the target object.
Definition object.h:392
aml_object_t * from
The object to start the search from when resolving the reference.
Definition object.h:393
A doubly linked list.
Definition list.h:51