1 /******************************************************************************* 2 * 3 * Module Name: dbutils - AML debugger utilities 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 "acnamesp.h" 47 #include "acdebug.h" 48 49 #define _COMPONENT ACPI_CA_DEBUGGER 50 ACPI_MODULE_NAME("dbutils") 51 52 /* Local prototypes */ 53 #ifdef ACPI_OBSOLETE_FUNCTIONS 54 acpi_status acpi_db_second_pass_parse(union acpi_parse_object *root); 55 56 void acpi_db_dump_buffer(u32 address); 57 #endif 58 59 static char *gbl_hex_to_ascii = "0123456789ABCDEF"; 60 61 /******************************************************************************* 62 * 63 * FUNCTION: acpi_db_match_argument 64 * 65 * PARAMETERS: user_argument - User command line 66 * arguments - Array of commands to match against 67 * 68 * RETURN: Index into command array or ACPI_TYPE_NOT_FOUND if not found 69 * 70 * DESCRIPTION: Search command array for a command match 71 * 72 ******************************************************************************/ 73 74 acpi_object_type 75 acpi_db_match_argument(char *user_argument, 76 struct acpi_db_argument_info *arguments) 77 { 78 u32 i; 79 80 if (!user_argument || user_argument[0] == 0) { 81 return (ACPI_TYPE_NOT_FOUND); 82 } 83 84 for (i = 0; arguments[i].name; i++) { 85 if (strstr(arguments[i].name, user_argument) == 86 arguments[i].name) { 87 return (i); 88 } 89 } 90 91 /* Argument not recognized */ 92 93 return (ACPI_TYPE_NOT_FOUND); 94 } 95 96 /******************************************************************************* 97 * 98 * FUNCTION: acpi_db_set_output_destination 99 * 100 * PARAMETERS: output_flags - Current flags word 101 * 102 * RETURN: None 103 * 104 * DESCRIPTION: Set the current destination for debugger output. Also sets 105 * the debug output level accordingly. 106 * 107 ******************************************************************************/ 108 109 void acpi_db_set_output_destination(u32 output_flags) 110 { 111 112 acpi_gbl_db_output_flags = (u8)output_flags; 113 114 if ((output_flags & ACPI_DB_REDIRECTABLE_OUTPUT) && 115 acpi_gbl_db_output_to_file) { 116 acpi_dbg_level = acpi_gbl_db_debug_level; 117 } else { 118 acpi_dbg_level = acpi_gbl_db_console_debug_level; 119 } 120 } 121 122 /******************************************************************************* 123 * 124 * FUNCTION: acpi_db_dump_external_object 125 * 126 * PARAMETERS: obj_desc - External ACPI object to dump 127 * level - Nesting level. 128 * 129 * RETURN: None 130 * 131 * DESCRIPTION: Dump the contents of an ACPI external object 132 * 133 ******************************************************************************/ 134 135 void acpi_db_dump_external_object(union acpi_object *obj_desc, u32 level) 136 { 137 u32 i; 138 139 if (!obj_desc) { 140 acpi_os_printf("[Null Object]\n"); 141 return; 142 } 143 144 for (i = 0; i < level; i++) { 145 acpi_os_printf(" "); 146 } 147 148 switch (obj_desc->type) { 149 case ACPI_TYPE_ANY: 150 151 acpi_os_printf("[Null Object] (Type=0)\n"); 152 break; 153 154 case ACPI_TYPE_INTEGER: 155 156 acpi_os_printf("[Integer] = %8.8X%8.8X\n", 157 ACPI_FORMAT_UINT64(obj_desc->integer.value)); 158 break; 159 160 case ACPI_TYPE_STRING: 161 162 acpi_os_printf("[String] Length %.2X = ", 163 obj_desc->string.length); 164 acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX); 165 acpi_os_printf("\n"); 166 break; 167 168 case ACPI_TYPE_BUFFER: 169 170 acpi_os_printf("[Buffer] Length %.2X = ", 171 obj_desc->buffer.length); 172 if (obj_desc->buffer.length) { 173 if (obj_desc->buffer.length > 16) { 174 acpi_os_printf("\n"); 175 } 176 177 acpi_ut_debug_dump_buffer(ACPI_CAST_PTR 178 (u8, 179 obj_desc->buffer.pointer), 180 obj_desc->buffer.length, 181 DB_BYTE_DISPLAY, _COMPONENT); 182 } else { 183 acpi_os_printf("\n"); 184 } 185 break; 186 187 case ACPI_TYPE_PACKAGE: 188 189 acpi_os_printf("[Package] Contains %u Elements:\n", 190 obj_desc->package.count); 191 192 for (i = 0; i < obj_desc->package.count; i++) { 193 acpi_db_dump_external_object(&obj_desc->package. 194 elements[i], level + 1); 195 } 196 break; 197 198 case ACPI_TYPE_LOCAL_REFERENCE: 199 200 acpi_os_printf("[Object Reference] = "); 201 acpi_db_display_internal_object(obj_desc->reference.handle, 202 NULL); 203 break; 204 205 case ACPI_TYPE_PROCESSOR: 206 207 acpi_os_printf("[Processor]\n"); 208 break; 209 210 case ACPI_TYPE_POWER: 211 212 acpi_os_printf("[Power Resource]\n"); 213 break; 214 215 default: 216 217 acpi_os_printf("[Unknown Type] %X\n", obj_desc->type); 218 break; 219 } 220 } 221 222 /******************************************************************************* 223 * 224 * FUNCTION: acpi_db_prep_namestring 225 * 226 * PARAMETERS: name - String to prepare 227 * 228 * RETURN: None 229 * 230 * DESCRIPTION: Translate all forward slashes and dots to backslashes. 231 * 232 ******************************************************************************/ 233 234 void acpi_db_prep_namestring(char *name) 235 { 236 237 if (!name) { 238 return; 239 } 240 241 acpi_ut_strupr(name); 242 243 /* Convert a leading forward slash to a backslash */ 244 245 if (*name == '/') { 246 *name = '\\'; 247 } 248 249 /* Ignore a leading backslash, this is the root prefix */ 250 251 if (ACPI_IS_ROOT_PREFIX(*name)) { 252 name++; 253 } 254 255 /* Convert all slash path separators to dots */ 256 257 while (*name) { 258 if ((*name == '/') || (*name == '\\')) { 259 *name = '.'; 260 } 261 262 name++; 263 } 264 } 265 266 /******************************************************************************* 267 * 268 * FUNCTION: acpi_db_local_ns_lookup 269 * 270 * PARAMETERS: name - Name to lookup 271 * 272 * RETURN: Pointer to a namespace node, null on failure 273 * 274 * DESCRIPTION: Lookup a name in the ACPI namespace 275 * 276 * Note: Currently begins search from the root. Could be enhanced to use 277 * the current prefix (scope) node as the search beginning point. 278 * 279 ******************************************************************************/ 280 281 struct acpi_namespace_node *acpi_db_local_ns_lookup(char *name) 282 { 283 char *internal_path; 284 acpi_status status; 285 struct acpi_namespace_node *node = NULL; 286 287 acpi_db_prep_namestring(name); 288 289 /* Build an internal namestring */ 290 291 status = acpi_ns_internalize_name(name, &internal_path); 292 if (ACPI_FAILURE(status)) { 293 acpi_os_printf("Invalid namestring: %s\n", name); 294 return (NULL); 295 } 296 297 /* 298 * Lookup the name. 299 * (Uses root node as the search starting point) 300 */ 301 status = acpi_ns_lookup(NULL, internal_path, ACPI_TYPE_ANY, 302 ACPI_IMODE_EXECUTE, 303 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, 304 NULL, &node); 305 if (ACPI_FAILURE(status)) { 306 acpi_os_printf("Could not locate name: %s, %s\n", 307 name, acpi_format_exception(status)); 308 } 309 310 ACPI_FREE(internal_path); 311 return (node); 312 } 313 314 /******************************************************************************* 315 * 316 * FUNCTION: acpi_db_uint32_to_hex_string 317 * 318 * PARAMETERS: value - The value to be converted to string 319 * buffer - Buffer for result (not less than 11 bytes) 320 * 321 * RETURN: None 322 * 323 * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image 324 * 325 * NOTE: It is the caller's responsibility to ensure that the length of buffer 326 * is sufficient. 327 * 328 ******************************************************************************/ 329 330 void acpi_db_uint32_to_hex_string(u32 value, char *buffer) 331 { 332 int i; 333 334 if (value == 0) { 335 strcpy(buffer, "0"); 336 return; 337 } 338 339 buffer[8] = '\0'; 340 341 for (i = 7; i >= 0; i--) { 342 buffer[i] = gbl_hex_to_ascii[value & 0x0F]; 343 value = value >> 4; 344 } 345 } 346 347 #ifdef ACPI_OBSOLETE_FUNCTIONS 348 /******************************************************************************* 349 * 350 * FUNCTION: acpi_db_second_pass_parse 351 * 352 * PARAMETERS: root - Root of the parse tree 353 * 354 * RETURN: Status 355 * 356 * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until 357 * second pass to parse the control methods 358 * 359 ******************************************************************************/ 360 361 acpi_status acpi_db_second_pass_parse(union acpi_parse_object *root) 362 { 363 union acpi_parse_object *op = root; 364 union acpi_parse_object *method; 365 union acpi_parse_object *search_op; 366 union acpi_parse_object *start_op; 367 acpi_status status = AE_OK; 368 u32 base_aml_offset; 369 struct acpi_walk_state *walk_state; 370 371 ACPI_FUNCTION_ENTRY(); 372 373 acpi_os_printf("Pass two parse ....\n"); 374 375 while (op) { 376 if (op->common.aml_opcode == AML_METHOD_OP) { 377 method = op; 378 379 /* Create a new walk state for the parse */ 380 381 walk_state = 382 acpi_ds_create_walk_state(0, NULL, NULL, NULL); 383 if (!walk_state) { 384 return (AE_NO_MEMORY); 385 } 386 387 /* Init the Walk State */ 388 389 walk_state->parser_state.aml = 390 walk_state->parser_state.aml_start = 391 method->named.data; 392 walk_state->parser_state.aml_end = 393 walk_state->parser_state.pkg_end = 394 method->named.data + method->named.length; 395 walk_state->parser_state.start_scope = op; 396 397 walk_state->descending_callback = 398 acpi_ds_load1_begin_op; 399 walk_state->ascending_callback = acpi_ds_load1_end_op; 400 401 /* Perform the AML parse */ 402 403 status = acpi_ps_parse_aml(walk_state); 404 405 base_aml_offset = 406 (method->common.value.arg)->common.aml_offset + 1; 407 start_op = (method->common.value.arg)->common.next; 408 search_op = start_op; 409 410 while (search_op) { 411 search_op->common.aml_offset += base_aml_offset; 412 search_op = 413 acpi_ps_get_depth_next(start_op, search_op); 414 } 415 } 416 417 if (op->common.aml_opcode == AML_REGION_OP) { 418 419 /* TBD: [Investigate] this isn't quite the right thing to do! */ 420 /* 421 * 422 * Method = (ACPI_DEFERRED_OP *) Op; 423 * Status = acpi_ps_parse_aml (Op, Method->Body, Method->body_length); 424 */ 425 } 426 427 if (ACPI_FAILURE(status)) { 428 break; 429 } 430 431 op = acpi_ps_get_depth_next(root, op); 432 } 433 434 return (status); 435 } 436 437 /******************************************************************************* 438 * 439 * FUNCTION: acpi_db_dump_buffer 440 * 441 * PARAMETERS: address - Pointer to the buffer 442 * 443 * RETURN: None 444 * 445 * DESCRIPTION: Print a portion of a buffer 446 * 447 ******************************************************************************/ 448 449 void acpi_db_dump_buffer(u32 address) 450 { 451 452 acpi_os_printf("\nLocation %X:\n", address); 453 454 acpi_dbg_level |= ACPI_LV_TABLES; 455 acpi_ut_debug_dump_buffer(ACPI_TO_POINTER(address), 64, DB_BYTE_DISPLAY, 456 ACPI_UINT32_MAX); 457 } 458 #endif 459