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/acpi.h> 45 #include "accommon.h" 46 #include "acdebug.h" 47 48 #define _COMPONENT ACPI_CA_DEBUGGER 49 ACPI_MODULE_NAME("dbconvert") 50 51 #define DB_DEFAULT_PKG_ELEMENTS 33 52 /******************************************************************************* 53 * 54 * FUNCTION: acpi_db_hex_char_to_value 55 * 56 * PARAMETERS: hex_char - Ascii Hex digit, 0-9|a-f|A-F 57 * return_value - Where the converted value is returned 58 * 59 * RETURN: Status 60 * 61 * DESCRIPTION: Convert a single hex character to a 4-bit number (0-16). 62 * 63 ******************************************************************************/ 64 acpi_status acpi_db_hex_char_to_value(int hex_char, u8 *return_value) 65 { 66 u8 value; 67 68 /* Digit must be ascii [0-9a-fA-F] */ 69 70 if (!isxdigit(hex_char)) { 71 return (AE_BAD_HEX_CONSTANT); 72 } 73 74 if (hex_char <= 0x39) { 75 value = (u8)(hex_char - 0x30); 76 } else { 77 value = (u8)(toupper(hex_char) - 0x37); 78 } 79 80 *return_value = value; 81 return (AE_OK); 82 } 83 84 /******************************************************************************* 85 * 86 * FUNCTION: acpi_db_hex_byte_to_binary 87 * 88 * PARAMETERS: hex_byte - Double hex digit (0x00 - 0xFF) in format: 89 * hi_byte then lo_byte. 90 * return_value - Where the converted value is returned 91 * 92 * RETURN: Status 93 * 94 * DESCRIPTION: Convert two hex characters to an 8 bit number (0 - 255). 95 * 96 ******************************************************************************/ 97 98 static acpi_status acpi_db_hex_byte_to_binary(char *hex_byte, u8 *return_value) 99 { 100 u8 local0; 101 u8 local1; 102 acpi_status status; 103 104 /* High byte */ 105 106 status = acpi_db_hex_char_to_value(hex_byte[0], &local0); 107 if (ACPI_FAILURE(status)) { 108 return (status); 109 } 110 111 /* Low byte */ 112 113 status = acpi_db_hex_char_to_value(hex_byte[1], &local1); 114 if (ACPI_FAILURE(status)) { 115 return (status); 116 } 117 118 *return_value = (u8)((local0 << 4) | local1); 119 return (AE_OK); 120 } 121 122 /******************************************************************************* 123 * 124 * FUNCTION: acpi_db_convert_to_buffer 125 * 126 * PARAMETERS: string - Input string to be converted 127 * object - Where the buffer object is returned 128 * 129 * RETURN: Status 130 * 131 * DESCRIPTION: Convert a string to a buffer object. String is treated a list 132 * of buffer elements, each separated by a space or comma. 133 * 134 ******************************************************************************/ 135 136 static acpi_status 137 acpi_db_convert_to_buffer(char *string, union acpi_object *object) 138 { 139 u32 i; 140 u32 j; 141 u32 length; 142 u8 *buffer; 143 acpi_status status; 144 145 /* Generate the final buffer length */ 146 147 for (i = 0, length = 0; string[i];) { 148 i += 2; 149 length++; 150 151 while (string[i] && ((string[i] == ',') || (string[i] == ' '))) { 152 i++; 153 } 154 } 155 156 buffer = ACPI_ALLOCATE(length); 157 if (!buffer) { 158 return (AE_NO_MEMORY); 159 } 160 161 /* Convert the command line bytes to the buffer */ 162 163 for (i = 0, j = 0; string[i];) { 164 status = acpi_db_hex_byte_to_binary(&string[i], &buffer[j]); 165 if (ACPI_FAILURE(status)) { 166 ACPI_FREE(buffer); 167 return (status); 168 } 169 170 j++; 171 i += 2; 172 while (string[i] && ((string[i] == ',') || (string[i] == ' '))) { 173 i++; 174 } 175 } 176 177 object->type = ACPI_TYPE_BUFFER; 178 object->buffer.pointer = buffer; 179 object->buffer.length = length; 180 return (AE_OK); 181 } 182 183 /******************************************************************************* 184 * 185 * FUNCTION: acpi_db_convert_to_package 186 * 187 * PARAMETERS: string - Input string to be converted 188 * object - Where the package object is returned 189 * 190 * RETURN: Status 191 * 192 * DESCRIPTION: Convert a string to a package object. Handles nested packages 193 * via recursion with acpi_db_convert_to_object. 194 * 195 ******************************************************************************/ 196 197 acpi_status acpi_db_convert_to_package(char *string, union acpi_object *object) 198 { 199 char *this; 200 char *next; 201 u32 i; 202 acpi_object_type type; 203 union acpi_object *elements; 204 acpi_status status; 205 206 elements = 207 ACPI_ALLOCATE_ZEROED(DB_DEFAULT_PKG_ELEMENTS * 208 sizeof(union acpi_object)); 209 210 this = string; 211 for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) { 212 this = acpi_db_get_next_token(this, &next, &type); 213 if (!this) { 214 break; 215 } 216 217 /* Recursive call to convert each package element */ 218 219 status = acpi_db_convert_to_object(type, this, &elements[i]); 220 if (ACPI_FAILURE(status)) { 221 acpi_db_delete_objects(i + 1, elements); 222 ACPI_FREE(elements); 223 return (status); 224 } 225 226 this = next; 227 } 228 229 object->type = ACPI_TYPE_PACKAGE; 230 object->package.count = i; 231 object->package.elements = elements; 232 return (AE_OK); 233 } 234 235 /******************************************************************************* 236 * 237 * FUNCTION: acpi_db_convert_to_object 238 * 239 * PARAMETERS: type - Object type as determined by parser 240 * string - Input string to be converted 241 * object - Where the new object is returned 242 * 243 * RETURN: Status 244 * 245 * DESCRIPTION: Convert a typed and tokenized string to a union acpi_object. Typing: 246 * 1) String objects were surrounded by quotes. 247 * 2) Buffer objects were surrounded by parentheses. 248 * 3) Package objects were surrounded by brackets "[]". 249 * 4) All standalone tokens are treated as integers. 250 * 251 ******************************************************************************/ 252 253 acpi_status 254 acpi_db_convert_to_object(acpi_object_type type, 255 char *string, union acpi_object *object) 256 { 257 acpi_status status = AE_OK; 258 259 switch (type) { 260 case ACPI_TYPE_STRING: 261 262 object->type = ACPI_TYPE_STRING; 263 object->string.pointer = string; 264 object->string.length = (u32)strlen(string); 265 break; 266 267 case ACPI_TYPE_BUFFER: 268 269 status = acpi_db_convert_to_buffer(string, object); 270 break; 271 272 case ACPI_TYPE_PACKAGE: 273 274 status = acpi_db_convert_to_package(string, object); 275 break; 276 277 default: 278 279 object->type = ACPI_TYPE_INTEGER; 280 status = acpi_ut_strtoul64(string, 281 (acpi_gbl_integer_byte_width | 282 ACPI_STRTOUL_BASE16), 283 &object->integer.value); 284 break; 285 } 286 287 return (status); 288 } 289 290 /******************************************************************************* 291 * 292 * FUNCTION: acpi_db_encode_pld_buffer 293 * 294 * PARAMETERS: pld_info - _PLD buffer struct (Using local struct) 295 * 296 * RETURN: Encode _PLD buffer suitable for return value from _PLD 297 * 298 * DESCRIPTION: Bit-packs a _PLD buffer struct. Used to test the _PLD macros 299 * 300 ******************************************************************************/ 301 302 u8 *acpi_db_encode_pld_buffer(struct acpi_pld_info *pld_info) 303 { 304 u32 *buffer; 305 u32 dword; 306 307 buffer = ACPI_ALLOCATE_ZEROED(ACPI_PLD_BUFFER_SIZE); 308 if (!buffer) { 309 return (NULL); 310 } 311 312 /* First 32 bits */ 313 314 dword = 0; 315 ACPI_PLD_SET_REVISION(&dword, pld_info->revision); 316 ACPI_PLD_SET_IGNORE_COLOR(&dword, pld_info->ignore_color); 317 ACPI_PLD_SET_RED(&dword, pld_info->red); 318 ACPI_PLD_SET_GREEN(&dword, pld_info->green); 319 ACPI_PLD_SET_BLUE(&dword, pld_info->blue); 320 ACPI_MOVE_32_TO_32(&buffer[0], &dword); 321 322 /* Second 32 bits */ 323 324 dword = 0; 325 ACPI_PLD_SET_WIDTH(&dword, pld_info->width); 326 ACPI_PLD_SET_HEIGHT(&dword, pld_info->height); 327 ACPI_MOVE_32_TO_32(&buffer[1], &dword); 328 329 /* Third 32 bits */ 330 331 dword = 0; 332 ACPI_PLD_SET_USER_VISIBLE(&dword, pld_info->user_visible); 333 ACPI_PLD_SET_DOCK(&dword, pld_info->dock); 334 ACPI_PLD_SET_LID(&dword, pld_info->lid); 335 ACPI_PLD_SET_PANEL(&dword, pld_info->panel); 336 ACPI_PLD_SET_VERTICAL(&dword, pld_info->vertical_position); 337 ACPI_PLD_SET_HORIZONTAL(&dword, pld_info->horizontal_position); 338 ACPI_PLD_SET_SHAPE(&dword, pld_info->shape); 339 ACPI_PLD_SET_ORIENTATION(&dword, pld_info->group_orientation); 340 ACPI_PLD_SET_TOKEN(&dword, pld_info->group_token); 341 ACPI_PLD_SET_POSITION(&dword, pld_info->group_position); 342 ACPI_PLD_SET_BAY(&dword, pld_info->bay); 343 ACPI_MOVE_32_TO_32(&buffer[2], &dword); 344 345 /* Fourth 32 bits */ 346 347 dword = 0; 348 ACPI_PLD_SET_EJECTABLE(&dword, pld_info->ejectable); 349 ACPI_PLD_SET_OSPM_EJECT(&dword, pld_info->ospm_eject_required); 350 ACPI_PLD_SET_CABINET(&dword, pld_info->cabinet_number); 351 ACPI_PLD_SET_CARD_CAGE(&dword, pld_info->card_cage_number); 352 ACPI_PLD_SET_REFERENCE(&dword, pld_info->reference); 353 ACPI_PLD_SET_ROTATION(&dword, pld_info->rotation); 354 ACPI_PLD_SET_ORDER(&dword, pld_info->order); 355 ACPI_MOVE_32_TO_32(&buffer[3], &dword); 356 357 if (pld_info->revision >= 2) { 358 359 /* Fifth 32 bits */ 360 361 dword = 0; 362 ACPI_PLD_SET_VERT_OFFSET(&dword, pld_info->vertical_offset); 363 ACPI_PLD_SET_HORIZ_OFFSET(&dword, pld_info->horizontal_offset); 364 ACPI_MOVE_32_TO_32(&buffer[4], &dword); 365 } 366 367 return (ACPI_CAST_PTR(u8, buffer)); 368 } 369 370 /******************************************************************************* 371 * 372 * FUNCTION: acpi_db_dump_pld_buffer 373 * 374 * PARAMETERS: obj_desc - Object returned from _PLD method 375 * 376 * RETURN: None. 377 * 378 * DESCRIPTION: Dumps formatted contents of a _PLD return buffer. 379 * 380 ******************************************************************************/ 381 382 #define ACPI_PLD_OUTPUT "%20s : %-6X\n" 383 384 void acpi_db_dump_pld_buffer(union acpi_object *obj_desc) 385 { 386 union acpi_object *buffer_desc; 387 struct acpi_pld_info *pld_info; 388 u8 *new_buffer; 389 acpi_status status; 390 391 /* Object must be of type Package with at least one Buffer element */ 392 393 if (obj_desc->type != ACPI_TYPE_PACKAGE) { 394 return; 395 } 396 397 buffer_desc = &obj_desc->package.elements[0]; 398 if (buffer_desc->type != ACPI_TYPE_BUFFER) { 399 return; 400 } 401 402 /* Convert _PLD buffer to local _PLD struct */ 403 404 status = acpi_decode_pld_buffer(buffer_desc->buffer.pointer, 405 buffer_desc->buffer.length, &pld_info); 406 if (ACPI_FAILURE(status)) { 407 return; 408 } 409 410 /* Encode local _PLD struct back to a _PLD buffer */ 411 412 new_buffer = acpi_db_encode_pld_buffer(pld_info); 413 if (!new_buffer) { 414 goto exit; 415 } 416 417 /* The two bit-packed buffers should match */ 418 419 if (memcmp(new_buffer, buffer_desc->buffer.pointer, 420 buffer_desc->buffer.length)) { 421 acpi_os_printf 422 ("Converted _PLD buffer does not compare. New:\n"); 423 424 acpi_ut_dump_buffer(new_buffer, 425 buffer_desc->buffer.length, DB_BYTE_DISPLAY, 426 0); 427 } 428 429 /* First 32-bit dword */ 430 431 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Revision", pld_info->revision); 432 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_IgnoreColor", 433 pld_info->ignore_color); 434 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Red", pld_info->red); 435 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Green", pld_info->green); 436 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Blue", pld_info->blue); 437 438 /* Second 32-bit dword */ 439 440 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Width", pld_info->width); 441 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Height", pld_info->height); 442 443 /* Third 32-bit dword */ 444 445 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_UserVisible", 446 pld_info->user_visible); 447 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Dock", pld_info->dock); 448 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Lid", pld_info->lid); 449 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Panel", pld_info->panel); 450 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_VerticalPosition", 451 pld_info->vertical_position); 452 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_HorizontalPosition", 453 pld_info->horizontal_position); 454 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Shape", pld_info->shape); 455 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupOrientation", 456 pld_info->group_orientation); 457 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupToken", 458 pld_info->group_token); 459 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupPosition", 460 pld_info->group_position); 461 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Bay", pld_info->bay); 462 463 /* Fourth 32-bit dword */ 464 465 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Ejectable", pld_info->ejectable); 466 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_EjectRequired", 467 pld_info->ospm_eject_required); 468 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_CabinetNumber", 469 pld_info->cabinet_number); 470 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_CardCageNumber", 471 pld_info->card_cage_number); 472 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Reference", pld_info->reference); 473 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Rotation", pld_info->rotation); 474 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Order", pld_info->order); 475 476 /* Fifth 32-bit dword */ 477 478 if (buffer_desc->buffer.length > 16) { 479 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_VerticalOffset", 480 pld_info->vertical_offset); 481 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_HorizontalOffset", 482 pld_info->horizontal_offset); 483 } 484 485 ACPI_FREE(new_buffer); 486 exit: 487 ACPI_FREE(pld_info); 488 } 489