libc: Move tf_printf and tf_snprintf to libc
authorAntonio Nino Diaz <antonio.ninodiaz@arm.com>
Wed, 15 Aug 2018 16:02:28 +0000 (17:02 +0100)
committerAntonio Nino Diaz <antonio.ninodiaz@arm.com>
Wed, 22 Aug 2018 09:26:05 +0000 (10:26 +0100)
Change their names to printf and snprintf. They are much smaller than
the previous versions we had, which makes them better suited for the
Trusted Firmware.

Change-Id: Ia872af91b7b967c47fce012eccecede7873a3daf
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
Makefile
common/tf_log.c
common/tf_printf.c [deleted file]
common/tf_snprintf.c [deleted file]
docs/psci-lib-integration-guide.rst
include/common/debug.h
include/lib/libc/stdio.h
lib/libc/libc.mk
lib/libc/printf.c [new file with mode: 0644]
lib/libc/snprintf.c [new file with mode: 0644]

index cb7eb08cfbebf2f864b217ce1ce993f137bd6beb..e7ca14a5724a76d42ae3181404bd1c953a058bed 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -202,8 +202,6 @@ include lib/libc/libc.mk
 
 BL_COMMON_SOURCES      +=      common/bl_common.c                      \
                                common/tf_log.c                         \
-                               common/tf_printf.c                      \
-                               common/tf_snprintf.c                    \
                                common/${ARCH}/debug.S                  \
                                lib/${ARCH}/cache_helpers.S             \
                                lib/${ARCH}/misc_helpers.S              \
index 54c0a43635e9f866c84c220c3f78f8dd3d7d91e3..6da1e85b62282d9e1523d0690c7987b700b63b5f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,11 +36,11 @@ void tf_log(const char *fmt, ...)
 
        prefix_str = plat_log_get_prefix(log_level);
 
-       if (prefix_str != NULL)
-               tf_string_print(prefix_str);
+       while (*prefix_str)
+               putchar(*prefix_str++);
 
        va_start(args, fmt);
-       tf_vprintf(fmt+1, args);
+       vprintf(fmt + 1, args);
        va_end(args);
 }
 
