1 /******************************************************************************
3 * Module Name: dtfield.c - Code generation for individual source fields
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2013, 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 "aslcompiler.h"
47 #include "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
:
108 DtCompileInteger (Buffer
, Field
, ByteLength
, Flags
);
111 case DT_FIELD_TYPE_STRING
:
113 DtCompileString (Buffer
, Field
, ByteLength
);
116 case DT_FIELD_TYPE_UUID
:
118 Status
= DtCompileUuid (Buffer
, Field
, ByteLength
);
119 if (ACPI_SUCCESS (Status
))
126 case DT_FIELD_TYPE_BUFFER
:
128 DtCompileBuffer (Buffer
, Field
->Value
, Field
, ByteLength
);
131 case DT_FIELD_TYPE_UNICODE
:
133 DtCompileUnicode (Buffer
, Field
, ByteLength
);
136 case DT_FIELD_TYPE_DEVICE_PATH
:
142 DtFatal (ASL_MSG_COMPILER_INTERNAL
, Field
, "Invalid field type");
148 /******************************************************************************
150 * FUNCTION: DtCompileString
152 * PARAMETERS: Buffer - Output buffer
153 * Field - String to be copied to buffer
154 * ByteLength - Maximum length of string
158 * DESCRIPTION: Copy string to the buffer
160 *****************************************************************************/
171 Length
= ACPI_STRLEN (Field
->Value
);
173 /* Check if the string is too long for the field */
175 if (Length
> ByteLength
)
177 sprintf (MsgBuffer
, "Maximum %u characters", ByteLength
);
178 DtError (ASL_ERROR
, ASL_MSG_STRING_LENGTH
, Field
, MsgBuffer
);
182 ACPI_MEMCPY (Buffer
, Field
->Value
, Length
);
186 /******************************************************************************
188 * FUNCTION: DtCompileUnicode
190 * PARAMETERS: Buffer - Output buffer
191 * Field - String to be copied to buffer
192 * ByteLength - Maximum length of string
196 * DESCRIPTION: Convert ASCII string to Unicode string
198 * Note: The Unicode string is 16 bits per character, no leading signature,
199 * with a 16-bit terminating NULL.
201 *****************************************************************************/
212 UINT16
*UnicodeString
;
215 AsciiString
= Field
->Value
;
216 UnicodeString
= (UINT16
*) Buffer
;
217 Count
= ACPI_STRLEN (AsciiString
) + 1;
219 /* Convert to Unicode string (including null terminator) */
221 for (i
= 0; i
< Count
; i
++)
223 UnicodeString
[i
] = (UINT16
) AsciiString
[i
];
228 /*******************************************************************************
230 * FUNCTION: DtCompileUuid
232 * PARAMETERS: Buffer - Output buffer
233 * Field - String to be copied to buffer
234 * ByteLength - Maximum length of string
238 * DESCRIPTION: Convert UUID string to 16-byte buffer
240 ******************************************************************************/
252 InString
= Field
->Value
;
254 Status
= AuValidateUuid (InString
);
255 if (ACPI_FAILURE (Status
))
257 sprintf (MsgBuffer
, "%s", Field
->Value
);
258 DtNameError (ASL_ERROR
, ASL_MSG_INVALID_UUID
, Field
, MsgBuffer
);
262 Status
= AuConvertStringToUuid (InString
, (char *) Buffer
);
269 /******************************************************************************
271 * FUNCTION: DtCompileInteger
273 * PARAMETERS: Buffer - Output buffer
274 * Field - Field obj with Integer to be compiled
275 * ByteLength - Byte length of the integer
276 * Flags - Additional compile info
280 * DESCRIPTION: Compile an integer. Supports integer expressions with C-style
283 *****************************************************************************/
297 /* Output buffer byte length must be in range 1-8 */
299 if ((ByteLength
> 8) || (ByteLength
== 0))
301 DtFatal (ASL_MSG_COMPILER_INTERNAL
, Field
,
302 "Invalid internal Byte length");
306 /* Resolve integer expression to a single integer value */
308 Status
= DtResolveIntegerExpression (Field
, &Value
);
309 if (ACPI_FAILURE (Status
))
314 /* Ensure that reserved fields are set to zero */
315 /* TBD: should we set to zero, or just make this an ERROR? */
316 /* TBD: Probably better to use a flag */
318 if (!ACPI_STRCMP (Field
->Name
, "Reserved") &&
321 DtError (ASL_WARNING
, ASL_MSG_RESERVED_VALUE
, Field
,
326 /* Check if the value must be non-zero */
328 if ((Value
== 0) && (Flags
& DT_NON_ZERO
))
330 DtError (ASL_ERROR
, ASL_MSG_ZERO_VALUE
, Field
, NULL
);
334 * Generate the maximum value for the data type (ByteLength)
335 * Note: construct chosen for maximum portability
337 MaxValue
= ((UINT64
) (-1)) >> (64 - (ByteLength
* 8));
339 /* Validate that the input value is within range of the target */
341 if (Value
> MaxValue
)
343 sprintf (MsgBuffer
, "%8.8X%8.8X", ACPI_FORMAT_UINT64 (Value
));
344 DtError (ASL_ERROR
, ASL_MSG_INTEGER_SIZE
, Field
, MsgBuffer
);
347 ACPI_MEMCPY (Buffer
, &Value
, ByteLength
);
352 /******************************************************************************
354 * FUNCTION: DtNormalizeBuffer
356 * PARAMETERS: Buffer - Input buffer
357 * Count - Output the count of hex number in
360 * RETURN: The normalized buffer, freed by caller
362 * DESCRIPTION: [1A,2B,3C,4D] or 1A, 2B, 3C, 4D will be normalized
365 *****************************************************************************/
374 UINT32 BufferCount
= 0;
375 BOOLEAN Separator
= TRUE
;
379 NewBuffer
= UtLocalCalloc (ACPI_STRLEN (Buffer
) + 1);
380 TmpBuffer
= NewBuffer
;
382 while ((c
= *Buffer
++))
386 /* Valid separators */
400 /* Insert blank as the standard separator */
416 *Count
= BufferCount
+ 1;
421 /******************************************************************************
423 * FUNCTION: DtCompileBuffer
425 * PARAMETERS: Buffer - Output buffer
426 * StringValue - Integer list to be compiled
427 * Field - Current field object
428 * ByteLength - Byte length of the integer list
430 * RETURN: Count of remaining data in the input list
432 * DESCRIPTION: Compile and pack an integer list, for example
433 * "AA 1F 20 3B" ==> Buffer[] = {0xAA,0x1F,0x20,0x3B}
435 *****************************************************************************/
451 /* Allow several different types of value separators */
453 StringValue
= DtNormalizeBuffer (StringValue
, &Count
);
456 for (i
= 0; i
< Count
; i
++)
458 /* Each element of StringValue is three chars */
460 Hex
[0] = StringValue
[(3 * i
)];
461 Hex
[1] = StringValue
[(3 * i
) + 1];
463 /* Convert one hex byte */
466 Status
= DtStrtoul64 (Hex
, &Value
);
467 if (ACPI_FAILURE (Status
))
469 DtError (ASL_ERROR
, ASL_MSG_BUFFER_ELEMENT
, Field
, MsgBuffer
);
473 Buffer
[i
] = (UINT8
) Value
;
477 ACPI_FREE (StringValue
);
478 return (ByteLength
- Count
);
482 /******************************************************************************
484 * FUNCTION: DtCompileFlag
486 * PARAMETERS: Buffer - Output buffer
487 * Field - Field to be compiled
492 * DESCRIPTION: Compile a flag
494 *****************************************************************************/
500 ACPI_DMTABLE_INFO
*Info
)
503 UINT32 BitLength
= 1;
504 UINT8 BitPosition
= 0;
508 Status
= DtStrtoul64 (Field
->Value
, &Value
);
509 if (ACPI_FAILURE (Status
))
511 DtError (ASL_ERROR
, ASL_MSG_INVALID_HEX_INTEGER
, Field
, NULL
);
514 switch (Info
->Opcode
)
525 BitPosition
= Info
->Opcode
;
529 case ACPI_DMT_FLAGS0
:
536 case ACPI_DMT_FLAGS1
:
543 case ACPI_DMT_FLAGS2
:
549 case ACPI_DMT_FLAGS4
:
557 DtFatal (ASL_MSG_COMPILER_INTERNAL
, Field
, "Invalid flag opcode");
561 /* Check range of the input flag value */
563 if (Value
>= ((UINT64
) 1 << BitLength
))
565 sprintf (MsgBuffer
, "Maximum %u bit", BitLength
);
566 DtError (ASL_ERROR
, ASL_MSG_FLAG_VALUE
, Field
, MsgBuffer
);
570 *Buffer
|= (UINT8
) (Value
<< BitPosition
);