1 /******************************************************************************
3 * Module Name: dtfield.c - Code generation for individual source fields
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2011, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
46 #include <contrib/dev/acpica/compiler/aslcompiler.h>
47 #include <contrib/dev/acpica/compiler/dtcompiler.h>
49 #define _COMPONENT DT_COMPILER
50 ACPI_MODULE_NAME ("dtfield")
53 /* Local prototypes */
79 /******************************************************************************
81 * FUNCTION: DtCompileOneField
83 * PARAMETERS: Buffer - Output buffer
84 * Field - Field to be compiled
85 * ByteLength - Byte length of the field
90 * DESCRIPTION: Compile a field value to binary
92 *****************************************************************************/
106 case DT_FIELD_TYPE_INTEGER:
107 DtCompileInteger (Buffer, Field, ByteLength, Flags);
110 case DT_FIELD_TYPE_STRING:
111 DtCompileString (Buffer, Field, ByteLength);
114 case DT_FIELD_TYPE_UUID:
115 Status = DtCompileUuid (Buffer, Field, ByteLength);
116 if (ACPI_SUCCESS (Status))
123 case DT_FIELD_TYPE_BUFFER:
124 DtCompileBuffer (Buffer, Field->Value, Field, ByteLength);
127 case DT_FIELD_TYPE_UNICODE:
128 DtCompileUnicode (Buffer, Field, ByteLength);
131 case DT_FIELD_TYPE_DEVICE_PATH:
135 DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid field type");
141 /******************************************************************************
143 * FUNCTION: DtCompileString
145 * PARAMETERS: Buffer - Output buffer
146 * Field - String to be copied to buffer
147 * ByteLength - Maximum length of string
151 * DESCRIPTION: Copy string to the buffer
153 *****************************************************************************/
164 Length = ACPI_STRLEN (Field->Value);
166 /* Check if the string is too long for the field */
168 if (Length > ByteLength)
170 sprintf (MsgBuffer, "Maximum %u characters", ByteLength);
171 DtError (ASL_ERROR, ASL_MSG_STRING_LENGTH, Field, MsgBuffer);
175 ACPI_MEMCPY (Buffer, Field->Value, Length);
179 /******************************************************************************
181 * FUNCTION: DtCompileUnicode
183 * PARAMETERS: Buffer - Output buffer
184 * Field - String to be copied to buffer
185 * ByteLength - Maximum length of string
189 * DESCRIPTION: Convert ASCII string to Unicode string
191 * Note: The Unicode string is 16 bits per character, no leading signature,
192 * with a 16-bit terminating NULL.
194 *****************************************************************************/
205 UINT16 *UnicodeString;
208 AsciiString = Field->Value;
209 UnicodeString = (UINT16 *) Buffer;
210 Count = ACPI_STRLEN (AsciiString) + 1;
212 /* Convert to Unicode string (including null terminator) */
214 for (i = 0; i < Count; i++)
216 UnicodeString[i] = (UINT16) AsciiString[i];
221 /*******************************************************************************
223 * FUNCTION: DtCompileUuid
225 * PARAMETERS: Buffer - Output buffer
226 * Field - String to be copied to buffer
227 * ByteLength - Maximum length of string
231 * DESCRIPTION: Convert UUID string to 16-byte buffer
233 ******************************************************************************/
245 InString = Field->Value;
247 Status = AuValidateUuid (InString);
248 if (ACPI_FAILURE (Status))
250 sprintf (MsgBuffer, "%s", Field->Value);
251 DtNameError (ASL_ERROR, ASL_MSG_INVALID_UUID, Field, MsgBuffer);
255 Status = AuConvertStringToUuid (InString, (char *) Buffer);
262 /******************************************************************************
264 * FUNCTION: DtCompileInteger
266 * PARAMETERS: Buffer - Output buffer
267 * Field - Field obj with Integer to be compiled
268 * ByteLength - Byte length of the integer
272 * DESCRIPTION: Compile an integer
274 *****************************************************************************/
286 char *Message = NULL;
291 /* Byte length must be in range 1-8 */
293 if ((ByteLength > 8) || (ByteLength == 0))
295 DtFatal (ASL_MSG_COMPILER_INTERNAL, Field,
296 "Invalid internal Byte length");
300 /* Convert string to an actual integer */
302 Status = DtStrtoul64 (Field->Value, &Value);
303 if (ACPI_FAILURE (Status))
305 if (Status == AE_LIMIT)
307 Message = "Constant larger than 64 bits";
309 else if (Status == AE_BAD_CHARACTER)
311 Message = "Invalid character in constant";
314 DtError (ASL_ERROR, ASL_MSG_INVALID_HEX_INTEGER, Field, Message);
318 /* Ensure that reserved fields are set to zero */
319 /* TBD: should we set to zero, or just make this an ERROR? */
320 /* TBD: Probably better to use a flag */
322 if (!ACPI_STRCMP (Field->Name, "Reserved") &&
325 DtError (ASL_WARNING, ASL_MSG_RESERVED_VALUE, Field,
330 /* Check if the value must be non-zero */
332 if ((Value == 0) && (Flags & DT_NON_ZERO))
334 DtError (ASL_ERROR, ASL_MSG_ZERO_VALUE, Field, NULL);
338 * Generate the maximum value for the data type (ByteLength)
339 * Note: construct chosen for maximum portability
341 MaxValue = ((UINT64) (-1)) >> (64 - (ByteLength * 8));
343 /* Validate that the input value is within range of the target */
345 if (Value > MaxValue)
347 sprintf (MsgBuffer, "Maximum %u bytes", ByteLength);
348 DtError (ASL_ERROR, ASL_MSG_INTEGER_SIZE, Field, MsgBuffer);
352 * TBD: hard code for ASF! Capabilites field.
354 * This field is actually a buffer, not a 56-bit integer --
355 * so, the ordering is reversed. Something should be fixed
356 * so we don't need this code.
360 Hex = ACPI_CAST_PTR (UINT8, &Value);
361 for (i = 6; i >= 0; i--)
370 ACPI_MEMCPY (Buffer, &Value, ByteLength);
375 /******************************************************************************
377 * FUNCTION: DtNormalizeBuffer
379 * PARAMETERS: Buffer - Input buffer
380 * Count - Output the count of hex number in
383 * RETURN: The normalized buffer, freed by caller
385 * DESCRIPTION: [1A,2B,3C,4D] or 1A, 2B, 3C, 4D will be normalized
388 *****************************************************************************/
397 UINT32 BufferCount = 0;
398 BOOLEAN Separator = TRUE;
402 NewBuffer = UtLocalCalloc (ACPI_STRLEN (Buffer) + 1);
403 TmpBuffer = NewBuffer;
405 while ((c = *Buffer++))
409 /* Valid separators */
421 /* Insert blank as the standard separator */
437 *Count = BufferCount + 1;
442 /******************************************************************************
444 * FUNCTION: DtCompileBuffer
446 * PARAMETERS: Buffer - Output buffer
447 * StringValue - Integer list to be compiled
448 * Field - Current field object
449 * ByteLength - Byte length of the integer list
451 * RETURN: Count of remaining data in the input list
453 * DESCRIPTION: Compile and pack an integer list, for example
454 * "AA 1F 20 3B" ==> Buffer[] = {0xAA,0x1F,0x20,0x3B}
456 *****************************************************************************/
472 /* Allow several different types of value separators */
474 StringValue = DtNormalizeBuffer (StringValue, &Count);
477 for (i = 0; i < Count; i++)
479 /* Each element of StringValue is three chars */
481 Hex[0] = StringValue[(3 * i)];
482 Hex[1] = StringValue[(3 * i) + 1];
484 /* Convert one hex byte */
487 Status = DtStrtoul64 (Hex, &Value);
488 if (ACPI_FAILURE (Status))
490 DtError (ASL_ERROR, ASL_MSG_BUFFER_ELEMENT, Field, MsgBuffer);
491 return (ByteLength - Count);
494 Buffer[i] = (UINT8) Value;
497 ACPI_FREE (StringValue);
498 return (ByteLength - Count);
502 /******************************************************************************
504 * FUNCTION: DtCompileFlag
506 * PARAMETERS: Buffer - Output buffer
507 * Field - Field to be compiled
512 * DESCRIPTION: Compile a flag
514 *****************************************************************************/
520 ACPI_DMTABLE_INFO *Info)
523 UINT32 BitLength = 1;
524 UINT8 BitPosition = 0;
528 Status = DtStrtoul64 (Field->Value, &Value);
529 if (ACPI_FAILURE (Status))
531 DtError (ASL_ERROR, ASL_MSG_INVALID_HEX_INTEGER, Field, NULL);
534 switch (Info->Opcode)
545 BitPosition = Info->Opcode;
549 case ACPI_DMT_FLAGS0:
556 case ACPI_DMT_FLAGS2:
564 DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid flag opcode");
568 /* Check range of the input flag value */
570 if (Value >= ((UINT64) 1 << BitLength))
572 sprintf (MsgBuffer, "Maximum %u bit", BitLength);
573 DtError (ASL_ERROR, ASL_MSG_FLAG_VALUE, Field, MsgBuffer);
577 *Buffer |= (UINT8) (Value << BitPosition);