1208625Sjkim/******************************************************************************
2208625Sjkim *
3208625Sjkim * Module Name: dtfield.c - Code generation for individual source fields
4208625Sjkim *
5208625Sjkim *****************************************************************************/
6208625Sjkim
7217365Sjkim/*
8245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp.
9208625Sjkim * All rights reserved.
10208625Sjkim *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
25208625Sjkim *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
29208625Sjkim *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
43208625Sjkim
44208625Sjkim#define __DTFIELD_C__
45208625Sjkim
46209746Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
47209746Sjkim#include <contrib/dev/acpica/compiler/dtcompiler.h>
48208625Sjkim
49208625Sjkim#define _COMPONENT          DT_COMPILER
50208625Sjkim        ACPI_MODULE_NAME    ("dtfield")
51208625Sjkim
52208625Sjkim
53208625Sjkim/* Local prototypes */
54208625Sjkim
55208625Sjkimstatic void
56208625SjkimDtCompileString (
57208625Sjkim    UINT8                   *Buffer,
58208625Sjkim    DT_FIELD                *Field,
59208625Sjkim    UINT32                  ByteLength);
60208625Sjkim
61217365Sjkimstatic void
62217365SjkimDtCompileUnicode (
63217365Sjkim    UINT8                   *Buffer,
64217365Sjkim    DT_FIELD                *Field,
65217365Sjkim    UINT32                  ByteLength);
66217365Sjkim
67217365Sjkimstatic ACPI_STATUS
68217365SjkimDtCompileUuid (
69217365Sjkim    UINT8                   *Buffer,
70217365Sjkim    DT_FIELD                *Field,
71217365Sjkim    UINT32                  ByteLength);
72217365Sjkim
73208625Sjkimstatic char *
74209734SjkimDtNormalizeBuffer (
75209734Sjkim    char                    *Buffer,
76209734Sjkim    UINT32                  *Count);
77208625Sjkim
78208625Sjkim
79208625Sjkim/******************************************************************************
80208625Sjkim *
81208625Sjkim * FUNCTION:    DtCompileOneField
82208625Sjkim *
83208625Sjkim * PARAMETERS:  Buffer              - Output buffer
84208625Sjkim *              Field               - Field to be compiled
85208625Sjkim *              ByteLength          - Byte length of the field
86208625Sjkim *              Type                - Field type
87208625Sjkim *
88208625Sjkim * RETURN:      None
89208625Sjkim *
90208625Sjkim * DESCRIPTION: Compile a field value to binary
91208625Sjkim *
92208625Sjkim *****************************************************************************/
93208625Sjkim
94208625Sjkimvoid
95208625SjkimDtCompileOneField (
96208625Sjkim    UINT8                   *Buffer,
97208625Sjkim    DT_FIELD                *Field,
98208625Sjkim    UINT32                  ByteLength,
99208625Sjkim    UINT8                   Type,
100208625Sjkim    UINT8                   Flags)
101208625Sjkim{
102217365Sjkim    ACPI_STATUS             Status;
103208625Sjkim
104208625Sjkim    switch (Type)
105208625Sjkim    {
106208625Sjkim    case DT_FIELD_TYPE_INTEGER:
107250838Sjkim
108208625Sjkim        DtCompileInteger (Buffer, Field, ByteLength, Flags);
109208625Sjkim        break;
110208625Sjkim
111208625Sjkim    case DT_FIELD_TYPE_STRING:
112250838Sjkim
113208625Sjkim        DtCompileString (Buffer, Field, ByteLength);
114208625Sjkim        break;
115208625Sjkim
116217365Sjkim    case DT_FIELD_TYPE_UUID:
117250838Sjkim
118217365Sjkim        Status = DtCompileUuid (Buffer, Field, ByteLength);
119217365Sjkim        if (ACPI_SUCCESS (Status))
120217365Sjkim        {
121217365Sjkim            break;
122217365Sjkim        }
123217365Sjkim
124217365Sjkim        /* Fall through. */
125217365Sjkim
126208625Sjkim    case DT_FIELD_TYPE_BUFFER:
127250838Sjkim
128208625Sjkim        DtCompileBuffer (Buffer, Field->Value, Field, ByteLength);
129208625Sjkim        break;
130208625Sjkim
131217365Sjkim    case DT_FIELD_TYPE_UNICODE:
132250838Sjkim
133217365Sjkim        DtCompileUnicode (Buffer, Field, ByteLength);
134217365Sjkim        break;
135217365Sjkim
136217365Sjkim    case DT_FIELD_TYPE_DEVICE_PATH:
137250838Sjkim
138217365Sjkim        break;
139217365Sjkim
140208625Sjkim    default:
141250838Sjkim
142208625Sjkim        DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid field type");
143208625Sjkim        break;
144208625Sjkim    }
145208625Sjkim}
146208625Sjkim
147208625Sjkim
148208625Sjkim/******************************************************************************
149208625Sjkim *
150208625Sjkim * FUNCTION:    DtCompileString
151208625Sjkim *
152208625Sjkim * PARAMETERS:  Buffer              - Output buffer
153208625Sjkim *              Field               - String to be copied to buffer
154208625Sjkim *              ByteLength          - Maximum length of string
155208625Sjkim *
156208625Sjkim * RETURN:      None
157208625Sjkim *
158208625Sjkim * DESCRIPTION: Copy string to the buffer
159208625Sjkim *
160208625Sjkim *****************************************************************************/
161208625Sjkim
162208625Sjkimstatic void
163208625SjkimDtCompileString (
164208625Sjkim    UINT8                   *Buffer,
165208625Sjkim    DT_FIELD                *Field,
166208625Sjkim    UINT32                  ByteLength)
167208625Sjkim{
168208625Sjkim    UINT32                  Length;
169208625Sjkim
170208625Sjkim
171208625Sjkim    Length = ACPI_STRLEN (Field->Value);
172208625Sjkim
173208625Sjkim    /* Check if the string is too long for the field */
174208625Sjkim
175208625Sjkim    if (Length > ByteLength)
176208625Sjkim    {
177208625Sjkim        sprintf (MsgBuffer, "Maximum %u characters", ByteLength);
178208625Sjkim        DtError (ASL_ERROR, ASL_MSG_STRING_LENGTH, Field, MsgBuffer);
179208625Sjkim        Length = ByteLength;
180208625Sjkim    }
181208625Sjkim
182208625Sjkim    ACPI_MEMCPY (Buffer, Field->Value, Length);
183208625Sjkim}
184208625Sjkim
185208625Sjkim
186208625Sjkim/******************************************************************************
187208625Sjkim *
188217365Sjkim * FUNCTION:    DtCompileUnicode
189217365Sjkim *
190217365Sjkim * PARAMETERS:  Buffer              - Output buffer
191217365Sjkim *              Field               - String to be copied to buffer
192217365Sjkim *              ByteLength          - Maximum length of string
193217365Sjkim *
194217365Sjkim * RETURN:      None
195217365Sjkim *
196217365Sjkim * DESCRIPTION: Convert ASCII string to Unicode string
197217365Sjkim *
198217365Sjkim * Note:  The Unicode string is 16 bits per character, no leading signature,
199217365Sjkim *        with a 16-bit terminating NULL.
200217365Sjkim *
201217365Sjkim *****************************************************************************/
202217365Sjkim
203217365Sjkimstatic void
204217365SjkimDtCompileUnicode (
205217365Sjkim    UINT8                   *Buffer,
206217365Sjkim    DT_FIELD                *Field,
207217365Sjkim    UINT32                  ByteLength)
208217365Sjkim{
209217365Sjkim    UINT32                  Count;
210217365Sjkim    UINT32                  i;
211217365Sjkim    char                    *AsciiString;
212217365Sjkim    UINT16                  *UnicodeString;
213217365Sjkim
214217365Sjkim
215217365Sjkim    AsciiString = Field->Value;
216217365Sjkim    UnicodeString = (UINT16 *) Buffer;
217217365Sjkim    Count = ACPI_STRLEN (AsciiString) + 1;
218217365Sjkim
219217365Sjkim    /* Convert to Unicode string (including null terminator) */
220217365Sjkim
221217365Sjkim    for (i = 0; i < Count; i++)
222217365Sjkim    {
223217365Sjkim        UnicodeString[i] = (UINT16) AsciiString[i];
224217365Sjkim    }
225217365Sjkim}
226217365Sjkim
227217365Sjkim
228217365Sjkim/*******************************************************************************
229217365Sjkim *
230217365Sjkim * FUNCTION:    DtCompileUuid
231217365Sjkim *
232217365Sjkim * PARAMETERS:  Buffer              - Output buffer
233217365Sjkim *              Field               - String to be copied to buffer
234217365Sjkim *              ByteLength          - Maximum length of string
235217365Sjkim *
236217365Sjkim * RETURN:      None
237217365Sjkim *
238217365Sjkim * DESCRIPTION: Convert UUID string to 16-byte buffer
239217365Sjkim *
240217365Sjkim ******************************************************************************/
241217365Sjkim
242217365Sjkimstatic ACPI_STATUS
243217365SjkimDtCompileUuid (
244217365Sjkim    UINT8                   *Buffer,
245217365Sjkim    DT_FIELD                *Field,
246217365Sjkim    UINT32                  ByteLength)
247217365Sjkim{
248217365Sjkim    char                    *InString;
249217365Sjkim    ACPI_STATUS             Status;
250217365Sjkim
251217365Sjkim
252217365Sjkim    InString = Field->Value;
253217365Sjkim
254217365Sjkim    Status = AuValidateUuid (InString);
255217365Sjkim    if (ACPI_FAILURE (Status))
256217365Sjkim    {
257217365Sjkim        sprintf (MsgBuffer, "%s", Field->Value);
258217365Sjkim        DtNameError (ASL_ERROR, ASL_MSG_INVALID_UUID, Field, MsgBuffer);
259217365Sjkim    }
260217365Sjkim    else
261217365Sjkim    {
262217365Sjkim        Status = AuConvertStringToUuid (InString, (char *) Buffer);
263217365Sjkim    }
264217365Sjkim
265217365Sjkim    return (Status);
266217365Sjkim}
267217365Sjkim
268217365Sjkim
269217365Sjkim/******************************************************************************
270217365Sjkim *
271208625Sjkim * FUNCTION:    DtCompileInteger
272208625Sjkim *
273208625Sjkim * PARAMETERS:  Buffer              - Output buffer
274208625Sjkim *              Field               - Field obj with Integer to be compiled
275208625Sjkim *              ByteLength          - Byte length of the integer
276218590Sjkim *              Flags               - Additional compile info
277208625Sjkim *
278208625Sjkim * RETURN:      None
279208625Sjkim *
280218590Sjkim * DESCRIPTION: Compile an integer. Supports integer expressions with C-style
281218590Sjkim *              operators.
282208625Sjkim *
283208625Sjkim *****************************************************************************/
284208625Sjkim
285208625Sjkimvoid
286208625SjkimDtCompileInteger (
287208625Sjkim    UINT8                   *Buffer,
288208625Sjkim    DT_FIELD                *Field,
289208625Sjkim    UINT32                  ByteLength,
290208625Sjkim    UINT8                   Flags)
291208625Sjkim{
292218590Sjkim    UINT64                  Value;
293208625Sjkim    UINT64                  MaxValue;
294220663Sjkim    ACPI_STATUS             Status;
295208625Sjkim
296208625Sjkim
297218590Sjkim    /* Output buffer byte length must be in range 1-8 */
298208625Sjkim
299208625Sjkim    if ((ByteLength > 8) || (ByteLength == 0))
300208625Sjkim    {
301208625Sjkim        DtFatal (ASL_MSG_COMPILER_INTERNAL, Field,
302208625Sjkim            "Invalid internal Byte length");
303208625Sjkim        return;
304208625Sjkim    }
305208625Sjkim
306218590Sjkim    /* Resolve integer expression to a single integer value */
307208625Sjkim
308220663Sjkim    Status = DtResolveIntegerExpression (Field, &Value);
309220663Sjkim    if (ACPI_FAILURE (Status))
310220663Sjkim    {
311220663Sjkim        return;
312220663Sjkim    }
313208625Sjkim
314208625Sjkim    /* Ensure that reserved fields are set to zero */
315208625Sjkim    /* TBD: should we set to zero, or just make this an ERROR? */
316208625Sjkim    /* TBD: Probably better to use a flag */
317208625Sjkim
318208625Sjkim    if (!ACPI_STRCMP (Field->Name, "Reserved") &&
319208625Sjkim        (Value != 0))
320208625Sjkim    {
321208625Sjkim        DtError (ASL_WARNING, ASL_MSG_RESERVED_VALUE, Field,
322208625Sjkim            "Setting to zero");
323208625Sjkim        Value = 0;
324208625Sjkim    }
325208625Sjkim
326208625Sjkim    /* Check if the value must be non-zero */
327208625Sjkim
328208625Sjkim    if ((Value == 0) && (Flags & DT_NON_ZERO))
329208625Sjkim    {
330208625Sjkim        DtError (ASL_ERROR, ASL_MSG_ZERO_VALUE, Field, NULL);
331208625Sjkim    }
332208625Sjkim
333208625Sjkim    /*
334208625Sjkim     * Generate the maximum value for the data type (ByteLength)
335208625Sjkim     * Note: construct chosen for maximum portability
336208625Sjkim     */
337208625Sjkim    MaxValue = ((UINT64) (-1)) >> (64 - (ByteLength * 8));
338208625Sjkim
339208625Sjkim    /* Validate that the input value is within range of the target */
340208625Sjkim
341208625Sjkim    if (Value > MaxValue)
342208625Sjkim    {
343218590Sjkim        sprintf (MsgBuffer, "%8.8X%8.8X", ACPI_FORMAT_UINT64 (Value));
344208625Sjkim        DtError (ASL_ERROR, ASL_MSG_INTEGER_SIZE, Field, MsgBuffer);
345208625Sjkim    }
346208625Sjkim
347208625Sjkim    ACPI_MEMCPY (Buffer, &Value, ByteLength);
348208625Sjkim    return;
349208625Sjkim}
350208625Sjkim
351208625Sjkim
352208625Sjkim/******************************************************************************
353208625Sjkim *
354209734Sjkim * FUNCTION:    DtNormalizeBuffer
355208625Sjkim *
356209734Sjkim * PARAMETERS:  Buffer              - Input buffer
357209734Sjkim *              Count               - Output the count of hex number in
358209734Sjkim *                                    the Buffer
359208625Sjkim *
360209734Sjkim * RETURN:      The normalized buffer, freed by caller
361208625Sjkim *
362209734Sjkim * DESCRIPTION: [1A,2B,3C,4D] or 1A, 2B, 3C, 4D will be normalized
363209734Sjkim *              to 1A 2B 3C 4D
364208625Sjkim *
365208625Sjkim *****************************************************************************/
366208625Sjkim
367208625Sjkimstatic char *
368209734SjkimDtNormalizeBuffer (
369209734Sjkim    char                    *Buffer,
370209734Sjkim    UINT32                  *Count)
371208625Sjkim{
372209734Sjkim    char                    *NewBuffer;
373209734Sjkim    char                    *TmpBuffer;
374209734Sjkim    UINT32                  BufferCount = 0;
375209734Sjkim    BOOLEAN                 Separator = TRUE;
376209734Sjkim    char                    c;
377208625Sjkim
378208625Sjkim
379209734Sjkim    NewBuffer = UtLocalCalloc (ACPI_STRLEN (Buffer) + 1);
380209734Sjkim    TmpBuffer = NewBuffer;
381208625Sjkim
382209734Sjkim    while ((c = *Buffer++))
383209734Sjkim    {
384209734Sjkim        switch (c)
385209734Sjkim        {
386209734Sjkim        /* Valid separators */
387208625Sjkim
388209734Sjkim        case '[':
389209734Sjkim        case ']':
390209734Sjkim        case ' ':
391209734Sjkim        case ',':
392250838Sjkim
393209734Sjkim            Separator = TRUE;
394209734Sjkim            break;
395209734Sjkim
396209734Sjkim        default:
397250838Sjkim
398209734Sjkim            if (Separator)
399209734Sjkim            {
400209734Sjkim                /* Insert blank as the standard separator */
401209734Sjkim
402209734Sjkim                if (NewBuffer[0])
403209734Sjkim                {
404209734Sjkim                    *TmpBuffer++ = ' ';
405209734Sjkim                    BufferCount++;
406209734Sjkim                }
407209734Sjkim
408209734Sjkim                Separator = FALSE;
409209734Sjkim            }
410209734Sjkim
411209734Sjkim            *TmpBuffer++ = c;
412209734Sjkim            break;
413209734Sjkim        }
414209734Sjkim    }
415209734Sjkim
416209734Sjkim    *Count = BufferCount + 1;
417209734Sjkim    return (NewBuffer);
418208625Sjkim}
419208625Sjkim
420208625Sjkim
421208625Sjkim/******************************************************************************
422208625Sjkim *
423208625Sjkim * FUNCTION:    DtCompileBuffer
424208625Sjkim *
425208625Sjkim * PARAMETERS:  Buffer              - Output buffer
426208625Sjkim *              StringValue         - Integer list to be compiled
427208625Sjkim *              Field               - Current field object
428208625Sjkim *              ByteLength          - Byte length of the integer list
429208625Sjkim *
430208625Sjkim * RETURN:      Count of remaining data in the input list
431208625Sjkim *
432208625Sjkim * DESCRIPTION: Compile and pack an integer list, for example
433208625Sjkim *              "AA 1F 20 3B" ==> Buffer[] = {0xAA,0x1F,0x20,0x3B}
434208625Sjkim *
435208625Sjkim *****************************************************************************/
436208625Sjkim
437208625SjkimUINT32
438208625SjkimDtCompileBuffer (
439208625Sjkim    UINT8                   *Buffer,
440208625Sjkim    char                    *StringValue,
441208625Sjkim    DT_FIELD                *Field,
442208625Sjkim    UINT32                  ByteLength)
443208625Sjkim{
444208625Sjkim    ACPI_STATUS             Status;
445208625Sjkim    char                    Hex[3];
446208625Sjkim    UINT64                  Value;
447208625Sjkim    UINT32                  i;
448208625Sjkim    UINT32                  Count;
449208625Sjkim
450208625Sjkim
451209734Sjkim    /* Allow several different types of value separators */
452208625Sjkim
453209734Sjkim    StringValue = DtNormalizeBuffer (StringValue, &Count);
454209734Sjkim
455208625Sjkim    Hex[2] = 0;
456208625Sjkim    for (i = 0; i < Count; i++)
457208625Sjkim    {
458209734Sjkim        /* Each element of StringValue is three chars */
459208625Sjkim
460209734Sjkim        Hex[0] = StringValue[(3 * i)];
461209734Sjkim        Hex[1] = StringValue[(3 * i) + 1];
462209734Sjkim
463208625Sjkim        /* Convert one hex byte */
464208625Sjkim
465208625Sjkim        Value = 0;
466208625Sjkim        Status = DtStrtoul64 (Hex, &Value);
467208625Sjkim        if (ACPI_FAILURE (Status))
468208625Sjkim        {
469208625Sjkim            DtError (ASL_ERROR, ASL_MSG_BUFFER_ELEMENT, Field, MsgBuffer);
470252279Sjkim            goto Exit;
471208625Sjkim        }
472208625Sjkim
473208625Sjkim        Buffer[i] = (UINT8) Value;
474208625Sjkim    }
475208625Sjkim
476252279SjkimExit:
477209734Sjkim    ACPI_FREE (StringValue);
478208625Sjkim    return (ByteLength - Count);
479208625Sjkim}
480208625Sjkim
481208625Sjkim
482208625Sjkim/******************************************************************************
483208625Sjkim *
484208625Sjkim * FUNCTION:    DtCompileFlag
485208625Sjkim *
486208625Sjkim * PARAMETERS:  Buffer              - Output buffer
487208625Sjkim *              Field               - Field to be compiled
488208625Sjkim *              Info                - Flag info
489208625Sjkim *
490209734Sjkim * RETURN:
491208625Sjkim *
492208625Sjkim * DESCRIPTION: Compile a flag
493208625Sjkim *
494208625Sjkim *****************************************************************************/
495208625Sjkim
496209734Sjkimvoid
497208625SjkimDtCompileFlag (
498208625Sjkim    UINT8                   *Buffer,
499208625Sjkim    DT_FIELD                *Field,
500209734Sjkim    ACPI_DMTABLE_INFO       *Info)
501208625Sjkim{
502208625Sjkim    UINT64                  Value = 0;
503208625Sjkim    UINT32                  BitLength = 1;
504209734Sjkim    UINT8                   BitPosition = 0;
505208625Sjkim    ACPI_STATUS             Status;
506208625Sjkim
507208625Sjkim
508208625Sjkim    Status = DtStrtoul64 (Field->Value, &Value);
509208625Sjkim    if (ACPI_FAILURE (Status))
510208625Sjkim    {
511208625Sjkim        DtError (ASL_ERROR, ASL_MSG_INVALID_HEX_INTEGER, Field, NULL);
512208625Sjkim    }
513208625Sjkim
514208625Sjkim    switch (Info->Opcode)
515208625Sjkim    {
516208625Sjkim    case ACPI_DMT_FLAG0:
517208625Sjkim    case ACPI_DMT_FLAG1:
518208625Sjkim    case ACPI_DMT_FLAG2:
519208625Sjkim    case ACPI_DMT_FLAG3:
520208625Sjkim    case ACPI_DMT_FLAG4:
521208625Sjkim    case ACPI_DMT_FLAG5:
522208625Sjkim    case ACPI_DMT_FLAG6:
523208625Sjkim    case ACPI_DMT_FLAG7:
524208625Sjkim
525209734Sjkim        BitPosition = Info->Opcode;
526208625Sjkim        BitLength = 1;
527208625Sjkim        break;
528208625Sjkim
529208625Sjkim    case ACPI_DMT_FLAGS0:
530209734Sjkim
531209734Sjkim        BitPosition = 0;
532209734Sjkim        BitLength = 2;
533209734Sjkim        break;
534209734Sjkim
535209734Sjkim
536228110Sjkim    case ACPI_DMT_FLAGS1:
537228110Sjkim
538228110Sjkim        BitPosition = 1;
539228110Sjkim        BitLength = 2;
540228110Sjkim        break;
541228110Sjkim
542228110Sjkim
543208625Sjkim    case ACPI_DMT_FLAGS2:
544208625Sjkim
545209734Sjkim        BitPosition = 2;
546208625Sjkim        BitLength = 2;
547208625Sjkim        break;
548208625Sjkim
549228110Sjkim    case ACPI_DMT_FLAGS4:
550228110Sjkim
551228110Sjkim        BitPosition = 4;
552228110Sjkim        BitLength = 2;
553228110Sjkim        break;
554228110Sjkim
555208625Sjkim    default:
556208625Sjkim
557208625Sjkim        DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid flag opcode");
558208625Sjkim        break;
559208625Sjkim    }
560208625Sjkim
561208625Sjkim    /* Check range of the input flag value */
562208625Sjkim
563208625Sjkim    if (Value >= ((UINT64) 1 << BitLength))
564208625Sjkim    {
565208625Sjkim        sprintf (MsgBuffer, "Maximum %u bit", BitLength);
566208625Sjkim        DtError (ASL_ERROR, ASL_MSG_FLAG_VALUE, Field, MsgBuffer);
567208625Sjkim        Value = 0;
568208625Sjkim    }
569208625Sjkim
570209734Sjkim    *Buffer |= (UINT8) (Value << BitPosition);
571208625Sjkim}
572