1 /* $OpenBSD: prom.c,v 1.9 2023/01/16 07:29:32 deraadt Exp $ */ 2 /* $NetBSD: prom.c,v 1.2 1996/11/25 16:18:16 cgd Exp $ */ 3 4 /* 5 * Mach Operating System 6 * Copyright (c) 1992 Carnegie Mellon University 7 * All Rights Reserved. 8 * 9 * Permission to use, copy, modify and distribute this software and its 10 * documentation is hereby granted, provided that both the copyright 11 * notice and this permission notice appear in all copies of the 12 * software, derivative works or modified versions, and any portions 13 * thereof, and that both notices appear in supporting documentation. 14 * 15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 17 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 18 * 19 * Carnegie Mellon requests users of this software to return to 20 * 21 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 22 * School of Computer Science 23 * Carnegie Mellon University 24 * Pittsburgh PA 15213-3890 25 * 26 * any improvements or extensions that they make and grant Carnegie Mellon 27 * the rights to redistribute these changes. 28 */ 29 30 #include <lib/libsa/stand.h> 31 32 #include <sys/types.h> 33 34 #include <machine/rpb.h> 35 #include <machine/prom.h> 36 37 int console; 38 39 void 40 init_prom_calls() 41 { 42 extern struct prom_vec prom_dispatch_v; 43 struct rpb *r; 44 struct crb *c; 45 char buf[4]; 46 47 r = (struct rpb *)HWRPB_ADDR; 48 c = (struct crb *)((u_int8_t *)r + r->rpb_crb_off); 49 50 prom_dispatch_v.routine_arg = c->crb_v_dispatch; 51 prom_dispatch_v.routine = c->crb_v_dispatch->entry_va; 52 53 /* Look for console tty. */ 54 prom_getenv(PROM_E_TTY_DEV, buf, 4); 55 console = buf[0] - '0'; 56 } 57 58 int 59 getchar() 60 { 61 prom_return_t ret; 62 63 for (;;) { 64 ret.bits = prom_dispatch(PROM_R_GETC, console, 0, 0, 0); 65 if (ret.u.status == 0 || ret.u.status == 1) 66 return (ret.u.retval); 67 } 68 } 69 70 void 71 putchar(c) 72 int c; 73 { 74 prom_return_t ret; 75 char cbuf; 76 77 if (c == '\r' || c == '\n') { 78 cbuf = '\r'; 79 do { 80 ret.bits = prom_dispatch(PROM_R_PUTS, console, 81 (u_int64_t)&cbuf, 1, 0); 82 } while ((ret.u.retval & 1) == 0); 83 cbuf = '\n'; 84 } else 85 cbuf = c; 86 do { 87 ret.bits = prom_dispatch(PROM_R_PUTS, console, 88 (u_int64_t)&cbuf, 1, 0); 89 } while ((ret.u.retval & 1) == 0); 90 } 91 92 int 93 prom_getenv(id, buf, len) 94 int id, len; 95 char *buf; 96 { 97 /* 98 * On at least some systems, the GETENV call requires a 99 * 8-byte-aligned buffer, or it bails out with a "kernel stack 100 * not valid halt". Provide a local, aligned buffer here and 101 * then copy to the caller's buffer. 102 */ 103 static char abuf[128] __attribute__ ((aligned (8))); 104 prom_return_t ret; 105 106 ret.bits = prom_dispatch(PROM_R_GETENV, id, (u_int64_t)abuf, 128, 0); 107 if (ret.u.status & 0x4) 108 ret.u.retval = 0; 109 len--; 110 if (len > ret.u.retval) 111 len = ret.u.retval; 112 memcpy(buf, abuf, len); 113 buf[len] = '\0'; 114 115 return (len); 116 } 117