Path: blob/main/sys/contrib/dev/acpica/components/disassembler/dmresrc.c
48524 views
/*******************************************************************************1*2* Module Name: dmresrc.c - Resource Descriptor disassembly3*4******************************************************************************/56/******************************************************************************7*8* 1. Copyright Notice9*10* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.11* All rights reserved.12*13* 2. License14*15* 2.1. This is your license from Intel Corp. under its intellectual property16* rights. You may have additional license terms from the party that provided17* you this software, covering your right to use that party's intellectual18* property rights.19*20* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a21* copy of the source code appearing in this file ("Covered Code") an22* irrevocable, perpetual, worldwide license under Intel's copyrights in the23* base code distributed originally by Intel ("Original Intel Code") to copy,24* make derivatives, distribute, use and display any portion of the Covered25* Code in any form, with the right to sublicense such rights; and26*27* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent28* license (with the right to sublicense), under only those claims of Intel29* patents that are infringed by the Original Intel Code, to make, use, sell,30* offer to sell, and import the Covered Code and derivative works thereof31* solely to the minimum extent necessary to exercise the above copyright32* license, and in no event shall the patent license extend to any additions33* to or modifications of the Original Intel Code. No other license or right34* is granted directly or by implication, estoppel or otherwise;35*36* The above copyright and patent license is granted only if the following37* conditions are met:38*39* 3. Conditions40*41* 3.1. Redistribution of Source with Rights to Further Distribute Source.42* Redistribution of source code of any substantial portion of the Covered43* Code or modification with rights to further distribute source must include44* the above Copyright Notice, the above License, this list of Conditions,45* and the following Disclaimer and Export Compliance provision. In addition,46* Licensee must cause all Covered Code to which Licensee contributes to47* contain a file documenting the changes Licensee made to create that Covered48* Code and the date of any change. Licensee must include in that file the49* documentation of any changes made by any predecessor Licensee. Licensee50* must include a prominent statement that the modification is derived,51* directly or indirectly, from Original Intel Code.52*53* 3.2. Redistribution of Source with no Rights to Further Distribute Source.54* Redistribution of source code of any substantial portion of the Covered55* Code or modification without rights to further distribute source must56* include the following Disclaimer and Export Compliance provision in the57* documentation and/or other materials provided with distribution. In58* addition, Licensee may not authorize further sublicense of source of any59* portion of the Covered Code, and must include terms to the effect that the60* license from Licensee to its licensee is limited to the intellectual61* property embodied in the software Licensee provides to its licensee, and62* not to intellectual property embodied in modifications its licensee may63* make.64*65* 3.3. Redistribution of Executable. Redistribution in executable form of any66* substantial portion of the Covered Code or modification must reproduce the67* above Copyright Notice, and the following Disclaimer and Export Compliance68* provision in the documentation and/or other materials provided with the69* distribution.70*71* 3.4. Intel retains all right, title, and interest in and to the Original72* Intel Code.73*74* 3.5. Neither the name Intel nor any other trademark owned or controlled by75* Intel shall be used in advertising or otherwise to promote the sale, use or76* other dealings in products derived from or relating to the Covered Code77* without prior written authorization from Intel.78*79* 4. Disclaimer and Export Compliance80*81* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED82* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE83* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,84* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY85* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY86* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A87* PARTICULAR PURPOSE.88*89* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES90* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR91* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,92* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY93* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL94* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS95* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY96* LIMITED REMEDY.97*98* 4.3. Licensee shall not export, either directly or indirectly, any of this99* software or system incorporating such software without first obtaining any100* required license or other approval from the U. S. Department of Commerce or101* any other agency or department of the United States Government. In the102* event Licensee exports any such software from the United States or103* re-exports any such software from a foreign destination, Licensee shall104* ensure that the distribution and export/re-export of the software is in105* compliance with all laws, regulations, orders, or other restrictions of the106* U.S. Export Administration Regulations. Licensee agrees that neither it nor107* any of its subsidiaries will export/re-export any technical data, process,108* software, or service, directly or indirectly, to any country for which the109* United States government or any agency thereof requires an export license,110* other governmental approval, or letter of assurance, without first obtaining111* such license, approval or letter.112*113*****************************************************************************114*115* Alternatively, you may choose to be licensed under the terms of the116* following license:117*118* Redistribution and use in source and binary forms, with or without119* modification, are permitted provided that the following conditions120* are met:121* 1. Redistributions of source code must retain the above copyright122* notice, this list of conditions, and the following disclaimer,123* without modification.124* 2. Redistributions in binary form must reproduce at minimum a disclaimer125* substantially similar to the "NO WARRANTY" disclaimer below126* ("Disclaimer") and any redistribution must be conditioned upon127* including a substantially similar Disclaimer requirement for further128* binary redistribution.129* 3. Neither the names of the above-listed copyright holders nor the names130* of any contributors may be used to endorse or promote products derived131* from this software without specific prior written permission.132*133* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS134* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT135* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR136* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT137* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,138* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT139* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,140* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY141* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT142* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE143* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.144*145* Alternatively, you may choose to be licensed under the terms of the146* GNU General Public License ("GPL") version 2 as published by the Free147* Software Foundation.148*149*****************************************************************************/150151#include <contrib/dev/acpica/include/acpi.h>152#include <contrib/dev/acpica/include/accommon.h>153#include <contrib/dev/acpica/include/amlcode.h>154#include <contrib/dev/acpica/include/acdisasm.h>155156157#define _COMPONENT ACPI_CA_DEBUGGER158ACPI_MODULE_NAME ("dbresrc")159160161/* Dispatch tables for Resource disassembly functions */162163static ACPI_RESOURCE_HANDLER AcpiGbl_DmResourceDispatch [] =164{165/* Small descriptors */166167NULL, /* 0x00, Reserved */168NULL, /* 0x01, Reserved */169NULL, /* 0x02, Reserved */170NULL, /* 0x03, Reserved */171AcpiDmIrqDescriptor, /* 0x04, ACPI_RESOURCE_NAME_IRQ_FORMAT */172AcpiDmDmaDescriptor, /* 0x05, ACPI_RESOURCE_NAME_DMA_FORMAT */173AcpiDmStartDependentDescriptor, /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */174AcpiDmEndDependentDescriptor, /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */175AcpiDmIoDescriptor, /* 0x08, ACPI_RESOURCE_NAME_IO_PORT */176AcpiDmFixedIoDescriptor, /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO_PORT */177AcpiDmFixedDmaDescriptor, /* 0x0A, ACPI_RESOURCE_NAME_FIXED_DMA */178NULL, /* 0x0B, Reserved */179NULL, /* 0x0C, Reserved */180NULL, /* 0x0D, Reserved */181AcpiDmVendorSmallDescriptor, /* 0x0E, ACPI_RESOURCE_NAME_SMALL_VENDOR */182NULL, /* 0x0F, ACPI_RESOURCE_NAME_END_TAG (not used) */183184/* Large descriptors */185186NULL, /* 0x00, Reserved */187AcpiDmMemory24Descriptor, /* 0x01, ACPI_RESOURCE_NAME_MEMORY_24 */188AcpiDmGenericRegisterDescriptor,/* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */189NULL, /* 0x03, Reserved */190AcpiDmVendorLargeDescriptor, /* 0x04, ACPI_RESOURCE_NAME_LARGE_VENDOR */191AcpiDmMemory32Descriptor, /* 0x05, ACPI_RESOURCE_NAME_MEMORY_32 */192AcpiDmFixedMemory32Descriptor, /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY_32 */193AcpiDmDwordDescriptor, /* 0x07, ACPI_RESOURCE_NAME_DWORD_ADDRESS_SPACE */194AcpiDmWordDescriptor, /* 0x08, ACPI_RESOURCE_NAME_WORD_ADDRESS_SPACE */195AcpiDmInterruptDescriptor, /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_XRUPT */196AcpiDmQwordDescriptor, /* 0x0A, ACPI_RESOURCE_NAME_QWORD_ADDRESS_SPACE */197AcpiDmExtendedDescriptor, /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS_SPACE */198AcpiDmGpioDescriptor, /* 0x0C, ACPI_RESOURCE_NAME_GPIO */199AcpiDmPinFunctionDescriptor, /* 0x0D, ACPI_RESOURCE_NAME_PIN_FUNCTION */200AcpiDmSerialBusDescriptor, /* 0x0E, ACPI_RESOURCE_NAME_SERIAL_BUS */201AcpiDmPinConfigDescriptor, /* 0x0F, ACPI_RESOURCE_NAME_PIN_CONFIG */202AcpiDmPinGroupDescriptor, /* 0x10, ACPI_RESOURCE_NAME_PIN_GROUP */203AcpiDmPinGroupFunctionDescriptor, /* 0x11, ACPI_RESOURCE_NAME_PIN_GROUP_FUNCTION */204AcpiDmPinGroupConfigDescriptor, /* 0x12, ACPI_RESOURCE_NAME_PIN_GROUP_CONFIG */205AcpiDmClockInputDescriptor, /* 0x13, ACPI_RESOURCE_NAME_CLOCK_INPUT */206};207208209/* Only used for single-threaded applications */210/* TBD: remove when name is passed as parameter to the dump functions */211212static UINT32 ResourceName;213214215/*******************************************************************************216*217* FUNCTION: AcpiDmDescriptorName218*219* PARAMETERS: None220*221* RETURN: None222*223* DESCRIPTION: Emit a name for the descriptor if one is present (indicated224* by the name being changed from the default name.) A name is only225* emitted if a reference to the descriptor has been made somewhere226* in the original ASL code.227*228******************************************************************************/229230void231AcpiDmDescriptorName (232void)233{234235if (ResourceName == ACPI_DEFAULT_RESNAME)236{237return;238}239240AcpiOsPrintf ("%4.4s", (char *) &ResourceName);241}242243244/*******************************************************************************245*246* FUNCTION: AcpiDmDumpInteger*247*248* PARAMETERS: Value - Value to emit249* Name - Associated name (emitted as a comment)250*251* RETURN: None252*253* DESCRIPTION: Integer output helper functions254*255******************************************************************************/256257void258AcpiDmDumpInteger8 (259UINT8 Value,260const char *Name)261{262AcpiOsPrintf ("0x%2.2X, // %s\n", Value, Name);263}264265void266AcpiDmDumpInteger16 (267UINT16 Value,268const char *Name)269{270AcpiOsPrintf ("0x%4.4X, // %s\n", Value, Name);271}272273void274AcpiDmDumpInteger32 (275UINT32 Value,276const char *Name)277{278AcpiOsPrintf ("0x%8.8X, // %s\n", Value, Name);279}280281void282AcpiDmDumpInteger64 (283UINT64 Value,284const char *Name)285{286AcpiOsPrintf ("0x%8.8X%8.8X, // %s\n", ACPI_FORMAT_UINT64 (Value), Name);287}288289290/*******************************************************************************291*292* FUNCTION: AcpiDmBitList293*294* PARAMETERS: Mask - 16-bit value corresponding to 16 interrupt295* or DMA values296*297* RETURN: None298*299* DESCRIPTION: Dump a bit mask as a list of individual interrupt/DMA levels.300*301******************************************************************************/302303void304AcpiDmBitList (305UINT16 Mask)306{307UINT32 i;308BOOLEAN Previous = FALSE;309310311/* Open the initializer list */312313AcpiOsPrintf ("{");314315/* Examine each bit */316317for (i = 0; i < 16; i++)318{319/* Only interested in bits that are set to 1 */320321if (Mask & 1)322{323if (Previous)324{325AcpiOsPrintf (",");326}327328Previous = TRUE;329AcpiOsPrintf ("%u", i);330}331332Mask >>= 1;333}334335/* Close list */336337AcpiOsPrintf ("}\n");338}339340341/*******************************************************************************342*343* FUNCTION: AcpiDmResourceTemplate344*345* PARAMETERS: Info - Current parse tree walk info346* ByteData - Pointer to the byte list data347* ByteCount - Length of the byte list348*349* RETURN: None350*351* DESCRIPTION: Dump the contents of a Resource Template containing a set of352* Resource Descriptors.353*354******************************************************************************/355356void357AcpiDmResourceTemplate (358ACPI_OP_WALK_INFO *Info,359ACPI_PARSE_OBJECT *Op,360UINT8 *ByteData,361UINT32 ByteCount)362{363ACPI_STATUS Status;364UINT32 CurrentByteOffset;365UINT8 ResourceType;366UINT32 ResourceLength;367void *Aml;368UINT32 Level;369BOOLEAN DependentFns = FALSE;370UINT8 ResourceIndex;371ACPI_NAMESPACE_NODE *Node;372373374if (Op->Asl.AmlOpcode != AML_FIELD_OP)375{376Info->MappingOp = Op;377}378379Level = Info->Level;380ResourceName = ACPI_DEFAULT_RESNAME;381Node = Op->Common.Node;382if (Node)383{384Node = Node->Child;385}386387for (CurrentByteOffset = 0; CurrentByteOffset < ByteCount;)388{389Aml = &ByteData[CurrentByteOffset];390391/* Get the descriptor type and length */392393ResourceType = AcpiUtGetResourceType (Aml);394ResourceLength = AcpiUtGetResourceLength (Aml);395396/* Validate the Resource Type and Resource Length */397398Status = AcpiUtValidateResource (NULL, Aml, &ResourceIndex);399if (ACPI_FAILURE (Status))400{401AcpiOsPrintf (402"/*** Could not validate Resource, type (%X) %s***/\n",403ResourceType, AcpiFormatException (Status));404return;405}406407/* Point to next descriptor */408409CurrentByteOffset += AcpiUtGetDescriptorLength (Aml);410411/* Descriptor pre-processing */412413switch (ResourceType)414{415case ACPI_RESOURCE_NAME_START_DEPENDENT:416417/* Finish a previous StartDependentFns */418419if (DependentFns)420{421Level--;422AcpiDmIndent (Level);423AcpiOsPrintf ("}\n");424}425break;426427case ACPI_RESOURCE_NAME_END_DEPENDENT:428429Level--;430DependentFns = FALSE;431break;432433case ACPI_RESOURCE_NAME_END_TAG:434435/* Normal exit, the resource list is finished */436437if (DependentFns)438{439/*440* Close an open StartDependentDescriptor. This indicates a441* missing EndDependentDescriptor.442*/443Level--;444445/* Go ahead and insert EndDependentFn() */446447AcpiDmEndDependentDescriptor (Info, Aml, ResourceLength, Level);448449AcpiDmIndent (Level);450AcpiOsPrintf (451"/*** Disassembler: inserted "452"missing EndDependentFn () ***/\n");453}454return;455456default:457458break;459}460461/* Disassemble the resource structure */462463if (Node)464{465ResourceName = Node->Name.Integer;466Node = Node->Peer;467}468469AcpiGbl_DmResourceDispatch [ResourceIndex] (470Info, Aml, ResourceLength, Level);471472/* Descriptor post-processing */473474if (ResourceType == ACPI_RESOURCE_NAME_START_DEPENDENT)475{476DependentFns = TRUE;477Level++;478}479}480}481482483/*******************************************************************************484*485* FUNCTION: AcpiDmIsResourceTemplate486*487* PARAMETERS: WalkState - Current walk info488* Op - Buffer Op to be examined489*490* RETURN: Status. AE_OK if valid template491*492* DESCRIPTION: Walk a byte list to determine if it consists of a valid set493* of resource descriptors. Nothing is output.494*495******************************************************************************/496497ACPI_STATUS498AcpiDmIsResourceTemplate (499ACPI_WALK_STATE *WalkState,500ACPI_PARSE_OBJECT *Op)501{502ACPI_STATUS Status;503ACPI_PARSE_OBJECT *NextOp;504UINT8 *Aml;505UINT8 *EndAml;506UINT32 BufferLength;507UINT32 DeclaredBufferLength;508509510/* This op must be a buffer */511512if (Op->Common.AmlOpcode != AML_BUFFER_OP)513{514return (AE_TYPE);515}516517/*518* Get the declared length of the buffer.519* This is the nn in "Buffer (nn)"520*/521NextOp = Op->Common.Value.Arg;522if (!NextOp)523{524AcpiOsPrintf ("NULL byte list in buffer\n");525return (AE_TYPE);526}527528DeclaredBufferLength = NextOp->Common.Value.Size;529530/* Get the length of the raw initialization byte list */531532NextOp = NextOp->Common.Next;533if (!NextOp)534{535return (AE_TYPE);536}537538Aml = NextOp->Named.Data;539BufferLength = NextOp->Common.Value.Size;540541/*542* Any buffer smaller than one byte cannot possibly be a resource543* template. Two bytes could possibly be a "NULL" resource template544* with a lone end tag descriptor (as generated via545* "ResourceTemplate(){}"), but this would be an extremely unusual546* case, as the template would be essentially useless. The disassembler547* therefore does not recognize any two-byte buffer as a resource548* template.549*/550if (BufferLength <= 2)551{552return (AE_TYPE);553}554555/*556* Not a template if declared buffer length != actual length of the557* initialization byte list. Because the resource macros will create558* a buffer of the exact required length (buffer length will be equal559* to the actual length).560*561* NOTE (April 2017): Resource templates with this issue have been562* seen in the field. We still don't want to attempt to disassemble563* a buffer like this to a resource template because this output564* would not match the original input buffer (it would be shorter565* than the original when the disassembled code is recompiled).566* Basically, a buffer like this appears to be hand crafted in the567* first place, so just emitting a buffer object instead of a568* resource template more closely resembles the original ASL code.569*/570if (DeclaredBufferLength != BufferLength)571{572return (AE_TYPE);573}574575/* Walk the byte list, abort on any invalid descriptor type or length */576577Status = AcpiUtWalkAmlResources (WalkState, Aml, BufferLength,578NULL, ACPI_CAST_INDIRECT_PTR (void, &EndAml));579if (ACPI_FAILURE (Status))580{581return (AE_TYPE);582}583584/*585* For the resource template to be valid, one EndTag must appear586* at the very end of the ByteList, not before. (For proper disassembly587* of a ResourceTemplate, the buffer must not have any extra data after588* the EndTag.)589*/590if ((Aml + BufferLength - sizeof (AML_RESOURCE_END_TAG)) != EndAml)591{592return (AE_AML_NO_RESOURCE_END_TAG);593}594595/*596* All resource descriptors are valid, therefore this list appears597* to be a valid resource template598*/599return (AE_OK);600}601602603