blob: bfbff093de7845a25c4ebaad9629d35a08f5ffa4 [file] [log] [blame]
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02001/*
2 * Copyright (c) 2014-2018, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef __DEBUG_H__
8#define __DEBUG_H__
9
10#include <stdio.h>
11
12/* TODO: Deal with per-image printf functions in a cleaner way. */
13
Antonio Nino Diaz0b1ab402018-12-05 15:38:39 +000014#if defined(IMAGE_CACTUS) || defined(IMAGE_IVY)
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020015/*
16 * The register MPIDR_EL1 can't be read from EL0, which means that mp_printf()
17 * can't be used.
18 */
19#define mp_printf printf
20#else
21/*
22 * Print a formatted string on the UART.
23 *
24 * Does the same thing as the standard libc's printf() function but in a MP-safe
25 * manner, i.e. it can be called from several CPUs simultaneously without
26 * getting interleaved messages.
27 *
28 * The messages printed using mp_printf() won't be saved in the test results
29 * (use tftf_testcase_output() instead for that). mp_printf() is meant to be
30 * used for debug traces only. Unlike messages stored in the tests output which
31 * appear only at the end of the test session in the test report, messages
32 * printed using mp_printf() will be displayed straight away.
33 *
34 * Messaged will be prefixed by the CPU MPID issuing the call, like that:
35 * [cpu 0x0002] Sending SGI #1 to cpu 0
36 */
37__attribute__((format(printf, 1, 2)))
38void mp_printf(const char *fmt, ...);
39#endif
40
41/*
42 * The log output macros print output to the console. These macros produce
43 * compiled log output only if the LOG_LEVEL defined in the makefile (or the
44 * make command line) is greater or equal than the level required for that
45 * type of log output.
46 * The format expected is similar to printf(). For example:
47 * INFO("Info %s.\n", "message") -> [cpu 0xxx] INFO: Info message.
48 * WARN("Warning %s.\n", "message") -> [cpu 0xxx] WARNING: Warning message.
49 */
50#define LOG_LEVEL_NONE 0
51#define LOG_LEVEL_ERROR 10
52#define LOG_LEVEL_NOTICE 20
53#define LOG_LEVEL_WARNING 30
54#define LOG_LEVEL_INFO 40
55#define LOG_LEVEL_VERBOSE 50
56
57#if LOG_LEVEL >= LOG_LEVEL_NOTICE
58# define NOTICE(...) mp_printf("NOTICE: " __VA_ARGS__)
59#else
60# define NOTICE(...)
61#endif
62
63#if LOG_LEVEL >= LOG_LEVEL_ERROR
64# define ERROR(...) mp_printf("ERROR: " __VA_ARGS__)
65#else
66# define ERROR(...)
67#endif
68
69#if LOG_LEVEL >= LOG_LEVEL_WARNING
70# define WARN(...) mp_printf("WARNING: " __VA_ARGS__)
71#else
72# define WARN(...)
73#endif
74
75#if LOG_LEVEL >= LOG_LEVEL_INFO
76# define INFO(...) mp_printf("INFO: " __VA_ARGS__)
77#else
78# define INFO(...)
79#endif
80
81#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
82# define VERBOSE(...) mp_printf("VERBOSE: " __VA_ARGS__)
83#else
84# define VERBOSE(...)
85#endif
86
87/*
88 * For the moment this Panic function is very basic, Report an error and
89 * spin. This can be expanded in the future to provide more information.
90 */
91#if DEBUG
92void __attribute__((__noreturn__)) do_panic(const char *file, int line);
93#define panic() do_panic(__FILE__, __LINE__)
94
95void __attribute__((__noreturn__)) do_bug_unreachable(const char *file, int line);
96#define bug_unreachable() do_bug_unreachable(__FILE__, __LINE__)
97
98#else
99void __attribute__((__noreturn__)) do_panic(void);
100#define panic() do_panic()
101
102void __attribute__((__noreturn__)) do_bug_unreachable(void);
103#define bug_unreachable() do_bug_unreachable()
104
105#endif
106
107#endif /* __DEBUG_H__ */