1/* $NetBSD: promcall.c,v 1.20 2011/02/20 07:50:25 matt Exp $ */ 2 3/* 4 * Copyright (c) 1988 University of Utah. 5 * Copyright (c) 1992, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * the Systems Programming Group of the University of Utah Computer 10 * Science Department and Ralph Campbell. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * from: Utah Hdr: cons.c 1.1 90/07/09 37 * 38 * @(#)cons.c 8.2 (Berkeley) 1/11/94 39 */ 40 41#include <sys/cdefs.h> 42__KERNEL_RCSID(0, "$NetBSD: promcall.c,v 1.20 2011/02/20 07:50:25 matt Exp $"); 43 44#include <sys/param.h> 45#include <sys/device.h> 46#include <sys/reboot.h> 47#include <sys/systm.h> 48 49#include <dev/cons.h> 50 51#include <pmax/dec_prom.h> 52#include <pmax/pmax/pmaxtype.h> 53#include <pmax/pmax/machdep.h> 54 55static int romgetc(dev_t); 56static void romputc(dev_t, int); 57 58#define DEFAULT_SCSIID 7 /* XXX - this should really live somewhere else */ 59 60/* 61 * Default consdev, for errors or warnings before 62 * consinit runs: use the PROM. 63 */ 64struct consdev promcd = { 65 NULL, /* probe */ 66 NULL, /* init */ 67 romgetc, /* getc */ 68 romputc, /* putc */ 69 nullcnpollc, /* pollc */ 70 NULL, /* bell */ 71 makedev(0, 0), 72 CN_DEAD, 73}; 74 75/* 76 * Get character from PROM console. 77 */ 78static int 79romgetc(dev_t dev) 80{ 81 int chr, s; 82 83 s = splhigh(); 84 chr = promcall(callv->_getchar); 85 splx(s); 86 return chr; 87} 88 89/* 90 * Print a character on PROM console. 91 */ 92static void 93romputc(dev_t dev, int c) 94{ 95 int s; 96 97 s = splhigh(); 98 promcall(callv->_printf, "%c", c); 99 splx(s); 100} 101 102/* 103 * Call back to the PROM to find out what devices it is using 104 * as console. 105 * Encoding is idiosyncratic; see DECstation Owners Guide. 106 */ 107void 108prom_findcons(int *kbdslot, int *crtslot, int *prom_using_screen) 109{ 110 char *oscon = 0; /* PROM osconsole string */ 111 112 /* 113 * Get and parse the "osconsole" environment variable. 114 */ 115 *crtslot = *kbdslot = -1; 116 oscon = prom_getenv("osconsole"); 117 if (oscon && *oscon >= '0' && *oscon <= '9') { 118 *kbdslot = *oscon - '0'; 119 *prom_using_screen = 0; 120 while (*++oscon) { 121 if (*oscon == ',') 122 *prom_using_screen = 1; 123 else if (*prom_using_screen && 124 *oscon >= '0' && *oscon <= '9') { 125 *crtslot = *kbdslot; 126 *kbdslot = *oscon - '0'; 127 break; 128 } 129 } 130 } 131 132 /* 133 * compensate for discrepancies in PROM syntax. 134 * XXX use cons_init vector instead? 135 */ 136 if (systype == DS_PMAX && *kbdslot == 1) 137 *prom_using_screen = 1; 138 139 /* 140 * On a 5000/200, The boot program uses the old, pre-rex PROM 141 * entrypoints, so the ROM sets osconsole to '1' like the PMAX. 142 * our parser loses. fix it by hand. 143 */ 144 if (systype == DS_3MAX && *crtslot == -1 && *kbdslot == 1) { 145 /* Try to use pmax onboard framebuffer */ 146 *prom_using_screen = 1; 147 *crtslot = 0; 148 *kbdslot = 7; 149 } 150 151} 152 153/* 154 * Get a prom environment variable. 155 */ 156char * 157prom_getenv(const char *name) 158{ 159 160 return (void *)promcall(callv->_getenv, name); 161} 162 163/* 164 * Get 32bit system type of Digital hardware. 165 * cputype, uint8_t [3] 166 * systype, uint8_t [2] 167 * firmware revision, uint8_t [1] 168 * hardware revision. uint8_t [0] 169 */ 170int 171prom_systype(void) 172{ 173#ifndef _LP64 174 char *cp; 175 176 if (callv != &callvec) 177#endif 178 return promcall(callv->_getsysid); 179#ifndef _LP64 180 cp = prom_getenv("systype"); 181 return (cp != NULL) ? strtoul(cp, NULL, 0) : 0; 182#endif 183} 184 185/* 186 * Reset machine by haltbutton. 187 */ 188void 189prom_haltbutton(void) 190{ 191 192 promcall(callv->_halt, (int *)0, 0); 193} 194 195/* 196 * Halt/reboot machine. 197 */ 198void __dead 199prom_halt(int howto, char *bootstr) 200{ 201 202 if (callv != &callvec) 203 promcall(callv->_rex, (howto & RB_HALT) ? 'h' : 'b'); 204 else { 205 void __dead (*f)(void); 206 207 f = (howto & RB_HALT) 208 ? (void *)DEC_PROM_REINIT 209 : (void *)DEC_PROM_AUTOBOOT; 210 (*f)(); 211 } 212 213 while(1) ; /* fool gcc */ 214 /*NOTREACHED*/ 215} 216 217/* 218 * Get the host SCSI ID from the PROM. 219 */ 220int 221prom_scsiid(int cnum) 222{ 223 char scsiid_var[8]; /* strlen("scsiidX") + NULL */ 224 char *cp; 225 226 snprintf(scsiid_var, 8, "scsiid%d", cnum); 227 cp = prom_getenv(scsiid_var); 228 return (cp != NULL) ? strtoul(cp, NULL, 0) : DEFAULT_SCSIID; 229} 230 231/* 232 * Get the memory bitmap from the PROM if we can 233 */ 234int 235prom_getbitmap(struct memmap *map) 236{ 237 char *cp; 238 int len; 239 240 if (callv->_getbitmap != NULL) 241 return promcall(callv->_getbitmap, map); 242 243 /* 244 * See if we can get the bitmap from the environment variables 245 */ 246 cp = prom_getenv("bitmaplen"); 247 if (cp == NULL) 248 return 0; 249 len = (int)strtoul(cp, NULL, 0) * 4; 250 cp = prom_getenv("bitmap"); 251 if (cp == NULL) 252 return 0; 253 memcpy(&map->bitmap, (char *)strtoul(cp, NULL, 0), len); 254 map->pagesize = 4096; 255 return len; 256} 257