📄 psargs.c
字号:
/******************************************************************************
*
* Module Name: psargs - Parse AML opcode arguments
* $Revision: 1.1 $
*
*****************************************************************************/
/*
* Copyright (C) 2000, 2001 R. Byron Moore
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <acpi.h>
#define _COMPONENT ACPI_PARSER
MODULE_NAME ("psargs")
/*******************************************************************************
*
* FUNCTION: Acpi_ps_get_next_package_length
*
* PARAMETERS: Parser_state - Current parser state object
*
* RETURN: Decoded package length. On completion, the AML pointer points
* past the length byte or bytes.
*
* DESCRIPTION: Decode and return a package length field
*
******************************************************************************/
u32
acpi_ps_get_next_package_length (
ACPI_PARSE_STATE *parser_state)
{
u32 encoded_length;
u32 length = 0;
encoded_length = (u32) GET8 (parser_state->aml);
parser_state->aml++;
switch (encoded_length >> 6) /* bits 6-7 contain encoding scheme */ {
case 0: /* 1-byte encoding (bits 0-5) */
length = (encoded_length & 0x3F);
break;
case 1: /* 2-byte encoding (next byte + bits 0-3) */
length = ((GET8 (parser_state->aml) << 04) |
(encoded_length & 0x0F));
parser_state->aml++;
break;
case 2: /* 3-byte encoding (next 2 bytes + bits 0-3) */
length = ((GET8 (parser_state->aml + 1) << 12) |
(GET8 (parser_state->aml) << 04) |
(encoded_length & 0x0F));
parser_state->aml += 2;
break;
case 3: /* 4-byte encoding (next 3 bytes + bits 0-3) */
length = ((GET8 (parser_state->aml + 2) << 20) |
(GET8 (parser_state->aml + 1) << 12) |
(GET8 (parser_state->aml) << 04) |
(encoded_length & 0x0F));
parser_state->aml += 3;
break;
}
return (length);
}
/*******************************************************************************
*
* FUNCTION: Acpi_ps_get_next_package_end
*
* PARAMETERS: Parser_state - Current parser state object
*
* RETURN: Pointer to end-of-package +1
*
* DESCRIPTION: Get next package length and return a pointer past the end of
* the package. Consumes the package length field
*
******************************************************************************/
u8 *
acpi_ps_get_next_package_end (
ACPI_PARSE_STATE *parser_state)
{
u8 *start = parser_state->aml;
NATIVE_UINT length;
length = (NATIVE_UINT) acpi_ps_get_next_package_length (parser_state);
return (start + length); /* end of package */
}
/*******************************************************************************
*
* FUNCTION: Acpi_ps_get_next_namestring
*
* PARAMETERS: Parser_state - Current parser state object
*
* RETURN: Pointer to the start of the name string (pointer points into
* the AML.
*
* DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
* prefix characters. Set parser state to point past the string.
* (Name is consumed from the AML.)
*
******************************************************************************/
NATIVE_CHAR *
acpi_ps_get_next_namestring (
ACPI_PARSE_STATE *parser_state)
{
u8 *start = parser_state->aml;
u8 *end = parser_state->aml;
u32 length;
/* Handle multiple prefix characters */
while (acpi_ps_is_prefix_char (GET8 (end))) {
/* include prefix '\\' or '^' */
end++;
}
/* Decode the path */
switch (GET8 (end)) {
case 0:
/* Null_name */
if (end == start) {
start = NULL;
}
end++;
break;
case AML_DUAL_NAME_PREFIX:
/* two name segments */
end += 9;
break;
case AML_MULTI_NAME_PREFIX_OP:
/* multiple name segments */
length = (u32) GET8 (end + 1) * 4;
end += 2 + length;
break;
default:
/* single name segment */
/* assert (Acpi_ps_is_lead (GET8 (End))); */
end += 4;
break;
}
parser_state->aml = (u8*) end;
return ((NATIVE_CHAR *) start);
}
/*******************************************************************************
*
* FUNCTION: Acpi_ps_get_next_namepath
*
* PARAMETERS: Parser_state - Current parser state object
* Arg - Where the namepath will be stored
* Arg_count - If the namepath points to a control method
* the method's argument is returned here.
* Method_call - Whether the namepath can be the start
* of a method call
*
* RETURN: None
*
* DESCRIPTION: Get next name (if method call, push appropriate # args). Names
* are looked up in either the parsed or internal namespace to
* determine if the name represents a control method. If a method
* is found, the number of arguments to the method is returned.
* This information is critical for parsing to continue correctly.
*
******************************************************************************/
#ifdef PARSER_ONLY
void
acpi_ps_get_next_namepath (
ACPI_PARSE_STATE *parser_state,
ACPI_PARSE_OBJECT *arg,
u32 *arg_count,
u8 method_call)
{
NATIVE_CHAR *path;
ACPI_PARSE_OBJECT *name_op;
ACPI_PARSE_OBJECT *op;
ACPI_PARSE_OBJECT *count;
path = acpi_ps_get_next_namestring (parser_state);
if (!path || !method_call) {
/* Null name case, create a null namepath object */
acpi_ps_init_op (arg, AML_NAMEPATH_OP);
arg->value.name = path;
return;
}
if (acpi_gbl_parsed_namespace_root) {
/*
* Lookup the name in the parsed namespace
*/
op = NULL;
if (method_call) {
op = acpi_ps_find (acpi_ps_get_parent_scope (parser_state),
path, AML_METHOD_OP, 0);
}
if (op) {
if (op->opcode == AML_METHOD_OP) {
/*
* The name refers to a control method, so this namepath is a
* method invocation. We need to 1) Get the number of arguments
* associated with this method, and 2) Change the NAMEPATH
* object into a METHODCALL object.
*/
count = acpi_ps_get_arg (op, 0);
if (count && count->opcode == AML_BYTE_OP) {
name_op = acpi_ps_alloc_op (AML_NAMEPATH_OP);
if (name_op) {
/* Change arg into a METHOD CALL and attach the name */
acpi_ps_init_op (arg, AML_METHODCALL_OP);
name_op->value.name = path;
/* Point METHODCALL/NAME to the METHOD Node */
name_op->node = (ACPI_NAMESPACE_NODE *) op;
acpi_ps_append_arg (arg, name_op);
*arg_count = count->value.integer &
METHOD_FLAGS_ARG_COUNT;
}
}
return;
}
/*
* Else this is normal named object reference.
* Just init the NAMEPATH object with the pathname.
* (See code below)
*/
}
}
/*
* Either we didn't find the object in the namespace, or the object is
* something other than a control method. Just initialize the Op with the
* pathname
*/
acpi_ps_init_op (arg, AML_NAMEPATH_OP);
arg->value.name = path;
return;
}
#else
void
acpi_ps_get_next_namepath (
ACPI_PARSE_STATE *parser_state,
ACPI_PARSE_OBJECT *arg,
u32 *arg_count,
u8 method_call)
{
NATIVE_CHAR *path;
ACPI_PARSE_OBJECT *name_op;
ACPI_STATUS status;
ACPI_NAMESPACE_NODE *method_node = NULL;
ACPI_NAMESPACE_NODE *node;
ACPI_GENERIC_STATE scope_info;
path = acpi_ps_get_next_namestring (parser_state);
if (!path || !method_call) {
/* Null name case, create a null namepath object */
acpi_ps_init_op (arg, AML_NAMEPATH_OP);
arg->value.name = path;
return;
}
if (method_call) {
/*
* Lookup the name in the internal namespace
*/
scope_info.scope.node = NULL;
node = parser_state->start_node;
if (node) {
scope_info.scope.node = node;
}
/*
* Lookup object. We don't want to add anything new to the namespace
* here, however. So we use MODE_EXECUTE. Allow searching of the
* parent tree, but don't open a new scope -- we just want to lookup the
* object (MUST BE mode EXECUTE to perform upsearch)
*/
status = acpi_ns_lookup (&scope_info, path, ACPI_TYPE_ANY, IMODE_EXECUTE,
NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE, NULL,
&node);
if (ACPI_SUCCESS (status)) {
if (node->type == ACPI_TYPE_METHOD) {
method_node = node;
name_op = acpi_ps_alloc_op (AML_NAMEPATH_OP);
if (name_op) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -