2001-06-13 Michael Snyder <msnyder@redhat.com>
[deliverable/binutils-gdb.git] / gdb / ser-e7kpc.c
CommitLineData
c906108c 1/* Remote serial interface using Hitachi E7000 PC ISA card in a PC
b6ba6518
KB
2 Copyright 1994, 1996, 1997, 1998, 1999, 2000
3 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
c906108c 11
c5aa993b
JM
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
c906108c 16
c5aa993b
JM
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
c906108c
SS
21
22#if defined __GO32__ || defined _WIN32
23#include "defs.h"
24#include "serial.h"
25#include "gdb_string.h"
26
c906108c 27#ifdef _WIN32
0b6a968e 28#define WIN32_LEAN_AND_MEAN
c906108c
SS
29#include <windows.h>
30#endif
31
32#ifdef __GO32__
33#include <sys/dos.h>
34#endif
35
a14ed312
KB
36static int e7000pc_open (serial_t scb, const char *name);
37static void e7000pc_raw (serial_t scb);
38static int e7000pc_readchar (serial_t scb, int timeout);
39static int e7000pc_setbaudrate (serial_t scb, int rate);
40static int e7000pc_write (serial_t scb, const char *str, int len);
41static void e7000pc_close (serial_t scb);
42static serial_ttystate e7000pc_get_tty_state (serial_t scb);
43static int e7000pc_set_tty_state (serial_t scb, serial_ttystate state);
c906108c
SS
44
45#define OFF_DPD 0x0000
46#define OFF_DDP 0x1000
47#define OFF_CPD 0x2000
48#define OFF_CDP 0x2400
49#define OFF_FA 0x3000
50#define OFF_FB 0x3002
51#define OFF_FC 0x3004
52#define OFF_IRQTOD 0x3008
53#define OFF_IRQTOP 0x300a
54#define OFF_READY 0x300c
55#define OFF_PON 0x300e
56
c5aa993b
JM
57#define IDLE 0x0000
58#define CMD_CI 0x4349
59#define CMD_CO 0x434f
60#define CMD_LO 0x4c4f
61#define CMD_LS 0x4c53
62#define CMD_SV 0x5356
63#define CMD_SS 0x5353
64#define CMD_OK 0x4f4b
65#define CMD_ER 0x4552
66#define CMD_NF 0x4e46
67#define CMD_AB 0x4142
68#define CMD_ED 0x4544
69#define CMD_CE 0x4345
c906108c
SS
70
71static unsigned long fa;
72static unsigned long irqtod;
73static unsigned long ready;
74static unsigned long fb;
c5aa993b
JM
75static unsigned long cpd;
76static unsigned long cdp;
c906108c
SS
77static unsigned long ready;
78static unsigned long pon;
79static unsigned long irqtop;
80static unsigned long board_at;
81
82#ifdef __GO32__
83
84#define SET_BYTE(x,y) { char _buf = y;dosmemput(&_buf,1, x);}
85#define SET_WORD(x,y) { short _buf = y;dosmemput(&_buf,2, x);}
86#define GET_BYTE(x) ( dosmemget(x,1,&bb), bb)
87#define GET_WORD(x) ( dosmemget(x,2,&sb), sb)
88static unsigned char bb;
89static unsigned short sb;
90
91#else /* win32 */
92
93#define SET_BYTE(x,y) *(volatile unsigned char *)(x) = (y)
94#define SET_WORD(x,y) *(volatile unsigned short *)(x) = (y)
95#define GET_BYTE(x) (*(volatile unsigned char *)(x))
96#define GET_WORD(x) (*(volatile unsigned short *)(x))
97#define dosmemget(FROM, LEN, TO) memcpy ((void *)(TO), (void *)(FROM), (LEN))
98#define dosmemput(FROM, LEN, TO) memcpy ((void *)(TO), (void *)(FROM), (LEN))
99#endif
100
c5aa993b
JM
101static struct sw
102 {
103 int sw;
104 int addr;
105 }
106sigs[] =
c906108c 107{
c5aa993b
JM
108 {
109 0x14, 0xd0000
110 }
111 ,
112 {
113 0x15, 0xd4000
114 }
115 ,
116 {
117 0x16, 0xd8000
118 }
119 ,
120 {
121 0x17, 0xdc000
122 }
123 ,
124 0
125};
c906108c 126
c906108c 127#define get_ds_base() 0
c906108c
SS
128
129static int
fba45db2 130e7000pc_init (void)
c906108c
SS
131{
132 int try;
133 unsigned long dsbase;
c5aa993b 134
c906108c
SS
135 dsbase = get_ds_base ();
136
137 /* Look around in memory for the board's signature */
138
139 for (try = 0; sigs[try].sw; try++)
140 {
141 int val;
142 board_at = sigs[try].addr - dsbase;
143 fa = board_at + OFF_FA;
144 fb = board_at + OFF_FB;
145 cpd = board_at + OFF_CPD;
146 cdp = board_at + OFF_CDP;
c5aa993b
JM
147 ready = board_at + OFF_READY;
148 pon = board_at + OFF_PON;
c906108c
SS
149 irqtop = board_at + OFF_IRQTOP;
150 irqtod = board_at + OFF_IRQTOD;
c5aa993b 151
c906108c
SS
152 val = GET_WORD (ready);
153
c5aa993b 154 if (val == (0xaaa0 | sigs[try].sw))
c906108c
SS
155 {
156 if (GET_WORD (pon) & 0xf)
157 {
158 SET_WORD (fa, 0);
159 SET_WORD (fb, 0);
160
c5aa993b 161 SET_WORD (irqtop, 1); /* Disable interrupts from e7000 */
c906108c 162 SET_WORD (ready, 1);
c5aa993b 163 printf_filtered ("\nConnected to the E7000PC at address 0x%x\n",
c906108c 164 sigs[try].addr);
c5aa993b 165 return 1;
c906108c
SS
166 }
167 error ("The E7000 PC board is working, but the E7000 is turned off.\n");
168 return 0;
169 }
170 }
171
172 error ("GDB cannot connect to the E7000 PC board, check that it is installed\n\
173and that the switch settings are correct. Some other DOS programs can \n\
174stop the board from working. Try starting from a very minimal boot, \n\
175perhaps you need to disable EMM386 over the region where the board has\n\
176its I/O space, remove other unneeded cards, etc etc\n");
177 return 0;
178
179}
180
181static int pbuf_size;
182static int pbuf_index;
183
184/* Return next byte from cdp. If no more, then return -1. */
185
c5aa993b 186static int
c906108c
SS
187e7000_get (void)
188{
189 static char pbuf[1000];
190 char tmp[1000];
191 int x;
192
c5aa993b 193 if (pbuf_index < pbuf_size)
c906108c
SS
194 {
195 x = pbuf[pbuf_index++];
196 }
197 else if ((GET_WORD (fb) & 1))
198 {
199 int i;
200 pbuf_size = GET_WORD (cdp + 2);
201
202 dosmemget (cdp + 8, pbuf_size + 1, tmp);
203
204 /* Tell the E7000 we've eaten */
c5aa993b 205 SET_WORD (fb, 0);
c906108c 206 /* Swap it around */
c5aa993b 207 for (i = 0; i < pbuf_size; i++)
c906108c 208 {
c5aa993b 209 pbuf[i] = tmp[i ^ 1];
c906108c
SS
210 }
211 pbuf_index = 0;
c5aa993b 212 x = pbuf[pbuf_index++];
c906108c 213 }
c5aa993b
JM
214 else
215 {
c906108c
SS
216 x = -1;
217 }
218 return x;
219}
220
221/* Works just like read(), except that it takes a TIMEOUT in seconds. Note
222 that TIMEOUT == 0 is a poll, and TIMEOUT == -1 means wait forever. */
223
224static int
fba45db2 225dosasync_read (int fd, char *buf, int len, int timeout)
c906108c
SS
226{
227 long now;
228 long then;
229 int i = 0;
230
231 /* Then look for some more if we're still hungry */
232 time (&now);
233 then = now + timeout;
234 while (i < len)
235 {
c5aa993b
JM
236 int ch = e7000_get ();
237
c906108c 238 /* While there's room in the buffer, and we've already
c5aa993b
JM
239 read the stuff in, suck it over */
240 if (ch != -1)
c906108c
SS
241 {
242 buf[i++] = ch;
c5aa993b 243 while (i < len && pbuf_index < pbuf_size)
c906108c 244 {
c5aa993b 245 ch = e7000_get ();
c906108c
SS
246 if (ch == -1)
247 break;
248 buf[i++] = ch;
249 }
250 }
251
252 time (&now);
253
254 if (timeout == 0)
255 return i;
256 if (now >= then && timeout > 0)
257 {
258 return i;
259 }
260 }
261 return len;
262}
263
264
265static int
fba45db2 266dosasync_write (int fd, const char *buf, int len)
c906108c
SS
267{
268 int i;
c5aa993b
JM
269 char dummy[1000];
270
c906108c 271 /* Construct copy locally */
c5aa993b
JM
272 ((short *) dummy)[0] = CMD_CI;
273 ((short *) dummy)[1] = len;
274 ((short *) dummy)[2] = 0;
275 ((short *) dummy)[3] = 0;
276 for (i = 0; i < len; i++)
c906108c 277 {
7a292a7a 278 dummy[(8 + i) ^ 1] = buf[i];
c906108c
SS
279 }
280
281 /* Wait for the card to get ready */
c5aa993b 282 while (GET_WORD (fa) & 1);
c906108c
SS
283
284 /* Blast onto the ISA card */
c5aa993b 285 dosmemput (dummy, 8 + len + 1, cpd);
c906108c
SS
286
287 SET_WORD (fa, 1);
c5aa993b 288 SET_WORD (irqtod, 1); /* Interrupt the E7000 */
c906108c
SS
289
290 return len;
291}
292
293static int
fba45db2 294e7000pc_open (serial_t scb, const char *name)
c906108c
SS
295{
296 if (strncasecmp (name, "pc", 2) != 0)
297 {
298 errno = ENOENT;
299 return -1;
300 }
301
302 scb->fd = e7000pc_init ();
303
304 if (!scb->fd)
305 return -1;
306
307 return 0;
308}
309
310static int
fba45db2 311e7000pc_noop (serial_t scb)
c906108c
SS
312{
313 return 0;
314}
315
316static void
fba45db2 317e7000pc_raw (serial_t scb)
c906108c
SS
318{
319 /* Always in raw mode */
320}
321
322static int
fba45db2 323e7000pc_readchar (serial_t scb, int timeout)
c906108c
SS
324{
325 char buf;
326
c5aa993b 327top:
c906108c
SS
328
329 if (dosasync_read (scb->fd, &buf, 1, timeout))
330 {
c5aa993b
JM
331 if (buf == 0)
332 goto top;
c906108c
SS
333 return buf;
334 }
335 else
336 return SERIAL_TIMEOUT;
337}
338
c5aa993b
JM
339struct e7000pc_ttystate
340{
c906108c
SS
341 int dummy;
342};
343
344/* e7000pc_{get set}_tty_state() are both dummys to fill out the function
345 vector. Someday, they may do something real... */
346
347static serial_ttystate
fba45db2 348e7000pc_get_tty_state (serial_t scb)
c906108c
SS
349{
350 struct e7000pc_ttystate *state;
351
352 state = (struct e7000pc_ttystate *) xmalloc (sizeof *state);
353
354 return (serial_ttystate) state;
355}
356
357static int
fba45db2 358e7000pc_set_tty_state (serial_t scb, serial_ttystate ttystate)
c906108c
SS
359{
360 return 0;
361}
362
363static int
fba45db2
KB
364e7000pc_noflush_set_tty_state (serial_t scb, serial_ttystate new_ttystate,
365 serial_ttystate old_ttystate)
c906108c
SS
366{
367 return 0;
368}
369
370static void
c2c6d25f
JM
371e7000pc_print_tty_state (serial_t scb,
372 serial_ttystate ttystate,
d9fcf2fb 373 struct ui_file *stream)
c906108c
SS
374{
375 /* Nothing to print. */
376 return;
377}
378
379static int
fba45db2 380e7000pc_setbaudrate (serial_t scb, int rate)
c906108c
SS
381{
382 return 0;
383}
384
55d80160
AC
385static int
386e7000pc_setstopbits (serial_t scb, int rate)
387{
388 return 0;
389}
390
c906108c 391static int
fba45db2 392e7000pc_write (serial_t scb, const char *str, int len)
c906108c
SS
393{
394 dosasync_write (scb->fd, str, len);
395
396 return 0;
397}
398
399static void
fba45db2 400e7000pc_close (serial_t scb)
c906108c
SS
401{
402}
403
404static struct serial_ops e7000pc_ops =
405{
406 "pc",
407 0,
408 e7000pc_open,
409 e7000pc_close,
410 e7000pc_readchar,
411 e7000pc_write,
412 e7000pc_noop, /* flush output */
413 e7000pc_noop, /* flush input */
414 e7000pc_noop, /* send break -- currently used only for nindy */
415 e7000pc_raw,
416 e7000pc_get_tty_state,
417 e7000pc_set_tty_state,
418 e7000pc_print_tty_state,
419 e7000pc_noflush_set_tty_state,
420 e7000pc_setbaudrate,
55d80160 421 e7000pc_setstopbits,
c906108c
SS
422 e7000pc_noop, /* wait for output to drain */
423};
424
425void
fba45db2 426_initialize_ser_e7000pc (void)
c906108c
SS
427{
428 serial_add_interface (&e7000pc_ops);
429}
430#else
431
432void
fba45db2 433_initialize_ser_e7000pc (void)
c906108c
SS
434{
435
436}
437#endif
This page took 0.146364 seconds and 4 git commands to generate.