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