1ae115bc7Smrj /*
2ae115bc7Smrj * CDDL HEADER START
3ae115bc7Smrj *
4ae115bc7Smrj * The contents of this file are subject to the terms of the
5ae115bc7Smrj * Common Development and Distribution License (the "License").
6ae115bc7Smrj * You may not use this file except in compliance with the License.
7ae115bc7Smrj *
8ae115bc7Smrj * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9ae115bc7Smrj * or http://www.opensolaris.org/os/licensing.
10ae115bc7Smrj * See the License for the specific language governing permissions
11ae115bc7Smrj * and limitations under the License.
12ae115bc7Smrj *
13ae115bc7Smrj * When distributing Covered Code, include this CDDL HEADER in each
14ae115bc7Smrj * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15ae115bc7Smrj * If applicable, add the following below this CDDL HEADER, with the
16ae115bc7Smrj * fields enclosed by brackets "[]" replaced with your own identifying
17ae115bc7Smrj * information: Portions Copyright [yyyy] [name of copyright owner]
18ae115bc7Smrj *
19ae115bc7Smrj * CDDL HEADER END
20ae115bc7Smrj */
21ae115bc7Smrj
22ae115bc7Smrj /*
23*0d928757SGary Mills * Copyright (c) 2012 Gary Mills
24*0d928757SGary Mills *
25ae115bc7Smrj * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
26ae115bc7Smrj * Use is subject to license terms.
27ae115bc7Smrj */
28ae115bc7Smrj
29ae115bc7Smrj #include <sys/types.h>
30ae115bc7Smrj #include <sys/param.h>
31ae115bc7Smrj #include <sys/machparam.h>
32ae115bc7Smrj #include <sys/archsystm.h>
33ae115bc7Smrj #include <sys/boot_console.h>
34ae115bc7Smrj #include <sys/varargs.h>
35843e1988Sjohnlev #include "dboot_asm.h"
36843e1988Sjohnlev #include "dboot_printf.h"
37843e1988Sjohnlev #include "dboot_xboot.h"
38843e1988Sjohnlev
39843e1988Sjohnlev #ifdef __xpv
40843e1988Sjohnlev #include <sys/hypervisor.h>
41843e1988Sjohnlev #endif
42ae115bc7Smrj
43ae115bc7Smrj /*
44ae115bc7Smrj * This file provides simple output formatting via dboot_printf()
45ae115bc7Smrj */
46ae115bc7Smrj
47ae115bc7Smrj static void do_dboot_printf(char *fmt, va_list args);
48ae115bc7Smrj
49ae115bc7Smrj static char digits[] = "0123456789abcdef";
50ae115bc7Smrj
51ae115bc7Smrj /*
52ae115bc7Smrj * Primitive version of panic, prints a message then resets the system
53ae115bc7Smrj */
54ae115bc7Smrj void
dboot_panic(char * fmt,...)55ae115bc7Smrj dboot_panic(char *fmt, ...)
56ae115bc7Smrj {
57ae115bc7Smrj va_list args;
58ae115bc7Smrj
59ae115bc7Smrj va_start(args, fmt);
60ae115bc7Smrj do_dboot_printf(fmt, args);
61ae115bc7Smrj
62*0d928757SGary Mills if (boot_console_type(NULL) == CONS_SCREEN_TEXT) {
63ae115bc7Smrj dboot_printf("Press any key to reboot\n");
64ae115bc7Smrj (void) bcons_getchar();
65ae115bc7Smrj }
66ae115bc7Smrj outb(0x64, 0xfe); /* this resets the system, see pc_reset() */
67ae115bc7Smrj dboot_halt(); /* just in case */
68ae115bc7Smrj }
69ae115bc7Smrj
70ae115bc7Smrj /*
71ae115bc7Smrj * printf for boot code
72ae115bc7Smrj */
73ae115bc7Smrj void
dboot_printf(char * fmt,...)74ae115bc7Smrj dboot_printf(char *fmt, ...)
75ae115bc7Smrj {
76ae115bc7Smrj va_list args;
77ae115bc7Smrj
78ae115bc7Smrj va_start(args, fmt);
79ae115bc7Smrj do_dboot_printf(fmt, args);
80ae115bc7Smrj }
81ae115bc7Smrj
82ae115bc7Smrj
83ae115bc7Smrj /*
84ae115bc7Smrj * output a string
85ae115bc7Smrj */
86ae115bc7Smrj static void
dboot_puts(char * s)87ae115bc7Smrj dboot_puts(char *s)
88ae115bc7Smrj {
89ae115bc7Smrj while (*s != 0) {
90ae115bc7Smrj bcons_putchar(*s);
91ae115bc7Smrj ++s;
92ae115bc7Smrj }
93ae115bc7Smrj }
94ae115bc7Smrj
95ae115bc7Smrj static void
dboot_putnum(uint64_t x,uint_t is_signed,uint8_t base)96ae115bc7Smrj dboot_putnum(uint64_t x, uint_t is_signed, uint8_t base)
97ae115bc7Smrj {
98ae115bc7Smrj char buffer[64]; /* digits in reverse order */
99ae115bc7Smrj int i;
100ae115bc7Smrj
101ae115bc7Smrj if (is_signed && (int64_t)x < 0) {
102ae115bc7Smrj bcons_putchar('-');
103ae115bc7Smrj x = -x;
104ae115bc7Smrj }
105ae115bc7Smrj
106ae115bc7Smrj for (i = -1; x != 0 && i <= 63; x /= base)
107ae115bc7Smrj buffer[++i] = digits[x - ((x / base) * base)];
108ae115bc7Smrj
109ae115bc7Smrj if (i < 0)
110ae115bc7Smrj buffer[++i] = '0';
111ae115bc7Smrj
112ae115bc7Smrj while (i >= 0)
113ae115bc7Smrj bcons_putchar(buffer[i--]);
114ae115bc7Smrj }
115ae115bc7Smrj
116ae115bc7Smrj /*
117ae115bc7Smrj * very primitive printf - only does %s, %d, %x, %lx, or %%
118ae115bc7Smrj */
119ae115bc7Smrj static void
do_dboot_printf(char * fmt,va_list args)120ae115bc7Smrj do_dboot_printf(char *fmt, va_list args)
121ae115bc7Smrj {
122ae115bc7Smrj char *s;
123ae115bc7Smrj uint64_t x;
124ae115bc7Smrj uint8_t base;
125ae115bc7Smrj uint8_t size;
126ae115bc7Smrj uint_t is_signed = 1;
127ae115bc7Smrj
128ae115bc7Smrj if (fmt == NULL) {
129ae115bc7Smrj dboot_puts("dboot_printf(): 1st arg is NULL\n");
130ae115bc7Smrj return;
131ae115bc7Smrj }
132ae115bc7Smrj for (; *fmt; ++fmt) {
133ae115bc7Smrj if (*fmt != '%') {
134ae115bc7Smrj bcons_putchar(*fmt);
135ae115bc7Smrj continue;
136ae115bc7Smrj }
137ae115bc7Smrj
138ae115bc7Smrj size = 0;
139ae115bc7Smrj again:
140ae115bc7Smrj ++fmt;
141ae115bc7Smrj switch (*fmt) {
142ae115bc7Smrj
143ae115bc7Smrj case '%':
144ae115bc7Smrj bcons_putchar(*fmt);
145ae115bc7Smrj break;
146ae115bc7Smrj
147ae115bc7Smrj case 'c':
148ae115bc7Smrj x = va_arg(args, int);
149ae115bc7Smrj bcons_putchar(x);
150ae115bc7Smrj break;
151ae115bc7Smrj
152ae115bc7Smrj case 's':
153ae115bc7Smrj s = va_arg(args, char *);
154ae115bc7Smrj if (s == NULL)
155ae115bc7Smrj dboot_puts("*NULL*");
156ae115bc7Smrj else
157ae115bc7Smrj dboot_puts(s);
158ae115bc7Smrj break;
159ae115bc7Smrj
160ae115bc7Smrj case 'p':
161ae115bc7Smrj x = va_arg(args, ulong_t);
162ae115bc7Smrj dboot_putnum(x, !is_signed, 16);
163ae115bc7Smrj break;
164ae115bc7Smrj
165ae115bc7Smrj case 'l':
166ae115bc7Smrj if (size == 0)
167ae115bc7Smrj size = sizeof (long);
168ae115bc7Smrj else if (size == sizeof (long))
169ae115bc7Smrj size = sizeof (long long);
170ae115bc7Smrj goto again;
171ae115bc7Smrj
172ae115bc7Smrj case 'd':
173ae115bc7Smrj if (size == 0)
174ae115bc7Smrj x = va_arg(args, int);
175ae115bc7Smrj else if (size == sizeof (long))
176ae115bc7Smrj x = va_arg(args, long);
177ae115bc7Smrj else
178ae115bc7Smrj x = va_arg(args, long long);
179ae115bc7Smrj dboot_putnum(x, is_signed, 10);
180ae115bc7Smrj break;
181ae115bc7Smrj
182ae115bc7Smrj case 'b':
183ae115bc7Smrj base = 2;
184ae115bc7Smrj goto unsigned_num;
185ae115bc7Smrj
186ae115bc7Smrj case 'o':
187ae115bc7Smrj base = 8;
188ae115bc7Smrj goto unsigned_num;
189ae115bc7Smrj
190ae115bc7Smrj case 'x':
191ae115bc7Smrj base = 16;
192ae115bc7Smrj unsigned_num:
193ae115bc7Smrj if (size == 0)
194ae115bc7Smrj x = va_arg(args, uint_t);
195ae115bc7Smrj else if (size == sizeof (long))
196ae115bc7Smrj x = va_arg(args, ulong_t);
197ae115bc7Smrj else
198ae115bc7Smrj x = va_arg(args, unsigned long long);
199ae115bc7Smrj dboot_putnum(x, !is_signed, base);
200ae115bc7Smrj break;
201ae115bc7Smrj
202ae115bc7Smrj default:
203ae115bc7Smrj dboot_puts("dboot_printf(): unknown % escape\n");
204ae115bc7Smrj }
205ae115bc7Smrj }
206ae115bc7Smrj }
207