Exemplo n.º 1
0
/*******************************************************************************
 *
 * FUNCTION:    acpi_rs_convert_aml_to_resources
 *
 * 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
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Takes the resource byte stream and parses it, creating a
 *              linked list of resources in the caller's output buffer
 *
 ******************************************************************************/
acpi_status
acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer)
{
	struct acpi_resource *resource = (void *)output_buffer;
	acpi_status status;
	u8 resource_index;
	u8 *end_aml;

	ACPI_FUNCTION_TRACE("rs_convert_aml_to_resources");

	end_aml = aml + aml_length;

	/* Loop until end-of-buffer or an end_tag is found */

	while (aml < end_aml) {
		/* Validate the Resource Type and Resource Length */

		status = acpi_ut_validate_resource(aml, &resource_index);
		if (ACPI_FAILURE(status)) {
			return_ACPI_STATUS(status);
		}

		/* Convert the AML byte stream resource to a local resource struct */

		status =
		    acpi_rs_convert_aml_to_resource(resource,
						    ACPI_CAST_PTR(union
								  aml_resource,
								  aml),
						    acpi_gbl_get_resource_dispatch
						    [resource_index]);
		if (ACPI_FAILURE(status)) {
			ACPI_EXCEPTION((AE_INFO, status,
					"Could not convert AML resource (Type %X)",
					*aml));
			return_ACPI_STATUS(status);
		}

		/* Normal exit on completion of an end_tag resource descriptor */

		if (acpi_ut_get_resource_type(aml) ==
		    ACPI_RESOURCE_NAME_END_TAG) {
			return_ACPI_STATUS(AE_OK);
		}

		/* Point to the next input AML resource */

		aml += acpi_ut_get_descriptor_length(aml);

		/* Point to the next structure in the output buffer */

		resource =
		    ACPI_ADD_PTR(struct acpi_resource, resource,
				 resource->length);
	}

	/* Did not find an end_tag resource descriptor */

	return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
}
Exemplo n.º 2
0
acpi_status
acpi_rs_convert_resources_to_aml(struct acpi_resource *resource,
				 acpi_size aml_size_needed, u8 * output_buffer)
{
	u8 *aml = output_buffer;
	u8 *end_aml = output_buffer + aml_size_needed;
	struct acpi_rsconvert_info *conversion_table;
	acpi_status status;

	ACPI_FUNCTION_TRACE(rs_convert_resources_to_aml);

	/* Walk the resource descriptor list, convert each descriptor */

	while (aml < end_aml) {

		/* Validate the (internal) Resource Type */

		if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
			ACPI_ERROR((AE_INFO,
				    "Invalid descriptor type (0x%X) in resource list",
				    resource->type));
			return_ACPI_STATUS(AE_BAD_DATA);
		}

		/* Sanity check the length. It must not be zero, or we loop forever */

		if (!resource->length) {
			ACPI_ERROR((AE_INFO,
				    "Invalid zero length descriptor in resource list\n"));
			return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
		}

		/* Perform the conversion */

		if (resource->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
			if (resource->data.common_serial_bus.type >
			    AML_RESOURCE_MAX_SERIALBUSTYPE) {
				conversion_table = NULL;
			} else {
				/* This is an I2C, SPI, or UART serial_bus descriptor */

				conversion_table =
				    acpi_gbl_convert_resource_serial_bus_dispatch
				    [resource->data.common_serial_bus.type];
			}
		} else {
			conversion_table =
			    acpi_gbl_set_resource_dispatch[resource->type];
		}

		if (!conversion_table) {
			ACPI_ERROR((AE_INFO,
				    "Invalid/unsupported resource descriptor: Type 0x%2.2X",
				    resource->type));
			return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
		}

		status = acpi_rs_convert_resource_to_aml(resource,
						         ACPI_CAST_PTR(union
								       aml_resource,
								       aml),
							 conversion_table);
		if (ACPI_FAILURE(status)) {
			ACPI_EXCEPTION((AE_INFO, status,
					"Could not convert resource (type 0x%X) to AML",
					resource->type));
			return_ACPI_STATUS(status);
		}

		/* Perform final sanity check on the new AML resource descriptor */

		status =
		    acpi_ut_validate_resource(NULL,
					      ACPI_CAST_PTR(union aml_resource,
							    aml), NULL);
		if (ACPI_FAILURE(status)) {
			return_ACPI_STATUS(status);
		}

		/* Check for end-of-list, normal exit */

		if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {

			/* An End Tag indicates the end of the input Resource Template */

			return_ACPI_STATUS(AE_OK);
		}

		/*
		 * Extract the total length of the new descriptor and set the
		 * Aml to point to the next (output) resource descriptor
		 */
		aml += acpi_ut_get_descriptor_length(aml);

		/* Point to the next input resource descriptor */

		resource = ACPI_NEXT_RESOURCE(resource);
	}

	/* Completed buffer, but did not find an end_tag resource descriptor */

	return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
}
Exemplo n.º 3
0
static void
acpi_dm_compare_aml_resources(u8 *aml1_buffer,
			      acpi_rsdesc_size aml1_buffer_length,
			      u8 *aml2_buffer,
			      acpi_rsdesc_size aml2_buffer_length)
{
	u8 *aml1;
	u8 *aml2;
	u8 *aml1_end;
	u8 *aml2_end;
	acpi_rsdesc_size aml1_length;
	acpi_rsdesc_size aml2_length;
	acpi_rsdesc_size offset = 0;
	u8 resource_type;
	u32 count = 0;
	u32 i;

	/* Compare overall buffer sizes (may be different due to size rounding) */

	if (aml1_buffer_length != aml2_buffer_length) {
		acpi_os_printf("**** Buffer length mismatch in converted "
			       "AML: Original %X, New %X ****\n",
			       aml1_buffer_length, aml2_buffer_length);
	}

	aml1 = aml1_buffer;
	aml2 = aml2_buffer;
	aml1_end = aml1_buffer + aml1_buffer_length;
	aml2_end = aml2_buffer + aml2_buffer_length;

	/* Walk the descriptor lists, comparing each descriptor */

	while ((aml1 < aml1_end) && (aml2 < aml2_end)) {

		/* Get the lengths of each descriptor */

		aml1_length = acpi_ut_get_descriptor_length(aml1);
		aml2_length = acpi_ut_get_descriptor_length(aml2);
		resource_type = acpi_ut_get_resource_type(aml1);

		/* Check for descriptor length match */

		if (aml1_length != aml2_length) {
			acpi_os_printf
			    ("**** Length mismatch in descriptor [%.2X] type %2.2X, "
			     "Offset %8.8X Len1 %X, Len2 %X ****\n", count,
			     resource_type, offset, aml1_length, aml2_length);
		}

		/* Check for descriptor byte match */

		else if (memcmp(aml1, aml2, aml1_length)) {
			acpi_os_printf
			    ("**** Data mismatch in descriptor [%.2X] type %2.2X, "
			     "Offset %8.8X ****\n", count, resource_type,
			     offset);

			for (i = 0; i < aml1_length; i++) {
				if (aml1[i] != aml2[i]) {
					acpi_os_printf
					    ("Mismatch at byte offset %.2X: is %2.2X, "
					     "should be %2.2X\n", i, aml2[i],
					     aml1[i]);
				}
			}
		}

		/* Exit on end_tag descriptor */

		if (resource_type == ACPI_RESOURCE_NAME_END_TAG) {
			return;
		}

		/* Point to next descriptor in each buffer */

		count++;
		offset += aml1_length;
		aml1 += aml1_length;
		aml2 += aml2_length;
	}
}
Exemplo n.º 4
0
acpi_status
acpi_rs_convert_resources_to_aml(struct acpi_resource *resource,
				 acpi_size aml_size_needed, u8 * output_buffer)
{
	u8 *aml = output_buffer;
	u8 *end_aml = output_buffer + aml_size_needed;
	acpi_status status;

	ACPI_FUNCTION_TRACE(rs_convert_resources_to_aml);

	

	while (aml < end_aml) {

		

		if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
			ACPI_ERROR((AE_INFO,
				    "Invalid descriptor type (%X) in resource list",
				    resource->type));
			return_ACPI_STATUS(AE_BAD_DATA);
		}

		

		status = acpi_rs_convert_resource_to_aml(resource, ACPI_CAST_PTR(union
										 aml_resource,
										 aml),
							 acpi_gbl_set_resource_dispatch
							 [resource->type]);
		if (ACPI_FAILURE(status)) {
			ACPI_EXCEPTION((AE_INFO, status,
					"Could not convert resource (type %X) to AML",
					resource->type));
			return_ACPI_STATUS(status);
		}

		

		status =
		    acpi_ut_validate_resource(ACPI_CAST_PTR
					      (union aml_resource, aml), NULL);
		if (ACPI_FAILURE(status)) {
			return_ACPI_STATUS(status);
		}

		

		if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {

			

			return_ACPI_STATUS(AE_OK);
		}

		
		aml += acpi_ut_get_descriptor_length(aml);

		

		resource =
		    ACPI_ADD_PTR(struct acpi_resource, resource,
				 resource->length);
	}

	

	return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
}
Exemplo n.º 5
0
acpi_status
acpi_rs_convert_resources_to_aml(struct acpi_resource *resource,
				 acpi_size aml_size_needed, u8 * output_buffer)
{
	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 < end_aml) {
		/* Validate the (internal) Resource Type */

		if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
			ACPI_ERROR((AE_INFO,
				    "Invalid descriptor type (%X) in resource list",
				    resource->type));
			return_ACPI_STATUS(AE_BAD_DATA);
		}

		/* Perform the conversion */

		status = acpi_rs_convert_resource_to_aml(resource,
							 ACPI_CAST_PTR(union
								       aml_resource,
								       aml),
							 acpi_gbl_set_resource_dispatch
							 [resource->type]);
		if (ACPI_FAILURE(status)) {
			ACPI_EXCEPTION((AE_INFO, status,
					"Could not convert resource (type %X) to AML",
					resource->type));
			return_ACPI_STATUS(status);
		}

		/* Perform final sanity check on the new AML resource descriptor */

		status =
		    acpi_ut_validate_resource(ACPI_CAST_PTR
					      (union aml_resource, aml), NULL);
		if (ACPI_FAILURE(status)) {
			return_ACPI_STATUS(status);
		}

		/* Check for end-of-list, normal exit */

		if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {
			/* An End Tag indicates the end of the input Resource Template */

			return_ACPI_STATUS(AE_OK);
		}

		/*
		 * Extract the total length of the new descriptor and set the
		 * Aml to point to the next (output) resource descriptor
		 */
		aml += acpi_ut_get_descriptor_length(aml);

		/* Point to the next input resource descriptor */

		resource =
		    ACPI_ADD_PTR(struct acpi_resource, resource,
				 resource->length);
	}

	/* Completed buffer, but did not find an end_tag resource descriptor */

	return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
}
Exemplo n.º 6
0
Arquivo: rscalc.c Projeto: PyroOS/Pyro
acpi_status
acpi_rs_get_list_length(u8 * aml_buffer,
			u32 aml_buffer_length, acpi_size * size_needed)
{
	acpi_status status;
	u8 *end_aml;
	u8 *buffer;
	u32 buffer_size;
	u16 temp16;
	u16 resource_length;
	u32 extra_struct_bytes;
	u8 resource_index;
	u8 minimum_aml_resource_length;

	ACPI_FUNCTION_TRACE(rs_get_list_length);

	*size_needed = 0;
	end_aml = aml_buffer + aml_buffer_length;

	/* Walk the list of AML resource descriptors */

	while (aml_buffer < end_aml) {

		/* Validate the Resource Type and Resource Length */

		status = acpi_ut_validate_resource(aml_buffer, &resource_index);
		if (ACPI_FAILURE(status)) {
			return_ACPI_STATUS(status);
		}

		/* Get the resource length and base (minimum) AML size */

		resource_length = acpi_ut_get_resource_length(aml_buffer);
		minimum_aml_resource_length =
		    acpi_gbl_resource_aml_sizes[resource_index];

		/*
		 * Augment the size for descriptors with optional
		 * and/or variable length fields
		 */
		extra_struct_bytes = 0;
		buffer =
		    aml_buffer + acpi_ut_get_resource_header_length(aml_buffer);

		switch (acpi_ut_get_resource_type(aml_buffer)) {
		case ACPI_RESOURCE_NAME_IRQ:
			/*
			 * IRQ Resource:
			 * Get the number of bits set in the 16-bit IRQ mask
			 */
			ACPI_MOVE_16_TO_16(&temp16, buffer);
			extra_struct_bytes = acpi_rs_count_set_bits(temp16);
			break;

		case ACPI_RESOURCE_NAME_DMA:
			/*
			 * DMA Resource:
			 * Get the number of bits set in the 8-bit DMA mask
			 */
			extra_struct_bytes = acpi_rs_count_set_bits(*buffer);
			break;

		case ACPI_RESOURCE_NAME_VENDOR_SMALL:
		case ACPI_RESOURCE_NAME_VENDOR_LARGE:
			/*
			 * Vendor Resource:
			 * Get the number of vendor data bytes
			 */
			extra_struct_bytes = resource_length;
			break;

		case ACPI_RESOURCE_NAME_END_TAG:
			/*
			 * End Tag:
			 * This is the normal exit, add size of end_tag
			 */
			*size_needed += ACPI_RS_SIZE_MIN;
			return_ACPI_STATUS(AE_OK);

		case ACPI_RESOURCE_NAME_ADDRESS32:
		case ACPI_RESOURCE_NAME_ADDRESS16:
		case ACPI_RESOURCE_NAME_ADDRESS64:
			/*
			 * Address Resource:
			 * Add the size of the optional resource_source
			 */
			extra_struct_bytes =
			    acpi_rs_stream_option_length(resource_length,
							 minimum_aml_resource_length);
			break;

		case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
			/*
			 * Extended IRQ Resource:
			 * Using the interrupt_table_length, add 4 bytes for each additional
			 * interrupt. Note: at least one interrupt is required and is
			 * included in the minimum descriptor size (reason for the -1)
			 */
			extra_struct_bytes = (buffer[1] - 1) * sizeof(u32);

			/* Add the size of the optional resource_source */

			extra_struct_bytes +=
			    acpi_rs_stream_option_length(resource_length -
							 extra_struct_bytes,
							 minimum_aml_resource_length);
			break;

		default:
			break;
		}

		/*
		 * Update the required buffer size for the internal descriptor structs
		 *
		 * Important: Round the size up for the appropriate alignment. This
		 * is a requirement on IA64.
		 */
		buffer_size = acpi_gbl_resource_struct_sizes[resource_index] +
		    extra_struct_bytes;
		buffer_size = (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(buffer_size);

		*size_needed += buffer_size;

		ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
				  "Type %.2X, AmlLength %.2X InternalLength %.2X\n",
				  acpi_ut_get_resource_type(aml_buffer),
				  acpi_ut_get_descriptor_length(aml_buffer),
				  buffer_size));

		/*
		 * Point to the next resource within the AML stream using the length
		 * contained in the resource descriptor header
		 */
		aml_buffer += acpi_ut_get_descriptor_length(aml_buffer);
	}

	/* Did not find an end_tag resource descriptor */

	return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
}