blob: 9a7667a5f0b025b74bb6df562c923d8d51b0f0c8 [file] [log] [blame]
Soby Mathewafe7e2f2014-06-12 17:23:58 +01001/*
2 * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30#include <debug.h>
31#include <stdarg.h>
32#include <stdint.h>
33
34/***********************************************************
35 * The tf_printf implementation for all BL stages
36 ***********************************************************/
37static void unsigned_num_print(unsigned long int unum, unsigned int radix)
38{
39 /* Just need enough space to store 64 bit decimal integer */
40 unsigned char num_buf[20];
Sandrine Bailleuxa64a8542015-03-05 10:54:34 +000041 int i = 0, rem;
Soby Mathewafe7e2f2014-06-12 17:23:58 +010042
43 do {
44 rem = unum % radix;
45 if (rem < 0xa)
46 num_buf[i++] = '0' + rem;
47 else
48 num_buf[i++] = 'a' + (rem - 0xa);
49 } while (unum /= radix);
50
51 while (--i >= 0)
52 putchar(num_buf[i]);
53}
54
55static void string_print(const char *str)
56{
57 while (*str)
58 putchar(*str++);
59}
60
61/*******************************************************************
62 * Reduced format print for Trusted firmware.
63 * The following formats are supported by this print
64 * %x - 32 bit hexadecimal format
65 * %llx and %lx -64 bit hexadecimal format
66 * %s - string format
67 * %d or %i - signed 32 bit decimal format
68 * %u - unsigned 32 bit decimal format
69 * %ld and %lld - signed 64 bit decimal format
70 * %lu and %llu - unsigned 64 bit decimal format
Antonio Nino Diazb3a0a7b2016-02-02 12:03:38 +000071 * %p - pointer format
Scott Branden57bd75c2016-03-23 13:37:33 -070072 * %z - size_t format
Soby Mathewafe7e2f2014-06-12 17:23:58 +010073 * Exits on all other formats.
74 *******************************************************************/
75
76void tf_printf(const char *fmt, ...)
77{
78 va_list args;
79 int bit64;
80 int64_t num;
81 uint64_t unum;
82 char *str;
83
84 va_start(args, fmt);
85 while (*fmt) {
86 bit64 = 0;
87
88 if (*fmt == '%') {
89 fmt++;
90 /* Check the format specifier */
91loop:
92 switch (*fmt) {
93 case 'i': /* Fall through to next one */
94 case 'd':
95 if (bit64)
96 num = va_arg(args, int64_t);
97 else
98 num = va_arg(args, int32_t);
99
100 if (num < 0) {
101 putchar('-');
102 unum = (unsigned long int)-num;
103 } else
104 unum = (unsigned long int)num;
105
106 unsigned_num_print(unum, 10);
107 break;
108 case 's':
109 str = va_arg(args, char *);
110 string_print(str);
111 break;
Antonio Nino Diazb3a0a7b2016-02-02 12:03:38 +0000112 case 'p':
113 unum = (uint64_t)va_arg(args, void *);
114
115 if (unum)
116 string_print("0x");
117
118 unsigned_num_print(unum, 16);
119 break;
Soby Mathewafe7e2f2014-06-12 17:23:58 +0100120 case 'x':
121 if (bit64)
122 unum = va_arg(args, uint64_t);
123 else
124 unum = va_arg(args, uint32_t);
125
126 unsigned_num_print(unum, 16);
127 break;
Scott Branden57bd75c2016-03-23 13:37:33 -0700128 case 'z':
129 if (sizeof(size_t) == 8)
130 bit64 = 1;
131 fmt++;
132 goto loop;
Soby Mathewafe7e2f2014-06-12 17:23:58 +0100133 case 'l':
134 bit64 = 1;
135 fmt++;
136 goto loop;
137 case 'u':
138 if (bit64)
139 unum = va_arg(args, uint64_t);
140 else
141 unum = va_arg(args, uint32_t);
142
143 unsigned_num_print(unum, 10);
144 break;
145 default:
146 /* Exit on any other format specifier */
147 goto exit;
148 }
149 fmt++;
150 continue;
151 }
152 putchar(*fmt++);
153 }
154exit:
155 va_end(args);
156}