void AcpiDmResourceTemplate ( ACPI_OP_WALK_INFO *Info, ACPI_PARSE_OBJECT *Op, UINT8 *ByteData, UINT32 ByteCount) { ACPI_STATUS Status; UINT32 CurrentByteOffset; UINT8 ResourceType; UINT32 ResourceLength; void *Aml; UINT32 Level; BOOLEAN DependentFns = FALSE; UINT8 ResourceIndex; ACPI_NAMESPACE_NODE *Node; if (Op->Asl.AmlOpcode != AML_FIELD_OP) { Info->MappingOp = Op; } Level = Info->Level; ResourceName = ACPI_DEFAULT_RESNAME; Node = Op->Common.Node; if (Node) { Node = Node->Child; } for (CurrentByteOffset = 0; CurrentByteOffset < ByteCount;) { Aml = &ByteData[CurrentByteOffset]; /* Get the descriptor type and length */ ResourceType = AcpiUtGetResourceType (Aml); ResourceLength = AcpiUtGetResourceLength (Aml); /* Validate the Resource Type and Resource Length */ Status = AcpiUtValidateResource (NULL, Aml, &ResourceIndex); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("/*** Could not validate Resource, type (%X) %s***/\n", ResourceType, AcpiFormatException (Status)); return; } /* Point to next descriptor */ CurrentByteOffset += AcpiUtGetDescriptorLength (Aml); /* Descriptor pre-processing */ switch (ResourceType) { case ACPI_RESOURCE_NAME_START_DEPENDENT: /* Finish a previous StartDependentFns */ if (DependentFns) { Level--; AcpiDmIndent (Level); AcpiOsPrintf ("}\n"); } break; case ACPI_RESOURCE_NAME_END_DEPENDENT: Level--; DependentFns = FALSE; break; case ACPI_RESOURCE_NAME_END_TAG: /* Normal exit, the resource list is finished */ if (DependentFns) { /* * Close an open StartDependentDescriptor. This indicates a * missing EndDependentDescriptor. */ Level--; DependentFns = FALSE; /* Go ahead and insert EndDependentFn() */ AcpiDmEndDependentDescriptor (Info, Aml, ResourceLength, Level); AcpiDmIndent (Level); AcpiOsPrintf ( "/*** Disassembler: inserted missing EndDependentFn () ***/\n"); } return; default: break; } /* Disassemble the resource structure */ if (Node) { ResourceName = Node->Name.Integer; Node = Node->Peer; } AcpiGbl_DmResourceDispatch [ResourceIndex] ( Info, Aml, ResourceLength, Level); /* Descriptor post-processing */ if (ResourceType == ACPI_RESOURCE_NAME_START_DEPENDENT) { DependentFns = TRUE; Level++; } } }
static void AcpiDmCompareAmlResources ( UINT8 *Aml1Buffer, ACPI_RSDESC_SIZE Aml1BufferLength, UINT8 *Aml2Buffer, ACPI_RSDESC_SIZE Aml2BufferLength) { UINT8 *Aml1; UINT8 *Aml2; UINT8 *Aml1End; UINT8 *Aml2End; ACPI_RSDESC_SIZE Aml1Length; ACPI_RSDESC_SIZE Aml2Length; ACPI_RSDESC_SIZE Offset = 0; UINT8 ResourceType; UINT32 Count = 0; UINT32 i; /* Compare overall buffer sizes (may be different due to size rounding) */ if (Aml1BufferLength != Aml2BufferLength) { AcpiOsPrintf ( "**** Buffer length mismatch in converted AML: Original %X, New %X ****\n", Aml1BufferLength, Aml2BufferLength); } Aml1 = Aml1Buffer; Aml2 = Aml2Buffer; Aml1End = Aml1Buffer + Aml1BufferLength; Aml2End = Aml2Buffer + Aml2BufferLength; /* Walk the descriptor lists, comparing each descriptor */ while ((Aml1 < Aml1End) && (Aml2 < Aml2End)) { /* Get the lengths of each descriptor */ Aml1Length = AcpiUtGetDescriptorLength (Aml1); Aml2Length = AcpiUtGetDescriptorLength (Aml2); ResourceType = AcpiUtGetResourceType (Aml1); /* Check for descriptor length match */ if (Aml1Length != Aml2Length) { AcpiOsPrintf ( "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X Len1 %X, Len2 %X ****\n", Count, ResourceType, Offset, Aml1Length, Aml2Length); } /* Check for descriptor byte match */ else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length)) { AcpiOsPrintf ( "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n", Count, ResourceType, Offset); for (i = 0; i < Aml1Length; i++) { if (Aml1[i] != Aml2[i]) { AcpiOsPrintf ("Mismatch at byte offset %.2X: is %2.2X, should be %2.2X\n", i, Aml2[i], Aml1[i]); } } } /* Exit on EndTag descriptor */ if (ResourceType == ACPI_RESOURCE_NAME_END_TAG) { return; } /* Point to next descriptor in each buffer */ Count++; Offset += Aml1Length; Aml1 += Aml1Length; Aml2 += Aml2Length; } }
ACPI_STATUS AcpiRsGetListLength ( UINT8 *AmlBuffer, UINT32 AmlBufferLength, ACPI_SIZE *SizeNeeded) { ACPI_STATUS Status; UINT8 *EndAml; UINT8 *Buffer; UINT32 BufferSize; UINT16 Temp16; UINT16 ResourceLength; UINT32 ExtraStructBytes; UINT8 ResourceIndex; UINT8 MinimumAmlResourceLength; AML_RESOURCE *AmlResource; ACPI_FUNCTION_TRACE (RsGetListLength); *SizeNeeded = ACPI_RS_SIZE_MIN; /* Minimum size is one EndTag */ EndAml = AmlBuffer + AmlBufferLength; /* Walk the list of AML resource descriptors */ while (AmlBuffer < EndAml) { /* Validate the Resource Type and Resource Length */ Status = AcpiUtValidateResource (NULL, AmlBuffer, &ResourceIndex); if (ACPI_FAILURE (Status)) { /* * Exit on failure. Cannot continue because the descriptor length * may be bogus also. */ return_ACPI_STATUS (Status); } AmlResource = (void *) AmlBuffer; /* Get the resource length and base (minimum) AML size */ ResourceLength = AcpiUtGetResourceLength (AmlBuffer); MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex]; /* * Augment the size for descriptors with optional * and/or variable length fields */ ExtraStructBytes = 0; Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer); switch (AcpiUtGetResourceType (AmlBuffer)) { 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); ExtraStructBytes = AcpiRsCountSetBits (Temp16); break; case ACPI_RESOURCE_NAME_DMA: /* * DMA Resource: * Get the number of bits set in the 8-bit DMA mask */ ExtraStructBytes = AcpiRsCountSetBits (*Buffer); break; case ACPI_RESOURCE_NAME_VENDOR_SMALL: case ACPI_RESOURCE_NAME_VENDOR_LARGE: /* * Vendor Resource: * Get the number of vendor data bytes */ ExtraStructBytes = ResourceLength; /* * There is already one byte included in the minimum * descriptor size. If there are extra struct bytes, * subtract one from the count. */ if (ExtraStructBytes) { ExtraStructBytes--; } break; case ACPI_RESOURCE_NAME_END_TAG: /* * End Tag: This is the normal exit */ 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 ResourceSource */ ExtraStructBytes = AcpiRsStreamOptionLength ( ResourceLength, MinimumAmlResourceLength); break; case ACPI_RESOURCE_NAME_EXTENDED_IRQ: /* * Extended IRQ Resource: * Using the InterruptTableLength, 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) */ ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32); /* Add the size of the optional ResourceSource */ ExtraStructBytes += AcpiRsStreamOptionLength ( ResourceLength - ExtraStructBytes, MinimumAmlResourceLength); break; case ACPI_RESOURCE_NAME_GPIO: /* Vendor data is optional */ if (AmlResource->Gpio.VendorLength) { ExtraStructBytes += AmlResource->Gpio.VendorOffset - AmlResource->Gpio.PinTableOffset + AmlResource->Gpio.VendorLength; } else { ExtraStructBytes += AmlResource->LargeHeader.ResourceLength + sizeof (AML_RESOURCE_LARGE_HEADER) - AmlResource->Gpio.PinTableOffset; } break; case ACPI_RESOURCE_NAME_SERIAL_BUS: MinimumAmlResourceLength = AcpiGbl_ResourceAmlSerialBusSizes[ AmlResource->CommonSerialBus.Type]; ExtraStructBytes += AmlResource->CommonSerialBus.ResourceLength - MinimumAmlResourceLength; 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. */ if (AcpiUtGetResourceType (AmlBuffer) == ACPI_RESOURCE_NAME_SERIAL_BUS) { BufferSize = AcpiGbl_ResourceStructSerialBusSizes[ AmlResource->CommonSerialBus.Type] + ExtraStructBytes; } else { BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] + ExtraStructBytes; } BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize); *SizeNeeded += BufferSize; ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES, "Type %.2X, AmlLength %.2X InternalLength %.2X\n", AcpiUtGetResourceType (AmlBuffer), AcpiUtGetDescriptorLength (AmlBuffer), BufferSize)); /* * Point to the next resource within the AML stream using the length * contained in the resource descriptor header */ AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer); } /* Did not find an EndTag resource descriptor */ return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); }
ACPI_STATUS AcpiRsConvertResourcesToAml ( ACPI_RESOURCE *Resource, ACPI_SIZE AmlSizeNeeded, UINT8 *OutputBuffer) { UINT8 *Aml = OutputBuffer; UINT8 *EndAml = OutputBuffer + AmlSizeNeeded; ACPI_RSCONVERT_INFO *ConversionTable; ACPI_STATUS Status; ACPI_FUNCTION_TRACE (RsConvertResourcesToAml); /* Walk the resource descriptor list, convert each descriptor */ while (Aml < EndAml) { /* 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.CommonSerialBus.Type > AML_RESOURCE_MAX_SERIALBUSTYPE) { ConversionTable = NULL; } else { /* This is an I2C, SPI, or UART SerialBus descriptor */ ConversionTable = AcpiGbl_ConvertResourceSerialBusDispatch[ Resource->Data.CommonSerialBus.Type]; } } else { ConversionTable = AcpiGbl_SetResourceDispatch[Resource->Type]; } if (!ConversionTable) { ACPI_ERROR ((AE_INFO, "Invalid/unsupported resource descriptor: Type 0x%2.2X", Resource->Type)); return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); } Status = AcpiRsConvertResourceToAml (Resource, ACPI_CAST_PTR (AML_RESOURCE, Aml), ConversionTable); 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 = AcpiUtValidateResource (NULL, ACPI_CAST_PTR (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 += AcpiUtGetDescriptorLength (Aml); /* Point to the next input resource descriptor */ Resource = ACPI_NEXT_RESOURCE (Resource); } /* Completed buffer, but did not find an EndTag resource descriptor */ return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); }
ACPI_STATUS AcpiRsConvertResourcesToAml ( ACPI_RESOURCE *Resource, ACPI_SIZE AmlSizeNeeded, UINT8 *OutputBuffer) { UINT8 *Aml = OutputBuffer; UINT8 *EndAml = OutputBuffer + AmlSizeNeeded; ACPI_STATUS Status; ACPI_FUNCTION_TRACE (RsConvertResourcesToAml); /* Walk the resource descriptor list, convert each descriptor */ while (Aml < EndAml) { /* 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); } /* Perform the conversion */ Status = AcpiRsConvertResourceToAml (Resource, ACPI_CAST_PTR (AML_RESOURCE, Aml), AcpiGbl_SetResourceDispatch[Resource->Type]); 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 = AcpiUtValidateResource ( ACPI_CAST_PTR (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 += AcpiUtGetDescriptorLength (Aml); /* Point to the next input resource descriptor */ Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length); } /* Completed buffer, but did not find an EndTag resource descriptor */ return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); }
ACPI_STATUS AcpiRsGetListLength ( UINT8 *AmlBuffer, UINT32 AmlBufferLength, ACPI_SIZE *SizeNeeded) { ACPI_STATUS Status; UINT8 *EndAml; UINT8 *Buffer; UINT32 BufferSize; UINT16 Temp16; UINT16 ResourceLength; UINT32 ExtraStructBytes; UINT8 ResourceIndex; UINT8 MinimumAmlResourceLength; ACPI_FUNCTION_TRACE (RsGetListLength); *SizeNeeded = 0; EndAml = AmlBuffer + AmlBufferLength; /* Walk the list of AML resource descriptors */ while (AmlBuffer < EndAml) { /* Validate the Resource Type and Resource Length */ Status = AcpiUtValidateResource (AmlBuffer, &ResourceIndex); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Get the resource length and base (minimum) AML size */ ResourceLength = AcpiUtGetResourceLength (AmlBuffer); MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex]; /* * Augment the size for descriptors with optional * and/or variable length fields */ ExtraStructBytes = 0; Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer); switch (AcpiUtGetResourceType (AmlBuffer)) { 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); ExtraStructBytes = AcpiRsCountSetBits (Temp16); break; case ACPI_RESOURCE_NAME_DMA: /* * DMA Resource: * Get the number of bits set in the 8-bit DMA mask */ ExtraStructBytes = AcpiRsCountSetBits (*Buffer); break; case ACPI_RESOURCE_NAME_VENDOR_SMALL: case ACPI_RESOURCE_NAME_VENDOR_LARGE: /* * Vendor Resource: * Get the number of vendor data bytes */ ExtraStructBytes = ResourceLength; break; case ACPI_RESOURCE_NAME_END_TAG: /* * End Tag: * This is the normal exit, add size of EndTag */ *SizeNeeded += 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 ResourceSource */ ExtraStructBytes = AcpiRsStreamOptionLength ( ResourceLength, MinimumAmlResourceLength); break; case ACPI_RESOURCE_NAME_EXTENDED_IRQ: /* * Extended IRQ Resource: * Using the InterruptTableLength, 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) */ ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32); /* Add the size of the optional ResourceSource */ ExtraStructBytes += AcpiRsStreamOptionLength ( ResourceLength - ExtraStructBytes, MinimumAmlResourceLength); 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. */ BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] + ExtraStructBytes; BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize); *SizeNeeded += BufferSize; ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES, "Type %.2X, AmlLength %.2X InternalLength %.2X\n", AcpiUtGetResourceType (AmlBuffer), AcpiUtGetDescriptorLength (AmlBuffer), BufferSize)); /* * Point to the next resource within the AML stream using the length * contained in the resource descriptor header */ AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer); } /* Did not find an EndTag resource descriptor */ return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); }