diff --git a/common/tf_printf.c b/common/tf_printf.c
deleted file mode 100644 (file)
index ecf058c..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
- *
- * 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
- ***********************************************************/
-
-#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)))
-
-int tf_string_print(const char *str)
-{
-       int count = 0;
-
-       assert(str);
-
-       while (*str) {
-               putchar(*str++);
-               count++;
-       }
-
-       return count;
-}
-
-static int unsigned_num_print(unsigned long long int unum, unsigned int radix,
-                             char padc, int padn)
-{
-       /* Just need enough space to store 64 bit decimal integer */
-       unsigned char num_buf[20];
-       int i = 0, rem, count = 0;
-
-       do {
-               rem = unum % radix;
-               if (rem < 0xa)
-                       num_buf[i++] = '0' + rem;
-               else
-                       num_buf[i++] = 'a' + (rem - 0xa);
-       } while (unum /= radix);
-
-       if (padn > 0) {
-               while (i < padn--) {
-                       putchar(padc);
-                       count++;
-               }
-       }
-
-       while (--i >= 0) {
-               putchar(num_buf[i]);
-               count++;
-       }
-
-       return count;
-}
-
-/*******************************************************************
- * Reduced format print for Trusted firmware.
- * The following type specifiers are supported by this print
- * %x - hexadecimal format
- * %s - string format
- * %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 following padding specifiers are supported by this print
- * %0NN - Left-pad the number with 0s (NN is a decimal number)
- *
- * The print exits on all other formats specifiers other than valid
- * combinations of the above specifiers.
- *******************************************************************/
-int tf_vprintf(const char *fmt, va_list args)
-{
-       int l_count;
-       long long int num;
-       unsigned long long int unum;
-       char *str;
-       char padc = 0; /* Padding character */
-       int padn; /* Number of characters to pad */
-       int count = 0; /* Number of printed characters */
-
-       while (*fmt) {
-               l_count = 0;
-               padn = 0;
-
-               if (*fmt == '%') {
-                       fmt++;
-                       /* Check the format specifier */
-loop:
-                       switch (*fmt) {
-                       case 'i': /* Fall through to next one */
-                       case 'd':
-                               num = get_num_va_args(args, l_count);
-                               if (num < 0) {
-                                       putchar('-');
-                                       unum = (unsigned long long int)-num;
-                                       padn--;
-                               } else
-                                       unum = (unsigned long long int)num;
-
-                               count += unsigned_num_print(unum, 10,
-                                                           padc, padn);
-                               break;
-                       case 's':
-                               str = va_arg(args, char *);
-                               count += tf_string_print(str);
-                               break;
-                       case 'p':
-                               unum = (uintptr_t)va_arg(args, void *);
-                               if (unum) {
-                                       count += tf_string_print("0x");
-                                       padn -= 2;
-                               }
-
-                               count += unsigned_num_print(unum, 16,
-                                                           padc, padn);
-                               break;
-                       case 'x':
-                               unum = get_unum_va_args(args, l_count);
-                               count += unsigned_num_print(unum, 16,
-                                                           padc, padn);
-                               break;
-                       case 'z':
-                               if (sizeof(size_t) == 8)
-                                       l_count = 2;
-
-                               fmt++;
-                               goto loop;
-                       case 'l':
-                               l_count++;
-                               fmt++;
-                               goto loop;
-                       case 'u':
-                               unum = get_unum_va_args(args, l_count);
-                               count += unsigned_num_print(unum, 10,
-                                                           padc, padn);
-                               break;
-                       case '0':
-                               padc = '0';
-                               padn = 0;
-                               fmt++;
-
-                               while (1) {
-                                       char ch = *fmt;
-                                       if (ch < '0' || ch > '9') {
-                                               goto loop;
-                                       }
-                                       padn = (padn * 10) + (ch - '0');
-                                       fmt++;
-                               }
-                       default:
-                               /* Exit on any other format specifier */
-                               return -1;
-                       }
-                       fmt++;
-                       continue;
-               }
-               putchar(*fmt++);
-               count++;
-       }
-
-       return count;
-}
-
-int tf_printf(const char *fmt, ...)
-{
-       int count;
-       va_list va;
-
-       va_start(va, fmt);
-       count = tf_vprintf(fmt, va);
-       va_end(va);
-
-       return count;
-}
diff --git a/common/tf_snprintf.c b/common/tf_snprintf.c
deleted file mode 100644 (file)
index 6df1377..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <debug.h>
-#include <platform.h>
-#include <stdarg.h>
-
-static void string_print(char **s, size_t n, size_t *chars_printed,
-                        const char *str)
-{
-       while (*str) {
-               if (*chars_printed < n)
-                       *(*s)++ = *str;
-               (*chars_printed)++;
-               str++;
-       }
-}
-
-static void unsigned_dec_print(char **s, size_t n, size_t *chars_printed,
-                              unsigned int unum)
-{
-       /* Enough for a 32-bit unsigned decimal integer (4294967295). */
-       unsigned char num_buf[10];
-       int i = 0, rem;
-
-       do {
-               rem = unum % 10;
-               num_buf[i++] = '0' + rem;
-       } while (unum /= 10);
-
-       while (--i >= 0) {
-               if (*chars_printed < n)
-                       *(*s)++ = num_buf[i];
-               (*chars_printed)++;
-       }
-}
-
-/*******************************************************************
- * Reduced snprintf to be used for Trusted firmware.
- * The following type specifiers are supported:
- *
- * %d or %i - signed decimal format
- * %s - string format
- * %u - unsigned decimal format
- *
- * The function panics on all other formats specifiers.
- *
- * It returns the number of characters that would be written if the
- * buffer was big enough. If it returns a value lower than n, the
- * whole string has been written.
- *******************************************************************/
-int tf_snprintf(char *s, size_t n, const char *fmt, ...)
-{
-       va_list args;
-       int num;
-       unsigned int unum;
-       char *str;
-       size_t chars_printed = 0;
-
-       if (n == 1) {
-               /* Buffer is too small to actually write anything else. */
-               *s = '\0';
-               n = 0;
-       } else if (n >= 2) {
-               /* Reserve space for the terminator character. */
-               n--;
-       }
-
-       va_start(args, fmt);
-       while (*fmt) {
-
-               if (*fmt == '%') {
-                       fmt++;
-                       /* Check the format specifier. */
-                       switch (*fmt) {
-                       case 'i':
-                       case 'd':
-                               num = va_arg(args, int);
-
-                               if (num < 0) {
-                                       if (chars_printed < n)
-                                               *s++ = '-';
-                                       chars_printed++;
-
-                                       unum = (unsigned int)-num;
-                               } else {
-                                       unum = (unsigned int)num;
-                               }
-
-                               unsigned_dec_print(&s, n, &chars_printed, unum);
-                               break;
-                       case 's':
-                               str = va_arg(args, char *);
-                               string_print(&s, n, &chars_printed, str);
-                               break;
-                       case 'u':
-                               unum = va_arg(args, unsigned int);
-                               unsigned_dec_print(&s, n, &chars_printed, unum);
-                               break;
-                       default:
-                               /* Panic on any other format specifier. */
-                               ERROR("tf_snprintf: specifier with ASCII code '%d' not supported.",
-                                     *fmt);
-                               plat_panic_handler();
-                       }
-                       fmt++;
-                       continue;
-               }
-
-               if (chars_printed < n)
-                       *s++ = *fmt;
-               fmt++;
-               chars_printed++;
-       }
-
-       va_end(args);
-
-       if (n > 0)
-               *s = '\0';
-
-       return chars_printed;
-}
index 47cbfcc8d4e4f2fc67cc88cdc36e2540dd4a0f28..d86fc29e667376abbdede6ea5d7fce3656eda575 100644 (file)
@@ -319,7 +319,7 @@ and some helper utilities for assert, print and memory operations as listed
 below. The TF-A source tree provides implementations for all
 these functions but the EL3 Runtime Software may use its own implementation.
 
