URL
https://opencores.org/ocsvn/adv_debug_sys/adv_debug_sys/trunk
Subversion Repositories adv_debug_sys
Compare Revisions
- This comparison shows the changes necessary to convert path
/adv_debug_sys/tags
- from Rev 26 to Rev 27
- ↔ Reverse comparison
Rev 26 → Rev 27
/ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/gdb-6.8-bz436037-reg-no-longer-active.patch
File deleted
/ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/icarus/Makefile
File deleted
\ No newline at end of file
/ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_win32/jp-io-vpi.dll
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_win32/jp-io-vpi.dll
Property changes :
Deleted: svn:executable
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_win32/Makefile
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_win32/Makefile (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_win32/Makefile (nonexistent)
@@ -1,27 +0,0 @@
-
-SRCDIR=../src/
-
-# The location of the ModelSim installation, used
-# to build the C lib for VPI. Used by MinGW, so use windows dir name, not /cygdrive/...
-MODEL=c:/altera/70/modelsim_ae
-
-# Different installs of Modelsim keep their libraries in different
-# directories (e.g. the version that comes with the Altera web version).
-# This directory must contain mtipli.dll
-MODEL_LIB=$(MODEL)/win32aloem
-
-# If building under windows, Modelsim requires that the VPI
-# library be compiled with MinGW, NOT cygwin GCC. The location
-# here is the default used by the auto-installer.
-MINGW_CC = c:/MinGW/bin/mingw32-gcc.exe
-
-
-default: vpi
-
-# This is for ModelSim under cygwin. Modelsim requires the shared lib
-# to be compiled with MinGW, not cygwin GCC.
-jp-io-vpi.dll: $(SRCDIR)jp-io-vpi.c Makefile
- $(MINGW_CC) -DWIN32 -c -I$(MODEL)/include $(SRCDIR)jp-io-vpi.c -o jp-io-vpi.o
- $(MINGW_CC) -DWIN32 -shared -Bsymbolic -o jp-io-vpi.dll jp-io-vpi.o -L$(MODEL_LIB) -lmtipli -lws2_32
-
-vpi: jp-io-vpi.dll Makefile
\ No newline at end of file
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_linux_x86/Makefile
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_linux_x86/Makefile (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/sim_lib/modelsim_linux_x86/Makefile (nonexistent)
@@ -1,20 +0,0 @@
-
-SRCDIR=../src/
-CC = gcc
-
-# The location of the ModelSim installation, used
-# to build the C lib for VPI. Must contain a subdir with
-# vpi_user.h.
-MODEL=/opt/modelsim
-
-
-
-default: vpi
-
-# This is for ModelSim under Linux (x86/32)
-# If RH v7.1 or lower, add -noinhibit-exec
-jp-io-vpi.so: $(SRCDIR)jp-io-vpi.c Makefile
- $(CC) -c -I$(MODEL)/modeltech/include $(SRCDIR)jp-io-vpi.c -o jp-io-vpi.o
- $(CC) -shared -Bsymbolic -o jp-io-vpi.so jp-io-vpi.o -lc
-
-vpi: jp-io-vpi.so Makefile
\ No newline at end of file
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/except.h
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/except.h (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/except.h (nonexistent)
@@ -1,52 +0,0 @@
-/* except.h -- OR1K architecture specific exceptions
-
-Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
-Copyright (C) 2008 Embecosm Limited
-
-Contributor Jeremy Bennett
-
-This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3 of the License, or (at your option)
-any later version.
-
-This program 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 General Public License for
-more details.
-
-You should have received a copy of the GNU General Public License along
-with this program. If not, see .
-*/
-
-/* This program is commented throughout in a fashion suitable for processing
- with Doxygen. */
-
-
-#ifndef EXCEPT__H
-#define EXCEPT__H
-
-
-/* Package includes */
-//#include "arch.h"
-
-/* 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
-
-#endif /* EXCEPT__H */
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/chain_commands.c
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/chain_commands.c (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/chain_commands.c (nonexistent)
@@ -1,491 +0,0 @@
-/* chain_commands.c -- JTAG protocol bridge between GDB and Advanced debug module.
- Copyright(C) Nathan Yawn, nyawn@opencores.net
- based on code from jp2 by Marko Mlinar, markom@opencores.org
-
- This file contains functions which perform mid-level transactions
- on a JTAG, such as setting a value in the TAP IR
- or doing a burst write on the JTAG chain.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-
-#include
-#include // for malloc()
-#include // for usleep()
-//#include // for mutexes
-
-#include "chain_commands.h" // For the return error codes
-#include "altera_virtual_jtag.h" // hardware-specifg defines for the Altera Virtual JTAG interface
-#include "cable_common.h" // low-level JTAG IO routines
-#include "adv_dbg_commands.h" // for the kludge in tap_reset()
-#include "errcodes.h"
-
-#define debug(...) //fprintf(stderr, __VA_ARGS__ )
-
-// How many tries before an abort
-#define NUM_SOFT_RETRIES 5
-
-// for the klugde in tap_reset()
-extern int current_reg_idx[DBG_MAX_MODULES];
-
-/* Currently selected scan chain in the debug unit - just to prevent unnecessary
- transfers. */
-int current_chain = -1;
-int desired_chain = -1;
-
-// wait for 100ms
-#define JTAG_RETRY_WAIT() usleep(100000);
-
-// Retry data
-int soft_retry_no = 0;
-//static int hard_retry_no = 0;
-
-// Configuration data
-int global_IR_size = 0;
-int global_IR_prefix_bits = 0;
-int global_IR_postfix_bits = 0;
-int global_DR_prefix_bits = 0;
-int global_DR_postfix_bits = 0;
-unsigned int global_jtag_cmd_debug = 0; // Value to be shifted into the TAP IR to select the debug unit (unused for virtual jtag)
-unsigned char global_altera_virtual_jtag = 0; // Set true to use virtual jtag mode
-unsigned int vjtag_cmd_vir = ALTERA_CYCLONE_CMD_VIR; // virtual IR-shift command for altera devices, may be configured on command line
-unsigned int vjtag_cmd_vdr = ALTERA_CYCLONE_CMD_VDR; // virtual DR-shift, ditto
-unsigned char global_xilinx_bscan = 0; // Set true if the hardware uses a Xilinx BSCAN_* device.
-
-
-///////////////////////////////////////////////////////////////////////
-// Configuration
-
-void config_set_IR_size(int size) {
- global_IR_size = size;
-}
-
-void config_set_IR_prefix_bits(int bits) {
- global_IR_prefix_bits = bits;
-}
-
-void config_set_IR_postfix_bits(int bits) {
- global_IR_postfix_bits = bits;
-}
-
-void config_set_DR_prefix_bits(int bits) {
- global_DR_prefix_bits = bits;
-}
-
-void config_set_DR_postfix_bits(int bits) {
- global_DR_postfix_bits = bits;
-}
-
-void config_set_debug_cmd(unsigned int cmd) {
- global_jtag_cmd_debug = cmd;
-}
-
-void config_set_alt_vjtag(unsigned char enable) {
- global_altera_virtual_jtag = (enable) ? 1:0;
-}
-
-// At present, all devices which support virtual JTAG use the same VIR/VDR
-// commands. But, if they ever change, these can be changed on the command line.
-void config_set_vjtag_cmd_vir(unsigned int cmd) {
- vjtag_cmd_vir = cmd;
-}
-
-void config_set_vjtag_cmd_vdr(unsigned int cmd) {
- vjtag_cmd_vdr = cmd;
-}
-
-void config_set_xilinx_bscan(unsigned char enable) {
- global_xilinx_bscan = (enable) ? 1:0;
-}
-
-//////////////////////////////////////////////////////////////////////
-// Functions which operate on the JTAG TAP
-
-
-/* Resets JTAG - Writes TRST=1, and TRST=0. Sends 8 TMS to put the TAP
- * in test_logic_reset mode, for good measure.
- */
-int tap_reset(void) {
- int i;
- int err = APP_ERR_NONE;
-
- debug("\nreset(");
- err |= jtag_write_bit(0);
- JTAG_RETRY_WAIT();
- /* In case we don't have TRST reset it manually */
- for(i = 0; i < 8; i++) err |= jtag_write_bit(TMS);
- err |= jtag_write_bit(TRST); // if TRST not supported, this puts us in test logic/reset
- JTAG_RETRY_WAIT();
- err |= jtag_write_bit(0); // run test / idle
- debug(")\n");
-
- // Reset data on current module/register selections
- current_chain = -1;
-
- // (this is only for the adv. debug i/f...bit of a kludge)
- for(i = 0; i < DBG_MAX_MODULES; i++)
- current_reg_idx[i] = -1;
-
- return err;
-}
-
- // Set the IR with the DEBUG command, one way or the other
-int tap_enable_debug_module(void)
-{
- uint32_t data;
- int err = APP_ERR_NONE;
-
- if(global_altera_virtual_jtag) {
- /* Set for virtual IR shift */
- err |= tap_set_ir(vjtag_cmd_vir); // This is the altera virtual IR scan command
- err |= jtag_write_bit(TMS); /* SELECT_DR SCAN */
- err |= jtag_write_bit(0); /* CAPTURE_DR */
- err |= jtag_write_bit(0); /* SHIFT_DR */
-
- /* Select debug scan chain in virtual IR */
- data = (0x1< 32) { // Deal with spill into the next word
- ir_chain[startoffset+1] &= ir >> (32-startshift);
- ir_chain[startoffset+1] |= (0xFFFFFFFF << (global_IR_size - (32-startshift))); // Put the 1's back in the MSB positions
- }
-
- // Do the actual JTAG transaction
- debug("Set IR 0x%X\n", ir);
- err |= jtag_write_bit(TMS); /* SELECT_DR SCAN */
- err |= jtag_write_bit(TMS); /* SELECT_IR SCAN */
-
- err |= jtag_write_bit(0); /* CAPTURE_IR */
- err |= jtag_write_bit(0); /* SHIFT_IR */
-
- /* write data, EXIT1_IR */
- debug("Setting IR, size %i, IR_size = %i, pre_size = %i, post_size = %i, data 0x%X\n", chain_size, global_IR_size, global_IR_prefix_bits, global_IR_postfix_bits, ir);
- err |= cable_write_stream(ir_chain, chain_size, 1); // Use cable_ call directly (not jtag_), so we don't add DR prefix bits
- debug("Done setting IR\n");
-
- err |= jtag_write_bit(TMS); /* UPDATE_IR */
- err |= jtag_write_bit(0); /* IDLE */
- current_chain = -1;
- return err;
-}
-
-
-// This assumes we are in the IDLE state, and we want to be in the SHIFT_DR state.
-int tap_set_shift_dr(void)
-{
- int err = APP_ERR_NONE;
-
- err |= jtag_write_bit(TMS); /* SELECT_DR SCAN */
- err |= jtag_write_bit(0); /* CAPTURE_DR */
- err |= jtag_write_bit(0); /* SHIFT_DR */
-
- return err;
-}
-
-// This transitions from EXIT1 to IDLE. It should be the last thing called
-// in any debug unit transaction.
-int tap_exit_to_idle(void)
-{
- int err = APP_ERR_NONE;
-
- err |= jtag_write_bit(TMS); /* UPDATE_DR */
- err |= jtag_write_bit(0); /* IDLE */
-
- return err;
-}
-
-////////////////////////////////////////////////////////////////////
-// Operations to read / write data over JTAG
-
-
-/* Writes TCLK=0, TRST=1, TMS=bit1, TDI=bit0
- and TCLK=1, TRST=1, TMS=bit1, TDI=bit0
-*/
-int jtag_write_bit(uint8_t packet) {
- debug("Wbit(%i)\n", packet);
- return cable_write_bit(packet);
-}
-
-int jtag_read_write_bit(uint8_t packet, uint8_t *in_bit) {
- int retval = cable_read_write_bit(packet, in_bit);
- debug("RWbit(%i,%i)", packet, *in_bit);
- return retval;
-}
-
-// This automatically adjusts for the DR length (other devices on scan chain)
-// when the set_TMS flag is true.
-int jtag_write_stream(uint32_t *out_data, int length_bits, unsigned char set_TMS)
-{
- int i;
- int err = APP_ERR_NONE;
-
- if(!set_TMS)
- err |= cable_write_stream(out_data, length_bits, 0);
- else if(global_DR_prefix_bits == 0)
- err |= cable_write_stream(out_data, length_bits, 1);
- else {
- err |= cable_write_stream(out_data, length_bits, 0);
- // It could be faster to do a cable_write_stream for all the prefix bits (if >= 8 bits),
- // but we'd need a data array of unknown (and theoretically unlimited)
- // size to hold the 0 bits to write. TODO: alloc/realloc one.
- for(i = 0; i < (global_DR_prefix_bits-1); i++)
- err |= jtag_write_bit(0);
- err |= jtag_write_bit(TMS);
- }
- return err;
-}
-
-// When set_TMS is true, this function insures the written data is in the desired position (past prefix bits)
-// before sending TMS. When 'adjust' is true, this function insures that the data read in accounts for postfix
-// bits (they are shifted through before the read starts).
-int jtag_read_write_stream(uint32_t *out_data, uint32_t *in_data, int length_bits, unsigned char adjust, unsigned char set_TMS)
-{
- int i;
- int err = APP_ERR_NONE;
-
- if(adjust && (global_DR_postfix_bits > 0)) {
- // It would be faster to do a cable_write_stream for all the postfix bits,
- // but we'd need a data array of unknown (and theoretically unlimited)
- // size to hold the '0' bits to write.
- for(i = 0; i < global_DR_postfix_bits; i++)
- err |= cable_write_bit(0);
- }
-
- // If there are both prefix and postfix bits, we may shift more bits than strictly necessary.
- // If we shifted out the data while burning through the postfix bits, these shifts could be subtracted
- // from the number of prefix shifts. However, that way leads to madness.
- if(!set_TMS)
- err |= cable_read_write_stream(out_data, in_data, length_bits, 0);
- else if(global_DR_prefix_bits == 0)
- err |= cable_read_write_stream(out_data, in_data, length_bits, 1);
- else {
- err |= cable_read_write_stream(out_data, in_data, length_bits, 0);
- // It would be faster to do a cable_write_stream for all the prefix bits,
- // but we'd need a data array of unknown (and theoretically unlimited)
- // size to hold the '0' bits to write.
- for(i = 0; i < (global_DR_prefix_bits-1); i++)
- err |= jtag_write_bit(0);
- err |= jtag_write_bit(TMS);
- }
- return err;
-}
-
-
-
-// This function attempts to determine the structure of the JTAG chain
-// It can determine how many devices are present.
-// If the devices support the IDCODE command, it will be read and stored.
-// There is no way to automatically determine the length of the IR registers -
-// this must be read from a BSDL file, if IDCODE is supported.
-// When IDCODE is not supported, IR length of the target device must be entered on the command line.
-
-#define ALLOC_SIZE 64
-#define MAX_DEVICES 1024
-int jtag_enumerate_chain(uint32_t **id_array, int *num_devices)
-{
- uint32_t invalid_code = 0x7f; // Shift this out, we know we're done when we get it back
- const unsigned int done_code = 0x3f; // invalid_code is altered, we keep this for comparison (minus the start bit)
- int devindex = 0; // which device we are currently trying to detect
- uint32_t tempID;
- uint32_t temp_manuf_code;
- uint32_t temp_rest_code;
- uint8_t start_bit = 0;
- uint32_t *idcodes;
- int reallocs = 0;
- int err = APP_ERR_NONE;
-
- // Malloc a reasonable number of entries, we'll expand if we must. Linked lists are overrated.
- idcodes = (uint32_t *) malloc(ALLOC_SIZE*sizeof(uint32_t));
- if(idcodes == NULL) {
- printf("Failed to allocate memory for device ID codes!\n");
- return APP_ERR_MALLOC;
- }
-
- // Put in SHIFT-DR mode
- err |= jtag_write_bit(TMS); /* SELECT_DR SCAN */
- err |= jtag_write_bit(0); /* CAPTURE_DR */
- err |= jtag_write_bit(0); /* SHIFT_DR */
-
- printf("Enumerating JTAG chain...\n");
-
- // Putting a limit on the # of devices supported has the useful side effect
- // of insuring we still exit in error cases (we never get the 0x7f manuf. id)
- while(devindex < MAX_DEVICES) {
- // get 1 bit. 0 = BYPASS, 1 = start of IDCODE
- err |= jtag_read_write_bit(invalid_code&0x01, &start_bit);
- invalid_code >>= 1;
-
- if(start_bit == 0) {
- if(devindex >= (ALLOC_SIZE << reallocs)) { // Enlarge the memory array if necessary, double the size each time
- idcodes = (uint32_t *) realloc(idcodes, (ALLOC_SIZE << ++reallocs)*sizeof(uint32_t));
- if(idcodes == NULL) {
- printf("Failed to allocate memory for device ID codes during enumeration!\n");
- return APP_ERR_MALLOC;
- }
- }
- idcodes[devindex] = -1;
- devindex++;
- }
- else {
- // get 11 bit manufacturer code
- err |= jtag_read_write_stream(&invalid_code, &temp_manuf_code, 11, 0, 0);
- invalid_code >>= 11;
-
- if(temp_manuf_code != done_code) {
- // get 20 more bits, rest of ID
- err |= jtag_read_write_stream(&invalid_code, &temp_rest_code, 20, 0, 0);
- invalid_code >>= 20;
- tempID = (temp_rest_code << 12) | (temp_manuf_code << 1) | 0x01;
- if(devindex >= (ALLOC_SIZE << reallocs)) { // Enlarge the memory array if necessary, double the size each time
- idcodes = (uint32_t *) realloc(idcodes, (ALLOC_SIZE << ++reallocs)*sizeof(unsigned long));
- if(idcodes == NULL) {
- printf("Failed to allocate memory for device ID codes during enumeration!\n");
- return APP_ERR_MALLOC;
- }
- }
- idcodes[devindex] = tempID;
- devindex++;
- } else {
- break;
- }
- }
-
- if(err) // Don't try to keep probing if we get a comm. error
- return err;
- }
-
- if(devindex >= MAX_DEVICES)
- printf("WARNING: maximum supported devices on JTAG chain (%i) exceeded.\n", MAX_DEVICES);
-
- // Put in IDLE mode
- err |= jtag_write_bit(TMS); /* EXIT1_DR */
- err |= jtag_write_bit(TMS); /* UPDATE_DR */
- err |= jtag_write_bit(0); /* IDLE */
-
- *id_array = idcodes;
- *num_devices = devindex;
-
- return err;
-}
-
-
-
-int jtag_get_idcode(uint32_t cmd, uint32_t *idcode)
-{
- uint32_t data_out = 0;
- int err = APP_ERR_NONE;
- unsigned char saveconfig = global_altera_virtual_jtag;
- global_altera_virtual_jtag = 0; // We want the actual IDCODE, not the virtual device IDCODE
-
- err |= tap_set_ir(cmd);
- err |= tap_set_shift_dr();
- err |= jtag_read_write_stream(&data_out, idcode, 32, 1, 1); /* EXIT1_DR */
-
- if(err)
- printf("Error getting ID code!\n");
-
- // Put in IDLE mode
- err |= jtag_write_bit(TMS); /* UPDATE_DR */
- err |= jtag_write_bit(0); /* IDLE */
-
- global_altera_virtual_jtag = saveconfig;
- return err;
-}
-
-
-/////////////////////////////////////////////////////////////////
-// Helper functions
-
-/* counts retries and returns zero if we should abort */
-/* TODO: dynamically adjust timings */
-int retry_do() {
- int err = APP_ERR_NONE;
-
- if (soft_retry_no >= NUM_SOFT_RETRIES) {
- return 0;
-
- // *** TODO: Add a 'hard retry', which re-initializes the cable, re-enumerates the bus, etc.
-
- } else { /* quick reset */
- if(err |= tap_reset()) {
- printf("Error %s while resetting for retry.\n", get_err_string(err));
- return 0;
- }
-
- // Put us back into DEBUG mode
- if(err |= tap_enable_debug_module()) {
- printf("Error %s enabling debug module during retry.\n", get_err_string(err));
- return 0;
- }
-
- soft_retry_no++;
- printf("Retry...\n");
- }
-
- return 1;
-}
-
-/* resets retry counter */
-void retry_ok() {
- soft_retry_no = 0;
-}
-
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/opencores_tap.h
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/opencores_tap.h (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/opencores_tap.h (nonexistent)
@@ -1,24 +0,0 @@
-#ifndef _OPENCORES_TAP_H_
-#define _OPENCODER_TAP_H_
-
-
-// Information on the OpenCores JTAG TAP
-// Included as a default, in place of a BSDL file
-// with the data.
-
-#define JI_SIZE (4)
-enum jtag_instr
- {
- JI_EXTEST = 0x0,
- JI_SAMPLE_PRELOAD = 0x1,
- JI_IDCODE = 0x2,
- JI_CHAIN_SELECT = 0x3,
- JI_INTEST = 0x4,
- JI_CLAMP = 0x5,
- JI_CLAMPZ = 0x6,
- JI_HIGHZ = 0x7,
- JI_DEBUG = 0x8,
- JI_BYPASS = 0xF
- };
-
-#endif
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_dbg_commands.c
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_dbg_commands.c (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_dbg_commands.c (nonexistent)
@@ -1,689 +0,0 @@
-/* adv_dbg_commands.c -- JTAG protocol bridge between GDB and Advanced debug module.
- Copyright(C) Nathan Yawn, nyawn@opencores.net
-
- This file contains functions which perform high-level transactions
- on a JTAG chain and debug unit, such as setting a value in the TAP IR
- or doing a burst write through the wishbone module of the debug unit.
- It uses the protocol for the Advanced Debug Interface (adv_dbg_if).
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-
-#include
-#include // for malloc()
-#include // for exit()
-//#include // for mutexes
-
-#include "chain_commands.h"
-#include "adv_dbg_commands.h" // hardware-specific defines for the debug module
-//#include "altera_virtual_jtag.h" // hardware-specifg defines for the Altera Virtual JTAG interface
-#include "cable_common.h" // low-level JTAG IO routines
-#include "errcodes.h"
-
-#define debug(...) //fprintf(stderr, __VA_ARGS__ )
-
-// How many '0' status bits to get during a burst read
-// before giving up
-#define MAX_READ_STATUS_WAIT 100
-
-// Currently selected internal register in each module
-// - cuts down on unnecessary transfers
-int current_reg_idx[DBG_MAX_MODULES];
-
-// Prototypes for local functions
-uint32_t adbg_compute_crc(uint32_t crc_in, uint32_t data_in, int length_bits);
-
-
-
-////////////////////////////////////////////////////////////////////////
-// Helper functions
-
-uint32_t adbg_compute_crc(uint32_t crc_in, uint32_t data_in, int length_bits)
-{
- int i;
- unsigned int d, c;
- uint32_t crc_out = crc_in;
-
- for(i = 0; i < length_bits; i = i+1)
- {
- d = ((data_in >> i) & 0x1) ? 0xffffffff : 0;
- c = (crc_out & 0x1) ? 0xffffffff : 0;
- crc_out = crc_out >> 1;
- crc_out = crc_out ^ ((d ^ c) & ADBG_CRC_POLY);
- }
- return crc_out;
-}
-
-//////////////////////////////////////////////////////////////////
-// Functions which operate on the advanced debug unit
-
-/* Selects one of the modules in the debug unit (e.g. wishbone unit, CPU0, etc.)
- */
-int adbg_select_module(int chain)
-{
- uint32_t data;
- int err = APP_ERR_NONE;
-
- if (current_chain == chain)
- return err;
-
- current_chain = -1;
- desired_chain = chain;
-
- // MSB of the data out must be set to 1, indicating a module select command
- data = chain | (1<> 16) | ((opcode & 0xf) << 16)) & ~(0x1<<20); // MSB must be 0 to access modules
-
- err |= tap_set_shift_dr(); /* SHIFT_DR */
-
- /* write data, EXIT1_DR */
- err |= jtag_write_stream(data, 53, 1); // When TMS is set (last parameter), DR length is also adjusted; EXIT1_DR
-
- err |= tap_exit_to_idle(); // Go from EXIT1 to IDLE
-
- /* reset retry counter */
- retry_ok();
-
- if(err)
- printf("Error %s sending burst command to module %i\n", get_err_string(err), desired_chain);
-
- return err;
-}
-
-// Set up and execute a burst read from a contiguous block of addresses.
-// Note that there is a minor weakness in the CRC algorithm in case of retries:
-// the CRC is only checked for the final burst read. Thus, if errors/partial retries
-// break up a transfer into multiple bursts, only the last burst will be CRC protected.
-#define MAX_BUS_ERRORS 10
-int adbg_wb_burst_read(int word_size_bytes, int word_count, unsigned long start_address, void *data)
-{
- unsigned char opcode;
- uint8_t status;
- unsigned long instream;
- int i, j;
- uint32_t crc_calc;
- uint32_t crc_read;
- unsigned char word_size_bits;
- uint32_t out_data = 0;
- uint32_t in_data;
- unsigned long addr;
- uint32_t err_data[2];
- int bus_error_retries = 0;
- int err = APP_ERR_NONE;
-
- debug("Doing burst read, word size %d, word count %d, start address 0x%lX", word_size_bytes, word_count, start_address);
-
- if(word_count <= 0) {
- debug("Ignoring illegal read burst length (%d)\n", word_count);
- return 0;
- }
-
- instream = 0;
- word_size_bits = word_size_bytes << 3;
-
- // Select the appropriate opcode
- switch(current_chain) {
- case DC_WISHBONE:
- if (word_size_bytes == 1) opcode = DBG_WB_CMD_BREAD8;
- else if(word_size_bytes == 2) opcode = DBG_WB_CMD_BREAD16;
- else if(word_size_bytes == 4) opcode = DBG_WB_CMD_BREAD32;
- else {
- printf("Tried burst read with invalid word size (%0x), defaulting to 4-byte words", word_size_bytes);
- opcode = DBG_WB_CMD_BREAD32;
- }
- break;
- case DC_CPU0:
- if(word_size_bytes == 4) opcode = DBG_CPU0_CMD_BREAD32;
- else {
- printf("Tried burst read with invalid word size (%0x), defaulting to 4-byte words", word_size_bytes);
- opcode = DBG_CPU0_CMD_BREAD32;
- }
- break;
- case DC_CPU1:
- if(word_size_bytes == 4) opcode = DBG_CPU1_CMD_BREAD32;
- else {
- printf("Tried burst read with invalid word size (%0x), defaulting to 4-byte words", word_size_bytes);
- opcode = DBG_CPU0_CMD_BREAD32;
- }
- break;
- default:
- printf("ERROR! Illegal debug chain selected while doing burst read!\n");
- return 1;
- }
-
- wb_burst_read_retry_full:
- i = 0;
- addr = start_address;
- wb_burst_read_retry_partial:
- crc_calc = 0xffffffff;
-
-
- // Send the BURST READ command, returns TAP to idle state
- if(err |= adbg_burst_command(opcode, addr, (word_count-i))) // word_count-i in case of partial retry
- return err;
-
- // This is a kludge to word around oddities in the Xilinx BSCAN_* devices, and the
- // adv_dbg_if state machine. The debug FSM needs 1 TCK between UPDATE_DR above, and
- // the CAPTURE_DR below, and the BSCAN_* won't provide it. So, we force it, by putting the TAP
- // in BYPASS, which makes the debug_select line inactive, which is AND'ed with the TCK line (in the xilinx_internal_jtag module),
- // which forces it low. Then we re-enable USER1/debug_select to make TCK high. One TCK
- // event, the hard way.
- if(global_xilinx_bscan) {
- err |= tap_set_ir(0xFFFFFFFF);
- err |= tap_enable_debug_module();
- }
-
- // Get us back to shift_dr mode to read a burst
- err |= tap_set_shift_dr();
-
- // We do not adjust for the DR length here. BYPASS regs are loaded with 0,
- // and the debug unit waits for a '1' status bit before beginning to read data.
-
- // Repeat for each word: wait until ready = 1, then read word_size_bits bits.
- for(; i < word_count; i++)
- {
- // Get 1 status bit, then word_size_bytes*8 bits
- status = 0;
- j = 0;
- while(!status) { // Status indicates whether there is a word available to read. Wait until it returns true.
- err |= jtag_read_write_bit(0, &status);
- j++;
- // If max count exceeded, retry starting with the failure address
- if(j > MAX_READ_STATUS_WAIT) {
- printf("Burst read timed out.\n");
- if(!retry_do()) {
- printf("Retry count exceeded in burst read!\n");
- return err|APP_ERR_MAX_RETRY;
- }
- err = APP_ERR_NONE; // on retry, errors cleared
- addr = start_address + (i*word_size_bytes);
- goto wb_burst_read_retry_partial;
- }
- }
-
- if(j > 1) { // It's actually normal for the first read of a burst to take 2 tries, even with a fast WB clock - 3 with a Xilinx BSCAN
- debug("Took %0d tries before good status bit during burst read", j);
- }
-
- // Get one word of data
- err |= jtag_read_write_stream(&out_data, &in_data, word_size_bits, 0, 0);
- debug("Read 0x%0lx", in_data);
-
- if(err) { // Break and retry as soon as possible on error
- printf("Error %s during burst read.\n", get_err_string(err));
- if(!retry_do()) {
- printf("Retry count exceeded in burst read!\n");
- return err|APP_ERR_MAX_RETRY;
- }
- err = APP_ERR_NONE; // on retry, errors cleared
- addr = start_address + (i*word_size_bytes);
- goto wb_burst_read_retry_partial;
- }
-
- crc_calc = adbg_compute_crc(crc_calc, in_data, word_size_bits);
-
- if(word_size_bytes == 1) ((unsigned char *)data)[i] = in_data & 0xFF;
- else if(word_size_bytes == 2) ((unsigned short *)data)[i] = in_data & 0xFFFF;
- else ((unsigned long *)data)[i] = in_data;
- }
-
- // All bus data was read. Read the data CRC from the debug module.
- err |= jtag_read_write_stream(&out_data, &crc_read, 32, 0, 1);
-
- err |= tap_exit_to_idle(); // Go from EXIT1 to IDLE
-
- if(crc_calc != crc_read) {
- printf("CRC ERROR! Computed 0x%x, read CRC 0x%x\n", crc_calc, crc_read);
- if(!retry_do()) {
- printf("Retry count exceeded! Abort!\n\n");
- return err|APP_ERR_CRC;
- }
- goto wb_burst_read_retry_full;
- }
- else debug("CRC OK!");
-
-
-
- // Now, read the error register, and retry/recompute as necessary.
- if(current_chain == DC_WISHBONE)
- {
- err |= adbg_ctrl_read(DBG_WB_REG_ERROR, err_data, 1); // First, just get 1 bit...read address only if necessary,
- if(err_data[0] & 0x1) { // Then we have a problem.
- err |= adbg_ctrl_read(DBG_WB_REG_ERROR, err_data, 33);
- addr = (err_data[0] >> 1) | (err_data[1] << 31);
- i = (addr - start_address) / word_size_bytes;
- printf("ERROR! WB bus error during burst read, address 0x%lX (index 0x%X), retrying!\n", addr, i);
- bus_error_retries++;
- if(bus_error_retries > MAX_BUS_ERRORS) {
- printf("Max WB bus errors reached during burst read\n");
- return err|APP_ERR_MAX_BUS_ERR;
- }
- // Don't call retry_do(), a JTAG reset won't help a WB bus error
- err_data[0] = 1;
- err |= adbg_ctrl_write(DBG_WB_REG_ERROR, err_data, 1); // Write 1 bit, to reset the error register,
- goto wb_burst_read_retry_partial;
- }
- }
-
- retry_ok();
- return err;
-}
-
-// Set up and execute a burst write to a contiguous set of addresses
-int adbg_wb_burst_write(void *data, int word_size_bytes, int word_count, unsigned long start_address)
-{
- unsigned char opcode;
- uint8_t status;
- uint32_t datawords[2] = {0,0};
- uint32_t statuswords[2] = {0,0};
- int i;
- uint32_t crc_calc;
- uint32_t crc_match;
- unsigned int word_size_bits;
- unsigned long addr;
- int bus_error_retries = 0;
- uint32_t err_data[2];
- int loopct, successes;
- int first_status_loop;
- int err = APP_ERR_NONE;
-
- debug("Doing burst write, word size %d, word count %d, start address 0x%lx", word_size_bytes, word_count, start_address);
- word_size_bits = word_size_bytes << 3;
-
- if(word_count <= 0) {
- printf("Ignoring illegal burst write size (%d)\n", word_count);
- return 0;
- }
-
- // Select the appropriate opcode
- switch(current_chain) {
- case DC_WISHBONE:
- if (word_size_bytes == 1) opcode = DBG_WB_CMD_BWRITE8;
- else if(word_size_bytes == 2) opcode = DBG_WB_CMD_BWRITE16;
- else if(word_size_bytes == 4) opcode = DBG_WB_CMD_BWRITE32;
- else {
- printf("Tried WB burst write with invalid word size (%0x), defaulting to 4-byte words", word_size_bytes);
- opcode = DBG_WB_CMD_BWRITE32;
- }
- break;
- case DC_CPU0:
- if(word_size_bytes == 4) opcode = DBG_CPU0_CMD_BWRITE32;
- else {
- printf("Tried CPU0 burst write with invalid word size (%0x), defaulting to 4-byte words", word_size_bytes);
- opcode = DBG_CPU0_CMD_BWRITE32;
- }
- break;
- case DC_CPU1:
- if(word_size_bytes == 4) opcode = DBG_CPU1_CMD_BWRITE32;
- else {
- printf("Tried CPU1 burst write with invalid word size (%0X), defaulting to 4-byte words", word_size_bytes);
- opcode = DBG_CPU0_CMD_BWRITE32;
- }
- break;
- default:
- printf("ERROR! Illegal debug chain selected while doing burst WRITE!\n");
- return 1;
- }
-
- // Compute which loop iteration in which to expect the first status bit
- first_status_loop = 1 + ((global_DR_prefix_bits + global_DR_postfix_bits)/(word_size_bits+1));
-
- wb_burst_write_retry_full:
- i = 0;
- addr = start_address;
- wb_burst_write_retry_partial:
- crc_calc = 0xffffffff;
- successes = 0;
-
-
- // Send burst command, return to idle state
- if(err |= adbg_burst_command(opcode, addr, (word_count-i))) // word_count-i in case of partial retry
- return err;
-
- // Get us back to shift_dr mode to write a burst
- //err |= jtag_write_bit(TMS); // select_dr_scan
- //err |= jtag_write_bit(0); // capture_ir
- //err |= jtag_write_bit(0); // shift_ir
- err |= tap_set_shift_dr();
-
- // Write a start bit (a 1) so it knows when to start counting
- err |= jtag_write_bit(TDO);
-
- // Now, repeat...
- for(loopct = 0; i < word_count; i++,loopct++) // loopct only used to check status...
- {
- // Write word_size_bytes*8 bits, then get 1 status bit
- if(word_size_bytes == 4) datawords[0] = ((unsigned long *)data)[i];
- else if(word_size_bytes == 2) datawords[0] = ((unsigned short *)data)[i];
- else datawords[0] = ((unsigned char *)data)[i];
-
- crc_calc = adbg_compute_crc(crc_calc, datawords[0], word_size_bits);
-
- // This is an optimization
- if((global_DR_prefix_bits + global_DR_postfix_bits) == 0) {
- err |= jtag_write_stream(datawords, word_size_bits, 0); // Write data
- err |= jtag_read_write_bit(0, &status); // Read status bit
- if(!status) {
- addr = start_address + (i*word_size_bytes);
- printf("Write before bus ready, retrying (idx %i, addr 0x%08lX).\n", i, addr);
- if(!retry_do()) { printf("Retry count exceeded! Abort!\n\n"); exit(1);}
- // Don't bother going to TAP idle state, we're about to reset the TAP
- goto wb_burst_write_retry_partial;
- }
- }
- else { // This is slower (for a USB cable anyway), because a read takes 1 more USB transaction than a write.
- err |= jtag_read_write_stream(datawords, statuswords, word_size_bits+1, 0, 0);
- debug("St. 0x%08lX 0x%08lX\n", statuswords[0], statuswords[1]);
- status = (statuswords[0] || statuswords[1]);
- if(loopct > first_status_loop) {
- if(status) successes++;
- else {
- i = successes;
- addr = start_address + (i*word_size_bytes);
- printf("Write before bus ready, retrying (idx %i, addr 0x%08lX).\n", i, addr);
- if(!retry_do()) { printf("Retry count exceeded! Abort!\n\n"); exit(1);}
- // Don't bother going to TAP idle state, we're about to reset the TAP
- goto wb_burst_write_retry_partial;
- }
- }
- }
-
- if(err) {
- printf("Error %s getting status bit, retrying.\n", get_err_string(err));
- if(!retry_do()) {
- printf("Retry count exceeded!\n");
- return err|APP_ERR_MAX_RETRY;
- }
- err = APP_ERR_NONE;
- addr = start_address + (i*word_size_bytes);
- // Don't bother going to TAP idle state, we're about to reset the TAP
- goto wb_burst_write_retry_partial;
- }
-
- debug("Wrote 0x%0lx", datawords[0]);
- }
-
- // *** If this is a multi-device chain, at least one status bit will be lost.
- // *** If we want to check for it, we'd have to look while sending the CRC, and
- // *** maybe while burning bits to get the match bit. So, for now, there is a
- // *** hole here.
-
- // Done sending data, Send the CRC we computed
- err |= jtag_write_stream(&crc_calc, 32, 0);
- for(i = 0; i < global_DR_prefix_bits; i++) // Push the CRC data all the way to the debug unit
- err |= jtag_write_bit(0); // Can't do this with a stream command without setting TMS on the last bit
-
- // Read the 'CRC match' bit, and go to exit1_dr
- // May need to adjust for other devices in chain!
- datawords[0] = 0;
- err |= jtag_read_write_stream(datawords, &crc_match, 1, 1, 0); // set 'adjust' to pull match bit all the way in
- // But don't set TMS above, that would shift prefix bits (again), wasting time.
- err |= jtag_write_bit(TMS); // exit1_dr
- err |= tap_exit_to_idle(); // Go from EXIT1 to IDLE
-
- if(!crc_match) {
- printf("CRC ERROR! match bit after write is %i (computed CRC 0x%x)", crc_match, crc_calc);
- if(!retry_do()) { printf("Retry count exceeded! Abort!\n\n"); exit(1);}
- goto wb_burst_write_retry_full;
- }
- else debug("CRC OK!");
-
-
- // Now, read the error register and retry/recompute as needed
- if (current_chain == DC_WISHBONE)
- {
- err |= adbg_ctrl_read(DBG_WB_REG_ERROR, err_data, 1); // First, just get 1 bit...read address only if necessary
- if(err_data[0] & 0x1) { // Then we have a problem.
- err |= adbg_ctrl_read(DBG_WB_REG_ERROR, err_data, 33);
- addr = (err_data[0] >> 1) | (err_data[1] << 31);
- i = (addr - start_address) / word_size_bytes;
- printf("ERROR! WB bus error during burst write, address 0x%lX (index 0x%X), retrying!\n", addr, i);
- bus_error_retries++;
- if(bus_error_retries > MAX_BUS_ERRORS) {
- printf("Max WB bus errors reached!\n");
- return err|APP_ERR_MAX_BUS_ERR;
- }
- // Don't call retry_do(), a JTAG reset won't help a WB bus error
- err |= adbg_ctrl_write(DBG_WB_REG_ERROR, err_data, 1); // Write 1 bit, to reset the error register.
- goto wb_burst_write_retry_partial;
- }
- }
-
- retry_ok();
- return err;
-}
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_ft2232.c
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_ft2232.c (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_ft2232.c (nonexistent)
@@ -1,880 +0,0 @@
-/* cable_ft2232.c - FT2232 based cable driver for the Advanced JTAG Bridge
- Copyright (C) 2008 Arnim Laeuger, arniml@opencores.org
- Copyright (C) 2009 José Ignacio Villar, jose@dte.us.es
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "cable_ft2232.h"
-#include "cable_common.h"
-#include "errcodes.h"
-int debug = 0;
-
-static int usbconn_ftdi_common_open( usbconn_t *conn);
-static void usbconn_ftdi_free( usbconn_t *conn );
-static int seq_purge(struct ftdi_context *ftdic, int purge_rx, int purge_tx);
-static int seq_reset(struct ftdi_context *ftdic);
-static int usbconn_ftdi_flush( ftdi_param_t *params );
-static int usbconn_ftdi_read( usbconn_t *conn, uint8_t *buf, int len );
-static int usbconn_ftdi_write( usbconn_t *conn, uint8_t *buf, int len, int recv );
-static int usbconn_ftdi_mpsse_open( usbconn_t *conn );
-static int usbconn_ftdi_close(usbconn_t *conn);
-
-usbconn_driver_t usbconn_ft2232_mpsse_driver = {
- "ftdi-mpsse",
- usbconn_ftdi_connect,
- usbconn_ftdi_free,
- usbconn_ftdi_mpsse_open,
- usbconn_ftdi_close,
- usbconn_ftdi_read,
- usbconn_ftdi_write
-};
-
-usbconn_cable_t usbconn_ft2232_mpsse_CableID2= {
- "CableID2", /* cable name */
- "CableID2", /* string pattern, not used */
- "ftdi-mpsse", /* default usbconn driver */
- 0x0403, /* VID */
- 0x6010 /* PID */
-};
-
-static usbconn_t *ft2232_device;
-
-
-
-/// ----------------------------------------------------------------------------------------------
-/// libftdi wrappers for debugging purposes.
-/// ----------------------------------------------------------------------------------------------
-
-void print_buffer(unsigned char *buf, int size) {
- int i=0;
- for(i=0; i 1) print_buffer(buf, size);
- return ftdi_write_data(ftdi, buf, size);
-}
-
-char *my_ftdi_get_error_string (struct ftdi_context *ftdi) {
- debug("[MYDBG] ftdi_get_error_string(ftdi);\n");
- return ftdi_get_error_string (ftdi);
-}
-
-int my_ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
- int ret = 0;
- debug("[MYDBG] ftdi_read_data(ftdi, buf=BUFFER[%d], size=%d);\n", size, size);
- ret = ftdi_read_data(ftdi, buf, size);
- if(debug) print_buffer(buf, size);
- return ret;
-}
-
-int my_ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product, const char* description, const char* serial) {
- debug("[MYDBG] ftdi_usb_open_desc(ftdi, vendor=%d, product=%d, description=DESCRIPTION, serial=SERIAL);\n", vendor, product);
- return ftdi_usb_open_desc(ftdi, vendor, product, description, serial);
-}
-
-void my_ftdi_deinit(struct ftdi_context *ftdi) {
- debug("[MYDBG] ftdi_deinit(ftdi);\n");
- ftdi_deinit(ftdi);
-}
-
-int my_ftdi_usb_purge_buffers(struct ftdi_context *ftdi) {
- debug("[MYDBG] ftdi_usb_purge_buffers(ftdi);\n");
- return ftdi_usb_purge_buffers(ftdi);
-}
-
-int my_ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi) {
- debug("[MYDBG] ftdi_usb_purge_rx_buffer(ftdi);\n");
- return ftdi_usb_purge_rx_buffer(ftdi);
-}
-
-int my_ftdi_usb_purge_tx_buffer(struct ftdi_context *ftdi) {
- debug("[MYDBG] ftdi_usb_purge_tx_buffer(ftdi);\n");
- return ftdi_usb_purge_tx_buffer(ftdi);
-}
-
-int my_ftdi_usb_reset(struct ftdi_context *ftdi) {
- debug("[MYDBG] ftdi_usb_reset(ftdi);\n");
- return ftdi_usb_reset(ftdi);
-}
-
-int my_ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency) {
- debug("[MYDBG] ftdi_set_latency_timer(ftdi, latency=0x%02x);\n", latency);
- return ftdi_set_latency_timer(ftdi, latency);
-}
-
-int my_ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate) {
- debug("[MYDBG] ftdi_set_baudrate(ftdi, baudrate=%d);\n", baudrate);
- return ftdi_set_baudrate(ftdi, baudrate);
-}
-
-int my_ftdi_read_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize) {
- debug("[MYDBG] ftdi_read_data_set_chunksize(ftdi, chunksize=%u);\n", chunksize);
- return ftdi_read_data_set_chunksize(ftdi, chunksize);
-}
-
-int my_ftdi_write_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize) {
- debug("[MYDBG] ftdi_write_data_set_chunksize(ftdi, chunksize=%u);\n", chunksize);
- return ftdi_write_data_set_chunksize(ftdi, chunksize);
-}
-
-int my_ftdi_set_event_char(struct ftdi_context *ftdi, unsigned char eventch, unsigned char enable) {
- debug("[MYDBG] ftdi_set_event_char(ftdi, eventch=0x%02x, enable=0x%02x);\n", eventch, enable);
- return ftdi_set_event_char(ftdi, eventch, enable);
-}
-
-int my_ftdi_set_error_char(struct ftdi_context *ftdi, unsigned char errorch, unsigned char enable) {
- debug("[MYDBG] ftdi_set_error_char(ftdi, errorch=0x%02x, enable=0x%02x);\n", errorch, enable);
- return ftdi_set_error_char(ftdi, errorch, enable);
-}
-
-int my_ftdi_set_bitmode(struct ftdi_context *ftdi, unsigned char bitmask, unsigned char mode) {
- debug("[MYDBG] ftdi_set_bitmode(ftdi, bitmask=0x%02x, mode=0x%02x);\n", bitmask, mode);
- return ftdi_set_bitmode(ftdi, bitmask, mode);
-}
-
-int my_ftdi_usb_close(struct ftdi_context *ftdi) {
- debug("[MYDBG] ftdi_usb_close(ftdi);\n");
- return ftdi_usb_close(ftdi);
-}
-
-
-
-/// ----------------------------------------------------------------------------------------------
-/// USBconn FTDI MPSSE subsystem
-/// ----------------------------------------------------------------------------------------------
-
-
-static int usbconn_ftdi_common_open(usbconn_t *conn) {
- ftdi_param_t *params = conn->params;
- struct ftdi_context * ftdic = params->ftdic;
- int error;
-
- printf("Initializing USB device\n");
-
- if ((error = my_ftdi_usb_open_desc(ftdic, conn->cable->vid, conn->cable->pid, NULL, NULL))) {
- if (error == -1) printf("usb_find_busses() failed\n");
- else if (error == -2) printf("usb_find_devices() failed\n");
- else if (error == -3) printf("usb device not found\n");
- else if (error == -4) printf("unable to open device\n");
- else if (error == -5) printf("unable to claim device\n");
- else if (error == -6) printf("reset failed\n");
- else if (error == -7) printf("set baudrate failed\n");
- else if (error == -8) printf("get product description failed\n");
- else if (error == -9) printf("get serial number failed\n");
- else if (error == -10) printf("unable to close device\n");
-
- my_ftdi_deinit(ftdic);
- ftdic = NULL;
-
- printf("Can't open FTDI usb device\n");
- return(-1);
- }
-
- return 0;
-}
-
-static int seq_purge(struct ftdi_context *ftdic, int purge_rx, int purge_tx) {
- int r = 0;
- unsigned char buf;
-
- if ((r = my_ftdi_usb_purge_buffers( ftdic )) < 0)
- printf("my_ftdi_usb_purge_buffers() failed\n");
- if (r >= 0) if ((r = my_ftdi_read_data( ftdic, &buf, 1 )) < 0)
- printf("my_ftdi_read_data() failed\n");
-
- return r < 0 ? -1 : 0;
-}
-
-static int seq_reset(struct ftdi_context *ftdic) {
-
- if (my_ftdi_usb_reset( ftdic ) < 0) {
- printf("my_ftdi_usb_reset() failed\n");
- return -1;
- }
-
- if(seq_purge(ftdic, 1, 1) < 0)
- return -1;
-
- return 0;
-}
-
-static int usbconn_ftdi_flush( ftdi_param_t *params )
- {
- int xferred;
- int recvd = 0;
-
- if (!params->ftdic)
- return -1;
-
- if (params->send_buffered == 0)
- return 0;
-
- if ((xferred = my_ftdi_write_data( params->ftdic, params->send_buf, params->send_buffered )) < 0)
- printf("my_ftdi_write_data() failed\n");
-
- if (xferred < params->send_buffered) {
- printf("Written fewer bytes than requested.\n");
- return -1;
- }
-
- params->send_buffered = 0;
-
- /* now read all scheduled receive bytes */
- if (params->to_recv) {
- if (params->recv_write_idx + params->to_recv > params->recv_buf_len) {
- /* extend receive buffer */
- params->recv_buf_len = params->recv_write_idx + params->to_recv;
- if (params->recv_buf)
- params->recv_buf = (uint8_t *)realloc( params->recv_buf, params->recv_buf_len );
- }
-
- if (!params->recv_buf) {
- printf("Receive buffer does not exist.\n");
- return -1;
- }
-
- while (recvd == 0)
- if ((recvd = my_ftdi_read_data( params->ftdic, &(params->recv_buf[params->recv_write_idx]), params->to_recv )) < 0)
- printf("Error from my_ftdi_read_data()\n");
-
- if (recvd < params->to_recv)
- printf("Received less bytes than requested.\n");
-
- params->to_recv -= recvd;
- params->recv_write_idx += recvd;
- }
-
- debug("[MYDBG] FLUSHING xferred=%u\n", xferred);
- return xferred < 0 ? -1 : xferred;
-}
-
-static int usbconn_ftdi_read( usbconn_t *conn, uint8_t *buf, int len ) {
- ftdi_param_t *params = conn->params;
- int cpy_len;
- int recvd = 0;
-
- if (!params->ftdic)
- return -1;
-
- /* flush send buffer to get all scheduled receive bytes */
- if (usbconn_ftdi_flush( params ) < 0)
- return -1;
-
- if (len == 0)
- return 0;
-
- /* check for number of remaining bytes in receive buffer */
- cpy_len = params->recv_write_idx - params->recv_read_idx;
- if (cpy_len > len)
- cpy_len = len;
- len -= cpy_len;
-
- if (cpy_len > 0) {
- /* get data from the receive buffer */
- memcpy( buf, &(params->recv_buf[params->recv_read_idx]), cpy_len );
- params->recv_read_idx += cpy_len;
- if (params->recv_read_idx == params->recv_write_idx)
- params->recv_read_idx = params->recv_write_idx = 0;
- }
-
- if (len > 0) {
- /* need to get more data directly from the device */
- while (recvd == 0)
- if ((recvd = my_ftdi_read_data( params->ftdic, &(buf[cpy_len]), len )) < 0)
- printf("Error from my_ftdi_read_data()\n");
- }
- debug("[MYDBG] READ cpy_len=%u ; len=%u\n", cpy_len, len);
- return recvd < 0 ? -1 : cpy_len + len;
-}
-
-static int usbconn_ftdi_write( usbconn_t *conn, uint8_t *buf, int len, int recv ) {
-
- ftdi_param_t *params = conn->params;
- int xferred = 0;
-
- if (!params->ftdic)
- return -1;
-
- /* this write function will try to buffer write data
- buffering will be ceased and a flush triggered in two cases. */
-
- /* Case A: max number of scheduled receive bytes will be exceeded
- with this write
- Case B: max number of scheduled send bytes has been reached */
- if ((params->to_recv + recv > FTDI_MAXRECV) || ((params->send_buffered > FTDX_MAXSEND) && (params->to_recv == 0)))
- xferred = usbconn_ftdi_flush(params);
-
- if (xferred < 0)
- return -1;
-
- /* now buffer this write */
- if (params->send_buffered + len > params->send_buf_len) {
- params->send_buf_len = params->send_buffered + len;
- if (params->send_buf)
- params->send_buf = (uint8_t *)realloc( params->send_buf, params->send_buf_len);
- }
-
- if (params->send_buf) {
- memcpy( &(params->send_buf[params->send_buffered]), buf, len );
- params->send_buffered += len;
- if (recv > 0)
- params->to_recv += recv;
-
- if (recv < 0) {
- /* immediate write requested, so flush the buffered data */
- xferred = usbconn_ftdi_flush( params );
- }
-
- debug("[MYDBG] WRITE inmediate=%s ; xferred=%u ; len=%u\n", ((recv < 0) ? "TRUE" : "FALSE"), xferred, len);
- return xferred < 0 ? -1 : len;
- }
- else {
- printf("Send buffer does not exist.\n");
- return -1;
- }
-}
-
-static int usbconn_ftdi_mpsse_open( usbconn_t *conn ) {
- ftdi_param_t *params = conn->params;
- struct ftdi_context *ftdic = params->ftdic;
-
- int r = 0;
-
- if (usbconn_ftdi_common_open(conn) < 0) {
- printf("Connection failed\n");
- return -1;
- }
-
- /* This sequence might seem weird and containing superfluous stuff.
- However, it's built after the description of JTAG_InitDevice
- Ref. FTCJTAGPG10.pdf
- Intermittent problems will occur when certain steps are skipped. */
-
- r = seq_reset( ftdic );
- if (r >= 0)
- r = seq_purge( ftdic, 1, 0 );
-
- if (r >= 0)
- if ((r = my_ftdi_write_data_set_chunksize( ftdic, FTDX_MAXSEND_MPSSE )) < 0)
- puts( my_ftdi_get_error_string( ftdic ) );
-
- if (r >= 0)
- if ((r = my_ftdi_read_data_set_chunksize( ftdic, FTDX_MAXSEND_MPSSE )) < 0)
- puts( my_ftdi_get_error_string( ftdic ) );
-
- /* set a reasonable latency timer value
- if this value is too low then the chip will send intermediate result data
- in short packets (suboptimal performance) */
- if (r >= 0)
- if ((r = my_ftdi_set_latency_timer( ftdic, 16 )) < 0)
- printf("my_ftdi_set_latency_timer() failed\n");
-
- if (r >= 0)
- if ((r = my_ftdi_set_bitmode( ftdic, 0x0b, BITMODE_MPSSE )) < 0)
- printf("my_ftdi_set_bitmode() failed\n");
-
- if (r >= 0)
- if ((r = my_ftdi_usb_reset( ftdic )) < 0)
- printf("my_ftdi_usb_reset() failed\n");
-
- if (r >= 0)
- r = seq_purge( ftdic, 1, 0 );
-
- /* set TCK Divisor */
- if (r >= 0) {
- uint8_t buf[3] = {TCK_DIVISOR, 0x00, 0x00};
- r = usbconn_ftdi_write( conn, buf, 3, 0 );
- }
-
- /* switch off loopback */
- if (r >= 0) {
- uint8_t buf[1] = {LOOPBACK_END};
- r = usbconn_ftdi_write( conn, buf, 1, 0 );
- }
-
- if (r >= 0)
- r = usbconn_ftdi_read( conn, NULL, 0 );
-
- if (r >= 0)
- if ((r = my_ftdi_usb_reset( ftdic )) < 0)
- printf("my_ftdi_usb_reset() failed\n");
-
- if (r >= 0)
- r = seq_purge( ftdic, 1, 0 );
-
- if (r < 0) {
- ftdi_usb_close( ftdic );
- ftdi_deinit( ftdic );
- /* mark ftdi layer as not initialized */
- params->ftdic = NULL;
- }
-
- return r < 0 ? -1 : 0;
-}
-
-static int usbconn_ftdi_close(usbconn_t *conn) {
- ftdi_param_t *params = conn->params;
-
- if (params->ftdic) {
- my_ftdi_usb_close(params->ftdic);
- my_ftdi_deinit(params->ftdic);
- params->ftdic = NULL;
- }
-
- return 0;
-}
-
-static void usbconn_ftdi_free( usbconn_t *conn )
-{
- ftdi_param_t *params = conn->params;
-
- if (params->send_buf) free( params->send_buf );
- if (params->recv_buf) free( params->recv_buf );
- if (params->ftdic) free( params->ftdic );
- if (params->serial) free( params->serial );
-
- free( conn->params );
- free( conn );
-}
-
-usbconn_t * usbconn_ftdi_connect() {
-
- usbconn_t *conn = malloc( sizeof( usbconn_t ) );
- ftdi_param_t *params = malloc( sizeof( ftdi_param_t ) );
- struct ftdi_context *ftdic = malloc( sizeof( struct ftdi_context ) );
-
- if (params) {
- params->send_buf_len = FTDX_MAXSEND;
- params->send_buffered = 0;
- params->send_buf = (uint8_t *) malloc( params->send_buf_len );
- params->recv_buf_len = FTDI_MAXRECV;
- params->to_recv = 0;
- params->recv_write_idx = 0;
- params->recv_read_idx = 0;
- params->recv_buf = (uint8_t *) malloc( params->recv_buf_len );
- }
-
- if (!conn || !params || !ftdic || !params->send_buf || !params->recv_buf) {
- printf("Can't allocate memory for ftdi context structures\n");
-
- if (conn) free( conn );
- if (params) free( params );
- if (ftdic) free( ftdic );
- if (params->send_buf) free( params->send_buf );
- if (params->recv_buf) free( params->recv_buf );
- return NULL;
- }
-
- conn->driver = &usbconn_ft2232_mpsse_driver;
- conn->cable = &usbconn_ft2232_mpsse_CableID2;
-
- ftdi_init( ftdic );
- params->ftdic = ftdic;
- params->pid = conn->cable->pid;
- params->vid = conn->cable->vid;
- params->serial = NULL;
-
- conn->params = params;
-
- printf("Structs successfully initialized\n");
-
- /* do a test open with the specified cable paramters,
- alternatively we could use libusb to detect the presence of the
- specified USB device */
- if (usbconn_ftdi_common_open(conn) != 0) {
- printf("Connection failed\n");
- usbconn_ftdi_free(conn);
- printf("Freeing structures.\n");
- return NULL;
- }
-
- my_ftdi_usb_close( ftdic );
-
- printf("Connected to libftdi driver.\n");
-
- return conn;
-}
-
-
-
-/// ----------------------------------------------------------------------------------------------
-/// High level functions to generate Tx/Rx commands
-/// ----------------------------------------------------------------------------------------------
-
-int cable_ft2232_write_bytes(usbconn_t *conn, unsigned char *buf, int len, int postread) {
-
- int cur_command_size;
- int max_command_size;
- int cur_chunk_len;
- int recv;
- int xferred;
- int i;
- unsigned char *mybuf;
-
- if(len == 0)
- return 0;
- debug("write_bytes(length=%d, postread=%s)\n", len, ((postread > 0) ? "TRUE" : "FALSE"));
- recv = 0;
- max_command_size = min(len, 65536)+3;
- mybuf = (unsigned char *) malloc( max_command_size );
-
- /// Command OPCODE: write bytes
- mybuf[0] = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_WRITE_NEG;
- if(postread) // if postread is enabled it will buffer incoming bytes
- mybuf[0] = mybuf[0] | MPSSE_DO_READ;
-
- // We divide the transmitting stream of bytes in chunks with a maximun length of 65536 bytes each.
- while(len > 0) {
- cur_chunk_len = min(len, 65536);
- len = len - cur_chunk_len;
- cur_command_size = cur_chunk_len + 3;
-
- /// Low and High bytes of the length field
- mybuf[1] = (unsigned char) ( cur_chunk_len - 1);
- mybuf[2] = (unsigned char) ((cur_chunk_len - 1) >> 8);
-
- debug("\tOPCODE: 0x%x\n", mybuf[0]);
- debug("\tLENGTL: 0x%02x\n", mybuf[1]);
- debug("\tLENGTH: 0x%02x\n", mybuf[2]);
-
- /// The rest of the command is filled with the bytes that will be transferred
- memcpy(&(mybuf[3]), buf, cur_chunk_len );
- buf = buf + cur_chunk_len;
- for(i = 0; i< cur_chunk_len; i++)
- if(debug>1) debug("\tBYTE%3d: 0x%02x\n", i, mybuf[3+i]);
-
- /// Finally we can ransmit the command
- xferred = usbconn_ftdi_write( conn, mybuf, cur_command_size, (postread ? cur_chunk_len : 0) );
- if(xferred != cur_command_size)
- return -1;
-
- // If OK, the update the number of incoming bytes that are being buffered for a posterior read
- if(postread)
- recv = recv + cur_chunk_len;
- }
- debug("\tPOSTREAD: %u bytes\n", recv);
-
- // Returns the number of buffered incoming bytes
- return recv;
-}
-
-int cable_ft2232_write_bits(usbconn_t *conn, unsigned char *buf, int len, int postread, int with_tms)
-{
- int max_command_size;
- int max_chunk_len;
- int cur_chunk_len;
- int recv;
- int xferred;
- int i;
- unsigned char *mybuf;
-
- if(len == 0)
- return 0;
-
- max_command_size = 3;
- mybuf = (unsigned char *) malloc( max_command_size );
-
- if(!with_tms) {
- /// Command OPCODE: write bits (can write up to 8 bits in a single command)
- max_chunk_len = 8;
- mybuf[0] = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_WRITE_NEG | MPSSE_BITMODE;
- }
- else {
- /// Command OPCODE: 0x4B write bit with tms (can write up to 1 bits in a single command)
- max_chunk_len = 1;
- mybuf[0] = MPSSE_WRITE_TMS|MPSSE_LSB|MPSSE_BITMODE|MPSSE_WRITE_NEG;
- }
-
- if(postread) // (OPCODE += 0x20) if postread is enabled it will buffer incoming bits
- mybuf[0] = mybuf[0] | MPSSE_DO_READ;
-
- // We divide the transmitting stream of bytes in chunks with a maximun length of max_chunk_len bits each.
- i=0;
- recv = 0;
- while(len > 0) {
- cur_chunk_len = min(len, max_chunk_len);
- len = len - cur_chunk_len;
-
- /// Bits length field
- mybuf[1] = (unsigned char) ( cur_chunk_len - 1);
-
- debug("\tOPCODE: 0x%x\n", mybuf[0]);
- debug("\tLENGTH: 0x%02x\n", mybuf[1]);
-
- if(!with_tms) {
- /// The last byte of the command is filled with the bits that will be transferred
- debug("\tDATA[%d] 0x%02x\n", (i/8), buf[i/8]);
- mybuf[2] = buf[i/8];
- i=i+8;
- }
- else {
- //TODO: seleccionar el bit a transmitir
- mybuf[2] = 0x01 | ((buf[(i/8)] >> (i%8)) << 7);
- i++;
- }
-
- debug("\tBYTE%3d: 0x%02x\n", i, mybuf[2]);
-
- /// Finally we can transmmit the command
- xferred = usbconn_ftdi_write( conn, mybuf, max_command_size, (postread ? 1 : 0) );
- if(xferred != max_command_size)
- return -1;
-
- // If OK, the update the number of incoming bytes that are being buffered for a posterior read
- if(postread)
- recv = recv + 1;
- }
- debug("\tPOSTREAD: %u bytes\n", recv);
-
- return recv;
-}
-
-int cable_ft2232_read_packed_bits(usbconn_t *conn, uint8_t *buf, int packet_len, int bits_per_packet, int offset)
-{
- unsigned char *mybuf;
- unsigned char dst_mask;
- unsigned char src_mask;
- int row_offset;
- int dst_row;
- int dst_col;
- int src_row;
- int src_col;
- int i;
- int r;
-
- if(packet_len == 0 || bits_per_packet == 0)
- return 0;
-
- mybuf = (unsigned char *) malloc( packet_len );
- if((r=usbconn_ftdi_read( conn, mybuf, packet_len )) < 0) {
- debug("Read failed\n");
- return -1;
- }
-
- if(bits_per_packet < 8) {
- for(i=0; i < packet_len; i++){ // rotate bits to the left side
-// debug("[MYDBG] unaligned bits[%d]=%02x\n", i, mybuf[i]);
- mybuf[i] = (mybuf[i] >> (8-bits_per_packet));
-// debug("[MYDBG] aligned bits[%d]=%02x\n", i, mybuf[i]);
- }
- for(i=offset; i < (packet_len*bits_per_packet+offset); i++) {
- dst_row = i / 8;
- dst_col = i % 8;
- src_row = (i-offset) / bits_per_packet;
- src_col = (i-offset) % bits_per_packet;
- dst_mask = ~(1 << dst_col);
- src_mask = (1 << src_col);
-// debug("[MYDBG] i=%4d dst[%3d][%3d] dst_mask=%02x dst_val=%02x dst_masked=%02x\n", i, dst_row, dst_col, dst_mask, buf[dst_row], (buf[dst_row] & dst_mask));
-// debug("[MYDBG] i=%4d src[%3d][%3d] src_mask=%02x src_val=%02x src_masked=%02x\n", i, src_row, src_col, src_mask, mybuf[src_row], (mybuf[src_row] & src_mask));
- if(dst_col >= src_col)
- buf[dst_row] = (buf[dst_row] & dst_mask) | ((mybuf[src_row] & src_mask) << (dst_col - src_col));
- else
- buf[dst_row] = (buf[dst_row] & dst_mask) | ((mybuf[src_row] & src_mask) >> (dst_col - src_col));
- }
-
- }
- else if(bits_per_packet == 8){
- row_offset = offset / 8;
-// debug("[MYDBG] Row offset=%d\n", row_offset);
- memcpy( &(buf[row_offset]), mybuf, packet_len);
- }
- else {
- return -1;
- }
-
-// debug("read_bits()-> %x\n", *buf);
- return ((r < 1) ? -1 : 0);
-}
-
-int cable_ft2232_write_stream(usbconn_t *conn, unsigned char *buf, int len, int postread, int with_tms) {
- int len_bytes;
- int len_bits;
- int len_tms_bits;
- unsigned char mybuf;
-
- len_tms_bits = ((with_tms) ? 1 : 0);
- len_bytes = ((len -len_tms_bits) / 8);
- len_bits = ((len -len_tms_bits) % 8);
-
- debug("[MYDBG] cable_ft2232_write_stream(len=%d postread=%d tms=%d) = %d bytes %dbits %dtms_bits\n", len, postread, with_tms, len_bytes, len_bits, len_tms_bits);
-
- if(len_bytes > 0)
- cable_ft2232_write_bytes(conn, buf, len_bytes, postread);
-
- if(len_bits > 0)
- cable_ft2232_write_bits(conn, &(buf[len_bytes]), len_bits, postread, 0);
-
- if(len_tms_bits > 0) {
- mybuf = (buf[len_bytes] >> len_bits);
- cable_ft2232_write_bits(conn, &mybuf, 1, postread, 1);
- }
-
- return 0;
-}
-
-int cable_ft2232_read_stream(usbconn_t *conn, unsigned char *buf, int len, int with_tms) {
- int len_bytes;
- int len_bits;
- int len_tms_bits;
-
- len_tms_bits = ((with_tms) ? 1 : 0);
- len_bytes = ((len -len_tms_bits) / 8);
- len_bits = ((len -len_tms_bits) % 8);
-
- debug("[MYDBG] cable_ft2232_read_stream(len=%d tms=%d) = %d bytes %dbits %dtms_bits\n", len, with_tms, len_bytes, len_bits, len_tms_bits);
-
- if(len_bytes > 0)
- cable_ft2232_read_packed_bits(conn, buf, len_bytes, 8, 0);
-
- if(len_bits > 0)
- cable_ft2232_read_packed_bits(conn, buf, 1, len_bits, (len_bytes * 8));
-
- if(len_tms_bits > 0)
- cable_ft2232_read_packed_bits(conn, buf, 1, 1, (len_bits + (len_bytes * 8)));
-
- return 0;
-}
-
-
-
-/// ----------------------------------------------------------------------------------------------
-/// Advanced Jtag debugger driver interface.
-/// ----------------------------------------------------------------------------------------------
-
-int cable_ftdi_init() {
- int err = APP_ERR_NONE;
- int res = 0;
- unsigned char *buf = malloc(10);
-
- ft2232_device = usbconn_ftdi_connect();
-
- if((res = usbconn_ftdi_mpsse_open(ft2232_device)) != 0)
- err |= APP_ERR_USB;
- printf("Open MPSSE mode returned: %s\n", ((res != 0) ? "FAIL" : "OK") );
-
- ftdi_param_t *params = ft2232_device->params;
- //struct ftdi_context * ftdic = params->ftdic;
-
- buf[0]= SET_BITS_LOW;
- buf[1]= 0x00;
- buf[2]= 0x0b;
- buf[3]= TCK_DIVISOR;
- buf[4]= 0x01;
- buf[5]= 0x00;
- buf[6]= SET_BITS_HIGH;
- buf[7]= ~0x04;
- buf[8]= 0x04;
- buf[9]= SEND_IMMEDIATE;
- if(usbconn_ftdi_write( ft2232_device , buf, 10, 0) != 10) {
- err |= APP_ERR_USB;
- printf("Initial write failed\n");
- }
-
- usbconn_ftdi_flush( params );
-
- return err;
-}
-
-int cable_ftdi_close() {
- usbconn_ftdi_close(ft2232_device);
- usbconn_ftdi_free(ft2232_device);
-
- return APP_ERR_NONE;
-}
-
-int cable_ftdi_flush() {
- ftdi_param_t *params = ft2232_device->params;
- usbconn_ftdi_flush( params );
-
- return APP_ERR_NONE;
-}
-
-int cable_ftdi_write_bit(uint8_t packet) {
- int err = APP_ERR_NONE;
- unsigned char buf;
- int tms;
-
- buf = ((packet & TDO) ? 0x01 : 0x00);
- tms = ((packet & TMS) ? 1 : 0);
-
- if(cable_ft2232_write_stream(ft2232_device, &buf, 1, 0, tms) < 0)
- err |= APP_ERR_COMM;
-
- cable_ftdi_flush();
-
- return err;
-
-}
-
-int cable_ftdi_read_write_bit(uint8_t packet_out, uint8_t *bit_in) {
-
- int err = APP_ERR_NONE;
- unsigned char buf;
- int tms;
-
- buf = ((packet_out & TDO) ? 0x01 : 0x00);
- tms = ((packet_out & TMS) ? 1 : 0);
-
- if(cable_ft2232_write_stream(ft2232_device, &buf, 1, 1, tms) < 0)
- err = APP_ERR_COMM;
-
- if(cable_ft2232_read_stream(ft2232_device, ((unsigned char *)bit_in), 1, tms) < 0)
- err = APP_ERR_COMM;
-
- return err;
-}
-
-int cable_ftdi_write_stream(uint32_t *stream, int len_bits, int set_last_bit) {
- int err = APP_ERR_NONE;
-
- if(cable_ft2232_write_stream(ft2232_device, ((unsigned char *)stream), len_bits, 0, set_last_bit) < 0)
- err |= APP_ERR_COMM;
-
- cable_ftdi_flush();
-
- return err;
-}
-
-int cable_ftdi_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit) {
- int err = APP_ERR_NONE;
- if(cable_ft2232_write_stream(ft2232_device, ((unsigned char *)outstream), len_bits, 1, set_last_bit) < 0)
- err |= APP_ERR_COMM;
- if(cable_ft2232_read_stream(ft2232_device, ((unsigned char *)instream), len_bits, set_last_bit) < 0)
- err |= APP_ERR_COMM;
-
- return err;
-}
-
-int cable_ftdi_opt(int c, char *str) {
- fprintf(stderr, "Unknown parameter '%c'\n", c);
- return APP_ERR_BAD_PARAM;
-}
-
-/// ----------------------------------------------------------------------------------------------
-
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/chain_commands.h
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/chain_commands.h (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/chain_commands.h (nonexistent)
@@ -1,49 +0,0 @@
-#ifndef _CHAIN_COMMANDS_H_
-#define _CHAIN_COMMANDS_H_
-
-#include
-
-// These two are used by both debug modules
-extern int current_chain;
-extern int desired_chain;
-
-// These are needed by the advanced debug module
-extern int global_DR_prefix_bits;
-extern int global_DR_postfix_bits;
-extern unsigned char global_xilinx_bscan;
-
-// Discover devices on JTAG chain
-int jtag_enumerate_chain(uint32_t **id_array, int *num_devices);
-int jtag_get_idcode(uint32_t cmd, uint32_t *idcode);
-
-// Functions to set configuration for the JTAG chain
-void config_set_IR_size(int size);
-void config_set_IR_prefix_bits(int bits);
-void config_set_IR_postfix_bits(int bits);
-void config_set_DR_prefix_bits(int bits);
-void config_set_DR_postfix_bits(int bits);
-void config_set_debug_cmd(unsigned int cmd);
-void config_set_alt_vjtag(unsigned char enable);
-void config_set_vjtag_cmd_vir(unsigned int cmd);
-void config_set_vjtag_cmd_vdr(unsigned int cmd);
-void config_set_xilinx_bscan(unsigned char enable);
-
-// Operations on the JTAG TAP
-int tap_reset(void);
-int tap_enable_debug_module(void);
-int tap_set_ir(int ir);
-int tap_set_shift_dr(void);
-int tap_exit_to_idle(void);
-
-// Functions to Send/receive bitstreams via JTAG
-// These functions are aware of other devices in the chain, and may adjust for them.
-int jtag_write_bit(uint8_t packet);
-int jtag_read_write_bit(uint8_t packet, uint8_t *in_bit);
-int jtag_write_stream(uint32_t *out_data, int length_bits, unsigned char set_TMS);
-int jtag_read_write_stream(uint32_t *out_data, uint32_t *in_data, int length_bits,
- unsigned char adjust, unsigned char set_TMS);
-
-int retry_do(void);
-void retry_ok(void);
-
-#endif
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/rsp-server.c
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/rsp-server.c (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/rsp-server.c (nonexistent)
@@ -1,2968 +0,0 @@
-/* rsp-server.c -- Remote Serial Protocol server for GDB
-
-Copyright (C) 2008 Embecosm Limited
-
-Contributor Jeremy Bennett
-
-This file was part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
-Adapted for adv_jtag_bridge by Nathan Yawn
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3 of the License, or (at your option)
-any later version.
-
-This program 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 General Public License for
-more details.
-
-You should have received a copy of the GNU General Public License along
-with this program. If not, see .
-*/
-
-/* This program is commented throughout in a fashion suitable for processing
- with Doxygen. */
-
-/* System includes */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-/* Package includes */
-#include "except.h"
-#include "spr-defs.h"
-#include "dbg_api.h"
-#include "errcodes.h"
-
-/* Define to log each packet */
-#define RSP_TRACE 0
-
-/*! Name of the RSP service */
-#define OR1KSIM_RSP_SERVICE "jtag-rsp"
-
-/*! Protocol used by Or1ksim */
-#define OR1KSIM_RSP_PROTOCOL "tcp"
-
-/* 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_GRPS + 3) /*!< Total GDB registers */
-
-/*! Trap instruction for OR32 */
-#define OR1K_TRAP_INSTR 0x21000001
-
-/*! Definition of GDB target signals. Data taken from the GDB 6.8
- source. Only those we use defined here. */
-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
-};
-
-/*! 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
-
-/*! String to map hex digits to chars */
-static const char hexchars[]="0123456789abcdef";
-
-/*! 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,
- BP_HARDWARE = 1,
- WP_WRITE = 2,
- WP_READ = 3,
- WP_ACCESS = 4
-};
-
-/*! Data structure for a matchpoint hash table entry */
-struct mp_entry
-{
- enum mp_type type; /*!< Type of matchpoint */
- unsigned long int addr; /*!< Address with the matchpoint */
- unsigned long int instr; /*!< Substituted instruction */
- struct mp_entry *next; /*!< Next entry with this hash */
-};
-
-/* Data to interface the GDB handler thread with the target handler thread */
-pthread_mutex_t rsp_mutex = PTHREAD_MUTEX_INITIALIZER; /*!< Mutex to protect the "target_running" member of the rsp struct */
-pthread_mutex_t target_handler_mutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t target_handler_cond = PTHREAD_COND_INITIALIZER;
-
-int target_handler_state = 0;
-pthread_t target_handler_thread;
-void *target_handler(void *arg);
-
-int pipe_fds[2]; // Descriptors for the pipe from the poller thread to the GDB interface thread
-
-// Work-around for the current OR1200 implementation; After setting the NPC,
-// it always reads back 0 until the next instruction is executed. This
-// is a problem with the way we handle memory breakpoints (resetting the NPC),
-// so we cache the last value we set the NPC to, incase we need it.
-unsigned char use_cached_npc = 0;
-unsigned int cached_npc = 0;
-
-/*! Central data for the RSP connection */
-static struct
-{
- int client_waiting; /*!< Is client waiting a response? */
- int target_running; /*!< Is target hardware running? --NAY */
- int single_step_mode;
- int proto_num; /*!< Number of the protocol used */
- int server_fd; /*!< FD for new connections */
- int client_fd; /*!< FD for talking to GDB */
- int sigval; /*!< GDB signal for any exception */
- unsigned long int start_addr; /*!< Start of last run */
- struct mp_entry *mp_hash[MP_HASH_SIZE]; /*!< Matchpoint hash table */
-} rsp;
-
-/* Forward declarations of static functions */
-void rsp_exception (unsigned long int except);
-static void rsp_server_request ();
-static void rsp_client_request ();
-static void rsp_server_close ();
-static void rsp_client_close ();
-static void put_packet (struct rsp_buf *buf);
-static void put_str_packet (const char *str);
-static struct rsp_buf *get_packet ();
-static void put_rsp_char (char c);
-static int get_rsp_char ();
-static int rsp_unescape (char *data,
- int len);
-static void mp_hash_init ();
-static void mp_hash_add (enum mp_type type,
- unsigned long int addr,
- unsigned long int instr);
-static struct mp_entry *mp_hash_lookup (enum mp_type type,
- unsigned long int addr);
-static struct mp_entry *mp_hash_delete (enum mp_type type,
- unsigned long int addr);
-static int hex (int c);
-static void reg2hex (unsigned long int val,
- char *buf);
-static unsigned long int hex2reg (char *buf);
-static void ascii2hex (char *dest,
- char *src);
-static void hex2ascii (char *dest,
- char *src);
-static unsigned int set_npc (unsigned long int addr);
-static void rsp_report_exception ();
-static void rsp_continue (struct rsp_buf *buf);
-static void rsp_continue_with_signal (struct rsp_buf *buf);
-static void rsp_continue_generic (unsigned long int except);
-static void rsp_read_all_regs ();
-static void rsp_write_all_regs (struct rsp_buf *buf);
-static void rsp_read_mem (struct rsp_buf *buf);
-static void rsp_write_mem (struct rsp_buf *buf);
-static void rsp_read_reg (struct rsp_buf *buf);
-static void rsp_write_reg (struct rsp_buf *buf);
-static void rsp_query (struct rsp_buf *buf);
-static void rsp_command (struct rsp_buf *buf);
-static void rsp_set (struct rsp_buf *buf);
-static void rsp_restart ();
-static void rsp_step (struct rsp_buf *buf);
-static void rsp_step_with_signal (struct rsp_buf *buf);
-static void rsp_step_generic (unsigned long int except);
-static void rsp_vpkt (struct rsp_buf *buf);
-static void rsp_write_mem_bin (struct rsp_buf *buf);
-static void rsp_remove_matchpoint (struct rsp_buf *buf);
-static void rsp_insert_matchpoint (struct rsp_buf *buf);
-
-void set_stall_state(int stall);
-
-/*---------------------------------------------------------------------------*/
-/*!Initialize the Remote Serial Protocol connection
-
- 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. */
-/*---------------------------------------------------------------------------*/
-void
-rsp_init (int portNum)
-{
- struct protoent *protocol; /* Protocol number */
- struct hostent *host_entry; /* Our host entry */
- struct sockaddr_in sock_addr; /* Socket address */
-
- int optval; /* Socket options */
- int flags; /* Socket flags */
- char name[256]; /* Our name */
- unsigned long tmp;
-
-
- /* Clear out the central data structure */
- rsp.client_waiting = 0; /* GDB client is not waiting for us */
- rsp.proto_num = -1; /* i.e. invalid */
- rsp.server_fd = -1; /* i.e. invalid */
- 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 ();
-
- /* Get the protocol number of TCP and save it for future use */
- protocol = getprotobyname (OR1KSIM_RSP_PROTOCOL);
- if (NULL == protocol)
- {
- fprintf (stderr, "Warning: RSP unable to load protocol \"%s\": %s\n",
- OR1KSIM_RSP_PROTOCOL, strerror (errno));
- return;
- }
-
- rsp.proto_num = protocol->p_proto; /* Saved for future client use */
-
- /* 0 is used as the RSP port number to indicate that we should use the
- service name instead. */
- if (0 == portNum)
- {
- struct servent *service =
- getservbyname (OR1KSIM_RSP_SERVICE, protocol->p_name);
-
- if (NULL == service)
- {
- fprintf (stderr, "Warning: RSP unable to find service \"%s\": %s\n",
- OR1KSIM_RSP_SERVICE, strerror (errno));
- return;
- }
-
- portNum = ntohs (service->s_port);
- }
-
- /* Create the socket using the TCP protocol */
- rsp.server_fd = socket (PF_INET, SOCK_STREAM, protocol->p_proto);
- if (rsp.server_fd < 0)
- {
- fprintf (stderr, "Warning: RSP could not create server socket: %s\n",
- strerror (errno));
- return;
- }
-
- /* Set this socket to reuse its address. This allows the server to keep
- trying before a GDB session has got going. */
- optval = 1;
- if (setsockopt(rsp.server_fd, SOL_SOCKET,
- SO_REUSEADDR, &optval, sizeof (optval)) < 0)
- {
- fprintf (stderr, "Cannot set SO_REUSEADDR option on server socket %d: "
- "%s\n", rsp.server_fd, strerror (errno));
- rsp_server_close();
- return;
- }
-
- /* The server should be non-blocking. Get the current flags and then set the
- non-blocking flags */
- flags = fcntl (rsp.server_fd, F_GETFL);
- if (flags < 0)
- {
- fprintf (stderr, "Warning: Unable to get flags for RSP server socket "
- "%d: %s\n", rsp.server_fd, strerror (errno));
- rsp_server_close();
- return;
- }
-
- flags |= O_NONBLOCK;
- if (fcntl (rsp.server_fd, F_SETFL, flags) < 0)
- {
- fprintf (stderr, "Warning: Unable to set flags for RSP server socket "
- "%d to 0x%08x: %s\n", rsp.server_fd, flags, strerror (errno));
- rsp_server_close();
- return;
- }
-
- /* Find out what our name is */
- if (gethostname (name, sizeof (name)) < 0)
- {
- fprintf (stderr, "Warning: Unable to get hostname for RSP server: %s\n",
- strerror (errno));
- rsp_server_close();
- return;
- }
-
- /* Find out what our address is */
- host_entry = gethostbyname (name);
- if (NULL == host_entry)
- {
- fprintf (stderr, "Warning: Unable to get host entry for RSP server: "
- "%s\n", strerror (errno));
- rsp_server_close();
- return;
- }
-
- /* Bind our socket to the appropriate address */
- memset (&sock_addr, 0, sizeof (sock_addr));
- sock_addr.sin_family = host_entry->h_addrtype;
- sock_addr.sin_port = htons (portNum);
-
- if (bind (rsp.server_fd,
- (struct sockaddr *)&sock_addr, sizeof (sock_addr)) < 0)
- {
- fprintf (stderr, "Warning: Unable to bind RSP server socket %d to port "
- "%d: %s\n", rsp.server_fd, portNum,
- strerror (errno));
- rsp_server_close();
- return;
- }
-
- /* Mark us as a passive port, with a maximum backlog of 1 connection (we
- never connect simultaneously to more than one RSP client!) */
- if (listen (rsp.server_fd, 1) < 0)
- {
- fprintf (stderr, "Warning: Unable to set RSP backlog on server socket "
- "%d to %d: %s\n", rsp.server_fd, 1, strerror (errno));
- rsp_server_close();
- return;
- }
-
- // Stall the CPU...it starts off running.
- set_stall_state(1);
- rsp.target_running = 0;
- target_handler_state = 0; // Don't start the polling thread until we have a client
- rsp.single_step_mode = 0;
-
- // Set up the CPU to break to the debug unit on exceptions.
- dbg_cpu0_read(SPR_DSR, &tmp);
- dbg_cpu0_write(SPR_DSR, tmp|SPR_DSR_TE|SPR_DSR_FPE|SPR_DSR_RE|SPR_DSR_IIE|SPR_DSR_AE|SPR_DSR_BUSEE);
-
- // Enable TRAP exception, but don't otherwise change the SR
- dbg_cpu0_read(SPR_SR, &tmp);
- dbg_cpu0_write(SPR_SR, tmp|SPR_SR_SM); // We set 'supervisor mode', which also enables TRAP exceptions
-
- if(0 > pipe(pipe_fds)) { // pipe_fds[0] is for reading, [1] is for writing
- perror("Error creating sockets: ");
- rsp_server_close();
- return;
- }
-
- // Create the harware target polling thread
- if(pthread_create(&target_handler_thread, NULL, target_handler, NULL))
- {
- fprintf(stderr, "Failed to create target handler thread!\n");
- rsp_server_close();
- return;
- }
-
-} /* 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 poll the RSP server for a client requesting to
- join. We can make no progress until the client is available.
-
- Then if the cause is an interrupt, and the interrupt not been notified to
- GDB, a packet reporting the cause of the interrupt is sent.
-
- The function then polls the RSP client port (if open)
- for available input. It then processes the GDB RSP request and return.
-
- If an error occurs when polling the RSP server, other than an interrupt, a
- warning message is printed out and the RSP server and client (if open)
- connections are closed.
-
- If an error occurs when polling the RSP client, other than an interrupt, a
- warning message is printed out and the RSP client connection is closed.
-
- Polling is always blocking (i.e. timeout -1). */
-/*---------------------------------------------------------------------------*/
-int handle_rsp (void)
-{
- struct pollfd fds[2]; /* The FD to poll for */
- char bitbucket;
-
- /* Give up if no RSP server port (this should not occur) */
- if (-1 == rsp.server_fd)
- {
- fprintf (stderr, "Warning: No RSP server port open\n");
- return 0;
- }
-
- /* If we have no RSP client, poll the server until we get one. */
- while (-1 == rsp.client_fd)
- {
- /* Poll for a client on the RSP server socket */
- fds[0].fd = rsp.server_fd; /* FD for the server socket */
- fds[0].events = POLLIN; /* Poll for input activity */
-
- /* Poll is always blocking. We can't do anything more until something
- happens here. */
- switch (poll (fds, 1, -1))
- {
- case -1:
- /* Error. Only one we ignore is an interrupt */
- if (EINTR != errno)
- {
- fprintf (stderr, "Warning: poll for RSP failed: closing "
- "server connection: %s\n", strerror (errno));
- rsp_client_close();
- rsp_server_close();
- return 0;
- }
- break;
-
- case 0:
- /* Timeout. This can't occur! */
- fprintf (stderr, "Warning: Unexpected RSP server poll timeout\n");
- break;
-
- default:
- /* Is the poll due to input available? If we succeed ignore any
- outstanding reports of exceptions. */
- if (POLLIN == (fds[0].revents & POLLIN))
- {
- rsp_server_request ();
- rsp.client_waiting = 0; /* No longer waiting */
- }
- else
- {
- /* Error leads to closing the client and server */
- fprintf (stderr, "Warning: RSP server received flags "
- "0x%08x: closing server connection\n", fds[0].revents);
- rsp_client_close();
- rsp_server_close();
- return 0;
- }
- }
- }
-
-
- /* Poll the RSP client socket for a message from GDB */
- /* Also watch for a message from the hardware poller thread.
- This might be easier if we used ppoll() and sent a Signal, instead
- of using a pipe? */
-
- fds[0].fd = rsp.client_fd; /* FD for the client socket */
- fds[0].events = POLLIN; /* Poll for input activity */
-
- fds[1].fd = pipe_fds[0];
- fds[1].events = POLLIN;
-
- /* Poll is always blocking. We can't do anything more until something
- happens here. */
- //fprintf(stderr, "Polling...\n");
- switch (poll (fds, 2, -1))
- {
- case -1:
- /* Error. Only one we ignore is an interrupt */
- if (EINTR != errno)
- {
- fprintf (stderr, "Warning: poll for RSP failed: closing "
- "server connection: %s\n", strerror (errno));
- rsp_client_close();
- rsp_server_close();
- return 0;
- }
-
- return 1;
-
- case 0:
- /* Timeout. This can't occur! */
- fprintf (stderr, "Warning: Unexpected RSP client poll timeout\n");
- return 1;
-
- default:
- /* Is the client activity due to input available? */
- if (POLLIN == (fds[0].revents & POLLIN))
- {
- rsp_client_request ();
- }
- else if(POLLIN == (fds[1].revents & POLLIN))
- {
- //fprintf(stderr, "Got pipe event from monitor thread\n");
- bitbucket = read(pipe_fds[0], &bitbucket, 1); // Clear the byte out and discard
- /* If we have an unacknowledged exception and a client is available, tell
- GDB. If this exception was a trap due to a memory breakpoint, then
- adjust the NPC. */
- if (rsp.client_waiting)
- {
- // Read the PPC
- unsigned long ppcval;
- dbg_cpu0_read(SPR_PPC, &ppcval);
-
- if ((TARGET_SIGNAL_TRAP == rsp.sigval) &&
- (NULL != mp_hash_lookup (BP_MEMORY, ppcval))) // We also get TRAP from a single-step, don't change npc unless it's really a BP
- {
- set_npc (ppcval);
- }
-
- rsp_report_exception();
- rsp.client_waiting = 0; /* No longer waiting */
- }
- }
- else
- {
- /* Error leads to closing the client, but not the server. */
- fprintf (stderr, "Warning: RSP client received flags "
- "0x%08x: closing client connection\n", fds[0].revents);
- rsp_client_close();
- }
- }
-
- return 1;
-} /* handle_rsp () */
-
-
-//---------------------------------------------------------------------------
-//!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
-//---------------------------------------------------------------------------
-
-void rsp_exception (unsigned long int except)
-{
- int sigval; // GDB signal equivalent to exception
-
- switch (except)
- {
- case SPR_DRR_RSTE: sigval = TARGET_SIGNAL_PWR; break;
- case SPR_DRR_BUSEE: sigval = TARGET_SIGNAL_BUS; break;
- case SPR_DRR_DPFE: sigval = TARGET_SIGNAL_SEGV; break;
- case SPR_DRR_IPFE: sigval = TARGET_SIGNAL_SEGV; break;
- case SPR_DRR_TTE: sigval = TARGET_SIGNAL_ALRM; break;
- case SPR_DRR_AE: sigval = TARGET_SIGNAL_BUS; break;
- case SPR_DRR_IIE: sigval = TARGET_SIGNAL_ILL; break;
- case SPR_DRR_IE: sigval = TARGET_SIGNAL_INT; break;
- case SPR_DRR_DME: sigval = TARGET_SIGNAL_SEGV; break;
- case SPR_DRR_IME: sigval = TARGET_SIGNAL_SEGV; break;
- case SPR_DRR_RE: sigval = TARGET_SIGNAL_FPE; break;
- case SPR_DRR_SCE: sigval = TARGET_SIGNAL_USR2; break;
- case SPR_DRR_FPE: sigval = TARGET_SIGNAL_FPE; break;
- case SPR_DRR_TE: sigval = TARGET_SIGNAL_TRAP; break;
-
- // In the current OR1200 hardware implementation, a single-step does not create a TRAP,
- // the DSR reads back 0. GDB expects a TRAP, so...
- case 0: sigval = TARGET_SIGNAL_TRAP; break;
-
- default:
- fprintf (stderr, "Warning: Unknown RSP exception %lu: 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 ()
-
-
-
-/*---------------------------------------------------------------------------*/
-/*!Handle a request to the server for a new client
-
- We may already have a client. If we do, we will accept an immediately close
- the new client. */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_server_request ()
-{
- struct sockaddr_in sock_addr; /* The socket address */
- socklen_t len; /* Size of the socket address */
- int fd; /* The client FD */
- int flags; /* fcntl () flags */
- int optval; /* Option value for setsockopt () */
-
- /* Get the client FD */
- len = sizeof (sock_addr);
- fd = accept (rsp.server_fd, (struct sockaddr *)&sock_addr, &len);
- if (fd < 0)
- {
- /* This is can happen, because a connection could have started, and then
- terminated due to a protocol error or user initiation before the
- accept could take place.
-
- Two of the errors we can ignore (a retry is permissible). All other
- errors, we assume the server port has gone tits up and close. */
-
- if ((errno != EWOULDBLOCK) && (errno != EAGAIN))
- {
- fprintf (stderr, "Warning: RSP server error creating client: "
- "closing connection %s\n", strerror (errno));
- rsp_client_close ();
- rsp_server_close ();
- }
-
- return;
- }
-
- /* If we already have a client, then immediately close the new one */
- if (-1 != rsp.client_fd)
- {
- fprintf (stderr, "Warning: Additional RSP client request refused\n");
- close (fd);
- return;
- }
-
- /* We have a new client, which should be non-blocking. Get the current flags
- and then set the non-blocking flags */
- flags = fcntl (fd, F_GETFL);
- if (flags < 0)
- {
- fprintf (stderr, "Warning: Unable to get flags for RSP client socket "
- "%d: %s\n", fd, strerror (errno));
- close (fd);
- return;
- }
-
- flags |= O_NONBLOCK;
- if (fcntl (fd, F_SETFL, flags) < 0)
- {
- fprintf (stderr, "Warning: Unable to set flags for RSP client socket "
- "%d to 0x%08x: %s\n", fd, flags, strerror (errno));
- close (fd);
- return;
- }
-
- /* Turn of Nagel's algorithm for the client socket. This means the client
- sends stuff immediately, it doesn't wait to fill up a packet. */
- optval = 0;
- len = sizeof (optval);
- if (setsockopt (fd, rsp.proto_num, TCP_NODELAY, &optval, len) < 0)
- {
- fprintf (stderr, "Warning: Unable to disable Nagel's algorithm for "
- "RSP client socket %d: %s\n", fd, strerror (errno));
- close (fd);
- return;
- }
-
- /* We have a new client socket */
- rsp.client_fd = fd;
-
- // Set the hardware polling thread to run
- // This will cause the poll() to be interrupted next time
- pthread_mutex_lock(&target_handler_mutex);
- target_handler_state = 1;
- pthread_mutex_unlock(&target_handler_mutex);
-
-} /* rsp_server_request () */
-
-
-/*---------------------------------------------------------------------------*/
-/*!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 ()
-{
- struct rsp_buf *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 == buf)
- {
- rsp_client_close ();
- return;
- }
-
-#if RSP_TRACE
- printf ("Packet received %s: %d chars\n", buf->data, buf->len );
- fflush (stdout);
-#endif
-
- // Check if target is running.
- int running = 0;
- pthread_mutex_lock(&rsp_mutex);
- running = rsp.target_running;
- pthread_mutex_unlock(&rsp_mutex);
-
- // If running, only process async BREAK command
- if(running)
- {
- if(buf->data[0] == 0x03) // 0x03 is the ctrl-C "break" command from GDB
- {
- // Send the STALL command to the target
- set_stall_state (1);
- }
- else
- {
- // Send a response to GDB indicating the target is not stalled: "Target not stopped"
- put_str_packet("O6154677274656e20746f73206f74707064650a0d"); // Need to hex-encode warning string (I think...)
- fprintf(stderr, "WARNING: Received GDB command 0x%X (%c) while target running!\n", buf->data[0], buf->data[0]);
- }
- return;
- }
-
- switch (buf->data[0])
- {
- case 0x03:
- fprintf(stderr, "Warning: asynchronous BREAK received while target stopped.\n");
- return;
-
- case '!':
- /* Request for extended remote mode */
- put_str_packet ("OK");
- 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 (buf);
- return;
-
- case 'C':
- /* Continue with signal */
- rsp_continue_with_signal (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 (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 */
- rsp_step (buf);
- return;
-
- case 'I':
- /* Single instruction step with signal */
- rsp_step_with_signal (buf);
- return;
-
- case 'k':
- /* Kill request. Do nothing for now. */
- return;
-
- case 'm':
- /* Read memory (symbolic) */
- rsp_read_mem (buf);
- return;
-
- case 'M':
- /* Write memory (symbolic) */
- rsp_write_mem (buf);
- return;
-
- case 'p':
- /* Read a register */
- rsp_read_reg (buf);
- return;
-
- case 'P':
- /* Write a register */
- rsp_write_reg (buf);
- return;
-
- case 'q':
- /* Any one of a number of query packets */
- rsp_query (buf);
- return;
-
- case 'Q':
- /* Any one of a number of set packets */
- rsp_set (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 (buf);
- return;
-
- case 'S':
- /* Single step (one high level instruction) with signal. This could be
- hard without DWARF2 info */
- rsp_step_with_signal (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 (buf);
- return;
-
- case 'X':
- /* Write memory (binary) */
- rsp_write_mem_bin (buf);
- return;
-
- case 'z':
- /* Remove a breakpoint/watchpoint. */
- rsp_remove_matchpoint (buf);
- return;
-
- case 'Z':
- /* Insert a breakpoint/watchpoint. */
- rsp_insert_matchpoint (buf);
- return;
-
- default:
- /* Unknown commands are ignored */
- fprintf (stderr, "Warning: Unknown RSP request %s\n", buf->data);
- return;
- }
-} /* rsp_client_request () */
-
-
-/*---------------------------------------------------------------------------*/
-/*!Close the server if it is open */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_server_close ()
-{
- // Stop the target handler thread
- pthread_mutex_lock(&target_handler_mutex);
- target_handler_state = 2;
- pthread_mutex_unlock(&target_handler_mutex);
-
- if (-1 != rsp.server_fd)
- {
- close (rsp.server_fd);
- rsp.server_fd = -1;
- }
-} /* rsp_server_close () */
-
-
-/*---------------------------------------------------------------------------*/
-/*!Close the client if it is open */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_client_close ()
-{
- unsigned char was_running = 0;
-
- // If target is running, stop it so we can modify SPRs
- pthread_mutex_lock(&rsp_mutex);
- was_running = rsp.target_running;
- pthread_mutex_unlock(&rsp_mutex);
- if(was_running) {
- set_stall_state(1);
- }
-
- // Clear the DSR: don't transfer control to the debug unit for any reason
- dbg_cpu0_write(SPR_DSR, 0);
-
- // If target was running, restart it.
- if(was_running) {
- set_stall_state(0);
- }
-
- // Stop the target handler thread. MUST BE DONE AFTER THE LAST set_stall_state()!
- pthread_mutex_lock(&target_handler_mutex);
- target_handler_state = 0;
- pthread_mutex_unlock(&target_handler_mutex);
-
- 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] buf The data to send */
-/*---------------------------------------------------------------------------*/
-static void
-put_packet (struct rsp_buf *buf)
-{
- 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 RSP_TRACE
- printf ("Putting %s\n", buf->data);
- fflush (stdout);
-#endif
-
- put_rsp_char ('$'); /* Start char */
-
- /* Body of the packet */
- for (count = 0; count < buf->len; count++)
- {
- unsigned char ch = buf->data[count];
-
- /* Check for escaped chars */
- if (('$' == ch) || ('#' == ch) || ('*' == ch) || ('}' == ch))
- {
- ch ^= 0x20;
- checksum += (unsigned char)'}';
- put_rsp_char ('}');
- }
-
- checksum += ch;
- put_rsp_char (ch);
- }
-
- put_rsp_char ('#'); /* End char */
-
- /* Computed checksum */
- put_rsp_char (hexchars[checksum >> 4]);
- put_rsp_char (hexchars[checksum % 16]);
-
- /* Check for ack of connection failure */
- ch = get_rsp_char ();
- if (-1 == 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 buf;
- 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 (buf.data, str, len);
- buf.data[len] = 0;
- buf.len = len;
-
- put_packet (&buf);
-
-} /* 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 ()
-{
- 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 */
- }
-
- // 0x03 is a special case, an out-of-band break when running
- if(ch == 0x03)
- {
- buf.data[0] = ch;
- buf.len = 1;
- return &buf;
- }
-
- ch = get_rsp_char ();
- }
-
- /* Read until a '#' or end of buffer is found */
- checksum = 0;
- count = 0;
- while (count < GDB_BUF_MAX - 1)
- {
- ch = get_rsp_char ();
-
- /* Check for connection failure */
- if (-1 == 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 (-1 == ch)
- {
- return NULL; /* Connection failed */
- }
- xmitcsum = hex (ch) << 4;
-
- ch = get_rsp_char ();
- if (-1 == 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);
-
- put_rsp_char ('-'); /* Failed checksum */
- }
- else
- {
- put_rsp_char ('+'); /* 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
-put_rsp_char (char c)
-{
- if (-1 == rsp.client_fd)
- {
- fprintf (stderr, "Warning: Attempt to write '%c' to unopened RSP "
- "client: Ignored\n", c);
- return;
- }
-
- /* Write until successful (we retry after interrupts) or catastrophic
- failure. */
- while (1)
- {
- switch (write (rsp.client_fd, &c, sizeof (c)))
- {
- 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 */
- }
- }
-} /* put_rsp_char () */
-
-
-/*---------------------------------------------------------------------------*/
-/*!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 ()
-{
- unsigned char c; /* The character read */
-
- if (-1 == rsp.client_fd)
- {
- fprintf (stderr, "Warning: Attempt to read from unopened RSP "
- "client: Ignored\n");
- return -1;
- }
-
- /* Read until successful (we retry after interrupts) or catastrophic
- failure. */
- while (1)
- {
- switch (read (rsp.client_fd, &c, sizeof (c)))
- {
- case -1:
- /* Error: only allow interrupts or would block */
- 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 () */
-
-
-/*---------------------------------------------------------------------------*/
-/*!"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 ()
-{
- 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,
- unsigned long int addr,
- unsigned long int 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 = 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,
- unsigned long int 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,
- unsigned long int 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] buf The buffer for the text string */
-/*---------------------------------------------------------------------------*/
-static void
-reg2hex (unsigned long int val,
- char *buf)
-{
- int n; /* Counter for digits */
-
- for (n = 0; n < 8; n++)
- {
-#ifdef WORDSBIGENDIAN
- int nyb_shift = n * 4;
-#else
- int nyb_shift = 28 - (n * 4);
-#endif
- buf[n] = hexchars[(val >> nyb_shift) & 0xf];
- }
-
- 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] buf The buffer with the hex string
-
- @return The value to convert */
-/*---------------------------------------------------------------------------*/
-static unsigned long int
-hex2reg (char *buf)
-{
- int n; /* Counter for digits */
- unsigned long int 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 (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 unsigned int set_npc (unsigned long int addr)
-{
- int errcode;
-
- errcode = dbg_cpu0_write(SPR_NPC, addr);
- cached_npc = addr;
- use_cached_npc = 1;
-
- /* This was done in the simulator. Is any of this necessary on the hardware? --NAY
- if (cpu_state.pc != addr)
- {
- cpu_state.pc = addr;
- cpu_state.delay_insn = 0;
- pcnext = addr + 4;
- }
- */
- return errcode;
-} /* set_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 ()
-{
- struct rsp_buf buf;
-
- /* Construct a signal received packet */
- buf.data[0] = 'S';
- buf.data[1] = hexchars[rsp.sigval >> 4];
- buf.data[2] = hexchars[rsp.sigval % 16];
- buf.data[3] = 0;
- buf.len = strlen (buf.data);
-
- put_packet (&buf);
-
-} /* 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] buf The full continue packet */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_continue (struct rsp_buf *buf)
-{
- unsigned long int addr; /* Address to continue from, if any */
-
- if (strncmp(buf->data, "c", 2))
- {
- if(1 != sscanf (buf->data, "c%lx", &addr))
- {
- fprintf (stderr,
- "Warning: RSP continue address %s not recognized: ignored\n",
- buf->data);
- }
- else
- {
- /* Set the address as the value of the next program counter */
- // TODO Is support for this really that simple? --NAY
- set_npc (addr);
- }
- }
-
- rsp_continue_generic (EXCEPT_NONE);
-
-} /* rsp_continue () */
-
-
-/*---------------------------------------------------------------------------*/
-/*!Handle a RSP continue with signal request
-
- Currently null. Will use the underlying generic continue function.
-
- @param[in] buf The full continue with signal packet */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_continue_with_signal (struct rsp_buf *buf)
-{
- printf ("RSP continue with signal '%s' received\n", 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 (unsigned long int except)
-{
- unsigned long tmp;
-
- /* Clear Debug Reason Register and watchpoint break generation in Debug Mode
- Register 2 */
- dbg_cpu0_write(SPR_DRR, 0);
- dbg_cpu0_read(SPR_DMR2, &tmp);
- tmp &= ~SPR_DMR2_WGB;
- dbg_cpu0_write(SPR_DMR2, tmp);
-
- /* Clear the single step trigger in Debug Mode Register 1 and set traps to be
- handled by the debug unit in the Debug Stop Register */
- dbg_cpu0_read(SPR_DMR1, &tmp);
- tmp &= ~(SPR_DMR1_ST|SPR_DMR1_BT); // clear single-step and trap-on-branch
- dbg_cpu0_write(SPR_DMR1, tmp);
-
- // *** TODO Is there ever a situation where the DSR will not be set to give us control on a TRAP? --NAY
-
- /* Unstall the processor (also starts the target handler thread) */
- set_stall_state (0);
-
- /* Note the GDB client is now waiting for a reply. */
- rsp.client_waiting = 1;
- rsp.single_step_mode = 0;
-
-} /* 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 ()
-{
- struct rsp_buf buf; /* Buffer for the reply */
- int r; /* Register index */
- unsigned long regbuf[MAX_GPRS];
- unsigned int errcode = APP_ERR_NONE;
-
- // Read all the GPRs in a single burst, for efficiency
- errcode = dbg_cpu0_read_block(SPR_GPR_BASE, regbuf, MAX_GPRS);
-
- /* Format the GPR data for output */
- for (r = 0; r < MAX_GPRS; r++)
- {
- reg2hex(regbuf[r], &(buf.data[r * 8]));
- }
-
- /* PPC, NPC and SR have consecutive addresses, read in one burst */
- errcode |= dbg_cpu0_read_block(SPR_NPC, regbuf, 3);
-
- // Note that reg2hex adds a NULL terminator; as such, they must be
- // put in buf.data in numerical order: PPC, NPC, SR
- reg2hex(regbuf[2], &(buf.data[PPC_REGNUM * 8]));
-
- if(use_cached_npc == 1) { // Hackery to work around CPU hardware quirk
- reg2hex(cached_npc, &(buf.data[NPC_REGNUM * 8]));
- }
- else {
- reg2hex(regbuf[0], &(buf.data[NPC_REGNUM * 8]));
- }
-
- reg2hex(regbuf[1], &(buf.data[SR_REGNUM * 8]));
-
- //fprintf(stderr, "Read SPRs: 0x%08X, 0x%08X, 0x%08X\n", regbuf[0], regbuf[1], regbuf[2]);
-
- /*
- dbg_cpu0_read(SPR_PPC, &tmp);
- reg2hex(tmp, &(buf.data[PPC_REGNUM * 8]));
-
- if(use_cached_npc == 1) { // Hackery to work around CPU hardware quirk
- tmp = cached_npc;
- }
- else {
- dbg_cpu0_read(SPR_NPC, &tmp);
- }
- reg2hex(tmp, &(buf.data[NPC_REGNUM * 8]));
-
- dbg_cpu0_read(SPR_SR, &tmp);
- reg2hex(tmp, &(buf.data[SR_REGNUM * 8]));
- */
-
- if(errcode == APP_ERR_NONE) {
- /* Finalize the packet and send it */
- buf.data[NUM_REGS * 8] = 0;
- buf.len = NUM_REGS * 8;
- put_packet (&buf);
- }
- else {
- fprintf(stderr, "Error while reading all registers: %s\n", get_err_string(errcode));
- put_str_packet("E01");
- }
-
-} /* 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] buf The original packet request. */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_write_all_regs (struct rsp_buf *buf)
-{
- int r; /* Register index */
- unsigned long regbuf[MAX_GPRS];
- unsigned int errcode;
-
- /* The GPRs */
- for (r = 0; r < MAX_GPRS; r++)
- {
- // Set up the data for a burst access
- regbuf[r] = hex2reg (&(buf->data[r * 8]));
- }
-
- errcode = dbg_cpu0_write_block(SPR_GPR_BASE, regbuf, MAX_GPRS);
-
- /* PPC, NPC and SR */
- regbuf[0] = hex2reg (&(buf->data[NPC_REGNUM * 8]));
- regbuf[1] = hex2reg (&(buf->data[SR_REGNUM * 8]));
- regbuf[2] = hex2reg (&(buf->data[PPC_REGNUM * 8]));
-
- errcode |= dbg_cpu0_write_block(SPR_NPC, regbuf, 3);
-
- /*
- tmp = hex2reg (&(buf->data[PPC_REGNUM * 8]));
- dbg_cpu0_write(SPR_PPC, tmp);
-
- tmp = hex2reg (&(buf->data[SR_REGNUM * 8]));
- dbg_cpu0_write(SPR_SR, tmp);
-
- tmp = hex2reg (&(buf->data[NPC_REGNUM * 8]));
- dbg_cpu0_write(SPR_NPC, tmp);
- */
-
- if(errcode == APP_ERR_NONE)
- put_str_packet ("OK");
- else {
- fprintf(stderr, "Error while writing all registers: %s\n", get_err_string(errcode));
- put_str_packet("E01");
- }
-
-} /* 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 buf, so trashes the original command.
-
- @param[in] buf The command received */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_read_mem (struct rsp_buf *buf)
-{
- unsigned int addr; /* Where to read the memory */
- int len; /* Number of bytes to read */
- int off; /* Offset into the memory */
- unsigned int errcode = APP_ERR_NONE;
-
- if (2 != sscanf (buf->data, "m%x,%x:", &addr, &len))
- {
- fprintf (stderr, "Warning: Failed to recognize RSP read memory "
- "command: %s\n", 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", buf->data);
- len = (GDB_BUF_MAX - 1) / 2;
- }
-
- // Do the memory read into a temporary buffer
- unsigned char *tmpbuf = (unsigned char *) malloc(len); // *** TODO check return, don't always malloc (use realloc)
- errcode = dbg_wb_read_block8(addr, tmpbuf, len);
-
-
- /* Refill the buffer with the reply */
- for (off = 0; off < len; off++)
- {
- unsigned char ch; /* The byte at the address */
-
- /* Check memory area is valid. Not really possible without knowing hardware configuration. */
-
- // Get the memory direct - no translation.
- ch = tmpbuf[off];
- buf->data[off * 2] = hexchars[ch >> 4];
- buf->data[off * 2 + 1] = hexchars[ch & 0xf];
- }
-
- free(tmpbuf);
-
- if(errcode == APP_ERR_NONE) {
- buf->data[off * 2] = 0; /* End of string */
- buf->len = strlen (buf->data);
- put_packet (buf);
- }
- else {
- fprintf(stderr, "Error reading memory: %s\n", get_err_string(errcode));
- put_str_packet("E01");
- }
-
-} /* rsp_read_mem () */
-
-
-/*---------------------------------------------------------------------------*/
-/*!Handle a RSP write memory (symbolic) request
-
- Syntax is:
-
- m,:
-
- 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 buf, so trashes the original command.
-
- @param[in] buf The command received */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_write_mem (struct rsp_buf *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 */
- unsigned int errcode;
-
- if (2 != sscanf (buf->data, "M%x,%x:", &addr, &len))
- {
- fprintf (stderr, "Warning: Failed to recognize RSP write memory "
- "command: %s\n", buf->data);
- put_str_packet ("E01");
- return;
- }
-
- /* Find the start of the data and check there is the amount we expect. */
- symdat = memchr ((const void *)buf->data, ':', GDB_BUF_MAX) + 1;
- datlen = buf->len - (symdat - 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;
- }
-
- /* Write the bytes to memory */
- // Put all the data into a single buffer, so it can be burst-written via JTAG.
- // One burst is much faster than many single-byte transactions.
- unsigned char *tmpbuf = (unsigned char *) malloc(len);
- for (off = 0; off < len; off++)
- {
- unsigned char nyb1 = hex (symdat[off * 2]);
- unsigned char nyb2 = hex (symdat[off * 2 + 1]);
- tmpbuf[off] = (nyb1 << 4) | nyb2;
- }
-
- errcode = dbg_wb_write_block8(addr, tmpbuf, len);
- free(tmpbuf);
-
- /* Can't really check if the memory addresses are valid on hardware. */
- if(errcode == APP_ERR_NONE) {
- put_str_packet ("OK");
- }
- else {
- fprintf(stderr, "Error writing memory: %s\n", get_err_string(errcode));
- put_str_packet("E01");
- }
-
-} /* 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] buf The original packet request. Reused for the reply. */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_read_reg (struct rsp_buf *buf)
-{
- unsigned int regnum;
- unsigned long tmp;
- unsigned int errcode = APP_ERR_NONE;
-
- /* Break out the fields from the data */
- if (1 != sscanf (buf->data, "p%x", ®num))
- {
- fprintf (stderr, "Warning: Failed to recognize RSP read register "
- "command: \'%s\'\n", buf->data);
- put_str_packet ("E01");
- return;
- }
-
- /* Get the relevant register */
- if (regnum < MAX_GPRS)
- {
- errcode = dbg_cpu0_read(SPR_GPR_BASE+regnum, &tmp);
- }
- else if (PPC_REGNUM == regnum)
- {
- errcode = dbg_cpu0_read(SPR_PPC, &tmp);
- }
- else if (NPC_REGNUM == regnum)
- {
- if(use_cached_npc) {
- tmp = cached_npc;
- } else {
- errcode = dbg_cpu0_read(SPR_NPC, &tmp);
- }
- }
- else if (SR_REGNUM == regnum)
- {
- errcode = dbg_cpu0_read(SPR_SR, &tmp);
- }
- 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;
- }
-
- if(errcode == APP_ERR_NONE) {
- reg2hex(tmp, buf->data);
- buf->len = strlen (buf->data);
- put_packet (buf);
- }
- else {
- fprintf(stderr, "Error reading register: %s\n", get_err_string(errcode));
- put_str_packet("E01");
- }
-
-} /* 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] buf The original packet request. */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_write_reg (struct rsp_buf *buf)
-{
- unsigned int regnum;
- char valstr[9]; /* Allow for EOS on the string */
- unsigned int errcode = APP_ERR_NONE;
-
- /* Break out the fields from the data */
- if (2 != sscanf (buf->data, "P%x=%8s", ®num, valstr))
- {
- fprintf (stderr, "Warning: Failed to recognize RSP write register "
- "command: %s\n", buf->data);
- put_str_packet ("E01");
- return;
- }
-
- /* Set the relevant register. Must translate between GDB register numbering and hardware reg. numbers. */
- if (regnum < MAX_GPRS)
- {
- errcode = dbg_cpu0_write(SPR_GPR_BASE+regnum, hex2reg(valstr));
- }
- else if (PPC_REGNUM == regnum)
- {
- errcode = dbg_cpu0_write(SPR_PPC, hex2reg(valstr));
- }
- else if (NPC_REGNUM == regnum)
- {
- errcode = set_npc (hex2reg (valstr));
- }
- else if (SR_REGNUM == regnum)
- {
- errcode = dbg_cpu0_write(SPR_SR, hex2reg(valstr));
- }
- 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;
- }
-
- if(errcode == APP_ERR_NONE) {
- put_str_packet ("OK");
- }
- else {
- fprintf(stderr, "Error writing register: %s\n", get_err_string(errcode));
- put_str_packet("E01");
- }
-
-} /* rsp_write_reg () */
-
-
-/*---------------------------------------------------------------------------*/
-/*!Handle a RSP query request
-
- @param[in] buf The request */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_query (struct rsp_buf *buf)
-{
- if (0 == strcmp ("qC", 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", 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", buf->data))
- {
- /* Return info about active threads. We return just '-1' */
- put_str_packet ("m-1");
- }
- else if (0 == strcmp ("qsThreadInfo", 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:", buf->data, strlen ("qGetTLSAddr:")))
- {
- /* We don't support this feature */
- put_str_packet ("");
- }
- else if (0 == strncmp ("qL", 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", buf->data))
- {
- /* Report any relocation */
- put_str_packet ("Text=0;Data=0;Bss=0");
- }
- else if (0 == strncmp ("qP", 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,", buf->data, strlen ("qRcmd,")))
- {
- /* This is used to interface to commands to do "stuff" */
- rsp_command (buf);
- }
- else if (0 == strncmp ("qSupported", 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. */
-
- char reply[GDB_BUF_MAX];
-
- sprintf (reply, "PacketSize=%x", GDB_BUF_MAX);
- put_str_packet (reply);
- }
- else if (0 == strncmp ("qSymbol:", 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,", 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 (buf->data, "%02x%02x%02x%02x%02x%02x%02x%02x%02x",
- 'R', 'u', 'n', 'n', 'a', 'b', 'l', 'e', 0);
- buf->len = strlen (buf->data);
- put_packet (buf);
- }
- else if (0 == strncmp ("qXfer:", 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] buf The request in full */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_command (struct rsp_buf *buf)
-{
- char cmd[GDB_BUF_MAX];
- unsigned long tmp;
-
- hex2ascii (cmd, &(buf->data[strlen ("qRcmd,")]));
-
- /* Work out which command it is */
- if (0 == strncmp ("readspr ", cmd, strlen ("readspr")))
- {
- unsigned int regno;
-
- /* 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 */
- dbg_cpu0_read(regno, &tmp); // TODO Check return value of all hardware accesses
- sprintf (cmd, "%8lx", tmp);
- ascii2hex (buf->data, cmd);
- buf->len = strlen (buf->data);
- put_packet (buf);
- }
- else if (0 == strncmp ("writespr ", cmd, strlen ("writespr")))
- {
- unsigned int regno;
- unsigned long int val;
-
- /* Parse and return error if we fail */
- if( 2 != sscanf (cmd, "writespr %4x %8lx", ®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;
- }
-
- /* Update the SPR and reply "OK" */
- dbg_cpu0_write(regno, val);
- put_str_packet ("OK");
- }
-
-} /* rsp_command () */
-
-
-/*---------------------------------------------------------------------------*/
-/*!Handle a RSP set request
-
- @param[in] buf The request */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_set (struct rsp_buf *buf)
-{
- if (0 == strncmp ("QPassSignals:", buf->data, strlen ("QPassSignals:")))
- {
- /* Passing signals not supported */
- put_str_packet ("");
- }
- else if ((0 == strncmp ("QTDP", buf->data, strlen ("QTDP"))) ||
- (0 == strncmp ("QFrame", buf->data, strlen ("QFrame"))) ||
- (0 == strcmp ("QTStart", buf->data)) ||
- (0 == strcmp ("QTStop", buf->data)) ||
- (0 == strcmp ("QTinit", buf->data)) ||
- (0 == strncmp ("QTro", 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. */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_restart ()
-{
- set_npc (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] buf The full step packet */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_step (struct rsp_buf *buf)
-{
- unsigned long int addr; /* The address to step from, if any */
-
- if(strncmp(buf->data, "s", 2))
- {
- if(1 != sscanf (buf->data, "s%lx", &addr))
- {
- fprintf (stderr,
- "Warning: RSP step address %s not recognized: ignored\n",
- buf->data);
- }
- else
- {
- /* Set the address as the value of the next program counter */
- // TODO Is implementing this really just this simple?
- //set_npc (addr);
- }
- }
-
- rsp_step_generic (EXCEPT_NONE);
-
-} /* rsp_step () */
-
-
-/*---------------------------------------------------------------------------*/
-/*!Handle a RSP step with signal request
-
- Currently null. Will use the underlying generic step function.
-
- @param[in] buf The full step with signal packet */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_step_with_signal (struct rsp_buf *buf)
-{
- int val;
- printf ("RSP step with signal '%s' received\n", buf->data);
- val = strtoul(&buf->data[1], NULL, 10);
- rsp_step_generic(val);
-} /* 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 (unsigned long int except)
-{
- unsigned long tmp;
-
- /* Clear Debug Reason Register and watchpoint break generation in Debug Mode
- Register 2 */
- tmp = 0;
- dbg_cpu0_write(SPR_DRR, tmp); // *** TODO Check return value of all hardware accesses
- dbg_cpu0_read(SPR_DMR2, &tmp);
- if(tmp & SPR_DMR2_WGB) {
- tmp &= ~SPR_DMR2_WGB;
- dbg_cpu0_write(SPR_DMR2, tmp);
- }
-
- /* Set the single step trigger in Debug Mode Register 1 and set traps to be
- handled by the debug unit in the Debug Stop Register */
- if(!rsp.single_step_mode)
- {
- dbg_cpu0_read(SPR_DMR1, &tmp);
- tmp |= SPR_DMR1_ST|SPR_DMR1_BT;
- dbg_cpu0_write(SPR_DMR1, tmp);
- dbg_cpu0_read(SPR_DSR, &tmp);
- if(!(tmp & SPR_DSR_TE)) {
- tmp |= SPR_DSR_TE;
- dbg_cpu0_write(SPR_DSR, tmp);
- }
- rsp.single_step_mode = 1;
- }
-
- /* 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] buf The request */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_vpkt (struct rsp_buf *buf)
-{
- if (0 == strncmp ("vAttach;", 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?", buf->data))
- {
- /* For now we don't support this. */
- put_str_packet ("");
- return;
- }
- else if (0 == strncmp ("vCont", 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:", 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:", 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:", 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", 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;", buf->data, strlen ("vRun;")))
- {
- /* We shouldn't be given any args, but check for this */
- if (buf->len > 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",
- 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] buf The command received */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_write_mem_bin (struct rsp_buf *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; /* Offset to start of binary data */
- int newlen; /* Number of bytes in bin data */
- unsigned int errcode;
-
- if (2 != sscanf (buf->data, "X%x,%x:", &addr, &len))
- {
- fprintf (stderr, "Warning: Failed to recognize RSP write memory "
- "command: %s\n", buf->data);
- put_str_packet ("E01");
- return;
- }
-
- /* Find the start of the data and "unescape" it */
- bindat = memchr ((const void *)buf->data, ':', GDB_BUF_MAX) + 1;
- off = bindat - buf->data;
- newlen = rsp_unescape (bindat, 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;
- }
-
- /* Write the bytes to memory */
- errcode = dbg_wb_write_block8(addr, (uint8_t *) bindat, len);
-
- // We can't really verify if the memory target address exists or not.
- // Don't write to non-existant memory unless your system wishbone implementation
- // has a hardware bus timeout.
- if(errcode == APP_ERR_NONE) {
- put_str_packet ("OK");
- }
- else {
- fprintf(stderr, "Error writing memory: %s\n", get_err_string(errcode));
- put_str_packet("E01");
- }
-
-} /* 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] buf The command received */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_remove_matchpoint (struct rsp_buf *buf)
-{
- enum mp_type type; /* What sort of matchpoint */
- unsigned long int addr; /* Address specified */
- int len; /* Matchpoint length (not used) */
- struct mp_entry *mpe; /* Info about the replaced instr */
- unsigned long instbuf[1];
-
- /* Break out the instruction */
- if (3 != sscanf (buf->data, "z%1d,%lx,%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)
- {
- instbuf[0] = mpe->instr;
- dbg_wb_write_block32(addr, instbuf, 1); // *** TODO Check return value
- 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] buf The command received */
-/*---------------------------------------------------------------------------*/
-static void
-rsp_insert_matchpoint (struct rsp_buf *buf)
-{
- enum mp_type type; /* What sort of matchpoint */
- unsigned long int addr; /* Address specified */
- int len; /* Matchpoint length (not used) */
- unsigned long instbuf[1];
-
- /* Break out the instruction */
- if (3 != sscanf (buf->data, "Z%1d,%lx,%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:
- /* Memory breakpoint - substitute a TRAP instruction */
- dbg_wb_read_block32(addr, instbuf, 1); // Get the old instruction. *** TODO Check return value
- mp_hash_add (type, addr, instbuf[0]);
- instbuf[0] = OR1K_TRAP_INSTR; // Set the TRAP instruction
- dbg_wb_write_block32(addr, instbuf, 1); // *** TODO Check return value
- 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_insert_matchpoint () */
-
-
-// Additions from this point on were added solely to handle hardware,
-// and did not come from simulator interface code.
-///////////////////////////////////////////////////////////////////////////
-//
-// Thread to poll for break on remote processor.
-///////////////////////////////////////////////////////////////////////////
-
-void *target_handler(void *arg)
-{
- unsigned char target_status = 0;
- int retval = APP_ERR_NONE;
- char string[] = "a"; // We send this through the pipe. Content is unimportant.
- unsigned int local_state = 0;
-
- while(1)
- {
- // Block on condition for GO or DETACH signal
- pthread_mutex_lock(&target_handler_mutex);
- if(target_handler_state == 0)
- {
- pthread_cond_wait(&target_handler_cond, &target_handler_mutex);
- }
-
- // if detach, exit thread
- if(target_handler_state == 2) // 2 = DETACH
- {
- target_handler_state = 0;
- pthread_mutex_unlock(&target_handler_mutex);
- return arg;
- }
-
- local_state = target_handler_state;
- pthread_mutex_unlock(&target_handler_mutex);
-
-
-
- if(local_state == 1) // Then start target polling loop, but keep checking for DETACH. State 1 == GO
- {
- while(1)
- {
- // non-blocking check for DETACH signal
- pthread_mutex_lock(&target_handler_mutex);
- if(target_handler_state == 2) // state 2 == DETACH
- {
- pthread_mutex_unlock(&target_handler_mutex);
- return arg;
- }
- pthread_mutex_unlock(&target_handler_mutex);
-
- // Poll target hardware
- retval = dbg_cpu0_read_ctrl(0, &target_status);
- if(retval != APP_ERR_NONE)
- fprintf(stderr, "ERROR 0x%X while polling target CPU status\n", retval);
- else {
- if(target_status & 0x01) // Did we get the stall bit? Bit 0 is STALL bit.
- {
- // clear the RUNNING flag
- pthread_mutex_lock(&rsp_mutex);
- rsp.target_running = 0;
- pthread_mutex_unlock(&rsp_mutex);
-
- // Log the exception so it can be sent back to GDB
- unsigned long drrval;
- dbg_cpu0_read(SPR_DRR, &drrval); // Read the DRR, find out why we stopped
- rsp_exception(drrval); // Send it to be translated and stored
-
- // Send message to GDB handler thread via socket (so it can break out of its poll())
- int ret = write(pipe_fds[1], string, 1);
- if(!ret) {
- fprintf(stderr, "Warning: target monitor write() to pipe returned 0\n");
- }
- else if(ret < 0) {
- perror("Error in target monitor write to pipe: ");
- }
-
- // Set our own state back to STOP
- pthread_mutex_lock(&target_handler_mutex);
- target_handler_state = 0;
- pthread_mutex_unlock(&target_handler_mutex);
-
- break; // Stop polling, block on the next GO/DETACH
- }
- }
-
- usleep(250000); // wait 1/4 second before polling again.
- }
- }
-
- else
- {
- fprintf(stderr, "Unknown command 0x%X received by target handler thread\n", local_state);
- pthread_mutex_lock(&target_handler_mutex); // Set our own state back to STOP
- target_handler_state = 0;
- pthread_mutex_unlock(&target_handler_mutex);
- }
- }
-
- return arg;
-}
-
-
-
-
-void set_stall_state(int stall)
-{
- int retval = 0;
- unsigned char data = (stall>0)? 1:0;
- unsigned char stalled = 0;
-
- // Set the 'running' variable, if necessary. Do this before actually starting the CPU.
- // The 'running' variable prevents us from responding to most GDB requests while the
- // CPU is running.
- // We don't ever set the 'running' bit to 0 here. Instead, we stall the CPU hardware, and let
- // the target handler thread detect the stall, then signal us to send a message up to
- // GDB and clear the 'running' bit.
- if(stall == 0)
- {
- use_cached_npc = 0;
- pthread_mutex_lock(&rsp_mutex);
- rsp.target_running = 1;
- pthread_mutex_unlock(&rsp_mutex);
- }
-
- // Actually start or stop the CPU hardware
- retval = dbg_cpu0_write_ctrl(0, data); // 0x01 is the STALL command bit
- if(retval != APP_ERR_NONE)
- fprintf(stderr, "ERROR 0x%X sending async STALL to target.\n", retval);
-
- dbg_cpu0_read_ctrl(0, &stalled);
- /*
- if (!(stalled & 0x1)) {
- printf("or1k is not stalled!\n");
- }
-
- fprintf(stderr, "Set STALL to %i\n", data);
- */
-
- // Wake up the target handler thread to poll for a new STALL
- if(stall == 0)
- {
- pthread_mutex_lock(&target_handler_mutex);
- target_handler_state = 1;
- pthread_cond_signal(&target_handler_cond);
- pthread_mutex_unlock(&target_handler_mutex);
- }
-
- return;
-}
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/README
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/README (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/README (nonexistent)
@@ -1,54 +0,0 @@
-These are the notes for building the Advanced JTAG Bridge program.
-Nathan Yawn, nathan.yawn@opencores.org
-
-BUILDING
-
-This program doesn't use automake. It has been developed using the cygwin
-environment under winXP, and should also compile under various GNU/Linux
-distributions. It has been tested and in known to work with Ubuntu 9.04.
-There are two sets of build flags defined in the Makefile,
-one for cygwin and one for Linux - one set is used, one is commented out.
-Edit the Makefile for your system, type "make," and see what happens...
-
-The program may be built with support for the Advanced Debug Interface
-(the default), or the legacy "debug_if" interface. To compile for the
-legacy interface, __LEGACY__ should be added to CFLAGS in the Makefile
-(the line is present but commented out by default). Note that support
-for the two different debug hardware units is mutually exclusive; both
-cannot be supported in the same build.
-
-DEPENDENCIES
-
-Adv_jtag_bridge has three dependencies:
-
-- The pthreads library (probably already installed)
-- Cygwin only: libioperm (for parallel port device access permissions)
-- libusb
-
-Since adv_jtag_bridge was written, a newer version of libusb has been
-released (1.0), which used a different interface. We still use the old
-interface (0.1), so be sure you install the "compatibility layer" if you
-install the latest libusb. As of December 2008, libUSB-Win32 still used
-v0.1, so cygwin users may not need to install any additional compatibility
-layer.
-
-BUGS
-
-GDB 6.8 has a bug which prevents it from working when no stack frame is
-present (such as at start-up on a bare-metal debugger, such as this one).
-A simple patch applied to GDB 6.8 will work around the problem (a general
-solution is not yet available). This patch can be found in the source
-directory of adv_jtag_bridge as "gdb-6.8-bz436037-reg-no-longer-active.patch".
-
-LICENSE
-
-This code is based on "jp2", which was distributed under the GNU Public
-License, version 2. Adv_jtag_bridge is therefore also distributed under
-this license.
-
-WARRANTY
-
-This program 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 General Public License for
-more details.
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_dbg_commands.h
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_dbg_commands.h (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/adv_dbg_commands.h (nonexistent)
@@ -1,73 +0,0 @@
-
-#ifndef _ADV_DBG_COMMANDS_H_
-#define _ADV_DBG_COMMANDS_H_
-
-
-// Definitions for the top-level debug unit. This really just consists
-// of a single register, used to select the active debug module ("chain").
-#define DBG_MODULE_SELECT_REG_SIZE 2
-#define DBG_MAX_MODULES 4 // used to size an array
-
-#define DC_WISHBONE 0
-#define DC_CPU0 1
-#define DC_CPU1 2
-
-// Polynomial for the CRC calculation
-// Yes, it's backwards. Yes, this is on purpose.
-// The hardware is designed this way to save on logic and routing,
-// and it's really all the same to us here.
-#define ADBG_CRC_POLY 0xedb88320
-
-// These are for the internal registers in the Wishbone module
-// The first is the length of the index register,
-// the indexes of the various registers are defined after that
-#define DBG_WB_REG_SEL_LEN 1
-#define DBG_WB_REG_ERROR 0
-
-// Opcode definitions for the Wishbone module
-#define DBG_WB_OPCODE_LEN 4
-#define DBG_WB_CMD_NOP 0x0
-#define DBG_WB_CMD_BWRITE8 0x1
-#define DBG_WB_CMD_BWRITE16 0x2
-#define DBG_WB_CMD_BWRITE32 0x3
-#define DBG_WB_CMD_BREAD8 0x5
-#define DBG_WB_CMD_BREAD16 0x6
-#define DBG_WB_CMD_BREAD32 0x7
-#define DBG_WB_CMD_IREG_WR 0x9 // This is both a select and a write
-#define DBG_WB_CMD_IREG_SEL 0xd // There is no 'read', the current register is always read. Use a NOP to read.
-
-
-// Internal register definitions for the CPU0 module
-#define DBG_CPU0_REG_SEL_LEN 1
-#define DBG_CPU0_REG_STATUS 0
-
-// Opcode definitions for the first CPU module
-#define DBG_CPU0_OPCODE_LEN 4
-#define DBG_CPU0_CMD_NOP 0x0
-#define DBG_CPU0_CMD_BWRITE32 0x3
-#define DBG_CPU0_CMD_BREAD32 0x7
-#define DBG_CPU0_CMD_IREG_WR 0x9 // This is both a select and a write
-#define DBG_CPU0_CMD_IREG_SEL 0xd // There is no 'read', the current register is always read. Use a NOP to read.
-
-// Internal register definitions for the CPU1 module
-#define DBG_CPU1_REG_SEL_LEN 1
-#define DBG_CPU1_REG_STATUS 0
-
-// Opcode definitions for the second CPU module
-#define DBG_CPU1_OPCODE_LEN 4
-#define DBG_CPU1_CMD_NOP 0x0
-#define DBG_CPU1_CMD_BWRITE32 0x3
-#define DBG_CPU1_CMD_BREAD32 0x7
-#define DBG_CPU1_CMD_IREG_WR 0x9 // This is both a select and a write
-#define DBG_CPU1_CMD_IREG_SEL 0xd // There is no 'read', the current register is always read. Use a NOP to read.
-
-// API to do transactions on the advanced debug interface
-int adbg_select_module(int chain);
-int adbg_select_ctrl_reg(unsigned long regidx);
-int adbg_ctrl_write(unsigned long regidx, uint32_t *cmd_data, int length_bits);
-int adbg_ctrl_read(unsigned long regidx, uint32_t *data, int databits);
-int adbg_burst_command(unsigned int opcode, unsigned long address, int length_words);
-int adbg_wb_burst_read(int word_size_bytes, int word_count, unsigned long start_address, void *data);
-int adbg_wb_burst_write(void *data, int word_size_bytes, int word_count, unsigned long start_address);
-
-#endif
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_ft2232.h
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_ft2232.h (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_ft2232.h (nonexistent)
@@ -1,107 +0,0 @@
-
-#ifndef _CABLE_FT2232_H_
-#define _CABLE_FT2232_H_
-
-#define debug(...) //fprintf(stderr, __VA_ARGS__ )
-#ifndef min
-#define min(X,Y) ((X) < (Y) ? (X) : (Y))
-#endif
-
-#define FTDX_MAXSEND 4096
-#define FTDX_MAXSEND_MPSSE (64 * 1024)
-#define FTDI_MAXRECV ( 4 * 64)
-
-#define BIT_CABLEID2_TCK 0 /* ADBUS0 */
-#define BIT_CABLEID2_TDIDO 1 /* ADBUS1 */
-#define BIT_CABLEID2_TDODI 2 /* ADBUS2 */
-#define BIT_CABLEID2_TMS 3 /* ADBUS3 */
-#define BITMASK_CABLEID2_TCK (1 << BIT_CABLEID2_TCK)
-#define BITMASK_CABLEID2_TDIDO (1 << BIT_CABLEID2_TDIDO)
-#define BITMASK_CABLEID2_TDODI (1 << BIT_CABLEID2_TDODI)
-#define BITMASK_CABLEID2_TMS (1 << BIT_CABLEID2_TMS)
-
-#define BIT_CABLEID2_OE 1 /* ACBUS1 */
-#define BIT_CABLEID2_RXLED 2 /* ACBUS2 */
-#define BIT_CABLEID2_TXLED 3 /* ACBUS3 */
-#define BITMASK_CABLEID2_OE (1 << BIT_CABLEID2_OE)
-#define BITMASK_CABLEID2_RXLED (1 << BIT_CABLEID2_RXLED)
-#define BITMASK_CABLEID2_TXLED (1 << BIT_CABLEID2_TXLED)
-
-typedef struct usbconn_t usbconn_t;
-
-typedef struct {
- char *name;
- char *desc;
- char *driver;
- int32_t vid;
- int32_t pid;
-} usbconn_cable_t;
-
-typedef struct {
- const char *type;
- usbconn_t *(*connect)( const char **, int, usbconn_cable_t *);
- void (*free)( usbconn_t * );
- int (*open)( usbconn_t * );
- int (*close)( usbconn_t * );
- int (*read)( usbconn_t *, uint8_t *, int );
- int (*write)( usbconn_t *, uint8_t *, int, int );
-} usbconn_driver_t;
-
-struct usbconn_t {
- usbconn_driver_t *driver;
- void *params;
- usbconn_cable_t *cable;
-};
-
-typedef struct {
- /* USB device information */
- unsigned int vid;
- unsigned int pid;
- struct ftdi_context *ftdic;
- char *serial;
- /* send and receive buffer handling */
- uint32_t send_buf_len;
- uint32_t send_buffered;
- uint8_t *send_buf;
- uint32_t recv_buf_len;
- uint32_t to_recv;
- uint32_t recv_write_idx;
- uint32_t recv_read_idx;
- uint8_t *recv_buf;
-} ftdi_param_t;
-
-
-usbconn_t * usbconn_ftdi_connect();
-int my_ftdi_write_data(struct ftdi_context *ftdi, unsigned char *buf, int size);
-char *my_ftdi_get_error_string (struct ftdi_context *ftdi);
-int my_ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size);
-int my_ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product, const char* description, const char* serial);
-void my_ftdi_deinit(struct ftdi_context *ftdi);
-int my_ftdi_usb_purge_buffers(struct ftdi_context *ftdi);
-int my_ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi);
-int my_ftdi_usb_purge_tx_buffer(struct ftdi_context *ftdi);
-int my_ftdi_usb_reset(struct ftdi_context *ftdi);
-int my_ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency);
-int my_ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate);
-int my_ftdi_read_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize);
-int my_ftdi_write_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize);
-int my_ftdi_set_event_char(struct ftdi_context *ftdi, unsigned char eventch, unsigned char enable);
-int my_ftdi_set_error_char(struct ftdi_context *ftdi, unsigned char errorch, unsigned char enable);
-int my_ftdi_set_bitmode(struct ftdi_context *ftdi, unsigned char bitmask, unsigned char mode);
-int my_ftdi_usb_close(struct ftdi_context *ftdi);
-int cable_common_write_bit(uint8_t packet);
-int cable_common_read_write_bit(uint8_t packet_out, uint8_t *bit_in);
-int cable_common_write_stream(uint32_t *stream, int len_bits, int set_last_bit);
-int cable_common_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit);
-int cable_ftdi_init();
-int cable_ftdi_write_bit(uint8_t packet);
-int cable_ftdi_read_write_bit(uint8_t packet_out, uint8_t *bit_in);
-int cable_ftdi_write_stream(uint32_t *stream, int len_bits, int set_last_bit);
-int cable_ftdi_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit);
-int cable_ftdi_opt(int c, char *str);
-int cable_ftdi_flush();
-int cable_ftdi_close();
-
-#endif
-
-
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/rsp-server.h
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/rsp-server.h (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/rsp-server.h (nonexistent)
@@ -1,36 +0,0 @@
-/* rsp-server.c -- Remote Serial Protocol server for GDB
-
-Copyright (C) 2008 Embecosm Limited
-
-Contributor Jeremy Bennett
-
-This file was part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
-Was actually purchased by Mom when I decided it was nice, but not affordable after two other recent pen purchases.
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3 of the License, or (at your option)
-any later version.
-
-This program 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 General Public License for
-more details.
-
-You should have received a copy of the GNU General Public License along
-with this program. If not, see .
-*/
-
-/* This program is commented throughout in a fashion suitable for processing
- with Doxygen. */
-
-
-#ifndef RSP_SERVER__H
-#define RSP_SERVER__H
-
-
-/* Function prototypes for external use */
-void rsp_init (int portNum);
-int handle_rsp (void); // returns 1 normally, 0 for an unrecoverable error
-
-#endif /* RSP_SERVER__H */
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_sim.c
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_sim.c (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_sim.c (nonexistent)
@@ -1,259 +0,0 @@
-/* cable_sim.c - Simulation connection drivers for the Advanced JTAG Bridge
- Copyright (C) 2001 Marko Mlinar, markom@opencores.org
- Copyright (C) 2004 György Jeney, nog@sdf.lonestar.org
-
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-
-#include "cable_common.h"
-#include "errcodes.h"
-
-#define debug(...) //fprintf(stderr, __VA_ARGS__ )
-
-/* Only used in the vpi */
-static int vpi_comm;
-static int vpi_port = 4567;
-static char *vpi_server = "localhost";
-
-/* Only used for the rtl_sim */
-static char *gdb_in = "gdb_in.dat";
-static char *gdb_out = "gdb_out.dat";
-
-
-
-/*-------------------------------------------[ rtl_sim specific functions ]---*/
-int cable_rtl_sim_init()
-{
- FILE *fin = fopen (gdb_in, "wt+");
- if(!fin) {
- fprintf(stderr, "Can not open %s\n", gdb_in);
- return APP_ERR_INIT_FAILED;
- }
- fclose(fin);
- return APP_ERR_NONE;
-}
-
-int cable_rtl_sim_out(uint8_t value)
-{
- FILE *fout;
- int num_read;
- int r;
- debug("O (%x)\n", value);
- fout = fopen(gdb_in, "wt+");
- fprintf(fout, "F\n");
- fflush(fout);
- fclose(fout);
- fout = fopen(gdb_out, "wt+");
- fprintf(fout, "%02X\n", value);
- fflush(fout);
- fclose(fout);
- do {
- fout = fopen(gdb_out, "rt");
- r = fscanf(fout,"%x", &num_read);
- fclose(fout);
- usleep(1000);
- debug(" (Ack %x) ", num_read);
- } while(!r || (num_read != (0x10 | value)));
- debug("\n");
- return APP_ERR_NONE;
-}
-
-uint8_t cable_rtl_sim_inout(uint8_t value, uint8_t *inval)
-{
- FILE *fin = 0;
- char ch;
- uint8_t data;
- debug("IO (");
-
- while(1) {
- fin = fopen(gdb_in, "rt");
- if(!fin) {
- usleep(1000);
- continue;
- }
- ch = fgetc(fin);
- fclose(fin);
- if((ch != '0') && (ch != '1')) {
- usleep(1000);
- continue;
- }
- else
- break;
- }
- data = ch == '1' ? 1 : 0;
-
- debug("%x,", data);
-
- cable_rtl_sim_out(value);
-
- debug("%x)\n", value);
-
- *inval = data;
- return APP_ERR_NONE;
-}
-
-
-int cable_rtl_sim_opt(int c, char *str)
-{
- switch(c) {
- case 'd':
- if(!(gdb_in = malloc(strlen(str) + 12))) { /* 12 == strlen("gdb_in.dat") + 2 */
- fprintf(stderr, "Unable to allocate enough memory\n");
- return APP_ERR_MALLOC;
- }
- if(!(gdb_out = malloc(strlen(str) + 13))) { /* 13 == strlen("gdb_out.dat") + 2 */
- fprintf(stderr, "Unable to allocate enough memory\n");
- free(gdb_in);
- return APP_ERR_MALLOC;
- }
-
- sprintf(gdb_in, "%s/gdb_in.dat", str);
- sprintf(gdb_out, "%s/gdb_out.dat", str);
- break;
- default:
- fprintf(stderr, "Unknown parameter '%c'\n", c);
- return APP_ERR_BAD_PARAM;
- }
- return APP_ERR_NONE;
-}
-
-/*-----------------------------------------------[ VPI specific functions ]---*/
-int cable_vpi_init()
-{
- struct sockaddr_in addr;
- struct hostent *he;
-
- if((vpi_comm = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
- fprintf(stderr, "Unable to create socket (%s)\n", strerror(errno));
- return APP_ERR_CONNECT;
- }
-
-
- if((he = gethostbyname(vpi_server)) == NULL) {
- perror("gethostbyname");
- return APP_ERR_CONNECT;
- }
-
- addr.sin_family = AF_INET;
- addr.sin_port = vpi_port;
- addr.sin_addr = *((struct in_addr *)he->h_addr);
- memset(addr.sin_zero, '\0', sizeof(addr.sin_zero));
-
- if(connect(vpi_comm, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
- fprintf(stderr, "Unable to connect to %s port %d (%s)\n", vpi_server, vpi_port,
- strerror(errno));
- return APP_ERR_CONNECT;
- }
-
- debug("VPI connected!");
-
- return APP_ERR_NONE;
-}
-
-int cable_vpi_out(uint8_t value)
-{
- uint8_t ack;
- int ret;
-
- /* Send the data to the socket */
- ret = send(vpi_comm, &value, 1, 0);
- debug("Sent %d, ret %d\n", value, ret);
-
- do {
- /* Ok, read the data */
- ret = recv(vpi_comm, &ack, 1, 0);
- if(ret < 0) {
- printf("Error during receive (%s)\n", strerror(errno));
- return APP_ERR_CONNECT;
- }
- } while(ack != (value | 0x10));
- return APP_ERR_NONE;
-}
-
-int cable_vpi_inout(uint8_t value, uint8_t *inval)
-{
- uint8_t dat;
-
- /* ask vpi to send us the out-bit */
- dat = 0x80;
- send(vpi_comm, &dat, 1, 0);
-
- /* Wait and read the data */
- recv(vpi_comm, &dat, 1, 0);
-
- if(dat > 1)
- fprintf(stderr, "Unexpected value: %i\n", dat);
-
- cable_vpi_out(value);
-
- *inval = dat;
- return APP_ERR_NONE;
-}
-
-void cable_vpi_wait()
-{
- uint8_t dat = 0x81;
-
- /* Get the sim to reply when the timeout has been reached */
- if(send(vpi_comm, &dat, 1, 0) < 1) {
- fprintf(stderr, "Failed to send pkt in cable_vpi_wait(): %s\n", strerror(errno));
- }
-
- /* block, waiting for the data */
- if(recv(vpi_comm, &dat, 1, 0) < 1) {
- fprintf(stderr, "Recv failed in cable_vpi_wait(): %s\n", strerror(errno));
- }
-
- if(dat != 0xFF)
- fprintf(stderr, "Warning: got wrong byte waiting for timeout: 0x%X\n", dat);
-
-}
-
-int cable_vpi_opt(int c, char *str)
-{
- switch(c) {
- case 'p':
- if((vpi_port = atoi(str)) == 0) {
- fprintf(stderr, "Bad port value for VPI sim: %s\n", str);
- return APP_ERR_BAD_PARAM;
- }
- break;
- case 's':
- vpi_server = strdup(str);
- if(vpi_server == NULL) {
- fprintf(stderr, "Unable to allocate enough memory for server string\n");
- return APP_ERR_MALLOC;
- }
- break;
- default:
- fprintf(stderr, "Unknown parameter '%c'\n", c);
- return APP_ERR_BAD_PARAM;
- }
- return APP_ERR_NONE;
-}
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_sim.h
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_sim.h (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_sim.h (nonexistent)
@@ -1,20 +0,0 @@
-
-#ifndef _CABLE_SIM_H_
-#define _CABLE_SIM_H_
-
-#include
-
-int cable_rtl_sim_init();
-int cable_rtl_sim_out(uint8_t value);
-int cable_rtl_sim_inout(uint8_t value, uint8_t *inval);
-void cable_rtl_sim_wait();
-int cable_rtl_sim_opt(int c, char *str);
-
-int cable_vpi_init();
-int cable_vpi_out(uint8_t value);
-int cable_vpi_inout(uint8_t value, uint8_t *inval);
-void cable_vpi_wait();
-int cable_vpi_opt(int c, char *str);
-
-
-#endif
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/bsdl.c
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/bsdl.c (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/bsdl.c (nonexistent)
@@ -1,238 +0,0 @@
-/* bsdl.c - BSDL file handler for the advanced JTAG bridge
- Copyright(C) 2008 Nathan Yawn
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include
-#include
-#include
-#include
-#include "bsdl.h"
-#include "bsdl_parse.h"
-
-
-#define debug(...) //fprintf(stderr, __VA_ARGS__ )
-
-// Globals to deal with directory names
-#define MAX_BSDL_DIRS 64 // Any more than this would take a looooong time...
-static char *bsdl_dirs[MAX_BSDL_DIRS];
-static int bsdl_current_dir = 0; // We try them in reverse order
-
-// Globals to hold the current, open directory
-DIR *bsdl_open_dir = NULL;
-
-// Globals to hold BSDL info
-static bsdlinfo *bsdl_head = NULL;
-static bsdlinfo *bsdl_tail = NULL;
-static bsdlinfo *bsdl_last = NULL; // optimization: pointer to the last struct we used (not necessarily the last in the linked list)
-
-// Prototypes for local functions
-bsdlinfo *get_bsdl_info(uint32_t idcode);
-
-
-
-//////////////////////////////////////////////////////////////////////
-// API for init and config
-
-void bsdl_init(void)
-{
- bsdl_dirs[0] = strdup("/opt/bsdl");
- bsdl_dirs[1] = strdup("/usr/share/bsdl");
- bsdl_dirs[2] = strdup("~/.bsdl");
- bsdl_dirs[3] = strdup(".");
- bsdl_current_dir = 3;
-}
-
-void bsdl_add_directory(const char *dirname)
-{
- if(bsdl_current_dir >= (MAX_BSDL_DIRS-1)) {
- printf("Max BSDL dirs (%d) exceeded; failed to add directory %s\n", MAX_BSDL_DIRS, dirname);
- return;
- }
-
- bsdl_current_dir++;
- bsdl_dirs[bsdl_current_dir] = strdup(dirname);
-}
-
-
-///////////////////////////////////////////////////////////////////
-// API to get device info from BSDL files, if available
-
-
-const char * bsdl_get_name(uint32_t idcode)
-{
- bsdlinfo *info;
- info = get_bsdl_info(idcode);
- if(info != NULL)
- return info->name;
-
- return NULL;
-
-
-}
-
-// Return the IR length of the device with the given IDCODE,
-// if its BSDL file is available. Returns -1 on
-// error, which is an invalid size.
-
-int bsdl_get_IR_size(uint32_t idcode)
-{
- bsdlinfo *info;
- info = get_bsdl_info(idcode);
- if(info != NULL)
- return info->IR_size;
-
- return -1;
-}
-
-
-// Returns the DEBUG command for the device with the gived IDCODE,
-// if its BSDL file is available. Returns 0xFFFFFFFF on error,
-// which is as invalid command (because it's the BYPASS command)
-uint32_t bsdl_get_debug_cmd(uint32_t idcode)
-{
- bsdlinfo *info;
- info = get_bsdl_info(idcode);
- if(info != NULL)
- return info->cmd_debug;
- return TAP_CMD_INVALID;
-}
-
-// Returns the USER1 command for the device with the gived IDCODE,
-// if its BSDL file is available. Returns 0xFFFFFFFF on error,
-// which is as invalid command (because it's the BYPASS command)
-uint32_t bsdl_get_user1_cmd(uint32_t idcode)
-{
- bsdlinfo *info;
- info = get_bsdl_info(idcode);
- if(info != NULL)
- return info->cmd_user1;
- return TAP_CMD_INVALID;
-}
-
-// Returns the IDCODE command for the device with the gived IDCODE,
-// if its BSDL file is available. Returns 0xFFFFFFFF on error,
-// which is as invalid command (because it's the BYPASS command)
-uint32_t bsdl_get_idcode_cmd(uint32_t idcode)
-{
- bsdlinfo *info;
- info = get_bsdl_info(idcode);
- if(info != NULL)
- return info->cmd_idcode;
- return TAP_CMD_INVALID;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Internal routines
-
-
-// This uses a lazy algorithm...first, search data we already have.
-// Then, parse new files (storing all data) only until we find
-// the data we want.
-bsdlinfo *get_bsdl_info(uint32_t idcode)
-{
- struct dirent *direntry = NULL;
- bsdlinfo *ptr = bsdl_head;
- char *c;
-
- // Check the last place we looked
- if(bsdl_last != NULL)
- if((bsdl_last->idcode & bsdl_last->idcode_mask) == (idcode & bsdl_last->idcode_mask))
- return bsdl_last;
-
- // First, search through the info already parsed
- while(ptr != NULL)
- {
- if((ptr->idcode & ptr->idcode_mask) == (idcode & ptr->idcode_mask))
- {
- bsdl_last = ptr;
- return ptr;
- }
- ptr = ptr->next;
- }
-
- // Parse files until we get the IDCODE we want
- while(1)
- {
- // Find and open a valid directory
- while(bsdl_open_dir == NULL)
- {
- if(bsdl_current_dir < 0)
- return NULL; // There are no more directories to check
- debug("Trying BSDL dir \'%s\'\n", bsdl_dirs[bsdl_current_dir]);
- bsdl_open_dir = opendir(bsdl_dirs[bsdl_current_dir]);
- if((bsdl_open_dir == NULL) && (bsdl_current_dir > 2)) // Don't warn if default dirs not found
- printf("Warning: unable to open BSDL directory \'%s\'\n", bsdl_dirs[bsdl_current_dir]);
- bsdl_current_dir--;
- direntry = NULL;
- }
-
- // Find a BSDL file
- do
- {
- direntry = readdir(bsdl_open_dir);
- if(direntry == NULL)
- { // We've exhausted this directory
- closedir(bsdl_open_dir);
- bsdl_open_dir = NULL;
- break;
- }
-
- // *** If a subdirectory, continue!!
-
- // Check if it's a BSDL file: .bsd, .bsdl, .BSD, .BSDL
- debug("Checking file \'%s\'\n", direntry->d_name);
- c = strrchr(direntry->d_name, '.');
- debug("File extension is \'%s\'\n", c);
- if(c == NULL)
- continue;
- if(!strcmp(c, ".bsd") || !strcmp(c, ".bsdl") || !strcmp(c, ".BSD") || !strcmp(c, ".BSDL"))
- break;
-
- }
- while(1);
-
- if(direntry == NULL) // We need a new directory
- continue;
-
- // Parse the BSDL file we found
- debug("Parsing file \'%s\'\n", direntry->d_name);
- ptr = parse_extract_values(direntry->d_name);
-
- // If we got good data...
- if(ptr != NULL)
- {
- // Store the values...
- if(bsdl_head == NULL) {
- bsdl_head = ptr;
- bsdl_tail = ptr;
- } else {
- bsdl_tail->next = ptr;
- bsdl_tail = ptr;
- }
-
- // ...and return if we got an IDCODE match
- if((ptr->idcode & ptr->idcode_mask) == (idcode & ptr->idcode_mask)) {
- bsdl_last = ptr;
- return ptr;
- }
- }
- } // while(1), parse files until we find a match or run out of dirs / files
-
-
- // If no more files to parse and not found, return NULL
- return NULL;
-}
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/doc/License_FDL-1.2.txt
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/doc/License_FDL-1.2.txt (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/doc/License_FDL-1.2.txt (nonexistent)
@@ -1,397 +0,0 @@
- GNU Free Documentation License
- Version 1.2, November 2002
-
-
- Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
- 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
-0. PREAMBLE
-
-The purpose of this License is to make a manual, textbook, or other
-functional and useful document "free" in the sense of freedom: to
-assure everyone the effective freedom to copy and redistribute it,
-with or without modifying it, either commercially or noncommercially.
-Secondarily, this License preserves for the author and publisher a way
-to get credit for their work, while not being considered responsible
-for modifications made by others.
-
-This License is a kind of "copyleft", which means that derivative
-works of the document must themselves be free in the same sense. It
-complements the GNU General Public License, which is a copyleft
-license designed for free software.
-
-We have designed this License in order to use it for manuals for free
-software, because free software needs free documentation: a free
-program should come with manuals providing the same freedoms that the
-software does. But this License is not limited to software manuals;
-it can be used for any textual work, regardless of subject matter or
-whether it is published as a printed book. We recommend this License
-principally for works whose purpose is instruction or reference.
-
-
-1. APPLICABILITY AND DEFINITIONS
-
-This License applies to any manual or other work, in any medium, that
-contains a notice placed by the copyright holder saying it can be
-distributed under the terms of this License. Such a notice grants a
-world-wide, royalty-free license, unlimited in duration, to use that
-work under the conditions stated herein. The "Document", below,
-refers to any such manual or work. Any member of the public is a
-licensee, and is addressed as "you". You accept the license if you
-copy, modify or distribute the work in a way requiring permission
-under copyright law.
-
-A "Modified Version" of the Document means any work containing the
-Document or a portion of it, either copied verbatim, or with
-modifications and/or translated into another language.
-
-A "Secondary Section" is a named appendix or a front-matter section of
-the Document that deals exclusively with the relationship of the
-publishers or authors of the Document to the Document's overall subject
-(or to related matters) and contains nothing that could fall directly
-within that overall subject. (Thus, if the Document is in part a
-textbook of mathematics, a Secondary Section may not explain any
-mathematics.) The relationship could be a matter of historical
-connection with the subject or with related matters, or of legal,
-commercial, philosophical, ethical or political position regarding
-them.
-
-The "Invariant Sections" are certain Secondary Sections whose titles
-are designated, as being those of Invariant Sections, in the notice
-that says that the Document is released under this License. If a
-section does not fit the above definition of Secondary then it is not
-allowed to be designated as Invariant. The Document may contain zero
-Invariant Sections. If the Document does not identify any Invariant
-Sections then there are none.
-
-The "Cover Texts" are certain short passages of text that are listed,
-as Front-Cover Texts or Back-Cover Texts, in the notice that says that
-the Document is released under this License. A Front-Cover Text may
-be at most 5 words, and a Back-Cover Text may be at most 25 words.
-
-A "Transparent" copy of the Document means a machine-readable copy,
-represented in a format whose specification is available to the
-general public, that is suitable for revising the document
-straightforwardly with generic text editors or (for images composed of
-pixels) generic paint programs or (for drawings) some widely available
-drawing editor, and that is suitable for input to text formatters or
-for automatic translation to a variety of formats suitable for input
-to text formatters. A copy made in an otherwise Transparent file
-format whose markup, or absence of markup, has been arranged to thwart
-or discourage subsequent modification by readers is not Transparent.
-An image format is not Transparent if used for any substantial amount
-of text. A copy that is not "Transparent" is called "Opaque".
-
-Examples of suitable formats for Transparent copies include plain
-ASCII without markup, Texinfo input format, LaTeX input format, SGML
-or XML using a publicly available DTD, and standard-conforming simple
-HTML, PostScript or PDF designed for human modification. Examples of
-transparent image formats include PNG, XCF and JPG. Opaque formats
-include proprietary formats that can be read and edited only by
-proprietary word processors, SGML or XML for which the DTD and/or
-processing tools are not generally available, and the
-machine-generated HTML, PostScript or PDF produced by some word
-processors for output purposes only.
-
-The "Title Page" means, for a printed book, the title page itself,
-plus such following pages as are needed to hold, legibly, the material
-this License requires to appear in the title page. For works in
-formats which do not have any title page as such, "Title Page" means
-the text near the most prominent appearance of the work's title,
-preceding the beginning of the body of the text.
-
-A section "Entitled XYZ" means a named subunit of the Document whose
-title either is precisely XYZ or contains XYZ in parentheses following
-text that translates XYZ in another language. (Here XYZ stands for a
-specific section name mentioned below, such as "Acknowledgements",
-"Dedications", "Endorsements", or "History".) To "Preserve the Title"
-of such a section when you modify the Document means that it remains a
-section "Entitled XYZ" according to this definition.
-
-The Document may include Warranty Disclaimers next to the notice which
-states that this License applies to the Document. These Warranty
-Disclaimers are considered to be included by reference in this
-License, but only as regards disclaiming warranties: any other
-implication that these Warranty Disclaimers may have is void and has
-no effect on the meaning of this License.
-
-
-2. VERBATIM COPYING
-
-You may copy and distribute the Document in any medium, either
-commercially or noncommercially, provided that this License, the
-copyright notices, and the license notice saying this License applies
-to the Document are reproduced in all copies, and that you add no other
-conditions whatsoever to those of this License. You may not use
-technical measures to obstruct or control the reading or further
-copying of the copies you make or distribute. However, you may accept
-compensation in exchange for copies. If you distribute a large enough
-number of copies you must also follow the conditions in section 3.
-
-You may also lend copies, under the same conditions stated above, and
-you may publicly display copies.
-
-
-3. COPYING IN QUANTITY
-
-If you publish printed copies (or copies in media that commonly have
-printed covers) of the Document, numbering more than 100, and the
-Document's license notice requires Cover Texts, you must enclose the
-copies in covers that carry, clearly and legibly, all these Cover
-Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
-the back cover. Both covers must also clearly and legibly identify
-you as the publisher of these copies. The front cover must present
-the full title with all words of the title equally prominent and
-visible. You may add other material on the covers in addition.
-Copying with changes limited to the covers, as long as they preserve
-the title of the Document and satisfy these conditions, can be treated
-as verbatim copying in other respects.
-
-If the required texts for either cover are too voluminous to fit
-legibly, you should put the first ones listed (as many as fit
-reasonably) on the actual cover, and continue the rest onto adjacent
-pages.
-
-If you publish or distribute Opaque copies of the Document numbering
-more than 100, you must either include a machine-readable Transparent
-copy along with each Opaque copy, or state in or with each Opaque copy
-a computer-network location from which the general network-using
-public has access to download using public-standard network protocols
-a complete Transparent copy of the Document, free of added material.
-If you use the latter option, you must take reasonably prudent steps,
-when you begin distribution of Opaque copies in quantity, to ensure
-that this Transparent copy will remain thus accessible at the stated
-location until at least one year after the last time you distribute an
-Opaque copy (directly or through your agents or retailers) of that
-edition to the public.
-
-It is requested, but not required, that you contact the authors of the
-Document well before redistributing any large number of copies, to give
-them a chance to provide you with an updated version of the Document.
-
-
-4. MODIFICATIONS
-
-You may copy and distribute a Modified Version of the Document under
-the conditions of sections 2 and 3 above, provided that you release
-the Modified Version under precisely this License, with the Modified
-Version filling the role of the Document, thus licensing distribution
-and modification of the Modified Version to whoever possesses a copy
-of it. In addition, you must do these things in the Modified Version:
-
-A. Use in the Title Page (and on the covers, if any) a title distinct
- from that of the Document, and from those of previous versions
- (which should, if there were any, be listed in the History section
- of the Document). You may use the same title as a previous version
- if the original publisher of that version gives permission.
-B. List on the Title Page, as authors, one or more persons or entities
- responsible for authorship of the modifications in the Modified
- Version, together with at least five of the principal authors of the
- Document (all of its principal authors, if it has fewer than five),
- unless they release you from this requirement.
-C. State on the Title page the name of the publisher of the
- Modified Version, as the publisher.
-D. Preserve all the copyright notices of the Document.
-E. Add an appropriate copyright notice for your modifications
- adjacent to the other copyright notices.
-F. Include, immediately after the copyright notices, a license notice
- giving the public permission to use the Modified Version under the
- terms of this License, in the form shown in the Addendum below.
-G. Preserve in that license notice the full lists of Invariant Sections
- and required Cover Texts given in the Document's license notice.
-H. Include an unaltered copy of this License.
-I. Preserve the section Entitled "History", Preserve its Title, and add
- to it an item stating at least the title, year, new authors, and
- publisher of the Modified Version as given on the Title Page. If
- there is no section Entitled "History" in the Document, create one
- stating the title, year, authors, and publisher of the Document as
- given on its Title Page, then add an item describing the Modified
- Version as stated in the previous sentence.
-J. Preserve the network location, if any, given in the Document for
- public access to a Transparent copy of the Document, and likewise
- the network locations given in the Document for previous versions
- it was based on. These may be placed in the "History" section.
- You may omit a network location for a work that was published at
- least four years before the Document itself, or if the original
- publisher of the version it refers to gives permission.
-K. For any section Entitled "Acknowledgements" or "Dedications",
- Preserve the Title of the section, and preserve in the section all
- the substance and tone of each of the contributor acknowledgements
- and/or dedications given therein.
-L. Preserve all the Invariant Sections of the Document,
- unaltered in their text and in their titles. Section numbers
- or the equivalent are not considered part of the section titles.
-M. Delete any section Entitled "Endorsements". Such a section
- may not be included in the Modified Version.
-N. Do not retitle any existing section to be Entitled "Endorsements"
- or to conflict in title with any Invariant Section.
-O. Preserve any Warranty Disclaimers.
-
-If the Modified Version includes new front-matter sections or
-appendices that qualify as Secondary Sections and contain no material
-copied from the Document, you may at your option designate some or all
-of these sections as invariant. To do this, add their titles to the
-list of Invariant Sections in the Modified Version's license notice.
-These titles must be distinct from any other section titles.
-
-You may add a section Entitled "Endorsements", provided it contains
-nothing but endorsements of your Modified Version by various
-parties--for example, statements of peer review or that the text has
-been approved by an organization as the authoritative definition of a
-standard.
-
-You may add a passage of up to five words as a Front-Cover Text, and a
-passage of up to 25 words as a Back-Cover Text, to the end of the list
-of Cover Texts in the Modified Version. Only one passage of
-Front-Cover Text and one of Back-Cover Text may be added by (or
-through arrangements made by) any one entity. If the Document already
-includes a cover text for the same cover, previously added by you or
-by arrangement made by the same entity you are acting on behalf of,
-you may not add another; but you may replace the old one, on explicit
-permission from the previous publisher that added the old one.
-
-The author(s) and publisher(s) of the Document do not by this License
-give permission to use their names for publicity for or to assert or
-imply endorsement of any Modified Version.
-
-
-5. COMBINING DOCUMENTS
-
-You may combine the Document with other documents released under this
-License, under the terms defined in section 4 above for modified
-versions, provided that you include in the combination all of the
-Invariant Sections of all of the original documents, unmodified, and
-list them all as Invariant Sections of your combined work in its
-license notice, and that you preserve all their Warranty Disclaimers.
-
-The combined work need only contain one copy of this License, and
-multiple identical Invariant Sections may be replaced with a single
-copy. If there are multiple Invariant Sections with the same name but
-different contents, make the title of each such section unique by
-adding at the end of it, in parentheses, the name of the original
-author or publisher of that section if known, or else a unique number.
-Make the same adjustment to the section titles in the list of
-Invariant Sections in the license notice of the combined work.
-
-In the combination, you must combine any sections Entitled "History"
-in the various original documents, forming one section Entitled
-"History"; likewise combine any sections Entitled "Acknowledgements",
-and any sections Entitled "Dedications". You must delete all sections
-Entitled "Endorsements".
-
-
-6. COLLECTIONS OF DOCUMENTS
-
-You may make a collection consisting of the Document and other documents
-released under this License, and replace the individual copies of this
-License in the various documents with a single copy that is included in
-the collection, provided that you follow the rules of this License for
-verbatim copying of each of the documents in all other respects.
-
-You may extract a single document from such a collection, and distribute
-it individually under this License, provided you insert a copy of this
-License into the extracted document, and follow this License in all
-other respects regarding verbatim copying of that document.
-
-
-7. AGGREGATION WITH INDEPENDENT WORKS
-
-A compilation of the Document or its derivatives with other separate
-and independent documents or works, in or on a volume of a storage or
-distribution medium, is called an "aggregate" if the copyright
-resulting from the compilation is not used to limit the legal rights
-of the compilation's users beyond what the individual works permit.
-When the Document is included in an aggregate, this License does not
-apply to the other works in the aggregate which are not themselves
-derivative works of the Document.
-
-If the Cover Text requirement of section 3 is applicable to these
-copies of the Document, then if the Document is less than one half of
-the entire aggregate, the Document's Cover Texts may be placed on
-covers that bracket the Document within the aggregate, or the
-electronic equivalent of covers if the Document is in electronic form.
-Otherwise they must appear on printed covers that bracket the whole
-aggregate.
-
-
-8. TRANSLATION
-
-Translation is considered a kind of modification, so you may
-distribute translations of the Document under the terms of section 4.
-Replacing Invariant Sections with translations requires special
-permission from their copyright holders, but you may include
-translations of some or all Invariant Sections in addition to the
-original versions of these Invariant Sections. You may include a
-translation of this License, and all the license notices in the
-Document, and any Warranty Disclaimers, provided that you also include
-the original English version of this License and the original versions
-of those notices and disclaimers. In case of a disagreement between
-the translation and the original version of this License or a notice
-or disclaimer, the original version will prevail.
-
-If a section in the Document is Entitled "Acknowledgements",
-"Dedications", or "History", the requirement (section 4) to Preserve
-its Title (section 1) will typically require changing the actual
-title.
-
-
-9. TERMINATION
-
-You may not copy, modify, sublicense, or distribute the Document except
-as expressly provided for under this License. Any other attempt to
-copy, modify, sublicense or distribute the Document is void, and will
-automatically terminate your rights under this License. However,
-parties who have received copies, or rights, from you under this
-License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-
-10. FUTURE REVISIONS OF THIS LICENSE
-
-The Free Software Foundation may publish new, revised versions
-of the GNU Free Documentation License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns. See
-http://www.gnu.org/copyleft/.
-
-Each version of the License is given a distinguishing version number.
-If the Document specifies that a particular numbered version of this
-License "or any later version" applies to it, you have the option of
-following the terms and conditions either of that specified version or
-of any later version that has been published (not as a draft) by the
-Free Software Foundation. If the Document does not specify a version
-number of this License, you may choose any version ever published (not
-as a draft) by the Free Software Foundation.
-
-
-ADDENDUM: How to use this License for your documents
-
-To use this License in a document you have written, include a copy of
-the License in the document and put the following copyright and
-license notices just after the title page:
-
- Copyright (c) YEAR YOUR NAME.
- Permission is granted to copy, distribute and/or modify this document
- under the terms of the GNU Free Documentation License, Version 1.2
- or any later version published by the Free Software Foundation;
- with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
- A copy of the license is included in the section entitled "GNU
- Free Documentation License".
-
-If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
-replace the "with...Texts." line with this:
-
- with the Invariant Sections being LIST THEIR TITLES, with the
- Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
-
-If you have Invariant Sections without Cover Texts, or some other
-combination of the three, merge those two alternatives to suit the
-situation.
-
-If your document contains nontrivial examples of program code, we
-recommend releasing these examples in parallel under your choice of
-free software license, such as the GNU General Public License,
-to permit their use in free software.
Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/doc/adv_jtag_bridge.pdf
===================================================================
--- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/doc/adv_jtag_bridge.pdf (revision 26)
+++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/doc/adv_jtag_bridge.pdf (nonexistent)
@@ -1,2502 +0,0 @@
-%PDF-1.4
-%äüöß
-2 0 obj
-< >
-stream
-xœm‘ËNÄ0E÷ù
-¯‘ì8FŠ"Ñy ±¨Ä±âµa˜Íü>Ž[`è J©cßú»h Žæ:”0’“3åv^àþ>´ØžÃ›Fã˜-C ÞzŸárKà$z}(Hµ£‚®º‚\;.èkç†*Ùˆ©J¦¯Ts“\i8 #zæïU¾ÒÐãZEÜjBÑ?Ž7f3šÝ‚ËÇlpB&.¸¸qµ–ܬý| +§"h9}z‡3rœÍXÌ"°²¦…Yøß(ר#Ç…:.®q3+·ú^¶š$jš<å°;…#Å#8EzÚ´ŽÈo¯üd’õìú u½¼ÃÝù.sßz9²i11y
-BF‘Ò0õ¿<;øT}
-endstream
-endobj
-
-3 0 obj
-290
-endobj
-
-5 0 obj
-< >
-stream
-xœVËëãF¾ç¯ð¹àt¤yØ3ÄÉÂÞ¶
-ôPzêJ·°{Ùõšñ#öþÚp<ôIŸ¤‘;Cóåô©qMëè5Ò³øùù÷æ§ïšd“Ÿÿ<]Ÿ§˜Î}ãq çó·æû6€ÍóŸGr£»¹‰þ»Ñ]2Æ\n‡è}tÁùܦÑ%¸ª4Üè}O¿;<ìwÉAnýè0“BOg餼G—²§.m÷"ó/Ï÷§ûóôa.’?¸‹„ŒßI‡‚DÈઘ·' ¯bn{F>ïÓÁ`“µ!~YÝôˆ{ä—žÃÒû½n!.õñ!pòªÁª–ô¨%DÞ€(È~"àüjº0•ð‹mÞ
-5¼ &5¡~«…Í„‘mY€ª&0<Û*€ddû†©³#Ø ÈqÄÞÐÌY‰û!ÏѤ!?ÿ:f¾ëÏaËüE,ÿ‹XþQÊÖ, ÀWŽ¥¬¹íÊ)‹®d€'PÄÞHk¬!ê2*¹&Ž—„gJ!N(«€ÓÞݖͤgÂHI4¬/XŠZú……
-SZØÑ„œFáUdûZ¤"§"rŽd4{*ì
-Í»CŠœãcoQœÂ9m(Vhjs‘·‰"CÇ+9®Bµˆ¥=‘Ÿ¥7hñ®<ÐP2ɪ®†êfm€:™õÂÊÒÅIá1'+!ïU|ÖW*¼"
-¢ÿ—n7”c?zzÆuOÒfÁÏuÉ.*}N£ý”?"”n‰´ÃÏ[„F÷z¹”ô¥Ä4#%ë[ÔŠ–íÒºJª¿fÄkŽlÆšü`)$\Ìoƒë"šæÞñÐ:ZÅM+FMNˆµæ‹ò7”^DÒÅÏU'N=½Òçè`HÞÕÖ^|)<±tŸS /龎$:p_Ê@nàR9ˆzh–*ýxrç®ù²²üûÍ@mûc“¢¾ýÝüøJ=À6‰«Þt¥_vÜÕñVÂùn¿¸9_,òPÒI/ø%á‹ö7·M˜»ÉQۄw†oN8КØÄ _à›x`KâCšö2DÑ ¥@@ÒÙsL[J€«¶Þœä5n.–*q—ö#ŸVuOÕ¥¢åfU4YSÃ"uÑÉücŸ‡µ$×Ì•-˜W7@^¥,L(0…~åËX_峋†ïʼn!tlT/Úž×ÊõņÕ2Ü80 Z>×ÓJ6îô›%LÈÁ㸃º]ryBøFBCçJËÙP£¤+yѽøª£ñúUBly*’;BœÄQ?÷R.Lw°kµEžŠl9g‚!Dà«Ï'x{™˜9ˆ2WÞ
-VEûÀÛ+]<
-ûsÆŒ:®Éy,,XÄD§¥I5ȸT4æïÆ9}rç
-Ïr—ÂAÐ^‰‰òÍ#Ð+}oñ»—êç–B>]ÈX_ÃìŽz¶è¤š¯è
-endstream
-endobj
-
-6 0 obj
-1105
-endobj
-
-8 0 obj
-< >
-stream
-xœVÁŽÛ ½û+8¯F²,%›¸RoÛFê¡êÝ^šJÙK¿0fìÅNeÉ3™yƒ#[%þ6w!ÅA†¡UÞÎÇ÷ÛOñõIüi¤ˆÏÛ¯ÆØÖ ëdÛ
--л^Ÿš¾o=AVµ†CÊȶ#¬ï8º›
-*P2P¶^*oÅúw>Gç‚A>‡[œ¡|·<bényrHçÈ`"f#h„6‚F¬49\dÆ{–áEd ªG–°ZdÙá*²»˜+{ºFê^8õúC|˜:¡¬¸¾~¤z0 µìâÁ;”¤¿_?5—kóÒ¼ˆè3ÒYTˆ0\éóǵ¢|<äM¤tâä·øÒ°éMP>gÏo‚r:£|~ƘX¡ÅH“ê2)N
-)a\¹Œ”P®^FJ(‘Îh"E‰eRœR¸L)¡\ªŒ”P"ÑDŠRˤ8)¤„q¹2RB¹d)¡D:£LÃDš&3iƸliF¹tiFiABb÷TÁr]ÊÝQ°œ¾ÒêËQ–¨âÔ4´W꽊¬Wô®
-s_Aû¥^פt’~(ù}mî‹h]mÞ³•fbóŠêÙ¼"O6¯£tƒm~
-ïBáCW&Þs}Ì^™F(ÈW¦‰7&ÞºÜKs¯bwÖÌ»h.Yˆ—,DO.”Ñ¡0U.°²/NühyÄùiËh·åï9ž)™ŸÃ8º÷÷¹ø°`–°–.•ŒÖJk[Ö)I5kâQº0Ñ…-CC`ïnË?e°FàVUð84%pÕÊÊ^ázœGÕExƒŽ\£;³ßgú¾â0BãjàÄïpÊÿINŠf“6Õ@ë åíÈýÔC
-.%ñÓN
-`Ó?Õ Fà°‡BŠ÷óY1õž˜¡T¹úº±O©„´jÃæ´-¬ll[©F¦`œ:\yçÞÂÐÏÛSδéDÛtô‘Ng
--øصpŒ`iCZQÑ'Ú¯™2ŽE™Ò 5?›ýï*DúwÏ¢÷R·^*d¯K*¤FðŸ
-©˜†4§+Òn×1iäy,ËãÁÓê9¾.%|ÃTÆi›Â³QasSóNL€É;èYYµ+6Ë…ýßþ ÝP
-endstream
-endobj
-
-9 0 obj
-854
-endobj
-
-11 0 obj
-<>
-stream
-xœíšKÛ6Çïþ:°K_"@X[ò¡· z(zk ‡É%_¿3¤${—yÄ”“BXÅ{)zþ?΋dÞ}Ý}îX·gøRsÀ»±tÿòw÷û/Ý¿áMº¾|Ú/;¥}g€ »üÕýz–×ÝåãŽõ~/S^:fÃKéÁ±—Û_„ÿóòÛn¼ì>dGeü â¨Ðq£rÍ,àà@1ÅΞÓ(àøwÂÇFä¬?ÈìÌþ—ß÷îéî%>¤Íªé„ñ—raæ^Ì”¾â‰~|ïD F6"TœÁHSˆ\Ñÿ Ï%´„Æqs£·–ü'«
-JªMÐße@˜à{儬0/
-/^!1•…΋¼àœòiä³S×?±µ¶ OÕÒôèL(Ää ¾ØÆ¢ËÐâ…8yÅŒ áO{nÜ–
-_€“{IfÔZºÈ_þÕÖd‡þ`KÂÓâR
-~V?.u¿·AV8y¥bäà,|szÿp¯S*AQŸ…¯‘™Wké6‚B]þÄnk p†‰gÁóñçDÊEG?,i§"ÌFO¿Þ²)½5ɤ¾ô{ü%ønéuÄŠ€¢/“™[kѾ¹œ[N"û;.ËI„¢)D£({„BF,F
-ïO%”BÀsjÿ†Ù«ªœÚ²¬rpÊȃ.é¬g—áýºÜåÌÓ2#¶6éÃEÚ潎N¢Û:JT aFGˆáïur2¶Öùrî 'ÑmAݬ<9ô±— ‰ù?OyÇ0W-U(ë¸ÍcKpA“Ì<³5
-O \]øĦkÂËöDƒË0« jCWbu¢Ù)1ÀC†ZIOzªVn°Â!”3pôs€ã=?sÙ^g¿ÄSküHW‘ØnÙ®gpfî¦c1Šê
-|G>”³M–®µv[¸ÞcbGÇÇšŽ²—Ù¦dÐ' 7y¦à¸Tc<=ˆyÙÓJ¾oϤ7ÙǶ¶õwQk“«=µþ%ºX‹HüwôªkݵP&N8CPhf¯b¾w,NŸßZê&`ÕEÕo«„’¤•&ß’¤`?w’Pº9GQƒˆY‹yÞ”p(;÷þ\k›6Ðï{/ëÄÊuÀf»’¾qI/ÌÛQq{bÞÆ\Kî%¹˜Ü#Zk±ëÊ&v,+9HÎÓ6á÷˜¸u—rSyÙpŃ–¶sc¶6ás\ï^ȉ¥±ø)/daEÚ+–±jŸêòà¼a.¼Â""Öd¡J¦Ý¤1–ò¥Õ
-FåÜs[›ú¡">(eèÕ³k/îµãN¨¤yz9Ww¾Ð°l'M°ËmÎhë(7tk•~ÌWNKköJŒÊ$»iÏqÀkœŽ0„qî…B!|FœCS螊’úHKûˆNALç ÎiÍYvY $úÔÜœ[Ãô”ÕaJ¬Œ0‰c%‚ ›´îbéÚsœÏ¾pQ>2‡n ²ƒµÖrû×]º&–]Ó52z£ë‰š½KCiMO›¤µµ©³µ{–D·-1¤0‘´×BJlW,ád “ø9V‡uëÍánPÓ«±ÈŸÕ32“jÍÓPUç#±+ñq=@û¡ûsD2á
-endstream
-endobj
-
-12 0 obj
-1258
-endobj
-
-14 0 obj
-<>
-stream
-xœÅ\I‹#˾ϯÐÙ0í\k!è.©¾=ðÁøæ|0ø]ü÷™‘‘K¥Ô3`„ZReeÆËKzÓ—ÿ~ûÏE]¾«ðvÑ&¼®{|ýýï—?ÿáòïôeü÷û?¿}üøæ—·í²ª-üàÇß.üt½Ä÷ÿøËU}ܾ۫:nýñ§oß~«.]íÛ>ºô~ÓWõˆ/{|ùL+¹ÛwsU&½÷ðÝhé°õ°ü/í`Y}û®Ó
-¦¼,±oý%lºØÝ–¸‡¸Ârƒ…·kú>Þ†›7{Y¼}s°´¹h“–¶æW†c/agújŒy8åÂV—xçtz}ÕÆ)ã´Òïáct8Ïv¥ËîZ©C›ð>^¯FÇ«–ôS“èÂo`K.ê0Kxµtûpýy„ïîñÍg\Ý¥¥kãzÊ«Åx\õ‘¶›¯K¿\Âés~fðLñ*»¥kî°ioQd|évKüC‡7ï7½Ò76ÉâgÓ*jAºWXUÓ(¡…+Xx7`DTü«{EÔ÷Åî¤=I8m`dä´Û-‹¥¢[oþjÞã—´kÑFé7*ÝÓÀ2Râþ›8²ðMÁn°ð3(t0ÀýÕ®’ 7Ÿc4é_P¤ »ÞÓAhÏî¯?nÛ5.Õ~¶»G@ãŠÅ*FÚõÍw ™ah|xí`øËlŽiágF÷N™d¶À7Gº.#”H•ÌwÃe;Ša Qƒ¦Ú$^kÙ,Ä'p õ‹Öc™óñøw:Pü6ž n’~þà*Y=Fx`#þ^ñG-]
-ºØ“ ù*î˜È@—(ˆ¤Ût±&í
-;LÖ‚DŠÍ uINDCÖPYÑ ¿zóÛÕ.IœAÑÈ#f1Íÿ½zÏàÞ<“»2\ÃÈk£‰ª°;€==j*ˆ,ý~\
-ümÜ|¸}¨Ï§aéÖ`u54$ý¾½ÕXš,B+î$IÕ$š{êˆu~ö~01%–˜ß)áp`Z8<“Å<ÕÌvƒ <)!…á_ØžÛÂlB€lq›½¹–ä€ã2·Í“¬(Œ$40© Ù,OÛXé%*Bby»›é/ã%ùô‡´t¦ˆQb•&毙;À‚Ù(vD?“ã±[ä.
-yAãõ¶rI¯Ù="ÁU6ð6Øj’Dâ 2{üü´ò–8ëYûÐqïÍt`U
-UâŠþ™šx¸åÈ„9EKºW>×rDãÇœÀ°ÕQW¢‚ ûK4,<6¯ž>ÉX˜A½ßø‘® ;‡5Ž²ÔGWœ}£ÇΞ(³.Ú4Ìż‹é^ÖÝôÚ
-ËG‡ÎD¼Êr:à\¦4æãf}v†á0ሠz°>8°ÉË%%É@Rì’Ró N²ÜdÇÉÖøÚ2EâÏêP,‘1Ÿ¼VسÏ,ìäà’$Ê•4^/–»6®á¤%e.þ¼Ü(¸FR¬ûë=$Þ-t3¬íÚñ£è÷’r¾C/IÎÝ*{_câ2Íõc¦ÂŒFôý8@"—É&ÇýÖ°ôÒ{o\ñÿ)½'ÎZ)x=ßOÐUJþ(-ØJTAôÕ¥‡Øí!ƒJŒŽl¤µzªìLkµ¦úRñPO9÷£©†Vxu!@g‰”‘|GrcAçJFŸýðÍéœj1/”ó}×>Z@á2˜ŠÈ@”!mâ.ÉgfŒ9çK7à6$‰2ƒÎy²MJØÊxŠÛ×·Ú™€Z é>¡,uR£e9ȃ_ÍY\¥ýAÀ‹¤ Œs“¾ŸHekîžÓé¯Â&ó‚T”6#¼gÈHŒ´ÄsèÇ¥±N3`7ûæk`£¹}„»Ù{SÜæå ôIüU—éax) (f5ú¢Oæ—‹_©ç:'•`3°ê‚¿ó¸@zz’WêK®—
-•5:t–4p¿ :¨ø¼&p™;ùŽayÌÆÞ3CrÙC^Qù͸kkEFÄéʃ‚Ô ŽÌ/ÆlA¼XÉ‚LWŒO¹ )+þÔ,ÈM¤ÃÏ‹Kl\ÒÌÛëœ Á¾xü!o[‚5¶ÀÌô¾á"O—)$8ÅjV<ášQ{§Ä‹n$Ê$çÊÙµI-êWhHfÑÌ˸œ*y~V-™?
-’U'xsK#U¡ÅÇ5,\Á矩1›rÁ´2žé’©ë9¯q)8¸ýR^óqõN¥*¢6ç´@ÔR’Ü ·¶»›#—¨üe©à¨)Áß1¥!Â
-^ I f–ûj¼Jrrª¸¡¦X•_£Ë6/õ¤hªªI‘¬Ûα2ÉJJÊì!Œ<ü€¿Äkºô+Ê”´¾”p¼¨{ßYöšÈqôÁPêa…UIÒƒrÆ^ìë¥NdºUü5É¡õ«M$%¦j\I£ÂN2ÁÊ»ù)1ÝŸwªƒæ~»/'
-åÒj9)¥ëMÚÙ-Yi‘röË£%ÕVÇ\Œ2pr ýš.ËÅÁ@¡øC•ìiÜi}•%×c{ô\¾¥ÂzÜÖØÅFeÙ ºo)Ê«:WWã‡ãòªŽ©mGÙ(E%Rá1…×Ýgª´™¦dK€QgjS<1¡dUDr`uOÀØwëÜyÆÛæ8yú‘°‹krtÎȵ«°SìûŽñáë•ã¤E4\oXM¦ˆ¸äÞ|²4*;¼7IÞ![bmá¼î0cæÁ‚‚¢†KõVΫ›H¥ŸÍë›'
-é;€ÌÒ«&A‘#ëÎ!,³z½¶õJ÷HJ)µÖ¨nU…:ë`91 Sz¢§X«µ‘ JY‰ O
-ÞtšÖÄ?‹K(d·Lý趬’nÛŒ‚êR)Šõ\Îê,c°]¨‹Aù=K+CÙ!)•½IVÖÒV£”+d!™y¶ò‚J I>XIÚ;Í0U{Sêm„‰âéNCáÈD.gWƒ*<•f‘sÐyk¹ð¸}!G»uƒ’¸LÌ-3s¦bšº±ÌNTš0³ë&õ;+~×þRT/X¦’Ixi/æjãf{®uJ²ü§j¯cŸ:jS¤~~×P+êU€yÞ¤ÎòôX"oe?1³®-Á?:¦úÏ葶#I
-7åTöù˜"Ü‹±°eVÞ1ä¦Q![¦Ö7Û*jQÍScÿòžŸ ‹mÓ¥´ã#5ÄYɲT7ïðãæê*Ÿ~b¤UjY¤ÀÙî!)yöÌf½eÛûçȦ)á1OÞ`(tyÜWN|»0©µŠc