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