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