Home | History | Annotate | Line # | Download | only in compiler
dtfield.c revision 1.13
      1   1.1    jruoho /******************************************************************************
      2   1.1    jruoho  *
      3   1.1    jruoho  * Module Name: dtfield.c - Code generation for individual source fields
      4   1.1    jruoho  *
      5   1.1    jruoho  *****************************************************************************/
      6   1.1    jruoho 
      7   1.2  christos /*
      8  1.13  christos  * Copyright (C) 2000 - 2019, Intel Corp.
      9   1.1    jruoho  * All rights reserved.
     10   1.1    jruoho  *
     11   1.2  christos  * Redistribution and use in source and binary forms, with or without
     12   1.2  christos  * modification, are permitted provided that the following conditions
     13   1.2  christos  * are met:
     14   1.2  christos  * 1. Redistributions of source code must retain the above copyright
     15   1.2  christos  *    notice, this list of conditions, and the following disclaimer,
     16   1.2  christos  *    without modification.
     17   1.2  christos  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18   1.2  christos  *    substantially similar to the "NO WARRANTY" disclaimer below
     19   1.2  christos  *    ("Disclaimer") and any redistribution must be conditioned upon
     20   1.2  christos  *    including a substantially similar Disclaimer requirement for further
     21   1.2  christos  *    binary redistribution.
     22   1.2  christos  * 3. Neither the names of the above-listed copyright holders nor the names
     23   1.2  christos  *    of any contributors may be used to endorse or promote products derived
     24   1.2  christos  *    from this software without specific prior written permission.
     25   1.2  christos  *
     26   1.2  christos  * Alternatively, this software may be distributed under the terms of the
     27   1.2  christos  * GNU General Public License ("GPL") version 2 as published by the Free
     28   1.2  christos  * Software Foundation.
     29   1.2  christos  *
     30   1.2  christos  * NO WARRANTY
     31   1.2  christos  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32   1.2  christos  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33   1.2  christos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34   1.2  christos  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35   1.2  christos  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36   1.2  christos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37   1.2  christos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38   1.2  christos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39   1.2  christos  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40   1.2  christos  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41   1.2  christos  * POSSIBILITY OF SUCH DAMAGES.
     42   1.2  christos  */
     43   1.1    jruoho 
     44   1.1    jruoho #include "aslcompiler.h"
     45   1.1    jruoho 
     46   1.1    jruoho #define _COMPONENT          DT_COMPILER
     47   1.1    jruoho         ACPI_MODULE_NAME    ("dtfield")
     48   1.1    jruoho 
     49   1.1    jruoho 
     50   1.1    jruoho /* Local prototypes */
     51   1.1    jruoho 
     52   1.1    jruoho static void
     53   1.1    jruoho DtCompileString (
     54   1.1    jruoho     UINT8                   *Buffer,
     55   1.1    jruoho     DT_FIELD                *Field,
     56   1.1    jruoho     UINT32                  ByteLength);
     57   1.1    jruoho 
     58   1.2  christos static void
     59   1.2  christos DtCompileUnicode (
     60   1.2  christos     UINT8                   *Buffer,
     61   1.2  christos     DT_FIELD                *Field,
     62   1.2  christos     UINT32                  ByteLength);
     63   1.1    jruoho 
     64   1.2  christos static ACPI_STATUS
     65   1.2  christos DtCompileUuid (
     66   1.1    jruoho     UINT8                   *Buffer,
     67   1.1    jruoho     DT_FIELD                *Field,
     68   1.1    jruoho     UINT32                  ByteLength);
     69   1.1    jruoho 
     70   1.2  christos static char *
     71   1.2  christos DtNormalizeBuffer (
     72   1.2  christos     char                    *Buffer,
     73   1.2  christos     UINT32                  *Count);
     74   1.2  christos 
     75   1.1    jruoho 
     76   1.1    jruoho /******************************************************************************
     77   1.1    jruoho  *
     78   1.1    jruoho  * FUNCTION:    DtCompileOneField
     79   1.1    jruoho  *
     80   1.1    jruoho  * PARAMETERS:  Buffer              - Output buffer
     81   1.1    jruoho  *              Field               - Field to be compiled
     82   1.1    jruoho  *              ByteLength          - Byte length of the field
     83   1.1    jruoho  *              Type                - Field type
     84   1.1    jruoho  *
     85   1.1    jruoho  * RETURN:      None
     86   1.1    jruoho  *
     87   1.1    jruoho  * DESCRIPTION: Compile a field value to binary
     88   1.1    jruoho  *
     89   1.1    jruoho  *****************************************************************************/
     90   1.1    jruoho 
     91   1.1    jruoho void
     92   1.1    jruoho DtCompileOneField (
     93   1.1    jruoho     UINT8                   *Buffer,
     94   1.1    jruoho     DT_FIELD                *Field,
     95   1.1    jruoho     UINT32                  ByteLength,
     96   1.1    jruoho     UINT8                   Type,
     97   1.1    jruoho     UINT8                   Flags)
     98   1.1    jruoho {
     99   1.2  christos     ACPI_STATUS             Status;
    100   1.1    jruoho 
    101   1.6  christos 
    102   1.1    jruoho     switch (Type)
    103   1.1    jruoho     {
    104   1.1    jruoho     case DT_FIELD_TYPE_INTEGER:
    105   1.2  christos 
    106   1.1    jruoho         DtCompileInteger (Buffer, Field, ByteLength, Flags);
    107   1.1    jruoho         break;
    108   1.1    jruoho 
    109   1.1    jruoho     case DT_FIELD_TYPE_STRING:
    110   1.2  christos 
    111   1.1    jruoho         DtCompileString (Buffer, Field, ByteLength);
    112   1.1    jruoho         break;
    113   1.1    jruoho 
    114   1.2  christos     case DT_FIELD_TYPE_UUID:
    115   1.2  christos 
    116   1.2  christos         Status = DtCompileUuid (Buffer, Field, ByteLength);
    117   1.2  christos         if (ACPI_SUCCESS (Status))
    118   1.2  christos         {
    119   1.2  christos             break;
    120   1.2  christos         }
    121   1.2  christos 
    122   1.2  christos         /* Fall through. */
    123   1.2  christos 
    124   1.1    jruoho     case DT_FIELD_TYPE_BUFFER:
    125   1.2  christos 
    126   1.1    jruoho         DtCompileBuffer (Buffer, Field->Value, Field, ByteLength);
    127   1.1    jruoho         break;
    128   1.1    jruoho 
    129   1.2  christos     case DT_FIELD_TYPE_UNICODE:
    130   1.2  christos 
    131   1.2  christos         DtCompileUnicode (Buffer, Field, ByteLength);
    132   1.2  christos         break;
    133   1.2  christos 
    134   1.2  christos     case DT_FIELD_TYPE_DEVICE_PATH:
    135   1.2  christos 
    136   1.1    jruoho         break;
    137   1.1    jruoho 
    138   1.1    jruoho     default:
    139   1.2  christos 
    140   1.1    jruoho         DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid field type");
    141   1.1    jruoho         break;
    142   1.1    jruoho     }
    143   1.1    jruoho }
    144   1.1    jruoho 
    145   1.1    jruoho 
    146   1.1    jruoho /******************************************************************************
    147   1.1    jruoho  *
    148   1.1    jruoho  * FUNCTION:    DtCompileString
    149   1.1    jruoho  *
    150   1.1    jruoho  * PARAMETERS:  Buffer              - Output buffer
    151   1.1    jruoho  *              Field               - String to be copied to buffer
    152   1.1    jruoho  *              ByteLength          - Maximum length of string
    153   1.1    jruoho  *
    154   1.1    jruoho  * RETURN:      None
    155   1.1    jruoho  *
    156   1.1    jruoho  * DESCRIPTION: Copy string to the buffer
    157   1.1    jruoho  *
    158   1.1    jruoho  *****************************************************************************/
    159   1.1    jruoho 
    160   1.1    jruoho static void
    161   1.1    jruoho DtCompileString (
    162   1.1    jruoho     UINT8                   *Buffer,
    163   1.1    jruoho     DT_FIELD                *Field,
    164   1.1    jruoho     UINT32                  ByteLength)
    165   1.1    jruoho {
    166   1.1    jruoho     UINT32                  Length;
    167   1.1    jruoho 
    168   1.1    jruoho 
    169   1.5  christos     Length = strlen (Field->Value);
    170   1.1    jruoho 
    171   1.1    jruoho     /* Check if the string is too long for the field */
    172   1.1    jruoho 
    173   1.1    jruoho     if (Length > ByteLength)
    174   1.1    jruoho     {
    175  1.12  christos         snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "Maximum %u characters", ByteLength);
    176  1.12  christos         DtError (ASL_ERROR, ASL_MSG_STRING_LENGTH, Field, AslGbl_MsgBuffer);
    177   1.1    jruoho         Length = ByteLength;
    178   1.1    jruoho     }
    179   1.1    jruoho 
    180   1.5  christos     memcpy (Buffer, Field->Value, Length);
    181   1.2  christos }
    182   1.2  christos 
    183   1.2  christos 
    184   1.2  christos /******************************************************************************
    185   1.2  christos  *
    186   1.2  christos  * FUNCTION:    DtCompileUnicode
    187   1.2  christos  *
    188   1.2  christos  * PARAMETERS:  Buffer              - Output buffer
    189   1.2  christos  *              Field               - String to be copied to buffer
    190   1.2  christos  *              ByteLength          - Maximum length of string
    191   1.2  christos  *
    192   1.2  christos  * RETURN:      None
    193   1.2  christos  *
    194   1.2  christos  * DESCRIPTION: Convert ASCII string to Unicode string
    195   1.2  christos  *
    196   1.2  christos  * Note:  The Unicode string is 16 bits per character, no leading signature,
    197   1.2  christos  *        with a 16-bit terminating NULL.
    198   1.2  christos  *
    199   1.2  christos  *****************************************************************************/
    200   1.2  christos 
    201   1.2  christos static void
    202   1.2  christos DtCompileUnicode (
    203   1.2  christos     UINT8                   *Buffer,
    204   1.2  christos     DT_FIELD                *Field,
    205   1.2  christos     UINT32                  ByteLength)
    206   1.2  christos {
    207   1.2  christos     UINT32                  Count;
    208   1.2  christos     UINT32                  i;
    209   1.2  christos     char                    *AsciiString;
    210   1.2  christos     UINT16                  *UnicodeString;
    211   1.2  christos 
    212   1.2  christos 
    213   1.2  christos     AsciiString = Field->Value;
    214   1.2  christos     UnicodeString = (UINT16 *) Buffer;
    215   1.5  christos     Count = strlen (AsciiString) + 1;
    216   1.2  christos 
    217   1.2  christos     /* Convert to Unicode string (including null terminator) */
    218   1.2  christos 
    219   1.2  christos     for (i = 0; i < Count; i++)
    220   1.2  christos     {
    221   1.2  christos         UnicodeString[i] = (UINT16) AsciiString[i];
    222   1.2  christos     }
    223   1.2  christos }
    224   1.2  christos 
    225   1.2  christos 
    226   1.2  christos /*******************************************************************************
    227   1.2  christos  *
    228   1.2  christos  * FUNCTION:    DtCompileUuid
    229   1.2  christos  *
    230   1.2  christos  * PARAMETERS:  Buffer              - Output buffer
    231   1.2  christos  *              Field               - String to be copied to buffer
    232   1.2  christos  *              ByteLength          - Maximum length of string
    233   1.2  christos  *
    234   1.2  christos  * RETURN:      None
    235   1.2  christos  *
    236   1.2  christos  * DESCRIPTION: Convert UUID string to 16-byte buffer
    237   1.2  christos  *
    238   1.2  christos  ******************************************************************************/
    239   1.2  christos 
    240   1.2  christos static ACPI_STATUS
    241   1.2  christos DtCompileUuid (
    242   1.2  christos     UINT8                   *Buffer,
    243   1.2  christos     DT_FIELD                *Field,
    244   1.2  christos     UINT32                  ByteLength)
    245   1.2  christos {
    246   1.2  christos     char                    *InString;
    247   1.2  christos     ACPI_STATUS             Status;
    248   1.2  christos 
    249   1.2  christos 
    250   1.2  christos     InString = Field->Value;
    251   1.1    jruoho 
    252   1.2  christos     Status = AuValidateUuid (InString);
    253   1.2  christos     if (ACPI_FAILURE (Status))
    254   1.2  christos     {
    255  1.12  christos         snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%s", Field->Value);
    256  1.12  christos         DtNameError (ASL_ERROR, ASL_MSG_INVALID_UUID, Field, AslGbl_MsgBuffer);
    257   1.2  christos     }
    258   1.2  christos     else
    259   1.2  christos     {
    260   1.3  christos         AcpiUtConvertStringToUuid (InString, Buffer);
    261   1.2  christos     }
    262   1.2  christos 
    263   1.2  christos     return (Status);
    264   1.1    jruoho }
    265   1.1    jruoho 
    266   1.1    jruoho 
    267   1.1    jruoho /******************************************************************************
    268   1.1    jruoho  *
    269   1.1    jruoho  * FUNCTION:    DtCompileInteger
    270   1.1    jruoho  *
    271   1.1    jruoho  * PARAMETERS:  Buffer              - Output buffer
    272   1.1    jruoho  *              Field               - Field obj with Integer to be compiled
    273   1.1    jruoho  *              ByteLength          - Byte length of the integer
    274   1.2  christos  *              Flags               - Additional compile info
    275   1.1    jruoho  *
    276   1.1    jruoho  * RETURN:      None
    277   1.1    jruoho  *
    278   1.2  christos  * DESCRIPTION: Compile an integer. Supports integer expressions with C-style
    279   1.2  christos  *              operators.
    280   1.1    jruoho  *
    281   1.1    jruoho  *****************************************************************************/
    282   1.1    jruoho 
    283   1.1    jruoho void
    284   1.1    jruoho DtCompileInteger (
    285   1.1    jruoho     UINT8                   *Buffer,
    286   1.1    jruoho     DT_FIELD                *Field,
    287   1.1    jruoho     UINT32                  ByteLength,
    288   1.1    jruoho     UINT8                   Flags)
    289   1.1    jruoho {
    290   1.2  christos     UINT64                  Value;
    291   1.1    jruoho     UINT64                  MaxValue;
    292   1.1    jruoho     ACPI_STATUS             Status;
    293   1.1    jruoho 
    294   1.1    jruoho 
    295   1.2  christos     /* Output buffer byte length must be in range 1-8 */
    296   1.1    jruoho 
    297   1.1    jruoho     if ((ByteLength > 8) || (ByteLength == 0))
    298   1.1    jruoho     {
    299   1.1    jruoho         DtFatal (ASL_MSG_COMPILER_INTERNAL, Field,
    300   1.1    jruoho             "Invalid internal Byte length");
    301   1.1    jruoho         return;
    302   1.1    jruoho     }
    303   1.1    jruoho 
    304   1.2  christos     /* Resolve integer expression to a single integer value */
    305   1.1    jruoho 
    306   1.2  christos     Status = DtResolveIntegerExpression (Field, &Value);
    307   1.1    jruoho     if (ACPI_FAILURE (Status))
    308   1.1    jruoho     {
    309   1.2  christos         return;
    310   1.1    jruoho     }
    311   1.1    jruoho 
    312   1.3  christos     /*
    313   1.3  christos      * Ensure that reserved fields are set properly. Note: uses
    314   1.3  christos      * the DT_NON_ZERO flag to indicate that the reserved value
    315   1.3  christos      * must be exactly one. Otherwise, the value must be zero.
    316   1.3  christos      * This is sufficient for now.
    317   1.3  christos      */
    318   1.3  christos 
    319   1.3  christos     /* TBD: Should use a flag rather than compare "Reserved" */
    320   1.1    jruoho 
    321   1.5  christos     if (!strcmp (Field->Name, "Reserved"))
    322   1.1    jruoho     {
    323   1.3  christos         if (Flags & DT_NON_ZERO)
    324   1.3  christos         {
    325   1.3  christos             if (Value != 1)
    326   1.3  christos             {
    327   1.3  christos                 DtError (ASL_WARNING, ASL_MSG_RESERVED_VALUE, Field,
    328   1.3  christos                     "Must be one, setting to one");
    329   1.3  christos                 Value = 1;
    330   1.3  christos             }
    331   1.3  christos         }
    332   1.3  christos         else if (Value != 0)
    333   1.3  christos         {
    334   1.3  christos             DtError (ASL_WARNING, ASL_MSG_RESERVED_VALUE, Field,
    335   1.3  christos                 "Must be zero, setting to zero");
    336   1.3  christos             Value = 0;
    337   1.3  christos         }
    338   1.1    jruoho     }
    339   1.1    jruoho 
    340   1.1    jruoho     /* Check if the value must be non-zero */
    341   1.1    jruoho 
    342   1.3  christos     else if ((Flags & DT_NON_ZERO) && (Value == 0))
    343   1.1    jruoho     {
    344   1.1    jruoho         DtError (ASL_ERROR, ASL_MSG_ZERO_VALUE, Field, NULL);
    345   1.1    jruoho     }
    346   1.1    jruoho 
    347   1.1    jruoho     /*
    348   1.1    jruoho      * Generate the maximum value for the data type (ByteLength)
    349   1.1    jruoho      * Note: construct chosen for maximum portability
    350   1.1    jruoho      */
    351   1.1    jruoho     MaxValue = ((UINT64) (-1)) >> (64 - (ByteLength * 8));
    352   1.1    jruoho 
    353   1.1    jruoho     /* Validate that the input value is within range of the target */
    354   1.1    jruoho 
    355   1.1    jruoho     if (Value > MaxValue)
    356   1.1    jruoho     {
    357  1.12  christos         snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%8.8X%8.8X - max %u bytes",
    358   1.2  christos             ACPI_FORMAT_UINT64 (Value), ByteLength);
    359  1.12  christos         DtError (ASL_ERROR, ASL_MSG_INTEGER_SIZE, Field, AslGbl_MsgBuffer);
    360   1.1    jruoho     }
    361   1.1    jruoho 
    362   1.5  christos     memcpy (Buffer, &Value, ByteLength);
    363   1.1    jruoho     return;
    364   1.1    jruoho }
    365   1.1    jruoho 
    366   1.1    jruoho 
    367   1.1    jruoho /******************************************************************************
    368   1.1    jruoho  *
    369   1.2  christos  * FUNCTION:    DtNormalizeBuffer
    370   1.1    jruoho  *
    371   1.2  christos  * PARAMETERS:  Buffer              - Input buffer
    372   1.7  christos  *              Count               - Output the count of hex numbers in
    373   1.2  christos  *                                    the Buffer
    374   1.1    jruoho  *
    375   1.7  christos  * RETURN:      The normalized buffer, must be freed by caller
    376   1.1    jruoho  *
    377   1.2  christos  * DESCRIPTION: [1A,2B,3C,4D] or 1A, 2B, 3C, 4D will be normalized
    378   1.2  christos  *              to 1A 2B 3C 4D
    379   1.1    jruoho  *
    380   1.1    jruoho  *****************************************************************************/
    381   1.1    jruoho 
    382   1.1    jruoho static char *
    383   1.2  christos DtNormalizeBuffer (
    384   1.2  christos     char                    *Buffer,
    385   1.2  christos     UINT32                  *Count)
    386   1.1    jruoho {
    387   1.2  christos     char                    *NewBuffer;
    388   1.2  christos     char                    *TmpBuffer;
    389   1.2  christos     UINT32                  BufferCount = 0;
    390   1.2  christos     BOOLEAN                 Separator = TRUE;
    391   1.2  christos     char                    c;
    392   1.2  christos 
    393   1.2  christos 
    394   1.5  christos     NewBuffer = UtLocalCalloc (strlen (Buffer) + 1);
    395   1.2  christos     TmpBuffer = NewBuffer;
    396   1.2  christos 
    397   1.2  christos     while ((c = *Buffer++))
    398   1.2  christos     {
    399   1.2  christos         switch (c)
    400   1.2  christos         {
    401   1.2  christos         /* Valid separators */
    402   1.1    jruoho 
    403   1.2  christos         case '[':
    404   1.2  christos         case ']':
    405   1.2  christos         case ' ':
    406   1.2  christos         case ',':
    407   1.1    jruoho 
    408   1.2  christos             Separator = TRUE;
    409   1.2  christos             break;
    410   1.1    jruoho 
    411   1.2  christos         default:
    412   1.1    jruoho 
    413   1.2  christos             if (Separator)
    414   1.2  christos             {
    415   1.2  christos                 /* Insert blank as the standard separator */
    416   1.2  christos 
    417   1.2  christos                 if (NewBuffer[0])
    418   1.2  christos                 {
    419   1.2  christos                     *TmpBuffer++ = ' ';
    420   1.2  christos                     BufferCount++;
    421   1.2  christos                 }
    422   1.2  christos 
    423   1.2  christos                 Separator = FALSE;
    424   1.2  christos             }
    425   1.2  christos 
    426   1.2  christos             *TmpBuffer++ = c;
    427   1.2  christos             break;
    428   1.2  christos         }
    429   1.2  christos     }
    430   1.2  christos 
    431   1.2  christos     *Count = BufferCount + 1;
    432   1.2  christos     return (NewBuffer);
    433   1.1    jruoho }
    434   1.1    jruoho 
    435   1.1    jruoho 
    436   1.1    jruoho /******************************************************************************
    437   1.1    jruoho  *
    438   1.1    jruoho  * FUNCTION:    DtCompileBuffer
    439   1.1    jruoho  *
    440   1.1    jruoho  * PARAMETERS:  Buffer              - Output buffer
    441   1.1    jruoho  *              StringValue         - Integer list to be compiled
    442   1.1    jruoho  *              Field               - Current field object
    443   1.1    jruoho  *              ByteLength          - Byte length of the integer list
    444   1.1    jruoho  *
    445   1.1    jruoho  * RETURN:      Count of remaining data in the input list
    446   1.1    jruoho  *
    447   1.1    jruoho  * DESCRIPTION: Compile and pack an integer list, for example
    448   1.1    jruoho  *              "AA 1F 20 3B" ==> Buffer[] = {0xAA,0x1F,0x20,0x3B}
    449   1.1    jruoho  *
    450   1.1    jruoho  *****************************************************************************/
    451   1.1    jruoho 
    452   1.1    jruoho UINT32
    453   1.1    jruoho DtCompileBuffer (
    454   1.1    jruoho     UINT8                   *Buffer,
    455   1.1    jruoho     char                    *StringValue,
    456   1.1    jruoho     DT_FIELD                *Field,
    457   1.1    jruoho     UINT32                  ByteLength)
    458   1.1    jruoho {
    459   1.7  christos     char                    *Substring;
    460   1.1    jruoho     ACPI_STATUS             Status;
    461   1.7  christos     UINT32                  Count;
    462   1.1    jruoho     UINT32                  i;
    463   1.1    jruoho 
    464   1.1    jruoho 
    465   1.2  christos     /* Allow several different types of value separators */
    466   1.2  christos 
    467   1.2  christos     StringValue = DtNormalizeBuffer (StringValue, &Count);
    468   1.7  christos     Substring = StringValue;
    469   1.7  christos 
    470   1.7  christos     /* Each element of StringValue is now three chars (2 hex + 1 space) */
    471   1.1    jruoho 
    472   1.7  christos     for (i = 0; i < Count; i++, Substring += 3)
    473   1.1    jruoho     {
    474   1.7  christos         /* Check for byte value too long */
    475   1.2  christos 
    476   1.7  christos         if (*(&Substring[2]) &&
    477   1.7  christos            (*(&Substring[2]) != ' '))
    478   1.7  christos         {
    479   1.7  christos             DtError (ASL_ERROR, ASL_MSG_BUFFER_ELEMENT, Field, Substring);
    480   1.7  christos             goto Exit;
    481   1.7  christos         }
    482   1.1    jruoho 
    483   1.7  christos         /* Convert two ASCII characters to one hex byte */
    484   1.1    jruoho 
    485   1.7  christos         Status = AcpiUtAsciiToHexByte (Substring, &Buffer[i]);
    486   1.1    jruoho         if (ACPI_FAILURE (Status))
    487   1.1    jruoho         {
    488   1.7  christos             DtError (ASL_ERROR, ASL_MSG_BUFFER_ELEMENT, Field, Substring);
    489   1.2  christos             goto Exit;
    490   1.1    jruoho         }
    491   1.1    jruoho     }
    492   1.1    jruoho 
    493   1.2  christos Exit:
    494   1.2  christos     ACPI_FREE (StringValue);
    495   1.1    jruoho     return (ByteLength - Count);
    496   1.1    jruoho }
    497   1.1    jruoho 
    498   1.1    jruoho 
    499   1.1    jruoho /******************************************************************************
    500   1.1    jruoho  *
    501   1.1    jruoho  * FUNCTION:    DtCompileFlag
    502   1.1    jruoho  *
    503   1.7  christos  * PARAMETERS:  Buffer                      - Output buffer
    504   1.7  christos  *              Field                       - Field to be compiled
    505   1.7  christos  *              Info                        - Flag info
    506   1.1    jruoho  *
    507   1.7  christos  * RETURN:      None
    508   1.1    jruoho  *
    509   1.7  christos  * DESCRIPTION: Compile a flag field. Handles flags up to 64 bits.
    510   1.1    jruoho  *
    511   1.1    jruoho  *****************************************************************************/
    512   1.1    jruoho 
    513   1.2  christos void
    514   1.1    jruoho DtCompileFlag (
    515   1.1    jruoho     UINT8                   *Buffer,
    516   1.1    jruoho     DT_FIELD                *Field,
    517   1.2  christos     ACPI_DMTABLE_INFO       *Info)
    518   1.1    jruoho {
    519   1.1    jruoho     UINT64                  Value = 0;
    520   1.1    jruoho     UINT32                  BitLength = 1;
    521   1.2  christos     UINT8                   BitPosition = 0;
    522   1.1    jruoho 
    523   1.1    jruoho 
    524   1.9  christos     Value = AcpiUtImplicitStrtoul64 (Field->Value);
    525   1.1    jruoho 
    526   1.1    jruoho     switch (Info->Opcode)
    527   1.1    jruoho     {
    528   1.1    jruoho     case ACPI_DMT_FLAG0:
    529   1.1    jruoho     case ACPI_DMT_FLAG1:
    530   1.1    jruoho     case ACPI_DMT_FLAG2:
    531   1.1    jruoho     case ACPI_DMT_FLAG3:
    532   1.1    jruoho     case ACPI_DMT_FLAG4:
    533   1.1    jruoho     case ACPI_DMT_FLAG5:
    534   1.1    jruoho     case ACPI_DMT_FLAG6:
    535   1.1    jruoho     case ACPI_DMT_FLAG7:
    536   1.1    jruoho 
    537   1.2  christos         BitPosition = Info->Opcode;
    538   1.1    jruoho         BitLength = 1;
    539   1.1    jruoho         break;
    540   1.1    jruoho 
    541   1.1    jruoho     case ACPI_DMT_FLAGS0:
    542   1.2  christos 
    543   1.2  christos         BitPosition = 0;
    544   1.2  christos         BitLength = 2;
    545   1.2  christos         break;
    546   1.2  christos 
    547   1.2  christos 
    548   1.2  christos     case ACPI_DMT_FLAGS1:
    549   1.2  christos 
    550   1.2  christos         BitPosition = 1;
    551   1.2  christos         BitLength = 2;
    552   1.2  christos         break;
    553   1.2  christos 
    554   1.2  christos 
    555   1.1    jruoho     case ACPI_DMT_FLAGS2:
    556   1.1    jruoho 
    557   1.2  christos         BitPosition = 2;
    558   1.2  christos         BitLength = 2;
    559   1.2  christos         break;
    560   1.2  christos 
    561   1.2  christos     case ACPI_DMT_FLAGS4:
    562   1.2  christos 
    563   1.2  christos         BitPosition = 4;
    564   1.1    jruoho         BitLength = 2;
    565   1.1    jruoho         break;
    566   1.1    jruoho 
    567   1.9  christos     case ACPI_DMT_FLAGS4_0:
    568   1.9  christos 
    569   1.9  christos         BitPosition = 0;
    570   1.9  christos         BitLength = 4;
    571   1.9  christos         break;
    572   1.9  christos 
    573   1.9  christos     case ACPI_DMT_FLAGS4_4:
    574   1.9  christos 
    575   1.9  christos         BitPosition = 4;
    576   1.9  christos         BitLength = 4;
    577   1.9  christos         break;
    578   1.9  christos 
    579   1.9  christos     case ACPI_DMT_FLAGS4_8:
    580   1.9  christos 
    581   1.9  christos         BitPosition = 8;
    582   1.9  christos         BitLength = 4;
    583   1.9  christos         break;
    584   1.9  christos 
    585   1.9  christos     case ACPI_DMT_FLAGS4_12:
    586   1.9  christos 
    587   1.9  christos         BitPosition = 12;
    588   1.9  christos         BitLength = 4;
    589   1.9  christos         break;
    590   1.9  christos 
    591   1.9  christos     case ACPI_DMT_FLAGS16_16:
    592   1.9  christos 
    593   1.9  christos         BitPosition = 16;
    594   1.9  christos         BitLength = 16;
    595   1.9  christos         break;
    596   1.9  christos 
    597   1.1    jruoho     default:
    598   1.1    jruoho 
    599   1.1    jruoho         DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid flag opcode");
    600   1.1    jruoho         break;
    601   1.1    jruoho     }
    602   1.1    jruoho 
    603   1.1    jruoho     /* Check range of the input flag value */
    604   1.1    jruoho 
    605   1.1    jruoho     if (Value >= ((UINT64) 1 << BitLength))
    606   1.1    jruoho     {
    607  1.12  christos         snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "Maximum %u bit", BitLength);
    608  1.12  christos         DtError (ASL_ERROR, ASL_MSG_FLAG_VALUE, Field, AslGbl_MsgBuffer);
    609   1.1    jruoho         Value = 0;
    610   1.1    jruoho     }
    611   1.1    jruoho 
    612   1.2  christos     *Buffer |= (UINT8) (Value << BitPosition);
    613   1.1    jruoho }
    614