76 object->overlay =
NULL;
79 object->parent =
NULL;
109 switch (object->type)
116 object->buffer.content =
NULL;
117 object->buffer.length = 0;
124 object->bufferField.target =
NULL;
125 object->bufferField.bitOffset = 0;
126 object->bufferField.bitSize = 0;
139 object->fieldUnit.index =
NULL;
141 object->fieldUnit.data =
NULL;
145 object->fieldUnit.bank =
NULL;
147 object->fieldUnit.bankValue =
NULL;
149 object->fieldUnit.opregion =
NULL;
153 object->fieldUnit.opregion =
NULL;
158 object->fieldUnit.fieldType = 0;
159 object->fieldUnit.bitOffset = 0;
160 object->fieldUnit.bitSize = 0;
163 object->integer.value = 0;
166 object->method.implementation =
NULL;
168 object->method.start =
NULL;
169 object->method.end =
NULL;
173 object->mutex.syncLevel = 0;
181 object->objectReference.target =
NULL;
184 object->opregion.space = 0;
185 object->opregion.offset = 0;
186 object->opregion.length = 0;
191 for (
uint64_t i = 0; i <
object->package.length; i++)
194 object->package.elements[i] =
NULL;
201 object->package.elements =
NULL;
202 object->package.length = 0;
205 object->powerResource.systemLevel = 0;
206 object->powerResource.resourceOrder = 0;
209 object->processor.procId = 0;
210 object->processor.pblkAddr = 0;
211 object->processor.pblkLen = 0;
218 object->string.content =
NULL;
219 object->string.length = 0;
228 object->alias.target =
NULL;
236 object->unresolved.from =
NULL;
238 object->unresolved.callback =
NULL;
247 object->local.value =
NULL;
254 object->arg.value =
NULL;
257 panic(
NULL,
"Unknown AML data type %u", object->type);
285 switch (parent->type)
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;
326 uint8_t srcMask = ((1 << bitsToCopy) - 1) << srcBit;
327 uint8_t bits = (src[srcByte] & srcMask) >> srcBit;
329 uint8_t dstMask = ((1 << bitsToCopy) - 1) << dstBit;
330 dst[dstByte] = (dst[dstByte] & ~dstMask) | (bits << dstBit);
332 dstOffset += bitsToCopy;
333 srcOffset += bitsToCopy;
334 bitCount -= bitsToCopy;
346 switch (object->type)
351 for (
uint64_t i = 0; i < (bitSize + 7) / 8; i++)
356 uint64_t effectiveBitSize = bitSize;
367 : ((1ULL << effectiveBitSize) - 1) << bitOffset;
369 object->integer.value = (
object->integer.value & ~mask) | ((value << bitOffset) & mask);
375 uint64_t length =
object->type ==
AML_BUFFER ?
object->buffer.length :
object->string.length;
379 if (bitOffset >= totalBits)
383 if (bitOffset + bitSize > totalBits)
385 bitSize = totalBits - bitOffset;
401 if (
object ==
NULL || out ==
NULL || bitSize == 0)
407 memset(out, 0, (bitSize + 7) / 8);
409 switch (object->type)
418 uint64_t effectiveBitSize = bitSize;
426 uint64_t value = (
object->integer.value >> bitOffset) & mask;
428 for (
uint64_t i = 0; i < (effectiveBitSize + 7) / 8; i++)
430 out[i] = (value >> (i * 8)) & 0xFF;
437 uint64_t length =
object->type ==
AML_BUFFER ?
object->buffer.length :
object->string.length;
441 if (bitOffset >= totalBits)
445 if (bitOffset + bitSize > totalBits)
447 bitSize = totalBits - bitOffset;
466 object->flags &= ~AML_OBJECT_EXCEPTION_ON_USE;
502 object->buffer.content =
object->buffer.smallBuffer;
504 object->buffer.length = length;
509 object->buffer.content =
malloc(length);
515 object->buffer.length = length;
540 if (
object ==
NULL || target ==
NULL || bitSize == 0)
557 object->bufferField.target =
REF(target);
558 object->bufferField.bitOffset = bitOffset;
559 object->bufferField.bitSize = bitSize;
618 if (
object ==
NULL || opregion ==
NULL || bitSize == 0)
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;
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;
672 if (
object ==
NULL || opregion ==
NULL || bank ==
NULL || bitSize == 0)
684 object->fieldUnit.index =
NULL;
685 object->fieldUnit.data =
NULL;
688 if (bankValueObj ==
NULL)
697 object->fieldUnit.bankValue = bankValueObj;
700 object->fieldUnit.opregion =
REF(opregion);
701 object->fieldUnit.fieldFlags = flags;
702 object->fieldUnit.bitOffset = bitOffset;
703 object->fieldUnit.bitSize = bitSize;
735 if (
object ==
NULL || ((
start == 0 || end == 0 ||
start > end) && implementation ==
NULL))
746 object->method.implementation = implementation;
747 object->method.methodFlags = flags;
748 object->method.start =
start;
749 object->method.end = end;
757 if (current ==
NULL || addr ==
NULL)
764 if (addr >= current->
method.
start && addr < current->method.end)
781 if (methodInMethod !=
NULL)
784 return methodInMethod;
814 if (
object ==
NULL || syncLevel > 15)
825 object->mutex.syncLevel = syncLevel;
833 if (
object ==
NULL || target ==
NULL)
844 object->objectReference.target =
REF(target);
851 if (
object ==
NULL || length == 0)
862 object->opregion.space = space;
863 object->opregion.offset = offset;
864 object->opregion.length = length;
884 object->package.elements =
object->package.smallElements;
896 for (
uint64_t i = 0; i < length; i++)
906 object->package.elements =
NULL;
910 object->package.length = length;
929 object->powerResource.systemLevel = systemLevel;
930 object->powerResource.resourceOrder = resourceOrder;
948 object->processor.procId = procId;
949 object->processor.pblkAddr = pblkAddr;
950 object->processor.pblkLen = pblkLen;
970 object->string.content =
object->string.smallString;
972 object->string.length = length;
977 object->string.content =
malloc(length + 1);
983 object->string.length = length;
996 size_t length =
strlen(str);
1007 if (
string ==
NULL || newLength == 0)
1013 if (newLength == string->
length)
1020 if (newLength > string->
length)
1024 string->content[newLength] =
'\0';
1025 string->length = newLength;
1032 string->smallString[newLength] =
'\0';
1034 string->content =
string->smallString;
1035 string->length = newLength;
1041 char* newBuffer =
malloc(newLength + 1);
1042 if (newBuffer ==
NULL)
1048 newBuffer[newLength] =
'\0';
1049 string->content = newBuffer;
1050 string->length = newLength;
1056 char* newBuffer =
malloc(newLength + 1);
1057 if (newBuffer ==
NULL)
1061 size_t copyLen = (newLength <
string->length ? newLength :
string->length);
1063 if (newLength > string->
length)
1067 newBuffer[newLength] =
'\0';
1069 string->content = newBuffer;
1070 string->length = newLength;
1098 if (
object ==
NULL || target ==
NULL)
1109 object->alias.target =
REF(target);
1138 if (
object ==
NULL || nameString ==
NULL || callback ==
NULL)
1150 object->unresolved.from =
REF(from);
1151 object->unresolved.callback = callback;
1194 object->arg.value =
NULL;
1199 object->arg.value =
REF(value);
#define assert(expression)
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.
uint32_t aml_pblk_addr_t
PblkAddr structure, deprecated in version 6.4 of the ACPI specification.
uint8_t aml_system_level_t
SystemLevel structure.
uint8_t aml_pblk_len_t
PblkLen structure, deprecated in version 6.4 of the ACPI specification.
aml_region_space_t
Region Space Encoding.
uint16_t aml_resource_order_t
ResourceOrder structure.
#define AML_EXCEPTION_RAISE(state, code)
Macro to raise an AML exception with the current function name.
uint8_t aml_integer_bit_size(void) PURE_FUNC
Get the bit size of an AML integer.
uint64_t aml_integer_t
AML Integer type.
aml_integer_t aml_integer_ones(void) PURE_FUNC
Get a mask with all bits set for the current AML integer size.
void aml_mutex_id_init(aml_mutex_id_t *mutex)
Create a new mutex and return its id.
void aml_mutex_id_deinit(aml_mutex_id_t *mutex)
Destroy the mutex with the given id.
#define AML_NAME_UNDEFINED
Macro for an undefined name.
void aml_namespace_remove(aml_object_t *object)
Remove an object from the namespace heirarchy it was added to.
aml_object_t * aml_namespace_get_root(void)
Get the root object of the namespace heirarchy.
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.
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.
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.
uint64_t aml_string_resize(aml_string_obj_t *string, uint64_t newLength)
Resize a string object to the new length.
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.
uint64_t aml_local_set(aml_object_t *object)
Set a object as a empty local variable.
uint64_t aml_event_set(aml_object_t *object)
Set a object as an event.
uint64_t aml_device_set(aml_object_t *object)
Set a object as a device or bus.
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.
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.
uint64_t aml_package_set(aml_object_t *object, uint64_t length)
Set a object as a package with the given number of elements.
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.
aml_method_obj_t * aml_method_find(const uint8_t *addr)
Find the method which contains the provided address in its AML bytecode range.
#define AML_SMALL_STRING_SIZE
Size of string buffers used for small objects optimization, not including the null terminator.
uint64_t aml_object_count_children(aml_object_t *parent)
Recursively count how many children an object has.
uint64_t aml_thermal_zone_set(aml_object_t *object)
Set a object as a thermal zone.
aml_object_t * aml_object_new(void)
Allocate a new ACPI object.
uint64_t aml_string_set(aml_object_t *object, const char *str)
Set a object as a string with the given value.
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.
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.
uint64_t aml_alias_set(aml_object_t *object, aml_object_t *target)
Set a object as an alias to the given target object.
uint64_t aml_arg_set(aml_object_t *object, aml_object_t *value)
Set a object as an argument with the given target object.
aml_object_t * aml_alias_obj_traverse(aml_alias_obj_t *alias)
Traverse an alias object to get the target object.
uint64_t aml_predefined_scope_set(aml_object_t *object)
Set a object as a predefined scope with the given name.
uint64_t aml_buffer_set_empty(aml_object_t *object, uint64_t length)
Set a object as an empty buffer with the given length.
aml_object_t *(* aml_method_implementation_t)(aml_method_obj_t *method, aml_object_t **args, uint64_t argCount)
Method Implementation function type.
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.
uint64_t aml_string_set_empty(aml_object_t *object, uint64_t length)
Set a object as an empty string with the given length.
uint64_t aml_debug_object_set(aml_object_t *object)
Set a object as a debug object.
#define AML_OBJECT_ID_NONE
Value for an invalid object id.
void aml_object_clear(aml_object_t *object)
Clear the data of a object, setting its type to AML_UNINITIALIZED.
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.
uint64_t aml_object_id_t
Object id type.
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.
#define AML_SMALL_BUFFER_SIZE
Size of buffers used for small objects optimization.
uint64_t aml_object_get_total_count(void)
Get the total amount of allocated ACPI objects.
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.
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.
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.
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.
#define AML_OBJECT_CACHE_SIZE
Amount of objects to store in the cache before freeing them instead.
#define AML_SMALL_PACKAGE_SIZE
Size of package element arrays used for small objects optimization.
@ AML_UNRESOLVED
Not in the spec, used internally to represent unresolved references.
@ AML_ALIAS
Not in the spec, used internally to represent Aliases.
@ AML_ARG
Not in the spec, used internally to represent method arguments.
@ AML_LOCAL
Not in the spec, used internally to represent method local variables.
@ AML_PREDEFINED_SCOPE
Not in the spec, used internally to represent _SB, _GPE, etc.
@ AML_FIELD_UNIT_BANK_FIELD
@ AML_FIELD_UNIT_INDEX_FIELD
@ AML_OBJECT_ROOT
Is the root object.
@ AML_OBJECT_EXCEPTION_ON_USE
@ AML_OBJECT_NAMED
Appears in the namespace tree. Will be set in aml_object_add().
@ AML_OBJECT_NONE
No flags.
void aml_patch_up_remove_unresolved(aml_unresolved_obj_t *unresolved)
Removes an unresolved reference from the global list.
uint64_t aml_patch_up_add_unresolved(aml_unresolved_obj_t *unresolved)
Adds a unresolved reference to the global list.
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.
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
void map_entry_init(map_entry_t *entry)
Initialize a map entry.
#define DEREF_DEFER(ptr)
RAII-style cleanup for scoped references.
static void ref_init(ref_t *ref, void *free)
Initialize a reference counter.
#define REF(ptr)
Increment reference count.
#define DEREF(ptr)
Decrement reference count.
#define EINVAL
Invalid argument.
#define errno
Error number variable.
#define LIST_FOR_EACH(elem, list, member)
Iterates over a list.
static uint64_t list_length(list_t *list)
Gets the length of the list.
#define LIST_CREATE(name)
Creates a list initializer.
#define LIST_FOR_EACH_SAFE(elem, temp, list, member)
Safely iterates over a list, allowing for element removal during iteration.
static void list_push(list_t *list, list_entry_t *entry)
Pushes an entry to the end of the list.
static bool list_is_empty(list_t *list)
Checks if a list is empty.
static void list_entry_init(list_entry_t *entry)
Initializes a list entry.
static void list_init(list_t *list)
Initializes a list.
static list_entry_t * list_pop(list_t *list)
Pops the first entry from the list.
#define NULL
Pointer error value.
#define ERR
Integer error value.
#define CONTAINER_OF(ptr, type, member)
Container of macro.
#define CONTAINER_OF_SAFE(ptr, type, member)
Safe container of macro.
EFI_PHYSICAL_ADDRESS buffer
static aml_object_id_t newObjectId
static uint64_t totalObjects
static uint64_t aml_object_check_clear(aml_object_t *object)
static aml_method_obj_t * aml_method_find_recursive(aml_object_t *current, const uint8_t *addr)
static void aml_copy_bits(uint8_t *dst, uint64_t dstOffset, const uint8_t *src, uint64_t srcOffset, uint64_t bitCount)
static list_t objectsCache
static void aml_object_free(aml_object_t *object)
__UINTPTR_TYPE__ uintptr_t
_PUBLIC void * calloc(size_t nmemb, size_t size)
_PUBLIC void * malloc(size_t size)
_PUBLIC void free(void *ptr)
_PUBLIC void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
_PUBLIC size_t strlen(const char *s)
_PUBLIC void * memset(void *s, int c, size_t n)
Data for an alias object.
aml_object_t * value
The object that was passed as the argument.
Data for a field unit object.
aml_field_unit_obj_type_t fieldType
The type of field unit.
aml_field_unit_obj_t * bank
Used for BankField.
aml_field_unit_obj_t * index
Used for IndexField.
aml_field_unit_obj_t * data
Used for IndexField.
aml_opregion_obj_t * opregion
Used for Field and BankField.
aml_object_t * bankValue
Used for BankField.
aml_object_t * value
The value of the local variable.
Data for a method object.
aml_buffer_field_obj_t bufferField
aml_object_reference_obj_t objectReference
aml_field_unit_obj_t fieldUnit
aml_package_obj_t package
aml_unresolved_obj_t unresolved
Data for an operation region object.
Data for a string object.
char smallString[AML_SMALL_STRING_SIZE+1]
Used for small object optimization.
aml_name_string_t nameString
The NameString representing the path to the target object.
aml_object_t * from
The object to start the search from when resolving the reference.