Update/correct copyright notices.
[platform/upstream/binutils.git] / gdb / ser-e7kpc.c
1 /* Remote serial interface using Hitachi E7000 PC ISA card in a PC
2    Copyright 1994, 1996, 1997, 1998, 1999, 2000
3    Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
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.
11
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.
16
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.  */
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
41 static int e7000pc_open (serial_t scb, const char *name);
42 static void e7000pc_raw (serial_t scb);
43 static int e7000pc_readchar (serial_t scb, int timeout);
44 static int e7000pc_setbaudrate (serial_t scb, int rate);
45 static int e7000pc_write (serial_t scb, const char *str, int len);
46 static void e7000pc_close (serial_t scb);
47 static serial_ttystate e7000pc_get_tty_state (serial_t scb);
48 static int e7000pc_set_tty_state (serial_t scb, serial_ttystate state);
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
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
75
76 static unsigned long fa;
77 static unsigned long irqtod;
78 static unsigned long ready;
79 static unsigned long fb;
80 static unsigned long cpd;
81 static unsigned long cdp;
82 static unsigned long ready;
83 static unsigned long pon;
84 static unsigned long irqtop;
85 static 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)
93 static unsigned char bb;
94 static 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
106 static struct sw
107   {
108     int sw;
109     int addr;
110   }
111 sigs[] =
112 {
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 };
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
138 static unsigned long
139 get_ds_base (void)
140 {
141   unsigned short dsval;
142   LDT_ENTRY ldt;
143   unsigned long dsbase;
144
145   __asm
146   {
147     mov dsval, ds
148   }
149
150   dsbase = 0;
151
152   GetThreadSelectorEntry (GetCurrentThread (), dsval, &ldt);
153
154   dsbase = ldt.HighWord.Bits.BaseHi << 24 | ldt.HighWord.Bits.BaseMid << 16
155     | ldt.BaseLow;
156
157   return dsbase;
158 }
159 #else /* !_MSC_VER */
160 #define get_ds_base() 0
161 #endif /* _MSC_VER */
162
163 static int
164 e7000pc_init (void)
165 {
166   int try;
167   unsigned long dsbase;
168
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;
181       ready = board_at + OFF_READY;
182       pon = board_at + OFF_PON;
183       irqtop = board_at + OFF_IRQTOP;
184       irqtod = board_at + OFF_IRQTOD;
185
186       val = GET_WORD (ready);
187
188       if (val == (0xaaa0 | sigs[try].sw))
189         {
190           if (GET_WORD (pon) & 0xf)
191             {
192               SET_WORD (fa, 0);
193               SET_WORD (fb, 0);
194
195               SET_WORD (irqtop, 1);     /* Disable interrupts from e7000 */
196               SET_WORD (ready, 1);
197               printf_filtered ("\nConnected to the E7000PC at address 0x%x\n",
198                                sigs[try].addr);
199               return 1;
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\
207 and that the switch settings are correct.  Some other DOS programs can \n\
208 stop the board from working.  Try starting from a very minimal boot, \n\
209 perhaps you need to disable EMM386 over the region where the board has\n\
210 its I/O space, remove other unneeded cards, etc etc\n");
211   return 0;
212
213 }
214
215 static int pbuf_size;
216 static int pbuf_index;
217
218 /* Return next byte from cdp.  If no more, then return -1.  */
219
220 static int
221 e7000_get (void)
222 {
223   static char pbuf[1000];
224   char tmp[1000];
225   int x;
226
227   if (pbuf_index < pbuf_size)
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 */
239       SET_WORD (fb, 0);
240       /* Swap it around */
241       for (i = 0; i < pbuf_size; i++)
242         {
243           pbuf[i] = tmp[i ^ 1];
244         }
245       pbuf_index = 0;
246       x = pbuf[pbuf_index++];
247     }
248   else
249     {
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
258 static int
259 dosasync_read (int fd, char *buf, int len, int timeout)
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     {
270       int ch = e7000_get ();
271
272       /* While there's room in the buffer, and we've already
273          read the stuff in, suck it over */
274       if (ch != -1)
275         {
276           buf[i++] = ch;
277           while (i < len && pbuf_index < pbuf_size)
278             {
279               ch = e7000_get ();
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
299 static int
300 dosasync_write (int fd, const char *buf, int len)
301 {
302   int i;
303   char dummy[1000];
304
305   /* Construct copy locally */
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++)
311     {
312       dummy[(8 + i) ^ 1] = buf[i];
313     }
314
315   /* Wait for the card to get ready */
316   while (GET_WORD (fa) & 1);
317
318   /* Blast onto the ISA card */
319   dosmemput (dummy, 8 + len + 1, cpd);
320
321   SET_WORD (fa, 1);
322   SET_WORD (irqtod, 1);         /* Interrupt the E7000 */
323
324   return len;
325 }
326
327 static int
328 e7000pc_open (serial_t scb, const char *name)
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
344 static int
345 e7000pc_noop (serial_t scb)
346 {
347   return 0;
348 }
349
350 static void
351 e7000pc_raw (serial_t scb)
352 {
353   /* Always in raw mode */
354 }
355
356 static int
357 e7000pc_readchar (serial_t scb, int timeout)
358 {
359   char buf;
360
361 top:
362
363   if (dosasync_read (scb->fd, &buf, 1, timeout))
364     {
365       if (buf == 0)
366         goto top;
367       return buf;
368     }
369   else
370     return SERIAL_TIMEOUT;
371 }
372
373 struct e7000pc_ttystate
374 {
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
381 static serial_ttystate
382 e7000pc_get_tty_state (serial_t scb)
383 {
384   struct e7000pc_ttystate *state;
385
386   state = (struct e7000pc_ttystate *) xmalloc (sizeof *state);
387
388   return (serial_ttystate) state;
389 }
390
391 static int
392 e7000pc_set_tty_state (serial_t scb, serial_ttystate ttystate)
393 {
394   return 0;
395 }
396
397 static int
398 e7000pc_noflush_set_tty_state (serial_t scb, serial_ttystate new_ttystate,
399                                serial_ttystate old_ttystate)
400 {
401   return 0;
402 }
403
404 static void
405 e7000pc_print_tty_state (serial_t scb,
406                          serial_ttystate ttystate,
407                          struct ui_file *stream)
408 {
409   /* Nothing to print.  */
410   return;
411 }
412
413 static int
414 e7000pc_setbaudrate (serial_t scb, int rate)
415 {
416   return 0;
417 }
418
419 static int
420 e7000pc_setstopbits (serial_t scb, int rate)
421 {
422   return 0;
423 }
424
425 static int
426 e7000pc_write (serial_t scb, const char *str, int len)
427 {
428   dosasync_write (scb->fd, str, len);
429
430   return 0;
431 }
432
433 static void
434 e7000pc_close (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_setstopbits,
456   e7000pc_noop,                 /* wait for output to drain */
457 };
458
459 void
460 _initialize_ser_e7000pc (void)
461 {
462   serial_add_interface (&e7000pc_ops);
463 }
464 #else
465
466 void
467 _initialize_ser_e7000pc (void)
468 {
469
470 }
471 #endif