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