Commit 68443ffe authored by Andy Grover's avatar Andy Grover

ACPI: Interpreter update to 20021111 - Adds support for SMBus OpRegions

parent d4eb4155
/******************************************************************************
*
* Module Name: evevent - Fixed and General Purpose Even handling and dispatch
* $Revision: 95 $
* $Revision: 96 $
*
*****************************************************************************/
......@@ -503,9 +503,9 @@ acpi_ev_gpe_initialize (void)
ACPI_REPORT_INFO (("GPE Block%d defined as GPE%d to GPE%d\n",
(s32) gpe_block,
acpi_gbl_gpe_block_info[gpe_block].block_base_number,
acpi_gbl_gpe_block_info[gpe_block].block_base_number +
((acpi_gbl_gpe_block_info[gpe_block].register_count * 8) -1)));
(u32) acpi_gbl_gpe_block_info[gpe_block].block_base_number,
(u32) (acpi_gbl_gpe_block_info[gpe_block].block_base_number +
((acpi_gbl_gpe_block_info[gpe_block].register_count * 8) -1))));
}
}
......
/******************************************************************************
*
* Module Name: exdump - Interpreter debug output routines
* $Revision: 162 $
* $Revision: 163 $
*
*****************************************************************************/
......@@ -590,6 +590,7 @@ acpi_ex_dump_object_descriptor (
acpi_ex_out_integer ("Length", obj_desc->buffer.length);
acpi_ex_out_pointer ("Pointer", obj_desc->buffer.pointer);
ACPI_DUMP_BUFFER (obj_desc->buffer.pointer, obj_desc->buffer.length);
break;
......
/******************************************************************************
*
* Module Name: exfield - ACPI AML (p-code) execution - field manipulation
* $Revision: 112 $
* $Revision: 113 $
*
*****************************************************************************/
......@@ -27,6 +27,8 @@
#include "acpi.h"
#include "acdispat.h"
#include "acinterp.h"
#include "acevents.h"
#include "amlcode.h"
#define _COMPONENT ACPI_EXECUTER
......@@ -82,6 +84,45 @@ acpi_ex_read_data_from_field (
}
}
}
else if ((ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD) &&
(obj_desc->field.region_obj->region.space_id == ACPI_ADR_SPACE_SMBUS)) {
/*
* This is an SMBus read. We must create a buffer to hold the data
* and directly access the region handler.
*/
buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
if (!buffer_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Create the actual read buffer */
buffer_desc->buffer.pointer = ACPI_MEM_CALLOCATE (ACPI_SMBUS_BUFFER_SIZE);
if (!buffer_desc->buffer.pointer) {
acpi_ut_remove_reference (buffer_desc);
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Complete the buffer object initialization */
buffer_desc->common.flags = AOPOBJ_DATA_VALID;
buffer_desc->buffer.length = ACPI_SMBUS_BUFFER_SIZE;
buffer = buffer_desc->buffer.pointer;
/* Lock entire transaction if requested */
locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
/*
* Perform the read.
* Note: Smbus protocol value is passed in upper 16-bits of Function
*/
status = acpi_ex_access_region (obj_desc, 0,
(acpi_integer *) buffer_desc->buffer.pointer,
ACPI_READ | (obj_desc->field.attribute << 16));
acpi_ex_release_global_lock (locked);
goto exit;
}
/*
* Allocate a buffer for the contents of the field.
......@@ -138,17 +179,17 @@ acpi_ex_read_data_from_field (
obj_desc->common_field.start_field_bit_offset,
obj_desc->common_field.base_byte_offset));
/* Lock entire transaction if requested */
locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
/* Read from the field */
status = acpi_ex_extract_from_field (obj_desc, buffer, length);
/*
* Release global lock if we acquired it earlier
*/
acpi_ex_release_global_lock (locked);
exit:
if (ACPI_FAILURE (status)) {
acpi_ut_remove_reference (buffer_desc);
}
......@@ -176,7 +217,8 @@ acpi_ex_read_data_from_field (
acpi_status
acpi_ex_write_data_to_field (
acpi_operand_object *source_desc,
acpi_operand_object *obj_desc)
acpi_operand_object *obj_desc,
acpi_operand_object **result_desc)
{
acpi_status status;
u32 length;
......@@ -184,6 +226,7 @@ acpi_ex_write_data_to_field (
void *buffer;
void *new_buffer;
u8 locked;
acpi_operand_object *buffer_desc;
ACPI_FUNCTION_TRACE_PTR ("Ex_write_data_to_field", obj_desc);
......@@ -207,6 +250,64 @@ acpi_ex_write_data_to_field (
}
}
}
else if ((ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD) &&
(obj_desc->field.region_obj->region.space_id == ACPI_ADR_SPACE_SMBUS)) {
/*
* This is an SMBus write. We will bypass the entire field mechanism
* and handoff the buffer directly to the handler.
*
* Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE).
*/
if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) {
ACPI_REPORT_ERROR (("SMBus write requires Buffer, found type %s\n",
acpi_ut_get_object_type_name (source_desc)));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
}
if (source_desc->buffer.length < ACPI_SMBUS_BUFFER_SIZE) {
ACPI_REPORT_ERROR (("SMBus write requires Buffer of length %X, found length %X\n",
ACPI_SMBUS_BUFFER_SIZE, source_desc->buffer.length));
return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
}
buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
if (!buffer_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Create the actual read buffer */
buffer_desc->buffer.pointer = ACPI_MEM_CALLOCATE (ACPI_SMBUS_BUFFER_SIZE);
if (!buffer_desc->buffer.pointer) {
acpi_ut_remove_reference (buffer_desc);
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Complete the buffer object initialization */
buffer_desc->common.flags = AOPOBJ_DATA_VALID;
buffer_desc->buffer.length = ACPI_SMBUS_BUFFER_SIZE;
buffer = buffer_desc->buffer.pointer;
ACPI_MEMCPY (buffer, source_desc->buffer.pointer, ACPI_SMBUS_BUFFER_SIZE);
/* Lock entire transaction if requested */
locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
/*
* Perform the write (returns status and perhaps data in the same buffer)
* Note: SMBus protocol type is passed in upper 16-bits of Function.
*/
status = acpi_ex_access_region (obj_desc, 0,
(acpi_integer *) buffer,
ACPI_WRITE | (obj_desc->field.attribute << 16));
acpi_ex_release_global_lock (locked);
*result_desc = buffer_desc;
return_ACPI_STATUS (status);
}
/*
* Get a pointer to the data to be written
......@@ -267,16 +368,13 @@ acpi_ex_write_data_to_field (
obj_desc->common_field.start_field_bit_offset,
obj_desc->common_field.base_byte_offset));
/* Lock entire transaction if requested */
locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
/*
* Write to the field
*/
status = acpi_ex_insert_into_field (obj_desc, buffer, length);
/* Write to the field */
/*
* Release global lock if we acquired it earlier
*/
status = acpi_ex_insert_into_field (obj_desc, buffer, length);
acpi_ex_release_global_lock (locked);
/* Free temporary buffer if we used one */
......
/******************************************************************************
*
* Module Name: exfldio - Aml Field I/O
* $Revision: 89 $
* $Revision: 90 $
*
*****************************************************************************/
......@@ -64,6 +64,8 @@ acpi_ex_setup_region (
rgn_desc = obj_desc->common_field.region_obj;
/* We must have a valid region */
if (ACPI_GET_OBJECT_TYPE (rgn_desc) != ACPI_TYPE_REGION) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed Region, found type %X (%s)\n",
ACPI_GET_OBJECT_TYPE (rgn_desc),
......@@ -83,6 +85,12 @@ acpi_ex_setup_region (
}
}
if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS) {
/* SMBus has a non-linear address space */
return_ACPI_STATUS (AE_OK);
}
/*
* Validate the request. The entire request from the byte offset for a
* length of one field datum (access width) must fit within the region.
......@@ -127,8 +135,10 @@ acpi_ex_setup_region (
* PARAMETERS: *Obj_desc - Field to be read
* Field_datum_byte_offset - Byte offset of this datum within the
* parent field
* *Value - Where to store value (must be 32 bits)
* Read_write - Read or Write flag
* *Value - Where to store value (must at least
* the size of acpi_integer)
* Function - Read or Write flag plus other region-
* dependent flags
*
* RETURN: Status
*
......@@ -141,7 +151,7 @@ acpi_ex_access_region (
acpi_operand_object *obj_desc,
u32 field_datum_byte_offset,
acpi_integer *value,
u32 read_write)
u32 function)
{
acpi_status status;
acpi_operand_object *rgn_desc;
......@@ -151,6 +161,15 @@ acpi_ex_access_region (
ACPI_FUNCTION_TRACE ("Ex_access_region");
/*
* Ensure that the region operands are fully evaluated and verify
* the validity of the request
*/
status = acpi_ex_setup_region (obj_desc, field_datum_byte_offset);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/*
* The physical address of this field datum is:
*
......@@ -163,7 +182,7 @@ acpi_ex_access_region (
+ obj_desc->common_field.base_byte_offset
+ field_datum_byte_offset;
if (read_write == ACPI_READ) {
if ((function & ACPI_IO_MASK) == ACPI_READ) {
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[READ]"));
}
else {
......@@ -181,7 +200,7 @@ acpi_ex_access_region (
/* Invoke the appropriate Address_space/Op_region handler */
status = acpi_ev_address_space_dispatch (rgn_desc, read_write,
status = acpi_ev_address_space_dispatch (rgn_desc, function,
address, ACPI_MUL_8 (obj_desc->common_field.access_byte_width), value);
if (ACPI_FAILURE (status)) {
......@@ -191,7 +210,6 @@ acpi_ex_access_region (
acpi_ut_get_region_name (rgn_desc->region.space_id),
rgn_desc->region.space_id));
}
else if (status == AE_NOT_EXIST) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Region %s(%X) has no handler\n",
......@@ -371,11 +389,6 @@ acpi_ex_field_datum_io (
* For simple Region_fields, we just directly access the owning
* Operation Region.
*/
status = acpi_ex_setup_region (obj_desc, field_datum_byte_offset);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
status = acpi_ex_access_region (obj_desc, field_datum_byte_offset, value,
read_write);
break;
......
......@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exoparg1 - AML execution - opcodes with 1 argument
* $Revision: 144 $
* $Revision: 145 $
*
*****************************************************************************/
......@@ -389,14 +389,16 @@ acpi_ex_opcode_1A_1T_1R (
return_ACPI_STATUS (status);
}
/*
* Normally, we would remove a reference on the Operand[0] parameter;
* But since it is being used as the internal return object
* (meaning we would normally increment it), the two cancel out,
* and we simply don't do anything.
*/
walk_state->result_obj = operand[0];
walk_state->operands[0] = NULL; /* Prevent deletion */
if (!walk_state->result_obj) {
/*
* Normally, we would remove a reference on the Operand[0] parameter;
* But since it is being used as the internal return object
* (meaning we would normally increment it), the two cancel out,
* and we simply don't do anything.
*/
walk_state->result_obj = operand[0];
walk_state->operands[0] = NULL; /* Prevent deletion */
}
return_ACPI_STATUS (status);
......@@ -461,7 +463,9 @@ acpi_ex_opcode_1A_1T_1R (
cleanup:
walk_state->result_obj = return_desc;
if (!walk_state->result_obj) {
walk_state->result_obj = return_desc;
}
/* Delete return object on error */
......
/******************************************************************************
*
* Module Name: exoparg2 - AML execution - opcodes with 2 arguments
* $Revision: 113 $
* $Revision: 114 $
*
*****************************************************************************/
......@@ -490,7 +490,9 @@ acpi_ex_opcode_2A_1T_1R (
goto cleanup;
}
walk_state->result_obj = return_desc;
if (!walk_state->result_obj) {
walk_state->result_obj = return_desc;
}
}
......
......@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exoparg3 - AML execution - opcodes with 3 arguments
* $Revision: 14 $
* $Revision: 15 $
*
*****************************************************************************/
......@@ -226,7 +226,9 @@ acpi_ex_opcode_3A_1T_1R (
/* Set the return object and exit */
walk_state->result_obj = return_desc;
if (!walk_state->result_obj) {
walk_state->result_obj = return_desc;
}
return_ACPI_STATUS (status);
}
......
......@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exprep - ACPI AML (p-code) execution - field prep utilities
* $Revision: 120 $
* $Revision: 121 $
*
*****************************************************************************/
......@@ -107,28 +107,24 @@ acpi_ex_decode_field_access (
break;
case AML_FIELD_ACCESS_BYTE:
case AML_FIELD_ACCESS_BUFFER: /* ACPI 2.0 (SMBus Buffer) */
byte_alignment = 1;
bit_length = 8;
bit_length = 8;
break;
case AML_FIELD_ACCESS_WORD:
byte_alignment = 2;
bit_length = 16;
bit_length = 16;
break;
case AML_FIELD_ACCESS_DWORD:
byte_alignment = 4;
bit_length = 32;
bit_length = 32;
break;
case AML_FIELD_ACCESS_QWORD: /* ACPI 2.0 */
case AML_FIELD_ACCESS_QWORD: /* ACPI 2.0 */
byte_alignment = 8;
bit_length = 64;
break;
case AML_FIELD_ACCESS_BUFFER: /* ACPI 2.0 */
byte_alignment = 8;
bit_length = 8;
bit_length = 64;
break;
default:
......
......@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exstore - AML Interpreter object store support
* $Revision: 173 $
* $Revision: 174 $
*
*****************************************************************************/
......@@ -81,7 +81,7 @@ acpi_ex_store (
if (ACPI_GET_DESCRIPTOR_TYPE (dest_desc) == ACPI_DESC_TYPE_NAMED) {
/*
* Dest is a namespace node,
* Storing an object into a Name "container"
* Storing an object into a Named node.
*/
status = acpi_ex_store_object_to_node (source_desc,
(acpi_namespace_node *) dest_desc, walk_state);
......@@ -435,7 +435,7 @@ acpi_ex_store_object_to_node (
/*
* For fields, copy the source data to the target field.
*/
status = acpi_ex_write_data_to_field (source_desc, target_desc);
status = acpi_ex_write_data_to_field (source_desc, target_desc, &walk_state->result_obj);
break;
......
/******************************************************************************
*
* Name: acconfig.h - Global configuration constants
* $Revision: 115 $
* $Revision: 117 $
*
*****************************************************************************/
......@@ -54,7 +54,7 @@
/* Version string */
#define ACPI_CA_VERSION 0x20021101
#define ACPI_CA_VERSION 0x20021111
/* Version of ACPI supported */
......@@ -166,6 +166,10 @@
#define ACPI_RSDP_CHECKSUM_LENGTH 20
#define ACPI_RSDP_XCHECKSUM_LENGTH 36
/* SMBus bidirectional buffer size */
#define ACPI_SMBUS_BUFFER_SIZE 34
/******************************************************************************
*
......
/******************************************************************************
*
* Name: acdisasm.h - AML disassembler
* $Revision: 4 $
* $Revision: 5 $
*
*****************************************************************************/
......@@ -239,6 +239,9 @@ void
acpi_dm_bit_list (
u16 mask);
void
acpi_dm_decode_attribute (
u8 attribute);
/*
* dmresrcl
......
/******************************************************************************
*
* Name: acinterp.h - Interpreter subcomponent prototypes and defines
* $Revision: 141 $
* $Revision: 142 $
*
*****************************************************************************/
......@@ -164,7 +164,8 @@ acpi_ex_read_data_from_field (
acpi_status
acpi_ex_write_data_to_field (
acpi_operand_object *source_desc,
acpi_operand_object *obj_desc);
acpi_operand_object *obj_desc,
acpi_operand_object **result_desc);
/*
* exmisc - ACPI AML (p-code) execution - specific opcodes
......
/******************************************************************************
*
* Name: actypes.h - Common data types for the entire ACPI subsystem
* $Revision: 240 $
* $Revision: 241 $
*
*****************************************************************************/
......@@ -499,6 +499,7 @@ typedef u32 acpi_object_type;
*/
#define ACPI_READ 0
#define ACPI_WRITE 1
#define ACPI_IO_MASK 1
/*
......
......@@ -3,7 +3,7 @@
* Name: amlcode.h - Definitions for AML, as included in "definition blocks"
* Declarations and definitions contained herein are derived
* directly from the ACPI specification.
* $Revision: 70 $
* $Revision: 71 $
*
*****************************************************************************/
......@@ -462,7 +462,8 @@ typedef enum
AML_FIELD_ATTRIB_SMB_BYTE = 0x06,
AML_FIELD_ATTRIB_SMB_WORD = 0x08,
AML_FIELD_ATTRIB_SMB_BLOCK = 0x0A,
AML_FIELD_ATTRIB_SMB_CALL = 0x0E
AML_FIELD_ATTRIB_SMB_WORD_CALL = 0x0C,
AML_FIELD_ATTRIB_SMB_BLOCK_CALL = 0x0D
} AML_ACCESS_ATTRIBUTE;
......
/******************************************************************************
*
* Module Name: nsdump - table dumping routines for debug
* $Revision: 145 $
* $Revision: 146 $
*
*****************************************************************************/
......@@ -180,7 +180,7 @@ acpi_ns_dump_one_object (
/* Indent the object according to the level */
acpi_os_printf ("%2d%*s", level - 1, level * 2, " ");
acpi_os_printf ("%2d%*s", (u32) level - 1, (int) level * 2, " ");
/* Check the node type and name */
......
......@@ -2,7 +2,7 @@
*
* Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
* parents and siblings and Scope manipulation
* $Revision: 115 $
* $Revision: 116 $
*
*****************************************************************************/
......@@ -45,7 +45,7 @@
*
* RETURN: None
*
* DESCRIPTION: Print warning message
* DESCRIPTION: Print warning message with full pathname
*
******************************************************************************/
......@@ -61,12 +61,16 @@ acpi_ns_report_error (
char *name;
/* Convert path to external format */
status = acpi_ns_externalize_name (ACPI_UINT32_MAX, internal_name, NULL, &name);
acpi_os_printf ("%8s-%04d: *** Error: Looking up ",
module_name, line_number);
if (name) {
/* Print target name */
if (ACPI_SUCCESS (status)) {
acpi_os_printf ("[%s]", name);
}
else {
......
/******************************************************************************
*
* Module Name: tbxfroot - Find the root ACPI table (RSDT)
* $Revision: 64 $
* $Revision: 65 $
*
*****************************************************************************/
......@@ -302,7 +302,8 @@ acpi_find_root_pointer (
status = acpi_tb_find_rsdp (&table_info, flags);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "RSDP structure not found\n"));
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "RSDP structure not found, %s Flags=%X\n",
acpi_format_exception (status), flags));
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
......@@ -406,6 +407,8 @@ acpi_tb_find_rsdp (
status = acpi_os_map_memory ((u64) LO_RSDP_WINDOW_BASE, LO_RSDP_WINDOW_SIZE,
(void **) &table_ptr);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n",
LO_RSDP_WINDOW_BASE, LO_RSDP_WINDOW_SIZE));
return_ACPI_STATUS (status);
}
......@@ -428,6 +431,8 @@ acpi_tb_find_rsdp (
status = acpi_os_map_memory ((u64) HI_RSDP_WINDOW_BASE, HI_RSDP_WINDOW_SIZE,
(void **) &table_ptr);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n",
HI_RSDP_WINDOW_BASE, HI_RSDP_WINDOW_SIZE));
return_ACPI_STATUS (status);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment