309 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/******************************************************************************3 *4 * Module Name: exdebug - Support for stores to the AML Debug Object5 *6 * Copyright (C) 2000 - 2023, Intel Corp.7 *8 *****************************************************************************/9 10#include <acpi/acpi.h>11#include "accommon.h"12#include "acinterp.h"13 14#define _COMPONENT ACPI_EXECUTER15ACPI_MODULE_NAME("exdebug")16 17#ifndef ACPI_NO_ERROR_MESSAGES18/*******************************************************************************19 *20 * FUNCTION: acpi_ex_do_debug_object21 *22 * PARAMETERS: source_desc - Object to be output to "Debug Object"23 * level - Indentation level (used for packages)24 * index - Current package element, zero if not pkg25 *26 * RETURN: None27 *28 * DESCRIPTION: Handles stores to the AML Debug Object. For example:29 * Store(INT1, Debug)30 *31 * This function is not compiled if ACPI_NO_ERROR_MESSAGES is set.32 *33 * This function is only enabled if acpi_gbl_enable_aml_debug_object is set, or34 * if ACPI_LV_DEBUG_OBJECT is set in the acpi_dbg_level. Thus, in the normal35 * operational case, stores to the debug object are ignored but can be easily36 * enabled if necessary.37 *38 ******************************************************************************/39void40acpi_ex_do_debug_object(union acpi_operand_object *source_desc,41 u32 level, u32 index)42{43 u32 i;44 u32 timer;45 union acpi_operand_object *object_desc;46 u32 value;47 48 ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc);49 50 /* Output must be enabled via the debug_object global or the dbg_level */51 52 if (!acpi_gbl_enable_aml_debug_object &&53 !(acpi_dbg_level & ACPI_LV_DEBUG_OBJECT)) {54 return_VOID;55 }56 57 /* Newline -- don't emit the line header */58 59 if (source_desc &&60 (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_OPERAND) &&61 (source_desc->common.type == ACPI_TYPE_STRING)) {62 if ((source_desc->string.length == 1) &&63 (*source_desc->string.pointer == '\n')) {64 acpi_os_printf("\n");65 return_VOID;66 }67 }68 69 /*70 * Print line header as long as we are not in the middle of an71 * object display72 */73 if (!((level > 0) && index == 0)) {74 if (acpi_gbl_display_debug_timer) {75 /*76 * We will emit the current timer value (in microseconds) with each77 * debug output. Only need the lower 26 bits. This allows for 6778 * million microseconds or 67 seconds before rollover.79 *80 * Convert 100 nanosecond units to microseconds81 */82 timer = ((u32)acpi_os_get_timer() / 10);83 timer &= 0x03FFFFFF;84 85 acpi_os_printf("ACPI Debug: T=0x%8.8X %*s", timer,86 level, " ");87 } else {88 acpi_os_printf("ACPI Debug: %*s", level, " ");89 }90 }91 92 /* Display the index for package output only */93 94 if (index > 0) {95 acpi_os_printf("(%.2u) ", index - 1);96 }97 98 if (!source_desc) {99 acpi_os_printf("[Null Object]\n");100 return_VOID;101 }102 103 if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_OPERAND) {104 105 /* No object type prefix needed for integers and strings */106 107 if ((source_desc->common.type != ACPI_TYPE_INTEGER) &&108 (source_desc->common.type != ACPI_TYPE_STRING)) {109 acpi_os_printf("%s ",110 acpi_ut_get_object_type_name111 (source_desc));112 }113 114 if (!acpi_ut_valid_internal_object(source_desc)) {115 acpi_os_printf("%p, Invalid Internal Object!\n",116 source_desc);117 return_VOID;118 }119 } else if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) ==120 ACPI_DESC_TYPE_NAMED) {121 acpi_os_printf("%s (Node %p)\n",122 acpi_ut_get_type_name(((struct123 acpi_namespace_node *)124 source_desc)->type),125 source_desc);126 return_VOID;127 } else {128 return_VOID;129 }130 131 /* source_desc is of type ACPI_DESC_TYPE_OPERAND */132 133 switch (source_desc->common.type) {134 case ACPI_TYPE_INTEGER:135 136 /* Output correct integer width */137 138 if (acpi_gbl_integer_byte_width == 4) {139 acpi_os_printf("0x%8.8X\n",140 (u32)source_desc->integer.value);141 } else {142 acpi_os_printf("0x%8.8X%8.8X\n",143 ACPI_FORMAT_UINT64(source_desc->integer.144 value));145 }146 break;147 148 case ACPI_TYPE_BUFFER:149 150 acpi_os_printf("[0x%.2X]\n", (u32)source_desc->buffer.length);151 acpi_ut_dump_buffer(source_desc->buffer.pointer,152 (source_desc->buffer.length < 256) ?153 source_desc->buffer.length : 256,154 DB_BYTE_DISPLAY, 0);155 break;156 157 case ACPI_TYPE_STRING:158 159 acpi_os_printf("\"%s\"\n", source_desc->string.pointer);160 break;161 162 case ACPI_TYPE_PACKAGE:163 164 acpi_os_printf("(Contains 0x%.2X Elements):\n",165 source_desc->package.count);166 167 /* Output the entire contents of the package */168 169 for (i = 0; i < source_desc->package.count; i++) {170 acpi_ex_do_debug_object(source_desc->package.171 elements[i], level + 4, i + 1);172 }173 break;174 175 case ACPI_TYPE_LOCAL_REFERENCE:176 177 acpi_os_printf("[%s] ",178 acpi_ut_get_reference_name(source_desc));179 180 /* Decode the reference */181 182 switch (source_desc->reference.class) {183 case ACPI_REFCLASS_INDEX:184 185 acpi_os_printf("0x%X\n", source_desc->reference.value);186 break;187 188 case ACPI_REFCLASS_TABLE:189 190 /* Case for ddb_handle */191 192 acpi_os_printf("Table Index 0x%X\n",193 source_desc->reference.value);194 return_VOID;195 196 default:197 198 break;199 }200 201 acpi_os_printf(" ");202 203 /* Check for valid node first, then valid object */204 205 if (source_desc->reference.node) {206 if (ACPI_GET_DESCRIPTOR_TYPE207 (source_desc->reference.node) !=208 ACPI_DESC_TYPE_NAMED) {209 acpi_os_printf210 (" %p - Not a valid namespace node\n",211 source_desc->reference.node);212 } else {213 acpi_os_printf("Node %p [%4.4s] ",214 source_desc->reference.node,215 (source_desc->reference.node)->216 name.ascii);217 218 switch ((source_desc->reference.node)->type) {219 220 /* These types have no attached object */221 222 case ACPI_TYPE_DEVICE:223 acpi_os_printf("Device\n");224 break;225 226 case ACPI_TYPE_THERMAL:227 acpi_os_printf("Thermal Zone\n");228 break;229 230 default:231 232 acpi_ex_do_debug_object((source_desc->233 reference.234 node)->object,235 level + 4, 0);236 break;237 }238 }239 } else if (source_desc->reference.object) {240 if (ACPI_GET_DESCRIPTOR_TYPE241 (source_desc->reference.object) ==242 ACPI_DESC_TYPE_NAMED) {243 244 /* Reference object is a namespace node */245 246 acpi_ex_do_debug_object(ACPI_CAST_PTR247 (union248 acpi_operand_object,249 source_desc->reference.250 object), level + 4, 0);251 } else {252 object_desc = source_desc->reference.object;253 value = source_desc->reference.value;254 255 switch (object_desc->common.type) {256 case ACPI_TYPE_BUFFER:257 258 acpi_os_printf("Buffer[%u] = 0x%2.2X\n",259 value,260 *source_desc->reference.261 index_pointer);262 break;263 264 case ACPI_TYPE_STRING:265 266 acpi_os_printf267 ("String[%u] = \"%c\" (0x%2.2X)\n",268 value,269 *source_desc->reference.270 index_pointer,271 *source_desc->reference.272 index_pointer);273 break;274 275 case ACPI_TYPE_PACKAGE:276 277 acpi_os_printf("Package[%u] = ", value);278 if (!(*source_desc->reference.where)) {279 acpi_os_printf280 ("[Uninitialized Package Element]\n");281 } else {282 acpi_ex_do_debug_object283 (*source_desc->reference.284 where, level + 4, 0);285 }286 break;287 288 default:289 290 acpi_os_printf291 ("Unknown Reference object type %X\n",292 object_desc->common.type);293 break;294 }295 }296 }297 break;298 299 default:300 301 acpi_os_printf("(Descriptor %p)\n", source_desc);302 break;303 }304 305 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "\n"));306 return_VOID;307}308#endif309