blob: c18e2f9907495b447bf79a47a7252ab4afe7f29f [file] [log] [blame]
Soby Mathewafe7e2f2014-06-12 17:23:58 +01001/*
Soby Mathewf62d5462016-03-22 17:38:00 +00002 * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
Soby Mathewafe7e2f2014-06-12 17:23:58 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Soby Mathewafe7e2f2014-06-12 17:23:58 +01005 */
Soby Mathew0691d972016-05-05 12:34:41 +01006#include <arch.h>
7#include <arch_helpers.h>
8#include <assert.h>
Soby Mathewafe7e2f2014-06-12 17:23:58 +01009#include <debug.h>
Soby Mathew0691d972016-05-05 12:34:41 +010010#include <limits.h>
Soby Mathewafe7e2f2014-06-12 17:23:58 +010011#include <stdarg.h>
12#include <stdint.h>
13
14/***********************************************************
15 * The tf_printf implementation for all BL stages
16 ***********************************************************/
Soby Mathewf62d5462016-03-22 17:38:00 +000017
18#define get_num_va_args(args, lcount) \
19 (((lcount) > 1) ? va_arg(args, long long int) : \
20 ((lcount) ? va_arg(args, long int) : va_arg(args, int)))
21
22#define get_unum_va_args(args, lcount) \
23 (((lcount) > 1) ? va_arg(args, unsigned long long int) : \
24 ((lcount) ? va_arg(args, unsigned long int) : va_arg(args, unsigned int)))
25
26static void string_print(const char *str)
27{
28 while (*str)
29 putchar(*str++);
30}
31
32static void unsigned_num_print(unsigned long long int unum, unsigned int radix)
Soby Mathewafe7e2f2014-06-12 17:23:58 +010033{
34 /* Just need enough space to store 64 bit decimal integer */
35 unsigned char num_buf[20];
Sandrine Bailleuxa64a8542015-03-05 10:54:34 +000036 int i = 0, rem;
Soby Mathewafe7e2f2014-06-12 17:23:58 +010037
38 do {
39 rem = unum % radix;
40 if (rem < 0xa)
41 num_buf[i++] = '0' + rem;
42 else
43 num_buf[i++] = 'a' + (rem - 0xa);
44 } while (unum /= radix);
45
46 while (--i >= 0)
47 putchar(num_buf[i]);
48}
49
Soby Mathewafe7e2f2014-06-12 17:23:58 +010050/*******************************************************************
51 * Reduced format print for Trusted firmware.
Soby Mathewf62d5462016-03-22 17:38:00 +000052 * The following type specifiers are supported by this print
53 * %x - hexadecimal format
Soby Mathewafe7e2f2014-06-12 17:23:58 +010054 * %s - string format
Soby Mathewf62d5462016-03-22 17:38:00 +000055 * %d or %i - signed decimal format
56 * %u - unsigned decimal format
Antonio Nino Diazb3a0a7b2016-02-02 12:03:38 +000057 * %p - pointer format
Soby Mathewf62d5462016-03-22 17:38:00 +000058 *
59 * The following length specifiers are supported by this print
60 * %l - long int (64-bit on AArch64)
61 * %ll - long long int (64-bit on AArch64)
62 * %z - size_t sized integer formats (64 bit on AArch64)
63 *
64 * The print exits on all other formats specifiers other than valid
65 * combinations of the above specifiers.
Soby Mathewafe7e2f2014-06-12 17:23:58 +010066 *******************************************************************/
Soby Mathewafe7e2f2014-06-12 17:23:58 +010067void tf_printf(const char *fmt, ...)
68{
69 va_list args;
Soby Mathewf62d5462016-03-22 17:38:00 +000070 int l_count;
71 long long int num;
72 unsigned long long int unum;
Soby Mathewafe7e2f2014-06-12 17:23:58 +010073 char *str;
74
75 va_start(args, fmt);
76 while (*fmt) {
Soby Mathewf62d5462016-03-22 17:38:00 +000077 l_count = 0;
Soby Mathewafe7e2f2014-06-12 17:23:58 +010078
79 if (*fmt == '%') {
80 fmt++;
81 /* Check the format specifier */
82loop:
83 switch (*fmt) {
84 case 'i': /* Fall through to next one */
85 case 'd':
Soby Mathewf62d5462016-03-22 17:38:00 +000086 num = get_num_va_args(args, l_count);
Soby Mathewafe7e2f2014-06-12 17:23:58 +010087 if (num < 0) {
88 putchar('-');
Soby Mathewf62d5462016-03-22 17:38:00 +000089 unum = (unsigned long long int)-num;
Soby Mathewafe7e2f2014-06-12 17:23:58 +010090 } else
Soby Mathewf62d5462016-03-22 17:38:00 +000091 unum = (unsigned long long int)num;
Soby Mathewafe7e2f2014-06-12 17:23:58 +010092
93 unsigned_num_print(unum, 10);
94 break;
95 case 's':
96 str = va_arg(args, char *);
97 string_print(str);
98 break;
Antonio Nino Diazb3a0a7b2016-02-02 12:03:38 +000099 case 'p':
Soby Mathewf62d5462016-03-22 17:38:00 +0000100 unum = (uintptr_t)va_arg(args, void *);
Antonio Nino Diazb3a0a7b2016-02-02 12:03:38 +0000101 if (unum)
102 string_print("0x");
103
104 unsigned_num_print(unum, 16);
105 break;
Soby Mathewafe7e2f2014-06-12 17:23:58 +0100106 case 'x':
Soby Mathewf62d5462016-03-22 17:38:00 +0000107 unum = get_unum_va_args(args, l_count);
Soby Mathewafe7e2f2014-06-12 17:23:58 +0100108 unsigned_num_print(unum, 16);
109 break;
Scott Branden57bd75c2016-03-23 13:37:33 -0700110 case 'z':
111 if (sizeof(size_t) == 8)
Soby Mathewf62d5462016-03-22 17:38:00 +0000112 l_count = 2;
113
Scott Branden57bd75c2016-03-23 13:37:33 -0700114 fmt++;
115 goto loop;
Soby Mathewafe7e2f2014-06-12 17:23:58 +0100116 case 'l':
Soby Mathewf62d5462016-03-22 17:38:00 +0000117 l_count++;
Soby Mathewafe7e2f2014-06-12 17:23:58 +0100118 fmt++;
119 goto loop;
120 case 'u':
Soby Mathewf62d5462016-03-22 17:38:00 +0000121 unum = get_unum_va_args(args, l_count);
Soby Mathewafe7e2f2014-06-12 17:23:58 +0100122 unsigned_num_print(unum, 10);
123 break;
124 default:
125 /* Exit on any other format specifier */
126 goto exit;
127 }
128 fmt++;
129 continue;
130 }
131 putchar(*fmt++);
132 }
133exit:
134 va_end(args);
135}