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