summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/resources/rsaddr.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2005-10-01 01:03:00 +0200
committerLen Brown <len.brown@intel.com>2005-12-10 06:20:25 +0100
commit50eca3eb89d73d9f0aa070b126c7ee6a616016ab (patch)
treeb2d06d21b34b9bd17eea4c53cff1f3866fa1b21d /drivers/acpi/resources/rsaddr.c
parentPull release into acpica branch (diff)
downloadlinux-50eca3eb89d73d9f0aa070b126c7ee6a616016ab.tar.xz
linux-50eca3eb89d73d9f0aa070b126c7ee6a616016ab.zip
[ACPI] ACPICA 20050930
Completed a major overhaul of the Resource Manager code - specifically, optimizations in the area of the AML/internal resource conversion code. The code has been optimized to simplify and eliminate duplicated code, CPU stack use has been decreased by optimizing function parameters and local variables, and naming conventions across the manager have been standardized for clarity and ease of maintenance (this includes function, parameter, variable, and struct/typedef names.) All Resource Manager dispatch and information tables have been moved to a single location for clarity and ease of maintenance. One new file was created, named "rsinfo.c". The ACPI return macros (return_ACPI_STATUS, etc.) have been modified to guarantee that the argument is not evaluated twice, making them less prone to macro side-effects. However, since there exists the possibility of additional stack use if a particular compiler cannot optimize them (such as in the debug generation case), the original macros are optionally available. Note that some invocations of the return_VALUE macro may now cause size mismatch warnings; the return_UINT8 and return_UINT32 macros are provided to eliminate these. (From Randy Dunlap) Implemented a new mechanism to enable debug tracing for individual control methods. A new external interface, acpi_debug_trace(), is provided to enable this mechanism. The intent is to allow the host OS to easily enable and disable tracing for problematic control methods. This interface can be easily exposed to a user or debugger interface if desired. See the file psxface.c for details. acpi_ut_callocate() will now return a valid pointer if a length of zero is specified - a length of one is used and a warning is issued. This matches the behavior of acpi_ut_allocate(). Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/resources/rsaddr.c')
-rw-r--r--drivers/acpi/resources/rsaddr.c1132
1 files changed, 376 insertions, 756 deletions
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c
index 798778261fb9..6f48ebf3304e 100644
--- a/drivers/acpi/resources/rsaddr.c
+++ b/drivers/acpi/resources/rsaddr.c
@@ -58,12 +58,20 @@ acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags);
static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource);
+static void
+acpi_rs_set_address_common(union aml_resource *aml,
+ struct acpi_resource *resource);
+
+static u8
+acpi_rs_get_address_common(struct acpi_resource *resource,
+ union aml_resource *aml);
+
/*******************************************************************************
*
* FUNCTION: acpi_rs_decode_general_flags
*
* PARAMETERS: Resource - Address resource data struct
- * Flags - Actual flag byte
+ * Flags - Raw AML flag byte
*
* RETURN: Decoded flag bits in resource struct
*
@@ -107,27 +115,19 @@ acpi_rs_decode_general_flags(union acpi_resource_data *resource, u8 flags)
static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource)
{
- u8 flags;
-
ACPI_FUNCTION_ENTRY();
- /* Producer / Consumer - flag bit[0] */
-
- flags = (u8) (resource->address.producer_consumer & 0x01);
-
- /* Decode (_DEC) - flag bit[1] */
-
- flags |= (u8) ((resource->address.decode & 0x01) << 1);
-
- /* Min Address Fixed (_MIF) - flag bit[2] */
-
- flags |= (u8) ((resource->address.min_address_fixed & 0x01) << 2);
-
- /* Max Address Fixed (_MAF) - flag bit[3] */
-
- flags |= (u8) ((resource->address.max_address_fixed & 0x01) << 3);
-
- return (flags);
+ return ((u8)
+
+ /* Producer / Consumer - flag bit[0] */
+ ((resource->address.producer_consumer & 0x01) |
+ /* Decode (_DEC) - flag bit[1] */
+ ((resource->address.decode & 0x01) << 1) |
+ /* Min Address Fixed (_MIF) - flag bit[2] */
+ ((resource->address.min_address_fixed & 0x01) << 2) |
+ /* Max Address Fixed (_MAF) - flag bit[3] */
+ ((resource->address.max_address_fixed & 0x01) << 3))
+ );
}
/*******************************************************************************
@@ -135,7 +135,7 @@ static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource)
* FUNCTION: acpi_rs_decode_specific_flags
*
* PARAMETERS: Resource - Address resource data struct
- * Flags - Actual flag byte
+ * Flags - Raw AML flag byte
*
* RETURN: Decoded flag bits in attribute struct
*
@@ -189,921 +189,541 @@ acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags)
static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource)
{
- u8 flags = 0;
-
ACPI_FUNCTION_ENTRY();
if (resource->address.resource_type == ACPI_MEMORY_RANGE) {
- /* Write Status (_RW) - flag bit[0] */
-
- flags = (u8)
- (resource->address.attribute.memory.
- read_write_attribute & 0x01);
-
- /* Memory Attributes (_MEM) - flag bits[2:1] */
-
- flags |= (u8)
- ((resource->address.attribute.memory.
- cache_attribute & 0x03) << 1);
+ return ((u8)
+
+ /* Write Status (_RW) - flag bit[0] */
+ ((resource->address.attribute.memory.
+ read_write_attribute & 0x01) |
+ /* Memory Attributes (_MEM) - flag bits[2:1] */
+ ((resource->address.attribute.memory.
+ cache_attribute & 0x03) << 1)));
} else if (resource->address.resource_type == ACPI_IO_RANGE) {
- /* Ranges (_RNG) - flag bits[1:0] */
-
- flags = (u8)
- (resource->address.attribute.io.range_attribute & 0x03);
-
- /* Translations (_TTP and _TRS) - flag bits[5:4] */
-
- flags |= (u8)
- ((resource->address.attribute.io.
- translation_attribute & 0x03) << 4);
+ return ((u8)
+
+ /* Ranges (_RNG) - flag bits[1:0] */
+ ((resource->address.attribute.io.
+ range_attribute & 0x03) |
+ /* Translations (_TTP and _TRS) - flag bits[5:4] */
+ ((resource->address.attribute.io.
+ translation_attribute & 0x03) << 4)));
}
- return (flags);
+ return (0);
}
/*******************************************************************************
*
- * FUNCTION: acpi_rs_address16_resource
+ * FUNCTION: acpi_rs_set_address_common
*
- * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
- * stream
- * bytes_consumed - Pointer to where the number of bytes
- * consumed the byte_stream_buffer is
- * returned
- * output_buffer - Pointer to the return data buffer
- * structure_size - Pointer to where the number of bytes
- * in the return data struct is returned
+ * PARAMETERS: Aml - Pointer to the AML resource descriptor
+ * Resource - Pointer to the internal resource struct
*
- * RETURN: Status
+ * RETURN: None
*
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- * structure pointed to by the output_buffer. Return the
- * number of bytes consumed from the byte stream.
+ * DESCRIPTION: Convert common flag fields from a resource descriptor to an
+ * AML descriptor
*
******************************************************************************/
-acpi_status
-acpi_rs_address16_resource(u8 * byte_stream_buffer,
- acpi_size * bytes_consumed,
- u8 ** output_buffer, acpi_size * structure_size)
+static void
+acpi_rs_set_address_common(union aml_resource *aml,
+ struct acpi_resource *resource)
{
- u32 index;
- u16 temp16;
- u8 temp8;
- u8 *temp_ptr;
- u8 *buffer = byte_stream_buffer;
- struct acpi_resource *output_struct = (void *)*output_buffer;
- acpi_size struct_size =
- ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16);
+ ACPI_FUNCTION_ENTRY();
- ACPI_FUNCTION_TRACE("rs_address16_resource");
+ /* Set the Resource Type (Memory, Io, bus_number, etc.) */
- /* Get the Descriptor Length field */
+ aml->address.resource_type = (u8) resource->data.address.resource_type;
- buffer += 1;
- ACPI_MOVE_16_TO_16(&temp16, buffer);
+ /* Set the general flags */
- /* Validate minimum descriptor length */
+ aml->address.flags = acpi_rs_encode_general_flags(&resource->data);
- if (temp16 < 13) {
- return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
- }
+ /* Set the type-specific flags */
- *bytes_consumed = temp16 + 3;
- output_struct->type = ACPI_RSTYPE_ADDRESS16;
+ aml->address.specific_flags =
+ acpi_rs_encode_specific_flags(&resource->data);
+}
- /* Get the Resource Type (Byte3) */
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_rs_get_address_common
+ *
+ * PARAMETERS: Resource - Pointer to the internal resource struct
+ * Aml - Pointer to the AML resource descriptor
+ *
+ * RETURN: TRUE if the resource_type field is OK, FALSE otherwise
+ *
+ * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor
+ * to an internal resource descriptor
+ *
+ ******************************************************************************/
- buffer += 2;
- temp8 = *buffer;
+static u8
+acpi_rs_get_address_common(struct acpi_resource *resource,
+ union aml_resource *aml)
+{
+ ACPI_FUNCTION_ENTRY();
- /* Values 0-2 and 0xC0-0xFF are valid */
+ /* Validate resource type */
- if ((temp8 > 2) && (temp8 < 0xC0)) {
- return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
+ if ((aml->address.resource_type > 2)
+ && (aml->address.resource_type < 0xC0)) {
+ return (FALSE);
}
- output_struct->data.address16.resource_type = temp8;
-
- /* Get the General Flags (Byte4) */
-
- buffer += 1;
- acpi_rs_decode_general_flags(&output_struct->data, *buffer);
-
- /* Get the Type Specific Flags (Byte5) */
-
- buffer += 1;
- acpi_rs_decode_specific_flags(&output_struct->data, *buffer);
-
- /* Get Granularity (Bytes 6-7) */
-
- buffer += 1;
- ACPI_MOVE_16_TO_32(&output_struct->data.address16.granularity, buffer);
+ /* Get the Resource Type (Memory, Io, bus_number, etc.) */
- /* Get min_address_range (Bytes 8-9) */
+ resource->data.address.resource_type = aml->address.resource_type;
- buffer += 2;
- ACPI_MOVE_16_TO_32(&output_struct->data.address16.min_address_range,
- buffer);
+ /* Get the General Flags */
- /* Get max_address_range (Bytes 10-11) */
+ acpi_rs_decode_general_flags(&resource->data, aml->address.flags);
- buffer += 2;
- ACPI_MOVE_16_TO_32(&output_struct->data.address16.max_address_range,
- buffer);
+ /* Get the Type-Specific Flags */
- /* Get address_translation_offset (Bytes 12-13) */
-
- buffer += 2;
- ACPI_MOVE_16_TO_32(&output_struct->data.address16.
- address_translation_offset, buffer);
+ acpi_rs_decode_specific_flags(&resource->data,
+ aml->address.specific_flags);
+ return (TRUE);
+}
- /* Get address_length (Bytes 14-15) */
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_rs_get_address16
+ *
+ * PARAMETERS: Aml - Pointer to the AML resource descriptor
+ * aml_resource_length - Length of the resource from the AML header
+ * Resource - Where the internal resource is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding
+ * internal resource descriptor, simplifying bitflags and handling
+ * alignment and endian issues if necessary.
+ *
+ ******************************************************************************/
- buffer += 2;
- ACPI_MOVE_16_TO_32(&output_struct->data.address16.address_length,
- buffer);
+acpi_status
+acpi_rs_get_address16(union aml_resource * aml,
+ u16 aml_resource_length, struct acpi_resource * resource)
+{
+ ACPI_FUNCTION_TRACE("rs_get_address16");
- /* Resource Source Index (if present) */
+ /* Get the Resource Type, general flags, and type-specific flags */
- buffer += 2;
+ if (!acpi_rs_get_address_common(resource, aml)) {
+ return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
+ }
/*
- * This will leave us pointing to the Resource Source Index
- * If it is present, then save it off and calculate the
- * pointer to where the null terminated string goes:
- * Each Interrupt takes 32-bits + the 5 bytes of the
- * stream that are default.
- *
- * Note: Some resource descriptors will have an additional null, so
- * we add 1 to the length.
+ * Get the following contiguous fields from the AML descriptor:
+ * Address Granularity
+ * Address Range Minimum
+ * Address Range Maximum
+ * Address Translation Offset
+ * Address Length
*/
- if (*bytes_consumed > (16 + 1)) {
- /* Dereference the Index */
-
- output_struct->data.address16.resource_source.index =
- (u32) * buffer;
-
- /* Point to the String */
+ acpi_rs_move_data(&resource->data.address16.granularity,
+ &aml->address16.granularity, 5,
+ ACPI_MOVE_TYPE_16_TO_32);
- buffer += 1;
+ /* Get the optional resource_source (index and string) */
- /* Point the String pointer to the end of this structure */
+ resource->length =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16) +
+ acpi_rs_get_resource_source(aml_resource_length,
+ sizeof(struct aml_resource_address16),
+ &resource->data.address16.
+ resource_source, aml, NULL);
- output_struct->data.address16.resource_source.string_ptr =
- (char *)((u8 *) output_struct + struct_size);
+ /* Complete the resource header */
- temp_ptr = (u8 *)
- output_struct->data.address16.resource_source.string_ptr;
-
- /* Copy the resource_source string into the buffer */
-
- index = 0;
- while (*buffer) {
- *temp_ptr = *buffer;
-
- temp_ptr++;
- buffer++;
- index++;
- }
-
- /* Add the terminating null and set the string length */
-
- *temp_ptr = 0;
- output_struct->data.address16.resource_source.string_length =
- index + 1;
-
- /*
- * In order for the struct_size to fall on a 32-bit boundary,
- * calculate the length of the string and expand the
- * struct_size to the next 32-bit boundary.
- */
- temp8 = (u8) (index + 1);
- struct_size += ACPI_ROUND_UP_to_32_bITS(temp8);
- } else {
- output_struct->data.address16.resource_source.index = 0;
- output_struct->data.address16.resource_source.string_length = 0;
- output_struct->data.address16.resource_source.string_ptr = NULL;
- }
-
- /* Set the Length parameter */
-
- output_struct->length = (u32) struct_size;
-
- /* Return the final size of the structure */
-
- *structure_size = struct_size;
+ resource->type = ACPI_RESOURCE_TYPE_ADDRESS16;
return_ACPI_STATUS(AE_OK);
}
/*******************************************************************************
*
- * FUNCTION: acpi_rs_address16_stream
+ * FUNCTION: acpi_rs_set_address16
*
- * PARAMETERS: Resource - Pointer to the resource linked list
- * output_buffer - Pointer to the user's return buffer
- * bytes_consumed - Pointer to where the number of bytes
- * used in the output_buffer is returned
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Aml - Where the AML descriptor is returned
*
* RETURN: Status
*
- * DESCRIPTION: Take the linked list resource structure and fills in the
- * the appropriate bytes in a byte stream
+ * DESCRIPTION: Convert an internal resource descriptor to the corresponding
+ * external AML resource descriptor.
*
******************************************************************************/
acpi_status
-acpi_rs_address16_stream(struct acpi_resource *resource,
- u8 ** output_buffer, acpi_size * bytes_consumed)
+acpi_rs_set_address16(struct acpi_resource *resource, union aml_resource *aml)
{
- u8 *buffer = *output_buffer;
- u8 *length_field;
- acpi_size actual_bytes;
-
- ACPI_FUNCTION_TRACE("rs_address16_stream");
-
- /* Set the Descriptor Type field */
+ acpi_size descriptor_length;
- *buffer = ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE;
- buffer += 1;
+ ACPI_FUNCTION_TRACE("rs_set_address16");
- /* Save a pointer to the Length field - to be filled in later */
+ /* Set the Resource Type, General Flags, and Type-Specific Flags */
- length_field = buffer;
- buffer += 2;
-
- /* Set the Resource Type (Memory, Io, bus_number) */
-
- *buffer = (u8) (resource->data.address16.resource_type & 0x03);
- buffer += 1;
-
- /* Set the general flags */
+ acpi_rs_set_address_common(aml, resource);
- *buffer = acpi_rs_encode_general_flags(&resource->data);
- buffer += 1;
-
- /* Set the type specific flags */
-
- *buffer = acpi_rs_encode_specific_flags(&resource->data);
- buffer += 1;
-
- /* Set the address space granularity */
-
- ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.granularity);
- buffer += 2;
-
- /* Set the address range minimum */
-
- ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.min_address_range);
- buffer += 2;
-
- /* Set the address range maximum */
-
- ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.max_address_range);
- buffer += 2;
-
- /* Set the address translation offset */
-
- ACPI_MOVE_32_TO_16(buffer,
- &resource->data.address16.
- address_translation_offset);
- buffer += 2;
-
- /* Set the address length */
-
- ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.address_length);
- buffer += 2;
+ /*
+ * Set the following contiguous fields in the AML descriptor:
+ * Address Granularity
+ * Address Range Minimum
+ * Address Range Maximum
+ * Address Translation Offset
+ * Address Length
+ */
+ acpi_rs_move_data(&aml->address16.granularity,
+ &resource->data.address16.granularity, 5,
+ ACPI_MOVE_TYPE_32_TO_16);
/* Resource Source Index and Resource Source are optional */
- if (resource->data.address16.resource_source.string_length) {
- *buffer = (u8) resource->data.address16.resource_source.index;
- buffer += 1;
+ descriptor_length = acpi_rs_set_resource_source(aml,
+ sizeof(struct
+ aml_resource_address16),
+ &resource->data.
+ address16.
+ resource_source);
- /* Copy the resource_source string */
+ /* Complete the AML descriptor header */
- ACPI_STRCPY((char *)buffer,
- resource->data.address16.resource_source.
- string_ptr);
-
- /*
- * Buffer needs to be set to the length of the string + one for the
- * terminating null
- */
- buffer +=
- (acpi_size) (ACPI_STRLEN
- (resource->data.address16.resource_source.
- string_ptr) + 1);
- }
-
- /* Return the number of bytes consumed in this operation */
-
- actual_bytes = ACPI_PTR_DIFF(buffer, *output_buffer);
- *bytes_consumed = actual_bytes;
-
- /*
- * Set the length field to the number of bytes consumed
- * minus the header size (3 bytes)
- */
- actual_bytes -= 3;
- ACPI_MOVE_SIZE_TO_16(length_field, &actual_bytes);
+ acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS16,
+ descriptor_length, aml);
return_ACPI_STATUS(AE_OK);
}
/*******************************************************************************
*
- * FUNCTION: acpi_rs_address32_resource
+ * FUNCTION: acpi_rs_get_address32
*
- * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
- * stream
- * bytes_consumed - Pointer to where the number of bytes
- * consumed the byte_stream_buffer is
- * returned
- * output_buffer - Pointer to the return data buffer
- * structure_size - Pointer to where the number of bytes
- * in the return data struct is returned
+ * PARAMETERS: Aml - Pointer to the AML resource descriptor
+ * aml_resource_length - Length of the resource from the AML header
+ * Resource - Where the internal resource is returned
*
* RETURN: Status
*
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- * structure pointed to by the output_buffer. Return the
- * number of bytes consumed from the byte stream.
+ * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding
+ * internal resource descriptor, simplifying bitflags and handling
+ * alignment and endian issues if necessary.
*
******************************************************************************/
acpi_status
-acpi_rs_address32_resource(u8 * byte_stream_buffer,
- acpi_size * bytes_consumed,
- u8 ** output_buffer, acpi_size * structure_size)
+acpi_rs_get_address32(union aml_resource *aml,
+ u16 aml_resource_length, struct acpi_resource *resource)
{
- u16 temp16;
- u8 temp8;
- u8 *temp_ptr;
- u32 index;
- u8 *buffer = byte_stream_buffer;
- struct acpi_resource *output_struct = (void *)*output_buffer;
- acpi_size struct_size =
- ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32);
-
- ACPI_FUNCTION_TRACE("rs_address32_resource");
-
- /* Get the Descriptor Length field */
-
- buffer += 1;
- ACPI_MOVE_16_TO_16(&temp16, buffer);
- /* Validate minimum descriptor length */
+ ACPI_FUNCTION_TRACE("rs_get_address32");
- if (temp16 < 23) {
- return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
- }
-
- *bytes_consumed = temp16 + 3;
- output_struct->type = ACPI_RSTYPE_ADDRESS32;
-
- /* Get the Resource Type (Byte3) */
-
- buffer += 2;
- temp8 = *buffer;
+ /* Get the Resource Type, general flags, and type-specific flags */
- /* Values 0-2 and 0xC0-0xFF are valid */
-
- if ((temp8 > 2) && (temp8 < 0xC0)) {
+ if (!acpi_rs_get_address_common(resource, (void *)aml)) {
return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
}
- output_struct->data.address32.resource_type = temp8;
-
- /* Get the General Flags (Byte4) */
-
- buffer += 1;
- acpi_rs_decode_general_flags(&output_struct->data, *buffer);
-
- /* Get the Type Specific Flags (Byte5) */
-
- buffer += 1;
- acpi_rs_decode_specific_flags(&output_struct->data, *buffer);
-
- /* Get Granularity (Bytes 6-9) */
-
- buffer += 1;
- ACPI_MOVE_32_TO_32(&output_struct->data.address32.granularity, buffer);
-
- /* Get min_address_range (Bytes 10-13) */
-
- buffer += 4;
- ACPI_MOVE_32_TO_32(&output_struct->data.address32.min_address_range,
- buffer);
-
- /* Get max_address_range (Bytes 14-17) */
-
- buffer += 4;
- ACPI_MOVE_32_TO_32(&output_struct->data.address32.max_address_range,
- buffer);
-
- /* Get address_translation_offset (Bytes 18-21) */
-
- buffer += 4;
- ACPI_MOVE_32_TO_32(&output_struct->data.address32.
- address_translation_offset, buffer);
-
- /* Get address_length (Bytes 22-25) */
-
- buffer += 4;
- ACPI_MOVE_32_TO_32(&output_struct->data.address32.address_length,
- buffer);
-
- /* Resource Source Index (if present) */
-
- buffer += 4;
-
/*
- * This will leave us pointing to the Resource Source Index
- * If it is present, then save it off and calculate the
- * pointer to where the null terminated string goes:
- *
- * Note: Some resource descriptors will have an additional null, so
- * we add 1 to the length.
+ * Get the following contiguous fields from the AML descriptor:
+ * Address Granularity
+ * Address Range Minimum
+ * Address Range Maximum
+ * Address Translation Offset
+ * Address Length
*/
- if (*bytes_consumed > (26 + 1)) {
- /* Dereference the Index */
-
- output_struct->data.address32.resource_source.index =
- (u32) * buffer;
-
- /* Point to the String */
+ acpi_rs_move_data(&resource->data.address32.granularity,
+ &aml->address32.granularity, 5,
+ ACPI_MOVE_TYPE_32_TO_32);
- buffer += 1;
+ /* Get the optional resource_source (index and string) */
- /* Point the String pointer to the end of this structure */
+ resource->length =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32) +
+ acpi_rs_get_resource_source(aml_resource_length,
+ sizeof(struct aml_resource_address32),
+ &resource->data.address32.
+ resource_source, aml, NULL);
- output_struct->data.address32.resource_source.string_ptr =
- (char *)((u8 *) output_struct + struct_size);
+ /* Complete the resource header */
- temp_ptr = (u8 *)
- output_struct->data.address32.resource_source.string_ptr;
-
- /* Copy the resource_source string into the buffer */
-
- index = 0;
- while (*buffer) {
- *temp_ptr = *buffer;
-
- temp_ptr++;
- buffer++;
- index++;
- }
-
- /* Add the terminating null and set the string length */
-
- *temp_ptr = 0;
- output_struct->data.address32.resource_source.string_length =
- index + 1;
-
- /*
- * In order for the struct_size to fall on a 32-bit boundary,
- * calculate the length of the string and expand the
- * struct_size to the next 32-bit boundary.
- */
- temp8 = (u8) (index + 1);
- struct_size += ACPI_ROUND_UP_to_32_bITS(temp8);
- } else {
- output_struct->data.address32.resource_source.index = 0;
- output_struct->data.address32.resource_source.string_length = 0;
- output_struct->data.address32.resource_source.string_ptr = NULL;
- }
-
- /* Set the Length parameter */
-
- output_struct->length = (u32) struct_size;
-
- /* Return the final size of the structure */
-
- *structure_size = struct_size;
+ resource->type = ACPI_RESOURCE_TYPE_ADDRESS32;
return_ACPI_STATUS(AE_OK);
}
/*******************************************************************************
*
- * FUNCTION: acpi_rs_address32_stream
+ * FUNCTION: acpi_rs_set_address32
*
- * PARAMETERS: Resource - Pointer to the resource linked list
- * output_buffer - Pointer to the user's return buffer
- * bytes_consumed - Pointer to where the number of bytes
- * used in the output_buffer is returned
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Aml - Where the AML descriptor is returned
*
* RETURN: Status
*
- * DESCRIPTION: Take the linked list resource structure and fills in the
- * the appropriate bytes in a byte stream
+ * DESCRIPTION: Convert an internal resource descriptor to the corresponding
+ * external AML resource descriptor.
*
******************************************************************************/
acpi_status
-acpi_rs_address32_stream(struct acpi_resource *resource,
- u8 ** output_buffer, acpi_size * bytes_consumed)
+acpi_rs_set_address32(struct acpi_resource *resource, union aml_resource *aml)
{
- u8 *buffer;
- u16 *length_field;
-
- ACPI_FUNCTION_TRACE("rs_address32_stream");
-
- buffer = *output_buffer;
+ acpi_size descriptor_length;
- /* Set the Descriptor Type field */
+ ACPI_FUNCTION_TRACE("rs_set_address32");
- *buffer = ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE;
- buffer += 1;
+ /* Set the Resource Type, General Flags, and Type-Specific Flags */
- /* Save a pointer to the Length field - to be filled in later */
+ acpi_rs_set_address_common(aml, resource);
- length_field = ACPI_CAST_PTR(u16, buffer);
- buffer += 2;
-
- /* Set the Resource Type (Memory, Io, bus_number) */
-
- *buffer = (u8) (resource->data.address32.resource_type & 0x03);
- buffer += 1;
-
- /* Set the general flags */
-
- *buffer = acpi_rs_encode_general_flags(&resource->data);
- buffer += 1;
-
- /* Set the type specific flags */
-
- *buffer = acpi_rs_encode_specific_flags(&resource->data);
- buffer += 1;
-
- /* Set the address space granularity */
-
- ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.granularity);
- buffer += 4;
-
- /* Set the address range minimum */
-
- ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.min_address_range);
- buffer += 4;
-
- /* Set the address range maximum */
-
- ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.max_address_range);
- buffer += 4;
-
- /* Set the address translation offset */
-
- ACPI_MOVE_32_TO_32(buffer,
- &resource->data.address32.
- address_translation_offset);
- buffer += 4;
-
- /* Set the address length */
-
- ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.address_length);
- buffer += 4;
+ /*
+ * Set the following contiguous fields in the AML descriptor:
+ * Address Granularity
+ * Address Range Minimum
+ * Address Range Maximum
+ * Address Translation Offset
+ * Address Length
+ */
+ acpi_rs_move_data(&aml->address32.granularity,
+ &resource->data.address32.granularity, 5,
+ ACPI_MOVE_TYPE_32_TO_32);
/* Resource Source Index and Resource Source are optional */
- if (resource->data.address32.resource_source.string_length) {
- *buffer = (u8) resource->data.address32.resource_source.index;
- buffer += 1;
-
- /* Copy the resource_source string */
+ descriptor_length = acpi_rs_set_resource_source(aml,
+ sizeof(struct
+ aml_resource_address32),
+ &resource->data.
+ address32.
+ resource_source);
- ACPI_STRCPY((char *)buffer,
- resource->data.address32.resource_source.
- string_ptr);
+ /* Complete the AML descriptor header */
- /*
- * Buffer needs to be set to the length of the string + one for the
- * terminating null
- */
- buffer +=
- (acpi_size) (ACPI_STRLEN
- (resource->data.address32.resource_source.
- string_ptr) + 1);
- }
-
- /* Return the number of bytes consumed in this operation */
-
- *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
-
- /*
- * Set the length field to the number of bytes consumed
- * minus the header size (3 bytes)
- */
- *length_field = (u16) (*bytes_consumed - 3);
+ acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS32,
+ descriptor_length, aml);
return_ACPI_STATUS(AE_OK);
}
/*******************************************************************************
*
- * FUNCTION: acpi_rs_address64_resource
+ * FUNCTION: acpi_rs_get_address64
*
- * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
- * stream
- * bytes_consumed - Pointer to where the number of bytes
- * consumed the byte_stream_buffer is
- * returned
- * output_buffer - Pointer to the return data buffer
- * structure_size - Pointer to where the number of bytes
- * in the return data struct is returned
+ * PARAMETERS: Aml - Pointer to the AML resource descriptor
+ * aml_resource_length - Length of the resource from the AML header
+ * Resource - Where the internal resource is returned
*
* RETURN: Status
*
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- * structure pointed to by the output_buffer. Return the
- * number of bytes consumed from the byte stream.
+ * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding
+ * internal resource descriptor, simplifying bitflags and handling
+ * alignment and endian issues if necessary.
*
******************************************************************************/
acpi_status
-acpi_rs_address64_resource(u8 * byte_stream_buffer,
- acpi_size * bytes_consumed,
- u8 ** output_buffer, acpi_size * structure_size)
+acpi_rs_get_address64(union aml_resource *aml,
+ u16 aml_resource_length, struct acpi_resource *resource)
{
- u16 temp16;
- u8 temp8;
- u8 resource_type;
- u8 *temp_ptr;
- u32 index;
- u8 *buffer = byte_stream_buffer;
- struct acpi_resource *output_struct = (void *)*output_buffer;
- acpi_size struct_size =
- ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64);
-
- ACPI_FUNCTION_TRACE("rs_address64_resource");
-
- /* Get the Descriptor Type */
-
- resource_type = *buffer;
-
- /* Get the Descriptor Length field */
-
- buffer += 1;
- ACPI_MOVE_16_TO_16(&temp16, buffer);
-
- /* Validate minimum descriptor length */
-
- if (temp16 < 43) {
- return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
- }
-
- *bytes_consumed = temp16 + 3;
- output_struct->type = ACPI_RSTYPE_ADDRESS64;
-
- /* Get the Resource Type (Byte3) */
+ ACPI_FUNCTION_TRACE("rs_get_address64");
- buffer += 2;
- temp8 = *buffer;
+ /* Get the Resource Type, general Flags, and type-specific Flags */
- /* Values 0-2 and 0xC0-0xFF are valid */
-
- if ((temp8 > 2) && (temp8 < 0xC0)) {
+ if (!acpi_rs_get_address_common(resource, aml)) {
return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
}
- output_struct->data.address64.resource_type = temp8;
-
- /* Get the General Flags (Byte4) */
-
- buffer += 1;
- acpi_rs_decode_general_flags(&output_struct->data, *buffer);
-
- /* Get the Type Specific Flags (Byte5) */
-
- buffer += 1;
- acpi_rs_decode_specific_flags(&output_struct->data, *buffer);
-
- if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) {
- /* Move past revision_id and Reserved byte */
-
- buffer += 2;
- }
-
- /* Get Granularity (Bytes 6-13) or (Bytes 8-15) */
-
- buffer += 1;
- ACPI_MOVE_64_TO_64(&output_struct->data.address64.granularity, buffer);
-
- /* Get min_address_range (Bytes 14-21) or (Bytes 16-23) */
-
- buffer += 8;
- ACPI_MOVE_64_TO_64(&output_struct->data.address64.min_address_range,
- buffer);
-
- /* Get max_address_range (Bytes 22-29) or (Bytes 24-31) */
-
- buffer += 8;
- ACPI_MOVE_64_TO_64(&output_struct->data.address64.max_address_range,
- buffer);
-
- /* Get address_translation_offset (Bytes 30-37) or (Bytes 32-39) */
-
- buffer += 8;
- ACPI_MOVE_64_TO_64(&output_struct->data.address64.
- address_translation_offset, buffer);
+ /*
+ * Get the following contiguous fields from the AML descriptor:
+ * Address Granularity
+ * Address Range Minimum
+ * Address Range Maximum
+ * Address Translation Offset
+ * Address Length
+ */
+ acpi_rs_move_data(&resource->data.address64.granularity,
+ &aml->address64.granularity, 5,
+ ACPI_MOVE_TYPE_64_TO_64);
- /* Get address_length (Bytes 38-45) or (Bytes 40-47) */
+ /* Get the optional resource_source (index and string) */
- buffer += 8;
- ACPI_MOVE_64_TO_64(&output_struct->data.address64.address_length,
- buffer);
+ resource->length =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64) +
+ acpi_rs_get_resource_source(aml_resource_length,
+ sizeof(struct aml_resource_address64),
+ &resource->data.address64.
+ resource_source, aml, NULL);
- output_struct->data.address64.resource_source.index = 0;
- output_struct->data.address64.resource_source.string_length = 0;
- output_struct->data.address64.resource_source.string_ptr = NULL;
+ /* Complete the resource header */
- if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) {
- /* Get type_specific_attribute (Bytes 48-55) */
+ resource->type = ACPI_RESOURCE_TYPE_ADDRESS64;
+ return_ACPI_STATUS(AE_OK);
+}
- buffer += 8;
- ACPI_MOVE_64_TO_64(&output_struct->data.address64.
- type_specific_attributes, buffer);
- } else {
- output_struct->data.address64.type_specific_attributes = 0;
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_rs_set_address64
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Aml - Where the AML descriptor is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert an internal resource descriptor to the corresponding
+ * external AML resource descriptor.
+ *
+ ******************************************************************************/
- /* Resource Source Index (if present) */
+acpi_status
+acpi_rs_set_address64(struct acpi_resource *resource, union aml_resource *aml)
+{
+ acpi_size descriptor_length;
- buffer += 8;
+ ACPI_FUNCTION_TRACE("rs_set_address64");
- /*
- * This will leave us pointing to the Resource Source Index
- * If it is present, then save it off and calculate the
- * pointer to where the null terminated string goes:
- * Each Interrupt takes 32-bits + the 5 bytes of the
- * stream that are default.
- *
- * Note: Some resource descriptors will have an additional null, so
- * we add 1 to the length.
- */
- if (*bytes_consumed > (46 + 1)) {
- /* Dereference the Index */
+ /* Set the Resource Type, General Flags, and Type-Specific Flags */
- output_struct->data.address64.resource_source.index =
- (u32) * buffer;
+ acpi_rs_set_address_common(aml, resource);
- /* Point to the String */
+ /*
+ * Set the following contiguous fields in the AML descriptor:
+ * Address Granularity
+ * Address Range Minimum
+ * Address Range Maximum
+ * Address Translation Offset
+ * Address Length
+ */
+ acpi_rs_move_data(&aml->address64.granularity,
+ &resource->data.address64.granularity, 5,
+ ACPI_MOVE_TYPE_64_TO_64);
- buffer += 1;
+ /* Resource Source Index and Resource Source are optional */
- /* Point the String pointer to the end of this structure */
+ descriptor_length = acpi_rs_set_resource_source(aml,
+ sizeof(struct
+ aml_resource_address64),
+ &resource->data.
+ address64.
+ resource_source);
- output_struct->data.address64.resource_source.
- string_ptr =
- (char *)((u8 *) output_struct + struct_size);
+ /* Complete the AML descriptor header */
- temp_ptr = (u8 *)
- output_struct->data.address64.resource_source.
- string_ptr;
+ acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS64,
+ descriptor_length, aml);
+ return_ACPI_STATUS(AE_OK);
+}
- /* Copy the resource_source string into the buffer */
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_rs_get_ext_address64
+ *
+ * PARAMETERS: Aml - Pointer to the AML resource descriptor
+ * aml_resource_length - Length of the resource from the AML header
+ * Resource - Where the internal resource is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding
+ * internal resource descriptor, simplifying bitflags and handling
+ * alignment and endian issues if necessary.
+ *
+ ******************************************************************************/
- index = 0;
- while (*buffer) {
- *temp_ptr = *buffer;
+acpi_status
+acpi_rs_get_ext_address64(union aml_resource *aml,
+ u16 aml_resource_length,
+ struct acpi_resource *resource)
+{
- temp_ptr++;
- buffer++;
- index++;
- }
+ ACPI_FUNCTION_TRACE("rs_get_ext_address64");
- /*
- * Add the terminating null and set the string length
- */
- *temp_ptr = 0;
- output_struct->data.address64.resource_source.
- string_length = index + 1;
+ /* Get the Resource Type, general flags, and type-specific flags */
- /*
- * In order for the struct_size to fall on a 32-bit boundary,
- * calculate the length of the string and expand the
- * struct_size to the next 32-bit boundary.
- */
- temp8 = (u8) (index + 1);
- struct_size += ACPI_ROUND_UP_to_32_bITS(temp8);
- }
+ if (!acpi_rs_get_address_common(resource, aml)) {
+ return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
}
- /* Set the Length parameter */
+ /*
+ * Get and validate the Revision ID
+ * Note: Only one revision ID is currently supported
+ */
+ resource->data.ext_address64.revision_iD =
+ aml->ext_address64.revision_iD;
+ if (aml->ext_address64.revision_iD !=
+ AML_RESOURCE_EXTENDED_ADDRESS_REVISION) {
+ return_ACPI_STATUS(AE_SUPPORT);
+ }
- output_struct->length = (u32) struct_size;
+ /*
+ * Get the following contiguous fields from the AML descriptor:
+ * Address Granularity
+ * Address Range Minimum
+ * Address Range Maximum
+ * Address Translation Offset
+ * Address Length
+ * Type-Specific Attribute
+ */
+ acpi_rs_move_data(&resource->data.ext_address64.granularity,
+ &aml->ext_address64.granularity, 6,
+ ACPI_MOVE_TYPE_64_TO_64);
- /* Return the final size of the structure */
+ /* Complete the resource header */
- *structure_size = struct_size;
+ resource->type = ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64;
+ resource->length =
+ ACPI_SIZEOF_RESOURCE(struct acpi_resource_extended_address64);
return_ACPI_STATUS(AE_OK);
}
/*******************************************************************************
*
- * FUNCTION: acpi_rs_address64_stream
+ * FUNCTION: acpi_rs_set_ext_address64
*
- * PARAMETERS: Resource - Pointer to the resource linked list
- * output_buffer - Pointer to the user's return buffer
- * bytes_consumed - Pointer to where the number of bytes
- * used in the output_buffer is returned
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Aml - Where the AML descriptor is returned
*
* RETURN: Status
*
- * DESCRIPTION: Take the linked list resource structure and fills in the
- * the appropriate bytes in a byte stream
+ * DESCRIPTION: Convert an internal resource descriptor to the corresponding
+ * external AML resource descriptor.
*
******************************************************************************/
acpi_status
-acpi_rs_address64_stream(struct acpi_resource *resource,
- u8 ** output_buffer, acpi_size * bytes_consumed)
+acpi_rs_set_ext_address64(struct acpi_resource *resource,
+ union aml_resource *aml)
{
- u8 *buffer;
- u16 *length_field;
-
- ACPI_FUNCTION_TRACE("rs_address64_stream");
-
- buffer = *output_buffer;
-
- /* Set the Descriptor Type field */
-
- *buffer = ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE;
- buffer += 1;
-
- /* Save a pointer to the Length field - to be filled in later */
-
- length_field = ACPI_CAST_PTR(u16, buffer);
- buffer += 2;
-
- /* Set the Resource Type (Memory, Io, bus_number) */
-
- *buffer = (u8) (resource->data.address64.resource_type & 0x03);
- buffer += 1;
-
- /* Set the general flags */
-
- *buffer = acpi_rs_encode_general_flags(&resource->data);
- buffer += 1;
-
- /* Set the type specific flags */
-
- *buffer = acpi_rs_encode_specific_flags(&resource->data);
- buffer += 1;
-
- /* Set the address space granularity */
+ ACPI_FUNCTION_TRACE("rs_set_ext_address64");
- ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.granularity);
- buffer += 8;
+ /* Set the Resource Type, General Flags, and Type-Specific Flags */
- /* Set the address range minimum */
+ acpi_rs_set_address_common(aml, resource);
- ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.min_address_range);
- buffer += 8;
+ /* Only one Revision ID is currently supported */
- /* Set the address range maximum */
-
- ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.max_address_range);
- buffer += 8;
-
- /* Set the address translation offset */
-
- ACPI_MOVE_64_TO_64(buffer,
- &resource->data.address64.
- address_translation_offset);
- buffer += 8;
-
- /* Set the address length */
-
- ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.address_length);
- buffer += 8;
-
- /* Resource Source Index and Resource Source are optional */
-
- if (resource->data.address64.resource_source.string_length) {
- *buffer = (u8) resource->data.address64.resource_source.index;
- buffer += 1;
-
- /* Copy the resource_source string */
-
- ACPI_STRCPY((char *)buffer,
- resource->data.address64.resource_source.
- string_ptr);
-
- /*
- * Buffer needs to be set to the length of the string + one for the
- * terminating null
- */
- buffer +=
- (acpi_size) (ACPI_STRLEN
- (resource->data.address64.resource_source.
- string_ptr) + 1);
- }
-
- /* Return the number of bytes consumed in this operation */
-
- *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
+ aml->ext_address64.revision_iD = AML_RESOURCE_EXTENDED_ADDRESS_REVISION;
+ aml->ext_address64.reserved = 0;
/*
- * Set the length field to the number of bytes consumed
- * minus the header size (3 bytes)
+ * Set the following contiguous fields in the AML descriptor:
+ * Address Granularity
+ * Address Range Minimum
+ * Address Range Maximum
+ * Address Translation Offset
+ * Address Length
+ * Type-Specific Attribute
*/
- *length_field = (u16) (*bytes_consumed - 3);
+ acpi_rs_move_data(&aml->ext_address64.granularity,
+ &resource->data.address64.granularity, 6,
+ ACPI_MOVE_TYPE_64_TO_64);
+
+ /* Complete the AML descriptor header */
+
+ acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64,
+ sizeof(struct
+ aml_resource_extended_address64),
+ aml);
return_ACPI_STATUS(AE_OK);
}