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