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 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 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 87ae115bc7Smrj dboot_puts(char *s) 88ae115bc7Smrj { 89ae115bc7Smrj while (*s != 0) { 90ae115bc7Smrj bcons_putchar(*s); 91ae115bc7Smrj ++s; 92ae115bc7Smrj } 93ae115bc7Smrj } 94ae115bc7Smrj 95ae115bc7Smrj static void 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 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