psargs.c
来自「linux 内核源代码」· C语言 代码 · 共 729 行 · 第 1/2 页
C
729 行
/* Save the namepath */ arg->common.value.name = path; return_ACPI_STATUS(status);}/******************************************************************************* * * FUNCTION: acpi_ps_get_next_simple_arg * * PARAMETERS: parser_state - Current parser state object * arg_type - The argument type (AML_*_ARG) * Arg - Where the argument is returned * * RETURN: None * * DESCRIPTION: Get the next simple argument (constant, string, or namestring) * ******************************************************************************/voidacpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, u32 arg_type, union acpi_parse_object *arg){ u32 length; u16 opcode; u8 *aml = parser_state->aml; ACPI_FUNCTION_TRACE_U32(ps_get_next_simple_arg, arg_type); switch (arg_type) { case ARGP_BYTEDATA: /* Get 1 byte from the AML stream */ opcode = AML_BYTE_OP; arg->common.value.integer = (acpi_integer) * aml; length = 1; break; case ARGP_WORDDATA: /* Get 2 bytes from the AML stream */ opcode = AML_WORD_OP; ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml); length = 2; break; case ARGP_DWORDDATA: /* Get 4 bytes from the AML stream */ opcode = AML_DWORD_OP; ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml); length = 4; break; case ARGP_QWORDDATA: /* Get 8 bytes from the AML stream */ opcode = AML_QWORD_OP; ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml); length = 8; break; case ARGP_CHARLIST: /* Get a pointer to the string, point past the string */ opcode = AML_STRING_OP; arg->common.value.string = ACPI_CAST_PTR(char, aml); /* Find the null terminator */ length = 0; while (aml[length]) { length++; } length++; break; case ARGP_NAME: case ARGP_NAMESTRING: acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); arg->common.value.name = acpi_ps_get_next_namestring(parser_state); return_VOID; default: ACPI_ERROR((AE_INFO, "Invalid ArgType %X", arg_type)); return_VOID; } acpi_ps_init_op(arg, opcode); parser_state->aml += length; return_VOID;}/******************************************************************************* * * FUNCTION: acpi_ps_get_next_field * * PARAMETERS: parser_state - Current parser state object * * RETURN: A newly allocated FIELD op * * DESCRIPTION: Get next field (named_field, reserved_field, or access_field) * ******************************************************************************/static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state *parser_state){ u32 aml_offset = (u32) ACPI_PTR_DIFF(parser_state->aml, parser_state->aml_start); union acpi_parse_object *field; u16 opcode; u32 name; ACPI_FUNCTION_TRACE(ps_get_next_field); /* Determine field type */ switch (ACPI_GET8(parser_state->aml)) { default: opcode = AML_INT_NAMEDFIELD_OP; break; case 0x00: opcode = AML_INT_RESERVEDFIELD_OP; parser_state->aml++; break; case 0x01: opcode = AML_INT_ACCESSFIELD_OP; parser_state->aml++; break; } /* Allocate a new field op */ field = acpi_ps_alloc_op(opcode); if (!field) { return_PTR(NULL); } field->common.aml_offset = aml_offset; /* Decode the field type */ switch (opcode) { case AML_INT_NAMEDFIELD_OP: /* Get the 4-character name */ ACPI_MOVE_32_TO_32(&name, parser_state->aml); acpi_ps_set_name(field, name); parser_state->aml += ACPI_NAME_SIZE; /* Get the length which is encoded as a package length */ field->common.value.size = acpi_ps_get_next_package_length(parser_state); break; case AML_INT_RESERVEDFIELD_OP: /* Get the length which is encoded as a package length */ field->common.value.size = acpi_ps_get_next_package_length(parser_state); break; case AML_INT_ACCESSFIELD_OP: /* * Get access_type and access_attrib and merge into the field Op * access_type is first operand, access_attribute is second */ field->common.value.integer = (((u32) ACPI_GET8(parser_state->aml) << 8)); parser_state->aml++; field->common.value.integer |= ACPI_GET8(parser_state->aml); parser_state->aml++; break; default: /* Opcode was set in previous switch */ break; } return_PTR(field);}/******************************************************************************* * * FUNCTION: acpi_ps_get_next_arg * * PARAMETERS: walk_state - Current state * parser_state - Current parser state object * arg_type - The argument type (AML_*_ARG) * return_arg - Where the next arg is returned * * RETURN: Status, and an op object containing the next argument. * * DESCRIPTION: Get next argument (including complex list arguments that require * pushing the parser stack) * ******************************************************************************/acpi_statusacpi_ps_get_next_arg(struct acpi_walk_state *walk_state, struct acpi_parse_state *parser_state, u32 arg_type, union acpi_parse_object **return_arg){ union acpi_parse_object *arg = NULL; union acpi_parse_object *prev = NULL; union acpi_parse_object *field; u32 subop; acpi_status status = AE_OK; ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg, parser_state); switch (arg_type) { case ARGP_BYTEDATA: case ARGP_WORDDATA: case ARGP_DWORDDATA: case ARGP_CHARLIST: case ARGP_NAME: case ARGP_NAMESTRING: /* Constants, strings, and namestrings are all the same size */ arg = acpi_ps_alloc_op(AML_BYTE_OP); if (!arg) { return_ACPI_STATUS(AE_NO_MEMORY); } acpi_ps_get_next_simple_arg(parser_state, arg_type, arg); break; case ARGP_PKGLENGTH: /* Package length, nothing returned */ parser_state->pkg_end = acpi_ps_get_next_package_end(parser_state); break; case ARGP_FIELDLIST: if (parser_state->aml < parser_state->pkg_end) { /* Non-empty list */ while (parser_state->aml < parser_state->pkg_end) { field = acpi_ps_get_next_field(parser_state); if (!field) { return_ACPI_STATUS(AE_NO_MEMORY); } if (prev) { prev->common.next = field; } else { arg = field; } prev = field; } /* Skip to End of byte data */ parser_state->aml = parser_state->pkg_end; } break; case ARGP_BYTELIST: if (parser_state->aml < parser_state->pkg_end) { /* Non-empty list */ arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP); if (!arg) { return_ACPI_STATUS(AE_NO_MEMORY); } /* Fill in bytelist data */ arg->common.value.size = (u32) ACPI_PTR_DIFF(parser_state->pkg_end, parser_state->aml); arg->named.data = parser_state->aml; /* Skip to End of byte data */ parser_state->aml = parser_state->pkg_end; } break; case ARGP_TARGET: case ARGP_SUPERNAME: case ARGP_SIMPLENAME: subop = acpi_ps_peek_opcode(parser_state); if (subop == 0 || acpi_ps_is_leading_char(subop) || acpi_ps_is_prefix_char(subop)) { /* null_name or name_string */ arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP); if (!arg) { return_ACPI_STATUS(AE_NO_MEMORY); } status = acpi_ps_get_next_namepath(walk_state, parser_state, arg, 0); } else { /* Single complex argument, nothing returned */ walk_state->arg_count = 1; } break; case ARGP_DATAOBJ: case ARGP_TERMARG: /* Single complex argument, nothing returned */ walk_state->arg_count = 1; break; case ARGP_DATAOBJLIST: case ARGP_TERMLIST: case ARGP_OBJLIST: if (parser_state->aml < parser_state->pkg_end) { /* Non-empty list of variable arguments, nothing returned */ walk_state->arg_count = ACPI_VAR_ARGS; } break; default: ACPI_ERROR((AE_INFO, "Invalid ArgType: %X", arg_type)); status = AE_AML_OPERAND_TYPE; break; } *return_arg = arg; return_ACPI_STATUS(status);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?