ifneq (${DEBUG}, 0)
BUILD_TYPE := debug
+ # Use LOG_LEVEL_INFO by default for debug builds
+ LOG_LEVEL := 40
else
BUILD_TYPE := release
+ # Use LOG_LEVEL_NOTICE by default for release builds
+ LOG_LEVEL := 20
endif
# Default build string (git branch and commit)
$(eval $(call assert_boolean,ASM_ASSERTION))
$(eval $(call add_define,ASM_ASSERTION))
+# Process LOG_LEVEL flag
+$(eval $(call add_define,LOG_LEVEL))
+
ASFLAGS += -nostdinc -ffreestanding -Wa,--fatal-warnings \
-Werror -Wmissing-include-dirs \
-mgeneral-regs-only -D__ASSEMBLY__ \
* `DEBUG`: Chooses between a debug and release build. It can take either 0
(release) or 1 (debug) as values. 0 is the default
+* `LOG_LEVEL`: Chooses the log level, which controls the amount of console log
+ output compiled into the build. This should be one of the following:
+
+ 0 (LOG_LEVEL_NONE)
+ 10 (LOG_LEVEL_NOTICE)
+ 20 (LOG_LEVEL_ERROR)
+ 30 (LOG_LEVEL_WARNING)
+ 40 (LOG_LEVEL_INFO)
+ 50 (LOG_LEVEL_VERBOSE)
+
+ All log output up to and including the log level is compiled into the build.
+ The default value is 40 in debug builds and 20 in release builds.
+
* `NS_TIMER_SWITCH`: Enable save and restore for non-secure timer register
contents upon world switch. It can take either 0 (don't save and restore) or
1 (do save and restore). 0 is the default. An SPD could set this to 1 if it
#include <stdio.h>
-/* If building the project with DEBUG disabled the INFO and WARN macros
- * won't produce any output. The ERROR macro is always enabled.
- * The format expected is the same as for printf().
- * INFO("Info %s.\n", "message") -> INFO: Info message.
- * WARN("Warning %s.\n", "message") -> WARN: Warning message.
- * ERROR("Error %s.\n", "message") -> ERROR: Error message.
- *
- * TODO : add debug levels.
+/* The log output macros print output to the console. These macros produce
+ * compiled log output only if the LOG_LEVEL defined in the makefile (or the
+ * make command line) is greater or equal than the level required for that
+ * type of log output.
+ * The format expected is the same as for printf(). For example:
+ * INFO("Info %s.\n", "message") -> INFO: Info message.
+ * WARN("Warning %s.\n", "message") -> WARNING: Warning message.
*/
-#if DEBUG
- #define INFO(...) tf_printf("INFO: " __VA_ARGS__)
- #define WARN(...) tf_printf("WARN: " __VA_ARGS__)
+
+#define LOG_LEVEL_NONE 0
+#define LOG_LEVEL_ERROR 10
+#define LOG_LEVEL_NOTICE 20
+#define LOG_LEVEL_WARNING 30
+#define LOG_LEVEL_INFO 40
+#define LOG_LEVEL_VERBOSE 50
+
+
+#if LOG_LEVEL >= LOG_LEVEL_NOTICE
+# define NOTICE(...) tf_printf("NOTICE: " __VA_ARGS__)
+#else
+# define NOTICE(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_ERROR
+# define ERROR(...) tf_printf("ERROR: " __VA_ARGS__)
+#else
+# define ERROR(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_WARNING
+# define WARN(...) tf_printf("WARNING: " __VA_ARGS__)
+#else
+# define WARN(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+# define INFO(...) tf_printf("INFO: " __VA_ARGS__)
+#else
+# define INFO(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+# define VERBOSE(...) tf_printf("VERBOSE: " __VA_ARGS__)
#else
- #define INFO(...)
- #define WARN(...)
+# define VERBOSE(...)
#endif
-#define ERROR(...) tf_printf("ERROR: " __VA_ARGS__)
void __dead2 do_panic(void);
#define panic() do_panic()