zs.c revision 1.85.4.1 1 /* $NetBSD: zs.c,v 1.85.4.1 2002/05/19 08:14:14 gehenna Exp $ */
2
3 /*-
4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Gordon W. Ross.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 /*
40 * Zilog Z8530 Dual UART driver (machine-dependent part)
41 *
42 * Runs two serial lines per chip using slave drivers.
43 * Plain tty/async lines use the zs_async slave.
44 * Sun keyboard/mouse uses the zs_kbd/zs_ms slaves.
45 */
46
47 #include "opt_ddb.h"
48 #include "opt_kgdb.h"
49
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/conf.h>
53 #include <sys/device.h>
54 #include <sys/file.h>
55 #include <sys/ioctl.h>
56 #include <sys/kernel.h>
57 #include <sys/proc.h>
58 #include <sys/tty.h>
59 #include <sys/time.h>
60 #include <sys/syslog.h>
61
62 #include <machine/bsd_openprom.h>
63 #include <machine/autoconf.h>
64 #include <machine/intr.h>
65 #include <machine/eeprom.h>
66 #include <machine/psl.h>
67 #include <machine/z8530var.h>
68
69 #include <dev/cons.h>
70 #include <dev/ic/z8530reg.h>
71
72 #include <sparc/sparc/vaddrs.h>
73 #include <sparc/sparc/auxreg.h>
74 #include <sparc/sparc/auxiotwo.h>
75 #include <sparc/dev/cons.h>
76
77 #include "kbd.h" /* NKBD */
78 #include "zs.h" /* NZS */
79
80 /* Make life easier for the initialized arrays here. */
81 #if NZS < 3
82 #undef NZS
83 #define NZS 3
84 #endif
85
86 /*
87 * Some warts needed by z8530tty.c -
88 * The default parity REALLY needs to be the same as the PROM uses,
89 * or you can not see messages done with printf during boot-up...
90 */
91 int zs_def_cflag = (CREAD | CS8 | HUPCL);
92
93 /*
94 * The Sun provides a 4.9152 MHz clock to the ZS chips.
95 */
96 #define PCLK (9600 * 512) /* PCLK pin input clock rate */
97
98 /*
99 * Select software interrupt bit based on TTY ipl.
100 */
101 #if PIL_TTY == 1
102 # define IE_ZSSOFT IE_L1
103 #elif PIL_TTY == 4
104 # define IE_ZSSOFT IE_L4
105 #elif PIL_TTY == 6
106 # define IE_ZSSOFT IE_L6
107 #else
108 # error "no suitable software interrupt bit"
109 #endif
110
111 #define ZS_DELAY() (CPU_ISSUN4C ? (0) : delay(2))
112
113 /* The layout of this is hardware-dependent (padding, order). */
114 struct zschan {
115 volatile u_char zc_csr; /* ctrl,status, and indirect access */
116 u_char zc_xxx0;
117 volatile u_char zc_data; /* data */
118 u_char zc_xxx1;
119 };
120 struct zsdevice {
121 /* Yes, they are backwards. */
122 struct zschan zs_chan_b;
123 struct zschan zs_chan_a;
124 };
125
126 /* ZS channel used as the console device (if any) */
127 void *zs_conschan_get, *zs_conschan_put;
128
129 static u_char zs_init_reg[16] = {
130 0, /* 0: CMD (reset, etc.) */
131 0, /* 1: No interrupts yet. */
132 0, /* 2: IVECT */
133 ZSWR3_RX_8 | ZSWR3_RX_ENABLE,
134 ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP,
135 ZSWR5_TX_8 | ZSWR5_TX_ENABLE,
136 0, /* 6: TXSYNC/SYNCLO */
137 0, /* 7: RXSYNC/SYNCHI */
138 0, /* 8: alias for data port */
139 ZSWR9_MASTER_IE | ZSWR9_NO_VECTOR,
140 0, /*10: Misc. TX/RX control bits */
141 ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD,
142 ((PCLK/32)/9600)-2, /*12: BAUDLO (default=9600) */
143 0, /*13: BAUDHI (default=9600) */
144 ZSWR14_BAUD_ENA | ZSWR14_BAUD_FROM_PCLK,
145 ZSWR15_BREAK_IE,
146 };
147
148 /* Console ops */
149 static int zscngetc __P((dev_t));
150 static void zscnputc __P((dev_t, int));
151 static void zscnpollc __P((dev_t, int));
152
153 struct consdev zs_consdev = {
154 NULL,
155 NULL,
156 zscngetc,
157 zscnputc,
158 zscnpollc,
159 NULL,
160 };
161
162
163 /****************************************************************
164 * Autoconfig
165 ****************************************************************/
166
167 /* Definition of the driver for autoconfig. */
168 static int zs_match_mainbus __P((struct device *, struct cfdata *, void *));
169 static int zs_match_obio __P((struct device *, struct cfdata *, void *));
170 static void zs_attach_mainbus __P((struct device *, struct device *, void *));
171 static void zs_attach_obio __P((struct device *, struct device *, void *));
172
173
174 static void zs_attach __P((struct zsc_softc *, struct zsdevice *, int));
175 static int zs_print __P((void *, const char *name));
176
177 struct cfattach zs_mainbus_ca = {
178 sizeof(struct zsc_softc), zs_match_mainbus, zs_attach_mainbus
179 };
180
181 struct cfattach zs_obio_ca = {
182 sizeof(struct zsc_softc), zs_match_obio, zs_attach_obio
183 };
184
185 extern struct cfdriver zs_cd;
186
187 /* Interrupt handlers. */
188 static int zshard __P((void *));
189 static int zssoft __P((void *));
190
191 static int zs_get_speed __P((struct zs_chanstate *));
192
193 /* Console device support */
194 static int zs_console_flags __P((int, int, int));
195
196 /* Power management hooks */
197 int zs_enable __P((struct zs_chanstate *));
198 void zs_disable __P((struct zs_chanstate *));
199
200
201 /*
202 * Is the zs chip present?
203 */
204 static int
205 zs_match_mainbus(parent, cf, aux)
206 struct device *parent;
207 struct cfdata *cf;
208 void *aux;
209 {
210 struct mainbus_attach_args *ma = aux;
211
212 if (strcmp(cf->cf_driver->cd_name, ma->ma_name) != 0)
213 return (0);
214
215 return (1);
216 }
217
218 static int
219 zs_match_obio(parent, cf, aux)
220 struct device *parent;
221 struct cfdata *cf;
222 void *aux;
223 {
224 union obio_attach_args *uoba = aux;
225 struct obio4_attach_args *oba;
226
227 if (uoba->uoba_isobio4 == 0) {
228 struct sbus_attach_args *sa = &uoba->uoba_sbus;
229
230 if (strcmp(cf->cf_driver->cd_name, sa->sa_name) != 0)
231 return (0);
232
233 return (1);
234 }
235
236 oba = &uoba->uoba_oba4;
237 return (bus_space_probe(oba->oba_bustag, oba->oba_paddr,
238 1, 0, 0, NULL, NULL));
239 }
240
241 static void
242 zs_attach_mainbus(parent, self, aux)
243 struct device *parent;
244 struct device *self;
245 void *aux;
246 {
247 struct zsc_softc *zsc = (void *) self;
248 struct mainbus_attach_args *ma = aux;
249
250 zsc->zsc_bustag = ma->ma_bustag;
251 zsc->zsc_dmatag = ma->ma_dmatag;
252 zsc->zsc_promunit = PROM_getpropint(ma->ma_node, "slave", -2);
253 zsc->zsc_node = ma->ma_node;
254
255 /*
256 * For machines with zs on mainbus (all sun4c models), we expect
257 * the device registers to be mapped by the PROM.
258 */
259 zs_attach(zsc, ma->ma_promvaddr, ma->ma_pri);
260 }
261
262 static void
263 zs_attach_obio(parent, self, aux)
264 struct device *parent;
265 struct device *self;
266 void *aux;
267 {
268 struct zsc_softc *zsc = (void *) self;
269 union obio_attach_args *uoba = aux;
270
271 if (uoba->uoba_isobio4 == 0) {
272 struct sbus_attach_args *sa = &uoba->uoba_sbus;
273 void *va;
274 struct zs_chanstate *cs;
275 int channel;
276
277 if (sa->sa_nintr == 0) {
278 printf(" no interrupt lines\n");
279 return;
280 }
281
282 /*
283 * Some sun4m models (Javastations) may not map the zs device.
284 */
285 if (sa->sa_npromvaddrs > 0)
286 va = (void *)sa->sa_promvaddr;
287 else {
288 bus_space_handle_t bh;
289
290 if (sbus_bus_map(sa->sa_bustag,
291 sa->sa_slot,
292 sa->sa_offset,
293 sa->sa_size,
294 BUS_SPACE_MAP_LINEAR, &bh) != 0) {
295 printf(" cannot map zs registers\n");
296 return;
297 }
298 va = (void *)bh;
299 }
300
301 /*
302 * Check if power state can be set, e.g. Tadpole 3GX
303 */
304 if (PROM_getpropint(sa->sa_node, "pwr-on-auxio2", 0))
305 {
306 printf (" powered via auxio2");
307 for (channel = 0; channel < 2; channel++) {
308 cs = &zsc->zsc_cs_store[channel];
309 cs->enable = zs_enable;
310 cs->disable = zs_disable;
311 }
312 }
313
314 zsc->zsc_bustag = sa->sa_bustag;
315 zsc->zsc_dmatag = sa->sa_dmatag;
316 zsc->zsc_promunit = PROM_getpropint(sa->sa_node, "slave", -2);
317 zsc->zsc_node = sa->sa_node;
318 zs_attach(zsc, va, sa->sa_pri);
319 } else {
320 struct obio4_attach_args *oba = &uoba->uoba_oba4;
321 bus_space_handle_t bh;
322 bus_addr_t paddr = oba->oba_paddr;
323
324 /*
325 * As for zs on mainbus, we require a PROM mapping.
326 */
327 if (bus_space_map(oba->oba_bustag,
328 paddr,
329 sizeof(struct zsdevice),
330 BUS_SPACE_MAP_LINEAR | OBIO_BUS_MAP_USE_ROM,
331 &bh) != 0) {
332 printf(" cannot map zs registers\n");
333 return;
334 }
335 zsc->zsc_bustag = oba->oba_bustag;
336 zsc->zsc_dmatag = oba->oba_dmatag;
337 /* Find prom unit by physical address */
338 if (cpuinfo.cpu_type == CPUTYP_4_100)
339 /*
340 * On the sun4/100, the top-most 4 bits are zero
341 * on obio addresses; force them to 1's for the
342 * sake of the comparison here.
343 */
344 paddr |= 0xf0000000;
345 zsc->zsc_promunit =
346 (paddr == 0xf1000000) ? 0 :
347 (paddr == 0xf0000000) ? 1 :
348 (paddr == 0xe0000000) ? 2 : -2;
349
350 zs_attach(zsc, (void *)bh, oba->oba_pri);
351 }
352 }
353 /*
354 * Attach a found zs.
355 *
356 * USE ROM PROPERTIES port-a-ignore-cd AND port-b-ignore-cd FOR
357 * SOFT CARRIER, AND keyboard PROPERTY FOR KEYBOARD/MOUSE?
358 */
359 static void
360 zs_attach(zsc, zsd, pri)
361 struct zsc_softc *zsc;
362 struct zsdevice *zsd;
363 int pri;
364 {
365 struct zsc_attach_args zsc_args;
366 struct zs_chanstate *cs;
367 int s, channel;
368 static int didintr, prevpri;
369
370 if (zsd == NULL) {
371 printf("configuration incomplete\n");
372 return;
373 }
374
375 printf(" softpri %d\n", PIL_TTY);
376
377 /*
378 * Initialize software state for each channel.
379 */
380 for (channel = 0; channel < 2; channel++) {
381 struct zschan *zc;
382
383 zsc_args.channel = channel;
384 cs = &zsc->zsc_cs_store[channel];
385 zsc->zsc_cs[channel] = cs;
386
387 cs->cs_channel = channel;
388 cs->cs_private = NULL;
389 cs->cs_ops = &zsops_null;
390 cs->cs_brg_clk = PCLK / 16;
391
392 zc = (channel == 0) ? &zsd->zs_chan_a : &zsd->zs_chan_b;
393
394 zsc_args.hwflags = zs_console_flags(zsc->zsc_promunit,
395 zsc->zsc_node,
396 channel);
397
398 if (zsc_args.hwflags & ZS_HWFLAG_CONSOLE) {
399 zsc_args.hwflags |= ZS_HWFLAG_USE_CONSDEV;
400 zsc_args.consdev = &zs_consdev;
401 }
402
403 if ((zsc_args.hwflags & ZS_HWFLAG_CONSOLE_INPUT) != 0) {
404 zs_conschan_get = zc;
405 }
406 if ((zsc_args.hwflags & ZS_HWFLAG_CONSOLE_OUTPUT) != 0) {
407 zs_conschan_put = zc;
408 }
409 /* Childs need to set cn_dev, etc */
410
411 cs->cs_reg_csr = &zc->zc_csr;
412 cs->cs_reg_data = &zc->zc_data;
413
414 bcopy(zs_init_reg, cs->cs_creg, 16);
415 bcopy(zs_init_reg, cs->cs_preg, 16);
416
417 /* XXX: Consult PROM properties for this?! */
418 cs->cs_defspeed = zs_get_speed(cs);
419 cs->cs_defcflag = zs_def_cflag;
420
421 /* Make these correspond to cs_defcflag (-crtscts) */
422 cs->cs_rr0_dcd = ZSRR0_DCD;
423 cs->cs_rr0_cts = 0;
424 cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS;
425 cs->cs_wr5_rts = 0;
426
427 /*
428 * Clear the master interrupt enable.
429 * The INTENA is common to both channels,
430 * so just do it on the A channel.
431 */
432 if (channel == 0) {
433 zs_write_reg(cs, 9, 0);
434 }
435
436 /*
437 * Look for a child driver for this channel.
438 * The child attach will setup the hardware.
439 */
440 if (!config_found(&zsc->zsc_dev, (void *)&zsc_args, zs_print)) {
441 /* No sub-driver. Just reset it. */
442 u_char reset = (channel == 0) ?
443 ZSWR9_A_RESET : ZSWR9_B_RESET;
444 s = splzs();
445 zs_write_reg(cs, 9, reset);
446 splx(s);
447 }
448 }
449
450 /*
451 * Now safe to install interrupt handlers. Note the arguments
452 * to the interrupt handlers aren't used. Note, we only do this
453 * once since both SCCs interrupt at the same level and vector.
454 */
455 if (!didintr) {
456 didintr = 1;
457 prevpri = pri;
458 bus_intr_establish(zsc->zsc_bustag, pri, IPL_SERIAL, 0,
459 zshard, NULL);
460 bus_intr_establish(zsc->zsc_bustag, PIL_TTY,
461 IPL_SOFTSERIAL,
462 BUS_INTR_ESTABLISH_SOFTINTR,
463 zssoft, NULL);
464 } else if (pri != prevpri)
465 panic("broken zs interrupt scheme");
466
467 evcnt_attach_dynamic(&zsc->zsc_intrcnt, EVCNT_TYPE_INTR, NULL,
468 zsc->zsc_dev.dv_xname, "intr");
469
470 /*
471 * Set the master interrupt enable and interrupt vector.
472 * (common to both channels, do it on A)
473 */
474 cs = zsc->zsc_cs[0];
475 s = splhigh();
476 /* interrupt vector */
477 zs_write_reg(cs, 2, zs_init_reg[2]);
478 /* master interrupt control (enable) */
479 zs_write_reg(cs, 9, zs_init_reg[9]);
480 splx(s);
481
482 #if 0
483 /*
484 * XXX: L1A hack - We would like to be able to break into
485 * the debugger during the rest of autoconfiguration, so
486 * lower interrupts just enough to let zs interrupts in.
487 * This is done after both zs devices are attached.
488 */
489 if (zsc->zsc_promunit == 1) {
490 printf("zs1: enabling zs interrupts\n");
491 (void)splfd(); /* XXX: splzs - 1 */
492 }
493 #endif
494 }
495
496 static int
497 zs_print(aux, name)
498 void *aux;
499 const char *name;
500 {
501 struct zsc_attach_args *args = aux;
502
503 if (name != NULL)
504 printf("%s: ", name);
505
506 if (args->channel != -1)
507 printf(" channel %d", args->channel);
508
509 return (UNCONF);
510 }
511
512 static volatile int zssoftpending;
513
514 /*
515 * Our ZS chips all share a common, autovectored interrupt,
516 * so we have to look at all of them on each interrupt.
517 */
518 static int
519 zshard(arg)
520 void *arg;
521 {
522 struct zsc_softc *zsc;
523 int unit, rr3, rval, softreq;
524
525 rval = softreq = 0;
526 for (unit = 0; unit < zs_cd.cd_ndevs; unit++) {
527 struct zs_chanstate *cs;
528
529 zsc = zs_cd.cd_devs[unit];
530 if (zsc == NULL)
531 continue;
532 rr3 = zsc_intr_hard(zsc);
533 /* Count up the interrupts. */
534 if (rr3) {
535 rval |= rr3;
536 zsc->zsc_intrcnt.ev_count++;
537 }
538 if ((cs = zsc->zsc_cs[0]) != NULL)
539 softreq |= cs->cs_softreq;
540 if ((cs = zsc->zsc_cs[1]) != NULL)
541 softreq |= cs->cs_softreq;
542 }
543
544 /* We are at splzs here, so no need to lock. */
545 if (softreq && (zssoftpending == 0)) {
546 zssoftpending = IE_ZSSOFT;
547 #if defined(SUN4M)
548 if (CPU_ISSUN4M)
549 raise(0, PIL_TTY);
550 else
551 #endif
552 ienab_bis(IE_ZSSOFT);
553 }
554 return (rval);
555 }
556
557 /*
558 * Similar scheme as for zshard (look at all of them)
559 */
560 static int
561 zssoft(arg)
562 void *arg;
563 {
564 struct zsc_softc *zsc;
565 int s, unit;
566
567 /* This is not the only ISR on this IPL. */
568 if (zssoftpending == 0)
569 return (0);
570
571 /*
572 * The soft intr. bit will be set by zshard only if
573 * the variable zssoftpending is zero. The order of
574 * these next two statements prevents our clearing
575 * the soft intr bit just after zshard has set it.
576 */
577 /* ienab_bic(IE_ZSSOFT); */
578 zssoftpending = 0;
579
580 /* Make sure we call the tty layer at spltty. */
581 s = spltty();
582 for (unit = 0; unit < zs_cd.cd_ndevs; unit++) {
583 zsc = zs_cd.cd_devs[unit];
584 if (zsc == NULL)
585 continue;
586 (void)zsc_intr_soft(zsc);
587 }
588 splx(s);
589 return (1);
590 }
591
592
593 /*
594 * Compute the current baud rate given a ZS channel.
595 */
596 static int
597 zs_get_speed(cs)
598 struct zs_chanstate *cs;
599 {
600 int tconst;
601
602 tconst = zs_read_reg(cs, 12);
603 tconst |= zs_read_reg(cs, 13) << 8;
604 return (TCONST_TO_BPS(cs->cs_brg_clk, tconst));
605 }
606
607 /*
608 * MD functions for setting the baud rate and control modes.
609 */
610 int
611 zs_set_speed(cs, bps)
612 struct zs_chanstate *cs;
613 int bps; /* bits per second */
614 {
615 int tconst, real_bps;
616
617 if (bps == 0)
618 return (0);
619
620 #ifdef DIAGNOSTIC
621 if (cs->cs_brg_clk == 0)
622 panic("zs_set_speed");
623 #endif
624
625 tconst = BPS_TO_TCONST(cs->cs_brg_clk, bps);
626 if (tconst < 0)
627 return (EINVAL);
628
629 /* Convert back to make sure we can do it. */
630 real_bps = TCONST_TO_BPS(cs->cs_brg_clk, tconst);
631
632 /* XXX - Allow some tolerance here? */
633 if (real_bps != bps)
634 return (EINVAL);
635
636 cs->cs_preg[12] = tconst;
637 cs->cs_preg[13] = tconst >> 8;
638
639 /* Caller will stuff the pending registers. */
640 return (0);
641 }
642
643 int
644 zs_set_modes(cs, cflag)
645 struct zs_chanstate *cs;
646 int cflag; /* bits per second */
647 {
648 int s;
649
650 /*
651 * Output hardware flow control on the chip is horrendous:
652 * if carrier detect drops, the receiver is disabled, and if
653 * CTS drops, the transmitter is stoped IN MID CHARACTER!
654 * Therefore, NEVER set the HFC bit, and instead use the
655 * status interrupt to detect CTS changes.
656 */
657 s = splzs();
658 cs->cs_rr0_pps = 0;
659 if ((cflag & (CLOCAL | MDMBUF)) != 0) {
660 cs->cs_rr0_dcd = 0;
661 if ((cflag & MDMBUF) == 0)
662 cs->cs_rr0_pps = ZSRR0_DCD;
663 } else
664 cs->cs_rr0_dcd = ZSRR0_DCD;
665 if ((cflag & CRTSCTS) != 0) {
666 cs->cs_wr5_dtr = ZSWR5_DTR;
667 cs->cs_wr5_rts = ZSWR5_RTS;
668 cs->cs_rr0_cts = ZSRR0_CTS;
669 } else if ((cflag & CDTRCTS) != 0) {
670 cs->cs_wr5_dtr = 0;
671 cs->cs_wr5_rts = ZSWR5_DTR;
672 cs->cs_rr0_cts = ZSRR0_CTS;
673 } else if ((cflag & MDMBUF) != 0) {
674 cs->cs_wr5_dtr = 0;
675 cs->cs_wr5_rts = ZSWR5_DTR;
676 cs->cs_rr0_cts = ZSRR0_DCD;
677 } else {
678 cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS;
679 cs->cs_wr5_rts = 0;
680 cs->cs_rr0_cts = 0;
681 }
682 splx(s);
683
684 /* Caller will stuff the pending registers. */
685 return (0);
686 }
687
688
689 /*
690 * Read or write the chip with suitable delays.
691 */
692
693 u_char
694 zs_read_reg(cs, reg)
695 struct zs_chanstate *cs;
696 u_char reg;
697 {
698 u_char val;
699
700 *cs->cs_reg_csr = reg;
701 ZS_DELAY();
702 val = *cs->cs_reg_csr;
703 ZS_DELAY();
704 return (val);
705 }
706
707 void
708 zs_write_reg(cs, reg, val)
709 struct zs_chanstate *cs;
710 u_char reg, val;
711 {
712 *cs->cs_reg_csr = reg;
713 ZS_DELAY();
714 *cs->cs_reg_csr = val;
715 ZS_DELAY();
716 }
717
718 u_char
719 zs_read_csr(cs)
720 struct zs_chanstate *cs;
721 {
722 u_char val;
723
724 val = *cs->cs_reg_csr;
725 ZS_DELAY();
726 return (val);
727 }
728
729 void
730 zs_write_csr(cs, val)
731 struct zs_chanstate *cs;
732 u_char val;
733 {
734 *cs->cs_reg_csr = val;
735 ZS_DELAY();
736 }
737
738 u_char
739 zs_read_data(cs)
740 struct zs_chanstate *cs;
741 {
742 u_char val;
743
744 val = *cs->cs_reg_data;
745 ZS_DELAY();
746 return (val);
747 }
748
749 void zs_write_data(cs, val)
750 struct zs_chanstate *cs;
751 u_char val;
752 {
753 *cs->cs_reg_data = val;
754 ZS_DELAY();
755 }
756
757 /****************************************************************
758 * Console support functions (Sun specific!)
759 * Note: this code is allowed to know about the layout of
760 * the chip registers, and uses that to keep things simple.
761 * XXX - I think I like the mvme167 code better. -gwr
762 ****************************************************************/
763
764 /*
765 * Handle user request to enter kernel debugger.
766 */
767 void
768 zs_abort(cs)
769 struct zs_chanstate *cs;
770 {
771 struct zschan *zc = zs_conschan_get;
772 int rr0;
773
774 /* Wait for end of break to avoid PROM abort. */
775 /* XXX - Limit the wait? */
776 do {
777 rr0 = zc->zc_csr;
778 ZS_DELAY();
779 } while (rr0 & ZSRR0_BREAK);
780
781 #if defined(KGDB)
782 zskgdb(cs);
783 #elif defined(DDB)
784 Debugger();
785 #else
786 printf("stopping on keyboard abort\n");
787 callrom();
788 #endif
789 }
790
791 int zs_getc __P((void *arg));
792 void zs_putc __P((void *arg, int c));
793
794 /*
795 * Polled input char.
796 */
797 int
798 zs_getc(arg)
799 void *arg;
800 {
801 struct zschan *zc = arg;
802 int s, c, rr0;
803
804 s = splhigh();
805 /* Wait for a character to arrive. */
806 do {
807 rr0 = zc->zc_csr;
808 ZS_DELAY();
809 } while ((rr0 & ZSRR0_RX_READY) == 0);
810
811 c = zc->zc_data;
812 ZS_DELAY();
813 splx(s);
814
815 /*
816 * This is used by the kd driver to read scan codes,
817 * so don't translate '\r' ==> '\n' here...
818 */
819 return (c);
820 }
821
822 /*
823 * Polled output char.
824 */
825 void
826 zs_putc(arg, c)
827 void *arg;
828 int c;
829 {
830 struct zschan *zc = arg;
831 int s, rr0;
832
833 s = splhigh();
834
835 /* Wait for transmitter to become ready. */
836 do {
837 rr0 = zc->zc_csr;
838 ZS_DELAY();
839 } while ((rr0 & ZSRR0_TX_READY) == 0);
840
841 /*
842 * Send the next character.
843 * Now you'd think that this could be followed by a ZS_DELAY()
844 * just like all the other chip accesses, but it turns out that
845 * the `transmit-ready' interrupt isn't de-asserted until
846 * some period of time after the register write completes
847 * (more than a couple instructions). So to avoid stray
848 * interrupts we put in the 2us delay regardless of cpu model.
849 */
850 zc->zc_data = c;
851 delay(2);
852
853 splx(s);
854 }
855
856 /*****************************************************************/
857 /*
858 * Polled console input putchar.
859 */
860 int
861 zscngetc(dev)
862 dev_t dev;
863 {
864 return (zs_getc(zs_conschan_get));
865 }
866
867 /*
868 * Polled console output putchar.
869 */
870 void
871 zscnputc(dev, c)
872 dev_t dev;
873 int c;
874 {
875 zs_putc(zs_conschan_put, c);
876 }
877
878 void
879 zscnpollc(dev, on)
880 dev_t dev;
881 int on;
882 {
883 /* No action needed */
884 }
885
886 int
887 zs_console_flags(promunit, node, channel)
888 int promunit;
889 int node;
890 int channel;
891 {
892 int cookie, flags = 0;
893
894 switch (prom_version()) {
895 case PROM_OLDMON:
896 case PROM_OBP_V0:
897 /*
898 * Use `promunit' and `channel' to derive the PROM
899 * stdio handles that correspond to this device.
900 */
901 if (promunit == 0)
902 cookie = PROMDEV_TTYA + channel;
903 else if (promunit == 1 && channel == 0)
904 cookie = PROMDEV_KBD;
905 else
906 cookie = -1;
907
908 if (cookie == prom_stdin())
909 flags |= ZS_HWFLAG_CONSOLE_INPUT;
910
911 /*
912 * Prevent the keyboard from matching the output device
913 * (note that PROMDEV_KBD == PROMDEV_SCREEN == 0!).
914 */
915 if (cookie != PROMDEV_KBD && cookie == prom_stdout())
916 flags |= ZS_HWFLAG_CONSOLE_OUTPUT;
917
918 break;
919
920 case PROM_OBP_V2:
921 case PROM_OBP_V3:
922 case PROM_OPENFIRM:
923
924 /*
925 * Match the nodes and device arguments prepared by
926 * consinit() against our device node and channel.
927 * (The device argument is the part of the OBP path
928 * following the colon, as in `/obio/zs@0,100000:a')
929 */
930
931 /* Default to channel 0 if there are no explicit prom args */
932 cookie = 0;
933
934 if (node == prom_stdin_node) {
935 if (prom_stdin_args[0] != '\0')
936 /* Translate (a,b) -> (0,1) */
937 cookie = prom_stdin_args[0] - 'a';
938
939 if (channel == cookie)
940 flags |= ZS_HWFLAG_CONSOLE_INPUT;
941 }
942
943 if (node == prom_stdout_node) {
944 if (prom_stdout_args[0] != '\0')
945 /* Translate (a,b) -> (0,1) */
946 cookie = prom_stdout_args[0] - 'a';
947
948 if (channel == cookie)
949 flags |= ZS_HWFLAG_CONSOLE_OUTPUT;
950 }
951
952 break;
953
954 default:
955 break;
956 }
957
958 return (flags);
959 }
960
961 /*
962 * Power management hooks for zsopen() and zsclose().
963 * We use them to power on/off the ports, if necessary.
964 */
965 int
966 zs_enable(cs)
967 struct zs_chanstate *cs;
968 {
969 auxiotwoserialendis (ZS_ENABLE);
970 cs->enabled = 1;
971 return(0);
972 }
973
974 void
975 zs_disable(cs)
976 struct zs_chanstate *cs;
977 {
978 auxiotwoserialendis (ZS_DISABLE);
979 cs->enabled = 0;
980 }
981