xref: /openbsd/sys/arch/sparc64/dev/zs.c (revision d415bd75)
1 /*	$OpenBSD: zs.c,v 1.32 2021/10/24 17:05:04 mpi Exp $	*/
2 /*	$NetBSD: zs.c,v 1.29 2001/05/30 15:24:24 lukem Exp $	*/
3 
4 /*-
5  * Copyright (c) 1996 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Gordon W. Ross.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * Zilog Z8530 Dual UART driver (machine-dependent part)
35  *
36  * Runs two serial lines per chip using slave drivers.
37  * Plain tty/async lines use the zstty slave.
38  * Sun keyboard/mouse uses the zskbd/zsms slaves.
39  */
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/conf.h>
44 #include <sys/device.h>
45 #include <sys/ioctl.h>
46 #include <sys/kernel.h>
47 #include <sys/proc.h>
48 #include <sys/tty.h>
49 #include <sys/time.h>
50 #include <sys/syslog.h>
51 
52 #include <machine/autoconf.h>
53 #include <machine/openfirm.h>
54 #include <machine/conf.h>
55 #include <machine/cpu.h>
56 #include <machine/psl.h>
57 #include <machine/z8530var.h>
58 
59 #include <dev/cons.h>
60 #include <dev/ic/z8530reg.h>
61 #include <sparc64/dev/fhcvar.h>
62 #include <ddb/db_output.h>
63 
64 #include <sparc64/dev/cons.h>
65 
66 struct cfdriver zs_cd = {
67 	NULL, "zs", DV_TTY
68 };
69 
70 /*
71  * Some warts needed by z8530tty.c -
72  * The default parity REALLY needs to be the same as the PROM uses,
73  * or you can not see messages done with printf during boot-up...
74  */
75 int zs_def_cflag = (CREAD | CS8 | HUPCL);
76 int zs_major = 12;
77 
78 /*
79  * The Sun provides a 4.9152 MHz clock to the ZS chips.
80  */
81 #define PCLK	(9600 * 512)	/* PCLK pin input clock rate */
82 
83 #define	ZS_DELAY()
84 
85 /* The layout of this is hardware-dependent (padding, order). */
86 struct zschan {
87 	volatile u_char	zc_csr;		/* ctrl,status, and indirect access */
88 	u_char		zc_xxx0;
89 	volatile u_char	zc_data;	/* data */
90 	u_char		zc_xxx1;
91 };
92 struct zsdevice {
93 	/* Yes, they are backwards. */
94 	struct	zschan zs_chan_b;
95 	struct	zschan zs_chan_a;
96 };
97 
98 /* ZS channel used as the console device (if any) */
99 void *zs_conschan_get, *zs_conschan_put;
100 
101 static u_char zs_init_reg[16] = {
102 	0,	/* 0: CMD (reset, etc.) */
103 	0,	/* 1: No interrupts yet. */
104 	0,	/* 2: IVECT */
105 	ZSWR3_RX_8 | ZSWR3_RX_ENABLE,
106 	ZSWR4_CLK_X16 | ZSWR4_ONESB,
107 	ZSWR5_TX_8 | ZSWR5_TX_ENABLE,
108 	0,	/* 6: TXSYNC/SYNCLO */
109 	0,	/* 7: RXSYNC/SYNCHI */
110 	0,	/* 8: alias for data port */
111 	ZSWR9_MASTER_IE | ZSWR9_NO_VECTOR,
112 	0,	/*10: Misc. TX/RX control bits */
113 	ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD,
114 	((PCLK/32)/9600)-2,	/*12: BAUDLO (default=9600) */
115 	0,			/*13: BAUDHI (default=9600) */
116 	ZSWR14_BAUD_ENA | ZSWR14_BAUD_FROM_PCLK,
117 	ZSWR15_BREAK_IE,
118 };
119 
120 /* Console ops */
121 static int  zscngetc(dev_t);
122 static void zscnputc(dev_t, int);
123 static void zscnpollc(dev_t, int);
124 
125 struct consdev zs_consdev = {
126 	NULL,
127 	NULL,
128 	zscngetc,
129 	zscnputc,
130 	zscnpollc,
131 	NULL,
132 };
133 
134 
135 /****************************************************************
136  * Autoconfig
137  ****************************************************************/
138 
139 /* Definition of the driver for autoconfig. */
140 static int  zs_match_sbus(struct device *, void *, void *);
141 static void zs_attach_sbus(struct device *, struct device *, void *);
142 
143 static int  zs_match_fhc(struct device *, void *, void *);
144 static void zs_attach_fhc(struct device *, struct device *, void *);
145 
146 static void zs_attach(struct zsc_softc *, struct zsdevice *, int);
147 static int  zs_print(void *, const char *name);
148 
149 const struct cfattach zs_sbus_ca = {
150 	sizeof(struct zsc_softc), zs_match_sbus, zs_attach_sbus
151 };
152 
153 const struct cfattach zs_fhc_ca = {
154 	sizeof(struct zsc_softc), zs_match_fhc, zs_attach_fhc
155 };
156 
157 extern int stdinnode;
158 extern int fbnode;
159 
160 /* Interrupt handlers. */
161 static int zshard(void *);
162 static void zssoft(void *);
163 
164 static int zs_get_speed(struct zs_chanstate *);
165 
166 /* Console device support */
167 static int zs_console_flags(int, int, int);
168 
169 /*
170  * Is the zs chip present?
171  */
172 static int
173 zs_match_sbus(struct device *parent, void *vcf, void *aux)
174 {
175 	struct cfdata *cf = vcf;
176 	struct sbus_attach_args *sa = aux;
177 
178 	if (strcmp(cf->cf_driver->cd_name, sa->sa_name) != 0)
179 		return (0);
180 
181 	return (1);
182 }
183 
184 static int
185 zs_match_fhc(struct device *parent, void *vcf, void *aux)
186 {
187 	struct cfdata *cf = vcf;
188 	struct fhc_attach_args *fa = aux;
189 
190 	if (strcmp(cf->cf_driver->cd_name, fa->fa_name) != 0)
191 		return (0);
192 	return (1);
193 }
194 
195 static void
196 zs_attach_sbus(struct device *parent, struct device *self, void *aux)
197 {
198 	struct zsc_softc *zsc = (void *) self;
199 	struct sbus_attach_args *sa = aux;
200 	struct zsdevice *zsaddr;
201 	bus_space_handle_t kvaddr;
202 
203 	if (sa->sa_nintr == 0) {
204 		printf(" no interrupt lines\n");
205 		return;
206 	}
207 
208 	/* Only map registers once. */
209 	if (sa->sa_npromvaddrs) {
210 		/*
211 		 * We're converting from a 32-bit pointer to a 64-bit
212 		 * pointer.  Since the 32-bit entity is negative, but
213 		 * the kernel is still mapped into the lower 4GB
214 		 * range, this needs to be zero-extended.
215 		 *
216 		 * XXXXX If we map the kernel and devices into the
217 		 * high 4GB range, this needs to be changed to
218 		 * sign-extend the address.
219 		 */
220 		zsaddr = (struct zsdevice *)
221 		    (unsigned long int)sa->sa_promvaddrs[0];
222 	} else {
223 		if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, sa->sa_offset,
224 		    sa->sa_size, BUS_SPACE_MAP_LINEAR, 0, &kvaddr) != 0) {
225 			printf("%s @ sbus: cannot map registers\n",
226 			       self->dv_xname);
227 			return;
228 		}
229 		zsaddr = (struct zsdevice *)
230 		    bus_space_vaddr(sa->sa_bustag, kvaddr);
231 	}
232 
233 	zsc->zsc_bustag = sa->sa_bustag;
234 	zsc->zsc_dmatag = sa->sa_dmatag;
235 	zsc->zsc_promunit = getpropint(sa->sa_node, "slave", -2);
236 	zsc->zsc_node = sa->sa_node;
237 
238 	zs_attach(zsc, zsaddr, sa->sa_pri);
239 }
240 
241 static void
242 zs_attach_fhc(struct device *parent, struct device *self, void *aux)
243 {
244 	struct zsc_softc *zsc = (void *) self;
245 	struct fhc_attach_args *fa = aux;
246 	struct zsdevice *zsaddr;
247 	bus_space_handle_t kvaddr;
248 
249 	if (fa->fa_nreg < 1 && fa->fa_npromvaddrs < 1) {
250 		printf(": no registers\n");
251 		return;
252 	}
253 
254 	if (fa->fa_nintr < 1) {
255 		printf(": no interrupts\n");
256 		return;
257 	}
258 
259 	if (fa->fa_npromvaddrs) {
260 		/*
261 		 * We're converting from a 32-bit pointer to a 64-bit
262 		 * pointer.  Since the 32-bit entity is negative, but
263 		 * the kernel is still mapped into the lower 4GB
264 		 * range, this needs to be zero-extended.
265 		 *
266 		 * XXXXX If we map the kernel and devices into the
267 		 * high 4GB range, this needs to be changed to
268 		 * sign-extend the address.
269 		 */
270 		zsaddr = (struct zsdevice *)
271 		    (unsigned long int)fa->fa_promvaddrs[0];
272 	} else {
273 		if (fhc_bus_map(fa->fa_bustag, fa->fa_reg[0].fbr_slot,
274 		    fa->fa_reg[0].fbr_offset, fa->fa_reg[0].fbr_size,
275 		    BUS_SPACE_MAP_LINEAR, &kvaddr) != 0) {
276 			printf("%s @ fhc: cannot map registers\n",
277 			    self->dv_xname);
278 			return;
279 		}
280 		zsaddr = (struct zsdevice *)
281 		    bus_space_vaddr(fa->fa_bustag, kvaddr);
282 	}
283 
284 	zsc->zsc_bustag = fa->fa_bustag;
285 	zsc->zsc_dmatag = NULL;
286 	zsc->zsc_promunit = getpropint(fa->fa_node, "slave", -2);
287 	zsc->zsc_node = fa->fa_node;
288 
289 	zs_attach(zsc, zsaddr, fa->fa_intr[0]);
290 }
291 
292 /*
293  * Attach a found zs.
294  *
295  * USE ROM PROPERTY keyboard FOR KEYBOARD/MOUSE?
296  */
297 static void
298 zs_attach(struct zsc_softc *zsc, struct zsdevice *zsd, int pri)
299 {
300 	struct zsc_attach_args zsc_args;
301 	struct zs_chanstate *cs;
302 	int s, channel, softpri = PIL_TTY;
303 
304 	if (zsd == NULL) {
305 		printf("configuration incomplete\n");
306 		return;
307 	}
308 
309 	printf(" softpri %d\n", softpri);
310 
311 	/*
312 	 * Initialize software state for each channel.
313 	 */
314 	for (channel = 0; channel < 2; channel++) {
315 		struct zschan *zc;
316 		struct device *child;
317 
318 		zsc_args.type = "serial";
319 		if (getproplen(zsc->zsc_node, "keyboard") == 0) {
320 			if (channel == 0)
321 				zsc_args.type = "keyboard";
322 			if (channel == 1)
323 				zsc_args.type = "mouse";
324 		}
325 
326 		zsc_args.channel = channel;
327 		cs = &zsc->zsc_cs_store[channel];
328 		zsc->zsc_cs[channel] = cs;
329 
330 		cs->cs_channel = channel;
331 		cs->cs_private = NULL;
332 		cs->cs_ops = &zsops_null;
333 		cs->cs_brg_clk = PCLK / 16;
334 
335 		zc = (channel == 0) ? &zsd->zs_chan_a : &zsd->zs_chan_b;
336 
337 		zsc_args.consdev = NULL;
338 		zsc_args.hwflags = zs_console_flags(zsc->zsc_promunit,
339 						    zsc->zsc_node,
340 						    channel);
341 
342 		if (zsc_args.hwflags & ZS_HWFLAG_CONSOLE) {
343 			zsc_args.hwflags |= ZS_HWFLAG_USE_CONSDEV;
344 			zsc_args.consdev = &zs_consdev;
345 		}
346 
347 		if (getproplen(zsc->zsc_node, channel == 0 ?
348 		    "port-a-ignore-cd" : "port-b-ignore-cd") == 0) {
349 			zsc_args.hwflags |= ZS_HWFLAG_NO_DCD;
350 		}
351 
352 		if ((zsc_args.hwflags & ZS_HWFLAG_CONSOLE_INPUT) != 0) {
353 			zs_conschan_get = zc;
354 		}
355 		if ((zsc_args.hwflags & ZS_HWFLAG_CONSOLE_OUTPUT) != 0) {
356 			zs_conschan_put = zc;
357 		}
358 		/* Childs need to set cn_dev, etc */
359 
360 		cs->cs_reg_csr  = &zc->zc_csr;
361 		cs->cs_reg_data = &zc->zc_data;
362 
363 		bcopy(zs_init_reg, cs->cs_creg, 16);
364 		bcopy(zs_init_reg, cs->cs_preg, 16);
365 
366 		/* XXX: Consult PROM properties for this?! */
367 		cs->cs_defspeed = zs_get_speed(cs);
368 		cs->cs_defcflag = zs_def_cflag;
369 
370 		/* Make these correspond to cs_defcflag (-crtscts) */
371 		cs->cs_rr0_dcd = ZSRR0_DCD;
372 		cs->cs_rr0_cts = 0;
373 		cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS;
374 		cs->cs_wr5_rts = 0;
375 
376 		/*
377 		 * Clear the master interrupt enable.
378 		 * The INTENA is common to both channels,
379 		 * so just do it on the A channel.
380 		 */
381 		if (channel == 0) {
382 			zs_write_reg(cs, 9, 0);
383 		}
384 
385 		/*
386 		 * Look for a child driver for this channel.
387 		 * The child attach will setup the hardware.
388 		 */
389 		if (!(child =
390 		      config_found(&zsc->zsc_dev, (void *)&zsc_args, zs_print))) {
391 			/* No sub-driver.  Just reset it. */
392 			u_char reset = (channel == 0) ?
393 				ZSWR9_A_RESET : ZSWR9_B_RESET;
394 			s = splzs();
395 			zs_write_reg(cs,  9, reset);
396 			splx(s);
397 		}
398 	}
399 
400 	/*
401 	 * Now safe to install interrupt handlers.
402 	 */
403 	if (bus_intr_establish(zsc->zsc_bustag, pri, IPL_SERIAL, 0, zshard,
404 	    zsc, zsc->zsc_dev.dv_xname) == NULL)
405 		panic("zsattach: could not establish interrupt");
406 	if (!(zsc->zsc_softintr = softintr_establish(softpri, zssoft, zsc)))
407 		panic("zsattach: could not establish soft interrupt");
408 
409 	/*
410 	 * Set the master interrupt enable and interrupt vector.
411 	 * (common to both channels, do it on A)
412 	 */
413 	cs = zsc->zsc_cs[0];
414 	s = splhigh();
415 	/* interrupt vector */
416 	zs_write_reg(cs, 2, zs_init_reg[2]);
417 	/* master interrupt control (enable) */
418 	zs_write_reg(cs, 9, zs_init_reg[9]);
419 	splx(s);
420 
421 }
422 
423 static int
424 zs_print(void *aux, const char *name)
425 {
426 	struct zsc_attach_args *args = aux;
427 
428 	if (name != NULL)
429 		printf("%s: ", name);
430 
431 	if (args->channel != -1)
432 		printf(" channel %d", args->channel);
433 
434 	return (UNCONF);
435 }
436 
437 static int
438 zshard(void *arg)
439 {
440 	struct zsc_softc *zsc = (struct zsc_softc *)arg;
441 	int rval = 0;
442 
443 	while (zsc_intr_hard(zsc))
444 		rval = 1;
445 	if ((zsc->zsc_cs[0] && zsc->zsc_cs[0]->cs_softreq) ||
446 	    (zsc->zsc_cs[1] && zsc->zsc_cs[1]->cs_softreq))
447 		softintr_schedule(zsc->zsc_softintr);
448 	return (rval);
449 }
450 
451 /*
452  * We need this only for TTY_DEBUG purposes.
453  */
454 static void
455 zssoft(void *arg)
456 {
457 	struct zsc_softc *zsc = (struct zsc_softc *)arg;
458 	int s;
459 
460 	/* Make sure we call the tty layer at spltty. */
461 	s = spltty();
462 	(void)zsc_intr_soft(zsc);
463 #ifdef TTY_DEBUG
464 	{
465 		struct zstty_softc *zst0 = zsc->zsc_cs[0]->cs_private;
466 		struct zstty_softc *zst1 = zsc->zsc_cs[1]->cs_private;
467 		if (zst0->zst_overflows || zst1->zst_overflows ) {
468 			struct trapframe *frame = (struct trapframe *)arg;
469 
470 			printf("zs silo overflow from %p\n",
471 			       (long)frame->tf_pc);
472 		}
473 	}
474 #endif
475 	splx(s);
476 }
477 
478 
479 /*
480  * Compute the current baud rate given a ZS channel.
481  */
482 static int
483 zs_get_speed(struct zs_chanstate *cs)
484 {
485 	int tconst;
486 
487 	tconst = zs_read_reg(cs, 12);
488 	tconst |= zs_read_reg(cs, 13) << 8;
489 	return (TCONST_TO_BPS(cs->cs_brg_clk, tconst));
490 }
491 
492 /*
493  * MD functions for setting the baud rate and control modes.
494  */
495 int
496 zs_set_speed(struct zs_chanstate *cs, int bps)
497 {
498 	int tconst, real_bps;
499 
500 	if (bps == 0)
501 		return (0);
502 
503 #ifdef	DIAGNOSTIC
504 	if (cs->cs_brg_clk == 0)
505 		panic("zs_set_speed");
506 #endif
507 
508 	tconst = BPS_TO_TCONST(cs->cs_brg_clk, bps);
509 	if (tconst < 0)
510 		return (EINVAL);
511 
512 	/* Convert back to make sure we can do it. */
513 	real_bps = TCONST_TO_BPS(cs->cs_brg_clk, tconst);
514 
515 	/* XXX - Allow some tolerance here? */
516 	if (real_bps != bps)
517 		return (EINVAL);
518 
519 	cs->cs_preg[12] = tconst;
520 	cs->cs_preg[13] = tconst >> 8;
521 
522 	/* Caller will stuff the pending registers. */
523 	return (0);
524 }
525 
526 int
527 zs_set_modes(struct zs_chanstate *cs, int cflag)
528 {
529 	int s;
530 
531 	/*
532 	 * Output hardware flow control on the chip is horrendous:
533 	 * if carrier detect drops, the receiver is disabled, and if
534 	 * CTS drops, the transmitter is stopped IN MID CHARACTER!
535 	 * Therefore, NEVER set the HFC bit, and instead use the
536 	 * status interrupt to detect CTS changes.
537 	 */
538 	s = splzs();
539 	cs->cs_rr0_pps = 0;
540 	if ((cflag & (CLOCAL | MDMBUF)) != 0) {
541 		cs->cs_rr0_dcd = 0;
542 		if ((cflag & MDMBUF) == 0)
543 			cs->cs_rr0_pps = ZSRR0_DCD;
544 	} else
545 		cs->cs_rr0_dcd = ZSRR0_DCD;
546 	if ((cflag & CRTSCTS) != 0) {
547 		cs->cs_wr5_dtr = ZSWR5_DTR;
548 		cs->cs_wr5_rts = ZSWR5_RTS;
549 		cs->cs_rr0_cts = ZSRR0_CTS;
550 #if 0 /* JLW */
551 	} else if ((cflag & CDTRCTS) != 0) {
552 		cs->cs_wr5_dtr = 0;
553 		cs->cs_wr5_rts = ZSWR5_DTR;
554 		cs->cs_rr0_cts = ZSRR0_CTS;
555 #endif
556 	} else if ((cflag & MDMBUF) != 0) {
557 		cs->cs_wr5_dtr = 0;
558 		cs->cs_wr5_rts = ZSWR5_DTR;
559 		cs->cs_rr0_cts = ZSRR0_DCD;
560 	} else {
561 		cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS;
562 		cs->cs_wr5_rts = 0;
563 		cs->cs_rr0_cts = 0;
564 	}
565 	splx(s);
566 
567 	/* Caller will stuff the pending registers. */
568 	return (0);
569 }
570 
571 
572 /*
573  * Read or write the chip with suitable delays.
574  */
575 
576 u_char
577 zs_read_reg(struct zs_chanstate *cs, u_char reg)
578 {
579 	u_char val;
580 
581 	*cs->cs_reg_csr = reg;
582 	ZS_DELAY();
583 	val = *cs->cs_reg_csr;
584 	ZS_DELAY();
585 	return (val);
586 }
587 
588 void
589 zs_write_reg(struct zs_chanstate *cs, u_char reg, u_char val)
590 {
591 	*cs->cs_reg_csr = reg;
592 	ZS_DELAY();
593 	*cs->cs_reg_csr = val;
594 	ZS_DELAY();
595 }
596 
597 u_char
598 zs_read_csr(struct zs_chanstate *cs)
599 {
600 	u_char val;
601 
602 	val = *cs->cs_reg_csr;
603 	ZS_DELAY();
604 	return (val);
605 }
606 
607 void
608 zs_write_csr(struct zs_chanstate *cs, u_char val)
609 {
610 	*cs->cs_reg_csr = val;
611 	ZS_DELAY();
612 }
613 
614 u_char
615 zs_read_data(struct zs_chanstate *cs)
616 {
617 	u_char val;
618 
619 	val = *cs->cs_reg_data;
620 	ZS_DELAY();
621 	return (val);
622 }
623 
624 void
625 zs_write_data(struct zs_chanstate *cs, u_char val)
626 {
627 	*cs->cs_reg_data = val;
628 	ZS_DELAY();
629 }
630 
631 /****************************************************************
632  * Console support functions (Sun specific!)
633  * Note: this code is allowed to know about the layout of
634  * the chip registers, and uses that to keep things simple.
635  * XXX - I think I like the mvme167 code better. -gwr
636  ****************************************************************/
637 
638 /*
639  * Handle user request to enter kernel debugger.
640  */
641 void
642 zs_abort(struct zs_chanstate *cs)
643 {
644 	volatile struct zschan *zc = zs_conschan_get;
645 	int rr0;
646 
647 	/* Wait for end of break to avoid PROM abort. */
648 	/* XXX - Limit the wait? */
649 	do {
650 		rr0 = zc->zc_csr;
651 		ZS_DELAY();
652 	} while (rr0 & ZSRR0_BREAK);
653 
654 #if defined(DDB)
655 	{
656 		extern int db_active;
657 
658 		if (!db_active)
659 			db_enter();
660 		else
661 			/* Debugger is probably hozed */
662 			callrom();
663 	}
664 #else
665 	printf("stopping on keyboard abort\n");
666 	callrom();
667 #endif
668 }
669 
670 
671 /*
672  * Polled input char.
673  */
674 int
675 zs_getc(void *arg)
676 {
677 	volatile struct zschan *zc = arg;
678 	int s, c, rr0;
679 
680 	s = splhigh();
681 	/* Wait for a character to arrive. */
682 	do {
683 		rr0 = zc->zc_csr;
684 		ZS_DELAY();
685 	} while ((rr0 & ZSRR0_RX_READY) == 0);
686 
687 	c = zc->zc_data;
688 	ZS_DELAY();
689 	splx(s);
690 
691 	return (c);
692 }
693 
694 /*
695  * Polled output char.
696  */
697 void
698 zs_putc(void *arg, int c)
699 {
700 	volatile struct zschan *zc = arg;
701 	int s, rr0;
702 
703 	s = splhigh();
704 
705 	/* Wait for transmitter to become ready. */
706 	do {
707 		rr0 = zc->zc_csr;
708 		ZS_DELAY();
709 	} while ((rr0 & ZSRR0_TX_READY) == 0);
710 
711 	/*
712 	 * Send the next character.
713 	 * Now you'd think that this could be followed by a ZS_DELAY()
714 	 * just like all the other chip accesses, but it turns out that
715 	 * the `transmit-ready' interrupt isn't de-asserted until
716 	 * some period of time after the register write completes
717 	 * (more than a couple instructions).  So to avoid stray
718 	 * interrupts we put in the 2us delay regardless of cpu model.
719 	 */
720 	zc->zc_data = c;
721 	delay(2);
722 
723 	splx(s);
724 }
725 
726 /*****************************************************************/
727 
728 
729 
730 
731 /*
732  * Polled console input putchar.
733  */
734 static int
735 zscngetc(dev_t dev)
736 {
737 	return (zs_getc(zs_conschan_get));
738 }
739 
740 /*
741  * Polled console output putchar.
742  */
743 static void
744 zscnputc(dev_t dev, int c)
745 {
746 	zs_putc(zs_conschan_put, c);
747 }
748 
749 int swallow_zsintrs;
750 
751 static void
752 zscnpollc(dev_t dev, int on)
753 {
754 	/*
755 	 * Need to tell zs driver to acknowledge all interrupts or we get
756 	 * annoying spurious interrupt messages.  This is because mucking
757 	 * with spl() levels during polling does not prevent interrupts from
758 	 * being generated.
759 	 */
760 
761 	if (on)
762 		swallow_zsintrs++;
763 	else
764 		swallow_zsintrs--;
765 }
766 
767 int
768 zs_console_flags(int promunit, int node, int channel)
769 {
770 	int cookie, flags = 0;
771 	u_int options;
772 	char buf[255];
773 
774 	/*
775 	 * We'll just to the OBP grovelling down here since that's
776 	 * the only type of firmware we support.
777 	 */
778 	options = OF_finddevice("/options");
779 
780 	/* Default to channel 0 if there are no explicit prom args */
781 	cookie = 0;
782 
783 	if (node == OF_instance_to_package(OF_stdin())) {
784 		if (OF_getprop(options, "input-device",
785 		    buf, sizeof(buf)) != -1) {
786 			if (strncmp("ttyb", buf, strlen("ttyb")) == 0)
787 				cookie = 1;
788 		}
789 
790 		if (channel == cookie)
791 			flags |= ZS_HWFLAG_CONSOLE_INPUT;
792 	}
793 
794 	if (node == OF_instance_to_package(OF_stdout())) {
795 		if (OF_getprop(options, "output-device",
796 		    buf, sizeof(buf)) != -1) {
797 			if (strncmp("ttyb", buf, strlen("ttyb")) == 0)
798 				cookie = 1;
799 		}
800 
801 		if (channel == cookie)
802 			flags |= ZS_HWFLAG_CONSOLE_OUTPUT;
803 	}
804 
805 	return (flags);
806 }
807