1 /* $NetBSD: zs.c,v 1.115 2009/05/22 03:51:30 mrg Exp $ */
4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Zilog Z8530 Dual UART driver (machine-dependent part)
35 * Runs two serial lines per chip using slave drivers.
36 * Plain tty/async lines use the zs_async slave.
37 * Sun keyboard/mouse uses the zs_kbd/zs_ms slaves.
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.115 2009/05/22 03:51:30 mrg Exp $");
45 #include "opt_sparc_arch.h"
47 #include <sys/param.h>
48 #include <sys/systm.h>
50 #include <sys/device.h>
52 #include <sys/ioctl.h>
53 #include <sys/kernel.h>
57 #include <sys/syslog.h>
60 #include <machine/bsd_openprom.h>
61 #include <machine/autoconf.h>
62 #include <machine/eeprom.h>
63 #include <machine/psl.h>
64 #include <machine/z8530var.h>
67 #include <dev/ic/z8530reg.h>
69 #include <sparc/sparc/vaddrs.h>
70 #include <sparc/sparc/auxreg.h>
71 #include <sparc/sparc/auxiotwo.h>
72 #include <sparc/dev/cons.h>
73 #include <dev/sun/kbd_ms_ttyvar.h>
80 * Some warts needed by z8530tty.c -
81 * The default parity REALLY needs to be the same as the PROM uses,
82 * or you can not see messages done with printf during boot-up...
84 int zs_def_cflag
= (CREAD
| CS8
| HUPCL
);
87 * The Sun provides a 4.9152 MHz clock to the ZS chips.
89 #define PCLK (9600 * 512) /* PCLK pin input clock rate */
91 #define ZS_DELAY() (CPU_ISSUN4C ? (0) : delay(2))
93 /* The layout of this is hardware-dependent (padding, order). */
95 volatile uint8_t zc_csr
; /* ctrl,status, and indirect access */
97 volatile uint8_t zc_data
; /* data */
101 /* Yes, they are backwards. */
102 struct zschan zs_chan_b
;
103 struct zschan zs_chan_a
;
106 /* ZS channel used as the console device (if any) */
107 void *zs_conschan_get
, *zs_conschan_put
;
109 static uint8_t zs_init_reg
[16] = {
110 0, /* 0: CMD (reset, etc.) */
111 0, /* 1: No interrupts yet. */
113 ZSWR3_RX_8
| ZSWR3_RX_ENABLE
,
114 ZSWR4_CLK_X16
| ZSWR4_ONESB
| ZSWR4_EVENP
,
115 ZSWR5_TX_8
| ZSWR5_TX_ENABLE
,
116 0, /* 6: TXSYNC/SYNCLO */
117 0, /* 7: RXSYNC/SYNCHI */
118 0, /* 8: alias for data port */
119 ZSWR9_MASTER_IE
| ZSWR9_NO_VECTOR
,
120 0, /*10: Misc. TX/RX control bits */
121 ZSWR11_TXCLK_BAUD
| ZSWR11_RXCLK_BAUD
,
122 ((PCLK
/32)/9600)-2, /*12: BAUDLO (default=9600) */
123 0, /*13: BAUDHI (default=9600) */
124 ZSWR14_BAUD_ENA
| ZSWR14_BAUD_FROM_PCLK
,
129 static int zscngetc(dev_t
);
130 static void zscnputc(dev_t
, int);
131 static void zscnpollc(dev_t
, int);
133 struct consdev zs_consdev
= {
143 /****************************************************************
145 ****************************************************************/
147 /* Definition of the driver for autoconfig. */
148 static int zs_match_mainbus(device_t
, cfdata_t
, void *);
149 static int zs_match_obio(device_t
, cfdata_t
, void *);
150 static void zs_attach_mainbus(device_t
, device_t
, void *);
151 static void zs_attach_obio(device_t
, device_t
, void *);
154 #include <sparc/dev/bootbusvar.h>
156 static int zs_match_bootbus(device_t
, cfdata_t
, void *);
157 static void zs_attach_bootbus(device_t
, device_t
, void *);
159 CFATTACH_DECL_NEW(zs_bootbus
, sizeof(struct zsc_softc
),
160 zs_match_bootbus
, zs_attach_bootbus
, NULL
, NULL
);
163 static void zs_attach(struct zsc_softc
*, struct zsdevice
*, int);
164 static int zs_print(void *, const char *name
);
166 CFATTACH_DECL_NEW(zs_mainbus
, sizeof(struct zsc_softc
),
167 zs_match_mainbus
, zs_attach_mainbus
, NULL
, NULL
);
169 CFATTACH_DECL_NEW(zs_obio
, sizeof(struct zsc_softc
),
170 zs_match_obio
, zs_attach_obio
, NULL
, NULL
);
172 extern struct cfdriver zs_cd
;
174 /* softintr(9) cookie, shared by all instances of this driver */
175 static void *zs_sicookie
;
177 /* Interrupt handlers. */
178 static int zshard(void *);
179 static void zssoft(void *);
181 static int zs_get_speed(struct zs_chanstate
*);
183 /* Console device support */
184 static int zs_console_flags(int, int, int);
186 /* Power management hooks */
187 int zs_enable(struct zs_chanstate
*);
188 void zs_disable(struct zs_chanstate
*);
191 /* XXX from dev/ic/z8530tty.c */
192 extern struct tty
*zstty_get_tty_from_dev(struct device
*);
195 * Is the zs chip present?
198 zs_match_mainbus(device_t parent
, cfdata_t cf
, void *aux
)
200 struct mainbus_attach_args
*ma
= aux
;
202 if (strcmp(cf
->cf_name
, ma
->ma_name
) != 0)
209 zs_match_obio(device_t parent
, cfdata_t cf
, void *aux
)
211 union obio_attach_args
*uoba
= aux
;
212 struct obio4_attach_args
*oba
;
214 if (uoba
->uoba_isobio4
== 0) {
215 struct sbus_attach_args
*sa
= &uoba
->uoba_sbus
;
217 if (strcmp(cf
->cf_name
, sa
->sa_name
) != 0)
223 oba
= &uoba
->uoba_oba4
;
224 return (bus_space_probe(oba
->oba_bustag
, oba
->oba_paddr
,
225 1, 0, 0, NULL
, NULL
));
230 zs_match_bootbus(device_t parent
, cfdata_t cf
, void *aux
)
232 struct bootbus_attach_args
*baa
= aux
;
234 return (strcmp(cf
->cf_name
, baa
->ba_name
) == 0);
239 zs_attach_mainbus(device_t parent
, device_t self
, void *aux
)
241 struct zsc_softc
*zsc
= device_private(self
);
242 struct mainbus_attach_args
*ma
= aux
;
245 zsc
->zsc_bustag
= ma
->ma_bustag
;
246 zsc
->zsc_dmatag
= ma
->ma_dmatag
;
247 zsc
->zsc_promunit
= prom_getpropint(ma
->ma_node
, "slave", -2);
248 zsc
->zsc_node
= ma
->ma_node
;
251 * For machines with zs on mainbus (all sun4c models), we expect
252 * the device registers to be mapped by the PROM.
254 zs_attach(zsc
, ma
->ma_promvaddr
, ma
->ma_pri
);
258 zs_attach_obio(device_t parent
, device_t self
, void *aux
)
260 struct zsc_softc
*zsc
= device_private(self
);
261 union obio_attach_args
*uoba
= aux
;
265 if (uoba
->uoba_isobio4
== 0) {
266 struct sbus_attach_args
*sa
= &uoba
->uoba_sbus
;
268 struct zs_chanstate
*cs
;
271 if (sa
->sa_nintr
== 0) {
272 aprint_error(": no interrupt lines\n");
277 * Some sun4m models (Javastations) may not map the zs device.
279 if (sa
->sa_npromvaddrs
> 0)
280 va
= (void *)sa
->sa_promvaddr
;
282 bus_space_handle_t bh
;
284 if (sbus_bus_map(sa
->sa_bustag
,
288 BUS_SPACE_MAP_LINEAR
, &bh
) != 0) {
289 aprint_error(": cannot map zs registers\n");
296 * Check if power state can be set, e.g. Tadpole 3GX
298 if (prom_getpropint(sa
->sa_node
, "pwr-on-auxio2", 0)) {
299 aprint_normal(": powered via auxio2");
300 for (channel
= 0; channel
< 2; channel
++) {
301 cs
= &zsc
->zsc_cs_store
[channel
];
302 cs
->enable
= zs_enable
;
303 cs
->disable
= zs_disable
;
307 zsc
->zsc_bustag
= sa
->sa_bustag
;
308 zsc
->zsc_dmatag
= sa
->sa_dmatag
;
309 zsc
->zsc_promunit
= prom_getpropint(sa
->sa_node
, "slave", -2);
310 zsc
->zsc_node
= sa
->sa_node
;
311 zs_attach(zsc
, va
, sa
->sa_pri
);
313 struct obio4_attach_args
*oba
= &uoba
->uoba_oba4
;
314 bus_space_handle_t bh
;
315 bus_addr_t paddr
= oba
->oba_paddr
;
318 * As for zs on mainbus, we require a PROM mapping.
320 if (bus_space_map(oba
->oba_bustag
,
322 sizeof(struct zsdevice
),
323 BUS_SPACE_MAP_LINEAR
| OBIO_BUS_MAP_USE_ROM
,
325 aprint_error(": cannot map zs registers\n");
328 zsc
->zsc_bustag
= oba
->oba_bustag
;
329 zsc
->zsc_dmatag
= oba
->oba_dmatag
;
331 * Find prom unit by physical address
332 * We're just comparing the address (not the iospace) here
334 paddr
= BUS_ADDR_PADDR(paddr
);
335 if (cpuinfo
.cpu_type
== CPUTYP_4_100
)
337 * On the sun4/100, the top-most 4 bits are zero
338 * on obio addresses; force them to 1's for the
339 * sake of the comparison here.
343 (paddr
== 0xf1000000) ? 0 :
344 (paddr
== 0xf0000000) ? 1 :
345 (paddr
== 0xe0000000) ? 2 : -2;
347 zs_attach(zsc
, (void *)bh
, oba
->oba_pri
);
353 zs_attach_bootbus(device_t parent
, device_t self
, void *aux
)
355 struct zsc_softc
*zsc
= device_private(self
);
356 struct bootbus_attach_args
*baa
= aux
;
361 if (baa
->ba_nintr
== 0) {
362 aprint_error(": no interrupt lines\n");
366 if (baa
->ba_npromvaddrs
> 0)
367 va
= (void *) baa
->ba_promvaddrs
;
369 bus_space_handle_t bh
;
371 if (bus_space_map(baa
->ba_bustag
,
372 BUS_ADDR(baa
->ba_slot
, baa
->ba_offset
),
373 baa
->ba_size
, BUS_SPACE_MAP_LINEAR
, &bh
) != 0) {
374 aprint_error(": cannot map zs registers\n");
380 zsc
->zsc_bustag
= baa
->ba_bustag
;
381 zsc
->zsc_promunit
= prom_getpropint(baa
->ba_node
, "slave", -2);
382 zsc
->zsc_node
= baa
->ba_node
;
383 zs_attach(zsc
, va
, baa
->ba_intr
[0].oi_pri
);
390 * USE ROM PROPERTIES port-a-ignore-cd AND port-b-ignore-cd FOR
391 * SOFT CARRIER, AND keyboard PROPERTY FOR KEYBOARD/MOUSE?
394 zs_attach(struct zsc_softc
*zsc
, struct zsdevice
*zsd
, int pri
)
396 struct zsc_attach_args zsc_args
;
397 struct zs_chanstate
*cs
;
399 static int didintr
, prevpri
;
400 #if (NKBD > 0) || (NMS > 0)
404 memset(&zsc_args
, 0, sizeof zsc_args
);
406 aprint_error(": configuration incomplete\n");
411 zs_sicookie
= softint_establish(SOFTINT_SERIAL
, zssoft
, NULL
);
412 if (zs_sicookie
== NULL
) {
413 aprint_error(": cannot establish soft int handler\n");
417 aprint_normal(" softpri %d\n", IPL_SOFTSERIAL
);
420 * Initialize software state for each channel.
422 for (channel
= 0; channel
< 2; channel
++) {
424 struct device
*child
;
427 zsc_args
.channel
= channel
;
428 zsc_args
.hwflags
= 0;
429 cs
= &zsc
->zsc_cs_store
[channel
];
430 zsc
->zsc_cs
[channel
] = cs
;
433 cs
->cs_channel
= channel
;
434 cs
->cs_private
= NULL
;
435 cs
->cs_ops
= &zsops_null
;
436 cs
->cs_brg_clk
= PCLK
/ 16;
438 zc
= (channel
== 0) ? &zsd
->zs_chan_a
: &zsd
->zs_chan_b
;
440 hwflags
= zs_console_flags(zsc
->zsc_promunit
,
445 /* Not using wscons console, so always set console flags.*/
446 zsc_args
.hwflags
= hwflags
;
447 if (zsc_args
.hwflags
& ZS_HWFLAG_CONSOLE
) {
448 zsc_args
.hwflags
|= ZS_HWFLAG_USE_CONSDEV
;
449 zsc_args
.consdev
= &zs_consdev
;
452 /* If we are unit 1, then this is the "real" console.
453 * Remember this in order to set up the keyboard and
454 * mouse line disciplines for SUN4 machines below.
455 * Also, don't set the console flags, otherwise we
456 * tell zstty_attach() to attach as console.
458 if (zsc
->zsc_promunit
== 1) {
459 if ((hwflags
& ZS_HWFLAG_CONSOLE_INPUT
) != 0 &&
461 #if (NKBD > 0) || (NMS > 0)
466 zsc_args
.hwflags
= hwflags
;
469 if ((zsc_args
.hwflags
& ZS_HWFLAG_CONSOLE_INPUT
) != 0) {
470 zs_conschan_get
= zc
;
472 if ((zsc_args
.hwflags
& ZS_HWFLAG_CONSOLE_OUTPUT
) != 0) {
473 zs_conschan_put
= zc
;
475 /* Childs need to set cn_dev, etc */
477 cs
->cs_reg_csr
= &zc
->zc_csr
;
478 cs
->cs_reg_data
= &zc
->zc_data
;
480 memcpy(cs
->cs_creg
, zs_init_reg
, 16);
481 memcpy(cs
->cs_preg
, zs_init_reg
, 16);
483 /* XXX: Consult PROM properties for this?! */
484 cs
->cs_defspeed
= zs_get_speed(cs
);
485 cs
->cs_defcflag
= zs_def_cflag
;
487 /* Make these correspond to cs_defcflag (-crtscts) */
488 cs
->cs_rr0_dcd
= ZSRR0_DCD
;
490 cs
->cs_wr5_dtr
= ZSWR5_DTR
| ZSWR5_RTS
;
494 * Clear the master interrupt enable.
495 * The INTENA is common to both channels,
496 * so just do it on the A channel.
499 zs_write_reg(cs
, 9, 0);
503 * Look for a child driver for this channel.
504 * The child attach will setup the hardware.
507 child
= config_found(zsc
->zsc_dev
, &zsc_args
, zs_print
);
509 /* No sub-driver. Just reset it. */
510 uint8_t reset
= (channel
== 0) ?
511 ZSWR9_A_RESET
: ZSWR9_B_RESET
;
513 zs_write_reg(cs
, 9, reset
);
516 #if (NKBD > 0) || (NMS > 0)
518 * If this was a zstty it has a keyboard
519 * property on it we need to attach the
520 * sunkbd and sunms line disciplines.
521 * There are no properties on SUN4 machines.
522 * For them, check if we have set the
523 * ch0_is_cons variable above.
525 if ((child
!= NULL
) &&
526 (device_is_a(child
, "zstty")) && (
527 (CPU_ISSUN4
&& ch0_is_cons
) || (!CPU_ISSUN4
&&
528 (prom_getproplen(zsc
->zsc_node
, "keyboard") == 0))))
530 struct kbd_ms_tty_attach_args kma
;
531 struct tty
*tp
= zstty_get_tty_from_dev(child
);
533 kma
.kmta_dev
= tp
->t_dev
;
534 kma
.kmta_consdev
= zsc_args
.consdev
;
536 /* Attach 'em if we got 'em. */
539 kma
.kmta_name
= "keyboard";
540 config_found(child
, &kma
, NULL
);
545 kma
.kmta_name
= "mouse";
546 config_found(child
, &kma
, NULL
);
554 * Now safe to install interrupt handlers. Note the arguments
555 * to the interrupt handlers aren't used. Note, we only do this
556 * once since both SCCs interrupt at the same level and vector.
561 bus_intr_establish(zsc
->zsc_bustag
, pri
, IPL_SERIAL
,
563 } else if (pri
!= prevpri
)
564 panic("broken zs interrupt scheme");
566 evcnt_attach_dynamic(&zsc
->zsc_intrcnt
, EVCNT_TYPE_INTR
, NULL
,
567 device_xname(zsc
->zsc_dev
), "intr");
570 * Set the master interrupt enable and interrupt vector.
571 * (common to both channels, do it on A)
575 /* interrupt vector */
576 zs_write_reg(cs
, 2, zs_init_reg
[2]);
577 /* master interrupt control (enable) */
578 zs_write_reg(cs
, 9, zs_init_reg
[9]);
583 * XXX: L1A hack - We would like to be able to break into
584 * the debugger during the rest of autoconfiguration, so
585 * lower interrupts just enough to let zs interrupts in.
586 * This is done after both zs devices are attached.
588 if (zsc
->zsc_promunit
== 1) {
589 aprint_debug("zs1: enabling zs interrupts\n");
590 (void)splfd(); /* XXX: splzs - 1 */
597 zs_print(void *aux
, const char *name
)
599 struct zsc_attach_args
*args
= aux
;
602 aprint_normal("%s: ", name
);
604 if (args
->channel
!= -1)
605 aprint_normal(" channel %d", args
->channel
);
610 static volatile int zssoftpending
;
613 * Our ZS chips all share a common, autovectored interrupt,
614 * so we have to look at all of them on each interrupt.
619 struct zsc_softc
*zsc
;
620 int unit
, rr3
, rval
, softreq
;
623 for (unit
= 0; unit
< zs_cd
.cd_ndevs
; unit
++) {
624 struct zs_chanstate
*cs
;
626 zsc
= device_lookup_private(&zs_cd
, unit
);
629 rr3
= zsc_intr_hard(zsc
);
630 /* Count up the interrupts. */
633 zsc
->zsc_intrcnt
.ev_count
++;
635 if ((cs
= zsc
->zsc_cs
[0]) != NULL
)
636 softreq
|= cs
->cs_softreq
;
637 if ((cs
= zsc
->zsc_cs
[1]) != NULL
)
638 softreq
|= cs
->cs_softreq
;
641 /* We are at splzs here, so no need to lock. */
642 if (softreq
&& (zssoftpending
== 0)) {
644 softint_schedule(zs_sicookie
);
650 * Similar scheme as for zshard (look at all of them)
655 struct zsc_softc
*zsc
;
658 /* This is not the only ISR on this IPL. */
659 if (zssoftpending
== 0)
663 * The soft intr. bit will be set by zshard only if
664 * the variable zssoftpending is zero. The order of
665 * these next two statements prevents our clearing
666 * the soft intr bit just after zshard has set it.
668 /* ienab_bic(IE_ZSSOFT); */
672 /* Make sure we call the tty layer with tty_lock held. */
673 mutex_spin_enter(&tty_lock
);
675 for (unit
= 0; unit
< zs_cd
.cd_ndevs
; unit
++) {
676 zsc
= device_lookup_private(&zs_cd
, unit
);
679 (void)zsc_intr_soft(zsc
);
682 mutex_spin_exit(&tty_lock
);
688 * Compute the current baud rate given a ZS channel.
691 zs_get_speed(struct zs_chanstate
*cs
)
695 tconst
= zs_read_reg(cs
, 12);
696 tconst
|= zs_read_reg(cs
, 13) << 8;
697 return (TCONST_TO_BPS(cs
->cs_brg_clk
, tconst
));
701 * MD functions for setting the baud rate and control modes.
702 * bps - in bits per second
705 zs_set_speed(struct zs_chanstate
*cs
, int bps
)
707 int tconst
, real_bps
;
713 if (cs
->cs_brg_clk
== 0)
714 panic("zs_set_speed");
717 tconst
= BPS_TO_TCONST(cs
->cs_brg_clk
, bps
);
721 /* Convert back to make sure we can do it. */
722 real_bps
= TCONST_TO_BPS(cs
->cs_brg_clk
, tconst
);
724 /* XXX - Allow some tolerance here? */
728 cs
->cs_preg
[12] = tconst
;
729 cs
->cs_preg
[13] = tconst
>> 8;
731 /* Caller will stuff the pending registers. */
736 zs_set_modes(struct zs_chanstate
*cs
, int cflag
)
740 * Output hardware flow control on the chip is horrendous:
741 * if carrier detect drops, the receiver is disabled, and if
742 * CTS drops, the transmitter is stoped IN MID CHARACTER!
743 * Therefore, NEVER set the HFC bit, and instead use the
744 * status interrupt to detect CTS changes.
748 if ((cflag
& (CLOCAL
| MDMBUF
)) != 0) {
750 if ((cflag
& MDMBUF
) == 0)
751 cs
->cs_rr0_pps
= ZSRR0_DCD
;
753 cs
->cs_rr0_dcd
= ZSRR0_DCD
;
754 if ((cflag
& CRTSCTS
) != 0) {
755 cs
->cs_wr5_dtr
= ZSWR5_DTR
;
756 cs
->cs_wr5_rts
= ZSWR5_RTS
;
757 cs
->cs_rr0_cts
= ZSRR0_CTS
;
758 } else if ((cflag
& CDTRCTS
) != 0) {
760 cs
->cs_wr5_rts
= ZSWR5_DTR
;
761 cs
->cs_rr0_cts
= ZSRR0_CTS
;
762 } else if ((cflag
& MDMBUF
) != 0) {
764 cs
->cs_wr5_rts
= ZSWR5_DTR
;
765 cs
->cs_rr0_cts
= ZSRR0_DCD
;
767 cs
->cs_wr5_dtr
= ZSWR5_DTR
| ZSWR5_RTS
;
773 /* Caller will stuff the pending registers. */
779 * Read or write the chip with suitable delays.
783 zs_read_reg(struct zs_chanstate
*cs
, uint8_t reg
)
787 *cs
->cs_reg_csr
= reg
;
789 val
= *cs
->cs_reg_csr
;
795 zs_write_reg(struct zs_chanstate
*cs
, uint8_t reg
, uint8_t val
)
798 *cs
->cs_reg_csr
= reg
;
800 *cs
->cs_reg_csr
= val
;
805 zs_read_csr(struct zs_chanstate
*cs
)
809 val
= *cs
->cs_reg_csr
;
815 zs_write_csr(struct zs_chanstate
*cs
, uint8_t val
)
818 *cs
->cs_reg_csr
= val
;
823 zs_read_data(struct zs_chanstate
*cs
)
827 val
= *cs
->cs_reg_data
;
833 zs_write_data(struct zs_chanstate
*cs
, uint8_t val
)
836 *cs
->cs_reg_data
= val
;
840 /****************************************************************
841 * Console support functions (Sun specific!)
842 * Note: this code is allowed to know about the layout of
843 * the chip registers, and uses that to keep things simple.
844 * XXX - I think I like the mvme167 code better. -gwr
845 ****************************************************************/
848 * Handle user request to enter kernel debugger.
851 zs_abort(struct zs_chanstate
*cs
)
853 struct zschan
*zc
= zs_conschan_get
;
856 /* Wait for end of break to avoid PROM abort. */
857 /* XXX - Limit the wait? */
861 } while (rr0
& ZSRR0_BREAK
);
868 printf("stopping on keyboard abort\n");
874 void zs_putc(void *, int);
882 struct zschan
*zc
= arg
;
886 /* Temporarily direct interrupts at ourselves */
888 omid
= setitr(cpuinfo
.mid
);
890 /* Wait for a character to arrive. */
894 } while ((rr0
& ZSRR0_RX_READY
) == 0);
902 * This is used by the kd driver to read scan codes,
903 * so don't translate '\r' ==> '\n' here...
909 * Polled output char.
912 zs_putc(void *arg
, int c
)
914 struct zschan
*zc
= arg
;
918 /* Temporarily direct interrupts at ourselves */
920 omid
= setitr(cpuinfo
.mid
);
922 /* Wait for transmitter to become ready. */
926 } while ((rr0
& ZSRR0_TX_READY
) == 0);
929 * Send the next character.
930 * Now you'd think that this could be followed by a ZS_DELAY()
931 * just like all the other chip accesses, but it turns out that
932 * the `transmit-ready' interrupt isn't de-asserted until
933 * some period of time after the register write completes
934 * (more than a couple instructions). So to avoid stray
935 * interrupts we put in the 2us delay regardless of CPU model.
944 /*****************************************************************/
946 * Polled console input putchar.
952 return (zs_getc(zs_conschan_get
));
956 * Polled console output putchar.
959 zscnputc(dev_t dev
, int c
)
962 zs_putc(zs_conschan_put
, c
);
966 zscnpollc(dev_t dev
, int on
)
969 /* No action needed */
973 zs_console_flags(int promunit
, int node
, int channel
)
975 int cookie
, flags
= 0;
977 switch (prom_version()) {
981 * Use `promunit' and `channel' to derive the PROM
982 * stdio handles that correspond to this device.
985 cookie
= PROMDEV_TTYA
+ channel
;
986 else if (promunit
== 1 && channel
== 0)
987 cookie
= PROMDEV_KBD
;
991 if (cookie
== prom_stdin())
992 flags
|= ZS_HWFLAG_CONSOLE_INPUT
;
995 * Prevent the keyboard from matching the output device
996 * (note that PROMDEV_KBD == PROMDEV_SCREEN == 0!).
998 if (cookie
!= PROMDEV_KBD
&& cookie
== prom_stdout())
999 flags
|= ZS_HWFLAG_CONSOLE_OUTPUT
;
1008 * Match the nodes and device arguments prepared by
1009 * consinit() against our device node and channel.
1010 * (The device argument is the part of the OBP path
1011 * following the colon, as in `/obio/zs@0,100000:a')
1014 /* Default to channel 0 if there are no explicit prom args */
1017 if (node
== prom_stdin_node
) {
1018 if (prom_stdin_args
[0] != '\0')
1019 /* Translate (a,b) -> (0,1) */
1020 cookie
= prom_stdin_args
[0] - 'a';
1022 if (channel
== cookie
)
1023 flags
|= ZS_HWFLAG_CONSOLE_INPUT
;
1026 if (node
== prom_stdout_node
) {
1027 if (prom_stdout_args
[0] != '\0')
1028 /* Translate (a,b) -> (0,1) */
1029 cookie
= prom_stdout_args
[0] - 'a';
1031 if (channel
== cookie
)
1032 flags
|= ZS_HWFLAG_CONSOLE_OUTPUT
;
1045 * Power management hooks for zsopen() and zsclose().
1046 * We use them to power on/off the ports, if necessary.
1049 zs_enable(struct zs_chanstate
*cs
)
1052 auxiotwoserialendis (ZS_ENABLE
);
1058 zs_disable(struct zs_chanstate
*cs
)
1061 auxiotwoserialendis (ZS_DISABLE
);