From bda663d36b94c723153246a4231bbc0f1cd1836e Mon Sep 17 00:00:00 2001 From: Robert Moore Date: Fri, 16 Sep 2005 16:51:15 -0400 Subject: [ACPI] ACPICA 20050916 Fixed a problem within the Resource Manager where support for the Generic Register descriptor was not fully implemented. This descriptor is now fully recognized, parsed, disassembled, and displayed. Restructured the Resource Manager code to utilize table-driven dispatch and lookup, eliminating many of the large switch() statements. This reduces overall subsystem code size and code complexity. Affects the resource parsing and construction, disassembly, and debug dump output. Cleaned up and restructured the debug dump output for all resource descriptors. Improved readability of the output and reduced code size. Fixed a problem where changes to internal data structures caused the optional ACPI_MUTEX_DEBUG code to fail compilation if specified. Signed-off-by: Robert Moore Signed-off-by: Len Brown --- drivers/acpi/resources/rslist.c | 533 +++++++++++++--------------------------- 1 file changed, 173 insertions(+), 360 deletions(-) (limited to 'drivers/acpi/resources/rslist.c') diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index 103eb31c284..87e75349dd0 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -47,44 +47,143 @@ #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rslist") +/* Dispatch table for convert-to-stream functions */ +typedef +acpi_status(*ACPI_STREAM_HANDLER) (struct acpi_resource * resource, + u8 ** output_buffer, + acpi_size * bytes_consumed); + +static ACPI_STREAM_HANDLER acpi_gbl_stream_dispatch[] = { + acpi_rs_irq_stream, /* ACPI_RSTYPE_IRQ */ + acpi_rs_dma_stream, /* ACPI_RSTYPE_DMA */ + acpi_rs_start_depend_fns_stream, /* ACPI_RSTYPE_START_DPF */ + acpi_rs_end_depend_fns_stream, /* ACPI_RSTYPE_END_DPF */ + acpi_rs_io_stream, /* ACPI_RSTYPE_IO */ + acpi_rs_fixed_io_stream, /* ACPI_RSTYPE_FIXED_IO */ + acpi_rs_vendor_stream, /* ACPI_RSTYPE_VENDOR */ + acpi_rs_end_tag_stream, /* ACPI_RSTYPE_END_TAG */ + acpi_rs_memory24_stream, /* ACPI_RSTYPE_MEM24 */ + acpi_rs_memory32_range_stream, /* ACPI_RSTYPE_MEM32 */ + acpi_rs_fixed_memory32_stream, /* ACPI_RSTYPE_FIXED_MEM32 */ + acpi_rs_address16_stream, /* ACPI_RSTYPE_ADDRESS16 */ + acpi_rs_address32_stream, /* ACPI_RSTYPE_ADDRESS32 */ + acpi_rs_address64_stream, /* ACPI_RSTYPE_ADDRESS64 */ + acpi_rs_extended_irq_stream, /* ACPI_RSTYPE_EXT_IRQ */ + acpi_rs_generic_register_stream /* ACPI_RSTYPE_GENERIC_REG */ +}; + +/* Dispatch tables for convert-to-resource functions */ + +typedef +acpi_status(*ACPI_RESOURCE_HANDLER) (u8 * byte_stream_buffer, + acpi_size * bytes_consumed, + u8 ** output_buffer, + acpi_size * structure_size); + +static ACPI_RESOURCE_HANDLER acpi_gbl_sm_resource_dispatch[] = { + NULL, /* 0x00, Reserved */ + NULL, /* 0x01, Reserved */ + NULL, /* 0x02, Reserved */ + NULL, /* 0x03, Reserved */ + acpi_rs_irq_resource, /* ACPI_RDESC_TYPE_IRQ_FORMAT */ + acpi_rs_dma_resource, /* ACPI_RDESC_TYPE_DMA_FORMAT */ + acpi_rs_start_depend_fns_resource, /* ACPI_RDESC_TYPE_START_DEPENDENT */ + acpi_rs_end_depend_fns_resource, /* ACPI_RDESC_TYPE_END_DEPENDENT */ + acpi_rs_io_resource, /* ACPI_RDESC_TYPE_IO_PORT */ + acpi_rs_fixed_io_resource, /* ACPI_RDESC_TYPE_FIXED_IO_PORT */ + NULL, /* 0x0A, Reserved */ + NULL, /* 0x0B, Reserved */ + NULL, /* 0x0C, Reserved */ + NULL, /* 0x0D, Reserved */ + acpi_rs_vendor_resource, /* ACPI_RDESC_TYPE_SMALL_VENDOR */ + acpi_rs_end_tag_resource /* ACPI_RDESC_TYPE_END_TAG */ +}; + +static ACPI_RESOURCE_HANDLER acpi_gbl_lg_resource_dispatch[] = { + NULL, /* 0x00, Reserved */ + acpi_rs_memory24_resource, /* ACPI_RDESC_TYPE_MEMORY_24 */ + acpi_rs_generic_register_resource, /* ACPI_RDESC_TYPE_GENERIC_REGISTER */ + NULL, /* 0x03, Reserved */ + acpi_rs_vendor_resource, /* ACPI_RDESC_TYPE_LARGE_VENDOR */ + acpi_rs_memory32_range_resource, /* ACPI_RDESC_TYPE_MEMORY_32 */ + acpi_rs_fixed_memory32_resource, /* ACPI_RDESC_TYPE_FIXED_MEMORY_32 */ + acpi_rs_address32_resource, /* ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE */ + acpi_rs_address16_resource, /* ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE */ + acpi_rs_extended_irq_resource, /* ACPI_RDESC_TYPE_EXTENDED_XRUPT */ + acpi_rs_address64_resource, /* ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE */ + acpi_rs_address64_resource /* ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE */ +}; + +/* Local prototypes */ + +static ACPI_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type); + /******************************************************************************* * * FUNCTION: acpi_rs_get_resource_type * - * PARAMETERS: resource_start_byte - Byte 0 of a resource descriptor + * PARAMETERS: resource_type - Byte 0 of a resource descriptor * - * RETURN: The Resource Type with no extraneous bits + * RETURN: The Resource Type with no extraneous bits (except the large/ + * small bit -- left alone) * * DESCRIPTION: Extract the Resource Type/Name from the first byte of * a resource descriptor. * ******************************************************************************/ -u8 acpi_rs_get_resource_type(u8 resource_start_byte) -{ +u8 acpi_rs_get_resource_type(u8 resource_type) +{ ACPI_FUNCTION_ENTRY(); /* Determine if this is a small or large resource */ - switch (resource_start_byte & ACPI_RDESC_TYPE_MASK) { - case ACPI_RDESC_TYPE_SMALL: + if (resource_type & ACPI_RDESC_TYPE_LARGE) { + /* Large Resource Type -- bits 6:0 contain the name */ + + return (resource_type); + } else { + /* Small Resource Type -- bits 6:3 contain the name */ + + return ((u8) (resource_type & ACPI_RDESC_SMALL_MASK)); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_resource_handler + * + * PARAMETERS: resource_type - Byte 0 of a resource descriptor + * + * RETURN: Pointer to the resource conversion handler + * + * DESCRIPTION: Extract the Resource Type/Name from the first byte of + * a resource descriptor. + * + ******************************************************************************/ - /* Small Resource Type -- Only bits 6:3 are valid */ +static ACPI_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type) +{ + ACPI_FUNCTION_ENTRY(); - return ((u8) (resource_start_byte & ACPI_RDESC_SMALL_MASK)); + /* Determine if this is a small or large resource */ - case ACPI_RDESC_TYPE_LARGE: + if (resource_type & ACPI_RDESC_TYPE_LARGE) { + /* Large Resource Type -- bits 6:0 contain the name */ - /* Large Resource Type -- All bits are valid */ + if (resource_type > ACPI_RDESC_LARGE_MAX) { + return (NULL); + } - return (resource_start_byte); + return (acpi_gbl_lg_resource_dispatch[(resource_type & + ACPI_RDESC_LARGE_MASK)]); + } else { + /* Small Resource Type -- bits 6:3 contain the name */ - default: - /* Invalid type */ - break; + return (acpi_gbl_sm_resource_dispatch[((resource_type & + ACPI_RDESC_SMALL_MASK) + >> 3)]); } - - return (0xFF); } /******************************************************************************* @@ -107,228 +206,70 @@ acpi_status acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, u32 byte_stream_buffer_length, u8 * output_buffer) { + u8 *buffer = output_buffer; acpi_status status; acpi_size bytes_parsed = 0; - u8 resource_type = 0; acpi_size bytes_consumed = 0; - u8 *buffer = output_buffer; acpi_size structure_size = 0; - u8 end_tag_processed = FALSE; struct acpi_resource *resource; + ACPI_RESOURCE_HANDLER handler; ACPI_FUNCTION_TRACE("rs_byte_stream_to_list"); - while (bytes_parsed < byte_stream_buffer_length && !end_tag_processed) { - /* The next byte in the stream is the resource type */ - - resource_type = acpi_rs_get_resource_type(*byte_stream_buffer); - - switch (resource_type) { - case ACPI_RDESC_TYPE_MEMORY_24: - /* - * 24-Bit Memory Resource - */ - status = acpi_rs_memory24_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_LARGE_VENDOR: - /* - * Vendor Defined Resource - */ - status = acpi_rs_vendor_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_MEMORY_32: - /* - * 32-Bit Memory Range Resource - */ - status = - acpi_rs_memory32_range_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_FIXED_MEMORY_32: - /* - * 32-Bit Fixed Memory Resource - */ - status = - acpi_rs_fixed_memory32_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: - case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE: - /* - * 64-Bit Address Resource - */ - status = acpi_rs_address64_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE: - /* - * 32-Bit Address Resource - */ - status = acpi_rs_address32_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE: - /* - * 16-Bit Address Resource - */ - status = acpi_rs_address16_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_EXTENDED_XRUPT: - /* - * Extended IRQ - */ - status = - acpi_rs_extended_irq_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_IRQ_FORMAT: - /* - * IRQ Resource - */ - status = acpi_rs_irq_resource(byte_stream_buffer, - &bytes_consumed, &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_DMA_FORMAT: - /* - * DMA Resource - */ - status = acpi_rs_dma_resource(byte_stream_buffer, - &bytes_consumed, &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_START_DEPENDENT: - /* - * Start Dependent Functions Resource - */ - status = - acpi_rs_start_depend_fns_resource - (byte_stream_buffer, &bytes_consumed, &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_END_DEPENDENT: - /* - * End Dependent Functions Resource - */ - status = - acpi_rs_end_depend_fns_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_IO_PORT: - /* - * IO Port Resource - */ - status = acpi_rs_io_resource(byte_stream_buffer, - &bytes_consumed, &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_FIXED_IO_PORT: - /* - * Fixed IO Port Resource - */ - status = acpi_rs_fixed_io_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_SMALL_VENDOR: - /* - * Vendor Specific Resource - */ - status = acpi_rs_vendor_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_END_TAG: - /* - * End Tag - */ - end_tag_processed = TRUE; - status = acpi_rs_end_tag_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - default: - /* - * Invalid/Unknown resource type - */ + /* Loop until end-of-buffer or an end_tag is found */ + + while (bytes_parsed < byte_stream_buffer_length) { + /* Get the handler associated with this Descriptor Type */ + + handler = acpi_rs_get_resource_handler(*byte_stream_buffer); + if (handler) { + /* Convert a byte stream resource to local resource struct */ + + status = handler(byte_stream_buffer, &bytes_consumed, + &buffer, &structure_size); + } else { + /* Invalid resource type */ + status = AE_AML_INVALID_RESOURCE_TYPE; - break; } if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - /* Update the return value and counter */ + /* Set the aligned length of the new resource descriptor */ - bytes_parsed += bytes_consumed; + resource = ACPI_CAST_PTR(struct acpi_resource, buffer); + resource->length = + (u32) ACPI_ALIGN_RESOURCE_SIZE(resource->length); - /* Set the byte stream to point to the next resource */ + /* Normal exit on completion of an end_tag resource descriptor */ + if (acpi_rs_get_resource_type(*byte_stream_buffer) == + ACPI_RDESC_TYPE_END_TAG) { + return_ACPI_STATUS(AE_OK); + } + + /* Update counter and point to the next input resource */ + + bytes_parsed += bytes_consumed; byte_stream_buffer += bytes_consumed; - /* Set the Buffer to the next structure */ + /* Point to the next structure in the output buffer */ - resource = ACPI_CAST_PTR(struct acpi_resource, buffer); - resource->length = - (u32) ACPI_ALIGN_RESOURCE_SIZE(resource->length); buffer += ACPI_ALIGN_RESOURCE_SIZE(structure_size); } - /* Check the reason for exiting the while loop */ + /* Completed buffer, but did not find an end_tag resource descriptor */ - if (!end_tag_processed) { - return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); - } - - return_ACPI_STATUS(AE_OK); + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); } /******************************************************************************* * * FUNCTION: acpi_rs_list_to_byte_stream * - * PARAMETERS: linked_list - Pointer to the resource linked list + * PARAMETERS: Resource - Pointer to the resource linked list * byte_steam_size_needed - Calculated size of the byte stream * needed from calling * acpi_rs_get_byte_stream_length() @@ -346,180 +287,52 @@ acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, ******************************************************************************/ acpi_status -acpi_rs_list_to_byte_stream(struct acpi_resource *linked_list, +acpi_rs_list_to_byte_stream(struct acpi_resource *resource, acpi_size byte_stream_size_needed, u8 * output_buffer) { - acpi_status status; u8 *buffer = output_buffer; acpi_size bytes_consumed = 0; - u8 done = FALSE; + acpi_status status; ACPI_FUNCTION_TRACE("rs_list_to_byte_stream"); - while (!done) { - switch (linked_list->id) { - case ACPI_RSTYPE_IRQ: - /* - * IRQ Resource - */ - status = - acpi_rs_irq_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_DMA: - /* - * DMA Resource - */ - status = - acpi_rs_dma_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_START_DPF: - /* - * Start Dependent Functions Resource - */ - status = acpi_rs_start_depend_fns_stream(linked_list, - &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_END_DPF: - /* - * End Dependent Functions Resource - */ - status = acpi_rs_end_depend_fns_stream(linked_list, - &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_IO: - /* - * IO Port Resource - */ - status = - acpi_rs_io_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_FIXED_IO: - /* - * Fixed IO Port Resource - */ - status = - acpi_rs_fixed_io_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_VENDOR: - /* - * Vendor Defined Resource - */ - status = - acpi_rs_vendor_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_END_TAG: - /* - * End Tag - */ - status = - acpi_rs_end_tag_stream(linked_list, &buffer, - &bytes_consumed); + /* Convert each resource descriptor in the list */ - /* An End Tag indicates the end of the Resource Template */ + while (1) { + /* Validate Type before dispatch */ - done = TRUE; - break; - - case ACPI_RSTYPE_MEM24: - /* - * 24-Bit Memory Resource - */ - status = - acpi_rs_memory24_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_MEM32: - /* - * 32-Bit Memory Range Resource - */ - status = - acpi_rs_memory32_range_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_FIXED_MEM32: - /* - * 32-Bit Fixed Memory Resource - */ - status = - acpi_rs_fixed_memory32_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_ADDRESS16: - /* - * 16-Bit Address Descriptor Resource - */ - status = acpi_rs_address16_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_ADDRESS32: - /* - * 32-Bit Address Descriptor Resource - */ - status = acpi_rs_address32_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_ADDRESS64: - /* - * 64-Bit Address Descriptor Resource - */ - status = acpi_rs_address64_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_EXT_IRQ: - /* - * Extended IRQ Resource - */ - status = - acpi_rs_extended_irq_stream(linked_list, &buffer, - &bytes_consumed); - break; - - default: - /* - * If we get here, everything is out of sync, - * so exit with an error - */ + if (resource->type > ACPI_RSTYPE_MAX) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid descriptor type (%X) in resource list\n", - linked_list->id)); - status = AE_BAD_DATA; - break; + resource->type)); + return_ACPI_STATUS(AE_BAD_DATA); } + /* Perform the conversion, per resource type */ + + status = acpi_gbl_stream_dispatch[resource->type] (resource, + &buffer, + &bytes_consumed); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - /* Set the Buffer to point to the open byte */ + /* Check for end-of-list */ + + if (resource->type == ACPI_RSTYPE_END_TAG) { + /* An End Tag indicates the end of the Resource Template */ + + return_ACPI_STATUS(AE_OK); + } + + /* Set the Buffer to point to the next (output) resource descriptor */ buffer += bytes_consumed; - /* Point to the next object */ + /* Point to the next input resource object */ - linked_list = ACPI_PTR_ADD(struct acpi_resource, - linked_list, linked_list->length); + resource = ACPI_PTR_ADD(struct acpi_resource, + resource, resource->length); } - - return_ACPI_STATUS(AE_OK); } -- cgit v1.2.3 From 50eca3eb89d73d9f0aa070b126c7ee6a616016ab Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 30 Sep 2005 19:03:00 -0400 Subject: [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 Signed-off-by: Len Brown --- drivers/acpi/resources/rslist.c | 290 ++++++++++++++++++++-------------------- 1 file changed, 146 insertions(+), 144 deletions(-) (limited to 'drivers/acpi/resources/rslist.c') diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index 87e75349dd0..f72d42e0927 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -47,106 +47,70 @@ #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rslist") -/* Dispatch table for convert-to-stream functions */ -typedef -acpi_status(*ACPI_STREAM_HANDLER) (struct acpi_resource * resource, - u8 ** output_buffer, - acpi_size * bytes_consumed); - -static ACPI_STREAM_HANDLER acpi_gbl_stream_dispatch[] = { - acpi_rs_irq_stream, /* ACPI_RSTYPE_IRQ */ - acpi_rs_dma_stream, /* ACPI_RSTYPE_DMA */ - acpi_rs_start_depend_fns_stream, /* ACPI_RSTYPE_START_DPF */ - acpi_rs_end_depend_fns_stream, /* ACPI_RSTYPE_END_DPF */ - acpi_rs_io_stream, /* ACPI_RSTYPE_IO */ - acpi_rs_fixed_io_stream, /* ACPI_RSTYPE_FIXED_IO */ - acpi_rs_vendor_stream, /* ACPI_RSTYPE_VENDOR */ - acpi_rs_end_tag_stream, /* ACPI_RSTYPE_END_TAG */ - acpi_rs_memory24_stream, /* ACPI_RSTYPE_MEM24 */ - acpi_rs_memory32_range_stream, /* ACPI_RSTYPE_MEM32 */ - acpi_rs_fixed_memory32_stream, /* ACPI_RSTYPE_FIXED_MEM32 */ - acpi_rs_address16_stream, /* ACPI_RSTYPE_ADDRESS16 */ - acpi_rs_address32_stream, /* ACPI_RSTYPE_ADDRESS32 */ - acpi_rs_address64_stream, /* ACPI_RSTYPE_ADDRESS64 */ - acpi_rs_extended_irq_stream, /* ACPI_RSTYPE_EXT_IRQ */ - acpi_rs_generic_register_stream /* ACPI_RSTYPE_GENERIC_REG */ -}; - -/* Dispatch tables for convert-to-resource functions */ - -typedef -acpi_status(*ACPI_RESOURCE_HANDLER) (u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, - acpi_size * structure_size); - -static ACPI_RESOURCE_HANDLER acpi_gbl_sm_resource_dispatch[] = { - NULL, /* 0x00, Reserved */ - NULL, /* 0x01, Reserved */ - NULL, /* 0x02, Reserved */ - NULL, /* 0x03, Reserved */ - acpi_rs_irq_resource, /* ACPI_RDESC_TYPE_IRQ_FORMAT */ - acpi_rs_dma_resource, /* ACPI_RDESC_TYPE_DMA_FORMAT */ - acpi_rs_start_depend_fns_resource, /* ACPI_RDESC_TYPE_START_DEPENDENT */ - acpi_rs_end_depend_fns_resource, /* ACPI_RDESC_TYPE_END_DEPENDENT */ - acpi_rs_io_resource, /* ACPI_RDESC_TYPE_IO_PORT */ - acpi_rs_fixed_io_resource, /* ACPI_RDESC_TYPE_FIXED_IO_PORT */ - NULL, /* 0x0A, Reserved */ - NULL, /* 0x0B, Reserved */ - NULL, /* 0x0C, Reserved */ - NULL, /* 0x0D, Reserved */ - acpi_rs_vendor_resource, /* ACPI_RDESC_TYPE_SMALL_VENDOR */ - acpi_rs_end_tag_resource /* ACPI_RDESC_TYPE_END_TAG */ -}; - -static ACPI_RESOURCE_HANDLER acpi_gbl_lg_resource_dispatch[] = { - NULL, /* 0x00, Reserved */ - acpi_rs_memory24_resource, /* ACPI_RDESC_TYPE_MEMORY_24 */ - acpi_rs_generic_register_resource, /* ACPI_RDESC_TYPE_GENERIC_REGISTER */ - NULL, /* 0x03, Reserved */ - acpi_rs_vendor_resource, /* ACPI_RDESC_TYPE_LARGE_VENDOR */ - acpi_rs_memory32_range_resource, /* ACPI_RDESC_TYPE_MEMORY_32 */ - acpi_rs_fixed_memory32_resource, /* ACPI_RDESC_TYPE_FIXED_MEMORY_32 */ - acpi_rs_address32_resource, /* ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE */ - acpi_rs_address16_resource, /* ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE */ - acpi_rs_extended_irq_resource, /* ACPI_RDESC_TYPE_EXTENDED_XRUPT */ - acpi_rs_address64_resource, /* ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE */ - acpi_rs_address64_resource /* ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE */ -}; - /* Local prototypes */ +static ACPI_GET_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type); -static ACPI_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type); +static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml); /******************************************************************************* * - * FUNCTION: acpi_rs_get_resource_type + * FUNCTION: acpi_rs_validate_resource_length * - * PARAMETERS: resource_type - Byte 0 of a resource descriptor + * PARAMETERS: Aml - Pointer to the AML resource descriptor * - * RETURN: The Resource Type with no extraneous bits (except the large/ - * small bit -- left alone) + * RETURN: Status - AE_OK if the resource length appears valid * - * DESCRIPTION: Extract the Resource Type/Name from the first byte of - * a resource descriptor. + * DESCRIPTION: Validate the resource_length. Fixed-length descriptors must + * have the exact length; variable-length descriptors must be + * at least as long as the minimum. Certain Small descriptors + * can vary in size by at most one byte. * ******************************************************************************/ -u8 acpi_rs_get_resource_type(u8 resource_type) +static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml) { + struct acpi_resource_info *resource_info; + u16 minimum_aml_resource_length; + u16 resource_length; + ACPI_FUNCTION_ENTRY(); - /* Determine if this is a small or large resource */ + /* Get the size and type info about this resource descriptor */ - if (resource_type & ACPI_RDESC_TYPE_LARGE) { - /* Large Resource Type -- bits 6:0 contain the name */ + resource_info = + acpi_rs_get_resource_info(aml->small_header.descriptor_type); + if (!resource_info) { + return (AE_AML_INVALID_RESOURCE_TYPE); + } + + resource_length = acpi_rs_get_resource_length(aml); + minimum_aml_resource_length = + resource_info->minimum_aml_resource_length; + + /* Validate based upon the type of resource, fixed length or variable */ + + if (resource_info->length_type == ACPI_FIXED_LENGTH) { + /* Fixed length resource, length must match exactly */ - return (resource_type); + if (resource_length != minimum_aml_resource_length) { + return (AE_AML_BAD_RESOURCE_LENGTH); + } + } else if (resource_info->length_type == ACPI_VARIABLE_LENGTH) { + /* Variable length resource, must be at least the minimum */ + + if (resource_length < minimum_aml_resource_length) { + return (AE_AML_BAD_RESOURCE_LENGTH); + } } else { - /* Small Resource Type -- bits 6:3 contain the name */ + /* Small variable length resource, allowed to be (Min) or (Min-1) */ - return ((u8) (resource_type & ACPI_RDESC_SMALL_MASK)); + if ((resource_length > minimum_aml_resource_length) || + (resource_length < (minimum_aml_resource_length - 1))) { + return (AE_AML_BAD_RESOURCE_LENGTH); + } } + + return (AE_OK); } /******************************************************************************* @@ -162,38 +126,38 @@ u8 acpi_rs_get_resource_type(u8 resource_type) * ******************************************************************************/ -static ACPI_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type) +static ACPI_GET_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type) { ACPI_FUNCTION_ENTRY(); /* Determine if this is a small or large resource */ - if (resource_type & ACPI_RDESC_TYPE_LARGE) { + if (resource_type & ACPI_RESOURCE_NAME_LARGE) { /* Large Resource Type -- bits 6:0 contain the name */ - if (resource_type > ACPI_RDESC_LARGE_MAX) { + if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { return (NULL); } - return (acpi_gbl_lg_resource_dispatch[(resource_type & - ACPI_RDESC_LARGE_MASK)]); + return (acpi_gbl_lg_get_resource_dispatch[(resource_type & + ACPI_RESOURCE_NAME_LARGE_MASK)]); } else { /* Small Resource Type -- bits 6:3 contain the name */ - return (acpi_gbl_sm_resource_dispatch[((resource_type & - ACPI_RDESC_SMALL_MASK) - >> 3)]); + return (acpi_gbl_sm_get_resource_dispatch[((resource_type & + ACPI_RESOURCE_NAME_SMALL_MASK) + >> 3)]); } } /******************************************************************************* * - * FUNCTION: acpi_rs_byte_stream_to_list + * FUNCTION: acpi_rs_convert_aml_to_resources * - * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream - * byte_stream_buffer_length - Length of byte_stream_buffer - * output_buffer - Pointer to the buffer that will - * contain the output structures + * PARAMETERS: aml_buffer - Pointer to the resource byte stream + * aml_buffer_length - Length of aml_buffer + * output_buffer - Pointer to the buffer that will + * contain the output structures * * RETURN: Status * @@ -203,37 +167,60 @@ static ACPI_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type) ******************************************************************************/ acpi_status -acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, - u32 byte_stream_buffer_length, u8 * output_buffer) +acpi_rs_convert_aml_to_resources(u8 * aml_buffer, + u32 aml_buffer_length, u8 * output_buffer) { u8 *buffer = output_buffer; acpi_status status; acpi_size bytes_parsed = 0; - acpi_size bytes_consumed = 0; - acpi_size structure_size = 0; struct acpi_resource *resource; - ACPI_RESOURCE_HANDLER handler; + u16 resource_length; + u32 descriptor_length; + ACPI_GET_RESOURCE_HANDLER handler; - ACPI_FUNCTION_TRACE("rs_byte_stream_to_list"); + ACPI_FUNCTION_TRACE("rs_convert_aml_to_resources"); /* Loop until end-of-buffer or an end_tag is found */ - while (bytes_parsed < byte_stream_buffer_length) { + while (bytes_parsed < aml_buffer_length) { /* Get the handler associated with this Descriptor Type */ - handler = acpi_rs_get_resource_handler(*byte_stream_buffer); - if (handler) { - /* Convert a byte stream resource to local resource struct */ + handler = acpi_rs_get_resource_handler(*aml_buffer); + if (!handler) { + /* No handler indicates invalid resource type */ - status = handler(byte_stream_buffer, &bytes_consumed, - &buffer, &structure_size); - } else { - /* Invalid resource type */ + return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); + } - status = AE_AML_INVALID_RESOURCE_TYPE; + resource_length = + acpi_rs_get_resource_length(ACPI_CAST_PTR + (union aml_resource, + aml_buffer)); + + descriptor_length = + acpi_rs_get_descriptor_length(ACPI_CAST_PTR + (union aml_resource, + aml_buffer)); + + /* + * Perform limited validation of the resource length, based upon + * what we know about the resource type + */ + status = + acpi_rs_validate_resource_length(ACPI_CAST_PTR + (union aml_resource, + aml_buffer)); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } + /* Convert a byte stream resource to local resource struct */ + + status = handler(ACPI_CAST_PTR(union aml_resource, aml_buffer), + resource_length, + ACPI_CAST_PTR(struct acpi_resource, buffer)); if (ACPI_FAILURE(status)) { + ACPI_REPORT_ERROR(("Could not convert AML resource (type %X) to resource, %s\n", *aml_buffer, acpi_format_exception(status))); return_ACPI_STATUS(status); } @@ -245,19 +232,19 @@ acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, /* Normal exit on completion of an end_tag resource descriptor */ - if (acpi_rs_get_resource_type(*byte_stream_buffer) == - ACPI_RDESC_TYPE_END_TAG) { + if (acpi_rs_get_resource_type(*aml_buffer) == + ACPI_RESOURCE_NAME_END_TAG) { return_ACPI_STATUS(AE_OK); } /* Update counter and point to the next input resource */ - bytes_parsed += bytes_consumed; - byte_stream_buffer += bytes_consumed; + bytes_parsed += descriptor_length; + aml_buffer += descriptor_length; /* Point to the next structure in the output buffer */ - buffer += ACPI_ALIGN_RESOURCE_SIZE(structure_size); + buffer += resource->length; } /* Completed buffer, but did not find an end_tag resource descriptor */ @@ -267,17 +254,15 @@ acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, /******************************************************************************* * - * FUNCTION: acpi_rs_list_to_byte_stream + * FUNCTION: acpi_rs_convert_resources_to_aml * - * PARAMETERS: Resource - Pointer to the resource linked list - * byte_steam_size_needed - Calculated size of the byte stream - * needed from calling - * acpi_rs_get_byte_stream_length() - * The size of the output_buffer is - * guaranteed to be >= - * byte_stream_size_needed - * output_buffer - Pointer to the buffer that will - * contain the byte stream + * PARAMETERS: Resource - Pointer to the resource linked list + * aml_size_needed - Calculated size of the byte stream + * needed from calling acpi_rs_get_aml_length() + * The size of the output_buffer is + * guaranteed to be >= aml_size_needed + * output_buffer - Pointer to the buffer that will + * contain the byte stream * * RETURN: Status * @@ -287,52 +272,69 @@ acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, ******************************************************************************/ acpi_status -acpi_rs_list_to_byte_stream(struct acpi_resource *resource, - acpi_size byte_stream_size_needed, - u8 * output_buffer) +acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, + acpi_size aml_size_needed, u8 * output_buffer) { - u8 *buffer = output_buffer; - acpi_size bytes_consumed = 0; + u8 *aml_buffer = output_buffer; acpi_status status; - ACPI_FUNCTION_TRACE("rs_list_to_byte_stream"); + ACPI_FUNCTION_TRACE("rs_convert_resources_to_aml"); /* Convert each resource descriptor in the list */ while (1) { - /* Validate Type before dispatch */ + /* Validate Resource Descriptor Type before dispatch */ - if (resource->type > ACPI_RSTYPE_MAX) { + if (resource->type > ACPI_RESOURCE_TYPE_MAX) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid descriptor type (%X) in resource list\n", resource->type)); return_ACPI_STATUS(AE_BAD_DATA); } - /* Perform the conversion, per resource type */ + /* Perform the conversion per resource type */ + + status = + acpi_gbl_set_resource_dispatch[resource->type] (resource, + ACPI_CAST_PTR + (union + aml_resource, + aml_buffer)); + if (ACPI_FAILURE(status)) { + ACPI_REPORT_ERROR(("Could not convert resource (type %X) to AML, %s\n", resource->type, acpi_format_exception(status))); + return_ACPI_STATUS(status); + } + + /* Perform final sanity check on the new AML resource descriptor */ - status = acpi_gbl_stream_dispatch[resource->type] (resource, - &buffer, - &bytes_consumed); + status = + acpi_rs_validate_resource_length(ACPI_CAST_PTR + (union aml_resource, + aml_buffer)); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - /* Check for end-of-list */ + /* Check for end-of-list, normal exit */ - if (resource->type == ACPI_RSTYPE_END_TAG) { - /* An End Tag indicates the end of the Resource Template */ + if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { + /* An End Tag indicates the end of the input Resource Template */ return_ACPI_STATUS(AE_OK); } - /* Set the Buffer to point to the next (output) resource descriptor */ + /* Extract the total length of the new descriptor */ + /* Set the aml_buffer to point to the next (output) resource descriptor */ - buffer += bytes_consumed; + aml_buffer += + acpi_rs_get_descriptor_length(ACPI_CAST_PTR + (union aml_resource, + aml_buffer)); - /* Point to the next input resource object */ + /* Point to the next input resource descriptor */ - resource = ACPI_PTR_ADD(struct acpi_resource, - resource, resource->length); + resource = + ACPI_PTR_ADD(struct acpi_resource, resource, + resource->length); } } -- cgit v1.2.3 From 0897831bb54eb36fd9e2a22da7f0f64be1b20d09 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 21 Oct 2005 00:00:00 -0400 Subject: [ACPI] ACPICA 20051021 Implemented support for the EM64T and other x86_64 processors. This essentially entails recognizing that these processors support non-aligned memory transfers. Previously, all 64-bit processors were assumed to lack hardware support for non-aligned transfers. Completed conversion of the Resource Manager to nearly full table-driven operation. Specifically, the resource conversion code (convert AML to internal format and the reverse) and the debug code to dump internal resource descriptors are fully table-driven, reducing code and data size and improving maintainability. The OSL interfaces for Acquire and Release Lock now use a 64-bit flag word on 64-bit processors instead of a fixed 32-bit word. (Alexey Starikovskiy) Implemented support within the resource conversion code for the Type-Specific byte within the various ACPI 3.0 *WordSpace macros. Fixed some issues within the resource conversion code for the type-specific flags for both Memory and I/O address resource descriptors. For Memory, implemented support for the MTP and TTP flags. For I/O, split the TRS and TTP flags into two separate fields. Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/resources/rslist.c | 92 +++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 45 deletions(-) (limited to 'drivers/acpi/resources/rslist.c') diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index f72d42e0927..ee17ef3315f 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -48,7 +48,8 @@ ACPI_MODULE_NAME("rslist") /* Local prototypes */ -static ACPI_GET_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type); +static struct acpi_rsconvert_info *acpi_rs_get_conversion_info(u8 + resource_type); static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml); @@ -83,7 +84,7 @@ static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml) return (AE_AML_INVALID_RESOURCE_TYPE); } - resource_length = acpi_rs_get_resource_length(aml); + resource_length = acpi_ut_get_resource_length(aml); minimum_aml_resource_length = resource_info->minimum_aml_resource_length; @@ -115,18 +116,17 @@ static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml) /******************************************************************************* * - * FUNCTION: acpi_rs_get_resource_handler + * FUNCTION: acpi_rs_get_conversion_info * * PARAMETERS: resource_type - Byte 0 of a resource descriptor * - * RETURN: Pointer to the resource conversion handler + * RETURN: Pointer to the resource conversion info table * - * DESCRIPTION: Extract the Resource Type/Name from the first byte of - * a resource descriptor. + * DESCRIPTION: Get the conversion table associated with this resource type * ******************************************************************************/ -static ACPI_GET_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type) +static struct acpi_rsconvert_info *acpi_rs_get_conversion_info(u8 resource_type) { ACPI_FUNCTION_ENTRY(); @@ -174,33 +174,24 @@ acpi_rs_convert_aml_to_resources(u8 * aml_buffer, acpi_status status; acpi_size bytes_parsed = 0; struct acpi_resource *resource; - u16 resource_length; - u32 descriptor_length; - ACPI_GET_RESOURCE_HANDLER handler; + acpi_rsdesc_size descriptor_length; + struct acpi_rsconvert_info *info; ACPI_FUNCTION_TRACE("rs_convert_aml_to_resources"); /* Loop until end-of-buffer or an end_tag is found */ while (bytes_parsed < aml_buffer_length) { - /* Get the handler associated with this Descriptor Type */ + /* Get the conversion table associated with this Descriptor Type */ - handler = acpi_rs_get_resource_handler(*aml_buffer); - if (!handler) { - /* No handler indicates invalid resource type */ + info = acpi_rs_get_conversion_info(*aml_buffer); + if (!info) { + /* No table indicates an invalid resource type */ return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); } - resource_length = - acpi_rs_get_resource_length(ACPI_CAST_PTR - (union aml_resource, - aml_buffer)); - - descriptor_length = - acpi_rs_get_descriptor_length(ACPI_CAST_PTR - (union aml_resource, - aml_buffer)); + descriptor_length = acpi_ut_get_descriptor_length(aml_buffer); /* * Perform limited validation of the resource length, based upon @@ -214,11 +205,16 @@ acpi_rs_convert_aml_to_resources(u8 * aml_buffer, return_ACPI_STATUS(status); } - /* Convert a byte stream resource to local resource struct */ + /* Convert the AML byte stream resource to a local resource struct */ - status = handler(ACPI_CAST_PTR(union aml_resource, aml_buffer), - resource_length, - ACPI_CAST_PTR(struct acpi_resource, buffer)); + status = + acpi_rs_convert_aml_to_resource(ACPI_CAST_PTR + (struct acpi_resource, + buffer), + ACPI_CAST_PTR(union + aml_resource, + aml_buffer), + info); if (ACPI_FAILURE(status)) { ACPI_REPORT_ERROR(("Could not convert AML resource (type %X) to resource, %s\n", *aml_buffer, acpi_format_exception(status))); return_ACPI_STATUS(status); @@ -232,7 +228,7 @@ acpi_rs_convert_aml_to_resources(u8 * aml_buffer, /* Normal exit on completion of an end_tag resource descriptor */ - if (acpi_rs_get_resource_type(*aml_buffer) == + if (acpi_ut_get_resource_type(aml_buffer) == ACPI_RESOURCE_NAME_END_TAG) { return_ACPI_STATUS(AE_OK); } @@ -276,14 +272,15 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, acpi_size aml_size_needed, u8 * output_buffer) { u8 *aml_buffer = output_buffer; + u8 *end_aml_buffer = output_buffer + aml_size_needed; acpi_status status; ACPI_FUNCTION_TRACE("rs_convert_resources_to_aml"); - /* Convert each resource descriptor in the list */ + /* Walk the resource descriptor list, convert each descriptor */ - while (1) { - /* Validate Resource Descriptor Type before dispatch */ + while (aml_buffer < end_aml_buffer) { + /* Validate the Resource Type */ if (resource->type > ACPI_RESOURCE_TYPE_MAX) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, @@ -292,14 +289,14 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, return_ACPI_STATUS(AE_BAD_DATA); } - /* Perform the conversion per resource type */ + /* Perform the conversion */ - status = - acpi_gbl_set_resource_dispatch[resource->type] (resource, - ACPI_CAST_PTR - (union - aml_resource, - aml_buffer)); + status = acpi_rs_convert_resource_to_aml(resource, + ACPI_CAST_PTR(union + aml_resource, + aml_buffer), + acpi_gbl_set_resource_dispatch + [resource->type]); if (ACPI_FAILURE(status)) { ACPI_REPORT_ERROR(("Could not convert resource (type %X) to AML, %s\n", resource->type, acpi_format_exception(status))); return_ACPI_STATUS(status); @@ -323,18 +320,23 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, return_ACPI_STATUS(AE_OK); } - /* Extract the total length of the new descriptor */ - /* Set the aml_buffer to point to the next (output) resource descriptor */ - - aml_buffer += - acpi_rs_get_descriptor_length(ACPI_CAST_PTR - (union aml_resource, - aml_buffer)); + /* + * Extract the total length of the new descriptor and set the + * aml_buffer to point to the next (output) resource descriptor + */ + aml_buffer += acpi_ut_get_descriptor_length(aml_buffer); /* Point to the next input resource descriptor */ resource = ACPI_PTR_ADD(struct acpi_resource, resource, resource->length); + + /* Check for end-of-list, normal exit */ + } + + /* Completed buffer, but did not find an end_tag resource descriptor */ + + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); } -- cgit v1.2.3 From 96db255c8f014ae3497507104e8df809785a619f Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 2 Nov 2005 00:00:00 -0500 Subject: [ACPI] ACPICA 20051102 Modified the subsystem initialization sequence to improve GPE support. The GPE initialization has been split into two parts in order to defer execution of the _PRW methods (Power Resources for Wake) until after the hardware is fully initialized and the SCI handler is installed. This allows the _PRW methods to access fields protected by the Global Lock. This will fix systems where a NO_GLOBAL_LOCK exception has been seen during initialization. Fixed a regression with the ConcatenateResTemplate() ASL operator introduced in the 20051021 release. Implemented support for "local" internal ACPI object types within the debugger "Object" command and the acpi_walk_namespace() external interfaces. These local types include RegionFields, BankFields, IndexFields, Alias, and reference objects. Moved common AML resource handling code into a new file, "utresrc.c". This code is shared by both the Resource Manager and the AML Debugger. Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/resources/rslist.c | 195 +++++++--------------------------------- 1 file changed, 32 insertions(+), 163 deletions(-) (limited to 'drivers/acpi/resources/rslist.c') diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index ee17ef3315f..b83996233c1 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -47,115 +47,12 @@ #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rslist") -/* Local prototypes */ -static struct acpi_rsconvert_info *acpi_rs_get_conversion_info(u8 - resource_type); - -static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml); - -/******************************************************************************* - * - * FUNCTION: acpi_rs_validate_resource_length - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * - * RETURN: Status - AE_OK if the resource length appears valid - * - * DESCRIPTION: Validate the resource_length. Fixed-length descriptors must - * have the exact length; variable-length descriptors must be - * at least as long as the minimum. Certain Small descriptors - * can vary in size by at most one byte. - * - ******************************************************************************/ - -static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml) -{ - struct acpi_resource_info *resource_info; - u16 minimum_aml_resource_length; - u16 resource_length; - - ACPI_FUNCTION_ENTRY(); - - /* Get the size and type info about this resource descriptor */ - - resource_info = - acpi_rs_get_resource_info(aml->small_header.descriptor_type); - if (!resource_info) { - return (AE_AML_INVALID_RESOURCE_TYPE); - } - - resource_length = acpi_ut_get_resource_length(aml); - minimum_aml_resource_length = - resource_info->minimum_aml_resource_length; - - /* Validate based upon the type of resource, fixed length or variable */ - - if (resource_info->length_type == ACPI_FIXED_LENGTH) { - /* Fixed length resource, length must match exactly */ - - if (resource_length != minimum_aml_resource_length) { - return (AE_AML_BAD_RESOURCE_LENGTH); - } - } else if (resource_info->length_type == ACPI_VARIABLE_LENGTH) { - /* Variable length resource, must be at least the minimum */ - - if (resource_length < minimum_aml_resource_length) { - return (AE_AML_BAD_RESOURCE_LENGTH); - } - } else { - /* Small variable length resource, allowed to be (Min) or (Min-1) */ - - if ((resource_length > minimum_aml_resource_length) || - (resource_length < (minimum_aml_resource_length - 1))) { - return (AE_AML_BAD_RESOURCE_LENGTH); - } - } - - return (AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_conversion_info - * - * PARAMETERS: resource_type - Byte 0 of a resource descriptor - * - * RETURN: Pointer to the resource conversion info table - * - * DESCRIPTION: Get the conversion table associated with this resource type - * - ******************************************************************************/ - -static struct acpi_rsconvert_info *acpi_rs_get_conversion_info(u8 resource_type) -{ - ACPI_FUNCTION_ENTRY(); - - /* Determine if this is a small or large resource */ - - if (resource_type & ACPI_RESOURCE_NAME_LARGE) { - /* Large Resource Type -- bits 6:0 contain the name */ - - if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { - return (NULL); - } - - return (acpi_gbl_lg_get_resource_dispatch[(resource_type & - ACPI_RESOURCE_NAME_LARGE_MASK)]); - } else { - /* Small Resource Type -- bits 6:3 contain the name */ - - return (acpi_gbl_sm_get_resource_dispatch[((resource_type & - ACPI_RESOURCE_NAME_SMALL_MASK) - >> 3)]); - } -} - /******************************************************************************* * * FUNCTION: acpi_rs_convert_aml_to_resources * - * PARAMETERS: aml_buffer - Pointer to the resource byte stream - * aml_buffer_length - Length of aml_buffer + * PARAMETERS: Aml - Pointer to the resource byte stream + * aml_length - Length of Aml * output_buffer - Pointer to the buffer that will * contain the output structures * @@ -165,42 +62,24 @@ static struct acpi_rsconvert_info *acpi_rs_get_conversion_info(u8 resource_type) * linked list of resources in the caller's output buffer * ******************************************************************************/ - acpi_status -acpi_rs_convert_aml_to_resources(u8 * aml_buffer, - u32 aml_buffer_length, u8 * output_buffer) +acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer) { - u8 *buffer = output_buffer; + struct acpi_resource *resource = (void *)output_buffer; acpi_status status; - acpi_size bytes_parsed = 0; - struct acpi_resource *resource; - acpi_rsdesc_size descriptor_length; - struct acpi_rsconvert_info *info; + u8 resource_index; + u8 *end_aml; ACPI_FUNCTION_TRACE("rs_convert_aml_to_resources"); - /* Loop until end-of-buffer or an end_tag is found */ - - while (bytes_parsed < aml_buffer_length) { - /* Get the conversion table associated with this Descriptor Type */ - - info = acpi_rs_get_conversion_info(*aml_buffer); - if (!info) { - /* No table indicates an invalid resource type */ + end_aml = aml + aml_length; - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); - } + /* Loop until end-of-buffer or an end_tag is found */ - descriptor_length = acpi_ut_get_descriptor_length(aml_buffer); + while (aml < end_aml) { + /* Validate the Resource Type and Resource Length */ - /* - * Perform limited validation of the resource length, based upon - * what we know about the resource type - */ - status = - acpi_rs_validate_resource_length(ACPI_CAST_PTR - (union aml_resource, - aml_buffer)); + status = acpi_ut_validate_resource(aml, &resource_index); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -208,42 +87,36 @@ acpi_rs_convert_aml_to_resources(u8 * aml_buffer, /* Convert the AML byte stream resource to a local resource struct */ status = - acpi_rs_convert_aml_to_resource(ACPI_CAST_PTR - (struct acpi_resource, - buffer), + acpi_rs_convert_aml_to_resource(resource, ACPI_CAST_PTR(union aml_resource, - aml_buffer), - info); + aml), + acpi_gbl_get_resource_dispatch + [resource_index]); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not convert AML resource (type %X) to resource, %s\n", *aml_buffer, acpi_format_exception(status))); + ACPI_REPORT_ERROR(("Could not convert AML resource (Type %X) to resource, %s\n", *aml, acpi_format_exception(status))); return_ACPI_STATUS(status); } - /* Set the aligned length of the new resource descriptor */ - - resource = ACPI_CAST_PTR(struct acpi_resource, buffer); - resource->length = - (u32) ACPI_ALIGN_RESOURCE_SIZE(resource->length); - /* Normal exit on completion of an end_tag resource descriptor */ - if (acpi_ut_get_resource_type(aml_buffer) == + if (acpi_ut_get_resource_type(aml) == ACPI_RESOURCE_NAME_END_TAG) { return_ACPI_STATUS(AE_OK); } - /* Update counter and point to the next input resource */ + /* Point to the next input AML resource */ - bytes_parsed += descriptor_length; - aml_buffer += descriptor_length; + aml += acpi_ut_get_descriptor_length(aml); /* Point to the next structure in the output buffer */ - buffer += resource->length; + resource = + ACPI_PTR_ADD(struct acpi_resource, resource, + resource->length); } - /* Completed buffer, but did not find an end_tag resource descriptor */ + /* Did not find an end_tag resource descriptor */ return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); } @@ -271,16 +144,16 @@ acpi_status acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, acpi_size aml_size_needed, u8 * output_buffer) { - u8 *aml_buffer = output_buffer; - u8 *end_aml_buffer = output_buffer + aml_size_needed; + u8 *aml = output_buffer; + u8 *end_aml = output_buffer + aml_size_needed; acpi_status status; ACPI_FUNCTION_TRACE("rs_convert_resources_to_aml"); /* Walk the resource descriptor list, convert each descriptor */ - while (aml_buffer < end_aml_buffer) { - /* Validate the Resource Type */ + while (aml < end_aml) { + /* Validate the (internal) Resource Type */ if (resource->type > ACPI_RESOURCE_TYPE_MAX) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, @@ -294,7 +167,7 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, status = acpi_rs_convert_resource_to_aml(resource, ACPI_CAST_PTR(union aml_resource, - aml_buffer), + aml), acpi_gbl_set_resource_dispatch [resource->type]); if (ACPI_FAILURE(status)) { @@ -305,9 +178,8 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, /* Perform final sanity check on the new AML resource descriptor */ status = - acpi_rs_validate_resource_length(ACPI_CAST_PTR - (union aml_resource, - aml_buffer)); + acpi_ut_validate_resource(ACPI_CAST_PTR + (union aml_resource, aml), NULL); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -322,18 +194,15 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, /* * Extract the total length of the new descriptor and set the - * aml_buffer to point to the next (output) resource descriptor + * Aml to point to the next (output) resource descriptor */ - aml_buffer += acpi_ut_get_descriptor_length(aml_buffer); + aml += acpi_ut_get_descriptor_length(aml); /* Point to the next input resource descriptor */ resource = ACPI_PTR_ADD(struct acpi_resource, resource, resource->length); - - /* Check for end-of-list, normal exit */ - } /* Completed buffer, but did not find an end_tag resource descriptor */ -- cgit v1.2.3 From c51a4de85de720670f2fbc592a6f8040af72ad87 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 17 Nov 2005 13:07:00 -0500 Subject: [ACPI] ACPICA 20051117 Fixed a problem in the AML parser where the method thread count could be decremented below zero if any errors occurred during the method parse phase. This should eliminate AE_AML_METHOD_LIMIT exceptions seen on some machines. This also fixed a related regression with the mechanism that detects and corrects methods that cannot properly handle reentrancy (related to the deployment of the new OwnerId mechanism.) Eliminated the pre-parsing of control methods (to detect errors) during table load. Related to the problem above, this was causing unwind issues if any errors occurred during the parse, and it seemed to be overkill. A table load should not be aborted if there are problems with any single control method, thus rendering this feature rather pointless. Fixed a problem with the new table-driven resource manager where an internal buffer overflow could occur for small resource templates. Implemented a new external interface, acpi_get_vendor_resource() This interface will find and return a vendor-defined resource descriptor within a _CRS or _PRS method via an ACPI 3.0 UUID match. (from Bjorn Helgaas) Removed the length limit (200) on string objects as per the upcoming ACPI 3.0A specification. This affects the following areas of the interpreter: 1) any implicit conversion of a Buffer to a String, 2) a String object result of the ASL Concatentate operator, 3) the String object result of the ASL ToString operator. Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/resources/rslist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/acpi/resources/rslist.c') diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index b83996233c1..573c0670564 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -112,7 +112,7 @@ acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer) /* Point to the next structure in the output buffer */ resource = - ACPI_PTR_ADD(struct acpi_resource, resource, + ACPI_ADD_PTR(struct acpi_resource, resource, resource->length); } @@ -201,7 +201,7 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, /* Point to the next input resource descriptor */ resource = - ACPI_PTR_ADD(struct acpi_resource, resource, + ACPI_ADD_PTR(struct acpi_resource, resource, resource->length); } -- cgit v1.2.3 From 4a90c7e86202f46fa9af011bdbcdf36e355d1721 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 13 Jan 2006 16:22:00 -0500 Subject: [ACPI] ACPICA 20060113 Added 2006 copyright. At SuSE's suggestion, enabled all error messages without enabling function tracing, ie with CONFIG_ACPI_DEBUG=n Replaced all instances of the ACPI_DEBUG_PRINT macro invoked at the ACPI_DB_ERROR and ACPI_DB_WARN debug levels with the ACPI_REPORT_ERROR and ACPI_REPORT_WARNING macros, respectively. This preserves all error and warning messages in the non-debug version of the ACPICA code (this has been referred to as the "debug lite" option.) Over 200 cases were converted to create a total of over 380 error/warning messages across the ACPICA code. This increases the code and data size of the default non-debug version by about 13K. Added ACPI_NO_ERROR_MESSAGES flag to enable deleting all messages. The size of the debug version remains about the same. Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/resources/rslist.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/acpi/resources/rslist.c') diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index 573c0670564..e4778a51c17 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -156,9 +156,7 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, /* Validate the (internal) Resource Type */ if (resource->type > ACPI_RESOURCE_TYPE_MAX) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid descriptor type (%X) in resource list\n", - resource->type)); + ACPI_REPORT_ERROR(("Invalid descriptor type (%X) in resource list\n", resource->type)); return_ACPI_STATUS(AE_BAD_DATA); } -- cgit v1.2.3 From b8e4d89357fc434618a59c1047cac72641191805 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 27 Jan 2006 16:43:00 -0500 Subject: [ACPI] ACPICA 20060127 Implemented support in the Resource Manager to allow unresolved namestring references within resource package objects for the _PRT method. This support is in addition to the previously implemented unresolved reference support within the AML parser. If the interpreter slack mode is enabled (true on Linux unless acpi=strict), these unresolved references will be passed through to the caller as a NULL package entry. http://bugzilla.kernel.org/show_bug.cgi?id=5741 Implemented and deployed new macros and functions for error and warning messages across the subsystem. These macros are simpler and generate less code than their predecessors. The new macros ACPI_ERROR, ACPI_EXCEPTION, ACPI_WARNING, and ACPI_INFO replace the ACPI_REPORT_* macros. Implemented the acpi_cpu_flags type to simplify host OS integration of the Acquire/Release Lock OSL interfaces. Suggested by Steven Rostedt and Andrew Morton. Fixed a problem where Alias ASL operators are sometimes not correctly resolved. causing AE_AML_INTERNAL http://bugzilla.kernel.org/show_bug.cgi?id=5189 http://bugzilla.kernel.org/show_bug.cgi?id=5674 Fixed several problems with the implementation of the ConcatenateResTemplate ASL operator. As per the ACPI specification, zero length buffers are now treated as a single EndTag. One-length buffers always cause a fatal exception. Non-zero length buffers that do not end with a full 2-byte EndTag cause a fatal exception. Fixed a possible structure overwrite in the AcpiGetObjectInfo external interface. (With assistance from Thomas Renninger) Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/resources/rslist.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers/acpi/resources/rslist.c') diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index e4778a51c17..1434e786477 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -94,7 +94,9 @@ acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer) acpi_gbl_get_resource_dispatch [resource_index]); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not convert AML resource (Type %X) to resource, %s\n", *aml, acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not convert AML resource (Type %X)", + *aml)); return_ACPI_STATUS(status); } @@ -156,7 +158,9 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, /* Validate the (internal) Resource Type */ if (resource->type > ACPI_RESOURCE_TYPE_MAX) { - ACPI_REPORT_ERROR(("Invalid descriptor type (%X) in resource list\n", resource->type)); + ACPI_ERROR((AE_INFO, + "Invalid descriptor type (%X) in resource list", + resource->type)); return_ACPI_STATUS(AE_BAD_DATA); } @@ -169,7 +173,9 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, acpi_gbl_set_resource_dispatch [resource->type]); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not convert resource (type %X) to AML, %s\n", resource->type, acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not convert resource (type %X) to AML", + resource->type)); return_ACPI_STATUS(status); } -- cgit v1.2.3