T32: Integrated Register read/write calls
* Tested without connected Lauterbach. T32_* functions are mocked via aspect. * New target t32cli, for sending T32 command cia cli. (for testing) git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@2103 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
1
debuggers/gdb/README
Normal file
1
debuggers/gdb/README
Normal file
@ -0,0 +1 @@
|
||||
TODO: a nice GDB backend.
|
||||
8
debuggers/t32/CMakeLists.txt
Normal file
8
debuggers/t32/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
include_directories(include)
|
||||
|
||||
include_directories(${CMAKE_BINARY_DIR}/src/core)
|
||||
|
||||
add_subdirectory(api)
|
||||
add_subdirectory(src)
|
||||
|
||||
6
debuggers/t32/api/CMakeLists.txt
Normal file
6
debuggers/t32/api/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
set(SRCS
|
||||
hlinknet.cc
|
||||
hremote.cc
|
||||
)
|
||||
|
||||
add_library(t32api ${SRCS})
|
||||
882
debuggers/t32/api/hlinknet.cc
Normal file
882
debuggers/t32/api/hlinknet.cc
Normal file
@ -0,0 +1,882 @@
|
||||
/****************************************************************
|
||||
* *
|
||||
* Copyright notice: *
|
||||
* *
|
||||
* Lauterbach Datentechnik GmbH *
|
||||
* Alle Rechte vorbehalten - All rights reserved *
|
||||
* *
|
||||
*****************************************************************
|
||||
|
||||
Module: hlinknet.c
|
||||
Function: Low level communication protocol for talking to TRACE32.
|
||||
Is used by CAPI routined implemented in hremote.c.
|
||||
Link both files with your application.
|
||||
|
||||
***************************************************************/
|
||||
|
||||
#include "t32.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
# include <fcntl.h>
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
|
||||
#ifdef DEC_VMS
|
||||
# include <file.h>
|
||||
# include <time.h>
|
||||
# include <errno.h>
|
||||
# include <socket.h>
|
||||
# include <inet.h>
|
||||
# include <netdb.h>
|
||||
# include <in.h>
|
||||
# define DONT_USE_ASYNC
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
# include <fcntl.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/time.h>
|
||||
# include <errno.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# include <netdb.h>
|
||||
# include <sys/select.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef UNIX_V
|
||||
# include <fcntl.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/time.h>
|
||||
# include <errno.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# include <netdb.h>
|
||||
# ifdef HP_UX
|
||||
typedef int socklen_t;
|
||||
# else
|
||||
# include <sys/select.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef OS_9
|
||||
# include <fcntl.h>
|
||||
# include <sys/time.h>
|
||||
# include <errno.h>
|
||||
# include <inet/socket.h>
|
||||
# include <inet/in.h>
|
||||
# include <inet/netdb.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define PCKLEN_MAX 1472 /* maximum size of UDP-packet */
|
||||
#define BUFLEN_MIN 6000
|
||||
|
||||
#ifndef MS_WINDOWS
|
||||
# ifndef UNIX_V
|
||||
extern struct hostent * gethostbyaddr();
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef DEC_VMS
|
||||
# define fd_set int
|
||||
# define FD_ZERO(fdset) (*fdset = 0)
|
||||
# define FD_SET(fd,fdset) (*fdset |= (1<<(fd)))
|
||||
# define FD_ISSET(fd,fdset) (*fdset & (1<<(fd)))
|
||||
#endif
|
||||
|
||||
#if defined(DEC_VMS) || defined(MS_WINDOWS) || defined(OS_9) || defined(LINUX)
|
||||
# define RECEIVEADDR (&ReceiveSocketAddress)
|
||||
static struct sockaddr ReceiveSocketAddress;
|
||||
#else
|
||||
# define RECEIVEADDR 0
|
||||
#endif
|
||||
|
||||
|
||||
struct LineStruct {
|
||||
char NodeName[80]; /* node name of host running T32 SW */
|
||||
int CommSocket; /* socket for communication */
|
||||
unsigned short HostPort; /* Host side port */
|
||||
unsigned short ReceivePort; /* Receiver Port */
|
||||
unsigned short TransmitPort; /* Transmitter Port in T32 */
|
||||
int PacketSize; /* Max. size of UDP-packet data */
|
||||
int PollTimeSec;
|
||||
int ReceiveToggleBit;
|
||||
unsigned char MessageId;
|
||||
int LineUp;
|
||||
unsigned short ReceiveSeq, TransmitSeq; /* block-ids */
|
||||
unsigned short LastReceiveSeq, LastTransmitSeq;
|
||||
unsigned char* LastTransmitBuffer;
|
||||
int LastTransmitSize;
|
||||
struct sockaddr_in SocketAddress;
|
||||
};
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
extern void T32_InstallAsyncSelect(HWND hwnd, int msg);
|
||||
extern void T32_UnInstallAsyncSelect(HWND hwnd);
|
||||
#endif
|
||||
|
||||
extern void LINE_SetReceiveToggleBit(int value);
|
||||
extern int LINE_GetReceiveToggleBit(void);
|
||||
extern int LINE_GetNextMessageId(void);
|
||||
extern int LINE_GetMessageId(void);
|
||||
extern int LINE_GetLineParamsSize (void);
|
||||
extern void LINE_SetDefaultLineParams (LineStruct* params);
|
||||
extern LineStruct* LINE_GetLine0Params (void);
|
||||
extern void LINE_SetLine (LineStruct* params);
|
||||
extern int LINE_LineConfig(char * in);
|
||||
extern void LINE_LineExit(void);
|
||||
extern int LINE_LineInit(char * message);
|
||||
extern int LINE_LineTransmit(unsigned char * in, int size);
|
||||
extern int LINE_LineDriverGetSocket(void);
|
||||
extern int LINE_LineReceive(unsigned char * out);
|
||||
extern int LINE_ReceiveNotifyMessage(unsigned char* package);
|
||||
extern int LINE_LineSync(void);
|
||||
|
||||
static int Connection(unsigned char *ipaddrused);
|
||||
|
||||
static struct timeval LongTime = { 0, 500000 };
|
||||
|
||||
|
||||
|
||||
static const LineStruct LineDefaultParams = {
|
||||
"localhost", -1, 0, 0, 20000, 1024, 5, -1, 0, 0};
|
||||
static LineStruct Line0Params = {
|
||||
"localhost", -1, 0, 0, 20000, 1024, 5, -1, 0, 0};
|
||||
|
||||
static LineStruct* pLineParams = &Line0Params;
|
||||
|
||||
|
||||
|
||||
static int str2dec (char* in)
|
||||
{
|
||||
int x = 0;
|
||||
while (*in) {
|
||||
x *= 10;
|
||||
if (*in < '0' || *in > '9')
|
||||
return -1;
|
||||
x += *in - '0';
|
||||
in++;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
void LINE_SetReceiveToggleBit(int value)
|
||||
{
|
||||
pLineParams->ReceiveToggleBit = value;
|
||||
}
|
||||
|
||||
|
||||
int LINE_GetReceiveToggleBit(void)
|
||||
{
|
||||
return pLineParams->ReceiveToggleBit;
|
||||
}
|
||||
|
||||
|
||||
int LINE_GetNextMessageId(void)
|
||||
{
|
||||
return ++pLineParams->MessageId;
|
||||
}
|
||||
|
||||
|
||||
int LINE_GetMessageId(void)
|
||||
{
|
||||
return pLineParams->MessageId;
|
||||
}
|
||||
|
||||
|
||||
int LINE_GetLineParamsSize (void)
|
||||
{
|
||||
return sizeof (LineStruct);
|
||||
}
|
||||
|
||||
void LINE_SetDefaultLineParams (LineStruct* params)
|
||||
{
|
||||
*params = LineDefaultParams;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
LineStruct* LINE_GetLine0Params (void)
|
||||
{
|
||||
return &Line0Params;
|
||||
}
|
||||
|
||||
|
||||
void LINE_SetLine (LineStruct* params)
|
||||
{
|
||||
pLineParams = params;
|
||||
}
|
||||
|
||||
|
||||
int LINE_LineConfig(char * in)
|
||||
{
|
||||
int x;
|
||||
LineStruct* line = pLineParams;
|
||||
|
||||
if (!strncmp((char *) in, "NODE=", 5)) {
|
||||
strcpy(line->NodeName, in+5);
|
||||
return 1;
|
||||
}
|
||||
if (!strncmp((char *) in, "PORT=", 5)) {
|
||||
x = str2dec (in+5);
|
||||
if (x == -1)
|
||||
return -1;
|
||||
line->TransmitPort = x;
|
||||
return 1;
|
||||
}
|
||||
if (!strncmp((char *) in, "HOSTPORT=", 9)) {
|
||||
x = str2dec (in+9);
|
||||
if (x == -1)
|
||||
return -1;
|
||||
line->HostPort = x;
|
||||
return 1;
|
||||
}
|
||||
if (!strncmp((char *) in, "PACKLEN=", 8)) {
|
||||
x = str2dec (in+8);
|
||||
if (x == -1)
|
||||
return -1;
|
||||
line->PacketSize = x;
|
||||
return 1;
|
||||
}
|
||||
if (!strncmp((char *) in, "TIMEOUT=", 8)) {
|
||||
x = str2dec (in+8);
|
||||
if (x == -1)
|
||||
return -1;
|
||||
line->PollTimeSec = x;
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void WinsockErrorMessage(char * out)
|
||||
{
|
||||
#ifdef MS_WINDOWS
|
||||
int err;
|
||||
err = WSAGetLastError();
|
||||
|
||||
switch (err) {
|
||||
case WSAHOST_NOT_FOUND:
|
||||
strcat(out, " (HOST_NOT_FOUND)");
|
||||
break;
|
||||
case WSATRY_AGAIN:
|
||||
strcat(out, " (TRY_AGAIN)");
|
||||
break;
|
||||
case WSANO_RECOVERY:
|
||||
strcat(out, " (NO_RECOVERY)");
|
||||
break;
|
||||
case WSANO_DATA:
|
||||
strcat(out, " (NO_DATA)");
|
||||
break;
|
||||
case WSAEINTR:
|
||||
strcat(out, " (INTR)");
|
||||
break;
|
||||
case WSANOTINITIALISED:
|
||||
strcat(out, " (NOTINITIALISED)");
|
||||
break;
|
||||
case WSAENETDOWN:
|
||||
strcat(out, " (NETDOWN)");
|
||||
break;
|
||||
case WSAEAFNOSUPPORT:
|
||||
strcat(out, " (WSAEAFNOSUPPORT)");
|
||||
break;
|
||||
case WSAEINPROGRESS:
|
||||
strcat(out, " (INPROGRESS)");
|
||||
break;
|
||||
case WSAEMFILE:
|
||||
strcat(out, " (WSAEMFILE)");
|
||||
break;
|
||||
case WSAENOBUFS:
|
||||
strcat(out, " (WSAENOBUFS)");
|
||||
break;
|
||||
case WSAEPROTONOSUPPORT:
|
||||
strcat(out, " (WSAEPROTONOSUPPORT)");
|
||||
break;
|
||||
case WSAEPROTOTYPE:
|
||||
strcat(out, " (WSAEPROTOTYPE)");
|
||||
break;
|
||||
case WSAESOCKTNOSUPPORT:
|
||||
strcat(out, " (WSAESOCKTNOSUPPORT)");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static long GetInetAddress(char * name, char * message)
|
||||
{
|
||||
struct hostent *hp;
|
||||
int i1, i2, i3, i4;
|
||||
|
||||
char ownname[256];
|
||||
|
||||
if (name == NULL) {
|
||||
gethostname(ownname, sizeof(ownname));
|
||||
name = ownname;
|
||||
}
|
||||
i1 = i2 = i3 = i4 = 0;
|
||||
|
||||
if (sscanf(name, "%d.%d.%d.%d", &i1, &i2, &i3, &i4) == 4) {
|
||||
if (i1 || i2 || i3 || i4) {
|
||||
return (i1 << 24) | (i2 << 16) | (i3 << 8) | (i4);
|
||||
}
|
||||
}
|
||||
hp = gethostbyname(name);
|
||||
|
||||
if (!hp) {
|
||||
strcpy(message, "node name (");
|
||||
strcat(message, name);
|
||||
strcat(message, ") unknown");
|
||||
WinsockErrorMessage(message);
|
||||
return -1l;
|
||||
}
|
||||
return ntohl(*(long *) (hp->h_addr));
|
||||
}
|
||||
|
||||
|
||||
void LINE_LineExit(void)
|
||||
{
|
||||
int i;
|
||||
LineStruct* line = pLineParams;
|
||||
static const unsigned char discon[] = {4, 0, 0, 0, 0, 0, 0, 0, 'T', 'R', 'A', 'C', 'E', '3', '2', 0};
|
||||
|
||||
if (!line->LineUp)
|
||||
return;
|
||||
|
||||
if (line->CommSocket != -1) {
|
||||
for (i = 0; i < 5; i++)
|
||||
sendto(line->CommSocket, (char *) discon, 16, 0,
|
||||
(struct sockaddr *) &(line->SocketAddress), sizeof(line->SocketAddress));
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
closesocket(line->CommSocket);
|
||||
#endif
|
||||
#if defined(DEC_VMS) || defined(UNIX_V) || defined(OS_9)
|
||||
close(line->CommSocket);
|
||||
#endif
|
||||
}
|
||||
#ifdef MS_WINDOWS
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
line->CommSocket = -1;
|
||||
line->LineUp = 0;
|
||||
}
|
||||
|
||||
|
||||
int LINE_LineInit(char * message)
|
||||
{
|
||||
int i, j;
|
||||
socklen_t length;
|
||||
int val;
|
||||
unsigned char ipaddrused[4];
|
||||
long remote_ip;
|
||||
int buflen;
|
||||
LineStruct* line = pLineParams;
|
||||
|
||||
if (line->LineUp)
|
||||
return 0;
|
||||
|
||||
if (line->CommSocket == -1) {
|
||||
#ifdef MS_WINDOWS
|
||||
WSADATA wsaData;
|
||||
if (WSAStartup(0x0101, &wsaData)) {
|
||||
strcpy(message, "TCP/IP not ready, check configuration");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if ((remote_ip = GetInetAddress(line->NodeName, message)) == -1l)
|
||||
return -1;
|
||||
|
||||
if (line->CommSocket == -1) {
|
||||
line->SocketAddress.sin_family = AF_INET;
|
||||
line->SocketAddress.sin_addr.s_addr = INADDR_ANY;
|
||||
line->SocketAddress.sin_port = line->HostPort; /* Port can be determined by
|
||||
* host */
|
||||
|
||||
if ((line->CommSocket = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
|
||||
strcpy(message, "cannot create socket");
|
||||
WinsockErrorMessage(message);
|
||||
goto done;
|
||||
}
|
||||
if ((i = bind(line->CommSocket, (struct sockaddr *) & line->SocketAddress, sizeof(line->SocketAddress))) == -1) {
|
||||
strcpy(message, "cannot bind socket");
|
||||
WinsockErrorMessage(message);
|
||||
goto done;
|
||||
}
|
||||
length = sizeof(line->SocketAddress);
|
||||
if (getsockname(line->CommSocket, (struct sockaddr *) & line->SocketAddress, &length) == -1) {
|
||||
strcpy(message, "cannot identify port");
|
||||
WinsockErrorMessage(message);
|
||||
goto done;
|
||||
}
|
||||
line->ReceivePort = ntohs(line->SocketAddress.sin_port);
|
||||
|
||||
line->SocketAddress.sin_family = AF_INET;
|
||||
line->SocketAddress.sin_addr.s_addr = INADDR_ANY;
|
||||
line->SocketAddress.sin_port = htons(line->TransmitPort);
|
||||
}
|
||||
line->SocketAddress.sin_addr.s_addr = htonl(remote_ip);
|
||||
|
||||
buflen = 18000;
|
||||
|
||||
#if !defined(OS_9)
|
||||
val = 0;
|
||||
length = sizeof(val);
|
||||
getsockopt(line->CommSocket, SOL_SOCKET, SO_RCVBUF, (char *) &val, &length);
|
||||
|
||||
if (val > 0 && val < line->PacketSize)
|
||||
line->PacketSize = val;
|
||||
|
||||
if (val < buflen) {
|
||||
val = buflen;
|
||||
length = sizeof(val);
|
||||
if (setsockopt(line->CommSocket, SOL_SOCKET, SO_RCVBUF, (char *) &val, length) == -1) {
|
||||
strcpy(message, "cannot alloc buffer for rcvsocket");
|
||||
goto done;
|
||||
}
|
||||
val = 0;
|
||||
length = sizeof(val);
|
||||
getsockopt(line->CommSocket, SOL_SOCKET, SO_RCVBUF, (char *) &val, &length);
|
||||
if (val < buflen) {
|
||||
strcpy(message, "cannot alloc buffer for rcvsocket");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
val = 0;
|
||||
length = sizeof(val);
|
||||
getsockopt(line->CommSocket, SOL_SOCKET, SO_SNDBUF, (char *) &val, &length);
|
||||
if (val < buflen) {
|
||||
val = buflen;
|
||||
length = sizeof(val);
|
||||
if (setsockopt(line->CommSocket, SOL_SOCKET, SO_SNDBUF, (char *) &val, length) == -1) {
|
||||
strcpy(message, "cannot alloc buffer for sndsocket");
|
||||
goto done;
|
||||
}
|
||||
val = 0;
|
||||
length = sizeof(val);
|
||||
getsockopt(line->CommSocket, SOL_SOCKET, SO_SNDBUF, (char *) &val, &length);
|
||||
if (val < buflen) {
|
||||
strcpy(message, "cannot alloc buffer for sndsocket");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
j = Connection(ipaddrused);
|
||||
|
||||
if (j == 0)
|
||||
continue;
|
||||
|
||||
if (j == 1) {
|
||||
line->LineUp = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
strcpy(message, "TRACE32 access refused");
|
||||
goto done;
|
||||
}
|
||||
|
||||
strcpy(message, "TRACE32 not responding");
|
||||
|
||||
done:
|
||||
LINE_LineExit(); /* Close connection if no success */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
|
||||
void T32_InstallAsyncSelect(HWND hwnd, int msg)
|
||||
{
|
||||
#ifndef DONT_USE_ASYNC
|
||||
WSAAsyncSelect(pLineParams->CommSocket, hwnd, msg, FD_READ);
|
||||
#endif
|
||||
}
|
||||
|
||||
void T32_UnInstallAsyncSelect(HWND hwnd)
|
||||
{
|
||||
#ifndef DONT_USE_ASYNC
|
||||
WSAAsyncSelect(pLineParams->CommSocket, hwnd, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
Sends a message to T32. Handles segmentation of _message_ into (one
|
||||
or multiple) _packages_.
|
||||
|
||||
@param in pointer to outgoing message (already includes 5 byte message header)
|
||||
@param size size of message
|
||||
@note the message must be allocated such that there is space in
|
||||
front of the message for adding the packet header
|
||||
*/
|
||||
|
||||
int LINE_LineTransmit(unsigned char * in, int size)
|
||||
{
|
||||
int packetSize;
|
||||
unsigned int tmpl;
|
||||
LineStruct* line = pLineParams;
|
||||
|
||||
line->LastTransmitBuffer = in;
|
||||
line->LastTransmitSize = size;
|
||||
line->LastTransmitSeq = line->TransmitSeq;
|
||||
in -= 4; /* space for packet header */
|
||||
|
||||
do {
|
||||
packetSize = (size > line->PacketSize - 4) ? line->PacketSize - 4 : size;
|
||||
|
||||
/* When sending multiple packets, the packet header is written inside the
|
||||
message's payload. Original contents needs to be saved/restored */
|
||||
|
||||
SETLONGVAR(tmpl, in[0]); /* save */
|
||||
|
||||
in[0] = 0x11; /* transmit data package */
|
||||
in[1] = (size > packetSize) ? 1 : 0; /* more packets follow */
|
||||
SETWORDVAR(in[2], line->TransmitSeq); /* packet sequence ID */
|
||||
|
||||
if (sendto(line->CommSocket,
|
||||
(char *) in,
|
||||
packetSize + 4, 0,
|
||||
(struct sockaddr *) & line->SocketAddress, sizeof(line->SocketAddress)
|
||||
) != packetSize + 4) {
|
||||
|
||||
SETLONGVAR(in[0], tmpl); /* restore buffer */
|
||||
return 0;
|
||||
}
|
||||
SETLONGVAR(in[0], tmpl); /* restore buffer */
|
||||
|
||||
line->TransmitSeq++;
|
||||
in += packetSize;
|
||||
size -= packetSize;
|
||||
}
|
||||
while (size > 0); /* more packets required? */
|
||||
|
||||
return line->LastTransmitSize;
|
||||
}
|
||||
|
||||
/** Receives a package from the socket, with timeout handling.
|
||||
@return number of received bytes or error number (<0)
|
||||
*/
|
||||
static int ReceiveWithTimeout(struct timeval *tim, unsigned char *dest, int size)
|
||||
{
|
||||
int i;
|
||||
fd_set readfds;
|
||||
socklen_t length;
|
||||
struct timeval timeout;
|
||||
LineStruct* line = pLineParams;
|
||||
|
||||
timeout = *tim;
|
||||
|
||||
#ifdef POLL_NET
|
||||
DWORD endpoll;
|
||||
static struct timeval tival = {0};
|
||||
|
||||
if (tim->tv_usec || tim->tv_sec)
|
||||
endpoll = GetCurrentTime() + tim->tv_usec / 1000 + tim->tv_sec * 1000;
|
||||
else
|
||||
endpoll = 0;
|
||||
retry:
|
||||
#endif
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET( (unsigned int)line->CommSocket, &readfds);
|
||||
|
||||
#ifdef POLL_NET
|
||||
i = select(FD_SETSIZE, &readfds, (fd_set *) NULL, (fd_set *) NULL, &tival);
|
||||
|
||||
if (i < 0)
|
||||
return i;
|
||||
|
||||
if (i == 0) {
|
||||
if (endpoll) {
|
||||
if (GetCurrentTime() < endpoll) {
|
||||
ScreenDispatcher(line->CommSocket);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
#else
|
||||
i = select(FD_SETSIZE, &readfds, (fd_set *) NULL, (fd_set *) NULL, &timeout);
|
||||
#endif
|
||||
|
||||
if (i <= 0) {
|
||||
return i;
|
||||
}
|
||||
length = sizeof(struct sockaddr);
|
||||
return recvfrom(line->CommSocket, dest, size, 0, (struct sockaddr *) RECEIVEADDR, &length);
|
||||
}
|
||||
|
||||
|
||||
int LINE_LineDriverGetSocket(void)
|
||||
{
|
||||
return pLineParams->CommSocket;
|
||||
}
|
||||
|
||||
/* Queue pending notifications */
|
||||
T32_NotificationPackage *T32_NotificationHead = NULL, *T32_NotificationTail = NULL;
|
||||
|
||||
/** Receives messages from the socket. Assembles multiple packets into
|
||||
a single message.
|
||||
|
||||
@param out output buffer for storing payload. Attention: there must
|
||||
be some space _before_ the output buffer (4 bytes or more)
|
||||
for temporary usage.
|
||||
@return number of bytes of the message or error number (<0)
|
||||
*/
|
||||
|
||||
int LINE_LineReceive(unsigned char * out)
|
||||
{
|
||||
int i, flag;
|
||||
int count;
|
||||
unsigned short tmpw;
|
||||
unsigned int tmpl;
|
||||
unsigned short s;
|
||||
LineStruct* line = pLineParams;
|
||||
register unsigned char *dest;
|
||||
static unsigned char handshake[] = {7, 0, 0, 0, 0, 0, 0, 0, 'T', 'R', 'A', 'C', 'E', '3', '2', 0};
|
||||
|
||||
retry:
|
||||
dest = out-4; /* adjust pointer so we place header BEFORE "out" and thus payload AT "out" */
|
||||
count = 0;
|
||||
s = line->ReceiveSeq;
|
||||
|
||||
do {
|
||||
|
||||
/* multiple packets are merged in-place: backup data that is
|
||||
overwritten package aby header */
|
||||
SETLONGVAR(tmpl, dest[0]);
|
||||
|
||||
do {
|
||||
struct timeval PollTime = {0, 0};
|
||||
PollTime.tv_sec = line->PollTimeSec;
|
||||
if ((i = ReceiveWithTimeout(&PollTime, dest, line->PacketSize)) <= 0) {
|
||||
if (i == -2)
|
||||
goto retry;
|
||||
return -1;
|
||||
}
|
||||
if (i <= 4) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Detect and enqeue async notification that slipped into a request/reply pair */
|
||||
if (dest[0] == T32_API_NOTIFICATION)
|
||||
{
|
||||
T32_NotificationPackage *newPackage, *oldHead;
|
||||
|
||||
newPackage = reinterpret_cast<T32_NotificationPackage*>( malloc(sizeof(T32_NotificationPackage)) );
|
||||
if (newPackage==NULL)
|
||||
return -1;
|
||||
|
||||
memcpy(newPackage, dest, i); /* in theory i should always be the package size, at least for ethernet */
|
||||
oldHead = T32_NotificationHead;
|
||||
newPackage->prev = NULL;
|
||||
newPackage->next = oldHead;
|
||||
if (oldHead)
|
||||
oldHead->prev = newPackage;
|
||||
T32_NotificationHead = newPackage;
|
||||
if (T32_NotificationTail==NULL) {
|
||||
T32_NotificationTail=newPackage;
|
||||
}
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (dest[0] != T32_API_RECEIVE) {
|
||||
return -1;
|
||||
}
|
||||
SETWORDVAR(tmpw, dest[2]);
|
||||
|
||||
if (tmpw == line->LastReceiveSeq && line->LastTransmitSize) {
|
||||
line->TransmitSeq = line->LastTransmitSeq;
|
||||
LINE_LineTransmit(line->LastTransmitBuffer, line->LastTransmitSize);
|
||||
}
|
||||
}
|
||||
while (tmpw != line->ReceiveSeq);
|
||||
|
||||
line->ReceiveSeq++;
|
||||
flag = dest[1];
|
||||
SETLONGVAR(dest[0], tmpl); /* restore payload overwritten by package header */
|
||||
dest += i - 4;
|
||||
count += i - 4;
|
||||
|
||||
if (count > LINE_MSIZE) {
|
||||
return -1;
|
||||
}
|
||||
if (flag == 2) {
|
||||
if (sendto(line->CommSocket, (char *) handshake, 16, 0,
|
||||
(struct sockaddr *) &line->SocketAddress, sizeof(line->SocketAddress)) != 16) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (flag);
|
||||
|
||||
line->LastReceiveSeq = s;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/** Receives notification messages. First checks for a queued
|
||||
notification and if none is available polls the socket for new
|
||||
notifications. For getting all pending notifications call the
|
||||
function until it returns -1.
|
||||
|
||||
@param package output buffer of size T32_PCKLEN_MAX for the package
|
||||
@return -1 no notification pending,
|
||||
>=0 notificataion type T32_E_BREAK, T32_E_EDIT, T32_E_BREAKPOINTCONFIG
|
||||
|
||||
*/
|
||||
|
||||
|
||||
int LINE_ReceiveNotifyMessage(unsigned char* package)
|
||||
{
|
||||
int len;
|
||||
static struct timeval LongTime = {0, 0};
|
||||
|
||||
/* Check for asynchronous notifications */
|
||||
if (T32_NotificationTail) {
|
||||
T32_NotificationPackage *prev = T32_NotificationTail->prev;
|
||||
if (prev)
|
||||
prev->next = NULL;
|
||||
memcpy(package, T32_NotificationTail->payload, T32_PCKLEN_MAX);
|
||||
free(T32_NotificationTail);
|
||||
T32_NotificationTail = prev;
|
||||
if (prev==NULL) /* deleted last message */
|
||||
T32_NotificationHead = NULL;
|
||||
} else {
|
||||
len = ReceiveWithTimeout(&LongTime, package, T32_PCKLEN_MAX);
|
||||
if (len < 2)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (package[0] != T32_API_NOTIFICATION)
|
||||
return -1;
|
||||
|
||||
return package[1]; /* type of notification: T32_E_BREAK, T32_E_EDIT, T32_E_BREAKPOINTCONFIG */
|
||||
}
|
||||
|
||||
/** Sends sync packets */
|
||||
int LINE_LineSync(void)
|
||||
{
|
||||
int i, j;
|
||||
unsigned char packet[T32_PCKLEN_MAX];
|
||||
static char magicPattern[] = "TRACE32";
|
||||
LineStruct* line = pLineParams;
|
||||
|
||||
j = 0;
|
||||
memset(packet, 0, sizeof(packet));
|
||||
|
||||
retry:
|
||||
packet[0] = T32_API_SYNCREQUEST;
|
||||
packet[1] = 0;
|
||||
SETWORDVAR(packet[2], line->TransmitSeq);
|
||||
SETWORDCONST(packet[4], 0);
|
||||
SETWORDCONST(packet[6], 0);
|
||||
strcpy((char *) (packet + 8), magicPattern);
|
||||
|
||||
if (sendto(line->CommSocket, (char *) packet, 16 /*size*/, 0,
|
||||
(struct sockaddr *) & line->SocketAddress, sizeof(line->SocketAddress)) == -1) {
|
||||
return -1;
|
||||
}
|
||||
while (1) { /* empty queue */
|
||||
if (++j > 20) {
|
||||
return -1;
|
||||
}
|
||||
if ((i = ReceiveWithTimeout(&LongTime, packet, T32_PCKLEN_MAX)) <= 0) {
|
||||
return -1;
|
||||
}
|
||||
if (i != 16 || packet[0] != T32_API_SYNCACKN || strcmp((char *) packet + 8, magicPattern)) {
|
||||
if (i == 16 && packet[0] == 5)
|
||||
goto retry;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
SETWORDVAR(line->ReceiveSeq, packet[2]);
|
||||
line->LastReceiveSeq = line->ReceiveSeq - 100;
|
||||
|
||||
|
||||
packet[0] = T32_API_SYNCBACK;
|
||||
packet[1] = 0;
|
||||
SETWORDVAR(packet[2], line->TransmitSeq);
|
||||
SETWORDCONST(packet[4], 0);
|
||||
SETWORDCONST(packet[6], 0);
|
||||
strcpy((char *) (packet + 8), magicPattern);
|
||||
|
||||
if (sendto(line->CommSocket, (char *) packet, 16, 0, (struct sockaddr *) & line->SocketAddress, sizeof(line->SocketAddress)) == -1) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int Connection(unsigned char *ipaddrused)
|
||||
{
|
||||
int i;
|
||||
unsigned char buffer[T32_PCKLEN_MAX];
|
||||
LineStruct* line = pLineParams;
|
||||
static const char magicPattern[] = "TRACE32";
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
buffer[0] = 3; /* CONNECTREQUEST */
|
||||
buffer[1] = 0;
|
||||
|
||||
line->TransmitSeq = 1;
|
||||
SETWORDVAR(buffer[2], line->TransmitSeq);
|
||||
SETWORDVAR(buffer[4], line->TransmitPort);
|
||||
SETWORDVAR(buffer[6], line->ReceivePort);
|
||||
|
||||
strcpy((char *) (buffer + 8), magicPattern);
|
||||
|
||||
if (sendto(line->CommSocket, (char *) buffer, line->PacketSize, 0, (struct sockaddr *) & line->SocketAddress, sizeof(line->SocketAddress)) == -1) {
|
||||
return 0;
|
||||
}
|
||||
if ((i = ReceiveWithTimeout(&LongTime, buffer, line->PacketSize)) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
if (strcmp((char *) (buffer + 8), magicPattern)) {
|
||||
return 0;
|
||||
}
|
||||
SETWORDVAR(line->ReceiveSeq, buffer[2]);
|
||||
|
||||
if (buffer[0] == 0x53) { /* POSITIVE CONNECTACKN from Debug Unit ? */
|
||||
ipaddrused[0] = 1;
|
||||
ipaddrused[1] = 1;
|
||||
ipaddrused[2] = 1;
|
||||
ipaddrused[3] = 11;
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (buffer[0] != 0x13) { /* POSITIVE CONNECTACKN ? */
|
||||
if (buffer[0] == 0x23) {/* NEGATIVE ? */
|
||||
ipaddrused[0] = buffer[4];
|
||||
ipaddrused[1] = buffer[5];
|
||||
ipaddrused[2] = buffer[6];
|
||||
ipaddrused[3] = buffer[7];
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
line->PacketSize = i;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
2427
debuggers/t32/api/hremote.cc
Normal file
2427
debuggers/t32/api/hremote.cc
Normal file
File diff suppressed because it is too large
Load Diff
366
debuggers/t32/include/t32.h
Normal file
366
debuggers/t32/include/t32.h
Normal file
@ -0,0 +1,366 @@
|
||||
#ifndef __T32_H__
|
||||
#define __T32_H__
|
||||
|
||||
#include <config/VariantConfig.hpp>
|
||||
|
||||
#if defined WIN32 || defined WIN64
|
||||
#ifndef MS_WINDOWS
|
||||
#define MS_WINDOWS
|
||||
#endif
|
||||
#define LOW_HIGH
|
||||
#endif
|
||||
|
||||
#ifdef DEC_VMS
|
||||
#define LOW_HIGH_BYTE
|
||||
#endif
|
||||
|
||||
#ifdef DEC_OSF1
|
||||
#define UNIX_V
|
||||
#define LOW_HIGH_BYTE
|
||||
#endif
|
||||
|
||||
#ifdef HP_UX
|
||||
#define UNIX_V
|
||||
#define HIGH_LOW_BYTE
|
||||
#endif
|
||||
|
||||
#ifdef IBM_AIX
|
||||
#define UNIX_V
|
||||
#define HIGH_LOW_BYTE
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
# ifndef LINUX
|
||||
# define LINUX
|
||||
# endif
|
||||
# define UNIX_V
|
||||
# define LOW_HIGH_BYTE
|
||||
#endif
|
||||
|
||||
#ifdef T32HOST_LINUX_X64
|
||||
# define UNIX_V
|
||||
# define LOW_HIGH_BYTE
|
||||
#endif
|
||||
|
||||
#ifdef LINUX_PPC
|
||||
# ifndef LINUX
|
||||
# define LINUX
|
||||
# endif
|
||||
# define UNIX_V
|
||||
# define HIGH_LOW_BYTE
|
||||
#endif
|
||||
|
||||
#ifdef T32HOST_MACOSX_X86
|
||||
# define UNIX_V
|
||||
# define LOW_HIGH_BYTE
|
||||
#endif
|
||||
|
||||
#ifdef SUN_SOL
|
||||
#define UNIX_V
|
||||
#define HIGH_LOW_BYTE
|
||||
#endif
|
||||
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int dword;
|
||||
|
||||
|
||||
#ifdef HIGH_LOW_BYTE
|
||||
|
||||
#define SETWORDCONST(A,B) ( ((unsigned char *)&(A))[0] = (B),((unsigned char *)&(A))[1] = (B)>>8 )
|
||||
#define SETLONGCONST(A,B) ( ((unsigned char *)&(A))[0] = (B),((unsigned char *)&(A))[1] = (B)>>8,((unsigned char *)&(A))[2] = (B)>>16,((unsigned char *)&(A))[3] = (B)>>24 )
|
||||
|
||||
#define SETWORDVAR(A,B) ( ((unsigned char *)&(A))[0] = ((unsigned char *)&(B))[1],((unsigned char *)&(A))[1] = ((unsigned char *)&(B))[0] )
|
||||
#define SETLONGVAR(A,B) ( ((unsigned char *)&(A))[0] = ((unsigned char *)&(B))[3],((unsigned char *)&(A))[1] = ((unsigned char *)&(B))[2],((unsigned char *)&(A))[2] = ((unsigned char *)&(B))[1],((unsigned char *)&(A))[3] = ((unsigned char *)&(B))[0] )
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HIGH_LOW
|
||||
|
||||
#define SETWORDCONST(A,B) ((*((unsigned short *)&(A))) = (unsigned short)((((B)>>8)&0xff)|(((B)<<8)&0xff00)))
|
||||
#define SETLONGCONST(A,B) ((*((int *)&(A))) = (int)((((B)>>24)&0xffl)|(((B)>>8)&0xff00l)|(((B)<<8)&0xff0000l)|(((B)<<24)&0xff000000l)))
|
||||
|
||||
#define SETWORDVAR(A,B) ( ((unsigned char *)&(A))[0] = ((unsigned char *)&(B))[1],((unsigned char *)&(A))[1] = ((unsigned char *)&(B))[0] )
|
||||
#define SETLONGVAR(A,B) ( ((unsigned char *)&(A))[0] = ((unsigned char *)&(B))[3],((unsigned char *)&(A))[1] = ((unsigned char *)&(B))[2],((unsigned char *)&(A))[2] = ((unsigned char *)&(B))[1],((unsigned char *)&(A))[3] = ((unsigned char *)&(B))[0] )
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef LOW_HIGH
|
||||
|
||||
#define SETWORDCONST(A,B) ((*((unsigned short *)&(A))) = (unsigned short)(B))
|
||||
#define SETLONGCONST(A,B) ((*((int *)&(A))) = (int)(B))
|
||||
|
||||
#define SETWORDVAR(A,B) ((*((unsigned short *)&(A))) = (*((unsigned short *)&(B))))
|
||||
#define SETLONGVAR(A,B) ((*((int *)&(A))) = (*((int *)&(B))))
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef LOW_HIGH_BYTE
|
||||
|
||||
#define SETWORDCONST(A,B) ( ((unsigned char *)&(A))[0] = (B),((unsigned char *)&(A))[1] = (B)>>8 )
|
||||
#define SETLONGCONST(A,B) ( ((unsigned char *)&(A))[0] = (B),((unsigned char *)&(A))[1] = (B)>>8,((unsigned char *)&(A))[2] = (B)>>16,((unsigned char *)&(A))[3] = (B)>>24 )
|
||||
|
||||
#define SETWORDVAR(A,B) ( ((unsigned char *)&(A))[0] = ((unsigned char *)&(B))[0],((unsigned char *)&(A))[1] = ((unsigned char *)&(B))[1] )
|
||||
#define SETLONGVAR(A,B) ( ((unsigned char *)&(A))[0] = ((unsigned char *)&(B))[0],((unsigned char *)&(A))[1] = ((unsigned char *)&(B))[1],((unsigned char *)&(A))[2] = ((unsigned char *)&(B))[2],((unsigned char *)&(A))[3] = ((unsigned char *)&(B))[3] )
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define LINE_MBLOCK 16384 /* large block mode */
|
||||
#define LINE_MSIZE (LINE_MBLOCK+256)
|
||||
|
||||
#define T32_DEV_OS 0
|
||||
#define T32_DEV_ICE 1
|
||||
#define T32_DEV_ICD 1 /* similar to ICE but clearer for user */
|
||||
|
||||
/* Events that can be generated by T32 */
|
||||
#define T32_MAX_EVENTS 3
|
||||
#define T32_E_BREAK 0x0 /* change in runstate, probably only "break" */
|
||||
#define T32_E_EDIT 0x1 /* user requested "edit source" in external editor */
|
||||
#define T32_E_BREAKPOINTCONFIG 0x2 /* breakpoint configuration changed (breakpoint set/removed) */
|
||||
|
||||
/* Callbacks should have the following protoypes */
|
||||
/************************* WARNING *****************************/
|
||||
/*
|
||||
* If you add more callback functions here, make sure you ONLY
|
||||
* use 'int', 'unsigned int', 'integral-type *' or 'float-type *' as parameters.
|
||||
*
|
||||
* No 'long', no 'long long', no 'short', no 'char', no floats, no typedefs
|
||||
* and no function pointers!
|
||||
* This is because we absolutely need to avoid portability problems here.
|
||||
*
|
||||
* Explanation:
|
||||
* The T32_NotificationCallback_t typedef'd below has an empty parameter list,
|
||||
* which we can't change anymore to a va_list because of backwards compatibility.
|
||||
* This means only the native types like 'int' and 'integral type *' can be used
|
||||
* safely, otherwise we run into hard-to-debug problems with type-promotion and
|
||||
* parameter-passing conventions on the varying platforms we support.
|
||||
*/
|
||||
extern void T32_callbackBreak(int generic);
|
||||
extern void T32_callbackEditExtern(int generic, int lineNr, unsigned char *fileName);
|
||||
extern void T32_callbackBreakpointConfig(int generic);
|
||||
|
||||
|
||||
#define T32_API_RECEIVE 0x1
|
||||
/* Missing: 0x5, */
|
||||
#define T32_API_NOTIFICATION 0x6
|
||||
|
||||
#define T32_API_SYNCREQUEST 0x02
|
||||
#define T32_API_SYNCACKN 0x12
|
||||
#define T32_API_SYNCBACK 0x22
|
||||
|
||||
#define T32_PCKLEN_MAX 1472
|
||||
|
||||
|
||||
|
||||
typedef struct t32_notification {
|
||||
|
||||
char payload[T32_PCKLEN_MAX]; /* maximum packet size*/
|
||||
|
||||
struct t32_notification *next, *prev;
|
||||
/* T32_NotificationPackage *next;
|
||||
T32_NotificationPackage *prev; */
|
||||
|
||||
} T32_NotificationPackage;
|
||||
|
||||
extern T32_NotificationPackage *T32_NotificationHead, *T32_NotificationTail; /* Queue pending notifications */
|
||||
|
||||
|
||||
|
||||
|
||||
#define T32_COM_RECEIVE_FAIL -1
|
||||
#define T32_COM_TRANSMIT_FAIL -2
|
||||
#define T32_COM_PARA_FAIL -3
|
||||
#define T32_COM_SEQ_FAIL -4
|
||||
#define T32_MAX_EVENT_FAIL -5
|
||||
#define T32_MALLOC_FAIL -6
|
||||
|
||||
|
||||
typedef void * T32_TAPACCESS_HANDLE;
|
||||
|
||||
#define T32_TAPACCESS_MAXBITS 0x3b00
|
||||
|
||||
#define T32_TAPACCESS_RELEASE ((T32_TAPACCESS_HANDLE)0)
|
||||
#define T32_TAPACCESS_HOLD ((T32_TAPACCESS_HANDLE)1)
|
||||
|
||||
#define T32_TAPACCESS_TDO 0x00
|
||||
#define T32_TAPACCESS_TDI 0x04
|
||||
#define T32_TAPACCESS_TMS 0x08
|
||||
#define T32_TAPACCESS_TCK 0x0c
|
||||
#define T32_TAPACCESS_nTRST 0x10
|
||||
#define T32_TAPACCESS_nRESET 0x14
|
||||
#define T32_TAPACCESS_nRESET_LATCH 0x18
|
||||
#define T32_TAPACCESS_VTREF 0x1c
|
||||
#define T32_TAPACCESS_VTREF_LATCH 0x20
|
||||
#define T32_TAPACCESS_nENOUT 0x24
|
||||
|
||||
#define T32_TAPACCESS_SET(x) (2|((x)&1))
|
||||
#define T32_TAPACCESS_SET_LOW 2
|
||||
#define T32_TAPACCESS_SET_HIGH 3
|
||||
#define T32_TAPACCESS_SET_0 T32_TAPACCESS_SET_LOW
|
||||
#define T32_TAPACCESS_SET_1 T32_TAPACCESS_SET_HIGH
|
||||
|
||||
#define T32_TAPACCESS_SHIFT 0x30
|
||||
#define T32_TAPACCESS_SHIFTTMS 0x40
|
||||
#define T32_TAPACCESS_SHIFTIR 0x50
|
||||
#define T32_TAPACCESS_SHIFTDR 0x60
|
||||
|
||||
#define T32_TAPACCESS_SLEEP_MS 0x7c
|
||||
#define T32_TAPACCESS_SLEEP_US 0x7d
|
||||
#define T32_TAPACCESS_SLEEP_HALF_CLOCK 0x7e
|
||||
#define T32_TAPACCESS_SLEEP T32_TAPACCESS_SLEEP_MS /*just for backwards compatibility*/
|
||||
|
||||
|
||||
#define SHIFTRAW_OPTION_INTERNAL_TMS 0x0001 /*do not use the internal options*/
|
||||
#define SHIFTRAW_OPTION_INTERNAL_TDI 0x0002
|
||||
#define SHIFTRAW_OPTION_INTERNAL_TDO 0x0004
|
||||
#define SHIFTRAW_OPTION_INTERNAL_ALL 0x0007
|
||||
|
||||
#define SHIFTRAW_OPTION_NONE 0x0000
|
||||
#define SHIFTRAW_OPTION_LASTTMS_ONE 0x0008
|
||||
#define SHIFTRAW_OPTION_TMS_ONE 0x0010
|
||||
#define SHIFTRAW_OPTION_TMS_ZERO 0x0000
|
||||
#define SHIFTRAW_OPTION_TDI_ONE 0x0040
|
||||
#define SHIFTRAW_OPTION_TDI_ZERO 0x0000
|
||||
#define SHIFTRAW_OPTION_TDI_LASTTDO 0x0020
|
||||
|
||||
#define T32_TAPACCESS_SPECIAL 0x80
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _NO_PROTO
|
||||
|
||||
extern int T32_Config( const char *, const char * );
|
||||
extern int T32_Init(void);
|
||||
extern int T32_Exit(void);
|
||||
extern int T32_Nop(void);
|
||||
extern int T32_NopFail(void);
|
||||
extern int T32_Ping(void);
|
||||
extern int T32_Stop(void);
|
||||
extern int T32_GetPracticeState(int * );
|
||||
extern int T32_Attach( int );
|
||||
extern int T32_GetState( int * );
|
||||
extern int T32_GetCpuInfo( char **, word *, word *, word * );
|
||||
extern int T32_GetRam(dword *, dword *, word *);
|
||||
extern int T32_ResetCPU(void);
|
||||
|
||||
extern int T32_WriteMemory( dword, int, byte * , int );
|
||||
extern int T32_WriteMemoryPipe( dword, int, byte * , int );
|
||||
extern int T32_WriteMemoryEx( dword, int, int, int, byte * , int );
|
||||
extern int T32_ReadMemory( dword, int, byte *, int );
|
||||
extern int T32_ReadMemoryEx( dword, int, int, int, byte * , int );
|
||||
|
||||
|
||||
#define T32_MEMORY_ACCESS_DATA 0x0000
|
||||
#define T32_MEMORY_ACCESS_PROGRAM 0x0001
|
||||
#define T32_MEMORY_ACCESS_ARM_CP0 0x0002
|
||||
#define T32_MEMORY_ACCESS_ARM_ICE 0x0003
|
||||
#define T32_MEMORY_ACCESS_ARM_ETM 0x0004
|
||||
#define T32_MEMORY_ACCESS_ARM_CP14 0x0005
|
||||
#define T32_MEMORY_ACCESS_ARM_CP15 0x0006
|
||||
#define T32_MEMORY_ACCESS_ARM_ARM 0x0007
|
||||
#define T32_MEMORY_ACCESS_ARM_THUMB 0x0008
|
||||
#define T32_MEMORY_ACCESS_ARM_PHYSICAL_ARM 0x0009
|
||||
#define T32_MEMORY_ACCESS_ARM_PHYSICAL_THUMB 0x000a
|
||||
#define T32_MEMORY_ACCESS_ARM_ETB 0x000b
|
||||
#define T32_MEMORY_ACCESS_ARM_PHYSICAL_DATA 0x000c
|
||||
#define T32_MEMORY_ACCESS_ARM_PHYSICAL_PROGRAM 0x000d
|
||||
#define T32_MEMORY_ACCESS_ARM_DAP 0x000e
|
||||
#define T32_MEMORY_ACCESS_ARM_USR 0x000f
|
||||
|
||||
#define T32_MEMORY_ATTR_WIDTHMASK 0x000f
|
||||
#define T32_MEMORY_ATTR_DUALPORT 0x0400
|
||||
#define T32_MEMORY_ATTR_NOINCREMENT 0x4000
|
||||
|
||||
|
||||
extern int T32_WriteRegister( dword, dword, dword * );
|
||||
extern int T32_ReadRegister( dword, dword, dword * );
|
||||
extern int T32_ReadPP( dword * );
|
||||
extern int T32_WriteBreakpoint( dword, int, int, int );
|
||||
extern int T32_ReadBreakpoint( dword, int, word * , int );
|
||||
extern int T32_Step(void);
|
||||
extern int T32_StepMode(int);
|
||||
extern int T32_SetMode(int);
|
||||
extern int T32_Go(void);
|
||||
extern int T32_Break(void);
|
||||
extern int T32_Terminate(int retval);
|
||||
extern int T32_Cmd( char * );
|
||||
extern int T32_CmdWin( dword, char * );
|
||||
extern int T32_EvalGet ( dword * );
|
||||
extern int T32_GetMessage ( char *, word * );
|
||||
extern int T32_GetTriggerMessage ( char* );
|
||||
extern int T32_GetSymbol ( char *, dword *, dword * , dword * );
|
||||
extern int T32_GetSource ( dword, char *, dword * );
|
||||
extern int T32_GetSelectedSource( char *, dword * );
|
||||
|
||||
extern int T32_AnaStatusGet( byte *, long *, long *, long * );
|
||||
extern int T32_AnaRecordGet( long , byte *, int );
|
||||
extern int T32_GetTraceState(int tracetype, int * state, long * size, long * min, long * max);
|
||||
extern int T32_ReadTrace(int tracetype, long record, int nrecords, unsigned long mask, byte * buffer);
|
||||
|
||||
typedef void (*T32_NotificationCallback_i_t)(int);
|
||||
typedef void (*T32_NotificationCallback_iicp_t)(int, int, unsigned char *);
|
||||
|
||||
#ifndef SUPPRESS_FUNCTION_TYPE_WARNING
|
||||
typedef void (*T32_NotificationCallback_t)();
|
||||
extern int T32_NotifyStateEnable( int event, T32_NotificationCallback_t func);
|
||||
#endif
|
||||
|
||||
extern int T32_CheckStateNotify( unsigned param1);
|
||||
extern void T32_GetSocketHandle( int *t32soc );
|
||||
|
||||
extern T32_TAPACCESS_HANDLE T32_TAPAccessAlloc(void);
|
||||
extern int T32_TAPAccessExecute(T32_TAPACCESS_HANDLE connection, T32_TAPACCESS_HANDLE connectionhold);
|
||||
extern int T32_TAPAccessFree(T32_TAPACCESS_HANDLE connection);
|
||||
extern int T32_TAPAccessSetInfo(int irpre, int irpost, int drpre, int drpost, int tristate, int tapstate, int tcklevel, int slave);
|
||||
extern int T32_TAPAccessShiftIR(T32_TAPACCESS_HANDLE connection, int numberofbits, byte * poutbits, byte * pinbits);
|
||||
extern int T32_TAPAccessShiftDR(T32_TAPACCESS_HANDLE connection, int numberofbits, byte * poutbits, byte * pinbits);
|
||||
extern int T32_TAPAccessShiftRaw(T32_TAPACCESS_HANDLE connection, int numberofbits, byte * pTMSBits, byte * pTDIBits, byte * pTDOBits, int options);
|
||||
extern int T32_TAPAccessDirect(T32_TAPACCESS_HANDLE connection, int nbytes, byte * poutbytes, byte * pinbytes);
|
||||
extern int T32_TAPAccessRelease(void);
|
||||
|
||||
extern int T32_Fdx_Resolve(char * name);
|
||||
extern int T32_Fdx_Open(char * name, char * mode);
|
||||
extern int T32_Fdx_Close(int channel);
|
||||
extern int T32_Fdx_ReceivePoll(int channel, void * data, int width, int maxsize);
|
||||
extern int T32_Fdx_Receive(int channel, void * data, int width, int maxsize);
|
||||
extern int T32_Fdx_SendPoll(int channel, void * data, int width, int size);
|
||||
extern int T32_Fdx_Send(int channel, void * data, int width, int size);
|
||||
|
||||
/*
|
||||
* New stream structure, to improve performance for PIPE mode.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int blen;
|
||||
unsigned char *ptr;
|
||||
unsigned char *ptrend;
|
||||
int channel;
|
||||
unsigned char buffer[4096];
|
||||
} T32_Fdx_Stream;
|
||||
|
||||
extern T32_Fdx_Stream *T32_Fdx_OpenStream(char *name, char *mode);
|
||||
extern int T32_Fdx_CloseStream(T32_Fdx_Stream * pstream);
|
||||
extern int T32_Fdx_ReceiveStreamNext(T32_Fdx_Stream * pstream, unsigned char *target, int width, int size);
|
||||
|
||||
#define T32_Fdx_ReceiveStream(__pstream,__target,__width,__len) ( \
|
||||
(((__pstream)->ptr >= (__pstream)->ptrend) ? \
|
||||
T32_Fdx_ReceiveStreamNext(__pstream,__target,__width,__len) : \
|
||||
((__pstream)->blen = ((__pstream)->ptr[0]|((__pstream)->ptr[1]<<8)), memcpy((__target),(__pstream)->ptr+2,(__pstream)->blen), (__pstream)->ptr += 2+(__pstream)->blen, (__pstream)->blen)))
|
||||
|
||||
|
||||
extern int T32_GetChannelSize(void);
|
||||
extern void T32_GetChannelDefaults(void* line);
|
||||
extern void T32_SetChannel(void* line);
|
||||
extern void* T32_GetChannel0(void);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
11
debuggers/t32/src/CMakeLists.txt
Normal file
11
debuggers/t32/src/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
set(SRCS
|
||||
T32Connector.cc
|
||||
)
|
||||
|
||||
add_executable(fail-client ${SRCS})
|
||||
target_link_libraries(fail-client -Wl,-whole-archive t32api -Wl,-no-whole-archive fail )
|
||||
|
||||
install(TARGETS fail-client RUNTIME DESTINATION bin)
|
||||
|
||||
add_executable(t32cli t32cli.cc)
|
||||
target_link_libraries(t32cli -Wl,-whole-archive t32api -Wl,-no-whole-archive)
|
||||
61
debuggers/t32/src/T32Connector.cc
Normal file
61
debuggers/t32/src/T32Connector.cc
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* FailT32 -- Fault Injection on the Lauterbach Trace32 System
|
||||
*
|
||||
* 1. Invoke t32 executable with appropriate Lauterbach Skript
|
||||
* - Script has to load binary
|
||||
* - and let system run until entry point
|
||||
* -> Then we have a readily configured system
|
||||
*
|
||||
* @author Martin Hoffmann <hoffmann@cs.fau.de>
|
||||
* @date 15.02.2013
|
||||
*/
|
||||
|
||||
#include <t32.h>
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "config/VariantConfig.hpp"
|
||||
#include "sal/SALInst.hpp"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
/* Default T32 error handler */
|
||||
void err(int ernum){
|
||||
if(err != 0){
|
||||
cerr << "Error: " << err << endl;
|
||||
//exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Here we go... */
|
||||
int main(int argc, char** argv){
|
||||
|
||||
// Evaluate arguments
|
||||
|
||||
// Setup connection to Lauterbach
|
||||
cout << "Lauterbach remote connection" << endl;
|
||||
int error;
|
||||
char hostname[] = "localhost";
|
||||
char packlen[] = "1024";
|
||||
char port[] = "20010";
|
||||
|
||||
cout << "[T32] Connecting to " << hostname << ":" << port << " Packlen: " << packlen << endl;
|
||||
T32_Config("NODE=", hostname);
|
||||
T32_Config("PACKLEN=", packlen);
|
||||
T32_Config("PORT=", port);
|
||||
|
||||
cout << "[T32] Init." << endl;
|
||||
err(T32_Init());
|
||||
|
||||
cout << "[T32] Attach." << endl;
|
||||
err(T32_Attach(T32_DEV_ICD));
|
||||
|
||||
|
||||
// Let the SimulatorController do the dirty work.
|
||||
fail::simulator.startup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
24
debuggers/t32/src/T32Connector.hpp
Normal file
24
debuggers/t32/src/T32Connector.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef __T32_CONNECTOR_HPP__
|
||||
#define __T32_CONNECTOR_HPP__
|
||||
|
||||
#include <t32.h>
|
||||
|
||||
namespace fail {
|
||||
|
||||
/**
|
||||
* \class T32Connector
|
||||
*/
|
||||
class T32Connector {
|
||||
public:
|
||||
|
||||
|
||||
/**
|
||||
* Save simulator state. Quite hard on real hardware! Also safe all HW registers!
|
||||
* @param path Location to store state information
|
||||
* @return \c true if the state has been successfully saved, \c false otherwise
|
||||
*/
|
||||
};
|
||||
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif // __T32_CONNECTOR_HPP__
|
||||
63
debuggers/t32/src/t32cli.cc
Normal file
63
debuggers/t32/src/t32cli.cc
Normal file
@ -0,0 +1,63 @@
|
||||
#include <t32.h>
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void err(int ernum){
|
||||
if(err != 0){
|
||||
cerr << "Error: " << err << endl;
|
||||
//exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int eval_command(){
|
||||
string cmd;
|
||||
char errmsg[128];
|
||||
cout << "%> ";
|
||||
getline(cin, cmd);
|
||||
if(cmd.compare("bye") == 0) return -1;
|
||||
|
||||
int err = T32_Cmd((char*)cmd.c_str());
|
||||
if(err != 0){
|
||||
cerr << "Could not execute command: " << err << endl;
|
||||
word errnum;
|
||||
T32_GetMessage(errmsg, &errnum);
|
||||
cerr << errmsg << "Type: " << errnum << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(void){
|
||||
cout << "Lauterbach remote connection" << endl;
|
||||
cout << "Enter bye to exit." << endl;
|
||||
int error;
|
||||
char hostname[] = "localhost";
|
||||
char packlen[] = "1024";
|
||||
char port[] = "20010";
|
||||
|
||||
cout << "[T32] Connecting to " << hostname << ":" << port << " Packlen: " << packlen << endl;
|
||||
T32_Config("NODE=", hostname);
|
||||
T32_Config("PACKLEN=", packlen);
|
||||
T32_Config("PORT=", port);
|
||||
|
||||
cout << "[T32] Init." << endl;
|
||||
err(T32_Init());
|
||||
|
||||
cout << "[T32] Attach." << endl;
|
||||
err(T32_Attach(T32_DEV_ICD));
|
||||
|
||||
while(eval_command() != -1);
|
||||
|
||||
cout << "[T32] Exit." << endl;
|
||||
err(T32_Exit());
|
||||
cout << "Bye." << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user