ACPI 5.0: Implement Connection() and AccessAs() changes
Support within the interpreter and operation region dispatch. Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
Родитель
ffef68273b
Коммит
9ce81784c9
|
@ -162,6 +162,7 @@ acpi_status acpi_ev_initialize_op_regions(void);
|
|||
|
||||
acpi_status
|
||||
acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
|
||||
union acpi_operand_object *field_obj,
|
||||
u32 function,
|
||||
u32 region_offset, u32 bit_width, u64 *value);
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ typedef u32 acpi_mutex_handle;
|
|||
|
||||
/* Total number of aml opcodes defined */
|
||||
|
||||
#define AML_NUM_OPCODES 0x7F
|
||||
#define AML_NUM_OPCODES 0x81
|
||||
|
||||
/* Forward declarations */
|
||||
|
||||
|
@ -249,12 +249,16 @@ struct acpi_create_field_info {
|
|||
struct acpi_namespace_node *field_node;
|
||||
struct acpi_namespace_node *register_node;
|
||||
struct acpi_namespace_node *data_register_node;
|
||||
struct acpi_namespace_node *connection_node;
|
||||
u8 *resource_buffer;
|
||||
u32 bank_value;
|
||||
u32 field_bit_position;
|
||||
u32 field_bit_length;
|
||||
u16 resource_length;
|
||||
u8 field_flags;
|
||||
u8 attribute;
|
||||
u8 field_type;
|
||||
u8 access_length;
|
||||
};
|
||||
|
||||
typedef
|
||||
|
|
|
@ -254,6 +254,7 @@ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_NOTIFY_INFO};
|
|||
u32 base_byte_offset; /* Byte offset within containing object */\
|
||||
u32 value; /* Value to store into the Bank or Index register */\
|
||||
u8 start_field_bit_offset;/* Bit offset within first field datum (0-63) */\
|
||||
u8 access_length; /* For serial regions/fields */
|
||||
|
||||
|
||||
struct acpi_object_field_common { /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */
|
||||
|
@ -261,7 +262,9 @@ struct acpi_object_field_common { /* COMMON FIELD (for BUFFER, REGION, BANK, and
|
|||
};
|
||||
|
||||
struct acpi_object_region_field {
|
||||
ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object *region_obj; /* Containing op_region object */
|
||||
ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO u16 resource_length;
|
||||
union acpi_operand_object *region_obj; /* Containing op_region object */
|
||||
u8 *resource_buffer; /* resource_template for serial regions/fields */
|
||||
};
|
||||
|
||||
struct acpi_object_bank_field {
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
#define ARGP_CONCAT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
|
||||
#define ARGP_CONCAT_RES_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
|
||||
#define ARGP_COND_REF_OF_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_SUPERNAME)
|
||||
#define ARGP_CONNECTFIELD_OP ARGP_LIST1 (ARGP_NAMESTRING)
|
||||
#define ARGP_CONTINUE_OP ARG_NONE
|
||||
#define ARGP_COPY_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_SIMPLENAME)
|
||||
#define ARGP_CREATE_BIT_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME)
|
||||
|
@ -164,6 +165,7 @@
|
|||
#define ARGP_RETURN_OP ARGP_LIST1 (ARGP_TERMARG)
|
||||
#define ARGP_REVISION_OP ARG_NONE
|
||||
#define ARGP_SCOPE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_TERMLIST)
|
||||
#define ARGP_SERIALFIELD_OP ARGP_LIST1 (ARGP_NAMESTRING)
|
||||
#define ARGP_SHIFT_LEFT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
|
||||
#define ARGP_SHIFT_RIGHT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
|
||||
#define ARGP_SIGNAL_OP ARGP_LIST1 (ARGP_SUPERNAME)
|
||||
|
@ -223,6 +225,7 @@
|
|||
#define ARGI_CONCAT_OP ARGI_LIST3 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA, ARGI_TARGETREF)
|
||||
#define ARGI_CONCAT_RES_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_BUFFER, ARGI_TARGETREF)
|
||||
#define ARGI_COND_REF_OF_OP ARGI_LIST2 (ARGI_OBJECT_REF, ARGI_TARGETREF)
|
||||
#define ARGI_CONNECTFIELD_OP ARGI_INVALID_OPCODE
|
||||
#define ARGI_CONTINUE_OP ARGI_INVALID_OPCODE
|
||||
#define ARGI_COPY_OP ARGI_LIST2 (ARGI_ANYTYPE, ARGI_SIMPLE_TARGET)
|
||||
#define ARGI_CREATE_BIT_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE)
|
||||
|
@ -294,6 +297,7 @@
|
|||
#define ARGI_RETURN_OP ARGI_INVALID_OPCODE
|
||||
#define ARGI_REVISION_OP ARG_NONE
|
||||
#define ARGI_SCOPE_OP ARGI_INVALID_OPCODE
|
||||
#define ARGI_SERIALFIELD_OP ARGI_INVALID_OPCODE
|
||||
#define ARGI_SHIFT_LEFT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
|
||||
#define ARGI_SHIFT_RIGHT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
|
||||
#define ARGI_SIGNAL_OP ARGI_LIST1 (ARGI_EVENT)
|
||||
|
|
|
@ -188,6 +188,14 @@
|
|||
#define AML_LLESSEQUAL_OP (u16) 0x9294
|
||||
#define AML_LNOTEQUAL_OP (u16) 0x9293
|
||||
|
||||
/*
|
||||
* Opcodes for "Field" operators
|
||||
*/
|
||||
#define AML_FIELD_OFFSET_OP (u8) 0x00
|
||||
#define AML_FIELD_ACCESS_OP (u8) 0x01
|
||||
#define AML_FIELD_CONNECTION_OP (u8) 0x02 /* ACPI 5.0 */
|
||||
#define AML_FIELD_EXT_ACCESS_OP (u8) 0x03 /* ACPI 5.0 */
|
||||
|
||||
/*
|
||||
* Internal opcodes
|
||||
* Use only "Unknown" AML opcodes, don't attempt to use
|
||||
|
@ -202,6 +210,8 @@
|
|||
#define AML_INT_METHODCALL_OP (u16) 0x0035
|
||||
#define AML_INT_RETURN_VALUE_OP (u16) 0x0036
|
||||
#define AML_INT_EVAL_SUBTREE_OP (u16) 0x0037
|
||||
#define AML_INT_CONNECTION_OP (u16) 0x0038
|
||||
#define AML_INT_EXTACCESSFIELD_OP (u16) 0x0039
|
||||
|
||||
#define ARG_NONE 0x0
|
||||
|
||||
|
|
|
@ -221,6 +221,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
|
|||
{
|
||||
acpi_status status;
|
||||
u64 position;
|
||||
union acpi_parse_object *child;
|
||||
|
||||
ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info);
|
||||
|
||||
|
@ -232,10 +233,11 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
|
|||
|
||||
while (arg) {
|
||||
/*
|
||||
* Three types of field elements are handled:
|
||||
* 1) Offset - specifies a bit offset
|
||||
* 2) access_as - changes the access mode
|
||||
* 3) Name - Enters a new named field into the namespace
|
||||
* Four types of field elements are handled:
|
||||
* 1) Name - Enters a new named field into the namespace
|
||||
* 2) Offset - specifies a bit offset
|
||||
* 3) access_as - changes the access mode/attributes
|
||||
* 4) Connection - Associate a resource template with the field
|
||||
*/
|
||||
switch (arg->common.aml_opcode) {
|
||||
case AML_INT_RESERVEDFIELD_OP:
|
||||
|
@ -253,21 +255,70 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
|
|||
break;
|
||||
|
||||
case AML_INT_ACCESSFIELD_OP:
|
||||
|
||||
case AML_INT_EXTACCESSFIELD_OP:
|
||||
/*
|
||||
* Get a new access_type and access_attribute -- to be used for all
|
||||
* field units that follow, until field end or another access_as
|
||||
* keyword.
|
||||
* Get new access_type, access_attribute, and access_length fields
|
||||
* -- to be used for all field units that follow, until the
|
||||
* end-of-field or another access_as keyword is encountered.
|
||||
* NOTE. These three bytes are encoded in the integer value
|
||||
* of the parseop for convenience.
|
||||
*
|
||||
* In field_flags, preserve the flag bits other than the
|
||||
* ACCESS_TYPE bits
|
||||
* ACCESS_TYPE bits.
|
||||
*/
|
||||
|
||||
/* access_type (byte_acc, word_acc, etc.) */
|
||||
|
||||
info->field_flags = (u8)
|
||||
((info->
|
||||
field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
|
||||
((u8) ((u32) arg->common.value.integer >> 8)));
|
||||
((u8)((u32)(arg->common.value.integer & 0x07))));
|
||||
|
||||
info->attribute = (u8) (arg->common.value.integer);
|
||||
/* access_attribute (attrib_quick, attrib_byte, etc.) */
|
||||
|
||||
info->attribute =
|
||||
(u8)((arg->common.value.integer >> 8) & 0xFF);
|
||||
|
||||
/* access_length (for serial/buffer protocols) */
|
||||
|
||||
info->access_length =
|
||||
(u8)((arg->common.value.integer >> 16) & 0xFF);
|
||||
break;
|
||||
|
||||
case AML_INT_CONNECTION_OP:
|
||||
/*
|
||||
* Clear any previous connection. New connection is used for all
|
||||
* fields that follow, similar to access_as
|
||||
*/
|
||||
info->resource_buffer = NULL;
|
||||
info->connection_node = NULL;
|
||||
|
||||
/*
|
||||
* A Connection() is either an actual resource descriptor (buffer)
|
||||
* or a named reference to a resource template
|
||||
*/
|
||||
child = arg->common.value.arg;
|
||||
if (child->common.aml_opcode == AML_INT_BYTELIST_OP) {
|
||||
info->resource_buffer = child->named.data;
|
||||
info->resource_length =
|
||||
(u16)child->named.value.integer;
|
||||
} else {
|
||||
/* Lookup the Connection() namepath, it should already exist */
|
||||
|
||||
status = acpi_ns_lookup(walk_state->scope_info,
|
||||
child->common.value.
|
||||
name, ACPI_TYPE_ANY,
|
||||
ACPI_IMODE_EXECUTE,
|
||||
ACPI_NS_DONT_OPEN_SCOPE,
|
||||
walk_state,
|
||||
&info->connection_node);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_ERROR_NAMESPACE(child->common.
|
||||
value.name,
|
||||
status);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AML_INT_NAMEDFIELD_OP:
|
||||
|
@ -374,6 +425,8 @@ acpi_ds_create_field(union acpi_parse_object *op,
|
|||
}
|
||||
}
|
||||
|
||||
ACPI_MEMSET(&info, 0, sizeof(struct acpi_create_field_info));
|
||||
|
||||
/* Second arg is the field flags */
|
||||
|
||||
arg = arg->common.next;
|
||||
|
@ -386,7 +439,6 @@ acpi_ds_create_field(union acpi_parse_object *op,
|
|||
info.region_node = region_node;
|
||||
|
||||
status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
|
||||
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
|
@ -474,8 +526,8 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
|
|||
*/
|
||||
while (arg) {
|
||||
/*
|
||||
* Ignore OFFSET and ACCESSAS terms here; we are only interested in the
|
||||
* field names in order to enter them into the namespace.
|
||||
* Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
|
||||
* in the field names in order to enter them into the namespace.
|
||||
*/
|
||||
if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
|
||||
status = acpi_ns_lookup(walk_state->scope_info,
|
||||
|
@ -651,6 +703,5 @@ acpi_ds_create_index_field(union acpi_parse_object *op,
|
|||
info.region_node = region_node;
|
||||
|
||||
status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
|
||||
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
|
|
@ -329,6 +329,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
|
|||
* FUNCTION: acpi_ev_address_space_dispatch
|
||||
*
|
||||
* PARAMETERS: region_obj - Internal region object
|
||||
* field_obj - Corresponding field. Can be NULL.
|
||||
* Function - Read or Write operation
|
||||
* region_offset - Where in the region to read or write
|
||||
* bit_width - Field width in bits (8, 16, 32, or 64)
|
||||
|
@ -344,6 +345,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
|
|||
|
||||
acpi_status
|
||||
acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
|
||||
union acpi_operand_object *field_obj,
|
||||
u32 function,
|
||||
u32 region_offset, u32 bit_width, u64 *value)
|
||||
{
|
||||
|
@ -353,6 +355,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
|
|||
union acpi_operand_object *handler_desc;
|
||||
union acpi_operand_object *region_obj2;
|
||||
void *region_context = NULL;
|
||||
struct acpi_connection_info *context;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ev_address_space_dispatch);
|
||||
|
||||
|
@ -375,6 +378,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
|
|||
return_ACPI_STATUS(AE_NOT_EXIST);
|
||||
}
|
||||
|
||||
context = handler_desc->address_space.context;
|
||||
|
||||
/*
|
||||
* It may be the case that the region has never been initialized.
|
||||
* Some types of regions require special init code
|
||||
|
@ -404,8 +409,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
|
|||
acpi_ex_exit_interpreter();
|
||||
|
||||
status = region_setup(region_obj, ACPI_REGION_ACTIVATE,
|
||||
handler_desc->address_space.context,
|
||||
®ion_context);
|
||||
context, ®ion_context);
|
||||
|
||||
/* Re-enter the interpreter */
|
||||
|
||||
|
@ -455,6 +459,25 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
|
|||
acpi_ut_get_region_name(region_obj->region.
|
||||
space_id)));
|
||||
|
||||
/*
|
||||
* Special handling for generic_serial_bus and general_purpose_io:
|
||||
* There are three extra parameters that must be passed to the
|
||||
* handler via the context:
|
||||
* 1) Connection buffer, a resource template from Connection() op.
|
||||
* 2) Length of the above buffer.
|
||||
* 3) Actual access length from the access_as() op.
|
||||
*/
|
||||
if (((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) ||
|
||||
(region_obj->region.space_id == ACPI_ADR_SPACE_GPIO)) &&
|
||||
context && field_obj) {
|
||||
|
||||
/* Get the Connection (resource_template) buffer */
|
||||
|
||||
context->connection = field_obj->field.resource_buffer;
|
||||
context->length = field_obj->field.resource_length;
|
||||
context->access_length = field_obj->field.access_length;
|
||||
}
|
||||
|
||||
if (!(handler_desc->address_space.handler_flags &
|
||||
ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
|
||||
/*
|
||||
|
@ -469,7 +492,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
|
|||
|
||||
status = handler(function,
|
||||
(region_obj->region.address + region_offset),
|
||||
bit_width, value, handler_desc->address_space.context,
|
||||
bit_width, value, context,
|
||||
region_obj2->extra.region_context);
|
||||
|
||||
if (ACPI_FAILURE(status)) {
|
||||
|
|
|
@ -297,9 +297,9 @@ acpi_ex_region_read(union acpi_operand_object *obj_desc, u32 length, u8 *buffer)
|
|||
/* Bytewise reads */
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
status = acpi_ev_address_space_dispatch(obj_desc, ACPI_READ,
|
||||
region_offset, 8,
|
||||
&value);
|
||||
status =
|
||||
acpi_ev_address_space_dispatch(obj_desc, NULL, ACPI_READ,
|
||||
region_offset, 8, &value);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -192,10 +192,13 @@ static struct acpi_exdump_info acpi_ex_dump_buffer_field[3] = {
|
|||
"Buffer Object"}
|
||||
};
|
||||
|
||||
static struct acpi_exdump_info acpi_ex_dump_region_field[3] = {
|
||||
static struct acpi_exdump_info acpi_ex_dump_region_field[5] = {
|
||||
{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_region_field), NULL},
|
||||
{ACPI_EXD_FIELD, 0, NULL},
|
||||
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(field.region_obj), "Region Object"}
|
||||
{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(field.access_length), "AccessLength"},
|
||||
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(field.region_obj), "Region Object"},
|
||||
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(field.resource_buffer),
|
||||
"ResourceBuffer"}
|
||||
};
|
||||
|
||||
static struct acpi_exdump_info acpi_ex_dump_bank_field[5] = {
|
||||
|
|
|
@ -283,11 +283,12 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
|
|||
|
||||
/* Invoke the appropriate address_space/op_region handler */
|
||||
|
||||
status =
|
||||
acpi_ev_address_space_dispatch(rgn_desc, function, region_offset,
|
||||
ACPI_MUL_8(obj_desc->common_field.
|
||||
access_byte_width),
|
||||
value);
|
||||
status = acpi_ev_address_space_dispatch(rgn_desc, obj_desc,
|
||||
function, region_offset,
|
||||
ACPI_MUL_8(obj_desc->
|
||||
common_field.
|
||||
access_byte_width),
|
||||
value);
|
||||
|
||||
if (ACPI_FAILURE(status)) {
|
||||
if (status == AE_NOT_IMPLEMENTED) {
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "acinterp.h"
|
||||
#include "amlcode.h"
|
||||
#include "acnamesp.h"
|
||||
#include "acdispat.h"
|
||||
|
||||
#define _COMPONENT ACPI_EXECUTER
|
||||
ACPI_MODULE_NAME("exprep")
|
||||
|
@ -455,6 +456,30 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
|
|||
obj_desc->field.region_obj =
|
||||
acpi_ns_get_attached_object(info->region_node);
|
||||
|
||||
/* Fields specific to generic_serial_bus fields */
|
||||
|
||||
obj_desc->field.access_length = info->access_length;
|
||||
|
||||
if (info->connection_node) {
|
||||
second_desc = info->connection_node->object;
|
||||
if (!(second_desc->common.flags & AOPOBJ_DATA_VALID)) {
|
||||
status =
|
||||
acpi_ds_get_buffer_arguments(second_desc);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
acpi_ut_delete_object_desc(obj_desc);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
|
||||
obj_desc->field.resource_buffer =
|
||||
second_desc->buffer.pointer;
|
||||
obj_desc->field.resource_length =
|
||||
(u16)second_desc->buffer.length;
|
||||
} else if (info->resource_buffer) {
|
||||
obj_desc->field.resource_buffer = info->resource_buffer;
|
||||
obj_desc->field.resource_length = info->resource_length;
|
||||
}
|
||||
|
||||
/* Allow full data read from EC address space */
|
||||
|
||||
if ((obj_desc->field.region_obj->region.space_id ==
|
||||
|
|
|
@ -484,34 +484,54 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
|
|||
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);
|
||||
u32 aml_offset;
|
||||
union acpi_parse_object *field;
|
||||
union acpi_parse_object *arg = NULL;
|
||||
u16 opcode;
|
||||
u32 name;
|
||||
u8 access_type;
|
||||
u8 access_attribute;
|
||||
u8 access_length;
|
||||
u32 pkg_length;
|
||||
u8 *pkg_end;
|
||||
u32 buffer_length;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ps_get_next_field);
|
||||
|
||||
aml_offset =
|
||||
(u32)ACPI_PTR_DIFF(parser_state->aml, parser_state->aml_start);
|
||||
|
||||
/* Determine field type */
|
||||
|
||||
switch (ACPI_GET8(parser_state->aml)) {
|
||||
default:
|
||||
|
||||
opcode = AML_INT_NAMEDFIELD_OP;
|
||||
break;
|
||||
|
||||
case 0x00:
|
||||
case AML_FIELD_OFFSET_OP:
|
||||
|
||||
opcode = AML_INT_RESERVEDFIELD_OP;
|
||||
parser_state->aml++;
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
case AML_FIELD_ACCESS_OP:
|
||||
|
||||
opcode = AML_INT_ACCESSFIELD_OP;
|
||||
parser_state->aml++;
|
||||
break;
|
||||
|
||||
case AML_FIELD_CONNECTION_OP:
|
||||
|
||||
opcode = AML_INT_CONNECTION_OP;
|
||||
parser_state->aml++;
|
||||
break;
|
||||
|
||||
case AML_FIELD_EXT_ACCESS_OP:
|
||||
|
||||
opcode = AML_INT_EXTACCESSFIELD_OP;
|
||||
parser_state->aml++;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
opcode = AML_INT_NAMEDFIELD_OP;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Allocate a new field op */
|
||||
|
@ -549,16 +569,111 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
|
|||
break;
|
||||
|
||||
case AML_INT_ACCESSFIELD_OP:
|
||||
case AML_INT_EXTACCESSFIELD_OP:
|
||||
|
||||
/*
|
||||
* Get access_type and access_attrib and merge into the field Op
|
||||
* access_type is first operand, access_attribute is second
|
||||
* access_type is first operand, access_attribute is second. stuff
|
||||
* these bytes into the node integer value for convenience.
|
||||
*/
|
||||
field->common.value.integer =
|
||||
(((u32) ACPI_GET8(parser_state->aml) << 8));
|
||||
|
||||
/* Get the two bytes (Type/Attribute) */
|
||||
|
||||
access_type = ACPI_GET8(parser_state->aml);
|
||||
parser_state->aml++;
|
||||
field->common.value.integer |= ACPI_GET8(parser_state->aml);
|
||||
access_attribute = ACPI_GET8(parser_state->aml);
|
||||
parser_state->aml++;
|
||||
|
||||
field->common.value.integer = (u8)access_type;
|
||||
field->common.value.integer |= (u16)(access_attribute << 8);
|
||||
|
||||
/* This opcode has a third byte, access_length */
|
||||
|
||||
if (opcode == AML_INT_EXTACCESSFIELD_OP) {
|
||||
access_length = ACPI_GET8(parser_state->aml);
|
||||
parser_state->aml++;
|
||||
|
||||
field->common.value.integer |=
|
||||
(u32)(access_length << 16);
|
||||
}
|
||||
break;
|
||||
|
||||
case AML_INT_CONNECTION_OP:
|
||||
|
||||
/*
|
||||
* Argument for Connection operator can be either a Buffer
|
||||
* (resource descriptor), or a name_string.
|
||||
*/
|
||||
if (ACPI_GET8(parser_state->aml) == AML_BUFFER_OP) {
|
||||
parser_state->aml++;
|
||||
|
||||
pkg_end = parser_state->aml;
|
||||
pkg_length =
|
||||
acpi_ps_get_next_package_length(parser_state);
|
||||
pkg_end += pkg_length;
|
||||
|
||||
if (parser_state->aml < pkg_end) {
|
||||
|
||||
/* Non-empty list */
|
||||
|
||||
arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP);
|
||||
if (!arg) {
|
||||
return_PTR(NULL);
|
||||
}
|
||||
|
||||
/* Get the actual buffer length argument */
|
||||
|
||||
opcode = ACPI_GET8(parser_state->aml);
|
||||
parser_state->aml++;
|
||||
|
||||
switch (opcode) {
|
||||
case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
|
||||
buffer_length =
|
||||
ACPI_GET8(parser_state->aml);
|
||||
parser_state->aml += 1;
|
||||
break;
|
||||
|
||||
case AML_WORD_OP: /* AML_WORDDATA_ARG */
|
||||
buffer_length =
|
||||
ACPI_GET16(parser_state->aml);
|
||||
parser_state->aml += 2;
|
||||
break;
|
||||
|
||||
case AML_DWORD_OP: /* AML_DWORDATA_ARG */
|
||||
buffer_length =
|
||||
ACPI_GET32(parser_state->aml);
|
||||
parser_state->aml += 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
buffer_length = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Fill in bytelist data */
|
||||
|
||||
arg->named.value.size = buffer_length;
|
||||
arg->named.data = parser_state->aml;
|
||||
}
|
||||
|
||||
/* Skip to End of byte data */
|
||||
|
||||
parser_state->aml = pkg_end;
|
||||
} else {
|
||||
arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP);
|
||||
if (!arg) {
|
||||
return_PTR(NULL);
|
||||
}
|
||||
|
||||
/* Get the Namestring argument */
|
||||
|
||||
arg->common.value.name =
|
||||
acpi_ps_get_next_namestring(parser_state);
|
||||
}
|
||||
|
||||
/* Link the buffer/namestring to parent (CONNECTION_OP) */
|
||||
|
||||
acpi_ps_append_arg(field, arg);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -638,7 +638,16 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = {
|
|||
|
||||
/* 7E */ ACPI_OP("Timer", ARGP_TIMER_OP, ARGI_TIMER_OP, ACPI_TYPE_ANY,
|
||||
AML_CLASS_EXECUTE, AML_TYPE_EXEC_0A_0T_1R,
|
||||
AML_FLAGS_EXEC_0A_0T_1R)
|
||||
AML_FLAGS_EXEC_0A_0T_1R),
|
||||
|
||||
/* ACPI 5.0 opcodes */
|
||||
|
||||
/* 7F */ ACPI_OP("-ConnectField-", ARGP_CONNECTFIELD_OP,
|
||||
ARGI_CONNECTFIELD_OP, ACPI_TYPE_ANY,
|
||||
AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_HAS_ARGS),
|
||||
/* 80 */ ACPI_OP("-ExtAccessField-", ARGP_CONNECTFIELD_OP,
|
||||
ARGI_CONNECTFIELD_OP, ACPI_TYPE_ANY,
|
||||
AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0)
|
||||
|
||||
/*! [End] no source code translation !*/
|
||||
};
|
||||
|
@ -657,7 +666,7 @@ static const u8 acpi_gbl_short_op_index[256] = {
|
|||
/* 0x20 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||
/* 0x28 */ _UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX,
|
||||
/* 0x30 */ 0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, 0x7D,
|
||||
/* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||
/* 0x38 */ 0x7F, 0x80, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||
/* 0x40 */ _UNK, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
|
||||
/* 0x48 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
|
||||
/* 0x50 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
|
||||
|
|
|
@ -74,6 +74,12 @@ union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn)
|
|||
|
||||
ACPI_FUNCTION_ENTRY();
|
||||
|
||||
/*
|
||||
if (Op->Common.aml_opcode == AML_INT_CONNECTION_OP)
|
||||
{
|
||||
return (Op->Common.Value.Arg);
|
||||
}
|
||||
*/
|
||||
/* Get the info structure for this opcode */
|
||||
|
||||
op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
|
||||
|
|
|
@ -957,6 +957,14 @@ acpi_status(*acpi_adr_space_handler) (u32 function,
|
|||
|
||||
#define ACPI_DEFAULT_HANDLER NULL
|
||||
|
||||
/* Special Context data for generic_serial_bus/general_purpose_io (ACPI 5.0) */
|
||||
|
||||
struct acpi_connection_info {
|
||||
u8 *connection;
|
||||
u16 length;
|
||||
u8 access_length;
|
||||
};
|
||||
|
||||
typedef
|
||||
acpi_status(*acpi_adr_space_setup) (acpi_handle region_handle,
|
||||
u32 function,
|
||||
|
|
Загрузка…
Ссылка в новой задаче