source: mainline/src/debug/print.c@ 18e0a6c

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

Implement several assembler functions in gcc's asm notation instead of in .s or .S file.
Gain both better speed and size.

  • Property mode set to 100644
File size: 6.3 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
36static char digits[] = "0123456789abcdef"; /**< Hexadecimal characters */
37static spinlock_t printflock; /**< printf spinlock */
38
39
40/** Print NULL terminated string
41 *
42 * Print characters from str using putchar() until
43 * \x00 character is reached.
44 *
45 * @param str Characters to print.
46 *
47 */
48void print_str(const char *str)
49{
50 int i = 0;
51 char c;
52
53 while (c = str[i++])
54 putchar(c);
55}
56
57
58/** Print hexadecimal digits
59 *
60 * Print fixed count of hexadecimal digits from
61 * the number num. The digits are printed in
62 * natural left-to-right order starting with
63 * the width-th digit.
64 *
65 * @param num Number containing digits.
66 * @param width Count of digits to print.
67 *
68 */
69void print_fixed_hex(const __native num, const int width)
70{
71 int i;
72
73 for (i = width*8 - 4; i >= 0; i -= 4)
74 putchar(digits[(num>>i) & 0xf]);
75}
76
77
78/** Print number in given base
79 *
80 * Print significant digits of a number in given
81 * base.
82 *
83 * @param num Number to print.
84 * @param base Base to print the number in (should
85 * be in range 2 .. 16).
86 *
87 */
88void print_number(const __native num, const unsigned int base)
89{
90 int val = num;
91 char d[sizeof(__native)*8+1]; /* this is good enough even for base == 2 */
92 int i = sizeof(__native)*8-1;
93
94 do {
95 d[i--] = digits[val % base];
96 } while (val /= base);
97
98 d[sizeof(__native)*8] = 0;
99 print_str(&d[i + 1]);
100}
101
102
103/** General formatted text print
104 *
105 * Print text formatted according the fmt parameter
106 * and variant arguments. Each formatting directive
107 * begins with % (percentage) character and one of the
108 * following character:
109 *
110 * % Prints the percentage character.
111 * s The next variant argument is treated as char*
112 * and printed as a NULL terminated string.
113 * c The next variant argument is treated as a single char.
114 * p The next variant argument is treated as a maximum
115 * bit-width integer with respect to architecture
116 * and printed in full hexadecimal width.
117 * P As with 'p', but '0x' is prefixed.
118 * q The next variant argument is treated as a 64b integer
119 * and printed in full hexadecimal width.
120 * Q As with 'q', but '0x' is prefixed.
121 * l The next variant argument is treated as a 32b integer
122 * and printed in full hexadecimal width.
123 * L As with 'l', but '0x' is prefixed.
124 * w The next variant argument is treated as a 16b integer
125 * and printed in full hexadecimal width.
126 * W As with 'w', but '0x' is prefixed.
127 * b The next variant argument is treated as a 8b integer
128 * and printed in full hexadecimal width.
129 * N As with 'b', but '0x' is prefixed.
130 * d The next variant argument is treated as integer
131 * and printed in standard decimal format (only significant
132 * digits).
133 * x The next variant argument is treated as integer
134 * and printed in standard hexadecimal format (only significant
135 * digits).
136 * X As with 'x', but '0x' is prefixed.
137 *
138 * All other characters from fmt except the formatting directives
139 * are printed in verbatim.
140 *
141 * @param fmt Formatting NULL terminated string.
142 *
143 */
144void printf(const char *fmt, ...)
145{
146 int irqpri, i = 0;
147 va_list ap;
148 char c;
149
150 va_start(ap, fmt);
151
152 irqpri = cpu_priority_high();
153 spinlock_lock(&printflock);
154
155 while (c = fmt[i++]) {
156 switch (c) {
157
158 /* control character */
159 case '%':
160 switch (c = fmt[i++]) {
161
162 /* percentile itself */
163 case '%':
164 break;
165
166 /*
167 * String and character conversions.
168 */
169 case 's':
170 print_str(va_arg(ap, char_ptr));
171 goto loop;
172
173 case 'c':
174 c = (char) va_arg(ap, int);
175 break;
176
177 /*
178 * Hexadecimal conversions with fixed width.
179 */
180 case 'P':
181 print_str("0x");
182 case 'p':
183 print_fixed_hex(va_arg(ap, __native), sizeof(__native));
184 goto loop;
185
186 case 'Q':
187 print_str("0x");
188 case 'q':
189 print_fixed_hex(va_arg(ap, __native), INT64);
190 goto loop;
191
192 case 'L':
193 print_str("0x");
194 case 'l':
195 print_fixed_hex(va_arg(ap, __native), INT32);
196 goto loop;
197
198 case 'W':
199 print_str("0x");
200 case 'w':
201 print_fixed_hex(va_arg(ap, __native), INT16);
202 goto loop;
203
204 case 'B':
205 print_str("0x");
206 case 'b':
207 print_fixed_hex(va_arg(ap, __native), INT8);
208 goto loop;
209
210 /*
211 * Decimal and hexadecimal conversions.
212 */
213 case 'd':
214 print_number(va_arg(ap, __native), 10);
215 goto loop;
216
217 case 'X':
218 print_str("0x");
219 case 'x':
220 print_number(va_arg(ap, __native), 16);
221 goto loop;
222
223 /*
224 * Bad formatting.
225 */
226 default:
227 goto out;
228 }
229
230 default: putchar(c);
231 }
232
233loop:
234 ;
235 }
236
237out:
238 spinlock_unlock(&printflock);
239 cpu_priority_restore(irqpri);
240
241 va_end(ap);
242}
Note: See TracBrowser for help on using the repository browser.