Path: blob/main/sys/contrib/dev/acpica/components/disassembler/dmbuffer.c
48524 views
/*******************************************************************************1*2* Module Name: dmbuffer - AML disassembler, buffer and string support3*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/acutils.h>154#include <contrib/dev/acpica/include/acdisasm.h>155#include <contrib/dev/acpica/include/acparser.h>156#include <contrib/dev/acpica/include/amlcode.h>157#include <contrib/dev/acpica/include/acinterp.h>158159160#define _COMPONENT ACPI_CA_DEBUGGER161ACPI_MODULE_NAME ("dmbuffer")162163/* Local prototypes */164165static void166AcpiDmUuid (167ACPI_PARSE_OBJECT *Op);168169static void170AcpiDmUnicode (171ACPI_PARSE_OBJECT *Op);172173static void174AcpiDmGetHardwareIdType (175ACPI_PARSE_OBJECT *Op);176177static void178AcpiDmPldBuffer (179UINT32 Level,180UINT8 *ByteData,181UINT32 ByteCount);182183static const char *184AcpiDmFindNameByIndex (185UINT64 Index,186const char **List);187188189#define ACPI_BUFFER_BYTES_PER_LINE 8190191192/*******************************************************************************193*194* FUNCTION: AcpiDmDisasmByteList195*196* PARAMETERS: Level - Current source code indentation level197* ByteData - Pointer to the byte list198* ByteCount - Length of the byte list199*200* RETURN: None201*202* DESCRIPTION: Dump an AML "ByteList" in Hex format. 8 bytes per line, prefixed203* with the hex buffer offset.204*205******************************************************************************/206207void208AcpiDmDisasmByteList (209UINT32 Level,210UINT8 *ByteData,211UINT32 ByteCount)212{213UINT32 i;214UINT32 j;215UINT32 CurrentIndex;216UINT8 BufChar;217218219if (!ByteCount)220{221return;222}223224for (i = 0; i < ByteCount; i += ACPI_BUFFER_BYTES_PER_LINE)225{226/* Line indent and offset prefix for each new line */227228AcpiDmIndent (Level);229if (ByteCount > ACPI_BUFFER_BYTES_PER_LINE)230{231AcpiOsPrintf ("/* %04X */ ", i);232}233234/* Dump the actual hex values */235236for (j = 0; j < ACPI_BUFFER_BYTES_PER_LINE; j++)237{238CurrentIndex = i + j;239if (CurrentIndex >= ByteCount)240{241/* Dump fill spaces */242243AcpiOsPrintf (" ");244continue;245}246247AcpiOsPrintf (" 0x%2.2X", ByteData[CurrentIndex]);248249/* Add comma if there are more bytes to display */250251if (CurrentIndex < (ByteCount - 1))252{253AcpiOsPrintf (",");254}255else256{257AcpiOsPrintf (" ");258}259}260261/* Dump the ASCII equivalents within a comment */262263AcpiOsPrintf (" // ");264for (j = 0; j < ACPI_BUFFER_BYTES_PER_LINE; j++)265{266CurrentIndex = i + j;267if (CurrentIndex >= ByteCount)268{269break;270}271272BufChar = ByteData[CurrentIndex];273if (isprint (BufChar))274{275AcpiOsPrintf ("%c", BufChar);276}277else278{279AcpiOsPrintf (".");280}281}282283/* Finished with this line */284285AcpiOsPrintf ("\n");286}287}288289290/*******************************************************************************291*292* FUNCTION: AcpiDmByteList293*294* PARAMETERS: Info - Parse tree walk info295* Op - Byte list op296*297* RETURN: None298*299* DESCRIPTION: Dump a buffer byte list, handling the various types of buffers.300* Buffer type must be already set in the Op DisasmOpcode.301*302******************************************************************************/303304void305AcpiDmByteList (306ACPI_OP_WALK_INFO *Info,307ACPI_PARSE_OBJECT *Op)308{309UINT8 *ByteData;310UINT32 ByteCount;311312313ByteData = Op->Named.Data;314ByteCount = (UINT32) Op->Common.Value.Integer;315316/*317* The byte list belongs to a buffer, and can be produced by either318* a ResourceTemplate, Unicode, quoted string, or a plain byte list.319*/320switch (Op->Common.Parent->Common.DisasmOpcode)321{322case ACPI_DASM_RESOURCE:323324AcpiDmResourceTemplate (325Info, Op->Common.Parent, ByteData, ByteCount);326break;327328case ACPI_DASM_STRING:329330AcpiDmIndent (Info->Level);331AcpiUtPrintString ((char *) ByteData, ACPI_UINT16_MAX);332AcpiOsPrintf ("\n");333break;334335case ACPI_DASM_UUID:336337AcpiDmUuid (Op);338break;339340case ACPI_DASM_UNICODE:341342AcpiDmUnicode (Op);343break;344345case ACPI_DASM_PLD_METHOD:346#if 0347AcpiDmDisasmByteList (Info->Level, ByteData, ByteCount);348#endif349AcpiDmPldBuffer (Info->Level, ByteData, ByteCount);350break;351352case ACPI_DASM_BUFFER:353default:354/*355* Not a resource, string, or unicode string.356* Just dump the buffer357*/358AcpiDmDisasmByteList (Info->Level, ByteData, ByteCount);359break;360}361}362363364/*******************************************************************************365*366* FUNCTION: AcpiDmIsUuidBuffer367*368* PARAMETERS: Op - Buffer Object to be examined369*370* RETURN: TRUE if buffer contains a UUID371*372* DESCRIPTION: Determine if a buffer Op contains a UUID373*374* To help determine whether the buffer is a UUID versus a raw data buffer,375* there a are a couple bytes we can look at:376*377* xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx378*379* The variant covered by the UUID specification is indicated by the two most380* significant bits of N being 1 0 (i.e., the hexadecimal N will always be381* 8, 9, A, or B).382*383* The variant covered by the UUID specification has five versions. For this384* variant, the four bits of M indicates the UUID version (i.e., the385* hexadecimal M will be either 1, 2, 3, 4, or 5).386*387******************************************************************************/388389BOOLEAN390AcpiDmIsUuidBuffer (391ACPI_PARSE_OBJECT *Op)392{393UINT8 *ByteData;394UINT32 ByteCount;395ACPI_PARSE_OBJECT *SizeOp;396ACPI_PARSE_OBJECT *NextOp;397398399/* Buffer size is the buffer argument */400401SizeOp = Op->Common.Value.Arg;402if (!SizeOp)403{404return (FALSE);405}406407/* Next, the initializer byte list to examine */408409NextOp = SizeOp->Common.Next;410if (!NextOp)411{412return (FALSE);413}414415/* Extract the byte list info */416417ByteData = NextOp->Named.Data;418ByteCount = (UINT32) NextOp->Common.Value.Integer;419420/* Byte count must be exactly 16 */421422if (ByteCount != UUID_BUFFER_LENGTH)423{424return (FALSE);425}426427/* Check for valid "M" and "N" values (see function header above) */428429if (((ByteData[7] & 0xF0) == 0x00) || /* M={1,2,3,4,5} */430((ByteData[7] & 0xF0) > 0x50) ||431((ByteData[8] & 0xF0) < 0x80) || /* N={8,9,A,B} */432((ByteData[8] & 0xF0) > 0xB0))433{434return (FALSE);435}436437/* Ignore the Size argument in the disassembly of this buffer op */438439SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;440return (TRUE);441}442443444/*******************************************************************************445*446* FUNCTION: AcpiDmUuid447*448* PARAMETERS: Op - Byte List op containing a UUID449*450* RETURN: None451*452* DESCRIPTION: Dump a buffer containing a UUID as a standard ASCII string.453*454* Output Format:455* In its canonical form, the UUID is represented by a string containing 32456* lowercase hexadecimal digits, displayed in 5 groups separated by hyphens.457* The complete form is 8-4-4-4-12 for a total of 36 characters (32458* alphanumeric characters representing hex digits and 4 hyphens). In bytes,459* 4-2-2-2-6. Example:460*461* ToUUID ("107ededd-d381-4fd7-8da9-08e9a6c79644")462*463******************************************************************************/464465static void466AcpiDmUuid (467ACPI_PARSE_OBJECT *Op)468{469UINT8 *Data;470const char *Description;471472473Data = ACPI_CAST_PTR (UINT8, Op->Named.Data);474475/* Emit the 36-byte UUID string in the proper format/order */476477AcpiOsPrintf (478"\"%2.2x%2.2x%2.2x%2.2x-"479"%2.2x%2.2x-"480"%2.2x%2.2x-"481"%2.2x%2.2x-"482"%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\")",483Data[3], Data[2], Data[1], Data[0],484Data[5], Data[4],485Data[7], Data[6],486Data[8], Data[9],487Data[10], Data[11], Data[12], Data[13], Data[14], Data[15]);488489/* Dump the UUID description string if available */490491Description = AcpiAhMatchUuid (Data);492if (Description)493{494AcpiOsPrintf (" /* %s */", Description);495}496else497{498AcpiOsPrintf (" /* Unknown UUID */");499}500}501502503/*******************************************************************************504*505* FUNCTION: AcpiDmIsUnicodeBuffer506*507* PARAMETERS: Op - Buffer Object to be examined508*509* RETURN: TRUE if buffer contains a UNICODE string510*511* DESCRIPTION: Determine if a buffer Op contains a Unicode string512*513******************************************************************************/514515BOOLEAN516AcpiDmIsUnicodeBuffer (517ACPI_PARSE_OBJECT *Op)518{519UINT8 *ByteData;520UINT32 ByteCount;521UINT32 WordCount;522ACPI_PARSE_OBJECT *SizeOp;523ACPI_PARSE_OBJECT *NextOp;524UINT32 i;525526527/* Buffer size is the buffer argument */528529SizeOp = Op->Common.Value.Arg;530if (!SizeOp)531{532return (FALSE);533}534535/* Next, the initializer byte list to examine */536537NextOp = SizeOp->Common.Next;538if (!NextOp)539{540return (FALSE);541}542543/* Extract the byte list info */544545ByteData = NextOp->Named.Data;546ByteCount = (UINT32) NextOp->Common.Value.Integer;547WordCount = ACPI_DIV_2 (ByteCount);548549/*550* Unicode string must have an even number of bytes and last551* word must be zero552*/553if ((!ByteCount) ||554(ByteCount < 4) ||555(ByteCount & 1) ||556((UINT16 *) (void *) ByteData)[WordCount - 1] != 0)557{558return (FALSE);559}560561/*562* For each word, 1st byte must be printable ascii, and the563* 2nd byte must be zero. This does not allow for escape564* sequences, but it is the most secure way to detect a565* unicode string.566*/567for (i = 0; i < (ByteCount - 2); i += 2)568{569if ((ByteData[i] == 0) ||570!(isprint (ByteData[i])) ||571(ByteData[(ACPI_SIZE) i + 1] != 0))572{573return (FALSE);574}575}576577/* Ignore the Size argument in the disassembly of this buffer op */578579SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;580return (TRUE);581}582583584/*******************************************************************************585*586* FUNCTION: AcpiDmIsStringBuffer587*588* PARAMETERS: Op - Buffer Object to be examined589*590* RETURN: TRUE if buffer contains a ASCII string, FALSE otherwise591*592* DESCRIPTION: Determine if a buffer Op contains a ASCII string593*594******************************************************************************/595596BOOLEAN597AcpiDmIsStringBuffer (598ACPI_PARSE_OBJECT *Op)599{600UINT8 *ByteData;601UINT32 ByteCount;602ACPI_PARSE_OBJECT *SizeOp;603ACPI_PARSE_OBJECT *NextOp;604UINT32 i;605606607/* Buffer size is the buffer argument */608609SizeOp = Op->Common.Value.Arg;610if (!SizeOp)611{612return (FALSE);613}614615/* Next, the initializer byte list to examine */616617NextOp = SizeOp->Common.Next;618if (!NextOp)619{620return (FALSE);621}622623/* Extract the byte list info */624625ByteData = NextOp->Named.Data;626ByteCount = (UINT32) NextOp->Common.Value.Integer;627628/* Last byte must be the null terminator */629630if ((!ByteCount) ||631(ByteCount < 2) ||632(ByteData[ByteCount-1] != 0))633{634return (FALSE);635}636637/*638* Check for a possible standalone resource EndTag, ignore it639* here. However, this sequence is also the string "Y", but640* this seems rare enough to be acceptable.641*/642if ((ByteCount == 2) && (ByteData[0] == 0x79))643{644return (FALSE);645}646647/* Check all bytes for ASCII */648649for (i = 0; i < (ByteCount - 1); i++)650{651/*652* TBD: allow some escapes (non-ascii chars).653* they will be handled in the string output routine654*/655656/* Not a string if not printable ascii */657658if (!isprint (ByteData[i]))659{660return (FALSE);661}662}663664return (TRUE);665}666667668/*******************************************************************************669*670* FUNCTION: AcpiDmIsPldBuffer671*672* PARAMETERS: Op - Buffer Object to be examined673*674* RETURN: TRUE if buffer appears to contain data produced via the675* ToPLD macro, FALSE otherwise676*677* DESCRIPTION: Determine if a buffer Op contains a _PLD structure678*679******************************************************************************/680681BOOLEAN682AcpiDmIsPldBuffer (683ACPI_PARSE_OBJECT *Op)684{685ACPI_NAMESPACE_NODE *Node;686ACPI_PARSE_OBJECT *SizeOp;687ACPI_PARSE_OBJECT *ByteListOp;688ACPI_PARSE_OBJECT *ParentOp;689UINT64 BufferSize;690UINT64 InitializerSize;691692693if (!Op)694{695return (FALSE);696}697698/*699* Get the BufferSize argument - Buffer(BufferSize)700* If the buffer was generated by the ToPld macro, it must701* be a BYTE constant.702*/703SizeOp = Op->Common.Value.Arg;704if (!SizeOp || SizeOp->Common.AmlOpcode != AML_BYTE_OP)705{706return (FALSE);707}708709/* Check the declared BufferSize, two possibilities */710711BufferSize = SizeOp->Common.Value.Integer;712if ((BufferSize != ACPI_PLD_REV1_BUFFER_SIZE) &&713(BufferSize != ACPI_PLD_REV2_BUFFER_SIZE))714{715return (FALSE);716}717718/*719* Check the initializer list length. This is the actual720* number of bytes in the buffer as counted by the AML parser.721* The declared BufferSize can be larger than the actual length.722* However, for the ToPLD macro, the BufferSize will be the same723* as the initializer list length.724*/725ByteListOp = SizeOp->Common.Next;726if (!ByteListOp)727{728return (FALSE); /* Zero-length buffer case */729}730731InitializerSize = ByteListOp->Common.Value.Integer;732if ((InitializerSize != ACPI_PLD_REV1_BUFFER_SIZE) &&733(InitializerSize != ACPI_PLD_REV2_BUFFER_SIZE))734{735return (FALSE);736}737738/* Final size check */739740if (BufferSize != InitializerSize)741{742return (FALSE);743}744745/* Now examine the buffer parent */746747ParentOp = Op->Common.Parent;748if (!ParentOp)749{750return (FALSE);751}752753/* Check for form: Name(_PLD, Buffer() {}). Not legal, however */754755if (ParentOp->Common.AmlOpcode == AML_NAME_OP)756{757Node = ParentOp->Common.Node;758759if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, METHOD_NAME__PLD))760{761/* Ignore the Size argument in the disassembly of this buffer op */762763SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;764return (TRUE);765}766767return (FALSE);768}769770/*771* Check for proper form: Name(_PLD, Package() {ToPLD()})772*773* Note: All other forms such as774* Return (Package() {ToPLD()})775* Local0 = ToPLD()776* etc. are not converted back to the ToPLD macro, because777* there is really no deterministic way to disassemble the buffer778* back to the ToPLD macro, other than trying to find the "_PLD"779* name780*/781if (ParentOp->Common.AmlOpcode == AML_PACKAGE_OP)782{783ParentOp = ParentOp->Common.Parent;784if (!ParentOp)785{786return (FALSE);787}788789if (ParentOp->Common.AmlOpcode == AML_NAME_OP)790{791Node = ParentOp->Common.Node;792793if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, METHOD_NAME__PLD))794{795/* Ignore the Size argument in the disassembly of this buffer op */796797SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;798return (TRUE);799}800}801}802803return (FALSE);804}805806807/*******************************************************************************808*809* FUNCTION: AcpiDmFindNameByIndex810*811* PARAMETERS: Index - Index of array to check812* List - Array to reference813*814* RETURN: String from List or empty string815*816* DESCRIPTION: Finds and returns the char string located at the given index817* position in List.818*819******************************************************************************/820821static const char *822AcpiDmFindNameByIndex (823UINT64 Index,824const char **List)825{826const char *NameString;827UINT32 i;828829830/* Bounds check */831832NameString = List[0];833i = 0;834835while (NameString)836{837i++;838NameString = List[i];839}840841if (Index >= i)842{843/* TBD: Add error msg */844845return ("");846}847848return (List[Index]);849}850851852/*******************************************************************************853*854* FUNCTION: AcpiDmPldBuffer855*856* PARAMETERS: Level - Current source code indentation level857* ByteData - Pointer to the byte list858* ByteCount - Length of the byte list859*860* RETURN: None861*862* DESCRIPTION: Dump and format the contents of a _PLD buffer object863*864******************************************************************************/865866#define ACPI_PLD_OUTPUT08 "%*.s%-22s = 0x%X,\n", ACPI_MUL_4 (Level), " "867#define ACPI_PLD_OUTPUT08P "%*.s%-22s = 0x%X)\n", ACPI_MUL_4 (Level), " "868#define ACPI_PLD_OUTPUT16 "%*.s%-22s = 0x%X,\n", ACPI_MUL_4 (Level), " "869#define ACPI_PLD_OUTPUT16P "%*.s%-22s = 0x%X)\n", ACPI_MUL_4 (Level), " "870#define ACPI_PLD_OUTPUT24 "%*.s%-22s = 0x%X,\n", ACPI_MUL_4 (Level), " "871#define ACPI_PLD_OUTPUTSTR "%*.s%-22s = \"%s\",\n", ACPI_MUL_4 (Level), " "872873static void874AcpiDmPldBuffer (875UINT32 Level,876UINT8 *ByteData,877UINT32 ByteCount)878{879ACPI_PLD_INFO *PldInfo;880ACPI_STATUS Status;881882883/* Check for valid byte count */884885if (ByteCount < ACPI_PLD_REV1_BUFFER_SIZE)886{887return;888}889890/* Convert _PLD buffer to local _PLD struct */891892Status = AcpiDecodePldBuffer (ByteData, ByteCount, &PldInfo);893if (ACPI_FAILURE (Status))894{895return;896}897898AcpiOsPrintf ("\n");899900/* First 32-bit dword */901902AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Revision", PldInfo->Revision);903AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_IgnoreColor", PldInfo->IgnoreColor);904AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Red", PldInfo->Red);905AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Green", PldInfo->Green);906AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Blue", PldInfo->Blue);907908/* Second 32-bit dword */909910AcpiOsPrintf (ACPI_PLD_OUTPUT16, "PLD_Width", PldInfo->Width);911AcpiOsPrintf (ACPI_PLD_OUTPUT16, "PLD_Height", PldInfo->Height);912913/* Third 32-bit dword */914915AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_UserVisible", PldInfo->UserVisible);916AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Dock", PldInfo->Dock);917AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Lid", PldInfo->Lid);918AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_Panel",919AcpiDmFindNameByIndex(PldInfo->Panel, AcpiGbl_PldPanelList));920921AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_VerticalPosition",922AcpiDmFindNameByIndex(PldInfo->VerticalPosition, AcpiGbl_PldVerticalPositionList));923924AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_HorizontalPosition",925AcpiDmFindNameByIndex(PldInfo->HorizontalPosition, AcpiGbl_PldHorizontalPositionList));926927AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_Shape",928AcpiDmFindNameByIndex(PldInfo->Shape, AcpiGbl_PldShapeList));929AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_GroupOrientation", PldInfo->GroupOrientation);930931AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_GroupToken", PldInfo->GroupToken);932AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_GroupPosition", PldInfo->GroupPosition);933AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Bay", PldInfo->Bay);934935/* Fourth 32-bit dword */936937AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Ejectable", PldInfo->Ejectable);938AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_EjectRequired", PldInfo->OspmEjectRequired);939AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_CabinetNumber", PldInfo->CabinetNumber);940AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_CardCageNumber", PldInfo->CardCageNumber);941AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Reference", PldInfo->Reference);942AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Rotation", PldInfo->Rotation);943944if (ByteCount >= ACPI_PLD_REV2_BUFFER_SIZE)945{946AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Order", PldInfo->Order);947948/* Fifth 32-bit dword */949950AcpiOsPrintf (ACPI_PLD_OUTPUT16, "PLD_VerticalOffset", PldInfo->VerticalOffset);951AcpiOsPrintf (ACPI_PLD_OUTPUT16P, "PLD_HorizontalOffset", PldInfo->HorizontalOffset);952}953else /* Rev 1 buffer */954{955AcpiOsPrintf (ACPI_PLD_OUTPUT08P, "PLD_Order", PldInfo->Order);956}957958ACPI_FREE (PldInfo);959}960961962/*******************************************************************************963*964* FUNCTION: AcpiDmUnicode965*966* PARAMETERS: Op - Byte List op containing Unicode string967*968* RETURN: None969*970* DESCRIPTION: Dump Unicode string as a standard ASCII string. (Remove971* the extra zero bytes).972*973******************************************************************************/974975static void976AcpiDmUnicode (977ACPI_PARSE_OBJECT *Op)978{979UINT16 *WordData;980UINT32 WordCount;981UINT32 i;982int OutputValue;983984985/* Extract the buffer info as a WORD buffer */986987WordData = ACPI_CAST_PTR (UINT16, Op->Named.Data);988WordCount = ACPI_DIV_2 (((UINT32) Op->Common.Value.Integer));989990/* Write every other byte as an ASCII character */991992AcpiOsPrintf ("\"");993for (i = 0; i < (WordCount - 1); i++)994{995OutputValue = (int) WordData[i];996997/* Handle values that must be escaped */998999if ((OutputValue == '\"') ||1000(OutputValue == '\\'))1001{1002AcpiOsPrintf ("\\%c", OutputValue);1003}1004else if (!isprint (OutputValue))1005{1006AcpiOsPrintf ("\\x%2.2X", OutputValue);1007}1008else1009{1010AcpiOsPrintf ("%c", OutputValue);1011}1012}10131014AcpiOsPrintf ("\")");1015}101610171018/*******************************************************************************1019*1020* FUNCTION: AcpiDmGetHardwareIdType1021*1022* PARAMETERS: Op - Op to be examined1023*1024* RETURN: None1025*1026* DESCRIPTION: Determine the type of the argument to a _HID or _CID1027* 1) Strings are allowed1028* 2) If Integer, determine if it is a valid EISAID1029*1030******************************************************************************/10311032static void1033AcpiDmGetHardwareIdType (1034ACPI_PARSE_OBJECT *Op)1035{1036UINT32 BigEndianId;1037UINT32 Prefix[3];1038UINT32 i;103910401041switch (Op->Common.AmlOpcode)1042{1043case AML_STRING_OP:10441045/* Mark this string as an _HID/_CID string */10461047Op->Common.DisasmOpcode = ACPI_DASM_HID_STRING;1048break;10491050case AML_WORD_OP:1051case AML_DWORD_OP:10521053/* Determine if a Word/Dword is a valid encoded EISAID */10541055/* Swap from little-endian to big-endian to simplify conversion */10561057BigEndianId = AcpiUtDwordByteSwap ((UINT32) Op->Common.Value.Integer);10581059/* Create the 3 leading ASCII letters */10601061Prefix[0] = ((BigEndianId >> 26) & 0x1F) + 0x40;1062Prefix[1] = ((BigEndianId >> 21) & 0x1F) + 0x40;1063Prefix[2] = ((BigEndianId >> 16) & 0x1F) + 0x40;10641065/* Verify that all 3 are ascii and alpha */10661067for (i = 0; i < 3; i++)1068{1069if (!ACPI_IS_ASCII (Prefix[i]) ||1070!isalpha (Prefix[i]))1071{1072return;1073}1074}10751076/* Mark this node as convertible to an EISA ID string */10771078Op->Common.DisasmOpcode = ACPI_DASM_EISAID;1079break;10801081default:1082break;1083}1084}108510861087/*******************************************************************************1088*1089* FUNCTION: AcpiDmCheckForHardwareId1090*1091* PARAMETERS: Op - Op to be examined1092*1093* RETURN: None1094*1095* DESCRIPTION: Determine if a Name() Op is a _HID/_CID.1096*1097******************************************************************************/10981099void1100AcpiDmCheckForHardwareId (1101ACPI_PARSE_OBJECT *Op)1102{1103UINT32 Name;1104ACPI_PARSE_OBJECT *NextOp;110511061107/* Get the NameSegment */11081109Name = AcpiPsGetName (Op);1110if (!Name)1111{1112return;1113}11141115NextOp = AcpiPsGetDepthNext (NULL, Op);1116if (!NextOp)1117{1118return;1119}11201121/* Check for _HID - has one argument */11221123if (ACPI_COMPARE_NAMESEG (&Name, METHOD_NAME__HID))1124{1125AcpiDmGetHardwareIdType (NextOp);1126return;1127}11281129/* Exit if not _CID */11301131if (!ACPI_COMPARE_NAMESEG (&Name, METHOD_NAME__CID))1132{1133return;1134}11351136/* _CID can contain a single argument or a package */11371138if (NextOp->Common.AmlOpcode != AML_PACKAGE_OP)1139{1140AcpiDmGetHardwareIdType (NextOp);1141return;1142}11431144/* _CID with Package: get the package length, check all elements */11451146NextOp = AcpiPsGetDepthNext (NULL, NextOp);1147if (!NextOp)1148{1149return;1150}11511152/* Don't need to use the length, just walk the peer list */11531154NextOp = NextOp->Common.Next;1155while (NextOp)1156{1157AcpiDmGetHardwareIdType (NextOp);1158NextOp = NextOp->Common.Next;1159}1160}116111621163/*******************************************************************************1164*1165* FUNCTION: AcpiDmDecompressEisaId1166*1167* PARAMETERS: EncodedId - Raw encoded EISA ID.1168*1169* RETURN: None1170*1171* DESCRIPTION: Convert an encoded EISAID back to the original ASCII String1172* and emit the correct ASL statement. If the ID is known, emit1173* a description of the ID as a comment.1174*1175******************************************************************************/11761177void1178AcpiDmDecompressEisaId (1179UINT32 EncodedId)1180{1181char IdBuffer[ACPI_EISAID_STRING_SIZE];1182const AH_DEVICE_ID *Info;118311841185/* Convert EISAID to a string an emit the statement */11861187AcpiExEisaIdToString (IdBuffer, EncodedId);1188AcpiOsPrintf ("EisaId (\"%s\")", IdBuffer);11891190/* If we know about the ID, emit the description */11911192Info = AcpiAhMatchHardwareId (IdBuffer);1193if (Info)1194{1195AcpiOsPrintf (" /* %s */", Info->Description);1196}1197}119811991200