OSDN Git Service

Initial revision
[pf3gnuchains/pf3gnuchains4x.git] / utils / amd-udi / montip / tdfunc.c
1 static char _[] = "@(#)tdfunc.c 5.25 93/10/28 08:44:32, Srini, AMD.";
2 /******************************************************************************
3  * Copyright 1991 Advanced Micro Devices, Inc.
4  *
5  * This software is the property of Advanced Micro Devices, Inc  (AMD)  which
6  * specifically  grants the user the right to modify, use and distribute this
7  * software provided this notice is not removed or altered.  All other rights
8  * are reserved by AMD.
9  *
10  * AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS
11  * SOFTWARE.  IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL
12  * DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR
13  * USE OF THIS SOFTWARE.
14  *
15  * So that all may benefit from your experience, please report  any  problems
16  * or  suggestions about this software to the 29K Technical Support Center at
17  * 800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131  in  the  UK,  or
18  * 0031-11-1129 in Japan, toll free.  The direct dial number is 512-462-4118.
19  *
20  * Advanced Micro Devices, Inc.
21  * 29K Support Products
22  * Mail Stop 573
23  * 5900 E. Ben White Blvd.
24  * Austin, TX 78741
25  * 800-292-9263
26  *****************************************************************************
27  *      Engineer: Srini Subramanian.
28  *****************************************************************************
29  * This module contains the functions to initialize, read, and write to the
30  * serial port on an Unix-based machine.
31  *****************************************************************************
32  */
33
34 /* This file contains the Target Dependent Functions used by Minimon's
35  * Message System.
36  */
37
38 #include  <stdio.h>
39
40 #include  <fcntl.h>
41 #include  <termio.h>
42
43 #ifdef __hpux
44 #include <sys/modem.h>
45 #endif
46
47 #include  "messages.h"
48 #include  "tdfunc.h"
49 #include  "mtip.h"
50 #include  "macros.h"
51
52 /* Serial connection */
53 /* 
54 ** Serial port routines
55 */
56
57 /*definitions */
58 #define BAUD_RATE       B9600
59 #define CHAR_SIZE         CS8
60 #define STOP_BITS           0
61 #define PARITY_ENABLE       0
62 #define PARITY              0
63
64 #define CH0_BUFFER_SIZE  1024
65
66 #define BLOCK 1
67 #define NOBLOCK 0
68
69 /* Global for serial */
70
71 static  int   msg_port;
72 static  INT32  in_byte_count=0;
73
74 extern  int     BlockCount;
75
76 /*
77 ** This function is used to initialize the communication
78 ** channel.  This consists of basically opening the com
79 ** port for reading and writing.
80 **
81 ** With Sun UNIX, each time the port is opened, the communication
82 ** parameters are reset to default values.  These default values for
83 ** the serial port are currently 9600 baud, 7 bits, even parity.
84 */
85
86 INT32
87 init_comm_serial(ignore1, ignore2)
88 INT32 ignore1;
89 INT32 ignore2;
90    {
91    int      result;
92    unsigned short  baud;
93    struct   termio tbuf;
94 #ifdef __hpux
95    mflag        mbits;
96 #else
97    int          mbits;
98 #endif
99    int          cd;     /* carrier detect */
100
101    /* Open serial port */   
102    if ((msg_port = open(tip_config.comm_port, O_NDELAY|O_RDWR)) == -1) {
103       return (-1);
104    }
105
106    /* Get baud rate */
107    if (strcmp(tip_config.baud_rate, "300") == 0)
108       baud = B300;
109    else
110    if (strcmp(tip_config.baud_rate, "600") == 0)
111       baud = B600;
112    else
113    if (strcmp(tip_config.baud_rate, "1200") == 0)
114       baud = B1200;
115    else
116    if (strcmp(tip_config.baud_rate, "2400") == 0)
117       baud = B2400;
118    else
119    if (strcmp(tip_config.baud_rate, "4800") == 0)
120       baud = B4800;
121    else
122    if (strcmp(tip_config.baud_rate, "9600") == 0)
123       baud = B9600;
124    else
125    if (strcmp(tip_config.baud_rate, "19200") == 0)
126       baud = B19200;
127    else
128    if (strcmp(tip_config.baud_rate, "38400") == 0)
129       baud = B38400;
130    else
131       return(-1);
132
133
134    /* Set up new parameters */
135    /* Get termio (for modification) */
136    result = ioctl(msg_port, TCGETA, &tbuf);
137    if (result == -1)
138       return (-1);
139
140    /*
141    ** Note:  On a Sun III, the port comes up at 9600 baud,
142    ** 7 bits, even parity, with read enabled.  We will change
143    ** this to 8 bits, no parity (with RTS/CTS handshaking).
144    ** We will also set I/O to "raw" mode.
145    */
146
147    /* Set up new parameters */
148    tbuf.c_iflag = 0;
149    tbuf.c_oflag = 0;
150    tbuf.c_cflag = (baud          | CHAR_SIZE | STOP_BITS | CREAD |
151                    PARITY_ENABLE | PARITY   );
152    tbuf.c_lflag = 0;
153    tbuf.c_cc[VMIN] = 0;  /* Number of characters to satisfy read */
154 #ifdef __hpux
155    tbuf.c_cc[VTIME] = 100;  /* intercharacter timer interval in seconds */
156 #else
157    tbuf.c_cc[VTIME] = 1;  /* intercharacter timer interval in seconds */
158 #endif
159
160    /* Set termio to new mode */
161    result = ioctl(msg_port, TCSETA, &tbuf);
162    if (result == -1)
163       return (-1);
164
165 #ifdef __hpux
166    /* modem status */
167    (void) ioctl (msg_port, MCGETA, &mbits);
168    mbits = (MDSR|MDTR|MRTS);
169    (void) ioctl (msg_port, MCSETA, &mbits);
170 #else
171    /* modem status */
172    (void) ioctl (msg_port, TIOCMGET, &mbits);
173    mbits  = (TIOCM_DTR|TIOCM_RTS);
174    (void) ioctl (msg_port, TIOCMSET, &mbits);
175 #endif
176
177    /* FLush queue */
178    if (ioctl(msg_port, TCFLSH, 2) == -1)
179       return (-1);
180
181    return(0);
182    }  /* end init_comm_serial() */
183
184
185 /*
186 ** This function is used to send a message over the
187 ** serial line.
188 **
189 ** If the message is successfully sent, a zero is
190 ** returned.  If the message was not sendable, a -1
191 ** is returned.  This function blocks.  That is, it
192 ** does not return until the message is completely
193 ** sent, or until an error is encountered.
194 **
195 */
196
197 INT32
198 send_bfr_serial(bfr_ptr, length, port_base, comm_err)
199    BYTE  *bfr_ptr;
200    INT32 length;
201    INT32 port_base;
202    INT32 *comm_err;
203    {
204    int    result;
205
206    /* Send message */
207    result = write(msg_port, (char *)bfr_ptr, length);
208    if (result != length)
209       return (-1);
210    else
211       return (0);
212
213    }  /* end msg_send_serial() */
214
215
216 /*
217 ** This function is used to receive a message over a
218 ** serial line.
219 **
220 ** If the message is waiting in the buffer, a zero is
221 ** returned and the buffer pointed to by msg_ptr is filled
222 ** in.  If no message was available, a -1 is returned.
223 **
224 */
225
226 /* Read as many characters as are coming and return the number of character
227  * read into the buffer.
228  * Buffer : pointer to the receiving buffer.
229  * nbytes : number of bytes requested.
230  * Mode   : Blocking/Non-blocking mode. In blocking mode, this will not
231  *          return until atleast a character is received. It is used when
232  *          the TIP is to wait for a response from the target, and there is
233  *          no need to poll the keyboard.
234  * PortBase : not used.
235  * CommError : Error during communication.
236  */
237 INT32
238 recv_bfr_serial(Buffer, nbytes, Mode, PortBase, CommError)
239    BYTE  *Buffer;
240    INT32 nbytes;
241    INT32 Mode;
242    INT32 PortBase;
243    INT32 *CommError;
244    {
245    int    result;
246    unsigned char          ch;
247    INT32    count;
248    int  bcount;
249    struct termio        OrigTBuf, NewTBuf;
250
251      count = 0;
252      do {
253         if (Mode == BLOCK) {
254           bcount = 0;
255           while (bcount++ < BlockCount) {
256             if ((result = read(msg_port, (char *)&ch, 1)) == 1) { /* success */
257               *Buffer++ = (BYTE) ch;
258               count = count + 1;
259               bcount = 0;
260             };
261             if (count == nbytes)
262               return (0);
263           };
264           return ((INT32) -1);
265         } else { /* non-block */
266           if ((result = read(msg_port, (char *)&ch, 1)) == 1) { /* success */
267             *Buffer++ = (BYTE) ch;
268             count = count + 1;
269           } else { /* Timed out */
270             return ((INT32) -1);
271           }
272         }
273      } while (count < nbytes);
274      return (0);
275
276 #ifdef DEBUG
277    if (Mode) { /* BLOCK while reading */
278      /*
279       * Set blocking mode by set MIN=0 and TIME > 0
280       * Here we set TIME to block for 60 seconds.
281       */
282       (void) ioctl (msg_port, TCGETA, &OrigTBuf);
283       (void) ioctl (msg_port, TCGETA, &NewTBuf);
284       NewTBuf.c_cc[4] = 0;      /* set MIN to 0 */
285       NewTBuf.c_cc[5] = 1;      /* 600 * 0.1 seconds */
286       (void) ioctl (msg_port, TCSETA, &NewTBuf);
287      count = 0;
288      do {
289         if (read(msg_port, (char *)&ch, 1) == 1) { /* success */
290           *Buffer++ = (BYTE) ch;
291           count = count + 1;
292         } else { /* Timed out */
293           (void) ioctl (msg_port, TCSETA, &OrigTBuf); /* restore termio */
294           return ((INT32) -1);
295         }
296      } while (count < nbytes);
297      (void) ioctl (msg_port, TCSETA, &OrigTBuf); /* restore termio */
298      return (0);
299    } else { /* Non blocking */
300      result = (INT32) -1;
301      count = 0;
302      while ((count < nbytes) && (read(msg_port, (char *)&ch, 1) == 1)) {
303        *Buffer++ = (BYTE) ch;
304        count = count + 1;
305        result = 0;
306      }
307      if (count == nbytes) /* read enough */
308        return (0);
309      else       /* not enough chars read */
310        return ((INT32) -1);
311    }
312 #endif
313 #if 0
314    result = read(msg_port, (char *) Buffer, nbytes); /* read as many */
315    if (result == nbytes) {
316      return (0);
317    } else {
318      return (-1);
319    }
320         if (result > 0) {
321                 in_byte_count = in_byte_count + result;
322                 block_count = 0;
323                 if (in_byte_count >= length) {
324                         /* Message received */
325                         in_byte_count = 0;
326                         return(0);
327                         }
328         } else {
329
330                 /* return if no char & not blocking */
331                 if (block == NOBLOCK) return (-1);  
332
333                 /* return if no char, blocking, and past block count */
334                 if ((block == BLOCK) && (block_count++ > BlockCount))
335                         return (-1);  
336                 }
337 #endif
338
339    }  /* end msg_recv_serial() */
340
341
342 #ifndef MSDOS
343 /*
344 ** This function is used to close the communication
345 ** channel.  This is used when resyncing the host and
346 ** target and when exiting the monitor.
347 */
348
349 INT32
350 reset_comm_pcserver(ignore1, ignore2)
351 INT32   ignore1;
352 INT32   ignore2;
353    {
354    unsigned char          ch;
355 #ifdef __hpux
356     mflag  mbits;
357 #else
358     int  mbits;
359 #endif
360
361    printf("reset:\n");
362    /* Reset message buffer counters */
363    in_byte_count = 0;
364
365 #ifdef __hpux
366    mbits = (MDSR|MDTR|MRTS);
367    (void) ioctl (msg_port, MCSETA, &mbits);
368 #else
369    mbits  = (TIOCM_DTR|TIOCM_RTS);
370    (void) ioctl (msg_port, TIOCMGET, &mbits);
371 #endif
372
373    /* Clear data from buffer */
374    if (ioctl(msg_port, TCFLSH, 2) == -1) {
375      return (-1);
376    }
377
378    return(0);
379    }  /* end reset_comm_serial() */
380 #endif
381
382 /*
383 ** This function is used to close the communication
384 ** channel.  This is used when resyncing the host and
385 ** target and when exiting the monitor.
386 */
387
388 INT32
389 reset_comm_serial(ignore1, ignore2)
390 INT32   ignore1;
391 INT32   ignore2;
392    {
393 #ifdef __hpux
394    mflag        mbits;
395 #else
396     int  mbits;
397 #endif
398
399    /* Reset message buffer counters */
400    in_byte_count = 0;
401
402 #ifdef __hpux
403    (void) ioctl (msg_port, MCGETA, &mbits);
404    mbits = (MDSR|MDTR|MRTS);
405    (void) ioctl (msg_port, MCSETA, &mbits);
406 #else
407    (void) ioctl (msg_port, TIOCMGET, &mbits);
408    mbits  = (TIOCM_DTR|TIOCM_RTS);
409    (void) ioctl (msg_port, TIOCMSET, &mbits);
410 #endif
411
412    /* Clear data from buffer */
413    if (ioctl(msg_port, TCFLSH, 2) == -1) {
414      return (-1);
415    }
416
417    return(0);
418    }  /* end reset_comm_serial() */
419
420
421 INT32
422 exit_comm_serial(ignore1, ignore2)
423 INT32   ignore1;
424 INT32   ignore2;
425    {
426    /* Reset message buffer counters */
427    in_byte_count = 0;
428
429    (void) close(msg_port);
430
431    return(0);
432    }  /* end reset_comm_serial() */
433 /*
434 ** This function is usually used to "kick-start" the target.
435 ** This is nesessary when targets are shared memory boards.
436 ** With serial communications, this function does nothing.
437 */
438
439 void
440 go_serial(port_base, msg_seg)
441 INT32 port_base;
442 INT32 msg_seg;
443    { return; }
444
445
446 INT32 
447 write_memory_serial (ignore1, ignore2, ignore3, ignore4, ignore5, ignore6)
448         INT32 ignore1;
449         ADDR32 ignore2;
450         BYTE *ignore3;
451         INT32 ignore4; 
452         INT32 ignore5;
453         INT32 ignore6; 
454
455         return(-1); }
456
457 INT32 
458 read_memory_serial (ignore1, ignore2, ignore3, ignore4, ignore5, ignore6)
459         INT32 ignore1;
460         ADDR32 ignore2;
461         BYTE *ignore3;
462         INT32 ignore4;
463         INT32 ignore5;
464         INT32 ignore6;
465 { return(-1); }
466
467 INT32
468 fill_memory_serial()
469    { return(-1); }
470
471 /*
472 ** Stubs for PC plug-in board routines
473 */
474
475 /* EB29K */
476
477 INT32  init_comm_eb29k()    {return (FAILURE);}
478 INT32  msg_send_eb29k()     {return (-1);}
479 INT32  msg_recv_eb29k()     {return (-1);}
480 INT32  reset_comm_eb29k()   {return (-1);}
481 INT32  exit_comm_eb29k()   {return (-1);}
482 void   go_eb29k()           {}
483 INT32  read_memory_eb29k()  {return (-1);}
484 INT32  write_memory_eb29k() {return (-1);}
485 INT32  fill_memory_eb29k()  {return (-1);}
486
487 /* LCB29K */
488
489 INT32  init_comm_lcb29k()   {return (FAILURE);}
490 INT32  msg_send_lcb29k()    {return (-1);}
491 INT32  msg_recv_lcb29k()    {return (-1);}
492 INT32  reset_comm_lcb29k()  {return (-1);}
493 INT32  exit_comm_lcb29k()  {return (-1);}
494 void   go_lcb29k()          {}
495 INT32  read_memory_lcb29k() {return (-1);}
496 INT32  write_memory_lcb29k(){return (-1);}
497 INT32  fill_memory_lcb29k() {return (-1);}
498
499 /* PCEB */
500
501 INT32  init_comm_pceb()     {return (FAILURE);}
502 INT32  msg_send_pceb()      {return (-1);}
503 INT32  msg_recv_pceb()      {return (-1);}
504 INT32  reset_comm_pceb()    {return (-1);}
505 INT32  exit_comm_pceb()    {return (-1);}
506 void   go_pceb()            {}
507 INT32  read_memory_pceb()   {return (-1);}
508 INT32  write_memory_pceb()  {return (-1);}
509 INT32  fill_memory_pceb()   {return (-1);}
510
511 /* EB030 */
512
513 INT32  init_comm_eb030()    {return (FAILURE);}
514 INT32  msg_send_eb030()     {return (-1);}
515 INT32  msg_recv_eb030()     {return (-1);}
516 INT32  reset_comm_eb030()   {return (-1);}
517 INT32  exit_comm_eb030()   {return (-1);}
518 void   go_eb030()           {}
519 INT32  read_memory_eb030()  {return (-1);}
520 INT32  write_memory_eb030() {return (-1);}
521 INT32  fill_memory_eb030()  {return (-1);}