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