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