zs_kgdb.c revision 1.6 1 /* $NetBSD: zs_kgdb.c,v 1.6 1996/06/17 15:40:36 gwr Exp $ */
2
3 /*
4 * Copyright (c) 1994 Gordon W. Ross
5 * Copyright (c) 1992, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This software was developed by the Computer Systems Engineering group
9 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
10 * contributed to Berkeley.
11 *
12 * All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by the University of
15 * California, Lawrence Berkeley Laboratory.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
25 * 3. All advertising materials mentioning features or use of this software
26 * must display the following acknowledgement:
27 * This product includes software developed by the University of
28 * California, Berkeley and its contributors.
29 * 4. Neither the name of the University nor the names of its contributors
30 * may be used to endorse or promote products derived from this software
31 * without specific prior written permission.
32 *
33 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
37 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 * SUCH DAMAGE.
44 *
45 * @(#)zs.c 8.1 (Berkeley) 7/19/93
46 */
47
48 /*
49 * Hooks for kgdb when attached vi the z8530 driver
50 * XXX - not tested yet...
51 *
52 * To use this, build a kernel with: option KGDB, and
53 * boot that kernel with "-d". (The kernel will call
54 * zs_kgdb_init, kgdb_connect.) When the console prints
55 * "kgdb waiting..." you run "gdb -k kernel" and then
56 * connect to the remote using: "target remote /dev/ttyX"
57 */
58
59 #include <sys/param.h>
60 #include <sys/systm.h>
61 #include <sys/proc.h>
62 #include <sys/device.h>
63 #include <sys/conf.h>
64 #include <sys/ioctl.h>
65 #include <sys/kernel.h>
66 #include <sys/syslog.h>
67
68 #include <dev/ic/z8530reg.h>
69 #include <machine/z8530var.h>
70
71 #include <machine/remote-sl.h>
72
73 /* The Sun3 provides a 4.9152 MHz clock to the ZS chips. */
74 #define PCLK (9600 * 512) /* PCLK pin input clock rate */
75 #define ZSHARD_PRI 6 /* Wired on the CPU board... */
76
77 #define ZS_DELAY() delay(2)
78
79 /* The layout of this is hardware-dependent (padding, order). */
80 struct zschan {
81 volatile u_char zc_csr; /* ctrl,status, and indirect access */
82 u_char zc_xxx0;
83 volatile u_char zc_data; /* data */
84 u_char zc_xxx1;
85 };
86
87 extern int kgdb_dev;
88 extern int kgdb_rate;
89
90 struct zschan * zs_get_chan_addr __P((int zsc_unit, int channel));
91
92 extern int zs_getc __P((void *arg));
93 extern void zs_putc __P((void *arg, int c));
94
95 struct zsops zsops_kgdb;
96
97 static u_char zs_kgdb_regs[16] = {
98 0, /* 0: CMD (reset, etc.) */
99 ZSWR1_RIE, /* NOT: (ZSWR1_TIE | ZSWR1_SIE) */
100 0x18 + ZSHARD_PRI, /* IVECT */
101 ZSWR3_RX_8 | ZSWR3_RX_ENABLE,
102 ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP,
103 ZSWR5_TX_8 | ZSWR5_TX_ENABLE,
104 0, /* 6: TXSYNC/SYNCLO */
105 0, /* 7: RXSYNC/SYNCHI */
106 0, /* 8: alias for data port */
107 ZSWR9_MASTER_IE,
108 0, /*10: Misc. TX/RX control bits */
109 ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD,
110 14, /*12: BAUDLO (default=9600) */
111 0, /*13: BAUDHI (default=9600) */
112 ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA,
113 ZSWR15_BREAK_IE | ZSWR15_DCD_IE,
114 };
115
116 /*
117 * This replaces "zs_reset()" in the sparc driver.
118 */
119 static void
120 zs_setparam(cs, iena, rate)
121 struct zs_chanstate *cs;
122 int iena;
123 int rate;
124 {
125 int s, tconst;
126
127 bcopy(zs_kgdb_regs, cs->cs_preg, 16);
128
129 if (iena == 0) {
130 cs->cs_preg[1] = 0;
131 }
132
133 /* Initialize the speed, etc. */
134 tconst = BPS_TO_TCONST(cs->cs_brg_clk, rate);
135 cs->cs_preg[5] |= ZSWR5_DTR | ZSWR5_RTS;
136 cs->cs_preg[12] = tconst;
137 cs->cs_preg[13] = tconst >> 8;
138
139 s = splhigh();
140 zs_loadchannelregs(cs);
141 splx(s);
142 }
143
144 /*
145 * Set up for kgdb; called at boot time before configuration.
146 * KGDB interrupts will be enabled later when zs0 is configured.
147 */
148 void
149 zs_kgdb_init()
150 {
151 struct zs_chanstate cs;
152 volatile struct zschan *zc;
153 int channel, zsc_unit;
154
155 if (major(kgdb_dev) != ZSTTY_MAJOR)
156 return;
157
158 /* Note: (ttya,ttyb) on zsc1, and (ttyc,ttyd) on zsc0 */
159 zsc_unit = 2 - (kgdb_dev & 2);
160 channel = kgdb_dev & 1;
161 printf("zs_kgdb_init: attaching zstty%d at %d baud\n",
162 channel, kgdb_rate);
163
164 /* Setup temporary chanstate. */
165 bzero((caddr_t)&cs, sizeof(cs));
166 zc = zs_get_chan_addr(zsc_unit, channel);
167 cs.cs_reg_csr = &zc->zc_csr;
168 cs.cs_reg_data = &zc->zc_data;
169 cs.cs_channel = channel;
170 cs.cs_brg_clk = PCLK / 16;
171
172 /* Now set parameters. (interrupts disabled) */
173 zs_setparam(&cs, 0, kgdb_rate);
174
175 /* Store the getc/putc functions and arg. */
176 kgdb_attach(zs_getc, zs_putc, (void *)zc);
177 }
178
179 /*
180 * This is a "hook" called by zstty_attach to allow the tty
181 * to be "taken over" for exclusive use by kgdb.
182 * Return non-zero if this is the kgdb port.
183 *
184 * Set the speed to kgdb_rate, CS8, etc.
185 */
186 int
187 zs_check_kgdb(cs, dev)
188 struct zs_chanstate *cs;
189 int dev;
190 {
191 int tconst;
192
193 if (dev != kgdb_dev)
194 return (0);
195
196 /*
197 * Yes, this is the kgdb port. Finish the autoconfig
198 * message and set up the port for our exclusive use.
199 */
200 printf(" (kgdb)\n");
201
202 cs->cs_private = NULL;
203 cs->cs_ops = &zsops_kgdb;
204
205 /* Now set parameters. (interrupts enabled) */
206 zs_setparam(&cs, 1, kgdb_rate);
207
208 return (1);
209 }
210
211 /*
212 * KGDB framing character received: enter kernel debugger. This probably
213 * should time out after a few seconds to avoid hanging on spurious input.
214 */
215 zskgdb()
216 {
217 int unit = minor(kgdb_dev);
218
219 printf("zstty%d: kgdb interrupt\n", unit);
220 /* This will trap into the debugger. */
221 kgdb_connect(1);
222 }
223
224
225 /****************************************************************
226 * Interface to the lower layer (zscc)
227 ****************************************************************/
228
229 int kgdb_input_lost;
230
231 static void
232 zs_kgdb_rxint(cs)
233 register struct zs_chanstate *cs;
234 {
235 register u_char c, rr1;
236
237 /* Read the input data ASAP. */
238 c = zs_read_data(cs);
239
240 /* Save the status register too. */
241 rr1 = zs_read_reg(cs, 1);
242
243 if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
244 /* Clear the receive error. */
245 zs_write_csr(cs, ZSWR0_RESET_ERRORS);
246 }
247
248 if (c == FRAME_START) {
249 zskgdb();
250 } else {
251 kgdb_input_lost++;
252 }
253 }
254
255 static void
256 zs_kgdb_txint(cs)
257 register struct zs_chanstate *cs;
258 {
259 register int rr0;
260
261 rr0 = zs_read_csr(cs);
262 zs_write_csr(cs, ZSWR0_RESET_TXINT);
263 }
264
265 static void
266 zs_kgdb_stint(cs)
267 register struct zs_chanstate *cs;
268 {
269 register int rr0;
270
271 rr0 = zs_read_csr(cs);
272 zs_write_csr(cs, ZSWR0_RESET_STATUS);
273 }
274
275 static void
276 zs_kgdb_softint(cs)
277 struct zs_chanstate *cs;
278 {
279 printf("zs_kgdb_softint?\n");
280 }
281
282 struct zsops zsops_kgdb = {
283 zs_kgdb_rxint, /* receive char available */
284 zs_kgdb_stint, /* external/status */
285 zs_kgdb_txint, /* xmit buffer empty */
286 zs_kgdb_softint, /* process software interrupt */
287 };
288