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