* dwarf2read.c (dwarf2_symbol_mark_computed): Handle corrupted
[platform/upstream/binutils.git] / gdb / ser-e7kpc.c
1 /* Remote serial interface using Renesas E7000 PC ISA card in a PC
2    Copyright (C) 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., 51 Franklin Street, Fifth Floor,
20    Boston, MA 02110-1301, USA.  */
21
22 #include "defs.h"
23 #if defined __GO32__ || defined _WIN32
24 #include "serial.h"
25 #include "gdb_string.h"
26
27 #ifdef _WIN32
28 #define WIN32_LEAN_AND_MEAN
29 #include <windows.h>
30 #endif
31
32 #ifdef __GO32__
33 #include <sys/dos.h>
34 #endif
35
36 #ifdef HAVE_TIME_H
37 #include <time.h>
38 #endif
39
40 static int e7000pc_open (struct serial *scb, const char *name);
41 static void e7000pc_raw (struct serial *scb);
42 static int e7000pc_readchar (struct serial *scb, int timeout);
43 static int e7000pc_setbaudrate (struct serial *scb, int rate);
44 static int e7000pc_write (struct serial *scb, const char *str, int len);
45 static void e7000pc_close (struct serial *scb);
46 static serial_ttystate e7000pc_get_tty_state (struct serial *scb);
47 static int e7000pc_set_tty_state (struct serial *scb, serial_ttystate state);
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
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
74
75 static unsigned long fa;
76 static unsigned long irqtod;
77 static unsigned long ready;
78 static unsigned long fb;
79 static unsigned long cpd;
80 static unsigned long cdp;
81 static unsigned long ready;
82 static unsigned long pon;
83 static unsigned long irqtop;
84 static 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)
92 static unsigned char bb;
93 static 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
105 static struct sw
106   {
107     int sw;
108     int addr;
109   }
110 sigs[] =
111 {
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 };
130
131 #define get_ds_base() 0
132
133 static int
134 e7000pc_init (void)
135 {
136   int try;
137   unsigned long dsbase;
138
139   dsbase = get_ds_base ();
140
141   /* Look around in memory for the board's signature */
142
143   for (try = 0; sigs[try].sw; try++)
144     {
145       int val;
146       board_at = sigs[try].addr - dsbase;
147       fa = board_at + OFF_FA;
148       fb = board_at + OFF_FB;
149       cpd = board_at + OFF_CPD;
150       cdp = board_at + OFF_CDP;
151       ready = board_at + OFF_READY;
152       pon = board_at + OFF_PON;
153       irqtop = board_at + OFF_IRQTOP;
154       irqtod = board_at + OFF_IRQTOD;
155
156       val = GET_WORD (ready);
157
158       if (val == (0xaaa0 | sigs[try].sw))
159         {
160           if (GET_WORD (pon) & 0xf)
161             {
162               SET_WORD (fa, 0);
163               SET_WORD (fb, 0);
164
165               SET_WORD (irqtop, 1);     /* Disable interrupts from e7000 */
166               SET_WORD (ready, 1);
167               printf_filtered ("\nConnected to the E7000PC at address 0x%x\n",
168                                sigs[try].addr);
169               return 1;
170             }
171           error (_("The E7000 PC board is working, but the E7000 is turned off."));
172           return 0;
173         }
174     }
175
176   error (_("GDB cannot connect to the E7000 PC board, check that it is installed\n\
177 and that the switch settings are correct.  Some other DOS programs can \n\
178 stop the board from working.  Try starting from a very minimal boot, \n\
179 perhaps you need to disable EMM386 over the region where the board has\n\
180 its I/O space, remove other unneeded cards, etc etc\n"));
181   return 0;
182
183 }
184
185 static int pbuf_size;
186 static int pbuf_index;
187
188 /* Return next byte from cdp.  If no more, then return -1.  */
189
190 static int
191 e7000_get (void)
192 {
193   static char pbuf[1000];
194   char tmp[1000];
195   int x;
196
197   if (pbuf_index < pbuf_size)
198     {
199       x = pbuf[pbuf_index++];
200     }
201   else if ((GET_WORD (fb) & 1))
202     {
203       int i;
204       pbuf_size = GET_WORD (cdp + 2);
205
206       dosmemget (cdp + 8, pbuf_size + 1, tmp);
207
208       /* Tell the E7000 we've eaten */
209       SET_WORD (fb, 0);
210       /* Swap it around */
211       for (i = 0; i < pbuf_size; i++)
212         {
213           pbuf[i] = tmp[i ^ 1];
214         }
215       pbuf_index = 0;
216       x = pbuf[pbuf_index++];
217     }
218   else
219     {
220       x = -1;
221     }
222   return x;
223 }
224
225 /* Works just like read(), except that it takes a TIMEOUT in seconds.  Note
226    that TIMEOUT == 0 is a poll, and TIMEOUT == -1 means wait forever. */
227
228 static int
229 dosasync_read (int fd, char *buf, int len, int timeout)
230 {
231   long now;
232   long then;
233   int i = 0;
234
235   /* Then look for some more if we're still hungry */
236   time (&now);
237   then = now + timeout;
238   while (i < len)
239     {
240       int ch = e7000_get ();
241
242       /* While there's room in the buffer, and we've already
243          read the stuff in, suck it over */
244       if (ch != -1)
245         {
246           buf[i++] = ch;
247           while (i < len && pbuf_index < pbuf_size)
248             {
249               ch = e7000_get ();
250               if (ch == -1)
251                 break;
252               buf[i++] = ch;
253             }
254         }
255
256       time (&now);
257
258       if (timeout == 0)
259         return i;
260       if (now >= then && timeout > 0)
261         {
262           return i;
263         }
264     }
265   return len;
266 }
267
268
269 static int
270 dosasync_write (int fd, const char *buf, int len)
271 {
272   int i;
273   char dummy[1000];
274
275   /* Construct copy locally */
276   ((short *) dummy)[0] = CMD_CI;
277   ((short *) dummy)[1] = len;
278   ((short *) dummy)[2] = 0;
279   ((short *) dummy)[3] = 0;
280   for (i = 0; i < len; i++)
281     {
282       dummy[(8 + i) ^ 1] = buf[i];
283     }
284
285   /* Wait for the card to get ready */
286   while (GET_WORD (fa) & 1);
287
288   /* Blast onto the ISA card */
289   dosmemput (dummy, 8 + len + 1, cpd);
290
291   SET_WORD (fa, 1);
292   SET_WORD (irqtod, 1);         /* Interrupt the E7000 */
293
294   return len;
295 }
296
297 static int
298 e7000pc_open (struct serial *scb, const char *name)
299 {
300   if (strncasecmp (name, "pc", 2) != 0)
301     {
302       errno = ENOENT;
303       return -1;
304     }
305
306   scb->fd = e7000pc_init ();
307
308   if (!scb->fd)
309     return -1;
310
311   return 0;
312 }
313
314 static int
315 e7000pc_noop (struct serial *scb)
316 {
317   return 0;
318 }
319
320 static void
321 e7000pc_raw (struct serial *scb)
322 {
323   /* Always in raw mode */
324 }
325
326 static int
327 e7000pc_readchar (struct serial *scb, int timeout)
328 {
329   char buf;
330
331 top:
332
333   if (dosasync_read (scb->fd, &buf, 1, timeout))
334     {
335       if (buf == 0)
336         goto top;
337       return buf;
338     }
339   else
340     return SERIAL_TIMEOUT;
341 }
342
343 struct e7000pc_ttystate
344 {
345   int dummy;
346 };
347
348 /* e7000pc_{get set}_tty_state() are both dummys to fill out the function
349    vector.  Someday, they may do something real... */
350
351 static serial_ttystate
352 e7000pc_get_tty_state (struct serial *scb)
353 {
354   struct e7000pc_ttystate *state;
355
356   state = (struct e7000pc_ttystate *) xmalloc (sizeof *state);
357
358   return (serial_ttystate) state;
359 }
360
361 static int
362 e7000pc_set_tty_state (struct serial *scb, serial_ttystate ttystate)
363 {
364   return 0;
365 }
366
367 static int
368 e7000pc_noflush_set_tty_state (struct serial *scb,
369                                serial_ttystate new_ttystate,
370                                serial_ttystate old_ttystate)
371 {
372   return 0;
373 }
374
375 static void
376 e7000pc_print_tty_state (struct serial *scb,
377                          serial_ttystate ttystate,
378                          struct ui_file *stream)
379 {
380   /* Nothing to print.  */
381   return;
382 }
383
384 static int
385 e7000pc_setbaudrate (struct serial *scb, int rate)
386 {
387   return 0;
388 }
389
390 static int
391 e7000pc_setstopbits (struct serial *scb, int rate)
392 {
393   return 0;
394 }
395
396 static int
397 e7000pc_write (struct serial *scb, const char *str, int len)
398 {
399   dosasync_write (scb->fd, str, len);
400
401   return 0;
402 }
403
404 static void
405 e7000pc_close (struct serial *scb)
406 {
407 }
408
409 static struct serial_ops e7000pc_ops =
410 {
411   "pc",
412   0,
413   e7000pc_open,
414   e7000pc_close,
415   e7000pc_readchar,
416   e7000pc_write,
417   e7000pc_noop,                 /* flush output */
418   e7000pc_noop,                 /* flush input */
419   e7000pc_noop,                 /* send break -- currently used only for nindy */
420   e7000pc_raw,
421   e7000pc_get_tty_state,
422   e7000pc_set_tty_state,
423   e7000pc_print_tty_state,
424   e7000pc_noflush_set_tty_state,
425   e7000pc_setbaudrate,
426   e7000pc_setstopbits,
427   e7000pc_noop,                 /* wait for output to drain */
428 };
429
430 #endif /*_WIN32 or __GO32__*/
431
432 extern initialize_file_ftype _initialize_ser_e7000pc; /* -Wmissing-prototypes */
433
434 void
435 _initialize_ser_e7000pc (void)
436 {
437 #if defined __GO32__ || defined _WIN32
438   serial_add_interface (&e7000pc_ops);
439 #endif  
440 }