zs_kgdb.c revision 1.4 1 /* $NetBSD: zs_kgdb.c,v 1.4 2003/07/15 02:43:19 lukem 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 * Hooks for kgdb when attached via the z8530 driver
41 *
42 * To use this, build a kernel with: option KGDB, and
43 * boot that kernel with "-d". (The kernel will call
44 * zs_kgdb_init, kgdb_connect.) When the console prints
45 * "kgdb waiting..." you run "gdb -k kernel" and do:
46 * (gdb) set remotebaud 19200
47 * (gdb) target remote /dev/ttyb
48 */
49
50 #include <sys/cdefs.h>
51 __KERNEL_RCSID(0, "$NetBSD: zs_kgdb.c,v 1.4 2003/07/15 02:43:19 lukem Exp $");
52
53 #include <sys/param.h>
54 #include <sys/systm.h>
55 #include <sys/proc.h>
56 #include <sys/device.h>
57 #include <sys/conf.h>
58 #include <sys/ioctl.h>
59 #include <sys/kernel.h>
60 #include <sys/syslog.h>
61 #include <sys/kgdb.h>
62
63 #include <dev/ic/z8530reg.h>
64 #include <machine/z8530var.h>
65 #include <mac68k/dev/zs_cons.h>
66
67 /*
68 * Macs supposely provide a 3.672 MHz clock to the SCC. Unfortunately,
69 * empirical evidence suggests that it's really a 3.6864 MHz clock.
70 * Oh, what to do, what to do?!
71 */
72 #define PCLK (9600 * 384) /* PCLK pin input clock rate */
73 #define ZSHARD_PRI 4 /* Wired on the CPU board... */
74
75 #define ZS_DELAY() delay(2)
76
77 /* The layout of this is hardware-dependent (padding, order). */
78 struct zschan {
79 volatile u_char zc_csr; /* ctrl,status, and indirect access */
80 u_char zc_xxx0;
81 u_char zc_xxx1; /* part of the other channel lives here! */
82 u_char zc_xxx2; /* Yea Apple! */
83 volatile u_char zc_data; /* data */
84 u_char zc_xxx3;
85 u_char zc_xxx4;
86 u_char zc_xxx5;
87 };
88
89 static void zs_setparam __P((struct zs_chanstate *, int, int));
90 static void zskgdb __P((struct zs_chanstate *));
91
92 struct zsops zsops_kgdb;
93
94 static u_char zs_kgdb_regs[16] = {
95 0, /* 0: CMD (reset, etc.) */
96 0, /* 1: ~(ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE) */
97 0x18 + ZSHARD_PRI, /* IVECT */
98 ZSWR3_RX_8 | ZSWR3_RX_ENABLE,
99 ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP,
100 ZSWR5_TX_8 | ZSWR5_TX_ENABLE,
101 0, /* 6: TXSYNC/SYNCLO */
102 0, /* 7: RXSYNC/SYNCHI */
103 0, /* 8: alias for data port */
104 ZSWR9_MASTER_IE,
105 0, /*10: Misc. TX/RX control bits */
106 ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD,
107 14, /*12: BAUDLO (default=9600) */
108 0, /*13: BAUDHI (default=9600) */
109 ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA,
110 ZSWR15_BREAK_IE,
111 };
112
113 /*
114 * This replaces "zs_reset()" in the sparc driver.
115 */
116 static void
117 zs_setparam(cs, iena, rate)
118 struct zs_chanstate *cs;
119 int iena;
120 int rate;
121 {
122 int s, tconst;
123
124 bcopy(zs_kgdb_regs, cs->cs_preg, 16);
125
126 if (iena) {
127 cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_SIE;
128 }
129
130 /* Initialize the speed, etc. */
131 tconst = BPS_TO_TCONST(cs->cs_brg_clk, rate);
132 cs->cs_preg[5] |= ZSWR5_DTR | ZSWR5_RTS;
133 cs->cs_preg[12] = tconst;
134 cs->cs_preg[13] = tconst >> 8;
135
136 s = splhigh();
137 zs_loadchannelregs(cs);
138 splx(s);
139 }
140
141 /*
142 * Set up for kgdb; called at boot time before configuration.
143 * KGDB interrupts will be enabled later when zs0 is configured.
144 * Called after cninit(), so printf() etc. works.
145 */
146 void
147 zs_kgdb_init()
148 {
149 struct zs_chanstate cs;
150 volatile struct zschan *zc;
151 int channel;
152 extern const struct cdevsw zstty_cdevsw;
153
154 /* printf("zs_kgdb_init: kgdb_dev=0x%x\n", kgdb_dev); */
155 if (cdevsw_lookup(kgdb_dev) != &zstty_cdevsw)
156 return;
157
158 /* Note: (ttya,ttyb) on zsc1, and (ttyc,ttyd) on zsc0 */
159 channel = kgdb_dev & 1;
160 printf("zs_kgdb_init: attaching tty0%c at %d baud\n",
161 '0' + (kgdb_dev & 3), kgdb_rate);
162
163 if (!zsinited)
164 zs_init();
165
166 /* Setup temporary chanstate. */
167 bzero((caddr_t)&cs, sizeof(cs));
168 zc = zs_get_chan_addr(0, channel);
169 if (zc == NULL) {
170 printf("zs_kgdb_init: zs not mapped.\n");
171 kgdb_dev = -1;
172 return;
173 }
174
175 cs.cs_channel = channel;
176 cs.cs_brg_clk = PCLK / 16;
177 cs.cs_reg_csr = &zc->zc_csr;
178 cs.cs_reg_data = &zc->zc_data;
179
180 /* Now set parameters. (interrupts disabled) */
181 zs_setparam(&cs, 0, kgdb_rate);
182
183 /* Store the getc/putc functions and arg. */
184 kgdb_attach(zs_getc, zs_putc, (void *)zc);
185 }
186
187 /*
188 * This is a "hook" called by zstty_attach to allow the tty
189 * to be "taken over" for exclusive use by kgdb.
190 * Return non-zero if this is the kgdb port.
191 *
192 * Set the speed to kgdb_rate, CS8, etc.
193 */
194 int
195 zs_check_kgdb(cs, dev)
196 struct zs_chanstate *cs;
197 int dev;
198 {
199
200 if (dev != kgdb_dev)
201 return (0);
202
203 /*
204 * Yes, this is port in use by kgdb.
205 */
206 cs->cs_private = NULL;
207 cs->cs_ops = &zsops_kgdb;
208
209 /* Now set parameters. (interrupts enabled) */
210 zs_setparam(cs, 1, kgdb_rate);
211
212 return (1);
213 }
214
215 /*
216 * KGDB framing character received: enter kernel debugger. This probably
217 * should time out after a few seconds to avoid hanging on spurious input.
218 */
219 static void
220 zskgdb(cs)
221 struct zs_chanstate *cs;
222 {
223 int unit = minor(kgdb_dev);
224
225 printf("zstty%d: kgdb interrupt\n", unit);
226 /* This will trap into the debugger. */
227 kgdb_connect(1);
228 }
229
230
231 /****************************************************************
232 * Interface to the lower layer (zscc)
233 ****************************************************************/
234
235 static void zs_kgdb_rxint __P((struct zs_chanstate *));
236 static void zs_kgdb_stint __P((struct zs_chanstate *, int));
237 static void zs_kgdb_txint __P((struct zs_chanstate *));
238 static void zs_kgdb_softint __P((struct zs_chanstate *));
239
240 int kgdb_input_lost;
241
242 static void
243 zs_kgdb_rxint(cs)
244 struct zs_chanstate *cs;
245 {
246 register u_char c, rr1;
247
248 /*
249 * First read the status, because reading the received char
250 * destroys the status of this char.
251 */
252 rr1 = zs_read_reg(cs, 1);
253 c = zs_read_data(cs);
254
255 if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
256 /* Clear the receive error. */
257 zs_write_csr(cs, ZSWR0_RESET_ERRORS);
258 }
259
260 if (c == KGDB_START) {
261 zskgdb(cs);
262 } else {
263 kgdb_input_lost++;
264 }
265 }
266
267 static void
268 zs_kgdb_txint(cs)
269 register struct zs_chanstate *cs;
270 {
271 register int rr0;
272
273 rr0 = zs_read_csr(cs);
274 zs_write_csr(cs, ZSWR0_RESET_TXINT);
275 }
276
277 static void
278 zs_kgdb_stint(cs, force)
279 register struct zs_chanstate *cs;
280 int force;
281 {
282 register int rr0;
283
284 rr0 = zs_read_csr(cs);
285 zs_write_csr(cs, ZSWR0_RESET_STATUS);
286
287 /*
288 * Check here for console break, so that we can abort
289 * even when interrupts are locking up the machine.
290 */
291 if (rr0 & ZSRR0_BREAK) {
292 zskgdb(cs);
293 }
294 }
295
296 static void
297 zs_kgdb_softint(cs)
298 struct zs_chanstate *cs;
299 {
300 printf("zs_kgdb_softint?\n");
301 }
302
303 struct zsops zsops_kgdb = {
304 zs_kgdb_rxint, /* receive char available */
305 zs_kgdb_stint, /* external/status */
306 zs_kgdb_txint, /* xmit buffer empty */
307 zs_kgdb_softint, /* process software interrupt */
308 };
309