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