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