OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /or1k/trunk
    from Rev 1778 to Rev 1779
    Reverse comparison

Rev 1778 → Rev 1779

/or_debug_proxy/includes/gdb.h
0,0 → 1,187
/*$$HEADER*/
/******************************************************************************/
/* */
/* H E A D E R I N F O R M A T I O N */
/* */
/******************************************************************************/
 
// Project Name : OpenRISC Debug Proxy
// File Name : gdb.h
// Prepared By : jb, rmd
// Project Start : 2008-10-01
 
/*$$COPYRIGHT NOTICE*/
/******************************************************************************/
/* */
/* C O P Y R I G H T N O T I C E */
/* */
/******************************************************************************/
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation;
version 2.1 of the License, a copy of which is available from
http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt.
 
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
 
/*$$CHANGE HISTORY*/
/******************************************************************************/
/* */
/* C H A N G E H I S T O R Y */
/* */
/******************************************************************************/
 
// Date Version Description
//------------------------------------------------------------------------
// 081101 First revision, adapted from existing "jp"
// debug proxy. jb, rmd
 
#ifndef GDB_H
#define GDB_H
 
#include <sys/types.h>
#include <inttypes.h>
 
extern void HandleServerSocket(void);
extern void handle_rsp (void);
int GetServerSocket(const char* name, const char* proto, int port);
extern void JTAGRequest(void);
void setup_or32(void);
void gdb_close();
 
extern int err;
 
/* All JTAG chains. */
enum jtag_chains
{
SC_GLOBAL, /* 0 Global BS Chain */
SC_RISC_DEBUG, /* 1 RISC Debug Interface chain */
SC_RISC_TEST, /* 2 RISC Test Chain */
SC_TRACE, /* 3 Trace Chain */
SC_REGISTER, /* 4 Register Chain */
SC_WISHBONE, /* 5 Memory chain */
SC_BLOCK, /* 6 Block Chains */
};
 
/* See JTAG documentation about these. */
#define JI_SIZE (4)
enum jtag_instr
{
JI_EXTEST,
JI_SAMPLE_PRELOAD,
JI_IDCODE,
JI_CHAIN_SELECT,
JI_INTEST,
JI_CLAMP,
JI_CLAMPZ,
JI_HIGHZ,
JI_DEBUG,
JI_BYPASS = 0xF
};
 
/* JTAG registers. */
#define JTAG_MODER (0x0)
#define JTAG_TSEL (0x1)
#define JTAG_QSEL (0x2)
#define JTAG_SSEL (0x3)
#define JTAG_RISCOP (0x4)
#define JTAG_RECWP0 (0x10)
#define JTAG_RECBP0 (0x1b)
 
/* This is repeated from gdb tm-or1k.h There needs to be
a better mechanism for tracking this, but I don't see
an easy way to share files between modules. */
 
typedef enum {
JTAG_COMMAND_READ = 1,
JTAG_COMMAND_WRITE = 2,
JTAG_COMMAND_BLOCK_READ = 3,
JTAG_COMMAND_BLOCK_WRITE = 4,
JTAG_COMMAND_CHAIN = 5,
} JTAG_proxy_protocol_commands;
 
/* Each transmit structure must begin with an integer
which specifies the type of command. Information
after this is variable. Make sure to have all information
aligned properly. If we stick with 32 bit integers, it
should be portable onto every platform. These structures
will be transmitted across the network in network byte
order.
*/
 
typedef struct {
uint32_t command;
uint32_t length;
uint32_t address;
uint32_t data_H;
uint32_t data_L;
} JTAGProxyWriteMessage;
 
typedef struct {
uint32_t command;
uint32_t length;
uint32_t address;
} JTAGProxyReadMessage;
 
typedef struct {
uint32_t command;
uint32_t length;
uint32_t address;
int32_t nRegisters;
uint32_t data[1];
} JTAGProxyBlockWriteMessage;
 
typedef struct {
uint32_t command;
uint32_t length;
uint32_t address;
int32_t nRegisters;
} JTAGProxyBlockReadMessage;
 
typedef struct {
uint32_t command;
uint32_t length;
uint32_t chain;
} JTAGProxyChainMessage;
 
/* The responses are messages specific, however convention
states the first word should be an error code. Again,
sticking with 32 bit integers should provide maximum
portability. */
 
typedef struct {
int32_t status;
} JTAGProxyWriteResponse;
 
typedef struct {
int32_t status;
uint32_t data_H;
uint32_t data_L;
} JTAGProxyReadResponse;
typedef struct {
int32_t status;
} JTAGProxyBlockWriteResponse;
 
typedef struct {
int32_t status;
int32_t nRegisters;
uint32_t data[1];
/* uint32_t data[nRegisters-1] still unread */
} JTAGProxyBlockReadResponse;
 
typedef struct {
int32_t status;
} JTAGProxyChainResponse;
 
 
#endif /* GDB_H */
/or_debug_proxy/includes/win_FTCJTAG.h
0,0 → 1,236
/*++
 
FTC MPSSE Interface DLLs - Copyright © FTDI Ltd. 2009
 
 
The source code to the FTCI2C, FTCJTAG and FTCSPI DLLs is provided as-is and no warranty is made as to its function or reliability.
 
This source code may be freely modified and redistributed, provided that the FTDI Ltd. copyright notice remains intact.
 
Copyright (c) 2005 Future Technology Devices International Ltd.
 
Module Name:
 
ftcjtag.h
 
Abstract:
 
API DLL for FT2232C Dual Device setup to simulate the Joint Test Action Group(JTAG) synchronous protocol.
FTCJTAG library definitions
 
Environment:
 
kernel & user mode
 
Revision History:
 
07/02/05 kra Created.
--*/
 
 
#ifndef win_FTCJTAG_H
#define win_FTCJTAG_H
 
 
// The following ifdef block is the standard way of creating macros
// which make exporting from a DLL simpler. All files within this DLL
// are compiled with the FTCJTAG_EXPORTS symbol defined on the command line.
// This symbol should not be defined on any project that uses this DLL.
// This way any other project whose source files include this file see
// FTCJTAG_API functions as being imported from a DLL, whereas this DLL
// sees symbols defined with this macro as being exported.
 
#ifdef FTCJTAG_EXPORTS
#define FTCJTAG_API __declspec(dllexport)
#else
#define FTCJTAG_API __declspec(dllimport)
#endif
 
typedef DWORD FTC_HANDLE;
typedef ULONG FTC_STATUS;
 
#define TEST_LOGIC_STATE 1
#define RUN_TEST_IDLE_STATE 2
#define PAUSE_TEST_DATA_REGISTER_STATE 3
#define PAUSE_INSTRUCTION_REGISTER_STATE 4
#define SHIFT_TEST_DATA_REGISTER_STATE 5
#define SHIFT_INSTRUCTION_REGISTER_STATE 6
 
#define FTC_SUCCESS 0 // FTC_OK
#define FTC_INVALID_HANDLE 1 // FTC_INVALID_HANDLE
#define FTC_DEVICE_NOT_FOUND 2 //FTC_DEVICE_NOT_FOUND
#define FTC_DEVICE_NOT_OPENED 3 //FTC_DEVICE_NOT_OPENED
#define FTC_IO_ERROR 4 //FTC_IO_ERROR
#define FTC_INSUFFICIENT_RESOURCES 5 // FTC_INSUFFICIENT_RESOURCES
 
#define FTC_FAILED_TO_COMPLETE_COMMAND 20 // cannot change, error code mapped from FT2232c classes
#define FTC_FAILED_TO_SYNCHRONIZE_DEVICE_MPSSE 21 // cannot change, error code mapped from FT2232c classes
#define FTC_INVALID_DEVICE_NAME_INDEX 22 // cannot change, error code mapped from FT2232c classes
#define FTC_NULL_DEVICE_NAME_BUFFER_POINTER 23 // cannot change, error code mapped from FT2232c classes
#define FTC_DEVICE_NAME_BUFFER_TOO_SMALL 24 // cannot change, error code mapped from FT2232c classes
#define FTC_INVALID_DEVICE_NAME 25 // cannot change, error code mapped from FT2232c classes
#define FTC_INVALID_LOCATION_ID 26 // cannot change, error code mapped from FT2232c classes
#define FTC_DEVICE_IN_USE 27 // cannot change, error code mapped from FT2232c classes
#define FTC_TOO_MANY_DEVICES 28 // cannot change, error code mapped from FT2232c classes
#define FTC_INVALID_CLOCK_DIVISOR 29
#define FTC_NULL_INPUT_OUTPUT_BUFFER_POINTER 30
#define FTC_INVALID_NUMBER_BITS 31
#define FTC_NULL_WRITE_DATA_BUFFER_POINTER 32
#define FTC_INVALID_NUMBER_BYTES 33
#define FTC_NUMBER_BYTES_TOO_SMALL 34
#define FTC_INVALID_TAP_CONTROLLER_STATE 35
#define FTC_NULL_READ_DATA_BUFFER_POINTER 36
#define FTC_COMMAND_SEQUENCE_BUFFER_FULL 37
#define FTC_NULL_READ_CMDS_DATA_BUFFER_POINTER 38
#define FTC_NO_COMMAND_SEQUENCE 39
#define FTC_NULL_DLL_VERSION_BUFFER_POINTER 40
#define FTC_DLL_VERSION_BUFFER_TOO_SMALL 41
#define FTC_NULL_LANGUAGE_CODE_BUFFER_POINTER 42
#define FTC_NULL_ERROR_MESSAGE_BUFFER_POINTER 43
#define FTC_ERROR_MESSAGE_BUFFER_TOO_SMALL 44
#define FTC_INVALID_LANGUAGE_CODE 45
#define FTC_INVALID_STATUS_CODE 46
 
#ifdef __cplusplus
extern "C" {
#endif
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_GetNumDevices(LPDWORD lpdwNumDevices);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_GetDeviceNameLocID(DWORD dwDeviceNameIndex, LPSTR lpDeviceNameBuffer, DWORD dwBufferSize, LPDWORD lpdwLocationID);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_OpenEx(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_Open(FTC_HANDLE *pftHandle);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_Close(FTC_HANDLE ftHandle);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_InitDevice(FTC_HANDLE ftHandle, DWORD dwClockDivisor);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_GetClock(DWORD dwClockDivisor, LPDWORD lpdwClockFrequencyHz);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_SetClock(FTC_HANDLE ftHandle, DWORD dwClockDivisor, LPDWORD lpdwClockFrequencyHz);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_SetLoopback(FTC_HANDLE ftHandle, BOOL bLoopbackState);
 
typedef struct Ft_Input_Output_Pins{
BOOL bPin1InputOutputState;
BOOL bPin1LowHighState;
BOOL bPin2InputOutputState;
BOOL bPin2LowHighState;
BOOL bPin3InputOutputState;
BOOL bPin3LowHighState;
BOOL bPin4InputOutputState;
BOOL bPin4LowHighState;
}FTC_INPUT_OUTPUT_PINS, *PFTC_INPUT_OUTPUT_PINS;
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_SetGPIOs(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins,
PFTC_INPUT_OUTPUT_PINS pLowInputOutputPinsData,
BOOL bControlHighInputOutputPins,
PFTC_INPUT_OUTPUT_PINS pHighInputOutputPinsData);
 
typedef struct Ft_Low_High_Pins{
BOOL bPin1LowHighState;
BOOL bPin2LowHighState;
BOOL bPin3LowHighState;
BOOL bPin4LowHighState;
}FTC_LOW_HIGH_PINS, *PFTC_LOW_HIGH_PINS;
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_GetGPIOs(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins,
PFTC_LOW_HIGH_PINS pLowPinsInputData,
BOOL bControlHighInputOutputPins,
PFTC_LOW_HIGH_PINS pHighPinsInputData);
 
#define MAX_WRITE_DATA_BYTES_BUFFER_SIZE 65536 // 64k bytes
 
typedef BYTE WriteDataByteBuffer[MAX_WRITE_DATA_BYTES_BUFFER_SIZE];
typedef WriteDataByteBuffer *PWriteDataByteBuffer;
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_Write(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
 
#define MAX_READ_DATA_BYTES_BUFFER_SIZE 65536 // 64k bytes
 
typedef BYTE ReadDataByteBuffer[MAX_READ_DATA_BYTES_BUFFER_SIZE];
typedef ReadDataByteBuffer *PReadDataByteBuffer;
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_Read(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead,
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned,
DWORD dwTapControllerState);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_WriteRead(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned,
DWORD dwTapControllerState);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_ClearCmdSequence(void);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_AddWriteCmd(BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_AddReadCmd(BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_AddWriteReadCmd(BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
 
#define MAX_READ_CMDS_DATA_BYTES_BUFFER_SIZE 131071 // 128K bytes
 
typedef BYTE ReadCmdSequenceDataByteBuffer[MAX_READ_CMDS_DATA_BYTES_BUFFER_SIZE];
typedef ReadCmdSequenceDataByteBuffer *PReadCmdSequenceDataByteBuffer;
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_ClearDeviceCmdSequence(FTC_HANDLE ftHandle);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_AddDeviceWriteCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_AddDeviceReadCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_AddDeviceWriteReadCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_ExecuteCmdSequence(FTC_HANDLE ftHandle, PReadCmdSequenceDataByteBuffer pReadCmdSequenceDataBuffer,
LPDWORD lpdwNumBytesReturned);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_GetDllVersion(LPSTR lpDllVersionBuffer, DWORD dwBufferSize);
 
FTCJTAG_API
FTC_STATUS WINAPI JTAG_GetErrorCodeString(LPSTR lpLanguage, FTC_STATUS StatusCode,
LPSTR lpErrorMessageBuffer, DWORD dwBufferSize);
 
 
#ifdef __cplusplus
}
#endif
 
 
#endif /* win_FTCJTAG_H */
/or_debug_proxy/includes/ftd2xx.h
0,0 → 1,952
/*++
 
FTC MPSSE Interface DLLs - Copyright © FTDI Ltd. 2009
 
 
The source code to the FTCI2C, FTCJTAG and FTCSPI DLLs is provided as-is and no warranty is made as to its function or reliability.
 
This source code may be freely modified and redistributed, provided that the FTDI Ltd. copyright notice remains intact.
 
Copyright (c) 2001-2006 Future Technology Devices International Ltd.
 
Module Name:
 
ftd2xx.h
 
Abstract:
 
Native USB interface for FTDI FT8U232/245/2232C
FTD2XX library definitions
 
Environment:
 
kernel & user mode
 
Revision History:
 
13/03/01 awm Created.
13/01/03 awm Added device information support.
19/03/03 awm Added FT_W32_CancelIo.
12/06/03 awm Added FT_StopInTask and FT_RestartInTask.
18/09/03 awm Added FT_SetResetPipeRetryCount.
10/10/03 awm Added FT_ResetPort.
/03/04 st modified for linux users
12/10/04 st added FT_SetVIDPID
 
--*/
 
 
#ifndef FTD2XX_H
#define FTD2XX_H
 
#ifndef _WINDOWS
#include <pthread.h>
#define WINAPI
#endif
 
// The following ifdef block is the standard way of creating macros
// which make exporting from a DLL simpler. All files within this DLL
// are compiled with the FTD2XX_EXPORTS symbol defined on the command line.
// This symbol should not be defined on any project that uses this DLL.
// This way any other project whose source files include this file see
// FTD2XX_API functions as being imported from a DLL, whereas this DLL
// sees symbols defined with this macro as being exported.
 
#ifdef FTD2XX_EXPORTS
#define FTD2XX_API __declspec(dllexport)
#else
#define FTD2XX_API __declspec(dllimport)
#endif
 
#ifndef _WINDOWS
#include "WinTypes.h"
#ifdef FTD2XX_API
#undef FTD2XX_API
#define FTD2XX_API
#endif
#endif
typedef struct _EVENT_HANDLE{
pthread_cond_t eCondVar;
pthread_mutex_t eMutex;
int iVar;
} EVENT_HANDLE;
 
typedef DWORD *FT_HANDLE;
 
typedef ULONG FT_STATUS;
 
//
// Device status
//
enum {
FT_OK,
FT_INVALID_HANDLE,
FT_DEVICE_NOT_FOUND,
FT_DEVICE_NOT_OPENED,
FT_IO_ERROR,
FT_INSUFFICIENT_RESOURCES,
FT_INVALID_PARAMETER,
FT_INVALID_BAUD_RATE, //7
 
FT_DEVICE_NOT_OPENED_FOR_ERASE,
FT_DEVICE_NOT_OPENED_FOR_WRITE,
FT_FAILED_TO_WRITE_DEVICE,
FT_EEPROM_READ_FAILED,
FT_EEPROM_WRITE_FAILED,
FT_EEPROM_ERASE_FAILED,
FT_EEPROM_NOT_PRESENT,
FT_EEPROM_NOT_PROGRAMMED,
FT_INVALID_ARGS,
FT_NOT_SUPPORTED,
FT_OTHER_ERROR
};
 
 
#define FT_SUCCESS(status) ((status) == FT_OK)
 
//
// FT_OpenEx Flags
//
 
#define FT_OPEN_BY_SERIAL_NUMBER 1
#define FT_OPEN_BY_DESCRIPTION 2
#define FT_OPEN_BY_LOCATION 4
//
// FT_ListDevices Flags (used in conjunction with FT_OpenEx Flags
//
 
#define FT_LIST_NUMBER_ONLY 0x80000000
#define FT_LIST_BY_INDEX 0x40000000
#define FT_LIST_ALL 0x20000000
 
#define FT_LIST_MASK (FT_LIST_NUMBER_ONLY|FT_LIST_BY_INDEX|FT_LIST_ALL)
 
//
// Baud Rates
//
 
#define FT_BAUD_300 300
#define FT_BAUD_600 600
#define FT_BAUD_1200 1200
#define FT_BAUD_2400 2400
#define FT_BAUD_4800 4800
#define FT_BAUD_9600 9600
#define FT_BAUD_14400 14400
#define FT_BAUD_19200 19200
#define FT_BAUD_38400 38400
#define FT_BAUD_57600 57600
#define FT_BAUD_115200 115200
#define FT_BAUD_230400 230400
#define FT_BAUD_460800 460800
#define FT_BAUD_921600 921600
 
//
// Word Lengths
//
 
#define FT_BITS_8 (UCHAR) 8
#define FT_BITS_7 (UCHAR) 7
#define FT_BITS_6 (UCHAR) 6
#define FT_BITS_5 (UCHAR) 5
 
//
// Stop Bits
//
 
#define FT_STOP_BITS_1 (UCHAR) 0
#define FT_STOP_BITS_1_5 (UCHAR) 1
#define FT_STOP_BITS_2 (UCHAR) 2
 
//
// Parity
//
 
#define FT_PARITY_NONE (UCHAR) 0
#define FT_PARITY_ODD (UCHAR) 1
#define FT_PARITY_EVEN (UCHAR) 2
#define FT_PARITY_MARK (UCHAR) 3
#define FT_PARITY_SPACE (UCHAR) 4
 
//
// Flow Control
//
 
#define FT_FLOW_NONE 0x0000
#define FT_FLOW_RTS_CTS 0x0100
#define FT_FLOW_DTR_DSR 0x0200
#define FT_FLOW_XON_XOFF 0x0400
 
//
// Purge rx and tx buffers
//
#define FT_PURGE_RX 1
#define FT_PURGE_TX 2
 
//
// Events
//
 
typedef void (*PFT_EVENT_HANDLER)(DWORD,DWORD);
 
#define FT_EVENT_RXCHAR 1
#define FT_EVENT_MODEM_STATUS 2
 
//
// Timeouts
//
 
#define FT_DEFAULT_RX_TIMEOUT 300
#define FT_DEFAULT_TX_TIMEOUT 300
 
//
// Device types
//
 
typedef ULONG FT_DEVICE;
 
enum {
FT_DEVICE_BM,
FT_DEVICE_AM,
FT_DEVICE_100AX,
FT_DEVICE_UNKNOWN,
FT_DEVICE_2232C,
FT_DEVICE_232R
};
 
 
#ifdef __cplusplus
extern "C" {
#endif
FTD2XX_API
FT_STATUS WINAPI FT_Open(
int deviceNumber,
FT_HANDLE *pHandle
);
 
FTD2XX_API
FT_STATUS WINAPI FT_OpenEx(
PVOID pArg1,
DWORD Flags,
FT_HANDLE *pHandle
);
 
FTD2XX_API
FT_STATUS WINAPI FT_ListDevices(
PVOID pArg1,
PVOID pArg2,
DWORD Flags
);
 
FTD2XX_API
FT_STATUS FT_SetVIDPID(
DWORD dwVID,
DWORD dwPID
);
FTD2XX_API
FT_STATUS FT_GetVIDPID(
DWORD * pdwVID,
DWORD * pdwPID
);
 
FTD2XX_API
FT_STATUS WINAPI FT_Close(
FT_HANDLE ftHandle
);
 
FTD2XX_API
FT_STATUS WINAPI FT_Read(
FT_HANDLE ftHandle,
LPVOID lpBuffer,
DWORD nBufferSize,
LPDWORD lpBytesReturned
);
 
FTD2XX_API
FT_STATUS WINAPI FT_Write(
FT_HANDLE ftHandle,
LPVOID lpBuffer,
DWORD nBufferSize,
LPDWORD lpBytesWritten
);
 
FTD2XX_API
FT_STATUS WINAPI FT_IoCtl( // Linux, OS X: Not supported
FT_HANDLE ftHandle,
DWORD dwIoControlCode,
LPVOID lpInBuf,
DWORD nInBufSize,
LPVOID lpOutBuf,
DWORD nOutBufSize,
LPDWORD lpBytesReturned,
LPOVERLAPPED lpOverlapped
);
 
FTD2XX_API
FT_STATUS WINAPI FT_SetBaudRate(
FT_HANDLE ftHandle,
ULONG BaudRate
);
 
FTD2XX_API
FT_STATUS WINAPI FT_SetDivisor(
FT_HANDLE ftHandle,
USHORT Divisor
);
 
FTD2XX_API
FT_STATUS WINAPI FT_SetDataCharacteristics(
FT_HANDLE ftHandle,
UCHAR WordLength,
UCHAR StopBits,
UCHAR Parity
);
 
FTD2XX_API
FT_STATUS WINAPI FT_SetFlowControl(
FT_HANDLE ftHandle,
USHORT FlowControl,
UCHAR XonChar,
UCHAR XoffChar
);
 
FTD2XX_API
FT_STATUS WINAPI FT_ResetDevice(
FT_HANDLE ftHandle
);
 
FTD2XX_API
FT_STATUS WINAPI FT_SetDtr(
FT_HANDLE ftHandle
);
 
FTD2XX_API
FT_STATUS WINAPI FT_ClrDtr(
FT_HANDLE ftHandle
);
 
FTD2XX_API
FT_STATUS WINAPI FT_SetRts(
FT_HANDLE ftHandle
);
 
FTD2XX_API
FT_STATUS WINAPI FT_ClrRts(
FT_HANDLE ftHandle
);
 
FTD2XX_API
FT_STATUS WINAPI FT_GetModemStatus(
FT_HANDLE ftHandle,
ULONG *pModemStatus
);
FTD2XX_API
FT_STATUS WINAPI FT_SetChars(
FT_HANDLE ftHandle,
UCHAR EventChar,
UCHAR EventCharEnabled,
UCHAR ErrorChar,
UCHAR ErrorCharEnabled
);
 
FTD2XX_API
FT_STATUS WINAPI FT_Purge(
FT_HANDLE ftHandle,
ULONG Mask
);
 
FTD2XX_API
FT_STATUS WINAPI FT_SetTimeouts(
FT_HANDLE ftHandle,
ULONG ReadTimeout,
ULONG WriteTimeout
);
 
FTD2XX_API
FT_STATUS WINAPI FT_GetQueueStatus(
FT_HANDLE ftHandle,
DWORD *dwRxBytes
);
 
FTD2XX_API
FT_STATUS WINAPI FT_SetEventNotification(
FT_HANDLE ftHandle,
DWORD Mask,
PVOID Param
);
 
FTD2XX_API
FT_STATUS WINAPI FT_GetStatus(
FT_HANDLE ftHandle,
DWORD *dwRxBytes,
DWORD *dwTxBytes,
DWORD *dwEventDWord
);
 
FTD2XX_API
FT_STATUS WINAPI FT_SetBreakOn(
FT_HANDLE ftHandle
);
 
FTD2XX_API
FT_STATUS WINAPI FT_SetBreakOff(
FT_HANDLE ftHandle
);
 
FTD2XX_API
FT_STATUS WINAPI FT_SetWaitMask( // Linux, OS X: Not supported
FT_HANDLE ftHandle,
DWORD Mask
);
 
FTD2XX_API
FT_STATUS WINAPI FT_WaitOnMask( // Linux, OS X: Not supported
FT_HANDLE ftHandle,
DWORD *Mask
);
 
FTD2XX_API
FT_STATUS WINAPI FT_GetEventStatus(
FT_HANDLE ftHandle,
DWORD *dwEventDWord
);
 
FTD2XX_API
FT_STATUS WINAPI FT_ReadEE(
FT_HANDLE ftHandle,
DWORD dwWordOffset,
LPWORD lpwValue
);
 
FTD2XX_API
FT_STATUS WINAPI FT_WriteEE(
FT_HANDLE ftHandle,
DWORD dwWordOffset,
WORD wValue
);
 
FTD2XX_API
FT_STATUS WINAPI FT_EraseEE(
FT_HANDLE ftHandle
);
//
// structure to hold program data for FT_Program function
//
typedef struct ft_program_data {
 
DWORD Signature1; // Header - must be 0x00000000
DWORD Signature2; // Header - must be 0xffffffff
DWORD Version; // Header - FT_PROGRAM_DATA version
// 0 = original
// 1 = FT2232C extensions
// 2 = FT232R extensions
 
WORD VendorId; // 0x0403
WORD ProductId; // 0x6001
char *Manufacturer; // "FTDI"
char *ManufacturerId; // "FT"
char *Description; // "USB HS Serial Converter"
char *SerialNumber; // "FT000001" if fixed, or NULL
WORD MaxPower; // 0 < MaxPower <= 500
WORD PnP; // 0 = disabled, 1 = enabled
WORD SelfPowered; // 0 = bus powered, 1 = self powered
WORD RemoteWakeup; // 0 = not capable, 1 = capable
//
// Rev4 extensions
//
UCHAR Rev4; // non-zero if Rev4 chip, zero otherwise
UCHAR IsoIn; // non-zero if in endpoint is isochronous
UCHAR IsoOut; // non-zero if out endpoint is isochronous
UCHAR PullDownEnable; // non-zero if pull down enabled
UCHAR SerNumEnable; // non-zero if serial number to be used
UCHAR USBVersionEnable; // non-zero if chip uses USBVersion
WORD USBVersion; // BCD (0x0200 => USB2)
//
// FT2232C extensions
//
UCHAR Rev5; // non-zero if Rev5 chip, zero otherwise
UCHAR IsoInA; // non-zero if in endpoint is isochronous
UCHAR IsoInB; // non-zero if in endpoint is isochronous
UCHAR IsoOutA; // non-zero if out endpoint is isochronous
UCHAR IsoOutB; // non-zero if out endpoint is isochronous
UCHAR PullDownEnable5; // non-zero if pull down enabled
UCHAR SerNumEnable5; // non-zero if serial number to be used
UCHAR USBVersionEnable5; // non-zero if chip uses USBVersion
WORD USBVersion5; // BCD (0x0200 => USB2)
UCHAR AIsHighCurrent; // non-zero if interface is high current
UCHAR BIsHighCurrent; // non-zero if interface is high current
UCHAR IFAIsFifo; // non-zero if interface is 245 FIFO
UCHAR IFAIsFifoTar; // non-zero if interface is 245 FIFO CPU target
UCHAR IFAIsFastSer; // non-zero if interface is Fast serial
UCHAR AIsVCP; // non-zero if interface is to use VCP drivers
UCHAR IFBIsFifo; // non-zero if interface is 245 FIFO
UCHAR IFBIsFifoTar; // non-zero if interface is 245 FIFO CPU target
UCHAR IFBIsFastSer; // non-zero if interface is Fast serial
UCHAR BIsVCP; // non-zero if interface is to use VCP drivers
//
// FT232R extensions
//
UCHAR UseExtOsc; // Use External Oscillator
UCHAR HighDriveIOs; // High Drive I/Os
UCHAR EndpointSize; // Endpoint size
 
UCHAR PullDownEnableR; // non-zero if pull down enabled
UCHAR SerNumEnableR; // non-zero if serial number to be used
 
UCHAR InvertTXD; // non-zero if invert TXD
UCHAR InvertRXD; // non-zero if invert RXD
UCHAR InvertRTS; // non-zero if invert RTS
UCHAR InvertCTS; // non-zero if invert CTS
UCHAR InvertDTR; // non-zero if invert DTR
UCHAR InvertDSR; // non-zero if invert DSR
UCHAR InvertDCD; // non-zero if invert DCD
UCHAR InvertRI; // non-zero if invert RI
 
UCHAR Cbus0; // Cbus Mux control
UCHAR Cbus1; // Cbus Mux control
UCHAR Cbus2; // Cbus Mux control
UCHAR Cbus3; // Cbus Mux control
UCHAR Cbus4; // Cbus Mux control
 
UCHAR RIsVCP; // zero if using VCP drivers
} FT_PROGRAM_DATA, *PFT_PROGRAM_DATA;
 
 
FTD2XX_API
FT_STATUS WINAPI FT_EE_Program(
FT_HANDLE ftHandle,
PFT_PROGRAM_DATA pData
);
 
FTD2XX_API
FT_STATUS WINAPI FT_EE_ProgramEx(
FT_HANDLE ftHandle,
PFT_PROGRAM_DATA lpData,
char *Manufacturer,
char *ManufacturerId,
char *Description,
char *SerialNumber
);
FTD2XX_API
FT_STATUS WINAPI FT_EE_Read(
FT_HANDLE ftHandle,
PFT_PROGRAM_DATA pData
);
 
FTD2XX_API
FT_STATUS WINAPI FT_EE_ReadEx(
FT_HANDLE ftHandle,
PFT_PROGRAM_DATA lpData,
char *Manufacturer,
char *ManufacturerId,
char *Description,
char *SerialNumber
);
FTD2XX_API
FT_STATUS WINAPI FT_EE_UASize(
FT_HANDLE ftHandle,
LPDWORD lpdwSize
);
 
FTD2XX_API
FT_STATUS WINAPI FT_EE_UAWrite(
FT_HANDLE ftHandle,
PUCHAR pucData,
DWORD dwDataLen
);
 
FTD2XX_API
FT_STATUS WINAPI FT_EE_UARead(
FT_HANDLE ftHandle,
PUCHAR pucData,
DWORD dwDataLen,
LPDWORD lpdwBytesRead
);
 
FTD2XX_API
FT_STATUS WINAPI FT_SetLatencyTimer(
FT_HANDLE ftHandle,
UCHAR ucLatency
);
 
FTD2XX_API
FT_STATUS WINAPI FT_GetLatencyTimer(
FT_HANDLE ftHandle,
PUCHAR pucLatency
);
 
FTD2XX_API
FT_STATUS WINAPI FT_SetBitMode(
FT_HANDLE ftHandle,
UCHAR ucMask,
UCHAR ucEnable
);
 
FTD2XX_API
FT_STATUS WINAPI FT_GetBitMode(
FT_HANDLE ftHandle,
PUCHAR pucMode
);
 
FTD2XX_API
FT_STATUS WINAPI FT_SetUSBParameters(
FT_HANDLE ftHandle,
ULONG ulInTransferSize,
ULONG ulOutTransferSize
);
FTD2XX_API
FT_STATUS WINAPI FT_SetDeadmanTimeout(
FT_HANDLE ftHandle,
ULONG ulDeadmanTimeout // -1 for infinite (2.6 kernels only). High +ve number for 2.4 kernels
);
FTD2XX_API
FT_STATUS WINAPI FT_GetDeviceInfo(
FT_HANDLE ftHandle,
FT_DEVICE *lpftDevice,
LPDWORD lpdwID,
PCHAR SerialNumber,
PCHAR Description,
LPVOID Dummy
);
 
FTD2XX_API
FT_STATUS WINAPI FT_StopInTask(
FT_HANDLE ftHandle
);
 
FTD2XX_API
FT_STATUS WINAPI FT_RestartInTask(
FT_HANDLE ftHandle
);
 
FTD2XX_API
FT_STATUS WINAPI FT_SetResetPipeRetryCount( // Linux, OS X: Not supported
FT_HANDLE ftHandle,
DWORD dwCount
);
 
FTD2XX_API
FT_STATUS WINAPI FT_ResetPort( // Linux, OS X: Not supported
FT_HANDLE ftHandle
);
FTD2XX_API
FT_STATUS WINAPI FT_CyclePort( // Linux, OS X: Not supported
FT_HANDLE ftHandle
);
 
 
//
// Win32-type functions
//
 
FTD2XX_API
FT_HANDLE WINAPI FT_W32_CreateFile(
LPCSTR lpszName,
DWORD dwAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreate,
DWORD dwAttrsAndFlags,
HANDLE hTemplate
);
 
FTD2XX_API
BOOL WINAPI FT_W32_CloseHandle(
FT_HANDLE ftHandle
);
 
FTD2XX_API
BOOL WINAPI FT_W32_ReadFile(
FT_HANDLE ftHandle,
LPVOID lpBuffer,
DWORD nBufferSize,
LPDWORD lpBytesReturned,
LPOVERLAPPED lpOverlapped
);
 
FTD2XX_API
BOOL WINAPI FT_W32_WriteFile(
FT_HANDLE ftHandle,
LPVOID lpBuffer,
DWORD nBufferSize,
LPDWORD lpBytesWritten,
LPOVERLAPPED lpOverlapped
);
 
FTD2XX_API
DWORD WINAPI FT_W32_GetLastError(
FT_HANDLE ftHandle
);
 
FTD2XX_API
BOOL WINAPI FT_W32_GetOverlappedResult( // Linux, OS X: Not supported
FT_HANDLE ftHandle,
LPOVERLAPPED lpOverlapped,
LPDWORD lpdwBytesTransferred,
BOOL bWait
);
 
FTD2XX_API
BOOL WINAPI FT_W32_CancelIo( // Linux, OS X: Not supported
FT_HANDLE ftHandle
);
 
 
//
// Win32 COMM API type functions
//
typedef struct _FTCOMSTAT {
DWORD fCtsHold : 1;
DWORD fDsrHold : 1;
DWORD fRlsdHold : 1;
DWORD fXoffHold : 1;
DWORD fXoffSent : 1;
DWORD fEof : 1;
DWORD fTxim : 1;
DWORD fReserved : 25;
DWORD cbInQue;
DWORD cbOutQue;
} FTCOMSTAT, *LPFTCOMSTAT;
 
typedef struct _FTDCB {
DWORD DCBlength; /* sizeof(FTDCB) */
DWORD BaudRate; /* Baudrate at which running */
DWORD fBinary: 1; /* Binary Mode (skip EOF check) */
DWORD fParity: 1; /* Enable parity checking */
DWORD fOutxCtsFlow:1; /* CTS handshaking on output */
DWORD fOutxDsrFlow:1; /* DSR handshaking on output */
DWORD fDtrControl:2; /* DTR Flow control */
DWORD fDsrSensitivity:1; /* DSR Sensitivity */
DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */
DWORD fOutX: 1; /* Enable output X-ON/X-OFF */
DWORD fInX: 1; /* Enable input X-ON/X-OFF */
DWORD fErrorChar: 1; /* Enable Err Replacement */
DWORD fNull: 1; /* Enable Null stripping */
DWORD fRtsControl:2; /* Rts Flow control */
DWORD fAbortOnError:1; /* Abort all reads and writes on Error */
DWORD fDummy2:17; /* Reserved */
WORD wReserved; /* Not currently used */
WORD XonLim; /* Transmit X-ON threshold */
WORD XoffLim; /* Transmit X-OFF threshold */
BYTE ByteSize; /* Number of bits/byte, 4-8 */
BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */
BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */
char XonChar; /* Tx and Rx X-ON character */
char XoffChar; /* Tx and Rx X-OFF character */
char ErrorChar; /* Error replacement char */
char EofChar; /* End of Input character */
char EvtChar; /* Received Event character */
WORD wReserved1; /* Fill for now. */
} FTDCB, *LPFTDCB;
 
typedef struct _FTTIMEOUTS {
DWORD ReadIntervalTimeout; /* Maximum time between read chars. */
DWORD ReadTotalTimeoutMultiplier; /* Multiplier of characters. */
DWORD ReadTotalTimeoutConstant; /* Constant in milliseconds. */
DWORD WriteTotalTimeoutMultiplier; /* Multiplier of characters. */
DWORD WriteTotalTimeoutConstant; /* Constant in milliseconds. */
} FTTIMEOUTS,*LPFTTIMEOUTS;
 
 
FTD2XX_API
BOOL WINAPI FT_W32_ClearCommBreak(
FT_HANDLE ftHandle
);
 
FTD2XX_API
BOOL WINAPI FT_W32_ClearCommError(
FT_HANDLE ftHandle,
LPDWORD lpdwErrors,
LPFTCOMSTAT lpftComstat
);
 
FTD2XX_API
BOOL WINAPI FT_W32_EscapeCommFunction(
FT_HANDLE ftHandle,
DWORD dwFunc
);
 
FTD2XX_API
BOOL WINAPI FT_W32_GetCommModemStatus(
FT_HANDLE ftHandle,
LPDWORD lpdwModemStatus
);
 
FTD2XX_API
BOOL WINAPI FT_W32_GetCommState(
FT_HANDLE ftHandle,
LPFTDCB lpftDcb
);
 
FTD2XX_API
BOOL WINAPI FT_W32_GetCommTimeouts(
FT_HANDLE ftHandle,
FTTIMEOUTS *pTimeouts
);
 
FTD2XX_API
BOOL WINAPI FT_W32_PurgeComm(
FT_HANDLE ftHandle,
DWORD dwMask
);
 
FTD2XX_API
BOOL WINAPI FT_W32_SetCommBreak(
FT_HANDLE ftHandle
);
 
FTD2XX_API
BOOL WINAPI FT_W32_SetCommMask(
FT_HANDLE ftHandle,
ULONG ulEventMask
);
 
FTD2XX_API
BOOL WINAPI FT_W32_SetCommState(
FT_HANDLE ftHandle,
LPFTDCB lpftDcb
);
 
FTD2XX_API
BOOL WINAPI FT_W32_SetCommTimeouts(
FT_HANDLE ftHandle,
FTTIMEOUTS *pTimeouts
);
 
FTD2XX_API
BOOL WINAPI FT_W32_SetupComm(
FT_HANDLE ftHandle,
DWORD dwReadBufferSize,
DWORD dwWriteBufferSize
);
 
FTD2XX_API
BOOL WINAPI FT_W32_WaitCommEvent(
FT_HANDLE ftHandle,
PULONG pulEvent,
LPOVERLAPPED lpOverlapped
);
 
//
// Device information
//
 
typedef struct _ft_device_list_info_node {
ULONG Flags;
ULONG Type;
ULONG ID;
DWORD LocId;
char SerialNumber[16];
char Description[64];
FT_HANDLE ftHandle;
} FT_DEVICE_LIST_INFO_NODE;
 
FTD2XX_API
FT_STATUS WINAPI FT_CreateDeviceInfoList(
LPDWORD lpdwNumDevs
);
 
FTD2XX_API
FT_STATUS WINAPI FT_GetDeviceInfoList(
FT_DEVICE_LIST_INFO_NODE *pDest,
LPDWORD lpdwNumDevs
);
 
FTD2XX_API
FT_STATUS WINAPI FT_GetDeviceInfoDetail(
DWORD dwIndex,
LPDWORD lpdwFlags,
LPDWORD lpdwType,
LPDWORD lpdwID,
LPDWORD lpdwLocId,
LPVOID lpSerialNumber,
LPVOID lpDescription,
FT_HANDLE *pftHandle
);
FTD2XX_API
FT_STATUS WINAPI FT_GetDriverVersion(
FT_HANDLE ftHandle,
LPDWORD lpdwVersion
);
FTD2XX_API
FT_STATUS WINAPI FT_GetLibraryVersion(
LPDWORD lpdwVersion
);
 
//
// Events
//
 
#define EV_RXCHAR 0x0001 // Any Character received
#define EV_RXFLAG 0x0002 // Received certain character
#define EV_TXEMPTY 0x0004 // Transmitt Queue Empty
#define EV_CTS 0x0008 // CTS changed state
#define EV_DSR 0x0010 // DSR changed state
#define EV_RLSD 0x0020 // RLSD changed state
#define EV_BREAK 0x0040 // BREAK received
#define EV_ERR 0x0080 // Line status error occurred
#define EV_RING 0x0100 // Ring signal detected
#define EV_PERR 0x0200 // Printer error occured
#define EV_RX80FULL 0x0400 // Receive buffer is 80 percent full
#define EV_EVENT1 0x0800 // Provider specific event 1
#define EV_EVENT2 0x1000 // Provider specific event 2
 
//
// Escape Functions
//
 
#define SETXOFF 1 // Simulate XOFF received
#define SETXON 2 // Simulate XON received
#define SETRTS 3 // Set RTS high
#define CLRRTS 4 // Set RTS low
#define SETDTR 5 // Set DTR high
#define CLRDTR 6 // Set DTR low
#define RESETDEV 7 // Reset device if possible
#define SETBREAK 8 // Set the device break line.
#define CLRBREAK 9 // Clear the device break line.
 
//
// PURGE function flags.
//
#define PURGE_TXABORT 0x0001 // Kill the pending/current writes to the comm port.
#define PURGE_RXABORT 0x0002 // Kill the pending/current reads to the comm port.
#define PURGE_TXCLEAR 0x0004 // Kill the transmit queue if there.
#define PURGE_RXCLEAR 0x0008 // Kill the typeahead buffer if there.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
#ifdef __cplusplus
}
#endif
 
 
#endif /* FTD2XX_H */
 
 
 
 
 
 
/or_debug_proxy/includes/usb_functions.h
0,0 → 1,82
/*$$HEADER*/
/******************************************************************************/
/* */
/* H E A D E R I N F O R M A T I O N */
/* */
/******************************************************************************/
 
// Project Name : OpenRISC Debug Proxy
// File Name : usb_functions.h
// Prepared By : jb
// Project Start : 2008-10-01
 
/*$$COPYRIGHT NOTICE*/
/******************************************************************************/
/* */
/* C O P Y R I G H T N O T I C E */
/* */
/******************************************************************************/
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation;
version 2.1 of the License, a copy of which is available from
http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt.
 
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
 
/*$$CHANGE HISTORY*/
/******************************************************************************/
/* */
/* C H A N G E H I S T O R Y */
/* */
/******************************************************************************/
 
// Date Version Description
//------------------------------------------------------------------------
// 081101 First revision jb
 
 
#ifndef CYGWIN_COMPILE
#include "WinTypes.h"
#endif
#include <stdint.h> // for uint_t types
/* Function prototypes */
uint32_t crc_calc(uint32_t crc, uint32_t input_bit);
/* Crc of current read or written data. */
extern uint32_t crc_r, crc_w;
 
int retry_do();
void retry_ok();
 
void usb_close_device_handle();
void usb_write_stream (uint32_t stream, uint32_t num_bits, DWORD dwTapControllerState);
void usb_readwritewrite_stream (uint32_t num_bits);
uint32_t usb_read_stream(uint32_t num_bits, DWORD dwTapControllerState);
uint32_t bit_reverse_data(uint32_t data, uint32_t length);
 
void usb_set_tap_ir(uint32_t ir);
void usb_dbg_test();
int usb_dbg_reset();
int usb_dbg_set_chain(int chain);
int usb_dbg_command(uint32_t type, uint32_t adr, uint32_t len);
int usb_dbg_ctrl(uint32_t reset, uint32_t stall);
int usb_dbg_ctrl_read(uint32_t *reset, uint32_t *stall);
int usb_dbg_go(unsigned char *data, uint16_t len, uint32_t read);
 
int usb_dbg_wb_read32(uint32_t adr, uint32_t *data);
int usb_dbg_wb_read_block32(uint32_t adr, uint32_t *data, uint32_t len);
int usb_dbg_wb_write32(uint32_t adr, uint32_t data);
int usb_dbg_wb_write_block32(uint32_t adr, uint32_t *data, uint32_t len);
int usb_dbg_cpu0_read(uint32_t adr, uint32_t *data);
int usb_dbg_cpu0_read_ctrl(uint32_t adr, unsigned char *data);
int usb_dbg_cpu0_write(uint32_t adr, uint32_t data);
int usb_dbg_cpu0_write_ctrl(uint32_t adr, unsigned char data);
/or_debug_proxy/includes/usb_driver_calls.h
0,0 → 1,90
/*$$HEADER*/
/******************************************************************************/
/* */
/* H E A D E R I N F O R M A T I O N */
/* */
/******************************************************************************/
 
// Project Name : OpenRISC Debug Proxy
// File Name : usb_functions.h
// Prepared By : jb
// Project Start : 2008-10-01
 
/*$$COPYRIGHT NOTICE*/
/******************************************************************************/
/* */
/* C O P Y R I G H T N O T I C E */
/* */
/******************************************************************************/
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation;
version 2.1 of the License, a copy of which is available from
http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt.
 
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
 
/*$$CHANGE HISTORY*/
/******************************************************************************/
/* */
/* C H A N G E H I S T O R Y */
/* */
/******************************************************************************/
 
// Date Version Description
//------------------------------------------------------------------------
// 090301 1.0 Generic header file for modules containing the
// platform specific D2XX MPSSE JTAG driver calls. jb
//
 
#ifndef CYGWIN_COMPILE
#include "FT2232cMpsseJtag.h"
#else
#include "win_FTCJTAG.h"
#endif
 
// Function prototypes
FTC_STATUS
FT2232_USB_JTAG_WriteDataToExternalDevice(
//FTC_HANDLE ftHandle,
BOOL bInstructionTestData,
DWORD dwNumBitsToWrite,
PWriteDataByteBuffer pWriteDataBuffer,
DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
 
 
FTC_STATUS
FT2232_USB_JTAG_ReadDataFromExternalDevice(
//FTC_HANDLE ftHandle,
BOOL bInstructionTestData,
DWORD dwNumBitsToRead,
PReadDataByteBuffer pReadDataBuffer,
LPDWORD lpdwNumBytesReturned,
DWORD dwTapControllerState);
FTC_STATUS
FT2232_USB_JTAG_WriteReadDataToFromExternalDevice(
//FTC_HANDLE ftHandle,
BOOL bInstructionTestData,
DWORD dwNumBitsToWriteRead,
PWriteDataByteBuffer pWriteDataBuffer,
DWORD dwNumBytesToWrite,
PReadDataByteBuffer pReadDataBuffer,
LPDWORD lpdwNumBytesReturned,
DWORD dwTapControllerState);
 
FTC_STATUS
FT2232_USB_JTAG_CloseDevice();
 
int init_usb_jtag();
 
 
/or_debug_proxy/includes/WinTypes.h
0,0 → 1,87
#ifndef __WINDOWS_TYPES__
#define __WINDOWS_TYPES__
 
#define MAX_NUM_DEVICES 50
#include <sys/time.h>
 
typedef unsigned long DWORD;
typedef unsigned long ULONG;
typedef unsigned short USHORT;
typedef short SHORT;
typedef unsigned char UCHAR;
typedef unsigned short WORD;
typedef unsigned char BYTE;
typedef unsigned char *LPBYTE;
typedef int BOOL;
typedef char BOOLEAN;
typedef char CHAR;
typedef int *LPBOOL;
typedef unsigned char *PUCHAR;
typedef const char *LPCSTR;
typedef char *PCHAR;
typedef void *PVOID;
typedef void *HANDLE;
typedef long LONG;
typedef int INT;
typedef unsigned int UINT;
typedef char *LPSTR;
typedef char *LPTSTR;
typedef DWORD *LPDWORD;
typedef WORD *LPWORD;
typedef ULONG *PULONG;
typedef PVOID LPVOID;
typedef void VOID;
typedef unsigned long long int ULONGLONG;
 
typedef struct _OVERLAPPED {
DWORD Internal;
DWORD InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
HANDLE hEvent;
} OVERLAPPED, *LPOVERLAPPED;
 
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength;
LPVOID lpSecurityDescriptor;
BOOL bInheritHandle;
} SECURITY_ATTRIBUTES , *LPSECURITY_ATTRIBUTES;
 
typedef struct timeval SYSTEMTIME;
typedef struct timeval FILETIME;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
 
//
// Modem Status Flags
//
#define MS_CTS_ON ((DWORD)0x0010)
#define MS_DSR_ON ((DWORD)0x0020)
#define MS_RING_ON ((DWORD)0x0040)
#define MS_RLSD_ON ((DWORD)0x0080)
 
//
// Error Flags
//
 
#define CE_RXOVER 0x0001 // Receive Queue overflow
#define CE_OVERRUN 0x0002 // Receive Overrun Error
#define CE_RXPARITY 0x0004 // Receive Parity Error
#define CE_FRAME 0x0008 // Receive Framing error
#define CE_BREAK 0x0010 // Break Detected
#define CE_TXFULL 0x0100 // TX Queue is full
#define CE_PTO 0x0200 // LPTx Timeout
#define CE_IOE 0x0400 // LPTx I/O Error
#define CE_DNS 0x0800 // LPTx Device not selected
#define CE_OOP 0x1000 // LPTx Out-Of-Paper
#define CE_MODE 0x8000 // Requested mode unsupported
 
#ifndef INVALID_HANDLE_VALUE
#define INVALID_HANDLE_VALUE 0xFFFFFFFF
#endif
 
#endif
/or_debug_proxy/includes/FT2232cMpsseJtag.h
0,0 → 1,424
/*++
 
FTC MPSSE Interface DLLs - Copyright © FTDI Ltd. 2009
 
 
The source code to the FTCI2C, FTCJTAG and FTCSPI DLLs is provided as-is and no warranty is made as to its function or reliability.
 
This source code may be freely modified and redistributed, provided that the FTDI Ltd. copyright notice remains intact.
 
Copyright (c) 2005 Future Technology Devices International Ltd.
 
Module Name:
 
ft2232cmpssejtag.h
 
Abstract:
 
FT2232C Dual Device Device Class Declaration/Definition.
 
Environment:
 
kernel & user mode
 
Revision History:
 
07/02/05 kra Created.
24/08/05 kra Added new function JTAG_GenerateClockPulses and new error code FTC_INVALID_NUMBER_CLOCK_PULSES
16/09/05 kra Version 1.50 - Added break statements after DLL_THREAD_ATTACH and DLL_THREAD_DETACH for multiple threaded applications
08/03/06 ana Version 1.08 - fix byte boundry mising bit.
19/11/08 Rene Baumann Port FTCJTAG to Linux.
--*/
 
#ifndef FT2232cMpsseJtag_H
#define FT2232cMpsseJtag_H
 
//#include <windows.h>
 
#include "FT2232c.h"
//#include "FTCJTAG.h" -- All required bits now included in this file. WinAPI things in there not needed here
 
 
// Defines from FTCJTAG.h
 
typedef DWORD FTC_HANDLE;
typedef ULONG FTC_STATUS;
 
#define TEST_LOGIC_STATE 1
#define RUN_TEST_IDLE_STATE 2
#define PAUSE_TEST_DATA_REGISTER_STATE 3
#define PAUSE_INSTRUCTION_REGISTER_STATE 4
#define SHIFT_TEST_DATA_REGISTER_STATE 5
#define SHIFT_INSTRUCTION_REGISTER_STATE 6
 
#define FTC_SUCCESS 0 // FTC_OK
#define FTC_INVALID_HANDLE 1 // FTC_INVALID_HANDLE
#define FTC_DEVICE_NOT_FOUND 2 //FTC_DEVICE_NOT_FOUND
#define FTC_DEVICE_NOT_OPENED 3 //FTC_DEVICE_NOT_OPENED
#define FTC_IO_ERROR 4 //FTC_IO_ERROR
#define FTC_INSUFFICIENT_RESOURCES 5 // FTC_INSUFFICIENT_RESOURCES
 
#define FTC_FAILED_TO_COMPLETE_COMMAND 20 // cannot change, error code mapped from FT2232c classes
#define FTC_FAILED_TO_SYNCHRONIZE_DEVICE_MPSSE 21 // cannot change, error code mapped from FT2232c classes
#define FTC_INVALID_DEVICE_NAME_INDEX 22 // cannot change, error code mapped from FT2232c classes
#define FTC_NULL_DEVICE_NAME_BUFFER_POINTER 23 // cannot change, error code mapped from FT2232c classes
#define FTC_DEVICE_NAME_BUFFER_TOO_SMALL 24 // cannot change, error code mapped from FT2232c classes
#define FTC_INVALID_DEVICE_NAME 25 // cannot change, error code mapped from FT2232c classes
#define FTC_INVALID_LOCATION_ID 26 // cannot change, error code mapped from FT2232c classes
#define FTC_DEVICE_IN_USE 27 // cannot change, error code mapped from FT2232c classes
#define FTC_TOO_MANY_DEVICES 28 // cannot change, error code mapped from FT2232c classes
#define FTC_INVALID_CLOCK_DIVISOR 29
#define FTC_NULL_INPUT_OUTPUT_BUFFER_POINTER 30
#define FTC_INVALID_NUMBER_BITS 31
#define FTC_NULL_WRITE_DATA_BUFFER_POINTER 32
#define FTC_INVALID_NUMBER_BYTES 33
#define FTC_NUMBER_BYTES_TOO_SMALL 34
#define FTC_INVALID_TAP_CONTROLLER_STATE 35
#define FTC_NULL_READ_DATA_BUFFER_POINTER 36
#define FTC_COMMAND_SEQUENCE_BUFFER_FULL 37
#define FTC_NULL_READ_CMDS_DATA_BUFFER_POINTER 38
#define FTC_NO_COMMAND_SEQUENCE 39
#define FTC_INVALID_NUMBER_CLOCK_PULSES 40
#define FTC_NULL_DLL_VERSION_BUFFER_POINTER 41
#define FTC_DLL_VERSION_BUFFER_TOO_SMALL 42
#define FTC_NULL_LANGUAGE_CODE_BUFFER_POINTER 43
#define FTC_NULL_ERROR_MESSAGE_BUFFER_POINTER 44
#define FTC_ERROR_MESSAGE_BUFFER_TOO_SMALL 45
#define FTC_INVALID_LANGUAGE_CODE 46
#define FTC_INVALID_STATUS_CODE 47
 
 
typedef struct Ft_Input_Output_Pins{
BOOL bPin1InputOutputState;
BOOL bPin1LowHighState;
BOOL bPin2InputOutputState;
BOOL bPin2LowHighState;
BOOL bPin3InputOutputState;
BOOL bPin3LowHighState;
BOOL bPin4InputOutputState;
BOOL bPin4LowHighState;
}FTC_INPUT_OUTPUT_PINS, *PFTC_INPUT_OUTPUT_PINS;
typedef struct Ft_Low_High_Pins{
BOOL bPin1LowHighState;
BOOL bPin2LowHighState;
BOOL bPin3LowHighState;
BOOL bPin4LowHighState;
}FTC_LOW_HIGH_PINS, *PFTC_LOW_HIGH_PINS;
#define MAX_WRITE_DATA_BYTES_BUFFER_SIZE 65536 // 64k bytes
 
typedef BYTE WriteDataByteBuffer[MAX_WRITE_DATA_BYTES_BUFFER_SIZE];
typedef WriteDataByteBuffer *PWriteDataByteBuffer;
 
 
#define MAX_READ_DATA_BYTES_BUFFER_SIZE 65536 // 64k bytes
 
typedef BYTE ReadDataByteBuffer[MAX_READ_DATA_BYTES_BUFFER_SIZE];
typedef ReadDataByteBuffer *PReadDataByteBuffer;
 
#define MAX_READ_CMDS_DATA_BYTES_BUFFER_SIZE 131071 // 128K bytes
 
typedef BYTE ReadCmdSequenceDataByteBuffer[MAX_READ_CMDS_DATA_BYTES_BUFFER_SIZE];
typedef ReadCmdSequenceDataByteBuffer *PReadCmdSequenceDataByteBuffer;
 
 
// end defines from FTCJTAG.h
 
 
#define DEVICE_CHANNEL_A " A"
#define DEVICE_CHANNEL_B " B"
 
#define DLL_VERSION_NUM "1.8"
 
#define USB_INPUT_BUFFER_SIZE 65536 // 64K
#define USB_OUTPUT_BUFFER_SIZE 65536 // 64K
 
const BYTE FT_EVENT_VALUE = 0;
const BYTE FT_ERROR_VALUE = 0;
 
#define DEVICE_READ_TIMEOUT_INFINITE 0
#define DEVICE_WRITE_TIMEOUT 5000 // 5 seconds
 
#define MIN_CLOCK_DIVISOR 0 // equivalent to 6MHz
#define MAX_CLOCK_DIVISOR 65535 // equivalent to 91Hz
 
#define MIN_NUM_BITS 2 // specifies the minimum number of bits that can be written or read to/from an external device
#define MAX_NUM_BITS 524280 // specifies the maximum number of bits that can be written or read to/from an external device
#define MIN_NUM_BYTES 1 // specifies the minimum number of bytes that can be written to an external device
#define MAX_NUM_BYTES 65535 // specifies the maximum number of bytes that can be written to an external device
 
#define NUMBITSINBYTE 8
 
#define MIN_NUM_CLOCK_PULSES 1 // specifies the minimum number of clock pulses that a FT2232C dual device can generate
#define MAX_NUM_CLOCK_PULSES 2000000000 // specifies the maximum number of clock pulses that a FT2232C dual device can generate
 
#define NUM_BYTE_CLOCK_PULSES_BLOCK_SIZE 32000 //4000
 
#define PIN1_HIGH_VALUE 1
#define PIN2_HIGH_VALUE 2
#define PIN3_HIGH_VALUE 4
#define PIN4_HIGH_VALUE 8
 
#define NUM_WRITE_COMMAND_BYTES 18
#define NUM_READ_COMMAND_BYTES 18
#define NUM_WRITE_READ_COMMAND_BYTES 19
 
#define MAX_ERROR_MSG_SIZE 250
 
const CHAR ENGLISH[3] = "EN";
 
const CHAR EN_Common_Errors[FTC_INSUFFICIENT_RESOURCES + 1][MAX_ERROR_MSG_SIZE] = {
"",
"Invalid device handle.",
"Device not found.",
"Device not opened.",
"General device IO error.",
"Insufficient resources available to execute function."};
 
const CHAR EN_New_Errors[(FTC_INVALID_STATUS_CODE - FTC_FAILED_TO_COMPLETE_COMMAND) + 1][MAX_ERROR_MSG_SIZE] = {
"Failed to complete command.",
"Failed to synchronize the device MPSSE interface.",
"Invalid device name index.",
"Pointer to device name buffer is null.",
"Buffer to contain device name is too small.",
"Invalid device name.",
"Invalid device location identifier.",
"Device already in use by another application.",
"More than one device detected.",
"Invalid clock divisor. Valid range is 0 - 65535.",
"Pointer to input output buffer is null.",
"Invalid number of bits. Valid range 2 to 524280. 524280 bits is equivalent to 64K bytes",
"Pointer to write data buffer is null.",
"Invalid size of write data buffer. Valid range is 1 - 65535",
"Buffer to contain number of bits is too small.",
"Invalid Test Access Port(TAP) controller state.",
"Pointer to read data buffer is null.",
"Command sequence buffer is full. Valid range is 1 - 131070 ie 128K bytes.",
"Pointer to read command sequence data buffer is null.",
"No command sequence found.",
"Invalid number of clock pulses. Valid range is 1 - 2000,000,000.",
"Pointer to dll version number buffer is null.",
"Buffer to contain dll version number is too small.",
"Pointer to language code buffer is null.",
"Pointer to error message buffer is null.",
"Buffer to contain error message is too small.",
"Unsupported language code.",
"Unknown status code = "};
 
const BYTE CLK_DATA_BYTES_OUT_ON_NEG_CLK_LSB_FIRST_CMD = '\x19';
const BYTE CLK_DATA_BITS_OUT_ON_NEG_CLK_LSB_FIRST_CMD = '\x1B';
const BYTE CLK_DATA_BYTES_IN_ON_POS_CLK_LSB_FIRST_CMD = '\x28';
const BYTE CLK_DATA_BITS_IN_ON_POS_CLK_LSB_FIRST_CMD = '\x2A';
const BYTE CLK_DATA_BYTES_OUT_ON_NEG_CLK_IN_ON_POS_CLK_LSB_FIRST_CMD = '\x39';
const BYTE CLK_DATA_BITS_OUT_ON_NEG_CLK_IN_ON_POS_CLK_LSB_FIRST_CMD = '\x3B';
 
const BYTE CLK_DATA_TMS_NO_READ_CMD = '\x4B';
const BYTE CLK_DATA_TMS_READ_CMD = '\x6B';
 
const BYTE SET_LOW_BYTE_DATA_BITS_CMD = '\x80';
const BYTE GET_LOW_BYTE_DATA_BITS_CMD = '\x81';
const BYTE SET_HIGH_BYTE_DATA_BITS_CMD = '\x82';
const BYTE GET_HIGH_BYTE_DATA_BITS_CMD = '\x83';
const BYTE SET_CLOCK_FREQUENCY_CMD = '\x86';
const BYTE SEND_ANSWER_BACK_IMMEDIATELY_CMD = '\x87';
 
enum JtagStates {TestLogicReset, RunTestIdle, PauseDataRegister, PauseInstructionRegister, ShiftDataRegister, ShiftInstructionRegister, Undefined};
 
#define NUM_JTAG_TMS_STATES 6
 
// go from current JTAG state to new JTAG state -> tlr rti pdr pir sdr sir
const BYTE TestLogicResetToNewJTAGState[NUM_JTAG_TMS_STATES] = {'\x01', '\x00', '\x0A', '\x16', '\x02', '\x06'};
const BYTE RunTestIdleToNewJTAGState[NUM_JTAG_TMS_STATES] = {'\x07', '\x00', '\x05', '\x0B', '\x01', '\x03'};
const BYTE PauseDataRegToNewJTAGState[NUM_JTAG_TMS_STATES] = {'\x1F', '\x03', '\x17', '\x2F', '\x01', '\x0F'};
const BYTE PauseInstructionRegToNewJTAGState[NUM_JTAG_TMS_STATES] = {'\x1F', '\x03', '\x17', '\x2F', '\x07', '\x01'};
const BYTE ShiftDataRegToNewJTAGState[NUM_JTAG_TMS_STATES] = {'\x1F', '\x03', '\x01', '\x2F', '\x00', '\x00'};
const BYTE ShiftInstructionRegToNewJTAGState[NUM_JTAG_TMS_STATES] = {'\x1F', '\x03', '\x17', '\x01', '\x00', '\x00'};
 
// number of TMS clocks to go from current JTAG state to new JTAG state -> tlr rti pdr pir sdr sir
const BYTE TestLogicResetToNewJTAGStateNumTMSClocks[NUM_JTAG_TMS_STATES] = {1, 1, 5, 6, 4, 5};
const BYTE RunTestIdleToNewJTAGStateNumTMSClocks[NUM_JTAG_TMS_STATES] = {3, 5, 4, 5, 3, 4};
const BYTE PauseDataRegToNewJTAGStateNumTMSClocks[NUM_JTAG_TMS_STATES] = {5, 3, 6, 7, 2, 6};
const BYTE PauseInstructionRegToNewJTAGStateNumTMSClocks[NUM_JTAG_TMS_STATES] = {5, 3, 6, 7, 5, 2};
const BYTE ShiftDataRegToNewJTAGStateNumTMSClocks[NUM_JTAG_TMS_STATES] = {5, 3, 2, 7, 0, 0};
const BYTE ShiftInstructionRegToNewJTAGStateNumTMSClocks[NUM_JTAG_TMS_STATES] = {5, 4, 6, 2, 0, 0};
 
#define NO_LAST_DATA_BIT 0
 
#define NUM_COMMAND_SEQUENCE_READ_DATA_BYTES 2
#define INIT_COMMAND_SEQUENCE_READ_DATA_BUFFER_SIZE 100
#define COMMAND_SEQUENCE_READ_DATA_BUFFER_SIZE_INCREMENT 10
 
typedef DWORD ReadCommandSequenceData[NUM_COMMAND_SEQUENCE_READ_DATA_BYTES];
typedef ReadCommandSequenceData *PReadCommandSequenceData;
 
typedef PReadCommandSequenceData ReadCommandsSequenceData[1];
typedef ReadCommandsSequenceData *PReadCommandsSequenceData;
 
typedef struct Ft_Device_Cmd_Sequence_Data{
DWORD hDevice; // handle to the opened and initialized FT2232C dual type device
DWORD dwNumBytesToSend;
POutputByteBuffer pCommandsSequenceDataOutPutBuffer;
DWORD dwSizeReadCommandsSequenceDataBuffer;
PReadCommandsSequenceData pReadCommandsSequenceDataBuffer;
DWORD dwNumReadCommandSequences;
}FTC_DEVICE_CMD_SEQUENCE_DATA, *PFTC_DEVICE_CMD_SEQUENCE_DATA;
 
 
static DWORD dwSavedLowPinsDirection = 0; // Removed from FT2232cMpsseJtag class to avoid segmentation fault. Rene
static DWORD dwSavedLowPinsValue = 0; // Removed from FT2232cMpsseJtag class to avoid segmentation fault. Rene
static JtagStates CurrentJtagState = Undefined; // Removed from FT2232cMpsseJtag class to avoid segmentation fault. Rene
static DWORD dwNumOpenedDevices = 0; // Removed from FT2232cMpsseJtag class to avoid segmentation fault. Rene
static FTC_DEVICE_CMD_SEQUENCE_DATA OpenedDevicesCommandsSequenceData[MAX_NUM_DEVICES]; // Removed from FT2232cMpsseJtag class to avoid segmentation fault. Rene
static INT iCommandsSequenceDataDeviceIndex = -1; // Removed from FT2232cMpsseJtag class to avoid segmentation fault. Rene
 
 
//----------------------------------------------------------------------------
class FT2232cMpsseJtag : private FT2232c
{
private:
// Moved out from this class to avoid segmentation fault. --> DWORD dwSavedLowPinsDirection; // Rene
// Moved out from this class to avoid segmentation fault. --> DWORD dwSavedLowPinsValue; // Rene
// Moved out from this class to avoid segmentation fault. --> JtagStates CurrentJtagState; // Rene
// Moved out from this class to avoid segmentation fault. --> DWORD dwNumOpenedDevices; // Rene
// Moved out from this class to avoid segmentation fault. --> FTC_DEVICE_CMD_SEQUENCE_DATA OpenedDevicesCommandsSequenceData[MAX_NUM_DEVICES]; // Rene
// Moved out from this class to avoid segmentation fault. --> INT iCommandsSequenceDataDeviceIndex; // Rene
 
FTC_STATUS CheckWriteDataToExternalDeviceBitsBytesParameters(DWORD dwNumBitsToWrite, DWORD dwNumBytesToWrite);
 
void AddByteToOutputBuffer(DWORD dwOutputByte, BOOL bClearOutputBuffer);
FTC_STATUS SetDataInOutClockFrequency(FTC_HANDLE ftHandle, DWORD dwClockDivisor);
FTC_STATUS InitDataInOutClockFrequency(FTC_HANDLE ftHandle, DWORD dwClockDivisor);
void SetJTAGToNewState(DWORD dwNewJtagState, DWORD dwNumTmsClocks, BOOL bDoReadOperation);
DWORD MoveJTAGFromOneStateToAnother(JtagStates NewJtagState, DWORD dwLastDataBit, BOOL bDoReadOperation);
FTC_STATUS ResetTAPContollerExternalDeviceSetToTestIdleMode(FTC_HANDLE ftHandle);
FTC_STATUS SetGeneralPurposeInputOutputPins(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins,
DWORD dwLowPinsDirection, DWORD dwLowPinsValue,
BOOL bControlHighInputOutputPins,
DWORD dwHighPinsDirection, DWORD dwHighPinsValue);
void GetGeneralPurposeInputOutputPinsInputStates(DWORD dwInputStatesReturnedValue, PFTC_LOW_HIGH_PINS pPinsInputData);
FTC_STATUS GetGeneralPurposeInputOutputPins(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins,
PFTC_LOW_HIGH_PINS pLowPinsInputData,
BOOL bControlHighInputOutputPins,
PFTC_LOW_HIGH_PINS pHighPinsInputData);
void AddWriteCommandDataToOutPutBuffer(BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
FTC_STATUS WriteDataToExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionData, DWORD dwNumBitsToWrite,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
void GetNumDataBytesToRead(DWORD dwNumBitsToRead, LPDWORD lpdwNumDataBytesToRead, LPDWORD lpdwNumRemainingDataBits);
FTC_STATUS GetDataFromExternalDevice(FTC_HANDLE ftHandle, DWORD dwNumBitsToRead, DWORD dwNumTmsClocks,
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned);
DWORD AddReadCommandToOutputBuffer(BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState);
FTC_STATUS ReadDataFromExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead,
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned,
DWORD dwTapControllerState);
DWORD AddWriteReadCommandDataToOutPutBuffer(BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
PWriteDataByteBuffer pWriteDataBuffer,
DWORD dwNumBytesToWrite, DWORD dwTapControllerState);
FTC_STATUS WriteReadDataToFromExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned,
DWORD dwTapControllerState);
FTC_STATUS GenerateTCKClockPulses(FTC_HANDLE ftHandle, DWORD dwNumClockPulses);
 
void ProcessReadCommandsSequenceBytes(PInputByteBuffer pInputBuffer, DWORD dwNumBytesRead, PReadCmdSequenceDataByteBuffer pReadCmdSequenceDataBuffer,
LPDWORD lpdwNumBytesReturned);
DWORD GetTotalNumCommandsSequenceDataBytesToRead (void);
void CopyReadCommandsSequenceDataBuffer(PReadCommandsSequenceData pDestinationBuffer, PReadCommandsSequenceData pSourceBuffer, DWORD dwSizeReadCommandsSequenceDataBuffer);
FTC_STATUS AddReadCommandSequenceData(DWORD dwNumBitsToRead, DWORD dwNumTmsClocks);
void CreateReadCommandsSequenceDataBuffer(void);
PReadCommandsSequenceData CreateReadCommandsSequenceDataBuffer(DWORD dwSizeReadCmdsSequenceDataBuffer);
void DeleteReadCommandsSequenceDataBuffer(PReadCommandsSequenceData pReadCmdsSequenceDataBuffer, DWORD dwSizeReadCommandsSequenceDataBuffer);
 
FTC_STATUS CreateDeviceCommandsSequenceDataBuffers(FTC_HANDLE ftHandle);
void ClearDeviceCommandSequenceData(FTC_HANDLE ftHandle);
DWORD GetNumBytesInCommandsSequenceDataBuffer(void);
DWORD GetCommandsSequenceDataDeviceIndex(FTC_HANDLE ftHandle);
void DeleteDeviceCommandsSequenceDataBuffers(FTC_HANDLE ftHandle);
 
FTC_STATUS AddDeviceWriteCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
FTC_STATUS AddDeviceReadCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState);
FTC_STATUS AddDeviceWriteReadCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
 
public:
FT2232cMpsseJtag(void);
~FT2232cMpsseJtag(void);
 
 
FTC_STATUS JTAG_GetNumDevices(LPDWORD lpdwNumDevices);
FTC_STATUS JTAG_GetDeviceNameLocationID(DWORD dwDeviceNameIndex, LPSTR lpDeviceNameBuffer, DWORD dwBufferSize, LPDWORD lpdwLocationID);
//FTC_STATUS JTAG_GetDeviceNameLocID(DWORD dwDeviceNameIndex, LPSTR lpDeviceNameBuffer, DWORD dwBufferSize, LPDWORD lpdwLocationID);
FTC_STATUS JTAG_OpenSpecifiedDevice(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle);
//FTC_STATUS JTAG_OpenEx(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle);
FTC_STATUS JTAG_OpenDevice(FTC_HANDLE *pftHandle);
//FTC_STATUS JTAG_Open(FTC_HANDLE *pftHandle);
FTC_STATUS JTAG_CloseDevice(FTC_HANDLE ftHandle);
//FTC_STATUS JTAG_Close(FTC_HANDLE ftHandle);
FTC_STATUS JTAG_InitDevice(FTC_HANDLE ftHandle, DWORD dwClockFrequencyValue);
FTC_STATUS JTAG_GetClock(DWORD dwClockDivisor, LPDWORD lpdwClockFrequencyHz);
FTC_STATUS JTAG_SetClock(FTC_HANDLE ftHandle, DWORD dwClockDivisor, LPDWORD lpdwClockFrequencyHz);
FTC_STATUS JTAG_SetDeviceLoopbackState(FTC_HANDLE ftHandle, BOOL bLoopbackState);
//FTC_STATUS JTAG_SetLoopback(FTC_HANDLE ftHandle, BOOL bLoopbackState);
FTC_STATUS JTAG_SetGeneralPurposeInputOutputPins(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins,
//FTC_STATUS JTAG_SetGPIOs(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins,
PFTC_INPUT_OUTPUT_PINS pLowInputOutputPinsData,
BOOL bControlHighInputOutputPins,
PFTC_INPUT_OUTPUT_PINS pHighInputOutputPinsData);
FTC_STATUS JTAG_GetGeneralPurposeInputOutputPins(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins,
//FTC_STATUS JTAG_GetGPIOs(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins,
PFTC_LOW_HIGH_PINS pLowPinsInputData,
BOOL bControlHighInputOutputPins,
PFTC_LOW_HIGH_PINS pHighPinsInputData);
FTC_STATUS JTAG_WriteDataToExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
//FTC_STATUS JTAG_Write(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
FTC_STATUS JTAG_ReadDataFromExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead,
//FTC_STATUS JTAG_Read(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead,
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned,
DWORD dwTapControllerState);
FTC_STATUS JTAG_WriteReadDataToFromExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
//FTC_STATUS JTAG_WriteRead(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned,
DWORD dwTapControllerState);
FTC_STATUS JTAG_GenerateTCKClockPulses(FTC_HANDLE ftHandle, DWORD dwNumClockPulses);
//FTC_STATUS JTAG_GenerateClockPulses(FTC_HANDLE ftHandle, DWORD dwNumClockPulses);
FTC_STATUS JTAG_ClearCommandSequence(void);
//FTC_STATUS JTAG_ClearCmdSequence(void);
FTC_STATUS JTAG_AddWriteCommand(BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
//FTC_STATUS JTAG_AddWriteCmd(BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
FTC_STATUS JTAG_AddReadCommand(BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState);
//FTC_STATUS JTAG_AddReadCmd(BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState);
FTC_STATUS JTAG_AddWriteReadCommand(BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
//FTC_STATUS JTAG_AddWriteReadCmd(BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
FTC_STATUS JTAG_ClearDeviceCommandSequence(FTC_HANDLE ftHandle);
//FTC_STATUS JTAG_ClearDeviceCmdSequence(FTC_HANDLE ftHandle);
FTC_STATUS JTAG_AddDeviceWriteCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
//FTC_STATUS JTAG_AddDeviceWriteCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
FTC_STATUS JTAG_AddDeviceReadCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState);
//FTC_STATUS JTAG_AddDeviceReadCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState);
FTC_STATUS JTAG_AddDeviceWriteReadCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
//FTC_STATUS JTAG_AddDeviceWriteReadCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
FTC_STATUS JTAG_ExecuteCommandSequence(FTC_HANDLE ftHandle, PReadCmdSequenceDataByteBuffer pReadCmdSequenceDataBuffer,
//FTC_STATUS JTAG_ExecuteCmdSequence(FTC_HANDLE ftHandle, PReadCmdSequenceDataByteBuffer pReadCmdSequenceDataBuffer,
LPDWORD lpdwNumBytesReturned);
FTC_STATUS JTAG_GetDllVersion(LPSTR lpDllVersionBuffer, DWORD dwBufferSize);
FTC_STATUS JTAG_GetErrorCodeString(LPSTR lpLanguage, FTC_STATUS StatusCode,
LPSTR lpErrorMessageBuffer, DWORD dwBufferSize);
};
 
#endif /* FT2232cMpsseJtag_H */
/or_debug_proxy/includes/FT2232c.h
0,0 → 1,186
/*++
 
FTC MPSSE Interface DLLs - Copyright © FTDI Ltd. 2009
 
 
The source code to the FTCI2C, FTCJTAG and FTCSPI DLLs is provided as-is and no warranty is made as to its function or reliability.
 
This source code may be freely modified and redistributed, provided that the FTDI Ltd. copyright notice remains intact.
 
Copyright (c) 2005 Future Technology Devices International Ltd.
 
Module Name:
 
FT2232c.h
 
Abstract:
 
FT2232C Dual Type Devices Base Class Declaration/Definition.
 
Environment:
 
kernel & user mode
 
Revision History:
 
07/02/05 kra Created.
25/08/05 kra Windows 2000 Professional always sets the USB buffer size to 4K ie 4096
19/11/08 Rene Baumann Port FTCJTAG to Linux.
--*/
 
#ifndef FT2232c_H
#define FT2232c_H
 
//#include <windows.h>
 
#include "ftd2xx.h"
 
typedef DWORD FTC_HANDLE;
typedef ULONG FTC_STATUS;
 
#define FTC_SUCCESS 0 //FTC_OK
#define FTC_INVALID_HANDLE 1 //FTC_INVALID_HANDLE
#define FTC_DEVICE_NOT_FOUND 2 //FTC_DEVICE_NOT_FOUND
#define FTC_DEVICE_NOT_OPENED 3 //FTC_DEVICE_NOT_OPENED
#define FTC_IO_ERROR 4 //FTC_IO_ERROR
#define FTC_INSUFFICIENT_RESOURCES 5 //FTC_INSUFFICIENT_RESOURCES
 
#define FTC_FAILED_TO_COMPLETE_COMMAND 20
#define FTC_FAILED_TO_SYNCHRONIZE_DEVICE_MPSSE 21
#define FTC_INVALID_DEVICE_NAME_INDEX 22
#define FTC_NULL_DEVICE_NAME_BUFFER_POINTER 23
#define FTC_DEVICE_NAME_BUFFER_TOO_SMALL 24
#define FTC_INVALID_DEVICE_NAME 25
#define FTC_INVALID_LOCATION_ID 26
#define FTC_DEVICE_IN_USE 27
#define FTC_TOO_MANY_DEVICES 28
 
#define MAX_NUM_DEVICE_NAME_CHARS 64
#define MAX_NUM_SERIAL_NUMBER_CHARS 16
 
typedef struct Ft_Device_Data{
DWORD dwProcessId; // process identifier of the calling process ie application
char szDeviceName[MAX_NUM_DEVICE_NAME_CHARS]; // pointer to the name of a FT2232C dual type device
DWORD dwLocationID; // the location identifier of a FT2232C dual type device
DWORD hDevice; // handle to the opened and initialized FT2232C dual type device
}FTC_DEVICE_DATA, *PFTC_DEVICE_DATA;
 
typedef DWORD FT2232CDeviceIndexes[MAX_NUM_DEVICES];
 
#define DEVICE_STRING_BUFF_SIZE 64
 
#define DEVICE_CHANNEL_A " A"
 
typedef char SerialNumber[MAX_NUM_SERIAL_NUMBER_CHARS];
 
const BYTE DEVICE_LATENCY_TIMER_VALUE = 16; // 16 milliseconds
 
#define OUTPUT_BUFFER_SIZE 131071 // 128K bytes
 
typedef BYTE OutputByteBuffer[OUTPUT_BUFFER_SIZE];
typedef OutputByteBuffer *POutputByteBuffer;
 
#define INPUT_BUFFER_SIZE 131071 // 128K bytes
 
typedef BYTE InputByteBuffer[INPUT_BUFFER_SIZE];
typedef InputByteBuffer *PInputByteBuffer;
 
#define CONVERT_1MS_TO_100NS 10000
 
#define MAX_COMMAND_TIMEOUT_PERIOD 5000 // 5 seconds
 
// 25/08/05 - Windows 2000 Professional always sets the USB buffer size to 4K ie 4096
#define MAX_NUM_BYTES_USB_WRITE 4096 //32768 // 32KB
#define MAX_NUM_BYTES_USB_WRITE_READ 4096 //32768 // 32KB
#define MAX_NUM_BYTES_USB_READ 32768 // 32KB
 
#define DEBUG_LIST_DEVICE 0
 
const BYTE MPSSE_INTERFACE_MASK = '\x00';
const BYTE RESET_MPSSE_INTERFACE = '\x00';
const BYTE ENABLE_MPSSE_INTERFACE = '\x02';
 
const __uint16_t DEVICE_OPENED_FLAG = '\x0001';
 
const int BASE_CLOCK_FREQUENCY_12_MHZ = 12000000;
 
const BYTE AA_ECHO_CMD_1 = '\xAA';
const BYTE AB_ECHO_CMD_2 = '\xAB';
 
const BYTE TURN_ON_LOOPBACK_CMD = '\x84';
const BYTE TURN_OFF_LOOPBACK_CMD = '\x85';
 
const BYTE BAD_COMMAND_RESPONSE = '\xFA';
 
 
 
class FT2232c
{
private:
// Moved to FT2232c.cpp to avoid segmentation fault. --> UINT uiNumOpenedDevices; // Rene
// Moved to FT2232c.cpp to avoid segmentation fault. --> FTC_DEVICE_DATA OpenedDevices[MAX_NUM_DEVICES]; // Rene
// Moved to FT2232c.cpp to avoid segmentation fault. --> OutputByteBuffer OutputBuffer; // Rene
// Moved to FT2232c.cpp to avoid segmentation fault. --> DWORD dwNumBytesToSend; // Rene
 
BOOLEAN FTC_DeviceInUse(LPSTR lpDeviceName, DWORD dwLocationID);
BOOLEAN FTC_DeviceOpened(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle);
FTC_STATUS FTC_IsDeviceNameLocationIDValid(LPSTR lpDeviceName, DWORD dwLocationID);
FTC_STATUS FTC_IsDeviceFT2232CType(LPSTR lpDeviceName, LPBOOL lpbFT2232CTypeDevice);
 
 
public:
FT2232c(void);
~FT2232c(void);
 
protected:
FTC_STATUS FTC_GetNumDevices(LPDWORD lpdwNumDevices, FT2232CDeviceIndexes *FT2232CIndexes);
FTC_STATUS FTC_GetNumNotOpenedDevices(LPDWORD lpdwNumNotOpenedDevices, FT2232CDeviceIndexes *FT2232CIndexes);
FTC_STATUS FTC_GetDeviceNameLocationID(DWORD dwDeviceIndex, LPSTR lpDeviceName, DWORD dwBufferSize, LPDWORD lpdwLocationID);
FTC_STATUS FTC_OpenSpecifiedDevice(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle);
FTC_STATUS FTC_OpenDevice(FTC_HANDLE *pftHandle);
FTC_STATUS FTC_CloseDevice(FTC_HANDLE ftHandle);
void FTC_GetClockFrequencyValues(DWORD dwClockFrequencyValue, LPDWORD lpdwClockFrequencyHz);
FTC_STATUS FTC_SetDeviceLoopbackState(FTC_HANDLE ftHandle, BOOL bLoopbackState);
 
void FTC_InsertDeviceHandle(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE ftHandle);
FTC_STATUS FTC_IsDeviceHandleValid(FTC_HANDLE ftHandle);
void FTC_RemoveDeviceHandle(FTC_HANDLE ftHandle);
 
FTC_STATUS FTC_ResetUSBDevicePurgeUSBInputBuffer(FTC_HANDLE ftHandle);
FTC_STATUS FTC_SetDeviceUSBBufferSizes(FTC_HANDLE ftHandle, DWORD InputBufferSize, DWORD OutputBufferSize);
FTC_STATUS FTC_SetDeviceSpecialCharacters(FTC_HANDLE ftHandle, BOOLEAN bEventEnabled, UCHAR EventCharacter,
BOOLEAN bErrorEnabled, UCHAR ErrorCharacter);
FTC_STATUS FTC_SetReadWriteDeviceTimeouts(FTC_HANDLE ftHandle, DWORD dwReadTimeoutmSec, DWORD dwWriteTimeoutmSec);
FTC_STATUS FTC_SetDeviceLatencyTimer(FTC_HANDLE ftHandle, BYTE LatencyTimermSec);
FTC_STATUS FTC_ResetMPSSEInterface(FTC_HANDLE ftHandle);
FTC_STATUS FTC_EnableMPSSEInterface(FTC_HANDLE ftHandle);
FTC_STATUS FTC_SendReceiveCommandFromMPSSEInterface(FTC_HANDLE ftHandle, BOOLEAN bSendEchoCommandContinuouslyOnce, BYTE EchoCommand, LPBOOL lpbCommandEchod);
FTC_STATUS FTC_SynchronizeMPSSEInterface(FTC_HANDLE ftHandle);
BOOLEAN FTC_Timeout(SYSTEMTIME StartSystemTime, DWORD dwTimeoutmSecs);
FTC_STATUS FTC_GetNumberBytesFromDeviceInputBuffer(FTC_HANDLE ftHandle, LPDWORD lpdwNumBytesDeviceInputBuffer);
 
void FTC_ClearOutputBuffer(void);
DWORD FTC_GetNumBytesInOutputBuffer(void);
void FTC_AddByteToOutputBuffer(DWORD dwOutputByte, BOOL bClearOutputBuffer);
FTC_STATUS FTC_SendBytesToDevice(FTC_HANDLE ftHandle);
FTC_STATUS FTC_ReadBytesFromDevice(FTC_HANDLE ftHandle, PInputByteBuffer InputBuffer,
DWORD dwNumBytesToRead, LPDWORD lpdwNumBytesRead);
FTC_STATUS FTC_ReadFixedNumBytesFromDevice(FTC_HANDLE ftHandle, PInputByteBuffer InputBuffer,
DWORD dwNumBytesToRead, LPDWORD lpdwNumDataBytesRead);
FTC_STATUS FTC_SendReadBytesToFromDevice(FTC_HANDLE ftHandle, PInputByteBuffer InputBuffer,
DWORD dwNumBytesToRead, LPDWORD lpdwNumBytesRead);
 
FTC_STATUS FTC_SendCommandsSequenceToDevice(FTC_HANDLE ftHandle);
FTC_STATUS FTC_ReadCommandsSequenceBytesFromDevice(FTC_HANDLE ftHandle, PInputByteBuffer InputBuffer,
DWORD dwNumBytesToRead, LPDWORD lpdwNumBytesRead);
};
 
 
 
#endif /* FT2232c_H */
 
/or_debug_proxy/includes/vpi_functions.h
0,0 → 1,91
/*$$HEADER*/
/******************************************************************************/
/* */
/* H E A D E R I N F O R M A T I O N */
/* */
/******************************************************************************/
 
// Project Name : OpenRISC Debug Proxy
// File Name : usb_functions.h
// Prepared By : jb
// Project Start : 2008-10-01
 
/*$$COPYRIGHT NOTICE*/
/******************************************************************************/
/* */
/* C O P Y R I G H T N O T I C E */
/* */
/******************************************************************************/
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation;
version 2.1 of the License, a copy of which is available from
http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt.
 
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
 
/*$$CHANGE HISTORY*/
/******************************************************************************/
/* */
/* C H A N G E H I S T O R Y */
/* */
/******************************************************************************/
 
// Date Version Description
//------------------------------------------------------------------------
// 081101 First revision jb
 
//TODO: Make this port variable (at both ends!!)
// HARDCODED port for communications with functions attached to RTL sim via VPI
#define VPI_PORT 54002
 
#ifdef DEBUG_VPI
#define debug printf
#else
#define debug
#endif
 
#ifdef DEBUG2_VPI
#define debug2 printf
#else
#define debug2
#endif
 
 
/* VPI communication function prototyopes */
void get_response_from_vpi();
void get_data_from_vpi();
void get_block_data_from_vpi(uint32_t len, uint32_t *data);
void send_data_to_vpi(uint32_t data);
void send_block_data_to_vpi(uint32_t len, uint32_t *data);
void send_address_to_vpi(uint32_t address);
void send_command_to_vpi(char CMD);
 
int vpi_connect();
 
void vpi_dbg_test();
int vpi_dbg_reset();
int vpi_dbg_set_chain(uint32_t chain);
int vpi_dbg_ctrl(uint32_t reset, uint32_t stall);
int vpi_dbg_ctrl_read(uint32_t *reset, uint32_t *stall);
 
int vpi_dbg_cpu0_write_ctrl(uint32_t adr, unsigned char data);
int vpi_dbg_cpu0_write(uint32_t adr, uint32_t data);
int vpi_dbg_cpu0_read_ctrl(uint32_t adr, unsigned char *data);
int vpi_dbg_cpu0_read(uint32_t adr, uint32_t *data);
int vpi_dbg_wb_write_block32(uint32_t adr, uint32_t *data, uint32_t len);
int vpi_dbg_wb_read_block32(uint32_t adr, uint32_t *data, uint32_t len);
int vpi_dbg_wb_write32(uint32_t adr, uint32_t data);
int vpi_dbg_wb_read32(uint32_t adr, uint32_t *data);
 
 
 
/or_debug_proxy/includes/win_FTCJTAG_ptrs.h
0,0 → 1,131
#ifndef _WIN_FTCJTAG_PTRS_H_
#define _WIN_FTCJTAG_PTRS_H_
 
typedef FTC_STATUS _stdcall (*jtagGetNumDevicesPtr)(LPDWORD lpdwNumDevices);
jtagGetNumDevicesPtr jtagGetNumDevices;
 
typedef FTC_STATUS _stdcall (*jtagInitDevicePtr)(FTC_HANDLE ftHandle, DWORD dwClockDivisor);
jtagInitDevicePtr jtagInitDevice;
 
typedef FTC_STATUS _stdcall (*jtagOpenPtr)(FTC_HANDLE *pftHandle);
jtagOpenPtr jtagOpen;
 
typedef FTC_STATUS _stdcall (*jtagOpenExPtr)(LPSTR lpDeviceName, DWORD dwLocationIO, FTC_HANDLE *pftHandle);
jtagOpenExPtr jtagOpenEx;
 
typedef FTC_STATUS _stdcall (*jtagGetDeviceNameLocIDPtr)(DWORD dwDeviceNameIndex, LPSTR lpDeviceNameBuffer, DWORD dwBufferSize, LPDWORD lpdwLocationID);
jtagGetDeviceNameLocIDPtr jtagGetDeviceNameLocID;
 
typedef FTC_STATUS _stdcall (*jtagClosePtr)(FTC_HANDLE ftHandle);
jtagClosePtr jtagClose;
 
 
typedef FTC_STATUS _stdcall (*jtagGetClockPtr)(DWORD dwClockDivisor, LPDWORD lpdwClockFrequencyHz);
jtagGetClockPtr jtagGetClock;
 
 
typedef FTC_STATUS _stdcall (*jtagSetClockPtr)(FTC_HANDLE ftHandle, DWORD dwClockDivisor, LPDWORD lpdwClockFrequencyHz);
jtagSetClockPtr jtagSetClock;
 
typedef FTC_STATUS _stdcall (*jtagSetLoopbackPtr)(FTC_HANDLE ftHandle, BOOL bLoopbackState);
jtagSetLoopbackPtr jtagSetLoopback;
 
 
typedef FTC_STATUS _stdcall (*jtagSetGPIOsPtr)(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins,
PFTC_INPUT_OUTPUT_PINS pLowInputOutputPinsData,
BOOL bControlHighInputOutputPins,
PFTC_INPUT_OUTPUT_PINS pHighInputOutputPinsData);
jtagSetGPIOsPtr jtagSetGPIOs;
 
 
typedef FTC_STATUS _stdcall (*jtagGetGPIOsPtr)(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins,
PFTC_LOW_HIGH_PINS pLowPinsInputData,
BOOL bControlHighInputOutputPins,
PFTC_LOW_HIGH_PINS pHighPinsInputData);
jtagGetGPIOsPtr jtagGetGPIOs;
 
 
typedef FTC_STATUS _stdcall (*jtagWritePtr)(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
jtagWritePtr jtagWrite;
 
 
typedef FTC_STATUS _stdcall (*jtagReadPtr)(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead,
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned,
DWORD dwTapControllerState);
jtagReadPtr jtagRead;
 
 
typedef FTC_STATUS _stdcall (*jtagWriteReadPtr)(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned,
DWORD dwTapControllerState);
jtagWriteReadPtr jtagWriteRead;
 
 
typedef FTC_STATUS _stdcall (*jtagAddWriteCmdPtr)(BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
jtagAddWriteCmdPtr jtagAddWriteCmd;
 
 
 
typedef FTC_STATUS _stdcall (*jtagAddReadCmdPtr)(BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState);
jtagAddReadCmdPtr jtagAddReadCmd;
 
 
 
typedef FTC_STATUS _stdcall (*jtagAddWriteReadCmdPtr)(BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
jtagAddWriteReadCmdPtr jtagAddWriteReadCmd;
 
 
 
 
typedef FTC_STATUS _stdcall (*jtagClearDeviceCmdSequencePtr)(FTC_HANDLE ftHandle);
jtagClearDeviceCmdSequencePtr jtagClearDeviceCmdSequence;
 
 
 
typedef FTC_STATUS _stdcall (*jtagAddDeviceWriteCmdPtr)(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
jtagAddDeviceWriteCmdPtr jtagAddDeviceWriteCmd;
 
 
 
typedef FTC_STATUS _stdcall (*jtagAddDeviceReadCmdPtr)(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState);
jtagAddDeviceReadCmdPtr jtagAddDeviceReadCmd;
 
 
 
typedef FTC_STATUS _stdcall (*jtagAddDeviceWriteReadCmdPtr)(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
DWORD dwTapControllerState);
jtagAddDeviceWriteReadCmdPtr jtagAddDeviceWriteReadCmd;
 
 
 
typedef FTC_STATUS _stdcall (*jtagExecuteCmdSequencePtr)(FTC_HANDLE ftHandle, PReadCmdSequenceDataByteBuffer pReadCmdSequenceDataBuffer,
LPDWORD lpdwNumBytesReturned);
jtagExecuteCmdSequencePtr jtagExecuteCmdSequence;
 
 
 
typedef FTC_STATUS _stdcall (*jtagGetDllVersionPtr)(LPSTR lpDllVersionBuffer, DWORD dwBufferSize);
jtagGetDllVersionPtr jtagGetDllVersion;
 
 
 
typedef FTC_STATUS _stdcall (*jtagGetErrorCodeStringPtr)(LPSTR lpLanguage, FTC_STATUS StatusCode,
LPSTR lpErrorMessageBuffer, DWORD dwBufferSize);
jtagGetErrorCodeStringPtr jtagGetErrorCodeString;
 
 
int getFTDIJTAGFunctions ();
 
 
#endif /* _WIN_FTCJTAG_PTRS_H_ */
/or_debug_proxy/includes/or_debug_proxy.h
0,0 → 1,163
/*$$HEADER*/
/******************************************************************************/
/* */
/* H E A D E R I N F O R M A T I O N */
/* */
/******************************************************************************/
 
// Project Name : OpenRISC Debug Proxy
// File Name : or_debug_proxy.h
// Prepared By : jb
// Project Start : 2008-10-01
 
/*$$COPYRIGHT NOTICE*/
/******************************************************************************/
/* */
/* C O P Y R I G H T N O T I C E */
/* */
/******************************************************************************/
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation;
version 2.1 of the License, a copy of which is available from
http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt.
 
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
 
/*$$CHANGE HISTORY*/
/******************************************************************************/
/* */
/* C H A N G E H I S T O R Y */
/* */
/******************************************************************************/
 
// Date Version Description
//------------------------------------------------------------------------
// 081101 First revision jb
 
#ifndef _OR_DEBUG_PROXY_H_
#define _OR_DEBUG_PROXY_H_
 
#ifndef DEBUG_CMDS
#define DEBUG_CMDS 0 // Output the actual commands being sent to the debug unit
#endif
 
#ifndef DEBUG_USB_DRVR_FUNCS
#define DEBUG_USB_DRVR_FUNCS 0 // Generate debug output from the USB driver functions
#endif
 
#ifndef DEBUG_GDB_BLOCK_DATA
#define DEBUG_GDB_BLOCK_DATA 0 // GDB Socket Block data print out
#endif
 
// This one is defined sometimes in the makefile, so check first
#ifndef DEBUG_GDB
#define DEBUG_GDB 0 // GDB RSP Debugging output enabled
#endif
 
#ifndef DEBUG_GDB_DUMP_DATA
#define DEBUG_GDB_DUMP_DATA 0 // GDB Socket Debugging - output all data we return to GDB client
#endif
 
#define Boolean uint32_t
#define false 0
#define true 1
 
/* Selects crc trailer size in bits. Currently supported: 8 */
#define CRC_SIZE (8)
 
#include <stdint.h>
 
extern int serverPort;
extern int server_fd;
 
extern int vpi_fd; // should be the descriptor for our connection to the VPI server
 
extern int current_chain;
extern int dbg_chain;
 
#define DBGCHAIN_SIZE 4 // Renamed from DC_SIZE due to definition clash with something in <windows.h> --jb 090302
#define DC_STATUS_SIZE 4
 
#define DC_WISHBONE 0
#define DC_CPU0 1
#define DC_CPU1 2
 
// Manually figure the 5-bit reversed values again if they change
#define DI_GO 0
#define DI_READ_CMD 1
#define DI_WRITE_CMD 2
#define DI_READ_CTRL 3
#define DI_WRITE_CTRL 4
 
#define DBG_CRC_SIZE 32
#define DBG_CRC_POLY 0x04c11db7
 
#define DBG_ERR_OK 0
#define DBG_ERR_INVALID_ENDPOINT 3
#define DBG_ERR_CRC 8
 
#define NUM_SOFT_RETRIES 3
#define NUM_HARD_RETRIES 3
#define NUM_ACCESS_RETRIES 10
 
/* setup connection with the target */
void dbg_test();
/* perform a reset of the debug chain (not of system!) */
int dbg_reset();
/* set instruction register of JTAG TAP */
int dbg_set_tap_ir(uint32_t ir);
/* Set "scan chain" of debug unit (NOT JTAG TAP!) */
int dbg_set_chain(uint32_t chain);
/* read a word from wishbone */
int dbg_wb_read32(uint32_t adr, uint32_t *data);
/* write a word to wishbone */
int dbg_wb_write32(uint32_t adr, uint32_t data);
/* read a block from wishbone */
int dbg_wb_read_block32(uint32_t adr, uint32_t *data, uint32_t len);
/* write a block to wishbone */
int dbg_wb_write_block32(uint32_t adr, uint32_t *data, uint32_t len);
/* read a register from cpu */
int dbg_cpu0_read(uint32_t adr, uint32_t *data);
/* read a register from cpu module */
int dbg_cpu0_read_ctrl(uint32_t adr, unsigned char *data);
/* write a cpu register */
int dbg_cpu0_write(uint32_t adr, uint32_t data);
/* write a cpu module register */
int dbg_cpu0_write_ctrl(uint32_t adr, unsigned char data);
 
void print_usage(); // Self explanatory
 
void check(char *fn, uint32_t l, uint32_t i);
 
/* Possible errors are listed here. */
enum enum_errors /* modified <chris@asics.ws> CZ 24/05/01 */
{
/* Codes > 0 are for system errors */
 
ERR_NONE = 0,
ERR_CRC = -1,
ERR_MEM = -2,
JTAG_PROXY_INVALID_COMMAND = -3,
JTAG_PROXY_SERVER_TERMINATED = -4,
JTAG_PROXY_NO_CONNECTION = -5,
JTAG_PROXY_PROTOCOL_ERROR = -6,
JTAG_PROXY_COMMAND_NOT_IMPLEMENTED = -7,
JTAG_PROXY_INVALID_CHAIN = -8,
JTAG_PROXY_INVALID_ADDRESS = -9,
JTAG_PROXY_ACCESS_EXCEPTION = -10, /* Write to ROM */
JTAG_PROXY_INVALID_LENGTH = -11,
JTAG_PROXY_OUT_OF_MEMORY = -12,
};
 
#endif /* _OR_DEBUG_PROXY_H_ */
 
/or_debug_proxy/lib/FTCJTAG.dll Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
or_debug_proxy/lib/FTCJTAG.dll Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: or_debug_proxy/src/win_usb_driver_calls.c =================================================================== --- or_debug_proxy/src/win_usb_driver_calls.c (nonexistent) +++ or_debug_proxy/src/win_usb_driver_calls.c (revision 1779) @@ -0,0 +1,477 @@ +/*$$HEADER*/ +/******************************************************************************/ +/* */ +/* H E A D E R I N F O R M A T I O N */ +/* */ +/******************************************************************************/ + +// Project Name : OpenRISC Debug Proxy +// File Name : win_usb_driver_calls.c +// Prepared By : jb +// Project Start : 2008-10-01 + +/*$$COPYRIGHT NOTICE*/ +/******************************************************************************/ +/* */ +/* C O P Y R I G H T N O T I C E */ +/* */ +/******************************************************************************/ +/* + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; + version 2.1 of the License, a copy of which is available from + http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/*$$DESCRIPTION*/ +/******************************************************************************/ +/* */ +/* D E S C R I P T I O N */ +/* */ +/******************************************************************************/ +// +// Some generically named functions for interfacing to the JTAG driver +// functions, making the code calling these platform independant. The correct +// driver calling file (either Cygwin or Linux driver) is included at compile +// time. +// Also included in this file is the USB-JTAG chip initialisation function. +// + + +/*$$CHANGE HISTORY*/ +/******************************************************************************/ +/* */ +/* C H A N G E H I S T O R Y */ +/* */ +/******************************************************************************/ + +// Date Version Description +//------------------------------------------------------------------------ +// 081101 First revision jb + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "win_FTCJTAG.h" + +#include "win_FTCJTAG_ptrs.h" + +#include "usb_driver_calls.h" + +#include "or_debug_proxy.h" + + +// Load the pointers and loading functions of the FTCJTAG driver +int getFTDIJTAGFunctions (){ + + HINSTANCE hLib; + + /* Load the library */ + hLib = LoadLibrary("lib/FTCJTAG.dll"); + + if (hLib == NULL) { + printf("Loading of library file \"FTCJTAG.dll\" failed!\n"); + return -1; + } + + + /* get the address of the functions */ + jtagGetNumDevices = (jtagGetNumDevicesPtr) GetProcAddress(hLib, "JTAG_GetNumDevices"); + + if (jtagGetNumDevices == NULL) { + printf("GetProcAddress for JTAG_GetNumDevices Failed.\n"); + return -1; + } + + jtagInitDevice = (jtagInitDevicePtr) GetProcAddress(hLib, "JTAG_InitDevice"); + if (jtagInitDevice == NULL) { + printf("GetProcAddress for JTAG_InitDevice Failed.\n"); + return -1; + } + + jtagOpen = (jtagOpenPtr) GetProcAddress(hLib, "JTAG_Open"); + if (jtagOpen == NULL) { + printf("GetProcAddress for JTAG_Open Failed.\n"); + return -1; + } + + jtagOpenEx = (jtagOpenExPtr) GetProcAddress(hLib, "JTAG_OpenEx"); + if (jtagOpenEx == NULL) { + printf("GetProcAddress for JTAG_OpenEx Failed.\n"); + return -1; + } + + jtagGetDeviceNameLocID = (jtagGetDeviceNameLocIDPtr) GetProcAddress(hLib, "JTAG_GetDeviceNameLocID"); + if (jtagGetDeviceNameLocID == NULL) { + printf("GetProcAddress for Failed JTAG_GetDeviceNameLocID.\n"); + return -1; + } + + jtagClose = (jtagClosePtr) GetProcAddress(hLib, "JTAG_Close"); + if (jtagClose == NULL) { + printf("GetProcAddress for JTAG_Close Failed.\n"); + return -1; + } + + jtagGetClock = (jtagGetClockPtr) GetProcAddress(hLib, "JTAG_GetClock"); + if (jtagGetClock == NULL) { + printf("GetProcAddress for JTAG_GetClock Failed.\n"); + return -1; + } + + jtagSetClock = (jtagSetClockPtr) GetProcAddress(hLib, "JTAG_SetClock"); + if (jtagSetClock == NULL) { + printf("GetProcAddress for JTAG_SetClock Failed.\n"); + return -1; + } + + jtagSetLoopback = (jtagSetLoopbackPtr) GetProcAddress(hLib, "JTAG_SetLoopback"); + if (jtagSetLoopback == NULL) { + printf("GetProcAddress for JTAG_SetLoopback Failed.\n"); + return -1; + } + + jtagSetGPIOs = (jtagSetGPIOsPtr) GetProcAddress(hLib, "JTAG_SetGPIOs"); + if (jtagSetGPIOs == NULL) { + printf("GetProcAddress for JTAG_SetGPIOs Failed.\n"); + return -1; + } + + jtagGetGPIOs = (jtagGetGPIOsPtr) GetProcAddress(hLib, "JTAG_GetGPIOs"); + if (jtagGetGPIOs == NULL) { + printf("GetProcAddress for JTAG_GetGPIOs Failed.\n"); + return -1; + } + + jtagWrite = (jtagWritePtr) GetProcAddress(hLib, "JTAG_Write"); + if (jtagWrite == NULL) { + printf("GetProcAddress for JTAG_Write Failed.\n"); + return -1; + } + + jtagRead = (jtagReadPtr) GetProcAddress(hLib, "JTAG_Read"); + if (jtagRead == NULL) { + printf("GetProcAddress for JTAG_Read Failed.\n"); + return -1; + } + + jtagWriteRead = (jtagWriteReadPtr) GetProcAddress(hLib, "JTAG_WriteRead"); + if (jtagWriteRead == NULL) { + printf("GetProcAddress for JTAG_WriteRead Failed.\n"); + return -1; + } + + jtagAddWriteCmd = (jtagAddWriteCmdPtr) GetProcAddress(hLib, "JTAG_AddWriteCmd"); + if (jtagAddWriteCmd == NULL) { + printf("GetProcAddress for JTAG_AddWriteCmd Failed.\n"); + return -1; + } + + jtagAddReadCmd = (jtagAddReadCmdPtr) GetProcAddress(hLib, "JTAG_AddReadCmd"); + if (jtagAddReadCmd == NULL) { + printf("GetProcAddress for JTAG_AddReadCmd Failed.\n"); + return -1; + } + + jtagAddWriteReadCmd = (jtagAddWriteReadCmdPtr) GetProcAddress(hLib, "JTAG_AddWriteReadCmd"); + if (jtagAddWriteReadCmd == NULL) { + printf("GetProcAddress for JTAG_AddWriteReadCmd Failed.\n"); + return -1; + } + + jtagClearDeviceCmdSequence = (jtagClearDeviceCmdSequencePtr) GetProcAddress(hLib, "JTAG_ClearDeviceCmdSequence"); + if (jtagClearDeviceCmdSequence == NULL) { + printf("GetProcAddress for Failed.\n JTAG_ClearDeviceCmdSequence"); + return -1; + } + + jtagAddDeviceReadCmd = (jtagAddDeviceReadCmdPtr) GetProcAddress(hLib, "JTAG_AddDeviceReadCmd"); + if (jtagAddDeviceReadCmd == NULL) { + printf("GetProcAddress for Failed JTAG_AddDeviceReadCmd.\n"); + return -1; + } + + jtagAddDeviceWriteReadCmd = (jtagAddDeviceWriteReadCmdPtr) GetProcAddress(hLib, "JTAG_AddDeviceWriteReadCmd"); + if (jtagAddDeviceWriteReadCmd == NULL) { + printf("GetProcAddress for Failed.\n JTAG_AddDeviceWriteReadCmd"); + return -1; + } + + jtagExecuteCmdSequence = (jtagExecuteCmdSequencePtr) GetProcAddress(hLib, "JTAG_ExecuteCmdSequence"); + if (jtagExecuteCmdSequence == NULL) { + printf("GetProcAddress for Failed JTAG_ExecuteCmdSequence.\n"); + return -1; + } + + jtagGetDllVersion = (jtagGetDllVersionPtr) GetProcAddress(hLib, "JTAG_GetDllVersion"); + if (jtagGetDllVersion == NULL) { + printf("GetProcAddress for JTAG_GetDllVersion Failed.\n"); + return -1; + } + + jtagGetErrorCodeString = (jtagGetErrorCodeStringPtr) GetProcAddress(hLib, "JTAG_GetErrorCodeString"); + if (jtagGetErrorCodeString == NULL) { + printf("GetProcAddress for Failed JTAG_GetErrorCodeString.\n"); + return -1; + } + + // = (Ptr) GetProcAddress(hLib, ""); + //if ( == NULL) { + // printf("GetProcAddress for Failed.\n"); + // return -1; + // } + + return 0; + +} + + +// Global USB JTAG device handle +FTC_HANDLE ftHandle; + +FTC_STATUS +FT2232_USB_JTAG_WriteDataToExternalDevice( + //FTC_HANDLE ftHandle, + BOOL bInstructionTestData, + DWORD dwNumBitsToWrite, + PWriteDataByteBuffer pWriteDataBuffer, + DWORD dwNumBytesToWrite, + DWORD dwTapControllerState) +{ + // Return the appropritae call to the Windows driver + return (jtagWrite)( + ftHandle, + bInstructionTestData, + dwNumBitsToWrite, + pWriteDataBuffer, + dwNumBytesToWrite, + dwTapControllerState); + +} + + +// Read data from external device +FTC_STATUS +FT2232_USB_JTAG_ReadDataFromExternalDevice( + //FTC_HANDLE ftHandle, + BOOL bInstructionTestData, + DWORD dwNumBitsToRead, + PReadDataByteBuffer pReadDataBuffer, + LPDWORD lpdwNumBytesReturned, + DWORD dwTapControllerState) + +{ + return (jtagRead)( + ftHandle, + bInstructionTestData, + dwNumBitsToRead, + pReadDataBuffer, + lpdwNumBytesReturned, + dwTapControllerState); + +} + + + + + + +// Write Read +FTC_STATUS +FT2232_USB_JTAG_WriteReadDataToFromExternalDevice( + //FTC_HANDLE ftHandle, + BOOL bInstructionTestData, + DWORD dwNumBitsToWriteRead, + PWriteDataByteBuffer pWriteDataBuffer, + DWORD dwNumBytesToWrite, + PReadDataByteBuffer pReadDataBuffer, + LPDWORD lpdwNumBytesReturned, + DWORD dwTapControllerState) +{ + + return (jtagWriteRead)( + ftHandle, + bInstructionTestData, + dwNumBitsToWriteRead, + pWriteDataBuffer, + dwNumBytesToWrite, + pReadDataBuffer, + lpdwNumBytesReturned, + dwTapControllerState); + +} + + + +// Close device +FTC_STATUS +FT2232_USB_JTAG_CloseDevice() +{ + return (jtagClose)(ftHandle); +} + + + + +// Set clock frequency +// Frequency = 12Mhz/((1+divisor)*2), +// divisor=1000 => Freq=5995Hz~=6kHz, divisor=500=>Freq=12kHz +#define USB_JTAG_CLK_DIVIDER 0 + +int init_usb_jtag() +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumDevices = 0; + char szDeviceName[100]; + DWORD dwLocationID = 0; + // Made global: FTC_HANDLE ftHandle; + DWORD dwClockFrequencyHz = 0; + FTC_INPUT_OUTPUT_PINS LowInputOutputPinsData; + FTC_INPUT_OUTPUT_PINS HighInputOutputPinsData; + FTC_LOW_HIGH_PINS LowPinsInputData; + FTC_LOW_HIGH_PINS HighPinsInputData; + BOOL bPerformCommandSequence = false; + + DWORD dwLoopCntr = 0; + char szDllVersion[10]; + + Status = (jtagGetNumDevices)(&dwNumDevices); + if (DEBUG_USB_DRVR_FUNCS) + printf("JTAG_GetNumDevices returned Status: 0x%x and %d devices\n", + Status, dwNumDevices); + + + + if (dwNumDevices == 0) + { + printf("Error: USB debug cable not detected\nPlease ensure the device is attached and correctly installed\n\n"); + exit(-1); + } + + + Status = (jtagGetDllVersion)(szDllVersion, 10); + + if (DEBUG_USB_DRVR_FUNCS) + printf("JTAG_GetDLLVersion returned Status: 0x%x and version %s\n", + Status, szDllVersion); + + + // To do: Iterate through dwNumDevices by index number ,looking for the ORSoC Device, "ORSoC OpenRISC debug cable A\0", + + if ((Status == FTC_SUCCESS) && (dwNumDevices > 0)) + { + if (dwNumDevices == 1) + { + Status = (jtagGetDeviceNameLocID)(0,szDeviceName,50, &dwLocationID); + + if (DEBUG_USB_DRVR_FUNCS) + printf("JTAG_GetDeviceNameLocID: %s at: 0x%x\n", + szDeviceName, dwLocationID); + + if (Status == FTC_SUCCESS) + { + Status = (jtagOpenEx)(szDeviceName, dwLocationID, &ftHandle); + + } + } + else + { + if (dwNumDevices == 2) + { + Status=(jtagGetDeviceNameLocID)(1,szDeviceName,50,&dwLocationID); + + if (Status == FTC_SUCCESS) + { + Status = (jtagOpenEx)(szDeviceName, dwLocationID, &ftHandle); + } + } + } + } + + + if ((Status == FTC_SUCCESS) && (dwNumDevices > 0)) + { + Status = (jtagInitDevice)(ftHandle, 0); + + // Set clock frequency + // Frequency = 12Mhz/((1+divisor)*2), + // divisor=1000 => Freq=5995Hz~=6kHz, divisor=500=>Freq=12kHz + if (Status == FTC_SUCCESS) + Status = (jtagSetClock)(ftHandle, USB_JTAG_CLK_DIVIDER, + &dwClockFrequencyHz); + + + if (Status == FTC_SUCCESS){ + printf("USB JTAG interface initialised\n"); + Status = (jtagGetClock)(5, &dwClockFrequencyHz); + } + + if (Status == FTC_SUCCESS) + { // true=output, false=input + LowInputOutputPinsData.bPin1InputOutputState = true; // ADBUS4 - + // set ADBUS4 to output 0 to enable JTAG buffers on Olimex devices + LowInputOutputPinsData.bPin2InputOutputState = true; //ADBUS5 + LowInputOutputPinsData.bPin3InputOutputState = true; + LowInputOutputPinsData.bPin4InputOutputState = true; + //ADBUS4 = 0 (enable JTAG buffers on Olimex devices) + LowInputOutputPinsData.bPin1LowHighState = false; // ADBUS4 + LowInputOutputPinsData.bPin2LowHighState = false; // ADBUS5 + LowInputOutputPinsData.bPin3LowHighState = true; // ADBUS6 + LowInputOutputPinsData.bPin4LowHighState = true; // ADBUS7 + + HighInputOutputPinsData.bPin1InputOutputState = true; // ACBUS0 + HighInputOutputPinsData.bPin2InputOutputState = true; // ACBUS1 + HighInputOutputPinsData.bPin3InputOutputState = true; // ACBUS2 + HighInputOutputPinsData.bPin4InputOutputState = true; // ACBUS3 + HighInputOutputPinsData.bPin1LowHighState = true; // ACBUS0 + HighInputOutputPinsData.bPin2LowHighState = true; // ACBUS1 + HighInputOutputPinsData.bPin3LowHighState = true; // ACBUS2 + HighInputOutputPinsData.bPin4LowHighState =true; // ACBUS3 + + Status = (jtagSetGPIOs)(ftHandle, true, &LowInputOutputPinsData, + true, &HighInputOutputPinsData); + + if (Status == FTC_SUCCESS) + Status = (jtagGetGPIOs)(ftHandle, true, &LowPinsInputData, + true, &HighPinsInputData); + + if (DEBUG_USB_DRVR_FUNCS) + printf("JTAG low gpio pins values: (ADBUS7-ADBUS4):%x%x%x%x\n", + (LowPinsInputData.bPin4LowHighState==true), + (LowPinsInputData.bPin3LowHighState==true), + (LowPinsInputData.bPin2LowHighState==true), + (LowPinsInputData.bPin1LowHighState==true)); + + if (DEBUG_USB_DRVR_FUNCS) + printf("JTAG high gpio pins values: (ACBUS3-ACBUS0): %x%x%x%x\n", + (HighPinsInputData.bPin4LowHighState==true), + (HighPinsInputData.bPin3LowHighState==true), + (HighPinsInputData.bPin2LowHighState==true), + (HighPinsInputData.bPin1LowHighState==true)); + } + } + + if (Status == FTC_SUCCESS) + return 0; + else + return 1; + +} Index: or_debug_proxy/src/usb_functions.c =================================================================== --- or_debug_proxy/src/usb_functions.c (nonexistent) +++ or_debug_proxy/src/usb_functions.c (revision 1779) @@ -0,0 +1,1069 @@ +/*$$HEADER*/ +/******************************************************************************/ +/* */ +/* H E A D E R I N F O R M A T I O N */ +/* */ +/******************************************************************************/ + +// Project Name : OpenRISC Debug Proxy +// File Name : usb_functions.c +// Prepared By : jb +// Project Start : 2008-10-01 + +/*$$COPYRIGHT NOTICE*/ +/******************************************************************************/ +/* */ +/* C O P Y R I G H T N O T I C E */ +/* */ +/******************************************************************************/ +/* + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; + version 2.1 of the License, a copy of which is available from + http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/*$$DESCRIPTION*/ +/******************************************************************************/ +/* */ +/* D E S C R I P T I O N */ +/* */ +/******************************************************************************/ +// +// Code calling the FT2232 JTAG MPSSE driver functions. Does a majority of the +// fiddly work when interfacing to the system via its debug module. +// + + +/*$$CHANGE HISTORY*/ +/******************************************************************************/ +/* */ +/* C H A N G E H I S T O R Y */ +/* */ +/******************************************************************************/ +// Date Version Description +//------------------------------------------------------------------------ +// 081101 First revision jb + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef CYGWIN_COMPILE +#include +#include "win_FTCJTAG.h" +#else // We're on Linux or Mac OS X +#include "WinTypes.h" // We still use things from here in this file - TODO: remove this dependency +#include "FT2232cMpsseJtag.h" +#endif + +#include "gdb.h" + +#include "usb_functions.h" + +#include "or_debug_proxy.h" + +#include "usb_driver_calls.h" + +// Global JTAG signals for reading/writing +DWORD dwNumBytesReturned = 0; + +/* Crc of current read or written data. */ +uint32_t crc_r, crc_w = 0; + +/* Generates new crc, sending in new bit input_bit */ +uint32_t crc_calc(uint32_t crc, uint32_t input_bit) { + uint32_t d = (input_bit) ? 0xfffffff : 0x0000000; + uint32_t crc_32 = ((crc >> 31)&1) ? 0xfffffff : 0x0000000; + crc <<= 1; + return crc ^ ((d ^ crc_32) & DBG_CRC_POLY); +} + +// Speedy bit reversing algorithms for base2 lengths +// Thanks to: http://aggregate.org/MAGIC/#Bit%20Reversal +uint32_t bit_reverse_swar_2(uint32_t x) +{ + x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1)); + return x; +} +uint32_t bit_reverse_swar_4(uint32_t x) +{ + x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1)); + x=(((x&0xcccccccc)>>2)|((x&0x33333333)<<2)); + return x; +} +uint32_t bit_reverse_swar_8(uint32_t x) +{ + x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1)); + x=(((x&0xcccccccc)>>2)|((x&0x33333333)<<2)); + x=(((x&0xf0f0f0f0)>>4)|((x&0x0f0f0f0f)<<4)); + return x; +} +uint32_t bit_reverse_swar_16(uint32_t x) +{ + x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1)); + x=(((x&0xcccccccc)>>2)|((x&0x33333333)<<2)); + x=(((x&0xf0f0f0f0)>>4)|((x&0x0f0f0f0f)<<4)); + x=(((x&0xff00ff00)>>8)|((x&0x00ff00ff)<<8)); + return x; +} +uint32_t bit_reverse_swar_32(uint32_t x) +{ + x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1)); + x=(((x&0xcccccccc)>>2)|((x&0x33333333)<<2)); + x=(((x&0xf0f0f0f0)>>4)|((x&0x0f0f0f0f)<<4)); + x=(((x&0xff00ff00)>>8)|((x&0x00ff00ff)<<8)); + x=(((x&0xffff0000)>>16)|((x&0x0000ffff)<<16)); // We could be on 64-bit arch! + return x; +} + +uint32_t bit_reverse_data(uint32_t data, uint32_t length){ + if (length == 2) return bit_reverse_swar_2(data); + if (length == 4) return bit_reverse_swar_4(data); + if (length == 8) return bit_reverse_swar_8(data); + if (length == 16) return bit_reverse_swar_16(data); + if (length == 32) return bit_reverse_swar_32(data); + // Long and laborious way - hopefully never gets called anymore! + uint32_t i,reverse=0; + for (i=0;i>i)&1)<<(length-1-i)); + return reverse; +} +// Constants that are used a lot, and were 5 bits, so might as well precalculate them +// These are from or_debug_proxy.h, so if the original values change these +// should be recalculated!! +const uint8_t DI_GO_5BITREVERSED = 0x00; +const uint8_t DI_READ_CMD_5BITREVERSED = 0x10; +const uint8_t DI_WRITE_CMD_5BITREVERSED = 0x08; +const uint8_t DI_READ_CTRL_5BITREVERSED = 0x18; +const uint8_t DI_WRITE_CTRL_5BITREVERSED = 0x04; + + +void usb_dbg_test() { + + uint32_t npc, ppc, r1; + unsigned char stalled; + + + + printf("Stalling or1k\n"); + err = dbg_cpu0_write_ctrl(0, 0x01); // stall or1k + + err = dbg_cpu0_read_ctrl(0, &stalled); + if (!(stalled & 0x1)) { + printf("or1k should be stalled\n"); // check stall or1k + exit(1); + } + + /* Clear Debug Reason Register (DRR) 0x3015 */ + err = dbg_cpu0_write((6 << 11) + 21, 0); + err = dbg_cpu0_read((0 << 11) + 16, &npc); /* Read NPC */ + err = dbg_cpu0_read((0 << 11) + 18, &ppc); /* Read PPC */ + err = dbg_cpu0_read(0x401, &r1); /* Read R1 */ + + if (err) + { + printf("Jtag error %d occured; exiting.", err); + FT2232_USB_JTAG_CloseDevice(); + exit(1); + } + printf("Read npc = %.8x ppc = %.8x r1 = %.8x\n", npc, ppc, r1); + + return; +} + +/* +void ensure_or1k_stalled(); + +// Function to check if the processor is stalled, if not, stall it. +// this is useful in the event that GDB thinks the processor is stalled, but has, in fact +// been hard reset on the board and is running. +void ensure_or1k_stalled() +{ + unsigned char stalled; + dbg_cpu0_read_ctrl(0, &stalled); + if ((stalled & 0x1) != 0x1) + { + if (DEBUG_CMDS) + printf("Processor not stalled, like we thought\n"); + + // Set the TAP controller to its OR1k chain + usb_set_tap_ir(JI_DEBUG); + current_chain = -1; + + // Processor isn't stalled, contrary to what we though, so stall it + printf("Stalling or1k\n"); + dbg_cpu0_write_ctrl(0, 0x01); // stall or1k + + } +} +*/ +/*---------------------------------------------------------------------------*/ +/*!Write up to 32-bits to the JTAG bus via the USB device + +Write up to 32-bits to the JTAG bus. + +@param[in] stream This should store the data to be written to the bus +@param[in] num_bits Number of bits to write on the JTAG bus +@param[in] dwTapControllerState State to leave the JTAG TAP in when done */ +/*---------------------------------------------------------------------------*/ +void usb_write_stream (uint32_t stream, uint32_t num_bits, DWORD dwTapControllerState){ + FTC_STATUS Status = FTC_SUCCESS; + uint32_t i,num_bytes; + WriteDataByteBuffer WriteDataBuffer; + + if ((num_bits/8)>0)num_bytes=(num_bits/8); + else num_bytes=1; + // First clear the buffer for the amount of data we're shifting in + // Bytewise copy the stream into WriteDataBuffer, LSB first + + // This means if we want to send things MSb first, we need to pass them + // to this function wrapped with a call to bit_reverse_data(data,length) + + for (i=0; i<(num_bytes)+1;i++) + WriteDataBuffer[i] = ((stream >>(8*i)) & (0xff)); + + // Now generate the CRC for what we're sending + // data should be presented MSb first (at bit0) + for (i=0;i>i)&1)); + + + if (DEBUG_USB_DRVR_FUNCS) + { + printf("\nusb_write_stream: num_bytes=%d, WriteDataBuffer contents for %d bits:",num_bytes,num_bits); + for (i=0;iJTAG_WriteDataToExternalDevice(ftHandle, false, num_bits, + // &WriteDataBuffer, num_bytes, dwTapControllerState); + // Platform independant function call + Status = FT2232_USB_JTAG_WriteDataToExternalDevice(false, num_bits, + &WriteDataBuffer, num_bytes, dwTapControllerState); + + if (Status != FTC_SUCCESS) + printf("Write to USB device failed: status code: %ld\n",Status); + +} + +/*---------------------------------------------------------------------------*/ +/*!Read up to 32-bits off the JTAG bus via the USB device + +The return value of this should remain uint32_t as we're returning all the +data in a signal variable. We never need more than 32-bits in a single read +when using this function. + +@param[in] num_bits Number of bits to read off from the USB +@param[in] dwTapControllerState State to leave the JTAG TAP in when done +@return: The data read from the USB device */ +/*---------------------------------------------------------------------------*/ +uint32_t usb_read_stream(uint32_t num_bits, DWORD dwTapControllerState){ + ReadDataByteBuffer ReadDataBuffer; + FTC_STATUS Status = FTC_SUCCESS; + uint32_t returnVal =0; + uint32_t i; + + // Platform independant driver call + Status = FT2232_USB_JTAG_ReadDataFromExternalDevice(false, num_bits, &ReadDataBuffer, &dwNumBytesReturned, dwTapControllerState); + + if (DEBUG_USB_DRVR_FUNCS) + printf("usb_read_stream: returned Status: 0x%lx from reading %u bits, \n", + Status,num_bits); + + if (Status == FTC_SUCCESS){ + + for(i=0;i>(i%8))&0x1)<<(num_bits-1-i); + } + } + // Generate the CRC for read + for (i=0;i>(num_bits-1-i))&1)); + + return returnVal; +} + +/* Sets TAP instruction register */ +void usb_set_tap_ir(uint32_t ir) { + + WriteDataByteBuffer WriteDataBuffer; + FTC_STATUS Status = FTC_SUCCESS; + + WriteDataBuffer[0] = ir; + + // Using global ftHandle, writing to TAP instruction register 4 bits, + //Status = pFT2232cMpsseJtag->JTAG_WriteDataToExternalDevice(ftHandle, true, + //JI_SIZE, &WriteDataBuffer, 1, RUN_TEST_IDLE_STATE); + // Platform independant driver call + + Status = FT2232_USB_JTAG_WriteDataToExternalDevice(true, JI_SIZE, &WriteDataBuffer, 1, RUN_TEST_IDLE_STATE); + + if (DEBUG_USB_DRVR_FUNCS) + printf("USB JTAG write of %x to instruction register returned Status: 0x%lx\n", + ir, Status); + current_chain = -1; +} + + +/* Resets JTAG, and sets DEBUG scan chain */ +int usb_dbg_reset() { + + // uint32_t err; + uint32_t id; + uint32_t reinit_count=0; + retry_jtag_init: + if (init_usb_jtag() > 0) + return DBG_ERR_CRC; + + // Set ID code instruction in IR + usb_set_tap_ir(JI_IDCODE); + + // Now read out the IDCODE for the device + id = usb_read_stream(32, RUN_TEST_IDLE_STATE); + + // if read ID was rubbish retry init - this is probably NOT the best way to do this... + if ((id == 0xffffffff) | (id == 0x00000002) | (id == 0x00000000)) { + //pFT2232cMpsseJtag->JTAG_CloseDevice(gFtHandle); + // Platform independant driver call + FT2232_USB_JTAG_CloseDevice(); + if (reinit_count++ > 4){ + printf("JTAG TAP ID read error. Unable to detect TAP controller. \nPlease ensure debugger is connected to target correctly.\n"); + exit(1); + } + goto retry_jtag_init; + } + + printf("JTAG ID = %08x\n", id & 0xffffffff); + + /* select debug scan chain and stay in it forever */ + usb_set_tap_ir(JI_DEBUG); + current_chain = -1; + return DBG_ERR_OK; +} + +/* counts retries and returns zero if we should abort */ +static int retry_no = 0; +int retry_do() { + + unsigned char stalled; + + //printf("RETRY\n"); + if (retry_no == 0) + printf("Communication error. Retrying\n"); + + // Odds are if we're having a communication problem, we should + // just reconnect to the processor. It's probably just been reset. + /* + FT2232_USB_JTAG_CloseDevice();// Close the device + + if (init_usb_jtag() > 0) + { + if (retry_no >= NUM_HARD_RETRIES) + return 1; + else + return 0; + } + */ + usb_set_tap_ir(JI_DEBUG); + + current_chain = -1; + + if (retry_no == 1) + sleep(1); + + else if ( retry_no < NUM_SOFT_RETRIES) + return 1; // Just attempt again + if ((retry_no >= NUM_SOFT_RETRIES) && (retry_no < NUM_SOFT_RETRIES + NUM_HARD_RETRIES) ) + { + // Attempt a stall of the processor and then we'll try again + //usb_dbg_test(); + printf("Stalling or1k\n"); + err = dbg_cpu0_write_ctrl(0, 0x01); // stall or1k + + err = dbg_cpu0_read_ctrl(0, &stalled); + if (!(stalled & 0x1)) { + printf("or1k should be stalled\n"); // check stall or1k + FT2232_USB_JTAG_CloseDevice();// Close the device + exit(1); + } + + retry_no++; + return 1; + } + else // Unable to get the processor going again, return 0 + return 0; + +} + +/* resets retry counter */ +void retry_ok() { + retry_no = 0; +} + +/* Sets scan chain. */ +int usb_dbg_set_chain(int chain) { + uint32_t status, crc_generated, crc_read; + dbg_chain = chain; + + try_again: + if (current_chain == chain) return DBG_ERR_OK; + current_chain = -1; + if (DEBUG_CMDS) printf("\n"); + if (DEBUG_CMDS) printf("set_chain %i\n", chain); + + crc_w = 0xffffffff; // reset crc write variable + + // CRC generated in usb_read/write_stream functions + + usb_write_stream((((bit_reverse_data(chain,DBGCHAIN_SIZE) & 0xf) << 1) | 1), + DBGCHAIN_SIZE+1 , PAUSE_TEST_DATA_REGISTER_STATE); + + usb_write_stream(bit_reverse_data(crc_w, DBG_CRC_SIZE),DBG_CRC_SIZE, + PAUSE_TEST_DATA_REGISTER_STATE); + + crc_r = 0xffffffff; // reset the crc_r variable + + status = (usb_read_stream(DC_STATUS_SIZE, + PAUSE_TEST_DATA_REGISTER_STATE) & 0xf); + + crc_generated = crc_r; + + crc_read = usb_read_stream(DBG_CRC_SIZE, RUN_TEST_IDLE_STATE); + //printf("%x %x %x\n",status, crc_generated, crc_read); + + /* CRCs must match, otherwise retry */ + if (crc_read != crc_generated) { + if (retry_do()) goto try_again; + else return DBG_ERR_CRC; + } + /* we should read expected status value, otherwise retry */ + if (status != 0) { + if (retry_do()) goto try_again; + else return status; + } + + /* reset retry counter */ + retry_ok(); + + current_chain = chain; + return DBG_ERR_OK; +} + + + +/* sends out a command with 32bit address and 16bit length, if len >= 0 */ +int usb_dbg_command(uint32_t type, uint32_t adr, uint32_t len) { + uint32_t i,status, crc_generated, crc_read; + + // JTAG driver things + FTC_STATUS Status = FTC_SUCCESS; + WriteDataByteBuffer WriteDataBuffer; + ReadDataByteBuffer ReadDataBuffer; + + try_again: + usb_dbg_set_chain(dbg_chain); + if (DEBUG_CMDS) printf("\n"); + if (DEBUG_CMDS) printf("comm %d %d %8x \n", type,len,adr); + + //Calculate CRCs first + crc_w = 0xffffffff; + + for (i=0;i> i) & 1); + //crc_w = crc_calc(crc_w, + // ((bit_reverse_data((DI_WRITE_CMD & 0xf),DBGCHAIN_SIZE+1))>>i)&1); + + for (i=0;i<4;i++) + crc_w = crc_calc(crc_w,((bit_reverse_data(type,4))>>i)&1); + + for (i=0;i<32;i++) + crc_w = crc_calc(crc_w,((bit_reverse_data(adr,32))>>i)&1); + + assert(len > 0); + for (i=0;i<16;i++) + crc_w = crc_calc(crc_w,((bit_reverse_data(len-1,16))>>i)&1); + + + + // Now pack the write data buffer + // 1-bit 0, 4-bits cmd, 4-bit type, 32-bit adr, 32-bit CRC + // [0] + //bits 0-4 + WriteDataBuffer[0]=(DI_WRITE_CMD_5BITREVERSED); + //bits 5-7 + WriteDataBuffer[0] |= ((bit_reverse_data(type,4)&0x7)<<5); + // [1] + // bit 0 - last bit of type + WriteDataBuffer[1] = ((bit_reverse_data(type,4)&0x08)>>3); + //bits 1-7 - first 7 bits of adr + WriteDataBuffer[1] |= ((bit_reverse_data(adr,32)&0x07f)<<1); + //[2-4] 24 bits of adr + for(i=0;i<3;i++) + WriteDataBuffer[2+i] = (bit_reverse_data(adr,32)>>(7+(i*8)))&0xff; + // [5] last bit of adr in bit 0, first 7 bits of len-1 follow + WriteDataBuffer[5] = (bit_reverse_data(adr,32)>>31)&1; + WriteDataBuffer[5] |= (bit_reverse_data(len-1,16)&0x7f)<<1; + // [6] bits 7-14 of (len-1) + WriteDataBuffer[6] = (bit_reverse_data(len-1,16)>>7)&0xff; + // [7] - last bit of len-1 and first 7 bits of the CRC + WriteDataBuffer[7] = (bit_reverse_data(len-1,16)>>15)&1; + //Reverse the CRC first + crc_w = bit_reverse_data(crc_w, DBG_CRC_SIZE); + WriteDataBuffer[7] |= (crc_w&0x7f)<<1; + //[8-10] next 24 bits (7-30) of crc_w + WriteDataBuffer[8] = (crc_w>>7)&0xff; + WriteDataBuffer[9] = (crc_w>>15)&0xff; + WriteDataBuffer[10] = (crc_w>>23)&0xff; + //[11] final bit of crc_w + WriteDataBuffer[11] = (crc_w>>31)&1; + + // Status = pFT2232cMpsseJtag->JTAG_WriteReadDataToFromExternalDevice(gFtHandle,false,89+4+32 , &WriteDataBuffer, 16, &ReadDataBuffer, &dwNumBytesReturned, RUN_TEST_IDLE_STATE); + // Platform independant driver call + Status = FT2232_USB_JTAG_WriteReadDataToFromExternalDevice(false,89+4+32 , &WriteDataBuffer, 16, &ReadDataBuffer, &dwNumBytesReturned, RUN_TEST_IDLE_STATE); + + if (Status != FTC_SUCCESS) + printf("USB write fail - code %ld\b",Status); + + // Now look through the read data + + // From bit1 of ReadDataBuffer[11] we should have our 4-bit status + status = (ReadDataBuffer[11] >> 1) & 0xf; + + // Now extract the received CRC + crc_read = 0; + //first 3 bits (0-2) + crc_read |= (ReadDataBuffer[11] >> 5) & 0x7; + // middle 3 bytes (bits 3 to 26) + for (i=0;i<3;i++) + crc_read |= ((ReadDataBuffer[12+i]&0xff) << ((i*8)+3)); + // last 5 bits from ReadDataBuffer[15] + crc_read |= (ReadDataBuffer[15]&0x1f)<<27; + + // Now calculate CRC on status + crc_r = 0xffffffff; + for(i=0;i>i)&1); + + crc_generated = crc_r; + // Now bit reverse status and crc_read as we unpacked them + // with the MSb going to the LSb + status = bit_reverse_data(status, DC_STATUS_SIZE); + crc_read = bit_reverse_data(crc_read, DBG_CRC_SIZE); + + //printf("%x %x %x\n", status, crc_read, crc_generated); + /* CRCs must match, otherwise retry */ + if (crc_read != crc_generated) { + //exit(1);//remove later + if (retry_do()) goto try_again; + else return DBG_ERR_CRC; + } + /* we should read expected status value, otherwise retry */ + if (status != 0) { + //exit(1);//remove later + if (retry_do()) goto try_again; + else return status; + } + /* reset retry counter */ + retry_ok(); + + return DBG_ERR_OK; +} + + +/* writes a ctrl reg */ +int usb_dbg_ctrl(uint32_t reset, uint32_t stall) { + uint32_t i,status, crc_generated, crc_read; + + // JTAG driver things + FTC_STATUS Status = FTC_SUCCESS; + WriteDataByteBuffer WriteDataBuffer; + ReadDataByteBuffer ReadDataBuffer; + +try_again: + usb_dbg_set_chain(dbg_chain); + if (DEBUG_CMDS) printf("\n"); + if (DEBUG_CMDS) printf("ctrl\n"); + if (DEBUG_CMDS) printf("reset %x stall %x\n", reset, stall); + + crc_w = 0xffffffff; + // Try packing everyhing we want to send into one write buffer + //Calculate CRCs first + for (i=0;i>i)&1); + //crc_w = crc_calc(crc_w, + // ((bit_reverse_data((DI_WRITE_CTRL & 0xf),DBGCHAIN_SIZE+1))>>i)&1); + crc_w = crc_calc(crc_w,(reset&1)); + crc_w = crc_calc(crc_w,(stall&1)); + for (i=0;i<50;i++) + crc_w = crc_calc(crc_w,0); + + + + // Now pack the write data buffer + // 1-bit 0, 4-bits cmd, 52-bits CPU control register data (only first 2 matter) + //bits 0-4 + WriteDataBuffer[0]=(DI_WRITE_CTRL_5BITREVERSED); + // bit 5 + WriteDataBuffer[0] |= (reset)<<(DBGCHAIN_SIZE+1); + // bit 6 + WriteDataBuffer[0] |= (stall)<<(DBGCHAIN_SIZE+2); + // Clear the next 48 bits + for (i=1; i<16;i++) //actually clear more than just the next 50 bits + WriteDataBuffer[i] = 0; + + //Reverse the CRC first + crc_w = bit_reverse_data(crc_w, DBG_CRC_SIZE); + //Now load in the CRC, but take note of fact + // that bit 0 of buffer[7] is last 0 from cmd register data + // fill up from WriteDataBuffer[7-11] + for (i=0;i<4;i++) + WriteDataBuffer[7+i] = ((crc_w<<1)>>(i*8))&0xff; + //Final bit, shift in and make sure is the only thing int he buffer + WriteDataBuffer[11]=0|((crc_w>>31)&1); + + + //Status = pFT2232cMpsseJtag->JTAG_WriteReadDataToFromExternalDevice(gFtHandle,false,89+4+32 , &WriteDataBuffer, 16, &ReadDataBuffer, &dwNumBytesReturned, RUN_TEST_IDLE_STATE); + // Platform independant driver call + Status = FT2232_USB_JTAG_WriteReadDataToFromExternalDevice(false,89+4+32 , &WriteDataBuffer, 16, &ReadDataBuffer, &dwNumBytesReturned, RUN_TEST_IDLE_STATE); + + + if (Status != FTC_SUCCESS) + printf("USB write fail - code %ld\b",Status); + + // Now look through the read data + + // From bit1 of ReadDataBuffer[11] we should have our 4-bit status + status = (ReadDataBuffer[11] >> 1) & 0xf; + + // Now extract the received CRC + crc_read = 0; + //first 3 bits (0-2) + crc_read |= (ReadDataBuffer[11] >> 5) & 0x7; + // middle 3 bytes (bits 3 to 26) + for (i=0;i<3;i++) + crc_read |= ((ReadDataBuffer[12+i]&0xff) << ((i*8)+3)); + // last 5 bits from ReadDataBuffer[15] + crc_read |= (ReadDataBuffer[15]&0x1f)<<27; + + + // Now calculate CRC on status and crc_read + crc_r = 0xffffffff; + for(i=0;i>i)&1); + + crc_generated = crc_r; + // Now bit reverse status and crc_read as we unpacked them + // with the MSb going to the LSb + status = bit_reverse_data(status, DC_STATUS_SIZE); + crc_read = bit_reverse_data(crc_read, DBG_CRC_SIZE); + + /* CRCs must match, otherwise retry */ + //printf("%x %x %x\n", status, crc_read, crc_generated); + if (crc_read != crc_generated) { + //exit(1);//Remove later!! + if (retry_do()) goto try_again; + else return DBG_ERR_CRC; + } + /* we should read expected status value, otherwise retry */ + if (status != 0) { + //exit(1);//Remove later!! + if (retry_do()) goto try_again; + else return status; + } + + /* reset retry counter */ + retry_ok(); + return DBG_ERR_OK; +} + + +/* reads control register */ +int usb_dbg_ctrl_read(uint32_t *reset, uint32_t *stall) { + uint32_t i, status, crc_generated, crc_read; + + // JTAG driver things + FTC_STATUS Status = FTC_SUCCESS; + WriteDataByteBuffer WriteDataBuffer; + ReadDataByteBuffer ReadDataBuffer; + + + try_again: + usb_dbg_set_chain(dbg_chain); + if (DEBUG_CMDS) printf("\n"); + if (DEBUG_CMDS) printf("ctrl_read\n"); + + crc_w = 0xffffffff; + // Try packing everyhing we want to send into one write buffer + //Calculate CRCs first + for (i=0;i>i)&1); + //crc_w = crc_calc(crc_w, + //((bit_reverse_data((DI_READ_CTRL & 0xf),DBGCHAIN_SIZE+1))>>i)&1); + + + // Now pack the write data buffer + // 1-bit 0, 4-bits cmd, 32-bit CRC + //bits 0-4 + WriteDataBuffer[0]=(DI_READ_CTRL_5BITREVERSED); + // Clear the next 48 bits + for (i=1; i<16;i++) //actually clear more than just the next 50 bits + WriteDataBuffer[i] = 0; + + //Reverse the CRC first + crc_w = bit_reverse_data(crc_w, DBG_CRC_SIZE); + //Now load in the CRC + //First 3 bits go in last 3 bits of buffer[0] + WriteDataBuffer[0] |= (crc_w & 0x7)<<5; + // The rest of crc_w goes in buffer[1-4] + for (i=0;i<3;i++) + WriteDataBuffer[1+i] = ((crc_w>>3)>>(i*8))&0xff; + //Final bit of write buffer with CRC + WriteDataBuffer[4] = ((crc_w>>3)>>(24))&0x1f; + + + + //Status = pFT2232cMpsseJtag->JTAG_WriteReadDataToFromExternalDevice(gFtHandle,false,5+32+52+4+32, &WriteDataBuffer, 16, &ReadDataBuffer, &dwNumBytesReturned, RUN_TEST_IDLE_STATE); + // Platform independant driver call + Status = FT2232_USB_JTAG_WriteReadDataToFromExternalDevice(false,5+32+52+4+32, &WriteDataBuffer, 16, &ReadDataBuffer, &dwNumBytesReturned, RUN_TEST_IDLE_STATE); + if (Status != FTC_SUCCESS) + printf("USB read fail - code %ld\b",Status); + + // Now look through the read data + //0 - 1+4-bit status, 3-bits CRC + //1,2,3 - CRC + //4 - first 5 bits CRC, last 3, control reg bits (first 3) + //5,6,7,8,9,10 - control reg data (48 bits) + //11 - bit0 - control reg data, bit 1-4 status bits, bits 5-7 CRC + //12, 13 14 - CRC + // 15 bits 0-4 CRC + // Starting from bit1 of ReadDataBuffer[11] we should have our 4-bit status + status = (ReadDataBuffer[11] >> 1) & 0xf; + + //reset bit should be in ReadDataBuffer[4] as bit 5 + *reset = (ReadDataBuffer[4] >> 5) & 1; + //stalled bit should be in ReadDataBuffer[4] as bit 6 + *stall = (ReadDataBuffer[4] >> 6) & 1; + // Now extract the received CRC + crc_read = 0; + //first 3 bits (0-2) of CRC are in bits 5-7 of ReadDataBuffer[11] + crc_read |= (ReadDataBuffer[11] >> 5) & 0x7; + // middle 3 bytes (bits 3 to 26) + for (i=0;i<3;i++) + crc_read |= ((ReadDataBuffer[12+i]&0xff) << ((i*8)+3)); + // last 5 bits from ReadDataBuffer[15] + crc_read |= (ReadDataBuffer[15]&0x1f)<<27; + + if (DEBUG_CMDS) printf("reset bit %x stalled bit %x:\n", + ((ReadDataBuffer[4] >> 5) & 1), ((ReadDataBuffer[4] >> 6) & 1)); + + // Now calculate CRC on status and crc_read + crc_r = 0xffffffff; + + crc_r = crc_calc(crc_r, ((ReadDataBuffer[4] >> 5) & 1)); + crc_r = crc_calc(crc_r, ((ReadDataBuffer[4] >> 6) & 1)); + for(i=0;i<50;i++) + crc_r = crc_calc(crc_r,0); + for(i=0;i>i)&1); + + crc_generated = crc_r; + // Now bit reverse status and crc_read as we unpacked them + // with the MSb going to the LSb + status = bit_reverse_data(status, DC_STATUS_SIZE); + crc_read = bit_reverse_data(crc_read, DBG_CRC_SIZE); + + /* CRCs must match, otherwise retry */ + //printf("%x %x %x\n", status, crc_generated, crc_read); + if (crc_read != crc_generated) { + if (retry_do()) goto try_again; + else return DBG_ERR_CRC; + } + /* we should read expected status value, otherwise retry */ + if (status != 0) { + if (retry_do()) goto try_again; + else return status; + } + /* reset retry counter */ + retry_ok(); + return DBG_ERR_OK; +} + + +/* issues a burst read/write */ +int usb_dbg_go(unsigned char *data, uint16_t len, uint32_t read) { + uint32_t status, crc_generated, crc_read; + int i,j; + uint8_t data_byte; + + // JTAG driver things + FTC_STATUS Status = FTC_SUCCESS; + WriteDataByteBuffer WriteDataBuffer; + ReadDataByteBuffer ReadDataBuffer; + + try_again: + usb_dbg_set_chain(dbg_chain); + if (DEBUG_CMDS) printf("\n"); + if (DEBUG_CMDS) printf("go len is %d, read is %d\n", len, read); + + crc_w = 0xffffffff; + // Try packing everyhing we want to send into one write buffer + //Calculate CRCs first + for (i=0;i>i)&1); + //crc_w = crc_calc(crc_w, + // ((bit_reverse_data((DI_GO & 0xf),DBGCHAIN_SIZE+1))>>i)&1); + // Set first 5 bits of WriteDataBuffer up to + // be the GO command and 0 first bit + WriteDataBuffer[0]=DI_GO_5BITREVERSED; + + if (read) + { + // Do GO command for a read + // 0 then 4-bit go command, then 32-bit CRC for the last 5 bits + // Then read (len+1)*8 + 4-bit status + 32-bit CRC + + + // Reverse crc_w + crc_w = bit_reverse_data(crc_w,DBG_CRC_SIZE); + + // Now pack in the 32-bit CRC as we're not + // writing anything else after it + //First 3 bits of each byte go in last 3 bits of buffer[i], + // next 5 go in buffer[i+1] + for(i=0;i<4;i++){ + WriteDataBuffer[i] |= ((crc_w>>(i*8))&0x07)<<5; + WriteDataBuffer[i+1] = ((crc_w>>(i*8))>>3)&0x1f; + } + + // Should have data up to WriteDataBuffer[4] bit 4 + // Read data should start at ReadDataBuffer[4] bit 5 + + //Clear the rest of the write buffer + for(i=5;i<(10+len);i++) + WriteDataBuffer[i]=0; + } + if (!read){ + // If we're writing we put in the 5 command bits, (len+1)*8 data bits, + // and then the 32-bit CRC do first 3 bits, then next 5 bits in + // each of the for loops iterations + for(i=0;i>3)&0x1f); + } + + // Now update the CRC for the data we just wrote + for (i=0;i>j)&1)); + } + + // Reverse crc_w + crc_w = bit_reverse_data(crc_w,DBG_CRC_SIZE); + + // If we have len=4 for example, we will write to + // WriteDataBuffer[4]'s first 5 bits + + // So now load in the 32-bit CRC from there + for(i=0;i<4;i++){ + WriteDataBuffer[len+i] |= ((crc_w>>(i*8))&0x07)<<5; + WriteDataBuffer[len+i+1] = ((crc_w>>(i*8))>>3)&0x1f; + } + // Should have data up to WriteDataBuffer[4+len] bit 4 + // Read data should start at ReadDataBuffer[4+len] bit 5 + + } + + //Status = pFT2232cMpsseJtag->JTAG_WriteReadDataToFromExternalDevice(gFtHandle,false,(5+(len*8)+32+36), &WriteDataBuffer, (6+len+4), &ReadDataBuffer,&dwNumBytesReturned,RUN_TEST_IDLE_STATE); + Status = FT2232_USB_JTAG_WriteReadDataToFromExternalDevice(false,(5+(len*8)+32+36), &WriteDataBuffer, (6+len+4), &ReadDataBuffer,&dwNumBytesReturned,RUN_TEST_IDLE_STATE); + + if (Status != FTC_SUCCESS) + printf("USB write fail - code %ld\n",Status); + + crc_r = 0xffffffff; + + if (read){ + // Look through our data, starting from ReadDataBuffer[4] bit 5 + // We receive len bytes, starting at ReadDataBuffer[4] bit 5, so + // unpack like so + if (DEBUG_USB_DRVR_FUNCS) printf("USB read data buffer: "); + for(i=0;i>5)&0x07; + // then next 5 from next ReadDataBuffer byte + data[i] |= (ReadDataBuffer[4+i+1]&0x1f)<<3; + + // Now calculate the CRC for this byte + for(j=0;j<8;j++) + crc_r = crc_calc(crc_r, (data[i]>>j)&1); + + // Now bit reverse the byte as it was read in MSb first but + // written to LSb first + data[i] = bit_reverse_data(data[i],8); + + if (DEBUG_USB_DRVR_FUNCS) printf("%2x",data[i]); + } + if (DEBUG_USB_DRVR_FUNCS) printf("\n"); + + // Should be up to ReadDataBuffer[4+len] bit 5 for data + status = (ReadDataBuffer[4+len]>>5)&0x07; + status |= (ReadDataBuffer[4+len+1]&1)<<3; + // Now get out crc_read + crc_read = 0; + for(i=0;i<4;i++){ + crc_read |= ((ReadDataBuffer[4+len+1+i]>>1)&0x7f)<<(i*8); + crc_read |= ((ReadDataBuffer[4+len+1+i+1]&0x1)<<7)<<(i*8); + } + + for(i=0;i<4;i++) + crc_r = crc_calc(crc_r, (status>>i)&1); + } + if (!read){ + // Just extract our 4-bits of status and CRC + status = (ReadDataBuffer[4+len]>>5)&0x07; + status |= (ReadDataBuffer[4+len+1]&1)<<3; + + // extract crc_read from the ReadDataBuffer + crc_read = 0; + for(i=0;i<4;i++){ + crc_read |= ((ReadDataBuffer[4+len+1+i]>>1)&0x7f)<<(i*8); + crc_read |= ((ReadDataBuffer[4+len+1+i+1]&1)<<7)<<(i*8); + } + // Calculate our own CRC from the status value + for(i=0;i<4;i++) + crc_r = crc_calc(crc_r, (status>>i)&1); + + } + + crc_generated = crc_r; + // Now bit reverse status and crc_read as we unpacked them + // with the MSb going to the LSb + status = bit_reverse_data(status, DC_STATUS_SIZE); + crc_read = bit_reverse_data(crc_read, DBG_CRC_SIZE); + + + /* CRCs must match, otherwise retry */ + if (crc_read != crc_generated) { + if (DEBUG_CMDS || DEBUG_USB_DRVR_FUNCS)printf("CRC mismatch: %x %x %x\n", status, crc_read, crc_generated); + if (retry_do()) goto try_again; + else return DBG_ERR_CRC; + } + /* we should read expected status value, otherwise retry */ + if (status != 0) { + if (retry_do()) goto try_again; + else return status; + } + + retry_ok(); + return DBG_ERR_OK; +} + +/* read a word from wishbone */ +int usb_dbg_wb_read32(uint32_t adr, uint32_t *data) { + // uint32_t err; + if ((err = usb_dbg_set_chain(DC_WISHBONE))) return err; + if ((err = usb_dbg_command(0x6, adr, 4))) return err; + if ((err = usb_dbg_go((unsigned char*)data, 4, 1))) return err; + *data = ntohl(*data); + return err; +} + +/* write a word to wishbone */ +int usb_dbg_wb_write32(uint32_t adr, uint32_t data) { + // uint32_t err; + data = ntohl(data); + if ((err = usb_dbg_set_chain(DC_WISHBONE))) return err; + if ((err = usb_dbg_command(0x2, adr, 4))) return err; + if ((err = usb_dbg_go((unsigned char*)&data, 4, 0))) return err; + return DBG_ERR_OK; +} + +/* read a block from wishbone */ +int usb_dbg_wb_read_block32(uint32_t adr, uint32_t *data, uint32_t len) { + uint32_t i; // err; + //printf("%08x %08x\n", adr, len); + if ((err = usb_dbg_set_chain(DC_WISHBONE))) return err; + if ((err = usb_dbg_command(0x6, adr, len))) return err; + if ((err = usb_dbg_go((unsigned char*)data, len, 1))) return err; + uint32_t * data_uint32 = (uint32_t *) data; // data[i] gives us a proper 64-bit wide word on a 64-bit arch, so cast back to network sized data when ntohl'ing + for (i = 0; i < len / 4; i ++) data_uint32[i] = ntohl(data_uint32[i]); + //printf("%08x\n", err); + return DBG_ERR_OK; +} + + +/* write a block to wishbone */ +int usb_dbg_wb_write_block32(uint32_t adr, uint32_t *data, uint32_t len) { + uint32_t i; //, err; + uint32_t * data_uint32 = (uint32_t *) data; // data[i] gives us a proper 64-bit wide word on a 64-bit arch, so cast back to network sized data when ntohl'ing + for (i = 0; i < len / 4; i ++) data_uint32[i] = ntohl(data_uint32[i]); + if ((err = usb_dbg_set_chain(DC_WISHBONE))) return err; + if ((err = usb_dbg_command(0x2, adr, len))) return err; + if ((err = usb_dbg_go((unsigned char*)data, len, 0))) return err; + return DBG_ERR_OK; +} + + +/* read a register from cpu */ +int usb_dbg_cpu0_read(uint32_t adr, uint32_t *data) { + // uint32_t err; + if ((err = usb_dbg_set_chain(DC_CPU0))) return err; + if ((err = usb_dbg_command(0x6, adr, 4))) return err; + if ((err = usb_dbg_go((unsigned char*)data, 4, 1))) return err; + *data = ntohl(*data); + return DBG_ERR_OK; +} + +/* write a cpu register */ +int usb_dbg_cpu0_write(uint32_t adr, uint32_t data) { + // uint32_t err; + data = ntohl(data); + if ((err = usb_dbg_set_chain(DC_CPU0))) return err; + if ((err = usb_dbg_command(0x2, adr, 4))) return err; + if ((err = usb_dbg_go((unsigned char*)&data, 4, 0))) return err; + return DBG_ERR_OK; +} + +/* write a cpu module register */ +int usb_dbg_cpu0_write_ctrl(uint32_t adr, unsigned char data) { + // no ensuring that or1k is stalled here, becuase we're call this from that function + if ((err = usb_dbg_set_chain(DC_CPU0))) return err; + if ((err = usb_dbg_ctrl(data & 2, data &1))) return err; + return DBG_ERR_OK; +} + +/* read a register from cpu module */ +int usb_dbg_cpu0_read_ctrl(uint32_t adr, unsigned char *data) { + // no ensuring that or1k is stalled here, becuase we're call this from that function + uint32_t r, s; + if ((err = usb_dbg_set_chain(DC_CPU0))) return err; + if ((err = usb_dbg_ctrl_read(&r, &s))) return err; + *data = (r << 1) | s; + return DBG_ERR_OK; +} + +/* Function to close the device handle. Is called when closing the app */ +void usb_close_device_handle() +{ + FT2232_USB_JTAG_CloseDevice(); +} Index: or_debug_proxy/src/linux_usb_driver_calls.c =================================================================== --- or_debug_proxy/src/linux_usb_driver_calls.c (nonexistent) +++ or_debug_proxy/src/linux_usb_driver_calls.c (revision 1779) @@ -0,0 +1,428 @@ +/*$$HEADER*/ +/******************************************************************************/ +/* */ +/* H E A D E R I N F O R M A T I O N */ +/* */ +/******************************************************************************/ + +// Project Name : OpenRISC Debug Proxy +// File Name : linux_usb_driver_calls.c +// Prepared By : jb +// Project Start : 2008-10-01 + +/*$$COPYRIGHT NOTICE*/ +/******************************************************************************/ +/* */ +/* C O P Y R I G H T N O T I C E */ +/* */ +/******************************************************************************/ +/* + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; + version 2.1 of the License, a copy of which is available from + http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/*$$DESCRIPTION*/ +/******************************************************************************/ +/* */ +/* D E S C R I P T I O N */ +/* */ +/******************************************************************************/ +// +// Some generically named functions for interfacing to the JTAG driver +// functions, making the code calling these platform independant. The correct +// driver calling file (either Cygwin or Linux driver) is included at compile +// time. +// Also included in this file is the USB-JTAG chip initialisation function. +// + + +/*$$CHANGE HISTORY*/ +/******************************************************************************/ +/* */ +/* C H A N G E H I S T O R Y */ +/* */ +/******************************************************************************/ + +// Date Version Description +//------------------------------------------------------------------------ +// 081101 First revision jb + +#include + +#include "WinTypes.h" + +#include "usb_driver_calls.h" + +#include "usb_functions.h" +#include "or_debug_proxy.h" + +#include "FT2232cMpsseJtag.h" + +static FT2232cMpsseJtag *pFT2232cMpsseJtag = NULL; + +// Global USB JTAG device handle +FTC_HANDLE ftHandle; + +// Write data to external device: +//FTC_STATUS FT2232cMpsseJtag::JTAG_WriteDataToExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite, + +FTC_STATUS +FT2232_USB_JTAG_WriteDataToExternalDevice( + //FTC_HANDLE ftHandle, + BOOL bInstructionTestData, + DWORD dwNumBitsToWrite, + PWriteDataByteBuffer pWriteDataBuffer, + DWORD dwNumBytesToWrite, + DWORD dwTapControllerState) +{ + // Call the driver from the libary compiled in Linux + return pFT2232cMpsseJtag->JTAG_WriteDataToExternalDevice( + ftHandle, + bInstructionTestData, + dwNumBitsToWrite, + pWriteDataBuffer, + dwNumBytesToWrite, + dwTapControllerState); +} + + +// Read data from external device +FTC_STATUS +FT2232_USB_JTAG_ReadDataFromExternalDevice( + //FTC_HANDLE ftHandle, + BOOL bInstructionTestData, + DWORD dwNumBitsToRead, + PReadDataByteBuffer pReadDataBuffer, + LPDWORD lpdwNumBytesReturned, + DWORD dwTapControllerState) + +{ + return pFT2232cMpsseJtag->JTAG_ReadDataFromExternalDevice( + ftHandle, + bInstructionTestData, + dwNumBitsToRead, + pReadDataBuffer, + lpdwNumBytesReturned, + dwTapControllerState); + +} + + + + + + +// Write Read +FTC_STATUS +FT2232_USB_JTAG_WriteReadDataToFromExternalDevice( + //FTC_HANDLE ftHandle, + BOOL bInstructionTestData, + DWORD dwNumBitsToWriteRead, + PWriteDataByteBuffer pWriteDataBuffer, + DWORD dwNumBytesToWrite, + PReadDataByteBuffer pReadDataBuffer, + LPDWORD lpdwNumBytesReturned, + DWORD dwTapControllerState) +{ + + return pFT2232cMpsseJtag->JTAG_WriteReadDataToFromExternalDevice( + ftHandle, + bInstructionTestData, + dwNumBitsToWriteRead, + pWriteDataBuffer, + dwNumBytesToWrite, + pReadDataBuffer, + lpdwNumBytesReturned, + dwTapControllerState); + +} + + + +// Close device +FTC_STATUS +FT2232_USB_JTAG_CloseDevice() +{ + return pFT2232cMpsseJtag->JTAG_CloseDevice(ftHandle); +} + + + +// Set clock frequency +// Frequency = 12Mhz/((1+divisor)*2), +// divisor=1000 => Freq=5995Hz~=6kHz, divisor=500=>Freq=12kHz +#define USB_JTAG_CLK_DIVIDER 0 + +int init_usb_jtag() +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumDevices = 0; + //char szDeviceName[100]; + //char szDeviceName[] = "Dual RS232 A"; // Original, unmodified FT2232 device name + // We now open the device by its name + char szDeviceName[] = "ORSoC OpenRISC debug cable A\0"; // ORSoC debug cable UART A name + DWORD dwLocationID = 0; + DWORD dwClockFrequencyHz = 0; + FTC_INPUT_OUTPUT_PINS LowInputOutputPinsData; + FTC_INPUT_OUTPUT_PINS HighInputOutputPinsData; + FTC_LOW_HIGH_PINS LowPinsInputData; + FTC_LOW_HIGH_PINS HighPinsInputData; + + //char szDllVersion[10]; + + // Has been changed to hardcode load device named "ORSoC OpenRISC debug cable A"; - jb 090301 + + /* + //Status = JTAG_GetNumDevices(&dwNumDevices); + Status = pFT2232cMpsseJtag->JTAG_GetNumDevices(&dwNumDevices); + if (DEBUG_USB_DRVR_FUNCS) + { + if (Status == FTC_SUCCESS) + printf("JTAG_GetNumDevices detected %ld available FT2232x device(s) connected to the system.\n", dwNumDevices); + else + { + printf("GetNumDevices failed with status code 0x%lx\n", Status); + exit(-1); + } + } + + if (dwNumDevices == 0) + { + printf("Error: USB Debugger device not detected\n"); + exit(-1); + } + + Status = pFT2232cMpsseJtag->JTAG_GetDllVersion(szDllVersion, 10); + + if (DEBUG_USB_DRVR_FUNCS) + printf("JTAG_GetDLLVersion returned Status: 0x%lx and version %s\n", Status, szDllVersion); + + */ + dwNumDevices = 1; + + if (Status == FTC_SUCCESS) + { + + + if (dwNumDevices == 1) + { + /* + Status = pFT2232cMpsseJtag->JTAG_GetDeviceNameLocationID(0,szDeviceName,50, &dwLocationID); + + if (DEBUG_USB_DRVR_FUNCS) + // In the Windows version it shows Dual RS323 A at: 0x321 + printf("JTAG_GetDeviceNameLocID: %s at: 0x%lx\n", szDeviceName, dwLocationID); + */ + dwLocationID = 0; + + if (Status == FTC_SUCCESS) + { + Status = pFT2232cMpsseJtag->JTAG_OpenSpecifiedDevice(szDeviceName,dwLocationID, &ftHandle); + } + } + else + // When there's more than 1 device, will just open first device. Perhaps implement selection menu for + // users in event that there's more than 1, but for now just hard code this to open the same device + { + //if (dwNumDevices == 2) + //{ + Status=pFT2232cMpsseJtag->JTAG_GetDeviceNameLocationID(1,szDeviceName,50,&dwLocationID); + + if (Status == FTC_SUCCESS) + { + Status = pFT2232cMpsseJtag->JTAG_OpenSpecifiedDevice(szDeviceName, dwLocationID, &ftHandle); + } + //} + } + + // Try initialising and obtaining a handle to a specific device + if (Status == FTC_SUCCESS) + { + printf("Initialising USB JTAG interface\n"); + Status = pFT2232cMpsseJtag->JTAG_InitDevice(ftHandle, 0); + + // Set clock frequency + // Frequency = 12Mhz/((1+divisor)*2), + // divisor=1000 => Freq=5995Hz~=6kHz, divisor=500=>Freq=12kHz + if (DEBUG_USB_DRVR_FUNCS) + printf("Setting JTAG clock frequency. Divisor = %d, TCK ~= %dkHz.\n", USB_JTAG_CLK_DIVIDER, (12000000/((USB_JTAG_CLK_DIVIDER+1)*2))/1000); + if (Status == FTC_SUCCESS) + Status = pFT2232cMpsseJtag->JTAG_SetClock(ftHandle, USB_JTAG_CLK_DIVIDER, &dwClockFrequencyHz); + + if (Status == FTC_SUCCESS){ + + Status = pFT2232cMpsseJtag->JTAG_GetClock(5, &dwClockFrequencyHz); + } + + } + + //if (Status == FTC_SUCCESS) + // Status = JTAG_SetLoopback(ftHandle, true); + if (Status == FTC_SUCCESS) + { + if (DEBUG_USB_DRVR_FUNCS) // Let LED blink + { + // true=output, false=input + LowInputOutputPinsData.bPin1InputOutputState = true; // ADBUS4 + LowInputOutputPinsData.bPin2InputOutputState = true; // ADBUS5 + LowInputOutputPinsData.bPin3InputOutputState = true; // ADBUS6 + LowInputOutputPinsData.bPin4InputOutputState = true; // ADBUS7 + LowInputOutputPinsData.bPin1LowHighState = false; // ADBUS4 + LowInputOutputPinsData.bPin2LowHighState = false; // ADBUS5 + LowInputOutputPinsData.bPin3LowHighState = true; // ADBUS6 + LowInputOutputPinsData.bPin4LowHighState = true; // ADBUS7 + + HighInputOutputPinsData.bPin1InputOutputState = true; // ACBUS0 Output + HighInputOutputPinsData.bPin2InputOutputState = true; // ACBUS1 Output + HighInputOutputPinsData.bPin3InputOutputState = true; // ACBUS2 Output + HighInputOutputPinsData.bPin4InputOutputState = true; // ACBUS3 Output + HighInputOutputPinsData.bPin1LowHighState = true; // ACBUS0 + HighInputOutputPinsData.bPin2LowHighState = true; // ACBUS1 + HighInputOutputPinsData.bPin3LowHighState = true; // ACBUS2 LED RXLEDA A1 OFF + HighInputOutputPinsData.bPin4LowHighState = false; // ACBUS3 LED TXLEDA A2 ON + + Status = pFT2232cMpsseJtag->JTAG_SetGeneralPurposeInputOutputPins(ftHandle, + true, + &LowInputOutputPinsData, + true, + &HighInputOutputPinsData); + + LowInputOutputPinsData.bPin1InputOutputState = true; // ADBUS4 + LowInputOutputPinsData.bPin2InputOutputState = true; // ADBUS5 + LowInputOutputPinsData.bPin3InputOutputState = true; // ADBUS6 + LowInputOutputPinsData.bPin4InputOutputState = true; // ADBUS7 + LowInputOutputPinsData.bPin1LowHighState = false; // ADBUS4 + LowInputOutputPinsData.bPin2LowHighState = false; // ADBUS5 + LowInputOutputPinsData.bPin3LowHighState = true; // ADBUS6 + LowInputOutputPinsData.bPin4LowHighState = true; // ADBUS7 + + HighInputOutputPinsData.bPin1InputOutputState = true; // ACBUS0 + HighInputOutputPinsData.bPin2InputOutputState = true; // ACBUS1 + HighInputOutputPinsData.bPin3InputOutputState = true; // ACBUS2 + HighInputOutputPinsData.bPin4InputOutputState = true; // ACBUS3 + HighInputOutputPinsData.bPin1LowHighState = true; // ACBUS0 + HighInputOutputPinsData.bPin2LowHighState = true; // ACBUS1 + HighInputOutputPinsData.bPin3LowHighState = false; // ACBUS2 LED RXLEDA A1 ON + HighInputOutputPinsData.bPin4LowHighState = true; // ACBUS3 LED TXLEDA A2 OFF + + Status = pFT2232cMpsseJtag->JTAG_SetGeneralPurposeInputOutputPins(ftHandle, + true, + &LowInputOutputPinsData, + true, + &HighInputOutputPinsData); + + LowInputOutputPinsData.bPin1InputOutputState = true; // ADBUS4 - + LowInputOutputPinsData.bPin2InputOutputState = true; // ADBUS5 + LowInputOutputPinsData.bPin3InputOutputState = true; // ADBUS6 + LowInputOutputPinsData.bPin4InputOutputState = true; // ADBUS7 + LowInputOutputPinsData.bPin1LowHighState = false; // ADBUS4 + LowInputOutputPinsData.bPin2LowHighState = false; // ADBUS5 + LowInputOutputPinsData.bPin3LowHighState = true; // ADBUS6 + LowInputOutputPinsData.bPin4LowHighState = true; // ADBUS7 + + HighInputOutputPinsData.bPin1InputOutputState = true; // ACBUS0 + HighInputOutputPinsData.bPin2InputOutputState = true; // ACBUS1 + HighInputOutputPinsData.bPin3InputOutputState = true; // ACBUS2 + HighInputOutputPinsData.bPin4InputOutputState = true; // ACBUS3 + HighInputOutputPinsData.bPin1LowHighState = true; // ACBUS0 + HighInputOutputPinsData.bPin2LowHighState = true; // ACBUS1 + HighInputOutputPinsData.bPin3LowHighState = true; // ACBUS2 LED RXLEDA A1 OFF + HighInputOutputPinsData.bPin4LowHighState = true; // ACBUS3 LED TXLEDA A2 OFF + + Status = pFT2232cMpsseJtag->JTAG_SetGeneralPurposeInputOutputPins(ftHandle, + true, + &LowInputOutputPinsData, + true, + &HighInputOutputPinsData); + + LowInputOutputPinsData.bPin1InputOutputState = true; // ADBUS4 - + LowInputOutputPinsData.bPin2InputOutputState = true; // ADBUS5 + LowInputOutputPinsData.bPin3InputOutputState = true; // ADBUS6 + LowInputOutputPinsData.bPin4InputOutputState = true; // ADBUS7 + LowInputOutputPinsData.bPin1LowHighState = false; // ADBUS4 + LowInputOutputPinsData.bPin2LowHighState = false; // ADBUS5 + LowInputOutputPinsData.bPin3LowHighState = true; // ADBUS6 + LowInputOutputPinsData.bPin4LowHighState = true; // ADBUS7 + + HighInputOutputPinsData.bPin1InputOutputState = true; // ACBUS0 + HighInputOutputPinsData.bPin2InputOutputState = true; // ACBUS1 + HighInputOutputPinsData.bPin3InputOutputState = true; // ACBUS2 + HighInputOutputPinsData.bPin4InputOutputState = true; // ACBUS3 + HighInputOutputPinsData.bPin1LowHighState = true; // ACBUS0 + HighInputOutputPinsData.bPin2LowHighState = true; // ACBUS1 + HighInputOutputPinsData.bPin3LowHighState = false; // ACBUS2 LED RXLEDA A1 ON + HighInputOutputPinsData.bPin4LowHighState = false; // ACBUS3 LED TXLEDA A2 ON + + Status = pFT2232cMpsseJtag->JTAG_SetGeneralPurposeInputOutputPins(ftHandle, + true, + &LowInputOutputPinsData, + true, + &HighInputOutputPinsData); + } + + // Setup GPIO pins for JTAG + LowInputOutputPinsData.bPin1InputOutputState = true; // ADBUS4 - + // set ADBUS4 to output 0 to enable JTAG buffers on Olimex devices + LowInputOutputPinsData.bPin2InputOutputState = true; //ADBUS5 + LowInputOutputPinsData.bPin3InputOutputState = true; + LowInputOutputPinsData.bPin4InputOutputState = true; + //ADBUS4 = 0 (enable JTAG buffers on Olimex devices) + LowInputOutputPinsData.bPin1LowHighState = false; // ADBUS4 + LowInputOutputPinsData.bPin2LowHighState = false; // ADBUS5 + LowInputOutputPinsData.bPin3LowHighState = true; // ADBUS6 + LowInputOutputPinsData.bPin4LowHighState = true; // ADBUS7 + + HighInputOutputPinsData.bPin1InputOutputState = true; // ACBUS0 + HighInputOutputPinsData.bPin2InputOutputState = true; // ACBUS1 + HighInputOutputPinsData.bPin3InputOutputState = true; // ACBUS2 + HighInputOutputPinsData.bPin4InputOutputState = true; // ACBUS3 + HighInputOutputPinsData.bPin1LowHighState = true; // ACBUS0 + HighInputOutputPinsData.bPin2LowHighState = true; // ACBUS1 + HighInputOutputPinsData.bPin3LowHighState = false; // ACBUS2 LED RXLEDA A1 ON + HighInputOutputPinsData.bPin4LowHighState = true; // ACBUS3 + + Status = pFT2232cMpsseJtag->JTAG_SetGeneralPurposeInputOutputPins(ftHandle, + true, + &LowInputOutputPinsData, + true, + &HighInputOutputPinsData); + + if (Status == FTC_SUCCESS) + Status = pFT2232cMpsseJtag->JTAG_GetGeneralPurposeInputOutputPins(ftHandle, true, &LowPinsInputData, + true, &HighPinsInputData); + + if (DEBUG_USB_DRVR_FUNCS) + printf("JTAG low gpio pins values: (ADBUS7-ADBUS4):%x%x%x%x\n", + (LowPinsInputData.bPin4LowHighState==true), + (LowPinsInputData.bPin3LowHighState==true), + (LowPinsInputData.bPin2LowHighState==true), + (LowPinsInputData.bPin1LowHighState==true)); + + if (DEBUG_USB_DRVR_FUNCS) + printf("JTAG high gpio pins values: (ACBUS3-ACBUS0): %x%x%x%x\n", + (HighPinsInputData.bPin4LowHighState==true), + (HighPinsInputData.bPin3LowHighState==true), + (HighPinsInputData.bPin2LowHighState==true), + (HighPinsInputData.bPin1LowHighState==true)); + } + } + + + if (Status == FTC_SUCCESS) + return 0; + else + return 1; + +} Index: or_debug_proxy/src/FT2232cMpsseJtag.cpp =================================================================== --- or_debug_proxy/src/FT2232cMpsseJtag.cpp (nonexistent) +++ or_debug_proxy/src/FT2232cMpsseJtag.cpp (revision 1779) @@ -0,0 +1,2017 @@ +/*++ + +FTC MPSSE Interface DLLs - Copyright © FTDI Ltd. 2009 + + +The source code to the FTCI2C, FTCJTAG and FTCSPI DLLs is provided as-is and no warranty is made as to its function or reliability. + +This source code may be freely modified and redistributed, provided that the FTDI Ltd. copyright notice remains intact. + +Copyright (c) 2005 Future Technology Devices International Ltd. + +Module Name: + + FT2232cMpsseJtag.cpp + +Abstract: + + FT2232C Dual Device Device Class Implementation. + +Environment: + + kernel & user mode + +Revision History: + + 07/02/05 kra Created. + 24/08/05 kra Added new function JTAG_GenerateClockPulses and new error code FTC_INVALID_NUMBER_CLOCK_PULSES + +--*/ + +#define WIO_DEFINED + +#include +#include +//#include // -- Possibly not needed, trying without -jb +#include +#include +#include +#include +#include +#include +#include + +// included for sched_yield() calls, +// used in place of Windows' Sleep(0) calls, +// however may not be good idea, not sure it's +// exactly the same thing!! -- Julius +#include + + +#include "FT2232cMpsseJtag.h" + + +FTC_STATUS FT2232cMpsseJtag::CheckWriteDataToExternalDeviceBitsBytesParameters(DWORD dwNumBitsToWrite, DWORD dwNumBytesToWrite) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumBytesForNumBits = 0; + + if (((dwNumBitsToWrite >= MIN_NUM_BITS) && (dwNumBitsToWrite <= MAX_NUM_BITS)) && + ((dwNumBytesToWrite >= MIN_NUM_BYTES) && (dwNumBytesToWrite <= MAX_NUM_BYTES))) + { + dwNumBytesForNumBits = (dwNumBitsToWrite / NUMBITSINBYTE); + + if ((dwNumBitsToWrite % NUMBITSINBYTE) > 0) + dwNumBytesForNumBits = dwNumBytesForNumBits + 1; + + if (dwNumBytesForNumBits > dwNumBytesToWrite) + Status = FTC_NUMBER_BYTES_TOO_SMALL; + } + else + { + if ((dwNumBitsToWrite < MIN_NUM_BITS) || (dwNumBitsToWrite > MAX_NUM_BITS)) + Status = FTC_INVALID_NUMBER_BITS; + else + Status = FTC_INVALID_NUMBER_BYTES; + } + + return Status; +} + +void FT2232cMpsseJtag::AddByteToOutputBuffer(DWORD dwOutputByte, BOOL bClearOutputBuffer) +{ + DWORD dwNumBytesToSend_temp = 0; + + if (iCommandsSequenceDataDeviceIndex == -1) + FTC_AddByteToOutputBuffer(dwOutputByte, bClearOutputBuffer); + else + { + // This is used when you are building up a sequence of commands ie write, read and write/read + dwNumBytesToSend_temp = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumBytesToSend; + + (*OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].pCommandsSequenceDataOutPutBuffer)[dwNumBytesToSend_temp] = (dwOutputByte & '\xFF'); + + dwNumBytesToSend_temp = dwNumBytesToSend_temp + 1; + + OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumBytesToSend = dwNumBytesToSend_temp; + } +} + +FTC_STATUS FT2232cMpsseJtag::SetDataInOutClockFrequency(FTC_HANDLE ftHandle, DWORD dwClockDivisor) +{ + FTC_STATUS Status = FTC_SUCCESS; + + AddByteToOutputBuffer(SET_CLOCK_FREQUENCY_CMD, true); + AddByteToOutputBuffer(dwClockDivisor, false); + AddByteToOutputBuffer((dwClockDivisor >> 8), false); + + Status = FTC_SendBytesToDevice(ftHandle); + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::InitDataInOutClockFrequency(FTC_HANDLE ftHandle, DWORD dwClockDivisor) +{ + FTC_STATUS Status = FTC_SUCCESS; + + // set general purpose I/O low pins 1-4 all to input except TDO + AddByteToOutputBuffer(SET_LOW_BYTE_DATA_BITS_CMD, true); + + dwSavedLowPinsValue = (dwSavedLowPinsValue & '\xF0'); + dwSavedLowPinsValue = (dwSavedLowPinsValue | '\x08'); // TDI,TCK start low + AddByteToOutputBuffer(dwSavedLowPinsValue, false); + + dwSavedLowPinsDirection = (dwSavedLowPinsDirection & '\xF0'); + dwSavedLowPinsDirection = (dwSavedLowPinsDirection | '\x0B'); + AddByteToOutputBuffer(dwSavedLowPinsDirection, false); + + // set general purpose I/O high pins 1-4 all to input + AddByteToOutputBuffer(SET_HIGH_BYTE_DATA_BITS_CMD, false); + AddByteToOutputBuffer(0, false); + AddByteToOutputBuffer(0, false); + + Status = FTC_SendBytesToDevice(ftHandle); + + if (Status == FTC_SUCCESS) + SetDataInOutClockFrequency(ftHandle, dwClockDivisor); + + return Status; +} + +// This procedure sets the JTAG to a new state +void FT2232cMpsseJtag::SetJTAGToNewState(DWORD dwNewJtagState, DWORD dwNumTmsClocks, BOOL bDoReadOperation) +{ + if ((dwNumTmsClocks >= 1) && (dwNumTmsClocks <= 7)) + { + if (bDoReadOperation == TRUE) + AddByteToOutputBuffer(CLK_DATA_TMS_READ_CMD, false); + else + AddByteToOutputBuffer(CLK_DATA_TMS_NO_READ_CMD, false); + + AddByteToOutputBuffer(((dwNumTmsClocks - 1) & '\xFF'), false); + AddByteToOutputBuffer((dwNewJtagState & '\xFF'), false); + } +} + +// This function returns the number of TMS clocks to work out the last bit of TDO +DWORD FT2232cMpsseJtag::MoveJTAGFromOneStateToAnother(JtagStates NewJtagState, DWORD dwLastDataBit, BOOL bDoReadOperation) +{ + DWORD dwNumTmsClocks = 0; + + if (CurrentJtagState == Undefined) + { + SetJTAGToNewState('\x7F', 7, false); + CurrentJtagState = TestLogicReset; + } + + switch (CurrentJtagState) + { + case TestLogicReset: + dwNumTmsClocks = TestLogicResetToNewJTAGStateNumTMSClocks[NewJtagState]; + SetJTAGToNewState((TestLogicResetToNewJTAGState[NewJtagState] | (dwLastDataBit << 7)), dwNumTmsClocks, bDoReadOperation); + break; + case RunTestIdle: + dwNumTmsClocks = RunTestIdleToNewJTAGStateNumTMSClocks[NewJtagState]; + SetJTAGToNewState((RunTestIdleToNewJTAGState[NewJtagState] | (dwLastDataBit << 7)), dwNumTmsClocks, bDoReadOperation); + break; + case PauseDataRegister: + dwNumTmsClocks = PauseDataRegToNewJTAGStateNumTMSClocks[NewJtagState]; + SetJTAGToNewState((PauseDataRegToNewJTAGState[NewJtagState] | (dwLastDataBit << 7)), dwNumTmsClocks, bDoReadOperation); + break; + case PauseInstructionRegister: + dwNumTmsClocks = PauseInstructionRegToNewJTAGStateNumTMSClocks[NewJtagState]; + SetJTAGToNewState((PauseInstructionRegToNewJTAGState[NewJtagState] | (dwLastDataBit << 7)), dwNumTmsClocks, bDoReadOperation); + break; + case ShiftDataRegister: + dwNumTmsClocks = ShiftDataRegToNewJTAGStateNumTMSClocks[NewJtagState]; + SetJTAGToNewState((ShiftDataRegToNewJTAGState[NewJtagState] | (dwLastDataBit << 7)), dwNumTmsClocks, bDoReadOperation); + break; + case ShiftInstructionRegister: + dwNumTmsClocks = ShiftInstructionRegToNewJTAGStateNumTMSClocks[NewJtagState]; + SetJTAGToNewState((ShiftInstructionRegToNewJTAGState[NewJtagState] | (dwLastDataBit << 7)), dwNumTmsClocks, bDoReadOperation); + break; + default : + // Added default state -- Julius + dwNumTmsClocks = TestLogicResetToNewJTAGStateNumTMSClocks[NewJtagState]; + SetJTAGToNewState((TestLogicResetToNewJTAGState[NewJtagState] | (dwLastDataBit << 7)), dwNumTmsClocks, bDoReadOperation); + break; + } + + CurrentJtagState = NewJtagState; + + return dwNumTmsClocks; +} + +FTC_STATUS FT2232cMpsseJtag::ResetTAPContollerExternalDeviceSetToTestIdleMode(FTC_HANDLE ftHandle) +{ + FTC_STATUS Status = FTC_SUCCESS; + + // set I/O low bits all out except TDO + AddByteToOutputBuffer(SET_LOW_BYTE_DATA_BITS_CMD, true); + + dwSavedLowPinsValue = (dwSavedLowPinsValue & '\xFF'); + // TDI,TCK start low + dwSavedLowPinsValue = (dwSavedLowPinsValue | '\x08'); + AddByteToOutputBuffer(dwSavedLowPinsValue, false); + + dwSavedLowPinsDirection = (dwSavedLowPinsDirection & '\xFF'); + dwSavedLowPinsDirection = (dwSavedLowPinsDirection | '\x0B'); + AddByteToOutputBuffer(dwSavedLowPinsDirection, false); + + //MoveJTAGFromOneStateToAnother(TestLogicReset, 1, false);JtagStates + MoveJTAGFromOneStateToAnother(Undefined, 1, false); + + MoveJTAGFromOneStateToAnother(RunTestIdle, NO_LAST_DATA_BIT, FALSE); + + Status = FTC_SendBytesToDevice(ftHandle); + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::SetGeneralPurposeInputOutputPins(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins, + DWORD dwLowPinsDirection, DWORD dwLowPinsValue, + BOOL bControlHighInputOutputPins, + DWORD dwHighPinsDirection, DWORD dwHighPinsValue) +{ + FTC_STATUS Status = FTC_SUCCESS; + + if (bControlLowInputOutputPins != false) + { + // output on the general purpose I/O low pins 1-4 + AddByteToOutputBuffer(SET_LOW_BYTE_DATA_BITS_CMD, true); + + // shift left by 4 bits ie move general purpose I/O low pins 1-4 from bits 0-3 to bits 4-7 + dwLowPinsValue = ((dwLowPinsValue & '\x0F') << 4); + + dwSavedLowPinsValue = (dwSavedLowPinsValue & '\x0F'); + dwSavedLowPinsValue = (dwSavedLowPinsValue | dwLowPinsValue); + AddByteToOutputBuffer(dwSavedLowPinsValue, false); + + // shift left by 4 bits ie move general purpose I/O low pins 1-4 from bits 0-3 to bits 4-7 + dwLowPinsDirection = ((dwLowPinsDirection & '\x0F') << 4); + + dwSavedLowPinsDirection = (dwSavedLowPinsDirection & '\x0F'); + dwSavedLowPinsDirection = (dwSavedLowPinsDirection | dwLowPinsDirection); + AddByteToOutputBuffer(dwSavedLowPinsDirection, false); + + Status = FTC_SendBytesToDevice(ftHandle); + } + + if (Status == FTC_SUCCESS) + { + if (bControlHighInputOutputPins != false) + { + // output on the general purpose I/O high pins 1-4 + AddByteToOutputBuffer(SET_HIGH_BYTE_DATA_BITS_CMD, true); + + dwHighPinsValue = (dwHighPinsValue & '\x0F'); + AddByteToOutputBuffer(dwHighPinsValue, false); + + dwHighPinsDirection = (dwHighPinsDirection & '\x0F'); + AddByteToOutputBuffer(dwHighPinsDirection, false); + + Status = FTC_SendBytesToDevice(ftHandle); + } + } + + return Status; +} + +void FT2232cMpsseJtag::GetGeneralPurposeInputOutputPinsInputStates(DWORD dwInputStatesReturnedValue, PFTC_LOW_HIGH_PINS pPinsInputData) +{ + if ((dwInputStatesReturnedValue & PIN1_HIGH_VALUE) == PIN1_HIGH_VALUE) + pPinsInputData->bPin1LowHighState = TRUE; + + if ((dwInputStatesReturnedValue & PIN2_HIGH_VALUE) == PIN2_HIGH_VALUE) + pPinsInputData->bPin2LowHighState = TRUE; + + if ((dwInputStatesReturnedValue & PIN3_HIGH_VALUE) == PIN3_HIGH_VALUE) + pPinsInputData->bPin3LowHighState = TRUE; + + if ((dwInputStatesReturnedValue & PIN4_HIGH_VALUE) == PIN4_HIGH_VALUE) + pPinsInputData->bPin4LowHighState = TRUE; +} + +FTC_STATUS FT2232cMpsseJtag::GetGeneralPurposeInputOutputPins(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins, + PFTC_LOW_HIGH_PINS pLowPinsInputData, + BOOL bControlHighInputOutputPins, + PFTC_LOW_HIGH_PINS pHighPinsInputData) +{ + FTC_STATUS Status = FTC_SUCCESS; + InputByteBuffer InputBuffer; + DWORD dwNumBytesRead = 0; + DWORD dwNumBytesDeviceInputBuffer; + + pLowPinsInputData->bPin1LowHighState = false; + pLowPinsInputData->bPin2LowHighState = false; + pLowPinsInputData->bPin3LowHighState = false; + pLowPinsInputData->bPin4LowHighState = false; + pHighPinsInputData->bPin1LowHighState = false; + pHighPinsInputData->bPin2LowHighState = false; + pHighPinsInputData->bPin3LowHighState = false; + pHighPinsInputData->bPin4LowHighState = false; + + // Put in this small delay incase the application programmer does a get GPIOs immediately after a set GPIOs + //Sleep(5); + // Removed Sleep() call and replaced with linux sleep to give up + // timeslice - sched_yield() -- not sure is best idea! -- Julius + sched_yield(); + + if (bControlLowInputOutputPins != false) + { + // Get the number of bytes in the device input buffer + Status = FT_GetQueueStatus((FT_HANDLE)ftHandle, &dwNumBytesDeviceInputBuffer); + + if (Status == FTC_SUCCESS) + { + if (dwNumBytesDeviceInputBuffer > 0) + Status = FTC_ReadBytesFromDevice(ftHandle, &InputBuffer, dwNumBytesDeviceInputBuffer, &dwNumBytesRead); + + if (Status == FTC_SUCCESS) + { + // get the states of the general purpose I/O low pins 1-4 + AddByteToOutputBuffer(GET_LOW_BYTE_DATA_BITS_CMD, true); + AddByteToOutputBuffer(SEND_ANSWER_BACK_IMMEDIATELY_CMD, false); + Status = FTC_SendBytesToDevice(ftHandle); + + if (Status == FTC_SUCCESS) + { + Status = FTC_GetNumberBytesFromDeviceInputBuffer(ftHandle, &dwNumBytesDeviceInputBuffer); + + if (Status == FTC_SUCCESS) + { + Status = FTC_ReadBytesFromDevice(ftHandle, &InputBuffer, dwNumBytesDeviceInputBuffer, &dwNumBytesRead); + + if (Status == FTC_SUCCESS) + // shift right by 4 bits ie move general purpose I/O low pins 1-4 from bits 4-7 to bits 0-3 + GetGeneralPurposeInputOutputPinsInputStates((InputBuffer[0] >> 4), pLowPinsInputData); + } + } + } + } + } + + if (bControlHighInputOutputPins != false) + { + // Get the number of bytes in the device input buffer + Status = FT_GetQueueStatus((FT_HANDLE)ftHandle, &dwNumBytesDeviceInputBuffer); + + if (Status == FTC_SUCCESS) + { + if (dwNumBytesDeviceInputBuffer > 0) + Status = FTC_ReadBytesFromDevice(ftHandle, &InputBuffer, dwNumBytesDeviceInputBuffer, &dwNumBytesRead); + + if (Status == FTC_SUCCESS) + { + // get the states of the general purpose I/O high pins 1-4 + AddByteToOutputBuffer(GET_HIGH_BYTE_DATA_BITS_CMD, true); + AddByteToOutputBuffer(SEND_ANSWER_BACK_IMMEDIATELY_CMD, false); + Status = FTC_SendBytesToDevice(ftHandle); + + if (Status == FTC_SUCCESS) + { + Status = FTC_GetNumberBytesFromDeviceInputBuffer(ftHandle, &dwNumBytesDeviceInputBuffer); + + if (Status == FTC_SUCCESS) + { + Status = FTC_ReadBytesFromDevice(ftHandle, &InputBuffer, dwNumBytesDeviceInputBuffer, &dwNumBytesRead); + + if (Status == FTC_SUCCESS) + GetGeneralPurposeInputOutputPinsInputStates(InputBuffer[0], pHighPinsInputData); + } + } + } + } + } + + return Status; +} + +void FT2232cMpsseJtag::AddWriteCommandDataToOutPutBuffer(BOOL bInstructionTestData, DWORD dwNumBitsToWrite, + PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, + DWORD dwTapControllerState) +{ + DWORD dwModNumBitsToWrite = 0; + DWORD dwDataBufferIndex = 0; + DWORD dwNumDataBytes = 0; + DWORD dwNumRemainingDataBits = 0; + DWORD dwLastDataBit = 0; + DWORD dwDataBitIndex = 0; + + // adjust for bit count of 1 less than no of bits + dwModNumBitsToWrite = (dwNumBitsToWrite - 1); + + if (bInstructionTestData == false) + MoveJTAGFromOneStateToAnother(ShiftDataRegister, NO_LAST_DATA_BIT, false); + else + MoveJTAGFromOneStateToAnother(ShiftInstructionRegister, NO_LAST_DATA_BIT, false); + + dwNumDataBytes = (dwModNumBitsToWrite / 8); + + if (dwNumDataBytes > 0) + { + // Number of whole bytes + dwNumDataBytes = (dwNumDataBytes - 1); + + // clk data bytes out on -ve clk LSB + AddByteToOutputBuffer(CLK_DATA_BYTES_OUT_ON_NEG_CLK_LSB_FIRST_CMD, false); + AddByteToOutputBuffer((dwNumDataBytes & '\xFF'), false); + AddByteToOutputBuffer(((dwNumDataBytes / 256) & '\xFF'), false); + + // now add the data bytes to go out + do + { + AddByteToOutputBuffer((*pWriteDataBuffer)[dwDataBufferIndex], false); + dwDataBufferIndex = (dwDataBufferIndex + 1); + } + while (dwDataBufferIndex < (dwNumDataBytes + 1)); + } + + dwNumRemainingDataBits = (dwModNumBitsToWrite % 8); + + if (dwNumRemainingDataBits > 0) + { + dwNumRemainingDataBits = (dwNumRemainingDataBits - 1); + + //clk data bits out on -ve clk LSB + AddByteToOutputBuffer(CLK_DATA_BITS_OUT_ON_NEG_CLK_LSB_FIRST_CMD, false); + AddByteToOutputBuffer((dwNumRemainingDataBits & '\xFF'), false); + AddByteToOutputBuffer((*pWriteDataBuffer)[dwDataBufferIndex], false); + } + + // get last bit + dwLastDataBit = (*pWriteDataBuffer)[dwDataBufferIndex]; + dwDataBitIndex = (dwNumBitsToWrite % 8); + + if (dwDataBitIndex == 0) + dwLastDataBit = (dwLastDataBit >> ((8 - dwDataBitIndex) - 1)); + else + dwLastDataBit = (dwLastDataBit >> (dwDataBitIndex - 1)); + + // end it in state passed in, take 1 off the dwTapControllerState variable to correspond with JtagStates enumerated types + MoveJTAGFromOneStateToAnother(JtagStates((dwTapControllerState - 1)), dwLastDataBit, false); +} + +FTC_STATUS FT2232cMpsseJtag::WriteDataToExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite, + PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, + DWORD dwTapControllerState) +{ + FTC_STATUS Status = FTC_SUCCESS; + + FTC_ClearOutputBuffer(); + + AddWriteCommandDataToOutPutBuffer(bInstructionTestData, dwNumBitsToWrite, pWriteDataBuffer, + dwNumBytesToWrite, dwTapControllerState); + + Status = FTC_SendBytesToDevice(ftHandle); + + return Status; +} + +void FT2232cMpsseJtag::GetNumDataBytesToRead(DWORD dwNumBitsToRead, LPDWORD lpdwNumDataBytesToRead, LPDWORD lpdwNumRemainingDataBits) +{ + DWORD dwModNumBitsToRead = 0; + DWORD dwNumDataBytesToRead = 0; + DWORD dwNumRemainingDataBits = 0; + + // adjust for bit count of 1 less than no of bits + dwModNumBitsToRead = (dwNumBitsToRead - 1); + + // Number of whole bytes to read + dwNumDataBytesToRead = (dwModNumBitsToRead / 8); + + // number of remaining bits + dwNumRemainingDataBits = (dwModNumBitsToRead % 8); + + // increase the number of whole bytes if bits left over + if (dwNumRemainingDataBits > 0) + dwNumDataBytesToRead = (dwNumDataBytesToRead + 1); + + // adjust for SHR of incoming byte + dwNumRemainingDataBits = (8 - dwNumRemainingDataBits); + + // add 1 for TMS read byte + dwNumDataBytesToRead = (dwNumDataBytesToRead + 1); + + *lpdwNumDataBytesToRead = dwNumDataBytesToRead; + *lpdwNumRemainingDataBits = dwNumRemainingDataBits; +} + +// This will work out the number of whole bytes to read and adjust for the TMS read +FTC_STATUS FT2232cMpsseJtag::GetDataFromExternalDevice(FTC_HANDLE ftHandle, DWORD dwNumBitsToRead, DWORD dwNumTmsClocks, + PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumReadDataBytes = 0; + DWORD dwNumRemainingDataBits = 0; + DWORD dwNumDataBytesRead = 0; + // DWORD dwNumBytesDeviceInputBuffer = 0; + InputByteBuffer InputBuffer; + DWORD dwBytesReadIndex = 0; + BYTE LastDataBit = 0; + + GetNumDataBytesToRead(dwNumBitsToRead, &dwNumReadDataBytes, &dwNumRemainingDataBits); + + Status = FTC_ReadFixedNumBytesFromDevice(ftHandle, &InputBuffer, dwNumReadDataBytes, &dwNumDataBytesRead); + + if (Status == FTC_SUCCESS) + { + // adjust last 2 bytes + if (dwNumRemainingDataBits < 8) + { + InputBuffer[dwNumReadDataBytes - 2] = (InputBuffer[dwNumReadDataBytes - 2] >> dwNumRemainingDataBits); + LastDataBit = (InputBuffer[dwNumReadDataBytes - 1] << (dwNumTmsClocks - 1)); + LastDataBit = (LastDataBit & '\x80'); // strip the rest + InputBuffer[dwNumReadDataBytes - 2] = (InputBuffer[dwNumReadDataBytes - 2] | (LastDataBit >> (dwNumRemainingDataBits - 1))); + + dwNumReadDataBytes = (dwNumReadDataBytes - 1); + + for (dwBytesReadIndex = 0 ; dwBytesReadIndex < dwNumReadDataBytes; dwBytesReadIndex++) + (*pReadDataBuffer)[dwBytesReadIndex] = InputBuffer[dwBytesReadIndex]; + } + else // case for 0 bit shift in data + TMS read bit + { + LastDataBit = (InputBuffer[dwNumReadDataBytes - 1] << (dwNumTmsClocks - 1)); + LastDataBit = (LastDataBit >> 7); // strip the rest + InputBuffer[dwNumReadDataBytes - 1] = LastDataBit; + + for (dwBytesReadIndex = 0 ; dwBytesReadIndex < dwNumReadDataBytes; dwBytesReadIndex++) + (*pReadDataBuffer)[dwBytesReadIndex] = InputBuffer[dwBytesReadIndex]; + } + + *lpdwNumBytesReturned = dwNumReadDataBytes; + } + + return Status; +} + +DWORD FT2232cMpsseJtag::AddReadCommandToOutputBuffer(BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState) +{ + DWORD dwModNumBitsToRead = 0; + DWORD dwNumDataBytes = 0; + DWORD dwNumRemainingDataBits = 0; + DWORD dwNumTmsClocks = 0; + + // adjust for bit count of 1 less than no of bits + dwModNumBitsToRead = (dwNumBitsToRead - 1); + + if (bInstructionTestData == false) + MoveJTAGFromOneStateToAnother(ShiftDataRegister, NO_LAST_DATA_BIT, false); + else + MoveJTAGFromOneStateToAnother(ShiftInstructionRegister, NO_LAST_DATA_BIT, false); + + dwNumDataBytes = (dwModNumBitsToRead / 8); + + if (dwNumDataBytes > 0) + { + // Number of whole bytes + dwNumDataBytes = (dwNumDataBytes - 1); + + // clk data bytes out on -ve clk LSB + AddByteToOutputBuffer(CLK_DATA_BYTES_IN_ON_POS_CLK_LSB_FIRST_CMD, false); + AddByteToOutputBuffer((dwNumDataBytes & '\xFF'), false); + AddByteToOutputBuffer(((dwNumDataBytes / 256) & '\xFF'), false); + } + + // number of remaining bits + dwNumRemainingDataBits = (dwModNumBitsToRead % 8); + + if (dwNumRemainingDataBits > 0) + { + dwNumRemainingDataBits = (dwNumRemainingDataBits - 1); + + //clk data bits out on -ve clk LSB + AddByteToOutputBuffer(CLK_DATA_BITS_IN_ON_POS_CLK_LSB_FIRST_CMD, false); + AddByteToOutputBuffer((dwNumRemainingDataBits & '\xFF'), false); + } + + // end it in state passed in, take 1 off the dwTapControllerState variable to correspond with JtagStates enumerated types + dwNumTmsClocks = MoveJTAGFromOneStateToAnother(JtagStates((dwTapControllerState - 1)), NO_LAST_DATA_BIT, true); + + return dwNumTmsClocks; +} + +FTC_STATUS FT2232cMpsseJtag::ReadDataFromExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, + PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned, + DWORD dwTapControllerState) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumTmsClocks = 0; + + FTC_ClearOutputBuffer(); + + dwNumTmsClocks = AddReadCommandToOutputBuffer(bInstructionTestData, dwNumBitsToRead, dwTapControllerState); + + AddByteToOutputBuffer(SEND_ANSWER_BACK_IMMEDIATELY_CMD, false); + + Status = FTC_SendBytesToDevice(ftHandle); + + if (Status == FTC_SUCCESS) + Status = GetDataFromExternalDevice(ftHandle, dwNumBitsToRead, dwNumTmsClocks, pReadDataBuffer, lpdwNumBytesReturned); + + return Status; +} + +DWORD FT2232cMpsseJtag::AddWriteReadCommandDataToOutPutBuffer(BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, + PWriteDataByteBuffer pWriteDataBuffer, + DWORD dwNumBytesToWrite, DWORD dwTapControllerState) +{ + DWORD dwModNumBitsToWriteRead = 0; + DWORD dwNumWriteDataBytes = 0; + DWORD dwDataBufferIndex = 0; + DWORD dwNumRemainingDataBits = 0; + DWORD dwLastDataBit = 0; + DWORD dwDataBitIndex = 0; + DWORD dwNumTmsClocks = 0; + + // adjust for bit count of 1 less than no of bits + dwModNumBitsToWriteRead = (dwNumBitsToWriteRead - 1); + + if (bInstructionTestData == false) + MoveJTAGFromOneStateToAnother(ShiftDataRegister, NO_LAST_DATA_BIT, false); + else + MoveJTAGFromOneStateToAnother(ShiftInstructionRegister, NO_LAST_DATA_BIT, false); + + dwNumWriteDataBytes = (dwModNumBitsToWriteRead / 8); + + if (dwNumWriteDataBytes > 0) + { + // Number of whole bytes + dwNumWriteDataBytes = (dwNumWriteDataBytes - 1); + + // clk data bytes out on -ve in +ve clk LSB + AddByteToOutputBuffer(CLK_DATA_BYTES_OUT_ON_NEG_CLK_IN_ON_POS_CLK_LSB_FIRST_CMD, false); + AddByteToOutputBuffer((dwNumWriteDataBytes & '\xFF'), false); + AddByteToOutputBuffer(((dwNumWriteDataBytes / 256) & '\xFF'), false); + + // now add the data bytes to go out + do + { + AddByteToOutputBuffer((*pWriteDataBuffer)[dwDataBufferIndex], false); + dwDataBufferIndex = (dwDataBufferIndex + 1); + } + while (dwDataBufferIndex < (dwNumWriteDataBytes + 1)); + } + + dwNumRemainingDataBits = (dwModNumBitsToWriteRead % 8); + + if (dwNumRemainingDataBits > 0) + { + dwNumRemainingDataBits = (dwNumRemainingDataBits - 1); + + // clk data bits out on -ve in +ve clk LSB + AddByteToOutputBuffer(CLK_DATA_BITS_OUT_ON_NEG_CLK_IN_ON_POS_CLK_LSB_FIRST_CMD, false); + AddByteToOutputBuffer((dwNumRemainingDataBits & '\xFF'), false); + AddByteToOutputBuffer((*pWriteDataBuffer)[dwDataBufferIndex], false); + } + + // get last bit + dwLastDataBit = (*pWriteDataBuffer)[dwDataBufferIndex]; + dwDataBitIndex = (dwNumBitsToWriteRead % 8); + + if (dwDataBitIndex == 8) + dwLastDataBit = (dwLastDataBit >> ((8 - dwDataBitIndex) - 1)); + else + dwLastDataBit = (dwLastDataBit >> (dwDataBitIndex - 1)); + + // end it in state passed in, take 1 off the dwTapControllerState variable to correspond with JtagStates enumerated types + dwNumTmsClocks = MoveJTAGFromOneStateToAnother(JtagStates((dwTapControllerState - 1)), dwLastDataBit, true); + + return dwNumTmsClocks; +} + +FTC_STATUS FT2232cMpsseJtag::WriteReadDataToFromExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, + PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, + PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned, + DWORD dwTapControllerState) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumRemainingDataBits = 0; + BYTE LastDataBit = 0; + DWORD dwNumTmsClocks = 0; + DWORD dwNumReadDataBytes = 0; + InputByteBuffer InputBuffer; + DWORD dwNumDataBytesRead = 0; + DWORD dwBytesReadIndex = 0; + + FTC_ClearOutputBuffer(); + + dwNumTmsClocks = AddWriteReadCommandDataToOutPutBuffer(bInstructionTestData, dwNumBitsToWriteRead, + pWriteDataBuffer, dwNumBytesToWrite, dwTapControllerState); + + AddByteToOutputBuffer(SEND_ANSWER_BACK_IMMEDIATELY_CMD, false); + + GetNumDataBytesToRead(dwNumBitsToWriteRead, &dwNumReadDataBytes, &dwNumRemainingDataBits); + + Status = FTC_SendReadBytesToFromDevice(ftHandle, &InputBuffer, dwNumReadDataBytes, &dwNumDataBytesRead); + + if (Status == FTC_SUCCESS) + { + // adjust last 2 bytes + if (dwNumRemainingDataBits < 8) + { + InputBuffer[dwNumReadDataBytes - 2] = (InputBuffer[dwNumReadDataBytes - 2] >> dwNumRemainingDataBits); + LastDataBit = (InputBuffer[dwNumReadDataBytes - 1] << (dwNumTmsClocks - 1)); + LastDataBit = (LastDataBit & '\x80'); // strip the rest + InputBuffer[dwNumReadDataBytes - 2] = (InputBuffer[dwNumReadDataBytes - 2] | (LastDataBit >> (dwNumRemainingDataBits - 1))); + + dwNumReadDataBytes = (dwNumReadDataBytes - 1); + + for (dwBytesReadIndex = 0 ; dwBytesReadIndex < dwNumReadDataBytes; dwBytesReadIndex++) + (*pReadDataBuffer)[dwBytesReadIndex] = InputBuffer[dwBytesReadIndex]; + } + else // case for 0 bit shift in data + TMS read bit + { + LastDataBit = (InputBuffer[dwNumReadDataBytes - 1] << (dwNumTmsClocks - 1)); + LastDataBit = (LastDataBit >> 7); // strip the rest + InputBuffer[dwNumReadDataBytes - 1] = LastDataBit; + + for (dwBytesReadIndex = 0 ; dwBytesReadIndex < dwNumReadDataBytes; dwBytesReadIndex++) + (*pReadDataBuffer)[dwBytesReadIndex] = InputBuffer[dwBytesReadIndex]; + } + + *lpdwNumBytesReturned = dwNumReadDataBytes; + } + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::GenerateTCKClockPulses(FTC_HANDLE ftHandle, DWORD dwNumClockPulses) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwTotalNumClockPulsesBytes = 0; + DWORD dwNumClockPulsesByteBlocks = 0; + DWORD dwNumClockPulsesByteBlockCntr = 0; + DWORD dwNumClockPulsesBytes = 0; + DWORD dwNumRemainingClockPulsesBits = 0; + // DWORD dwDataBufferIndex = 0; + + MoveJTAGFromOneStateToAnother(RunTestIdle, NO_LAST_DATA_BIT, FALSE); + + dwTotalNumClockPulsesBytes = (dwNumClockPulses / NUMBITSINBYTE); + + if (dwTotalNumClockPulsesBytes > 0) + { + dwNumClockPulsesByteBlocks = (dwTotalNumClockPulsesBytes / NUM_BYTE_CLOCK_PULSES_BLOCK_SIZE); + + do + { + if (dwNumClockPulsesByteBlockCntr < dwNumClockPulsesByteBlocks) + dwNumClockPulsesBytes = NUM_BYTE_CLOCK_PULSES_BLOCK_SIZE; + else + dwNumClockPulsesBytes = (dwTotalNumClockPulsesBytes - (dwNumClockPulsesByteBlockCntr * NUM_BYTE_CLOCK_PULSES_BLOCK_SIZE)); + + if (dwNumClockPulsesBytes > 0) + { + // Number of whole bytes + dwNumClockPulsesBytes = (dwNumClockPulsesBytes - 1); + + // clk data bytes out on -ve clk LSB + AddByteToOutputBuffer(CLK_DATA_BYTES_OUT_ON_NEG_CLK_LSB_FIRST_CMD, false); + AddByteToOutputBuffer((dwNumClockPulsesBytes & '\xFF'), false); + AddByteToOutputBuffer(((dwNumClockPulsesBytes / 256) & '\xFF'), false); + + DWORD dwDataBufferIndex = 0; + + // now add the data bytes ie 0 to go out with the clock pulses + do + { + AddByteToOutputBuffer(0, false); + dwDataBufferIndex = (dwDataBufferIndex + 1); + } + while (dwDataBufferIndex < (dwNumClockPulsesBytes + 1)); + } + + Status = FTC_SendBytesToDevice(ftHandle); + + dwNumClockPulsesByteBlockCntr = (dwNumClockPulsesByteBlockCntr + 1); + } + while ((dwNumClockPulsesByteBlockCntr <= dwNumClockPulsesByteBlocks) && (Status == FTC_SUCCESS)); + } + + if (Status == FTC_SUCCESS) + { + dwNumRemainingClockPulsesBits = (dwNumClockPulses % NUMBITSINBYTE); + + if (dwNumRemainingClockPulsesBits > 0) + { + dwNumRemainingClockPulsesBits = (dwNumRemainingClockPulsesBits - 1); + + //clk data bits out on -ve clk LSB + AddByteToOutputBuffer(CLK_DATA_BITS_OUT_ON_NEG_CLK_LSB_FIRST_CMD, false); + AddByteToOutputBuffer((dwNumRemainingClockPulsesBits & '\xFF'), false); + AddByteToOutputBuffer('\xFF', false); + + Status = FTC_SendBytesToDevice(ftHandle); + } + } + + //MoveJTAGFromOneStateToAnother(RunTestIdle, NO_LAST_DATA_BIT, FALSE); + + //Status = FTC_SendBytesToDevice(ftHandle); + + return Status; +} + +void FT2232cMpsseJtag::ProcessReadCommandsSequenceBytes(PInputByteBuffer pInputBuffer, DWORD dwNumBytesRead, PReadCmdSequenceDataByteBuffer pReadCmdSequenceDataBuffer, + LPDWORD lpdwNumBytesReturned) +{ + DWORD CommandSequenceIndex = 0; + PReadCommandsSequenceData pReadCommandsSequenceDataBuffer; + DWORD dwNumReadCommandSequences; + PReadCommandSequenceData pReadCmdSequenceData; + DWORD dwNumBitsToRead = 0; + DWORD dwNumTmsClocks = 0; + DWORD dwNumReadDataBytes = 0; + DWORD dwNumRemainingDataBits = 0; + BYTE LastDataBit = 0; + DWORD dwBytesReadIndex = 0; + DWORD dwNumReadBytesProcessed = 0; + DWORD dwTotalNumBytesRead = 0; + DWORD dwNumBytesReturned = 0; + + if (iCommandsSequenceDataDeviceIndex != -1) + { + pReadCommandsSequenceDataBuffer = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].pReadCommandsSequenceDataBuffer; + dwNumReadCommandSequences = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumReadCommandSequences; + + for (CommandSequenceIndex = 0; (CommandSequenceIndex < dwNumReadCommandSequences); CommandSequenceIndex++) + { + pReadCmdSequenceData = (*pReadCommandsSequenceDataBuffer)[CommandSequenceIndex]; + dwNumBitsToRead = (*pReadCmdSequenceData)[0]; + dwNumTmsClocks = (*pReadCmdSequenceData)[1]; + + GetNumDataBytesToRead(dwNumBitsToRead, &dwNumReadDataBytes, &dwNumRemainingDataBits); + + dwNumReadBytesProcessed = (dwNumReadBytesProcessed + dwNumReadDataBytes); + + // adjust last 2 bytes + if (dwNumRemainingDataBits < 8) + { + (*pInputBuffer)[dwNumReadBytesProcessed - 2] = ((*pInputBuffer)[dwNumReadBytesProcessed - 2] >> dwNumRemainingDataBits); + LastDataBit = ((*pInputBuffer)[dwNumReadBytesProcessed - 1] << (dwNumTmsClocks - 1)); + LastDataBit = (LastDataBit & '\x80'); // strip the rest + (*pInputBuffer)[dwNumReadBytesProcessed - 2] = ((*pInputBuffer)[dwNumReadBytesProcessed - 2] | (LastDataBit >> (dwNumRemainingDataBits - 1))); + + dwNumReadDataBytes = (dwNumReadDataBytes - 1); + + for (dwBytesReadIndex = 0; dwBytesReadIndex < dwNumReadDataBytes; dwBytesReadIndex++) + (*pReadCmdSequenceDataBuffer)[(dwBytesReadIndex + dwNumBytesReturned)] = (*pInputBuffer)[(dwBytesReadIndex + dwTotalNumBytesRead)]; + } + else // case for 0 bit shift in data + TMS read bit + { + LastDataBit = ((*pInputBuffer)[dwNumReadBytesProcessed - 1] << (dwNumTmsClocks - 1)); + LastDataBit = (LastDataBit >> 7); // strip the rest + (*pInputBuffer)[dwNumReadBytesProcessed - 1] = LastDataBit; + + for (dwBytesReadIndex = 0; dwBytesReadIndex < dwNumReadDataBytes; dwBytesReadIndex++) + (*pReadCmdSequenceDataBuffer)[(dwBytesReadIndex + dwNumBytesReturned)] = (*pInputBuffer)[(dwBytesReadIndex + dwTotalNumBytesRead)]; + } + + dwTotalNumBytesRead = dwNumReadBytesProcessed; + + dwNumBytesReturned = (dwNumBytesReturned + dwNumReadDataBytes); + } + } + + *lpdwNumBytesReturned = dwNumBytesReturned; +} + +DWORD FT2232cMpsseJtag::GetTotalNumCommandsSequenceDataBytesToRead(void) +{ + DWORD dwTotalNumBytesToBeRead = 0; + DWORD CommandSequenceIndex = 0; + PReadCommandsSequenceData pReadCommandsSequenceDataBuffer; + DWORD dwNumReadCommandSequences = 0; + PReadCommandSequenceData pReadCmdSequenceData; + DWORD dwNumBitsToRead = 0; + DWORD dwNumDataBytesToRead = 0; + DWORD dwNumRemainingDataBits = 0; + + if (iCommandsSequenceDataDeviceIndex != -1) + { + pReadCommandsSequenceDataBuffer = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].pReadCommandsSequenceDataBuffer; + dwNumReadCommandSequences = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumReadCommandSequences; + + for (CommandSequenceIndex = 0; (CommandSequenceIndex < dwNumReadCommandSequences); CommandSequenceIndex++) + { + pReadCmdSequenceData = (*pReadCommandsSequenceDataBuffer)[CommandSequenceIndex]; + dwNumBitsToRead = (*pReadCmdSequenceData)[0]; + + GetNumDataBytesToRead(dwNumBitsToRead, &dwNumDataBytesToRead, &dwNumRemainingDataBits); + + dwTotalNumBytesToBeRead = (dwTotalNumBytesToBeRead + dwNumDataBytesToRead); + } + } + + return dwTotalNumBytesToBeRead; +} + +void FT2232cMpsseJtag::CopyReadCommandsSequenceDataBuffer(PReadCommandsSequenceData pDestinationBuffer, PReadCommandsSequenceData pSourceBuffer, DWORD dwSizeReadCommandsSequenceDataBuffer) +{ + DWORD CommandSequenceIndex = 0; + PReadCommandSequenceData pReadCmdSequenceData; + DWORD dwNumBitsToRead = 0; + DWORD dwNumTmsClocks = 0; + + for (CommandSequenceIndex = 0; (CommandSequenceIndex < dwSizeReadCommandsSequenceDataBuffer); CommandSequenceIndex++) + { + pReadCmdSequenceData = (*pSourceBuffer)[CommandSequenceIndex]; + dwNumBitsToRead = (*pReadCmdSequenceData)[0]; + dwNumTmsClocks = (*pReadCmdSequenceData)[1]; + + pReadCmdSequenceData = (*pDestinationBuffer)[CommandSequenceIndex]; + (*pReadCmdSequenceData)[0] = dwNumBitsToRead; + (*pReadCmdSequenceData)[1] = dwNumTmsClocks; + } +} + +FTC_STATUS FT2232cMpsseJtag::AddReadCommandSequenceData(DWORD dwNumBitsToRead, DWORD dwNumTmsClocks) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwSizeReadCommandsSequenceDataBuffer; + PReadCommandsSequenceData pReadCommandsSequenceDataBuffer; + DWORD dwNumReadCommandSequences; + PReadCommandsSequenceData pTmpReadCmdsSequenceDataBuffer; + PReadCommandSequenceData pReadCmdSequenceData; + + if (iCommandsSequenceDataDeviceIndex != -1) + { + dwSizeReadCommandsSequenceDataBuffer = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwSizeReadCommandsSequenceDataBuffer; + pReadCommandsSequenceDataBuffer = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].pReadCommandsSequenceDataBuffer; + dwNumReadCommandSequences = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumReadCommandSequences; + + if (dwNumReadCommandSequences > (dwSizeReadCommandsSequenceDataBuffer - 1)) + { + pTmpReadCmdsSequenceDataBuffer = CreateReadCommandsSequenceDataBuffer(dwSizeReadCommandsSequenceDataBuffer); + + if (pTmpReadCmdsSequenceDataBuffer != NULL) + { + // Temporary save the contents of the read commands sequence data buffer + CopyReadCommandsSequenceDataBuffer(pTmpReadCmdsSequenceDataBuffer, pReadCommandsSequenceDataBuffer, dwSizeReadCommandsSequenceDataBuffer); + + DeleteReadCommandsSequenceDataBuffer(pReadCommandsSequenceDataBuffer, dwSizeReadCommandsSequenceDataBuffer); + + // Increase the size of the read commands sequence data buffer + pReadCommandsSequenceDataBuffer = CreateReadCommandsSequenceDataBuffer((dwSizeReadCommandsSequenceDataBuffer + COMMAND_SEQUENCE_READ_DATA_BUFFER_SIZE_INCREMENT)); + + if (pReadCommandsSequenceDataBuffer != NULL) + { + CopyReadCommandsSequenceDataBuffer(pReadCommandsSequenceDataBuffer, pTmpReadCmdsSequenceDataBuffer, dwSizeReadCommandsSequenceDataBuffer); + + DeleteReadCommandsSequenceDataBuffer(pTmpReadCmdsSequenceDataBuffer, dwSizeReadCommandsSequenceDataBuffer); + + dwSizeReadCommandsSequenceDataBuffer = (dwSizeReadCommandsSequenceDataBuffer + COMMAND_SEQUENCE_READ_DATA_BUFFER_SIZE_INCREMENT); + + OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwSizeReadCommandsSequenceDataBuffer = dwSizeReadCommandsSequenceDataBuffer; + OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].pReadCommandsSequenceDataBuffer = pReadCommandsSequenceDataBuffer; + } + else + Status = FTC_INSUFFICIENT_RESOURCES; + } + else + Status = FTC_INSUFFICIENT_RESOURCES; + } + + if (Status == FTC_SUCCESS) + { + if (dwNumReadCommandSequences > 0) + pReadCmdSequenceData = (*pReadCommandsSequenceDataBuffer)[(dwNumReadCommandSequences - 1)]; + + pReadCmdSequenceData = (*pReadCommandsSequenceDataBuffer)[dwNumReadCommandSequences]; + + (*pReadCmdSequenceData)[0] = dwNumBitsToRead; + (*pReadCmdSequenceData)[1] = dwNumTmsClocks; + + dwNumReadCommandSequences = (dwNumReadCommandSequences + 1); + + OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumReadCommandSequences = dwNumReadCommandSequences; + } + } + + return Status; +} + +PReadCommandsSequenceData FT2232cMpsseJtag::CreateReadCommandsSequenceDataBuffer(DWORD dwSizeReadCmdsSequenceDataBuffer) +{ + PReadCommandsSequenceData pReadCmdsSequenceDataBuffer; + DWORD CommandSequenceIndex = 0; + PReadCommandSequenceData pReadCmdSequenceData; + + pReadCmdsSequenceDataBuffer = PReadCommandsSequenceData(new ReadCommandsSequenceData[dwSizeReadCmdsSequenceDataBuffer]); + + if (pReadCmdsSequenceDataBuffer != NULL) + { + for (CommandSequenceIndex = 0; (CommandSequenceIndex < dwSizeReadCmdsSequenceDataBuffer); CommandSequenceIndex++) + { + pReadCmdSequenceData = PReadCommandSequenceData(new ReadCommandSequenceData); + + (*pReadCmdsSequenceDataBuffer)[CommandSequenceIndex] = pReadCmdSequenceData; + } + } + + return pReadCmdsSequenceDataBuffer; +} + +void FT2232cMpsseJtag::DeleteReadCommandsSequenceDataBuffer(PReadCommandsSequenceData pReadCmdsSequenceDataBuffer, DWORD dwSizeReadCommandsSequenceDataBuffer) +{ + DWORD CommandSequenceIndex = 0; + PReadCommandSequenceData pReadCmdSequenceData; + + for (CommandSequenceIndex = 0; (CommandSequenceIndex < dwSizeReadCommandsSequenceDataBuffer); CommandSequenceIndex++) + { + pReadCmdSequenceData = (*pReadCmdsSequenceDataBuffer)[CommandSequenceIndex]; + + delete [] pReadCmdSequenceData; + } + + delete [] pReadCmdsSequenceDataBuffer; +} + +FTC_STATUS FT2232cMpsseJtag::CreateDeviceCommandsSequenceDataBuffers(FTC_HANDLE ftHandle) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwDeviceIndex = 0; + BOOLEAN bDeviceDataBuffersCreated = false; + + for (dwDeviceIndex = 0; ((dwDeviceIndex < MAX_NUM_DEVICES) && !bDeviceDataBuffersCreated); dwDeviceIndex++) + { + if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice == 0) + { + bDeviceDataBuffersCreated = true; + + OpenedDevicesCommandsSequenceData[dwDeviceIndex].pCommandsSequenceDataOutPutBuffer = POutputByteBuffer(new OutputByteBuffer); + + if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].pCommandsSequenceDataOutPutBuffer != NULL) + { + OpenedDevicesCommandsSequenceData[dwDeviceIndex].pReadCommandsSequenceDataBuffer = CreateReadCommandsSequenceDataBuffer(INIT_COMMAND_SEQUENCE_READ_DATA_BUFFER_SIZE); + + if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].pReadCommandsSequenceDataBuffer != NULL) + { + OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice = ftHandle; + OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwNumBytesToSend = 0; + OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwSizeReadCommandsSequenceDataBuffer = INIT_COMMAND_SEQUENCE_READ_DATA_BUFFER_SIZE; + OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwNumReadCommandSequences = 0; + } + else + { + delete [] OpenedDevicesCommandsSequenceData[dwDeviceIndex].pCommandsSequenceDataOutPutBuffer; + + Status = FTC_INSUFFICIENT_RESOURCES; + } + } + else + Status = FTC_INSUFFICIENT_RESOURCES; + } + } + + if ((Status == FTC_SUCCESS) && (bDeviceDataBuffersCreated == true)) + dwNumOpenedDevices = dwNumOpenedDevices + 1; + + return Status; +} + +void FT2232cMpsseJtag::ClearDeviceCommandSequenceData(FTC_HANDLE ftHandle) +{ + DWORD dwDeviceIndex = 0; + BOOLEAN bDeviceHandleFound = false; + + if (ftHandle != 0) + { + for (dwDeviceIndex = 0; ((dwDeviceIndex < MAX_NUM_DEVICES) && !bDeviceHandleFound); dwDeviceIndex++) + { + if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice == ftHandle) + { + bDeviceHandleFound = true; + + OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwNumBytesToSend = 0; + OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwNumReadCommandSequences = 0; + } + } + } + else + { + // This code is executed if there is only one device connected to the system, this code is here just in case + // that a device was unplugged from the system, while the system was still running + for (dwDeviceIndex = 0; ((dwDeviceIndex < MAX_NUM_DEVICES) && !bDeviceHandleFound); dwDeviceIndex++) + { + if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice != 0) + { + bDeviceHandleFound = true; + + OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwNumBytesToSend = 0; + OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwNumReadCommandSequences = 0; + } + } + } +} + +DWORD FT2232cMpsseJtag::GetNumBytesInCommandsSequenceDataBuffer(void) +{ + DWORD dwNumBytesToSend_temp = 0; + + if (iCommandsSequenceDataDeviceIndex != -1) + // Get the number commands to be executed in sequence ie write, read and write/read + dwNumBytesToSend_temp = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumBytesToSend; + + return dwNumBytesToSend_temp; +} + +DWORD FT2232cMpsseJtag::GetCommandsSequenceDataDeviceIndex(FTC_HANDLE ftHandle) +{ + DWORD dwDeviceIndex = 0; + BOOLEAN bDeviceHandleFound = false; + INT iCmdsSequenceDataDeviceIndex = 0; + + if (ftHandle != 0) + { + for (dwDeviceIndex = 0; ((dwDeviceIndex < MAX_NUM_DEVICES) && !bDeviceHandleFound); dwDeviceIndex++) + { + if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice == ftHandle) + { + bDeviceHandleFound = true; + + iCmdsSequenceDataDeviceIndex = dwDeviceIndex; + } + } + } + else + { + // This code is executed if there is only one device connected to the system, this code is here just in case + // that a device was unplugged from the system, while the system was still running + for (dwDeviceIndex = 0; ((dwDeviceIndex < MAX_NUM_DEVICES) && !bDeviceHandleFound); dwDeviceIndex++) + { + if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice != 0) + { + bDeviceHandleFound = true; + + iCmdsSequenceDataDeviceIndex = dwDeviceIndex; + } + } + } + + return iCmdsSequenceDataDeviceIndex; +} + +void FT2232cMpsseJtag::DeleteDeviceCommandsSequenceDataBuffers(FTC_HANDLE ftHandle) +{ + DWORD dwDeviceIndex = 0; + BOOLEAN bDeviceHandleFound = false; + POutputByteBuffer pCmdsSequenceDataOutPutBuffer; + + for (dwDeviceIndex = 0; ((dwDeviceIndex < MAX_NUM_DEVICES) && !bDeviceHandleFound); dwDeviceIndex++) + { + if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice == ftHandle) + { + bDeviceHandleFound = true; + + OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice = 0; + OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwNumBytesToSend = 0; + pCmdsSequenceDataOutPutBuffer = OpenedDevicesCommandsSequenceData[dwDeviceIndex].pCommandsSequenceDataOutPutBuffer; + delete [] pCmdsSequenceDataOutPutBuffer; + OpenedDevicesCommandsSequenceData[dwDeviceIndex].pCommandsSequenceDataOutPutBuffer = NULL; + DeleteReadCommandsSequenceDataBuffer(OpenedDevicesCommandsSequenceData[dwDeviceIndex].pReadCommandsSequenceDataBuffer, + OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwSizeReadCommandsSequenceDataBuffer); + OpenedDevicesCommandsSequenceData[dwDeviceIndex].pReadCommandsSequenceDataBuffer = NULL; + } + } + + if ((dwNumOpenedDevices > 0) && bDeviceHandleFound) + dwNumOpenedDevices = dwNumOpenedDevices - 1; +} + +FTC_STATUS FT2232cMpsseJtag::AddDeviceWriteCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite, + PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, + DWORD dwTapControllerState) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumCommandDataBytes = 0; + + if (pWriteDataBuffer != NULL) + { + Status = CheckWriteDataToExternalDeviceBitsBytesParameters(dwNumBitsToWrite, dwNumBytesToWrite); + + if (Status == FTC_SUCCESS) + { + if ((dwTapControllerState >= TEST_LOGIC_STATE) && (dwTapControllerState <= SHIFT_INSTRUCTION_REGISTER_STATE)) + { + dwNumCommandDataBytes = (NUM_WRITE_COMMAND_BYTES + dwNumBytesToWrite); + + iCommandsSequenceDataDeviceIndex = GetCommandsSequenceDataDeviceIndex(ftHandle); + + if ((GetNumBytesInCommandsSequenceDataBuffer() + dwNumCommandDataBytes) < OUTPUT_BUFFER_SIZE) + AddWriteCommandDataToOutPutBuffer(bInstructionTestData, dwNumBitsToWrite, pWriteDataBuffer, + dwNumBytesToWrite, dwTapControllerState); + else + Status = FTC_COMMAND_SEQUENCE_BUFFER_FULL; + + // Reset to indicate that you are not building up a sequence of commands + iCommandsSequenceDataDeviceIndex = -1; + } + else + Status = FTC_INVALID_TAP_CONTROLLER_STATE; + } + } + else + Status = FTC_NULL_WRITE_DATA_BUFFER_POINTER; + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::AddDeviceReadCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumTmsClocks = 0; + + if ((dwNumBitsToRead >= MIN_NUM_BITS) && (dwNumBitsToRead <= MAX_NUM_BITS)) + { + if ((dwTapControllerState >= TEST_LOGIC_STATE) && (dwTapControllerState <= SHIFT_INSTRUCTION_REGISTER_STATE)) + { + iCommandsSequenceDataDeviceIndex = GetCommandsSequenceDataDeviceIndex(ftHandle); + + if ((GetNumBytesInCommandsSequenceDataBuffer() + NUM_READ_COMMAND_BYTES) < OUTPUT_BUFFER_SIZE) + { + dwNumTmsClocks = AddReadCommandToOutputBuffer(bInstructionTestData, dwNumBitsToRead, dwTapControllerState); + + Status = AddReadCommandSequenceData(dwNumBitsToRead, dwNumTmsClocks); + } + else + Status = FTC_COMMAND_SEQUENCE_BUFFER_FULL; + + // Reset to indicate that you are not building up a sequence of commands + iCommandsSequenceDataDeviceIndex = -1; + } + else + Status = FTC_INVALID_TAP_CONTROLLER_STATE; + } + else + Status = FTC_INVALID_NUMBER_BITS; + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::AddDeviceWriteReadCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, + PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, + DWORD dwTapControllerState) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumCommandDataBytes = 0; + DWORD dwNumTmsClocks = 0; + + if (pWriteDataBuffer != NULL) + { + Status = CheckWriteDataToExternalDeviceBitsBytesParameters(dwNumBitsToWriteRead, dwNumBytesToWrite); + + if (Status == FTC_SUCCESS) + { + if ((dwTapControllerState >= TEST_LOGIC_STATE) && (dwTapControllerState <= SHIFT_INSTRUCTION_REGISTER_STATE)) + { + dwNumCommandDataBytes = (NUM_WRITE_READ_COMMAND_BYTES + dwNumBytesToWrite); + + iCommandsSequenceDataDeviceIndex = GetCommandsSequenceDataDeviceIndex(ftHandle); + + if ((GetNumBytesInCommandsSequenceDataBuffer() + dwNumCommandDataBytes) < OUTPUT_BUFFER_SIZE) + { + dwNumTmsClocks = AddWriteReadCommandDataToOutPutBuffer(bInstructionTestData, dwNumBitsToWriteRead, pWriteDataBuffer, + dwNumBytesToWrite, dwTapControllerState); + + Status = AddReadCommandSequenceData(dwNumBitsToWriteRead, dwNumTmsClocks); + } + else + Status = FTC_COMMAND_SEQUENCE_BUFFER_FULL; + + // Reset to indicate that you are not building up a sequence of commands + iCommandsSequenceDataDeviceIndex = -1; + } + else + Status = FTC_INVALID_TAP_CONTROLLER_STATE; + } + } + else + Status = FTC_NULL_WRITE_DATA_BUFFER_POINTER; + + return Status; +} + +FT2232cMpsseJtag::FT2232cMpsseJtag(void) +{ + DWORD dwDeviceIndex = 0; + + CurrentJtagState = Undefined; + + dwSavedLowPinsDirection = 0; + dwSavedLowPinsValue = 0; + + dwNumOpenedDevices = 0; + + for (dwDeviceIndex = 0; (dwDeviceIndex < MAX_NUM_DEVICES); dwDeviceIndex++) + OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice = 0; + + iCommandsSequenceDataDeviceIndex = -1; +} + +FT2232cMpsseJtag::~FT2232cMpsseJtag(void) +{ + DWORD dwDeviceIndex = 0; + POutputByteBuffer pCmdsSequenceDataOutPutBuffer; + + if (dwNumOpenedDevices > 0) + { + for (dwDeviceIndex = 0; (dwDeviceIndex < MAX_NUM_DEVICES); dwDeviceIndex++) + { + if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice != 0) + { + OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice = 0; + + pCmdsSequenceDataOutPutBuffer = OpenedDevicesCommandsSequenceData[dwDeviceIndex].pCommandsSequenceDataOutPutBuffer; + + if (pCmdsSequenceDataOutPutBuffer != NULL) + delete [] pCmdsSequenceDataOutPutBuffer; + + OpenedDevicesCommandsSequenceData[dwDeviceIndex].pCommandsSequenceDataOutPutBuffer = NULL; + + if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].pReadCommandsSequenceDataBuffer != NULL) + DeleteReadCommandsSequenceDataBuffer(OpenedDevicesCommandsSequenceData[dwDeviceIndex].pReadCommandsSequenceDataBuffer, + OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwSizeReadCommandsSequenceDataBuffer); + + OpenedDevicesCommandsSequenceData[dwDeviceIndex].pReadCommandsSequenceDataBuffer = NULL; + } + } + } +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_GetNumDevices(LPDWORD lpdwNumDevices) +{ + FTC_STATUS Status = FTC_SUCCESS; + FT2232CDeviceIndexes FT2232CIndexes; + + *lpdwNumDevices = 0; + + Status = FTC_GetNumDevices(lpdwNumDevices, &FT2232CIndexes); + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_GetDeviceNameLocationID(DWORD dwDeviceNameIndex, LPSTR lpDeviceNameBuffer, DWORD dwBufferSize, LPDWORD lpdwLocationID) +//FTC_STATUS FT2232cMpsseJtag::JTAG_GetDeviceNameLocID(DWORD dwDeviceNameIndex, LPSTR lpDeviceNameBuffer, DWORD dwBufferSize, LPDWORD lpdwLocationID) +{ + return FTC_GetDeviceNameLocationID(dwDeviceNameIndex, lpDeviceNameBuffer, dwBufferSize, lpdwLocationID); +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_OpenSpecifiedDevice(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle) +//FTC_STATUS FT2232cMpsseJtag::JTAG_OpenEx(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle) +{ + FTC_STATUS Status = FTC_SUCCESS; + + Status = FTC_OpenSpecifiedDevice(lpDeviceName, dwLocationID, pftHandle); + + if (Status == FTC_SUCCESS) + { + Status = CreateDeviceCommandsSequenceDataBuffers(*pftHandle); + + if (Status != FTC_SUCCESS) + { + FTC_CloseDevice(*pftHandle); + + *pftHandle = 0; + } + } + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_OpenDevice(FTC_HANDLE *pftHandle) +//FTC_STATUS FT2232cMpsseJtag::JTAG_Open(FTC_HANDLE *pftHandle) +{ + FTC_STATUS Status = FTC_SUCCESS; + + Status = FTC_OpenDevice(pftHandle); + + if (Status == FTC_SUCCESS) + { + Status = CreateDeviceCommandsSequenceDataBuffers(*pftHandle); + + if (Status != FTC_SUCCESS) + { + // FTC_CloseDevice(*pftHandle); + FTC_CloseDevice(*pftHandle); + + *pftHandle = 0; + } + } + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_CloseDevice(FTC_HANDLE ftHandle) +{ + FTC_STATUS Status = FTC_SUCCESS; + + Status = FTC_CloseDevice(ftHandle); + + DeleteDeviceCommandsSequenceDataBuffers(ftHandle); + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_InitDevice(FTC_HANDLE ftHandle, DWORD dwClockDivisor) +{ + FTC_STATUS Status = FTC_SUCCESS; + + Status = FTC_IsDeviceHandleValid(ftHandle); + + if (Status == FTC_SUCCESS) + { + if ((dwClockDivisor >= MIN_CLOCK_DIVISOR) && (dwClockDivisor <= MAX_CLOCK_DIVISOR)) + { + Status = FTC_ResetUSBDevicePurgeUSBInputBuffer(ftHandle); + + if (Status == FTC_SUCCESS) + Status = FTC_SetDeviceUSBBufferSizes(ftHandle, USB_INPUT_BUFFER_SIZE, USB_OUTPUT_BUFFER_SIZE); + + if (Status == FTC_SUCCESS) + Status = FTC_SetDeviceSpecialCharacters(ftHandle, false, FT_EVENT_VALUE, false, FT_ERROR_VALUE); + + if (Status == FTC_SUCCESS) + Status = FTC_SetReadWriteDeviceTimeouts(ftHandle, DEVICE_READ_TIMEOUT_INFINITE, DEVICE_WRITE_TIMEOUT); + + if (Status == FTC_SUCCESS) + Status = FTC_SetDeviceLatencyTimer(ftHandle, DEVICE_LATENCY_TIMER_VALUE); + + if (Status == FTC_SUCCESS) + Status = FTC_ResetMPSSEInterface(ftHandle); + + if (Status == FTC_SUCCESS) + Status = FTC_EnableMPSSEInterface(ftHandle); + + if (Status == FTC_SUCCESS) + Status = FTC_SynchronizeMPSSEInterface(ftHandle); + + if (Status == FTC_SUCCESS) + Status = FTC_ResetUSBDevicePurgeUSBInputBuffer(ftHandle); + + if (Status == FTC_SUCCESS) + //Sleep(20); // wait for all the USB stuff to complete + // Removed Sleep() call and replaced with linux sleep to give up + // timeslice - sched_yield() -- not sure is best idea! -- Julius + sched_yield(); + + if (Status == FTC_SUCCESS) + Status = InitDataInOutClockFrequency(ftHandle, dwClockDivisor); + + if (Status == FTC_SUCCESS) + // Status = FTC_SetDeviceLoopbackState(ftHandle, false); + Status = FTC_SetDeviceLoopbackState(ftHandle, false); + + if (Status == FTC_SUCCESS) + //Sleep(20); // wait for all the USB stuff to complete + // Removed Sleep() call and replaced with linux sleep to give up + // timeslice - sched_yield() -- not sure is best idea! -- Julius + sched_yield(); + + if (Status == FTC_SUCCESS) + Status = FTC_ResetUSBDevicePurgeUSBInputBuffer(ftHandle); + + if (Status == FTC_SUCCESS) + //Sleep(20); // wait for all the USB stuff to complete + // Removed Sleep() call and replaced with linux sleep to give up + // timeslice - sched_yield() -- not sure is best idea! -- Julius + sched_yield(); + + if (Status == FTC_SUCCESS) + Status = ResetTAPContollerExternalDeviceSetToTestIdleMode(ftHandle); + } + else + Status = FTC_INVALID_CLOCK_DIVISOR; + } + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_GetClock(DWORD dwClockDivisor, LPDWORD lpdwClockFrequencyHz) +{ + FTC_STATUS Status = FTC_SUCCESS; + + if ((dwClockDivisor >= MIN_CLOCK_DIVISOR) && (dwClockDivisor <= MAX_CLOCK_DIVISOR)) + FTC_GetClockFrequencyValues(dwClockDivisor, lpdwClockFrequencyHz); + else + Status = FTC_INVALID_CLOCK_DIVISOR; + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_SetClock(FTC_HANDLE ftHandle, DWORD dwClockDivisor, LPDWORD lpdwClockFrequencyHz) +{ + FTC_STATUS Status = FTC_SUCCESS; + + Status = FTC_IsDeviceHandleValid(ftHandle); + + if (Status == FTC_SUCCESS) + { + if ((dwClockDivisor >= MIN_CLOCK_DIVISOR) && (dwClockDivisor <= MAX_CLOCK_DIVISOR)) + { + Status = SetDataInOutClockFrequency(ftHandle, dwClockDivisor); + + if (Status == FTC_SUCCESS) + FTC_GetClockFrequencyValues(dwClockDivisor, lpdwClockFrequencyHz); + } + else + Status = FTC_INVALID_CLOCK_DIVISOR; + } + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_SetDeviceLoopbackState(FTC_HANDLE ftHandle, BOOL bLoopbackState) +//FTC_STATUS FT2232cMpsseJtag::JTAG_SetLoopback(FTC_HANDLE ftHandle, BOOL bLoopbackState) +{ + return FTC_SetDeviceLoopbackState(ftHandle, bLoopbackState); +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_SetGeneralPurposeInputOutputPins(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins, +//FTC_STATUS FT2232cMpsseJtag::JTAG_SetGPIOs(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins, + PFTC_INPUT_OUTPUT_PINS pLowInputOutputPinsData, + BOOL bControlHighInputOutputPins, + PFTC_INPUT_OUTPUT_PINS pHighInputOutputPinsData) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwLowPinsDirection = 0; + DWORD dwLowPinsValue = 0; + DWORD dwHighPinsDirection = 0; + DWORD dwHighPinsValue = 0; + + Status = FTC_IsDeviceHandleValid(ftHandle); + + if (Status == FTC_SUCCESS) + { + if ((pLowInputOutputPinsData != NULL) && (pHighInputOutputPinsData != NULL)) + { + if (pLowInputOutputPinsData->bPin1InputOutputState != false) + dwLowPinsDirection = (dwLowPinsDirection | '\x01'); + if (pLowInputOutputPinsData->bPin2InputOutputState != false) + dwLowPinsDirection = (dwLowPinsDirection | '\x02'); + if (pLowInputOutputPinsData->bPin3InputOutputState != false) + dwLowPinsDirection = (dwLowPinsDirection | '\x04'); + if (pLowInputOutputPinsData->bPin4InputOutputState != false) + dwLowPinsDirection = (dwLowPinsDirection | '\x08'); + if (pLowInputOutputPinsData->bPin1LowHighState != false) + dwLowPinsValue = (dwLowPinsValue | '\x01'); + if (pLowInputOutputPinsData->bPin2LowHighState != false) + dwLowPinsValue = (dwLowPinsValue | '\x02'); + if (pLowInputOutputPinsData->bPin3LowHighState != false) + dwLowPinsValue = (dwLowPinsValue | '\x04'); + if (pLowInputOutputPinsData->bPin4LowHighState != false) + dwLowPinsValue = (dwLowPinsValue | '\x08'); + + if (pHighInputOutputPinsData->bPin1InputOutputState != false) + dwHighPinsDirection = (dwHighPinsDirection | '\x01'); + if (pHighInputOutputPinsData->bPin2InputOutputState != false) + dwHighPinsDirection = (dwHighPinsDirection | '\x02'); + if (pHighInputOutputPinsData->bPin3InputOutputState != false) + dwHighPinsDirection = (dwHighPinsDirection | '\x04'); + if (pHighInputOutputPinsData->bPin4InputOutputState != false) + dwHighPinsDirection = (dwHighPinsDirection | '\x08'); + if (pHighInputOutputPinsData->bPin1LowHighState != false) + dwHighPinsValue = (dwHighPinsValue | '\x01'); + if (pHighInputOutputPinsData->bPin2LowHighState != false) + dwHighPinsValue = (dwHighPinsValue | '\x02'); + if (pHighInputOutputPinsData->bPin3LowHighState != false) + dwHighPinsValue = (dwHighPinsValue | '\x04'); + if (pHighInputOutputPinsData->bPin4LowHighState != false) + dwHighPinsValue = (dwHighPinsValue | '\x08'); + + Status = SetGeneralPurposeInputOutputPins(ftHandle, bControlLowInputOutputPins, + dwLowPinsDirection, dwLowPinsValue, + bControlHighInputOutputPins, + dwHighPinsDirection, dwHighPinsValue); + } + else + Status = FTC_NULL_INPUT_OUTPUT_BUFFER_POINTER; + } + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_GetGeneralPurposeInputOutputPins(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins, +//FTC_STATUS FT2232cMpsseJtag::JTAG_GetGPIOs(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins, + PFTC_LOW_HIGH_PINS pLowPinsInputData, + BOOL bControlHighInputOutputPins, + PFTC_LOW_HIGH_PINS pHighPinsInputData) +{ + FTC_STATUS Status = FTC_SUCCESS; + + Status = FTC_IsDeviceHandleValid(ftHandle); + + if (Status == FTC_SUCCESS) + { + if ((pLowPinsInputData != NULL) && (pHighPinsInputData != NULL)) + Status = GetGeneralPurposeInputOutputPins(ftHandle, bControlLowInputOutputPins, pLowPinsInputData, + bControlHighInputOutputPins, pHighPinsInputData); + else + Status = FTC_NULL_INPUT_OUTPUT_BUFFER_POINTER; + } + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_WriteDataToExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite, +//FTC_STATUS FT2232cMpsseJtag::JTAG_Write(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite, + PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, + DWORD dwTapControllerState) +{ + FTC_STATUS Status = FTC_SUCCESS; + + Status = FTC_IsDeviceHandleValid(ftHandle); + + if (Status == FTC_SUCCESS) + { + if (pWriteDataBuffer != NULL) + { + Status = CheckWriteDataToExternalDeviceBitsBytesParameters(dwNumBitsToWrite, dwNumBytesToWrite); + + if (Status == FTC_SUCCESS) + { + if ((dwTapControllerState >= TEST_LOGIC_STATE) && (dwTapControllerState <= SHIFT_INSTRUCTION_REGISTER_STATE)) + Status = WriteDataToExternalDevice(ftHandle, bInstructionTestData, dwNumBitsToWrite, pWriteDataBuffer, + dwNumBytesToWrite, dwTapControllerState); + else + Status = FTC_INVALID_TAP_CONTROLLER_STATE; + } + } + else + Status = FTC_NULL_WRITE_DATA_BUFFER_POINTER; + } + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_ReadDataFromExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, +//FTC_STATUS FT2232cMpsseJtag::JTAG_Read(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, + PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned, + DWORD dwTapControllerState) +{ + FTC_STATUS Status = FTC_SUCCESS; + + Status = FTC_IsDeviceHandleValid(ftHandle); + + if (Status == FTC_SUCCESS) + { + if (pReadDataBuffer != NULL) + { + if ((dwNumBitsToRead >= MIN_NUM_BITS) && (dwNumBitsToRead <= MAX_NUM_BITS)) + { + if ((dwTapControllerState >= TEST_LOGIC_STATE) && (dwTapControllerState <= SHIFT_INSTRUCTION_REGISTER_STATE)) + Status = ReadDataFromExternalDevice(ftHandle, bInstructionTestData, dwNumBitsToRead, pReadDataBuffer, + lpdwNumBytesReturned, dwTapControllerState); + else + Status = FTC_INVALID_TAP_CONTROLLER_STATE; + } + else + Status = FTC_INVALID_NUMBER_BITS; + } + else + Status = FTC_NULL_READ_DATA_BUFFER_POINTER; + } + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_WriteReadDataToFromExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, +//FTC_STATUS FT2232cMpsseJtag::JTAG_WriteRead(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, + PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, + PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned, + DWORD dwTapControllerState) +{ + FTC_STATUS Status = FTC_SUCCESS; + + Status = FTC_IsDeviceHandleValid(ftHandle); + + if (Status == FTC_SUCCESS) + { + if ((pWriteDataBuffer != NULL) && (pReadDataBuffer != NULL)) + { + Status = CheckWriteDataToExternalDeviceBitsBytesParameters(dwNumBitsToWriteRead, dwNumBytesToWrite); + + if (Status == FTC_SUCCESS) + { + if ((dwTapControllerState >= TEST_LOGIC_STATE) && (dwTapControllerState <= SHIFT_INSTRUCTION_REGISTER_STATE)) + Status = WriteReadDataToFromExternalDevice(ftHandle, bInstructionTestData, dwNumBitsToWriteRead, + pWriteDataBuffer, dwNumBytesToWrite, pReadDataBuffer, + lpdwNumBytesReturned, dwTapControllerState); + else + Status = FTC_INVALID_TAP_CONTROLLER_STATE; + } + } + else + { + if (pWriteDataBuffer == NULL) + Status = FTC_NULL_WRITE_DATA_BUFFER_POINTER; + else + Status = FTC_NULL_READ_DATA_BUFFER_POINTER; + } + } + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_GenerateTCKClockPulses(FTC_HANDLE ftHandle, DWORD dwNumClockPulses) +//FTC_STATUS FT2232cMpsseJtag::JTAG_GenerateClockPulses(FTC_HANDLE ftHandle, DWORD dwNumClockPulses) +{ + FTC_STATUS Status = FTC_SUCCESS; + + Status = FTC_IsDeviceHandleValid(ftHandle); + + if (Status == FTC_SUCCESS) + { + if ((dwNumClockPulses >= MIN_NUM_CLOCK_PULSES) && (dwNumClockPulses <= MAX_NUM_CLOCK_PULSES)) + Status = GenerateTCKClockPulses(ftHandle, dwNumClockPulses); + else + Status = FTC_INVALID_NUMBER_CLOCK_PULSES; + } + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_ClearCommandSequence(void) +//FTC_STATUS FT2232cMpsseJtag::JTAG_ClearCmdSequence(void) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumDevices; + FT2232CDeviceIndexes FT2232CIndexes; + + Status = FTC_GetNumDevices(&dwNumDevices, &FT2232CIndexes); + + if (Status == FTC_SUCCESS) + { + if (dwNumDevices == 1) + ClearDeviceCommandSequenceData(0); + else + Status = FTC_TOO_MANY_DEVICES; + } + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_AddWriteCommand(BOOL bInstructionTestData, DWORD dwNumBitsToWrite, +//FTC_STATUS FT2232cMpsseJtag::JTAG_AddWriteCmd(BOOL bInstructionTestData, DWORD dwNumBitsToWrite, + PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, + DWORD dwTapControllerState) +{ + FTC_STATUS Status = FTC_SUCCESS; + //DWORD dwNumCommandDataBytes = 0; + DWORD dwNumDevices; + FT2232CDeviceIndexes FT2232CIndexes; + + Status = FTC_GetNumDevices(&dwNumDevices, &FT2232CIndexes); + + if (Status == FTC_SUCCESS) + { + if (dwNumDevices == 1) + // ftHandle parameter set to 0 to indicate only one device present in the system + Status = AddDeviceWriteCommand(0, bInstructionTestData, dwNumBitsToWrite, pWriteDataBuffer, dwNumBytesToWrite, dwTapControllerState); + else + Status = FTC_TOO_MANY_DEVICES; + } + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_AddReadCommand(BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState) +//FTC_STATUS FT2232cMpsseJtag::JTAG_AddReadCmd(BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState) +{ + FTC_STATUS Status = FTC_SUCCESS; + //DWORD dwNumTmsClocks = 0; + DWORD dwNumDevices; + FT2232CDeviceIndexes FT2232CIndexes; + + Status = FTC_GetNumDevices(&dwNumDevices, &FT2232CIndexes); + + if (Status == FTC_SUCCESS) + { + if (dwNumDevices == 1) + // ftHandle parameter set to 0 to indicate only one device present in the system + Status = AddDeviceReadCommand(0, bInstructionTestData, dwNumBitsToRead, dwTapControllerState); + else + Status = FTC_TOO_MANY_DEVICES; + } + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_AddWriteReadCommand(BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, +//FTC_STATUS FT2232cMpsseJtag::JTAG_AddWriteReadCmd(BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, + PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, + DWORD dwTapControllerState) +{ + FTC_STATUS Status = FTC_SUCCESS; + //DWORD dwNumCommandDataBytes = 0; + //DWORD dwNumTmsClocks = 0; + DWORD dwNumDevices; + FT2232CDeviceIndexes FT2232CIndexes; + + Status = FTC_GetNumDevices(&dwNumDevices, &FT2232CIndexes); + + if (Status == FTC_SUCCESS) + { + if (dwNumDevices == 1) + // ftHandle parameter set to 0 to indicate only one device present in the system + Status = AddDeviceWriteReadCommand(0, bInstructionTestData, dwNumBitsToWriteRead, pWriteDataBuffer, dwNumBytesToWrite, dwTapControllerState); + else + Status = FTC_TOO_MANY_DEVICES; + } + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_ClearDeviceCommandSequence(FTC_HANDLE ftHandle) +//FTC_STATUS FT2232cMpsseJtag::JTAG_ClearDeviceCmdSequence(FTC_HANDLE ftHandle) +{ + FTC_STATUS Status = FTC_SUCCESS; + + Status = FTC_IsDeviceHandleValid(ftHandle); + + if (Status == FTC_SUCCESS) + ClearDeviceCommandSequenceData(ftHandle); + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceWriteCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite, +//FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceWriteCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite, + PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, + DWORD dwTapControllerState) +{ + FTC_STATUS Status = FTC_SUCCESS; + + Status = FTC_IsDeviceHandleValid(ftHandle); + + if (Status == FTC_SUCCESS) + Status = AddDeviceWriteCommand(ftHandle, bInstructionTestData, dwNumBitsToWrite, pWriteDataBuffer, dwNumBytesToWrite, dwTapControllerState); + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceReadCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState) +//FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceReadCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState) +{ + FTC_STATUS Status = FTC_SUCCESS; + + Status = FTC_IsDeviceHandleValid(ftHandle); + + if (Status == FTC_SUCCESS) + Status = AddDeviceReadCommand(ftHandle, bInstructionTestData, dwNumBitsToRead, dwTapControllerState); + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceWriteReadCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, +//FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceWriteReadCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, + PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, + DWORD dwTapControllerState) +{ + FTC_STATUS Status = FTC_SUCCESS; + + Status = FTC_IsDeviceHandleValid(ftHandle); + + if (Status == FTC_SUCCESS) + Status = AddDeviceWriteReadCommand(ftHandle, bInstructionTestData, dwNumBitsToWriteRead, pWriteDataBuffer, dwNumBytesToWrite, dwTapControllerState); + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_ExecuteCommandSequence(FTC_HANDLE ftHandle, PReadCmdSequenceDataByteBuffer pReadCmdSequenceDataBuffer, +//FTC_STATUS FT2232cMpsseJtag::JTAG_ExecuteCmdSequence(FTC_HANDLE ftHandle, PReadCmdSequenceDataByteBuffer pReadCmdSequenceDataBuffer, + LPDWORD lpdwNumBytesReturned) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumCmdSequenceBytes = 0; + DWORD dwCmdSequenceByteIndex = 0; + InputByteBuffer InputBuffer; + DWORD dwTotalNumBytesToBeRead = 0; + DWORD dwNumBytesRead = 0; + + Status = FTC_IsDeviceHandleValid(ftHandle); + + if (Status == FTC_SUCCESS) + { + if (pReadCmdSequenceDataBuffer != NULL) + { + iCommandsSequenceDataDeviceIndex = GetCommandsSequenceDataDeviceIndex(ftHandle); + + dwNumCmdSequenceBytes = GetNumBytesInCommandsSequenceDataBuffer(); + + if (dwNumCmdSequenceBytes > 0) + { + AddByteToOutputBuffer(SEND_ANSWER_BACK_IMMEDIATELY_CMD, false); + + FTC_ClearOutputBuffer(); + + dwNumCmdSequenceBytes = GetNumBytesInCommandsSequenceDataBuffer(); + + // Transfer sequence of commands for specified device to output buffer for transmission to device + for (dwCmdSequenceByteIndex = 0; (dwCmdSequenceByteIndex < dwNumCmdSequenceBytes); dwCmdSequenceByteIndex++) + FTC_AddByteToOutputBuffer((*OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].pCommandsSequenceDataOutPutBuffer)[dwCmdSequenceByteIndex], false); + + OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumBytesToSend = 0; + + Status = FTC_SendCommandsSequenceToDevice(ftHandle); + + if (Status == FTC_SUCCESS) + { + if (OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumReadCommandSequences > 0) + { + // Calculate the total number of bytes to be read, as a result of a command sequence + dwTotalNumBytesToBeRead = GetTotalNumCommandsSequenceDataBytesToRead(); + + Status = FTC_ReadCommandsSequenceBytesFromDevice(ftHandle, &InputBuffer, dwTotalNumBytesToBeRead, &dwNumBytesRead); + + if (Status == FTC_SUCCESS) + { + // Process all bytes received and return them in the read data buffer + ProcessReadCommandsSequenceBytes(&InputBuffer, dwNumBytesRead, pReadCmdSequenceDataBuffer, lpdwNumBytesReturned); + } + } + } + + OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumReadCommandSequences = 0; + } + else + Status = FTC_NO_COMMAND_SEQUENCE; + + iCommandsSequenceDataDeviceIndex = -1; + } + else + Status = FTC_NULL_READ_CMDS_DATA_BUFFER_POINTER; + } + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_GetDllVersion(LPSTR lpDllVersionBuffer, DWORD dwBufferSize) +{ + FTC_STATUS Status = FTC_SUCCESS; + + if (lpDllVersionBuffer != NULL) + { + if (dwBufferSize > strlen(DLL_VERSION_NUM)) + strcpy(lpDllVersionBuffer, DLL_VERSION_NUM); + else + Status = FTC_DLL_VERSION_BUFFER_TOO_SMALL; + } + else + Status = FTC_NULL_DLL_VERSION_BUFFER_POINTER; + + return Status; +} + +FTC_STATUS FT2232cMpsseJtag::JTAG_GetErrorCodeString(LPSTR lpLanguage, FTC_STATUS StatusCode, + LPSTR lpErrorMessageBuffer, DWORD dwBufferSize) +{ + FTC_STATUS Status = FTC_SUCCESS; + CHAR szErrorMsg[MAX_ERROR_MSG_SIZE]; + INT iCharCntr = 0; + + if ((lpLanguage != NULL) && (lpErrorMessageBuffer != NULL)) + { + for (iCharCntr = 0; (iCharCntr < MAX_ERROR_MSG_SIZE); iCharCntr++) + szErrorMsg[iCharCntr] = '\0'; + + if (((StatusCode >= FTC_SUCCESS) && (StatusCode <= FTC_INSUFFICIENT_RESOURCES)) || + ((StatusCode >= FTC_FAILED_TO_COMPLETE_COMMAND) && (StatusCode <= FTC_INVALID_STATUS_CODE))) + { + if (strcmp(lpLanguage, ENGLISH) == 0) + { + if ((StatusCode >= FTC_SUCCESS) && (StatusCode <= FTC_INSUFFICIENT_RESOURCES)) + strcpy(szErrorMsg, EN_Common_Errors[StatusCode]); + else + strcpy(szErrorMsg, EN_New_Errors[(StatusCode - FTC_FAILED_TO_COMPLETE_COMMAND)]); + } + else + { + strcpy(szErrorMsg, EN_New_Errors[FTC_INVALID_LANGUAGE_CODE - FTC_FAILED_TO_COMPLETE_COMMAND]); + + Status = FTC_INVALID_LANGUAGE_CODE; + } + } + else + { + sprintf(szErrorMsg, "%s%d", EN_New_Errors[FTC_INVALID_STATUS_CODE - FTC_FAILED_TO_COMPLETE_COMMAND], (int)StatusCode); + + Status = FTC_INVALID_STATUS_CODE; + } + + if (dwBufferSize > strlen(szErrorMsg)) + strcpy(lpErrorMessageBuffer, szErrorMsg); + else + Status = FTC_ERROR_MESSAGE_BUFFER_TOO_SMALL; + } + else + { + if (lpLanguage == NULL) + Status = FTC_NULL_LANGUAGE_CODE_BUFFER_POINTER; + else + Status = FTC_NULL_ERROR_MESSAGE_BUFFER_POINTER; + } + + return Status; +} Index: or_debug_proxy/src/FT2232c.cpp =================================================================== --- or_debug_proxy/src/FT2232c.cpp (nonexistent) +++ or_debug_proxy/src/FT2232c.cpp (revision 1779) @@ -0,0 +1,1161 @@ +/*++ + +FTC MPSSE Interface DLLs - Copyright © FTDI Ltd. 2009 + + +The source code to the FTCI2C, FTCJTAG and FTCSPI DLLs is provided as-is and no warranty is made as to its function or reliability. + +This source code may be freely modified and redistributed, provided that the FTDI Ltd. copyright notice remains intact. + +Copyright (c) 2005 Future Technology Devices International Ltd. + +Module Name: + + FT2232c.cpp + +Abstract: + + FT2232C Dual Type Devices Base Class Implementation. + +Environment: + + kernel & user mode + +Revision History: + + 07/02/05 kra Created. + 25/08/05 kra Windows 2000 Professional always sets the USB buffer size to 4K ie 4096 + 19/11/08 Rene Baumann Port FTCJTAG to Linux. + +--*/ + + +#include +#include +#include +//#include // -- Possibly not needed, trying without -jb +#include +#include +#include +#include +#include +#include + +#include +#include + + +#include "FT2232c.h" +#include "WinTypes.h" + + +//couple of simple string functions + char* strupr(char *string); + char* strlwr(char *string); + + static UINT uiNumOpenedDevices = 0; // Removed from class FT2232c in FT2232c.h to avoid segmentation fault. Rene + static FTC_DEVICE_DATA OpenedDevices[MAX_NUM_DEVICES]; // Removed from class FT2232c in FT2232c.h to avoid segmentation fault. Rene + static OutputByteBuffer OutputBuffer; // Removed from class FT2232c in FT2232c.h to avoid segmentation fault. Rene + static DWORD dwNumBytesToSend = 0; // Removed from class FT2232c in FT2232c.h to avoid segmentation fault. Rene + + +BOOLEAN FT2232c::FTC_DeviceInUse(LPSTR lpDeviceName, DWORD dwLocationID) +{ + BOOLEAN bDeviceInUse = false; + DWORD dwProcessId = 0; + BOOLEAN bLocationIDFound = false; + INT iDeviceCntr = 0; + + if (uiNumOpenedDevices > 0) + { + //dwProcessId = GetCurrentProcessId(); + dwProcessId = getpid(); //Changed windows call to linux\s getpid() + + for (iDeviceCntr = 0; ((iDeviceCntr < MAX_NUM_DEVICES) && !bLocationIDFound); iDeviceCntr++) + { + // Only check device name and location id not the current application + if (OpenedDevices[iDeviceCntr].dwProcessId != dwProcessId) + { + if (strcmp(OpenedDevices[iDeviceCntr].szDeviceName, lpDeviceName) == 0) + { + if (OpenedDevices[iDeviceCntr].dwLocationID == dwLocationID) + bLocationIDFound = true; + } + } + } + + if (bLocationIDFound) + bDeviceInUse = true; + } + + return bDeviceInUse; +} + +BOOLEAN FT2232c::FTC_DeviceOpened(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle) +{ + BOOLEAN bDeviceOpen = false; + DWORD dwProcessId = 0; + BOOLEAN bLocationIDFound = false; + INT iDeviceCntr = 0; + + if (uiNumOpenedDevices > 0) + { + //dwProcessId = GetCurrentProcessId(); + dwProcessId = getpid(); //Changed windows call to linux one + + for (iDeviceCntr = 0; ((iDeviceCntr < MAX_NUM_DEVICES) && !bLocationIDFound); iDeviceCntr++) + { + if (OpenedDevices[iDeviceCntr].dwProcessId == dwProcessId) + { + if (strcmp(OpenedDevices[iDeviceCntr].szDeviceName, lpDeviceName) == 0) + { + if (OpenedDevices[iDeviceCntr].dwLocationID == dwLocationID) + { + // Device has already been opened by this application, so just return the handle to the device + *pftHandle = OpenedDevices[iDeviceCntr].hDevice; + bLocationIDFound = true; + } + } + } + } + + if (bLocationIDFound) + bDeviceOpen = true; + } + + return bDeviceOpen; +} + +FTC_STATUS FT2232c::FTC_IsDeviceNameLocationIDValid(LPSTR lpDeviceName, DWORD dwLocationID) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumOfDevices = 0; + FT2232CDeviceIndexes FT2232CIndexes; + DWORD dwFlags = 0; + DWORD dwDeviceType = 0; + DWORD dwProductVendorID = 0; + DWORD dwLocID = 0; + SerialNumber szSerialNumber; + char szDeviceNameBuffer[DEVICE_STRING_BUFF_SIZE + 1]; + FT_HANDLE ftHandle; + BOOL bDeviceNameFound = false; + DWORD dwDeviceIndex = 0; + + // Get the number of devices connected to the system + Status = FTC_GetNumDevices(&dwNumOfDevices, &FT2232CIndexes); + + if (Status == FTC_SUCCESS) + { + if (dwNumOfDevices > 0) + { + do + { + Status = FT_GetDeviceInfoDetail(FT2232CIndexes[dwDeviceIndex], &dwFlags, &dwDeviceType, &dwProductVendorID, + &dwLocID, szSerialNumber, szDeviceNameBuffer, &ftHandle); + + if (Status == FTC_SUCCESS) + { + if (strcmp(szDeviceNameBuffer, lpDeviceName) == 0) + bDeviceNameFound = true; + } + dwDeviceIndex++; + } + while ((dwDeviceIndex < dwNumOfDevices) && (Status == FTC_SUCCESS) && (bDeviceNameFound == false)); + + if (bDeviceNameFound == TRUE) + { + if (dwLocID != dwLocationID) + Status = FTC_INVALID_LOCATION_ID; + } + else + Status = FTC_INVALID_DEVICE_NAME; + } + else + Status = FTC_DEVICE_NOT_FOUND; + } + + return Status; +} + +FTC_STATUS FT2232c::FTC_IsDeviceFT2232CType(LPSTR lpDeviceName, LPBOOL lpbFT2232CTypeDevice) +{ + FTC_STATUS Status = FTC_SUCCESS; + LPSTR pszStringSearch; + + *lpbFT2232CTypeDevice = false; + + // Search for the last occurrence of the channel string ie ' A' + if ((pszStringSearch = strstr(strupr(lpDeviceName), DEVICE_CHANNEL_A)) != NULL) + { + // Ensure the last two characters of the device name is ' A' ie channel A + if (strlen(pszStringSearch) == 2) + *lpbFT2232CTypeDevice = true; + } + + return Status; +} + +FT2232c::FT2232c(void) +{ + INT iDeviceCntr = 0; + + uiNumOpenedDevices = 0; + + for (iDeviceCntr = 0; (iDeviceCntr < MAX_NUM_DEVICES); iDeviceCntr++) + OpenedDevices[iDeviceCntr].dwProcessId = 0; + + dwNumBytesToSend = 0; +} + +FT2232c::~FT2232c(void) +{ + +} + +FTC_STATUS FT2232c::FTC_GetNumDevices(LPDWORD lpdwNumDevices, FT2232CDeviceIndexes *FT2232CIndexes) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumOfDevices = 0; + DWORD dwDeviceIndex = 0; + DWORD dwFlags = 0; + DWORD dwDeviceType = 0; + DWORD dwProductVendorID = 0; + SerialNumber szSerialNumber; + char szDeviceNameBuffer[DEVICE_STRING_BUFF_SIZE + 1]; + FT_HANDLE ftHandle; + DWORD dwLocationID; + DWORD i; + BOOL bFT2232CTypeDevice = false; + + *lpdwNumDevices = 0; + + // Get the number of devices connected to the system + Status = FT_CreateDeviceInfoList(&dwNumOfDevices); + +if(DEBUG_LIST_DEVICE){ + FT_STATUS ftStatus; + FT_DEVICE_LIST_INFO_NODE *devInfo; + DWORD numDevs; + // create the device information list + ftStatus = FT_CreateDeviceInfoList(&numDevs); + if (ftStatus == FT_OK) { + printf("Number of devices is %ld\n",numDevs); + } + if (numDevs > 0) { + // allocate storage for list based on numDevs + devInfo = + (FT_DEVICE_LIST_INFO_NODE*)malloc(sizeof(FT_DEVICE_LIST_INFO_NODE)*numDevs); + // get the device information list + ftStatus = FT_GetDeviceInfoList(devInfo,&numDevs); + if (ftStatus == FT_OK) { + for ( i = 0; i < numDevs; i++) { + printf("Dev %ld:\n",i); + printf(" Flags=0x%lx\n",devInfo[i].Flags); + printf(" Type=0x%lx\n",devInfo[i].Type); + printf(" ID=0x%lx\n",devInfo[i].ID); + printf(" LocId=0x%lx\n",devInfo[i].LocId); + printf(" SerialNumber=%s\n",devInfo[i].SerialNumber); + printf(" Description=%s\n",devInfo[i].Description); + printf(" ftHandle=0x%lx\n",(unsigned long int)devInfo[i].ftHandle); + } + } + } +} + + + + + + if (Status == FTC_SUCCESS) + { + if (dwNumOfDevices > 0) + { + do + { + // Devices previously opened by another application, results in 0 being returned for dwflags, dwDeviceType, + // dwProductVendorID, dwLocationID and ftHandle and empty being returned in szSerialNumber and + // szDeviceNameBuffer. This problem is in the FTD2XX.DLL. + Status = FT_GetDeviceInfoDetail(dwDeviceIndex, &dwFlags, &dwDeviceType, &dwProductVendorID, + &dwLocationID, szSerialNumber, szDeviceNameBuffer, &ftHandle); + // The flag value is a 4-byte bit map containing miscellaneous data as defined in the - Type Definitions. + // Bit 0 (least significant bit) of this number indicates if the port is open (1) or closed (0). + // Bit 1 indicates if the device is enumerated as a high-speed USB device (2) or a full-speed USB device (0). + // The remaining bits (2 - 31) are reserved. + + // dwDeviceType = 4 --> FT_DEVICE_2232C see FT_DEVICE in ftd2xx.h + if (Status == FTC_SUCCESS) + { + Status = FTC_IsDeviceFT2232CType(szDeviceNameBuffer, &bFT2232CTypeDevice); + + if (Status == FTC_SUCCESS) + { + if (bFT2232CTypeDevice == TRUE) + { + // The number of devices returned is, not opened devices ie channel A plus devices opened by the + // calling application. Devices previously opened by another application are not included in this + // number. + (*FT2232CIndexes)[*lpdwNumDevices] = dwDeviceIndex; + + *lpdwNumDevices = *lpdwNumDevices + 1; + } + } + } + else + { + // if a device has already been opened by another application, the FT_GetDeviceInfoDetail call will + // return an INVALID_HANDLE error code, ignore this error code and continue + if (Status == FTC_INVALID_HANDLE) + Status = FTC_SUCCESS; + } + + dwDeviceIndex++; + } + while ((dwDeviceIndex < dwNumOfDevices) && (Status == FTC_SUCCESS)); + } + } + + return Status; +} + +FTC_STATUS FT2232c::FTC_GetNumNotOpenedDevices(LPDWORD lpdwNumNotOpenedDevices, FT2232CDeviceIndexes *FT2232CIndexes) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumOfDevices = 0; + DWORD dwDeviceIndex = 0; + DWORD dwFlags = 0; + DWORD dwDeviceType = 0; + DWORD dwProductVendorID = 0; + SerialNumber szSerialNumber; + char szDeviceNameBuffer[DEVICE_STRING_BUFF_SIZE + 1]; + FT_HANDLE ftHandle; + DWORD dwLocationID; + BOOL bFT2232CTypeDevice = false; + + *lpdwNumNotOpenedDevices = 0; + + // Get the number of devices connected to the system + Status = FT_CreateDeviceInfoList(&dwNumOfDevices); + + if (Status == FTC_SUCCESS) + { + if (dwNumOfDevices > 0) + { + do + { + Status = FT_GetDeviceInfoDetail(dwDeviceIndex, &dwFlags, &dwDeviceType, &dwProductVendorID, + &dwLocationID, szSerialNumber, szDeviceNameBuffer, &ftHandle); + + if (Status == FTC_SUCCESS) + { + Status = FTC_IsDeviceFT2232CType(szDeviceNameBuffer, &bFT2232CTypeDevice); + + if (Status == FTC_SUCCESS) + { + if ((bFT2232CTypeDevice == TRUE) && ((dwFlags & DEVICE_OPENED_FLAG) == 0)) + { + (*FT2232CIndexes)[*lpdwNumNotOpenedDevices] = dwDeviceIndex; + + *lpdwNumNotOpenedDevices = *lpdwNumNotOpenedDevices + 1; + } + } + } + else + { + // if a device has already been opened by another application, the FT_GetDeviceInfoDetail call will + // return an INVALID_HANDLE error code, ignore this error code and continue + if (Status == FTC_INVALID_HANDLE) + Status = FTC_SUCCESS; + } + + dwDeviceIndex++; + } + while ((dwDeviceIndex < dwNumOfDevices) && (Status == FTC_SUCCESS)); + } + } + + return Status; +} + +FTC_STATUS FT2232c::FTC_GetDeviceNameLocationID(DWORD dwDeviceIndex, LPSTR lpDeviceName, DWORD dwBufferSize, LPDWORD lpdwLocationID) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumDevices = 0; + FT2232CDeviceIndexes FT2232CIndexes; + DWORD dwFlags = 0; + DWORD dwDeviceType = 0; + DWORD dwProductVendorID = 0; + SerialNumber szSerialNumber; + char szDeviceNameBuffer[DEVICE_STRING_BUFF_SIZE + 1]; + FT_HANDLE ftHandle; + + if (lpDeviceName != NULL) + { + Status = FTC_GetNumDevices(&dwNumDevices, &FT2232CIndexes); + + if (Status == FTC_SUCCESS) + { + if (dwNumDevices > 0) + { + if (dwDeviceIndex < dwNumDevices) + { + Status = FT_GetDeviceInfoDetail(FT2232CIndexes[dwDeviceIndex], &dwFlags, &dwDeviceType, &dwProductVendorID, + lpdwLocationID, szSerialNumber, szDeviceNameBuffer, &ftHandle); + + if (Status == FTC_SUCCESS) + { + if (strlen(szDeviceNameBuffer) <= dwBufferSize) + strcpy(lpDeviceName, szDeviceNameBuffer); + else + Status = FTC_DEVICE_NAME_BUFFER_TOO_SMALL; + } + } + else + Status = FTC_INVALID_DEVICE_NAME_INDEX; + } + else + Status = FTC_DEVICE_NOT_FOUND; + } + } + else + Status = FTC_NULL_DEVICE_NAME_BUFFER_POINTER; + + return Status; +} + +FTC_STATUS FT2232c::FTC_OpenSpecifiedDevice(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle) +{ + FTC_STATUS Status = FTC_SUCCESS; + FT_HANDLE ftHandle; + + if (lpDeviceName != NULL) + { + + // Caused driver to remove both devices loaded by ftdi_sio in /dev/ + // We wish the second, /dev/ttyUSB1 to remain to connect a terminal + // program to it. - jb 090301 + //Status = FTC_IsDeviceNameLocationIDValid(lpDeviceName, dwLocationID); + + if (Status == FTC_SUCCESS) + { + + if (!FTC_DeviceInUse(lpDeviceName, dwLocationID)) + { + + if (!FTC_DeviceOpened(lpDeviceName, dwLocationID, pftHandle)) + { + + // To open a device in Linux the FT_OPEN_BY_DESCRIPTION has to be used. Rene + Status = FT_OpenEx((PVOID)lpDeviceName, FT_OPEN_BY_DESCRIPTION, &ftHandle); + // Linux das not return the LocationID + // Status = FT_OpenEx((PVOID)dwLocationID, FT_OPEN_BY_LOCATION, &ftHandle); + + if (Status == FTC_SUCCESS) + { + *pftHandle = (DWORD)ftHandle; + + FTC_InsertDeviceHandle(lpDeviceName, dwLocationID, *pftHandle); + } + + } + + } + else + Status = FTC_DEVICE_IN_USE; + } + } + else + Status = FTC_NULL_DEVICE_NAME_BUFFER_POINTER; + + return Status; +} + +FTC_STATUS FT2232c::FTC_OpenDevice(FTC_HANDLE *pftHandle) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumDevices = 0; + FT2232CDeviceIndexes FT2232CIndexes; + char szDeviceName[DEVICE_STRING_BUFF_SIZE + 1]; + DWORD dwLocationID; + + Status = FTC_GetNumDevices(&dwNumDevices, &FT2232CIndexes); + + if (Status == FTC_SUCCESS) + { + if (dwNumDevices == 1) + { + Status = FTC_GetDeviceNameLocationID(FT2232CIndexes[0], szDeviceName, (DEVICE_STRING_BUFF_SIZE + 1), &dwLocationID); + + if (Status == FTC_SUCCESS) + Status = FTC_OpenSpecifiedDevice(szDeviceName, dwLocationID, pftHandle); + } + else + { + if (dwNumDevices == 0) + Status = FTC_DEVICE_NOT_FOUND; + else + Status = FTC_TOO_MANY_DEVICES; + } + } + + return Status; +} + +FTC_STATUS FT2232c::FTC_CloseDevice(FTC_HANDLE ftHandle) +{ + FTC_STATUS Status = FTC_SUCCESS; + + Status = FTC_IsDeviceHandleValid(ftHandle); + + if (Status == FTC_SUCCESS) + { + Status = FT_Close((FT_HANDLE)ftHandle); + + FTC_RemoveDeviceHandle(ftHandle); + } + + return Status; +} + +void FT2232c::FTC_GetClockFrequencyValues(DWORD dwClockFrequencyValue, LPDWORD lpdwClockFrequencyHz) +{ + *lpdwClockFrequencyHz = (BASE_CLOCK_FREQUENCY_12_MHZ / ((1 + dwClockFrequencyValue) * 2)); +} + +FTC_STATUS FT2232c::FTC_SetDeviceLoopbackState(FTC_HANDLE ftHandle, BOOL bLoopbackState) +{ + FTC_STATUS Status = FTC_SUCCESS; + + Status = FTC_IsDeviceHandleValid(ftHandle); + + if (Status == FTC_SUCCESS) + { + if (bLoopbackState == false) + // turn off loopback + FTC_AddByteToOutputBuffer(TURN_OFF_LOOPBACK_CMD, true); + else + // turn on loopback + FTC_AddByteToOutputBuffer(TURN_ON_LOOPBACK_CMD, true); + + FTC_SendBytesToDevice(ftHandle); + } + + return Status; +} + +void FT2232c::FTC_InsertDeviceHandle(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE ftHandle) +{ + DWORD dwProcessId = 0; + INT iDeviceCntr = 0; + BOOLEAN bDeviceftHandleInserted = false; + + if (uiNumOpenedDevices < MAX_NUM_DEVICES) + { + //dwProcessId = GetCurrentProcessId(); + dwProcessId = getpid(); //Changed windows call to linux\s getpid() + + for (iDeviceCntr = 0; ((iDeviceCntr < MAX_NUM_DEVICES) && !bDeviceftHandleInserted); iDeviceCntr++) + { + if (OpenedDevices[iDeviceCntr].dwProcessId == 0) + { + OpenedDevices[iDeviceCntr].dwProcessId = dwProcessId; + strcpy(OpenedDevices[iDeviceCntr].szDeviceName, lpDeviceName); + OpenedDevices[iDeviceCntr].dwLocationID = dwLocationID; + OpenedDevices[iDeviceCntr].hDevice = ftHandle; + + uiNumOpenedDevices = uiNumOpenedDevices + 1; + + bDeviceftHandleInserted = true; + } + } + } +} + +FTC_STATUS FT2232c::FTC_IsDeviceHandleValid(FTC_HANDLE ftHandle) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwProcessId = 0; + INT iDeviceCntr = 0; + BOOLEAN bDevicempHandleFound = false; + + if ((uiNumOpenedDevices > 0) && (ftHandle > 0)) + { + //dwProcessId = GetCurrentProcessId(); + dwProcessId = getpid(); //Changed windows call to linux\s getpid() + + for (iDeviceCntr = 0; ((iDeviceCntr < MAX_NUM_DEVICES) && !bDevicempHandleFound); iDeviceCntr++) + { + if (OpenedDevices[iDeviceCntr].dwProcessId == dwProcessId) + { + if (OpenedDevices[iDeviceCntr].hDevice == ftHandle) + bDevicempHandleFound = true; + } + } + + if (!bDevicempHandleFound) + Status = FTC_INVALID_HANDLE; + } + else + Status = FTC_INVALID_HANDLE; + + return Status; +} + + +void FT2232c::FTC_RemoveDeviceHandle(FTC_HANDLE ftHandle) +{ + DWORD dwProcessId = 0; + INT iDeviceCntr = 0; + BOOLEAN bDevicempHandleFound = false; + + if (uiNumOpenedDevices > 0) + { + //dwProcessId = GetCurrentProcessId(); + dwProcessId = getpid(); //Changed windows call to linux\s getpid() + + for (iDeviceCntr = 0; ((iDeviceCntr < MAX_NUM_DEVICES) && !bDevicempHandleFound); iDeviceCntr++) + { + if (OpenedDevices[iDeviceCntr].dwProcessId == dwProcessId) + { + if (OpenedDevices[iDeviceCntr].hDevice == ftHandle) + { + OpenedDevices[iDeviceCntr].dwProcessId = 0; + strcpy(OpenedDevices[iDeviceCntr].szDeviceName, ""); + OpenedDevices[iDeviceCntr].dwLocationID = 0; + OpenedDevices[iDeviceCntr].hDevice = 0; + + uiNumOpenedDevices = uiNumOpenedDevices - 1; + + bDevicempHandleFound = true; + } + } + } + } +} + +FTC_STATUS FT2232c::FTC_ResetUSBDevicePurgeUSBInputBuffer(FTC_HANDLE ftHandle) +{ + FTC_STATUS Status = FTC_SUCCESS; + InputByteBuffer InputBuffer; + DWORD dwNumBytesRead = 0; + DWORD dwNumBytesDeviceInputBuffer; + + Status = FT_ResetDevice((FT_HANDLE)ftHandle); + + if (Status == FTC_SUCCESS) + { + // Get the number of bytes in the device input buffer + Status = FT_GetQueueStatus((FT_HANDLE)ftHandle, &dwNumBytesDeviceInputBuffer); + + if (Status == FTC_SUCCESS) + { + if (dwNumBytesDeviceInputBuffer > 0) + FTC_ReadBytesFromDevice(ftHandle, &InputBuffer, dwNumBytesDeviceInputBuffer, &dwNumBytesRead); + } + } + + return Status; +} + +FTC_STATUS FT2232c::FTC_SetDeviceUSBBufferSizes(FTC_HANDLE ftHandle, DWORD InputBufferSize, DWORD OutputBufferSize) +{ + return FT_SetUSBParameters((FT_HANDLE)ftHandle, InputBufferSize, OutputBufferSize); +} + +FTC_STATUS FT2232c::FTC_SetDeviceSpecialCharacters(FTC_HANDLE ftHandle, BOOLEAN bEventEnabled, UCHAR EventCharacter, + BOOLEAN bErrorEnabled, UCHAR ErrorCharacter) +{ + UCHAR EventCharEnabled = UCHAR(bEventEnabled); + UCHAR ErrorCharEnabled = UCHAR(bErrorEnabled); + + // Set the special characters for the device. disable event and error characters + return FT_SetChars((FT_HANDLE)ftHandle, EventCharacter, EventCharEnabled, ErrorCharacter, ErrorCharEnabled); +} + +FTC_STATUS FT2232c::FTC_SetReadWriteDeviceTimeouts(FTC_HANDLE ftHandle, DWORD dwReadTimeoutmSec, DWORD dwWriteTimeoutmSec) +{ + // Sets the read and write timeouts in milli-seconds for the device + return FT_SetTimeouts((FT_HANDLE)ftHandle, dwReadTimeoutmSec, dwWriteTimeoutmSec); +} + +FTC_STATUS FT2232c::FTC_SetDeviceLatencyTimer(FTC_HANDLE ftHandle, BYTE LatencyTimermSec) +{ + // Set the device latency timer to a number of milliseconds + return FT_SetLatencyTimer((FT_HANDLE)ftHandle, LatencyTimermSec); +} + +FTC_STATUS FT2232c::FTC_ResetMPSSEInterface(FTC_HANDLE ftHandle) +{ + return FT_SetBitMode((FT_HANDLE)ftHandle, MPSSE_INTERFACE_MASK, RESET_MPSSE_INTERFACE); +} + +FTC_STATUS FT2232c::FTC_EnableMPSSEInterface(FTC_HANDLE ftHandle) +{ + return FT_SetBitMode((FT_HANDLE)ftHandle, MPSSE_INTERFACE_MASK, ENABLE_MPSSE_INTERFACE); +} + +FTC_STATUS FT2232c::FTC_SendReceiveCommandFromMPSSEInterface(FTC_HANDLE ftHandle, BOOLEAN bSendEchoCommandContinuouslyOnce, BYTE EchoCommand, LPBOOL lpbCommandEchod) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumBytesDeviceInputBuffer = 0; + //SYSTEMTIME StartTime; + InputByteBuffer InputBuffer; + DWORD dwNumBytesRead = 0; + DWORD dwByteCntr = 0; + BOOL bBadCommandResponse = false; + + // New timeout detection variables for linux build -- Julius + struct timeval tv; + time_t time_start; // to store number of seconds since unix epoch + + + *lpbCommandEchod = false; + + if (!bSendEchoCommandContinuouslyOnce) + { + // Causes the device to echo back the command character and wait in command mode + FTC_AddByteToOutputBuffer(EchoCommand, true); + FTC_SendBytesToDevice(ftHandle); + } + + // Windows only time functions - removed for linux library build -- Julius + //GetLocalTime(&StartTime); + gettimeofday(&tv, NULL); + time_start = tv.tv_sec; + + do + { + // Send the echo command every time round the loop + if (bSendEchoCommandContinuouslyOnce) + { + // Causes the device to echo back the command character and wait in command mode + FTC_AddByteToOutputBuffer(EchoCommand, true); + FTC_SendBytesToDevice(ftHandle); + } + + // Get the number of bytes in the device input buffer + Status = FT_GetQueueStatus((FT_HANDLE)ftHandle, &dwNumBytesDeviceInputBuffer); + + if (Status == FTC_SUCCESS) + { + //Sleep(0); // give up timeslice - not exist in linux! + // perhaps #include and do a sched_yield(); + // This basically checks if the time we took from the first GetLocalTime was bigger than + // MAX_COMMAND_TIMEOUT_PERIOD + //if (FTC_Timeout(StartTime, MAX_COMMAND_TIMEOUT_PERIOD)) + gettimeofday(&tv, NULL); + if ((tv.tv_sec - time_start) > (MAX_COMMAND_TIMEOUT_PERIOD/1000)) + Status = FTC_FAILED_TO_COMPLETE_COMMAND; + + + + } + + if (Status == FTC_SUCCESS) + { + if (dwNumBytesDeviceInputBuffer > 0) + { + FTC_ReadBytesFromDevice(ftHandle, &InputBuffer, dwNumBytesDeviceInputBuffer, &dwNumBytesRead); + + if (dwNumBytesRead > 0) + { + dwByteCntr = 0; + + do + { + if (dwByteCntr <= (dwNumBytesRead - 1)) + { + if (InputBuffer[dwByteCntr] == BAD_COMMAND_RESPONSE) + bBadCommandResponse = true; + else + { + if (bBadCommandResponse == TRUE) + { + if (InputBuffer[dwByteCntr] == EchoCommand) + *lpbCommandEchod = true; + } + + bBadCommandResponse = false; + } + } + + dwByteCntr = dwByteCntr + 1; + } + while ((dwByteCntr < dwNumBytesRead) && (*lpbCommandEchod == false)); + } + } + } + } + while ((*lpbCommandEchod == false) && (Status == FTC_SUCCESS)); + + return Status; +} + +FTC_STATUS FT2232c::FTC_SynchronizeMPSSEInterface(FTC_HANDLE ftHandle) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumBytesDeviceInputBuffer = 0; + InputByteBuffer InputBuffer; + DWORD dwNumBytesRead = 0; + BOOL bCommandEchod = false; + + // Get the number of bytes in the device input buffer + Status = FT_GetQueueStatus((FT_HANDLE)ftHandle, &dwNumBytesDeviceInputBuffer); + + if (Status == FTC_SUCCESS) + { + if (dwNumBytesDeviceInputBuffer > 0) + FTC_ReadBytesFromDevice(ftHandle, &InputBuffer, dwNumBytesDeviceInputBuffer, &dwNumBytesRead); + + Status = FTC_SendReceiveCommandFromMPSSEInterface(ftHandle, TRUE, AA_ECHO_CMD_1, &bCommandEchod); + + if (Status == FTC_SUCCESS) + { + if (bCommandEchod == TRUE) + { + Status = FTC_SendReceiveCommandFromMPSSEInterface(ftHandle, FALSE, AB_ECHO_CMD_2, &bCommandEchod); + + if (Status == FTC_SUCCESS) + { + if (bCommandEchod == false) + Status = FTC_FAILED_TO_SYNCHRONIZE_DEVICE_MPSSE; + } + } + else + Status = FTC_FAILED_TO_SYNCHRONIZE_DEVICE_MPSSE; + } + } + + return Status; +} + +/* +BOOLEAN FT2232c::FTC_Timeout(SYSTEMTIME StartSystemTime, DWORD dwTimeoutmSecs) +{ + BOOLEAN bTimoutExpired = false; + FILETIME StartFileTime; + ULARGE_INTEGER StartTime; + SYSTEMTIME EndSystemTime; + FILETIME EndFileTime; + ULARGE_INTEGER EndTime; + ULONGLONG ulTimeoutmSecs = dwTimeoutmSecs * CONVERT_1MS_TO_100NS; //10000; + + GetLocalTime(&EndSystemTime); + + SystemTimeToFileTime(&StartSystemTime, &StartFileTime); + + StartTime.LowPart = StartFileTime.dwLowDateTime; + StartTime.HighPart = StartFileTime.dwHighDateTime; + + SystemTimeToFileTime(&EndSystemTime, &EndFileTime); + + EndTime.LowPart = EndFileTime.dwLowDateTime; + EndTime.HighPart = EndFileTime.dwHighDateTime; + + if ((EndTime.QuadPart - StartTime.QuadPart) > ulTimeoutmSecs) + bTimoutExpired = true; + + return bTimoutExpired; + }*/ + +FTC_STATUS FT2232c::FTC_GetNumberBytesFromDeviceInputBuffer(FTC_HANDLE ftHandle, LPDWORD lpdwNumBytesDeviceInputBuffer) +{ + FTC_STATUS Status = FTC_SUCCESS; + //SYSTEMTIME StartTime; + + // New timeout detection variables for linux build -- Julius + struct timeval tv; + time_t time_start; // to store number of seconds since unix epoch + + + // Windows only time functions - removed for linux library build -- Julius + //GetLocalTime(&StartTime); + gettimeofday(&tv, NULL); + time_start = tv.tv_sec; + + + do + { + // Get the number of bytes in the device input buffer + Status = FT_GetQueueStatus((FT_HANDLE)ftHandle, lpdwNumBytesDeviceInputBuffer); + + if (Status == FTC_SUCCESS) + { + //Sleep(0); // give up timeslice - not exist in linux! + // perhaps #include and do a sched_yield(); + // This basically checks if the time we took from the first GetLocalTime was bigger than + // MAX_COMMAND_TIMEOUT_PERIOD + //if (FTC_Timeout(StartTime, MAX_COMMAND_TIMEOUT_PERIOD)) + gettimeofday(&tv, NULL); + if ((tv.tv_sec - time_start) > (MAX_COMMAND_TIMEOUT_PERIOD / 1000)) + Status = FTC_FAILED_TO_COMPLETE_COMMAND; + } + } + while ((*lpdwNumBytesDeviceInputBuffer == 0) && (Status == FTC_SUCCESS)); + + return Status; +} + +void FT2232c::FTC_ClearOutputBuffer(void) +{ + dwNumBytesToSend = 0; +} + +void FT2232c::FTC_AddByteToOutputBuffer(DWORD dwOutputByte, BOOL bClearOutputBuffer) +{ + if (bClearOutputBuffer == TRUE) + dwNumBytesToSend = 0; + + OutputBuffer[dwNumBytesToSend] = (dwOutputByte & '\xFF'); + + dwNumBytesToSend = dwNumBytesToSend + 1; +} + +DWORD FT2232c::FTC_GetNumBytesInOutputBuffer(void) +{ + return dwNumBytesToSend; +} + +FTC_STATUS FT2232c::FTC_SendBytesToDevice(FTC_HANDLE ftHandle) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumDataBytesToSend = 0; + DWORD dwNumBytesSent = 0; + DWORD dwTotalNumBytesSent = 0; + + if (dwNumBytesToSend > MAX_NUM_BYTES_USB_WRITE) + { + do + { + // 25/08/05 - Can only use 4096 byte block as Windows 2000 Professional does not allow you to alter the USB buffer size + // 25/08/05 - Windows 2000 Professional always sets the USB buffer size to 4K ie 4096 + if ((dwTotalNumBytesSent + MAX_NUM_BYTES_USB_WRITE) <= dwNumBytesToSend) + dwNumDataBytesToSend = MAX_NUM_BYTES_USB_WRITE; + else + dwNumDataBytesToSend = (dwNumBytesToSend - dwTotalNumBytesSent); + + // This function sends data to a FT2232C dual type device. The dwNumBytesToSend variable specifies the number of + // bytes in the output buffer to be sent to a FT2232C dual type device. The dwNumBytesSent variable contains + // the actual number of bytes sent to a FT2232C dual type device. + Status = FT_Write((FT_HANDLE)ftHandle, &OutputBuffer[dwTotalNumBytesSent], dwNumDataBytesToSend, &dwNumBytesSent); + + dwTotalNumBytesSent = dwTotalNumBytesSent + dwNumBytesSent; + } + while ((dwTotalNumBytesSent < dwNumBytesToSend) && (Status == FTC_SUCCESS)); + } + else + { + // This function sends data to a FT2232C dual type device. The dwNumBytesToSend variable specifies the number of + // bytes in the output buffer to be sent to a FT2232C dual type device. The dwNumBytesSent variable contains + // the actual number of bytes sent to a FT2232C dual type device. + Status = FT_Write((FT_HANDLE)ftHandle, OutputBuffer, dwNumBytesToSend, &dwNumBytesSent); + } + + + dwNumBytesToSend = 0; + + return Status; +} + +FTC_STATUS FT2232c::FTC_ReadBytesFromDevice(FTC_HANDLE ftHandle, PInputByteBuffer InputBuffer, + DWORD dwNumBytesToRead, LPDWORD lpdwNumBytesRead) +{ + // This function reads data from a FT2232C dual type device. The dwNumBytesToRead variable specifies the maximum + // number of bytes to be read from a FT2232C dual type device. The lpdwNumBytesRead variable contains the actual + // number of bytes read from a FT2232C dual type device, which may range from zero to the actual number of bytes + // requested, depending on how many have been received at the time of the request + the read timeout value. + // The bytes read from a FT2232C dual type device, will be returned in the input buffer. + return FT_Read((FT_HANDLE)ftHandle, InputBuffer, dwNumBytesToRead, lpdwNumBytesRead); +} + +FTC_STATUS FT2232c::FTC_ReadFixedNumBytesFromDevice(FTC_HANDLE ftHandle, PInputByteBuffer InputBuffer, + DWORD dwNumBytesToRead, LPDWORD lpdwNumDataBytesRead) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumBytesDeviceInputBuffer = 0; + InputByteBuffer TmpInputByteBuffer; + DWORD dwNumBytesRead = 0; + DWORD dwBytesReadIndex = 0; + + do + { + Status = FTC_GetNumberBytesFromDeviceInputBuffer(ftHandle, &dwNumBytesDeviceInputBuffer); + + if ((Status == FTC_SUCCESS) && (dwNumBytesDeviceInputBuffer > 0)) + { + Status = FTC_ReadBytesFromDevice(ftHandle, &TmpInputByteBuffer, dwNumBytesDeviceInputBuffer, &dwNumBytesRead); + + if (Status == FTC_SUCCESS) + { + for (dwBytesReadIndex = 0 ; dwBytesReadIndex < dwNumBytesRead; dwBytesReadIndex++) + { + (*InputBuffer)[*lpdwNumDataBytesRead] = TmpInputByteBuffer[dwBytesReadIndex]; + *lpdwNumDataBytesRead = (*lpdwNumDataBytesRead + 1); + } + } + } + } + while ((*lpdwNumDataBytesRead < dwNumBytesToRead) && (Status == FTC_SUCCESS)); + + return Status; +} + +FTC_STATUS FT2232c::FTC_SendReadBytesToFromDevice(FTC_HANDLE ftHandle, PInputByteBuffer InputBuffer, + DWORD dwNumBytesToRead, LPDWORD lpdwNumBytesRead) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumBytesSent = 0; + DWORD dwNumControlSendBytes = 0; + DWORD dwNumDataBytesRead = 0; + + if (dwNumBytesToSend > MAX_NUM_BYTES_USB_WRITE_READ) + { + // This function sends data to a FT2232C dual type device. The dwNumBytesToSend variable specifies the number of + // bytes in the output buffer to be sent to a FT2232C dual type device. The dwNumBytesSent variable contains + // the actual number of bytes sent to a FT2232C dual type device. + Status = FT_Write((FT_HANDLE)ftHandle, OutputBuffer, MAX_NUM_BYTES_USB_WRITE_READ, &dwNumBytesSent); + + if (Status == FTC_SUCCESS) + { + dwNumControlSendBytes = (dwNumBytesToSend - dwNumBytesToRead); + + Status = FTC_ReadFixedNumBytesFromDevice(ftHandle, InputBuffer, (MAX_NUM_BYTES_USB_WRITE_READ - dwNumControlSendBytes), &dwNumDataBytesRead); + + if (Status == FTC_SUCCESS) + { + Status = FT_Write((FT_HANDLE)ftHandle, &OutputBuffer[dwNumBytesSent], (dwNumBytesToSend - dwNumBytesSent), &dwNumBytesSent); + + if (Status == FTC_SUCCESS) + { + Status = FTC_ReadFixedNumBytesFromDevice(ftHandle, InputBuffer, (dwNumBytesToRead - dwNumDataBytesRead), &dwNumDataBytesRead); + + if (Status == FTC_SUCCESS) + *lpdwNumBytesRead = dwNumDataBytesRead; + } + } + } + } + else + { + // This function sends data to a FT2232C dual type device. The dwNumBytesToSend variable specifies the number of + // bytes in the output buffer to be sent to a FT2232C dual type device. The dwNumBytesSent variable contains + // the actual number of bytes sent to a FT2232C dual type device. + Status = FT_Write((FT_HANDLE)ftHandle, OutputBuffer, dwNumBytesToSend, &dwNumBytesSent); + + if (Status == FTC_SUCCESS) + { + Status = FTC_ReadFixedNumBytesFromDevice(ftHandle, InputBuffer, dwNumBytesToRead, &dwNumDataBytesRead); + + if (Status == FTC_SUCCESS) + *lpdwNumBytesRead = dwNumDataBytesRead; + } + } + + dwNumBytesToSend = 0; + + return Status; +} + +FTC_STATUS FT2232c::FTC_SendCommandsSequenceToDevice(FTC_HANDLE ftHandle) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumDataBytesToSend = 0; + DWORD dwNumBytesSent = 0; + DWORD dwTotalNumBytesSent = 0; + + if (dwNumBytesToSend > MAX_NUM_BYTES_USB_WRITE) + { + do + { + if ((dwTotalNumBytesSent + MAX_NUM_BYTES_USB_WRITE) <= dwNumBytesToSend) + dwNumDataBytesToSend = MAX_NUM_BYTES_USB_WRITE; + else + dwNumDataBytesToSend = (dwNumBytesToSend - dwTotalNumBytesSent); + + // This function sends data to a FT2232C dual type device. The dwNumBytesToSend variable specifies the number of + // bytes in the output buffer to be sent to a FT2232C dual type device. The dwNumBytesSent variable contains + // the actual number of bytes sent to a FT2232C dual type device. + Status = FT_Write((FT_HANDLE)ftHandle, &OutputBuffer[dwTotalNumBytesSent], dwNumDataBytesToSend, &dwNumBytesSent); + + dwTotalNumBytesSent = dwTotalNumBytesSent + dwNumBytesSent; + } + while ((dwTotalNumBytesSent < dwNumBytesToSend) && (Status == FTC_SUCCESS)); + } + else + { + // This function sends data to a FT2232C dual type device. The dwNumBytesToSend variable specifies the number of + // bytes in the output buffer to be sent to a FT2232C dual type device. The dwNumBytesSent variable contains + // the actual number of bytes sent to a FT2232C dual type device. + Status = FT_Write((FT_HANDLE)ftHandle, OutputBuffer, dwNumBytesToSend, &dwNumBytesSent); + } + + dwNumBytesToSend = 0; + + return Status; +} + +FTC_STATUS FT2232c::FTC_ReadCommandsSequenceBytesFromDevice(FTC_HANDLE ftHandle, PInputByteBuffer InputBuffer, + DWORD dwNumBytesToRead, LPDWORD lpdwNumBytesRead) +{ + FTC_STATUS Status = FTC_SUCCESS; + DWORD dwNumDataBytesToRead = 0; + DWORD dwNumBytesRead = 0; + DWORD dwTotalNumBytesRead = 0; + + if (dwNumBytesToRead > MAX_NUM_BYTES_USB_READ) + { + do + { + if ((dwTotalNumBytesRead + MAX_NUM_BYTES_USB_WRITE_READ) <= dwNumBytesToRead) + dwNumDataBytesToRead = MAX_NUM_BYTES_USB_WRITE_READ; + else + dwNumDataBytesToRead = (dwNumBytesToRead - dwTotalNumBytesRead); + + Status = FTC_ReadFixedNumBytesFromDevice(ftHandle, InputBuffer, dwNumDataBytesToRead, &dwNumBytesRead); + + dwTotalNumBytesRead = dwTotalNumBytesRead + dwNumBytesRead; + } + while ((dwTotalNumBytesRead < dwNumBytesToRead) && (Status == FTC_SUCCESS)); + + *lpdwNumBytesRead = dwTotalNumBytesRead; + } + else + Status = FTC_ReadFixedNumBytesFromDevice(ftHandle, InputBuffer, dwNumBytesToRead, lpdwNumBytesRead); + + return Status; +} + + +// Define strupr and strlwr - not included in standard gcc libraries + + +//#if defined(__cplusplus) && __cplusplus +// extern "C" { +//#endif + +char* strupr(char *string) +{ + char *s; + + if (string) + { + for (s = string; *s; ++s) + *s = toupper(*s); + } + return string; +} + +char* strlwr(char *string) +{ + char *s; + + if (string) + { + for (s = string; *s; ++s) + *s = tolower(*s); + } + return string; +} + +//#if defined(__cplusplus) && __cplusplus +//} +//#endif Index: or_debug_proxy/src/vpi_functions.c =================================================================== --- or_debug_proxy/src/vpi_functions.c (nonexistent) +++ or_debug_proxy/src/vpi_functions.c (revision 1779) @@ -0,0 +1,613 @@ +/*$$HEADER*/ +/******************************************************************************/ +/* */ +/* H E A D E R I N F O R M A T I O N */ +/* */ +/******************************************************************************/ + +// Project Name : OpenRISC Debug Proxy +// File Name : vpi_functions.c +// Prepared By : jb +// Project Start : 2008-10-01 + +/*$$COPYRIGHT NOTICE*/ +/******************************************************************************/ +/* */ +/* C O P Y R I G H T N O T I C E */ +/* */ +/******************************************************************************/ +/* + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; + version 2.1 of the License, a copy of which is available from + http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/*$$DESCRIPTION*/ +/******************************************************************************/ +/* */ +/* D E S C R I P T I O N */ +/* */ +/******************************************************************************/ +// +// Implements communications with a Verilog RTL simulation via functions running +// in the simulator, attached via VPI. +// + + +/*$$CHANGE HISTORY*/ +/******************************************************************************/ +/* */ +/* C H A N G E H I S T O R Y */ +/* */ +/******************************************************************************/ + +// Date Version Description +//------------------------------------------------------------------------ +// 081101 First revision jb + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "gdb.h" + +#include "or_debug_proxy.h" + +#include "vpi_functions.h" + +// Definition of MSG_WAITALL -- appears to be missing from Cygwin's sys/socket.h +#ifdef CYGWIN_COMPILE +#define MSG_WAITALL 0 +#endif + +// socket stuff for connection to the VPI interface +int vpiPort = VPI_PORT; +int vpi_fd; // should be the descriptor for our connection to the VPI server + +#ifdef RTL_SIM +#define DBG_VPI 1 +#else +#define DBG_VPI 0 +#endif + +//Protocol ensuring synchronisation with the jp-rtl_sim program + +// 1. jp-rtl_sim will first write a command byte +// 2. jp-rtl_sim will then send the address if it's a read or write +// or the data to write if it's a dbg_cpu_wr_ctrl (stall & reset bits) +// 3. will then send data if we're writing and we sent address in 2 +// 4. wait for response from vpi functions + +// commands: +// 4'h1 jtag set instruction register (input: instruction value) +// 4'h2 set debug chain (dbg_set_command here) (input: chain value) +// 4'h3 cpu_ctrl_wr (input: ctrl value (2 bits)) +// 4'h4 cpu_ctrl_rd (output: ctrl value (2bits)) +// 4'h5 cpu wr reg (inputs: address, data) +// 4'h6 cpu rd reg (input: address; output: data) +// 4'h7 wb wr 32 (inputs: address, data) +// 4'h8 wb rd 32 (input: address; output: data) +// 4'h9 wb wr block 32 (inputs: address, length, data) +// 4'ha wb rd block 32 (inputs: address, length; output: data) +// 4'hb reset +// 4'hc read jtag id (output: data) + +#define CMD_JTAG_SET_IR 0x1 +#define CMD_SET_DEBUG_CHAIN 0x2 +#define CMD_CPU_CTRL_WR 0x3 +#define CMD_CPU_CTRL_RD 0x4 +#define CMD_CPU_WR_REG 0x5 +#define CMD_CPU_RD_REG 0x6 +#define CMD_WB_WR32 0x7 +#define CMD_WB_RD32 0x8 +#define CMD_WB_BLOCK_WR32 0x9 +#define CMD_WB_BLOCK_RD32 0xa +#define CMD_RESET 0xb +#define CMD_READ_JTAG_ID 0xc + + +void send_command_to_vpi(char CMD) +{ + // first thing we do is send a command + // and wait for an ack + uint32_t n; + char cmd_resp; + + n = write(vpi_fd,&CMD, 1); // send the command to the sim + + if (n < 0) perror("ERROR writing to VPI socket"); + + n = recv(vpi_fd,&cmd_resp,1, MSG_WAITALL); // block and wait for the ack + + if (n < 0) perror("ERROR Reading from VPI socket"); + + if (cmd_resp != CMD) perror("Response from RTL sim incorrect"); //check it acked with cmd + + return; +} + +void send_address_to_vpi(uint32_t address) +{ + // Now send address + uint32_t n; + + char* send_buf; + + address = htonl(address); + + send_buf = (char *) &address; + + n = write(vpi_fd,send_buf, 4); // send the address to the sim + + if (n < 0) perror("ERROR writing to VPI socket"); + + return; +} + +void send_data_to_vpi(uint32_t data) +{ + // Now send data + uint32_t n; + + data = htonl(data); + + char* send_buf; + + send_buf = (char *) &data; + + n = write(vpi_fd,send_buf, 4); // Write the data to the socket + + if (n < 0) perror("ERROR writing to VPI socket"); + + return; + +} + +void send_block_data_to_vpi(uint32_t len, uint32_t *data) +{ + // Now send data + uint32_t n, i; + + for (i = 0; i < (len/4); i++) + data[i] = htonl(data[i]); + + char* send_buf; + + send_buf = (char *) data; + + n = write(vpi_fd,send_buf, len); // Write the data to the socket + + if (n < 0) perror("ERROR writing to VPI socket"); + + return; + +} + +void get_data_from_vpi(uint32_t* data) +{ + + uint32_t n; + + uint32_t inc_data; + + char* recv_buf; + + recv_buf = (char*) &inc_data; + + n = recv(vpi_fd,recv_buf,4, MSG_WAITALL); // block and wait for the data + + if (n < 0) perror("ERROR Reading from VPI socket"); + + inc_data = ntohl(inc_data); + + if (DBG_VPI) printf("get_data_from_vpi: 0x%.8x\n",inc_data); + + *data = inc_data; + + return; + +} + +void get_block_data_from_vpi(uint32_t len, uint32_t* data) +{ + uint32_t n, i; + + char* recv_buf; + + recv_buf = (char *) data; + + n = recv(vpi_fd, recv_buf, len, MSG_WAITALL); // block and wait for the data + + if (n < 0) perror("ERROR Reading from VPI socket"); + + // re-order host compliant style the recieved words + if (DBG_VPI) printf("get_block_data_from_vpi: %d bytes",len); + for (i = 0;i < (len/4); i++) + { + data[i] = ntohl(data[i]); + + if (DBG_VPI) printf("0x%.8x ",data[i]); + } + if (DBG_VPI) printf("\n"); + + return; + +} + +void get_response_from_vpi() +{ + // Basically just wait for the response from VPI + // by blocking wait on recv + + uint32_t n; + char tmp; + + n = recv(vpi_fd,&tmp,1, MSG_WAITALL); // block and wait + + if (n < 0) perror("ERROR Reading from VPI socket"); + + return; +} + +/* Resets JTAG + Writes TRST=0 + and TRST=1 */ +static void jp2_reset_JTAG() { + + debug2("\nreset("); + + send_command_to_vpi(CMD_RESET); + + get_response_from_vpi(); + + debug2(")\n"); + +} + + +int vpi_connect() { + int sockfd; + struct sockaddr_in serv_addr; + struct hostent *server; + socklen_t flags; + char sTemp[256]; + + debug2("Started vpi_connect()\n"); + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + //sockfd = socket(PF_INET, SOCK_STREAM, 0); + + if (sockfd < 0) { + perror("ERROR opening socket"); + goto socket_setup_exit; + } + + server = gethostbyname("localhost"); + + if (server == NULL) { + fprintf(stderr,"ERROR, no such host\n"); + goto socket_setup_exit; + } + + /* + if(fcntl(sockfd, F_GETFL, &flags) < 0) { + sprintf(sTemp, "Unable to get flags for socket %d", sockfd); + perror(sTemp); + close(sockfd); + goto socket_setup_exit; + } + + // Set the nonblocking flag + if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) { + sprintf(sTemp, "Unable to set flags for socket %d to value 0x%08x", + sockfd, flags | O_NONBLOCK); + perror(sTemp); + close(sockfd); + goto socket_setup_exit; + } + */ + + bzero((char *) &serv_addr, sizeof(serv_addr)); + + serv_addr.sin_family = AF_INET; + + bcopy(server->h_addr,(char *)&serv_addr.sin_addr.s_addr,server->h_length); + + serv_addr.sin_port = htons(vpiPort); + + printf("Initialising connection with simulation\n"); + + if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) + { + perror("Error connecting"); + goto socket_setup_exit; + } + + return sockfd; + + socket_setup_exit: + if (vpi_fd) close(vpi_fd); + exit(1); + +} + +/* Resets JTAG, and sets DEBUG scan chain */ + int vpi_dbg_reset() { + + uint32_t id; + + jp2_reset_JTAG(); + + /* set idcode jtag chain */ + send_command_to_vpi(CMD_JTAG_SET_IR); + + send_data_to_vpi(JI_IDCODE); + + get_response_from_vpi(); + + /* now read out the jtag id */ + send_command_to_vpi(CMD_READ_JTAG_ID); + + //id = get_data_from_vpi(); + get_data_from_vpi((uint32_t *)&id); + + get_response_from_vpi(); + + printf("JTAG ID = %08x\n", (unsigned int) id); + + /* now set the chain to debug */ + send_command_to_vpi(CMD_JTAG_SET_IR); + + send_data_to_vpi(JI_DEBUG); + + get_response_from_vpi(); + + current_chain = -1; + return DBG_ERR_OK; +} + +void vpi_dbg_test() { + + uint32_t npc, ppc, r1; + unsigned char stalled; + + printf(" Stall or1k\n"); + dbg_cpu0_write_ctrl(0, 0x01); // stall or1k + + dbg_cpu0_read_ctrl(0, &stalled); + if (!(stalled & 0x1)) { + printf(" or1k stall failed. Exiting\n"); // check stall or1k + if (vpi_fd) close(vpi_fd); + exit(1); + } + + debug2(" Reading npc\n"); + dbg_cpu0_read((0 << 11) + 16, &npc); + debug2(" Reading ppc\n"); + dbg_cpu0_read((0 << 11) + 18, &ppc); + debug2(" Reading r1\n"); + dbg_cpu0_read(0x401, &r1); + printf(" Read npc = %.8x ppc = %.8x r1 = %.8x\n", npc, ppc, r1); + +} + +/* Sets scan chain. */ +int vpi_dbg_set_chain(uint32_t chain) { + //uint32_t status, crc_generated, crc_read; + + if (current_chain == chain) + return DBG_ERR_OK; + + dbg_chain = chain; + + send_command_to_vpi(CMD_SET_DEBUG_CHAIN); + + send_data_to_vpi(chain); + + get_response_from_vpi(); + + current_chain = chain; + + return DBG_ERR_OK; +} + +/* writes a ctrl reg */ +int vpi_dbg_ctrl(uint32_t reset, uint32_t stall) +{ + + debug("\n"); + debug2("ctrl\n"); + + vpi_dbg_set_chain(dbg_chain); + + send_command_to_vpi(CMD_CPU_CTRL_WR); + + //send_data_to_vpi(((reset & 0x1) | ((stall&0x1)<<1))); + send_data_to_vpi(((stall & 0x1) | ((reset&0x1)<<1))); + + get_response_from_vpi(); + + return DBG_ERR_OK; +} + +/* reads control register */ +int vpi_dbg_ctrl_read(uint32_t *reset, uint32_t *stall) +{ + + uint32_t resp; + + vpi_dbg_set_chain(dbg_chain); + + debug("\n"); + debug2("ctrl\n"); + + vpi_dbg_set_chain(dbg_chain); + + send_command_to_vpi(CMD_CPU_CTRL_RD); + + get_data_from_vpi((uint32_t *)&resp); + + if (DBG_VPI) printf(" dbg_ctrl_read: 0x%.8x\n",resp); + + get_response_from_vpi(); + + *reset = (resp & 0x00000001); + + *stall = ((resp >> 1) & 0x00000001); + + return DBG_ERR_OK; +} + +/* read a word from wishbone */ +int vpi_dbg_wb_read32(uint32_t adr, uint32_t *data) +{ + //uint32_t resp; + + vpi_dbg_set_chain(DC_WISHBONE); + + send_command_to_vpi(CMD_WB_RD32); + + send_address_to_vpi(adr); + + get_data_from_vpi(data); + + get_response_from_vpi(); + + return 0; +} + +/* write a word to wishbone */ +int vpi_dbg_wb_write32(uint32_t adr, uint32_t data) +{ + + vpi_dbg_set_chain(DC_WISHBONE); + + send_command_to_vpi(CMD_WB_WR32); + + send_address_to_vpi(adr); + + send_data_to_vpi(data); + + get_response_from_vpi(); + + return 0; +} + +/* read a block from wishbone */ +int vpi_dbg_wb_read_block32(uint32_t adr, uint32_t *data, uint32_t len) +{ + + // len is in B Y T E S ! ! + + if (DBG_VPI) printf("block read len: %d from addr: 0x%.8x\n",len, adr); + + vpi_dbg_set_chain(DC_WISHBONE); + + send_command_to_vpi(CMD_WB_BLOCK_RD32); + + send_data_to_vpi(adr); + + send_data_to_vpi(len); + + get_block_data_from_vpi(len, data); + + get_response_from_vpi(); + + return DBG_ERR_OK; +} + +/* write a block to wishbone */ +int vpi_dbg_wb_write_block32(uint32_t adr, uint32_t *data, uint32_t len) +{ + + vpi_dbg_set_chain(DC_WISHBONE); + + send_command_to_vpi(CMD_WB_BLOCK_WR32); + + send_data_to_vpi(adr); + + send_data_to_vpi(len); + + send_block_data_to_vpi(len, data); + + get_response_from_vpi(); + + return DBG_ERR_OK; +} + +/* read a register from cpu */ +int vpi_dbg_cpu0_read(uint32_t adr, uint32_t *data) +{ + + vpi_dbg_set_chain(DC_CPU0); + + send_command_to_vpi(CMD_CPU_RD_REG); + + send_address_to_vpi(adr); + + get_data_from_vpi(data); + + get_response_from_vpi(); + + return 0; + +} + +/* write a cpu register */ +int vpi_dbg_cpu0_write(uint32_t adr, uint32_t data) +{ + + vpi_dbg_set_chain(DC_CPU0); + + send_command_to_vpi(CMD_CPU_WR_REG); + + send_address_to_vpi(adr); + + send_data_to_vpi(data); + + get_response_from_vpi(); + + return 0; +} + + +/* write a cpu module register */ +int vpi_dbg_cpu0_write_ctrl(uint32_t adr, unsigned char data) { + uint32_t err; + if ((err = vpi_dbg_set_chain(DC_CPU0))) return err; + if ((err = vpi_dbg_ctrl(data & 2, data &1))) return err; + return DBG_ERR_OK; +} + +/* read a register from cpu module */ +int vpi_dbg_cpu0_read_ctrl(uint32_t adr, unsigned char *data) { + uint32_t err; + uint32_t r, s; + if ((err = vpi_dbg_set_chain(DC_CPU0))) return err; + if ((err = vpi_dbg_ctrl_read(&r, &s))) return err; + *data = (r << 1) | s; + return DBG_ERR_OK; +} Index: or_debug_proxy/src/or_debug_proxy.c =================================================================== --- or_debug_proxy/src/or_debug_proxy.c (nonexistent) +++ or_debug_proxy/src/or_debug_proxy.c (revision 1779) @@ -0,0 +1,363 @@ +/*$$HEADER*/ +/******************************************************************************/ +/* */ +/* H E A D E R I N F O R M A T I O N */ +/* */ +/******************************************************************************/ + +// Project Name : OpenRISC Debug Proxy +// File Name : or_debug_proxy.c +// Prepared By : jb +// Project Start : 2008-10-01 + +/*$$COPYRIGHT NOTICE*/ +/******************************************************************************/ +/* */ +/* C O P Y R I G H T N O T I C E */ +/* */ +/******************************************************************************/ +/* + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; + version 2.1 of the License, a copy of which is available from + http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/*$$DESCRIPTION*/ +/******************************************************************************/ +/* */ +/* D E S C R I P T I O N */ +/* */ +/******************************************************************************/ +// +// The entry point for the OpenRISC debug proxy console application. Is +// compilable under both Linux/Unix systems and Cygwin Windows. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Windows includes +#ifdef CYGWIN_COMPILE +#include +#include "win_FTCJTAG.h" +#include "win_FTCJTAG_ptrs.h" +#else +#include +void catch_sigint(int sig_num); // First param must be "int" +#endif + +#include "gdb.h" +#include "usb_functions.h" +#include "vpi_functions.h" +#include "or_debug_proxy.h" + +// Defines of endpoint numbers +#define ENDPOINT_TARGET_NONE 0 +#define ENDPOINT_TARGET_USB 1 +#define ENDPOINT_TARGET_VPI 2 +static int endpoint_target; // Either VPI interface via sockets, or the USB device + +#define GDB_PROTOCOL_JTAG 1 +#define GDB_PROTOCOL_RSP 2 +#define GDB_PROTOCOL_NONE 3 + +int err; // Global error value + +/* Currently selected scan chain - just to prevent unnecessary transfers. */ +int current_chain = -1; + +/* The chain that should be currently selected. */ +int dbg_chain = -1; + +int main(int argc, char *argv[]) { + + char *s; + int gdb_protocol = GDB_PROTOCOL_NONE; + endpoint_target = ENDPOINT_TARGET_NONE; + int inp_arg = 1; + + // init our global error number + err = DBG_ERR_OK; + + // Parse input options + if (argc < 3) + { + print_usage(); + exit(1); + } + + err = DBG_ERR_OK; + srand(getpid()); + + // Parse through the input, check what we've been given + + while ( argv[inp_arg] != NULL ) + { + if(strcmp(argv[inp_arg], "-j") == 0) + { + gdb_protocol = GDB_PROTOCOL_JTAG; + endpoint_target = ENDPOINT_TARGET_USB; + } + else if(strcmp(argv[inp_arg], "-r") == 0) + { + gdb_protocol = GDB_PROTOCOL_RSP; + endpoint_target = ENDPOINT_TARGET_USB; + } + else if(strcmp(argv[inp_arg], "-v") == 0) + { + gdb_protocol = GDB_PROTOCOL_RSP; + endpoint_target = ENDPOINT_TARGET_VPI; + } + else + { + serverPort = strtol(argv[2],&s,10); + } + + inp_arg++; + } + + if(endpoint_target == ENDPOINT_TARGET_NONE || gdb_protocol == GDB_PROTOCOL_NONE || serverPort > 65535 || *s != '\0') + { + print_usage(); + exit(1); + } + +#ifdef CYGWIN_COMPILE + // Load the FTCJTAG DLL function pointers + if (getFTDIJTAGFunctions() < 0){ + exit(-1); + } +#endif + +#ifndef CYGWIN_COMPILE + // Install a signal handler to exit gracefully + // when we receive a sigint + signal(SIGINT, catch_sigint); +#endif + + /* Initialise connection to our OR1k system */ + current_chain = -1; + /* USB Endpoint */ + if (endpoint_target == ENDPOINT_TARGET_USB) + { + printf("\nConnecting to OR1k via USB debug cable\n\n"); + if ((err = usb_dbg_reset())) goto JtagIfError; + dbg_test(); // Perform some tests + } + /* RTL simulation endpoint */ + else if (endpoint_target == ENDPOINT_TARGET_VPI){ + printf("\nConnecting to OR1k RTL simulation\n\n"); + // Connect to the (hopefully) already running RTL simulation server running via VPI + vpi_fd = vpi_connect(); + + if ((err = vpi_dbg_reset())) goto JtagIfError; + vpi_dbg_test(); // Perform some tests + } + + /* We have a connection to the target system. Now establish server connection. */ + if(gdb_protocol == GDB_PROTOCOL_JTAG) + { // Connect to JTAG server + if((server_fd = GetServerSocket("or1ksim","tcp", serverPort))) { + // printf("JTAG Proxy server started on port %d\n", serverPort); + printf("Remote JTAG proxy server started on port %d\n", serverPort); + printf("Note: The OpenRISC remote JTAG protocol is now DEPRECATED. Please use GDB version 6.8 or later.\n"); + printf("Press CTRL+c to exit.\n"); + } else { + // fprintf(stderr,"Cannot start JTAG Proxy server on port %d\n", serverPort); + fprintf(stderr,"Cannot start Proxy server on port %d\n", serverPort); + exit(-1); + } + + /* Do endless loop of checking and handle GDB requests. Ctrl-c exits. */ + // HandleServerSocket(true); + HandleServerSocket(); + return 0; + } + else if(gdb_protocol == GDB_PROTOCOL_RSP) + { // Connect to RSP server + /* RSP always starts stalled as though we have just reset the processor. */ + // rsp_exception (EXCEPT_TRAP); + handle_rsp (); + // if((server_fd = GetServerSocket("or1ksim","tcp", serverPort))) { + }else { + fprintf(stderr,"Cannot start RSP Proxy server on port %d\n", serverPort); + exit(-1); + } + + +JtagIfError: + fprintf(stderr,"Connection via USB debug cable failed (err = %d).\nPlease ensure the device is attached and correctly installed\n\n", err); + exit(-1); + return 0; +} + + + +int dbg_reset() +{ + if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_reset(); + else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_reset(); + else return DBG_ERR_INVALID_ENDPOINT; +} + +void dbg_test() { + if (endpoint_target == ENDPOINT_TARGET_USB) usb_dbg_test(); + else if (endpoint_target == ENDPOINT_TARGET_VPI) vpi_dbg_test(); +} + +/* Set TAP instruction register */ +int dbg_set_tap_ir(uint32_t ir) { + if (endpoint_target == ENDPOINT_TARGET_USB) usb_set_tap_ir(ir); + else return DBG_ERR_INVALID_ENDPOINT; + return 0; +} + +/* Sets scan chain. */ +int dbg_set_chain(uint32_t chain) { + if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_set_chain(chain); + else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_set_chain(chain); + else return DBG_ERR_INVALID_ENDPOINT; +} + +/* sends out a command with 32bit address and 16bit length, if len >= 0 */ +int dbg_command(uint32_t type, uint32_t adr, uint32_t len) { + // This is never called by any of the VPI functions, so only USB endpoint + if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_command(type,adr,len); + else return DBG_ERR_INVALID_ENDPOINT; +} + +/* writes a ctrl reg */ +int dbg_ctrl(uint32_t reset, uint32_t stall) { + if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_ctrl(reset, stall); + else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_ctrl(reset, stall); + else return DBG_ERR_INVALID_ENDPOINT; +} + +/* reads control register */ +int dbg_ctrl_read(uint32_t *reset, uint32_t *stall) { + if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_ctrl_read(reset, stall); + else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_ctrl_read(reset, stall); + else return DBG_ERR_INVALID_ENDPOINT; +} + +/* issues a burst read/write */ +int dbg_go(unsigned char *data, uint16_t len, uint32_t read) { + // Only USB endpouint32_t option here + if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_go(data, len, read); + else return DBG_ERR_INVALID_ENDPOINT; +} + +/* read a word from wishbone */ +int dbg_wb_read32(uint32_t adr, uint32_t *data) { + if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_wb_read32(adr, data); + else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_wb_read32(adr, data); + else return DBG_ERR_INVALID_ENDPOINT; +} + + +/* write a word to wishbone */ +int dbg_wb_write32(uint32_t adr, uint32_t data) { + if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_wb_write32( adr, data); + else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_wb_write32( adr, data); + else return DBG_ERR_INVALID_ENDPOINT; +} + +/* read a block from wishbone */ +int dbg_wb_read_block32(uint32_t adr, uint32_t *data, uint32_t len) { + if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_wb_read_block32( adr, data, len); + else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_wb_read_block32( adr, data, len); + else return DBG_ERR_INVALID_ENDPOINT; +} + + +/* write a block to wishbone */ +int dbg_wb_write_block32(uint32_t adr, uint32_t *data, uint32_t len) { + if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_wb_write_block32( adr, data, len); + else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_wb_write_block32( adr, data, len); + else return DBG_ERR_INVALID_ENDPOINT; +} + +/* read a register from cpu */ +int dbg_cpu0_read(uint32_t adr, uint32_t *data) { + if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_cpu0_read( adr, data); + else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_cpu0_read( adr, data); + else return DBG_ERR_INVALID_ENDPOINT; +} + +/* write a cpu register */ +int dbg_cpu0_write(uint32_t adr, uint32_t data) { + if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_cpu0_write( adr, data); + else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_cpu0_write( adr, data); + else return DBG_ERR_INVALID_ENDPOINT; +} + +/* write a cpu module register */ +int dbg_cpu0_write_ctrl(uint32_t adr, unsigned char data) { + if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_cpu0_write_ctrl( adr, data); + else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_cpu0_write_ctrl( adr, data); + else return DBG_ERR_INVALID_ENDPOINT; +} + + +/* read a register from cpu module */ +int dbg_cpu0_read_ctrl(uint32_t adr, unsigned char *data) { + if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_cpu0_read_ctrl( adr, data); + else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_cpu0_read_ctrl( adr, data); + else return DBG_ERR_INVALID_ENDPOINT; +} + + +void test_sdram(void) { + return; +} + +// Close down gracefully when we receive any kill signals +void catch_sigint(int sig_num) +{ + // Close down any potentially open sockets and USB handles + if (vpi_fd) close(vpi_fd); + if (server_fd) close(server_fd); + usb_close_device_handle(); + gdb_close(); + printf("\nInterrupt signal received. Closing down connections and exiting\n\n"); + exit(0); +} + +void print_usage() +{ + printf("Invalid or insufficient arguments\n"); + printf("\n"); + printf("OpenRISC GDB proxy server usage: or_debug_proxy -server_type port\n"); + printf("\n"); + printf("server_type:\n"); + printf("\t-r Start a server using RSP, connection to hadware target via\n\t USB\n"); + printf("\t-j Start a server using legacy OR remote JTAG protocol, to\n\t hardware target via USB\n"); + printf("\t-v Start a server using RSP, connection to RTL sim. VPI server\n\t target via sockets\n"); + printf("\n"); + printf("port:\n"); + printf("\tAny free port within the usable range of 0 - 65535\n"); + printf("\n"); + printf("Example:\n"); + printf("\tStart a GDB server on port 5555, using RSP, connecting to\n\thardware target via USB\n"); + printf("\tor_debug_proxy -r 5555\n"); + printf("\n"); + fflush (stdout); +} Index: or_debug_proxy/src/gdb.c =================================================================== --- or_debug_proxy/src/gdb.c (nonexistent) +++ or_debug_proxy/src/gdb.c (revision 1779) @@ -0,0 +1,4031 @@ +/*$$HEADER*/ +/******************************************************************************/ +/* */ +/* H E A D E R I N F O R M A T I O N */ +/* */ +/******************************************************************************/ + +// Project Name : OpenRISC Debug Proxy +// File Name : gdb.c +// Prepared By : jb, rmd +// Project Start : 2008-10-01 + +/*$$COPYRIGHT NOTICE*/ +/******************************************************************************/ +/* */ +/* C O P Y R I G H T N O T I C E */ +/* */ +/******************************************************************************/ +/* + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; + version 2.1 of the License, a copy of which is available from + http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/*$$DESCRIPTION*/ +/******************************************************************************/ +/* */ +/* D E S C R I P T I O N */ +/* */ +/******************************************************************************/ +// +// Implements GDB stub for OpenRISC debug proxy. +// + + +/*$$CHANGE HISTORY*/ +/******************************************************************************/ +/* */ +/* C H A N G E H I S T O R Y */ +/* */ +/******************************************************************************/ + +// Date Version Description +//------------------------------------------------------------------------ +// 081101 Imported code from "jp" project jb +// 090219 Adapted code from Jeremy Bennett's RSP server +// for the or1ksim project. rmb +// 090304 Finished RSP server code import, added extra +// functions, adding stability when debugging on +// a remote target. jb + +#ifdef CYGWIN_COMPILE + +#else +// linux includes +#include +#endif + +#include +#include +#include +#include +#include +#include + +/* Libraries for JTAG proxy server. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/*! Name of the Or1ksim RSP service */ +#define OR1KSIM_RSP_SERVICE "or1ksim-rsp" + +#include "gdb.h" /* partially copied from gdb/config/or1k */ +#include "or_debug_proxy.h" + +#define MAX_GPRS (32) + +/* Indices of GDB registers that are not GPRs. Must match GDB settings! */ +#define PPC_REGNUM (MAX_GPRS + 0) /*!< Previous PC */ +#define NPC_REGNUM (MAX_GPRS + 1) /*!< Next PC */ +#define SR_REGNUM (MAX_GPRS + 2) /*!< Supervision Register */ +#define NUM_REGS (MAX_GPRS + 3) /*!< Total GDB registers */ + +/* OR1k CPU registers address */ +#define NPC_CPU_REG_ADD 0x10 /* Next PC */ +#define SR_CPU_REG_ADD 0x11 /* Supervision Register */ +#define PPC_CPU_REG_ADD 0x12 /* Previous PC */ +#define DMR1_CPU_REG_ADD ((6 << 11) + 16) /* Debug Mode Register 1 (DMR1) 0x3010 */ +#define DMR2_CPU_REG_ADD ((6 << 11) + 17) /* Debug Mode Register 2 (DMR2) 0x3011 */ +#define DSR_CPU_REG_ADD ((6 << 11) + 20) /* Debug Stop Register (DSR) 0x3014 */ +#define DRR_CPU_REG_ADD ((6 << 11) + 21) /* Debug Reason Register (DRR) 0x3015 */ + +/*! Trap instruction for OR32 */ +#define OR1K_TRAP_INSTR 0x21000001 + +/*! The maximum number of characters in inbound/outbound buffers. The largest + packets are the 'G' packet, which must hold the 'G' and all the registers + with two hex digits per byte and the 'g' reply, which must hold all the + registers, and (in our implementation) an end-of-string (0) + character. Adding the EOS allows us to print out the packet as a + string. So at least NUMREGBYTES*2 + 1 (for the 'G' or the EOS) are needed + for register packets */ +#define GDB_BUF_MAX ((NUM_REGS) * 8 + 1) + +/*! Size of the matchpoint hash table. Largest prime < 2^10 */ +#define MP_HASH_SIZE 1021 + +/* Definition of special-purpose registers (SPRs). */ +#define MAX_SPRS (0x10000) + +#define SPR_DMR1_ST 0x00400000 /* Single-step trace*/ +#define SPR_DMR2_WGB 0x003ff000 /* Watchpoints generating breakpoint */ +#define SPR_DSR_TE 0x00002000 /* Trap exception */ + +#define WORDSBIGENDIAN_N + +/* Definition of OR1K exceptions */ +#define EXCEPT_NONE 0x0000 +#define EXCEPT_RESET 0x0100 +#define EXCEPT_BUSERR 0x0200 +#define EXCEPT_DPF 0x0300 +#define EXCEPT_IPF 0x0400 +#define EXCEPT_TICK 0x0500 +#define EXCEPT_ALIGN 0x0600 +#define EXCEPT_ILLEGAL 0x0700 +#define EXCEPT_INT 0x0800 +#define EXCEPT_DTLBMISS 0x0900 +#define EXCEPT_ITLBMISS 0x0a00 +#define EXCEPT_RANGE 0x0b00 +#define EXCEPT_SYSCALL 0x0c00 +#define EXCEPT_FPE 0x0d00 +#define EXCEPT_TRAP 0x0e00 + +// Changed to #defines from static const int's due to compile error +// DRR (Debug Reason Register) Bits +#define SPR_DRR_RSTE 0x00000001 //!< Reset +#define SPR_DRR_BUSEE 0x00000002 //!< Bus error +#define SPR_DRR_DPFE 0x00000004 //!< Data page fault +#define SPR_DRR_IPFE 0x00000008 //!< Insn page fault +#define SPR_DRR_TTE 0x00000010 //!< Tick timer +#define SPR_DRR_AE 0x00000020 //!< Alignment +#define SPR_DRR_IIE 0x00000040 //!< Illegal instruction +#define SPR_DRR_IE 0x00000080 //!< Interrupt +#define SPR_DRR_DME 0x00000100 //!< DTLB miss +#define SPR_DRR_IME 0x00000200 //!< ITLB miss +#define SPR_DRR_RE 0x00000400 //!< Range fault +#define SPR_DRR_SCE 0x00000800 //!< System call +#define SPR_DRR_FPE 0x00001000 //!< Floating point +#define SPR_DRR_TE 0x00002000 //!< Trap + + +/*! Definition of GDB target signals. Data taken from the GDB 6.8 + source. Only those we use defined here. The exact meaning of + signal number is defined by the header `include/gdb/signals.h' + in the GDB source code. For an explanation of what each signal + means, see target_signal_to_string.*/ +enum target_signal { + TARGET_SIGNAL_NONE = 0, + TARGET_SIGNAL_INT = 2, + TARGET_SIGNAL_ILL = 4, + TARGET_SIGNAL_TRAP = 5, + TARGET_SIGNAL_FPE = 8, + TARGET_SIGNAL_BUS = 10, + TARGET_SIGNAL_SEGV = 11, + TARGET_SIGNAL_ALRM = 14, + TARGET_SIGNAL_USR2 = 31, + TARGET_SIGNAL_PWR = 32 +}; + +/*! String to map hex digits to chars */ +static const char hexchars[]="0123456789abcdef"; + + +//! Is the NPC cached? + +//! Setting the NPC flushes the pipeline, so subsequent reads will return +//! zero until the processor has refilled the pipeline. This will not be +//! happening if the processor is stalled (as it is when GDB had control), +//! so we must cache the NPC. As soon as the processor is unstalled, this +//! cached value becomes invalid. So we must track the stall state, and if +//! appropriate cache the NPC. +enum stallStates { + STALLED, + UNSTALLED, + UNKNOWN +} stallState; + +int npcIsCached; //!< Is the NPC cached - should be bool +uint32_t npcCachedValue; //!< Cached value of the NPC + + + + +/************************ + JTAG Server Routines +************************/ +int serverIP = 0; +int serverPort = 0; +int server_fd = 0; +int gdb_fd = 0; + +static int tcp_level = 0; + +/* global to store what chain the debug unit is currently connected to +(not the JTAG TAP, but the onchip debug module has selected) */ +int gdb_chain = -1; + +/*! Data structure for RSP buffers. Can't be null terminated, since it may + include zero bytes */ +struct rsp_buf +{ + char data[GDB_BUF_MAX]; + int len; +}; + +/*! Enumeration of different types of matchpoint. These have explicit values + matching the second digit of 'z' and 'Z' packets. */ +enum mp_type { + BP_MEMORY = 0, // software-breakpoint Z0 break + BP_HARDWARE = 1, // hardware-breakpoint Z1 hbreak + WP_WRITE = 2, // write-watchpoint Z2 watch + WP_READ = 3, // read-watchpoint Z3 rwatch + WP_ACCESS = 4 // access-watchpoint Z4 awatch +}; + +/*! Data structure for a matchpoint hash table entry */ +struct mp_entry +{ + enum mp_type type; /*!< Type of matchpoint */ + uint32_t addr; /*!< Address with the matchpoint */ + uint32_t instr; /*!< Substituted instruction */ + struct mp_entry *next; /*!< Next entry with this hash */ +}; + +/*! Central data for the RSP connection */ +static struct +{ + int client_waiting; /*!< Is client waiting a response? */ +// Not used int proto_num; /*!< Number of the protocol used */ + int client_fd; /*!< FD for talking to GDB */ + int sigval; /*!< GDB signal for any exception */ + uint32_t start_addr; /*!< Start of last run */ + struct mp_entry *mp_hash[MP_HASH_SIZE]; /*!< Matchpoint hash table */ +} rsp; + +/* Forward declarations of static functions */ +static char *printTime(void); +static int gdb_read(void*, int); +static int gdb_write(void*, int); +static void ProtocolClean(int, int32_t); +static void GDBRequest(void); +static void rsp_interrupt(); +static unsigned char rsp_peek(); +static struct rsp_buf *get_packet (void); +static void rsp_init (void); +static void set_npc (uint32_t addr); +static uint32_t get_npc(); +static void rsp_check_for_exception(); +static int check_for_exception_vector(uint32_t ppc); +static void rsp_exception (uint32_t except); +static int get_rsp_char (void); +static int hex (int c); +static void rsp_get_client (void); +static void rsp_client_request (void); +static void rsp_client_close (void); +static void client_close (char err); +static void put_str_packet (const char *str); +static void rsp_report_exception (void); +static void put_packet (struct rsp_buf *p_buf); +static void send_rsp_str (unsigned char *data, int len); +static void rsp_query (struct rsp_buf *p_buf); +static void rsp_vpkt (struct rsp_buf *p_buf); +static void rsp_step (struct rsp_buf *p_buf); +static void rsp_step_with_signal (struct rsp_buf *p_buf); +static void rsp_step_generic (uint32_t addr, uint32_t except); +static void rsp_continue (struct rsp_buf *p_buf); +static void rsp_continue_with_signal (struct rsp_buf *p_buf); +static void rsp_continue_generic (uint32_t addr, uint32_t except); +static void rsp_read_all_regs (void); +static void rsp_write_all_regs (struct rsp_buf *p_buf); +static void rsp_read_mem (struct rsp_buf *p_buf); +static void rsp_write_mem (struct rsp_buf *p_buf); +static void rsp_write_mem_bin (struct rsp_buf *p_buf); +static int rsp_unescape (char *data, int len); +static void rsp_read_reg (struct rsp_buf *p_buf); +static void rsp_write_reg (struct rsp_buf *p_buf); +static void mp_hash_init (void); +static void mp_hash_add (enum mp_type type, uint32_t addr, uint32_t instr); +static struct mp_entry * mp_hash_lookup (enum mp_type type, uint32_t addr); +static struct mp_entry * mp_hash_delete (enum mp_type type, uint32_t addr); +static void rsp_remove_matchpoint (struct rsp_buf *p_buf); +static void rsp_insert_matchpoint (struct rsp_buf *p_buf); +static void rsp_command (struct rsp_buf *p_buf); +static void rsp_set (struct rsp_buf *p_buf); +static void rsp_restart (void); +static void ascii2hex (char *dest,char *src); +static void hex2ascii (char *dest, char *src); +static uint32_t hex2reg (char *p_buf); +static void reg2hex (uint32_t val, char *p_buf); +static void swap_buf(char* p_buf, int len); +static void set_stall_state (int state); +static void gdb_ensure_or1k_stalled(); +static int gdb_set_chain(int chain); +static int gdb_write_reg(uint32_t adr, uint32_t data); +static int gdb_read_reg(uint32_t adr, uint32_t *data); +static int gdb_write_block(uint32_t adr, uint32_t *data, int len); +static int gdb_read_block(uint32_t adr, uint32_t *data, int len); + +char *printTime(void) +{ + time_t tid; + struct tm *strtm; + static char timeBuf[20]; + + time(&tid); + strtm = localtime(&tid); + sprintf(timeBuf,"[%.02d:%.02d:%.02d] ",strtm->tm_hour,strtm->tm_min,strtm->tm_sec); + return timeBuf; +} + +/*---------------------------------------------------------------------------*/ +/*!Initialize the Remote Serial Protocol connection + + Set up the central data structures. */ +/*---------------------------------------------------------------------------*/ +void +rsp_init (void) +{ + /* Clear out the central data structure */ + rsp.client_waiting = 0; /* GDB client is not waiting for us */ + rsp.client_fd = -1; /* i.e. invalid */ + rsp.sigval = 0; /* No exception */ + rsp.start_addr = EXCEPT_RESET; /* Default restart point */ + + /* Set up the matchpoint hash table */ + mp_hash_init (); + + /* RSP always starts stalled as though we have just reset the processor. */ + rsp_exception (EXCEPT_TRAP); + + /* Setup the NPC caching variables */ + stallState = STALLED; + // Force a caching of the NPC + npcIsCached = 0; + get_npc(); + +} /* rsp_init () */ + +/*---------------------------------------------------------------------------*/ +/*!Look for action on RSP + + This function is called when the processor has stalled, which, except for + initialization, must be due to an interrupt. + + If we have no RSP client, we get one. We can make no progress until the + client is available. + + Then if the cause is an exception following a step or continue command, and + the exception not been notified to GDB, a packet reporting the cause of the + exception is sent. + + The next client request is then processed. */ +/*---------------------------------------------------------------------------*/ +void +handle_rsp (void) +{ + uint32_t temp_uint32; + + rsp_init(); + + while (1){ + /* If we have no RSP client, wait until we get one. */ + while (-1 == rsp.client_fd) + { + rsp_get_client (); + rsp.client_waiting = 0; /* No longer waiting */ + } + + /* If we have an unacknowledged exception tell the GDB client. If this + exception was a trap due to a memory breakpoint, then adjust the NPC. */ + if (rsp.client_waiting) + { + + // Check for exception + rsp_check_for_exception(); + + if(DEBUG_GDB) + { + gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32); + printf("PPC is currently 0x%08x\n", temp_uint32); + } + + // Get the PPC to check if we've hit a software breakpoint + gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32); + + if ((TARGET_SIGNAL_TRAP == rsp.sigval) && (NULL != mp_hash_lookup (BP_MEMORY, temp_uint32))) + { + if (stallState != STALLED) + // This is a quick fix for a strange situation seen in some of the simulators where + // the sw bp would be detected, but the stalled state variable wasn't updated correctly + // indicating that last time it checked, it wasn't set but the processor has now hit the + // breakpoint. So run rsp_check_for_exception() to bring everything up to date. + rsp_check_for_exception(); + + if(DEBUG_GDB) printf("Software breakpoint hit at 0x%08x. Rolling back NPC to this instruction\n", temp_uint32); + + set_npc (temp_uint32); + + rsp_report_exception(); + rsp.client_waiting = 0; /* No longer waiting */ + } + else if(stallState == STALLED) { + // If we're here, the thing has stalled, but not because of a breakpoint we set + // report back the exception + + rsp_report_exception(); + rsp.client_waiting = 0; /* No longer waiting */ + + } + // Check if PPC is at a known exception vector + // (Illegal inst., unaligned access, etc.) + else if (check_for_exception_vector(temp_uint32)) + { + rsp_report_exception(); + rsp.client_waiting = 0; + } + + if (rsp.client_waiting) + sleep(1); + + } + + + + // See if there's any incoming data from the client by peeking at the socket + if (rsp_peek() > 0) + { + if (rsp_peek() == 0x03 && (stallState != STALLED)) // ETX, end of text control char + { + // Got an interrupt command from GDB, this function should + // pull the packet off the socket and stall the processor. + // and then send a stop reply packet with signal TARGET_SIGNAL_NONE + rsp_interrupt(); + rsp.client_waiting = 0; + } + else if (rsp.client_waiting == 0) + { + // Default handling of data from the client: + /* Get a RSP client request */ + rsp_client_request (); + } + } /* end if (rsp_peek() > 0) */ + } +} /* handle_rsp () */ + + +/* + Check if processor is stalled - if it is, read the DRR + and return the target signal code +*/ +static void rsp_check_for_exception() +{ + + unsigned char stalled; + uint32_t drr; + err = dbg_cpu0_read_ctrl(0, &stalled); /* check if we're stalled */ + + if (!(stalled & 0x01)) + { + // Processor not stalled. Just return; + return; + } + + if (DEBUG_GDB) printf("rsp_check_for_exception() detected processor was stalled\nChecking DRR\n"); + + // We're stalled + stallState = STALLED; + npcIsCached = 0; + + gdb_set_chain(SC_RISC_DEBUG); + + // Now read the DRR (Debug Reason Register) + gdb_read_reg(DRR_CPU_REG_ADD, &drr); + + if (DEBUG_GDB) printf("DRR: 0x%08x\n", drr); + + switch ((int)(drr&0xffffffff)) + { + case SPR_DRR_RSTE: rsp.sigval = TARGET_SIGNAL_PWR; break; + case SPR_DRR_BUSEE: rsp.sigval = TARGET_SIGNAL_BUS; break; + case SPR_DRR_DPFE: rsp.sigval = TARGET_SIGNAL_SEGV; break; + case SPR_DRR_IPFE: rsp.sigval = TARGET_SIGNAL_SEGV; break; + case SPR_DRR_TTE: rsp.sigval = TARGET_SIGNAL_ALRM; break; + case SPR_DRR_AE: rsp.sigval = TARGET_SIGNAL_BUS; break; + case SPR_DRR_IIE: rsp.sigval = TARGET_SIGNAL_ILL; break; + case SPR_DRR_IE: rsp.sigval = TARGET_SIGNAL_INT; break; + case SPR_DRR_DME: rsp.sigval = TARGET_SIGNAL_SEGV; break; + case SPR_DRR_IME: rsp.sigval = TARGET_SIGNAL_SEGV; break; + case SPR_DRR_RE: rsp.sigval = TARGET_SIGNAL_FPE; break; + case SPR_DRR_SCE: rsp.sigval = TARGET_SIGNAL_USR2; break; + case SPR_DRR_FPE: rsp.sigval = TARGET_SIGNAL_FPE; break; + case SPR_DRR_TE: rsp.sigval = TARGET_SIGNAL_TRAP; break; + + default: + // This must be the case of single step (which does not set DRR) + rsp.sigval = TARGET_SIGNAL_TRAP; break; + } + + if (DEBUG_GDB) printf("rsp.sigval: 0x%x\n", rsp.sigval); + + return; +} + +/*---------------------------------------------------------------------------*/ +/*!Check if PPC is in an exception vector that halts program flow + +Compare the provided PPC with known exception vectors that are fatal +to a program's execution. Call rsp_exception(ppc) to set the appropriate +sigval and return. + +@param[in] ppc Value of current PPC, as read from debug unit +@return: 1 if we set a sigval and should return control to GDB, else 0 */ +/*---------------------------------------------------------------------------*/ +static int +check_for_exception_vector(uint32_t ppc) +{ + switch(ppc) + { + // The following should return sigvals to GDB for processing + case EXCEPT_BUSERR: + case EXCEPT_ALIGN: + case EXCEPT_ILLEGAL: + case EXCEPT_TRAP: if(DEBUG_GDB) + printf("PPC at exception address\n"); + rsp_exception(ppc); + return 1; + + default: + return 0; + } + return 1; +} + +/*---------------------------------------------------------------------------*/ +/*!Note an exception for future processing + + The simulator has encountered an exception. Record it here, so that a + future call to handle_exception will report it back to the client. The + signal is supplied in Or1ksim form and recorded in GDB form. + + We flag up a warning if an exception is already pending, and ignore the + earlier exception. + + @param[in] except The exception (Or1ksim form) */ +/*---------------------------------------------------------------------------*/ +void +rsp_exception (uint32_t except) +{ + int sigval; /* GDB signal equivalent to exception */ + + switch (except) + { + case EXCEPT_RESET: sigval = TARGET_SIGNAL_PWR; break; + case EXCEPT_BUSERR: sigval = TARGET_SIGNAL_BUS; break; + case EXCEPT_DPF: sigval = TARGET_SIGNAL_SEGV; break; + case EXCEPT_IPF: sigval = TARGET_SIGNAL_SEGV; break; + case EXCEPT_TICK: sigval = TARGET_SIGNAL_ALRM; break; + case EXCEPT_ALIGN: sigval = TARGET_SIGNAL_BUS; break; + case EXCEPT_ILLEGAL: sigval = TARGET_SIGNAL_ILL; break; + case EXCEPT_INT: sigval = TARGET_SIGNAL_INT; break; + case EXCEPT_DTLBMISS: sigval = TARGET_SIGNAL_SEGV; break; + case EXCEPT_ITLBMISS: sigval = TARGET_SIGNAL_SEGV; break; + case EXCEPT_RANGE: sigval = TARGET_SIGNAL_FPE; break; + case EXCEPT_SYSCALL: sigval = TARGET_SIGNAL_USR2; break; + case EXCEPT_FPE: sigval = TARGET_SIGNAL_FPE; break; + case EXCEPT_TRAP: sigval = TARGET_SIGNAL_TRAP; break; + + default: + fprintf (stderr, "Warning: Unknown RSP exception %u: Ignored\n", except); + return; + } + + if ((0 != rsp.sigval) && (sigval != rsp.sigval)) + { + fprintf (stderr, "Warning: RSP signal %d received while signal " + "%d pending: Pending exception replaced\n", sigval, rsp.sigval); + } + + rsp.sigval = sigval; /* Save the signal value */ + +} /* rsp_exception () */ + + +/*---------------------------------------------------------------------------*/ +/*!Get a new client connection. + + Blocks until the client connection is available. + + A lot of this code is copied from remote_open in gdbserver remote-utils.c. + + This involves setting up a socket to listen on a socket for attempted + connections from a single GDB instance (we couldn't be talking to multiple + GDBs at once!). + + The service is specified either as a port number in the Or1ksim configuration + (parameter rsp_port in section debug, default 51000) or as a service name + in the constant OR1KSIM_RSP_SERVICE. + + The protocol used for communication is specified in OR1KSIM_RSP_PROTOCOL. */ +/*---------------------------------------------------------------------------*/ +static void +rsp_get_client (void) +{ + int tmp_fd; /* Temporary descriptor for socket */ + int optval; /* Socket options */ + struct sockaddr_in sock_addr; /* Socket address */ + socklen_t len; /* Size of the socket address */ + + /* 0 is used as the RSP port number to indicate that we should use the + service name instead. */ + if (0 == serverPort) + { + struct servent *service = getservbyname (OR1KSIM_RSP_SERVICE, "tcp"); + if (NULL == service) + { + fprintf (stderr, "Warning: RSP unable to find service \"%s\": %s\n", + OR1KSIM_RSP_SERVICE, strerror (errno)); + return; + } + serverPort = ntohs (service->s_port); + } + + /* Open a socket on which we'll listen for clients */ + tmp_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (tmp_fd < 0) + { + fprintf (stderr, "ERROR: Cannot open RSP socket\n"); + exit (0); + } + + /* Allow rapid reuse of the port on this socket */ + optval = 1; + setsockopt (tmp_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, + sizeof (optval)); + + /* Bind the port to the socket */ + sock_addr.sin_family = PF_INET; + sock_addr.sin_port = htons (serverPort); + sock_addr.sin_addr.s_addr = INADDR_ANY; + if (bind (tmp_fd, (struct sockaddr *) &sock_addr, sizeof (sock_addr))) + { + fprintf (stderr, "ERROR: Cannot bind to RSP socket\n"); + exit (0); + } + + /* Listen for (at most one) client */ + if (0 != listen (tmp_fd, 1)) + { + fprintf (stderr, "ERROR: Cannot listen on RSP socket\n"); + exit (0); + } + + printf("Waiting for gdb connection on localhost:%d\n", serverPort); + fflush (stdout); + + printf("Press CTRL+c to exit.\n"); + fflush (stdout); + + /* Accept a client which connects */ + len = sizeof (sock_addr); + rsp.client_fd = accept (tmp_fd, (struct sockaddr *)&sock_addr, &len); + + if (-1 == rsp.client_fd) + { + fprintf (stderr, "Warning: Failed to accept RSP client\n"); + return; + } + + /* Enable TCP keep alive process */ + optval = 1; + setsockopt (rsp.client_fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, + sizeof (optval)); + + /* Set socket to be non-blocking */ + + /* We do this because when we're given a continue, or step + instruction,command we set the processor stall off, then instnatly check + if it's stopped. If it hasn't then we drop through and wait for input + from GDB. Obviously this will cause problems when it will stop after we + do the check. So now, rsp_peek() has been implemented to simply check if + there's an incoming command from GDB (only interested in interrupt + commands), otherwise it returns back to and poll the processor's PPC and + stall bit. It can only do this if the socket is non-blocking. + + At first test, simply adding this line appeared to give no problems with + the existing code. No "simulation" of blocking behaviour on the + non-blocking socket was required (in the event that a read/write throws + back a EWOULDBLOCK error, as was looked to be the case in the previous + GDB handling code) -- Julius + */ + if (ioctl(rsp.client_fd, FIONBIO, (char *)&optval) > 0 ) + { + perror("ioctl() failed"); + close(rsp.client_fd); + close(tmp_fd); + exit(0); + } + + /* Don't delay small packets, for better interactive response (disable + Nagel's algorithm) */ + optval = 1; + setsockopt (rsp.client_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&optval, + sizeof (optval)); + + /* Socket is no longer needed */ + close (tmp_fd); /* No longer need this */ + signal (SIGPIPE, SIG_IGN); /* So we don't exit if client dies */ + + printf ("Remote debugging from host %s\n", inet_ntoa (sock_addr.sin_addr)); +} /* rsp_get_client () */ + + +/*---------------------------------------------------------------------------*/ +/*!Deal with a request from the GDB client session + + In general, apart from the simplest requests, this function replies on + other functions to implement the functionality. */ +/*---------------------------------------------------------------------------*/ +static void rsp_client_request (void) +{ + struct rsp_buf *p_buf = get_packet (); /* Message sent to us */ + + // Null packet means we hit EOF or the link was closed for some other + // reason. Close the client and return + if (NULL == p_buf) + { + rsp_client_close (); + return; + } + + if (DEBUG_GDB){ + printf("%s-----------------------------------------------------\n", printTime()); + printf ("Packet received %s: %d chars\n", p_buf->data, p_buf->len ); + fflush (stdout); + } + + switch (p_buf->data[0]) + { + case '!': + /* Request for extended remote mode */ + put_str_packet ("OK"); // OK = supports and has enabled extended mode. + return; + + case '?': + /* Return last signal ID */ + rsp_report_exception(); + return; + + case 'A': + /* Initialization of argv not supported */ + fprintf (stderr, "Warning: RSP 'A' packet not supported: ignored\n"); + put_str_packet ("E01"); + return; + + case 'b': + /* Setting baud rate is deprecated */ + fprintf (stderr, "Warning: RSP 'b' packet is deprecated and not " + "supported: ignored\n"); + return; + + case 'B': + /* Breakpoints should be set using Z packets */ + fprintf (stderr, "Warning: RSP 'B' packet is deprecated (use 'Z'/'z' " + "packets instead): ignored\n"); + return; + + case 'c': + /* Continue */ + rsp_continue (p_buf); + return; + + case 'C': + /* Continue with signal */ + rsp_continue_with_signal (p_buf); + return; + + case 'd': + /* Disable debug using a general query */ + fprintf (stderr, "Warning: RSP 'd' packet is deprecated (define a 'Q' " + "packet instead: ignored\n"); + return; + + case 'D': + /* Detach GDB. Do this by closing the client. The rules say that + execution should continue. TODO. Is this really then intended + meaning? Or does it just mean that only vAttach will be recognized + after this? */ + put_str_packet ("OK"); + rsp_client_close (); + set_stall_state (0); + return; + + case 'F': + /* File I/O is not currently supported */ + fprintf (stderr, "Warning: RSP file I/O not currently supported: 'F' " + "packet ignored\n"); + return; + + case 'g': + rsp_read_all_regs (); + return; + + case 'G': + rsp_write_all_regs (p_buf); + return; + + case 'H': + /* Set the thread number of subsequent operations. For now ignore + silently and just reply "OK" */ + put_str_packet ("OK"); + return; + + case 'i': + /* Single instruction step */ + fprintf (stderr, "Warning: RSP cycle stepping not supported: target " + "stopped immediately\n"); + rsp.client_waiting = 1; /* Stop reply will be sent */ + return; + + case 'I': + /* Single instruction step with signal */ + fprintf (stderr, "Warning: RSP cycle stepping not supported: target " + "stopped immediately\n"); + rsp.client_waiting = 1; /* Stop reply will be sent */ + return; + + case 'k': + /* Kill request. Do nothing for now. */ + return; + + case 'm': + /* Read memory (symbolic) */ + rsp_read_mem (p_buf); + return; + + case 'M': + /* Write memory (symbolic) */ + rsp_write_mem (p_buf); + return; + + case 'p': + /* Read a register */ + rsp_read_reg (p_buf); + return; + + case 'P': + /* Write a register */ + rsp_write_reg (p_buf); + return; + + case 'q': + /* Any one of a number of query packets */ + rsp_query (p_buf); + return; + + case 'Q': + /* Any one of a number of set packets */ + rsp_set (p_buf); + return; + + case 'r': + /* Reset the system. Deprecated (use 'R' instead) */ + fprintf (stderr, "Warning: RSP 'r' packet is deprecated (use 'R' " + "packet instead): ignored\n"); + return; + + case 'R': + /* Restart the program being debugged. */ + rsp_restart (); + return; + + case 's': + /* Single step (one high level instruction). This could be hard without + DWARF2 info */ + rsp_step (p_buf); + return; + + case 'S': + /* Single step (one high level instruction) with signal. This could be + hard without DWARF2 info */ + rsp_step_with_signal (p_buf); + return; + + case 't': + /* Search. This is not well defined in the manual and for now we don't + support it. No response is defined. */ + fprintf (stderr, "Warning: RSP 't' packet not supported: ignored\n"); + return; + + case 'T': + /* Is the thread alive. We are bare metal, so don't have a thread + context. The answer is always "OK". */ + put_str_packet ("OK"); + return; + + case 'v': + /* Any one of a number of packets to control execution */ + rsp_vpkt (p_buf); + return; + + case 'X': + /* Write memory (binary) */ + rsp_write_mem_bin (p_buf); + return; + + case 'z': + /* Remove a breakpoint/watchpoint. */ + rsp_remove_matchpoint (p_buf); + return; + + case 'Z': + /* Insert a breakpoint/watchpoint. */ + rsp_insert_matchpoint (p_buf); + return; + + default: + /* Unknown commands are ignored */ + fprintf (stderr, "Warning: Unknown RSP request %s\n", p_buf->data); + return; + } +} /* rsp_client_request () */ + + +/*---------------------------------------------------------------------------*/ +/*!Close the connection to the client if it is open */ +/*---------------------------------------------------------------------------*/ +static void +rsp_client_close (void) +{ + if (-1 != rsp.client_fd) + { + close (rsp.client_fd); + rsp.client_fd = -1; + } +} /* rsp_client_close () */ + + +/*---------------------------------------------------------------------------*/ +/*!Send a packet to the GDB client + + Modeled on the stub version supplied with GDB. Put out the data preceded by + a '$', followed by a '#' and a one byte checksum. '$', '#', '*' and '}' are + escaped by preceding them with '}' and then XORing the character with + 0x20. + + @param[in] p_buf The data to send */ +/*---------------------------------------------------------------------------*/ +static void +put_packet (struct rsp_buf *p_buf) +{ + unsigned char data[GDB_BUF_MAX * 2]; + int len; + int ch; /* Ack char */ + + /* Construct $#. Repeat until the GDB client + acknowledges satisfactory receipt. */ + do + { + unsigned char checksum = 0; /* Computed checksum */ + int count = 0; /* Index into the buffer */ + + if (DEBUG_GDB_DUMP_DATA){ + printf ("Putting %s\n\n", p_buf->data); + fflush (stdout); + } + + len = 0; + data[len++] = '$'; /* Start char */ + + /* Body of the packet */ + for (count = 0; count < p_buf->len; count++) + { + unsigned char ch = p_buf->data[count]; + + /* Check for escaped chars */ + if (('$' == ch) || ('#' == ch) || ('*' == ch) || ('}' == ch)) + { + ch ^= 0x20; + checksum += (unsigned char)'}'; + data[len++] = '}'; + } + + checksum += ch; + data[len++] = ch; + } + + data[len++] = '#'; /* End char */ + + /* Computed checksum */ + data[len++] = (hexchars[checksum >> 4]); + data[len++] = (hexchars[checksum % 16]); + + send_rsp_str ((unsigned char *) &data, len); + + /* Check for ack of connection failure */ + ch = get_rsp_char (); + if (0 > ch) + { + return; /* Fail the put silently. */ + } + } + while ('+' != ch); + +} /* put_packet () */ + + +/*---------------------------------------------------------------------------*/ +/*!Convenience to put a constant string packet + + param[in] str The text of the packet */ +/*---------------------------------------------------------------------------*/ +static void +put_str_packet (const char *str) +{ + struct rsp_buf buffer; + int len = strlen (str); + + /* Construct the packet to send, so long as string is not too big, + otherwise truncate. Add EOS at the end for convenient debug printout */ + + if (len >= GDB_BUF_MAX) + { + fprintf (stderr, "Warning: String %s too large for RSP packet: " + "truncated\n", str); + len = GDB_BUF_MAX - 1; + } + + strncpy (buffer.data, str, len); + buffer.data[len] = 0; + buffer.len = len; + + put_packet (&buffer); + +} /* put_str_packet () */ + + +/*---------------------------------------------------------------------------*/ +/*!Get a packet from the GDB client + + Modeled on the stub version supplied with GDB. The data is in a static + buffer. The data should be copied elsewhere if it is to be preserved across + a subsequent call to get_packet(). + + Unlike the reference implementation, we don't deal with sequence + numbers. GDB has never used them, and this implementation is only intended + for use with GDB 6.8 or later. Sequence numbers were removed from the RSP + standard at GDB 5.0. + + @return A pointer to the static buffer containing the data */ +/*---------------------------------------------------------------------------*/ +static struct rsp_buf * +get_packet (void) +{ + static struct rsp_buf buf; /* Survives the return */ + + /* Keep getting packets, until one is found with a valid checksum */ + while (1) + { + unsigned char checksum; /* The checksum we have computed */ + int count; /* Index into the buffer */ + int ch; /* Current character */ + + /* Wait around for the start character ('$'). Ignore all other + characters */ + ch = get_rsp_char (); + + while (ch != '$') + { + if (-1 == ch) + { + return NULL; /* Connection failed */ + } + + ch = get_rsp_char (); + + // Potentially handle an interrupt character (0x03) here + } + + /* Read until a '#' or end of buffer is found */ + checksum = 0; + count = 0; + while (count < GDB_BUF_MAX - 1) + { + ch = get_rsp_char (); + + if(rsp.client_waiting && DEBUG_GDB) + { + printf("%x\n",ch); + } + + + /* Check for connection failure */ + if (0 > ch) + { + return NULL; + } + + /* If we hit a start of line char begin all over again */ + if ('$' == ch) + { + checksum = 0; + count = 0; + + continue; + } + + /* Break out if we get the end of line char */ + if ('#' == ch) + { + break; + } + + /* Update the checksum and add the char to the buffer */ + + checksum = checksum + (unsigned char)ch; + buf.data[count] = (char)ch; + count = count + 1; + } + + /* Mark the end of the buffer with EOS - it's convenient for non-binary + data to be valid strings. */ + buf.data[count] = 0; + buf.len = count; + + /* If we have a valid end of packet char, validate the checksum */ + if ('#' == ch) + { + unsigned char xmitcsum; /* The checksum in the packet */ + + ch = get_rsp_char (); + if (0 > ch) + { + return NULL; /* Connection failed */ + } + xmitcsum = hex (ch) << 4; + + ch = get_rsp_char (); + if (0 > ch) + { + return NULL; /* Connection failed */ + } + + xmitcsum += hex (ch); + + /* If the checksums don't match print a warning, and put the + negative ack back to the client. Otherwise put a positive ack. */ + if (checksum != xmitcsum) + { + fprintf (stderr, "Warning: Bad RSP checksum: Computed " + "0x%02x, received 0x%02x\n", checksum, xmitcsum); + + ch = '-'; + send_rsp_str ((unsigned char *) &ch, 1); /* Failed checksum */ + } + else + { + ch = '+'; + send_rsp_str ((unsigned char *) &ch, 1); /* successful transfer */ + break; + } + } + else + { + fprintf (stderr, "Warning: RSP packet overran buffer\n"); + } + } + return &buf; /* Success */ +} /* get_packet () */ + + +/*---------------------------------------------------------------------------*/ +/*!Put a single character out onto the client socket + + This should only be called if the client is open, but we check for safety. + + @param[in] c The character to put out */ +/*---------------------------------------------------------------------------*/ +static void +send_rsp_str (unsigned char *data, int len) +{ + if (-1 == rsp.client_fd) + { + fprintf (stderr, "Warning: Attempt to write '%s' to unopened RSP " + "client: Ignored\n", data); + return; + } + + /* Write until successful (we retry after interrupts) or catastrophic + failure. */ + while (1) + { + switch (write (rsp.client_fd, data, len)) + { + case -1: + /* Error: only allow interrupts or would block */ + if ((EAGAIN != errno) && (EINTR != errno)) + { + fprintf (stderr, "Warning: Failed to write to RSP client: " + "Closing client connection: %s\n", + strerror (errno)); + rsp_client_close (); + return; + } + + break; + + case 0: + break; /* Nothing written! Try again */ + + default: + return; /* Success, we can return */ + } + } +} /* send_rsp_str () */ + + +/*---------------------------------------------------------------------------*/ +/*!Get a single character from the client socket + + This should only be called if the client is open, but we check for safety. + + @return The character read, or -1 on failure */ +/*---------------------------------------------------------------------------*/ +static int +get_rsp_char () +{ + if (-1 == rsp.client_fd) + { + fprintf (stderr, "Warning: Attempt to read from unopened RSP " + "client: Ignored\n"); + return -1; + } + + /* Non-blocking read until successful (we retry after interrupts) or + catastrophic failure. */ + while (1) + { + unsigned char c; + + switch (read (rsp.client_fd, &c, sizeof (c))) + { + case -1: + /* Error: only allow interrupts */ + if ((EAGAIN != errno) && (EINTR != errno)) + { + fprintf (stderr, "Warning: Failed to read from RSP client: " + "Closing client connection: %s\n", + strerror (errno)); + rsp_client_close (); + return -1; + } + + break; + + case 0: + // EOF + rsp_client_close (); + return -1; + + default: + return c & 0xff; /* Success, we can return (no sign extend!) */ + } + } +} /* get_rsp_char () */ + +/*---------------------------------------------------------------------------*/ +/* !Peek at data coming into server from GDB + + Useful for polling for ETX (0x3) chars being sent when GDB wants to + interrupt + + @return the char we peeked, 0 otherwise */ +/*---------------------------------------------------------------------------*/ +static unsigned char +rsp_peek() +{ + /* + if (-1 == rsp.client_fd) + { + fprintf (stderr, "Warning: Attempt to read from unopened RSP " + "client: Ignored\n"); + return -1; + } + */ + unsigned char c; + int n; + // Using recv here instead of read becuase we can pass the MSG_PEEK + // flag, which lets us look at what's on the socket, without actually + // taking it off + + //if (DEBUG_GDB) + // printf("peeking at GDB socket...\n"); + n = recv (rsp.client_fd, &c, sizeof (c), MSG_PEEK); + //if (DEBUG_GDB) + // printf("peeked, got n=%d, c=0x%x\n",n, c); + + if (n == 0) + return 0; + else + return c; + + // return c; +} + +/*---------------------------------------------------------------------------*/ +/*!Handle an interrupt from GDB + + Detect an interrupt from GDB and stall the processor */ +/*---------------------------------------------------------------------------*/ +static void +rsp_interrupt() +{ + unsigned char c; + + if (read (rsp.client_fd, &c, sizeof (c)) <= 0) + { + // Had issues, just return + return; + } + + // Ensure this is a ETX control char (0x3), currently, we only call this + // function when we've peeked and seen it, otherwise, ignore, return and pray + // things go back to normal... + if (c != 0x03) + { + printf("Warning: Interrupt character expected but not found on socket.\n"); + return; + } + + // Otherwise, it's an interrupt packet, stall the processor, and upon return + // to the main handle_rsp() loop, it will inform GDB. + + if (DEBUG_GDB) printf("Interrupt received from GDB. Stalling processor.\n"); + + set_stall_state (1); + + // Send a stop reply response, manually set rsp.sigval to TARGET_SIGNAL_NONE + rsp.sigval = TARGET_SIGNAL_NONE; + rsp_report_exception(); + rsp.client_waiting = 0; /* No longer waiting */ + + return; + +} + + +/*---------------------------------------------------------------------------*/ +/*!"Unescape" RSP binary data + + '#', '$' and '}' are escaped by preceding them by '}' and oring with 0x20. + + This function reverses that, modifying the data in place. + + @param[in] data The array of bytes to convert + @para[in] len The number of bytes to be converted + + @return The number of bytes AFTER conversion */ +/*---------------------------------------------------------------------------*/ +static int +rsp_unescape (char *data, + int len) +{ + int from_off = 0; /* Offset to source char */ + int to_off = 0; /* Offset to dest char */ + + while (from_off < len) + { + /* Is it escaped */ + if ( '}' == data[from_off]) + { + from_off++; + data[to_off] = data[from_off] ^ 0x20; + } + else + { + data[to_off] = data[from_off]; + } + + from_off++; + to_off++; + } + + return to_off; + +} /* rsp_unescape () */ + + +/*---------------------------------------------------------------------------*/ +/*!Initialize the matchpoint hash table + + This is an open hash table, so this function clears all the links to + NULL. */ +/*---------------------------------------------------------------------------*/ +static void +mp_hash_init (void) +{ + int i; + + for (i = 0; i < MP_HASH_SIZE; i++) + { + rsp.mp_hash[i] = NULL; + } +} /* mp_hash_init () */ + + +/*---------------------------------------------------------------------------*/ +/*!Add an entry to the matchpoint hash table + + Add the entry if it wasn't already there. If it was there do nothing. The + match just be on type and addr. The instr need not match, since if this is + a duplicate insertion (perhaps due to a lost packet) they will be + different. + + @param[in] type The type of matchpoint + @param[in] addr The address of the matchpoint + @para[in] instr The instruction to associate with the address */ +/*---------------------------------------------------------------------------*/ +static void +mp_hash_add (enum mp_type type, + uint32_t addr, + uint32_t instr) +{ + int hv = addr % MP_HASH_SIZE; + struct mp_entry *curr; + + /* See if we already have the entry */ + for(curr = rsp.mp_hash[hv]; NULL != curr; curr = curr->next) + { + if ((type == curr->type) && (addr == curr->addr)) + { + return; /* We already have the entry */ + } + } + + /* Insert the new entry at the head of the chain */ + curr = (struct mp_entry*) malloc (sizeof (*curr)); + + curr->type = type; + curr->addr = addr; + curr->instr = instr; + curr->next = rsp.mp_hash[hv]; + + rsp.mp_hash[hv] = curr; + +} /* mp_hash_add () */ + + +/*---------------------------------------------------------------------------*/ +/*!Look up an entry in the matchpoint hash table + + The match must be on type AND addr. + + @param[in] type The type of matchpoint + @param[in] addr The address of the matchpoint + + @return The entry deleted, or NULL if the entry was not found */ +/*---------------------------------------------------------------------------*/ +static struct mp_entry * mp_hash_lookup (enum mp_type type, uint32_t addr) +{ + int hv = addr % MP_HASH_SIZE; + struct mp_entry *curr; + + /* Search */ + for (curr = rsp.mp_hash[hv]; NULL != curr; curr = curr->next) + { + if ((type == curr->type) && (addr == curr->addr)) + { + return curr; /* The entry found */ + } + } + + /* Not found */ + return NULL; + +} /* mp_hash_lookup () */ + + +/*---------------------------------------------------------------------------*/ +/*!Delete an entry from the matchpoint hash table + + If it is there the entry is deleted from the hash table. If it is not + there, no action is taken. The match must be on type AND addr. + + The usual fun and games tracking the previous entry, so we can delete + things. + + @note The deletion DOES NOT free the memory associated with the entry, + since that is returned. The caller should free the memory when they + have used the information. + + @param[in] type The type of matchpoint + @param[in] addr The address of the matchpoint + + @return The entry deleted, or NULL if the entry was not found */ +/*---------------------------------------------------------------------------*/ +static struct mp_entry * +mp_hash_delete (enum mp_type type, + uint32_t addr) +{ + int hv = addr % MP_HASH_SIZE; + struct mp_entry *prev = NULL; + struct mp_entry *curr; + + /* Search */ + for (curr = rsp.mp_hash[hv]; NULL != curr; curr = curr->next) + { + if ((type == curr->type) && (addr == curr->addr)) + { + /* Found - delete. Method depends on whether we are the head of + chain. */ + if (NULL == prev) + { + rsp.mp_hash[hv] = curr->next; + } + else + { + prev->next = curr->next; + } + + return curr; /* The entry deleted */ + } + + prev = curr; + } + + /* Not found */ + return NULL; + +} /* mp_hash_delete () */ + + +/*---------------------------------------------------------------------------*/ +/*!Utility to give the value of a hex char + + @param[in] ch A character representing a hexadecimal digit. Done as -1, + for consistency with other character routines, which can use + -1 as EOF. + + @return The value of the hex character, or -1 if the character is + invalid. */ +/*---------------------------------------------------------------------------*/ +static int hex (int c) +{ + return ((c >= 'a') && (c <= 'f')) ? c - 'a' + 10 : + ((c >= '0') && (c <= '9')) ? c - '0' : + ((c >= 'A') && (c <= 'F')) ? c - 'A' + 10 : -1; + +} /* hex () */ + + +/*---------------------------------------------------------------------------*/ +/*!Convert a register to a hex digit string + + The supplied 32-bit value is converted to an 8 digit hex string according + the target endianism. It is null terminated for convenient printing. + + @param[in] val The value to convert + @param[out] p_buf The buffer for the text string */ +/*---------------------------------------------------------------------------*/ +static void +reg2hex (uint32_t val, char *p_buf) +{ + int n; /* Counter for digits */ + int nyb_shift; + + for (n = 0; n < 8; n++) + { +#ifdef WORDSBIGENDIAN + if(n%2==0){ + nyb_shift = n * 4 + 4; + } + else{ + nyb_shift = n * 4 - 4; + } +#else + nyb_shift = 28 - (n * 4); +#endif + p_buf[n] = hexchars[(val >> nyb_shift) & 0xf]; + } + + p_buf[8] = 0; /* Useful to terminate as string */ + +} /* reg2hex () */ + + +/*---------------------------------------------------------------------------*/ +/*!Convert a hex digit string to a register value + + The supplied 8 digit hex string is converted to a 32-bit value according + the target endianism + + @param[in] p_buf The buffer with the hex string + + @return The value to convert */ +/*---------------------------------------------------------------------------*/ +static uint32_t +hex2reg (char *p_buf) +{ + int n; /* Counter for digits */ + uint32_t val = 0; /* The result */ + + for (n = 0; n < 8; n++) + { +#ifdef WORDSBIGENDIAN + int nyb_shift = n * 4; +#else + int nyb_shift = 28 - (n * 4); +#endif + val |= hex (p_buf[n]) << nyb_shift; + } + + return val; + +} /* hex2reg () */ + + +/*---------------------------------------------------------------------------*/ +/*!Convert an ASCII character string to pairs of hex digits + + Both source and destination are null terminated. + + @param[out] dest Buffer to store the hex digit pairs (null terminated) + @param[in] src The ASCII string (null terminated) */ +/*---------------------------------------------------------------------------*/ +static void ascii2hex (char *dest, + char *src) +{ + int i; + + /* Step through converting the source string */ + for (i = 0; src[i] != '\0'; i++) + { + char ch = src[i]; + + dest[i * 2] = hexchars[ch >> 4 & 0xf]; + dest[i * 2 + 1] = hexchars[ch & 0xf]; + } + + dest[i * 2] = '\0'; + +} /* ascii2hex () */ + + +/*---------------------------------------------------------------------------*/ +/*!Convert pairs of hex digits to an ASCII character string + + Both source and destination are null terminated. + + @param[out] dest The ASCII string (null terminated) + @param[in] src Buffer holding the hex digit pairs (null terminated) */ +/*---------------------------------------------------------------------------*/ +static void hex2ascii (char *dest, + char *src) +{ + int i; + + /* Step through convering the source hex digit pairs */ + for (i = 0; src[i * 2] != '\0' && src[i * 2 + 1] != '\0'; i++) + { + dest[i] = ((hex (src[i * 2]) & 0xf) << 4) | (hex (src[i * 2 + 1]) & 0xf); + } + + dest[i] = '\0'; + +} /* hex2ascii () */ + + +/*---------------------------------------------------------------------------*/ +/*!Set the program counter + + This sets the value in the NPC SPR. Not completely trivial, since this is + actually cached in cpu_state.pc. Any reset of the NPC also involves + clearing the delay state and setting the pcnext global. + + Only actually do this if the requested address is different to the current + NPC (avoids clearing the delay pipe). + + @param[in] addr The address to use */ +/*---------------------------------------------------------------------------*/ +static void +set_npc (uint32_t addr) +{ + + // First set the chain + gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */ + + + if (addr != get_npc()) + { + + gdb_write_reg(NPC_CPU_REG_ADD, addr); + + if (STALLED == stallState) + { + if (DEBUG_GDB) printf("set_npc(): New NPC value (0x%08x) written and locally cached \n", addr); + npcCachedValue = addr; + npcIsCached = 1; + } + else + { + if (DEBUG_GDB) printf("set_npc(): New NPC value (0x%08x) written \n", addr); + npcIsCached = 0; + } + + + } + else + return; + + +} /* set_npc () */ + + +//! Read the value of the Next Program Counter (a SPR) + +//! Setting the NPC flushes the pipeline, so subsequent reads will return +//! zero until the processor has refilled the pipeline. This will not be +//! happening if the processor is stalled (as it is when GDB had control), +//! so we must cache the NPC. As soon as the processor is unstalled, this +//! cached value becomes invalid. + +//! If we are stalled and the value has been cached, use it. If we are stalled +//! and the value has not been cached, cache it (for efficiency) and use +//! it. Otherwise read the corresponding SPR. + +//! @return The value of the NPC +static uint32_t get_npc () +{ + uint32_t current_npc; + + if (STALLED == stallState) + { + if (npcIsCached == 0) + { + err = gdb_set_chain(SC_RISC_DEBUG); + err = gdb_read_reg(NPC_CPU_REG_ADD, &npcCachedValue); + if(err > 0){ + printf("Error %d reading NPC\n", err); + rsp_client_close (); + return 0; + } + if (DEBUG_GDB) printf("get_npc(): caching newly read NPC value (0x%08x)\n",npcCachedValue); + + + npcIsCached = 1; + } + else + if (DEBUG_GDB) printf("get_npc(): reading cached NPC value (0x%08x)\n",npcCachedValue); + + return npcCachedValue; + } + else + { + err = gdb_read_reg(NPC_CPU_REG_ADD, ¤t_npc); + if(err > 0){ + printf("Error %d reading NPC\n", err); + rsp_client_close (); + return 0; + } + return current_npc; + + } +} // get_npc () + + + +/*---------------------------------------------------------------------------*/ +/*!Send a packet acknowledging an exception has occurred + + This is only called if there is a client FD to talk to */ +/*---------------------------------------------------------------------------*/ +static void +rsp_report_exception (void) +{ + struct rsp_buf buffer; + + /* Construct a signal received packet */ + buffer.data[0] = 'S'; + buffer.data[1] = hexchars[rsp.sigval >> 4]; + buffer.data[2] = hexchars[rsp.sigval % 16]; + buffer.data[3] = 0; + buffer.len = strlen (buffer.data); + + put_packet (&buffer); + +} /* rsp_report_exception () */ + + +/*---------------------------------------------------------------------------*/ +/*!Handle a RSP continue request + + Parse the command to see if there is an address. Uses the underlying + generic continue function, with EXCEPT_NONE. + + @param[in] p_buf The full continue packet */ +/*---------------------------------------------------------------------------*/ +static void +rsp_continue (struct rsp_buf *p_buf) +{ + uint32_t addr; /* Address to continue from, if any */ + + // First set the chain + err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */ + + // Make sure the processor is stalled + gdb_ensure_or1k_stalled(); + + if(err > 0){ + printf("Error %d to set RISC Debug Interface chain in the CONTINUE command 'c'\n", err); + rsp_client_close (); + return; + } + + if (0 == strcmp ("c", p_buf->data)) + { + // Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */ + /* ---------- NPC ---------- */ + addr = get_npc(); + } + else if (1 != sscanf (p_buf->data, "c%x", &addr)) + { + fprintf (stderr, + "Warning: RSP continue address %s not recognized: ignored\n", + p_buf->data); + + // Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */ + /* ---------- NPC ---------- */ + addr = get_npc(); + } + + if (DEBUG_GDB) printf("rsp_continue() --> Read NPC = 0x%08x\n", addr); + + rsp_continue_generic (addr, EXCEPT_NONE); + +} /* rsp_continue () */ + + +/*---------------------------------------------------------------------------*/ +/*!Handle a RSP continue with signal request + + Currently null. Will use the underlying generic continue function. + + @param[in] p_buf The full continue with signal packet */ +/*---------------------------------------------------------------------------*/ +static void +rsp_continue_with_signal (struct rsp_buf *p_buf) +{ + printf ("RSP continue with signal '%s' received\n", p_buf->data); + +} /* rsp_continue_with_signal () */ + + +/*---------------------------------------------------------------------------*/ +/*!Generic processing of a continue request + + The signal may be EXCEPT_NONE if there is no exception to be + handled. Currently the exception is ignored. + + The single step flag is cleared in the debug registers and then the + processor is unstalled. + + @param[in] addr Address from which to step + @param[in] except The exception to use (if any) */ +/*---------------------------------------------------------------------------*/ +static void +rsp_continue_generic (uint32_t addr, + uint32_t except) +{ + uint32_t temp_uint32; + + /* Set the address as the value of the next program counter */ + set_npc (addr); + + /* Clear Debug Reason Register (DRR) 0x3015 */ + // Arc sim --> cpu_state.sprs[SPR_DRR] = 0; + if(gdb_write_reg(DRR_CPU_REG_ADD, 0)) printf("Error write to DRR register\n"); + + /* Clear watchpoint break generation in Debug Mode Register 2 (DMR2) 0x3011 */ + // Arc sim --> cpu_state.sprs[SPR_DMR2] &= ~SPR_DMR2_WGB; + if(gdb_read_reg(DMR2_CPU_REG_ADD, &temp_uint32)) printf("Error read from DMR2 register\n"); + temp_uint32 &= ~SPR_DMR2_WGB; + if(gdb_write_reg(DMR2_CPU_REG_ADD, temp_uint32)) printf("Error write to DMR2 register\n"); + + /* Clear the single step trigger in Debug Mode Register 1 (DMR1) Register 0x3010 */ + // Arc sim --> cpu_state.sprs[SPR_DMR1] &= ~SPR_DMR1_ST; + if(gdb_read_reg(DMR1_CPU_REG_ADD, &temp_uint32)) printf("Error read from DMR1 register\n"); + temp_uint32 &= ~SPR_DMR1_ST; + if(gdb_write_reg(DMR1_CPU_REG_ADD, temp_uint32)) printf("Error write to DMR1 register\n"); + + /* Set traps to be handled by the debug unit in the Debug Stop Register (DSR) Register 0x3014 */ + // Arc sim --> cpu_state.sprs[SPR_DSR] |= SPR_DSR_TE; + if(gdb_read_reg(DSR_CPU_REG_ADD, &temp_uint32)) printf("Error read from DSR register\n"); + temp_uint32 |= SPR_DSR_TE; + if(gdb_write_reg(DSR_CPU_REG_ADD, temp_uint32)) printf("Error write to DSR register\n"); + + /* Unstall the processor */ + set_stall_state (0); + + /* Note the GDB client is now waiting for a reply. */ + rsp.client_waiting = 1; + +} /* rsp_continue_generic () */ + + +/*---------------------------------------------------------------------------*/ +/*!Handle a RSP read all registers request + + The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PPC + (i.e. SPR PPC), NPC (i.e. SPR NPC) and SR (i.e. SPR SR). Each register is + returned as a sequence of bytes in target endian order. + + Each byte is packed as a pair of hex digits. */ +/*---------------------------------------------------------------------------*/ +static void +rsp_read_all_regs (void) +{ + struct rsp_buf buffer; /* Buffer for the reply */ + int r; /* Register index */ + uint32_t temp_uint32; + + // Make sure the processor is stalled + gdb_ensure_or1k_stalled(); + + // First set the chain + gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */ + + + // Read all GPRs + for (r = 0; r < MAX_GPRS; r++){ + + err = gdb_read_reg(0x400 + r, &temp_uint32); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in gdb_read_reg at reg. %d\n", err, r); + put_str_packet ("E01"); + return; + } + reg2hex (temp_uint32, &(buffer.data[r * 8])); + + if (DEBUG_GDB_DUMP_DATA){ + switch(r % 4) + { + case 0: + printf("gpr%02d 0x%08x ", r, temp_uint32); + break; + case 1: + case 2: + printf("0x%08x ", temp_uint32); + break; + case 3: + printf("0x%08x\n", temp_uint32); + break; + default: + break; + } + } + + } + /* ---------- PPC ---------- */ + err = gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in gdb_read_reg read --> PPC\n", err); + put_str_packet ("E01"); + return; + } + reg2hex (temp_uint32, &(buffer.data[PPC_REGNUM * 8])); + if (DEBUG_GDB_DUMP_DATA) printf("PPC 0x%08x\n", temp_uint32); + /* ---------- NPC ---------- */ + temp_uint32 = get_npc(); + /* + err = gdb_read_reg(NPC_CPU_REG_ADD, &temp_uint32); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in gdb_read_reg read --> NPC\n", err); + put_str_packet ("E01"); + return; + } + */ + reg2hex (temp_uint32, &(buffer.data[NPC_REGNUM * 8])); + if (DEBUG_GDB_DUMP_DATA) printf("NPC 0x%08x\n", temp_uint32); + /* ---------- SR ---------- */ + err = gdb_read_reg(SR_CPU_REG_ADD, &temp_uint32); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in gdb_read_reg read --> SP\n", err); + put_str_packet ("E01"); + return; + } + reg2hex (temp_uint32, &(buffer.data[SR_REGNUM * 8])); + if (DEBUG_GDB_DUMP_DATA) printf("SR 0x%08x\n", temp_uint32); + + /* Finalize the packet and send it */ + buffer.data[NUM_REGS * 8] = 0; + buffer.len = NUM_REGS * 8; + + put_packet (&buffer); + return; +} /* rsp_read_all_regs () */ + + +/*---------------------------------------------------------------------------*/ +/*!Handle a RSP write all registers request + + The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PPC + (i.e. SPR PPC), NPC (i.e. SPR NPC) and SR (i.e. SPR SR). Each register is + supplied as a sequence of bytes in target endian order. + + Each byte is packed as a pair of hex digits. + + @todo There is no error checking at present. Non-hex chars will generate a + warning message, but there is no other check that the right amount + of data is present. The result is always "OK". + + @param[in] p_buf The original packet request. */ +/*---------------------------------------------------------------------------*/ +static void +rsp_write_all_regs (struct rsp_buf *p_buf) +{ + uint32_t regnum; /* Register index */ + // char valstr[9]; /* Allow for EOS on the string */ + + // /* Check for valid data */ + // if (0 != (strcmp ("G", p_buf->data)) && (GDB_BUF_MAX != strlen(p_buf->data))) + // { + // fprintf (stderr, "Warning: Failed to recognize RSP write register " + // "command: %s\n", p_buf->data); + // // put_str_packet ("E01"); + // return; + // } + + // Make sure the processor is stalled + gdb_ensure_or1k_stalled(); + + // First set the chain + err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */ + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err); + put_str_packet ("E01"); + return; + } + + /* ---------- GPRS ---------- */ + for (regnum = 0; regnum < MAX_GPRS; regnum++) + { + err = gdb_write_reg(0x400 + regnum, hex2reg (&p_buf->data[regnum * 8 + 1])); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> GPRS\n", err); + put_str_packet ("E01"); + return; + } + } + + /* ---------- PPC ---------- */ + err = gdb_write_reg(PPC_CPU_REG_ADD, hex2reg (&p_buf->data[PPC_REGNUM * 8 + 1])); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> PPC\n", err); + put_str_packet ("E01"); + return; + } + /* ---------- SR ---------- */ + err = gdb_write_reg(SR_CPU_REG_ADD, hex2reg (&p_buf->data[SR_REGNUM * 8 + 1])); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> SR\n", err); + put_str_packet ("E01"); + return; + } + /* ---------- NPC ---------- */ + set_npc(hex2reg (&p_buf->data[NPC_REGNUM * 8 + 1])); + /* + err = gdb_write_reg(NPC_CPU_REG_ADD, hex2reg (&p_buf->data[NPC_REGNUM * 8 + 1])); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> NPC\n", err); + put_str_packet ("E01"); + return; + } + */ + /* Acknowledge. TODO: We always succeed at present, even if the data was + defective. */ + put_str_packet ("OK"); +} /* rsp_write_all_regs () */ + + +/*---------------------------------------------------------------------------*/ +/* Handle a RSP read memory (symbolic) request + + Syntax is: + + m,: + + The response is the bytes, lowest address first, encoded as pairs of hex + digits. + + The length given is the number of bytes to be read. + + @note This function reuses p_buf, so trashes the original command. + + @param[in] p_buf The command received */ +/*---------------------------------------------------------------------------*/ +static void rsp_read_mem (struct rsp_buf *p_buf) +{ + unsigned int addr; /* Where to read the memory */ + int len; /* Number of bytes to read */ + int off; /* Offset into the memory */ + uint32_t temp_uint32 = 0; + char *rec_buf; + + + if (2 != sscanf (p_buf->data, "m%x,%x:", &addr, &len)) + { + fprintf (stderr, "Warning: Failed to recognize RSP read memory " + "command: %s\n", p_buf->data); + put_str_packet ("E01"); + return; + } + + /* Make sure we won't overflow the buffer (2 chars per byte) */ + if ((len * 2) >= GDB_BUF_MAX) + { + fprintf (stderr, "Warning: Memory read %s too large for RSP packet: " + "truncated\n", p_buf->data); + len = (GDB_BUF_MAX - 1) / 2; + } + + if(!(rec_buf = (char*)malloc(len))) { + put_str_packet ("E01"); + ProtocolClean(0, JTAG_PROXY_OUT_OF_MEMORY); + return; + } + + // Make sure the processor is stalled + gdb_ensure_or1k_stalled(); + + // Set chain 5 --> Wishbone Memory chain + err = gdb_set_chain(SC_WISHBONE); + if(err){ + if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err); + put_str_packet ("E01"); + return; + } + + // Read the data from Wishbone Memory chain + err = gdb_read_block(addr, (uint32_t*)rec_buf, len); + if(err){ + put_str_packet ("E01"); + return; + } + + /* Refill the buffer with the reply */ + for( off = 0 ; off < len ; off ++ ) { + ; + temp_uint32 = (temp_uint32 << 8) | (0x000000ff & *(rec_buf + off)); + + if((off %4 ) == 3){ + temp_uint32 = htonl(temp_uint32); + reg2hex (temp_uint32, &(p_buf->data[off * 2 - 6])); + } + if (DEBUG_GDB_BLOCK_DATA){ + switch(off % 16) + { + case 3: + printf("Add 0x%08x Data 0x%08x ", addr + off - 3, temp_uint32); + break; + case 7: + case 11: + printf("0x%08x ", temp_uint32); + break; + case 15: + printf("0x%08x\n", temp_uint32); + break; + default: + break; + } + if ((len - off == 1) && (off % 16) < 15) printf("\n"); + } + } + + if (DEBUG_GDB && (err > 0)) printf("\nError %x\n", err);fflush (stdout); + free(rec_buf); + p_buf->data[off * 2] = 0; /* End of string */ + p_buf->len = strlen (p_buf->data); + put_packet (p_buf); +} /* rsp_read_mem () */ + + +/*---------------------------------------------------------------------------*/ +/*!Handle a RSP write memory (symbolic) request ("M") + + Syntax is: + + M,: + + Example: M4015cc,2:c320# + (Write the value 0xc320 to address 0x4015cc.) + + An example target response: + + $OK# + + The data is the bytes, lowest address first, encoded as pairs of hex + digits. + + The length given is the number of bytes to be written. + + @note This function reuses p_buf, so trashes the original command. + + @param[in] p_buf The command received */ +/*---------------------------------------------------------------------------*/ +static void +rsp_write_mem (struct rsp_buf *p_buf) +{ + unsigned int addr; /* Where to write the memory */ + int len; /* Number of bytes to write */ + char *symdat; /* Pointer to the symboli data */ + int datlen; /* Number of digits in symbolic data */ + int off; /* Offset into the memory */ + int nibc; /* Nibbel counter */ + uint32_t val; + + if (2 != sscanf (p_buf->data, "M%x,%x:", &addr, &len)) + { + fprintf (stderr, "Warning: Failed to recognize RSP write memory " + "command: %s\n", p_buf->data); + put_str_packet ("E01"); + return; + } + + /* Find the start of the data and check there is the amount we expect. */ + symdat = (char*) memchr ((const void *)p_buf->data, ':', GDB_BUF_MAX) + 1; + datlen = p_buf->len - (symdat - p_buf->data); + + /* Sanity check */ + if (len * 2 != datlen) + { + fprintf (stderr, "Warning: Write of %d digits requested, but %d digits " + "supplied: packet ignored\n", len * 2, datlen ); + put_str_packet ("E01"); + return; + } + + // Make sure the processor is stalled + gdb_ensure_or1k_stalled(); + + + // Set chain 5 --> Wishbone Memory chain + err = gdb_set_chain(SC_WISHBONE); + if(err){ + put_str_packet ("E01"); + return; + } + + val = 0; + off = 0; + /* Write the bytes to memory */ + for (nibc = 0; nibc < datlen; nibc++) + { + val |= 0x0000000f & hex (symdat[nibc]); + if(nibc % 8 == 7){ + err = gdb_write_block(addr + off, &val, 4); + if (DEBUG_GDB) printf("Error %x\n", err);fflush (stdout); + if(err){ + put_str_packet ("E01"); + return; + } + val = 0; + off += 4; + } + val <<= 4; + } + put_str_packet ("OK"); +} /* rsp_write_mem () */ + + +/*---------------------------------------------------------------------------*/ +/*!Read a single register + + The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC + (i.e. SPR NPC) and SR (i.e. SPR SR). The register is returned as a + sequence of bytes in target endian order. + + Each byte is packed as a pair of hex digits. + + @param[in] p_buf The original packet request. Reused for the reply. */ +/*---------------------------------------------------------------------------*/ +static void +rsp_read_reg (struct rsp_buf *p_buf) +{ + unsigned int regnum; + uint32_t temp_uint32; + + /* Break out the fields from the data */ + if (1 != sscanf (p_buf->data, "p%x", ®num)) + { + fprintf (stderr, "Warning: Failed to recognize RSP read register " + "command: %s\n", p_buf->data); + put_str_packet ("E01"); + return; + } + + // Make sure the processor is stalled + gdb_ensure_or1k_stalled(); + + // First set the chain + err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */ + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err); + put_str_packet ("E01"); + return; + } + + /* Get the relevant register */ + if (regnum < MAX_GPRS) + { + err = gdb_read_reg(0x400 + regnum, &temp_uint32); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in rsp_read_reg at reg. %d \n", err, regnum); + put_str_packet ("E01"); + return; + } + reg2hex (temp_uint32, p_buf->data); + } + else if (PPC_REGNUM == regnum) /* ---------- PPC ---------- */ + { + err = gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in rsp_read_reg read --> PPC\n", err); + put_str_packet ("E01"); + return; + } + reg2hex (temp_uint32, p_buf->data); + } + else if (NPC_REGNUM == regnum) /* ---------- NPC ---------- */ + { + temp_uint32 = get_npc(); + /* + err = gdb_read_reg(NPC_CPU_REG_ADD, &temp_uint32); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in rsp_read_reg read --> PPC\n", err); + put_str_packet ("E01"); + return; + } + */ + reg2hex (temp_uint32, p_buf->data); + } + else if (SR_REGNUM == regnum) /* ---------- SR ---------- */ + { + err = gdb_read_reg(SR_CPU_REG_ADD, &temp_uint32); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in rsp_read_reg read --> PPC\n", err); + put_str_packet ("E01"); + return; + } + reg2hex (temp_uint32, p_buf->data); + } + else + { + /* Error response if we don't know the register */ + fprintf (stderr, "Warning: Attempt to read unknown register 0x%x: " + "ignored\n", regnum); + put_str_packet ("E01"); + return; + } + + p_buf->len = strlen (p_buf->data); + put_packet (p_buf); + +} /* rsp_read_reg () */ + + +/*---------------------------------------------------------------------------*/ +/*!Write a single register + + The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC + (i.e. SPR NPC) and SR (i.e. SPR SR). The register is specified as a + sequence of bytes in target endian order. + + Each byte is packed as a pair of hex digits. + + @param[in] p_buf The original packet request. */ +/*---------------------------------------------------------------------------*/ +static void +rsp_write_reg (struct rsp_buf *p_buf) +{ + unsigned int regnum; + char valstr[9]; /* Allow for EOS on the string */ + // int err = 0; + + /* Break out the fields from the data */ + if (2 != sscanf (p_buf->data, "P%x=%8s", ®num, valstr)) + { + fprintf (stderr, "Warning: Failed to recognize RSP write register " + "command: %s\n", p_buf->data); + put_str_packet ("E01"); + return; + } + + // Make sure the processor is stalled + gdb_ensure_or1k_stalled(); + + // First set the chain + err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */ + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err); + put_str_packet ("E01"); + return; + } + + /* Set the relevant register */ + if (regnum < MAX_GPRS) /* ---------- GPRS ---------- */ + { + err = gdb_write_reg(0x400 + regnum, hex2reg (valstr)); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> GPRS\n", err); + put_str_packet ("E01"); + return; + } + } + else if (PPC_REGNUM == regnum) /* ---------- PPC ---------- */ + { + err = gdb_write_reg(PPC_CPU_REG_ADD, hex2reg (valstr)); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> PPC\n", err); + put_str_packet ("E01"); + return; + } + } + else if (NPC_REGNUM == regnum) /* ---------- NPC ---------- */ + { + set_npc(hex2reg (valstr)); + /* + err = gdb_write_reg(NPC_CPU_REG_ADD, hex2reg (valstr)); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> NPC\n", err); + put_str_packet ("E01"); + return; + } + */ + } + else if (SR_REGNUM == regnum) /* ---------- SR ---------- */ + { + err = gdb_write_reg(SR_CPU_REG_ADD, hex2reg (valstr)); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> SR\n", err); + put_str_packet ("E01"); + return; + } + } + else + { + /* Error response if we don't know the register */ + fprintf (stderr, "Warning: Attempt to write unknown register 0x%x: " + "ignored\n", regnum); + put_str_packet ("E01"); + return; + } + + put_str_packet ("OK"); + +} /* rsp_write_reg () */ + + +/*---------------------------------------------------------------------------*/ +/*!Handle a RSP query request + + @param[in] p_buf The request */ +/*---------------------------------------------------------------------------*/ +static void +rsp_query (struct rsp_buf *p_buf) +{ + if (0 == strcmp ("qC", p_buf->data)) + { + /* Return the current thread ID (unsigned hex). A null response + indicates to use the previously selected thread. Since we do not + support a thread concept, this is the appropriate response. */ + put_str_packet (""); + } + else if (0 == strncmp ("qCRC", p_buf->data, strlen ("qCRC"))) + { + /* Return CRC of memory area */ + fprintf (stderr, "Warning: RSP CRC query not supported\n"); + put_str_packet ("E01"); + } + else if (0 == strcmp ("qfThreadInfo", p_buf->data)) + { + /* Return info about active threads. We return just '-1' */ + put_str_packet ("m-1"); + } + else if (0 == strcmp ("qsThreadInfo", p_buf->data)) + { + /* Return info about more active threads. We have no more, so return the + end of list marker, 'l' */ + put_str_packet ("l"); + } + else if (0 == strncmp ("qGetTLSAddr:", p_buf->data, strlen ("qGetTLSAddr:"))) + { + /* We don't support this feature */ + put_str_packet (""); + } + else if (0 == strncmp ("qL", p_buf->data, strlen ("qL"))) + { + /* Deprecated and replaced by 'qfThreadInfo' */ + fprintf (stderr, "Warning: RSP qL deprecated: no info returned\n"); + put_str_packet ("qM001"); + } + else if (0 == strcmp ("qOffsets", p_buf->data)) + { + /* Report any relocation */ + put_str_packet ("Text=0;Data=0;Bss=0"); + } + else if (0 == strncmp ("qP", p_buf->data, strlen ("qP"))) + { + /* Deprecated and replaced by 'qThreadExtraInfo' */ + fprintf (stderr, "Warning: RSP qP deprecated: no info returned\n"); + put_str_packet (""); + } + else if (0 == strncmp ("qRcmd,", p_buf->data, strlen ("qRcmd,"))) + { + /* This is used to interface to commands to do "stuff" */ + rsp_command (p_buf); + } + else if (0 == strncmp ("qSupported", p_buf->data, strlen ("qSupported"))) + { + /* Report a list of the features we support. For now we just ignore any + supplied specific feature queries, but in the future these may be + supported as well. Note that the packet size allows for 'G' + all the + registers sent to us, or a reply to 'g' with all the registers and an + EOS so the buffer is a well formed string. */ + setup_or32(); // setup cpu + char reply[GDB_BUF_MAX]; + sprintf (reply, "PacketSize=%x", GDB_BUF_MAX); + put_str_packet (reply); + } + else if (0 == strncmp ("qSymbol:", p_buf->data, strlen ("qSymbol:"))) + { + /* Offer to look up symbols. Nothing we want (for now). TODO. This just + ignores any replies to symbols we looked up, but we didn't want to + do that anyway! */ + put_str_packet ("OK"); + } + else if (0 == strncmp ("qThreadExtraInfo,", p_buf->data, + strlen ("qThreadExtraInfo,"))) + { + /* Report that we are runnable, but the text must be hex ASCI + digits. For now do this by steam, reusing the original packet */ + sprintf (p_buf->data, "%02x%02x%02x%02x%02x%02x%02x%02x%02x", + 'R', 'u', 'n', 'n', 'a', 'b', 'l', 'e', 0); + p_buf->len = strlen (p_buf->data); + put_packet (p_buf); + } + else if (0 == strncmp ("qXfer:", p_buf->data, strlen ("qXfer:"))) + { + /* For now we support no 'qXfer' requests, but these should not be + expected, since they were not reported by 'qSupported' */ + fprintf (stderr, "Warning: RSP 'qXfer' not supported: ignored\n"); + put_str_packet (""); + } + else + { + fprintf (stderr, "Unrecognized RSP query: ignored\n"); + } +} /* rsp_query () */ + + +/*---------------------------------------------------------------------------*/ +/*!Handle a RSP qRcmd request + + The actual command follows the "qRcmd," in ASCII encoded to hex + + @param[in] p_buf The request in full */ +/*---------------------------------------------------------------------------*/ +static void +rsp_command (struct rsp_buf *p_buf) +{ + char cmd[GDB_BUF_MAX]; + unsigned int regno; + uint32_t temp_uint32; + + hex2ascii (cmd, &(p_buf->data[strlen ("qRcmd,")])); + + /* Work out which command it is */ + if (0 == strncmp ("readspr ", cmd, strlen ("readspr"))) + { + /* Parse and return error if we fail */ + if( 1 != sscanf (cmd, "readspr %4x", ®no)) + { + fprintf (stderr, "Warning: qRcmd %s not recognized: ignored\n", cmd); + put_str_packet ("E01"); + return; + } + + /* SPR out of range */ + if (regno > MAX_SPRS) + { + fprintf (stderr, "Warning: qRcmd readspr %x too large: ignored\n", + regno); + put_str_packet ("E01"); + return; + } + + /* Construct the reply */ + + // Make sure the processor is stalled + gdb_ensure_or1k_stalled(); + + // First set the chain + gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */ + + // special case for NPC + if(regno == NPC_CPU_REG_ADD) + temp_uint32 = get_npc(); + else + { + err = gdb_read_reg(regno, &temp_uint32); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in rsp_command at reg. %x \n", err, regno); + } + else{ + reg2hex (temp_uint32, cmd); + if (DEBUG_GDB) printf("Error %d Command readspr Read reg. %x = 0x%08x\n", err, regno, temp_uint32); + } + } + + // pack the result into the buffer to send back + sprintf (cmd, "%8x", (unsigned int)temp_uint32); + ascii2hex (p_buf->data, cmd); + p_buf->len = strlen (p_buf->data); + put_packet (p_buf); + } + else if (0 == strncmp ("writespr ", cmd, strlen ("writespr"))) + { + unsigned int regno; + uint32_t val; + + /* Parse and return error if we fail */ + if( 2 != sscanf (cmd, "writespr %4x %8x", ®no, &val)) + { + fprintf (stderr, "Warning: qRcmd %s not recognized: ignored\n", + cmd); + put_str_packet ("E01"); + return; + } + + /* SPR out of range */ + if (regno > MAX_SPRS) + { + fprintf (stderr, "Warning: qRcmd writespr %x too large: ignored\n", + regno); + put_str_packet ("E01"); + return; + } + + // Make sure the processor is stalled + gdb_ensure_or1k_stalled(); + + // First set the chain + gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */ + + /* set the relevant register */ + // special case for NPC + if(regno == NPC_CPU_REG_ADD) + set_npc(val); + else + { + + err = gdb_write_reg(regno, val); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in rsp_command write Reg. %x = 0x%08x\n", err, regno, val); + put_str_packet ("E01"); + return; + } + else{ + if (DEBUG_GDB) printf("Error %d Command writespr Write reg. %x = 0x%08x\n", err, regno, val); + } + } + put_str_packet ("OK"); + } +} /* rsp_command () */ + + +/*---------------------------------------------------------------------------*/ +/*!Handle a RSP set request + + @param[in] p_buf The request */ +/*---------------------------------------------------------------------------*/ +static void +rsp_set (struct rsp_buf *p_buf) +{ + if (0 == strncmp ("QPassSignals:", p_buf->data, strlen ("QPassSignals:"))) + { + /* Passing signals not supported */ + put_str_packet (""); + } + else if ((0 == strncmp ("QTDP", p_buf->data, strlen ("QTDP"))) || + (0 == strncmp ("QFrame", p_buf->data, strlen ("QFrame"))) || + (0 == strcmp ("QTStart", p_buf->data)) || + (0 == strcmp ("QTStop", p_buf->data)) || + (0 == strcmp ("QTinit", p_buf->data)) || + (0 == strncmp ("QTro", p_buf->data, strlen ("QTro")))) + { + /* All tracepoint features are not supported. This reply is really only + needed to 'QTDP', since with that the others should not be + generated. */ + put_str_packet (""); + } + else + { + fprintf (stderr, "Unrecognized RSP set request: ignored\n"); + } +} /* rsp_set () */ + + +/*---------------------------------------------------------------------------*/ +/*!Handle a RSP restart request + + For now we just put the program counter back to the one used with the last + vRun request. There is no point in unstalling the processor, since we'll + never get control back. */ +/*---------------------------------------------------------------------------*/ +static void +rsp_restart (void) +{ + // Make sure the processor is stalled + gdb_ensure_or1k_stalled(); + + // First set the chain + err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */ + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err); + put_str_packet ("E01"); + return; + } + // OR32 Arc sim equivalent --> set_npc (rsp.start_addr); + /* Set NPC to reset vector 0x100 */ + set_npc(rsp.start_addr); + /* + err = gdb_write_reg(NPC_CPU_REG_ADD, rsp.start_addr); + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in rsp_restart write Reg. %x = 0x%08x\n", err, NPC_CPU_REG_ADD, rsp.start_addr); + put_str_packet ("E01"); + return; + } + + else{ + if (DEBUG_GDB) printf("Error %d Command Reset. Set NPC to Start vector %x = 0x%08x\n", err, NPC_CPU_REG_ADD, rsp.start_addr); + } + */ +} /* rsp_restart () */ + + +/*---------------------------------------------------------------------------*/ +/*!Handle a RSP step request + + Parse the command to see if there is an address. Uses the underlying + generic step function, with EXCEPT_NONE. + + @param[in] p_buf The full step packet */ +/*---------------------------------------------------------------------------*/ +static void +rsp_step (struct rsp_buf *p_buf) +{ + uint32_t addr; /* The address to step from, if any */ + + // Make sure the processor is stalled + gdb_ensure_or1k_stalled(); + + // First set the chain + err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */ + if(err > 0){ + printf("Error %d to set RISC Debug Interface chain in the STEP command 's'\n", err); + rsp_client_close (); + return; + } + + if (0 == strcmp ("s", p_buf->data)) + { + // Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */ + /* ---------- Npc ---------- */ + addr = get_npc(); + /* + err = gdb_read_reg(NPC_CPU_REG_ADD, &addr); + if(err > 0){ + printf("Error %d to read NPC in the STEP command 's'\n", err); + rsp_client_close (); + return; + } + */ + } + else if (1 != sscanf (p_buf->data, "s%x", &addr)) + { + fprintf (stderr, + "Warning: RSP step address %s not recognized: ignored\n", + p_buf->data); + + // Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */ + /* ---------- NPC ---------- */ + addr = get_npc(); + /* + err = gdb_read_reg(NPC_CPU_REG_ADD, &addr); + if(err > 0){ + printf("Error %d to read NPC in the STEP command 's'\n", err); + rsp_client_close (); + return; + } + */ + } + + //if (DEBUG_GDB) printf("rsp_step() --> Read NPC = 0x%08x\n", addr); + rsp_step_generic (addr, EXCEPT_NONE); + +} /* rsp_step () */ + + +/*---------------------------------------------------------------------------*/ +/*!Handle a RSP step with signal request + + Currently null. Will use the underlying generic step function. + + @param[in] p_buf The full step with signal packet */ +/*---------------------------------------------------------------------------*/ +static void +rsp_step_with_signal (struct rsp_buf *p_buf) +{ + printf ("RSP step with signal '%s' received\n", p_buf->data); + +} /* rsp_step_with_signal () */ + + +/*---------------------------------------------------------------------------*/ +/*!Generic processing of a step request + + The signal may be EXCEPT_NONE if there is no exception to be + handled. Currently the exception is ignored. + + The single step flag is set in the debug registers and then the processor + is unstalled. + + @param[in] addr Address from which to step + @param[in] except The exception to use (if any) */ +/*---------------------------------------------------------------------------*/ +static void +rsp_step_generic (uint32_t addr, + uint32_t except) +{ + uint32_t temp_uint32; + + /* Set the address as the value of the next program counter */ + + set_npc (addr); + + /* Clear Debug Reason Register (DRR) 0x3015 */ + // Arc sim --> cpu_state.sprs[SPR_DRR] = 0; + if(gdb_write_reg(DRR_CPU_REG_ADD, 0)) printf("Error write to DRR register\n"); + + /* Clear watchpoint break generation in Debug Mode Register 2 (DMR2) 0x3011 */ + // Arc sim --> cpu_state.sprs[SPR_DMR2] &= ~SPR_DMR2_WGB; + if(gdb_read_reg(DMR2_CPU_REG_ADD, &temp_uint32)) printf("Error read from DMR2 register\n"); + temp_uint32 &= ~SPR_DMR2_WGB; + if(gdb_write_reg(DMR2_CPU_REG_ADD, temp_uint32)) printf("Error write to DMR2 register\n"); + + /* Set the single step trigger in Debug Mode Register 1 (DMR1) Register 0x3010 */ + // Arc sim --> cpu_state.sprs[SPR_DMR1] |= SPR_DMR1_ST; + if(gdb_read_reg(DMR1_CPU_REG_ADD, &temp_uint32)) printf("Error read from DMR1 register\n"); + temp_uint32 |= SPR_DMR1_ST; + if(gdb_write_reg(DMR1_CPU_REG_ADD, temp_uint32)) printf("Error write to DMR1 register\n"); + + /* Set traps to be handled by the debug unit in the Debug Stop Register (DSR) Register 0x3014 */ + // Arc sim --> cpu_state.sprs[SPR_DSR] |= SPR_DSR_TE; + if(gdb_read_reg(DSR_CPU_REG_ADD, &temp_uint32)) printf("Error read from DSR register\n"); + temp_uint32 |= SPR_DSR_TE; + if(gdb_write_reg(DSR_CPU_REG_ADD, temp_uint32)) printf("Error write to DSR register\n"); + + /* Unstall the processor */ + set_stall_state (0); + + /* Note the GDB client is now waiting for a reply. */ + rsp.client_waiting = 1; + +} /* rsp_step_generic () */ + + +/*---------------------------------------------------------------------------*/ +/*!Handle a RSP 'v' packet + + These are commands associated with executing the code on the target + + @param[in] p_buf The request */ +/*---------------------------------------------------------------------------*/ +static void +rsp_vpkt (struct rsp_buf *p_buf) +{ + if (0 == strncmp ("vAttach;", p_buf->data, strlen ("vAttach;"))) + { + /* Attaching is a null action, since we have no other process. We just + return a stop packet (using TRAP) to indicate we are stopped. */ + put_str_packet ("S05"); + return; + } + else if (0 == strcmp ("vCont?", p_buf->data)) + { + /* For now we don't support this. */ + put_str_packet (""); + return; + } + else if (0 == strncmp ("vCont", p_buf->data, strlen ("vCont"))) + { + /* This shouldn't happen, because we've reported non-support via vCont? + above */ + fprintf (stderr, "Warning: RSP vCont not supported: ignored\n" ); + return; + } + else if (0 == strncmp ("vFile:", p_buf->data, strlen ("vFile:"))) + { + /* For now we don't support this. */ + fprintf (stderr, "Warning: RSP vFile not supported: ignored\n" ); + put_str_packet (""); + return; + } + else if (0 == strncmp ("vFlashErase:", p_buf->data, strlen ("vFlashErase:"))) + { + /* For now we don't support this. */ + fprintf (stderr, "Warning: RSP vFlashErase not supported: ignored\n" ); + put_str_packet ("E01"); + return; + } + else if (0 == strncmp ("vFlashWrite:", p_buf->data, strlen ("vFlashWrite:"))) + { + /* For now we don't support this. */ + fprintf (stderr, "Warning: RSP vFlashWrite not supported: ignored\n" ); + put_str_packet ("E01"); + return; + } + else if (0 == strcmp ("vFlashDone", p_buf->data)) + { + /* For now we don't support this. */ + fprintf (stderr, "Warning: RSP vFlashDone not supported: ignored\n" ); + put_str_packet ("E01"); + return; + } + else if (0 == strncmp ("vRun;", p_buf->data, strlen ("vRun;"))) + { + /* We shouldn't be given any args, but check for this */ + if (p_buf->len > (int) strlen ("vRun;")) + { + fprintf (stderr, "Warning: Unexpected arguments to RSP vRun " + "command: ignored\n"); + } + + /* Restart the current program. However unlike a "R" packet, "vRun" + should behave as though it has just stopped. We use signal + 5 (TRAP). */ + rsp_restart (); + put_str_packet ("S05"); + } + else + { + fprintf (stderr, "Warning: Unknown RSP 'v' packet type %s: ignored\n", + p_buf->data); + put_str_packet ("E01"); + return; + } +} /* rsp_vpkt () */ + + +/*---------------------------------------------------------------------------*/ +/*!Handle a RSP write memory (binary) request + + Syntax is: + + X,: + + Followed by the specified number of bytes as raw binary. Response should be + "OK" if all copied OK, E if error has occurred. + + The length given is the number of bytes to be written. However the number + of data bytes may be greater, since '#', '$' and '}' are escaped by + preceding them by '}' and oring with 0x20. + + @param[in] p_buf The command received */ +/*---------------------------------------------------------------------------*/ +static void +rsp_write_mem_bin (struct rsp_buf *p_buf) +{ + unsigned int addr; /* Where to write the memory */ + int len; /* Number of bytes to write */ + char *bindat; /* Pointer to the binary data */ + int off = 0; /* Offset to start of binary data */ + int newlen; /* Number of bytes in bin data */ + + if (2 != sscanf (p_buf->data, "X%x,%x:", &addr, &len)) + { + fprintf (stderr, "Warning: Failed to recognize RSP write memory " + "command: %s\n", p_buf->data); + put_str_packet ("E01"); + return; + } + + /* Find the start of the data and "unescape" it */ + bindat = p_buf->data; + while(off < GDB_BUF_MAX){ + if(bindat[off] == ':'){ + bindat = bindat + off + 1; + off++; + break; + } + off++; + } + if(off >= GDB_BUF_MAX){ + put_str_packet ("E01"); + return; + } + + newlen = rsp_unescape (bindat, p_buf->len - off); + + /* Sanity check */ + if (newlen != len) + { + int minlen = len < newlen ? len : newlen; + + fprintf (stderr, "Warning: Write of %d bytes requested, but %d bytes " + "supplied. %d will be written\n", len, newlen, minlen); + len = minlen; + } + + // Make sure the processor is stalled + gdb_ensure_or1k_stalled(); + + // Set chain 5 --> Wishbone Memory chain + err = gdb_set_chain(SC_WISHBONE); + if(err){ + put_str_packet ("E01"); + return; + } + + /* Write the bytes to memory */ + if (len) + { + swap_buf(bindat, len); + + if (DEBUG_GDB_BLOCK_DATA){ + uint32_t temp_uint32; + for (off = 0; off < len; off++){ + temp_uint32 = (temp_uint32 << 8) | (0x000000ff & bindat[off]); + if((off %4 ) == 3){ + temp_uint32 = htonl(temp_uint32); + } + switch(off % 16) + { + case 3: + printf("Add 0x%08x Data 0x%08x ", addr + off - 3, temp_uint32); + break; + case 7: + case 11: + printf("0x%08x ", temp_uint32); + break; + case 15: + printf("0x%08x\n", temp_uint32); + break; + default: + break; + } + if ((len - off == 1) && (off % 16) < 15) printf("\n"); + } + } + + err = gdb_write_block(addr, (uint32_t*)bindat, len); + if(err){ + put_str_packet ("E01"); + return; + } + if (DEBUG_GDB) printf("Error %x\n", err);fflush (stdout); + } + put_str_packet ("OK"); + +} /* rsp_write_mem_bin () */ + + +/*---------------------------------------------------------------------------*/ +/*!Handle a RSP remove breakpoint or matchpoint request + + For now only memory breakpoints are implemented, which are implemented by + substituting a breakpoint at the specified address. The implementation must + cope with the possibility of duplicate packets. + + @todo This doesn't work with icache/immu yet + + @param[in] p_buf The command received */ +/*---------------------------------------------------------------------------*/ +static void +rsp_remove_matchpoint (struct rsp_buf *p_buf) +{ + enum mp_type type; /* What sort of matchpoint */ + uint32_t addr; /* Address specified */ + int len; /* Matchpoint length (not used) */ + struct mp_entry *mpe; /* Info about the replaced instr */ + + /* Break out the instruction */ + if (3 != sscanf (p_buf->data, "z%1d,%x,%1d", (int *)&type, &addr, &len)) + { + fprintf (stderr, "Warning: RSP matchpoint deletion request not " + "recognized: ignored\n"); + put_str_packet ("E01"); + return; + } + + /* Sanity check that the length is 4 */ + if (4 != len) + { + fprintf (stderr, "Warning: RSP matchpoint deletion length %d not " + "valid: 4 assumed\n", len); + len = 4; + } + + /* Sort out the type of matchpoint */ + switch (type) + { + case BP_MEMORY: + /* Memory breakpoint - replace the original instruction. */ + mpe = mp_hash_delete (type, addr); + + /* If the BP hasn't yet been deleted, put the original instruction + back. Don't forget to free the hash table entry afterwards. */ + if (NULL != mpe) + { + // Arc Sim Code --> set_program32 (addr, mpe->instr); + // Make sure the processor is stalled + gdb_ensure_or1k_stalled(); + + // Set chain 5 --> Wishbone Memory chain + err = gdb_set_chain(SC_WISHBONE); + if(err){ + put_str_packet ("E01"); + return; + } + err = gdb_write_block(addr, &mpe->instr, 4); + if(err){ + put_str_packet ("E01"); + return; + } + free (mpe); + } + + put_str_packet ("OK"); + return; + + case BP_HARDWARE: + put_str_packet (""); /* Not supported */ + return; + + case WP_WRITE: + put_str_packet (""); /* Not supported */ + return; + + case WP_READ: + put_str_packet (""); /* Not supported */ + return; + + case WP_ACCESS: + put_str_packet (""); /* Not supported */ + return; + + default: + fprintf (stderr, "Warning: RSP matchpoint type %d not " + "recognized: ignored\n", type); + put_str_packet ("E01"); + return; + + } +} /* rsp_remove_matchpoint () */ + + +/*---------------------------------------------------------------------------*/ +/*!Handle a RSP insert breakpoint or matchpoint request + + For now only memory breakpoints are implemented, which are implemented by + substituting a breakpoint at the specified address. The implementation must + cope with the possibility of duplicate packets. + + @todo This doesn't work with icache/immu yet + + @param[in] p_buf The command received */ +/*---------------------------------------------------------------------------*/ +static void +rsp_insert_matchpoint (struct rsp_buf *p_buf) +{ + enum mp_type type; /* What sort of matchpoint */ + uint32_t addr; /* Address specified */ + int len; /* Matchpoint length (not used) */ + uint32_t instr; + + /* Break out the instruction */ + if (3 != sscanf (p_buf->data, "Z%1d,%x,%1d", (int *)&type, &addr, &len)) + { + fprintf (stderr, "Warning: RSP matchpoint insertion request not " + "recognized: ignored\n"); + put_str_packet ("E01"); + return; + } + + /* Sanity check that the length is 4 */ + if (4 != len) + { + fprintf (stderr, "Warning: RSP matchpoint insertion length %d not " + "valid: 4 assumed\n", len); + len = 4; + } + + /* Sort out the type of matchpoint */ + switch (type) + { + case BP_MEMORY: // software-breakpoint Z0 break + /* Memory breakpoint - substitute a TRAP instruction */ + // Make sure the processor is stalled + gdb_ensure_or1k_stalled(); + + // Set chain 5 --> Wishbone Memory chain + gdb_set_chain(SC_WISHBONE); + + // Read the data from Wishbone Memory chain + // Arc Sim Code --> mp_hash_add (type, addr, eval_direct32 (addr, 0, 0)); + gdb_read_block(addr, &instr, 4); + + mp_hash_add (type, addr, instr); + + // Arc Sim Code --> set_program32 (addr, OR1K_TRAP_INSTR); + instr = OR1K_TRAP_INSTR; + err = gdb_write_block(addr, &instr, 4); + if(err){ + put_str_packet ("E01"); + return; + } + put_str_packet ("OK"); + return; + + case BP_HARDWARE: // hardware-breakpoint Z1 hbreak + put_str_packet (""); /* Not supported */ + return; + + case WP_WRITE: // write-watchpoint Z2 watch + put_str_packet (""); /* Not supported */ + return; + + case WP_READ: // read-watchpoint Z3 rwatch + put_str_packet (""); /* Not supported */ + return; + + case WP_ACCESS: // access-watchpoint Z4 awatch + put_str_packet (""); /* Not supported */ + return; + + default: + fprintf (stderr, "Warning: RSP matchpoint type %d not " + "recognized: ignored\n", type); + put_str_packet ("E01"); + return; + } +} /* rsp_insert_matchpoint () */ + + +/*--------------------------------------------------------------------------- +Setup the or32 to init state + +---------------------------------------------------------------------------*/ +void setup_or32(void) +{ + uint32_t temp_uint32; + // First set the chain + err = gdb_set_chain(SC_REGISTER); /* 4 Register Chain */ + if(err > 0){ + if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err); + } + if(gdb_read_reg(0x04, &temp_uint32)) printf("Error read from register\n"); + if (DEBUG_GDB) printf("Read from chain 4 SC_REGISTER at add 0x00000004 = 0x%08x\n", temp_uint32 ); + + if(gdb_write_reg(0x04, 0x00000001)) printf("Error write to register\n"); + if (DEBUG_GDB) printf("Write to chain 4 SC_REGISTER at add 0x00000004 = 0x00000001\n"); + + // if(gdb_read_reg(0x04, &temp_uint32)) printf("Error read from register\n"); + // if (DEBUG_GDB) printf("Read from chain 4 SC_REGISTER at add 0x00000004 = 0x%08x\n", temp_uint32 ); + + // if(gdb_read_reg(0x04, &temp_uint32)) printf("Error read from register\n"); + // if (DEBUG_GDB) printf("Read from chain 4 SC_REGISTER at add 0x00000004 = 0x%08x\n", temp_uint32 ); + + if(gdb_write_reg(0x00, 0x01000001)) printf("Error write to register\n"); + if (DEBUG_GDB) printf("Write to chain 4 SC_REGISTER at add 0x00000000 = 0x01000001\n"); +} + +// Function to check if the processor is stalled - if not then stall it. +// this is useful in the event that GDB thinks the processor is stalled, but has, in fact +// been hard reset on the board and is running. +static void gdb_ensure_or1k_stalled() +{ + unsigned char stalled; + dbg_cpu0_read_ctrl(0, &stalled); + if ((stalled & 0x1) != 0x1) + { + if (DEBUG_GDB) + printf("Processor not stalled, like we thought\n"); + + // Set the TAP controller to its OR1k chain + dbg_set_tap_ir(JI_DEBUG); + gdb_chain = -1; + + // Processor isn't stalled, contrary to what we though, so stall it + printf("Stalling or1k\n"); + dbg_cpu0_write_ctrl(0, 0x01); // stall or1k + } +} + + +int gdb_read_reg(uint32_t adr, uint32_t *data) { + switch (gdb_chain) { + case SC_RISC_DEBUG: return dbg_cpu0_read(adr, data) ? ERR_CRC : ERR_NONE; + case SC_REGISTER: return dbg_cpu0_read_ctrl(adr, (unsigned char*)data) ? + ERR_CRC : ERR_NONE; + case SC_WISHBONE: return dbg_wb_read32(adr, data) ? ERR_CRC : ERR_NONE; + case SC_TRACE: *data = 0; return 0; + default: return JTAG_PROXY_INVALID_CHAIN; + } +} + +int gdb_write_reg(uint32_t adr, uint32_t data) { + switch (gdb_chain) { /* remap registers, to be compatible with jp1 */ + case SC_RISC_DEBUG: if (adr == JTAG_RISCOP) adr = 0x00; + return dbg_cpu0_write(adr, data) ? ERR_CRC : ERR_NONE; + case SC_REGISTER: return dbg_cpu0_write_ctrl(adr, data) ? ERR_CRC : ERR_NONE; + case SC_WISHBONE: return dbg_wb_write32(adr, data) ? ERR_CRC : ERR_NONE; + case SC_TRACE: return 0; + default: return JTAG_PROXY_INVALID_CHAIN; + } +} + +int gdb_read_block(uint32_t adr, uint32_t *data, int len) { + if (DEBUG_CMDS) printf("rb %d\n", gdb_chain); + switch (gdb_chain) { + case SC_WISHBONE: return dbg_wb_read_block32(adr, data, len) ? + ERR_CRC : ERR_NONE; + default: return JTAG_PROXY_INVALID_CHAIN; + } +} + +int gdb_write_block(uint32_t adr, uint32_t *data, int len) { + if (DEBUG_CMDS) printf("wb %d\n", gdb_chain); + switch (gdb_chain) { + case SC_WISHBONE: return dbg_wb_write_block32(adr, data, len) ? + ERR_CRC : ERR_NONE; + default: return JTAG_PROXY_INVALID_CHAIN; + } +} + +int gdb_set_chain(int chain) { + switch (chain) { + case SC_RISC_DEBUG: + case SC_REGISTER: + case SC_TRACE: + case SC_WISHBONE: gdb_chain = chain; + return ERR_NONE; + default: return JTAG_PROXY_INVALID_CHAIN; + } +} + +/* Added by CZ 24/05/01 */ +int GetServerSocket(const char* name, const char* proto, int port) { + struct servent *service; + struct protoent *protocol; + struct sockaddr_in sa; + struct hostent *hp; + int sockfd; + char myname[256]; + //int flags; --changed to socklen_t for c++?! -- Julius + socklen_t flags; + char sTemp[256]; + + /* First, get the protocol number of TCP */ + if (!(protocol = getprotobyname(proto))) { + sprintf(sTemp, "Unable to load protocol \"%s\"", proto); + perror(sTemp); + return 0; + } + tcp_level = protocol->p_proto; /* Save for later */ + + /* If we weren't passed a non standard port, get the port + from the services directory. */ + if (!port && (service = getservbyname(name, protocol->p_name))) + port = ntohs(service->s_port); + + /* Create the socket using the TCP protocol */ + if ((sockfd = socket(PF_INET, SOCK_STREAM, protocol->p_proto)) < 0) { + perror("Unable to create socket"); + return 0; + } + + flags = 1; + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, + (const char*)&flags, sizeof(int)) < 0) { + sprintf(sTemp, "Can not set SO_REUSEADDR option on socket %d", sockfd); + perror(sTemp); + close(sockfd); + return 0; + } + + /* The server should also be non blocking. Get the current flags. */ + if(fcntl(sockfd, F_GETFL, &flags) < 0) { + sprintf(sTemp, "Unable to get flags for socket %d", sockfd); + perror(sTemp); + close(sockfd); + return 0; + } + + /* Set the nonblocking flag */ + if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) { + sprintf(sTemp, "Unable to set flags for socket %d to value 0x%08x", + sockfd, flags | O_NONBLOCK); + perror(sTemp); + close(sockfd); + return 0; + } + + /* Find out what our address is */ + memset(&sa, 0, sizeof(struct sockaddr_in)); + gethostname(myname, sizeof(myname)); + if(!(hp = gethostbyname(myname))) { + perror("Unable to read hostname"); + close(sockfd); + return 0; + } + + /* Bind our socket to the appropriate address */ + sa.sin_family = hp->h_addrtype; + sa.sin_port = htons(port); + if(bind(sockfd, (struct sockaddr*)&sa, sizeof(struct sockaddr_in)) < 0) { + sprintf(sTemp, "Unable to bind socket %d to port %d", sockfd, port); + perror(sTemp); + close(sockfd); + return 0; + } + serverIP = sa.sin_addr.s_addr; + flags = sizeof(struct sockaddr_in); + if(getsockname(sockfd, (struct sockaddr*)&sa, &flags) < 0) { + sprintf(sTemp, "Unable to get socket information for socket %d", sockfd); + perror(sTemp); + close(sockfd); + return 0; + } + serverPort = ntohs(sa.sin_port); + + /* Set the backlog to 1 connections */ + if(listen(sockfd, 1) < 0) { + sprintf(sTemp, "Unable to set backlog on socket %d to %d", sockfd, 1); + perror(sTemp); + close(sockfd); + return 0; + } + + return sockfd; +} + +//void HandleServerSocket(Boolean block) { +void HandleServerSocket(void) { + struct pollfd fds[2]; + int n; + uint32_t temp_uint32; + + rebuild: + n = 0; + if(!server_fd && !gdb_fd) return; + + if(server_fd) { + fds[n].fd = server_fd; + fds[n].events = POLLIN; + fds[n++].revents = 0; + } + if(gdb_fd) { + fds[n].fd = gdb_fd; + fds[n].events = POLLIN; + fds[n++].revents = 0; + } + + while(1) { + switch(poll(fds, n, -1)) { + case 0: + case -1: + if(errno == EINTR) continue; + perror("poll"); + server_fd = 0; + return; + default: + /* Make sure to handle the gdb port first! */ + if (gdb_fd && (fds[0].revents && !server_fd || fds[1].revents && server_fd)) + { + int revents = server_fd ? fds[1].revents : fds[0].revents; + if (revents & POLLIN){ + /* If we have an unacknowledged exception tell the GDB client. If this + exception was a trap due to a memory breakpoint, then adjust the NPC. */ + if (rsp.client_waiting) + { + err = gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32); + if(err) printf("Error read from PPC register\n"); + if ((TARGET_SIGNAL_TRAP == rsp.sigval) && + (NULL != mp_hash_lookup (BP_MEMORY, temp_uint32))) + { + set_npc (temp_uint32); + } + + rsp_report_exception(); + rsp.client_waiting = 0; /* No longer waiting */ + } + GDBRequest(); + } + else {/* Error Occurred */ + printf("\n%sSocket closed.\n",printTime()); + //fprintf(stderr, + //"Received flags 0x%08x on gdb socket. Shutting down.\n", revents); + close(gdb_fd); + gdb_fd = 0; + } + } + + // Go to blocking accept() instead of looping around through poll(), + // takes a loot of CPU resources and it doesn't work when + // reconnecting... Jonas Rosén + if(!gdb_fd) + { + JTAGRequest(); + rsp.client_waiting = 0; /* No longer waiting */ + goto rebuild; + } + + if(fds[0].revents && server_fd) { + if(fds[0].revents & POLLIN) { + JTAGRequest(); + rsp.client_waiting = 0; /* No longer waiting */ + goto rebuild; + } else { /* Error Occurred */ + fprintf(stderr, + "Received flags 0x%08x on server. Shutting down.\n", + fds[0].revents); + close(server_fd); + server_fd = 0; + serverPort = 0; + serverIP = 0; + return; + } + } + break; + } /* End of switch statement */ + } /* End of while statement */ +} + +void JTAGRequest(void) { + struct sockaddr_in sa; + struct sockaddr* addr = (struct sockaddr*)&sa; + //int n = sizeof(struct sockaddr_in); --changed to socklen_t from int type + socklen_t n = sizeof(struct sockaddr_in); + int fd = accept(server_fd, addr, &n); + int on_off = 0; /* Turn off Nagel's algorithm on the socket */ + int flags; + char sTemp[256]; + if (DEBUG_GDB) printf("JTAGRequest\n"); + + if(fd < 0) { + /* This is valid, because a connection could have started, + and then terminated due to a protocol error or user + initiation before the accept could take place. */ + if(errno != EWOULDBLOCK && errno != EAGAIN) { + perror("accept"); + close(server_fd); + server_fd = 0; + serverPort = 0; + serverIP = 0; + } + return; + } + + if(gdb_fd) { + close(fd); + return; + } + + if(fcntl(fd, F_GETFL, &flags) < 0) { + sprintf(sTemp, "Unable to get flags for gdb socket %d", fd); + perror(sTemp); + close(fd); + return; + } + + /* Rene + if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { + sprintf(sTemp, "Unable to set flags for gdb socket %d to value 0x%08x", + fd, flags | O_NONBLOCK); + perror(sTemp); + close(fd); + return; + } Rene */ + + if(setsockopt(fd, tcp_level, TCP_NODELAY, &on_off, sizeof(int)) < 0) { + sprintf(sTemp, "Unable to disable Nagel's algorithm for socket %d.\nsetsockopt", fd); + perror(sTemp); + close(fd); + return; + } + + printf("\n%sConnection established from %s on port %d\n", printTime(),inet_ntoa(sa.sin_addr),ntohs(sa.sin_port)); + gdb_fd = fd; +} + + +/*--------------------------------------------------------------------------- +* Decode the GDB command. +* +*---------------------------------------------------------------------------*/ +static void GDBRequest(void) { + JTAGProxyWriteMessage msg_write; + JTAGProxyReadMessage msg_read; + JTAGProxyChainMessage msg_chain; + JTAGProxyWriteResponse resp_write; + JTAGProxyReadResponse resp_read; + JTAGProxyChainResponse resp_chain; + JTAGProxyBlockWriteMessage *msg_bwrite; + JTAGProxyBlockReadMessage msg_bread; + JTAGProxyBlockWriteResponse resp_bwrite; + JTAGProxyBlockReadResponse *resp_bread; + char *p_buf; + uint32_t command; + uint32_t length; + int len, i; + + /* First, we must read the incomming command */ + if(gdb_read(&command, sizeof(uint32_t)) < 0) { + client_close ('1'); + return; + } + command = ntohl(command); + + if(gdb_read(&length, sizeof(uint32_t)) < 0) { + client_close ('2'); + return; + } + length = ntohl(length); + if (DEBUG_GDB) printf("\n%s-----------------------------------------------------\nCommand %d Length %d ", printTime(), command, length); + + if (DEBUG_GDB){ + switch(command){ + case JTAG_COMMAND_READ: + printf("JTAG_COMMAND_READ \n"); + break; + case JTAG_COMMAND_WRITE: + printf("JTAG_COMMAND_WRITE \n"); + break; + case JTAG_COMMAND_BLOCK_READ: + printf("JTAG_COMMAND_BLOCK_READ \n"); + break; + case JTAG_COMMAND_BLOCK_WRITE: + printf("JTAG_COMMAND_BLOCK_WRITE\n"); + break; + case JTAG_COMMAND_CHAIN: + printf("JTAG_COMMAND_CHAIN \n"); + break; + } + } + + /* Now, verify the protocol and implement the command */ + switch(command) { + case JTAG_COMMAND_WRITE: + if(length != sizeof(msg_write) - 8) { + ProtocolClean(length, JTAG_PROXY_PROTOCOL_ERROR); + return; + } + p_buf = (char*)&msg_write; + if(gdb_read(&p_buf[8], length) < 0) { + client_close ('3'); + return; + } + msg_write.address = ntohl(msg_write.address); + msg_write.data_H = ntohl(msg_write.data_H); + msg_write.data_L = ntohl(msg_write.data_L); + err = gdb_write_reg(msg_write.address, msg_write.data_L); + resp_write.status = htonl(err); + if (DEBUG_GDB) printf("Write Reg to Chain %d at add 0x%08x -> H-Data 0x%08x L-Data 0x%08x Error %d", + gdb_chain, msg_write.address, msg_write.data_H, msg_write.data_L, err);fflush (stdout); + if(gdb_write(&resp_write, sizeof(resp_write)) < 0) { + client_close ('4'); + return; + } + break; + case JTAG_COMMAND_READ: + if(length != sizeof(msg_read) - 8) { + ProtocolClean(length, JTAG_PROXY_PROTOCOL_ERROR); + return; + } + p_buf = (char*)&msg_read; + if(gdb_read(&p_buf[8], length) < 0) { + client_close ('5'); + return; + } + msg_read.address = ntohl(msg_read.address); + err = gdb_read_reg(msg_read.address, (uint32_t *)&resp_read.data_L); + if (DEBUG_GDB) printf("Read Reg from Chain %d at add 0x%08x", gdb_chain, msg_read.address); + resp_read.status = htonl(err); + resp_read.data_H = 0; + resp_read.data_L = htonl(resp_read.data_L); + if(gdb_write(&resp_read, sizeof(resp_read)) < 0) { + client_close ('6'); + return; + } + if (DEBUG_GDB) printf(" --> Data 0x%08x Error %d\n", htonl(resp_read.data_L), err);fflush (stdout); + break; + case JTAG_COMMAND_BLOCK_WRITE: + if(length < sizeof(JTAGProxyBlockWriteMessage)-8) { + ProtocolClean(length, JTAG_PROXY_PROTOCOL_ERROR); + return; + } + if(!(p_buf = (char*)malloc(8+length))) { + ProtocolClean(length, JTAG_PROXY_OUT_OF_MEMORY); + return; + } + msg_bwrite = (JTAGProxyBlockWriteMessage*)p_buf; + if(gdb_read(&p_buf[8], length) < 0) { + client_close ('5'); + free(p_buf); + return; + } + msg_bwrite->address = ntohl(msg_bwrite->address); + msg_bwrite->nRegisters = ntohl(msg_bwrite->nRegisters); + if (DEBUG_GDB) printf("Block Write to Chain %d start add 0x%08x Write %d (32 bit words):\n\n", gdb_chain, msg_bwrite->address, msg_bwrite->nRegisters); + for(i=0;inRegisters;i++) { + msg_bwrite->data[i] = ntohl(msg_bwrite->data[i]); + if (DEBUG_GDB_BLOCK_DATA){ + if ((i % 4) == 0) printf("Add 0x%08x Data 0x%08x ", msg_bwrite->address + (i * 4), msg_bwrite->data[i]); + else if ((i % 4) == 3) printf("0x%08x\n", msg_bwrite->data[i]); + else printf("0x%08x ", msg_bwrite->data[i]); + + // add a new line on the last data, but not if it is the last one in the colum + if ((msg_bwrite->nRegisters - i == 1) && (i % 4) < 3) printf("\n"); + } + } + err = gdb_write_block(msg_bwrite->address, (uint32_t*)msg_bwrite->data, msg_bwrite->nRegisters * 4); + if (DEBUG_GDB) printf("Error %x\n", err);fflush (stdout); + resp_bwrite.status = htonl(err); + free(p_buf); + msg_bwrite = (JTAGProxyBlockWriteMessage *)NULL; + p_buf = (char *)msg_bwrite; + if(gdb_write(&resp_bwrite, sizeof(resp_bwrite)) < 0) { + client_close ('4'); + return; + } + break; + case JTAG_COMMAND_BLOCK_READ: + if(length != sizeof(msg_bread) - 8) { + ProtocolClean(length, JTAG_PROXY_PROTOCOL_ERROR); + return; + } + p_buf = (char*)&msg_bread; + if(gdb_read(&p_buf[8], length) < 0) { + client_close ('5'); + return; + } + msg_bread.address = ntohl(msg_bread.address); + msg_bread.nRegisters = ntohl(msg_bread.nRegisters); + if (DEBUG_GDB) printf("Block Read from Chain %d start add 0x%08x Read %d (32 bit words):\n\n", gdb_chain, msg_bread.address, msg_bread.nRegisters); + len = sizeof(JTAGProxyBlockReadResponse) + 4*(msg_bread.nRegisters-1); + if(!(p_buf = (char*)malloc(len))) { + ProtocolClean(0, JTAG_PROXY_OUT_OF_MEMORY); + return; + } + resp_bread = (JTAGProxyBlockReadResponse*)p_buf; + err = gdb_read_block(msg_bread.address, (uint32_t*)resp_bread->data, msg_bread.nRegisters * 4); + for(i=0;idata[i] = htonl(resp_bread->data[i]); + if (DEBUG_GDB_BLOCK_DATA){ + if ((i % 4) == 0) printf("Add 0x%08x Data 0x%08x ", msg_bread.address + (i * 4), htonl(resp_bread->data[i])); + else if ((i % 4) == 3) printf("0x%08x\n", htonl(resp_bread->data[i])); + else printf("0x%08x ", htonl(resp_bread->data[i])); + } + // add a new line on the last data, but not if it is the last one in the colum + if ((msg_bread.nRegisters - i == 1) && (i % 4) < 3) printf("\n"); + } + resp_bread->status = htonl(err); + resp_bread->nRegisters = htonl(msg_bread.nRegisters); + if (DEBUG_GDB) printf("\nError %x\n", err);fflush (stdout); + if(gdb_write(resp_bread, len) < 0) { + client_close ('6'); + free(p_buf); + return; + } + free(p_buf); + resp_bread = (JTAGProxyBlockReadResponse *)NULL; + p_buf = (char *)resp_bread; + break; + case JTAG_COMMAND_CHAIN: + if(length != sizeof(msg_chain) - 8) { + ProtocolClean(length, JTAG_PROXY_PROTOCOL_ERROR); + return; + } + p_buf = (char*)&msg_chain; + if(gdb_read(&p_buf[8], sizeof(msg_chain)-8) < 0) { + client_close ('7'); + return; + } + msg_chain.chain = htonl(msg_chain.chain); + err = gdb_set_chain(msg_chain.chain); + resp_chain.status = htonl(err); + if (DEBUG_GDB){ + switch(msg_chain.chain){ + case SC_GLOBAL: /* 0 Global BS Chain */ + printf("Set Chain %d Global BS Chain Error %x\n", msg_chain.chain, err); + break; + case SC_RISC_DEBUG: /* 1 RISC Debug Interface chain */ + printf("Set Chain %d RISC Debug Interface chain Error %x\n", msg_chain.chain, err); + break; + case SC_RISC_TEST: /* 2 RISC Test Chain */ + printf("Set Chain %d RISC Test Chain Error %x\n", msg_chain.chain, err); + break; + case SC_TRACE: /* 3 Trace Chain */ + printf("Set Chain %d Trace Chain Error %x\n", msg_chain.chain, err); + break; + case SC_REGISTER: /* 4 Register Chain */ + printf("Set Chain %d Register Chain Error %x\n", msg_chain.chain, err); + break; + case SC_WISHBONE: /* 5 Memory chain */ + printf("Set Chain %d Wishbone Memory chain Error %x\n", msg_chain.chain, err); + break; + case SC_BLOCK: /* 6 Block Chains */ + printf("Set Chain %d Block Chains Error %x\n", msg_chain.chain, err); + break; + default: /* Invalid chain */ + printf("Set Chain %d Invalid chain Error %x\n", msg_chain.chain, err); + break; + } + fflush (stdout); + } + if(gdb_write(&resp_chain, sizeof(resp_chain)) < 0) { + client_close ('8'); + return; + } + break; + default: + perror("Unknown JTAG command.");fflush (stdout); + ProtocolClean(length, JTAG_PROXY_COMMAND_NOT_IMPLEMENTED); + break; + } +} + +static void ProtocolClean(int length, int32_t err) { + char buffer[4096]; + + err = htonl(err); + if((gdb_read(buffer, length) < 0) || (gdb_write(&err, sizeof(err)) < 0) && gdb_fd) { + perror("gdb socket - 9"); + close(gdb_fd); + gdb_fd = 0; + } +} + +static int gdb_write(void* p_buf, int len) { + int n; + char* w_buf = (char*)p_buf; + struct pollfd block; + + while(len) { + if((n = write(gdb_fd, w_buf, len)) < 0) { + switch(errno) { + case EWOULDBLOCK: /* or EAGAIN */ + /* We've been called on a descriptor marked + for nonblocking I/O. We better simulate + blocking behavior. */ + block.fd = gdb_fd; + block.events = POLLOUT; + block.revents = 0; + poll(&block, 1, -1); + continue; + case EINTR: + continue; + case EPIPE: + close(gdb_fd); + gdb_fd = 0; + return -1; + default: + return -1; + } + } else { + len -= n; + w_buf += n; + } + } + return 0; +} + +static int gdb_read(void* p_buf, int len) { + int n; + char* r_buf = (char*)p_buf; + struct pollfd block; + + while(len) { + if((n = read(gdb_fd, r_buf, len)) < 0) { + switch(errno) { + case EWOULDBLOCK: /* or EAGAIN */ + /* We've been called on a descriptor marked + for nonblocking I/O. We better simulate + blocking behavior. */ + block.fd = gdb_fd; + block.events = POLLIN; + block.revents = 0; + poll(&block, 1, -1); + continue; + case EINTR: + continue; + default: + return -1; + } + } else if(n == 0) { + close(gdb_fd); + gdb_fd = 0; + return -1; + } else { + len -= n; + r_buf += n; + } + } + return 0; +} + + +/***************************************************************************** +* Close the connection to the client if it is open +******************************************************************************/ +static void client_close (char err) +{ + if(gdb_fd) { + perror("gdb socket - " + err); + close(gdb_fd); + gdb_fd = 0; + } +} /* client_close () */ + + +/*---------------------------------------------------------------------------*/ +/* Swap a buffer of 4-byte from 1234 to 4321 + + parameter[in] p_buf and len + parameter[out] none */ +/*---------------------------------------------------------------------------*/ +static void swap_buf(char* p_buf, int len) +{ + int temp; + int n = 0; + + if (len > 2) + { + while(n < len){ + // swap 0 and 3 + temp = p_buf[n]; + p_buf[n] = p_buf[n + 3]; + p_buf[n + 3] = temp; + // swap 1 and 2 + temp = p_buf[n + 1]; + p_buf[n + 1] = p_buf[n + 2]; + p_buf[n + 2] = temp; + + n += 4; + } + } +} + + +/*---------------------------------------------------------------------------*/ +/*!Set the stall state of the processor + + @param[in] state If non-zero stall the processor. */ +/*---------------------------------------------------------------------------*/ +static void +set_stall_state (int state) +{ + + if(state == 0) + { + err = dbg_cpu0_write_ctrl(0, 0); /* unstall or1k */ + stallState = UNSTALLED; + npcIsCached = 0; + rsp.sigval = TARGET_SIGNAL_NONE; + } + else + { + err = dbg_cpu0_write_ctrl(0, 0x01); /* stall or1k */ + stallState = STALLED; + } + + if(err > 0 && DEBUG_GDB)printf("Error %d in set_stall_state Stall state = %d\n", err, state); + +} /* set_stall_state () */ + + +/*---------------------------------------------------------------------------*/ +/*!Close down the connection with GDB in the event of a kill signal + + */ +/*---------------------------------------------------------------------------*/ +void gdb_close() +{ + if (gdb_fd) close(gdb_fd); + // Maybe do other things here! +} Index: or_debug_proxy/README =================================================================== --- or_debug_proxy/README (nonexistent) +++ or_debug_proxy/README (revision 1779) @@ -0,0 +1,325 @@ +=============================================================================== +-- OpenRISC Debug Proxy -- +=============================================================================== + +=============================================================================== +-- Description -- +=============================================================================== +A console application that implements a GDB stub and various ways to +communicate with an OpenRISC processor system. This done by initally making a +connection to a target system before handling a connection from a GDB client +and relaying debug commands. Connections to the target can be made in many +ways, however debugging FPGA or ASIC targets will be through use of the ORSoC +USB debug cable. +=============================================================================== +-- Versions -- +=============================================================================== +0.1.0 090201 jb@orsoc.se +0.1.1 090304 jb@orsoc.se +0.1.2 090511 jb@orsoc.se + +=============================================================================== +-- Installation -- +=============================================================================== + +The OR debug proxy application runs on multiple platforms only requiring +slightly different driver configurations on each. Currently, Cygwin Windows, +several Linux distos and Mac OS X (10.4 and above) are supported. All require +installation of some form of the FTDI Chip FTD2XX driver. Instructions for +each platform follow. + +------------------------------------------------------------------------------- +-- Installation on Cygwin Windows -- +------------------------------------------------------------------------------- + +-- ORSoC OpenRISC USB debug cable driver installation -- + + As per the installation instructions included in FTDI Chip's D2XX Windows + driver. http://www.ftdichip.com/Drivers/D2XX.htm + +-- Compilation of the OpenRISC Debug Proxy application -- + + While in the same directory which this file is located in, run a simple + "make" command. + + user@cygwin-host ~/or_debug_proxy + $ make + + Run the resulting executable (or_debug_proxy.exe) for usage details. + +------------------------------------------------------------------------------- +-- Installation on Linux +------------------------------------------------------------------------------- + +-- ORSoC OpenRISC USB debug cable driver installation -- + +Before we begin: + +It is required that the Linux distribution have a version 2.4 kernel, or +above. This is due to the USB driver libraries by FTDI Chip used to interface +with the USB debug device. + +The ORSoC USB debugger cable uses a FTDI dual UART/FIFO chip. + +An aside: These USB to serial devices typically trigger the loading of another +FTDI driver when they're attached to the system. This is the ftdi_sio driver +and now comes standard in newer kernels. This is of use to us, as one of the +two serial devices will remain is a standard uart under /dev/ttyUSBx. However, +to enable a high-speed JTAG interface with our hardware we require newer, +specialised drivers from FTDI called the D2XX drivers. + +The Linux driver can be obtained from FTDI Chip's website, +http://www.ftdichip.com, and is found under the links to "Drivers" and then +"D2XX". At the time of writing, the latest version was libftd2xx 0.4.16 and +could be downloaded directly off their site from +http://www.ftdichip.com/Drivers/D2XX/Linux/libftd2xx0.4.16.tar.gz + +Statically linked driver: + +The simplest way to enable these drivers is to link the application +statically - that is, have a copy of the driver along with the debugging +application. This is much simpler than the following driver installation +instructions. Typically in the FTDI drivers there is also a directory called +static_lib/ and this contains a driver that can be statically linked against +when compiling. To compile the OpenRISC debug proxy like this, copy the file in +that static_lib/ path into the lib/ directory under the or_debug_proxy/ +build directory, and do: + + user@host:~/or_debug_proxy$ make or_debug_proxy_static + +This will result in the executable being statically linked to the driver file +in the the lib/ folder. + +Dynamically linked driver install directions: + +Uncompress the driver package (tar xzvf libftd2xx0.4.16.tar.gz) and read the +file "readme.dat" located inside, but don't complete their way of installing +yet. Their installation method should be modified slightly to allow easier use +of the USB device by users. Read the following before performing the install +as per the instructions in "readme.dat", and ammend their installation process +as you go. + +* In step 4, create an additional symbolic link, however this time with only a + trailing zero, like so: + + user@host:/usr/local/lib$ ln -s libftd2xx.so.x.x.xx libftd2xx.so.0 + +* Again, in step 6, create an additional symbolic link with only a trailing + zero: + + user@host:/usr/lib$ ln -s /usr/local/lib/libftd2xx.so.x.x.xx libftd2xx.so.0 + +* In step 7 (the following may vary depending on your distribution, however in + the most recent Ubuntu our suggested modification was required) instead of + the line provided in "readme.dat", use the following in your /etc/fstab file + (note the difference is a change from "usbdevfs" to "usbfs") + + none /proc/bus/usb usbfs defaults,devmode=0666 0 0 + +* The last step (mount -a) outlined in "readme.dat" can then be performed. + +-- Setting USB device permissions -- + +Depending on the Linux distribution and how recent it is, the method for +defining the permissions of the USB device when it's loaded by the kernel can +vary. + +* Recent udev systems (most 2.6 kernel systems) + +There can be variations in the way udev organises its files for setting up +rules and permissions of devices attached to the system, but the following +should cover most systems. + +Do a listing of the udev rules directory + + user@host:~$ ls /etc/udev/rules.d/ + +There should be a file somewhere, with the word "permissions" in the name. On +some systems it could be called "40-permissions.rules", on others possibly +"020_permissions.rules". Locate the permissions file in /etc/udev/rules.d/ +and, as the super user (root), open the file to edit. The author prefers nano. + + user@host:/etc/udev/rules.d$ sudo nano 40-permissions.rules + [sudo] password for user: + +Of course, editing as super user (sudo'ing) will require the ability to sudo. + +The following can differ from system to system. In this case, a recent version +of Ubuntu, the file "40-permissions.rules" was present and will be edited. + +In this particular permissions file there are different sections, some with +labels. + +Search for the lines with LABEL="usb_serial_start" and +LABEL="usb_serial_end". In BETWEEN these two LABEL lines, insert two new lines +containing the following: + + # Permissions for ORSoC USB debugger FT2232 device + ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", MODE="0666", GROUP="tty" + +If these LABEL="" lines cannot be found (for instance, different distros have +their udev setup differently) insert the above line anywhere in the file. This +is not a definite way of enabling these permissions, and udev exists in many +forms and configurations, so if this does not work, please contact the author +regarding the issue. + +* Fedora 9 + +As an example of a slightly different system, Fedora 9 does not have a +xx-permissions.rules file. The solution is to create a new file, but in this +case choose the name "51-permissions.rules". It can have just the rule listed +above: + + # Permissions for ORSoC USB debugger FT2232 device + ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", MODE="0666", GROUP="tty" + +The reason for the filename change is that the udev rules files are read in +lexical order (i.e. the order they would appear in a dictionary). With Fedora +9 the old FTDI driver is included as standard, and there is default rule in +50-udev-default.rules, which would override anything in 40-permissions.rules +(since it would be read first). By using the name 51-permissions.rules, our +rule will override anything set in 50-udev-default.rules. + +If you find problems with permissions, then check that no later rules files +are overriding settings. + +The devices whose permissions are set are /dev/ttyUSB0 /dev/ttyUSB1, the +/dev/usbdevnnn for the USB slot (nnn) being used, and the files in +/dev/bus/usb/nnn/xxx. They should all be in group tty and have permission +rw-rw-rw. + +* Older systems, (early udev, devfs) + +None of these systems were tested, however it should be easy enough to locate +the device by the vendor ID and product ID on the USB bus. See the Udev +instructions above for these values. + +* Reloading the ftdi_sio driver + +If it is desired that the D2XX drivers be unloaded and the original ftdi_sio one +reactivated (recreating the two /dev/ttyUSB devices), it is as simple as +removing and replacing the USB dongle from the system. However, it can also be +done at the prompt by first running as root "modprobe -r ftdi_sio", and then +"modprobe ftdi_sio vendor=0x0403 product=0x6010", which totally removes and +then reloads the device. + +-- Compilation of the OpenRISC Debug Proxy application -- + + While in the same directory which this file is located in, run a simple + "make" command. + + user@host:~/or_debug_proxy$ make + + The proxy application can then be run with the desired options, or for + usage details, run the program with no options specified. + + user@host:~/or_debug_proxy$ ./or_debug_proxy + + Invalid or insufficient arguments + + OpenRISC GDB proxy server usage: or_debug_proxy -server_type port + + server_type: + -r Start a server using RSP, connection to hadware target via + USB + -j Start a server using legacy OR remote JTAG protocol, to + hardware target via USB + -v Start a server using RSP, connection to RTL sim. VPI server + target via sockets + + port_number: + Any free port within the usable range of 0 - 65535 + + Example: + Start a GDB server on port 5555, using RSP, connecting to + hardware target via USB + or_debug_proxy -r 5555 + + +* Platforms tested, and known to be working, on: + Ubuntu 8.04 + Debian + +------------------------------------------------------------------------------- +-- Installation on Mac OS X -- +------------------------------------------------------------------------------- + +-- ORSoC OpenRISC USB debug cable driver installation -- + + As per the installation instructions included in FTDI Chip's D2XX Mac OS X + driver. http://www.ftdichip.com/Drivers/D2XX.htm + +-- Compilation of the OpenRISC Debug Proxy application -- + + As per the Linux instructions. + + +* Note: Tested on an Intel Mac, running OS X version 10.4 + + + +=============================================================================== +-- Usage notes -- +=============================================================================== + +When the program initialises it sets up some form of communication with an +OpenRISC processor (developed and tested with a OR1k design similar to the +ORPSoC design found in the OR1k project archive on OpenCores), either via a +USB debug cable or via sockets interface to an RTL simulation. After this, it +waits for a connection from GDB, and then the debugging session can begin. + +The proxy has been written to be robust, for example it will hopefully handle +disruptions like processor crashes, hardware resets, and connection dropouts +gracefully enough to not require a complete restart of the proxy and GDB. + +Some basic mechanics of the proxy are as follows: + +* When the program is "continued" from GDB, the proxy will poll the previous + program counter (PPC), checking it against the internal list of software + breakpoints, at second intervals to see if a software breakpoint has been + reached. + +* The one second polling also applies to "interrupt" (^C signals) from GDB, + which will cause the processor to be stalled, wherever it is, and control + returned to GDB (the proxy will await further commands from GDB.) It is + optional to implement this awareness of the interrupt signal from GDB, but + the developers have found this functionality extremely useful and thought + others might too. + +* Troubleshooting tip: If the proxy prints out the following line(s): + RSP step with signal 'S04' received + when attempting to continue, or single step, a program from GDB, it is + necessary to restart both the proxy and GDB before being continuing. + This bug is perhaps caused by changing the file GDB is debugging during the + same session. + +TODO List: + * Explicit char and short reading and writing ability: + Currently only full word writing and reading is supported by the proxy. + It would be great if individual words and chars could be read also. It + is possible to receive such requests from GDB, so there's no reason why + they shouldn't be supported. It should be simple enough to implement. + * Correct organisation of non-word aligned reading + There's some problems when reading a word from a non-word aligned + boundary. This should be possible, for instance in GDB, doing something + like "x/4 0x101" should read the four bytes starting at address 0x101 + and should display them LSB first. However this doesn't appear to + function as intended. + * USB<->JTAG Driver TODO: Increase speed of the proxy + It appears that the current transfer rate of around 20k/s is due to + pauses in the driver. This was deteremined by profiling the proxy and + noticing that, over a 4-odd megabyte transfer from GDB, taking about 4 + minutes, the proxy only executed for 2.5 seconds, and the three most + used functions, accounting for 50% of execution were functions in the + driver. This indicates that either better use of, or better + implementation of, the driver could dramatically increase speed. + * USB<->JTAG Driver TODO: + Get the latest version of the MPSSE function code (from + http://ftdichip.com/Projects/MPSSE/FTCJTAG/FTCJTAG_Source.zip at last + check) and update our Linux compatible version with the ones here. This + might provide improved stability or performance, but from the list of + improvements made to the files from our version it doesn't appear like + it would result in significant improvement in the proxy app. + * Better README + It would be nice to provide more important documentation of nuances of + the proxy operation Index: or_debug_proxy/Makefile =================================================================== --- or_debug_proxy/Makefile (nonexistent) +++ or_debug_proxy/Makefile (revision 1779) @@ -0,0 +1,141 @@ +# +#****************************************************************************# +# # +# H E A D E R I N F O R M A T I O N # +# # +#****************************************************************************# + +# Project Name : OpenRISC Debug Proxy +# File Name : Makefile +# Prepared By : jb +# Project Start : 2008-10-01 + +#$$COPYRIGHT NOTICE# +#****************************************************************************# +# # +# C O P Y R I G H T N O T I C E # +# # +#****************************************************************************# + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; +# version 2.1 of the License, a copy of which is available from +# http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 +# USA. +# + +#$$CHANGE HISTORY# +#****************************************************************************# +# # +# C H A N G E H I S T O R Y # +# # +#****************************************************************************# + +# Date Version Description +#------------------------------------------------------------------------ +# 090301 0.1.0 Makefile for OpenRISC debug proxy. jb +# 2 Apr 09 0.1.1 Jeremy Bennett. Added static target + +#DBGCPPFLAGS=-D DEBUG_GDB=1 +#DBGCPPFLAGS=-D DEBUG_USB_DRVR_FUNCS=1 +#DBGCPPFLAGS=-D DEBUG_USB_DRVR_FUNCS=1 -D DEBUG_GDB=1 -D DEBUG_CMDS=1 + + +# Common Flags +COMMON_CPPFLAGS = -I./includes +COMMON_CXXFLAGS = -O2 -g +COMMON_LDFLAGS = -Wall -g + +# Flags for static library +STATIC_LIBDIR = lib +STATIC_LIB = libftd2xx.a.0.4.16 +STATIC_LDFLAGS = $(COMMON_LDFLAGS) $(STATIC_LIBDIR)/$(STATIC_LIB) \ + -lpthread -ldl + +#Determine whether we're on Cygwin +ifndef OSTYPE + # Basically we're interested in finding out if we're + # in a cygwin environement, so let's find out this way + # Note: Typically in a bash environment, $OSTYPE is set + # but sometimes make can't figure it out. So we'll do it + # this way: + ifeq (CYGWIN, $(findstring CYGWIN, $(shell uname))) + OSTYPE=cygwin + endif +endif + +ifeq ($(OSTYPE),cygwin) + OR_DEBUG_PROXY_SRC = src/or_debug_proxy.c \ + src/gdb.c \ + src/usb_functions.c \ + src/win_usb_driver_calls.c \ + src/vpi_functions.c + CXX = gcc + CPPFLAGS = $(COMMON_CPPFLAGS) -I./obj -DCYGWIN_COMPILE=1 $(DBGCPPFLAGS) + CXXFLAGS = $(COMMON_CXXFLAGS) + DYNAMIC_LDFLAGS = $(COMMON_LDFLAGS) + EXE = .exe +else + OR_DEBUG_PROXY_SRC = src/or_debug_proxy.c \ + src/gdb.c \ + src/FT2232c.cpp \ + src/FT2232cMpsseJtag.cpp \ + src/usb_functions.c \ + src/linux_usb_driver_calls.c \ + src/vpi_functions.c + CXX = g++ + CPPFLAGS = $(COMMON_CPPFLAGS) $(DBGCPPFLAGS) + CXXFLAGS = $(COMMON_CXXFLAGS) + DYNAMIC_LDFLAGS = $(COMMON_LDFLAGS) -lftd2xx + EXE = +endif + +APP = or_debug_proxy +APP_DYNAMIC = $(APP)$(EXE) +APP_STATIC = $(APP)_static$(EXE) + + +# ----------------------------------------------------------------------------- +# Build dynamic and static targets from scratch +.PHONY: all +all: clean $(APP_DYNAMIC) + +static: clean $(APP_STATIC) + +# Dynamic target +$(APP_DYNAMIC): $(OR_DEBUG_PROXY_SRC) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $+ $(DYNAMIC_LDFLAGS) -o $@ + +# Static target +$(APP_STATIC): $(OR_DEBUG_PROXY_SRC) $(STATIC_LIBDIR)/$(STATIC_LIB) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $+ $(STATIC_LDFLAGS) -o $@ + cp $(APP_STATIC) $(APP) + +# ----------------------------------------------------------------------------- +# Target for checking the static lib is in the place it should be +$(STATIC_LIBDIR)/$(STATIC_LIB): + @echo + @echo "The static library, $(STATIC_LIB), is missing." + @echo "Please download the driver to build a statically linked version" + @echo "of this app. For Linux, try:" + @echo "\twget http://www.ftdichip.com/Drivers/D2XX/Linux/libftd2xx0.4.16.tar.gz" + @echo "\ttar xzf libftd2xx0.4.16.tar.gz" + @echo "\tcp libftd2xx0.4.16/static_lib/libftd2xx.a.0.4.16 lib" + @echo + @exit 1 +# ----------------------------------------------------------------------------- +# Tidy up +clean: + $(RM) $(APP_DYNAMIC) + $(RM) $(APP_STATIC) + find ./ -name "*~" | xargs $(RM) Index: or_debug_proxy/TAGS =================================================================== --- or_debug_proxy/TAGS (nonexistent) +++ or_debug_proxy/TAGS (revision 1779) @@ -0,0 +1,1155 @@ + +src/FT2232c.cpp,2219 + static UINT uiNumOpenedDevices 49,871 + static FTC_DEVICE_DATA OpenedDevices[OpenedDevices50,1006 + static OutputByteBuffer OutputBuffer;51,1141 + static DWORD dwNumBytesToSend 52,1276 +BOOLEAN FT2232c::FTC_DeviceInUse(55,1418 +BOOLEAN FT2232c::FTC_DeviceOpened(87,2318 +FTC_STATUS FT2232c::FTC_IsDeviceNameLocationIDValid(122,3348 +FTC_STATUS FT2232c::FTC_IsDeviceFT2232CType(173,4788 +FT2232c::FT2232c(191,5306 +FT2232c::~FT2232c(203,5530 +FTC_STATUS FT2232c::FTC_GetNumDevices(208,5560 +FTC_STATUS FT2232c::FTC_GetNumNotOpenedDevices(313,9440 +FTC_STATUS FT2232c::FTC_GetDeviceNameLocationID(372,11236 +FTC_STATUS FT2232c::FTC_OpenSpecifiedDevice(418,12575 +FTC_STATUS FT2232c::FTC_OpenDevice(465,13870 +FTC_STATUS FT2232c::FTC_CloseDevice(496,14640 +void FT2232c::FTC_GetClockFrequencyValues(512,14923 +FTC_STATUS FT2232c::FTC_SetDeviceLoopbackState(517,15122 +void FT2232c::FTC_InsertDeviceHandle(538,15610 +FTC_STATUS FT2232c::FTC_IsDeviceHandleValid(566,16506 +void FT2232c::FTC_RemoveDeviceHandle(597,17292 +FTC_STATUS FT2232c::FTC_ResetUSBDevicePurgeUSBInputBuffer(628,18189 +FTC_STATUS FT2232c::FTC_SetDeviceUSBBufferSizes(652,18840 +FTC_STATUS FT2232c::FTC_SetDeviceSpecialCharacters(657,19047 +FTC_STATUS FT2232c::FTC_SetReadWriteDeviceTimeouts(667,19557 +FTC_STATUS FT2232c::FTC_SetDeviceLatencyTimer(673,19840 +FTC_STATUS FT2232c::FTC_ResetMPSSEInterface(679,20065 +FTC_STATUS FT2232c::FTC_EnableMPSSEInterface(684,20225 +FTC_STATUS FT2232c::FTC_SendReceiveCommandFromMPSSEInterface(689,20387 +FTC_STATUS FT2232c::FTC_SynchronizeMPSSEInterface(786,23320 +FTC_STATUS FT2232c::FTC_GetNumberBytesFromDeviceInputBuffer(853,25224 +void FT2232c::FTC_ClearOutputBuffer(891,26491 +void FT2232c::FTC_AddByteToOutputBuffer(896,26562 +DWORD FT2232c::FTC_GetNumBytesInOutputBuffer(906,26817 +FTC_STATUS FT2232c::FTC_SendBytesToDevice(911,26900 +FTC_STATUS FT2232c::FTC_ReadBytesFromDevice(952,28644 +FTC_STATUS FT2232c::FTC_ReadFixedNumBytesFromDevice(963,29472 +FTC_STATUS FT2232c::FTC_SendReadBytesToFromDevice(995,30577 +FTC_STATUS FT2232c::FTC_SendCommandsSequenceToDevice(1051,32797 +FTC_STATUS FT2232c::FTC_ReadCommandsSequenceBytesFromDevice(1089,34333 +char* strupr(1128,35572 +char* strlwr(1140,35750 + +src/FT2232cMpsseJtag.cpp,4152 +#define WIO_DEFINED24,394 +FTC_STATUS FT2232cMpsseJtag::CheckWriteDataToExternalDeviceBitsBytesParameters(47,907 +void FT2232cMpsseJtag::AddByteToOutputBuffer(74,1752 +FTC_STATUS FT2232cMpsseJtag::SetDataInOutClockFrequency(93,2552 +FTC_STATUS FT2232cMpsseJtag::InitDataInOutClockFrequency(106,2916 +void FT2232cMpsseJtag::SetJTAGToNewState(135,3943 +DWORD FT2232cMpsseJtag::MoveJTAGFromOneStateToAnother(150,4493 +FTC_STATUS FT2232cMpsseJtag::ResetTAPContollerExternalDeviceSetToTestIdleMode(198,6628 +FTC_STATUS FT2232cMpsseJtag::SetGeneralPurposeInputOutputPins(224,7506 +void FT2232cMpsseJtag::GetGeneralPurposeInputOutputPinsInputStates(273,9398 +FTC_STATUS FT2232cMpsseJtag::GetGeneralPurposeInputOutputPins(288,10018 +void FT2232cMpsseJtag::AddWriteCommandDataToOutPutBuffer(383,13694 +FTC_STATUS FT2232cMpsseJtag::WriteDataToExternalDevice(448,16074 +void FT2232cMpsseJtag::GetNumDataBytesToRead(464,16707 +FTC_STATUS FT2232cMpsseJtag::GetDataFromExternalDevice(494,17733 +DWORD FT2232cMpsseJtag::AddReadCommandToOutputBuffer(541,19674 +FTC_STATUS FT2232cMpsseJtag::ReadDataFromExternalDevice(587,21283 +DWORD FT2232cMpsseJtag::AddWriteReadCommandDataToOutPutBuffer(608,22106 +FTC_STATUS FT2232cMpsseJtag::WriteReadDataToFromExternalDevice(676,24682 +FTC_STATUS FT2232cMpsseJtag::GenerateTCKClockPulses(732,27167 +void FT2232cMpsseJtag::ProcessReadCommandsSequenceBytes(809,29756 +DWORD FT2232cMpsseJtag::GetTotalNumCommandsSequenceDataBytesToRead(873,32805 +void FT2232cMpsseJtag::CopyReadCommandsSequenceDataBuffer(903,33999 +FTC_STATUS FT2232cMpsseJtag::AddReadCommandSequenceData(922,34800 +PReadCommandsSequenceData FT2232cMpsseJtag::CreateReadCommandsSequenceDataBuffer(988,38026 +void FT2232cMpsseJtag::DeleteReadCommandsSequenceDataBuffer(1009,38805 +FTC_STATUS FT2232cMpsseJtag::CreateDeviceCommandsSequenceDataBuffers(1024,39341 +void FT2232cMpsseJtag::ClearDeviceCommandSequenceData(1067,41106 +DWORD FT2232cMpsseJtag::GetNumBytesInCommandsSequenceDataBuffer(1102,42321 +DWORD FT2232cMpsseJtag::GetCommandsSequenceDataDeviceIndex(1113,42713 +void FT2232cMpsseJtag::DeleteDeviceCommandsSequenceDataBuffers(1149,43787 +FTC_STATUS FT2232cMpsseJtag::AddDeviceWriteCommand(1176,45094 +FTC_STATUS FT2232cMpsseJtag::AddDeviceReadCommand(1214,46595 +FTC_STATUS FT2232cMpsseJtag::AddDeviceWriteReadCommand(1246,47733 +FT2232cMpsseJtag::FT2232cMpsseJtag(1289,49442 +FT2232cMpsseJtag::~FT2232cMpsseJtag(1306,49821 +FTC_STATUS FT2232cMpsseJtag::JTAG_GetNumDevices(1336,51029 +FTC_STATUS FT2232cMpsseJtag::JTAG_GetDeviceNameLocationID(1348,51286 +FTC_STATUS FT2232cMpsseJtag::JTAG_OpenSpecifiedDevice(1354,51701 +FTC_STATUS FT2232cMpsseJtag::JTAG_OpenDevice(1376,52264 +FTC_STATUS FT2232cMpsseJtag::JTAG_CloseDevice(1399,52742 +FTC_STATUS FT2232cMpsseJtag::JTAG_InitDevice(1410,52960 +FTC_STATUS FT2232cMpsseJtag::JTAG_GetClock(1484,55524 +FTC_STATUS FT2232cMpsseJtag::JTAG_SetClock(1496,55882 +FTC_STATUS FT2232cMpsseJtag::JTAG_SetDeviceLoopbackState(1518,56470 +FTC_STATUS FT2232cMpsseJtag::JTAG_SetGeneralPurposeInputOutputPins(1524,56727 +FTC_STATUS FT2232cMpsseJtag::JTAG_GetGeneralPurposeInputOutputPins(1588,59995 +FTC_STATUS FT2232cMpsseJtag::JTAG_WriteDataToExternalDevice(1610,61004 +FTC_STATUS FT2232cMpsseJtag::JTAG_ReadDataFromExternalDevice(1641,62248 +FTC_STATUS FT2232cMpsseJtag::JTAG_WriteReadDataToFromExternalDevice(1672,63494 +FTC_STATUS FT2232cMpsseJtag::JTAG_GenerateTCKClockPulses(1710,65169 +FTC_STATUS FT2232cMpsseJtag::JTAG_ClearCommandSequence(1728,65737 +FTC_STATUS FT2232cMpsseJtag::JTAG_AddWriteCommand(1748,66191 +FTC_STATUS FT2232cMpsseJtag::JTAG_AddReadCommand(1772,67140 +FTC_STATUS FT2232cMpsseJtag::JTAG_AddWriteReadCommand(1794,67903 +FTC_STATUS FT2232cMpsseJtag::JTAG_ClearDeviceCommandSequence(1819,68914 +FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceWriteCommand(1832,69257 +FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceReadCommand(1847,69995 +FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceWriteReadCommand(1860,70542 +FTC_STATUS FT2232cMpsseJtag::JTAG_ExecuteCommandSequence(1875,71312 +FTC_STATUS FT2232cMpsseJtag::JTAG_GetDllVersion(1943,74065 +FTC_STATUS FT2232cMpsseJtag::JTAG_GetErrorCodeString(1960,74474 + +src/gdb.c,4899 +#define OR1KSIM_RSP_SERVICE 95,3823 +#define MAX_GPRS 100,3957 +#define PPC_REGNUM 103,4058 +#define NPC_REGNUM 104,4113 +#define SR_REGNUM 105,4164 +#define NUM_REGS 106,4228 +#define NPC_CPU_REG_ADD 109,4325 +#define SR_CPU_REG_ADD 110,4376 +#define PPC_CPU_REG_ADD 111,4440 +#define DMR1_CPU_REG_ADD 112,4495 +#define DMR2_CPU_REG_ADD 113,4579 +#define DSR_CPU_REG_ADD 114,4663 +#define DRR_CPU_REG_ADD 115,4744 +#define OR1K_TRAP_INSTR 118,4862 +#define GDB_BUF_MAX 127,5371 +#define MP_HASH_SIZE 130,5477 +#define MAX_SPRS 133,5559 +#define SPR_DMR1_ST 135,5587 +#define SPR_DMR2_WGB 136,5646 +#define SPR_DSR_TE 137,5723 +#define WORDSBIGENDIAN_N139,5779 +#define EXCEPT_NONE 142,5841 +#define EXCEPT_RESET 143,5872 +#define EXCEPT_BUSERR 144,5900 +#define EXCEPT_DPF 145,5929 +#define EXCEPT_IPF 146,5955 +#define EXCEPT_TICK 147,5981 +#define EXCEPT_ALIGN 148,6008 +#define EXCEPT_ILLEGAL 149,6036 +#define EXCEPT_INT 150,6066 +#define EXCEPT_DTLBMISS 151,6092 +#define EXCEPT_ITLBMISS 152,6123 +#define EXCEPT_RANGE 153,6154 +#define EXCEPT_SYSCALL 154,6182 +#define EXCEPT_FPE 155,6212 +#define EXCEPT_TRAP 156,6238 +#define SPR_DRR_RSTE 160,6370 +#define SPR_DRR_BUSEE 161,6415 +#define SPR_DRR_DPFE 162,6464 +#define SPR_DRR_IPFE 163,6519 +#define SPR_DRR_TTE 164,6574 +#define SPR_DRR_AE 165,6624 +#define SPR_DRR_IIE 166,6673 +#define SPR_DRR_IE 167,6732 +#define SPR_DRR_DME 168,6781 +#define SPR_DRR_IME 169,6830 +#define SPR_DRR_RE 170,6879 +#define SPR_DRR_SCE 171,6930 +#define SPR_DRR_FPE 172,6981 +#define SPR_DRR_TE 173,7035 +enum target_signal 181,7389 + TARGET_SIGNAL_NONE 182,7410 + TARGET_SIGNAL_INT 183,7437 + TARGET_SIGNAL_ILL 184,7464 + TARGET_SIGNAL_TRAP 185,7491 + TARGET_SIGNAL_FPE 186,7518 + TARGET_SIGNAL_BUS 187,7545 + TARGET_SIGNAL_SEGV 188,7572 + TARGET_SIGNAL_ALRM 189,7599 + TARGET_SIGNAL_USR2 190,7626 + TARGET_SIGNAL_PWR 191,7653 +static const char hexchars[hexchars195,7724 +enum stallStates 206,8201 + STALLED,207,8220 + UNSTALLED,208,8231 + UNKNOWN209,8244 +} stallState;210,8254 +unsigned int npcIsCached;212,8269 +unsigned long int npcCachedValue;213,8324 +unsigned int serverIP 221,8469 +unsigned int serverPort 222,8496 +unsigned int server_fd 223,8525 +unsigned int gdb_fd 224,8553 +static int tcp_level 226,8579 +int gdb_chain 230,8742 +struct rsp_buf234,8862 + char data[data236,8879 + int len;237,8906 +enum mp_type 242,9057 + BP_MEMORY 243,9072 + BP_HARDWARE 244,9126 + WP_WRITE 245,9181 + WP_READ 246,9236 + WP_ACCESS 247,9292 +struct mp_entry251,9416 + enum mp_type type;253,9434 + unsigned long int addr;254,9489 + unsigned long int instr;255,9553 + struct mp_entry *next;next256,9614 + int client_waiting;262,9739 + int client_fd;264,9892 + int sigval;265,9955 + unsigned long int start_addr;266,10022 + struct mp_entry *mp_hash[mp_hash267,10080 +} rsp;268,10154 +char *printTime(printTime333,13215 +rsp_init 351,13751 +handle_rsp 389,15042 +static void rsp_check_for_exception(485,17873 +check_for_exception_vector(549,20176 +rsp_exception 581,21215 +rsp_get_client 636,23409 +static void rsp_client_request 749,27487 +rsp_client_close 958,33010 +put_packet 979,33691 +put_str_packet 1043,35292 +get_packet 1082,36581 +send_rsp_str 1209,39656 +get_rsp_char 1255,40902 +rsp_peek(1305,42151 +rsp_interrupt(1341,43066 +rsp_unescape 1390,44513 +mp_hash_init 1425,45326 +mp_hash_add 1449,46095 +static struct mp_entry * mp_hash_lookup 1488,47173 +mp_hash_delete 1527,48408 +static int hex 1572,49618 +reg2hex 1591,50313 +hex2reg 1627,51215 +static void ascii2hex 1655,51985 +static void hex2ascii 1682,52727 +set_npc 1711,53656 +static unsigned long int get_npc 1757,54854 +rsp_report_exception 1802,55949 +rsp_continue 1827,56697 +rsp_continue_with_signal 1875,58135 +rsp_continue_generic 1895,58851 +rsp_read_all_regs 1944,60980 +rsp_write_all_regs 2043,63864 +static void rsp_read_mem 2125,66454 +rsp_write_mem 2234,69314 +rsp_read_reg 2310,71521 +rsp_write_reg 2406,74255 +rsp_query 2492,76742 +rsp_command 2596,80632 +rsp_set 2710,83678 +rsp_restart 2744,85009 +rsp_step 2783,86240 +rsp_step_with_signal 2845,88018 +rsp_step_generic 2865,88714 +rsp_vpkt 2913,90676 +rsp_write_mem_bin 3005,93702 +rsp_remove_matchpoint 3113,96509 +rsp_insert_matchpoint 3207,99190 +void setup_or32(3287,101693 +static void gdb_ensure_or1k_stalled(3314,103010 +int gdb_read_reg(3334,103506 +int gdb_write_reg(3345,103949 +int gdb_read_block(3356,104450 +int gdb_write_block(3365,104747 +int gdb_set_chain(3374,105046 +int GetServerSocket(3386,105312 +void HandleServerSocket(3482,108113 +void JTAGRequest(3573,110472 +static void GDBRequest(3635,112217 +static void ProtocolClean(3868,121116 +static int gdb_write(3879,121370 +static int gdb_read(3913,122144 +static void client_close 3951,123098 +static void swap_buf(3967,123542 +set_stall_state 3996,124170 + +src/linux_usb_driver_calls.c,368 +static FT2232cMpsseJtag *pFT2232cMpsseJtag pFT2232cMpsseJtag72,3236 +FTC_HANDLE ftHandle;75,3321 +FT2232_USB_JTAG_WriteDataToExternalDevice(81,3523 +FT2232_USB_JTAG_ReadDataFromExternalDevice(102,4123 +FT2232_USB_JTAG_WriteReadDataToFromExternalDevice(128,4674 +FT2232_USB_JTAG_CloseDevice(155,5373 +#define USB_JTAG_CLK_DIVIDER 165,5590 +int init_usb_jtag(167,5622 + +src/or_debug_proxy.c,869 +#define ENDPOINT_TARGET_NONE 70,2831 +#define ENDPOINT_TARGET_USB 71,2862 +#define ENDPOINT_TARGET_VPI 72,2892 +static int endpoint_target;73,2922 +#define GDB_PROTOCOL_JTAG 75,3006 +#define GDB_PROTOCOL_RSP 76,3035 +#define GDB_PROTOCOL_NONE 77,3064 +int err 79,3094 +int current_chain 82,3185 +int dbg_chain 85,3261 +void check(88,3420 +int main(95,3572 +int dbg_reset(211,6849 +void dbg_test(218,7055 +int dbg_set_tap_ir(224,7240 +int dbg_set_chain(231,7414 +int dbg_command(238,7727 +int dbg_ctrl(245,8008 +int dbg_ctrl_read(252,8284 +int dbg_go(259,8586 +int dbg_wb_read32(266,8842 +int dbg_wb_write32(274,9148 +int dbg_wb_read_block32(281,9459 +int dbg_wb_write_block32(289,9805 +int dbg_cpu0_read(296,10152 +int dbg_cpu0_write(303,10455 +int dbg_cpu0_write_ctrl(310,10767 +int dbg_cpu0_read_ctrl(318,11099 +void test_sdram(325,11391 +void print_usage(329,11427 + +src/usb_functions.c,816 +DWORD dwNumBytesReturned 88,3574 +int crc_r,91,3649 +int crc_r, crc_w 91,3649 +unsigned long crc_calc(94,3726 +int bit_reverse_data(101,3966 +void usb_dbg_test(108,4118 +void usb_write_stream 171,5758 +ULONGEST usb_read_stream(212,7196 +void usb_set_tap_ir(242,8183 +int usb_dbg_reset(264,8880 +static int retry_no 300,9926 +int retry_do(301,9951 +void retry_ok(354,11192 +int usb_dbg_set_chain(359,11252 +int usb_dbg_command(410,12646 +int usb_dbg_ctrl(555,17431 +int usb_dbg_ctrl_read(661,20837 +int usb_dbg_go(772,24725 +int usb_dbg_wb_read32(938,30218 +int usb_dbg_wb_write32(948,30548 +int usb_dbg_wb_read_block32(958,30886 +int usb_dbg_wb_write_block32(971,31346 +int usb_dbg_cpu0_read(982,31743 +int usb_dbg_cpu0_write(992,32072 +int usb_dbg_cpu0_write_ctrl(1002,32407 +int usb_dbg_cpu0_read_ctrl(1010,32740 + +src/vpi_functions.c,1293 +#define MSG_WAITALL 83,3416 +unsigned int vpiPort 87,3498 +unsigned int vpi_fd;88,3531 +#define DBG_VPI 91,3633 +#define DBG_VPI 93,3657 +#define CMD_JTAG_SET_IR 118,4646 +#define CMD_SET_DEBUG_CHAIN 119,4674 +#define CMD_CPU_CTRL_WR 120,4706 +#define CMD_CPU_CTRL_RD 121,4734 +#define CMD_CPU_WR_REG 122,4762 +#define CMD_CPU_RD_REG 123,4789 +#define CMD_WB_WR32 124,4816 +#define CMD_WB_RD32 125,4840 +#define CMD_WB_BLOCK_WR32 126,4864 +#define CMD_WB_BLOCK_RD32 127,4894 +#define CMD_RESET 128,4924 +#define CMD_READ_JTAG_ID 129,4946 +void send_command_to_vpi(132,4977 +void send_address_to_vpi(152,5469 +void send_data_to_vpi(170,5771 +void send_block_data_to_vpi(189,6059 +void get_data_from_vpi(209,6413 +void get_block_data_from_vpi(234,6829 +void get_response_from_vpi(260,7385 +static void jp2_reset_JTAG(278,7709 +int vpi_connect(291,7853 + int vpi_dbg_reset(358,9445 +void vpi_dbg_test(392,10071 +int vpi_dbg_set_chain(418,10719 +int vpi_dbg_ctrl(438,11061 +int vpi_dbg_ctrl_read(457,11420 +int vpi_dbg_wb_read32(485,11927 +int vpi_dbg_wb_write32(503,12230 +int vpi_dbg_wb_read_block32(520,12509 +int vpi_dbg_wb_write_block32(543,12959 +int vpi_dbg_cpu0_read(562,13298 +int vpi_dbg_cpu0_write(580,13575 +int vpi_dbg_cpu0_write_ctrl(598,13856 +int vpi_dbg_cpu0_read_ctrl(606,14111 + +src/win_usb_driver_calls.c,337 +int getFTDIJTAGFunctions 82,3443 +FTC_HANDLE ftHandle;247,8553 +FT2232_USB_JTAG_WriteDataToExternalDevice(250,8586 +FT2232_USB_JTAG_ReadDataFromExternalDevice(272,9131 +FT2232_USB_JTAG_WriteReadDataToFromExternalDevice(298,9612 +FT2232_USB_JTAG_CloseDevice(325,10213 +#define USB_JTAG_CLK_DIVIDER 336,10407 +int init_usb_jtag(338,10439 + +includes/FT2232c.h,2275 +#define FT2232c_H26,475 +typedef DWORD FTC_HANDLE;32,545 +typedef ULONG FTC_STATUS;33,572 +#define FTC_SUCCESS 35,601 +#define FTC_INVALID_HANDLE 36,634 +#define FTC_DEVICE_NOT_FOUND 37,685 +#define FTC_DEVICE_NOT_OPENED 38,740 +#define FTC_IO_ERROR 39,797 +#define FTC_INSUFFICIENT_RESOURCES 40,836 +#define FTC_FAILED_TO_COMPLETE_COMMAND 42,905 +#define FTC_FAILED_TO_SYNCHRONIZE_DEVICE_MPSSE 43,948 +#define FTC_INVALID_DEVICE_NAME_INDEX 44,999 +#define FTC_NULL_DEVICE_NAME_BUFFER_POINTER 45,1041 +#define FTC_DEVICE_NAME_BUFFER_TOO_SMALL 46,1089 +#define FTC_INVALID_DEVICE_NAME 47,1134 +#define FTC_INVALID_LOCATION_ID 48,1170 +#define FTC_DEVICE_IN_USE 49,1206 +#define FTC_TOO_MANY_DEVICES 50,1236 +#define MAX_NUM_DEVICE_NAME_CHARS 52,1271 +#define MAX_NUM_SERIAL_NUMBER_CHARS 53,1309 +typedef struct Ft_Device_Data{Ft_Device_Data55,1351 + DWORD dwProcessId;56,1383 + char szDeviceName[szDeviceName57,1490 + DWORD dwLocationID;58,1596 + DWORD hDevice;59,1706 +}FTC_DEVICE_DATA, *PFTC_DEVICE_DATA;PFTC_DEVICE_DATA60,1824 +typedef DWORD FT2232CDeviceIndexes[FT2232CDeviceIndexes62,1864 +#define DEVICE_STRING_BUFF_SIZE 64,1920 +#define DEVICE_CHANNEL_A 66,1958 +typedef char SerialNumber[SerialNumber68,1991 +const BYTE DEVICE_LATENCY_TIMER_VALUE 70,2050 +#define OUTPUT_BUFFER_SIZE 72,2116 +typedef BYTE OutputByteBuffer[OutputByteBuffer74,2168 +typedef OutputByteBuffer *POutputByteBuffer;POutputByteBuffer75,2220 +#define INPUT_BUFFER_SIZE 77,2268 +typedef BYTE InputByteBuffer[InputByteBuffer79,2319 +typedef InputByteBuffer *PInputByteBuffer;PInputByteBuffer80,2369 +#define CONVERT_1MS_TO_100NS 82,2415 +#define MAX_COMMAND_TIMEOUT_PERIOD 84,2453 +#define MAX_NUM_BYTES_USB_WRITE 87,2597 +#define MAX_NUM_BYTES_USB_WRITE_READ 88,2651 +#define MAX_NUM_BYTES_USB_READ 89,2710 +#define DEBUG_LIST_DEVICE 91,2758 +const BYTE MPSSE_INTERFACE_MASK 93,2790 +const BYTE RESET_MPSSE_INTERFACE 94,2835 +const BYTE ENABLE_MPSSE_INTERFACE 95,2879 +const __uint16_t DEVICE_OPENED_FLAG 97,2926 +const int BASE_CLOCK_FREQUENCY_12_MHZ 99,2978 +const BYTE AA_ECHO_CMD_1 101,3031 +const BYTE AB_ECHO_CMD_2 102,3067 +const BYTE TURN_ON_LOOPBACK_CMD 104,3105 +const BYTE TURN_OFF_LOOPBACK_CMD 105,3148 +const BYTE BAD_COMMAND_RESPONSE 107,3194 +class FT2232c111,3243 + +includes/FT2232cMpsseJtag.h,8548 +#define FT2232cMpsseJtag_H28,727 +typedef DWORD FTC_HANDLE;38,949 +typedef ULONG FTC_STATUS;39,976 +#define TEST_LOGIC_STATE 41,1005 +#define RUN_TEST_IDLE_STATE 42,1033 +#define PAUSE_TEST_DATA_REGISTER_STATE 43,1064 +#define PAUSE_INSTRUCTION_REGISTER_STATE 44,1106 +#define SHIFT_TEST_DATA_REGISTER_STATE 45,1150 +#define SHIFT_INSTRUCTION_REGISTER_STATE 46,1192 +#define FTC_SUCCESS 48,1238 +#define FTC_INVALID_HANDLE 49,1271 +#define FTC_DEVICE_NOT_FOUND 50,1323 +#define FTC_DEVICE_NOT_OPENED 51,1378 +#define FTC_IO_ERROR 52,1435 +#define FTC_INSUFFICIENT_RESOURCES 53,1474 +#define FTC_FAILED_TO_COMPLETE_COMMAND 55,1544 +#define FTC_FAILED_TO_SYNCHRONIZE_DEVICE_MPSSE 56,1653 +#define FTC_INVALID_DEVICE_NAME_INDEX 57,1762 +#define FTC_NULL_DEVICE_NAME_BUFFER_POINTER 58,1871 +#define FTC_DEVICE_NAME_BUFFER_TOO_SMALL 59,1981 +#define FTC_INVALID_DEVICE_NAME 60,2090 +#define FTC_INVALID_LOCATION_ID 61,2199 +#define FTC_DEVICE_IN_USE 62,2308 +#define FTC_TOO_MANY_DEVICES 63,2417 +#define FTC_INVALID_CLOCK_DIVISOR 64,2526 +#define FTC_NULL_INPUT_OUTPUT_BUFFER_POINTER 65,2564 +#define FTC_INVALID_NUMBER_BITS 66,2613 +#define FTC_NULL_WRITE_DATA_BUFFER_POINTER 67,2649 +#define FTC_INVALID_NUMBER_BYTES 68,2696 +#define FTC_NUMBER_BYTES_TOO_SMALL 69,2733 +#define FTC_INVALID_TAP_CONTROLLER_STATE 70,2772 +#define FTC_NULL_READ_DATA_BUFFER_POINTER 71,2817 +#define FTC_COMMAND_SEQUENCE_BUFFER_FULL 72,2863 +#define FTC_NULL_READ_CMDS_DATA_BUFFER_POINTER 73,2908 +#define FTC_NO_COMMAND_SEQUENCE 74,2959 +#define FTC_INVALID_NUMBER_CLOCK_PULSES 75,2995 +#define FTC_NULL_DLL_VERSION_BUFFER_POINTER 76,3039 +#define FTC_DLL_VERSION_BUFFER_TOO_SMALL 77,3087 +#define FTC_NULL_LANGUAGE_CODE_BUFFER_POINTER 78,3132 +#define FTC_NULL_ERROR_MESSAGE_BUFFER_POINTER 79,3182 +#define FTC_ERROR_MESSAGE_BUFFER_TOO_SMALL 80,3232 +#define FTC_INVALID_LANGUAGE_CODE 81,3279 +#define FTC_INVALID_STATUS_CODE 82,3317 +typedef struct Ft_Input_Output_Pins{Ft_Input_Output_Pins85,3357 + BOOL bPin1InputOutputState;86,3395 + BOOL bPin1LowHighState;87,3427 + BOOL bPin2InputOutputState;88,3455 + BOOL bPin2LowHighState;89,3487 + BOOL bPin3InputOutputState;90,3515 + BOOL bPin3LowHighState;91,3547 + BOOL bPin4InputOutputState;92,3575 + BOOL bPin4LowHighState;93,3607 +}FTC_INPUT_OUTPUT_PINS, *PFTC_INPUT_OUTPUT_PINS;PFTC_INPUT_OUTPUT_PINS94,3635 +typedef struct Ft_Low_High_Pins{Ft_Low_High_Pins95,3685 + BOOL bPin1LowHighState;96,3719 + BOOL bPin2LowHighState;97,3747 + BOOL bPin3LowHighState;98,3775 + BOOL bPin4LowHighState;99,3803 +}FTC_LOW_HIGH_PINS, *PFTC_LOW_HIGH_PINS;PFTC_LOW_HIGH_PINS100,3831 +#define MAX_WRITE_DATA_BYTES_BUFFER_SIZE 101,3873 +typedef BYTE WriteDataByteBuffer[WriteDataByteBuffer103,3939 +typedef WriteDataByteBuffer *PWriteDataByteBuffer;PWriteDataByteBuffer104,4008 +#define MAX_READ_DATA_BYTES_BUFFER_SIZE 107,4064 +typedef BYTE ReadDataByteBuffer[ReadDataByteBuffer109,4129 +typedef ReadDataByteBuffer *PReadDataByteBuffer;PReadDataByteBuffer110,4196 +#define MAX_READ_CMDS_DATA_BYTES_BUFFER_SIZE 112,4248 +typedef BYTE ReadCmdSequenceDataByteBuffer[ReadCmdSequenceDataByteBuffer114,4319 +typedef ReadCmdSequenceDataByteBuffer *PReadCmdSequenceDataByteBuffer;PReadCmdSequenceDataByteBuffer115,4402 +#define DEVICE_CHANNEL_A 121,4513 +#define DEVICE_CHANNEL_B 122,4544 +#define DLL_VERSION_NUM 124,4577 +#define USB_INPUT_BUFFER_SIZE 126,4610 +#define USB_OUTPUT_BUFFER_SIZE 127,4656 +const BYTE FT_EVENT_VALUE 129,4704 +const BYTE FT_ERROR_VALUE 130,4736 +#define DEVICE_READ_TIMEOUT_INFINITE 132,4770 +#define DEVICE_WRITE_TIMEOUT 133,4810 +#define MIN_CLOCK_DIVISOR 135,4860 +#define MAX_CLOCK_DIVISOR 136,4915 +#define MIN_NUM_BITS 138,4972 +#define MAX_NUM_BITS 139,5097 +#define MIN_NUM_BYTES 140,5222 +#define MAX_NUM_BYTES 141,5335 +#define NUMBITSINBYTE 143,5450 +#define MIN_NUM_CLOCK_PULSES 145,5477 +#define MAX_NUM_CLOCK_PULSES 146,5606 +#define NUM_BYTE_CLOCK_PULSES_BLOCK_SIZE 148,5737 +#define PIN1_HIGH_VALUE 150,5794 +#define PIN2_HIGH_VALUE 151,5822 +#define PIN3_HIGH_VALUE 152,5850 +#define PIN4_HIGH_VALUE 153,5878 +#define NUM_WRITE_COMMAND_BYTES 155,5908 +#define NUM_READ_COMMAND_BYTES 156,5944 +#define NUM_WRITE_READ_COMMAND_BYTES 157,5979 +#define MAX_ERROR_MSG_SIZE 159,6022 +const CHAR ENGLISH[ENGLISH161,6056 +const CHAR EN_Common_Errors[EN_Common_Errors163,6089 +const CHAR EN_New_Errors[EN_New_Errors171,6365 +const BYTE CLK_DATA_BYTES_OUT_ON_NEG_CLK_LSB_FIRST_CMD 201,7930 +const BYTE CLK_DATA_BITS_OUT_ON_NEG_CLK_LSB_FIRST_CMD 202,7996 +const BYTE CLK_DATA_BYTES_IN_ON_POS_CLK_LSB_FIRST_CMD 203,8061 +const BYTE CLK_DATA_BITS_IN_ON_POS_CLK_LSB_FIRST_CMD 204,8126 +const BYTE CLK_DATA_BYTES_OUT_ON_NEG_CLK_IN_ON_POS_CLK_LSB_FIRST_CMD 205,8190 +const BYTE CLK_DATA_BITS_OUT_ON_NEG_CLK_IN_ON_POS_CLK_LSB_FIRST_CMD 206,8270 +const BYTE CLK_DATA_TMS_NO_READ_CMD 208,8351 +const BYTE CLK_DATA_TMS_READ_CMD 209,8398 +const BYTE SET_LOW_BYTE_DATA_BITS_CMD 211,8444 +const BYTE GET_LOW_BYTE_DATA_BITS_CMD 212,8493 +const BYTE SET_HIGH_BYTE_DATA_BITS_CMD 213,8542 +const BYTE GET_HIGH_BYTE_DATA_BITS_CMD 214,8592 +const BYTE SET_CLOCK_FREQUENCY_CMD 215,8642 +const BYTE SEND_ANSWER_BACK_IMMEDIATELY_CMD 216,8688 +enum JtagStates 218,8745 +enum JtagStates {TestLogicReset,TestLogicReset218,8745 +enum JtagStates {TestLogicReset, RunTestIdle,218,8745 +enum JtagStates {TestLogicReset, RunTestIdle, PauseDataRegister,218,8745 +enum JtagStates {TestLogicReset, RunTestIdle, PauseDataRegister, PauseInstructionRegister,218,8745 +enum JtagStates {TestLogicReset, RunTestIdle, PauseDataRegister, PauseInstructionRegister, ShiftDataRegister,218,8745 +enum JtagStates {TestLogicReset, RunTestIdle, PauseDataRegister, PauseInstructionRegister, ShiftDataRegister, ShiftInstructionRegister,218,8745 +enum JtagStates {TestLogicReset, RunTestIdle, PauseDataRegister, PauseInstructionRegister, ShiftDataRegister, ShiftInstructionRegister, Undefined}Undefined218,8745 +#define NUM_JTAG_TMS_STATES 220,8896 +const BYTE TestLogicResetToNewJTAGState[TestLogicResetToNewJTAGState223,9044 +const BYTE RunTestIdleToNewJTAGState[RunTestIdleToNewJTAGState224,9163 +const BYTE PauseDataRegToNewJTAGState[PauseDataRegToNewJTAGState225,9282 +const BYTE PauseInstructionRegToNewJTAGState[PauseInstructionRegToNewJTAGState226,9401 +const BYTE ShiftDataRegToNewJTAGState[ShiftDataRegToNewJTAGState227,9520 +const BYTE ShiftInstructionRegToNewJTAGState[ShiftInstructionRegToNewJTAGState228,9639 +const BYTE TestLogicResetToNewJTAGStateNumTMSClocks[TestLogicResetToNewJTAGStateNumTMSClocks231,9866 +const BYTE RunTestIdleToNewJTAGStateNumTMSClocks[RunTestIdleToNewJTAGStateNumTMSClocks232,9972 +const BYTE PauseDataRegToNewJTAGStateNumTMSClocks[PauseDataRegToNewJTAGStateNumTMSClocks233,10078 +const BYTE PauseInstructionRegToNewJTAGStateNumTMSClocks[PauseInstructionRegToNewJTAGStateNumTMSClocks234,10184 +const BYTE ShiftDataRegToNewJTAGStateNumTMSClocks[ShiftDataRegToNewJTAGStateNumTMSClocks235,10290 +const BYTE ShiftInstructionRegToNewJTAGStateNumTMSClocks[ShiftInstructionRegToNewJTAGStateNumTMSClocks236,10396 +#define NO_LAST_DATA_BIT 238,10504 +#define NUM_COMMAND_SEQUENCE_READ_DATA_BYTES 240,10534 +#define INIT_COMMAND_SEQUENCE_READ_DATA_BUFFER_SIZE 241,10582 +#define COMMAND_SEQUENCE_READ_DATA_BUFFER_SIZE_INCREMENT 242,10639 +typedef DWORD ReadCommandSequenceData[ReadCommandSequenceData244,10702 +typedef ReadCommandSequenceData *PReadCommandSequenceData;PReadCommandSequenceData245,10780 +typedef PReadCommandSequenceData ReadCommandsSequenceData[ReadCommandsSequenceData247,10842 +typedef ReadCommandsSequenceData *PReadCommandsSequenceData;PReadCommandsSequenceData248,10905 +typedef struct Ft_Device_Cmd_Sequence_Data{Ft_Device_Cmd_Sequence_Data250,10969 + DWORD hDevice;251,11014 + DWORD dwNumBytesToSend;252,11132 + POutputByteBuffer pCommandsSequenceDataOutPutBuffer;253,11159 + DWORD dwSizeReadCommandsSequenceDataBuffer;254,11215 + PReadCommandsSequenceData pReadCommandsSequenceDataBuffer;255,11262 + DWORD dwNumReadCommandSequences;256,11324 +}FTC_DEVICE_CMD_SEQUENCE_DATA, *PFTC_DEVICE_CMD_SEQUENCE_DATA;PFTC_DEVICE_CMD_SEQUENCE_DATA257,11360 + static DWORD dwSavedLowPinsDirection 260,11428 + static DWORD dwSavedLowPinsValue 261,11561 + static JtagStates CurrentJtagState 262,11691 + static DWORD dwNumOpenedDevices 263,11834 + static FTC_DEVICE_CMD_SEQUENCE_DATA OpenedDevicesCommandsSequenceData[OpenedDevicesCommandsSequenceData264,11964 + static INT iCommandsSequenceDataDeviceIndex 265,12129 +class FT2232cMpsseJtag 269,12352 + +includes/ftd2xx.h,7279 +#define FTD2XX_H34,652 +#define WINAPI38,712 +#define FTD2XX_API 50,1258 +#define FTD2XX_API 52,1307 +#undef FTD2XX_API58,1419 +#define FTD2XX_API59,1438 +typedef struct _EVENT_HANDLE{_EVENT_HANDLE62,1474 + pthread_cond_t eCondVar;63,1505 + pthread_mutex_t eMutex;64,1532 + int iVar;65,1558 +} EVENT_HANDLE;66,1570 +typedef DWORD *FT_HANDLE;FT_HANDLE68,1589 +typedef ULONG FT_STATUS;70,1621 + FT_OK,76,1686 + FT_INVALID_HANDLE,77,1695 + FT_DEVICE_NOT_FOUND,78,1716 + FT_DEVICE_NOT_OPENED,79,1739 + FT_IO_ERROR,80,1763 + FT_INSUFFICIENT_RESOURCES,81,1778 + FT_INVALID_PARAMETER,82,1807 + FT_INVALID_BAUD_RATE,83,1831 + FT_DEVICE_NOT_OPENED_FOR_ERASE,85,1861 + FT_DEVICE_NOT_OPENED_FOR_WRITE,86,1895 + FT_FAILED_TO_WRITE_DEVICE,87,1929 + FT_EEPROM_READ_FAILED,88,1958 + FT_EEPROM_WRITE_FAILED,89,1983 + FT_EEPROM_ERASE_FAILED,90,2009 + FT_EEPROM_NOT_PRESENT,91,2035 + FT_EEPROM_NOT_PROGRAMMED,92,2060 + FT_INVALID_ARGS,93,2088 + FT_NOT_SUPPORTED,94,2107 + FT_OTHER_ERROR95,2127 +#define FT_SUCCESS(99,2152 +#define FT_OPEN_BY_SERIAL_NUMBER 105,2232 +#define FT_OPEN_BY_DESCRIPTION 106,2271 +#define FT_OPEN_BY_LOCATION 107,2310 +#define FT_LIST_NUMBER_ONLY 112,2420 +#define FT_LIST_BY_INDEX 113,2462 +#define FT_LIST_ALL 114,2501 +#define FT_LIST_MASK 116,2538 +#define FT_BAUD_300 122,2638 +#define FT_BAUD_600 123,2665 +#define FT_BAUD_1200 124,2692 +#define FT_BAUD_2400 125,2720 +#define FT_BAUD_4800 126,2748 +#define FT_BAUD_9600 127,2776 +#define FT_BAUD_14400 128,2804 +#define FT_BAUD_19200 129,2834 +#define FT_BAUD_38400 130,2864 +#define FT_BAUD_57600 131,2894 +#define FT_BAUD_115200 132,2924 +#define FT_BAUD_230400 133,2956 +#define FT_BAUD_460800 134,2988 +#define FT_BAUD_921600 135,3020 +#define FT_BITS_8 141,3081 +#define FT_BITS_7 142,3112 +#define FT_BITS_6 143,3143 +#define FT_BITS_5 144,3174 +#define FT_STOP_BITS_1 150,3231 +#define FT_STOP_BITS_1_5 151,3266 +#define FT_STOP_BITS_2 152,3302 +#define FT_PARITY_NONE 158,3360 +#define FT_PARITY_ODD 159,3395 +#define FT_PARITY_EVEN 160,3429 +#define FT_PARITY_MARK 161,3464 +#define FT_PARITY_SPACE 162,3499 +#define FT_FLOW_NONE 168,3564 +#define FT_FLOW_RTS_CTS 169,3600 +#define FT_FLOW_DTR_DSR 170,3636 +#define FT_FLOW_XON_XOFF 171,3672 +#define FT_PURGE_RX 176,3746 +#define FT_PURGE_TX 177,3777 +typedef void (*PFT_EVENT_HANDLER)PFT_EVENT_HANDLER183,3831 +#define FT_EVENT_RXCHAR 185,3882 +#define FT_EVENT_MODEM_STATUS 186,3914 +#define FT_DEFAULT_RX_TIMEOUT 192,3974 +#define FT_DEFAULT_TX_TIMEOUT 193,4011 +typedef ULONG FT_DEVICE;199,4077 + FT_DEVICE_BM,202,4113 + FT_DEVICE_AM,203,4132 + FT_DEVICE_100AX,204,4151 + FT_DEVICE_UNKNOWN,205,4173 + FT_DEVICE_2232C,206,4197 + FT_DEVICE_232R207,4216 +typedef struct ft_program_data 432,7971 + DWORD Signature1;434,8007 + DWORD Signature2;435,8061 + DWORD Version;436,8114 + WORD VendorId;441,8307 + WORD ProductId;442,8337 + char *Manufacturer;Manufacturer443,8368 + char *ManufacturerId;ManufacturerId444,8402 + char *Description;Description445,8435 + char *SerialNumber;SerialNumber446,8487 + WORD MaxPower;447,8543 + WORD PnP;448,8586 + WORD SelfPowered;449,8631 + WORD RemoteWakeup;450,8690 + UCHAR Rev4;454,8776 + UCHAR IsoIn;455,8835 + UCHAR IsoOut;456,8895 + UCHAR PullDownEnable;457,8957 + UCHAR SerNumEnable;458,9015 + UCHAR USBVersionEnable;459,9079 + WORD USBVersion;460,9142 + UCHAR Rev5;464,9221 + UCHAR IsoInA;465,9280 + UCHAR IsoInB;466,9341 + UCHAR IsoOutA;467,9402 + UCHAR IsoOutB;468,9465 + UCHAR PullDownEnable5;469,9528 + UCHAR SerNumEnable5;470,9587 + UCHAR USBVersionEnable5;471,9651 + WORD USBVersion5;472,9714 + UCHAR AIsHighCurrent;473,9760 + UCHAR BIsHighCurrent;474,9826 + UCHAR IFAIsFifo;475,9892 + UCHAR IFAIsFifoTar;476,9950 + UCHAR IFAIsFastSer;477,10022 + UCHAR AIsVCP;478,10086 + UCHAR IFBIsFifo;479,10152 + UCHAR IFBIsFifoTar;480,10210 + UCHAR IFBIsFastSer;481,10282 + UCHAR BIsVCP;482,10346 + UCHAR UseExtOsc;486,10445 + UCHAR HighDriveIOs;487,10493 + UCHAR EndpointSize;488,10536 + UCHAR PullDownEnableR;490,10579 + UCHAR SerNumEnableR;491,10638 + UCHAR InvertTXD;493,10704 + UCHAR InvertRXD;494,10751 + UCHAR InvertRTS;495,10798 + UCHAR InvertCTS;496,10845 + UCHAR InvertDTR;497,10892 + UCHAR InvertDSR;498,10939 + UCHAR InvertDCD;499,10986 + UCHAR InvertRI;500,11033 + UCHAR Cbus0;502,11081 + UCHAR Cbus1;503,11119 + UCHAR Cbus2;504,11157 + UCHAR Cbus3;505,11195 + UCHAR Cbus4;506,11233 + UCHAR RIsVCP;508,11273 +} FT_PROGRAM_DATA, *PFT_PROGRAM_DATA;PFT_PROGRAM_DATA510,11324 +typedef struct _FTCOMSTAT 701,14908 + DWORD fCtsHold 702,14937 + DWORD fDsrHold 703,14962 + DWORD fRlsdHold 704,14987 + DWORD fXoffHold 705,15013 + DWORD fXoffSent 706,15039 + DWORD fEof 707,15065 + DWORD fTxim 708,15086 + DWORD fReserved 709,15108 + DWORD cbInQue;710,15135 + DWORD cbOutQue;711,15155 +} FTCOMSTAT, *LPFTCOMSTAT;LPFTCOMSTAT712,15176 +typedef struct _FTDCB 714,15206 + DWORD DCBlength;715,15231 + DWORD BaudRate;716,15296 + DWORD fBinary:fBinary717,15361 + DWORD fParity:fParity718,15426 + DWORD fOutxCtsFlow:fOutxCtsFlow719,15491 + DWORD fOutxDsrFlow:fOutxDsrFlow720,15556 + DWORD fDtrControl:fDtrControl721,15621 + DWORD fDsrSensitivity:fDsrSensitivity722,15686 + DWORD fTXContinueOnXoff:fTXContinueOnXoff723,15751 + DWORD fOutX:fOutX724,15817 + DWORD fInX:fInX725,15882 + DWORD fErrorChar:fErrorChar726,15947 + DWORD fNull:fNull727,16012 + DWORD fRtsControl:fRtsControl728,16077 + DWORD fAbortOnError:fAbortOnError729,16142 + DWORD fDummy2:fDummy2730,16212 + WORD wReserved;731,16277 + WORD XonLim;732,16342 + WORD XoffLim;733,16407 + BYTE ByteSize;734,16472 + BYTE Parity;735,16537 + BYTE StopBits;736,16602 + char XonChar;737,16667 + char XoffChar;738,16732 + char ErrorChar;739,16797 + char EofChar;740,16862 + char EvtChar;741,16927 + WORD wReserved1;742,16992 +} FTDCB, *LPFTDCB;LPFTDCB743,17057 +typedef struct _FTTIMEOUTS 745,17079 + DWORD ReadIntervalTimeout;746,17109 + DWORD ReadTotalTimeoutMultiplier;747,17189 + DWORD ReadTotalTimeoutConstant;748,17269 + DWORD WriteTotalTimeoutMultiplier;749,17349 + DWORD WriteTotalTimeoutConstant;750,17429 +} FTTIMEOUTS,*LPFTTIMEOUTS;LPFTTIMEOUTS751,17509 +typedef struct _ft_device_list_info_node 837,18937 + ULONG Flags;838,18981 + ULONG Type;839,18996 + ULONG ID;840,19013 + DWORD LocId;841,19025 + char SerialNumber[SerialNumber842,19040 + char Description[Description843,19065 + FT_HANDLE ftHandle;844,19089 +} FT_DEVICE_LIST_INFO_NODE;845,19111 +#define EV_RXCHAR 885,19781 +#define EV_RXFLAG 886,19844 +#define EV_TXEMPTY 887,19911 +#define EV_CTS 888,19973 +#define EV_DSR 889,20031 +#define EV_RLSD 890,20089 +#define EV_BREAK 891,20148 +#define EV_ERR 892,20203 +#define EV_RING 893,20270 +#define EV_PERR 894,20331 +#define EV_RX80FULL 895,20393 +#define EV_EVENT1 896,20467 +#define EV_EVENT2 897,20533 +#define SETXOFF 903,20632 +#define SETXON 904,20695 +#define SETRTS 905,20757 +#define CLRRTS 906,20810 +#define SETDTR 907,20862 +#define CLRDTR 908,20915 +#define RESETDEV 909,20967 +#define SETBREAK 910,21032 +#define CLRBREAK 911,21099 +#define PURGE_TXABORT 916,21204 +#define PURGE_RXABORT 917,21294 +#define PURGE_TXCLEAR 918,21383 +#define PURGE_RXCLEAR 919,21457 + +includes/gdb.h,2617 +#define GDB_H49,2541 +enum enum_errors 64,2883 + ERR_NONE 68,2992 + ERR_CRC 69,3009 + ERR_MEM 70,3026 + JTAG_PROXY_INVALID_COMMAND 71,3043 + JTAG_PROXY_SERVER_TERMINATED 72,3079 + JTAG_PROXY_NO_CONNECTION 73,3117 + JTAG_PROXY_PROTOCOL_ERROR 74,3151 + JTAG_PROXY_COMMAND_NOT_IMPLEMENTED 75,3186 + JTAG_PROXY_INVALID_CHAIN 76,3230 + JTAG_PROXY_INVALID_ADDRESS 77,3264 + JTAG_PROXY_ACCESS_EXCEPTION 78,3300 + JTAG_PROXY_INVALID_LENGTH 79,3357 + JTAG_PROXY_OUT_OF_MEMORY 80,3393 +enum jtag_chains84,3459 + SC_GLOBAL,86,3482 + SC_RISC_DEBUG,87,3527 + SC_RISC_TEST,88,3583 + SC_TRACE,89,3628 + SC_REGISTER,90,3669 + SC_WISHBONE,91,3713 + SC_BLOCK,92,3755 +#define JI_SIZE 96,3849 +enum jtag_instr97,3870 + JI_EXTEST,99,3892 + JI_SAMPLE_PRELOAD,100,3908 + JI_IDCODE,101,3932 + JI_CHAIN_SELECT,102,3948 + JI_INTEST,103,3970 + JI_CLAMP,104,3986 + JI_CLAMPZ,105,4001 + JI_HIGHZ,106,4017 + JI_DEBUG,107,4032 + JI_BYPASS 108,4047 + JI_BYPASS = 0xFxF108,4047 +#define JTAG_MODER 112,4100 +#define JTAG_TSEL 113,4127 +#define JTAG_QSEL 114,4154 +#define JTAG_SSEL 115,4181 +#define JTAG_RISCOP 116,4208 +#define JTAG_RECWP0 117,4235 +#define JTAG_RECBP0 118,4263 + JTAG_COMMAND_READ 125,4478 + JTAG_COMMAND_WRITE 126,4504 + JTAG_COMMAND_BLOCK_READ 127,4531 + JTAG_COMMAND_BLOCK_WRITE 128,4563 + JTAG_COMMAND_CHAIN 129,4596 +} JTAG_proxy_protocol_commands;130,4623 + uint32_t command;142,5042 + uint32_t length;143,5063 + uint32_t address;144,5083 + uint32_t data_H;145,5104 + uint32_t data_L;146,5124 +} JTAGProxyWriteMessage;147,5144 + uint32_t command;150,5190 + uint32_t length;151,5211 + uint32_t address;152,5231 +} JTAGProxyReadMessage;153,5252 + uint32_t command;156,5297 + uint32_t length;157,5318 + uint32_t address;158,5338 + int32_t nRegisters;159,5359 + uint32_t data[data160,5383 +} JTAGProxyBlockWriteMessage;161,5404 + uint32_t command;164,5455 + uint32_t length;165,5476 + uint32_t address;166,5496 + int32_t nRegisters;167,5517 +} JTAGProxyBlockReadMessage;168,5541 + uint32_t command;171,5591 + uint32_t length;172,5612 + uint32_t chain;173,5632 +} JTAGProxyChainMessage;174,5651 + int32_t status;182,5894 +} JTAGProxyWriteResponse;183,5913 + int32_t status;186,5960 + uint32_t data_H;187,5979 + uint32_t data_L;188,5999 +} JTAGProxyReadResponse;189,6019 + int32_t status;192,6067 +} JTAGProxyBlockWriteResponse;193,6086 + int32_t status;196,6138 + int32_t nRegisters;197,6157 + uint32_t data[data198,6180 +} JTAGProxyBlockReadResponse;200,6251 + int32_t status;203,6302 +} JTAGProxyChainResponse;204,6321 + +includes/or_debug_proxy.h,878 +#define _OR_DEBUG_PROXY_H_48,2471 +#define DEBUG_CMDS 51,2521 +#define DEBUG_USB_DRVR_FUNCS 55,2643 +#define DEBUG_GDB_BLOCK_DATA 59,2770 +#define DEBUG_GDB 64,2933 +#define DEBUG_GDB_DUMP_DATA 68,3030 +#define Boolean 71,3138 +#define false 72,3159 +#define true 73,3176 +#define CRC_SIZE 76,3258 +#define DBGCHAIN_SIZE 86,3497 +#define DC_STATUS_SIZE 87,3622 +#define DC_WISHBONE 89,3653 +#define DC_CPU0 90,3682 +#define DC_CPU1 91,3711 +#define DI_GO 93,3742 +#define DI_READ_CMD 94,3768 +#define DI_WRITE_CMD 95,3794 +#define DI_READ_CTRL 96,3820 +#define DI_WRITE_CTRL 97,3846 +#define DBG_CRC_SIZE 99,3874 +#define DBG_CRC_POLY 100,3904 +#define DBG_ERR_OK 102,3944 +#define DBG_ERR_INVALID_ENDPOINT 103,3973 +#define DBG_ERR_CRC 104,4009 +#define NUM_SOFT_RETRIES 106,4040 +#define NUM_HARD_RETRIES 107,4069 +#define NUM_ACCESS_RETRIES 108,4098 +#define CHECK(139,5295 + +includes/usb_functions.h,26 +#define ULONGEST 48,2413 + +includes/vpi_functions.h,118 +#define VPI_PORT 49,2525 +#define debug 52,2566 +#define debug54,2593 +#define debug2 58,2633 +#define debug260,2661 + +includes/win_FTCJTAG.h,3276 +#define win_FTCJTAG_H26,400 +#define FTCJTAG_API 38,950 +#define FTCJTAG_API 40,1000 +typedef DWORD FTC_HANDLE;43,1053 +typedef ULONG FTC_STATUS;44,1080 +#define TEST_LOGIC_STATE 46,1109 +#define RUN_TEST_IDLE_STATE 47,1137 +#define PAUSE_TEST_DATA_REGISTER_STATE 48,1168 +#define PAUSE_INSTRUCTION_REGISTER_STATE 49,1210 +#define SHIFT_TEST_DATA_REGISTER_STATE 50,1254 +#define SHIFT_INSTRUCTION_REGISTER_STATE 51,1296 +#define FTC_SUCCESS 53,1342 +#define FTC_INVALID_HANDLE 54,1375 +#define FTC_DEVICE_NOT_FOUND 55,1427 +#define FTC_DEVICE_NOT_OPENED 56,1482 +#define FTC_IO_ERROR 57,1539 +#define FTC_INSUFFICIENT_RESOURCES 58,1578 +#define FTC_FAILED_TO_COMPLETE_COMMAND 60,1648 +#define FTC_FAILED_TO_SYNCHRONIZE_DEVICE_MPSSE 61,1757 +#define FTC_INVALID_DEVICE_NAME_INDEX 62,1866 +#define FTC_NULL_DEVICE_NAME_BUFFER_POINTER 63,1975 +#define FTC_DEVICE_NAME_BUFFER_TOO_SMALL 64,2085 +#define FTC_INVALID_DEVICE_NAME 65,2194 +#define FTC_INVALID_LOCATION_ID 66,2303 +#define FTC_DEVICE_IN_USE 67,2412 +#define FTC_TOO_MANY_DEVICES 68,2521 +#define FTC_INVALID_CLOCK_DIVISOR 69,2630 +#define FTC_NULL_INPUT_OUTPUT_BUFFER_POINTER 70,2668 +#define FTC_INVALID_NUMBER_BITS 71,2717 +#define FTC_NULL_WRITE_DATA_BUFFER_POINTER 72,2753 +#define FTC_INVALID_NUMBER_BYTES 73,2800 +#define FTC_NUMBER_BYTES_TOO_SMALL 74,2837 +#define FTC_INVALID_TAP_CONTROLLER_STATE 75,2876 +#define FTC_NULL_READ_DATA_BUFFER_POINTER 76,2921 +#define FTC_COMMAND_SEQUENCE_BUFFER_FULL 77,2967 +#define FTC_NULL_READ_CMDS_DATA_BUFFER_POINTER 78,3012 +#define FTC_NO_COMMAND_SEQUENCE 79,3063 +#define FTC_NULL_DLL_VERSION_BUFFER_POINTER 80,3099 +#define FTC_DLL_VERSION_BUFFER_TOO_SMALL 81,3147 +#define FTC_NULL_LANGUAGE_CODE_BUFFER_POINTER 82,3192 +#define FTC_NULL_ERROR_MESSAGE_BUFFER_POINTER 83,3242 +#define FTC_ERROR_MESSAGE_BUFFER_TOO_SMALL 84,3292 +#define FTC_INVALID_LANGUAGE_CODE 85,3339 +#define FTC_INVALID_STATUS_CODE 86,3377 +typedef struct Ft_Input_Output_Pins{Ft_Input_Output_Pins119,4347 + BOOL bPin1InputOutputState;120,4385 + BOOL bPin1LowHighState;121,4417 + BOOL bPin2InputOutputState;122,4445 + BOOL bPin2LowHighState;123,4477 + BOOL bPin3InputOutputState;124,4505 + BOOL bPin3LowHighState;125,4537 + BOOL bPin4InputOutputState;126,4565 + BOOL bPin4LowHighState;127,4597 +}FTC_INPUT_OUTPUT_PINS, *PFTC_INPUT_OUTPUT_PINS;PFTC_INPUT_OUTPUT_PINS128,4625 +typedef struct Ft_Low_High_Pins{Ft_Low_High_Pins136,5010 + BOOL bPin1LowHighState;137,5044 + BOOL bPin2LowHighState;138,5072 + BOOL bPin3LowHighState;139,5100 + BOOL bPin4LowHighState;140,5128 +}FTC_LOW_HIGH_PINS, *PFTC_LOW_HIGH_PINS;PFTC_LOW_HIGH_PINS141,5156 +#define MAX_WRITE_DATA_BYTES_BUFFER_SIZE 149,5513 +typedef BYTE WriteDataByteBuffer[WriteDataByteBuffer151,5579 +typedef WriteDataByteBuffer *PWriteDataByteBuffer;PWriteDataByteBuffer152,5648 +#define MAX_READ_DATA_BYTES_BUFFER_SIZE 159,5972 +typedef BYTE ReadDataByteBuffer[ReadDataByteBuffer161,6037 +typedef ReadDataByteBuffer *PReadDataByteBuffer;PReadDataByteBuffer162,6104 +#define MAX_READ_CMDS_DATA_BYTES_BUFFER_SIZE 191,7554 +typedef BYTE ReadCmdSequenceDataByteBuffer[ReadCmdSequenceDataByteBuffer193,7625 +typedef ReadCmdSequenceDataByteBuffer *PReadCmdSequenceDataByteBuffer;PReadCmdSequenceDataByteBuffer194,7708 + +includes/win_FTCJTAG_ptrs.h,2991 +#define _WIN_FTCJTAG_PTRS_H_2,30 +typedef FTC_STATUS _stdcall (*jtagGetNumDevicesPtr)jtagGetNumDevicesPtr5,65 +jtagGetNumDevicesPtr jtagGetNumDevices;6,143 +typedef FTC_STATUS _stdcall (*jtagInitDevicePtr)jtagInitDevicePtr8,186 +jtagInitDevicePtr jtagInitDevice;9,280 +typedef FTC_STATUS _stdcall (*jtagOpenPtr)jtagOpenPtr11,317 +jtagOpenPtr jtagOpen;12,385 +typedef FTC_STATUS _stdcall (*jtagOpenExPtr)jtagOpenExPtr14,410 +jtagOpenExPtr jtagOpenEx;15,520 +typedef FTC_STATUS _stdcall (*jtagGetDeviceNameLocIDPtr)jtagGetDeviceNameLocIDPtr17,549 +jtagGetDeviceNameLocIDPtr jtagGetDeviceNameLocID;18,703 +typedef FTC_STATUS _stdcall (*jtagClosePtr)jtagClosePtr20,756 +jtagClosePtr jtagClose;21,823 +typedef FTC_STATUS _stdcall (*jtagGetClockPtr)jtagGetClockPtr24,852 +jtagGetClockPtr jtagGetClock;25,953 +typedef FTC_STATUS _stdcall (*jtagSetClockPtr)jtagSetClockPtr28,988 +jtagSetClockPtr jtagSetClock;29,1110 +typedef FTC_STATUS _stdcall (*jtagSetLoopbackPtr)jtagSetLoopbackPtr31,1143 +jtagSetLoopbackPtr jtagSetLoopback;32,1237 +typedef FTC_STATUS _stdcall (*jtagSetGPIOsPtr)jtagSetGPIOsPtr35,1278 +jtagSetGPIOsPtr jtagSetGPIOs;39,1647 +typedef FTC_STATUS _stdcall (*jtagGetGPIOsPtr)jtagGetGPIOsPtr42,1682 +jtagGetGPIOsPtr jtagGetGPIOs;46,1935 +typedef FTC_STATUS _stdcall (*jtagWritePtr)jtagWritePtr49,1970 +jtagWritePtr jtagWrite;52,2200 +typedef FTC_STATUS _stdcall (*jtagReadPtr)jtagReadPtr55,2229 +jtagReadPtr jtagRead;58,2458 +typedef FTC_STATUS _stdcall (*jtagWriteReadPtr)jtagWriteReadPtr61,2485 +jtagWriteReadPtr jtagWriteRead;65,2791 +typedef FTC_STATUS _stdcall (*jtagAddWriteCmdPtr)jtagAddWriteCmdPtr68,2828 +jtagAddWriteCmdPtr jtagAddWriteCmd;71,3041 +typedef FTC_STATUS _stdcall (*jtagAddReadCmdPtr)jtagAddReadCmdPtr75,3084 +jtagAddReadCmdPtr jtagAddReadCmd;76,3213 +typedef FTC_STATUS _stdcall (*jtagAddWriteReadCmdPtr)jtagAddWriteReadCmdPtr80,3254 +jtagAddWriteReadCmdPtr jtagAddWriteReadCmd;83,3537 +typedef FTC_STATUS _stdcall (*jtagClearDeviceCmdSequencePtr)jtagClearDeviceCmdSequencePtr88,3590 +jtagClearDeviceCmdSequencePtr jtagClearDeviceCmdSequence;89,3674 +typedef FTC_STATUS _stdcall (*jtagAddDeviceWriteCmdPtr)jtagAddDeviceWriteCmdPtr93,3739 + jtagAddDeviceWriteCmdPtr jtagAddDeviceWriteCmd;96,3977 +typedef FTC_STATUS _stdcall (*jtagAddDeviceReadCmdPtr)jtagAddDeviceReadCmdPtr100,4039 +jtagAddDeviceReadCmdPtr jtagAddDeviceReadCmd;101,4195 +typedef FTC_STATUS _stdcall (*jtagAddDeviceWriteReadCmdPtr)jtagAddDeviceWriteReadCmdPtr105,4248 +jtagAddDeviceWriteReadCmdPtr jtagAddDeviceWriteReadCmd;108,4502 +typedef FTC_STATUS _stdcall (*jtagExecuteCmdSequencePtr)jtagExecuteCmdSequencePtr112,4565 +jtagExecuteCmdSequencePtr jtagExecuteCmdSequence;114,4743 +typedef FTC_STATUS _stdcall (*jtagGetDllVersionPtr)jtagGetDllVersionPtr118,4800 +jtagGetDllVersionPtr jtagGetDllVersion;119,4900 +typedef FTC_STATUS _stdcall (*jtagGetErrorCodeStringPtr)jtagGetErrorCodeStringPtr123,4947 +jtagGetErrorCodeStringPtr jtagGetErrorCodeString;125,5104 + +includes/WinTypes.h,2042 +#define __WINDOWS_TYPES__2,26 +#define MAX_NUM_DEVICES 4,53 +typedef unsigned long DWORD;7,103 +typedef unsigned long ULONG;8,133 +typedef unsigned short USHORT;9,163 +typedef short SHORT;10,195 +typedef unsigned char UCHAR;11,219 +typedef unsigned short WORD;12,248 +typedef unsigned char BYTE;13,277 +typedef unsigned char *LPBYTE;LPBYTE14,305 +typedef int BOOL;15,336 +typedef char BOOLEAN;16,356 +typedef char CHAR;17,380 +typedef int *LPBOOL;LPBOOL18,401 +typedef unsigned char *PUCHAR;PUCHAR19,424 +typedef const char *LPCSTR;LPCSTR20,456 +typedef char *PCHAR;PCHAR21,484 +typedef void *PVOID;PVOID22,506 +typedef void *HANDLE;HANDLE23,529 +typedef long LONG;24,553 +typedef int INT;25,574 +typedef unsigned int UINT;26,593 +typedef char *LPSTR;LPSTR27,621 +typedef char *LPTSTR;LPTSTR28,644 +typedef DWORD *LPDWORD;LPDWORD29,668 +typedef WORD *LPWORD;LPWORD30,694 +typedef ULONG *PULONG;PULONG31,718 +typedef PVOID LPVOID;32,742 +typedef void VOID;33,765 +typedef unsigned long long int ULONGLONG;34,785 +typedef struct _OVERLAPPED 36,828 + DWORD Internal;37,857 + DWORD InternalHigh;38,874 + DWORD Offset;39,895 + DWORD OffsetHigh;40,910 + HANDLE hEvent;41,929 +} OVERLAPPED, *LPOVERLAPPED;LPOVERLAPPED42,945 +typedef struct _SECURITY_ATTRIBUTES 44,975 + DWORD nLength;45,1013 + LPVOID lpSecurityDescriptor;46,1029 + BOOL bInheritHandle;47,1059 +} SECURITY_ATTRIBUTES , *LPSECURITY_ATTRIBUTES;LPSECURITY_ATTRIBUTES48,1081 +typedef struct timeval SYSTEMTIME;50,1130 +typedef struct timeval FILETIME;51,1165 +#define TRUE 53,1211 +#define FALSE 56,1247 +#define MS_CTS_ON 62,1299 +#define MS_DSR_ON 63,1343 +#define MS_RING_ON 64,1387 +#define MS_RLSD_ON 65,1431 +#define CE_RXOVER 71,1498 +#define CE_OVERRUN 72,1560 +#define CE_RXPARITY 73,1621 +#define CE_FRAME 74,1681 +#define CE_BREAK 75,1742 +#define CE_TXFULL 76,1796 +#define CE_PTO 77,1852 +#define CE_IOE 78,1904 +#define CE_DNS 79,1958 +#define CE_OOP 80,2022 +#define CE_MODE 81,2079 +#define INVALID_HANDLE_VALUE 84,2175 + +includes/usb_driver_calls.h,0

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.