1 /******************************************************************************* 2 * 3 * Module Name: dbconvert - debugger miscellaneous conversion routines 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 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. 25 * 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. 29 * 30 * NO WARRANTY 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. 42 */ 43 44 45 #include <contrib/dev/acpica/include/acpi.h> 46 #include <contrib/dev/acpica/include/accommon.h> 47 #include <contrib/dev/acpica/include/acdebug.h> 48 49 #ifdef ACPI_DEBUGGER 50 51 #define _COMPONENT ACPI_CA_DEBUGGER 52 ACPI_MODULE_NAME ("dbconvert") 53 54 55 #define DB_DEFAULT_PKG_ELEMENTS 33 56 57 58 /******************************************************************************* 59 * 60 * FUNCTION: AcpiDbHexCharToValue 61 * 62 * PARAMETERS: HexChar - Ascii Hex digit, 0-9|a-f|A-F 63 * ReturnValue - Where the converted value is returned 64 * 65 * RETURN: Status 66 * 67 * DESCRIPTION: Convert a single hex character to a 4-bit number (0-16). 68 * 69 ******************************************************************************/ 70 71 ACPI_STATUS 72 AcpiDbHexCharToValue ( 73 int HexChar, 74 UINT8 *ReturnValue) 75 { 76 UINT8 Value; 77 78 79 /* Digit must be ascii [0-9a-fA-F] */ 80 81 if (!ACPI_IS_XDIGIT (HexChar)) 82 { 83 return (AE_BAD_HEX_CONSTANT); 84 } 85 86 if (HexChar <= 0x39) 87 { 88 Value = (UINT8) (HexChar - 0x30); 89 } 90 else 91 { 92 Value = (UINT8) (ACPI_TOUPPER (HexChar) - 0x37); 93 } 94 95 *ReturnValue = Value; 96 return (AE_OK); 97 } 98 99 100 /******************************************************************************* 101 * 102 * FUNCTION: AcpiDbHexByteToBinary 103 * 104 * PARAMETERS: HexByte - Double hex digit (0x00 - 0xFF) in format: 105 * HiByte then LoByte. 106 * ReturnValue - Where the converted value is returned 107 * 108 * RETURN: Status 109 * 110 * DESCRIPTION: Convert two hex characters to an 8 bit number (0 - 255). 111 * 112 ******************************************************************************/ 113 114 static ACPI_STATUS 115 AcpiDbHexByteToBinary ( 116 char *HexByte, 117 UINT8 *ReturnValue) 118 { 119 UINT8 Local0; 120 UINT8 Local1; 121 ACPI_STATUS Status; 122 123 124 /* High byte */ 125 126 Status = AcpiDbHexCharToValue (HexByte[0], &Local0); 127 if (ACPI_FAILURE (Status)) 128 { 129 return (Status); 130 } 131 132 /* Low byte */ 133 134 Status = AcpiDbHexCharToValue (HexByte[1], &Local1); 135 if (ACPI_FAILURE (Status)) 136 { 137 return (Status); 138 } 139 140 *ReturnValue = (UINT8) ((Local0 << 4) | Local1); 141 return (AE_OK); 142 } 143 144 145 /******************************************************************************* 146 * 147 * FUNCTION: AcpiDbConvertToBuffer 148 * 149 * PARAMETERS: String - Input string to be converted 150 * Object - Where the buffer object is returned 151 * 152 * RETURN: Status 153 * 154 * DESCRIPTION: Convert a string to a buffer object. String is treated a list 155 * of buffer elements, each separated by a space or comma. 156 * 157 ******************************************************************************/ 158 159 static ACPI_STATUS 160 AcpiDbConvertToBuffer ( 161 char *String, 162 ACPI_OBJECT *Object) 163 { 164 UINT32 i; 165 UINT32 j; 166 UINT32 Length; 167 UINT8 *Buffer; 168 ACPI_STATUS Status; 169 170 171 /* Generate the final buffer length */ 172 173 for (i = 0, Length = 0; String[i];) 174 { 175 i+=2; 176 Length++; 177 178 while (String[i] && 179 ((String[i] == ',') || (String[i] == ' '))) 180 { 181 i++; 182 } 183 } 184 185 Buffer = ACPI_ALLOCATE (Length); 186 if (!Buffer) 187 { 188 return (AE_NO_MEMORY); 189 } 190 191 /* Convert the command line bytes to the buffer */ 192 193 for (i = 0, j = 0; String[i];) 194 { 195 Status = AcpiDbHexByteToBinary (&String[i], &Buffer[j]); 196 if (ACPI_FAILURE (Status)) 197 { 198 ACPI_FREE (Buffer); 199 return (Status); 200 } 201 202 j++; 203 i+=2; 204 while (String[i] && 205 ((String[i] == ',') || (String[i] == ' '))) 206 { 207 i++; 208 } 209 } 210 211 Object->Type = ACPI_TYPE_BUFFER; 212 Object->Buffer.Pointer = Buffer; 213 Object->Buffer.Length = Length; 214 return (AE_OK); 215 } 216 217 218 /******************************************************************************* 219 * 220 * FUNCTION: AcpiDbConvertToPackage 221 * 222 * PARAMETERS: String - Input string to be converted 223 * Object - Where the package object is returned 224 * 225 * RETURN: Status 226 * 227 * DESCRIPTION: Convert a string to a package object. Handles nested packages 228 * via recursion with AcpiDbConvertToObject. 229 * 230 ******************************************************************************/ 231 232 ACPI_STATUS 233 AcpiDbConvertToPackage ( 234 char *String, 235 ACPI_OBJECT *Object) 236 { 237 char *This; 238 char *Next; 239 UINT32 i; 240 ACPI_OBJECT_TYPE Type; 241 ACPI_OBJECT *Elements; 242 ACPI_STATUS Status; 243 244 245 Elements = ACPI_ALLOCATE_ZEROED ( 246 DB_DEFAULT_PKG_ELEMENTS * sizeof (ACPI_OBJECT)); 247 248 This = String; 249 for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) 250 { 251 This = AcpiDbGetNextToken (This, &Next, &Type); 252 if (!This) 253 { 254 break; 255 } 256 257 /* Recursive call to convert each package element */ 258 259 Status = AcpiDbConvertToObject (Type, This, &Elements[i]); 260 if (ACPI_FAILURE (Status)) 261 { 262 AcpiDbDeleteObjects (i + 1, Elements); 263 ACPI_FREE (Elements); 264 return (Status); 265 } 266 267 This = Next; 268 } 269 270 Object->Type = ACPI_TYPE_PACKAGE; 271 Object->Package.Count = i; 272 Object->Package.Elements = Elements; 273 return (AE_OK); 274 } 275 276 277 /******************************************************************************* 278 * 279 * FUNCTION: AcpiDbConvertToObject 280 * 281 * PARAMETERS: Type - Object type as determined by parser 282 * String - Input string to be converted 283 * Object - Where the new object is returned 284 * 285 * RETURN: Status 286 * 287 * DESCRIPTION: Convert a typed and tokenized string to an ACPI_OBJECT. Typing: 288 * 1) String objects were surrounded by quotes. 289 * 2) Buffer objects were surrounded by parentheses. 290 * 3) Package objects were surrounded by brackets "[]". 291 * 4) All standalone tokens are treated as integers. 292 * 293 ******************************************************************************/ 294 295 ACPI_STATUS 296 AcpiDbConvertToObject ( 297 ACPI_OBJECT_TYPE Type, 298 char *String, 299 ACPI_OBJECT *Object) 300 { 301 ACPI_STATUS Status = AE_OK; 302 303 304 switch (Type) 305 { 306 case ACPI_TYPE_STRING: 307 Object->Type = ACPI_TYPE_STRING; 308 Object->String.Pointer = String; 309 Object->String.Length = (UINT32) ACPI_STRLEN (String); 310 break; 311 312 case ACPI_TYPE_BUFFER: 313 Status = AcpiDbConvertToBuffer (String, Object); 314 break; 315 316 case ACPI_TYPE_PACKAGE: 317 Status = AcpiDbConvertToPackage (String, Object); 318 break; 319 320 default: 321 Object->Type = ACPI_TYPE_INTEGER; 322 Status = AcpiUtStrtoul64 (String, 16, &Object->Integer.Value); 323 break; 324 } 325 326 return (Status); 327 } 328 329 330 /******************************************************************************* 331 * 332 * FUNCTION: AcpiDbEncodePldBuffer 333 * 334 * PARAMETERS: PldInfo - _PLD buffer struct (Using local struct) 335 * 336 * RETURN: Encode _PLD buffer suitable for return value from _PLD 337 * 338 * DESCRIPTION: Bit-packs a _PLD buffer struct. Used to test the _PLD macros 339 * 340 ******************************************************************************/ 341 342 UINT8 * 343 AcpiDbEncodePldBuffer ( 344 ACPI_PLD_INFO *PldInfo) 345 { 346 UINT32 *Buffer; 347 UINT32 Dword; 348 349 350 Buffer = ACPI_ALLOCATE_ZEROED (ACPI_PLD_BUFFER_SIZE); 351 if (!Buffer) 352 { 353 return (NULL); 354 } 355 356 /* First 32 bits */ 357 358 Dword = 0; 359 ACPI_PLD_SET_REVISION (&Dword, PldInfo->Revision); 360 ACPI_PLD_SET_IGNORE_COLOR (&Dword, PldInfo->IgnoreColor); 361 ACPI_PLD_SET_COLOR (&Dword, PldInfo->Color); 362 ACPI_MOVE_32_TO_32 (&Buffer[0], &Dword); 363 364 /* Second 32 bits */ 365 366 Dword = 0; 367 ACPI_PLD_SET_WIDTH (&Dword, PldInfo->Width); 368 ACPI_PLD_SET_HEIGHT (&Dword, PldInfo->Height); 369 ACPI_MOVE_32_TO_32 (&Buffer[1], &Dword); 370 371 /* Third 32 bits */ 372 373 Dword = 0; 374 ACPI_PLD_SET_USER_VISIBLE (&Dword, PldInfo->UserVisible); 375 ACPI_PLD_SET_DOCK (&Dword, PldInfo->Dock); 376 ACPI_PLD_SET_LID (&Dword, PldInfo->Lid); 377 ACPI_PLD_SET_PANEL (&Dword, PldInfo->Panel); 378 ACPI_PLD_SET_VERTICAL (&Dword, PldInfo->VerticalPosition); 379 ACPI_PLD_SET_HORIZONTAL (&Dword, PldInfo->HorizontalPosition); 380 ACPI_PLD_SET_SHAPE (&Dword, PldInfo->Shape); 381 ACPI_PLD_SET_ORIENTATION (&Dword, PldInfo->GroupOrientation); 382 ACPI_PLD_SET_TOKEN (&Dword, PldInfo->GroupToken); 383 ACPI_PLD_SET_POSITION (&Dword, PldInfo->GroupPosition); 384 ACPI_PLD_SET_BAY (&Dword, PldInfo->Bay); 385 ACPI_MOVE_32_TO_32 (&Buffer[2], &Dword); 386 387 /* Fourth 32 bits */ 388 389 Dword = 0; 390 ACPI_PLD_SET_EJECTABLE (&Dword, PldInfo->Ejectable); 391 ACPI_PLD_SET_OSPM_EJECT (&Dword, PldInfo->OspmEjectRequired); 392 ACPI_PLD_SET_CABINET (&Dword, PldInfo->CabinetNumber); 393 ACPI_PLD_SET_CARD_CAGE (&Dword, PldInfo->CardCageNumber); 394 ACPI_PLD_SET_REFERENCE (&Dword, PldInfo->Reference); 395 ACPI_PLD_SET_ROTATION (&Dword, PldInfo->Rotation); 396 ACPI_PLD_SET_ORDER (&Dword, PldInfo->Order); 397 ACPI_MOVE_32_TO_32 (&Buffer[3], &Dword); 398 399 if (PldInfo->Revision >= 2) 400 { 401 /* Fifth 32 bits */ 402 403 Dword = 0; 404 ACPI_PLD_SET_VERT_OFFSET (&Dword, PldInfo->VerticalOffset); 405 ACPI_PLD_SET_HORIZ_OFFSET (&Dword, PldInfo->HorizontalOffset); 406 ACPI_MOVE_32_TO_32 (&Buffer[4], &Dword); 407 } 408 409 return (ACPI_CAST_PTR (UINT8, Buffer)); 410 } 411 412 413 /******************************************************************************* 414 * 415 * FUNCTION: AcpiDbDumpPldBuffer 416 * 417 * PARAMETERS: ObjDesc - Object returned from _PLD method 418 * 419 * RETURN: None. 420 * 421 * DESCRIPTION: Dumps formatted contents of a _PLD return buffer. 422 * 423 ******************************************************************************/ 424 425 #define ACPI_PLD_OUTPUT "%20s : %-6X\n" 426 427 void 428 AcpiDbDumpPldBuffer ( 429 ACPI_OBJECT *ObjDesc) 430 { 431 ACPI_OBJECT *BufferDesc; 432 ACPI_PLD_INFO *PldInfo; 433 UINT8 *NewBuffer; 434 ACPI_STATUS Status; 435 436 437 /* Object must be of type Package with at least one Buffer element */ 438 439 if (ObjDesc->Type != ACPI_TYPE_PACKAGE) 440 { 441 return; 442 } 443 444 BufferDesc = &ObjDesc->Package.Elements[0]; 445 if (BufferDesc->Type != ACPI_TYPE_BUFFER) 446 { 447 return; 448 } 449 450 /* Convert _PLD buffer to local _PLD struct */ 451 452 Status = AcpiDecodePldBuffer (BufferDesc->Buffer.Pointer, 453 BufferDesc->Buffer.Length, &PldInfo); 454 if (ACPI_FAILURE (Status)) 455 { 456 return; 457 } 458 459 /* Encode local _PLD struct back to a _PLD buffer */ 460 461 NewBuffer = AcpiDbEncodePldBuffer (PldInfo); 462 if (!NewBuffer) 463 { 464 return; 465 } 466 467 /* The two bit-packed buffers should match */ 468 469 if (ACPI_MEMCMP (NewBuffer, BufferDesc->Buffer.Pointer, 470 BufferDesc->Buffer.Length)) 471 { 472 AcpiOsPrintf ("Converted _PLD buffer does not compare. New:\n"); 473 474 AcpiUtDumpBuffer (NewBuffer, 475 BufferDesc->Buffer.Length, DB_BYTE_DISPLAY, 0); 476 } 477 478 /* First 32-bit dword */ 479 480 AcpiOsPrintf (ACPI_PLD_OUTPUT, "Revision", PldInfo->Revision); 481 AcpiOsPrintf (ACPI_PLD_OUTPUT, "IgnoreColor", PldInfo->IgnoreColor); 482 AcpiOsPrintf (ACPI_PLD_OUTPUT, "Color", PldInfo->Color); 483 484 /* Second 32-bit dword */ 485 486 AcpiOsPrintf (ACPI_PLD_OUTPUT, "Width", PldInfo->Width); 487 AcpiOsPrintf (ACPI_PLD_OUTPUT, "Height", PldInfo->Height); 488 489 /* Third 32-bit dword */ 490 491 AcpiOsPrintf (ACPI_PLD_OUTPUT, "UserVisible", PldInfo->UserVisible); 492 AcpiOsPrintf (ACPI_PLD_OUTPUT, "Dock", PldInfo->Dock); 493 AcpiOsPrintf (ACPI_PLD_OUTPUT, "Lid", PldInfo->Lid); 494 AcpiOsPrintf (ACPI_PLD_OUTPUT, "Panel", PldInfo->Panel); 495 AcpiOsPrintf (ACPI_PLD_OUTPUT, "VerticalPosition", PldInfo->VerticalPosition); 496 AcpiOsPrintf (ACPI_PLD_OUTPUT, "HorizontalPosition", PldInfo->HorizontalPosition); 497 AcpiOsPrintf (ACPI_PLD_OUTPUT, "Shape", PldInfo->Shape); 498 AcpiOsPrintf (ACPI_PLD_OUTPUT, "GroupOrientation", PldInfo->GroupOrientation); 499 AcpiOsPrintf (ACPI_PLD_OUTPUT, "GroupToken", PldInfo->GroupToken); 500 AcpiOsPrintf (ACPI_PLD_OUTPUT, "GroupPosition", PldInfo->GroupPosition); 501 AcpiOsPrintf (ACPI_PLD_OUTPUT, "Bay", PldInfo->Bay); 502 503 /* Fourth 32-bit dword */ 504 505 AcpiOsPrintf (ACPI_PLD_OUTPUT, "Ejectable", PldInfo->Ejectable); 506 AcpiOsPrintf (ACPI_PLD_OUTPUT, "OspmEjectRequired", PldInfo->OspmEjectRequired); 507 AcpiOsPrintf (ACPI_PLD_OUTPUT, "CabinetNumber", PldInfo->CabinetNumber); 508 AcpiOsPrintf (ACPI_PLD_OUTPUT, "CardCageNumber", PldInfo->CardCageNumber); 509 AcpiOsPrintf (ACPI_PLD_OUTPUT, "Reference", PldInfo->Reference); 510 AcpiOsPrintf (ACPI_PLD_OUTPUT, "Rotation", PldInfo->Rotation); 511 AcpiOsPrintf (ACPI_PLD_OUTPUT, "Order", PldInfo->Order); 512 513 /* Fifth 32-bit dword */ 514 515 if (BufferDesc->Buffer.Length > 16) 516 { 517 AcpiOsPrintf (ACPI_PLD_OUTPUT, "VerticalOffset", PldInfo->VerticalOffset); 518 AcpiOsPrintf (ACPI_PLD_OUTPUT, "HorizontalOffset", PldInfo->HorizontalOffset); 519 } 520 521 ACPI_FREE (PldInfo); 522 ACPI_FREE (NewBuffer); 523 } 524 525 #endif /* ACPI_DEBUGGER */ 526