blob: c1d4188900b402bd88029fd5a59c944c3301ebfa [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
Soby Mathewafe7e2f2014-06-12 17:23:58 +010072 * Exits on all other formats.
73 *******************************************************************/
74
75void tf_printf(const char *fmt, ...)
76{
77 va_list args;
78 int bit64;
79 int64_t num;
80 uint64_t unum;
81 char *str;
82
83 va_start(args, fmt);
84 while (*fmt) {
85 bit64 = 0;
86
87 if (*fmt == '%') {
88 fmt++;
89 /* Check the format specifier */
90loop:
91 switch (*fmt) {
92 case 'i': /* Fall through to next one */
93 case 'd':
94 if (bit64)
95 num = va_arg(args, int64_t);
96 else
97 num = va_arg(args, int32_t);
98
99 if (num < 0) {
100 putchar('-');
101 unum = (unsigned long int)-num;
102 } else
103 unum = (unsigned long int)num;
104
105 unsigned_num_print(unum, 10);
106 break;
107 case 's':
108 str = va_arg(args, char *);
109 string_print(str);
110 break;
Antonio Nino Diazb3a0a7b2016-02-02 12:03:38 +0000111 case 'p':
112 unum = (uint64_t)va_arg(args, void *);
113
114 if (unum)
115 string_print("0x");
116
117 unsigned_num_print(unum, 16);
118 break;
Soby Mathewafe7e2f2014-06-12 17:23:58 +0100119 case 'x':
120 if (bit64)
121 unum = va_arg(args, uint64_t);
122 else
123 unum = va_arg(args, uint32_t);
124
125 unsigned_num_print(unum, 16);
126 break;
127 case 'l':
128 bit64 = 1;
129 fmt++;
130 goto loop;
131 case 'u':
132 if (bit64)
133 unum = va_arg(args, uint64_t);
134 else
135 unum = va_arg(args, uint32_t);
136
137 unsigned_num_print(unum, 10);
138 break;
139 default:
140 /* Exit on any other format specifier */
141 goto exit;
142 }
143 fmt++;
144 continue;
145 }
146 putchar(*fmt++);
147 }
148exit:
149 va_end(args);
150}