📄 onindy.c
字号:
/***************************************************************************** * Copyright 1990, 1992 Free Software Foundation, Inc. * * This code was donated by Intel Corp. * * Intel hereby grants you permission to copy, modify, and * distribute this software and its documentation. Intel grants * this permission provided that the above copyright notice * appears in all copies and that both the copyright notice and * this permission notice appear in supporting documentation. In * addition, Intel grants this permission provided that you * prominently mark as not part of the original any modifications * made to this software or documentation, and that the name of * Intel Corporation not be used in advertising or publicity * pertaining to distribution of the software or the documentation * without specific, written prior permission. * * Intel Corporation does not warrant, guarantee or make any * representations regarding the use of, or the results of the use * of, the software and documentation in terms of correctness, * accuracy, reliability, currentness, or otherwise; and you rely * on the software, documentation and results solely at your own risk. *****************************************************************************/static char rcsid[] = "Id: Onindy.c,v 1.1.1.1 1991/03/28 16:20:43 rich Exp $";/****************************************************************************** * * NINDY INTERFACE ROUTINES * * This version of the NINDY interface routines supports NINDY versions * 2.13 and older. The older versions used a hex communication protocol, * instead of the (faster) current binary protocol. These routines have * been renamed by prepending the letter 'O' to their names, to avoid * conflict with the current version. The old versions are kept only for * backward compatibility, and well disappear in a future release. * ******************************************************************************/#include <stdio.h>#include <sys/ioctl.h>#include <sys/types.h> /* Needed by file.h on Sys V */#include <sys/file.h>#include <signal.h>#include <sys/stat.h>#include <fcntl.h> /* Needed on Sys V */#include "ttycntl.h"#include "block_io.h"#include "wait.h"#include "env.h"#ifdef USG# include <unistd.h># include "sysv.h"#else /* BSD */# include "string.h"#endif#ifndef TRUE#define TRUE 1#endif#ifndef FALSE#define FALSE 0#endif#ifndef ERROR#define ERROR -1#endif#define REGISTER_BYTES ((36*4) + (4*8))extern char *malloc();extern void free ();static int quiet; /* TRUE => stifle unnecessary messages */static int nindy_fd; /* File descriptor of tty connected to 960/NINDY board*/static OninStrGet(); /**************************** * * * MISCELLANEOUS UTILTIES * * * ****************************//****************************************************************************** * fromhex: * Convert a hex ascii digit h to a binary integer ******************************************************************************/staticintfromhex( h ) int h;{ if (h >= '0' && h <= '9'){ h -= '0'; } else if (h >= 'a' && h <= 'f'){ h -= 'a' - 10; } else { h = 0; } return (h & 0xff);}/****************************************************************************** * hexbin: * Convert a string of ASCII hex digits to a string of binary bytes. ******************************************************************************/statichexbin( n, hexp, binp ) int n; /* Number of bytes to convert (twice this many digits)*/ char *hexp; /* Get hex from here */ char *binp; /* Put binary here */{ while ( n-- ){ *binp++ = (fromhex(*hexp) << 4) | fromhex(*(hexp+1)); hexp += 2; }}/****************************************************************************** * binhex: * Convert a string of binary bytes to a string of ASCII hex digits ******************************************************************************/staticbinhex( n, binp, hexp ) int n; /* Number of bytes to convert */ char *binp; /* Get binary from here */ char *hexp; /* Place hex here */{ static char tohex[] = "0123456789abcdef"; while ( n-- ){ *hexp++ = tohex[ (*binp >> 4) & 0xf ]; *hexp++ = tohex[ *binp & 0xf ]; binp++; }}/****************************************************************************** * byte_order: * If the host byte order is different from 960 byte order (i.e., the * host is big-endian), reverse the bytes in the passed value; otherwise, * return the passed value unchanged. * ******************************************************************************/staticlongbyte_order( n ) long n;{ long rev; int i; static short test = 0x1234; if (*((char *) &test) == 0x12) { /* * Big-endian host, swap the bytes. */ rev = 0; for ( i = 0; i < sizeof(n); i++ ){ rev <<= 8; rev |= n & 0xff; n >>= 8; } n = rev; } return n;}/****************************************************************************** * say: * This is a printf that takes at most two arguments (in addition to the * format string) and that outputs nothing if verbose output has been * suppressed. ******************************************************************************/staticsay( fmt, arg1, arg2 ) char *fmt; int arg1, arg2;{ if ( !quiet ){ printf( fmt, arg1, arg2 ); fflush( stdout ); }}/****************************************************************************** * exists: * Creates a full pathname by concatenating up to three name components * onto a specified base name; optionally looks up the base name as a * runtime environment variable; and checks to see if the file or * directory specified by the pathname actually exists. * * Returns: the full pathname if it exists, NULL otherwise. * (returned pathname is in malloc'd memory and must be freed * by caller). *****************************************************************************/staticchar *exists( base, c1, c2, c3, env ) char *base; /* Base directory of path */ char *c1, *c2, *c3; /* Components (subdirectories and/or file name) to be * appended onto the base directory name. One or * more may be omitted by passing NULL pointers. */ int env; /* If 1, '*base' is the name of an environment variable * to be examined for the base directory name; * otherwise, '*base' is the actual name of the * base directory. */{ struct stat buf;/* For call to 'stat' -- never examined */ char *path; /* Pointer to full pathname (malloc'd memory) */ int len; /* Length of full pathname (incl. terminator) */ extern char *getenv(); if ( env ){ base = getenv( base ); if ( base == NULL ){ return NULL; } } len = strlen(base) + 4; /* +4 for terminator and "/" before each component */ if ( c1 != NULL ){ len += strlen(c1); } if ( c2 != NULL ){ len += strlen(c2); } if ( c3 != NULL ){ len += strlen(c3); } path = malloc( len ); strcpy( path, base ); if ( c1 != NULL ){ strcat( path, "/" ); strcat( path, c1 ); if ( c2 != NULL ){ strcat( path, "/" ); strcat( path, c2 ); if ( c3 != NULL ){ strcat( path, "/" ); strcat( path, c3 ); } } } if ( stat(path,&buf) != 0 ){ free( path ); path = NULL; } return path;} /***************************** * * * LOW-LEVEL COMMUNICATION * * * *****************************//****************************************************************************** * readchar: * Wait for a character to come in on the NINDY tty, and return it. ******************************************************************************/staticreadchar(){ unsigned char c; while (read(nindy_fd,&c,1) != 1){ ; } return c;}/****************************************************************************** * getpkt: * Read a packet from a remote NINDY, with error checking, and return * it in the indicated buffer. ******************************************************************************/staticgetpkt (buf) char *buf;{ unsigned char recv; /* Checksum received */ unsigned char csum; /* Checksum calculated */ char *bp; /* Poointer into the buffer */ int c; while (1){ csum = 0; bp = buf; while ( (c = readchar()) != '#' ){ *bp++ = c; csum += c; } *bp = 0; recv = fromhex(readchar()) << 4; recv |= fromhex(readchar()); if ( csum == recv ){ break; } fprintf(stderr, "Bad checksum (recv=0x%02x; calc=0x%02x); retrying\r\n", recv, csum ); write (nindy_fd, "-", 1); } write (nindy_fd, "+", 1);}/****************************************************************************** * putpkt: * Checksum and send a gdb command to a remote NINDY, and wait for * positive acknowledgement. * ******************************************************************************/staticputpkt( cmd ) char *cmd; /* Command to be sent, without lead ^P (\020) * or trailing checksum */{ char ack; /* Response received from NINDY */ char checksum[4]; char *p; unsigned int s; char resend; for ( s='\020', p=cmd; *p; p++ ){ s += *p; } sprintf( checksum, "#%02x", s & 0xff ); /* Send checksummed message over and over until we get a positive ack */ resend = TRUE; do { if ( resend ){ write( nindy_fd, "\020", 1 ); write( nindy_fd, cmd, strlen(cmd) ); write( nindy_fd, checksum, strlen(checksum) ); } if ( read( nindy_fd, &ack, 1 ) != 1 ){ fprintf(stderr,"oink\n"); } if ( ack == '-' ){ fprintf( stderr, "Remote NAK, resending\r\n" ); resend = TRUE; } else if ( ack != '+' ){ fprintf( stderr, "Bad ACK, ignored: <%c>\r\n", ack ); resend = FALSE; } } while ( ack != '+' );}/****************************************************************************** * send: * Send a message to a remote NINDY and return the reply in the same * buffer (clobbers the input message). Check for error responses * as indicated by the second argument. * ******************************************************************************/staticsend( buf, ack_required )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -