aboutsummaryrefslogtreecommitdiffstats
path: root/common/tf_printf.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/tf_printf.c')
-rw-r--r--common/tf_printf.c145
1 files changed, 73 insertions, 72 deletions
diff --git a/common/tf_printf.c b/common/tf_printf.c
index 02461c0b..f73842ac 100644
--- a/common/tf_printf.c
+++ b/common/tf_printf.c
@@ -1,44 +1,41 @@
/*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of ARM nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
#include <debug.h>
+#include <limits.h>
#include <stdarg.h>
#include <stdint.h>
/***********************************************************
* The tf_printf implementation for all BL stages
***********************************************************/
-static void unsigned_num_print(unsigned long int unum, unsigned int radix)
+
+#define get_num_va_args(args, lcount) \
+ (((lcount) > 1) ? va_arg(args, long long int) : \
+ ((lcount) ? va_arg(args, long int) : va_arg(args, int)))
+
+#define get_unum_va_args(args, lcount) \
+ (((lcount) > 1) ? va_arg(args, unsigned long long int) : \
+ ((lcount) ? va_arg(args, unsigned long int) : va_arg(args, unsigned int)))
+
+void tf_string_print(const char *str)
+{
+ assert(str);
+
+ while (*str)
+ putchar(*str++);
+}
+
+static void unsigned_num_print(unsigned long long int unum, unsigned int radix)
{
/* Just need enough space to store 64 bit decimal integer */
unsigned char num_buf[20];
- int i = 0 , rem;
+ int i = 0, rem;
do {
rem = unum % radix;
@@ -52,36 +49,32 @@ static void unsigned_num_print(unsigned long int unum, unsigned int radix)
putchar(num_buf[i]);
}
-static void string_print(const char *str)
-{
- while (*str)
- putchar(*str++);
-}
-
/*******************************************************************
* Reduced format print for Trusted firmware.
- * The following formats are supported by this print
- * %x - 32 bit hexadecimal format
- * %llx and %lx -64 bit hexadecimal format
+ * The following type specifiers are supported by this print
+ * %x - hexadecimal format
* %s - string format
- * %d or %i - signed 32 bit decimal format
- * %u - unsigned 32 bit decimal format
- * %ld and %lld - signed 64 bit decimal format
- * %lu and %llu - unsigned 64 bit decimal format
- * Exits on all other formats.
+ * %d or %i - signed decimal format
+ * %u - unsigned decimal format
+ * %p - pointer format
+ *
+ * The following length specifiers are supported by this print
+ * %l - long int (64-bit on AArch64)
+ * %ll - long long int (64-bit on AArch64)
+ * %z - size_t sized integer formats (64 bit on AArch64)
+ *
+ * The print exits on all other formats specifiers other than valid
+ * combinations of the above specifiers.
*******************************************************************/
-
-void tf_printf(const char *fmt, ...)
+void tf_vprintf(const char *fmt, va_list args)
{
- va_list args;
- int bit64;
- int64_t num;
- uint64_t unum;
+ int l_count;
+ long long int num;
+ unsigned long long int unum;
char *str;
- va_start(args, fmt);
while (*fmt) {
- bit64 = 0;
+ l_count = 0;
if (*fmt == '%') {
fmt++;
@@ -90,52 +83,60 @@ loop:
switch (*fmt) {
case 'i': /* Fall through to next one */
case 'd':
- if (bit64)
- num = va_arg(args, int64_t);
- else
- num = va_arg(args, int32_t);
-
+ num = get_num_va_args(args, l_count);
if (num < 0) {
putchar('-');
- unum = (unsigned long int)-num;
+ unum = (unsigned long long int)-num;
} else
- unum = (unsigned long int)num;
+ unum = (unsigned long long int)num;
unsigned_num_print(unum, 10);
break;
case 's':
str = va_arg(args, char *);
- string_print(str);
+ tf_string_print(str);
break;
- case 'x':
- if (bit64)
- unum = va_arg(args, uint64_t);
- else
- unum = va_arg(args, uint32_t);
+ case 'p':
+ unum = (uintptr_t)va_arg(args, void *);
+ if (unum)
+ tf_string_print("0x");
unsigned_num_print(unum, 16);
break;
+ case 'x':
+ unum = get_unum_va_args(args, l_count);
+ unsigned_num_print(unum, 16);
+ break;
+ case 'z':
+ if (sizeof(size_t) == 8)
+ l_count = 2;
+
+ fmt++;
+ goto loop;
case 'l':
- bit64 = 1;
+ l_count++;
fmt++;
goto loop;
case 'u':
- if (bit64)
- unum = va_arg(args, uint64_t);
- else
- unum = va_arg(args, uint32_t);
-
+ unum = get_unum_va_args(args, l_count);
unsigned_num_print(unum, 10);
break;
default:
/* Exit on any other format specifier */
- goto exit;
+ return;
}
fmt++;
continue;
}
putchar(*fmt++);
}
-exit:
- va_end(args);
+}
+
+void tf_printf(const char *fmt, ...)
+{
+ va_list va;
+
+ va_start(va, fmt);
+ tf_vprintf(fmt, va);
+ va_end(va);
}