1 /******************************************************************************* 2 * 3 * Module Name: dbconvert - debugger miscellaneous conversion routines 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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 an 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 = 281 acpi_ut_strtoul64(string, 16, acpi_gbl_integer_byte_width, 282 &object->integer.value); 283 break; 284 } 285 286 return (status); 287 } 288 289 /******************************************************************************* 290 * 291 * FUNCTION: acpi_db_encode_pld_buffer 292 * 293 * PARAMETERS: pld_info - _PLD buffer struct (Using local struct) 294 * 295 * RETURN: Encode _PLD buffer suitable for return value from _PLD 296 * 297 * DESCRIPTION: Bit-packs a _PLD buffer struct. Used to test the _PLD macros 298 * 299 ******************************************************************************/ 300 301 u8 *acpi_db_encode_pld_buffer(struct acpi_pld_info *pld_info) 302 { 303 u32 *buffer; 304 u32 dword; 305 306 buffer = ACPI_ALLOCATE_ZEROED(ACPI_PLD_BUFFER_SIZE); 307 if (!buffer) { 308 return (NULL); 309 } 310 311 /* First 32 bits */ 312 313 dword = 0; 314 ACPI_PLD_SET_REVISION(&dword, pld_info->revision); 315 ACPI_PLD_SET_IGNORE_COLOR(&dword, pld_info->ignore_color); 316 ACPI_PLD_SET_RED(&dword, pld_info->red); 317 ACPI_PLD_SET_GREEN(&dword, pld_info->green); 318 ACPI_PLD_SET_BLUE(&dword, pld_info->blue); 319 ACPI_MOVE_32_TO_32(&buffer[0], &dword); 320 321 /* Second 32 bits */ 322 323 dword = 0; 324 ACPI_PLD_SET_WIDTH(&dword, pld_info->width); 325 ACPI_PLD_SET_HEIGHT(&dword, pld_info->height); 326 ACPI_MOVE_32_TO_32(&buffer[1], &dword); 327 328 /* Third 32 bits */ 329 330 dword = 0; 331 ACPI_PLD_SET_USER_VISIBLE(&dword, pld_info->user_visible); 332 ACPI_PLD_SET_DOCK(&dword, pld_info->dock); 333 ACPI_PLD_SET_LID(&dword, pld_info->lid); 334 ACPI_PLD_SET_PANEL(&dword, pld_info->panel); 335 ACPI_PLD_SET_VERTICAL(&dword, pld_info->vertical_position); 336 ACPI_PLD_SET_HORIZONTAL(&dword, pld_info->horizontal_position); 337 ACPI_PLD_SET_SHAPE(&dword, pld_info->shape); 338 ACPI_PLD_SET_ORIENTATION(&dword, pld_info->group_orientation); 339 ACPI_PLD_SET_TOKEN(&dword, pld_info->group_token); 340 ACPI_PLD_SET_POSITION(&dword, pld_info->group_position); 341 ACPI_PLD_SET_BAY(&dword, pld_info->bay); 342 ACPI_MOVE_32_TO_32(&buffer[2], &dword); 343 344 /* Fourth 32 bits */ 345 346 dword = 0; 347 ACPI_PLD_SET_EJECTABLE(&dword, pld_info->ejectable); 348 ACPI_PLD_SET_OSPM_EJECT(&dword, pld_info->ospm_eject_required); 349 ACPI_PLD_SET_CABINET(&dword, pld_info->cabinet_number); 350 ACPI_PLD_SET_CARD_CAGE(&dword, pld_info->card_cage_number); 351 ACPI_PLD_SET_REFERENCE(&dword, pld_info->reference); 352 ACPI_PLD_SET_ROTATION(&dword, pld_info->rotation); 353 ACPI_PLD_SET_ORDER(&dword, pld_info->order); 354 ACPI_MOVE_32_TO_32(&buffer[3], &dword); 355 356 if (pld_info->revision >= 2) { 357 358 /* Fifth 32 bits */ 359 360 dword = 0; 361 ACPI_PLD_SET_VERT_OFFSET(&dword, pld_info->vertical_offset); 362 ACPI_PLD_SET_HORIZ_OFFSET(&dword, pld_info->horizontal_offset); 363 ACPI_MOVE_32_TO_32(&buffer[4], &dword); 364 } 365 366 return (ACPI_CAST_PTR(u8, buffer)); 367 } 368 369 /******************************************************************************* 370 * 371 * FUNCTION: acpi_db_dump_pld_buffer 372 * 373 * PARAMETERS: obj_desc - Object returned from _PLD method 374 * 375 * RETURN: None. 376 * 377 * DESCRIPTION: Dumps formatted contents of a _PLD return buffer. 378 * 379 ******************************************************************************/ 380 381 #define ACPI_PLD_OUTPUT "%20s : %-6X\n" 382 383 void acpi_db_dump_pld_buffer(union acpi_object *obj_desc) 384 { 385 union acpi_object *buffer_desc; 386 struct acpi_pld_info *pld_info; 387 u8 *new_buffer; 388 acpi_status status; 389 390 /* Object must be of type Package with at least one Buffer element */ 391 392 if (obj_desc->type != ACPI_TYPE_PACKAGE) { 393 return; 394 } 395 396 buffer_desc = &obj_desc->package.elements[0]; 397 if (buffer_desc->type != ACPI_TYPE_BUFFER) { 398 return; 399 } 400 401 /* Convert _PLD buffer to local _PLD struct */ 402 403 status = acpi_decode_pld_buffer(buffer_desc->buffer.pointer, 404 buffer_desc->buffer.length, &pld_info); 405 if (ACPI_FAILURE(status)) { 406 return; 407 } 408 409 /* Encode local _PLD struct back to a _PLD buffer */ 410 411 new_buffer = acpi_db_encode_pld_buffer(pld_info); 412 if (!new_buffer) { 413 goto exit; 414 } 415 416 /* The two bit-packed buffers should match */ 417 418 if (memcmp(new_buffer, buffer_desc->buffer.pointer, 419 buffer_desc->buffer.length)) { 420 acpi_os_printf 421 ("Converted _PLD buffer does not compare. New:\n"); 422 423 acpi_ut_dump_buffer(new_buffer, 424 buffer_desc->buffer.length, DB_BYTE_DISPLAY, 425 0); 426 } 427 428 /* First 32-bit dword */ 429 430 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Revision", pld_info->revision); 431 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_IgnoreColor", 432 pld_info->ignore_color); 433 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Red", pld_info->red); 434 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Green", pld_info->green); 435 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Blue", pld_info->blue); 436 437 /* Second 32-bit dword */ 438 439 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Width", pld_info->width); 440 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Height", pld_info->height); 441 442 /* Third 32-bit dword */ 443 444 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_UserVisible", 445 pld_info->user_visible); 446 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Dock", pld_info->dock); 447 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Lid", pld_info->lid); 448 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Panel", pld_info->panel); 449 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_VerticalPosition", 450 pld_info->vertical_position); 451 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_HorizontalPosition", 452 pld_info->horizontal_position); 453 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Shape", pld_info->shape); 454 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupOrientation", 455 pld_info->group_orientation); 456 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupToken", 457 pld_info->group_token); 458 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupPosition", 459 pld_info->group_position); 460 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Bay", pld_info->bay); 461 462 /* Fourth 32-bit dword */ 463 464 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Ejectable", pld_info->ejectable); 465 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_EjectRequired", 466 pld_info->ospm_eject_required); 467 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_CabinetNumber", 468 pld_info->cabinet_number); 469 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_CardCageNumber", 470 pld_info->card_cage_number); 471 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Reference", pld_info->reference); 472 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Rotation", pld_info->rotation); 473 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Order", pld_info->order); 474 475 /* Fifth 32-bit dword */ 476 477 if (buffer_desc->buffer.length > 16) { 478 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_VerticalOffset", 479 pld_info->vertical_offset); 480 acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_HorizontalOffset", 481 pld_info->horizontal_offset); 482 } 483 484 ACPI_FREE(new_buffer); 485 exit: 486 ACPI_FREE(pld_info); 487 } 488