The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/acpica/components/disassembler/dmbuffer.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*******************************************************************************
    2  *
    3  * Module Name: dmbuffer - AML disassembler, buffer and string support
    4  *
    5  ******************************************************************************/
    6 
    7 /******************************************************************************
    8  *
    9  * 1. Copyright Notice
   10  *
   11  * Some or all of this work - Copyright (c) 1999 - 2022, Intel Corp.
   12  * All rights reserved.
   13  *
   14  * 2. License
   15  *
   16  * 2.1. This is your license from Intel Corp. under its intellectual property
   17  * rights. You may have additional license terms from the party that provided
   18  * you this software, covering your right to use that party's intellectual
   19  * property rights.
   20  *
   21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
   22  * copy of the source code appearing in this file ("Covered Code") an
   23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
   24  * base code distributed originally by Intel ("Original Intel Code") to copy,
   25  * make derivatives, distribute, use and display any portion of the Covered
   26  * Code in any form, with the right to sublicense such rights; and
   27  *
   28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
   29  * license (with the right to sublicense), under only those claims of Intel
   30  * patents that are infringed by the Original Intel Code, to make, use, sell,
   31  * offer to sell, and import the Covered Code and derivative works thereof
   32  * solely to the minimum extent necessary to exercise the above copyright
   33  * license, and in no event shall the patent license extend to any additions
   34  * to or modifications of the Original Intel Code. No other license or right
   35  * is granted directly or by implication, estoppel or otherwise;
   36  *
   37  * The above copyright and patent license is granted only if the following
   38  * conditions are met:
   39  *
   40  * 3. Conditions
   41  *
   42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
   43  * Redistribution of source code of any substantial portion of the Covered
   44  * Code or modification with rights to further distribute source must include
   45  * the above Copyright Notice, the above License, this list of Conditions,
   46  * and the following Disclaimer and Export Compliance provision. In addition,
   47  * Licensee must cause all Covered Code to which Licensee contributes to
   48  * contain a file documenting the changes Licensee made to create that Covered
   49  * Code and the date of any change. Licensee must include in that file the
   50  * documentation of any changes made by any predecessor Licensee. Licensee
   51  * must include a prominent statement that the modification is derived,
   52  * directly or indirectly, from Original Intel Code.
   53  *
   54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
   55  * Redistribution of source code of any substantial portion of the Covered
   56  * Code or modification without rights to further distribute source must
   57  * include the following Disclaimer and Export Compliance provision in the
   58  * documentation and/or other materials provided with distribution. In
   59  * addition, Licensee may not authorize further sublicense of source of any
   60  * portion of the Covered Code, and must include terms to the effect that the
   61  * license from Licensee to its licensee is limited to the intellectual
   62  * property embodied in the software Licensee provides to its licensee, and
   63  * not to intellectual property embodied in modifications its licensee may
   64  * make.
   65  *
   66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
   67  * substantial portion of the Covered Code or modification must reproduce the
   68  * above Copyright Notice, and the following Disclaimer and Export Compliance
   69  * provision in the documentation and/or other materials provided with the
   70  * distribution.
   71  *
   72  * 3.4. Intel retains all right, title, and interest in and to the Original
   73  * Intel Code.
   74  *
   75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
   76  * Intel shall be used in advertising or otherwise to promote the sale, use or
   77  * other dealings in products derived from or relating to the Covered Code
   78  * without prior written authorization from Intel.
   79  *
   80  * 4. Disclaimer and Export Compliance
   81  *
   82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
   83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
   84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
   85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
   86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
   87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
   88  * PARTICULAR PURPOSE.
   89  *
   90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
   91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
   92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
   93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
   94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
   95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
   96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
   97  * LIMITED REMEDY.
   98  *
   99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  100  * software or system incorporating such software without first obtaining any
  101  * required license or other approval from the U. S. Department of Commerce or
  102  * any other agency or department of the United States Government. In the
  103  * event Licensee exports any such software from the United States or
  104  * re-exports any such software from a foreign destination, Licensee shall
  105  * ensure that the distribution and export/re-export of the software is in
  106  * compliance with all laws, regulations, orders, or other restrictions of the
  107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  108  * any of its subsidiaries will export/re-export any technical data, process,
  109  * software, or service, directly or indirectly, to any country for which the
  110  * United States government or any agency thereof requires an export license,
  111  * other governmental approval, or letter of assurance, without first obtaining
  112  * such license, approval or letter.
  113  *
  114  *****************************************************************************
  115  *
  116  * Alternatively, you may choose to be licensed under the terms of the
  117  * following license:
  118  *
  119  * Redistribution and use in source and binary forms, with or without
  120  * modification, are permitted provided that the following conditions
  121  * are met:
  122  * 1. Redistributions of source code must retain the above copyright
  123  *    notice, this list of conditions, and the following disclaimer,
  124  *    without modification.
  125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  126  *    substantially similar to the "NO WARRANTY" disclaimer below
  127  *    ("Disclaimer") and any redistribution must be conditioned upon
  128  *    including a substantially similar Disclaimer requirement for further
  129  *    binary redistribution.
  130  * 3. Neither the names of the above-listed copyright holders nor the names
  131  *    of any contributors may be used to endorse or promote products derived
  132  *    from this software without specific prior written permission.
  133  *
  134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  145  *
  146  * Alternatively, you may choose to be licensed under the terms of the
  147  * GNU General Public License ("GPL") version 2 as published by the Free
  148  * Software Foundation.
  149  *
  150  *****************************************************************************/
  151 
  152 #include <contrib/dev/acpica/include/acpi.h>
  153 #include <contrib/dev/acpica/include/accommon.h>
  154 #include <contrib/dev/acpica/include/acutils.h>
  155 #include <contrib/dev/acpica/include/acdisasm.h>
  156 #include <contrib/dev/acpica/include/acparser.h>
  157 #include <contrib/dev/acpica/include/amlcode.h>
  158 #include <contrib/dev/acpica/include/acinterp.h>
  159 
  160 
  161 #define _COMPONENT          ACPI_CA_DEBUGGER
  162         ACPI_MODULE_NAME    ("dmbuffer")
  163 
  164 /* Local prototypes */
  165 
  166 static void
  167 AcpiDmUuid (
  168     ACPI_PARSE_OBJECT       *Op);
  169 
  170 static void
  171 AcpiDmUnicode (
  172     ACPI_PARSE_OBJECT       *Op);
  173 
  174 static void
  175 AcpiDmGetHardwareIdType (
  176     ACPI_PARSE_OBJECT       *Op);
  177 
  178 static void
  179 AcpiDmPldBuffer (
  180     UINT32                  Level,
  181     UINT8                   *ByteData,
  182     UINT32                  ByteCount);
  183 
  184 static const char *
  185 AcpiDmFindNameByIndex (
  186     UINT64                  Index,
  187     const char              **List);
  188 
  189 
  190 #define ACPI_BUFFER_BYTES_PER_LINE      8
  191 
  192 
  193 /*******************************************************************************
  194  *
  195  * FUNCTION:    AcpiDmDisasmByteList
  196  *
  197  * PARAMETERS:  Level               - Current source code indentation level
  198  *              ByteData            - Pointer to the byte list
  199  *              ByteCount           - Length of the byte list
  200  *
  201  * RETURN:      None
  202  *
  203  * DESCRIPTION: Dump an AML "ByteList" in Hex format. 8 bytes per line, prefixed
  204  *              with the hex buffer offset.
  205  *
  206  ******************************************************************************/
  207 
  208 void
  209 AcpiDmDisasmByteList (
  210     UINT32                  Level,
  211     UINT8                   *ByteData,
  212     UINT32                  ByteCount)
  213 {
  214     UINT32                  i;
  215     UINT32                  j;
  216     UINT32                  CurrentIndex;
  217     UINT8                   BufChar;
  218 
  219 
  220     if (!ByteCount)
  221     {
  222         return;
  223     }
  224 
  225     for (i = 0; i < ByteCount; i += ACPI_BUFFER_BYTES_PER_LINE)
  226     {
  227         /* Line indent and offset prefix for each new line */
  228 
  229         AcpiDmIndent (Level);
  230         if (ByteCount > ACPI_BUFFER_BYTES_PER_LINE)
  231         {
  232             AcpiOsPrintf ("/* %04X */ ", i);
  233         }
  234 
  235         /* Dump the actual hex values */
  236 
  237         for (j = 0; j < ACPI_BUFFER_BYTES_PER_LINE; j++)
  238         {
  239             CurrentIndex = i + j;
  240             if (CurrentIndex >= ByteCount)
  241             {
  242                 /* Dump fill spaces */
  243 
  244                 AcpiOsPrintf ("      ");
  245                 continue;
  246             }
  247 
  248             AcpiOsPrintf (" 0x%2.2X", ByteData[CurrentIndex]);
  249 
  250             /* Add comma if there are more bytes to display */
  251 
  252             if (CurrentIndex < (ByteCount - 1))
  253             {
  254                 AcpiOsPrintf (",");
  255             }
  256             else
  257             {
  258                 AcpiOsPrintf (" ");
  259             }
  260         }
  261 
  262         /* Dump the ASCII equivalents within a comment */
  263 
  264         AcpiOsPrintf ("  // ");
  265         for (j = 0; j < ACPI_BUFFER_BYTES_PER_LINE; j++)
  266         {
  267             CurrentIndex = i + j;
  268             if (CurrentIndex >= ByteCount)
  269             {
  270                 break;
  271             }
  272 
  273             BufChar = ByteData[CurrentIndex];
  274             if (isprint (BufChar))
  275             {
  276                 AcpiOsPrintf ("%c", BufChar);
  277             }
  278             else
  279             {
  280                 AcpiOsPrintf (".");
  281             }
  282         }
  283 
  284         /* Finished with this line */
  285 
  286         AcpiOsPrintf ("\n");
  287     }
  288 }
  289 
  290 
  291 /*******************************************************************************
  292  *
  293  * FUNCTION:    AcpiDmByteList
  294  *
  295  * PARAMETERS:  Info            - Parse tree walk info
  296  *              Op              - Byte list op
  297  *
  298  * RETURN:      None
  299  *
  300  * DESCRIPTION: Dump a buffer byte list, handling the various types of buffers.
  301  *              Buffer type must be already set in the Op DisasmOpcode.
  302  *
  303  ******************************************************************************/
  304 
  305 void
  306 AcpiDmByteList (
  307     ACPI_OP_WALK_INFO       *Info,
  308     ACPI_PARSE_OBJECT       *Op)
  309 {
  310     UINT8                   *ByteData;
  311     UINT32                  ByteCount;
  312 
  313 
  314     ByteData = Op->Named.Data;
  315     ByteCount = (UINT32) Op->Common.Value.Integer;
  316 
  317     /*
  318      * The byte list belongs to a buffer, and can be produced by either
  319      * a ResourceTemplate, Unicode, quoted string, or a plain byte list.
  320      */
  321     switch (Op->Common.Parent->Common.DisasmOpcode)
  322     {
  323     case ACPI_DASM_RESOURCE:
  324 
  325         AcpiDmResourceTemplate (
  326             Info, Op->Common.Parent, ByteData, ByteCount);
  327         break;
  328 
  329     case ACPI_DASM_STRING:
  330 
  331         AcpiDmIndent (Info->Level);
  332         AcpiUtPrintString ((char *) ByteData, ACPI_UINT16_MAX);
  333         AcpiOsPrintf ("\n");
  334         break;
  335 
  336     case ACPI_DASM_UUID:
  337 
  338         AcpiDmUuid (Op);
  339         break;
  340 
  341     case ACPI_DASM_UNICODE:
  342 
  343         AcpiDmUnicode (Op);
  344         break;
  345 
  346     case ACPI_DASM_PLD_METHOD:
  347 #if 0
  348         AcpiDmDisasmByteList (Info->Level, ByteData, ByteCount);
  349 #endif
  350         AcpiDmPldBuffer (Info->Level, ByteData, ByteCount);
  351         break;
  352 
  353     case ACPI_DASM_BUFFER:
  354     default:
  355         /*
  356          * Not a resource, string, or unicode string.
  357          * Just dump the buffer
  358          */
  359         AcpiDmDisasmByteList (Info->Level, ByteData, ByteCount);
  360         break;
  361     }
  362 }
  363 
  364 
  365 /*******************************************************************************
  366  *
  367  * FUNCTION:    AcpiDmIsUuidBuffer
  368  *
  369  * PARAMETERS:  Op              - Buffer Object to be examined
  370  *
  371  * RETURN:      TRUE if buffer contains a UUID
  372  *
  373  * DESCRIPTION: Determine if a buffer Op contains a UUID
  374  *
  375  * To help determine whether the buffer is a UUID versus a raw data buffer,
  376  * there a are a couple bytes we can look at:
  377  *
  378  *    xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
  379  *
  380  * The variant covered by the UUID specification is indicated by the two most
  381  * significant bits of N being 1 0 (i.e., the hexadecimal N will always be
  382  * 8, 9, A, or B).
  383  *
  384  * The variant covered by the UUID specification has five versions. For this
  385  * variant, the four bits of M indicates the UUID version (i.e., the
  386  * hexadecimal M will be either 1, 2, 3, 4, or 5).
  387  *
  388  ******************************************************************************/
  389 
  390 BOOLEAN
  391 AcpiDmIsUuidBuffer (
  392     ACPI_PARSE_OBJECT       *Op)
  393 {
  394     UINT8                   *ByteData;
  395     UINT32                  ByteCount;
  396     ACPI_PARSE_OBJECT       *SizeOp;
  397     ACPI_PARSE_OBJECT       *NextOp;
  398 
  399 
  400     /* Buffer size is the buffer argument */
  401 
  402     SizeOp = Op->Common.Value.Arg;
  403     if (!SizeOp)
  404     {
  405         return (FALSE);
  406     }
  407 
  408     /* Next, the initializer byte list to examine */
  409 
  410     NextOp = SizeOp->Common.Next;
  411     if (!NextOp)
  412     {
  413         return (FALSE);
  414     }
  415 
  416     /* Extract the byte list info */
  417 
  418     ByteData = NextOp->Named.Data;
  419     ByteCount = (UINT32) NextOp->Common.Value.Integer;
  420 
  421     /* Byte count must be exactly 16 */
  422 
  423     if (ByteCount != UUID_BUFFER_LENGTH)
  424     {
  425         return (FALSE);
  426     }
  427 
  428     /* Check for valid "M" and "N" values (see function header above) */
  429 
  430     if (((ByteData[7] & 0xF0) == 0x00) || /* M={1,2,3,4,5} */
  431         ((ByteData[7] & 0xF0) > 0x50)  ||
  432         ((ByteData[8] & 0xF0) < 0x80)  || /* N={8,9,A,B} */
  433         ((ByteData[8] & 0xF0) > 0xB0))
  434     {
  435         return (FALSE);
  436     }
  437 
  438     /* Ignore the Size argument in the disassembly of this buffer op */
  439 
  440     SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
  441     return (TRUE);
  442 }
  443 
  444 
  445 /*******************************************************************************
  446  *
  447  * FUNCTION:    AcpiDmUuid
  448  *
  449  * PARAMETERS:  Op              - Byte List op containing a UUID
  450  *
  451  * RETURN:      None
  452  *
  453  * DESCRIPTION: Dump a buffer containing a UUID as a standard ASCII string.
  454  *
  455  * Output Format:
  456  * In its canonical form, the UUID is represented by a string containing 32
  457  * lowercase hexadecimal digits, displayed in 5 groups separated by hyphens.
  458  * The complete form is 8-4-4-4-12 for a total of 36 characters (32
  459  * alphanumeric characters representing hex digits and 4 hyphens). In bytes,
  460  * 4-2-2-2-6. Example:
  461  *
  462  *    ToUUID ("107ededd-d381-4fd7-8da9-08e9a6c79644")
  463  *
  464  ******************************************************************************/
  465 
  466 static void
  467 AcpiDmUuid (
  468     ACPI_PARSE_OBJECT       *Op)
  469 {
  470     UINT8                   *Data;
  471     const char              *Description;
  472 
  473 
  474     Data = ACPI_CAST_PTR (UINT8, Op->Named.Data);
  475 
  476     /* Emit the 36-byte UUID string in the proper format/order */
  477 
  478     AcpiOsPrintf (
  479         "\"%2.2x%2.2x%2.2x%2.2x-"
  480         "%2.2x%2.2x-"
  481         "%2.2x%2.2x-"
  482         "%2.2x%2.2x-"
  483         "%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\")",
  484         Data[3], Data[2], Data[1], Data[0],
  485         Data[5], Data[4],
  486         Data[7], Data[6],
  487         Data[8], Data[9],
  488         Data[10], Data[11], Data[12], Data[13], Data[14], Data[15]);
  489 
  490     /* Dump the UUID description string if available */
  491 
  492     Description = AcpiAhMatchUuid (Data);
  493     if (Description)
  494     {
  495         AcpiOsPrintf (" /* %s */", Description);
  496     }
  497     else
  498     {
  499         AcpiOsPrintf (" /* Unknown UUID */");
  500     }
  501 }
  502 
  503 
  504 /*******************************************************************************
  505  *
  506  * FUNCTION:    AcpiDmIsUnicodeBuffer
  507  *
  508  * PARAMETERS:  Op              - Buffer Object to be examined
  509  *
  510  * RETURN:      TRUE if buffer contains a UNICODE string
  511  *
  512  * DESCRIPTION: Determine if a buffer Op contains a Unicode string
  513  *
  514  ******************************************************************************/
  515 
  516 BOOLEAN
  517 AcpiDmIsUnicodeBuffer (
  518     ACPI_PARSE_OBJECT       *Op)
  519 {
  520     UINT8                   *ByteData;
  521     UINT32                  ByteCount;
  522     UINT32                  WordCount;
  523     ACPI_PARSE_OBJECT       *SizeOp;
  524     ACPI_PARSE_OBJECT       *NextOp;
  525     UINT32                  i;
  526 
  527 
  528     /* Buffer size is the buffer argument */
  529 
  530     SizeOp = Op->Common.Value.Arg;
  531     if (!SizeOp)
  532     {
  533         return (FALSE);
  534     }
  535 
  536     /* Next, the initializer byte list to examine */
  537 
  538     NextOp = SizeOp->Common.Next;
  539     if (!NextOp)
  540     {
  541         return (FALSE);
  542     }
  543 
  544     /* Extract the byte list info */
  545 
  546     ByteData = NextOp->Named.Data;
  547     ByteCount = (UINT32) NextOp->Common.Value.Integer;
  548     WordCount = ACPI_DIV_2 (ByteCount);
  549 
  550     /*
  551      * Unicode string must have an even number of bytes and last
  552      * word must be zero
  553      */
  554     if ((!ByteCount)     ||
  555          (ByteCount < 4) ||
  556          (ByteCount & 1) ||
  557         ((UINT16 *) (void *) ByteData)[WordCount - 1] != 0)
  558     {
  559         return (FALSE);
  560     }
  561 
  562     /*
  563      * For each word, 1st byte must be printable ascii, and the
  564      * 2nd byte must be zero. This does not allow for escape
  565      * sequences, but it is the most secure way to detect a
  566      * unicode string.
  567      */
  568     for (i = 0; i < (ByteCount - 2); i += 2)
  569     {
  570         if ((ByteData[i] == 0) ||
  571             !(isprint (ByteData[i])) ||
  572             (ByteData[(ACPI_SIZE) i + 1] != 0))
  573         {
  574             return (FALSE);
  575         }
  576     }
  577 
  578     /* Ignore the Size argument in the disassembly of this buffer op */
  579 
  580     SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
  581     return (TRUE);
  582 }
  583 
  584 
  585 /*******************************************************************************
  586  *
  587  * FUNCTION:    AcpiDmIsStringBuffer
  588  *
  589  * PARAMETERS:  Op              - Buffer Object to be examined
  590  *
  591  * RETURN:      TRUE if buffer contains a ASCII string, FALSE otherwise
  592  *
  593  * DESCRIPTION: Determine if a buffer Op contains a ASCII string
  594  *
  595  ******************************************************************************/
  596 
  597 BOOLEAN
  598 AcpiDmIsStringBuffer (
  599     ACPI_PARSE_OBJECT       *Op)
  600 {
  601     UINT8                   *ByteData;
  602     UINT32                  ByteCount;
  603     ACPI_PARSE_OBJECT       *SizeOp;
  604     ACPI_PARSE_OBJECT       *NextOp;
  605     UINT32                  i;
  606 
  607 
  608     /* Buffer size is the buffer argument */
  609 
  610     SizeOp = Op->Common.Value.Arg;
  611     if (!SizeOp)
  612     {
  613         return (FALSE);
  614     }
  615 
  616     /* Next, the initializer byte list to examine */
  617 
  618     NextOp = SizeOp->Common.Next;
  619     if (!NextOp)
  620     {
  621         return (FALSE);
  622     }
  623 
  624     /* Extract the byte list info */
  625 
  626     ByteData = NextOp->Named.Data;
  627     ByteCount = (UINT32) NextOp->Common.Value.Integer;
  628 
  629     /* Last byte must be the null terminator */
  630 
  631     if ((!ByteCount)     ||
  632          (ByteCount < 2) ||
  633          (ByteData[ByteCount-1] != 0))
  634     {
  635         return (FALSE);
  636     }
  637 
  638     /*
  639      * Check for a possible standalone resource EndTag, ignore it
  640      * here. However, this sequence is also the string "Y", but
  641      * this seems rare enough to be acceptable.
  642      */
  643     if ((ByteCount == 2) && (ByteData[0] == 0x79))
  644     {
  645         return (FALSE);
  646     }
  647 
  648     /* Check all bytes for ASCII */
  649 
  650     for (i = 0; i < (ByteCount - 1); i++)
  651     {
  652         /*
  653          * TBD: allow some escapes (non-ascii chars).
  654          * they will be handled in the string output routine
  655          */
  656 
  657         /* Not a string if not printable ascii */
  658 
  659         if (!isprint (ByteData[i]))
  660         {
  661             return (FALSE);
  662         }
  663     }
  664 
  665     return (TRUE);
  666 }
  667 
  668 
  669 /*******************************************************************************
  670  *
  671  * FUNCTION:    AcpiDmIsPldBuffer
  672  *
  673  * PARAMETERS:  Op                  - Buffer Object to be examined
  674  *
  675  * RETURN:      TRUE if buffer appears to contain data produced via the
  676  *              ToPLD macro, FALSE otherwise
  677  *
  678  * DESCRIPTION: Determine if a buffer Op contains a _PLD structure
  679  *
  680  ******************************************************************************/
  681 
  682 BOOLEAN
  683 AcpiDmIsPldBuffer (
  684     ACPI_PARSE_OBJECT       *Op)
  685 {
  686     ACPI_NAMESPACE_NODE     *Node;
  687     ACPI_PARSE_OBJECT       *SizeOp;
  688     ACPI_PARSE_OBJECT       *ByteListOp;
  689     ACPI_PARSE_OBJECT       *ParentOp;
  690     UINT64                  BufferSize;
  691     UINT64                  InitializerSize;
  692 
  693 
  694     if (!Op)
  695     {
  696         return (FALSE);
  697     }
  698 
  699     /*
  700      * Get the BufferSize argument - Buffer(BufferSize)
  701      * If the buffer was generated by the ToPld macro, it must
  702      * be a BYTE constant.
  703      */
  704     SizeOp = Op->Common.Value.Arg;
  705     if (!SizeOp || SizeOp->Common.AmlOpcode != AML_BYTE_OP)
  706     {
  707         return (FALSE);
  708     }
  709 
  710     /* Check the declared BufferSize, two possibilities */
  711 
  712     BufferSize = SizeOp->Common.Value.Integer;
  713     if ((BufferSize != ACPI_PLD_REV1_BUFFER_SIZE) &&
  714         (BufferSize != ACPI_PLD_REV2_BUFFER_SIZE))
  715     {
  716         return (FALSE);
  717     }
  718 
  719     /*
  720      * Check the initializer list length. This is the actual
  721      * number of bytes in the buffer as counted by the AML parser.
  722      * The declared BufferSize can be larger than the actual length.
  723      * However, for the ToPLD macro, the BufferSize will be the same
  724      * as the initializer list length.
  725      */
  726     ByteListOp = SizeOp->Common.Next;
  727     if (!ByteListOp)
  728     {
  729         return (FALSE); /* Zero-length buffer case */
  730     }
  731 
  732     InitializerSize = ByteListOp->Common.Value.Integer;
  733     if ((InitializerSize != ACPI_PLD_REV1_BUFFER_SIZE) &&
  734         (InitializerSize != ACPI_PLD_REV2_BUFFER_SIZE))
  735     {
  736         return (FALSE);
  737     }
  738 
  739     /* Final size check */
  740 
  741     if (BufferSize != InitializerSize)
  742     {
  743         return (FALSE);
  744     }
  745 
  746     /* Now examine the buffer parent */
  747 
  748     ParentOp = Op->Common.Parent;
  749     if (!ParentOp)
  750     {
  751         return (FALSE);
  752     }
  753 
  754     /* Check for form: Name(_PLD, Buffer() {}). Not legal, however */
  755 
  756     if (ParentOp->Common.AmlOpcode == AML_NAME_OP)
  757     {
  758         Node = ParentOp->Common.Node;
  759 
  760         if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, METHOD_NAME__PLD))
  761         {
  762             /* Ignore the Size argument in the disassembly of this buffer op */
  763 
  764             SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
  765             return (TRUE);
  766         }
  767 
  768         return (FALSE);
  769     }
  770 
  771     /*
  772      * Check for proper form: Name(_PLD, Package() {ToPLD()})
  773      *
  774      * Note: All other forms such as
  775      *      Return (Package() {ToPLD()})
  776      *      Local0 = ToPLD()
  777      * etc. are not converted back to the ToPLD macro, because
  778      * there is really no deterministic way to disassemble the buffer
  779      * back to the ToPLD macro, other than trying to find the "_PLD"
  780      * name
  781      */
  782     if (ParentOp->Common.AmlOpcode == AML_PACKAGE_OP)
  783     {
  784         ParentOp = ParentOp->Common.Parent;
  785         if (!ParentOp)
  786         {
  787             return (FALSE);
  788         }
  789 
  790         if (ParentOp->Common.AmlOpcode == AML_NAME_OP)
  791         {
  792             Node = ParentOp->Common.Node;
  793 
  794             if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, METHOD_NAME__PLD))
  795             {
  796                 /* Ignore the Size argument in the disassembly of this buffer op */
  797 
  798                 SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
  799                 return (TRUE);
  800             }
  801         }
  802     }
  803 
  804     return (FALSE);
  805 }
  806 
  807 
  808 /*******************************************************************************
  809  *
  810  * FUNCTION:    AcpiDmFindNameByIndex
  811  *
  812  * PARAMETERS:  Index               - Index of array to check
  813  *              List                - Array to reference
  814  *
  815  * RETURN:      String from List or empty string
  816  *
  817  * DESCRIPTION: Finds and returns the char string located at the given index
  818  *              position in List.
  819  *
  820  ******************************************************************************/
  821 
  822 static const char *
  823 AcpiDmFindNameByIndex (
  824     UINT64                  Index,
  825     const char              **List)
  826 {
  827     const char              *NameString;
  828     UINT32                  i;
  829 
  830 
  831     /* Bounds check */
  832 
  833     NameString = List[0];
  834     i = 0;
  835 
  836     while (NameString)
  837     {
  838         i++;
  839         NameString = List[i];
  840     }
  841 
  842     if (Index >= i)
  843     {
  844         /* TBD: Add error msg */
  845 
  846         return ("");
  847     }
  848 
  849     return (List[Index]);
  850 }
  851 
  852 
  853 /*******************************************************************************
  854  *
  855  * FUNCTION:    AcpiDmPldBuffer
  856  *
  857  * PARAMETERS:  Level               - Current source code indentation level
  858  *              ByteData            - Pointer to the byte list
  859  *              ByteCount           - Length of the byte list
  860  *
  861  * RETURN:      None
  862  *
  863  * DESCRIPTION: Dump and format the contents of a _PLD buffer object
  864  *
  865  ******************************************************************************/
  866 
  867 #define ACPI_PLD_OUTPUT08   "%*.s%-22s = 0x%X,\n", ACPI_MUL_4 (Level), " "
  868 #define ACPI_PLD_OUTPUT08P  "%*.s%-22s = 0x%X)\n", ACPI_MUL_4 (Level), " "
  869 #define ACPI_PLD_OUTPUT16   "%*.s%-22s = 0x%X,\n", ACPI_MUL_4 (Level), " "
  870 #define ACPI_PLD_OUTPUT16P  "%*.s%-22s = 0x%X)\n", ACPI_MUL_4 (Level), " "
  871 #define ACPI_PLD_OUTPUT24   "%*.s%-22s = 0x%X,\n", ACPI_MUL_4 (Level), " "
  872 #define ACPI_PLD_OUTPUTSTR  "%*.s%-22s = \"%s\",\n", ACPI_MUL_4 (Level), " "
  873 
  874 static void
  875 AcpiDmPldBuffer (
  876     UINT32                  Level,
  877     UINT8                   *ByteData,
  878     UINT32                  ByteCount)
  879 {
  880     ACPI_PLD_INFO           *PldInfo;
  881     ACPI_STATUS             Status;
  882 
  883 
  884     /* Check for valid byte count */
  885 
  886     if (ByteCount < ACPI_PLD_REV1_BUFFER_SIZE)
  887     {
  888         return;
  889     }
  890 
  891     /* Convert _PLD buffer to local _PLD struct */
  892 
  893     Status = AcpiDecodePldBuffer (ByteData, ByteCount, &PldInfo);
  894     if (ACPI_FAILURE (Status))
  895     {
  896         return;
  897     }
  898 
  899     AcpiOsPrintf ("\n");
  900 
  901     /* First 32-bit dword */
  902 
  903     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_Revision", PldInfo->Revision);
  904     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_IgnoreColor", PldInfo->IgnoreColor);
  905     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_Red", PldInfo->Red);
  906     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_Green", PldInfo->Green);
  907     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_Blue", PldInfo->Blue);
  908 
  909     /* Second 32-bit dword */
  910 
  911     AcpiOsPrintf (ACPI_PLD_OUTPUT16,  "PLD_Width", PldInfo->Width);
  912     AcpiOsPrintf (ACPI_PLD_OUTPUT16,  "PLD_Height", PldInfo->Height);
  913 
  914     /* Third 32-bit dword */
  915 
  916     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_UserVisible", PldInfo->UserVisible);
  917     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_Dock", PldInfo->Dock);
  918     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_Lid", PldInfo->Lid);
  919     AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_Panel",
  920         AcpiDmFindNameByIndex(PldInfo->Panel, AcpiGbl_PldPanelList));
  921 
  922     AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_VerticalPosition",
  923         AcpiDmFindNameByIndex(PldInfo->VerticalPosition, AcpiGbl_PldVerticalPositionList));
  924 
  925     AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_HorizontalPosition",
  926         AcpiDmFindNameByIndex(PldInfo->HorizontalPosition, AcpiGbl_PldHorizontalPositionList));
  927 
  928     AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_Shape",
  929         AcpiDmFindNameByIndex(PldInfo->Shape, AcpiGbl_PldShapeList));
  930     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_GroupOrientation", PldInfo->GroupOrientation);
  931 
  932     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_GroupToken", PldInfo->GroupToken);
  933     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_GroupPosition", PldInfo->GroupPosition);
  934     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_Bay", PldInfo->Bay);
  935 
  936     /* Fourth 32-bit dword */
  937 
  938     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_Ejectable", PldInfo->Ejectable);
  939     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_EjectRequired", PldInfo->OspmEjectRequired);
  940     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_CabinetNumber", PldInfo->CabinetNumber);
  941     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_CardCageNumber", PldInfo->CardCageNumber);
  942     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_Reference", PldInfo->Reference);
  943     AcpiOsPrintf (ACPI_PLD_OUTPUT08,  "PLD_Rotation", PldInfo->Rotation);
  944 
  945     if (ByteCount >= ACPI_PLD_REV2_BUFFER_SIZE)
  946     {
  947         AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Order", PldInfo->Order);
  948 
  949         /* Fifth 32-bit dword */
  950 
  951         AcpiOsPrintf (ACPI_PLD_OUTPUT16,  "PLD_VerticalOffset", PldInfo->VerticalOffset);
  952         AcpiOsPrintf (ACPI_PLD_OUTPUT16P, "PLD_HorizontalOffset", PldInfo->HorizontalOffset);
  953     }
  954     else /* Rev 1 buffer */
  955     {
  956         AcpiOsPrintf (ACPI_PLD_OUTPUT08P, "PLD_Order", PldInfo->Order);
  957     }
  958 
  959     ACPI_FREE (PldInfo);
  960 }
  961 
  962 
  963 /*******************************************************************************
  964  *
  965  * FUNCTION:    AcpiDmUnicode
  966  *
  967  * PARAMETERS:  Op              - Byte List op containing Unicode string
  968  *
  969  * RETURN:      None
  970  *
  971  * DESCRIPTION: Dump Unicode string as a standard ASCII string. (Remove
  972  *              the extra zero bytes).
  973  *
  974  ******************************************************************************/
  975 
  976 static void
  977 AcpiDmUnicode (
  978     ACPI_PARSE_OBJECT       *Op)
  979 {
  980     UINT16                  *WordData;
  981     UINT32                  WordCount;
  982     UINT32                  i;
  983     int                     OutputValue;
  984 
  985 
  986     /* Extract the buffer info as a WORD buffer */
  987 
  988     WordData = ACPI_CAST_PTR (UINT16, Op->Named.Data);
  989     WordCount = ACPI_DIV_2 (((UINT32) Op->Common.Value.Integer));
  990 
  991     /* Write every other byte as an ASCII character */
  992 
  993     AcpiOsPrintf ("\"");
  994     for (i = 0; i < (WordCount - 1); i++)
  995     {
  996         OutputValue = (int) WordData[i];
  997 
  998         /* Handle values that must be escaped */
  999 
 1000         if ((OutputValue == '\"') ||
 1001             (OutputValue == '\\'))
 1002         {
 1003             AcpiOsPrintf ("\\%c", OutputValue);
 1004         }
 1005         else if (!isprint (OutputValue))
 1006         {
 1007             AcpiOsPrintf ("\\x%2.2X", OutputValue);
 1008         }
 1009         else
 1010         {
 1011             AcpiOsPrintf ("%c", OutputValue);
 1012         }
 1013     }
 1014 
 1015     AcpiOsPrintf ("\")");
 1016 }
 1017 
 1018 
 1019 /*******************************************************************************
 1020  *
 1021  * FUNCTION:    AcpiDmGetHardwareIdType
 1022  *
 1023  * PARAMETERS:  Op              - Op to be examined
 1024  *
 1025  * RETURN:      None
 1026  *
 1027  * DESCRIPTION: Determine the type of the argument to a _HID or _CID
 1028  *              1) Strings are allowed
 1029  *              2) If Integer, determine if it is a valid EISAID
 1030  *
 1031  ******************************************************************************/
 1032 
 1033 static void
 1034 AcpiDmGetHardwareIdType (
 1035     ACPI_PARSE_OBJECT       *Op)
 1036 {
 1037     UINT32                  BigEndianId;
 1038     UINT32                  Prefix[3];
 1039     UINT32                  i;
 1040 
 1041 
 1042     switch (Op->Common.AmlOpcode)
 1043     {
 1044     case AML_STRING_OP:
 1045 
 1046         /* Mark this string as an _HID/_CID string */
 1047 
 1048         Op->Common.DisasmOpcode = ACPI_DASM_HID_STRING;
 1049         break;
 1050 
 1051     case AML_WORD_OP:
 1052     case AML_DWORD_OP:
 1053 
 1054         /* Determine if a Word/Dword is a valid encoded EISAID */
 1055 
 1056         /* Swap from little-endian to big-endian to simplify conversion */
 1057 
 1058         BigEndianId = AcpiUtDwordByteSwap ((UINT32) Op->Common.Value.Integer);
 1059 
 1060         /* Create the 3 leading ASCII letters */
 1061 
 1062         Prefix[0] = ((BigEndianId >> 26) & 0x1F) + 0x40;
 1063         Prefix[1] = ((BigEndianId >> 21) & 0x1F) + 0x40;
 1064         Prefix[2] = ((BigEndianId >> 16) & 0x1F) + 0x40;
 1065 
 1066         /* Verify that all 3 are ascii and alpha */
 1067 
 1068         for (i = 0; i < 3; i++)
 1069         {
 1070             if (!ACPI_IS_ASCII (Prefix[i]) ||
 1071                 !isalpha (Prefix[i]))
 1072             {
 1073                 return;
 1074             }
 1075         }
 1076 
 1077         /* Mark this node as convertible to an EISA ID string */
 1078 
 1079         Op->Common.DisasmOpcode = ACPI_DASM_EISAID;
 1080         break;
 1081 
 1082     default:
 1083         break;
 1084     }
 1085 }
 1086 
 1087 
 1088 /*******************************************************************************
 1089  *
 1090  * FUNCTION:    AcpiDmCheckForHardwareId
 1091  *
 1092  * PARAMETERS:  Op              - Op to be examined
 1093  *
 1094  * RETURN:      None
 1095  *
 1096  * DESCRIPTION: Determine if a Name() Op is a _HID/_CID.
 1097  *
 1098  ******************************************************************************/
 1099 
 1100 void
 1101 AcpiDmCheckForHardwareId (
 1102     ACPI_PARSE_OBJECT       *Op)
 1103 {
 1104     UINT32                  Name;
 1105     ACPI_PARSE_OBJECT       *NextOp;
 1106 
 1107 
 1108     /* Get the NameSegment */
 1109 
 1110     Name = AcpiPsGetName (Op);
 1111     if (!Name)
 1112     {
 1113         return;
 1114     }
 1115 
 1116     NextOp = AcpiPsGetDepthNext (NULL, Op);
 1117     if (!NextOp)
 1118     {
 1119         return;
 1120     }
 1121 
 1122     /* Check for _HID - has one argument */
 1123 
 1124     if (ACPI_COMPARE_NAMESEG (&Name, METHOD_NAME__HID))
 1125     {
 1126         AcpiDmGetHardwareIdType (NextOp);
 1127         return;
 1128     }
 1129 
 1130     /* Exit if not _CID */
 1131 
 1132     if (!ACPI_COMPARE_NAMESEG (&Name, METHOD_NAME__CID))
 1133     {
 1134         return;
 1135     }
 1136 
 1137     /* _CID can contain a single argument or a package */
 1138 
 1139     if (NextOp->Common.AmlOpcode != AML_PACKAGE_OP)
 1140     {
 1141         AcpiDmGetHardwareIdType (NextOp);
 1142         return;
 1143     }
 1144 
 1145     /* _CID with Package: get the package length, check all elements */
 1146 
 1147     NextOp = AcpiPsGetDepthNext (NULL, NextOp);
 1148     if (!NextOp)
 1149     {
 1150         return;
 1151     }
 1152 
 1153     /* Don't need to use the length, just walk the peer list */
 1154 
 1155     NextOp = NextOp->Common.Next;
 1156     while (NextOp)
 1157     {
 1158         AcpiDmGetHardwareIdType (NextOp);
 1159         NextOp = NextOp->Common.Next;
 1160     }
 1161 }
 1162 
 1163 
 1164 /*******************************************************************************
 1165  *
 1166  * FUNCTION:    AcpiDmDecompressEisaId
 1167  *
 1168  * PARAMETERS:  EncodedId       - Raw encoded EISA ID.
 1169  *
 1170  * RETURN:      None
 1171  *
 1172  * DESCRIPTION: Convert an encoded EISAID back to the original ASCII String
 1173  *              and emit the correct ASL statement. If the ID is known, emit
 1174  *              a description of the ID as a comment.
 1175  *
 1176  ******************************************************************************/
 1177 
 1178 void
 1179 AcpiDmDecompressEisaId (
 1180     UINT32                  EncodedId)
 1181 {
 1182     char                    IdBuffer[ACPI_EISAID_STRING_SIZE];
 1183     const AH_DEVICE_ID      *Info;
 1184 
 1185 
 1186     /* Convert EISAID to a string an emit the statement */
 1187 
 1188     AcpiExEisaIdToString (IdBuffer, EncodedId);
 1189     AcpiOsPrintf ("EisaId (\"%s\")", IdBuffer);
 1190 
 1191     /* If we know about the ID, emit the description */
 1192 
 1193     Info = AcpiAhMatchHardwareId (IdBuffer);
 1194     if (Info)
 1195     {
 1196         AcpiOsPrintf (" /* %s */", Info->Description);
 1197     }
 1198 }

Cache object: cb27d733478d540480a9473ff9e81578


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.