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