xref: /onnv-gate/usr/src/uts/i86pc/dboot/dboot_printf.c (revision 5084:7d838c5c0eed)
13446Smrj /*
23446Smrj  * CDDL HEADER START
33446Smrj  *
43446Smrj  * The contents of this file are subject to the terms of the
53446Smrj  * Common Development and Distribution License (the "License").
63446Smrj  * You may not use this file except in compliance with the License.
73446Smrj  *
83446Smrj  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93446Smrj  * or http://www.opensolaris.org/os/licensing.
103446Smrj  * See the License for the specific language governing permissions
113446Smrj  * and limitations under the License.
123446Smrj  *
133446Smrj  * When distributing Covered Code, include this CDDL HEADER in each
143446Smrj  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153446Smrj  * If applicable, add the following below this CDDL HEADER, with the
163446Smrj  * fields enclosed by brackets "[]" replaced with your own identifying
173446Smrj  * information: Portions Copyright [yyyy] [name of copyright owner]
183446Smrj  *
193446Smrj  * CDDL HEADER END
203446Smrj  */
213446Smrj 
223446Smrj /*
233446Smrj  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
243446Smrj  * Use is subject to license terms.
253446Smrj  */
263446Smrj 
273446Smrj #pragma ident	"%Z%%M%	%I%	%E% SMI"
283446Smrj 
293446Smrj #include <sys/types.h>
303446Smrj #include <sys/param.h>
313446Smrj #include <sys/machparam.h>
323446Smrj #include <sys/archsystm.h>
333446Smrj #include <sys/boot_console.h>
34*5084Sjohnlev #include <sys/varargs.h>
35*5084Sjohnlev #include "dboot_asm.h"
363446Smrj #include "dboot_printf.h"
37*5084Sjohnlev #include "dboot_xboot.h"
383446Smrj 
39*5084Sjohnlev #ifdef __xpv
40*5084Sjohnlev #include <sys/hypervisor.h>
41*5084Sjohnlev #endif
423446Smrj 
433446Smrj /*
443446Smrj  * This file provides simple output formatting via dboot_printf()
453446Smrj  */
463446Smrj 
473446Smrj static void do_dboot_printf(char *fmt, va_list args);
483446Smrj 
493446Smrj static char digits[] = "0123456789abcdef";
503446Smrj 
513446Smrj /*
523446Smrj  * Primitive version of panic, prints a message then resets the system
533446Smrj  */
543446Smrj void
dboot_panic(char * fmt,...)553446Smrj dboot_panic(char *fmt, ...)
563446Smrj {
573446Smrj 	va_list	args;
583446Smrj 
593446Smrj 	va_start(args, fmt);
603446Smrj 	do_dboot_printf(fmt, args);
613446Smrj 
623446Smrj 	if (console == CONS_SCREEN_TEXT) {
633446Smrj 		dboot_printf("Press any key to reboot\n");
643446Smrj 		(void) bcons_getchar();
653446Smrj 	}
663446Smrj 	outb(0x64, 0xfe);	/* this resets the system, see pc_reset() */
673446Smrj 	dboot_halt();		/* just in case */
683446Smrj }
693446Smrj 
703446Smrj /*
713446Smrj  * printf for boot code
723446Smrj  */
733446Smrj void
dboot_printf(char * fmt,...)743446Smrj dboot_printf(char *fmt, ...)
753446Smrj {
763446Smrj 	va_list args;
773446Smrj 
783446Smrj 	va_start(args, fmt);
793446Smrj 	do_dboot_printf(fmt, args);
803446Smrj }
813446Smrj 
823446Smrj 
833446Smrj /*
843446Smrj  * output a string
853446Smrj  */
863446Smrj static void
dboot_puts(char * s)873446Smrj dboot_puts(char *s)
883446Smrj {
893446Smrj 	while (*s != 0) {
903446Smrj 		bcons_putchar(*s);
913446Smrj 		++s;
923446Smrj 	}
933446Smrj }
943446Smrj 
953446Smrj static void
dboot_putnum(uint64_t x,uint_t is_signed,uint8_t base)963446Smrj dboot_putnum(uint64_t x, uint_t is_signed, uint8_t base)
973446Smrj {
983446Smrj 	char buffer[64];	/* digits in reverse order */
993446Smrj 	int i;
1003446Smrj 
1013446Smrj 	if (is_signed && (int64_t)x < 0) {
1023446Smrj 		bcons_putchar('-');
1033446Smrj 		x = -x;
1043446Smrj 	}
1053446Smrj 
1063446Smrj 	for (i  = -1; x != 0 && i <= 63; x /= base)
1073446Smrj 		buffer[++i] = digits[x - ((x / base) * base)];
1083446Smrj 
1093446Smrj 	if (i < 0)
1103446Smrj 		buffer[++i] = '0';
1113446Smrj 
1123446Smrj 	while (i >= 0)
1133446Smrj 		bcons_putchar(buffer[i--]);
1143446Smrj }
1153446Smrj 
1163446Smrj /*
1173446Smrj  * very primitive printf - only does %s, %d, %x, %lx, or %%
1183446Smrj  */
1193446Smrj static void
do_dboot_printf(char * fmt,va_list args)1203446Smrj do_dboot_printf(char *fmt, va_list args)
1213446Smrj {
1223446Smrj 	char *s;
1233446Smrj 	uint64_t x;
1243446Smrj 	uint8_t base;
1253446Smrj 	uint8_t size;
1263446Smrj 	uint_t is_signed = 1;
1273446Smrj 
1283446Smrj 	if (fmt == NULL) {
1293446Smrj 		dboot_puts("dboot_printf(): 1st arg is NULL\n");
1303446Smrj 		return;
1313446Smrj 	}
1323446Smrj 	for (; *fmt; ++fmt) {
1333446Smrj 		if (*fmt != '%') {
1343446Smrj 			bcons_putchar(*fmt);
1353446Smrj 			continue;
1363446Smrj 		}
1373446Smrj 
1383446Smrj 		size = 0;
1393446Smrj again:
1403446Smrj 		++fmt;
1413446Smrj 		switch (*fmt) {
1423446Smrj 
1433446Smrj 		case '%':
1443446Smrj 			bcons_putchar(*fmt);
1453446Smrj 			break;
1463446Smrj 
1473446Smrj 		case 'c':
1483446Smrj 			x = va_arg(args, int);
1493446Smrj 			bcons_putchar(x);
1503446Smrj 			break;
1513446Smrj 
1523446Smrj 		case 's':
1533446Smrj 			s = va_arg(args, char *);
1543446Smrj 			if (s == NULL)
1553446Smrj 				dboot_puts("*NULL*");
1563446Smrj 			else
1573446Smrj 				dboot_puts(s);
1583446Smrj 			break;
1593446Smrj 
1603446Smrj 		case 'p':
1613446Smrj 			x = va_arg(args, ulong_t);
1623446Smrj 			dboot_putnum(x, !is_signed, 16);
1633446Smrj 			break;
1643446Smrj 
1653446Smrj 		case 'l':
1663446Smrj 			if (size == 0)
1673446Smrj 				size = sizeof (long);
1683446Smrj 			else if (size == sizeof (long))
1693446Smrj 				size = sizeof (long long);
1703446Smrj 			goto again;
1713446Smrj 
1723446Smrj 		case 'd':
1733446Smrj 			if (size == 0)
1743446Smrj 				x = va_arg(args, int);
1753446Smrj 			else if (size == sizeof (long))
1763446Smrj 				x = va_arg(args, long);
1773446Smrj 			else
1783446Smrj 				x = va_arg(args, long long);
1793446Smrj 			dboot_putnum(x, is_signed, 10);
1803446Smrj 			break;
1813446Smrj 
1823446Smrj 		case 'b':
1833446Smrj 			base = 2;
1843446Smrj 			goto unsigned_num;
1853446Smrj 
1863446Smrj 		case 'o':
1873446Smrj 			base = 8;
1883446Smrj 			goto unsigned_num;
1893446Smrj 
1903446Smrj 		case 'x':
1913446Smrj 			base = 16;
1923446Smrj unsigned_num:
1933446Smrj 			if (size == 0)
1943446Smrj 				x = va_arg(args, uint_t);
1953446Smrj 			else if (size == sizeof (long))
1963446Smrj 				x = va_arg(args, ulong_t);
1973446Smrj 			else
1983446Smrj 				x = va_arg(args, unsigned long long);
1993446Smrj 			dboot_putnum(x, !is_signed, base);
2003446Smrj 			break;
2013446Smrj 
2023446Smrj 		default:
2033446Smrj 			dboot_puts("dboot_printf(): unknown % escape\n");
2043446Smrj 		}
2053446Smrj 	}
2063446Smrj }
207