2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
30 * Mach Operating System
31 * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
32 * All Rights Reserved.
34 * Permission to use, copy, modify and distribute this software and its
35 * documentation is hereby granted, provided that both the copyright
36 * notice and this permission notice appear in all copies of the
37 * software, derivative works or modified versions, and any portions
38 * thereof, and that both notices appear in supporting documentation.
40 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
41 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
42 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
44 * Carnegie Mellon requests users of this software to return to
46 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
47 * School of Computer Science
48 * Carnegie Mellon University
49 * Pittsburgh PA 15213-3890
51 * any improvements or extensions that they make and grant Carnegie Mellon
52 * the rights to redistribute these changes.
56 * Common code for printf et al.
58 * The calling routine typically takes a variable number of arguments,
59 * and passes the address of the first one. This implementation
60 * assumes a straightforward, stack implementation, aligned to the
61 * machine's wordsize. Increasing addresses are assumed to point to
62 * successive arguments (left-to-right), as is the case for a machine
63 * with a downward-growing stack with arguments pushed right-to-left.
65 * To write, for example, fprintf() using this routine, the code
67 * fprintf(fd, format, args)
71 * _doprnt(format, &args, fd);
74 * would suffice. (This example does not handle the fprintf's "return
75 * value" correctly, but who looks at the return value of fprintf
78 * This version implements the following printf features:
80 * %d decimal conversion
81 * %u unsigned conversion
82 * %x hexadecimal conversion
83 * %X hexadecimal conversion with capital letters
84 * %D hexdump, ptr & separator string ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
85 * if you use, "%*D" then there's a length, the data ptr and then the separator
89 * %m.n field width, precision
90 * %-m.n left adjustment
92 * %*.* width and precision taken from arguments
94 * This version does not implement %f, %e, or %g. It accepts, but
95 * ignores, an `l' as in %ld, %lo, %lx, and %lu, and therefore will not
96 * work correctly on machines for which sizeof(long) != sizeof(int).
98 * As mentioned, this version does not return any reasonable value.
100 * Permission is granted to use, modify, or propagate this code as
101 * long as this notice is incorporated.
103 * Steve Summit 3/25/87
105 * Tweaked for long long support and extended to support the hexdump %D
106 * specifier by dbg 05/02/02.
110 * Added formats for decoding device registers:
112 * printf("reg = %b", regval, "<base><arg>*")
114 * where <base> is the output base expressed as a control character:
115 * i.e. '\10' gives octal, '\20' gives hex. Each <arg> is a sequence of
116 * characters, the first of which gives the bit number to be inspected
117 * (origin 1), and the rest (up to a control character (<= 32)) give the
118 * name of the register. Thus
119 * printf("reg = %b\n", 3, "\10\2BITTWO\1BITONE")
121 * reg = 3<BITTWO,BITONE>
123 * If the second character in <arg> is also a control character, it
124 * indicates the last bit of a bit field. In this case, printf will extract
125 * bits <1> to <2> and print it. Characters following the second control
126 * character are printed before the bit field.
127 * printf("reg = %b\n", 0xb, "\10\4\3FIELD1=\2BITTWO\1BITONE")
129 * reg = b<FIELD1=2,BITONE>
131 * The %B format is like %b but the bits are numbered from the most
132 * significant (the bit weighted 31), which is called 1, to the least
133 * significant, called 32.
136 * Added for general use:
137 * # prefix for alternate format:
139 * leading 0 for octal
140 * + print '+' if positive
141 * blank print ' ' if positive
143 * z signed hexadecimal
145 * n unsigned, 'radix'
147 * D,U,O,Z same as corresponding lower-case versions
151 * Added support for print long long (64-bit) integers.
152 * Use %lld, %Ld or %qd to print a 64-bit int. Other
153 * output bases such as x, X, u, U, o, and O also work.
157 #include <mach_kdb.h>
158 #include <mach_kdp.h>
159 #include <platforms.h>
160 #include <mach/boolean.h>
162 #include <kern/cpu_number.h>
163 #include <kern/lock.h>
164 #include <kern/thread.h>
165 #include <kern/sched_prim.h>
166 #include <kern/misc_protos.h>
169 #include <mach_assert.h>
171 #include <sys/msgbuf.h>
175 #include <ppc/Firmware.h>
178 #define isdigit(d) ((d) >= '0' && (d) <= '9')
179 #define Ctod(c) ((c) - '0')
181 #define MAXBUF (sizeof(long long int) * 8) /* enough for binary */
182 static char digs
[] = "0123456789abcdef";
186 register unsigned long long int u
, /* number to print */
188 void (*putc
)(int, void *),
191 char buf
[MAXBUF
]; /* build number here */
192 register char * p
= &buf
[MAXBUF
-1];
196 *p
-- = digs
[u
% base
];
200 while (++p
!= &buf
[MAXBUF
]) {
208 boolean_t _doprnt_truncates
= FALSE
;
212 register const char *fmt
,
214 /* character output routine */
215 void (*putc
)(int, void *arg
),
217 int radix
) /* default radix - for '%r' */
224 unsigned long long u
;
227 boolean_t altfmt
, truncate
;
234 while ((c
= *fmt
) != '\0') {
280 length
= 10 * length
+ Ctod(c
);
285 length
= va_arg(*argp
, int);
298 prec
= 10 * prec
+ Ctod(c
);
303 prec
= va_arg(*argp
, int);
309 c
= *++fmt
; /* need it if sizeof(int) < sizeof(long) */
314 } else if (c
== 'q' || c
== 'L') {
320 capitals
=0; /* Assume lower case printing */
331 u
= va_arg(*argp
, unsigned long long);
333 u
= va_arg(*argp
, unsigned long);
335 p
= va_arg(*argp
, char *);
337 nprinted
+= printnum(u
, base
, putc
, arg
);
343 while ((i
= *p
++) != '\0') {
361 for (; (c
= *p
) > 32; p
++) {
365 nprinted
+= printnum((unsigned)( (u
>>(j
-1)) & ((2<<(i
-j
))-1)),
368 else if (u
& (1<<(i
-1))) {
376 for (; (c
= *p
) > 32; p
++) {
394 c
= va_arg(*argp
, int);
405 prec
= 0x7fffffff; /* MAXINT */
407 p
= va_arg(*argp
, char *);
412 if (length
> 0 && !ladjust
) {
416 for (; *p
!= '\0' && n
< prec
; p
++)
431 if (++n
> prec
|| (length
> 0 && n
> length
))
438 if (n
< length
&& ladjust
) {
450 truncate
= _doprnt_truncates
;
459 up
= (unsigned char *)va_arg(*argp
, unsigned char *);
460 p
= (char *)va_arg(*argp
, char *);
464 (*putc
)(digs
[(*up
>> 4)], arg
);
465 (*putc
)(digs
[(*up
& 0x0f)], arg
);
479 truncate
= _doprnt_truncates
;
484 truncate
= _doprnt_truncates
;
492 truncate
= _doprnt_truncates
;
498 capitals
=16; /* Print in upper case */
502 truncate
= _doprnt_truncates
;
508 capitals
=16; /* Print in upper case */
512 truncate
= _doprnt_truncates
;
518 truncate
= _doprnt_truncates
;
525 n
= va_arg(*argp
, long long);
527 n
= va_arg(*argp
, long);
531 sign_char
= plus_sign
;
541 u
= va_arg(*argp
, unsigned long long);
543 u
= va_arg(*argp
, unsigned long);
549 char buf
[MAXBUF
]; /* build number here */
550 register char * p
= &buf
[MAXBUF
-1];
551 static char digits
[] = "0123456789abcdef0123456789ABCDEF";
554 if (truncate
) u
= (long long)((int)(u
));
556 if (u
!= 0 && altfmt
) {
564 /* Print in the correct case */
565 *p
-- = digits
[(u
% base
)+capitals
];
569 length
-= (&buf
[MAXBUF
-1] - p
);
573 length
-= strlen((const char *) prefix
);
575 if (padc
== ' ' && !ladjust
) {
576 /* blank padding goes before prefix */
577 while (--length
>= 0) {
583 (*putc
)(sign_char
, arg
);
588 (*putc
)(*prefix
++, arg
);
593 /* zero padding goes after sign and prefix */
594 while (--length
>= 0) {
599 while (++p
!= &buf
[MAXBUF
]) {
605 while (--length
>= 0) {
628 dummy_putc(int ch
, void *arg
)
630 void (*real_putc
)(char) = arg
;
637 register const char *fmt
,
639 /* character output routine */
641 int radix
) /* default radix - for '%r' */
643 __doprnt(fmt
, argp
, dummy_putc
, putc
, radix
);
647 boolean_t new_printf_cpu_number
= FALSE
;
648 #endif /* MP_PRINTF */
651 decl_simple_lock_data(,printf_lock
)
652 decl_mutex_data(,sprintf_lock
)
658 * Lock is only really needed after the first thread is created.
660 simple_lock_init(&printf_lock
, ETAP_MISC_PRINTF
);
661 mutex_init(&sprintf_lock
, ETAP_MISC_PRINTF
);
664 /* derived from boot_gets */
672 char *strmax
= str
+ maxlen
- 1; /* allow space for trailing 0 */
700 if (c
>= ' ' && c
< '\177') {
706 printf("%c", '\007'); /* beep */
717 extern unsigned int debug_mode
, disableDebugOuput
, disableConsoleOutput
;
719 if ((debug_mode
&& !disableDebugOuput
) || !disableConsoleOutput
)
728 dbugprintf(const char *fmt
, ...)
733 extern void db_putchar(char c
);
736 va_start(listp
, fmt
);
737 _doprnt(fmt
, &listp
, db_putchar
, 16);
744 printf(const char *fmt
, ...)
748 disable_preemption();
749 va_start(listp
, fmt
);
750 _doprnt(fmt
, &listp
, conslog_putc
, 16);
759 extern unsigned int debug_mode
, disableDebugOuput
, disableConsoleOutput
;
761 if ((debug_mode
&& !disableDebugOuput
) || !disableConsoleOutput
)
768 kdb_printf(const char *fmt
, ...)
772 va_start(listp
, fmt
);
773 _doprnt(fmt
, &listp
, consdebug_putc
, 16);
777 static char *copybyte_str
;
783 *copybyte_str
++ = byte
;
784 *copybyte_str
= '\0';
788 sprintf(char *buf
, const char *fmt
, ...)
792 va_start(listp
, fmt
);
793 mutex_lock(&sprintf_lock
);
795 _doprnt(fmt
, &listp
, copybyte
, 16);
796 mutex_unlock(&sprintf_lock
);