1130812Smarcel/* Remote serial interface using Renesas E7000 PC ISA card in a PC 2130812Smarcel Copyright 1994, 1996, 1997, 1998, 1999, 2000 3130812Smarcel Free Software Foundation, Inc. 4130812Smarcel 5130812Smarcel This file is part of GDB. 6130812Smarcel 7130812Smarcel This program is free software; you can redistribute it and/or modify 8130812Smarcel it under the terms of the GNU General Public License as published by 9130812Smarcel the Free Software Foundation; either version 2 of the License, or 10130812Smarcel (at your option) any later version. 11130812Smarcel 12130812Smarcel This program is distributed in the hope that it will be useful, 13130812Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 14130812Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15130812Smarcel GNU General Public License for more details. 16130812Smarcel 17130812Smarcel You should have received a copy of the GNU General Public License 18130812Smarcel along with this program; if not, write to the Free Software 19130812Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 20130812Smarcel Boston, MA 02111-1307, USA. */ 21130812Smarcel 22130812Smarcel#include "defs.h" 23130812Smarcel#if defined __GO32__ || defined _WIN32 24130812Smarcel#include "serial.h" 25130812Smarcel#include "gdb_string.h" 26130812Smarcel 27130812Smarcel#ifdef _WIN32 28130812Smarcel#define WIN32_LEAN_AND_MEAN 29130812Smarcel#include <windows.h> 30130812Smarcel#endif 31130812Smarcel 32130812Smarcel#ifdef __GO32__ 33130812Smarcel#include <sys/dos.h> 34130812Smarcel#endif 35130812Smarcel 36130812Smarcelstatic int e7000pc_open (struct serial *scb, const char *name); 37130812Smarcelstatic void e7000pc_raw (struct serial *scb); 38130812Smarcelstatic int e7000pc_readchar (struct serial *scb, int timeout); 39130812Smarcelstatic int e7000pc_setbaudrate (struct serial *scb, int rate); 40130812Smarcelstatic int e7000pc_write (struct serial *scb, const char *str, int len); 41130812Smarcelstatic void e7000pc_close (struct serial *scb); 42130812Smarcelstatic serial_ttystate e7000pc_get_tty_state (struct serial *scb); 43130812Smarcelstatic int e7000pc_set_tty_state (struct serial *scb, serial_ttystate state); 44130812Smarcel 45130812Smarcel#define OFF_DPD 0x0000 46130812Smarcel#define OFF_DDP 0x1000 47130812Smarcel#define OFF_CPD 0x2000 48130812Smarcel#define OFF_CDP 0x2400 49130812Smarcel#define OFF_FA 0x3000 50130812Smarcel#define OFF_FB 0x3002 51130812Smarcel#define OFF_FC 0x3004 52130812Smarcel#define OFF_IRQTOD 0x3008 53130812Smarcel#define OFF_IRQTOP 0x300a 54130812Smarcel#define OFF_READY 0x300c 55130812Smarcel#define OFF_PON 0x300e 56130812Smarcel 57130812Smarcel#define IDLE 0x0000 58130812Smarcel#define CMD_CI 0x4349 59130812Smarcel#define CMD_CO 0x434f 60130812Smarcel#define CMD_LO 0x4c4f 61130812Smarcel#define CMD_LS 0x4c53 62130812Smarcel#define CMD_SV 0x5356 63130812Smarcel#define CMD_SS 0x5353 64130812Smarcel#define CMD_OK 0x4f4b 65130812Smarcel#define CMD_ER 0x4552 66130812Smarcel#define CMD_NF 0x4e46 67130812Smarcel#define CMD_AB 0x4142 68130812Smarcel#define CMD_ED 0x4544 69130812Smarcel#define CMD_CE 0x4345 70130812Smarcel 71130812Smarcelstatic unsigned long fa; 72130812Smarcelstatic unsigned long irqtod; 73130812Smarcelstatic unsigned long ready; 74130812Smarcelstatic unsigned long fb; 75130812Smarcelstatic unsigned long cpd; 76130812Smarcelstatic unsigned long cdp; 77130812Smarcelstatic unsigned long ready; 78130812Smarcelstatic unsigned long pon; 79130812Smarcelstatic unsigned long irqtop; 80130812Smarcelstatic unsigned long board_at; 81130812Smarcel 82130812Smarcel#ifdef __GO32__ 83130812Smarcel 84130812Smarcel#define SET_BYTE(x,y) { char _buf = y;dosmemput(&_buf,1, x);} 85130812Smarcel#define SET_WORD(x,y) { short _buf = y;dosmemput(&_buf,2, x);} 86130812Smarcel#define GET_BYTE(x) ( dosmemget(x,1,&bb), bb) 87130812Smarcel#define GET_WORD(x) ( dosmemget(x,2,&sb), sb) 88130812Smarcelstatic unsigned char bb; 89130812Smarcelstatic unsigned short sb; 90130812Smarcel 91130812Smarcel#else /* win32 */ 92130812Smarcel 93130812Smarcel#define SET_BYTE(x,y) *(volatile unsigned char *)(x) = (y) 94130812Smarcel#define SET_WORD(x,y) *(volatile unsigned short *)(x) = (y) 95130812Smarcel#define GET_BYTE(x) (*(volatile unsigned char *)(x)) 96130812Smarcel#define GET_WORD(x) (*(volatile unsigned short *)(x)) 97130812Smarcel#define dosmemget(FROM, LEN, TO) memcpy ((void *)(TO), (void *)(FROM), (LEN)) 98130812Smarcel#define dosmemput(FROM, LEN, TO) memcpy ((void *)(TO), (void *)(FROM), (LEN)) 99130812Smarcel#endif 100130812Smarcel 101130812Smarcelstatic struct sw 102130812Smarcel { 103130812Smarcel int sw; 104130812Smarcel int addr; 105130812Smarcel } 106130812Smarcelsigs[] = 107130812Smarcel{ 108130812Smarcel { 109130812Smarcel 0x14, 0xd0000 110130812Smarcel } 111130812Smarcel , 112130812Smarcel { 113130812Smarcel 0x15, 0xd4000 114130812Smarcel } 115130812Smarcel , 116130812Smarcel { 117130812Smarcel 0x16, 0xd8000 118130812Smarcel } 119130812Smarcel , 120130812Smarcel { 121130812Smarcel 0x17, 0xdc000 122130812Smarcel } 123130812Smarcel , 124130812Smarcel 0 125130812Smarcel}; 126130812Smarcel 127130812Smarcel#define get_ds_base() 0 128130812Smarcel 129130812Smarcelstatic int 130130812Smarcele7000pc_init (void) 131130812Smarcel{ 132130812Smarcel int try; 133130812Smarcel unsigned long dsbase; 134130812Smarcel 135130812Smarcel dsbase = get_ds_base (); 136130812Smarcel 137130812Smarcel /* Look around in memory for the board's signature */ 138130812Smarcel 139130812Smarcel for (try = 0; sigs[try].sw; try++) 140130812Smarcel { 141130812Smarcel int val; 142130812Smarcel board_at = sigs[try].addr - dsbase; 143130812Smarcel fa = board_at + OFF_FA; 144130812Smarcel fb = board_at + OFF_FB; 145130812Smarcel cpd = board_at + OFF_CPD; 146130812Smarcel cdp = board_at + OFF_CDP; 147130812Smarcel ready = board_at + OFF_READY; 148130812Smarcel pon = board_at + OFF_PON; 149130812Smarcel irqtop = board_at + OFF_IRQTOP; 150130812Smarcel irqtod = board_at + OFF_IRQTOD; 151130812Smarcel 152130812Smarcel val = GET_WORD (ready); 153130812Smarcel 154130812Smarcel if (val == (0xaaa0 | sigs[try].sw)) 155130812Smarcel { 156130812Smarcel if (GET_WORD (pon) & 0xf) 157130812Smarcel { 158130812Smarcel SET_WORD (fa, 0); 159130812Smarcel SET_WORD (fb, 0); 160130812Smarcel 161130812Smarcel SET_WORD (irqtop, 1); /* Disable interrupts from e7000 */ 162130812Smarcel SET_WORD (ready, 1); 163130812Smarcel printf_filtered ("\nConnected to the E7000PC at address 0x%x\n", 164130812Smarcel sigs[try].addr); 165130812Smarcel return 1; 166130812Smarcel } 167130812Smarcel error ("The E7000 PC board is working, but the E7000 is turned off.\n"); 168130812Smarcel return 0; 169130812Smarcel } 170130812Smarcel } 171130812Smarcel 172130812Smarcel error ("GDB cannot connect to the E7000 PC board, check that it is installed\n\ 173130812Smarceland that the switch settings are correct. Some other DOS programs can \n\ 174130812Smarcelstop the board from working. Try starting from a very minimal boot, \n\ 175130812Smarcelperhaps you need to disable EMM386 over the region where the board has\n\ 176130812Smarcelits I/O space, remove other unneeded cards, etc etc\n"); 177130812Smarcel return 0; 178130812Smarcel 179130812Smarcel} 180130812Smarcel 181130812Smarcelstatic int pbuf_size; 182130812Smarcelstatic int pbuf_index; 183130812Smarcel 184130812Smarcel/* Return next byte from cdp. If no more, then return -1. */ 185130812Smarcel 186130812Smarcelstatic int 187130812Smarcele7000_get (void) 188130812Smarcel{ 189130812Smarcel static char pbuf[1000]; 190130812Smarcel char tmp[1000]; 191130812Smarcel int x; 192130812Smarcel 193130812Smarcel if (pbuf_index < pbuf_size) 194130812Smarcel { 195130812Smarcel x = pbuf[pbuf_index++]; 196130812Smarcel } 197130812Smarcel else if ((GET_WORD (fb) & 1)) 198130812Smarcel { 199130812Smarcel int i; 200130812Smarcel pbuf_size = GET_WORD (cdp + 2); 201130812Smarcel 202130812Smarcel dosmemget (cdp + 8, pbuf_size + 1, tmp); 203130812Smarcel 204130812Smarcel /* Tell the E7000 we've eaten */ 205130812Smarcel SET_WORD (fb, 0); 206130812Smarcel /* Swap it around */ 207130812Smarcel for (i = 0; i < pbuf_size; i++) 208130812Smarcel { 209130812Smarcel pbuf[i] = tmp[i ^ 1]; 210130812Smarcel } 211130812Smarcel pbuf_index = 0; 212130812Smarcel x = pbuf[pbuf_index++]; 213130812Smarcel } 214130812Smarcel else 215130812Smarcel { 216130812Smarcel x = -1; 217130812Smarcel } 218130812Smarcel return x; 219130812Smarcel} 220130812Smarcel 221130812Smarcel/* Works just like read(), except that it takes a TIMEOUT in seconds. Note 222130812Smarcel that TIMEOUT == 0 is a poll, and TIMEOUT == -1 means wait forever. */ 223130812Smarcel 224130812Smarcelstatic int 225130812Smarceldosasync_read (int fd, char *buf, int len, int timeout) 226130812Smarcel{ 227130812Smarcel long now; 228130812Smarcel long then; 229130812Smarcel int i = 0; 230130812Smarcel 231130812Smarcel /* Then look for some more if we're still hungry */ 232130812Smarcel time (&now); 233130812Smarcel then = now + timeout; 234130812Smarcel while (i < len) 235130812Smarcel { 236130812Smarcel int ch = e7000_get (); 237130812Smarcel 238130812Smarcel /* While there's room in the buffer, and we've already 239130812Smarcel read the stuff in, suck it over */ 240130812Smarcel if (ch != -1) 241130812Smarcel { 242130812Smarcel buf[i++] = ch; 243130812Smarcel while (i < len && pbuf_index < pbuf_size) 244130812Smarcel { 245130812Smarcel ch = e7000_get (); 246130812Smarcel if (ch == -1) 247130812Smarcel break; 248130812Smarcel buf[i++] = ch; 249130812Smarcel } 250130812Smarcel } 251130812Smarcel 252130812Smarcel time (&now); 253130812Smarcel 254130812Smarcel if (timeout == 0) 255130812Smarcel return i; 256130812Smarcel if (now >= then && timeout > 0) 257130812Smarcel { 258130812Smarcel return i; 259130812Smarcel } 260130812Smarcel } 261130812Smarcel return len; 262130812Smarcel} 263130812Smarcel 264130812Smarcel 265130812Smarcelstatic int 266130812Smarceldosasync_write (int fd, const char *buf, int len) 267130812Smarcel{ 268130812Smarcel int i; 269130812Smarcel char dummy[1000]; 270130812Smarcel 271130812Smarcel /* Construct copy locally */ 272130812Smarcel ((short *) dummy)[0] = CMD_CI; 273130812Smarcel ((short *) dummy)[1] = len; 274130812Smarcel ((short *) dummy)[2] = 0; 275130812Smarcel ((short *) dummy)[3] = 0; 276130812Smarcel for (i = 0; i < len; i++) 277130812Smarcel { 278130812Smarcel dummy[(8 + i) ^ 1] = buf[i]; 279130812Smarcel } 280130812Smarcel 281130812Smarcel /* Wait for the card to get ready */ 282130812Smarcel while (GET_WORD (fa) & 1); 283130812Smarcel 284130812Smarcel /* Blast onto the ISA card */ 285130812Smarcel dosmemput (dummy, 8 + len + 1, cpd); 286130812Smarcel 287130812Smarcel SET_WORD (fa, 1); 288130812Smarcel SET_WORD (irqtod, 1); /* Interrupt the E7000 */ 289130812Smarcel 290130812Smarcel return len; 291130812Smarcel} 292130812Smarcel 293130812Smarcelstatic int 294130812Smarcele7000pc_open (struct serial *scb, const char *name) 295130812Smarcel{ 296130812Smarcel if (strncasecmp (name, "pc", 2) != 0) 297130812Smarcel { 298130812Smarcel errno = ENOENT; 299130812Smarcel return -1; 300130812Smarcel } 301130812Smarcel 302130812Smarcel scb->fd = e7000pc_init (); 303130812Smarcel 304130812Smarcel if (!scb->fd) 305130812Smarcel return -1; 306130812Smarcel 307130812Smarcel return 0; 308130812Smarcel} 309130812Smarcel 310130812Smarcelstatic int 311130812Smarcele7000pc_noop (struct serial *scb) 312130812Smarcel{ 313130812Smarcel return 0; 314130812Smarcel} 315130812Smarcel 316130812Smarcelstatic void 317130812Smarcele7000pc_raw (struct serial *scb) 318130812Smarcel{ 319130812Smarcel /* Always in raw mode */ 320130812Smarcel} 321130812Smarcel 322130812Smarcelstatic int 323130812Smarcele7000pc_readchar (struct serial *scb, int timeout) 324130812Smarcel{ 325130812Smarcel char buf; 326130812Smarcel 327130812Smarceltop: 328130812Smarcel 329130812Smarcel if (dosasync_read (scb->fd, &buf, 1, timeout)) 330130812Smarcel { 331130812Smarcel if (buf == 0) 332130812Smarcel goto top; 333130812Smarcel return buf; 334130812Smarcel } 335130812Smarcel else 336130812Smarcel return SERIAL_TIMEOUT; 337130812Smarcel} 338130812Smarcel 339130812Smarcelstruct e7000pc_ttystate 340130812Smarcel{ 341130812Smarcel int dummy; 342130812Smarcel}; 343130812Smarcel 344130812Smarcel/* e7000pc_{get set}_tty_state() are both dummys to fill out the function 345130812Smarcel vector. Someday, they may do something real... */ 346130812Smarcel 347130812Smarcelstatic serial_ttystate 348130812Smarcele7000pc_get_tty_state (struct serial *scb) 349130812Smarcel{ 350130812Smarcel struct e7000pc_ttystate *state; 351130812Smarcel 352130812Smarcel state = (struct e7000pc_ttystate *) xmalloc (sizeof *state); 353130812Smarcel 354130812Smarcel return (serial_ttystate) state; 355130812Smarcel} 356130812Smarcel 357130812Smarcelstatic int 358130812Smarcele7000pc_set_tty_state (struct serial *scb, serial_ttystate ttystate) 359130812Smarcel{ 360130812Smarcel return 0; 361130812Smarcel} 362130812Smarcel 363130812Smarcelstatic int 364130812Smarcele7000pc_noflush_set_tty_state (struct serial *scb, 365130812Smarcel serial_ttystate new_ttystate, 366130812Smarcel serial_ttystate old_ttystate) 367130812Smarcel{ 368130812Smarcel return 0; 369130812Smarcel} 370130812Smarcel 371130812Smarcelstatic void 372130812Smarcele7000pc_print_tty_state (struct serial *scb, 373130812Smarcel serial_ttystate ttystate, 374130812Smarcel struct ui_file *stream) 375130812Smarcel{ 376130812Smarcel /* Nothing to print. */ 377130812Smarcel return; 378130812Smarcel} 379130812Smarcel 380130812Smarcelstatic int 381130812Smarcele7000pc_setbaudrate (struct serial *scb, int rate) 382130812Smarcel{ 383130812Smarcel return 0; 384130812Smarcel} 385130812Smarcel 386130812Smarcelstatic int 387130812Smarcele7000pc_setstopbits (struct serial *scb, int rate) 388130812Smarcel{ 389130812Smarcel return 0; 390130812Smarcel} 391130812Smarcel 392130812Smarcelstatic int 393130812Smarcele7000pc_write (struct serial *scb, const char *str, int len) 394130812Smarcel{ 395130812Smarcel dosasync_write (scb->fd, str, len); 396130812Smarcel 397130812Smarcel return 0; 398130812Smarcel} 399130812Smarcel 400130812Smarcelstatic void 401130812Smarcele7000pc_close (struct serial *scb) 402130812Smarcel{ 403130812Smarcel} 404130812Smarcel 405130812Smarcelstatic struct serial_ops e7000pc_ops = 406130812Smarcel{ 407130812Smarcel "pc", 408130812Smarcel 0, 409130812Smarcel e7000pc_open, 410130812Smarcel e7000pc_close, 411130812Smarcel e7000pc_readchar, 412130812Smarcel e7000pc_write, 413130812Smarcel e7000pc_noop, /* flush output */ 414130812Smarcel e7000pc_noop, /* flush input */ 415130812Smarcel e7000pc_noop, /* send break -- currently used only for nindy */ 416130812Smarcel e7000pc_raw, 417130812Smarcel e7000pc_get_tty_state, 418130812Smarcel e7000pc_set_tty_state, 419130812Smarcel e7000pc_print_tty_state, 420130812Smarcel e7000pc_noflush_set_tty_state, 421130812Smarcel e7000pc_setbaudrate, 422130812Smarcel e7000pc_setstopbits, 423130812Smarcel e7000pc_noop, /* wait for output to drain */ 424130812Smarcel}; 425130812Smarcel 426130812Smarcel#endif /*_WIN32 or __GO32__*/ 427130812Smarcel 428130812Smarcelextern initialize_file_ftype _initialize_ser_e7000pc; /* -Wmissing-prototypes */ 429130812Smarcel 430130812Smarcelvoid 431130812Smarcel_initialize_ser_e7000pc (void) 432130812Smarcel{ 433130812Smarcel#if defined __GO32__ || defined _WIN32 434130812Smarcel serial_add_interface (&e7000pc_ops); 435130812Smarcel#endif 436130812Smarcel} 437