-**Functions : assert(), memcpy(), memset**
+**Functions : assert(), memcpy(), memset(), printf()**
 
 These must be implemented as described in ISO C Standard.
 
@@ -353,14 +353,6 @@ This function invalidates (flushes) the data cache for memory at address
 This function will be called by the PSCI library on encountering a critical
 failure that cannot be recovered from. This function **must not** return.
 
-**Function : tf\_printf()**
-
-This is printf-compatible function, but unlike printf, it does not return any
-value. The TF-A source tree provides an implementation which
-is optimized for stack usage and supports only a subset of format specifiers.
-The details of the format specifiers supported can be found in the
-``tf_printf.c`` file in the TF-A source tree.
-
 CPU Context management API
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
index 3c99ce5016d61ece491b65b16afe496c49a5c8e1..4c5560f5f8f3c62f9c2fb8814347c6793471f266 100644 (file)
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __DEBUG_H__
-#define __DEBUG_H__
+#ifndef DEBUG_H
+#define DEBUG_H
 
 /*
  * The log output macros print output to the console. These macros produce
@@ -90,11 +90,7 @@ void __dead2 do_panic(void);
 void __dead2 __stack_chk_fail(void);
 
 void tf_log(const char *fmt, ...) __printflike(1, 2);
-int tf_printf(const char *fmt, ...) __printflike(1, 2);
-int tf_snprintf(char *s, size_t n, const char *fmt, ...) __printflike(3, 4);
-int tf_vprintf(const char *fmt, va_list args);
-int tf_string_print(const char *str);
 void tf_log_set_max_level(unsigned int log_level);
 
 #endif /* __ASSEMBLY__ */
-#endif /* __DEBUG_H__ */
+#endif /* DEBUG_H */
index 83fd18c5771c3934f06c6f619bb9ad39b0ca7483..3d9323efa508bd265545be17f29228287ad1a309 100644 (file)
@@ -11,6 +11,7 @@
 #ifndef STDIO_H
 #define STDIO_H
 
+#include <cdefs.h>
 #include <stdio_.h>
 
 #ifndef NULL
 
 #define EOF            -1
 
-int printf(const char *fmt, ...);
-int snprintf(char *s, size_t n, const char *fmt, ...);
-int sprintf(char *s, const char *fmt, ...);
-int sscanf(const char *s, const char *fmt, ...);
+int printf(const char *fmt, ...) __printflike(1, 2);
+int snprintf(char *s, size_t n, const char *fmt, ...) __printflike(3, 4);
 
 #ifdef STDARG_H
-int vsnprintf(char *s, size_t n, const char *fmt, va_list arg);
-int vsprintf(char *s, const char *fmt, va_list arg);
+int vprintf(const char *fmt, va_list args);
 #endif
 
 int putchar(int c);
