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
Line 
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>
32#include <arch/arg.h>
33#include <arch/asm.h>
34
35#include <arch.h>
36
37static char digits[] = "0123456789abcdef"; /**< Hexadecimal characters */
38SPINLOCK_INITIALIZE(printflock); /**< printf spinlock */
39
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
54 while ((c = str[i++]))
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
104
105/** General formatted text print
106 *
107 * Print text formatted according the fmt parameter
108 * and variant arguments. Each formatting directive
109 * begins with \% (percentage) character and one of the
110 * following character:
111 *
112 * \% Prints the percentage character.
113 *
114 * s The next variant argument is treated as char*
115 * and printed as a NULL terminated string.
116 *
117 * c The next variant argument is treated as a single char.
118 *
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.
122 *
123 * P As with 'p', but '0x' is prefixed.
124 *
125 * q The next variant argument is treated as a 64b integer
126 * and printed in full hexadecimal width.
127 *
128 * Q As with 'q', but '0x' is prefixed.
129 *
130 * l The next variant argument is treated as a 32b integer
131 * and printed in full hexadecimal width.
132 *
133 * L As with 'l', but '0x' is prefixed.
134 *
135 * w The next variant argument is treated as a 16b integer
136 * and printed in full hexadecimal width.
137 *
138 * W As with 'w', but '0x' is prefixed.
139 *
140 * b The next variant argument is treated as a 8b integer
141 * and printed in full hexadecimal width.
142 *
143 * B As with 'b', but '0x' is prefixed.
144 *
145 * d The next variant argument is treated as integer
146 * and printed in standard decimal format (only significant
147 * digits).
148 *
149 * x The next variant argument is treated as integer
150 * and printed in standard hexadecimal format (only significant
151 * digits).
152 *
153 * X As with 'x', but '0x' is prefixed.
154 *
155 * All other characters from fmt except the formatting directives
156 * are printed in verbatim.
157 *
158 * @param fmt Formatting NULL terminated string.
159 */
160void printf(const char *fmt, ...)
161{
162 int irqpri, i = 0;
163 va_list ap;
164 char c;
165
166 va_start(ap, fmt);
167
168 irqpri = interrupts_disable();
169 spinlock_lock(&printflock);
170
171 while ((c = fmt[i++])) {
172 switch (c) {
173
174 /* control character */
175 case '%':
176
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;
226
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;
239
240 /*
241 * Bad formatting.
242 */
243 default:
244 goto out;
245 }
246
247 default: putchar(c);
248 }
249
250loop:
251 ;
252 }
253
254out:
255 spinlock_unlock(&printflock);
256 interrupts_restore(irqpri);
257
258 va_end(ap);
259}
Note: See TracBrowser for help on using the repository browser.