utdebug.c revision 1.22 1 /******************************************************************************
2 *
3 * Module Name: utdebug - Debug print/trace routines
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2023, 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 #define EXPORT_ACPI_INTERFACES
45
46 #include "acpi.h"
47 #include "accommon.h"
48 #include "acinterp.h"
49
50 #define _COMPONENT ACPI_UTILITIES
51 ACPI_MODULE_NAME ("utdebug")
52
53
54 #ifdef ACPI_DEBUG_OUTPUT
55
56 static ACPI_THREAD_ID AcpiGbl_PreviousThreadId = (ACPI_THREAD_ID) 0xFFFFFFFF;
57 static const char *AcpiGbl_FunctionEntryPrefix = "----Entry";
58 static const char *AcpiGbl_FunctionExitPrefix = "----Exit-";
59
60
61 /*******************************************************************************
62 *
63 * FUNCTION: AcpiUtInitStackPtrTrace
64 *
65 * PARAMETERS: None
66 *
67 * RETURN: None
68 *
69 * DESCRIPTION: Save the current CPU stack pointer at subsystem startup
70 *
71 ******************************************************************************/
72
73 void
74 AcpiUtInitStackPtrTrace (
75 void)
76 {
77 ACPI_SIZE CurrentSp;
78
79
80 #pragma GCC diagnostic push
81 #if defined(__GNUC__) && __GNUC__ >= 12
82 #pragma GCC diagnostic ignored "-Wdangling-pointer="
83 #endif
84 AcpiGbl_EntryStackPointer = &CurrentSp;
85 #pragma GCC diagnostic pop
86 }
87
88
89 /*******************************************************************************
90 *
91 * FUNCTION: AcpiUtTrackStackPtr
92 *
93 * PARAMETERS: None
94 *
95 * RETURN: None
96 *
97 * DESCRIPTION: Save the current CPU stack pointer
98 *
99 ******************************************************************************/
100
101 void
102 AcpiUtTrackStackPtr (
103 void)
104 {
105 ACPI_SIZE CurrentSp;
106
107
108 if (&CurrentSp < AcpiGbl_LowestStackPointer)
109 {
110 #pragma GCC diagnostic push
111 #if defined(__GNUC__) && __GNUC__ >= 12
112 #pragma GCC diagnostic ignored "-Wdangling-pointer="
113 #endif
114 AcpiGbl_LowestStackPointer = &CurrentSp;
115 #pragma GCC diagnostic pop
116 }
117
118 if (AcpiGbl_NestingLevel > AcpiGbl_DeepestNesting)
119 {
120 AcpiGbl_DeepestNesting = AcpiGbl_NestingLevel;
121 }
122 }
123
124
125 /*******************************************************************************
126 *
127 * FUNCTION: AcpiUtTrimFunctionName
128 *
129 * PARAMETERS: FunctionName - Ascii string containing a procedure name
130 *
131 * RETURN: Updated pointer to the function name
132 *
133 * DESCRIPTION: Remove the "Acpi" prefix from the function name, if present.
134 * This allows compiler macros such as __FUNCTION__ to be used
135 * with no change to the debug output.
136 *
137 ******************************************************************************/
138
139 static const char *
140 AcpiUtTrimFunctionName (
141 const char *FunctionName)
142 {
143
144 /* All Function names are longer than 4 chars, check is safe */
145
146 if (*(ACPI_CAST_PTR (UINT32, FunctionName)) == ACPI_PREFIX_MIXED)
147 {
148 /* This is the case where the original source has not been modified */
149
150 return (FunctionName + 4);
151 }
152
153 if (*(ACPI_CAST_PTR (UINT32, FunctionName)) == ACPI_PREFIX_LOWER)
154 {
155 /* This is the case where the source has been 'linuxized' */
156
157 return (FunctionName + 5);
158 }
159
160 return (FunctionName);
161 }
162
163
164 /*******************************************************************************
165 *
166 * FUNCTION: AcpiDebugPrint
167 *
168 * PARAMETERS: RequestedDebugLevel - Requested debug print level
169 * LineNumber - Caller's line number (for error output)
170 * FunctionName - Caller's procedure name
171 * ModuleName - Caller's module name
172 * ComponentId - Caller's component ID
173 * Format - Printf format field
174 * ... - Optional printf arguments
175 *
176 * RETURN: None
177 *
178 * DESCRIPTION: Print error message with prefix consisting of the module name,
179 * line number, and component ID.
180 *
181 ******************************************************************************/
182
183 void ACPI_INTERNAL_VAR_XFACE
184 AcpiDebugPrint (
185 UINT32 RequestedDebugLevel,
186 UINT32 LineNumber,
187 const char *FunctionName,
188 const char *ModuleName,
189 UINT32 ComponentId,
190 const char *Format,
191 ...)
192 {
193 ACPI_THREAD_ID ThreadId;
194 va_list args;
195 #ifdef ACPI_APPLICATION
196 int FillCount;
197 #endif
198
199 /* Check if debug output enabled */
200
201 if (!ACPI_IS_DEBUG_ENABLED (RequestedDebugLevel, ComponentId))
202 {
203 return;
204 }
205
206 /*
207 * Thread tracking and context switch notification
208 */
209 ThreadId = AcpiOsGetThreadId ();
210 if (ThreadId != AcpiGbl_PreviousThreadId)
211 {
212 if (ACPI_LV_THREADS & AcpiDbgLevel)
213 {
214 AcpiOsPrintf (
215 "\n**** Context Switch from TID %u to TID %u ****\n\n",
216 (UINT32) AcpiGbl_PreviousThreadId, (UINT32) ThreadId);
217 }
218
219 AcpiGbl_PreviousThreadId = ThreadId;
220 AcpiGbl_NestingLevel = 0;
221 }
222
223 /*
224 * Display the module name, current line number, thread ID (if requested),
225 * current procedure nesting level, and the current procedure name
226 */
227 AcpiOsPrintf ("%9s-%04d ", ModuleName, LineNumber);
228
229 #ifdef ACPI_APPLICATION
230 /*
231 * For AcpiExec/iASL only, emit the thread ID and nesting level.
232 * Note: nesting level is really only useful during a single-thread
233 * execution. Otherwise, multiple threads will keep resetting the
234 * level.
235 */
236 if (ACPI_LV_THREADS & AcpiDbgLevel)
237 {
238 AcpiOsPrintf ("[%u] ", (UINT32) ThreadId);
239 }
240
241 FillCount = 48 - AcpiGbl_NestingLevel -
242 strlen (AcpiUtTrimFunctionName (FunctionName));
243 if (FillCount < 0)
244 {
245 FillCount = 0;
246 }
247
248 AcpiOsPrintf ("[%02d] %*s",
249 AcpiGbl_NestingLevel, AcpiGbl_NestingLevel + 1, " ");
250 AcpiOsPrintf ("%s%*s: ",
251 AcpiUtTrimFunctionName (FunctionName), FillCount, " ");
252
253 #else
254 AcpiOsPrintf ("%-22.22s: ", AcpiUtTrimFunctionName (FunctionName));
255 #endif
256
257 va_start (args, Format);
258 AcpiOsVprintf (Format, args);
259 va_end (args);
260 }
261
262 ACPI_EXPORT_SYMBOL (AcpiDebugPrint)
263
264
265 /*******************************************************************************
266 *
267 * FUNCTION: AcpiDebugPrintRaw
268 *
269 * PARAMETERS: RequestedDebugLevel - Requested debug print level
270 * LineNumber - Caller's line number
271 * FunctionName - Caller's procedure name
272 * ModuleName - Caller's module name
273 * ComponentId - Caller's component ID
274 * Format - Printf format field
275 * ... - Optional printf arguments
276 *
277 * RETURN: None
278 *
279 * DESCRIPTION: Print message with no headers. Has same interface as
280 * DebugPrint so that the same macros can be used.
281 *
282 ******************************************************************************/
283
284 void ACPI_INTERNAL_VAR_XFACE
285 AcpiDebugPrintRaw (
286 UINT32 RequestedDebugLevel,
287 UINT32 LineNumber,
288 const char *FunctionName,
289 const char *ModuleName,
290 UINT32 ComponentId,
291 const char *Format,
292 ...)
293 {
294 va_list args;
295
296
297 /* Check if debug output enabled */
298
299 if (!ACPI_IS_DEBUG_ENABLED (RequestedDebugLevel, ComponentId))
300 {
301 return;
302 }
303
304 va_start (args, Format);
305 AcpiOsVprintf (Format, args);
306 va_end (args);
307 }
308
309 ACPI_EXPORT_SYMBOL (AcpiDebugPrintRaw)
310
311
312 /*******************************************************************************
313 *
314 * FUNCTION: AcpiUtTrace
315 *
316 * PARAMETERS: LineNumber - Caller's line number
317 * FunctionName - Caller's procedure name
318 * ModuleName - Caller's module name
319 * ComponentId - Caller's component ID
320 *
321 * RETURN: None
322 *
323 * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
324 * set in DebugLevel
325 *
326 ******************************************************************************/
327
328 void
329 AcpiUtTrace (
330 UINT32 LineNumber,
331 const char *FunctionName,
332 const char *ModuleName,
333 UINT32 ComponentId)
334 {
335
336 AcpiGbl_NestingLevel++;
337 AcpiUtTrackStackPtr ();
338
339 /* Check if enabled up-front for performance */
340
341 if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId))
342 {
343 AcpiDebugPrint (ACPI_LV_FUNCTIONS,
344 LineNumber, FunctionName, ModuleName, ComponentId,
345 "%s\n", AcpiGbl_FunctionEntryPrefix);
346 }
347 }
348
349 ACPI_EXPORT_SYMBOL (AcpiUtTrace)
350
351
352 /*******************************************************************************
353 *
354 * FUNCTION: AcpiUtTracePtr
355 *
356 * PARAMETERS: LineNumber - Caller's line number
357 * FunctionName - Caller's procedure name
358 * ModuleName - Caller's module name
359 * ComponentId - Caller's component ID
360 * Pointer - Pointer to display
361 *
362 * RETURN: None
363 *
364 * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
365 * set in DebugLevel
366 *
367 ******************************************************************************/
368
369 void
370 AcpiUtTracePtr (
371 UINT32 LineNumber,
372 const char *FunctionName,
373 const char *ModuleName,
374 UINT32 ComponentId,
375 const void *Pointer)
376 {
377
378 AcpiGbl_NestingLevel++;
379 AcpiUtTrackStackPtr ();
380
381 /* Check if enabled up-front for performance */
382
383 if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId))
384 {
385 AcpiDebugPrint (ACPI_LV_FUNCTIONS,
386 LineNumber, FunctionName, ModuleName, ComponentId,
387 "%s %p\n", AcpiGbl_FunctionEntryPrefix, Pointer);
388 }
389 }
390
391
392 /*******************************************************************************
393 *
394 * FUNCTION: AcpiUtTraceStr
395 *
396 * PARAMETERS: LineNumber - Caller's line number
397 * FunctionName - Caller's procedure name
398 * ModuleName - Caller's module name
399 * ComponentId - Caller's component ID
400 * String - Additional string to display
401 *
402 * RETURN: None
403 *
404 * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
405 * set in DebugLevel
406 *
407 ******************************************************************************/
408
409 void
410 AcpiUtTraceStr (
411 UINT32 LineNumber,
412 const char *FunctionName,
413 const char *ModuleName,
414 UINT32 ComponentId,
415 const char *String)
416 {
417
418 AcpiGbl_NestingLevel++;
419 AcpiUtTrackStackPtr ();
420
421 /* Check if enabled up-front for performance */
422
423 if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId))
424 {
425 AcpiDebugPrint (ACPI_LV_FUNCTIONS,
426 LineNumber, FunctionName, ModuleName, ComponentId,
427 "%s %s\n", AcpiGbl_FunctionEntryPrefix, String);
428 }
429 }
430
431
432 /*******************************************************************************
433 *
434 * FUNCTION: AcpiUtTraceU32
435 *
436 * PARAMETERS: LineNumber - Caller's line number
437 * FunctionName - Caller's procedure name
438 * ModuleName - Caller's module name
439 * ComponentId - Caller's component ID
440 * Integer - Integer to display
441 *
442 * RETURN: None
443 *
444 * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
445 * set in DebugLevel
446 *
447 ******************************************************************************/
448
449 void
450 AcpiUtTraceU32 (
451 UINT32 LineNumber,
452 const char *FunctionName,
453 const char *ModuleName,
454 UINT32 ComponentId,
455 UINT32 Integer)
456 {
457
458 AcpiGbl_NestingLevel++;
459 AcpiUtTrackStackPtr ();
460
461 /* Check if enabled up-front for performance */
462
463 if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId))
464 {
465 AcpiDebugPrint (ACPI_LV_FUNCTIONS,
466 LineNumber, FunctionName, ModuleName, ComponentId,
467 "%s %08X\n", AcpiGbl_FunctionEntryPrefix, Integer);
468 }
469 }
470
471
472 /*******************************************************************************
473 *
474 * FUNCTION: AcpiUtExit
475 *
476 * PARAMETERS: LineNumber - Caller's line number
477 * FunctionName - Caller's procedure name
478 * ModuleName - Caller's module name
479 * ComponentId - Caller's component ID
480 *
481 * RETURN: None
482 *
483 * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
484 * set in DebugLevel
485 *
486 ******************************************************************************/
487
488 void
489 AcpiUtExit (
490 UINT32 LineNumber,
491 const char *FunctionName,
492 const char *ModuleName,
493 UINT32 ComponentId)
494 {
495
496 /* Check if enabled up-front for performance */
497
498 if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId))
499 {
500 AcpiDebugPrint (ACPI_LV_FUNCTIONS,
501 LineNumber, FunctionName, ModuleName, ComponentId,
502 "%s\n", AcpiGbl_FunctionExitPrefix);
503 }
504
505 if (AcpiGbl_NestingLevel)
506 {
507 AcpiGbl_NestingLevel--;
508 }
509 }
510
511 ACPI_EXPORT_SYMBOL (AcpiUtExit)
512
513
514 /*******************************************************************************
515 *
516 * FUNCTION: AcpiUtStatusExit
517 *
518 * PARAMETERS: LineNumber - Caller's line number
519 * FunctionName - Caller's procedure name
520 * ModuleName - Caller's module name
521 * ComponentId - Caller's component ID
522 * Status - Exit status code
523 *
524 * RETURN: None
525 *
526 * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
527 * set in DebugLevel. Prints exit status also.
528 *
529 ******************************************************************************/
530
531 void
532 AcpiUtStatusExit (
533 UINT32 LineNumber,
534 const char *FunctionName,
535 const char *ModuleName,
536 UINT32 ComponentId,
537 ACPI_STATUS Status)
538 {
539
540 /* Check if enabled up-front for performance */
541
542 if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId))
543 {
544 if (ACPI_SUCCESS (Status))
545 {
546 AcpiDebugPrint (ACPI_LV_FUNCTIONS,
547 LineNumber, FunctionName, ModuleName, ComponentId,
548 "%s %s\n", AcpiGbl_FunctionExitPrefix,
549 AcpiFormatException (Status));
550 }
551 else
552 {
553 AcpiDebugPrint (ACPI_LV_FUNCTIONS,
554 LineNumber, FunctionName, ModuleName, ComponentId,
555 "%s ****Exception****: %s\n", AcpiGbl_FunctionExitPrefix,
556 AcpiFormatException (Status));
557 }
558 }
559
560 if (AcpiGbl_NestingLevel)
561 {
562 AcpiGbl_NestingLevel--;
563 }
564 }
565
566 ACPI_EXPORT_SYMBOL (AcpiUtStatusExit)
567
568
569 /*******************************************************************************
570 *
571 * FUNCTION: AcpiUtValueExit
572 *
573 * PARAMETERS: LineNumber - Caller's line number
574 * FunctionName - Caller's procedure name
575 * ModuleName - Caller's module name
576 * ComponentId - Caller's component ID
577 * Value - Value to be printed with exit msg
578 *
579 * RETURN: None
580 *
581 * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
582 * set in DebugLevel. Prints exit value also.
583 *
584 ******************************************************************************/
585
586 void
587 AcpiUtValueExit (
588 UINT32 LineNumber,
589 const char *FunctionName,
590 const char *ModuleName,
591 UINT32 ComponentId,
592 UINT64 Value)
593 {
594
595 /* Check if enabled up-front for performance */
596
597 if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId))
598 {
599 AcpiDebugPrint (ACPI_LV_FUNCTIONS,
600 LineNumber, FunctionName, ModuleName, ComponentId,
601 "%s %8.8X%8.8X\n", AcpiGbl_FunctionExitPrefix,
602 ACPI_FORMAT_UINT64 (Value));
603 }
604
605 if (AcpiGbl_NestingLevel)
606 {
607 AcpiGbl_NestingLevel--;
608 }
609 }
610
611 ACPI_EXPORT_SYMBOL (AcpiUtValueExit)
612
613
614 /*******************************************************************************
615 *
616 * FUNCTION: AcpiUtPtrExit
617 *
618 * PARAMETERS: LineNumber - Caller's line number
619 * FunctionName - Caller's procedure name
620 * ModuleName - Caller's module name
621 * ComponentId - Caller's component ID
622 * Ptr - Pointer to display
623 *
624 * RETURN: None
625 *
626 * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
627 * set in DebugLevel. Prints exit value also.
628 *
629 ******************************************************************************/
630
631 void
632 AcpiUtPtrExit (
633 UINT32 LineNumber,
634 const char *FunctionName,
635 const char *ModuleName,
636 UINT32 ComponentId,
637 UINT8 *Ptr)
638 {
639
640 /* Check if enabled up-front for performance */
641
642 if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId))
643 {
644 AcpiDebugPrint (ACPI_LV_FUNCTIONS,
645 LineNumber, FunctionName, ModuleName, ComponentId,
646 "%s %p\n", AcpiGbl_FunctionExitPrefix, Ptr);
647 }
648
649 if (AcpiGbl_NestingLevel)
650 {
651 AcpiGbl_NestingLevel--;
652 }
653 }
654
655
656 /*******************************************************************************
657 *
658 * FUNCTION: AcpiUtStrExit
659 *
660 * PARAMETERS: LineNumber - Caller's line number
661 * FunctionName - Caller's procedure name
662 * ModuleName - Caller's module name
663 * ComponentId - Caller's component ID
664 * String - String to display
665 *
666 * RETURN: None
667 *
668 * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
669 * set in DebugLevel. Prints exit value also.
670 *
671 ******************************************************************************/
672
673 void
674 AcpiUtStrExit (
675 UINT32 LineNumber,
676 const char *FunctionName,
677 const char *ModuleName,
678 UINT32 ComponentId,
679 const char *String)
680 {
681
682 /* Check if enabled up-front for performance */
683
684 if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId))
685 {
686 AcpiDebugPrint (ACPI_LV_FUNCTIONS,
687 LineNumber, FunctionName, ModuleName, ComponentId,
688 "%s %s\n", AcpiGbl_FunctionExitPrefix, String);
689 }
690
691 if (AcpiGbl_NestingLevel)
692 {
693 AcpiGbl_NestingLevel--;
694 }
695 }
696
697
698 /*******************************************************************************
699 *
700 * FUNCTION: AcpiTracePoint
701 *
702 * PARAMETERS: Type - Trace event type
703 * Begin - TRUE if before execution
704 * Aml - Executed AML address
705 * Pathname - Object path
706 * Pointer - Pointer to the related object
707 *
708 * RETURN: None
709 *
710 * DESCRIPTION: Interpreter execution trace.
711 *
712 ******************************************************************************/
713
714 void
715 AcpiTracePoint (
716 ACPI_TRACE_EVENT_TYPE Type,
717 BOOLEAN Begin,
718 UINT8 *Aml,
719 char *Pathname)
720 {
721
722 ACPI_FUNCTION_ENTRY ();
723
724 AcpiExTracePoint (Type, Begin, Aml, Pathname);
725
726 #ifdef ACPI_USE_SYSTEM_TRACER
727 AcpiOsTracePoint (Type, Begin, Aml, Pathname);
728 #endif
729 }
730
731 ACPI_EXPORT_SYMBOL (AcpiTracePoint)
732
733
734 #endif
735