| // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later | 
 | /* | 
 |  * Console Log routines | 
 |  * Wraps libc and console lower level functions | 
 |  * does fancy-schmancy things like timestamps and priorities | 
 |  * Doesn't make waffles. | 
 |  * | 
 |  * Copyright 2013-2018 IBM Corp. | 
 |  */ | 
 |  | 
 | #include "skiboot.h" | 
 | #include "unistd.h" | 
 | #include "stdio.h" | 
 | #include "console.h" | 
 | #include "timebase.h" | 
 | #include <debug_descriptor.h> | 
 |  | 
 | int vprlog(int log_level, const char *fmt, va_list ap) | 
 | { | 
 | 	int count; | 
 | 	char buffer[320]; | 
 | 	bool flush_to_drivers = true; | 
 | 	unsigned long tb = mftb(); | 
 |  | 
 | 	/* It's safe to return 0 when we "did" something here | 
 | 	 * as only printf cares about how much we wrote, and | 
 | 	 * if you change log_level to below PR_PRINTF then you | 
 | 	 * get everything you deserve. | 
 | 	 * By default, only PR_DEBUG and higher are stored in memory. | 
 | 	 * PR_TRACE and PR_INSANE are for those having a bad day. | 
 | 	 */ | 
 | 	if (log_level > (debug_descriptor.console_log_levels >> 4)) | 
 | 		return 0; | 
 |  | 
 | 	count = snprintf(buffer, sizeof(buffer), "[%5lu.%09lu,%d] ", | 
 | 			 tb_to_secs(tb), tb_remaining_nsecs(tb), log_level); | 
 | 	count+= vsnprintf(buffer+count, sizeof(buffer)-count, fmt, ap); | 
 |  | 
 | 	if (log_level > (debug_descriptor.console_log_levels & 0x0f)) | 
 | 		flush_to_drivers = false; | 
 |  | 
 | 	console_write(flush_to_drivers, buffer, count); | 
 |  | 
 | 	return count; | 
 | } | 
 |  | 
 | /* we don't return anything as what on earth are we going to do | 
 |  * if we actually fail to print a log message? Print a log message about it? | 
 |  * Callers shouldn't care, prlog and friends should do something generically | 
 |  * sane in such crazy situations. | 
 |  */ | 
 | void _prlog(int log_level, const char* fmt, ...) | 
 | { | 
 | 	va_list ap; | 
 |  | 
 | 	va_start(ap, fmt); | 
 | 	vprlog(log_level, fmt, ap); | 
 | 	va_end(ap); | 
 | } | 
 |  | 
 | int _printf(const char* fmt, ...) | 
 | { | 
 | 	int count; | 
 | 	va_list ap; | 
 |  | 
 | 	va_start(ap, fmt); | 
 | 	count = vprlog(PR_PRINTF, fmt, ap); | 
 | 	va_end(ap); | 
 |  | 
 | 	return count; | 
 | } |