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