Home | History | Annotate | Line # | Download | only in common
prom.c revision 1.11
      1  1.11   nathanw /* $NetBSD: prom.c,v 1.11 2002/07/30 20:36:42 nathanw 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.1       cgd init_prom_calls()
     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.1       cgd 	prom_getenv(PROM_E_TTY_DEV, buf, 4);
     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.10       cgd test_getchar(xc)
     67   1.4      ross 	int *xc;
     68   1.4      ross {
     69  1.10       cgd 	prom_return_t ret;
     70  1.10       cgd 
     71  1.10       cgd 	ret.bits = prom_dispatch(PROM_R_GETC, console);
     72  1.10       cgd 	*xc = ret.u.retval;
     73  1.10       cgd 	return ret.u.status == 0 || ret.u.status == 1;
     74   1.4      ross }
     75  1.10       cgd #endif
     76   1.4      ross 
     77  1.10       cgd #if !defined(NO_GETCHAR)
     78   1.1       cgd int
     79   1.1       cgd getchar()
     80   1.1       cgd {
     81   1.4      ross 	int c;
     82   1.1       cgd 
     83   1.1       cgd 	for (;;) {
     84  1.10       cgd 		if (test_getchar(&c)) {
     85   1.4      ross 			if (c == 3)
     86   1.4      ross 				halt();
     87   1.4      ross 			return c;
     88   1.4      ross 		}
     89   1.1       cgd 	}
     90   1.1       cgd }
     91  1.10       cgd #endif
     92  1.10       cgd 
     93  1.10       cgd static void
     94  1.10       cgd putonechar(c)
     95  1.10       cgd 	int c;
     96  1.10       cgd {
     97  1.10       cgd 	prom_return_t ret;
     98  1.10       cgd 	char cbuf = c;
     99  1.10       cgd 
    100  1.10       cgd 	do {
    101  1.10       cgd 		ret.bits = prom_dispatch(PROM_R_PUTS, console, &cbuf, 1);
    102  1.10       cgd 	} while ((ret.u.retval & 1) == 0);
    103  1.10       cgd }
    104   1.1       cgd 
    105   1.9      ross void
    106   1.9      ross putchar(c)
    107   1.6       cgd 	int c;
    108   1.6       cgd {
    109  1.10       cgd #if !defined(NO_PUTCHAR_HALT)
    110   1.9      ross 	int typed_c;
    111  1.10       cgd #endif
    112   1.6       cgd 
    113   1.9      ross 	if (c == '\r' || c == '\n') {
    114  1.10       cgd 		putonechar('\r');
    115  1.10       cgd 		c = '\n';
    116  1.10       cgd 	}
    117  1.10       cgd 	putonechar(c);
    118  1.10       cgd #if !defined(NO_PUTCHAR_HALT)
    119  1.10       cgd 	if (test_getchar(&typed_c))
    120   1.4      ross 		if (typed_c == 3)
    121   1.4      ross 			halt();
    122  1.10       cgd #endif
    123   1.1       cgd }
    124   1.1       cgd 
    125   1.1       cgd int
    126   1.1       cgd prom_getenv(id, buf, len)
    127   1.1       cgd 	int id, len;
    128   1.1       cgd 	char *buf;
    129   1.1       cgd {
    130  1.11   nathanw 	/*
    131  1.11   nathanw 	 * On at least some systems, the GETENV call requires a
    132  1.11   nathanw 	 * 8-byte-aligned buffer, or it bails out with a "kernel stack
    133  1.11   nathanw 	 * not valid halt". Provide a local, aligned buffer here and
    134  1.11   nathanw 	 * then copy to the caller's buffer.
    135  1.11   nathanw 	 */
    136  1.11   nathanw 	static char abuf[128] __attribute__((aligned (8)));
    137   1.1       cgd 	prom_return_t ret;
    138   1.1       cgd 
    139  1.11   nathanw 	ret.bits = prom_dispatch(PROM_R_GETENV, id, abuf, 128);
    140   1.1       cgd 	if (ret.u.status & 0x4)
    141   1.1       cgd 		ret.u.retval = 0;
    142  1.11   nathanw 	len = min(len - 1, ret.u.retval);
    143  1.11   nathanw 	memcpy(buf, abuf, len);
    144  1.11   nathanw 	buf[len] = '\0';
    145   1.1       cgd 
    146  1.11   nathanw 	return (len);
    147   1.1       cgd }
    148