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