From d66f0df2c2b064725d7fee53a36970328690c51b Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sat, 22 Jul 2023 17:57:20 +0100 Subject: [PATCH] tools: amldecode: add parsing support for more AML opcodes --- tools/amldecode/aml/object.c | 6 +- tools/amldecode/aml/object.h | 5 +- tools/amldecode/aml/opcode.c | 754 +++++++++++++++++++++++++++-------- tools/amldecode/aml/parser.c | 27 +- tools/amldecode/aml/value.h | 4 + 5 files changed, 613 insertions(+), 183 deletions(-) diff --git a/tools/amldecode/aml/object.c b/tools/amldecode/aml/object.c index e68a501..2455266 100644 --- a/tools/amldecode/aml/object.c +++ b/tools/amldecode/aml/object.c @@ -99,7 +99,7 @@ void acpi_object_print(struct acpi_object *object, int depth) } if (object->name[0] == 0) { - printf("\n"); + printf(" [%s]\n", acpi_object_type_string(object->type)); } else { printf("%s [%s]\n", object->name, acpi_object_type_string(object->type)); } @@ -121,7 +121,7 @@ const char *acpi_object_type_string(enum acpi_object_type type) OBJECT_TYPE_STRING(ACPI_OBJECT_NONE) OBJECT_TYPE_STRING(ACPI_OBJECT_VALUE) OBJECT_TYPE_STRING(ACPI_OBJECT_NAMESPACE) - OBJECT_TYPE_STRING(ACPI_OBJECT_CPU) + OBJECT_TYPE_STRING(ACPI_OBJECT_PROCESSOR) OBJECT_TYPE_STRING(ACPI_OBJECT_DEVICE) OBJECT_TYPE_STRING(ACPI_OBJECT_METHOD) OBJECT_TYPE_STRING(ACPI_OBJECT_POWER_RESOURCE) @@ -130,6 +130,8 @@ const char *acpi_object_type_string(enum acpi_object_type type) OBJECT_TYPE_STRING(ACPI_OBJECT_FIELD) OBJECT_TYPE_STRING(ACPI_OBJECT_PACKAGE) OBJECT_TYPE_STRING(ACPI_OBJECT_BUFFER) + OBJECT_TYPE_STRING(ACPI_OBJECT_ALIAS) + OBJECT_TYPE_STRING(ACPI_OBJECT_MUTEX) default: return ""; } diff --git a/tools/amldecode/aml/object.h b/tools/amldecode/aml/object.h index 62c312a..0d669cd 100644 --- a/tools/amldecode/aml/object.h +++ b/tools/amldecode/aml/object.h @@ -8,7 +8,7 @@ enum acpi_object_type { ACPI_OBJECT_NONE = 0, ACPI_OBJECT_VALUE, ACPI_OBJECT_NAMESPACE, - ACPI_OBJECT_CPU, + ACPI_OBJECT_PROCESSOR, ACPI_OBJECT_DEVICE, ACPI_OBJECT_METHOD, ACPI_OBJECT_POWER_RESOURCE, @@ -17,6 +17,9 @@ enum acpi_object_type { ACPI_OBJECT_FIELD, ACPI_OBJECT_PACKAGE, ACPI_OBJECT_BUFFER, + ACPI_OBJECT_ALIAS, + ACPI_OBJECT_MUTEX, + ACPI_OBJECT_EVENT, }; struct acpi_object { diff --git a/tools/amldecode/aml/opcode.c b/tools/amldecode/aml/opcode.c index 7132d91..13f320b 100644 --- a/tools/amldecode/aml/opcode.c +++ b/tools/amldecode/aml/opcode.c @@ -7,6 +7,7 @@ #include "value.h" #include "object.h" #include "parser.h" +#include "../table.h" #define BYTECODE(opcode, parser, name) \ { opcode, 0, parser, name } @@ -150,7 +151,11 @@ static enum parse_status read_name(struct aml_parser *parser, char **out) c = '\\'; } - if (!isalnum(c) && c != '_' && c != '\\') { + if (c == AML_PARENT_PREFIX_CHAR) { + c = '^'; + } + + if (!isalnum(c) && c != '_' && c != '\\' && c != '^') { return PARSE_BADSTRING; } @@ -307,7 +312,7 @@ static enum parse_status parse_string_prefix(struct aml_parser *parser, struct a buf[i] = c; } - buf[len - 1] = '\0'; + buf[len] = '\0'; out->type = AML_VALUE_STRING; out->value.str = buf; @@ -372,7 +377,11 @@ static enum parse_status parse_op_region(struct aml_parser *parser, struct aml_v return status; } - if (!aml_value_is_integer(®ion_offset)) { + if (aml_value_is_name(®ion_offset)) { + /* TODO */ + } else if (aml_value_is_integer(®ion_offset)) { + /* TODO */ + } else { free(name); return PARSE_BADTYPE; } @@ -384,12 +393,16 @@ static enum parse_status parse_op_region(struct aml_parser *parser, struct aml_v return status; } - if (!aml_value_is_integer(®ion_len)) { + if (aml_value_is_name(®ion_len)) { + /* TODO */ + } else if (aml_value_is_integer(®ion_len)) { + /* TODO */ + } else { free(name); return PARSE_BADTYPE; } - struct acpi_object *op_region = acpi_object_create(name, ACPI_OBJECT_OPERATION_REGION); + struct acpi_object *op_region = acpi_object_create(NULL, ACPI_OBJECT_OPERATION_REGION); op_region->publish_path = name; out->type = AML_VALUE_OBJECT; @@ -398,12 +411,109 @@ static enum parse_status parse_op_region(struct aml_parser *parser, struct aml_v return PARSE_OK; } +static enum parse_status parse_named_field(struct aml_parser *parser, struct acpi_object *region) +{ + char unit_name[ACPI_OBJECT_NAME_MAX]; + enum parse_status status = read_single_segment_name(parser, unit_name); + if (status != PARSE_OK) { + return status; + } + + int bits = read_pkg_length(parser); + if (bits < 0) { + return PARSE_EOF; + } + + struct acpi_object *field = acpi_object_create(unit_name, ACPI_OBJECT_FIELD); + //field_unit->field_unit.size = bits / 8; + + acpi_object_add_child(region, field); + return PARSE_OK; +} + +static enum parse_status parse_reserved_field(struct aml_parser *parser, struct acpi_object *region) +{ + int c = aml_parser_advance(parser); + if (c < 0) { + return PARSE_EOF; + } + + int bits = read_pkg_length(parser); + if (bits < 0) { + return PARSE_EOF; + } + + struct acpi_object *field = acpi_object_create(NULL, ACPI_OBJECT_FIELD); + //field_unit->field_unit.size = bits / 8; + + acpi_object_add_child(region, field); + return PARSE_OK; +} + +static enum parse_status parse_access_field(struct aml_parser *parser, struct acpi_object *region) +{ + int c = aml_parser_advance(parser); + if (c < 0) { + return PARSE_EOF; + } + + int access_type = aml_parser_advance(parser); + if (access_type < 0) { + return PARSE_EOF; + } + + int access_attrib = aml_parser_advance(parser); + if (access_attrib < 0) { + return PARSE_EOF; + } + + struct acpi_object *field = acpi_object_create(NULL, ACPI_OBJECT_FIELD); + //field_unit->field_unit.size = bits / 8; + + acpi_object_add_child(region, field); + return PARSE_OK; +} + +static enum parse_status parse_extended_access_field(struct aml_parser *parser, struct acpi_object *region) +{ + int c = aml_parser_advance(parser); + if (c < 0) { + return PARSE_EOF; + } + + int access_type = aml_parser_advance(parser); + if (access_type < 0) { + return PARSE_EOF; + } + + int ext_access_attrib = aml_parser_advance(parser); + if (ext_access_attrib < 0) { + return PARSE_EOF; + } + + int access_length = aml_parser_advance(parser); + if (access_length < 0) { + return PARSE_EOF; + } + + struct acpi_object *field = acpi_object_create(NULL, ACPI_OBJECT_FIELD); + //field_unit->field_unit.size = bits / 8; + + acpi_object_add_child(region, field); + return PARSE_OK; +} + +static enum parse_status parse_connect_field(struct aml_parser *parser, struct acpi_object *region) +{ + return PARSE_UNKNOWNOP; +} + static enum parse_status parse_field(struct aml_parser *parser, struct aml_value *out) { - long start = aml_parser_cursorpos(parser); + aml_parser_advance(parser); + aml_parser_advance(parser); - aml_parser_advance(parser); - aml_parser_advance(parser); + long start = aml_parser_cursorpos(parser); long len = read_pkg_length(parser); if (len < 0) { @@ -423,29 +533,111 @@ static enum parse_status parse_field(struct aml_parser *parser, struct aml_value } struct acpi_object *region = aml_parser_resolve_path(parser, name); - free(name); if (!region) { return PARSE_BADREF; } + free(name); + long end = start + len; while (aml_parser_cursorpos(parser) < end) { - char unit_name[ACPI_OBJECT_NAME_MAX]; - status = read_single_segment_name(parser, unit_name); - if (status != PARSE_OK) { - return status; - } - - int bits = read_pkg_length(parser); - if (bits < 0) { + int c = aml_parser_peek(parser); + if (isalpha(c)) { + /* Named field */ + status = parse_named_field(parser, region); + } else if (c == 0x00) { + /* Reserved field */ + status = parse_reserved_field(parser, region); + } else if (c == 0x01) { + /* Access field */ + status = parse_access_field(parser, region); + } else if (c == 0x03) { + /* Extended access field */ + status = parse_extended_access_field(parser, region); + } else if (c == 0x02) { + /* Connect field */ + status = parse_connect_field(parser, region); + } else if (c < 0) { return PARSE_EOF; + } else { + return PARSE_UNKNOWNOP; } - struct acpi_object *field = acpi_object_create(unit_name, ACPI_OBJECT_FIELD); - //field_unit->field_unit.size = bits / 8; + } - acpi_object_add_child(region, field); + out->type = AML_VALUE_NONE; + return PARSE_OK; +} + +static enum parse_status parse_index_field(struct aml_parser *parser, struct aml_value *out) +{ + aml_parser_advance(parser); + aml_parser_advance(parser); + + long start = aml_parser_cursorpos(parser); + + long len = read_pkg_length(parser); + if (len < 0) { + return PARSE_EOF; + } + + char *index_name; + enum parse_status status = read_name(parser, &index_name); + if (status != PARSE_OK) { + return status; + } + + char *data_name; + status = read_name(parser, &data_name); + if (status != PARSE_OK) { + free(index_name); + return status; + } + + int flags = aml_parser_advance(parser); + if (flags < 0) { + free(index_name); + free(data_name); + return PARSE_EOF; + } + + free(index_name); + free(data_name); + +#if 0 + struct acpi_object *region = aml_parser_resolve_path(parser, index_name); + + if (!region) { + return PARSE_BADREF; + } +#endif + + long end = start + len; + while (aml_parser_cursorpos(parser) < end) { + int c = aml_parser_advance(parser); +#if 0 + if (isalpha(c)) { + /* Named field */ + status = parse_named_field(parser, region); + } else if (c == 0x00) { + /* Reserved field */ + status = parse_reserved_field(parser, region); + } else if (c == 0x01) { + /* Access field */ + status = parse_access_field(parser, region); + } else if (c == 0x03) { + /* Extended access field */ + status = parse_extended_access_field(parser, region); + } else if (c == 0x02) { + /* Connect field */ + status = parse_connect_field(parser, region); + } else if (c < 0) { + return PARSE_EOF; + } else { + return PARSE_UNKNOWNOP; + } +#endif } out->type = AML_VALUE_NONE; @@ -517,6 +709,7 @@ static enum parse_status parse_package(struct aml_parser *parser, struct aml_val { aml_parser_advance(parser); + long start = aml_parser_cursorpos(parser); long len = read_pkg_length(parser); if (len < 0) { return PARSE_EOF; @@ -539,6 +732,10 @@ static enum parse_status parse_package(struct aml_parser *parser, struct aml_val // TODO add value to package } + while (aml_parser_cursorpos(parser) < start + len) { + aml_parser_advance(parser); + } + out->type = AML_VALUE_OBJECT; out->value.object = pkg; @@ -561,6 +758,7 @@ static enum parse_status parse_name_chars(struct aml_parser *parser, struct aml_ static enum parse_status parse_buffer(struct aml_parser *parser, struct aml_value *out) { aml_parser_advance(parser); + long start = aml_parser_cursorpos(parser); long pkg_len = read_pkg_length(parser); if (pkg_len < 0) { return PARSE_EOF; @@ -577,8 +775,10 @@ static enum parse_status parse_buffer(struct aml_parser *parser, struct aml_valu } uint64_t nbytes = aml_value_get_integer(&buffer_size); + long end = start + pkg_len; - for (uint64_t i = 0; i < nbytes; i++) { + while (aml_parser_cursorpos(parser) < end) { + //for (uint64_t i = 0; i < nbytes; i++) { int b = aml_parser_advance(parser); if (b < 0) { return PARSE_EOF; @@ -631,160 +831,362 @@ static enum parse_status parse_method(struct aml_parser *parser, struct aml_valu return PARSE_OK; } +static enum parse_status parse_ones(struct aml_parser *parser, struct aml_value *out) +{ + aml_parser_advance(parser); + if (parser->revision == 0x02) { + out->type = AML_VALUE_UINT64; + out->value.uint64 = 0xFFFFFFFFFFFFFFFF; + } else { + out->type = AML_VALUE_UINT32; + out->value.uint32 = 0xFFFFFFFF; + } + + return PARSE_OK; +} + +static enum parse_status parse_processor(struct aml_parser *parser, struct aml_value *out) +{ + aml_parser_advance(parser); + aml_parser_advance(parser); + + long start = aml_parser_cursorpos(parser); + + long pkg_len = read_pkg_length(parser); + if (pkg_len < 0) { + return PARSE_EOF; + } + + char *name; + enum parse_status status = read_name(parser, &name); + if (status != PARSE_OK) { + return status; + } + + int proc_id = aml_parser_advance(parser); + if (proc_id < 0) { + return PARSE_EOF; + } + + int a = aml_parser_advance(parser); + int b = aml_parser_advance(parser); + int c = aml_parser_advance(parser); + int d = aml_parser_advance(parser); + + if (d < 0) { + return PARSE_EOF; + } + + int pblk_len = aml_parser_advance(parser); + if (pblk_len < 0) { + return PARSE_EOF; + } + + struct acpi_object *processor = acpi_object_create(NULL, ACPI_OBJECT_PROCESSOR); + processor->publish_path = name; + processor->scope_end = start + pkg_len; + + out->type = AML_VALUE_OBJECT; + out->value.object = processor; + + return PARSE_OK; +} + +static enum parse_status parse_alias(struct aml_parser *parser, struct aml_value *out) +{ + aml_parser_advance(parser); + + char *target_path, *alias_path; + enum parse_status status = read_name(parser, &target_path); + if (status != PARSE_OK) { + return status; + } + + status = read_name(parser, &alias_path); + if (status != PARSE_OK) { + return status; + } + + struct acpi_object *alias = acpi_object_create(NULL, ACPI_OBJECT_ALIAS); + alias->publish_path = alias_path; + free(target_path); + + out->type = AML_VALUE_OBJECT; + out->value.object = alias; + + return PARSE_OK; +} + +static enum parse_status parse_mutex(struct aml_parser *parser, struct aml_value *out) +{ + aml_parser_advance(parser); + aml_parser_advance(parser); + + char *name; + enum parse_status status = read_name(parser, &name); + if (status != PARSE_OK) { + return status; + } + + int sync_flags = aml_parser_advance(parser); + if (sync_flags < 0) { + free(name); + return PARSE_EOF; + } + + struct acpi_object *mutex = acpi_object_create(NULL, ACPI_OBJECT_MUTEX); + mutex->publish_path = name; + + out->type = AML_VALUE_OBJECT; + out->value.object = mutex; + + return PARSE_OK; +} + +static enum parse_status parse_create_byte_field(struct aml_parser *parser, struct aml_value *out) +{ + aml_parser_advance(parser); + + char *buffer_path; + enum parse_status status = read_name(parser, &buffer_path); + if (status != PARSE_OK) { + return status; + } + + struct aml_value byte_index; + status = parse_opcode(parser, &byte_index); + if (status != PARSE_OK) { + return status; + } + + char *field_name; + status = read_name(parser, &field_name); + if (status != PARSE_OK) { + return status; + } + + struct acpi_object *field = acpi_object_create(NULL, ACPI_OBJECT_FIELD); + field->publish_path = field_name; + + /* TODO */ + + free(buffer_path); + + out->type = AML_VALUE_OBJECT; + out->value.object = field; + + return PARSE_OK; +} + +static enum parse_status parse_create_word_field(struct aml_parser *parser, struct aml_value *out) +{ + aml_parser_advance(parser); + + char *buffer_path; + enum parse_status status = read_name(parser, &buffer_path); + if (status != PARSE_OK) { + return status; + } + + struct aml_value byte_index; + status = parse_opcode(parser, &byte_index); + if (status != PARSE_OK) { + return status; + } + + char *field_name; + status = read_name(parser, &field_name); + if (status != PARSE_OK) { + return status; + } + + struct acpi_object *field = acpi_object_create(NULL, ACPI_OBJECT_FIELD); + field->publish_path = field_name; + + /* TODO */ + + free(buffer_path); + + out->type = AML_VALUE_OBJECT; + out->value.object = field; + + return PARSE_OK; +} + +static enum parse_status parse_event(struct aml_parser *parser, struct aml_value *out) +{ + aml_parser_advance(parser); + aml_parser_advance(parser); + + char *name; + enum parse_status status = read_name(parser, &name); + if (status != PARSE_OK) { + return status; + } + + struct acpi_object *event = acpi_object_create(NULL, ACPI_OBJECT_EVENT); + event->publish_path = name; + + out->type = AML_VALUE_OBJECT; + out->value.object = event; + + return PARSE_OK; +} + struct aml_byte_encoding byte_encoding[] = { - BYTECODE(AML_ZERO_OP, parse_zero, "ZeroOp"), - BYTECODE(AML_ONE_OP, parse_one, "OneOp"), - BYTECODE(AML_ALIAS_OP, NULL, "AliasOp"), - BYTECODE(AML_NAME_OP, parse_name, "NameOp"), - BYTECODE(AML_BYTE_PREFIX, parse_byte_prefix, "BytePrefix"), - BYTECODE(AML_WORD_PREFIX, parse_word_prefix, "WordPrefix"), - BYTECODE(AML_DWORD_PREFIX, parse_dword_prefix, "DWordPrefix"), - BYTECODE(AML_STRING_PREFIX, parse_string_prefix, "StringPrefix"), - BYTECODE(AML_QWORD_PREFIX, parse_qword_prefix, "QWordPrefix"), - BYTECODE(AML_SCOPE_OP, parse_scope, "ScopeOp"), - BYTECODE(AML_BUFFER_OP, parse_buffer, "BufferOp"), - BYTECODE(AML_PACKAGE_OP, parse_package, "PackageOp"), - BYTECODE(AML_VAR_PACKAGE_OP, NULL, "VarPackageOp"), - BYTECODE(AML_METHOD_OP, parse_method, "MethodOp"), - BYTECODE(AML_DUAL_NAME_PREFIX, NULL, "DualNamePrefix"), - BYTECODE(AML_MULTI_NAME_PREFIX, NULL, "MultiNamePrefix"), - BYTECODE('0', parse_name_chars, "DigitChar"), - BYTECODE('1', parse_name_chars, "DigitChar"), - BYTECODE('2', parse_name_chars, "DigitChar"), - BYTECODE('3', parse_name_chars, "DigitChar"), - BYTECODE('4', parse_name_chars, "DigitChar"), - BYTECODE('5', parse_name_chars, "DigitChar"), - BYTECODE('6', parse_name_chars, "DigitChar"), - BYTECODE('7', parse_name_chars, "DigitChar"), - BYTECODE('8', parse_name_chars, "DigitChar"), - BYTECODE('9', parse_name_chars, "DigitChar"), - BYTECODE('A', parse_name_chars, "NameChar"), - BYTECODE('B', parse_name_chars, "NameChar"), - BYTECODE('C', parse_name_chars, "NameChar"), - BYTECODE('D', parse_name_chars, "NameChar"), - BYTECODE('E', parse_name_chars, "NameChar"), - BYTECODE('F', parse_name_chars, "NameChar"), - BYTECODE('G', parse_name_chars, "NameChar"), - BYTECODE('H', parse_name_chars, "NameChar"), - BYTECODE('I', parse_name_chars, "NameChar"), - BYTECODE('J', parse_name_chars, "NameChar"), - BYTECODE('K', parse_name_chars, "NameChar"), - BYTECODE('L', parse_name_chars, "NameChar"), - BYTECODE('M', parse_name_chars, "NameChar"), - BYTECODE('N', parse_name_chars, "NameChar"), - BYTECODE('O', parse_name_chars, "NameChar"), - BYTECODE('P', parse_name_chars, "NameChar"), - BYTECODE('Q', parse_name_chars, "NameChar"), - BYTECODE('R', parse_name_chars, "NameChar"), - BYTECODE('S', parse_name_chars, "NameChar"), - BYTECODE('T', parse_name_chars, "NameChar"), - BYTECODE('U', parse_name_chars, "NameChar"), - BYTECODE('V', parse_name_chars, "NameChar"), - BYTECODE('W', parse_name_chars, "NameChar"), - BYTECODE('X', parse_name_chars, "NameChar"), - BYTECODE('Y', parse_name_chars, "NameChar"), - BYTECODE('Z', parse_name_chars, "NameChar"), - EXT_BYTECODE(AML_EXT_MUTEX_OP, NULL, "MutexOp"), - EXT_BYTECODE(AML_EXT_EVENT_OP, NULL, "EventOp"), - EXT_BYTECODE(AML_EXT_COND_REF_OF_OP, NULL, "CondRefOfOp"), - EXT_BYTECODE(AML_EXT_CREATE_FIELD_OP, NULL, "CreateFieldOp"), - EXT_BYTECODE(AML_EXT_LOAD_TABLE_OP, NULL, "LoadTableOp"), - EXT_BYTECODE(AML_EXT_LOAD_OP, NULL, "LoadOp"), - EXT_BYTECODE(AML_EXT_STALL_OP, NULL, "StallOp"), - EXT_BYTECODE(AML_EXT_SLEEP_OP, NULL, "SleepOp"), - EXT_BYTECODE(AML_EXT_ACQUIRE_OP, NULL, "AcquireOp"), - EXT_BYTECODE(AML_EXT_SIGNAL_OP, NULL, "SignalOp"), - EXT_BYTECODE(AML_EXT_WAIT_OP, NULL, "WaitOp"), - EXT_BYTECODE(AML_EXT_RESET_OP, NULL, "ResetOp"), - EXT_BYTECODE(AML_EXT_RELEASE_OP, NULL, "ReleaseOp"), - EXT_BYTECODE(AML_EXT_FROM_BCD_OP, NULL, "FromBCDOp"), - EXT_BYTECODE(AML_EXT_TO_BCD_OP, NULL, "ToBCDOp"), - EXT_BYTECODE(AML_EXT_UNLOAD_OP, NULL, "UnloadOp"), - EXT_BYTECODE(AML_EXT_REVISION_OP, NULL, "RevisionOp"), - EXT_BYTECODE(AML_EXT_DEBUG_OP, NULL, "DebugOp"), - EXT_BYTECODE(AML_EXT_FATAL_OP, NULL, "FatalOp"), - EXT_BYTECODE(AML_EXT_TIMER_OP, NULL, "TimerOp"), - EXT_BYTECODE(AML_EXT_REGION_OP, parse_op_region, "OpRegionOp"), - EXT_BYTECODE(AML_EXT_FIELD_OP, parse_field, "FieldOp"), - EXT_BYTECODE(AML_EXT_DEVICE_OP, parse_device, "DeviceOp"), - EXT_BYTECODE(AML_EXT_PROCESSOR_OP, NULL, "ProcessorOp"), - EXT_BYTECODE(AML_EXT_POWER_RES_OP, NULL, "PowerResOp"), - EXT_BYTECODE(AML_EXT_THERMAL_ZONE_OP, NULL, "ThermalZoneOp"), - EXT_BYTECODE(AML_EXT_INDEX_FIELD_OP, NULL, "IndexFieldOp"), - EXT_BYTECODE(AML_EXT_BANK_FIELD_OP, NULL, "BankFieldOp"), - EXT_BYTECODE(AML_EXT_DATA_REGION_OP, NULL, "DataRegionOp"), - BYTECODE(AML_ROOT_CHAR, NULL, "RootChar"), - BYTECODE(AML_PARENT_PREFIX_CHAR, NULL, "ParentPrefixChar"), - BYTECODE('_', NULL, "NameChar"), - BYTECODE(AML_LOCAL0, NULL, "Local0Op"), - BYTECODE(AML_LOCAL1, NULL, "Local1Op"), - BYTECODE(AML_LOCAL2, NULL, "Local2Op"), - BYTECODE(AML_LOCAL3, NULL, "Local3Op"), - BYTECODE(AML_LOCAL4, NULL, "Local4Op"), - BYTECODE(AML_LOCAL5, NULL, "Local5Op"), - BYTECODE(AML_LOCAL6, NULL, "Local6Op"), - BYTECODE(AML_LOCAL7, NULL, "Local7Op"), - BYTECODE(AML_ARG0, NULL, "Arg0Op"), - BYTECODE(AML_ARG1, NULL, "Arg1Op"), - BYTECODE(AML_ARG2, NULL, "Arg2Op"), - BYTECODE(AML_ARG3, NULL, "Arg3Op"), - BYTECODE(AML_ARG4, NULL, "Arg4Op"), - BYTECODE(AML_ARG5, NULL, "Arg5Op"), - BYTECODE(AML_ARG6, NULL, "Arg6Op"), - BYTECODE(AML_STORE_OP, NULL, "StoreOp"), - BYTECODE(AML_REF_OF_OP, NULL, "RefOfOp"), - BYTECODE(AML_ADD_OP, NULL, "AddOp"), - BYTECODE(AML_CONCAT_OP, NULL, "ConcatOp"), - BYTECODE(AML_SUBTRACT_OP, NULL, "SubtractOp"), - BYTECODE(AML_INCREMENT_OP, NULL, "IncrementOp"), - BYTECODE(AML_DECREMENT_OP, NULL, "DecrementOp"), - BYTECODE(AML_MULTIPLY_OP, NULL, "MultiplyOp"), - BYTECODE(AML_DIVIDE_OP, NULL, "DivideOp"), - BYTECODE(AML_SHIFT_LEFT_OP, NULL, "ShiftLeftOp"), - BYTECODE(AML_SHIFT_RIGHT_OP, NULL, "ShiftRightOp"), - BYTECODE(AML_AND_OP, NULL, "AndOp"), - BYTECODE(AML_NAND_OP, NULL, "NAndOp"), - BYTECODE(AML_OR_OP, NULL, "OrOp"), - BYTECODE(AML_NOR_OP, NULL, "NorOp"), - BYTECODE(AML_XOR_OP, NULL, "XOrOp"), - BYTECODE(AML_NOT_OP, NULL, "NotOp"), - BYTECODE(AML_FIND_SET_LEFT_BIT_OP, NULL, "FindSetLeftBitOp"), - BYTECODE(AML_FIND_SET_RIGHT_BIT_OP, NULL, "FindSetRightBitOp"), - BYTECODE(AML_DEREF_OF_OP, NULL, "DerefOfOp"), - BYTECODE(AML_CONCAT_RES_OP, NULL, "ConcatResOp"), - BYTECODE(AML_MOD_OP, NULL, "ModOp"), - BYTECODE(AML_NOTIFY_OP, NULL, "NotifyOp"), - BYTECODE(AML_SIZE_OF_OP, NULL, "SizeOfOp"), - BYTECODE(AML_INDEX_OP, NULL, "IndexOp"), - BYTECODE(AML_MATCH_OP, NULL, "MatchOp"), - BYTECODE(AML_CREATE_DWORD_FIELD_OP, NULL, "CreateDWordFieldOp"), - BYTECODE(AML_CREATE_WORD_FIELD_OP, NULL, "CreateWordFieldOp"), - BYTECODE(AML_CREATE_BYTE_FIELD_OP, NULL, "CreateByteFieldOp"), - BYTECODE(AML_CREATE_BIT_FIELD_OP, NULL, "CreateBitFieldOp"), - BYTECODE(AML_OBJECT_TYPE_OP, NULL, "ObjectTypeOp"), - BYTECODE(AML_CREATE_QWORD_FIELD_OP, NULL, "CreateQWordFieldOp"), - BYTECODE(AML_LAND_OP, NULL, "LAndOp"), - BYTECODE(AML_LOR_OP, NULL, "LOrOp"), - BYTECODE(AML_LNOT_OP, NULL, "LNotOp"), - BYTECODE(AML_LEQUAL_OP, NULL, "LEqualOp"), - BYTECODE(AML_LGREATER_OP, NULL, "LGreaterOp"), - BYTECODE(AML_LLESS_OP, NULL, "LLessOp"), - BYTECODE(AML_TO_BUFFER_OP, NULL, "ToBufferOp"), - BYTECODE(AML_TO_DEC_STRING_OP, NULL, "ToDecimalStringOp"), - BYTECODE(AML_TO_HEX_STRING_OP, NULL, "ToHexStringOp"), - BYTECODE(AML_TO_INTEGER_OP, NULL, "ToIntegerOp"), - BYTECODE(AML_TO_STRING_OP, NULL, "ToStringOp"), - BYTECODE(AML_COPY_OBJECT_OP, NULL, "CopyObjectOp"), - BYTECODE(AML_MID_OP, NULL, "MidOp"), - BYTECODE(AML_CONTINUE_OP, NULL, "ContinueOp"), - BYTECODE(AML_IF_OP, NULL, "IfOp"), - BYTECODE(AML_ELSE_OP, NULL, "ElseOp"), - BYTECODE(AML_WHILE_OP, NULL, "WhileOp"), - BYTECODE(AML_NOOP_OP, NULL, "NoopOp"), - BYTECODE(AML_RETURN_OP, NULL, "ReturnOp"), - BYTECODE(AML_BREAK_OP, NULL, "BreakOp"), - BYTECODE(AML_BREAK_POINT_OP, NULL, "BreakPointOp"), - BYTECODE(AML_ONES_OP, NULL, "OnesOp"), + BYTECODE(AML_ZERO_OP, parse_zero, "ZeroOp"), + BYTECODE(AML_ONE_OP, parse_one, "OneOp"), + BYTECODE(AML_ALIAS_OP, parse_alias, "AliasOp"), + BYTECODE(AML_NAME_OP, parse_name, "NameOp"), + BYTECODE(AML_BYTE_PREFIX, parse_byte_prefix, "BytePrefix"), + BYTECODE(AML_WORD_PREFIX, parse_word_prefix, "WordPrefix"), + BYTECODE(AML_DWORD_PREFIX, parse_dword_prefix, "DWordPrefix"), + BYTECODE(AML_STRING_PREFIX, parse_string_prefix, "StringPrefix"), + BYTECODE(AML_QWORD_PREFIX, parse_qword_prefix, "QWordPrefix"), + BYTECODE(AML_SCOPE_OP, parse_scope, "ScopeOp"), + BYTECODE(AML_BUFFER_OP, parse_buffer, "BufferOp"), + BYTECODE(AML_PACKAGE_OP, parse_package, "PackageOp"), + BYTECODE(AML_VAR_PACKAGE_OP, NULL, "VarPackageOp"), + BYTECODE(AML_METHOD_OP, parse_method, "MethodOp"), + BYTECODE(AML_DUAL_NAME_PREFIX, NULL, "DualNamePrefix"), + BYTECODE(AML_MULTI_NAME_PREFIX, NULL, "MultiNamePrefix"), + BYTECODE('0', parse_name_chars, "DigitChar"), + BYTECODE('1', parse_name_chars, "DigitChar"), + BYTECODE('2', parse_name_chars, "DigitChar"), + BYTECODE('3', parse_name_chars, "DigitChar"), + BYTECODE('4', parse_name_chars, "DigitChar"), + BYTECODE('5', parse_name_chars, "DigitChar"), + BYTECODE('6', parse_name_chars, "DigitChar"), + BYTECODE('7', parse_name_chars, "DigitChar"), + BYTECODE('8', parse_name_chars, "DigitChar"), + BYTECODE('9', parse_name_chars, "DigitChar"), + BYTECODE('A', parse_name_chars, "NameChar"), + BYTECODE('B', parse_name_chars, "NameChar"), + BYTECODE('C', parse_name_chars, "NameChar"), + BYTECODE('D', parse_name_chars, "NameChar"), + BYTECODE('E', parse_name_chars, "NameChar"), + BYTECODE('F', parse_name_chars, "NameChar"), + BYTECODE('G', parse_name_chars, "NameChar"), + BYTECODE('H', parse_name_chars, "NameChar"), + BYTECODE('I', parse_name_chars, "NameChar"), + BYTECODE('J', parse_name_chars, "NameChar"), + BYTECODE('K', parse_name_chars, "NameChar"), + BYTECODE('L', parse_name_chars, "NameChar"), + BYTECODE('M', parse_name_chars, "NameChar"), + BYTECODE('N', parse_name_chars, "NameChar"), + BYTECODE('O', parse_name_chars, "NameChar"), + BYTECODE('P', parse_name_chars, "NameChar"), + BYTECODE('Q', parse_name_chars, "NameChar"), + BYTECODE('R', parse_name_chars, "NameChar"), + BYTECODE('S', parse_name_chars, "NameChar"), + BYTECODE('T', parse_name_chars, "NameChar"), + BYTECODE('U', parse_name_chars, "NameChar"), + BYTECODE('V', parse_name_chars, "NameChar"), + BYTECODE('W', parse_name_chars, "NameChar"), + BYTECODE('X', parse_name_chars, "NameChar"), + BYTECODE('Y', parse_name_chars, "NameChar"), + BYTECODE('Z', parse_name_chars, "NameChar"), + EXT_BYTECODE(AML_EXT_MUTEX_OP, parse_mutex, "MutexOp"), + EXT_BYTECODE(AML_EXT_EVENT_OP, parse_event, "EventOp"), + EXT_BYTECODE(AML_EXT_COND_REF_OF_OP, NULL, "CondRefOfOp"), + EXT_BYTECODE(AML_EXT_CREATE_FIELD_OP, NULL, "CreateFieldOp"), + EXT_BYTECODE(AML_EXT_LOAD_TABLE_OP, NULL, "LoadTableOp"), + EXT_BYTECODE(AML_EXT_LOAD_OP, NULL, "LoadOp"), + EXT_BYTECODE(AML_EXT_STALL_OP, NULL, "StallOp"), + EXT_BYTECODE(AML_EXT_SLEEP_OP, NULL, "SleepOp"), + EXT_BYTECODE(AML_EXT_ACQUIRE_OP, NULL, "AcquireOp"), + EXT_BYTECODE(AML_EXT_SIGNAL_OP, NULL, "SignalOp"), + EXT_BYTECODE(AML_EXT_WAIT_OP, NULL, "WaitOp"), + EXT_BYTECODE(AML_EXT_RESET_OP, NULL, "ResetOp"), + EXT_BYTECODE(AML_EXT_RELEASE_OP, NULL, "ReleaseOp"), + EXT_BYTECODE(AML_EXT_FROM_BCD_OP, NULL, "FromBCDOp"), + EXT_BYTECODE(AML_EXT_TO_BCD_OP, NULL, "ToBCDOp"), + EXT_BYTECODE(AML_EXT_UNLOAD_OP, NULL, "UnloadOp"), + EXT_BYTECODE(AML_EXT_REVISION_OP, NULL, "RevisionOp"), + EXT_BYTECODE(AML_EXT_DEBUG_OP, NULL, "DebugOp"), + EXT_BYTECODE(AML_EXT_FATAL_OP, NULL, "FatalOp"), + EXT_BYTECODE(AML_EXT_TIMER_OP, NULL, "TimerOp"), + EXT_BYTECODE(AML_EXT_REGION_OP, parse_op_region, "OpRegionOp"), + EXT_BYTECODE(AML_EXT_FIELD_OP, parse_field, "FieldOp"), + EXT_BYTECODE(AML_EXT_DEVICE_OP, parse_device, "DeviceOp"), + EXT_BYTECODE(AML_EXT_PROCESSOR_OP, parse_processor, "ProcessorOp"), + EXT_BYTECODE(AML_EXT_POWER_RES_OP, NULL, "PowerResOp"), + EXT_BYTECODE(AML_EXT_THERMAL_ZONE_OP, NULL, "ThermalZoneOp"), + EXT_BYTECODE(AML_EXT_INDEX_FIELD_OP, parse_index_field, "IndexFieldOp"), + EXT_BYTECODE(AML_EXT_BANK_FIELD_OP, NULL, "BankFieldOp"), + EXT_BYTECODE(AML_EXT_DATA_REGION_OP, NULL, "DataRegionOp"), + BYTECODE(AML_ROOT_CHAR, NULL, "RootChar"), + BYTECODE(AML_PARENT_PREFIX_CHAR, NULL, "ParentPrefixChar"), + BYTECODE('_', NULL, "NameChar"), + BYTECODE(AML_LOCAL0, NULL, "Local0Op"), + BYTECODE(AML_LOCAL1, NULL, "Local1Op"), + BYTECODE(AML_LOCAL2, NULL, "Local2Op"), + BYTECODE(AML_LOCAL3, NULL, "Local3Op"), + BYTECODE(AML_LOCAL4, NULL, "Local4Op"), + BYTECODE(AML_LOCAL5, NULL, "Local5Op"), + BYTECODE(AML_LOCAL6, NULL, "Local6Op"), + BYTECODE(AML_LOCAL7, NULL, "Local7Op"), + BYTECODE(AML_ARG0, NULL, "Arg0Op"), + BYTECODE(AML_ARG1, NULL, "Arg1Op"), + BYTECODE(AML_ARG2, NULL, "Arg2Op"), + BYTECODE(AML_ARG3, NULL, "Arg3Op"), + BYTECODE(AML_ARG4, NULL, "Arg4Op"), + BYTECODE(AML_ARG5, NULL, "Arg5Op"), + BYTECODE(AML_ARG6, NULL, "Arg6Op"), + BYTECODE(AML_STORE_OP, NULL, "StoreOp"), + BYTECODE(AML_REF_OF_OP, NULL, "RefOfOp"), + BYTECODE(AML_ADD_OP, NULL, "AddOp"), + BYTECODE(AML_CONCAT_OP, NULL, "ConcatOp"), + BYTECODE(AML_SUBTRACT_OP, NULL, "SubtractOp"), + BYTECODE(AML_INCREMENT_OP, NULL, "IncrementOp"), + BYTECODE(AML_DECREMENT_OP, NULL, "DecrementOp"), + BYTECODE(AML_MULTIPLY_OP, NULL, "MultiplyOp"), + BYTECODE(AML_DIVIDE_OP, NULL, "DivideOp"), + BYTECODE(AML_SHIFT_LEFT_OP, NULL, "ShiftLeftOp"), + BYTECODE(AML_SHIFT_RIGHT_OP, NULL, "ShiftRightOp"), + BYTECODE(AML_AND_OP, NULL, "AndOp"), + BYTECODE(AML_NAND_OP, NULL, "NAndOp"), + BYTECODE(AML_OR_OP, NULL, "OrOp"), + BYTECODE(AML_NOR_OP, NULL, "NorOp"), + BYTECODE(AML_XOR_OP, NULL, "XOrOp"), + BYTECODE(AML_NOT_OP, NULL, "NotOp"), + BYTECODE(AML_FIND_SET_LEFT_BIT_OP, NULL, "FindSetLeftBitOp"), + BYTECODE(AML_FIND_SET_RIGHT_BIT_OP, NULL, "FindSetRightBitOp"), + BYTECODE(AML_DEREF_OF_OP, NULL, "DerefOfOp"), + BYTECODE(AML_CONCAT_RES_OP, NULL, "ConcatResOp"), + BYTECODE(AML_MOD_OP, NULL, "ModOp"), + BYTECODE(AML_NOTIFY_OP, NULL, "NotifyOp"), + BYTECODE(AML_SIZE_OF_OP, NULL, "SizeOfOp"), + BYTECODE(AML_INDEX_OP, NULL, "IndexOp"), + BYTECODE(AML_MATCH_OP, NULL, "MatchOp"), + BYTECODE(AML_CREATE_DWORD_FIELD_OP, NULL, "CreateDWordFieldOp"), + BYTECODE(AML_CREATE_WORD_FIELD_OP, parse_create_word_field, "CreateWordFieldOp"), + BYTECODE(AML_CREATE_BYTE_FIELD_OP, parse_create_byte_field, "CreateByteFieldOp"), + BYTECODE(AML_CREATE_BIT_FIELD_OP, NULL, "CreateBitFieldOp"), + BYTECODE(AML_OBJECT_TYPE_OP, NULL, "ObjectTypeOp"), + BYTECODE(AML_CREATE_QWORD_FIELD_OP, NULL, "CreateQWordFieldOp"), + BYTECODE(AML_LAND_OP, NULL, "LAndOp"), + BYTECODE(AML_LOR_OP, NULL, "LOrOp"), + BYTECODE(AML_LNOT_OP, NULL, "LNotOp"), + BYTECODE(AML_LEQUAL_OP, NULL, "LEqualOp"), + BYTECODE(AML_LGREATER_OP, NULL, "LGreaterOp"), + BYTECODE(AML_LLESS_OP, NULL, "LLessOp"), + BYTECODE(AML_TO_BUFFER_OP, NULL, "ToBufferOp"), + BYTECODE(AML_TO_DEC_STRING_OP, NULL, "ToDecimalStringOp"), + BYTECODE(AML_TO_HEX_STRING_OP, NULL, "ToHexStringOp"), + BYTECODE(AML_TO_INTEGER_OP, NULL, "ToIntegerOp"), + BYTECODE(AML_TO_STRING_OP, NULL, "ToStringOp"), + BYTECODE(AML_COPY_OBJECT_OP, NULL, "CopyObjectOp"), + BYTECODE(AML_MID_OP, NULL, "MidOp"), + BYTECODE(AML_CONTINUE_OP, NULL, "ContinueOp"), + BYTECODE(AML_IF_OP, NULL, "IfOp"), + BYTECODE(AML_ELSE_OP, NULL, "ElseOp"), + BYTECODE(AML_WHILE_OP, NULL, "WhileOp"), + BYTECODE(AML_NOOP_OP, NULL, "NoopOp"), + BYTECODE(AML_RETURN_OP, NULL, "ReturnOp"), + BYTECODE(AML_BREAK_OP, NULL, "BreakOp"), + BYTECODE(AML_BREAK_POINT_OP, NULL, "BreakPointOp"), + BYTECODE(AML_ONES_OP, parse_ones, "OnesOp"), }; static unsigned int nr_byte_encoding = sizeof byte_encoding / sizeof(struct aml_byte_encoding); @@ -815,12 +1217,12 @@ enum parse_status parse_opcode(struct aml_parser *parser, struct aml_value *out) } if (!opcode) { - fprintf(stderr, "unrecognised opcode at 0x%04x: %02x:%02x\n", offset, op0, op1); + fprintf(stderr, "unrecognised opcode at 0x%04lx: %02x:%02x\n", offset + sizeof(struct acpi_table), op0, op1); return PARSE_UNKNOWNOP; } if (!opcode->parser) { - fprintf(stderr, "unimplemented opcode at 0x%04x: %02x:%02x (%s)\n", offset, op0, op1, opcode->name); + fprintf(stderr, "unimplemented opcode at 0x%04lx: %02x:%02x (%s)\n", offset + sizeof(struct acpi_table), op0, op1, opcode->name); return PARSE_UNKNOWNOP; } diff --git a/tools/amldecode/aml/parser.c b/tools/amldecode/aml/parser.c index 6fc13c9..aae42af 100644 --- a/tools/amldecode/aml/parser.c +++ b/tools/amldecode/aml/parser.c @@ -5,6 +5,7 @@ #include "opcode.h" #include "object.h" #include "value.h" +#include "../table.h" void aml_parser_init(struct aml_parser *parser, void *p, size_t len) { @@ -116,6 +117,7 @@ void aml_parser_add_object(struct aml_parser *parser, struct acpi_object *object } tok = next_tok; + cur = next; } strncpy(object->name, tok, sizeof object->name - 1); @@ -192,12 +194,14 @@ static bool should_pop_current_scope(struct aml_parser *parser) enum parse_status aml_parser_parse_into_namespace(struct aml_parser *parser, struct acpi_namespace *ns) { parser->ns = ns; + aml_parser_push_scope(parser, ns->root); + enum parse_status status = PARSE_OK; while (1) { struct aml_value value; - enum parse_status status = parse_opcode(parser, &value); + status = parse_opcode(parser, &value); if (status != PARSE_OK) { - return status; + break; } if (value.type == AML_VALUE_OBJECT) { @@ -210,7 +214,16 @@ enum parse_status aml_parser_parse_into_namespace(struct aml_parser *parser, str } } - return PARSE_OK; + if (status == PARSE_EOF && !parser->cur_scope->next) { + status = PARSE_OK; + } + + if (status != PARSE_OK) { + fprintf(stderr, "parse error at 0x%04lx: %s\n", + aml_parser_cursorpos(parser) + sizeof(struct acpi_table), parse_status_string(status)); + } + + return status; } struct acpi_object *aml_parser_resolve_path(struct aml_parser *parser, const char *path) @@ -223,10 +236,16 @@ struct acpi_object *aml_parser_resolve_path(struct aml_parser *parser, const cha size_t path_len = strlen(path); char *rpath = malloc(path_len + 1); + char *token_buf = rpath; strcpy(rpath, path); + while (*token_buf == '^') { + cur = cur->parent; + token_buf++; + } + char *sp; - char *tok = strtok_r(rpath, ".", &sp); + char *tok = strtok_r(token_buf, ".", &sp); if (tok && object_name_is_always_root(tok)) { cur = parser->ns->root; } diff --git a/tools/amldecode/aml/value.h b/tools/amldecode/aml/value.h index 1d652fc..83be064 100644 --- a/tools/amldecode/aml/value.h +++ b/tools/amldecode/aml/value.h @@ -36,6 +36,10 @@ static inline bool aml_value_is_integer(const struct aml_value *value) { return value->type == AML_VALUE_UINT8 || value->type == AML_VALUE_UINT16 || value->type == AML_VALUE_UINT32 || value->type == AML_VALUE_UINT64; } +static inline bool aml_value_is_name(const struct aml_value *value) +{ + return value->type == AML_VALUE_NAME; +} extern uint64_t aml_value_get_integer(const struct aml_value *value); extern void aml_value_destroy(struct aml_value *value);