1*54fd6939SJiyong Park /* 2*54fd6939SJiyong Park * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved. 3*54fd6939SJiyong Park * 4*54fd6939SJiyong Park * SPDX-License-Identifier: BSD-3-Clause 5*54fd6939SJiyong Park */ 6*54fd6939SJiyong Park 7*54fd6939SJiyong Park #include <stdarg.h> 8*54fd6939SJiyong Park #include <assert.h> 9*54fd6939SJiyong Park #include <stdio.h> 10*54fd6939SJiyong Park 11*54fd6939SJiyong Park #include <common/debug.h> 12*54fd6939SJiyong Park #include <plat/common/platform.h> 13*54fd6939SJiyong Park 14*54fd6939SJiyong Park /* Set the default maximum log level to the `LOG_LEVEL` build flag */ 15*54fd6939SJiyong Park static unsigned int max_log_level = LOG_LEVEL; 16*54fd6939SJiyong Park 17*54fd6939SJiyong Park /* 18*54fd6939SJiyong Park * The common log function which is invoked by TF-A code. 19*54fd6939SJiyong Park * This function should not be directly invoked and is meant to be 20*54fd6939SJiyong Park * only used by the log macros defined in debug.h. The function 21*54fd6939SJiyong Park * expects the first character in the format string to be one of the 22*54fd6939SJiyong Park * LOG_MARKER_* macros defined in debug.h. 23*54fd6939SJiyong Park */ tf_log(const char * fmt,...)24*54fd6939SJiyong Parkvoid tf_log(const char *fmt, ...) 25*54fd6939SJiyong Park { 26*54fd6939SJiyong Park unsigned int log_level; 27*54fd6939SJiyong Park va_list args; 28*54fd6939SJiyong Park const char *prefix_str; 29*54fd6939SJiyong Park 30*54fd6939SJiyong Park /* We expect the LOG_MARKER_* macro as the first character */ 31*54fd6939SJiyong Park log_level = fmt[0]; 32*54fd6939SJiyong Park 33*54fd6939SJiyong Park /* Verify that log_level is one of LOG_MARKER_* macro defined in debug.h */ 34*54fd6939SJiyong Park assert((log_level > 0U) && (log_level <= LOG_LEVEL_VERBOSE)); 35*54fd6939SJiyong Park assert((log_level % 10U) == 0U); 36*54fd6939SJiyong Park 37*54fd6939SJiyong Park if (log_level > max_log_level) 38*54fd6939SJiyong Park return; 39*54fd6939SJiyong Park 40*54fd6939SJiyong Park prefix_str = plat_log_get_prefix(log_level); 41*54fd6939SJiyong Park 42*54fd6939SJiyong Park while (*prefix_str != '\0') { 43*54fd6939SJiyong Park (void)putchar(*prefix_str); 44*54fd6939SJiyong Park prefix_str++; 45*54fd6939SJiyong Park } 46*54fd6939SJiyong Park 47*54fd6939SJiyong Park va_start(args, fmt); 48*54fd6939SJiyong Park (void)vprintf(fmt + 1, args); 49*54fd6939SJiyong Park va_end(args); 50*54fd6939SJiyong Park } 51*54fd6939SJiyong Park tf_log_newline(const char log_fmt[2])52*54fd6939SJiyong Parkvoid tf_log_newline(const char log_fmt[2]) 53*54fd6939SJiyong Park { 54*54fd6939SJiyong Park unsigned int log_level = log_fmt[0]; 55*54fd6939SJiyong Park 56*54fd6939SJiyong Park /* Verify that log_level is one of LOG_MARKER_* macro defined in debug.h */ 57*54fd6939SJiyong Park assert((log_level > 0U) && (log_level <= LOG_LEVEL_VERBOSE)); 58*54fd6939SJiyong Park assert((log_level % 10U) == 0U); 59*54fd6939SJiyong Park 60*54fd6939SJiyong Park if (log_level > max_log_level) 61*54fd6939SJiyong Park return; 62*54fd6939SJiyong Park 63*54fd6939SJiyong Park putchar('\n'); 64*54fd6939SJiyong Park } 65*54fd6939SJiyong Park 66*54fd6939SJiyong Park /* 67*54fd6939SJiyong Park * The helper function to set the log level dynamically by platform. The 68*54fd6939SJiyong Park * maximum log level is determined by `LOG_LEVEL` build flag at compile time 69*54fd6939SJiyong Park * and this helper can set a lower (or equal) log level than the one at compile. 70*54fd6939SJiyong Park */ tf_log_set_max_level(unsigned int log_level)71*54fd6939SJiyong Parkvoid tf_log_set_max_level(unsigned int log_level) 72*54fd6939SJiyong Park { 73*54fd6939SJiyong Park assert(log_level <= LOG_LEVEL_VERBOSE); 74*54fd6939SJiyong Park assert((log_level % 10U) == 0U); 75*54fd6939SJiyong Park 76*54fd6939SJiyong Park /* Cap log_level to the compile time maximum. */ 77*54fd6939SJiyong Park if (log_level <= (unsigned int)LOG_LEVEL) 78*54fd6939SJiyong Park max_log_level = log_level; 79*54fd6939SJiyong Park } 80