index 0dee4f55efeef3ec37d28cf3ebe3fe67adb48522..554f36bb7a7b5dc195205f06afbdba9131ba2747 100644 (file)
@@ -16,12 +16,12 @@ LIBC_SRCS   :=      $(addprefix lib/libc/,  \
                        printf.c                        \
                        putchar.c                       \
                        puts.c                          \
+                       snprintf.c                      \
                        strchr.c                        \
                        strcmp.c                        \
                        strlen.c                        \
                        strncmp.c                       \
-                       strnlen.c                       \
-                       subr_prf.c)
+                       strnlen.c)
 
 INCLUDES       +=      -Iinclude/lib/libc              \
                        -Iinclude/lib/libc/$(ARCH)      \
diff --git a/lib/libc/printf.c b/lib/libc/printf.c
new file mode 100644 (file)
index 0000000..a1a8024
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+#include <debug.h>
+#include <stdarg.h>
+#include <stdint.h>
+
+/***********************************************************
+ * The tf_printf implementation for all BL stages
+ ***********************************************************/
+
+#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)))
+
+static int string_print(const char *str)
+{
+       int count = 0;
+
+       assert(str);
+
+       while (*str) {
+               putchar(*str++);
+               count++;
+       }
+
+       return count;
+}
+
+static int unsigned_num_print(unsigned long long int unum, unsigned int radix,
+                             char padc, int padn)
+{
+       /* Just need enough space to store 64 bit decimal integer */
+       unsigned char num_buf[20];
+       int i = 0, rem, count = 0;
+
+       do {
+               rem = unum % radix;
+               if (rem < 0xa)
+                       num_buf[i++] = '0' + rem;
+               else
+                       num_buf[i++] = 'a' + (rem - 0xa);
+       } while (unum /= radix);
+
+       if (padn > 0) {
+               while (i < padn--) {
+                       putchar(padc);
+                       count++;
+               }
+       }
+
+       while (--i >= 0) {
+               putchar(num_buf[i]);
+               count++;
+       }
+
+       return count;
+}
+
+/*******************************************************************
+ * Reduced format print for Trusted firmware.
+ * The following type specifiers are supported by this print
+ * %x - hexadecimal format
+ * %s - string format
+ * %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 following padding specifiers are supported by this print
+ * %0NN - Left-pad the number with 0s (NN is a decimal number)
+ *
+ * The print exits on all other formats specifiers other than valid
+ * combinations of the above specifiers.
+ *******************************************************************/
+int vprintf(const char *fmt, va_list args)
+{
+       int l_count;
+       long long int num;
+       unsigned long long int unum;
+       char *str;
+       char padc = 0; /* Padding character */
+       int padn; /* Number of characters to pad */
+       int count = 0; /* Number of printed characters */
+
+       while (*fmt) {
+               l_count = 0;
+               padn = 0;
+
+               if (*fmt == '%') {
+                       fmt++;
+                       /* Check the format specifier */
+loop:
+                       switch (*fmt) {
+                       case 'i': /* Fall through to next one */
+                       case 'd':
+                               num = get_num_va_args(args, l_count);
+                               if (num < 0) {
+                                       putchar('-');
+                                       unum = (unsigned long long int)-num;
+                                       padn--;
+                               } else
+                                       unum = (unsigned long long int)num;
+
+                               count += unsigned_num_print(unum, 10,
+                                                           padc, padn);
+                               break;
+                       case 's':
+                               str = va_arg(args, char *);
+                               count += string_print(str);
+                               break;
+                       case 'p':
+                               unum = (uintptr_t)va_arg(args, void *);
+                               if (unum) {
+                                       count += string_print("0x");
+                                       padn -= 2;
+                               }
+
+                               count += unsigned_num_print(unum, 16,
+                                                           padc, padn);
+                               break;
+                       case 'x':
+                               unum = get_unum_va_args(args, l_count);
+                               count += unsigned_num_print(unum, 16,
+                                                           padc, padn);
+                               break;
+                       case 'z':
+                               if (sizeof(size_t) == 8)
+                                       l_count = 2;
+
+                               fmt++;
+                               goto loop;
+                       case 'l':
+                               l_count++;
+                               fmt++;
+                               goto loop;
+                       case 'u':
+                               unum = get_unum_va_args(args, l_count);
+                               count += unsigned_num_print(unum, 10,
+                                                           padc, padn);
+                               break;
+                       case '0':
+                               padc = '0';
+                               padn = 0;
+                               fmt++;
+
+                               while (1) {
+                                       char ch = *fmt;
+                                       if (ch < '0' || ch > '9') {
+                                               goto loop;
+                                       }
+                                       padn = (padn * 10) + (ch - '0');
+                                       fmt++;
+                               }
+                       default:
+                               /* Exit on any other format specifier */
+                               return -1;
+                       }
+                       fmt++;
+                       continue;
+               }
+               putchar(*fmt++);
+               count++;
+       }
+
+       return count;
+}
+
+int printf(const char *fmt, ...)
+{
+       int count;
+       va_list va;
+
+       va_start(va, fmt);
+       count = vprintf(fmt, va);
+       va_end(va);
+
+       return count;
+}
diff --git a/lib/libc/snprintf.c b/lib/libc/snprintf.c
new file mode 100644 (file)
index 0000000..0738a86
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <platform.h>
+#include <stdarg.h>
+
+static void string_print(char **s, size_t n, size_t *chars_printed,
+                        const char *str)
+{
+       while (*str) {
+               if (*chars_printed < n)
+                       *(*s)++ = *str;
+               (*chars_printed)++;
+               str++;
+       }
+}
+
+static void unsigned_dec_print(char **s, size_t n, size_t *chars_printed,
+                              unsigned int unum)
+{
+       /* Enough for a 32-bit unsigned decimal integer (4294967295). */
+       unsigned char num_buf[10];
+       int i = 0, rem;
+
+       do {
+               rem = unum % 10;
+               num_buf[i++] = '0' + rem;
+       } while (unum /= 10);
+
+       while (--i >= 0) {
+               if (*chars_printed < n)
+                       *(*s)++ = num_buf[i];
+               (*chars_printed)++;
+       }
+}
+
+/*******************************************************************
+ * Reduced snprintf to be used for Trusted firmware.
+ * The following type specifiers are supported:
+ *
+ * %d or %i - signed decimal format
+ * %s - string format
+ * %u - unsigned decimal format
+ *
+ * The function panics on all other formats specifiers.
+ *
+ * It returns the number of characters that would be written if the
+ * buffer was big enough. If it returns a value lower than n, the
+ * whole string has been written.
+ *******************************************************************/
+int snprintf(char *s, size_t n, const char *fmt, ...)
+{
+       va_list args;
+       int num;
+       unsigned int unum;
+       char *str;
+       size_t chars_printed = 0;
+
+       if (n == 1) {
+               /* Buffer is too small to actually write anything else. */
+               *s = '\0';
+               n = 0;
+       } else if (n >= 2) {
+               /* Reserve space for the terminator character. */
+               n--;
+       }
+
+       va_start(args, fmt);
+       while (*fmt) {
+
+               if (*fmt == '%') {
+                       fmt++;
+                       /* Check the format specifier. */
+                       switch (*fmt) {
+                       case 'i':
+                       case 'd':
+                               num = va_arg(args, int);
+
+                               if (num < 0) {
+                                       if (chars_printed < n)
+                                               *s++ = '-';
+                                       chars_printed++;
+
+                                       unum = (unsigned int)-num;
+                               } else {
+                                       unum = (unsigned int)num;
+                               }
+
+                               unsigned_dec_print(&s, n, &chars_printed, unum);
+                               break;
+                       case 's':
+                               str = va_arg(args, char *);
+                               string_print(&s, n, &chars_printed, str);
+                               break;
+                       case 'u':
+                               unum = va_arg(args, unsigned int);
+                               unsigned_dec_print(&s, n, &chars_printed, unum);
+                               break;
+                       default:
+                               /* Panic on any other format specifier. */
+                               ERROR("snprintf: specifier with ASCII code '%d' not supported.",
+                                     *fmt);
+                               plat_panic_handler();
+                       }
+                       fmt++;
+                       continue;
+               }
+
+               if (chars_printed < n)
+                       *s++ = *fmt;
+               fmt++;
+               chars_printed++;
+       }
+
+       va_end(args);
+
+       if (n > 0)
+               *s = '\0';
+
+       return chars_printed;
+}