xref: /netbsd/sys/arch/sun2/dev/zs_any.c (revision ce099b40)
1 /*	$NetBSD: zs_any.c,v 1.18 2008/04/28 20:23:37 martin 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 and Matthew Fredette.
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  *
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.
30  */
31 
32 /*
33  * Zilog Z8530 Dual UART driver (machine-dependent part)
34  *
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.
38  */
39 
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: zs_any.c,v 1.18 2008/04/28 20:23:37 martin Exp $");
42 
43 #include "opt_kgdb.h"
44 
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/conf.h>
48 #include <sys/device.h>
49 #include <sys/file.h>
50 #include <sys/ioctl.h>
51 #include <sys/kernel.h>
52 #include <sys/proc.h>
53 #include <sys/tty.h>
54 #include <sys/time.h>
55 #include <sys/syslog.h>
56 
57 #include <machine/autoconf.h>
58 #include <machine/bus.h>
59 #include <machine/z8530var.h>
60 
61 #ifdef	KGDB
62 #include <uvm/uvm_extern.h>
63 
64 #include <machine/idprom.h>
65 #include <machine/pmap.h>
66 #include <sun2/dev/cons.h>
67 #endif
68 
69 #include <sun2/sun2/machdep.h>
70 #include <dev/ic/z8530reg.h>
71 #include <dev/sun/kbd_reg.h>
72 
73 /****************************************************************
74  * Autoconfig
75  ****************************************************************/
76 
77 /* Definition of the driver for autoconfig. */
78 static int	zs_any_match(device_t, cfdata_t, void *);
79 static void	zs_any_attach(device_t, device_t, void *);
80 
81 CFATTACH_DECL_NEW(zs_obio, sizeof(struct zsc_softc),
82     zs_any_match, zs_any_attach, NULL, NULL);
83 
84 CFATTACH_DECL_NEW(zs_obmem, sizeof(struct zsc_softc),
85     zs_any_match, zs_any_attach, NULL, NULL);
86 
87 CFATTACH_DECL_NEW(zs_mbmem, sizeof(struct zsc_softc),
88     zs_any_match, zs_any_attach, NULL, NULL);
89 
90 /*
91  * Is the zs chip present?
92  */
93 static int
zs_any_match(device_t parent,cfdata_t cf,void * aux)94 zs_any_match(device_t parent, cfdata_t cf, void *aux)
95 {
96 	struct mainbus_attach_args *ma = aux;
97 	bus_space_handle_t bh;
98 	int matched;
99 
100 	/* Make sure there is something there... */
101 	if (bus_space_map(ma->ma_bustag, ma->ma_paddr, sizeof(struct zsdevice),
102 			  0, &bh))
103 		return (0);
104 	matched = (bus_space_peek_1(ma->ma_bustag, bh, 0, NULL) == 0);
105 	bus_space_unmap(ma->ma_bustag, bh, sizeof(struct zsdevice));
106 	if (!matched)
107 		return (0);
108 
109 	/* Default interrupt priority (always splbio==2) */
110 	if (ma->ma_pri == -1)
111 		ma->ma_pri = ZSHARD_PRI;
112 
113 	return (1);
114 }
115 
116 /*
117  * Attach a found zs.
118  */
119 static void
zs_any_attach(device_t parent,device_t self,void * aux)120 zs_any_attach(device_t parent, device_t self, void *aux)
121 {
122 	struct zsc_softc *zsc = device_private(self);
123 	struct mainbus_attach_args *ma = aux;
124 	bus_space_handle_t bh;
125 
126 	zsc->zsc_dev = self;
127         zsc->zsc_bustag = ma->ma_bustag;
128         zsc->zsc_dmatag = ma->ma_dmatag;
129 	/* XXX device_unit() abuse */
130         zsc->zsc_promunit = device_unit(self);
131         zsc->zsc_node = 0;
132 
133 	/* Map in the device. */
134 	if (bus_space_map(ma->ma_bustag, ma->ma_paddr, sizeof(struct zsdevice),
135 			  BUS_SPACE_MAP_LINEAR, &bh)) {
136 		aprint_normal("\n");
137 		panic("%s: can't map", __func__);
138 	}
139 
140 	/* This is where we break the bus_space(9) abstraction: */
141 	zs_attach(zsc, (void *)bh, ma->ma_pri);
142 }
143 
144 int
zs_console_flags(int promunit,int node,int channel)145 zs_console_flags(int promunit, int node, int channel)
146 {
147 	int cookie, flags = 0;
148 
149 	/*
150 	 * Use `promunit' and `channel' to derive the PROM
151 	 * stdio handles that correspond to this device.
152 	 */
153 	if (promunit == 0)
154 		cookie = PROMDEV_TTYA + channel;
155 	else if (promunit == 1 && channel == 0)
156 		cookie = PROMDEV_KBD;
157 	else
158 		cookie = -1;
159 
160 	/*
161 	 * We have the console keyboard only if it's a Sun-2
162 	 * keyboard or better. (i.e., not a Sun-1 parallel kbd).
163 	 */
164 	if (cookie == prom_stdin() &&
165 	    (cookie != PROMDEV_KBD || prom_kbdid() >= KB_SUN2))
166 		flags |= ZS_HWFLAG_CONSOLE_INPUT;
167 
168 	/*
169 	 * Prevent the keyboard from matching the output device
170 	 * (note that PROMDEV_KBD == PROMDEV_SCREEN == 0!).
171 	 */
172 	if (cookie != PROMDEV_KBD && cookie == prom_stdout())
173 		flags |= ZS_HWFLAG_CONSOLE_OUTPUT;
174 
175 	return (flags);
176 }
177 
178 #ifdef	KGDB
179 /*
180  * Find a zs mapped by the PROM.  Currently this only works to find
181  * zs0 on obio.
182  */
183 void *
zs_find_prom(int unit)184 zs_find_prom(int unit)
185 {
186 	bus_addr_t zs0_phys;
187 	vaddr_t va;
188 
189 	if (unit != 0)
190 		return (NULL);
191 
192 	/*
193 	 * The physical address of zs0 is model-dependent.
194 	 */
195 	zs0_phys = (cpu_machine_id == ID_SUN2_120 ? 0x002000 : 0x7f2000);
196 	if (find_prom_map(zs0_phys, PMAP_OBIO, sizeof(struct zsdevice), &va))
197 		return (NULL);
198 
199 	return (void *)va;
200 }
201 #endif	/* KGDB */
202