⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nindy.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * 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: nindy.c,v 1.1.1.1 1991/03/28 16:20:57 rich Exp $";/****************************************************************************** * *	 		NINDY INTERFACE ROUTINES * * The routines in this file define and implement an interface between code * (such as a high-level debugger) running on a remote host and the NINDY * ROM monitor on an i960 board.  These routines are to be linked with  * and called by the host code. * * These routines handle both the formatting/transferring of commands to NINDY * and the receipt/formatting of data returned in response to them.  The * actual transfer protocol is hidden from the host programmer within them. * For a full description of the lowest level NINDY/host transfer protocol, * see the block header of the file gdb.c, in the NINDY source code. * * The caller of these routines should be aware that: * * (1) ninConnect() should be called to open communications with the *     remote NINDY board before any of the other routines are invoked. * * (2) almost all interactions are driven by the host: nindy sends information *     in response to host commands. * * (3) the lone exception to (2) is the single character DLE (^P, 0x10). *     Receipt of a DLE from NINDY indicates that the application program *     running under NINDY has stopped execution and that NINDY is now *     available to talk to the host (all other communication received after *     the application has been started should be presumed to come from the *     application and should be passed on by the host to stdout). * * (4) the reason the application program stopped can be determined with the *     ninStopWhy() function.  There are three classes of stop reasons: * *	(a) the application has terminated execution. *	    The host should take appropriate action. * *	(b) the application had a fault or trace event. *	    The host should take appropriate action. * *	(c) the application wishes to make a service request (srq) of the host; *	    e.g., to open/close a file, read/write a file, etc.  The ninSrq() *	    function should be called to determine the nature of the request *	    and process it. * * WARNING: Changes made here should be tested in both gdb960 and comm960. * ******************************************************************************/#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"#	include <sys/time.h>#endif#ifndef ERROR#define ERROR	-1#endif#define DLE	0x10	/* ^P */#define XON	0x11	/* ^Q */#define XOFF	0x13	/* ^S */#define ESC	0x1b#define REGISTER_BYTES	((36*4) + (4*8))#define TIMEOUT		-1extern char *malloc();extern void free();static int quiet = 0;	/* 1 => stifle unnecessary messages */static int nindy_fd;	/* File descriptor of tty connected to 960/NINDY board*/static int old_nindy = 0; /* 1 => use old (hex) communication protocol */static ninStrGet();		/****************************		 *                          *		 *  MISCELLANEOUS UTILTIES  *		 *                          *		 ****************************/#if 0/****************************************************************************** * byteswap: *	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. * ******************************************************************************/staticlongbyteswap( 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;}#endif /****************************************************************************** * get_int: *	Copy the little-endian integer pointed at by 'p'  and return it in *	the host byte order.  'p' may be an unaligned address, so do the copy *	a byte at a time. ******************************************************************************/intget_int( p )    unsigned char *p;{	int n;	int i;	n = 0;	p += sizeof(int) - 1;	for ( i = 0; i < sizeof(n); i++ ){		n <<= 8;		n |= *p--;	}	return n;}/****************************************************************************** * put_int: *	Copy the integer 'n' (which is in host byte order) to the location *	pointed at by 'p', leaving it in little-endian byte order. *	'p' may be an unaligned address, so do the move a byte at a time. ******************************************************************************/intput_int( p, n )    unsigned char *p;    int n;{	int i;	for ( i = 0; i < sizeof(n); i++ ){		*p++ = n;		n >>= 8;	}}/****************************************************************************** * 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. ******************************************************************************//* FIXME: use varargs for this.  */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  *		 *                           *		 *****************************//****************************************************************************** * timed_read: *	Read up to 'n' characters (less if fewer are available) from the NINDY *	tty. Wait up to 'timeout' seconds for something to arrive.  Return *	the number of characters read, 0 on timeout. ******************************************************************************/#ifdef USGstatic int saw_alarm;static voidalarm_handler(){	saw_alarm = 1;}staticinttimed_read(buf,n,timeout)    unsigned char * buf;	/* Where to put the read characters	*/    int n;			/* Max number of characters to read	*/    int timeout;		/* Timeout, in seconds			*/{        void (*old_alarm)();    /* Save alarm signal handler here on entry */	int cnt;        old_alarm = signal( SIGALRM,alarm_handler );        saw_alarm = 0;        alarm(timeout);        do {		cnt = n;                TTY_NBREAD(nindy_fd,cnt,buf);        } while ( (cnt <= 0) && !saw_alarm );        alarm(0);        signal( SIGALRM,old_alarm );	return saw_alarm ? 0 : cnt;}#else		/* BSD */staticinttimed_read(buf,n,timeout)    unsigned char * buf;	/* Where to put the read characters	*/    int n;			/* Max number of characters to read	*/    int timeout;		/* Timeout, in seconds			*/{	struct timeval t;	fd_set f;	t.tv_sec = (long) timeout;	t.tv_usec= 0;	FD_ZERO( &f );	FD_SET( nindy_fd, &f );	if ( select(nindy_fd+1,&f,0,0,&t) ){		return read( nindy_fd, buf, n );	} else {		return 0;	}}#endif/****************************************************************************** * rdnin: *	Read *exactly* 'n' characters from the NINDY tty.  Translate escape *	sequences into single characters, counting each such sequence as  *	1 character. * *	An escape sequence consists of ESC and a following character.  The *	ESC is discarded and the other character gets bit 0x40 cleared -- *	thus ESC P == ^P, ESC S == ^S, ESC [ == ESC, etc. * *	Return 1 if successful, 0 if more than 'timeout' seconds pass without *	any input. ******************************************************************************/staticintrdnin(buf,n,timeout)    unsigned char * buf;	/* Where to place characters read	*/    int n;			/* Number of characters to read		*/    int timeout;		/* Timeout, in seconds			*/{	static unsigned char *mybuf = NULL;				/* Dynamically allocated local buffer */	static int mybuflen = 0;				/* Current size of local buffer	*/	int escape_seen;	/* 1 => last character of a read was an ESC */	int nread;		/* Number of chars returned by timed_read() */	unsigned char c;	int i;	/* Make sure local buffer is big enough	 */	if ( n > mybuflen ){		if ( mybuf ){			free( mybuf );		}		mybuf = (unsigned char *) malloc( mybuflen=n );	}	/* More than one loop will be necessary if there are any	 * escape sequences in the input	 */	escape_seen = 0;	while ( n ){		nread = timed_read(mybuf,n,timeout);		if ( nread <= 0 ){			return 0;	/* TIMED OUT */		}		/* Copy characters from local buffer to caller's buffer,		 * converting escape sequences as they're encountered.		 */		for ( i = 0; i < nread; i++ ){			c = mybuf[i];			if ( escape_seen ){				escape_seen = 0;				c &= ~0x40;			} else if ( c == ESC ){				if ( ++i >= nread ){					/* Need to refill local buffer */					escape_seen = 1;					break;				}				c = mybuf[i] & ~0x40;			}			*buf++ = c;			n--;		}	}	return 1;}/****************************************************************************** * getpkt: *	Read a packet from a remote NINDY, with error checking, into the *	indicated buffer. * *	Return packet status byte on success, TIMEOUT on failure. ******************************************************************************/staticintgetpkt(buf)     unsigned char *buf;{	int i;	unsigned char hdr[3];	/* Packet header:				 *	hdr[0] = low byte of message length				 *	hdr[1] = high byte of message length				 *	hdr[2] = message status				 */	int cnt;		/* Message length (status byte + data)	*/	unsigned char cs_calc;	/* Checksum calculated			*/	unsigned char cs_recv;	/* Checksum received			*/	static char errfmt[] =			"Bad checksum (recv=0x%02x; calc=0x%02x); retrying\r\n";	while (1){		if ( !rdnin(hdr,3,5) ){			return TIMEOUT;		}		cnt = (hdr[1]<<8) + hdr[0] - 1;					/* -1 for status byte (already read) */		/* Caller's buffer may only be big enough for message body,		 * without status byte and checksum, so make sure to read		 * checksum into a separate buffer.		 */		if ( !rdnin(buf,cnt,5) || !rdnin(&cs_recv,1,5) ){			return TIMEOUT;		}		/* Calculate checksum		 */		cs_calc = hdr[0] + hdr[1] + hdr[2];		for ( i = 0; i < cnt; i++ ){			cs_calc += buf[i];		}		if ( cs_calc == cs_recv ){			write (nindy_fd, "+", 1);			return hdr[2];		}	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -