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 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 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 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 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 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 311 e7000pc_noop (struct serial *scb) 312 { 313 return 0; 314 } 315 316 static void 317 e7000pc_raw (struct serial *scb) 318 { 319 /* Always in raw mode */ 320 } 321 322 static int 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 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 358 e7000pc_set_tty_state (struct serial *scb, serial_ttystate ttystate) 359 { 360 return 0; 361 } 362 363 static int 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 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 381 e7000pc_setbaudrate (struct serial *scb, int rate) 382 { 383 return 0; 384 } 385 386 static int 387 e7000pc_setstopbits (struct serial *scb, int rate) 388 { 389 return 0; 390 } 391 392 static int 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 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 431 _initialize_ser_e7000pc (void) 432 { 433 #if defined __GO32__ || defined _WIN32 434 serial_add_interface (&e7000pc_ops); 435 #endif 436 } 437