Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: dtfield.c - Code generation for individual source fields
  4.  *
  5.  *****************************************************************************/
  6.  
  7. /******************************************************************************
  8.  *
  9.  * 1. Copyright Notice
  10.  *
  11.  * Some or all of this work - Copyright (c) 1999 - 2010, 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. #define __DTFIELD_C__
  117.  
  118. #include "aslcompiler.h"
  119. #include "dtcompiler.h"
  120.  
  121. #define _COMPONENT          DT_COMPILER
  122.         ACPI_MODULE_NAME    ("dtfield")
  123.  
  124.  
  125. /* Local prototypes */
  126.  
  127. static void
  128. DtCompileString (
  129.     UINT8                   *Buffer,
  130.     DT_FIELD                *Field,
  131.     UINT32                  ByteLength);
  132.  
  133. static char *
  134. DtPciPathToBuffer (
  135.     char                    *PciPath);
  136.  
  137. static void
  138. DtCompilePciPath (
  139.     UINT8                   *Buffer,
  140.     char                    *StringValue,
  141.     DT_FIELD                *Field,
  142.     UINT32                  ByteLength);
  143.  
  144.  
  145. /******************************************************************************
  146.  *
  147.  * FUNCTION:    DtCompileOneField
  148.  *
  149.  * PARAMETERS:  Buffer              - Output buffer
  150.  *              Field               - Field to be compiled
  151.  *              ByteLength          - Byte length of the field
  152.  *              Type                - Field type
  153.  *
  154.  * RETURN:      None
  155.  *
  156.  * DESCRIPTION: Compile a field value to binary
  157.  *
  158.  *****************************************************************************/
  159.  
  160. void
  161. DtCompileOneField (
  162.     UINT8                   *Buffer,
  163.     DT_FIELD                *Field,
  164.     UINT32                  ByteLength,
  165.     UINT8                   Type,
  166.     UINT8                   Flags)
  167. {
  168.  
  169.     switch (Type)
  170.     {
  171.     case DT_FIELD_TYPE_INTEGER:
  172.         DtCompileInteger (Buffer, Field, ByteLength, Flags);
  173.         break;
  174.  
  175.     case DT_FIELD_TYPE_STRING:
  176.         DtCompileString (Buffer, Field, ByteLength);
  177.         break;
  178.  
  179.     case DT_FIELD_TYPE_BUFFER:
  180.         DtCompileBuffer (Buffer, Field->Value, Field, ByteLength);
  181.         break;
  182.  
  183.     case DT_FIELD_TYPE_PCI_PATH:
  184.         DtCompilePciPath (Buffer, Field->Value, Field, ByteLength);
  185.         break;
  186.  
  187.     default:
  188.         DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid field type");
  189.         break;
  190.     }
  191. }
  192.  
  193.  
  194. /******************************************************************************
  195.  *
  196.  * FUNCTION:    DtCompileString
  197.  *
  198.  * PARAMETERS:  Buffer              - Output buffer
  199.  *              Field               - String to be copied to buffer
  200.  *              ByteLength          - Maximum length of string
  201.  *
  202.  * RETURN:      None
  203.  *
  204.  * DESCRIPTION: Copy string to the buffer
  205.  *
  206.  *****************************************************************************/
  207.  
  208. static void
  209. DtCompileString (
  210.     UINT8                   *Buffer,
  211.     DT_FIELD                *Field,
  212.     UINT32                  ByteLength)
  213. {
  214.     UINT32                  Length;
  215.  
  216.  
  217.     Length = ACPI_STRLEN (Field->Value);
  218.  
  219.     /* Check if the string is too long for the field */
  220.  
  221.     if (Length > ByteLength)
  222.     {
  223.         sprintf (MsgBuffer, "Maximum %u characters", ByteLength);
  224.         DtError (ASL_ERROR, ASL_MSG_STRING_LENGTH, Field, MsgBuffer);
  225.         Length = ByteLength;
  226.     }
  227.  
  228.     /* If input string is shorter than ByteLength, pad with blanks */
  229.  
  230.     ACPI_MEMSET (Buffer, 0x20, ByteLength);
  231.     ACPI_MEMCPY (Buffer, Field->Value, Length);
  232. }
  233.  
  234.  
  235. /******************************************************************************
  236.  *
  237.  * FUNCTION:    DtCompileInteger
  238.  *
  239.  * PARAMETERS:  Buffer              - Output buffer
  240.  *              Field               - Field obj with Integer to be compiled
  241.  *              ByteLength          - Byte length of the integer
  242.  *
  243.  * RETURN:      None
  244.  *
  245.  * DESCRIPTION: Compile an integer
  246.  *
  247.  *****************************************************************************/
  248.  
  249. void
  250. DtCompileInteger (
  251.     UINT8                   *Buffer,
  252.     DT_FIELD                *Field,
  253.     UINT32                  ByteLength,
  254.     UINT8                   Flags)
  255. {
  256.     UINT64                  Value = 0;
  257.     UINT64                  MaxValue;
  258.     UINT8                   *Hex;
  259.     char                    *Message = NULL;
  260.     ACPI_STATUS             Status;
  261.     int                     i;
  262.  
  263.  
  264.     /* Byte length must be in range 1-8 */
  265.  
  266.     if ((ByteLength > 8) || (ByteLength == 0))
  267.     {
  268.         DtFatal (ASL_MSG_COMPILER_INTERNAL, Field,
  269.             "Invalid internal Byte length");
  270.         return;
  271.     }
  272.  
  273.     /* Convert string to an actual integer */
  274.  
  275.     Status = DtStrtoul64 (Field->Value, &Value);
  276.     if (ACPI_FAILURE (Status))
  277.     {
  278.         if (Status == AE_LIMIT)
  279.         {
  280.             Message = "Constant larger than 64 bits";
  281.         }
  282.         else if (Status == AE_BAD_CHARACTER)
  283.         {
  284.             Message = "Invalid character in constant";
  285.         }
  286.  
  287.         DtError (ASL_ERROR, ASL_MSG_INVALID_HEX_INTEGER, Field, Message);
  288.         goto Exit;
  289.     }
  290.  
  291.     /* Ensure that reserved fields are set to zero */
  292.     /* TBD: should we set to zero, or just make this an ERROR? */
  293.     /* TBD: Probably better to use a flag */
  294.  
  295.     if (!ACPI_STRCMP (Field->Name, "Reserved") &&
  296.         (Value != 0))
  297.     {
  298.         DtError (ASL_WARNING, ASL_MSG_RESERVED_VALUE, Field,
  299.             "Setting to zero");
  300.         Value = 0;
  301.     }
  302.  
  303.     /* Check if the value must be non-zero */
  304.  
  305.     if ((Value == 0) && (Flags & DT_NON_ZERO))
  306.     {
  307.         DtError (ASL_ERROR, ASL_MSG_ZERO_VALUE, Field, NULL);
  308.     }
  309.  
  310.     /*
  311.      * Generate the maximum value for the data type (ByteLength)
  312.      * Note: construct chosen for maximum portability
  313.      */
  314.     MaxValue = ((UINT64) (-1)) >> (64 - (ByteLength * 8));
  315.  
  316.     /* Validate that the input value is within range of the target */
  317.  
  318.     if (Value > MaxValue)
  319.     {
  320.         sprintf (MsgBuffer, "Maximum %u bytes", ByteLength);
  321.         DtError (ASL_ERROR, ASL_MSG_INTEGER_SIZE, Field, MsgBuffer);
  322.     }
  323.  
  324.     /*
  325.      * TBD: hard code for ASF! Capabilites field.
  326.      *
  327.      * This field is actually a buffer, not a 56-bit integer --
  328.      * so, the ordering is reversed. Something should be fixed
  329.      * so we don't need this code.
  330.      */
  331.     if (ByteLength == 7)
  332.     {
  333.         Hex = ACPI_CAST_PTR (UINT8, &Value);
  334.         for (i = 6; i >= 0; i--)
  335.         {
  336.             Buffer[i] = *Hex;
  337.             Hex++;
  338.         }
  339.         return;
  340.     }
  341.  
  342. Exit:
  343.     ACPI_MEMCPY (Buffer, &Value, ByteLength);
  344.     return;
  345. }
  346.  
  347.  
  348. /******************************************************************************
  349.  *
  350.  * FUNCTION:    DtPciPathToBuffer
  351.  *
  352.  * PARAMETERS:  PciPath             - DMAR "PCI Path" field
  353.  *
  354.  * RETURN:      Strings of PCI path
  355.  *
  356.  * DESCRIPTION: Remove brackets and comma from DMAR "PCI Path" string, for
  357.  *              example: [1D, 01] ==> 1D 01
  358.  *
  359.  *****************************************************************************/
  360.  
  361. static char *
  362. DtPciPathToBuffer (
  363.     char                    *PciPath)
  364. {
  365.     char                    *Buffer;
  366.  
  367.  
  368.     Buffer = UtLocalCalloc (6);
  369.  
  370.     Buffer[0] = PciPath[1];
  371.     Buffer[1] = PciPath[2];
  372.     Buffer[2] = ' ';
  373.     Buffer[3] = PciPath[5];
  374.     Buffer[4] = PciPath[6];
  375.  
  376.     return (Buffer);
  377. }
  378.  
  379.  
  380. /******************************************************************************
  381.  *
  382.  * FUNCTION:    DtCompileBuffer
  383.  *
  384.  * PARAMETERS:  Buffer              - Output buffer
  385.  *              StringValue         - Integer list to be compiled
  386.  *              Field               - Current field object
  387.  *              ByteLength          - Byte length of the integer list
  388.  *
  389.  * RETURN:      Count of remaining data in the input list
  390.  *
  391.  * DESCRIPTION: Compile and pack an integer list, for example
  392.  *              "AA 1F 20 3B" ==> Buffer[] = {0xAA,0x1F,0x20,0x3B}
  393.  *
  394.  *****************************************************************************/
  395.  
  396. UINT32
  397. DtCompileBuffer (
  398.     UINT8                   *Buffer,
  399.     char                    *StringValue,
  400.     DT_FIELD                *Field,
  401.     UINT32                  ByteLength)
  402. {
  403.     ACPI_STATUS             Status;
  404.     char                    Hex[3];
  405.     UINT64                  Value;
  406.     UINT32                  i;
  407.     UINT32                  Count;
  408.  
  409.  
  410.     Count = ACPI_STRLEN (StringValue) / 3 + 1;
  411.  
  412.     Hex[2] = 0;
  413.     for (i = 0; i < Count; i++)
  414.     {
  415.         Hex[0] = StringValue[0];
  416.         Hex[1] = StringValue[1];
  417.  
  418.         /* Convert one hex byte */
  419.  
  420.         Value = 0;
  421.         Status = DtStrtoul64 (Hex, &Value);
  422.         if (ACPI_FAILURE (Status))
  423.         {
  424.             DtError (ASL_ERROR, ASL_MSG_BUFFER_ELEMENT, Field, MsgBuffer);
  425.             return (ByteLength - Count);
  426.         }
  427.  
  428.         Buffer[i] = (UINT8) Value;
  429.         StringValue += 3;
  430.     }
  431.  
  432.     return (ByteLength - Count);
  433. }
  434.  
  435.  
  436. /******************************************************************************
  437.  *
  438.  * FUNCTION:    DtCompilePciPath
  439.  *
  440.  * PARAMETERS:  Buffer              - Output buffer
  441.  *              StringValue         - DMAR pci path string
  442.  *              ByteLength          - Byte length of DMAR pci path string, 2
  443.  *
  444.  * RETURN:      None
  445.  *
  446.  * DESCRIPTION: Compile DMAR PCI path string to binary
  447.  *
  448.  *****************************************************************************/
  449.  
  450. static void
  451. DtCompilePciPath (
  452.     UINT8                   *Buffer,
  453.     char                    *StringValue,
  454.     DT_FIELD                *Field,
  455.     UINT32                  ByteLength)
  456. {
  457.     char                    *PciPathBuffer;
  458.  
  459.  
  460.     /* Parse path to simple hex digits, then convert to binary */
  461.  
  462.     PciPathBuffer = DtPciPathToBuffer (StringValue);
  463.  
  464.     DtCompileBuffer (Buffer, PciPathBuffer, Field, ByteLength);
  465.     ACPI_FREE (PciPathBuffer);
  466. }
  467.  
  468.  
  469. /******************************************************************************
  470.  *
  471.  * FUNCTION:    DtCompileFlag
  472.  *
  473.  * PARAMETERS:  Buffer              - Output buffer
  474.  *              Field               - Field to be compiled
  475.  *              Info                - Flag info
  476.  *              BitPosition         - Flag bit position
  477.  *
  478.  * RETURN:      Next flag bit position
  479.  *
  480.  * DESCRIPTION: Compile a flag
  481.  *
  482.  *****************************************************************************/
  483.  
  484. UINT32
  485. DtCompileFlag (
  486.     UINT8                   *Buffer,
  487.     DT_FIELD                *Field,
  488.     ACPI_DMTABLE_INFO       *Info,
  489.     UINT32                  BitPosition)
  490. {
  491.     UINT64                  Value = 0;
  492.     UINT32                  BitLength = 1;
  493.     ACPI_STATUS             Status;
  494.  
  495.  
  496.     Status = DtStrtoul64 (Field->Value, &Value);
  497.     if (ACPI_FAILURE (Status))
  498.     {
  499.         DtError (ASL_ERROR, ASL_MSG_INVALID_HEX_INTEGER, Field, NULL);
  500.     }
  501.  
  502.     switch (Info->Opcode)
  503.     {
  504.     case ACPI_DMT_FLAG0:
  505.     case ACPI_DMT_FLAG1:
  506.     case ACPI_DMT_FLAG2:
  507.     case ACPI_DMT_FLAG3:
  508.     case ACPI_DMT_FLAG4:
  509.     case ACPI_DMT_FLAG5:
  510.     case ACPI_DMT_FLAG6:
  511.     case ACPI_DMT_FLAG7:
  512.  
  513.         BitLength = 1;
  514.         break;
  515.  
  516.     case ACPI_DMT_FLAGS0:
  517.     case ACPI_DMT_FLAGS2:
  518.  
  519.         BitLength = 2;
  520.         break;
  521.  
  522.     default:
  523.  
  524.         DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid flag opcode");
  525.         break;
  526.     }
  527.  
  528.     /* Check range of the input flag value */
  529.  
  530.     if (Value >= ((UINT64) 1 << BitLength))
  531.     {
  532.         sprintf (MsgBuffer, "Maximum %u bit", BitLength);
  533.         DtError (ASL_ERROR, ASL_MSG_FLAG_VALUE, Field, MsgBuffer);
  534.         Value = 0;
  535.     }
  536.  
  537.     /* Insert the flag, return next flag bit position */
  538.  
  539.     Buffer += ACPI_DIV_8 (BitPosition);
  540.     *Buffer |= (UINT8) (Value << ACPI_MOD_8 (BitPosition));
  541.  
  542.     return (BitPosition + BitLength);
  543. }
  544.