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