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