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

Subversion Repositories or1k

Compare Revisions

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

Rev 1779 → Rev 1778

/trunk/or_debug_proxy/lib/FTCJTAG.dll Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
trunk/or_debug_proxy/lib/FTCJTAG.dll Property changes : Deleted: svn:executable ## -1 +0,0 ## -* \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: trunk/or_debug_proxy/src/usb_functions.c =================================================================== --- trunk/or_debug_proxy/src/usb_functions.c (revision 1779) +++ trunk/or_debug_proxy/src/usb_functions.c (nonexistent) @@ -1,1069 +0,0 @@ -/*$$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: trunk/or_debug_proxy/src/linux_usb_driver_calls.c =================================================================== --- trunk/or_debug_proxy/src/linux_usb_driver_calls.c (revision 1779) +++ trunk/or_debug_proxy/src/linux_usb_driver_calls.c (nonexistent) @@ -1,428 +0,0 @@ -/*$$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: trunk/or_debug_proxy/src/FT2232cMpsseJtag.cpp =================================================================== --- trunk/or_debug_proxy/src/FT2232cMpsseJtag.cpp (revision 1779) +++ trunk/or_debug_proxy/src/FT2232cMpsseJtag.cpp (nonexistent) @@ -1,2017 +0,0 @@ -/*++ - -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: trunk/or_debug_proxy/src/FT2232c.cpp =================================================================== --- trunk/or_debug_proxy/src/FT2232c.cpp (revision 1779) +++ trunk/or_debug_proxy/src/FT2232c.cpp (nonexistent) @@ -1,1161 +0,0 @@ -/*++ - -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: trunk/or_debug_proxy/src/vpi_functions.c =================================================================== --- trunk/or_debug_proxy/src/vpi_functions.c (revision 1779) +++ trunk/or_debug_proxy/src/vpi_functions.c (nonexistent) @@ -1,613 +0,0 @@ -/*$$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: trunk/or_debug_proxy/src/or_debug_proxy.c =================================================================== --- trunk/or_debug_proxy/src/or_debug_proxy.c (revision 1779) +++ trunk/or_debug_proxy/src/or_debug_proxy.c (nonexistent) @@ -1,363 +0,0 @@ -/*$$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: trunk/or_debug_proxy/src/gdb.c =================================================================== --- trunk/or_debug_proxy/src/gdb.c (revision 1779) +++ trunk/or_debug_proxy/src/gdb.c (nonexistent) @@ -1,4031 +0,0 @@ -/*$$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: trunk/or_debug_proxy/src/win_usb_driver_calls.c =================================================================== --- trunk/or_debug_proxy/src/win_usb_driver_calls.c (revision 1779) +++ trunk/or_debug_proxy/src/win_usb_driver_calls.c (nonexistent) @@ -1,477 +0,0 @@ -/*$$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; - -}

powered by: WebSVN 2.1.0

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