1 /*
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 ***********************************************************/
unsigned_num_print(unsigned long int unum,unsigned int radix)37 static 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];
41 int i = 0 , rem;
42
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
string_print(const char * str)55 static 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
71 * Exits on all other formats.
72 *******************************************************************/
73
tf_printf(const char * fmt,...)74 void tf_printf(const char *fmt, ...)
75 {
76 va_list args;
77 int bit64;
78 int64_t num;
79 uint64_t unum;
80 char *str;
81
82 va_start(args, fmt);
83 while (*fmt) {
84 bit64 = 0;
85
86 if (*fmt == '%') {
87 fmt++;
88 /* Check the format specifier */
89 loop:
90 switch (*fmt) {
91 case 'i': /* Fall through to next one */
92 case 'd':
93 if (bit64)
94 num = va_arg(args, int64_t);
95 else
96 num = va_arg(args, int32_t);
97
98 if (num < 0) {
99 putchar('-');
100 unum = (unsigned long int)-num;
101 } else
102 unum = (unsigned long int)num;
103
104 unsigned_num_print(unum, 10);
105 break;
106 case 's':
107 str = va_arg(args, char *);
108 string_print(str);
109 break;
110 case 'x':
111 if (bit64)
112 unum = va_arg(args, uint64_t);
113 else
114 unum = va_arg(args, uint32_t);
115
116 unsigned_num_print(unum, 16);
117 break;
118 case 'l':
119 bit64 = 1;
120 fmt++;
121 goto loop;
122 case 'u':
123 if (bit64)
124 unum = va_arg(args, uint64_t);
125 else
126 unum = va_arg(args, uint32_t);
127
128 unsigned_num_print(unum, 10);
129 break;
130 default:
131 /* Exit on any other format specifier */
132 goto exit;
133 }
134 fmt++;
135 continue;
136 }
137 putchar(*fmt++);
138 }
139 exit:
140 va_end(args);
141 }
142