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