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