source: mainline/generic/src/debug/print.c@ dfd9186

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since dfd9186 was 5fe5f1e, checked in by Jakub Jermar <jakub@…>, 19 years ago

Clean up.

  • Property mode set to 100644
File size: 6.4 KB
RevLine 
[f761f1eb]1/*
2 * Copyright (C) 2001-2004 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <putchar.h>
30#include <print.h>
31#include <synch/spinlock.h>
[0d2f805]32#include <arch/arg.h>
[18e0a6c]33#include <arch/asm.h>
[0d2f805]34
[e83a9f7]35#include <arch.h>
[f761f1eb]36
[dc747e3]37static char digits[] = "0123456789abcdef"; /**< Hexadecimal characters */
38SPINLOCK_INITIALIZE(printflock); /**< printf spinlock */
[f761f1eb]39
[e16e036a]40
41/** Print NULL terminated string
42 *
43 * Print characters from str using putchar() until
44 * \\0 character is reached.
45 *
46 * @param str Characters to print.
47 *
48 */
49static void print_str(const char *str)
50{
51 int i = 0;
52 char c;
53
[5a95b25]54 while ((c = str[i++]))
[e16e036a]55 putchar(c);
56}
57
58
59/** Print hexadecimal digits
60 *
61 * Print fixed count of hexadecimal digits from
62 * the number num. The digits are printed in
63 * natural left-to-right order starting with
64 * the width-th digit.
65 *
66 * @param num Number containing digits.
67 * @param width Count of digits to print.
68 *
69 */
70static void print_fixed_hex(const __u64 num, const int width)
71{
72 int i;
73
74 for (i = width*8 - 4; i >= 0; i -= 4)
75 putchar(digits[(num>>i) & 0xf]);
76}
77
78
79/** Print number in given base
80 *
81 * Print significant digits of a number in given
82 * base.
83 *
84 * @param num Number to print.
85 * @param base Base to print the number in (should
86 * be in range 2 .. 16).
87 *
88 */
89static void print_number(const __native num, const unsigned int base)
90{
91 int val = num;
92 char d[sizeof(__native)*8+1]; /* this is good enough even for base == 2 */
93 int i = sizeof(__native)*8-1;
94
95 do {
96 d[i--] = digits[val % base];
97 } while (val /= base);
98
99 d[sizeof(__native)*8] = 0;
100 print_str(&d[i + 1]);
101}
102
103
[724b58a]104
105/** General formatted text print
106 *
107 * Print text formatted according the fmt parameter
108 * and variant arguments. Each formatting directive
[26f9943]109 * begins with \% (percentage) character and one of the
[724b58a]110 * following character:
111 *
[26f9943]112 * \% Prints the percentage character.
113 *
[d7568a9f]114 * s The next variant argument is treated as char*
[724b58a]115 * and printed as a NULL terminated string.
[26f9943]116 *
[d7568a9f]117 * c The next variant argument is treated as a single char.
[26f9943]118 *
[da79d0fd]119 * p The next variant argument is treated as a maximum
120 * bit-width integer with respect to architecture
121 * and printed in full hexadecimal width.
[26f9943]122 *
[da79d0fd]123 * P As with 'p', but '0x' is prefixed.
[26f9943]124 *
[da79d0fd]125 * q The next variant argument is treated as a 64b integer
126 * and printed in full hexadecimal width.
[26f9943]127 *
[da79d0fd]128 * Q As with 'q', but '0x' is prefixed.
[26f9943]129 *
[d7568a9f]130 * l The next variant argument is treated as a 32b integer
[724b58a]131 * and printed in full hexadecimal width.
[26f9943]132 *
[724b58a]133 * L As with 'l', but '0x' is prefixed.
[26f9943]134 *
[d7568a9f]135 * w The next variant argument is treated as a 16b integer
[724b58a]136 * and printed in full hexadecimal width.
[26f9943]137 *
[724b58a]138 * W As with 'w', but '0x' is prefixed.
[26f9943]139 *
[d7568a9f]140 * b The next variant argument is treated as a 8b integer
[724b58a]141 * and printed in full hexadecimal width.
[26f9943]142 *
143 * B As with 'b', but '0x' is prefixed.
144 *
[d7568a9f]145 * d The next variant argument is treated as integer
[724b58a]146 * and printed in standard decimal format (only significant
147 * digits).
[26f9943]148 *
[d7568a9f]149 * x The next variant argument is treated as integer
[724b58a]150 * and printed in standard hexadecimal format (only significant
151 * digits).
[26f9943]152 *
[724b58a]153 * X As with 'x', but '0x' is prefixed.
[26f9943]154 *
[724b58a]155 * All other characters from fmt except the formatting directives
156 * are printed in verbatim.
157 *
158 * @param fmt Formatting NULL terminated string.
[f761f1eb]159 */
[27dc170]160void printf(const char *fmt, ...)
[f761f1eb]161{
[0d2f805]162 int irqpri, i = 0;
163 va_list ap;
164 char c;
[51022e9b]165
[0d2f805]166 va_start(ap, fmt);
[f761f1eb]167
[22f7769]168 irqpri = interrupts_disable();
[f761f1eb]169 spinlock_lock(&printflock);
[0d2f805]170
[5a95b25]171 while ((c = fmt[i++])) {
[f761f1eb]172 switch (c) {
173
174 /* control character */
175 case '%':
[51022e9b]176
[b0edf3b2]177 switch (c = fmt[i++]) {
178
179 /* percentile itself */
180 case '%':
181 break;
182
183 /*
184 * String and character conversions.
185 */
186 case 's':
187 print_str(va_arg(ap, char_ptr));
188 goto loop;
189
190 case 'c':
191 c = (char) va_arg(ap, int);
192 break;
193
194 /*
195 * Hexadecimal conversions with fixed width.
196 */
197 case 'P':
198 print_str("0x");
199 case 'p':
200 print_fixed_hex(va_arg(ap, __native), sizeof(__native));
201 goto loop;
202
203 case 'Q':
204 print_str("0x");
205 case 'q':
206 print_fixed_hex(va_arg(ap, __u64), INT64);
207 goto loop;
208
209 case 'L':
210 print_str("0x");
211 case 'l':
212 print_fixed_hex(va_arg(ap, __native), INT32);
213 goto loop;
214
215 case 'W':
216 print_str("0x");
217 case 'w':
218 print_fixed_hex(va_arg(ap, __native), INT16);
219 goto loop;
220
221 case 'B':
222 print_str("0x");
223 case 'b':
224 print_fixed_hex(va_arg(ap, __native), INT8);
225 goto loop;
[b524c5e0]226
[b0edf3b2]227 /*
228 * Decimal and hexadecimal conversions.
229 */
230 case 'd':
231 print_number(va_arg(ap, __native), 10);
232 goto loop;
233
234 case 'X':
235 print_str("0x");
236 case 'x':
237 print_number(va_arg(ap, __native), 16);
238 goto loop;
[f761f1eb]239
[b0edf3b2]240 /*
241 * Bad formatting.
242 */
243 default:
244 goto out;
245 }
[f761f1eb]246
247 default: putchar(c);
248 }
249
250loop:
251 ;
252 }
253
254out:
255 spinlock_unlock(&printflock);
[22f7769]256 interrupts_restore(irqpri);
[0d2f805]257
258 va_end(ap);
[f761f1eb]259}
Note: See TracBrowser for help on using the repository browser.