1 /****************************************************************************** 2 * 3 * Module Name: exdebug - Support for stores to the AML Debug Object 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2021, 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 MERCHANTABILITY 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.h" 45 #include "accommon.h" 46 #include "acinterp.h" 47 48 49 #define _COMPONENT ACPI_EXECUTER 50 ACPI_MODULE_NAME ("exdebug") 51 52 53 #ifndef ACPI_NO_ERROR_MESSAGES 54 /******************************************************************************* 55 * 56 * FUNCTION: AcpiExDoDebugObject 57 * 58 * PARAMETERS: SourceDesc - Object to be output to "Debug Object" 59 * Level - Indentation level (used for packages) 60 * Index - Current package element, zero if not pkg 61 * 62 * RETURN: None 63 * 64 * DESCRIPTION: Handles stores to the AML Debug Object. For example: 65 * Store(INT1, Debug) 66 * 67 * This function is not compiled if ACPI_NO_ERROR_MESSAGES is set. 68 * 69 * This function is only enabled if AcpiGbl_EnableAmlDebugObject is set, or 70 * if ACPI_LV_DEBUG_OBJECT is set in the AcpiDbgLevel. Thus, in the normal 71 * operational case, stores to the debug object are ignored but can be easily 72 * enabled if necessary. 73 * 74 ******************************************************************************/ 75 76 void 77 AcpiExDoDebugObject ( 78 ACPI_OPERAND_OBJECT *SourceDesc, 79 UINT32 Level, 80 UINT32 Index) 81 { 82 UINT32 i; 83 UINT32 Timer; 84 ACPI_OPERAND_OBJECT *ObjectDesc; 85 UINT32 Value; 86 87 88 ACPI_FUNCTION_TRACE_PTR (ExDoDebugObject, SourceDesc); 89 90 91 /* Output must be enabled via the DebugObject global or the DbgLevel */ 92 93 if (!AcpiGbl_EnableAmlDebugObject && 94 !(AcpiDbgLevel & ACPI_LV_DEBUG_OBJECT)) 95 { 96 return_VOID; 97 } 98 99 /* Newline -- don't emit the line header */ 100 101 if (SourceDesc && 102 (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_OPERAND) && 103 (SourceDesc->Common.Type == ACPI_TYPE_STRING)) 104 { 105 if ((SourceDesc->String.Length == 1) && 106 (*SourceDesc->String.Pointer == '\n')) 107 { 108 AcpiOsPrintf ("\n"); 109 return_VOID; 110 } 111 } 112 113 /* 114 * Print line header as long as we are not in the middle of an 115 * object display 116 */ 117 if (!((Level > 0) && Index == 0)) 118 { 119 if (AcpiGbl_DisplayDebugTimer) 120 { 121 /* 122 * We will emit the current timer value (in microseconds) with each 123 * debug output. Only need the lower 26 bits. This allows for 67 124 * million microseconds or 67 seconds before rollover. 125 * 126 * Convert 100 nanosecond units to microseconds 127 */ 128 Timer = ((UINT32) AcpiOsGetTimer () / 10); 129 Timer &= 0x03FFFFFF; 130 131 AcpiOsPrintf ("ACPI Debug: T=0x%8.8X %*s", Timer, Level, " "); 132 } 133 else 134 { 135 AcpiOsPrintf ("ACPI Debug: %*s", Level, " "); 136 } 137 } 138 139 /* Display the index for package output only */ 140 141 if (Index > 0) 142 { 143 AcpiOsPrintf ("(%.2u) ", Index - 1); 144 } 145 146 if (!SourceDesc) 147 { 148 AcpiOsPrintf ("[Null Object]\n"); 149 return_VOID; 150 } 151 152 if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_OPERAND) 153 { 154 /* No object type prefix needed for integers and strings */ 155 156 if ((SourceDesc->Common.Type != ACPI_TYPE_INTEGER) && 157 (SourceDesc->Common.Type != ACPI_TYPE_STRING)) 158 { 159 AcpiOsPrintf ("%s ", AcpiUtGetObjectTypeName (SourceDesc)); 160 } 161 162 if (!AcpiUtValidInternalObject (SourceDesc)) 163 { 164 AcpiOsPrintf ("%p, Invalid Internal Object!\n", SourceDesc); 165 return_VOID; 166 } 167 } 168 else if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED) 169 { 170 AcpiOsPrintf ("%s (Node %p)\n", 171 AcpiUtGetTypeName (((ACPI_NAMESPACE_NODE *) SourceDesc)->Type), 172 SourceDesc); 173 return_VOID; 174 } 175 else 176 { 177 return_VOID; 178 } 179 180 /* SourceDesc is of type ACPI_DESC_TYPE_OPERAND */ 181 182 switch (SourceDesc->Common.Type) 183 { 184 case ACPI_TYPE_INTEGER: 185 186 /* Output correct integer width */ 187 188 if (AcpiGbl_IntegerByteWidth == 4) 189 { 190 AcpiOsPrintf ("0x%8.8X\n", 191 (UINT32) SourceDesc->Integer.Value); 192 } 193 else 194 { 195 AcpiOsPrintf ("0x%8.8X%8.8X\n", 196 ACPI_FORMAT_UINT64 (SourceDesc->Integer.Value)); 197 } 198 break; 199 200 case ACPI_TYPE_BUFFER: 201 202 AcpiOsPrintf ("[0x%.2X]\n", (UINT32) SourceDesc->Buffer.Length); 203 AcpiUtDumpBuffer (SourceDesc->Buffer.Pointer, 204 (SourceDesc->Buffer.Length < 256) ? 205 SourceDesc->Buffer.Length : 256, DB_BYTE_DISPLAY, 0); 206 break; 207 208 case ACPI_TYPE_STRING: 209 210 AcpiOsPrintf ("\"%s\"\n", SourceDesc->String.Pointer); 211 break; 212 213 case ACPI_TYPE_PACKAGE: 214 215 AcpiOsPrintf ("(Contains 0x%.2X Elements):\n", 216 SourceDesc->Package.Count); 217 218 /* Output the entire contents of the package */ 219 220 for (i = 0; i < SourceDesc->Package.Count; i++) 221 { 222 AcpiExDoDebugObject (SourceDesc->Package.Elements[i], 223 Level + 4, i + 1); 224 } 225 break; 226 227 case ACPI_TYPE_LOCAL_REFERENCE: 228 229 AcpiOsPrintf ("[%s] ", AcpiUtGetReferenceName (SourceDesc)); 230 231 /* Decode the reference */ 232 233 switch (SourceDesc->Reference.Class) 234 { 235 case ACPI_REFCLASS_INDEX: 236 237 AcpiOsPrintf ("0x%X\n", SourceDesc->Reference.Value); 238 break; 239 240 case ACPI_REFCLASS_TABLE: 241 242 /* Case for DdbHandle */ 243 244 AcpiOsPrintf ("Table Index 0x%X\n", SourceDesc->Reference.Value); 245 return_VOID; 246 247 default: 248 249 break; 250 } 251 252 AcpiOsPrintf (" "); 253 254 /* Check for valid node first, then valid object */ 255 256 if (SourceDesc->Reference.Node) 257 { 258 if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Node) != 259 ACPI_DESC_TYPE_NAMED) 260 { 261 AcpiOsPrintf (" %p - Not a valid namespace node\n", 262 SourceDesc->Reference.Node); 263 } 264 else 265 { 266 AcpiOsPrintf ("Node %p [%4.4s] ", SourceDesc->Reference.Node, 267 (SourceDesc->Reference.Node)->Name.Ascii); 268 269 switch ((SourceDesc->Reference.Node)->Type) 270 { 271 /* These types have no attached object */ 272 273 case ACPI_TYPE_DEVICE: 274 AcpiOsPrintf ("Device\n"); 275 break; 276 277 case ACPI_TYPE_THERMAL: 278 AcpiOsPrintf ("Thermal Zone\n"); 279 break; 280 281 default: 282 283 AcpiExDoDebugObject ((SourceDesc->Reference.Node)->Object, 284 Level + 4, 0); 285 break; 286 } 287 } 288 } 289 else if (SourceDesc->Reference.Object) 290 { 291 if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Object) == 292 ACPI_DESC_TYPE_NAMED) 293 { 294 /* Reference object is a namespace node */ 295 296 AcpiExDoDebugObject (ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, 297 SourceDesc->Reference.Object), 298 Level + 4, 0); 299 } 300 else 301 { 302 ObjectDesc = SourceDesc->Reference.Object; 303 Value = SourceDesc->Reference.Value; 304 305 switch (ObjectDesc->Common.Type) 306 { 307 case ACPI_TYPE_BUFFER: 308 309 AcpiOsPrintf ("Buffer[%u] = 0x%2.2X\n", 310 Value, *SourceDesc->Reference.IndexPointer); 311 break; 312 313 case ACPI_TYPE_STRING: 314 315 AcpiOsPrintf ("String[%u] = \"%c\" (0x%2.2X)\n", 316 Value, *SourceDesc->Reference.IndexPointer, 317 *SourceDesc->Reference.IndexPointer); 318 break; 319 320 case ACPI_TYPE_PACKAGE: 321 322 AcpiOsPrintf ("Package[%u] = ", Value); 323 if (!(*SourceDesc->Reference.Where)) 324 { 325 AcpiOsPrintf ("[Uninitialized Package Element]\n"); 326 } 327 else 328 { 329 AcpiExDoDebugObject (*SourceDesc->Reference.Where, 330 Level+4, 0); 331 } 332 break; 333 334 default: 335 336 AcpiOsPrintf ("Unknown Reference object type %X\n", 337 ObjectDesc->Common.Type); 338 break; 339 } 340 } 341 } 342 break; 343 344 default: 345 346 AcpiOsPrintf ("(Descriptor %p)\n", SourceDesc); 347 break; 348 } 349 350 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n")); 351 return_VOID; 352 } 353 #endif 354