Commit 26ad1247 authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] ACPICA 20041210 from Bob Moore

ACPI 3.0 support is nearing completion in both the iASL
compiler and the ACPI CA core subsystem.

Fixed a problem in the ToDecimalString operator where the
resulting string length was incorrectly calculated. The
length is now calculated exactly, eliminating incorrect
AE_STRING_LIMIT exceptions.

Fixed a problem in the ToHexString operator to allow a
maximum 200 character string to be produced.

Fixed a problem in the internal string-to-buffer and
buffer-to-buffer copy routine where the length of the
resulting buffer was not truncated to the new size (if
the target buffer already existed).
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent ce8f5e23
......@@ -399,9 +399,9 @@ acpi_ex_convert_to_string (
{
union acpi_operand_object *return_desc;
u8 *new_buf;
u32 i;
u32 string_length = 0;
u16 base = 16;
u32 i;
u8 separator = ',';
......@@ -461,6 +461,8 @@ acpi_ex_convert_to_string (
case ACPI_TYPE_BUFFER:
/* Setup string length, base, and separator */
switch (type) {
case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by to_decimal_string operator */
/*
......@@ -468,9 +470,23 @@ acpi_ex_convert_to_string (
* decimal values separated by commas."
*/
base = 10;
string_length = obj_desc->buffer.length; /* 4 chars for each decimal */
/*lint -fallthrough */
/*
* Calculate the final string length. Individual string values
* are variable length (include separator for each)
*/
for (i = 0; i < obj_desc->buffer.length; i++) {
if (obj_desc->buffer.pointer[i] >= 100) {
string_length += 4;
}
else if (obj_desc->buffer.pointer[i] >= 10) {
string_length += 3;
}
else {
string_length += 2;
}
}
break;
case ACPI_IMPLICIT_CONVERT_HEX:
/*
......@@ -478,56 +494,56 @@ acpi_ex_convert_to_string (
*"The entire contents of the buffer are converted to a string of
* two-character hexadecimal numbers, each separated by a space."
*/
if (type == ACPI_IMPLICIT_CONVERT_HEX) {
separator = ' ';
}
/*lint -fallthrough */
separator = ' ';
string_length = (obj_desc->buffer.length * 3);
break;
case ACPI_EXPLICIT_CONVERT_HEX: /* Used by to_hex_string operator */
/*
* From ACPI: "If Data is a buffer, it is converted to a string of
* hexadecimal values separated by commas."
*/
string_length += (obj_desc->buffer.length * 3);
if (string_length > ACPI_MAX_STRING_CONVERSION) /* ACPI limit */ {
return_ACPI_STATUS (AE_AML_STRING_LIMIT);
}
/* Create a new string object and string buffer */
return_desc = acpi_ut_create_string_object ((acpi_size) string_length -1);
if (!return_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
string_length = (obj_desc->buffer.length * 3);
break;
new_buf = return_desc->buffer.pointer;
default:
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/*
* Convert buffer bytes to hex or decimal values
* (separated by commas)
*/
for (i = 0; i < obj_desc->buffer.length; i++) {
new_buf += acpi_ex_convert_to_ascii (
(acpi_integer) obj_desc->buffer.pointer[i], base,
new_buf, 1);
*new_buf++ = separator; /* each separated by a comma or space */
}
/*
* Perform the conversion.
* (-1 because of extra separator included in string_length from above)
*/
string_length--;
if (string_length > ACPI_MAX_STRING_CONVERSION) /* ACPI limit */ {
return_ACPI_STATUS (AE_AML_STRING_LIMIT);
}
/* Null terminate the string (overwrites final comma from above) */
/*
* Create a new string object and string buffer
*/
return_desc = acpi_ut_create_string_object ((acpi_size) string_length);
if (!return_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
new_buf--;
*new_buf = 0;
new_buf = return_desc->buffer.pointer;
/* Recalculate length */
/*
* Convert buffer bytes to hex or decimal values
* (separated by commas or spaces)
*/
for (i = 0; i < obj_desc->buffer.length; i++) {
new_buf += acpi_ex_convert_to_ascii (
(acpi_integer) obj_desc->buffer.pointer[i], base,
new_buf, 1);
*new_buf++ = separator; /* each separated by a comma or space */
}
return_desc->string.length = (u32)
ACPI_STRLEN (return_desc->string.pointer);
break;
/* Null terminate the string (overwrites final comma/space from above) */
default:
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
new_buf--;
*new_buf = 0;
break;
default:
......
......@@ -93,34 +93,35 @@ acpi_ex_store_buffer_to_buffer (
return_ACPI_STATUS (AE_NO_MEMORY);
}
target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
target_desc->buffer.length = length;
}
/*
* Buffer is a static allocation,
* only place what will fit in the buffer.
*/
/* Copy source buffer to target buffer */
if (length <= target_desc->buffer.length) {
/* Clear existing buffer and copy in the new one */
ACPI_MEMSET (target_desc->buffer.pointer, 0, target_desc->buffer.length);
ACPI_MEMCPY (target_desc->buffer.pointer, buffer, length);
/* Set the new length of the target */
target_desc->buffer.length = length;
}
else {
/*
* Truncate the source, copy only what will fit
*/
/* Truncate the source, copy only what will fit */
ACPI_MEMCPY (target_desc->buffer.pointer, buffer, target_desc->buffer.length);
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Truncating src buffer from %X to %X\n",
"Truncating source buffer from %X to %X\n",
length, target_desc->buffer.length));
}
/* Copy flags */
target_desc->buffer.flags = source_desc->buffer.flags;
target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
return_ACPI_STATUS (AE_OK);
}
......
......@@ -187,7 +187,7 @@ acpi_tb_init_generic_address (
new_gas_struct->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
new_gas_struct->register_bit_width = register_bit_width;
new_gas_struct->register_bit_offset = 0;
new_gas_struct->reserved = 0;
new_gas_struct->access_width = 0;
}
......@@ -503,7 +503,7 @@ acpi_tb_convert_table_fadt (void)
*
* FUNCTION: acpi_tb_convert_table_facs
*
* PARAMETERS: table_info - Info for currently installad FACS
* PARAMETERS: table_info - Info for currently installed FACS
*
* RETURN: Status
*
......
......@@ -64,7 +64,7 @@
/* Version string */
#define ACPI_CA_VERSION 0x20041203
#define ACPI_CA_VERSION 0x20041210
/*
* OS name, used for the _OS object. The _OS object is essentially obsolete,
......@@ -99,7 +99,7 @@
/* Version of ACPI supported */
#define ACPI_CA_SUPPORT_LEVEL 2
#define ACPI_CA_SUPPORT_LEVEL 3
/* String size constants */
......
......@@ -316,6 +316,12 @@ acpi_dm_dword_descriptor (
u32 length,
u32 level);
void
acpi_dm_extended_descriptor (
struct asl_extended_address_desc *resource,
u32 length,
u32 level);
void
acpi_dm_qword_descriptor (
struct asl_qword_address_desc *resource,
......
......@@ -862,7 +862,6 @@ struct acpi_bit_register_info
/*
* Large resource descriptor types
*/
#define ACPI_RDESC_TYPE_MEMORY_24 0x81
#define ACPI_RDESC_TYPE_GENERAL_REGISTER 0x82
#define ACPI_RDESC_TYPE_LARGE_VENDOR 0x84
......@@ -872,6 +871,7 @@ struct acpi_bit_register_info
#define ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE 0x88
#define ACPI_RDESC_TYPE_EXTENDED_XRUPT 0x89
#define ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE 0x8A
#define ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE 0x8B
/*****************************************************************************
......
......@@ -115,7 +115,7 @@ struct acpi_generic_address
u8 address_space_id; /* Address space where struct or register exists. */
u8 register_bit_width; /* Size in bits of given register */
u8 register_bit_offset; /* Bit offset within the register */
u8 reserved; /* Must be 0 */
u8 access_width; /* Minimum Access size (ACPI 3.0) */
u64 address; /* 64-bit address of struct or register */
};
......
......@@ -50,6 +50,8 @@
#define ASL_RESNAME_ADDRESS "_ADR"
#define ASL_RESNAME_ALIGNMENT "_ALN"
#define ASL_RESNAME_ADDRESSSPACE "_ASI"
#define ASL_RESNAME_ACCESSSIZE "_ASZ"
#define ASL_RESNAME_TYPESPECIFICATTRIBUTES "_ATT"
#define ASL_RESNAME_BASEADDRESS "_BAS"
#define ASL_RESNAME_BUSMASTER "_BM_" /* Master(1), Slave(0) */
#define ASL_RESNAME_DECODE "_DEC"
......@@ -223,6 +225,27 @@ struct asl_fixed_memory_32_desc
};
struct asl_extended_address_desc
{
u8 descriptor_type;
u16 length;
u8 resource_type;
u8 flags;
u8 specific_flags;
u8 revision_iD;
u8 reserved;
u64 granularity;
u64 address_min;
u64 address_max;
u64 translation_offset;
u64 address_length;
u64 type_specific_attributes;
u8 optional_fields[2]; /* Used for length calculation only */
};
#define ASL_EXTENDED_ADDRESS_DESC_REVISION 1 /* ACPI 3.0 */
struct asl_qword_address_desc
{
u8 descriptor_type;
......@@ -289,7 +312,7 @@ struct asl_general_register_desc
u8 address_space_id;
u8 bit_width;
u8 bit_offset;
u8 reserved;
u8 access_size; /* ACPI 3.0, was Reserved */
u64 address;
};
......@@ -317,6 +340,7 @@ union asl_resource_desc
struct asl_qword_address_desc qas;
struct asl_dword_address_desc das;
struct asl_word_address_desc was;
struct asl_extended_address_desc eas;
struct asl_extended_xrupt_desc exx;
struct asl_general_register_desc grg;
u32 u32_item;
......
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