OpenCores
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 27 to Rev 26
    Reverse comparison

Rev 27 → Rev 26

/ADS_RELEASE_1_2_0/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/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/Software/adv_jtag_bridge/sim_lib/modelsim_win32/Makefile =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/sim_lib/modelsim_win32/Makefile (revision 27) +++ ADS_RELEASE_1_2_0/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/Software/adv_jtag_bridge/sim_lib/modelsim_linux_x86/Makefile =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/sim_lib/modelsim_linux_x86/Makefile (revision 27) +++ ADS_RELEASE_1_2_0/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/Software/adv_jtag_bridge/cable_xpc_dlc9.h =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_xpc_dlc9.h (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_xpc_dlc9.h (nonexistent) @@ -1,14 +0,0 @@ - -#ifndef _CABLE_XPC_DLC9_H_ -#define _CABLE_XPC_DLC9_H_ - -#include - -int cable_xpcusb_init(); -int cable_xpcusb_out(uint8_t value); -int cable_xpcusb_inout(uint8_t value, uint8_t *inval); -int cable_xpcusb_opt(int c, char *str); -int cable_xpcusb_read_write_bit(uint8_t packet_out, uint8_t *bit_in); - - -#endif Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_usbblaster.h =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_usbblaster.h (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_usbblaster.h (nonexistent) @@ -1,15 +0,0 @@ - -#ifndef _CABLE_USBBLASTER_H_ -#define _CABLE_USBBLASTER_H_ - -#include - -int cable_usbblaster_init(); -int cable_usbblaster_out(uint8_t value); -int cable_usbblaster_inout(uint8_t value, uint8_t *in_bit); -int cable_usbblaster_write_stream(uint32_t *stream, int len_bits, int set_last_bit); -int cable_usbblaster_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit); -int cable_usbblaster_opt(int c, char *str); -void cable_usbblaster_wait(); - -#endif Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/errcodes.c =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/errcodes.c (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/errcodes.c (nonexistent) @@ -1,54 +0,0 @@ -/* errcodes.c - Error code to plaintext translator 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 "errcodes.h" - -// We can declare the error string with a fixed size, because it can't -// have more than ALL of the error strings in it. Be sure to expand it -// as more errors are added. Also, put a space at the end of each -// error string, as there may be multiple errors. -char errstr[256]; -char *get_err_string(int err) -{ - errstr[0] = '\0'; - - if(err & APP_ERR_COMM) - strcat(errstr, "\'JTAG comm error\' "); - if(err & APP_ERR_MALLOC) - strcat(errstr, "\'malloc failed\' "); - if(err & APP_ERR_MAX_RETRY) - strcat(errstr, "\'max retries\' "); - if(err & APP_ERR_CRC) - strcat(errstr, "\'CRC mismatch\' "); - if(err & APP_ERR_MAX_BUS_ERR) - strcat(errstr, "\'max WishBone bus errors\' "); - if(err & APP_ERR_CABLE_INVALID) - strcat(errstr, "\'Invalid cable\' "); - if(err & APP_ERR_INIT_FAILED) - strcat(errstr, "\'init failed\' "); - if(err & APP_ERR_BAD_PARAM) - strcat(errstr, "\'bad command line parameter\' "); - if(err & APP_ERR_CONNECT) - strcat(errstr, "\'connection failed\' "); - if(err & APP_ERR_USB) - strcat(errstr, "\'USB\' "); - if(err & APP_ERR_CABLENOTFOUND) - strcat(errstr, "\'cable not found\' "); - return errstr; -} Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/opencores_tap.h =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/opencores_tap.h (revision 27) +++ ADS_RELEASE_1_2_0/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/Software/adv_jtag_bridge/errcodes.h =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/errcodes.h (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/errcodes.h (nonexistent) @@ -1,22 +0,0 @@ -#ifndef _ERRCODES_H_ -#define _ERRCODES_H_ - -// Errors in high-level chain transactions -// An error is a 32-bit bit-encoded value -#define APP_ERR_NONE 0x0 -#define APP_ERR_COMM 0x1 -#define APP_ERR_MALLOC 0x2 -#define APP_ERR_MAX_RETRY 0x4 -#define APP_ERR_CRC 0x08 -#define APP_ERR_MAX_BUS_ERR 0x10 -#define APP_ERR_CABLE_INVALID 0x20 -#define APP_ERR_INIT_FAILED 0x40 -#define APP_ERR_BAD_PARAM 0x080 -#define APP_ERR_CONNECT 0x100 -#define APP_ERR_USB 0x200 -#define APP_ERR_CABLENOTFOUND 0x400 -#define APP_ERR_TEST_FAIL 0x0800 - -char *get_err_string(int errval); - -#endif Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_common.c =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_common.c (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_common.c (nonexistent) @@ -1,358 +0,0 @@ -/* cable_common.c -- Interface to the low-level cable drivers - Copyright (C) 2001 Marko Mlinar, markom@opencores.org - Copyright (C) 2004 Gyrgy Jeney, nog@sdf.lonestar.org - Copyright (C) 2008 Nathan Yawn, nathan.yawn@opencores.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 "cable_common.h" -#include "cable_parallel.h" -#include "cable_sim.h" -#include "cable_usbblaster.h" -#include "cable_ft2232.h" -#include "cable_xpc_dlc9.h" -#include "errcodes.h" - -#define debug(...) //fprintf(stderr, __VA_ARGS__ ) - -static struct jtag_cable { - const char *name; - int (*inout_func)(uint8_t, uint8_t *); - int (*out_func)(uint8_t); - int (*init_func)(); - void (*wait_func)(); - int (*opt_func)(int, char *); - int (*bit_out_func)(uint8_t); - int (*bit_inout_func)(uint8_t, uint8_t *); - int (*stream_out_func)(uint32_t *, int, int); - int (*stream_inout_func)(uint32_t *, uint32_t *, int, int); - int (*flush_func)(); - const char *opts; - const char *help; -} jtag_cables[] = { - { "rtl_sim", - cable_rtl_sim_inout, - cable_rtl_sim_out, - cable_rtl_sim_init, - NULL, - cable_rtl_sim_opt, - cable_common_write_bit, - cable_common_read_write_bit, - cable_common_write_stream, - cable_common_read_stream, - NULL, - "d:", - "-d [directory] Directory in which gdb_in.dat/gdb_out.dat may be found\n" }, - { "vpi", - cable_vpi_inout, - cable_vpi_out, - cable_vpi_init, - cable_vpi_wait, - cable_vpi_opt, - cable_common_write_bit, - cable_common_read_write_bit, - cable_common_write_stream, - cable_common_read_stream, - NULL, - "s:p:", - "-p [port] Port number that the VPI module is listening on\n\t-s [server] Server that the VPI module is running on\n" }, - { "xpc3", - cable_xpc3_inout, - cable_xpc3_out, - cable_parallel_init, - cable_parallel_phys_wait, - cable_parallel_opt, - cable_common_write_bit, - cable_common_read_write_bit, - cable_common_write_stream, - cable_common_read_stream, - NULL, - "p:", - "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n" }, - { "xess", - cable_xess_inout, - cable_xess_out, - cable_parallel_init, - cable_parallel_phys_wait, - cable_parallel_opt, - cable_common_write_bit, - cable_common_read_write_bit, - cable_common_write_stream, - cable_common_read_stream, - NULL, - "p:", - "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n" }, -#ifdef __SUPPORT_USB_CABLES__ - { "usbblaster", - cable_usbblaster_inout, - cable_usbblaster_out, - cable_usbblaster_init, - NULL, - cable_usbblaster_opt, - cable_common_write_bit, - cable_common_read_write_bit, - cable_usbblaster_write_stream, - cable_usbblaster_read_stream, - NULL, - "", - "no options\n" }, - { "xpc_usb", - cable_xpcusb_inout, - cable_xpcusb_out, - cable_xpcusb_init, - NULL, - cable_xpcusb_opt, - cable_common_write_bit, - cable_xpcusb_read_write_bit, - cable_common_write_stream, - cable_common_read_stream, - NULL, - "", - "no options\n" }, -#ifdef __SUPPORT_FTDI_CABLES__ - { "ft2232", - NULL, - NULL, - cable_ftdi_init, - NULL, - cable_ftdi_opt, - cable_ftdi_write_bit, - cable_ftdi_read_write_bit, - cable_ftdi_write_stream, - cable_ftdi_read_stream, - cable_ftdi_flush, - "", - "no options\n" }, -#endif // __SUPPORT_FTDI_CABLES__ -#endif // __SUPPORT_USB_CABLES__ - { NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL } }; - -static struct jtag_cable *jtag_cable_in_use = NULL; /* The currently selected cable */ - - -///////////////////////////////////////////////////////////////////////////////////// -// Cable subsystem / init functions - - -/* Selects a cable for use */ -int cable_select(const char *cable) -{ - int i; - - for(i = 0; jtag_cables[i].name; i++) { - if(!strcmp(cable, jtag_cables[i].name)) { - jtag_cable_in_use = &jtag_cables[i]; - return APP_ERR_NONE; - } - } - - return APP_ERR_CABLE_INVALID; -} - -/* Calls the init function of the cable - */ -int cable_init() -{ - return jtag_cable_in_use->init_func(); -} - -/* Parses command-line options specific to the selected cable */ -int cable_parse_opt(int c, char *str) -{ - return jtag_cable_in_use->opt_func(c, str); -} - -const char *cable_get_args() -{ - if(jtag_cable_in_use != NULL) - return jtag_cable_in_use->opts; - else - return NULL; -} - -/* Prints a (short) useage message for each available cable */ -void cable_print_help() -{ - int i; - printf("Available cables: "); - - for(i = 0; jtag_cables[i].name; i++) { - if(i) - printf(", "); - printf("%s", jtag_cables[i].name); - } - - printf("\n\nOptions availible for the cables:\n"); - for(i = 0; jtag_cables[i].name; i++) { - if(!jtag_cables[i].help) - continue; - printf(" %s:\n %s", jtag_cables[i].name, jtag_cables[i].help); - } -} - - -///////////////////////////////////////////////////////////////////////////////// -// Cable API Functions - -int cable_write_stream(uint32_t *stream, int len_bits, int set_last_bit) { - return jtag_cable_in_use->stream_out_func(stream, len_bits, set_last_bit); -} - -int cable_read_write_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit) { - return jtag_cable_in_use->stream_inout_func(outstream, instream, len_bits, set_last_bit); -} - -int cable_write_bit(uint8_t packet) { - return jtag_cable_in_use->bit_out_func(packet); -} - -int cable_read_write_bit(uint8_t packet_out, uint8_t *bit_in) { - return jtag_cable_in_use->bit_inout_func(packet_out, bit_in); -} - -int cable_flush(void) { - if(jtag_cable_in_use->flush_func != NULL) - return jtag_cable_in_use->flush_func(); - return APP_ERR_NONE; -} - - -///////////////////////////////////////////////////////////////////////////////////// -// Common functions which may or may not be used by individual drivers - - -/* Note that these make no assumption as to the starting state of the clock, - * and they leave the clock HIGH. But, these need to interface with other routines (like - * the byte-shift mode in the USB-Blaster), which begin by assuming that a new - * data bit is available at TDO, which only happens after a FALLING edge of TCK. - * So, routines which assume new data is available will need to start by dropping - * the clock. - */ -int cable_common_write_bit(uint8_t packet) { - uint8_t data = TRST_BIT; // TRST is active low, don't clear unless /set/ in 'packet' - int err = APP_ERR_NONE; - - /* Write data, drop clock */ - if(packet & TDO) data |= TDI_BIT; - if(packet & TMS) data |= TMS_BIT; - if(packet & TRST) data &= ~TRST_BIT; - - err |= jtag_cable_in_use->out_func(data); - if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func(); - - /* raise clock, to do write */ - err |= jtag_cable_in_use->out_func(data | TCLK_BIT); - if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func(); - - return err; -} - -int cable_common_read_write_bit(uint8_t packet_out, uint8_t *bit_in) { - uint8_t data = TRST_BIT; // TRST is active low, don't clear unless /set/ in 'packet' - int err = APP_ERR_NONE; - - /* Write data, drop clock */ - if(packet_out & TDO) data |= TDI_BIT; - if(packet_out & TMS) data |= TMS_BIT; - if(packet_out & TRST) data &= ~TRST_BIT; - - err |= jtag_cable_in_use->out_func(data); // drop the clock to make data available, set the out data - if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func(); - err |= jtag_cable_in_use->inout_func((data | TCLK_BIT), bit_in); // read in bit, clock high for out bit. - if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func(); - - return err; -} - - -/* Writes bitstream via bit-bang. Can be used by any driver which does not have a high-speed transfer function. - * Transfers LSB to MSB of stream[0], then LSB to MSB of stream[1], etc. - */ -int cable_common_write_stream(uint32_t *stream, int len_bits, int set_last_bit) { - int i; - int index = 0; - int bits_this_index = 0; - uint8_t out; - int err = APP_ERR_NONE; - - debug("writeSrrm%d(", len_bits); - for(i = 0; i < len_bits - 1; i++) { - out = (stream[index] >> bits_this_index) & 1; - err |= cable_write_bit(out); - debug("%i", out); - bits_this_index++; - if(bits_this_index >= 32) { - index++; - bits_this_index = 0; - } - } - - out = (stream[index] >>(len_bits - 1)) & 0x1; - if(set_last_bit) out |= TMS; - err |= cable_write_bit(out); - debug("%i)\n", out); - return err; -} - -/* Gets bitstream via bit-bang. Can be used by any driver which does not have a high-speed transfer function. - * Transfers LSB to MSB of stream[0], then LSB to MSB of stream[1], etc. - */ -int cable_common_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit) { - int i; - int index = 0; - int bits_this_index = 0; - uint8_t inval, outval; - int err = APP_ERR_NONE; - - instream[0] = 0; - - debug("readStrm%d(", len_bits); - for(i = 0; i < (len_bits - 1); i++) { - outval = (outstream[index] >> bits_this_index) & 0x1; - err |= cable_read_write_bit(outval, &inval); - debug("%i", inval); - instream[index] |= (inval << bits_this_index); - bits_this_index++; - if(bits_this_index >= 32) { - index++; - bits_this_index = 0; - instream[index] = 0; // It's safe to do this, because there's always at least one more bit - } - } - - if (set_last_bit) - outval = ((outstream[index] >> (len_bits - 1)) & 1) | TMS; - else - outval = (outstream[index] >> (len_bits - 1)) & 1; - - err |= cable_read_write_bit(outval, &inval); - debug("%i", inval); - instream[index] |= (inval << bits_this_index); - - debug(") = 0x%lX\n", instream[0]); - - return err; -} - - - Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/bsdl_parse.c =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/bsdl_parse.c (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/bsdl_parse.c (nonexistent) @@ -1,487 +0,0 @@ -/* bsdl_parse.c - BSDL parser 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 // isspace(), etc. -#include // malloc(), strtoul(), etc. -#include "bsdl.h" // has constants - - -#define debug(...) //fprintf(stderr, __VA_ARGS__ ) - -char * strtoupper(char *str); -int get_line(char *filedata, int startpos, char **linedata, int filesize); -char * strchr_s(char *str, char *chars); -void parse_opcodes(char *cmdbuf, uint32_t *debug_cmd, uint32_t *user1_cmd, uint32_t *idcode_cmd); - -// We assume that no value will be more than 128 chars -char tmpbuf[128]; - - - ///////////////////////////////////////////////////////////////// - // API call: extract desired info from 1 BSDL fise - -bsdlinfo *parse_extract_values(char *bsdlfilename) -{ - FILE *fd; - int filesize; - bsdlinfo *ret; - char *filedata; - char *linedata; - char *token; - char *last; - char *cmdbuf; - int filepos = 0; - int i,j; - char done,valid,opens; - - int IR_size = -1; - uint8_t found_IR_size = 0; - uint32_t debug_cmd = TAP_CMD_INVALID; - uint32_t user1_cmd = TAP_CMD_INVALID; - uint32_t idcode_cmd = TAP_CMD_INVALID; - uint8_t found_cmds = 0; - uint32_t idcode = 0; - uint32_t idcode_mask = 0xFFFFFFFF; // 'X' is a valid char in an IDCODE, set 0's here for X's. - uint8_t found_idcode = 0; - char *entityname = NULL; - - // Open the file - fd = fopen(bsdlfilename, "r"); - if(fd == NULL) { - printf("ERROR: failed to open BSDL file %s\n", bsdlfilename); - return NULL; - } - - fseek(fd, 0, SEEK_END); - filesize = ftell(fd); - fseek(fd, 0, SEEK_SET); - - filedata = (char *) malloc(filesize); - if(filedata == NULL) { - printf("ERROR: failed to allocate memory for BSDL file %s\n", bsdlfilename); - return NULL; - } - - if(fread(filedata, 1, filesize, fd) < filesize) { // 1 long read will be faster than many short ones - printf("Warning: failed to read entire BSDL file %s\n", bsdlfilename); - } - - fclose(fd); - - - // while there's more data and not all values have been found - while((filepos < filesize) && (!found_IR_size || !found_cmds || !found_idcode)) - { - // Get a line. Replace any "--" with a \0 char - filepos = get_line(filedata, filepos, &linedata, filesize); - - // look for each value - token = strtok_r(linedata, " \t", &last); - if(token == NULL) { - printf("ERROR: End of file reached before END statement is BSDL file \'%s\'\n", bsdlfilename); - break; - } - - if(!strcmp(strtoupper(token), "ENTITY")) { - // Parse an entity line - token = strtok_r(NULL, " \t", &last); - if(token != NULL) { - entityname = (char *) malloc(strlen(token)); - if(entityname != NULL) strcpy(entityname, token); - debug("Found entity \'%s\'\n", entityname); - } else { - printf("Parse error near ENTITY token in file %s\n", bsdlfilename); - } - } - else if(!strcmp(strtoupper(token), "CONSTANT")) { - // Parse a constant declaration...we ignore them, just get lines until we find a ';' char - // assume nothing else useful comes on the line after the ';' - // Slightly awkward, since we have to search the rest of the line after the strtok, then possible - // new lines as well. - token = strtok_r(NULL, " \t", &last); // debug...don't worry about error, token only used in printf - debug("Ignoring constant \'%s\'\n", token); // debug - while(strchr(last, ';') == NULL) { - filepos = get_line(filedata, filepos, &last, filesize); - } - } - else if(!strcmp(strtoupper(token), "GENERIC")) { - // Parse a generic declaration...we ignore them, just get lines until we find a ';' char - // assume nothing else useful comes on the line after the ';' - // Slightly awkward, since we have to search the rest of the line after the strtok, then possible - // new lines as well. - token = strtok_r(NULL, " \t", &last); // debug...don't worry about error, token only used in printf - debug("Ignoring generic \'%s\'\n", token); // debug - while(strchr(last, ';') == NULL) { - filepos = get_line(filedata, filepos, &last, filesize); - } - } - else if(!strcmp(strtoupper(token), "USE")) { - // Parse a 'use' declaration...we ignore them, just get lines until we find a ';' char - // assume nothing else useful comes on the line after the ';' - // Note that there may be no space after the token, so add ';' to the tokenizing list in the debug bits. - // Slightly awkward, since we have to search the rest of the line after the strtok, then possible - // new lines as well. - token = strtok_r(NULL, " \t;", &last); // debug ...don't worry about error, token only used in printf - debug("Ignoring use \'%s\'\n", token); // debug - while(strchr(last, ';') == NULL) { - filepos = get_line(filedata, filepos, &last, filesize); - } - } - else if(!strcmp(strtoupper(token), "END")) { - // We're done, whether we've found what we want or not. Eject eject eject... - debug("Found END token, stopping parser\n"); - break; - } - else if(!strcmp(strtoupper(token), "PORT")) { - // Parse a port list. Find a '(', find a ')', find a ';'. - // Note that "()" pairs may occur in between. - // 'last' must be set in the first two strchr() calls so that the next strchr() call will - // begin parsing after the previous char position. Otherwise, e.g. a ';' before the ')' but on the same - // line would (incorrectly) satisfy the search. - while((last = strchr(last, '(')) == NULL) { - filepos = get_line(filedata, filepos, &last, filesize); - } - opens = 1; - last++; // don't leave 'last' pointing at the '(' char, since we're looking for another - - do { - while((last = strchr_s(last, "()")) == NULL) { - filepos = get_line(filedata, filepos, &last, filesize); // *** abort if new line is empty - } - if(*last == '(') opens++; - else if(*last == ')') opens--; - last++; // don't leave last pointing at the same "()" char, since we're looking for another - } while(opens); - - - while(strchr(last, ';') == NULL) { - filepos = get_line(filedata, filepos, &last, filesize); - } - debug("Ignored port statement\n"); - } - else if(!strcmp(strtoupper(token), "ATTRIBUTE")) { - // Parse an attribute - token = strtok_r(NULL, " \t", &last); // *** check for error - if(!strcmp(strtoupper(token), "INSTRUCTION_LENGTH")) { - // Find ':', then "entity", then "is", then take anything before the ';' as the value - while((last = strchr(last, ':')) == NULL) { - filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? - } - while((last = strstr(last, "entity")) == NULL) { // don't do strtoupper() here, that would do the entire line - filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? - } - while((last = strstr(last, "is")) == NULL) { - filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? - } - - // scan until the end of the line looking for data - j = 0; - done = 0; - while(*last != '\0') { - if(isdigit(*last)) tmpbuf[j++] = *last; - else if(*last == ';') { done = 1; break;} - last++; - } - // May need to go to additional lines - while(!done) { - filepos = get_line(filedata, filepos, &linedata, filesize); // *** break if linedata has no data - while(*linedata != '\0') { - if(isdigit(*linedata)) tmpbuf[j++] = *linedata; - else if(*linedata == ';') { done = 1; break;} - linedata++; - } - } - - tmpbuf[j] = '\0'; - IR_size = strtoul(tmpbuf, NULL, 0); - found_IR_size = 1; - debug("Found IR size %i (%s)\n", IR_size, tmpbuf); - } // end if INSTRUCTION_LENGTH - - else if(!strcmp(strtoupper(token), "INSTRUCTION_OPCODE")) { - // Find ": entity is" - while((last = strchr(last, ':')) == NULL) { - filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? - } - while((last = strstr(last, "entity")) == NULL) { // don't do strtoupper() here, that would do the entire line - filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? - } - while((last = strstr(last, "is")) == NULL) { - filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? - } - - // We're going to copy the entire attribute (all commands) into a temp. buffer. We need a big enough buffer, - // and we can't just scan for ';' to find out because there's a '\0' at the end of this line. - // But, it can't be bigger than the entire rest of the file, so... - cmdbuf = (char *) malloc(filesize-filepos); - // Parse until ';', and grab everything between each pair of "" found - // Note that 'last' still points at "is" - j = 0; - done = 0; - valid = 0; - while(*last != '\0') { - if(*last == ';') { done = 1; break;} // Put this first in case of badly formed BSDL files - else if(valid && (*last != '\"')) cmdbuf[j++] = *last; - else if(*last == '\"') valid = !valid; - last++; - } - // May need to go to additional lines - while(!done) { - filepos = get_line(filedata, filepos, &linedata, filesize); // *** break if linedata has no data - while(*linedata != '\0') { - if(valid && (*linedata != '\"')) cmdbuf[j++] = *linedata; - else if(*linedata == '\"') valid = !valid; - else if(*linedata == ';') { done = 1; break;} - linedata++; - } - } - cmdbuf[j] = '\0'; - - // Parse the opcodes attribute. This is an exercise unto itself, so do it in another function. - parse_opcodes(cmdbuf, &debug_cmd, &user1_cmd, &idcode_cmd); - found_cmds = 1; - free(cmdbuf); - - } // end if INSTRUCTION_OPCODE - - else if(!strcmp(strtoupper(token), "IDCODE_REGISTER")) { - // Find : entity is - while((last = strchr(last, ':')) == NULL) { - filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? - } - while((last = strstr(last, "entity")) == NULL) { // don't do strtoupper() here, that would do the entire line - filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? - } - while((last = strstr(last, "is")) == NULL) { - filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? - } - - // Parse until ';', and grab everything between each pair of "" found - // Note that 'last' still points at "is" - j = 0; - done = 0; - valid = 0; - while(*last != '\0') { - if(*last == ';') { done = 1; break;} // Put this first in case of badly formed BSDL files - else if(valid && (*last != '\"')) tmpbuf[j++] = *last; - else if(*last == '\"') valid = !valid; - last++; - } - // May need to go to additional lines - while(!done) { - filepos = get_line(filedata, filepos, &linedata, filesize); // *** break if linedata has no data - while(*linedata != '\0') { - if(valid && (*linedata != '\"')) tmpbuf[j++] = *linedata; - else if(*linedata == '\"') valid = !valid; - else if(*linedata == ';') { done = 1; break;} - linedata++; - } - } - tmpbuf[j] = '\0'; - - // Parse the tmpbuf - if(j != 32) printf("Warning: found %i chars (expected 32) while getting IDCODE in BSDL file %s.\n", j, bsdlfilename); // Sanity check - debug("Got IDCODE string \'%s\'\n", tmpbuf); - for(i = 0; i < j; i++) { - if(tmpbuf[i] == '1') idcode |= 0x1<<(31-i); - else if(toupper(tmpbuf[i]) == 'X') idcode_mask &= ~(0x1<<(31-i)); - } - debug("Found IDCODE 0x%08X (%s), mask is 0x%08X\n", idcode, tmpbuf, idcode_mask); - found_idcode = 1; - - } // end if IDCODE_REGISTER - - else { - debug("Ignoring attribute \'%s\'\n", token); - // Consume chars until ';' found - while(strchr(last, ';') == NULL) { - filepos = get_line(filedata, filepos, &last, filesize); - } - } - } - else { - debug("Unknown token \'%s\' found in BSDL file %s\n", token, bsdlfilename); - } - } - - free(filedata); - - // Put the data in a struct for return and storage - ret = (bsdlinfo *) malloc(sizeof(bsdlinfo)); - if(ret == NULL) { - printf("Error: out of memory, unable to store BSDL info for file %s\n", bsdlfilename); - return NULL; - } - - ret->name = entityname; // this was malloc'd, so it's persistant, this is safe - ret->idcode = idcode; - ret->idcode_mask = idcode_mask; - ret->IR_size = IR_size; - ret->cmd_debug = debug_cmd; - ret->cmd_user1 = user1_cmd; - ret->cmd_idcode = idcode_cmd; - ret->next = NULL; - - return ret; -} - - - -////////////////////////////////////////////////////////////////////////////////////////////// -// Local / helper functions - - -// Returns 1 line from a complete file buffer pointed to by *filedata. Removes leading -// whitespace, ignores comment lines, removes trailing comments (comments denoted by "--") -// startpos: index in filedata[] to start looking for a new line. -// linedata: set to point to the first char of the new line. -// filesize: used so we don't go past the end of filedata[] -// The return value is the first index after the returned line. This may be 1 past the end of the buffer. -int get_line(char *filedata, int startpos, char **linedata, int filesize) -{ - int lineidx = startpos; - unsigned char loop; - char *commentptr; - - do { - loop = 0; - while(isspace(filedata[lineidx]) && (lineidx < filesize)) lineidx++; // burn leading whitespace chars - - if(lineidx >= (filesize-1)) { // We look at the data at lineidx and lineidx+1...don't look at invalid offsets. - lineidx = filesize-1; - break; - } - - if((filedata[lineidx] == '-') && (filedata[lineidx+1] == '-')) - { // then this is a full-line comment, with no useful data - while(((filedata[lineidx] != '\n') && (filedata[lineidx] != '\r')) && (lineidx < filesize)) - lineidx++; // burn comment line up to CR/LF - loop = 1; - } - } while(loop); - - // Set the line pointer - *linedata = &filedata[lineidx]; - - // Put a NULL char at the newline - while(!iscntrl(filedata[lineidx]) && (lineidx < filesize)) lineidx++; - if(lineidx >= filesize) { // Don't write past the end of the array. - lineidx = filesize-1; - } - filedata[lineidx] = '\0'; - - // Put a NULL at the first "--" string, if any - commentptr = strstr(*linedata, "--"); - if(commentptr != NULL) *commentptr = '\0'; - - return lineidx+1; -} - - -// In-place string capitalizer -char * strtoupper(char *str) -{ - int i = 0; - - while(str[i] != '\0') { - str[i] = toupper(str[i]); - i++; - } - - return str; -} - -// Searches a string 'str' for the first occurance of any -// character in the string 'chars'. Returns a pointer to -// the char in 'str' if one is found, returns NULL if -// none of the chars in 'chars' are present in 'str'. -char * strchr_s(char *str, char *chars) -{ - int slen = strlen(chars); - char *ptr = str; - int i; - - while(*ptr != '\0') { - for(i = 0; i < slen; i++) { - if(*ptr == chars[i]) - return ptr; - } - ptr++; - } - - return NULL; -} - - -// Parses a string with command name / opcode pairs of the format -// EXTEST (1111000000),SAMPLE (1111000001), [...] -// There may or may not be a space between the name and the open paren. -// We do not assume a comma after the last close paren. -#define TARGET_DEBUG 1 -#define TARGET_USER1 2 -#define TARGET_IDCODE 3 -void parse_opcodes(char *cmdbuf, uint32_t *debug_cmd, uint32_t *user1_cmd, uint32_t *idcode_cmd) -{ - char *saveptr = NULL; - char *cmd; - char *token; - char *saveptr2; - int target; - int opcode; - - cmd = strtok_r(cmdbuf, ",", &saveptr); - while(cmd != NULL) - { - // 'cmd' should now have one pair in the form "EXTEST (1111000000)" - target = 0; - token = strtok_r(cmd, " \t(", &saveptr2); - if(!strcmp(strtoupper(token), "DEBUG")) { - target = TARGET_DEBUG; - debug("Found DEBUG opcode: "); - } - else if(!strcmp(strtoupper(token), "USER1")) { - target = TARGET_USER1; - debug("Found USER1 opcode:"); - } - else if(!strcmp(strtoupper(token), "IDCODE")) { - target = TARGET_IDCODE; - debug("Found IDCODE opcode: "); - } - - if(target) { // don't parse opcode number unless necessary - token = strtok_r(NULL, " \t()", &saveptr2); - if(token != NULL) { - opcode = strtoul(token, NULL, 2); // *** Test for errors - debug("0x%X (%s)\n", opcode, token); - - if(target == TARGET_DEBUG) *debug_cmd = opcode; - else if(target == TARGET_USER1) *user1_cmd = opcode; - else if(target == TARGET_IDCODE) *idcode_cmd = opcode; - } - else { - printf("Error: failed to find opcode value after identifier.\n"); - } - } - - cmd = strtok_r(NULL, ",", &saveptr); - } - - -} Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_sim.c =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_sim.c (revision 27) +++ ADS_RELEASE_1_2_0/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 Gyrgy 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/Software/adv_jtag_bridge/cable_parallel.c =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_parallel.c (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_parallel.c (nonexistent) @@ -1,191 +0,0 @@ -/* cable_parallel.c - Parallel cable drivers (XPC3 and XESS) for the Advanced JTAG Bridge - Copyright (C) 2001 Marko Mlinar, markom@opencores.org - Copyright (C) 2004 Gyrgy 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 // for inb(), outb() -#include -#include - -#include "cable_common.h" -#include "errcodes.h" - - -#define LPT_READ (base+1) -#define LPT_WRITE base - -// Common functions used by both cable types -static int cable_parallel_out(uint8_t value); -static int cable_parallel_inout(uint8_t value, uint8_t *inval); - - -static int base = 0x378; - - - -///////////////////////////////////////////////////////////////////////////////// -/*-------------------------------------[ Parallel port specific functions ]---*/ -/////////////////////////////////////////////////////////////////////////////// - -int cable_parallel_init() -{ - - //#ifndef WIN32 - if (ioperm(base, 3, 1)) { - fprintf(stderr, "Couldn't get the port at %x\n", base); - perror("Root privileges are required.\n"); - return APP_ERR_INIT_FAILED; - } - printf("Connected to parallel port at %x\n", base); - printf("Dropping root privileges.\n"); - setreuid(getuid(), getuid()); - //#endif - - return APP_ERR_NONE; -} - - -int cable_parallel_opt(int c, char *str) -{ - switch(c) { - case 'p': - if(!sscanf(str, "%x", &base)) { - fprintf(stderr, "p parameter must have a hex number as parameter\n"); - return APP_ERR_BAD_PARAM; - } - break; - default: - fprintf(stderr, "Unknown parameter '%c'\n", c); - return APP_ERR_BAD_PARAM; - } - return APP_ERR_NONE; -} - -/*-----------------------------------------[ Physical board wait function ]---*/ -void cable_parallel_phys_wait() -{ - usleep(10); -} - -/*----------------------------------------------[ xpc3 specific functions ]---*/ -int cable_xpc3_out(uint8_t value) -{ - uint8_t out = 0; - - /* First convert the bits in value byte to the ones that the cable wants */ - if(value & TCLK_BIT) - out |= 0x02; /* D1 pin 3 */ - if(value & TRST_BIT) - out |= 0x10; /* Not used */ - if(value & TDI_BIT) - out |= 0x01; /* D0 pin 2 */ - if(value & TMS_BIT) - out |= 0x04; /* D2 pin 4 */ - - return cable_parallel_out(out); -} - -int cable_xpc3_inout(uint8_t value, uint8_t *inval) -{ - uint8_t in; - int retval; - uint8_t out = 0; - - /* First convert the bits in value byte to the ones that the cable wants */ - if(value & TCLK_BIT) - out |= 0x02; /* D1 pin 3 */ - if(value & TRST_BIT) - out |= 0x10; /* Not used */ - if(value & TDI_BIT) - out |= 0x01; /* D0 pin 2 */ - if(value & TMS_BIT) - out |= 0x04; /* D2 pin 4 */ - - retval = cable_parallel_inout(out, &in); - - if(in & 0x10) /* S6 pin 13 */ - *inval = 1; - else - *inval = 0; - - return retval; -} - -/*----------------------------------------------[ xess specific functions ]---*/ -int cable_xess_out(uint8_t value) -{ - uint8_t out = 0; - - /* First convert the bits in value byte to the ones that the cable wants */ - if(value & TCLK_BIT) - out |= 0x04; /* D2 pin 4 */ - if(value & TRST_BIT) - out |= 0x08; /* D3 pin 5 */ - if(value & TDI_BIT) - out |= 0x10; /* D4 pin 6 */ - if(value & TMS_BIT) - out |= 0x20; /* D3 pin 5 */ - - return cable_parallel_out(out); -} - -uint8_t cable_xess_inout(uint8_t value, uint8_t *inval) -{ - uint8_t in; - int retval; - uint8_t out = 0; - - /* First convert the bits in value byte to the ones that the cable wants */ - if(value & TCLK_BIT) - out |= 0x04; /* D2 pin 4 */ - if(value & TRST_BIT) - out |= 0x08; /* D3 pin 5 */ - if(value & TDI_BIT) - out |= 0x10; /* D4 pin 6 */ - if(value & TMS_BIT) - out |= 0x20; /* D3 pin 5 */ - - retval = cable_parallel_inout(out, &in); - - if(in & 0x20) /* S5 pin 12*/ - *inval = 1; - else - *inval = 0; - - return retval; -} - - -/*----------------------------------------------[ common helper functions ]---*/ -// 'static' for internal access only - -static int cable_parallel_out(uint8_t value) -{ - outb(value, LPT_WRITE); - return APP_ERR_NONE; -} - -static int cable_parallel_inout(uint8_t value, uint8_t *inval) -{ - *inval = inb(LPT_READ); - outb(value, LPT_WRITE); - - return APP_ERR_NONE; -} Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_common.h =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_common.h (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_common.h (nonexistent) @@ -1,44 +0,0 @@ - -#ifndef _CABLE_COMMON_H_ -#define _CABLE_COMMON_H_ - -#include - -// Defines to use in the 'packet' args of cable_write_bit() -// and cable_read_write_bit(). Note that while TRST is -// active low for JTAG hardware, here the TRST bit -// should be set when you want the TRST wire active -// (JTAG TAP to be reset). -#define TRST (0x04) -#define TMS (0x02) -#define TDO (0x01) - -// These should only be used in the cable_* files. -#define TCLK_BIT (0x01) -#define TRST_BIT (0x02) -#define TDI_BIT (0x04) -#define TMS_BIT (0x08) -#define TDO_BIT (0x20) - -// Cable subsystem / init routines -int cable_select(const char *cable); -int cable_init(); -int cable_parse_opt(int c, char *str); -const char *cable_get_args(); -void cable_print_help(); - - -// Cable API routines -int cable_write_bit(uint8_t packet); -int cable_read_write_bit(uint8_t packet_out, uint8_t *bit_in); -int cable_write_stream(uint32_t *stream, int len_bits, int set_last_bit); -int cable_read_write_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit); -int cable_flush(void); - -// Common functions for lower-level drivers to use as desired -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); - -#endif Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/bsdl_parse.h =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/bsdl_parse.h (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/bsdl_parse.h (nonexistent) @@ -1,9 +0,0 @@ -#ifndef _BSDL_PARSE_H_ -#define _BSDL_PARSE_H_ - -#include "bsdl.h" // need definition of bsdlinfo here - - -bsdlinfo * parse_extract_values(char *bsdlfilename); - -#endif Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_sim.h =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_sim.h (revision 27) +++ ADS_RELEASE_1_2_0/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/Software/adv_jtag_bridge/doc/gpl-2.0.txt =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/gpl-2.0.txt (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/gpl-2.0.txt (nonexistent) @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, 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. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program 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. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public 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. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/License_FDL-1.2.txt =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/License_FDL-1.2.txt (revision 27) +++ ADS_RELEASE_1_2_0/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/Software/adv_jtag_bridge/doc/adv_jtag_bridge.pdf =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/adv_jtag_bridge.pdf (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/adv_jtag_bridge.pdf (nonexistent) @@ -1,2502 +0,0 @@ -%PDF-1.4 -%äüöß -2 0 obj -<> -stream -xmN0 E -8F"y a>[`Jch :03v^>؞ÛF-CzrK$z}(H\;.k *وJTs\i8 #zUZEjB?7f3݂lpB&.qܬ| +"h9} z3rX"Y(ר#Dž:.q3+^$j<尐;##8Ezod u.sz9i11y -BF0<;T} -endstream -endobj - -3 0 obj -290 -endobj - -5 0 obj -<> -stream -xVF ty3޶ -Pz J{#p<I;CqM5ҳd<]}q6Gr ]2\n}tܦ%4}O;`!~Y{n!.!p%Dހ(~"j0m -5 &5~̈́mY&0<*dd# q Y!!?:faE,XQ, W)d'PHk!2*&g J!N (ݖͤgHI4/XZ -SZфFUdZ""rd4{* -ͻCcoQ9m(Vhjs"C+9B=7hJ6%L㸃]ryBFBCJ˭P+yѽUBly*;BQ?R.LwkEl9g!D'x{92W -VE+]< -sƌ:y,,XDI5ȸT49}r -r A^ #+}oB>]X_z -endstream -endobj - -6 0 obj -1105 -endobj - -8 0 obj -<> -stream -xV +8F,%RoF^JK0 fNe3y#[%6w!AUOIiۯ d --Э^o=AVCȶ#8 -*P2P^*ow>GA>[|<bnyrH`" f#h6F49\d{Ed GZd*+{F^8C|:~z0 ;_?5kҼ3YT0\ ǵ|gor:|~ƘXH2)N -)a\P^FJ(h"EeRR¸L)\P"DRˤ8)q2RBd)D:LD&3iƸl iFt iFiABbTr]QQ4W꽊W -s_A^פt~(}mh]m޳fbټ"O6tm~ -BCW&s}^F(W7&ޏ܏Ksbw̻h.Y,DO.ѡ0U./Nhyih9)8`.Jk[)I5kQ0х-CC`n?eFVU84%pՏʏ^zGEx\;g0BjpINf6@ ԭC -.%N -`?ՠFఇBY1T¹Oj-ll[F¦`: \ySδDtNg --صp`iCZQ'گ2E5?*DwR^*dK*F -4+n1iy,9.%|Ti³QasSNL;YY+6˅ P -endstream -endobj - -9 0 obj -854 -endobj - -11 0 obj -<> -stream -xK6:K_"@X[z(zk%_3${yĔBX{)z?΋d}}XgRstw/ݿM|/;}gz~/S^:fK_n>dGe qr,@1Ξ( wF?%>ͪra^̔~|DF6"THS\ %qs' -JMe@{0/ -/^!1΋iS?OL(8yŌ O{n -_{IfZ_d`KR -~V?.uAV8yb,|szpS*AQWk6B]nkpgDEG?,i"FO޲)5{%nuĊ/[kѾ[N";.I¢)D({BF,F -O%Bsj٫ڲrpȃ.g܏̐2#6E潎N:JT aFGur2r 'mAݬ<9?Oy0W-U(cKpA<5 -O\]ĦkD0 j CWbu)1CZIOzVn!3ps=?s^gSkHWnٮgpfc1 -|G>Mv[ޭcbGǚ٦d'7yTc<=yJoϤ7ǶwQk=%XHwkݵP&N8CPhfbw,NZ&`Eo&ߒ`?wP9GQYyޔp(;\k6{/ufqI/ Qq{b\K%#Zk&v,+9H6u rSypŃsc6s\^ȉ)/daE+ja.""dJݤ1խ -Fs[">(eճk/N¨yz9Wwаl'Mmh(7tk~WNK kJ$iqk0qB!|FCS螊HKNAL iYvY $ܜ[aJ0c% bsϾpQ>2n r]&]52z뉚KCiMO{D-10BJlW,dø9VunPȟ32jÓPU#+q=@sD2 -endstream -endobj - -12 0 obj -1258 -endobj - -14 0 obj -<> -stream -x\I#ϯ0\k!.=|0]K3`ZReeKzӗ~E]v&{|?e?}旷-.tU}ܾ۫:no~.]>~W/{|L+wsU&h /`Y} -,o%lݖrk>ކ 7{Y}shWc/agjy8Vxtz})ct8vZC>^FǫSo`K.0Kxtpyg\ݥkzʫx\K\s~fL*kioQd|vKC7776g*jAWXUӁ (+Xx7`DT{E= I8m`d-[ojkF7*2R8Mn3(t0ծ7c4_PAh?n5.~G@*Fw ah|x`ligFNd7G.#Hwe;a Q $^k,'pcw:P6n~* Y=Fx`#^G-] - *@(t& -;LւD uINDCPY z.IA#f1z<2\k;==j*,~\ - m|}ϧa`u54$X,B+$I${u~~01%)p`Z8<Z@2@!m.gf9K76$2yMJx׷ڙZ >,uRe9ȃ_Y\AsHek&T6#gÈHsǥN3`7k`}{SIUax) (f5O 旋_©:'`3ꂿ@zzWK -5:t4p :&p;ay3CrC^Q͸kkEFʃ ̭/lAXɂLWO)+,MϋKl\ x!o[5̐"O)$8jV<Q{ċn$$ٵI-WhHf ˸*y~V-? -U'xsK#U5,\灟1r2钩9q)8R^qN*6@R #e)1! -^ I fjJrrX_6/hIα2JJ!A=K+C!)IVV+d!yJ I>XI;0U{SmNCD.gW*mgFŀ ZXT2Yj'#FaۢlA~9I3Wx,uI'~8 -sǺC´GtBsT ;NAS ->.a -endstream -endobj - -15 0 obj -3576 -endobj - -17 0 obj -<> -stream -x[ˎ߯:@w,mw/,2 E~ /} +KYij/b./>.uK?]_~׏qy^V\.]q9> vYnZ 7uf>,xΙYzƛyM7mﶎDn`,L[ L(M+]/qË8ȃm <" Ơ@+p -?`~ICė0rzzQpZ4C: E߿/-f1h0'ek^}2[k1)fhZs`-} gaQm`;!wɜ.,V~8 -J&%' +"K+;']yХ3+V@9T&.҈3}|]@ lkl;כ+>ZD|ɂ?$1JF(E˿~71c&Xq.,,54ND"_~T̞%N7eD1QRCv +?\ʈ:hXk(+y=ϼh K@x}H%K0٣ c8? --N' Y&eGWɦ&ŧ\Fwh+U6q] -ReLӦUɆBl6yɞ,̌w/5TL&}srHQKO~Wѫ+f[6wqʞ9@AX|B&iUBT,iPs0s(rm`Dr [d"iUH$$e fzW_TؔL#$0zS):I`@ kC FuE ZJ2-#|GP-pFkw$Y6͎B6Ԧ>쟄 R*u?I(Ͼ:go='-vTlj#]@) `4 -JQu0^X.6z,Ɵg<:m_ͼ#89gM+ -L`a ]e(AyI06@jj˃#AscdZ"̨CF͡[Պ$Ӑ#"n6-E}GXfSz*%G.ʔAYʊCvwewX1_ gFg+Eۀˈ;kOW#Bu__w74M:RãB5+p}J56rJ%~2х'~s&@rWRqC*6EwnQ,{"34ϲ-z֢6 -J0К!<=' HnϒQyGTXnm5 ;A$Ve: -Y_mgҪiSb.t"~ %ȧΩ ],LaF+ܥ˅(ĔriL_ώ. YI;RJ\Fv`zI4dK_q00(7 aԦb\6{"V(n%/^䫶Q&:?iEiĭYWU[9 0Y@M]9Sݚdm . *}xyTkNVFI2R]*J~={^[SH|[}Ǟl Ƣ$m90oQv> վ 0i[H[*^ڻhNmn6=\gz7>pfnUZ*0CXqW1gw{mƓjy@-꽯;0fWE#>2Cy=YS8Kl)8Z(^û|Hj6tUvD"%~yWN{ژ+#+d~jcv Y6oG٨!yץUKm.Dp~rQҢy<L?a$)?4(նZUG}Ć_e -N8]]cL;Ss]w2p ;KQ{9u&|Tr*֒JQq] ldA@8p-헕7?=FH4G7?#&d7NJBHB;jYd"*h (:Rgef#으g;:dɭキ`oҩsy<|+rd|)o?[ٜd3S!:8"jAc鸋ġ`si[;i-6l)!~iB;$3<8dXWwsϑ)|?muܬv:MBsv\Y=~N_փ[͖I0*G涖r2"v#[r/lWL -endstream -endobj - -18 0 obj -3267 -endobj - -20 0 obj -<> -stream -xZI4Zs";@7/߱i2x4TWe*"!㗋\|y_~.?M_p^f.|6nfʩj2F+ W̓h]W>]+5)Z_gnj7.?4/Fom<9OF匟Cq]min]yiuaej^;>`3VvNrȻaQ< -مY|x~TY˛c,\uO2k6.o2lI=ݵu07 L`xXًn<⺩^,/, -1s`ALC5n?kՃ& -;9d8Nn/تڱىu0,#1i=¢da3508A:o2MS])" -aIAwZ/8N -8"ɊةU'lb†-֯Afe+"`nSN lʣ,"[P -gwO)X13YYUe@Q,WN$ 0@(9]hRY?2l e "]R!8OGwy wfJɌ -ń9S/0I̲vL3m^:S4z a(;i΂iP+- "/c)!8Q:ۄ1+2cCFpʖ1Ai: `?ZEĻ5ƙܤ|0Ucy iJ=x$23Tutݙ$B uIU\1%$1tnc3i$uy'FR6YY, -yFahjČ -@rgBE$Q# Q -,?[mf+N؊Z -BWT>"ӥLhG%t< -=oFInA_CEsn`AK0$0BfLF*>{`JZNxiK-_B& pErs&*3LT*,!IGF+xkTqnnKEox5iz.W!BMg=~W뫽ȵPjSΣlԿn6H^WH27+̊-=$X=k^{ć 33` R$Dts+`Uv */Gܪm[@uX> -stream -x[j+fg?`{Ƌ.&E wOR%u{|C0nTԩƼ^}1WN뼦~||,]f._3\|/Wq{uWnOw?/]ޖhp|͚5i ~x0oMWɀlLi~fr|=f+o&bhYc˸45]t6MЅr!k- p| o]pxAOqޠ{ΥGׄ•k2 -;NgÅ pr+7 -">}`B0rg V[H&6>Vu[Z{/x(ie[5azS^VM,fcBou!x/rݫi<&.}Oe0_vDdt 87F>n>^a>R#|\3.Us@8#'dF}5,5f08 -t$v2G8͊;{f.i4)ajV$)^dlm umNu|IQԷ]UYfoQyPƧ%3U-{X3aT{UUJMx} S&);{jUX>-B*-'Ӵ2/(l1q"} - Vdu$]0!RZT֊G=mt;Tep]Ok3# " ijn$%F)]]R2xOˁZCYl8Rz0:b).JYDP^qL -gļ4XgF4"B*JNt;Awrjc0"{IreU7SRɂxӰwhN*ݑvILWtHD+i<{$v$̽V7@fА iG/Gmg=\56Wu\-BqAUp.YG˚jhjK> M+qS=?xBvG -V -\n:8AkWPVFԑH>_.o͗iU4$)[uh:[u8# -d,RMcʧ -tp?`sl -0'Huiʼi{֬2Q}]SyMɰ9S[&uk1lZu'9bbFAT'`מ&(^ KhaH KѲy -zuOFpZ0rǯLlk0o -%TW==gہ ٶ;ŽV^Mäɑݟt# yfzq`lm7̛L`hnG68D΂L%6Fюkоl!ŽCϻDw X[;yN6zVݯ{I|=}v7׋vmwGӓ&P֦**VSF -VboVuRj.(xs6IGqZhN\m{Q5!LNL^q0oJ&oO zB$XuHkF8S pjlը|q -endstream -endobj - -24 0 obj -3242 -endobj - -26 0 obj -<> -stream -xZɊWlh9Z@Ko ->߼3#3"2#*uiRUV/^D~˻69^˯>'{qhsnm||k[<5cN9>ݔ ީSipmhɘx_&\u{P+&tQp՛V7ą_Q$5 9M*Lnozf-:qIX=d  -Dv3m<} -XEr}om=(Ba53 -L.I"K{U.\$?UnHAAN{ɕ')\W}R'7j:ωCuʡEjɁd%Mnh -Άl׃3YJ&f|ȤA)M TTn4Ћ uʙs+/@8!]*/w$JC`CgT)RLzƽøh=jOYHFr|NpHh(YÃ^%·9NgZ)Ǟf1A=V;2㯞Mc -(75sҦ)54H3\#9[":JO'Z(u[>*Tɓ9uҙWoHNHtE:/MBuiCȔ0.z -& -8Pуw 7 -dh -ڂ˟r(uu5 5о:s, xdqUL{Tb.Zyh ?yѭQ$3|[ԪpuVPV~gvpޕGr5҆ BL+ -Yܮ|^ŭ4AuPTx)a>ԪGpgX0룰&c"bPTҞmT&:Er3N c'DSaסE}MPб9=|RO7hA할f^.Զ=f7mXi?͝)CbN np!'.JAu`{ {}y{pS^![ib-]ijӍvx1GL)# -l)L!Ot< 3q)gn:/dKy$LMAMatߋj&^vz8SNi"fK%F2n/9b$pqlV|Gwl`z{<,'~#)KXfp`֥g1MU2|B-@8o r -)u -wL3hK&׺kn'Dj*i0`x-<2ɬna6TdǕ,0ֱc+Q,Nn5Tz汹- OHbX+pؠw6li6qR&~'\27\#pcSPqzPc7 -^,8~yCˍRM&bL SX,VbW5!0 - -3Ga"CD Xw E@lF"-1gl_k1CڙОa -ߜ^ük,ݰZڱ䑉9\dA)p:#HImshM|dnXSO 8|}/Rq+Z_ҵBڭߪ[ir"%HlSƭ:ͭǒϿ[ѝR7@O?5y<(![לrZ}JR߅*r(10hiut D\Stվ{j^?bN@oJ+*/+7 -endstream -endobj - -27 0 obj -2804 -endobj - -29 0 obj -<> -stream -xY=#7 WH}xvRr "@%K.]pow~Gͺt(wk:>~]fÍ~20+V^?~{~}j6{9N?-u}wr¢etyQD(MOwkpYpE~^h+^xF-Yt͘#$K|U=6ADxŪ g#X}ħ23P0G/PP-[P|`sn`]ߢEhDaD -D\ z<9*Mm9`";Vi KWt&v:vPL!jwN7= MVDPraF -`:jԊŞL̗−4RߍBIz@@\<թNGS&xu#^K܍J9ze6b3>簀EI%MpiG$>`Dzy dx;G $dG{;-c VsוC5RK -Hq@y&eW_Hym7i 9ȴ̚bKk @le6;*QG+XLa퓲IEp%)Ae\^V{ozmz/ݸZ5S׺]M(L@{G7U%g)JZ5se~*zP ZIT8iMa([ pVt8y!!׵W96`u -&ݡN/텏Lb@.Ym;-.uشdэë(3npoDd RaFj:rQԗsx_1sW;X9-sf44e@Ã&ȷUK!ŷK%T}.!J #kr E@q@kM}f?$y]UL6]qJ2S<1}z-קpk0$r'v*0<ωW,OUεK*7[b)VJIknq  -n٫&v>lU[h}FYߠf/z"Tje.V-av9,TLHShzJcVܫ࣢cD -wg-э0ZS}Β,6#; -Ġ.êvfJN5w-cZf` -m&Q%C?_nR;<_=2 (`jὉk ^`#ovP#;W{&~n3gC睞"Sd-3@J>[ -/*7n}ЙzR(PT-} *mfK4eaQ(+/ ߗH0xբ].i;Kq*ѵ< n"۱4!OYtZ*(kCڳ]ό}to$k>м^a 1o{ڼV> /`$'I -+o@- ږ5=i>Nf21 -endstream -endobj - -30 0 obj -1943 -endobj - -32 0 obj -<> -stream -xXˎ6 Wx] Hl0΢ Ew}]ˇd#vN0NlsxH\4C? co4?~!7׶诶y5ƚDL;6}{8-.>p==mF0p O?MJ&DSMi` 7\ھeZc `-qADOȧiM--hUOKy]Bp~yE tNY>!JH27@Ɛ=9#7|H}CVA;tc2kp&*:Ngc<2jE廇) sdž~D?:Nl[ϑfB@oPDYBhTןXab -b8c {+ 玸htEjjID8wa@ -kk6uj |^TKه&Fy>M|6ҙqrNfhbv[\e,o wRKcaTW[ֲآ;KO?R>c{Z#4Edc&MA&?jo`f{Jb]<<n[!Q\IT$RZ[T(nSS&X{x̛ݿQϥ֖z Oq > -stream -xUM@ W\+i><`{Co Joz(t/}ؙHޓF? -5Gcde]_Q?b65p_zi?N?k+88]{l -=`Եfj2"Kx5,$r@LDzF& |/!~0]_ze 3v\LzTw±R>e;(7NW%ߥJuMbx{(p͌"'aɐB>K8U{:( RvGCBIĢNCZBWcJ'٠5yxMKPqX9m "tӱ<0 al0bUעnm@P`*P(QQG'rBgdҀȁ)l]t%"HnVJHu ) KŭњJ`o^tD%Bnw/Ux%djXEӪ(QPބk(G5dv -ukw]}# 8b*z3D!=ء}~滈WzMJuw*ocۂz-Og/BhNTB -S>6MF) 22e y"8ʶ.>6M -endstream -endobj - -36 0 obj -706 -endobj - -38 0 obj -<> -stream -x[Ikݿ_u;c辶}АE.dȷOIUJA?^Iuj8u$<&॓ -?/up\ \vUo~}qRʿ^;McW/&|H? -?=Ia#|O~ -VGKUBau%kUJݍ000ge2RwD)vݤT>>]w9ěvxi񶇿p-\Eӫ387ݻ #EYu SUhu S# _ó:\+'p5|0&=AVGWR -LT)& S;UP*Z^9|,_aMh:OjqP0~dNhJ nљdvEO'|= -ad&xi7x-RZa!Vv!Yahm%1n676{)G4)£"^]7GV̅]L2"7Xfl)+"Sz`KGja.|Fr a38s_CvAyJNmMS3MN'U`~u59$_F\#-=ۖE_Un9.& LCU yJ*؍2}R۰ri&!T"2̢Cl9-FcUzPhG$ 0Ҁ[ڼ[tf%@R=clcH -8L ధUBJ S Ś4^TQOVZUY2Rݦ#kӜ#yyFZ/CJJ A%{3 N=ĘhH-n+]5L2njYJaċyP󘟷B9۱!wb_ʮ2ECl.|ћT -lۑZ8 -~r ҙKtù>JڸΨs懏H0Ntd#*fVm <$Ym#-IefHnǛ|ed8l+z3hV/[YXJ,kƓ"|]:or񡒺s%1*Ya]XJV`|@N̄JɱqKu# -G>Y[4_`΂^mӇ־&BF79ۻ9]bF'|F3YNI4MhQR?תէ㹃ƇCmtA3cFہ{D{wՌ\q^2j]%o kLju=j'b V9 -H&j},=b *k&nj?i`.ˆuU=5X< 'R)fN+K[͕Bߕ$%E#="hScHDfuu J;;'_ Q),;Q -GGUSYѴT5=^l}ZM!͏ݵ_DD'$ݲ^"u -o鹆|r6:lOynB-l1\n^3N[V1A/yeWnM] %,^/b@{Ƨg1nQiԦmSky@äS)Hr;fv4VA!9l`ؑURo -%*&;**T-/3eDx, Hv^ZI]ԛD [HC UAHQ? T_het qy]z}bGy'w.nehB> -f?c .=ZB HϝӀO7w/l⺈c.Q(KͥhUma Ƴ,#0kzNـ4,> -stream -x[ˎ߯:@;|J6`pKEv4E]&0Y_,T:UU_E]Tx;i^{|r1~v |s˛~,o>R~hqE?"Zu>=\MjZT6eVSeu[/nBH7b*BRwٺ(bAe&V-HqT狲gd$J&Q7i:io,&z-X"iJM@ 13||܂ +&T^9FE^ɨh׾ihF#PoNV4,VH#Je ^IO}Ҩw4|n7,.m֑:E~FzzLL u`z/-ы_EDdYٞ83mA_X uXQ dmԺӪ]B6Jw_R +p,LH)|+żjQ"/z0 װgueDD|7Re827'*n+ }1^=h -ϖUwu咳2 mVsLzU~2)"WRd_ -~_D)]>;dLֆ elxOauhGZFXH֘/*vLRQ*N[*=6,.5/wMYβ4{$KLBwA@xv(xܽVu P8 5=0r5'7zfX׊@9>Vq==s -$yZ  I݋ -!BmzKgGs-Z9jQZົkdٽS0fSEm1I[wSTL4b!q4dALa@hEv}95'r*b6Zfdi; ;n2m='Luf!Z2e8󭶷b,X {?kʷZuÀa{3H$tFvShT{C^4=)0Ps Q:m"㰆EFLCΩ<,9zHEqFO삥MZw[˩$2EnDY8 -nH!EMO`f8l\>okk}3^M3ÌΊ[ ǟav"5Z*uZWᜪUL %,bvp0ST,Z6%lfIggiWpKFqn5r#SE3ǻʺV^'W15Ix\*0KcTaOBđJ {BG0woM]gDp(;<~c^1zK*՗ϯUTmA\a,A:ZfqbL|YH:c &zJ$h$jϐ6*A [Lskyhg[AXR`݅+7~lFÃ&m1V FW(8>b -<_C3b3rE# ==52>.5bp{#S_lqQ1侎ꨧ50:׾rTl;Ϸ y*բ6ٵ?e>'b:kH[?8G&%iϜHQͣ+LrW9ɑL.Q&vm[ݾDBY @Ϙ\(j;ckS<{zL·:+diݙvΫDI'iLCyTTS/bR]mĜ=X/ -endstream -endobj - -42 0 obj -3126 -endobj - -44 0 obj -<> -stream -xZKo#7W9n@` 1 l6K֋f$g,#wUEz̳~`h?Ǚ>?KOoO!>Oh&dxeןv:aafG?䘐Vȟô7^<ǧӗp{nd0X( C7vqo}Mo-xo,lJsz܃UYM@[Q艖^YZ{,P:O2BVQ-=Ob?HBe+waI'Ңs/"owuʾRy )z@ǷWW=K9X 0#;(Wi ql]=s]/*DJ"+:(= bX`ktq9kz :5zgahg]t|g{C؃xV -m݌:hɲSDqӑ\ -g,MhJHC+ -ءCzKIdKQBtYb&-}L -sݳ J=4TƑj~-}LmX2voAQꮧ%%$RW5> -s QPK=z^tˣrd'kS<^mHc靶!I'QM491lhRu=z,T F"[ìePjC%- -{(x+t"еb mwn}M]KJEJ7enV}`& ԧNdh1m, [ -ا%AmZ̝E`s VW'|_ɗ髽M5ՖZM -&BjGa3H2TrInYIȭ -jHo!U^pn9*B5UM5sJD<U{(|u[10Q[Mb=U$G}֝eA rz8#"} - 'yYtsƤP$9Y1h+mO&XtL8'7@r -Cua)CrX\ѫGRu}clK׹?mndsħZš%qfR)!5f3l+v ɉo,h@`HV4mxo#ݪB0 0_)a^,/KYx@&SZp -QG(`:Բ _y:Aa \ǦR 3Hcqf,ݒ.S䎏ǹRH<*x8eRro_K-<}D%s#/xO`a]n(lַ]t'|ltuͥ5acA3k)6PQ -vj-}Zao38ܱpCPoCULi/Zj;3dQ3`..̨>dk3|x?xj)_W߅-(cbF;| -̀9\Tיў -r}Y;ج -b/Tŷ*s\;U윅;+U5]_׵To^mَ42p~]R!:A -<ѓ[iD쉳RӶ>L zn:h^gcVTI&6'CmҸM}ˋ8eѩ\gyy=;/q=b4ӟF)jn?TIPi"fpјn_h@2048+2mj8ҧdhvxWv4Cܗ, -endstream -endobj - -45 0 obj -2460 -endobj - -47 0 obj -<> -stream -xYK$7 ϯs;n( -f- r&C {ߏd.?f]jᇬO'ɣ.˿'u:+|5sӯ? ?_/o/_ ,xNN6+_5rpǏ羜⮳̠3F+rÔeh-*5 -TpjJo7}S_7^!O镄xXu^ -9b٪)tzL/^NF48@MS:!ot(a_wQ@x=\n5-IjHځ@kÜdٵE -B7s{ak$}gD!vX NX|@dq;`A0t0 K3=€{ -S#:FqL# I27/):V)g3,̈́P \Ҭ֕JSzR -\I\?HT#fC%39BNCrЂ>W[䱌E? -5٠&8k\:w#Ʊ?Ȃ)y/RD{p+qxK|yQ\]J)-ɹQ22#Ih`y$YR,t18*i2bA0؆M`ypP8߯eJ3 8ꐓkVvNN(Kre]Hb@DՂ ˾po_V -2IqڻDTGǤP[<".cG+A% qOkwCGa A["Oǥ?>IvQ[=Jek/;ݚY|<ȏ7gD6 -@i?E5T)+mG,,Q:銮 Q+r;ux"ٷ 颃 }e?BFRF&|PR5NNW޴RVFQ(ꤡ] CMn3T)qOLG -endstream -endobj - -48 0 obj -1622 -endobj - -52 0 obj -<> -stream -xSKkQf2ZSkS&jI.Кm0u2<`af" -B۸rƅ;ADpQut!W".jIOȝ9 BPuKk$ 4?rA"vu*GuC|jӀ!_Sx~|?BA>SC);ck1\KlNNښed=x~ ['LmvW*=RhɌZlj|[O]l[e\7j-Ss k8JCcDI2DE`C{.xhÀŧHUlhsLOTj`BQd)FOQY{3|ݐa -endstream -endobj - -53 0 obj -573 -endobj - -54 0 obj -<> -endobj - -55 0 obj -<> -stream -x]AO 96&f&=?´؁L)VM<@x7kQ13.qe0H|pPewMJ oKƹ16ү-78=8Y;{@ޯ~Mg j[8=O6=u.;"_mKd USU-4[? }Xd-ISSNc2K2{?'ŴSe}~my -endstream -endobj - -56 0 obj -<> -endobj - -57 0 obj -<> -stream -x}y|TEpUݭݝ;k&Kl$$ [D1 ICZ/ #eF}qE& Aq)Π2*8.tSuo޼{}?[V:uYݝ=!dAԆw"G;t+On0B+W̹- !$|y'xB ʻ)TOf*U&(>Yep}9&gR-p?;!1)9ūƥ? Jd^gDNCҺhл}`Vυ؏=v8=FQroIRDAY,j?ڎy~,=m ao|; TzqFx_̑+rZ^bTt;z _d52{HP;zdR3ԂzG,r3뇲P+r.DB aZt1 FB#JBh6jP (~;}h)90Zuq8/^oO] hGϠaݜ8d9wwN8O$I-i"{%Bn%ς$Qrq\.7%4n:{;nv%_+O ҄,BJ/`s1Cl//$^Km錄b m0L ?vpgj/VWD;\vr )XGhݏ0ܯ -h t9_J?AЭ>.JfbP n< ܚ'Yh.yp܍$_Sz y ]~w -*Bp]-|/ȋ0$g/ ;ȐI*sx\ŭ 0Oea' -d5 Ea|~א%2f<\?~hiK?rL_Oчp%H&.ҍ8$Y2L ncoѿP=w[܃ѳɣ(M8MDgA9z й.9$_;Cw?~Xp -tAV^} -{>eҿ'H5A\ zY:6 -#m}z+A/8 -owoAoہO0A`3l _=6s=!ĩ1a4UH-zfS'O**X?!/7';+HOKS)I w\l6l2$Q98nLjEO.BɧS&J-%u+cԦ-$l|} ʕ-"eI;cЖU%쬝CN],ֱ@hA B F؉)Es@ "J,KLda2CH#,C8bQEBi.*[N Xc^R DA*#p$T.@Tv_f,ImȀ}j4 <^5pp2^A+:Z&v10\3Ҽ.a_F #riJDuHXZqeJ:N'*>85'$ne 3Sua׌e\" ȱ@l,оt}ceXfkjm$ØFCi+6ӧ(|ESsTzjBnISGpl#6De3Q'3 KS3Sf$fΗǧW_mrn;2n^n;f]g &㈏uyJE}̸ -? -Y29e,y9EyJ (w>*34f8dzk+g1$} :69R*&N1x):i$ -*L$󆁡iƧL2JF٠8El|I qJavt]w}㗰=uvv||?F`aR-Ou/^jbcTOVa -Uh~:(ܒS5tq@l9;пLF:ؠeΨ;i+FASM -tMyMW[җuzۅğ{*[zpb=8_󫫯ǃ6lkMLk\yʟ wԚtnhGKSg޲$03>] vXR(\qQ؉# xx]a|? ^cQޚʧ -"HZ",7oorV1pEHOs!S)g ̘$,bhI/pGe?U*3Ʉ$DʷTJ Ȟ/ho`N;FG9G$4!S -NbR$|9EI޷o{yN}6B$brJ1&A$C,orȿ2 )ixx?KgLOY$o -mǏH{M{fJvtpxy(/MyO9|tʸȴ9bdsI(!͢ؤ T_.Isͪm2K&F6 fpY"/pc`/Cj(#'a0XnZІØϿm¦jmFb|q]6 NT+OE\5 QW~{G'+`}\>d4MT&.y\\LȌ,Ȋ\| ;sr{^)WTV-u77wzsnܻ/\'Ny6նvÁEXZdtd @vrjM_' -J2CajH[ ZhG -71B~uڎԀK[CaI4fFc a9)|GIZf2ٴ -vZ&Ycz30bDT2hRnHrq_} Έ~4[|ĥ3Vr -<[.QW9ѯؾΜNO$nv/פD| \ yZ"wIn+UqǗ[.GW`NWUgJ+JY lzZ5 -l0b{^M.crDh]C*,q?þIɋ1.(/+.|"C( ǩ6bՂKuo<_iY\4.ᖘno2IF#A\j(aH8Vs8b!h e -a!"xrjV q vr"[#jlӨL#>1xi*YK#c:S6xhFm'K]F?јiLxjWPrAP$>|̩ܙ?,ށˢ -_$S}4Z8jG hm$qBkڵ4-5IL Hq)aD2hn [^Pͤ -t./]&%qI CR:CT$b0l -)7.eѹ#Q -ֳ -K~lXIHѽ/) i^ g=OW?\K.,,ȋnS]P½Թ;lqFE8 S~؁ )^:!3I6S -꼏_#'INB$шC% -b?m?Ŧ~Z 1r; Ô0I,xäqꞜsYks{3܉Wе{ZEռ(3ƶGnmZl|5 A`{Sj,NL\,(9y9jNU`gY֦a}9 -qT քC93q\QzYjN -:Ƕ(*n{iڢڬ+ܖy.'JHθ kLvSipKSΤ@ 8i Iux8 -<T̞\weH;~B?ϯ92"\B;A)AS-2ˇd@<7ϞD,iXU3Z\qELCbj}0c@mTjL -hhDC$u WlDʕG~?͟4n8vq -u\F6Ko]qظSϻ ^L~._^YZ6'+%SϿs߸!gJğ gyž޺d ddԀ)/z1Ű$!&x+,&=>˘J Ok467&:܎7㰒x XY3 OcHH^FeɸfՂY!JBX׳C5X -߫/ݧ-%,@,q k·8 -چ55A4R:lMݝ:Jo.G4-m]=}W,z_jy4ZpN;^o;n_|zORx %>5UbզyvAS0fPi3SMs-7*b -?VzN5\T - -C(FنaRkVϗ3Msj2>d5*.OTAIܰwkvE!L&(UAδ|yX,,//y?~so۞͝|/y9_FexxCo&m9"oM~.bT4ߧ\ye¥W$m<'*3;g&%oJߓL oOfqn߹G|<{"ϐ?Y ;=:y ?ʴ-Ғ7+IHnO:t8IHAel=l]d$4W@fc`_%2:Cx >|T%i݇ -`9EI!)4O,H}h9y!` @J3\ֺq[utӟhAj(űoM̟MrНrB54ȅڨ2VMVS{qAW2`XuER)ߏ/<(x8һ^>9wμjNϝ}ƴ8mk~N:nrxJrFĄ3K ?sA~+jg48O9}.%&=͹ێb!.o1Nvvcm\t`n=O -Rfv -NBQ -Map%>ZzH%,ֵ]{vOkNGc#5ck<ŹauE'c^sPN%WMsq>VVUn>{[wY~/[ڳyja0WR+~§wl:qIf -|߱_.$(BM8$ RD4PϜQ+,6;i|{_rfq`F܂:H/Œƃ#cAA#`'8%ªNx@ YqK%B$b GQ z8'%i9KY4^"fr iꬿ6sq{ -[G'3++Q0Zs̳-!Vl{'x#hń! KUcXy8pj1YbL& H8U!+$yabh1;DxEk*5m5qML8d5]g yA *1ڸ>HK|=]} {5a<}$54پ# &;|tb|\5Ű! $d;=){Iw=T?\JOW㥱==udH -rXhL7a_BS9}Rǟ{׷]Ӛoڎ7FnTÿG~Y|qfad_~9x6^~;?xl?dN-.z_w/Ks9yakjKnߋmu&*=Z;NSf,3-s|LjRT6d7NgLQ3|긻Sv9ِ4v".Sű YImvՎ`ev̞)_54qsg>%!yOe\qprooeyf70N:, ۲GcpV;ԭU?@R -H.Auo"~A 0(=Q>QFs5LOKIFZeGo\Zƥ+wE[mѷ͗ *_}!cя:yϯ|3psZk.h` 5Gp:J^Pw& -K|Ʒ}ԶxvdAa|?ȿ͋|Bpz\l5f$IXU O:>{|X ~s  п|xZ}$a2dN$Vxߔ>>C{V>w?lytgmzgII֢>2ܫW̯ٸm:u274˺ǃ!؍&!{ fbcGG1lxM΀@-(^6/0pVajrB\KS,-2@UgAe<6gO"汓v F4pɦ6T.%1ţ?n3 CBf`wVvL+yIw*$PQ{.4I+w&/\4mJYJ9Жe7^4Ss6&L*=}ѳbѳo` -D\^rIQ|kŸ>Ý7`>ޞ,Eܖ -EٞWl/njbNCf!PB\h:n'ɧsD>Š|oڃ-kUԁ[ -;Itܓ|gx3 8̘rΤ r7[oz -G&db@Ԫ =eA5Vͻ$L%M_ћۋ'ok=U/n"u;_\ѱ+`^ -V^DR1Ӌ<<M X\xkw|"|O@Ta "8q$[W ( gϴNv'TXKR,,]fqV-}====3oX__skAW7 qn{70{! &gwaG-#%;GӇވ -nNT!aIϩXIũ8VceQ_A']?\֜vL YTgq<$$7$뻑gq._\1 @Πھ?.>:39>ߺ|Zч~ -ő85*.+I4Z7%fګDHQkcr1mf}hAmIx#ξw<~]˵3 -D}EK<#O-Xp8߷o~?Sn{=)R\җu\KR$9ϪZEqaqTf+*n ڊnl>[Ȑ &ZD"C1Zd>WW|c5:6FasBZ&th܊n7o6neq -X J&$pAf9j36FAMf3l3x r,DO{p -|jIY%z-~]QЎ'sSy /%(:#Sb&h, -˙mW#qLzK$^FIP^$dO7On"UvOd*L޽ DnVYvB,Uns1Rk( bڇŸh}w{bfMb ;<؇{3nE?nV\u~ѿSE1s?&H$Y$͔fsZ -1wғ@p*.d!~ߛWHٴtl!ݞLOLO"{sRbr,,Y)KKK7+̛ -{:7]~n)33O%=@@Ɠ_sJWG'}|{?eڕ`6iƄpl˲t8bTUGL $&%))1)8P();IɁ0R]GJ2 -ʲjZr C`2NKCAfLjL^qe7Hf9 s.vVD;4=%AO*Qq -Oy1M>t\Y,A!%+yXFf~}uf~lK .uNKk6E_XzљP+ĕԱeU͛'ml3(I/ǀINhA jt#'%O ]\-Gk! -_oyzr`_GK}?z%{kyd:jP7!x+=HjqPA~1$$ުcN}\k/9a7uH=[\x dF#?c?i" ]sRŨ[ 9MPv=_ } ,A  P5gCjO 8s -Pp/2Z -BrH{d4 v#Z!$ -'R Cq)ٴez,\Վ -I.ko̗ -~ݳP[*-["(#PV_UjQvX;X8la):̣qr߫"JÏ밄a 8F<&O6[J0mVaas7zqHtT[9T a9>E~BE간V3t؈KtDMp}; -bu-aqSyQQ#2XO(3"xuGrKt]E팳aO\eunjF+9#9EkaUie뿚X?tX?b0F5V[t_U|jef4*sܿrþ9!Cf{ -lU[h][cJEc~)uԸ56>W;^?vt{:E!݋3O!-~"W !֚)3ŨBǤ;pLImU -!?uq.;ֵV7EM!e^[k[7)3::mJ{sCRV] Δm=K -&e%?Gܬ,jRBkB:ۚ9ᮧ -eL͔5.:P~Nq9/ն{0AdٴR+ٮ,o wVV䤔ЪpWw3Ԩ[n@]PV2Eʕ+sF%Zh9#=;Vuַ7[R:׆[WѶa|mt=?\ߕE{ 7땅=0mݡJ[: < TC]UYƈCeK[gHiio򕆦܄` -ԭÊC -6NihRzWt=!em0 -4S˺׆Z!ns]8+Yn*ڠġF5HX oiA­=]l]Cc9Al 2ζm=i _F6ϕPs;pMY^blG+%k -7z}{{A4v)0P:J)N3%ۭ.}h"tH1n:z(= -62rS wh2u˘xmK íu!Kc4o w7ׯC֭]@4.1Eolkic4uwO]vmN.9 -m-M-͹-tӉP3X̜3cڢ9ʙYsf_XL|^EVմ :5b&@(̠q d:um=e63GXp0 -:C!*9J54k1h[A>*k8`BӝnXQ -1#`i@zWtC@f1w -<ŠTڔ5=+@@BƶQ2]7< @땮PCg[Ѷa* LagN[CTs%L'0m4!e -ւBYj@_[@P~Xu&:NcQbÀku3f]Mm=`:Ck¡)d4@㨊#kCӉTn# -}wwON#9yʤ &+0o„:`2j]}lHuG?QF= -^P\}Z{_:Z~bpǸ'}p݉n=큻1mg#??F~~6󳑟lg#??F~~6󳑟ld#}{FØgAIsà23䂖?4ǰӏcDjt@۷l(9ʏa -<۵wDZ}s21f5N~ -J*zXLiulώ?+m:%Ge{ʟɼʟWHDAYؾEI;~kux18oDWp*8a5 -pZ -5\* K/=c H~ -E7? }S m-ײPZ*1ZnۧrzHBP)\+!]iz=uqp_AT7ƌ9h+!q45Ps'h߯a` BZ\`͍i>n.Tͅq>H! -SH5BTiH۬?7W~_5MfCdzbh2͚7=Cɛ}| -(.a[%6-țHT!H!$!^H E~Rq9hK`y c`EǹaHk݈aIdC"[ŭ+%bz}Z -744f9-ttT i ( BtA2p oVo=ID2)BW!c/hf*i7ӹd|[H -&2v?7 <; <3 ~ Y/3ƾL<2Q>N3o.A|+z- ̫̀җyw'0yp(@~q+yp@~X}9s`[ }/x) ٻ?q@ߙ:5܆[ -0@1ܯkzۡ+˰[}Vm_ -.~6.}0 wKv{+`9Ao >睖zT&z4L- ᝐsě( CGx[VI%vJމRoz3t7EMb Nl,` -!a,Q+` ?_l h.rF\\X8=29X1 --L -VD U,ۉմ4UP"'`#BtqVE=iE@i+a5z^]=c 8QܚROsxf\_zu{@I5~=E#dVGL#T0\s_ [qM5>h&A=\8#`b^=-{U6|U%z [Xye?駫 uH`aEd˗픤ZWV -e9evחUw`wOwu -^ -. - -΂ - -n -\뭂Vn`Uۦ?s[gVPP`UpT**u 5 ]|16S0cZ -V]Bʦ/ -endstream -endobj - -58 0 obj -17953 -endobj - -59 0 obj -<> -endobj - -60 0 obj -<> -stream -x]n0 O\Sվlv{WN %4c T7`ks/ -LEy`{a%׮K.5B9VGrDhXȚ -9)DGȏܟs<@>s(cpOb_cO+_bOL}?|x&5dAnԇcr@f}v?T?bPyܭu#BCISio" -endstream -endobj - -61 0 obj -<> -endobj - -62 0 obj -<> -stream -xy|U8>3g'ល=@"$@XFas!ZE[*Dh%$DjZEH[RiKVr' j~>3,,6̜tut )kڪ-DBVK}$O#$Mkl[Cم6!Uk66>$! -^l -5] AhcJd|+rNjZ۵ >5r@V3~m݆_Y,"4rK!݆PvA[kg(##fH!di< cPi(i:h2[6r{ ~9LJNIMKȜ8)+;grnՏpų)=3"3c VB,?6N2Dn9hg -0z9Pځm( b4P'ݍ~@EG[F;4/Fa>>4h+ңh!v:|cݏ~o~:Э^*A%P.>Eǰ6 (m#ѷT~1e!~6 -6 r/zEp iZZz -CbN 7D"Q}<$oΈAG`3_G}9a\;÷D> &EC?+ѷ W9F,[Kn&7so,m -B}:5:^Wb -u &A 4BOCϯױJ|=n;iG>![9":?wA>t5ڄ6mAWo"੸ ?i ђDRA$!7{W - wIuR}F~=Ȏ OAe@[@*D';T~x9zwO/0K>d: ӭ>r?:|Nwoɟ9Kpc\7ȝ>-| -O+|8+\%, -O / -"Al?nhk8cwiE@v5 IG -oit -.eK8o[w8~fs =E|Q -y"`n.er9rm^rrkn~o_W kpB~!\.DbxW$JSJNMo63`xkA>7sydgV -s؜)}߅|SY$Xb4ǿ!+Яp-{U@O5N' )"Kȣ} -~w9< -߄ f&qqT}XFnu -BQ }BBnX:2w߆ի=  F|+T 7#(Hԕ`IFD'wM*ИAJCMׁ-DQ ޽ѾoE7F[x"'"3܃w^[" -h}=8> ۅ}AGkdH@u0z 1 k7^4`SaRG؇@g_ΤZ(qЍ`'E?B0nQ=vʁ+n4@yT)ZC0ߠQ6`f%gh)jJ|8pe; [Е8?x& -?b&FGf81Q+]af0r -Ycx!J)qEiS Cys&MHOKMIN -&d8v9vb6 -zV#& -})}|JpI4q}2d]^Oek*PK5XMe&EhDyVP{mfP,3r9cvAi)ZyV_ٺmjgBs`iX7i":l;30{ִi0>_p>op&A0qh݃6lvYWWMfB3ܛxƒиtqܶYf&m* --X64@me@E2Fn^ևo.e::Y4zO2شZ`o[Z1)GojY0W-8Ud%&Xc=`281UPQb:>^, œGx*V?O5Hsveͧ}B%(o; :5GLQɨAܗٗAED*gtɔ`Eȇ*uӲe] -Z biGJvfu%C#%Ŵgd6|m}_e4Mq8V^(X`2yֶZUbSGT^#*D8V -ByheXfWdBǁP ,YjgǞպ@_ JqHEch(e^~Yq0^>W-߶MwYYmʂrٶmuўAv!{ͪa`]q}ewW$4V<w,8;-_v;LJk>eˎ+\2KS2Mr O4(P+YKb4#yX$pS(/+ARؑG8F^(D|(WjIe}ڳ<(>iZWYCek^2ݚ;- -ݔH^rJڸ8g - oY e* Y/Slc04.9$чH 5B~ߴ Qo-ENxðkLMo6fҐq:Ndv,%Dc?!t}|!x%D%,Mp!R⧄@U2 -{ 3?lgpd&LK/DB$QD ԔYhӀhG8zgS᧚-!b2Z6O$hX[ &RY+084tW毼˧ _/#5+HYM%.zVNx[۵w:tB/k&k itG[.h$vt% RS -SP+@Zy [!=!`]L5&d Wq'diJm3jZ>E)_NƁg2]ńC!˺ҝ2|.}f4ƛJ\Bȩ!u'T<&7ۊlUjMQ8(ASbz,Μ=,V&s5-06]xCِPg;&leOX1u® s@yxc>2:8 -xk2\+&/2'.(˜)S(͟vy׿xvGZ};Hos:< "s1̳^Y\mv5mͮ<;NK>96U64iW[/7on7k:b;Қ= 9#d3֐(AjUcC0ͅ -_Ƙو\Bj&2/ˤ P͙1%U;^[p -,H"N#2W4ߴyue#^(':EU;5?znK8y]ȯ/++{ss{ҧ)+/MX}}2J |ROԧI$y|+_y4GKP%AN.aK4 LP P1B_g!@J .yl`Kߐ -vA{tOY7^[{]lg@U`.sV,3kKSh-c7H1Y -yPX!=uOyccz?F`:V|(.zCHk``JKS+D^xåTK'?ʜ^֤|ŚyyW~⥋ _C~lʒ )Ksj">\q:p(A1SaLJL -Cr]qfbizc8Ѹ)Nݺ=ƽvNkŠW5ĠcC!$ R BlC-ۅ><kğyWh1?)C4n˥_?g!rU'R5勖@jXfk@@Am3tovL,q 3'v? -^UR'( -u,i83<4U ʼ\tӌ\7XXܭ{*Q0QVФO~6;2ဋ:bٷk=^quȟkn) {w)r~Mɞ8}w|y 6;6.͉eM_ٶ7Uc{}~ba(9qnjO@9`AQ.nW$&^Hp͎k{VowiJwU) -e htD+ULwV{דn9%p"$$NN4&ѓ$%1 -ބPkҥ$Tƴ0\+0} H&<@.] ZnJ)CHsd0MT#CtMS S44c߰@oW¡ZЫ䀍Kpܸqno깁gRgv JLزcxvn>KâV%5$jzzJ oɜP)` "'1sEQY}fbp8ן,#-7'/y? -_7㤂e3gѓ?d=|#wvu|WSVo' fMҖI-$7 ) $iƌveZUۖx~նM@q!4g;i}HD· DֹML} -'X/+wR4ps;eYl5]x:s`ѳ庭 -2z"E(9pȋb-{榺;j58 {'KmnyÏi"QRYP)ON - -_6 ! UuKhůzܪ(g^lhԬc$UFmld"fo1Oa1 6q`Sa`޹yvJX<* d(5#ٍS?yc݂~pR=O͡~D$f>GԶi{۵sDB-=Lsg4WE㈇Jb&M&g{D3ҸR;DX˴=R\ڄ!b]]cn6v`d7#` m|޼o׿ו^7;W8 -vfsmHmʒ&h -#b0zK R|BC[AXG6xyPإpH/fkV&VK^Q8]%.1rГWnT ARыv< GIVf? +\w9a+s;P˽Wz\PY\FrbI -VA8jFnjjQ,Kp ī G1yѳ|;JV+NrC]d7q;*rWro&GmwFA7C+{hĮALߞm'vM`]򜅗y®ds!ߝj3 ^ಜǿ˿/OK*p/uʽBތ=չئ9Ӡ45Ɗ>hH%8vh咨һybXt}) -nGx7z村~r@S˖ot5/vmٲ:㞿c =EЅiR~Ǽj]_k6t;_]9^:x./֕Z'M׭k.Z^oeWEdmHk]Flٶb@c)?yŠ/16}1iDL!F1{ڎ<`)3͑{_s#;#{NK'Eÿs"{5QvDXg&ӆ< -8b@wV8Is8`bͮƥ="RþK] t= d)YYYmY=Y۳z4rVNr$H1Kۤ˗戽C3Dl({5WcBlW$3[#*@.44 -l{,um5A>+n^غ#F3^Z>w/a[o敋 -G}hŪg2Spݨ!K -ڥW\D6h -56jσ@ =?rn -o*h/+55lQ2U\I$ -!Dⴰ&j!+PW_ggw)^E_sm=IYUղEBKҍ{/)^ Ռ)_P"[!l_ӣg—,\N26vM_s½yW\&MThr5} > %mN+CrCNئeHF}QLa{[Og3<-ۮ\Im~"ŁNGI,lYPuuwEFa.@=7.GcE?f$h2UHZָWiJKK,;,;:qv|_()ٮ5e&l,WWǵ9.'7n(7;t~9f+}[/܇{nLJrn9/߹ّ kWx˼|G|ro%ͤT"lV0`- 9_bk̳|Pρ3D_o+!ixk즈LtȈS - -Pk2 - -0X]|2fmƸxQ [Td%d0Y@ -ƌ5Dl5ǮhrGW[i`TLd[WXd4Scu - k -!׽i&fFTSt{]޾Ao#3<{;U_Rq:֠‡7tθ"}O}ˢX -angT<JTc hp.C iBPp&4 -L_MIߕGmxN|З~2t gWBt\1{X xɗbo'IF'^Xq):ْb*k87H/.%!Zqm<ɠP<TE+S`ܩP5U)P!)5L"z{9՟ړʡT95'5ʧzX4rԪQ5M&sJm,|pܪޑI3EFJ}Ka셅1wP㎜ǯ~<-!r6!u SJ&E)>UxqՊkg>8\MV|?h];"=|bٖ/6o~߯~L]GlK%igO7NˍYqKiuc=3Uz.LOL - -m@BqkTt1F -z^ +luR@$6A})X[_D\s@l֖Uۅ4k%OVzcߣ:4ZPbJ31ZMs'"-D~Eϡ{Qcjv͹ U]E58B-)y1E/<[dНFnO"OD>Hm=ѓj J^!]v5Bq ;J]S-lxrb `9  -VKX#':\`{W`̑Arx?I8\{`yZ87^QTfь焣)/Fs//^7ٖt߾C69Rx -W)K|ƻ#݀Uyñ~{8bgq>2QTM[M;5O Oivv۟CGLփWCvkȾD_m\a]h^a!o-9&0<<6\vgq͂% Q@N`wWhӞr ;cNT -|Z? v.q\sYqDLVXbCc5آt]?k_{O3onZ8U[ՂVh¢K7`[akdO;y0ǎm=R -iœJRu*N5IZBo#Kf>sbgpryL7kiwعg" {O#>ŧ /\= Q(l(Ͳ>di]f`qf[Fx6+^e2:L&MK\%^wt&_lQFv;A/*1VVߒm!ٖbKЪڗl6fiI7V@ -q=~$.:W8Bз$(@n!#s|RW -=bqT*)r-(lb5cX7o٦ukl'g<0|OQ7&hg֭?9sy]Р@ U+ӯwkjvz{4OُYۇۍNaue9KIt Le,q2 %ᄘlPL+ړڨ2c*$l`!'%{Nz&~ өoqy]Ui -G|"n^0 _4wȅ79>pGw>{n Rz7Av#@q0JBN.ڄ#P!#FoRH£~u@Am8M[ -ڢGA[O -=aB0l pj03b5(o=̆e9D~1)lK_G"{ sȆS灆N@+瘗J71NiuFL7Tf*3K09UnF:ﺄ;wxoO.`6-2u7$da4J[ tj4Hch1qb8$yqk[ תck{1\=a_c/ӆY5tZ#KZ.;\.=e`j Uϋ/t@ouT]X_]_T1;Yhū>v۟).~:0(7?iٕs- - ~'{g>=dM϶[+4Cq399qRo8 -=<^o1F<^E9˙xyLE8݊ӓ,ҋ1 y^ȥ#Ů4Uw)V6D~\Sx#.+SIJ8n*ũN#DL#a浧_GQtQB׻^}3ba>>Wj7c_0F# aEԥSI3"QҗC"d /w?\ -iA^K <mH/',As!yUth%y@XB`U_ThLUaMHd%m -0D%?-Fd9ZtG` -( `aX4 -Uoe0Kc*L} -U -Q#C)UP+jХ֒ahEg72,f-eLFd - ys 7'MR\[k ^8` ] k! g:y%+6հfMLTi'u*c-Y:ƫtȌְ:mLb0c3/ͣE5ʙl4T6ש;kFDZƤK+RW(plQ;Pv lL60v2'1ӱK1mTlzJ2ԡM ?6jn=+X -ZmLK6bf3iyDաȈGZoc2͑e ʦ -O5f1j41]ZZZ,ՉV0q -`%s2&*vYtd1*Wk@d( p -{h2ezaƶpc]}X~Jj -Z[Z K.mhkjnmg3/ic54Sx sK.YF^ؼS^ w 7t4׭uMHXL- wtҦrry]cU`X[U +Wu5u[ήpGAnnEre]"W͓+亖93 esn]Qִq|VXQemN77H[hou4DTSsK[[k:6ʝu@E Tsl^2Qͽj5C֎Խ/7u4 \ kl#3 -&wvBwtBu~w}ܬ6E'7w512mmmaw@ꁨ#y]-]a]@w,Qu]Z ExI;| w!4vY +t:inibSڸ&<TZ;i/Ꮅ-FGjh_ -\oM5m@VyU0ľN^׆v-P- dlC'1r7Sb -05e['5]"uʰ "Ũn旅"L L# |6uɘxBrmݪM-t~bhٶn#bwյРJ 6Lumee5uuM^~}ZU`[f7u]_쵝+ijh>r e~E՜9%Us*esJg_4K.jYfͯ2ꌺ& ()O`0.FѯQ16*t+7[)f=63ӣXp0@U0,К@ ZWR5̮Cs=00.L)>7EYغ*̪0k@zWvwA0VШqJ()Ft׭  %/na2qd0'rxɝmf0:_ TlaFqLTv0r“r7]V.R2|4?6q{NQ4G{1C܃G2=4`*%T >n@P+w/ @IsP`@gʵ@ zYZ@5`wo2sB1`ɭ,qp\ -"?w3 8\X -:Nelz13J8ʅx&CqZw)OwZFn+<3=sN8/~38w'!Zn8CL% -Ydse]p-7G.([% 'e܄~w] -7_G)wDq} ej.*IPD ˇn@ۀMۀ5ۀ5`ېJ?66n=a<4 -a@RZyc@; oj)8׉* |׀ۓz`S8mZ (sFF?12s~ɫ$y;V\_S!rrzQ/i|$пŵcǰɻdCbOA#A|?3 HE'K~ܟdpǩ͕[L^$/xhm ~ DO@xtAG!>?!S&!X3dD/hHgQ,UHIA{ -~dDEP<{T 6!xZFK3܆* hf!@7BtA膰G`F`16h6hcmn0j0jF-`F-`2 :ZeQ Q0*0*aTF%`T2 0PCa -`(0PCa990r#0r#aF`0 0dCf2`Ȁ!0dCf0, aX!PӀq0Niq0Ni80Ni8MNPNI@9PNI@9 ('I@9 ('թw1b!lb -F`F>>}0z0zaF/`F/e -bυr ^ŕtoFft7,f -VoB,^RX 5_`.q B+]C8Abރ%J"o*]~$NK,V Q/\G̎iAfx~ -x3|HH?gx'hUg<}C ))32}'n ~>+nP!$,//S& -!A] U!F{FDajÓh?+%Z|R7?{3PXLD{!jS ?5/F~V"7@t2SSh (J2td+)S?~!AXD4`@x+hm3+UQbvDPʲJƕUM$-f/n҂ HN5HЋ 5P(BQ/&4 -@@?W[RWYqni'-d߳װ85J]ziv`  ki!Q7ﰟ@՟Ȍ`¾w}Fғ9}:Kf7[cgI{=ahgON__QsXbx @F⹃t쥀A4O\B0"*B\W+ \z$E\p@UF'P`urkX(M.bc Ed>,C}a1&sy\?[2hwX[Лwᦪ]TιܼsFZ]VpxfdX_waejm^ekؖ2A -*sV6A\CqmV -mUa~~ -ba6A4p3W3[1˅l7,IcrSQdwi,=e˅3x$f ^hr1Txuc5kc,߳ -;$'Τ~߀, -'t2jyNգ 4`pfPQMC%KTO0U/xwC'=D,=_1b -)Ba")RzL&L=s{fƒV.'HhӎGR#`0ÉaxF[T#u1N?vl{-w$I ?^䏖/u -endstream -endobj - -63 0 obj -19844 -endobj - -64 0 obj -<> -endobj - -65 0 obj -<> -stream -x]M0>nvv%EHpn+@8?;q)ũ?E0D/c(Q/y%Er⯇pnK|0pQO?Ǵ>_}XTU9_/%0qy<?WF֚*4>vuUj߷{..PB~ilW\kcȒšwoVFbvm){梦s5Yӿقo*0 -N⳿ԡI.<58ߡ: ӿ5FC'L\CFbH}kҿFL?//L+rVGGOl?ε_?v#C -gU1\*mL{7O3YhW -endstream -endobj - -66 0 obj -<> -endobj - -67 0 obj -<> -stream -xz{|[ŕ{d=,K%ىe[NLXp^$NjNXJz4 &8"DS! c ~ @?@s @{C'+ -Q4`d<ѵuౢA$ -:~p7Ol!);Ӕ8~"5=/ay+1l06 Ph2uZ7="^&ZDI -F9bmXԼyNM_2{"#ErܜCv |Ar|M(</ohD"VR7?_C4F$z5s~NABGP 62a{OE-M,yXE+͏JkBր2GHS✢ -Yv:'&:JDD|zހb -LLvuM:qm=8jzt޴B zsm.`Jabr ?WQ;{z}OHMc6dӜ{b4;NGa/vgQ -e  c<)bI9grkhJJ,VcpU߇TiGG *|"E0tA@Nkz.Zz -+ގ@׵(sYRJi`|+Ѥ:kG4cqKE{hOXӝW>-`W#jV[ -:S1o#|ӳ_ ([I}*@1OAfg^( -@@k;Joץœaur-.YVP_t/J((tX%rlͱݛ=CΓ|_YAq68/ -gw.D>Inкkwm)U-kZOeWA AR@O{e-Fą^h.Wu!m5Ť8N'V钖cWZZ%/bϡa+z™cf -$}lltjjKԅ]MmAv,jv~3_ō۶x( oʒMM%λSj##֤ypy݇^+"O7٬bõq-N=+wSxBڏxԤ7+R]c -oc .)ϫv-N35WM3zZ/@>-F w/ ,|''O6ӊ(MVm'/OqX/x& -JψNmM/%>^B7UmzW߷b6]XyNj~J!+݂͐^ۢF`J8Yt8ՠ[A_SCv5:γzo7}֫zkxX<_UjȽ5k1C%=]ux+7\QOboVGدK_fIމzz8.A,ʦC2Nn.BЃ=4H17k: + -47} M87R9p7yZ_$4vMy6 -VaK+~ "Z)nfV}c$hX±Fc -6nXA c8Ht|xc Aa - -4=~°Zxc yHs,X!DJ9p{0G+deS=ñ;Ss~9S2`ӯb.LxcCSp?%76"nXŨ0lvm hws,Aqa+scGAi[џFuNjg=ƗxIXa775qN ^1}4{9(1]dXfsLptcYǼc9p%n*1ac2'8QM90b{JMuuyh`tdld߸MLJF)CǔXrX2Q9o9J\w%GPR[^%W.Sh<<={#` $a?}ЍmF0>%q8J0 ,CJd:Ɨ8UCqO.X"j! C0`5YƑC4 -)v!*䬅CQ>+D%1feբyWi:rWb3qkv1am G3!6jNIqdYC,>4~l168@qB0hc,Jput9nA?JbT} |X 1+8K>¤Q3jQٌKR}UceG.l:O(Pl=<@yϠ0ߜs [] ϭ0(߼`xV0^"lˤh/cΞ1&whw%BOYY~qճ{ʏ/Y=k.ک@;v|ne[1LZ_ƗxlF -1/YZh_;1,~US݉깽xw`q&#ܧ|ҽ>nΝGz4:\Rsa^5s ]BU//в]SAy~'7駊{W*ςv*dS U&|l<|u_ǫbϜp\댲5Ϣ#uR*m=ˑcj/Xƽu[,5~[j"$KkRLjt%5/WYJ#+Qj1wr,_jIQ}_y'zRddVG݅MVGx4{3&s -~L -i<2)BS왑e|8p980(ɔqP\))2?UPHb B:+S,s`p2 OwfNl堣X+T0,33lwf@0r -**Œ眢b)T"GklA:B9se7Tfn$edjdRC,WGVPc)$ge0p`6| -@Fh,KIJ9GIk8ظQSꥲȜ 3lUsPt1`h'µ2WBĂZX26Qi}E_W=yU~\^gD=W++_~([߸ -!Z_6=@^ovg^/{ hps?mS|iSOO=1~BwO[hp4u?s_8>syѿ#l'=o} `.(_6j[;V[qkMuʵN)zfވ>jUËGHpg*^!\L=Lmw׾>1_oi\:ADdBdϝ]`m8>z\/5}&.NIL钿ɏ` -/;69UN**JY_ɲXSq_y[#{NEGw٥Yhwzd6pm~g)V i%#4*yޛq 56ci#1ɧ|H[hh'ig`ډpx(4> -endobj - -70 0 obj -<> -stream -x]Kn0Oe0$DBH)I$} @-cg3Iݜ}&ق6<ݜ~Af\i+z˱, v=駲d[؛[ꨦ+<)p |QaެUWЇ>O}FH(nT~Y_bgNIl; 3RK{i#^~v.Tݶ -ޡLwmc -e r;cut>EgsI!8~<*9GFsÉiwj')z v -endstream -endobj - -71 0 obj -<> -endobj - -72 0 obj -<> -stream -xܽ{`8|\wfo3g3& -r rQ.$ $ (\DT*XbjRhZhEE(oKi=l}}__yΙ3  -G2̬hvN,7_~#(g#hL'ɝ -w'B܈FȇFZC h6܉Cq ف -SKOPzt :؟ ݊6[eh2jBw h:ݎ hj듳$O>~Hv#+ -:8N$#o<FgAC+=Vs805 }P%:1q}x-;jy&ٞ<¨5G\e29 6VAUt gP0+|MtoHTD2x҄~Dpim|k!f@o7?bnV -nLG~O3~Lۂ, 8FCPpblIe!=q6УqSlj߆1#̣_r߈0Rt71vx -7x3?OS<3,fd5pLZM]ĬįJ%7)'`dIg_03 |3xލ;S/3wO|ApLd2-Mǘpb|,6Ζln g.ȝ䒀"~$1:AYoS%$v$':Fi@ `!CkXm W x^W&Ѿ~>ۙ0ǍL=t03_"kel^Vla/d.b\˭>>o T$t -%'Sj^g zg -h )̯_?EJ8م0pͯ3Dt`d.1J<OCAFm{nPw+y`÷0_ -6# 9;o,rO?p2.yv2p,>^bu 3$e6 q7D,3h-f~`oABt*kѧ9eB4r[7@ FW1{}D@'9}zy.Sq̀uhZ܀V3QwZ˄ UL;ȁl%s&_ a_RWCtA{;1N>N.D˒ 6'B^ oL܌QfΟ~ sle>`1;/`;pWVwhHnK;$h(cDf_r =$Of`5$I(ȣZ11}^qUÇ -RZR\4h`~yhVIϛqT۬dc -FGhv.$>5dLVCiWԡoԍzOIh娼6::){TJkp%Spf&7q6}ʆkFAuz'[6þ1adCڃQQl퓧=*YտkGkڝqZʹ #EڌHFۺSAjsfU -5j9MB宑6}b7j$uf}Y}fkU29cjOӠ5fcլvHȨGGEZ&ڰuQ -&M]?'ϢhmYPvTxm@@W>_OQ -s8Mf <-NS{0Ic!ڵ: -z2+ -cJ.CֺP 0>(.٪ #v>Gj[]2r">a5x|"H)j._F -n>4p[[5ПI|WA}YFZCB^jgjȓc'i3ȓ'=D;ns*^a?<7?e,m_2yfBcBLO)&Yv. wJ1JuƵJ_L^ o[kf7ۇůL"}El[Y0go*_ XhpyGgej# 93yl(9B:l$)gd+ -L -w/n1Qm֚zyy}kt&j -pՀ`5x˔}:2mi[`fd5U٬B:eH.$ $x Xha)G3h#gIaTyJ*u*MSUuNK7Оv$/zjf|(3+D~DbDŽg,2A #lv_HSf"ɋ("_V"HseROT.ƍr]\UVge._V}e::`VEw9akdUy9҃25+Pӡ˔,pTE^0>QvFU<$|z5o[7cB3]?sSwL|@Ȥ_~+; -+!mDxm|<k*O}(`ji]7IVKZg\A9}*s) -r - -pUGk]KUªK%Mx7ܮTEBaYDG.&TĄ9Ef(aӁH) -+|NIi'v;3 u 'VBHd`+٢_!VDVԬVf'!I&^:!}:^}n<+1*/˻cUV*#܀?-',*1-.3c@,H?K|=-xߜo}b:εL38%Jil}y.d>[l #^Ɍ P>< -˥]#EI(# 碲BsYd7pŠ -G"K${$Iȃ1tDFX ,6l˲.z%qʥ`::Wm0KY|Q6MGfqt^ep:q"/I8C'/Q*ɄW$?!J#A -f+j{kd2tjDvS:h`6$Z o,`m]f4Beb.~K8{e5(χ -L^Wq0Cٖdzojkp}?4%$ᏤO8yDbwmўF'ʏǁ CCzd`~?{~~}pڐаE[=}4۞GT,dP\CWN&<(/\o.6r-%Zo2|@2`,w]LKU|1ҶKW_Q?_S?_Q#tu|`6B8Jd"ktF80d^8 -RΕ¬_RJL0?F+#F3dAm6Bn%eӆ -eNݑbc{c|jfF3! - "yce2\#}Aj -_N -LP!06j?PI/Hg,#Ҹ0hh;˻.vŕKAS6A; +A#B#U~9$TA1k"c% -QZBž{5S MKx}+b¯lËŧ[n]_v-/LV$_Ѱo9EK>c̏7N0seZ_~xv܀U.oj(0/U^Wsäny;?| 3+`}#l˘E^E;e 4w*Y`]96-5b^.rHĝbxL<% -"τDBtBN սDnpAɼZ} zEEsJ%.00r|R5ZZQӢ^F N(;qO}1Ybc(f6q"{a'ϳgɮt5+a4-b$׆^+*04*}zN֗G.ªQ棢+uX|̇}d6 .i^2`2m9t) #INIg%N"DU0Y%}h˒LZH^ҒP^cH Z]TtU/c1w#32j;`(\VP8[-j!PKQ5hxf)D0Uڮ VLRVuٔ) x㺥J[=)”fb< FEpWʎf95(YTasy&@D1 {u"Ľb"Sb-HQQInR݈cED/!{4{wz۽I/e<`,i: ~!L'G:hBFp~mQ!J841 -a}(G -6POYM9l!l8C,@DQ!Mq˱/Xx_cs6>N*CyR7A5K -\պ͟1.S]V/tTr8$ 7aUۡ"ySގv"LIEt - -|K Z}C_oH@vN'^u ċ}{Ky%L>9]}u>YwF3% -lwcSCeOKs)5{>r1+TSE-Z`-o=蜫1k -øΛud\%s=lU&?r_&x:ͳ٥t*/G r` -~H9?O9qx.XeSMJsk>RQc͢%z0+ s+ԅRu ~ٿ?`_yлԡ:t[*]9Je҄ۂsO%&rhz" -Sz+lE̳*8B)L"ŎS*do~zŇ5OMV׵>;h]w+iMg}XY~3&Fe̪Z+#ݑv/xLJa",XHs999EE"yum#֑̍ef=[Ώke Lyb?yRr&+DS@v -322NV2]ٖXgd^гɀ dg\FxHzER\:f| -3+c<cڡ`<`Nt&=&r23O@ &…X38"z![q%V h̀F -]t27ՃS8BOPKATfn~IMѱ"h}SDճߐfy5 -@NhNjx9i)$s@#m:A']=rfAM+MJ<<^Gu#*sJ7k, -=${ -bR -+dٵ%d#BYQO\I\e(dɪq!NR\2UIˌ -len*+h'~3<ȗa9={F ౭|g GR;4 2aChJ -ʌ|^eHԗ'sqB@ABЇN?KɦJTlv5hiT\+}WYYx9b, r4lE2I4itK5mBn[zq?X'@k6rkm}.o6Y6Xm{G}$7M+$ZLH?͆"~dn`5 KB]:u -d#dCEv|vkZJӘz.b'P[5Y4#-1b0H#P4 ANMEK>y狗n;qiq;,2livP<}fr40>vO;n[o'=v酒2e;#~OquS KIv/˰+309; f]+'+=$i߾&5Zx?Ywc1NbL $e2'2AU+ [&|+怣O&<+/Ioȼ'ˍtc0J3 -bt5=-5~0{?޳큄+q{H_gGsY9N+m^:0,(Ze-0hXMxH:7y$*֬XNX뭼"ib6&H^wa\jM]rWVƜ'peZbdՠdzY}L ء1eĬC F -~FDN7I_<0L# aF* -ZF؛,so[íPJJJCi -aw K.d?<>..ϒ/: 4X$p<DzEAXIEzMzd* j 0 -U,XN&K, ,NƯK6i.VMCI`2 ɑ0FbYיg -&n ar˩sm[`.t[@fidblܑEE*H(B+U-p}B"SM82ûΜ<q//3KĘk[AJ/s1 -w Njhlӫܙ|fy`qTf<8Pp< 4-,F6PXpH?b9U6Wm[('#w/tӃ~23NAGeU/\ -P!ed(\[3K8&pduX\ -r1l Y(G̷%Tf^+beuZuTbqekFl8)\jʳ:򜹮BP4ue!Ax :$q{_@:ϝw~(|-4F`JPM.| -'BE+!ڱ-!DؙOl [՘WsS9uUUc&0Ӌj I+a/{XgQaY@Ɋ1\яN3UhrycwxvĸljA|Ob,N6"dNɞK؛?$7ɷ%O[UF%)_ϳ<>//-(Py^?#ROz"0Q=ʾSWހ+7;C)''9=cڬfӘ`dc8ShSsXUK$O1 AܳDu$!FYyj8Ը -e-T󞏾&5NCkwU - +M҈!엃ࡁa4.#aQ6]>dU&:^w\s[̲>,|Y{ i^q9A3dЫBqgܣ9==bAc ߮hv~/^#< xKS5,[Jkڗtc]Zi>*HbZRݳ G# -$ۢNBc,c Fi01'IۥRtL:#]D$eHzI3묔 1,h[@*' b'\;w; Ǹ 8;)Kq= ]P2!Ch, -$RBn!p-)QkfD[F2qwiq Ci\Dbt;\1t2 XIq8ȸgs|%N0$\ :k<2$5Q+Iq?K黬N,)] -tХ#JnE,g.#;]l -Glm 4? + -̇XòX׌Ή++bp.#"-d󲞞Q"VdcF2-CtgEKv'cp1 -nDUdxA0зQo$c6OYʥԶ),X)N3%3@[جe,^NjDmMO.2[V -3*S,4fS`G?x㍎D)#7~x~+;O<IJgP^DcGB|Vc#(=)dQg';<삝vx(QOvMA/r,+-["5;rSF.(S3cvjQ-7<^GXk8tv5d"''d)e -4l:g1qtaGMswaILly׼Ms,X9/XWov݂xOw͇/Tu>޽*YsU_23~ 7\*a?7'[_K*] UjAܚq:2A1{'vEYd x"ȴrgͮO'>iomj~W -6 NGKK k"ۂwE -~D>e/0DGE&9:#LN6Xt".CV(O W{fjZ=޻Vb.=*cj$p 0K 1\b[i][;mx+K}7y=iڿ{4eͲ 柹[~+$>J=iK%:6` iyTFxdH!?"\N' -3vd?^~]MIZyO53:#HkS-gY_Ls ^:wB* -Xd7=szF._Mӹ3~BZ'#/1hT44ՠf'E|8Ggm78XO}5>5fF~h " Q!^p259ʚ6'AYٯ9O:8N.YdgneOڼ@-oBrtr%x{dsr̹ -_ij][Z4mlÅe'?ܺYkVpJNC>'W?#79yzlS8nubS0gŎ4BÑ0ChLޠ2M9DVHH44_((Y٠bȋFvFp#CAkdaYsM[?V/grL% 9V0t=AY!mgI.uB{|bxl8-N1 -yi48(T^ẹSd{hUWEcJP>ȪȕUO(A{7@ 9}_t:nj[goy;݃7^>ӱ"f6}*x}2a~ŀf2i.{ -.*upnӜt(? O -1: c'Y,[.tYݮ;7D!&v+ךk˵ -:Vy?ޭ|I#)붆CspFhCӦ-#6qs\N89VL`M> -VLa0d*:[+\zŸ:58 Ŗ&ɶAKPGGH[ 6 s4ۯ\< ]AE!'&KtGl  y^AydM}}VOOYCT*gW}S5lEn /(ΧxkbƳ2u$vfIbn%/;ؙu?bڕ˿{M4bYpJgeK|4|=3]^:OMX{o>vg3ތx[l؞!`ØRxf}glzy}cSCiê8Q氊0kKř(T*Q׫\u2>RW{DJEJC3TMc4.%ɂ~ -5\ٯ'3bRR6F|1DTʋTʓo'D;Yq$ -cǯƲQᥦ n ?~oW,zWѮW=my[`_a\7NslSzQۜ|)?+23pq00M2;!XmrV{o .,78ye|`;;o> h|3pd~:׊MIsp4D $sX٧Xz+gJ#(V6lMXKAC9 iPZVMW׈+fsN܎/`.WI(ET?aa!*Ć7-Ei-SM࡚ wEJrq\nR -yFyISP4+e߼_=)qb;޷Z_&xm]'> D# <_JpZdhlkқeoXho\rmoNheQY[:a9ϹY-y\\rÔ18e Ū:Xo8{>%cEyitjb~3mX'S߽F 6.f2EB +Hx$e0Ha& Z֗~T7CM\3?7?;-8s{ϭ\Z%WN-3wM}}[#ğă2 xl9`H* 蝋-HDt$CC:1Ujolya亖.qc3 \7KۭBWbo$]~kF$"?&\gn~ @0='f 7l2)g_MR`Az?jNy5R^M^D荊DL2H 3 G-aG`8E3 xv낅~O%~0t1=^zclaؖ:\sŹG/W3zTmwyhxՃ?I~ -d:ke8.'- dNJGg;_w%ϙ@N -4 -@N -\&<@yX6 vDG.͌Yb]d_XqSVdlbZouޭl̾=~玴iόBc A1TBuGrsp _EKsX}ƎLi -#vح|&pd" -8'; > ./OKη5<f7?i4 -='P?܏ӏtN,1ᘋ,Gkz>.tM'TwPyEdO@'{H).2Υ!|oADeluM/L|#D1>C (b'#.9}OK|Wr+<*Q -rGl@sQcvKОgo pғ`FIڜa1qc$?[|9b523J#iķn' FBYt_T7CT&t=GP&eoHY4ss 1}eEQTA LEr*8C|aRL.-VZ+' --:Im| -K!9|xDPp)E$bykmdF׫+CTegw}g}Џ2я{䷉9CzR@M?<L 䡛vW\ ~x[ct6 =gښ+X` -yFq'k@"۝h6O'atׅ~~8WoyEc8ލʀT*}l Uv]>_fv+ΰVX'YY+{CYԗR^ҠXkC=ztp{|k7e)IiC]򘫬g[-.ެX߂qXg̢!,9Dta -": -Y3 (X_vsydMLaj@+*]ubDtI*> -,6-ݗYLbl,R,kT3r -sBSc/ںW u[0ēH'aIFG*A||ZQ 1N0 f}-#A"|-&)L7xUk6]y,;_$_Ldcs,X(7?k i$xub"ib7S\+! 1e(v879ym hz3({3,s-^BD78IA8+vy -7LsH zF{DpAi3ktdbJNPBy^=J|}6{dз %}jRHhhrmJ&4DrN--I#ip]A{mডC#iO(SxkhPA)S"՗_̺jițKi -RZ}WgRxBzjңxouM.o6)XOqJ9]BfW4B^(OpC7Ѻp)D2Nn31RgrjwʵA+p73sVPL&:c[(FIO =oZ4[m4Gj=RC/9k&s$ -j+%w)3l)"5_GfӶ\}2M6ylH\Ɍ^ibۨWRZܡQ֙oT[B4ӹgp21Yd2)JsnrgIO?T/}K~k|ufh -+(_h902.QXEqJGT'}7{)5jrY4.EkFIui/ϧjdu(Rm/2

-D9([ߧ 駃H<O\u -9JxZᨤӑDB9rS֓o&{y?bIIѧ6zdϽ4$G5o)3[9R#l2[#{)Kh#Ͷ3)ySt7g\}OPf&?~R`O-75 yT2gRfYQ(JL\ݖSHZjBKLl2k`ߡEie ]K{L1hZ: 5mv$O1G zJ^?cn)?WMWwbJ;vhJ>lb3_}{)Q -^{%O#叱tߥ\":޴Ќ^oѠ[Z"oꡕ6 wk1F>+t4k:;SmJ}eM+ -tO⟌@'6| A^U * 4,9k%pзRIj?u1[чW7/vkʦeMmljinjmklZ5/m_ -ʴiMKVVm2xoPYp)XDڸUZZ߲~%SXRےva3[ZI*ZZ>m6v~ږZӂZKֶZ2 -ΘMmbJm҂e%75@=5x67UjqBn#6iT=iImkVVb|ihȦemKIZVkA@Rm~}ke:(U6k -+.ku --u0 H4ֵ8jil5#X_W͑B+F*2O{qw$p0`da@-a#0 -!j 18E. -q6%Dt'T2SGIfIgҙugJLLqeM6ugICS;ĸ }o۷iG'T%E2HAV:ThG!SӍtrJMEzJ 4qh)‘t<QI KkOի#3U㣨DlBhmG\Xhgse\O""IhlJ -"#JP*b7B=29"Q`)0V07 -}$bq^D5^֐R"Cil:Ibu'zJźH -,D19y86U= bd<2͇jFL5E=d*Hu}d2 +aɄw\OĽ ?ބ6o_ Q -=w PzVֳ?x? #+Q!kG1]Dt-&&ytZNeg,HX_l GTgbxi:gxvfx:X8G:Fuq/ɣPKjAut -7QWMhy5<۔H<EE4d֍ʡ +;;hj4ε3W m6269L;.^ Nczdf&GQǴq>2Ý@,b&xY{=V51 {Q55a e-d:>=4S3s=;-nupKXE,lܭpyVG'qCuoo۽C!T6ݧӺ:nF^Z}I&?hӴ#ذ/D6&f_I Yi^yHpO -G#‘~Hp_8/ G#‘~Hpx}uݙ8NqWm.n[m u|^==ǩA"/oY^@Y`,ˀDdP/ Y5I`D-gnlXY#fq蛢8]=ZŬn4]&lhr^R|>P%U7%IP~C(%2yNT9WnYlJL|^Ҋ@ [fK_c}RſPY3RR(fOSd+i]*rsrf}!h+qD=༅8ً90+˹wt3:#_qCșg<'MhN+j^<#_t_yŝ`P=+(TE|3qhP͆5eAa<#w84p3r\N8)stܿ}kleMJGcFG(rA7y+n**?'m&r)3h¨{)B4dШb.OK?lPI -t{=} {7g)}*Z}'O`.k'hOp~Oäjr_E]^muVPa [!{Y$u~Yx𬴏~<}]p(OzDBspzMC3P\,ljzϞBGۢ\S%Bg*u}B鄊)T-)TR9rR$5SzyE2t<_vzY ۷A7w||,-""g3slS u6YU>O$o{my<@6yƍuF)n MSi3ˬ5uģ4ƺ^<&h{-h#]NH2:?<8kvOh[۴)_>oV6WJҪ"[׮7(Յ%` \qy˜F=T[CmD<]$+M+h+X}(]^ -endstream -endobj - -73 0 obj -21896 -endobj - -74 0 obj -<> -endobj - -75 0 obj -<> -stream -x]n0z -C O;|h -)~rvƐ~Z,~?EF?wnwΣϴQ/i%<]4VY#]pWa:oYFV6>]_T)|rzx\}vZwޅΟ]*Vv6s~J%S Ѫ(*FmDХ貄5=#Oܗg;z -k--++~xt!.M~&-oooo/97C_>kщM~h[$~ -KM? -k|!#dFC&K&K񐿒$~a#)ܕQk_z a6#טBqyT2ۘѻnfTq -z -endstream -endobj - -76 0 obj -<> -endobj - -77 0 obj -<> -stream -xܽw`8<{o~t'NI.2e"w[ز$[eIdbm ZlJI^R y ŴCH@w3s+Y$Oyfvvvy[R݈EBۖ־OBض}~EHv醾[;R@HCbmBHEh퟿Xh -AC; ^ /RC޶2{I%[Z/훧s-=[:jC{}C,B'Ӑ_E(p?hKIa9T&W(UjV7Mffw8]nP8Es>YnEvrCrf徔lFlgPxB;h?V+ըkh3CaT.BځbH@Ȋ[\ Ȗ{ -}ļ-t چ~+H(MmD&/Q -ɸz2\EF5-ENt9p!/Gaå9t+Nh Z6wJBtoZ4>{Ы0*F3pϝFTRա7ѝOgKScjE[yhBk7؋0 vHzW}gXKQl]nSX%x3̓~_=N3軀_b7^%eWe}7g頯KQ'A^}{mt}9,=&ɼj$TQl]n@{8Oyx2:9|e>}'"#$C8h1P -@'SE?@GB>|c̓ϸ/%)woKlPJQ5@_z]@Wяѯ?? g<vs=:{;;\IOt5{{\#moj з//&mWR|9 -ߌo1sML/brpoKvJeٕDF P -^Z޲}Yk?n}oc*l>p,V܉CmGF?s3MA?حm1lIT28%+a$.͔=*xɪl$ۜ6LnEn{nGܣ'ssgn/*iD%h+0}Ga qpOwox}ӧKp)K%^ -N-|7/35S K.#cbL%3Y,fژ<<͜f^*e \02^>>;%[s -4q.Uqkw%QSd ߓǤ?~(ʢGdGe9V)q1f5/2mQnx'bx eC@oB - 822w K$?,Qq'ׁtrDft@:rY؍Vܗ8[75Lm::(| -a)Aз=@irB[:=gng2s2} zowFܻ =}{)Pʁ?݆̽9f7W-&ìb_RE NנX3c:w`C8nj73L6ozMQbrH -|>8ߍ~*k=8qj1NQ -L*XuHx̝[LV(hRn9j5+5|Ma&5#?GE+iv`%?2F& -Ba -><;g#x_?2g{prV`VQT4b ZLV_uAr -tj]?&=aC# VYm#(0sDU,} -EFG 8G5+F֕8wmY,4n↩w]p'zG+WB,nxFD{:BOTGď(3Û=#h)ʽH+uv3^RXHB6  }tqQ揁>= -\J}>B}Z݋VܟS49͑ tO=B0Ӹd{s@  s -v)FMPt4wzkd΍+a -A3EGyՊSzl,Yq̬u3W ½xZLOre딀nz46-Oa6 g%p%CuT6lLH}"#\*aGcoV3^s\Mx -X%\J> j%ϞR?sgùJKA7 ~j~tjP]sv= 5_12RfFqoGx2ʘ6Ȃ-(G#{hqsӎcpQc@0gh8t%oh<>vnl ?[W3lil- -DJ؀-l-/,r0Ne6Z$y#Is{fPGՒɞ{O.ۃنK#8w_W~xߗx?ٜ_*.,s%ܗk ;]YDɸ*9{GuY*e* -HhJKe-ӓX-@V-8ҧo? 8dBEFeᐕ+ão$#Y;j -pb4cc]b-4N^e-zͰ9< q0ZcاOZg @(,zKBH}9my9ثsgRnRܻݟwYfPh5" ߧC uce|j@>Չ#L\[ѹxxܘ~1`WXmI\{A^2cƐr_^sVKI܂~ ͶƑƑ* /tM3ErN%NpʊJT;UVQXYQ^fUʀuTVV)Wk,[kq嚞6p,.ڲLv^лW;c .tnZ"/Y=zKP=~dCA,]X2"\L&,H*g 8ۑ^5ikkωEڽY/4gAJj5z({o.c2,[oȆH/*L44M4!'ןѼՌ!MR2#"?kd>;6hccuyFJQcӱSgM[ )l̀G0!]f$T,xy8 -wɀVlxnږay^@Gr!ScyU5 - ! -w0OL/AK ->)yUR%8޲*Zt78zhѩŨ?_[y?M52"#>c|cң0ڌyme<۴uFgQiXȚ/5,PRT}SZjO3F:)wycg}2A {]H*8&]T*%`PnGF RQ8@Dѩ$D4bZ;LZ5]XX Gm /V4̆2pc0ؽHR4PӫBv=!^LTQ̕5sKCq6N_`:B\aѰK+k5.+b].U hI"*_x-M ]XZu/NXx^ tkή3f-1 !l RjU9]Qur1T%IZpiD@la"i9ٕ^we~s[o۴a^feK7|+pamcNC[@^?A|y1)TP(7d审 Tcֺ5*(-f(`F#7D-f}4 Iö:ilC ŒL_'\of1Ǎ:36⁓% -\22b͋9cu,j*1 Mgǁ-1i 0k+}<%RBX`]p&oc{SAj>nʾUbͲ$2绯⎓C.ŦZ+#/.G!9o=nN 3:s^^D88qNu\}c<^/FGcIԄ3xKh0ჂJ,<A2IX`yhUI- )^(JBN?^ - -)c_?s"='⼭js~YMjnL*w0P&Z^?60X)-ak`Hjxx ͋}a\e9ͭB)SLcM:q|HhfMkZa=3mW2[KjXK$VB1P[OUں*m t\pR+V[޷*MƚԨO:#8ղZT¨ϣ -[G:EeFqX#S4-LTP)A7͙@Y&=7{c*w\wh# i̪]$">M罪)}6&ҁj-6Y04el~S'tx"Q'4kUձXuU+fFgTf]K9.kZUVeg]՛Ͷ΋ҥ2|Z )[0L/Oc騠S^ɬ`OroXAuANcB.a>8^`Wy c{i]N옝85ip{v~uzy@}-9]^^~!̅eH~x/*Iv(9B1h|!x> <ˏ2"eجq ܣ|8|jj΍9@PhP␛G^W$D!B`a2ȵWد54@wZ>Q(ak5m/}Ǽ]ȗ՗'jfrp}rc ֓i!XUή"*&p^b=NP2I0&sBݦr -*{ 1ƯjijA$/ -p;^0v! ϟ~//=gvO BAxeD,5g[c5i<ϵESTP)% E+$M -ҫ?yK|b[hzH6XMSw{?~줯b-B~u }Kk77[p`Qp\d>sBMNdTF =b +GJ#!@GrJtN@fÈQr?ҫ$?U$ &}d]_non7og_~4IsRbȕ(HJSU -@yQV}Q%уc CIG@TYQg19c8IC3TU)(;~bb=H K()hJpdţ'~ğfWQ{?b*+=u501W/? ̓I ԓP\do, -˭dJ16`nL3TWfzR|8aOըy[;R/\ZP;3uv ؖ;?xxs[EqJpH+soO蛾CONR%.$)|վ9B2|'5}χTVp_uGJw42ZMn#Aw Vj)no˽^bƢ6>@\hێFTƘw[81#W5/[ m_t.[]&e'<663C!S?fW#ӊ-G]*ꈉ(\3c7~y%WlPԜ|7i}ekc_9U27/B -ܾDD2{֎ԀoX|pQӥ.d>ayâXZzm,A,l0h,RL. 63ƤP#2UVRc -G\K˽.rqY -"j&S]rGyWIVcGVp-JTpKpce3iyאk6GXX~< 3NdN4!{Q,AK5y|#^bWe, :S -gN<ւ넏XQ\-Je${3bZ}驈Fe5{4WG4[_"- -JK~Px7N:`e<ؗ}ڀ6wk>`Ws8PMGR:Cg=yш3cMMCƻht:oh -L>012P8I*ı" -tfT<JcԱ&Ѕ)} ñSM?OH>:7'gEiR*<>Ҝe&(KHXѯD -KO , N7wBA  -ĤIXGmtb8J@5m}ySlnG+2qו%7+nZ9wmJ͎f}k=rΊĵ7"3S{`<²w= U63^cUƈx\o8N%d5C#OXq%EŊŞExCj -^}5Џ1%^|757T,ZEfWJ,_)i+Ԇt$T:MyLxn?jOX -{FfkڳZpL8܆om,4;ů?aAm2R늮J0h.^ۤzWhviw..]r^=:}jRK7ڋ/_/+wi(zR}X{Xg/菕L+XK5$RVBO+'㟁'sg>8 -(P~JRSG?ղ_15D^ٛ}kOMCs*Ə-0捎+Õ^fVij6@CIJ3S/\8TV,7RR}Iŝ.릢!ugѥ5{}Ejκ[{wŽŇ4T>6ppj`i'N -m4,ً{+̾VusH8\XڻD7gGq$8܄4U20C¨1Uj0(ɚ_A2%ͱXRYU孮5WWעyV5̝[]]-&cՍ -zd9%K{PLЦ~cb‡p ,B ]- -Rոz+COVg\=Ws+4 i1xfla -D*IXUl%,;ֲʧXvOs s텆,mG}W - -jĘ`d qԯp :kM]$xTqj0te&\ʉu:#:202)0U~׮JWʹ]ୋT{ -RȔVj/êԺ 8T`B5ϥ|]jAe\x4^(+]ťͮY5#{.V)3͵Do,K3z&Cz>ɡmٟ3{ր:p XW%,$[U\R7miN*fffgT;pN;Z}D})3k -A8 @;QYHZ~`z -qC6Dd?v q?56k&r^Fpc秴j"ּ -L(=j+1'M1=9kVJ#pe|l|lrb,84KZ`OKښEՉ_8.8ju~: ̵N4ddTE̦ ] TqhΦ0fa^К55^CLaN)mʢyΝ$8G]٬k.uf1~tF~դ)$`iҙ+W6A>!ʔ߃Ff= zR!gT>dz~yt}:Ӎ{e*Er2LV*+؂Lݍ)YeeԒ"fpK6nj|P/bn솅v<bwb[D-wv+ {'̻A/DFC{\JPGJWIj#}CCcAg^;#ÑG|UBE4DLaqwP) 9F_ ~O&aUUs#ݜNh4 4k5N0g nIHJ{nR/JNccucmXW[V/8RhՊg7!0d7VCүlZ&oϫga߾-႘7K(M37qWlo3kQ/6@w -;:WJ[.D.92f#dHHax1 Kg4$CN0|zFy'LH,G:%Bi|9YpD.S# +dTǼ:e#J p4ſXlͧ5t7UDG몑jD"\|˳_.vZ|- 9+5xmE,bTFO6Ԡ2Quj?d -2 Q8mJ< %U|n+W[~v!C)9 |w$)R8[5nu7'liVnȐ^с$'`naѐ -3/>|K6,w]ScWU*az|`u$?l;ҞX{컿'XaUopLtbQ1t -GYI ';ۤ?+>G 箻}-"d25SS%TԤ䢲)PVٲtʥt](QI, ,k-K˹n4T/-!};|t*OKc4VۡԧMBB @Al ænUlxUGK< *fD2(zMaD /ˌ>dNxݮUjaa e쾔jXI -R` -f Jl2! o7f%AmNw9PJ}?J w9t.81\~f qo脧1DPBN݋e"S5~?aЅmŖ)qp%#[NA1&J,H'eN*! -nMzfmhuxu䶤h"ܘSuR -͡P:u!A F!-,؅,./Sc 笩9ʦU![trjEgdeq=O>=NtlY=В^3|~W-ux)F.ToVWYu3Jy2Zh]_ܧ1h gv˫fUԛ0LNJ&ḍwhf! -!z!Y;L11ARY] 0F<5ǽ`{#:one7} -q_oEIx$N>DEe.wBpS&s0sIw 56 ^~UZ 5Yf֩p1aEJVL8N -ÑJf 7v|VWx]15?--zˏTeg\mE|G|5_<d{|11C!~XG_BYR~`vOw1VB&p p\}Bk,h py"cpxRƍ]|ۅ܈@RSXl.,,l6.|,FR`@b,4G za1S-Cc$qYbNyM4U)^Z(m6ijuG&c`r1Vw!SL¿dQH -f29 sdWLe3;{*}22wNLNjfjEcڽ/$S5KaYe.#?J 3 bڳP9h -lݝ%$ YŧYEPL -ޟ{W#fT^s&ɘ3 -AP۽' iʟG -.Pi&4<~o}@DHxeA-+/"Bw{3؆!K1=cLuЦ)9>D -M5_ /%N O6Ao2"p` /{aœwf_}VrUYxII)8 iy]m #P ٜ]\Gdُ^274#쏹>Vy+U0 )%7H̀,?JW᦬mدFOP'0wuᛢEǷj.vFM'ng|5WV5d$ƚYٍ[( wl7[62Fg64c0x]6Ty -IoE2qԨbGQŀA4aY? x1+)q9#pu!-/PX:uFE-lqV1%BuթM嗕enLP=|HTPwBl腤iYK,..v!7.*.0&JL%,O$7߄_YTF&'Hq(XO(:! ƔhRl;)zwQ`8IvҎ88 ;sgNI'vFTOwM-X,&Cȇ$5$֏4e#~)=L(`:u#ƑmV8rFsƑ8B`4G7:ߒ)28 -adN]+ >.o:?5eb '>e,~*\\5أV6~㇗ N~{=>_";WwnBPæ; C`N8b.f`}r|BHLZRiN RTUbtaVc[f\!GY̊Ћ#oF1o 0,YބZUU>#R qyK/ali -F shEƠMjԜ*.Ɋ%J4` 1G x:OEQ9t'n4Uz8#~U<8Ӟa(>u~68j>~M@u2,g4&7~l4Fd_\JƴԈ嗎'l|brǻwʿr|}HL1ԓPWx{g.qŏ[= -h"䍄YsKigՁ -P6n)Y -l[hލPV&eB H=U?F -fj|ܶV+go1M|*wO2=}n◞ -.PA*|z|HvOŤ\ Y9pV0 ^dݨV@Y΍qfw{|p(*8M5Pw(dw:hc]NqT. Խ_x963fJ -cN;HUKrQw=_n8gRn4XL֨vuvlwYp{3ཝ( Az@K\|r;ozhOAd),B`;EX%$/Q9+ -t=ad{P}V -()Wmk; me<N/B -tPko/x --o%%5>OwWϷo _ߒOQjZ=R֏6C=y( -u[8]xȓ:bK<<ϣ0}_\7Pz:NҧtCۤ-TvV(f)X㩜uLoSm#S+}w9i6 C])|o*8{3YF46 -yQtKPjmmvrQ>;<mZyL\I|?fRud|C/x)ܽb86:;ҶHP:E,Dy:r>1@G-r]'c~Qߑ -Po@~HoMpO2O26')-pv -#FumN'mliz9koq4UnF8w:S -y0(@Sv'Zn:wJk}&Cl꧸k P -%TkLQ$h-zT~ZKK]^?OȒ'}J x-,,yJ̡ڃCI3\WtXz8hAJz;_0StAI?i%R9[o;ɈO -jىiJ!Y=b뭴Ԧ9JmD:=]ʿ_af_!Z\"K]StT- -"3|"@N.j~*&5z2Sm?b*oK_s(<`罔Vj':^&_*ȼM-t'kVڣ>.QOh΋87Ny/y{S⇢S_1MFWt&^;_=m5Z2Tq^^CnD딛yn`h򖦍R+4 -ϷLK}vі#L 'dhO/}ylG0(&k -7z{_C迭sS{!ZA=-iG*Q4 -_DxBb%ȌR(LRJ!*S( -9I;[o'%I{dcCk[o"~Vo_o`WoVnlo*%Hc|so6R27sL.e%n~q~q@G%][:;v{4 vwM_|vղʲL6unSkP_\,oWcKkfwÿ3߱k`f~a 4 6l([{Pd%V־ΡE]=ɳ]@byc5S/jw ˖tv -@_H[wwt?0ȷu}$IJ8q~oO;c@_k_Gްw]{:Kx, %tl}wn{{:H{;z-ЁmmmuӮm mcWOk7ߞo2z;tbWq_Уh@6v]K;zw ;U%]mN(a[?!c -t:ә R It'AhlBnݷɷSЮc֕Hʮ#tNޣGzzxӽ=4–7ՙƩLj sG=\dkkMͭ[Mma9iG8%]*JxL ^ws/3?&d0d`r%'pY#,&Rcq4GXw &+/ kG!px{0I,Sk㆓N$"iDɤ)&:& %%Jӥ=NH1WBp˜O|r2X} uu%0!a -VsN$zyO8TXxe(,znltT -ʆ-4!nQ]7A?8?|98՝`I -}Gd4#t HCO1,ǫ]۾CEN,]m!V_MMqT|~?- ֯۰nT_SK|xGfYD⥯s>4M$ -l aw 8&=-l*6 -JM¦RaSTT*l*6 -JM¦RaSTT?T{ݓ<홉%ɽaILLWmx7t;ҳ=_?cn/D'UOyd٘F[.?uڴd -BZ: l䉞DFњI84 61:}fu7AWD?M=Ŝ>uOwkryWH{81,PS}*u3)Bq4$ N#)x\_Rzccb}q1zz;T"fɇ1+*ϥVzԏB󠂂˄B_Oul~\#6Q'2m ݁dΌې>d"eY5 =D%!oYi -!aH:' \_z%%t8Mah9!>-d ©A+]].s; -R흫` ;E1(V2VԫWW$uVr]5=Q}w>sy4|$Cx^`W!o.|ʉU|ئ-*sRo+2WS骆2j zl-bWfwۥ\_5Vk~6`kVZι~2WU֭rPxae*$hcv} X>'aZi1 U_|ޫJγ*ށCWiTQt xTk B%!| R-N-CM)~E3aq~`HN*5;tVԨjBKhXTO]8'Q```f,F-tFDSPo"b*vEC0t[ofy!o!JZ!Dps:`|PQu>8AKpY -Ja([` - / N%zx^\KnK~~i_ZB6a,9P9m<_\&K5Y, -җd)&K,K!nѬ5<_9}pa:}*%qL0aYVX+ -@c -fRAdS0SU8+Y è3% -Jџu1?>P1qb#Ѐ9+`~Z@AXM9, .!/UZIe=yeTg -:P]}w{o@/_+7MW>|WJ;}{ط-Cjs8 -Cpe}^tKm ܪl kQY&_bﲀqrds=f;W/z,C/[%hTY*-eVkj&`%EܝlCb6an6s}*If"m;vdjݑL]~#J#Id[3KK1Sl7#Ks(q"S,> -endobj - -80 0 obj -<> -stream -x]n0E|"0CM&)RcCzVtl&^7{׍ԹӵԑΝQm׌Jͥ8ב.{w2uw5[ŷ;wV!a Q%QUNS=<%koq7!/>2PiCݐݙ2I*UvUDw%H9ڇPB$KFjl39V$d̏….`^b2w-Kua}C< j[f\Sÿד}40 v^Vz?eg -To-;\LKfgo} -3Nߟ J`< -> -endobj - -82 0 obj -<> -stream -xԼy|8>3խ}K+dI>d[qi'8% GiPRBIhUhN( -)iK)/%7PhqKgFv}zw}yF0␲++"?)Bز -Z>ee%iBHU}U/ !"ثk/]K}߅6B}ō">ʆ.7Y|+vM= {ҝi}_tK?PځlX"%tੇ>Xip?=*'/DF&lGx"YJWeں|}CciZ[mfϙ9B?n8 >^E{8OQqnp% -וNrt?y"E(Nj2Csu{,&ڋh#~(fPAȉz]$JN;lvrBcv;KG*eM8oYCN(/opCdFq}Y:` -=oG;:~{J4 -Du;*x;؉J~ct)t z &A2 Ѕh%ܽSJҌCP$;IW9Bs -5<~@:ѵhַ`DϢ#W'ql9Q-{; ܉{~{\[JR Un AxWmff:~?gߓ-J@_(EhZCףoW}Cß -|E$.sC3Bh{|haf,(xQ.~H ?q#Pj( -h-|l} -^vU0O427۹Y⟋#lõ{0 C=EpFN\kqܝܽk!7axumr +Ҩ5\t%o!tmGw܃g`/ѯ{WۿXw;% -~JRGԓF:v8%'#ǭpp<%IbB-RDD)./_|ҒFU t+!`!*_,ƻp! -_sx+*-x߂oŷ q4>a|_OpQ'YRYd>Yd=d\_I9B\VrCOY__ʿ\ -ZQeWUZZzPWꬨUM[bInc/M|`o ]a+^ 3"_ӜsWpWuϸx yWpA ݅J{rEc࿎\Q1K*|5j"yj #?I}xg -u -`;q%( Oks3q'pA4C -~GOqOyD_kp\iQ/#;&b\c@0s;SEt5P$</q -rߟ)rlac\-@9G@M@у@5((GD7]? P[:o[@^8Hπ~' @Yc(;wc -#Ah>v"G]2= =Ƨ2pAxlqz<輛 -: L|]Qz[P(=V]{]i?G[^DHuc_@=QП<xgKүfhHS+/0o1T[+up G,-]qQ3〻Hx2iMƆ|]mMu.J*x, W`z.f%Ѡi5jQ%(Gb#|,<{v͇WB -Gd(rU\S[M\S9WKr3jJay̰<]f{qw1x -BZ;SrHukτmKUiOPЈ3<;cg{>Ԉ'<}I{0EW龨}7JU#(l:v$9kF}i~pEzs۹Ks&!\>Ga,/D;WR>Xz8/-C˱/>2i[|Tͨf%XgPh4}%_<69ԗӾR90#m߮ҽ`V۷wWWe)lh;#w &@mf ;/ڧ;.9"y碞"p ZJ iFo@QfwyVG1be2Vr4UF/)QNѶ|`[E%;>T|`PsCw#y#}E~$G8)p#Z% piJI6O4_(ihF-KgR C(\Ggen"ACAO㗔lى1Qwl'UF -DDkEE -zP - -Մ¶ -[,fLHfTTo+X`-e,K9I8itLpT <-)RK^Ib9$O&IjMC\zI"+$dV+Jhy [ -":Hcxah>:,`W˒CV(b,KHv8+䳃Q*Js]<Cpls:jk|m -"X {w/ڝDxcsDvi1ii¼"gFϷ3Ͼ09qnt 9mEnQ'hQV3QNGG4+,A@wGbխ-,2d - -4W~z5-h-%@+vRᒢ9ͣx1K!Kxvl)JYȰy{/:&u:Jy:ZbYX-r0搖,;ݎoq4I--7Oj+5)-jQQܩlhksR5ioә9nu`ˊүEu͙dU؋H_;)Ӕz_,N]e| -zumqW#5+=P5\E0o\bu*\E&,|(]Q^(JRy^,GJ-T 7,rO[b -ό%=z|xfT4>2>472hT*OEqj?oE?Wum2+? -DQkD+*+j -|"vOUèQfUj|k՝ij6_܄m)2r曊݌Lo)~o$2k -^l)2tfi3W-9:0]ݝc;*V YNqDL#h&J"#. $sרI\S9êÕùݕ!{rɷ[;^)T JdHB -Db."1QsE<+&Ĝ:%P0 ItPqF11P5i0-<+,X y9+@|8+.GɃeJAHy&@&&-fLagRF0!u1[ -.$ci,Ůeb>kЕh߃N-2`',D/r.GL=ƲJ%LiP)q'Ϛ#؂5wε@v؋za^4dD)55am4NG.)vo_L)p4wB)4"M̥ѠʤB7t7չI>w@Ӝchbƛ|u4?_EIݬn.W?)I6}KdsZ/8Kl49Yr)^kNms̈;y򔝔80e7<R;Kx&?K~PGc3wo鉿omvhsJa}z Ѩኳ&s&sdNrNeC)ŇS4oh - -ޭ٫!6OF0)ƫs}QVidZ[_fLVazh;TL6&Uɡ8l. ڀ23LA@Bx8Z)M -mf &VP]9^߱ƱՈԹ-}ܥI+5_WyF#0Kk]ƱVvhڭhR6OLD[- τzφ ~SqSZj9| - -٬Fşz$c[&iMI][tjp -u<5q ątMJ,s"-<J1r(S`Q @u*{ -8HFWU?n)\M4Mא Hk)䖜@qXLX4:C4ʻBƖW~te4w7y. %="heCL wh~OYzVOr}ž"0GO'|t?aqb /w Vj3;_.%"~#ڎ>o[g̨/J=[k E {kQn!fܬnt8Gz#SW]p9X]x}ٛ*^YRh4CsD?zf\Pe\GDLEW'UҤ׷JfOp5cvlN51Mh$b3/u6#U#unhQ|s@znePcvS٭˟[eW[oxeWO^3B)'9ϦWQS^ϖZ]{xjЛPgxgTY./Ck}ZCRۘlK K4Jy>;%QX:b/v˰?8x9WQgkK4LzŠRm`6W{sSssS'赛]?+pS}[-\U PJu$vt_l>0g_`H}i pKcTy#W,h-"~K#Q_LU&#c  Ůs-?꣢ Akm=Zrjvqǵk}^Pg@Q4>\i?`` ;+(XM -_7?]r[V~YG;^M?Տ)8; -Gs@r[ -V҄1'F22Uf25Bi^kRL@qQ) oTyr@N0t.+5椾"ļHvΎ3dٲhlLzt,06ud)=HFKqiM;Vev/2JqF茎v~i?g=>R'Ο)_NZH˥mf4n֙^^g^FѼ1}qc?5ܴ޺xeΪDbdxh~4(EkLm"+q/U(;|YN׷ 9Ńw|on}Y,.(p.VzrWz{ʫn{k-vSUKj(vpzs.ևz.//tY< dC~n$.'Mӌ,12ie~# -jQc1QD > MAZO6{TZpY3,Y/rloF{hĕ;Q~DPDY9$9*F-x-qRF \ev]^(#5[;חa}R-+\}~o{ܲӡ -A+m:5c4\"QNJVf*zcskGĜF%jz>Gܥڪ.yuy /`t4/Nj9Z:TzM\DiV!ͺjG5#?3ZD")]0i#lm(ӮZ- -nvn< -װxpe@b/_DڑLޱű9ljSRz}5'5D=>Vgh+.XrFmQ2FKxNv&S0S5(J@vכ[Q?tuiʔ* el1sDx.\+UjIPMT4sɜӖsS]rܲ`Y` N}i]ЪEल:ʘ=o5[^C|ub+~JܫJtÆ7ضw7iTn{.Ȫ~QyTUI#Sfb *-(Pl_˱I%RKʪ:4,Ϻ_(,T-{=>r:a -x_O'K\}+~u!v]]'ws%cէ|`̵,çâY? NG~DC@rRC2}93)NN ǎF $[&Jԅ~,e%q h DZ@!ۃA -lXI%r*E%*ڎ5`ߩA*n`[Y)$._ǠޅAɧnXJC4*xAI*`l'&(P~$6IG9|+&nn[[P0k.m.lzlsW=2˫0`WLR8[@ 3˛R98NaHQ< e6(=XE,q.yP\(F[\)C*S0 V&XQs\^e=ʦRcRbJ&SaNwq5DZ]&Kw -k 鱾rjWªLW"s$ xX%$K<D$' @@i1>4g\@SJ -Aa _9Q8w5fEK{Uj1pkCk%9H$nz>t -𥚯ėx-×ZZ`3'vM^:Q{&*k}SB%%JB41De x:HmsBB}n-E;qԗnjBt,TVfܖN_)(!Z) 5 -ZtbT[QDBxfR+>VNQ=ұc}-1VJRvŒQttBWpzbKFMhõ*S(j0a<9uȻF>N,-U;N{þmU;3`|Di*6Zas,>ߝ<}XF%eH׮!yCSήqIuu@8Qڏ^Ȍbbt/xKft7+,HؠMqcVV#D'UE͑K~jf_C\h)7 -v8(Wq;Tcuzw%:בQUks8Ƈ0]ajh,p% eȧ>5xgA$&.7S_L|.~*}j<!z{7Mvsu4=T@xwLdGeȎÑB_/5 ]$h NoYAPq2PfL/-]ռp9Ӏ^k!۲2Yx-ӊLN2{ ӊ1@8]fv{p9jLr:0ZNW^%B/X"W .*dwB!ߣڗ,j͒E-us̬P@B% -Kt.0:.(vp6 -A-G9T%-'U^JUF`̷4_NVmomy?8^{sl'^Z)o.Tϭo"WE/vQiVF=Ŗ( -_l*:ewto(ŏI kzT#!vs(KFsTa[׫7 ͨ󪇘gZѻjnv H4\j[Z_N~@ -rx}ngnw˹X^ nx^DfvOH6E,*ÃX^ -&0]SNOH%N$LL) cXI\+/-W9^nq-!wTlr 8Ӆ2w8-`:h R9aITu#G_O1rW,[~Zv6W NIA?LjP:uCtlL|H -tZ*8@Y&gRroFߏBTtdpS -b7u.mj}~ hMumu]5j͏e%E>l3%EF->]C Rd<ËK}xR{yse97_6|_ȇ&/Q͇ `!_\RC> 5E+[yBcOﳔ8666$`r';ιdh(2)\0.B:?erȩΔ3gog_/ީ3u]3{ުg\ӚdlfY9AcX05.Wtfu:lnӣKg mڽlٛk{-^Gaa-PݿR-b~A` lR,)1c{b'c|L+zD{ѣ8q`Pk < G*"DE0J~o˩1STsn -U(6#@=@,^5\,}rkr[ʛu'l_l]?rwr7X{a~C M3ȣ ZwRI}_ŏݷrY\kr ,DžyH^:MVc@߰:yCNtu`(yF~gϔq30tL/ڻ񟅻D}iR"z@)~I\\@jWV{P8 L -1pq -F': Q,FI1s-1&(SHhTbYB`TY%g:ɛْmx -Y/.FVz3?֡Fy@՛[)ԏ*`ZI8 ؄ -SLR" -4 -zzO.اXDMjUz5 -yHOޭҨU*x|75Li4&RqKqiIЍUE({)-5w%A;j6Llͤeos4D=lCy\ z|erՏ#oˆ[EXAg"`F(Jw_WM76Zwoj5I2M-]KQQr N7ڌ6EܣejFl8:#6F"[8(TNrJ?IwI|+ sMZu'(;Ŧg/wh-oʙ Ff}LbXZ&ɺp93\*4Uh*ojQ9/uRh2ꖓ?O~kΟ^vO^^}G2ccW+2_Eɵ8g>Cqȑ[.\<뗤#~/+Qe&YMcE`on-~ϳ`rFgsUKpx1>FC7ãԈQNn1rY%kӐgٽf4٣pL,ts=D׬.{t U|Ih Եf`7:rl(9\ X^v@;rnr{WG""{"#^"T!cicS9ʕpJs%ֹd27[@hޭЋVvuQ[coKR7 -*ؾ]..}]kxw&WS)m~첣돖y ;DTۑSdiӾn-e1%&Mo4WVN+&%_$i^Wޗ8EŹ&Z+jR4;DƌVV󔱢&bض蒲2L+~lE%`WQbsKw=k> C.:ǥ+g~RnЇ a CA$JlV`'-t^TN>k{]B"嶠gHKw>R|nrw$*_ʯF?A{i Ȯ^"twAK^L#)6sħE"/痩;To0o'@\f -wj75XNMZL`i57g76onj&>(P!T%~ih̊'J,?zݱ͇/7NǫZB(|'<[.*M`mF1T7)G{j*uz%:^qϓCT ƞ6T]w|N -_xԙ4gYߩIefGCB ;ѿ -mPƒE.@ -jʚzϤ 2)\xP/|j[ؘ>׮zf07^jF\}re -v+WEmϒ^?4+ol\yͲ}o_y_7nmǎo~xمu@ 0!NE&°MP0q?ޅXfA4/ZFyD4Yʷ)Wh!&>'@O8Di|1|6skw@>u8r4[o}q)D.,~E| 3ѽǗu~Wx*yȻw|J؟P^ub(l -z0J%W4K:c8K]Yp"wh΢< - YRe$lKc7LdDcR~ƧThb]u.ڼZCתZ k}ۢnrc`:m n஢PMO0jyD2#q{Rn^[bsr!tܔG2GV$:n蘪1U(!ZuV+ʖU[ٲjptL6v6K&܆s{܆\Iۀo*88EBlMlʳ-Vhb<[sfUi؜љY -ԉ17KRnd'S,}_,5CкNEYfe",؞+K5\+˵Γ0 {mZP޿̀ - -=O M)|Λ3]%9;axK 1t.yu>Bpf̕>:q].Wc׫upýK] xW/r2%gT4$(ylz3(g8nM:PǻZT'B2Fbt֒DzNT8:rj{NP],ϗ//^%ow#⫕׷Z֙v g1Y q:tA ek;{\бANvXbyfUm-%5>1DD?C>;@ˆKx4N(%!Fe\)υ쇉e<4GܢS -jks{') 9D~6<&e2*]tFռ:Ӿ|w\+Y]O73_(_O~ -3ArJ:98}i0y -!M&{>l죸RM+Lv=IUy -Xʱ?|ݩ>TӸA([uSgwIW46MSmu5+.Gc?(Q}DE鑋K?Z~4i$ן$]N~fGިF-/OIŠ 3ـ Ģh8ʿΡmvbXˁ'w<Q -BF ʱk;3jqԶt9:zRv _ -g!WD ݆.? A630yCs2d*|. ĘdѺ|}j:U^y;KRm3eϲ_2SZ(}"158N&{Q&9#δO5f"ɉI -l2NLSqe0m23= aEKdja(9zs#f$kdj-mPlY-Ų%$ ` ; ; YpB -ln’l!p4^UHl~US]]]ի^zi ٭ך -ZbzPtNfl>7̌>xf,79sArQg1zB1<,z)Rz76]IzF,.D(e%S,ԯ&HʿSc>ƻ'$&ѱ`lj/g_Nv(bm7G4+@=ޠ7B01-x?*L]<ިn?hg혝%Dťƾ1E"6bR "0/,VCU>DBqu2I+>K -!le;tGoܶ5mqq={Q}ݶV/}0eӘrkշUj)Wz4Y9s63jX'䗞bZ vU--㥖qk#[KT91GXɢz=iXwŷۮdLe3w=ѢMvWbo;wcͭxV?uk[vDX^n>u -ӣ5t3*Fi(t -IMffE mu`sÆ,&IO\b -' -8*" }3 fbIzUFbDqD*y#j>x?C - NHdLpOOT9?U^E-KYH-G-Q!uM=7D@ l."f__5vb1;&X226郀B"޹=W3o,(7,_+ܱXx-//mX$B_N¬ 7w?;U8~(Ss[mUuޛL -k)qVX|75 v);v/Uj*jB #b_u˜3I3}ܻ5\_bBCl? حɇa9~2GVy .c#HRx -*#OF÷Kysw* -l(&XgyWD Vjg_a9t3c̳RAz옄L.P?:g;J.`q)qFQz+415"oT?ыwicM0':2#p$+;qEddq'&0 vVJv\%m :9Ca>nа6KCSb߶wC쓮SBhGi/,Nk%B<>&=Ho.5T*{dj>֔바m6Lw?`D2{:7 rCv.-U5XHLtEl$r1#k -qU;AuHK}B{DW jbIn0Sˠ*d%#,%KQ*Y}* -}FTJl{8::b]T|W \^v\AAaȨ5V¸:ID*$VG8j2*.qo4):֖IJ4Ts~bs0ښnoҊm[䧶7tSų9$2VtkTVDsoٚ]9έ N{*ʮ5,) ֈ4"r^HM9^n[V׺ꢿ!LhTy#>dmQͺVt7x9>=/yt_|4wBwRISovM0XaNr8&rȡJCI -K̠z7Zu\A_p4C/{7oql ܌MU jMRONHz*"q%z 1lG'?ի{tQ&{;+r{t/q}/"b+m"$<^@' -HwZ3'0Hxb/9J(];~Tu&P9Jk8Xj!ЋNS+=.j mg$z{E.J ݬa.Hȡ?KT;~3 8UOUO9Ak={G,.Fre -cjuC,'Vݘu}RĬ<;k1h`EDrY<ƦF/+67x6x7ImF5UÆaӰye00nn277`ٟzHP򦂩 -x6b:g2's - L jVVWAd|Ah\^Y]Wu -W7ff -jAչ播d%z=߮y.u|s2I@(1f^J{| (OIJsoU -(h45fU\GM#Iֱ$R@qZ2Xh}1 -xbm2̟33lF e~ ?X3*-<}t+JגK@ez˔-MKvPB(ړqC.-07m~<2kS &-Ꚙ -D|.ɓݔ*6H.f+XGJYy=DTQyjfSٔN-#1[ѫ{oN|O/zX̻DNkN%gѿ -[˩?{6o{_ѩ[Y}v -7;|{'%G2\% ط[<f&uƓnFBڪ1v Hn+YtA+l CBl'J!B%-'f~eSo)!\K|%$G1#o_(MZK}[Q]pjCRv7ZwPeIج PsnBh }Hs9vw{Y*eO, @LQ,tLT{t+E=~qʠ2sS\1sV= rK^'|LŎQԼgV -VAxHe? ;N%kWx cNKvN!enYv(٢$%/ -]:*.g0K(6T'$r^|SQkIx -|~PUMZ7I0V'-'-Řh!-D=A=9L4폋BG",qXeP0y.Hr^tkq$ϳ\gBuԙ}zPKqisĘ.*NNY"c^w>˽lGonց} OO,3[YlZai -6y`_,\Ř~_)"*^h];.,`M^05+UuJJcLs6f ->T]o@ k< >D52d!TN.TN.i.% .j [[0c' -x2ՁD"gt=9)iLdsP<U"fĠs H ڱ*Xo050mx_CWb -Rnx,do@NvH_-,u5[𽁝>~~-Y8e9TGZ^߰ƿx?;w:b 0>Y/>4,8 XxUA%`&5e!+b@B2ҷ-$so MYdcrAcޔ"z̚."w㜛QaAy¼sqwP],<ۢmth,.aq8K1GMUVV!Ш(OwK0A"淡R!eAOv %"AswNB$(yw* vALzN@|-sZ铫XtN%'EDqmتuՃ~59kCZ̵LQ)|{a}7ኡd"Dvґoaz'<Ĵ*<5h5@H@Iu_==?«vfj6gJ"֑-A621q"jv.76~-N1nOq@;@&-MSeFkÝUZ940pq4rK=0!rHŎ'9O-Q~_>דo}3ܲ]z3mGn&Y xQ'Ռvw?yF=쵪k7T-\Rf#GÊ8̍'Eu#5:j1aDvD#H5Tp͙UGIx$]kTO:2zcYœٞIqQQG+ -A#t6?xFc1]d&2C,o> TG5ԪvGvYw"n-آy,{}kػnWF~oOw>9l/\s{kԽ1|3G$^P^;>gݏxժ -"^ϵ - -ULkuƹcPSU3*NX OҤ**쮏?$L/8;pp9cuQEg^1&cFCgBؘlqg";WFtl ᲼w|22٥_E i& -'6hs..04g>!ٟ3vO7r;"~:(Qb2@\oQi_4 49׋pVބ MXhr0NLMtfrP(âvR ġ8)ֈ9nYO7teCWf"`eC i}E︿u9 -n_ɟl ?v-{$ \(VV䱪n~5Ӓ1)-n -*ib⌇p8ʺQM{6>n+6ytf| -RۂDe|UoRRFp@0R؉^L]7|OA $t$|$`HSO6l={~f|ϖE[Xlv RɆĶ\ۋmx8}}-Y:x"Ιm[UG3=Bd*WXm cEJP^#MqbCm~b8#fq:$fy`¶VӶV -4^JIB,X%at x&4<i8SVmy!+Rh\o+nM!B9|5ވ1|1,sbȊ(|8̄ǘˡ;.twLS?@6nu -4 ! מpv&۱Sٍm*Ƶaj,}MLij&"X&ٍňPY,sN*ptI'H:sY"[v6dӜm&B&{E9HK͚.ӧV+4y10b_<nsU΅h98{d>^-MX*.f}z-7h+?=xcl.u>|Gs!ְ -߁"ge|Ƥ;,e}d z}7JR.}#rg՞A͠v/WOO{;E?T(5J.d6u|DhC Z/08?He@B)Q_xs9J59xa^iY;3GkSt^A|E` - -SU$OU<"X꾢41JΜ,Wqvm5si2d`2 -[-[)c Vyu.D-iyrRWHnA 5É&3mW*'^lKF.]ʜaI853Z$3\Nv"rKS>sRX?;, ^$*0t>m*1CNɢ=H|]xhiDqaweyN'&Y9 -◕!^tX`dSWeϽ@/Pb8K=l/zƃSdNk0:T{`!C)?XR^L^rm["!MҬ{u5A6jIQ _czTK -NfR.hT)%12ܮL9!)O$r<-`luc^#YPZA>3k&i:U z21<<"^*@pG֥ss;&|<秀"x%zTkhz$huVX47VgGLfˌU߈Ǜ3驺U}@/VY4"h`ݾ:a^ cvYv[Ef|QbHv,Y͵׭]*Ǘ@Xe q5F)j]ԵؒȦ)'p⻗8xruSAG Ɇr[b;:>C҇zZtִ,6k~ܵf^o49]Vd;f8%[PZhMgzl⸙ܼ%l%]2yb>5CoӃbF:tWvla.L0a68(,\dwlgh43 efXfӛLN{:Mq*}Rc;D[P0a A! - -3Ca&(B!34@  -3g0L&f3RtAy^ k@%/?Yq>?7nh/l,06Ĝ'ԃ%" Vy! -L&l&gЇoS^0;&̡ l7܊gV2\*f+ʹ_*wMIuJ69a4JY،8cJZ-56Ȯs^n~ -6XFwcnuxո9Mj55|C~y}/t nEo݃;?Vtb9\l^蚗]׹Vg?{/~},[FA -gBb ȶEfcۃt.[srYwg.]I.wO6)diBK3o-VbPG -"U$x$b-f?}~uBOI=M;QFO,r,m,O\U+)"6 >xǘ7~AIb.Xe^ox_vM鋵gODoFY1dwOwSEwă[4ԱgYM@A1jN.fvi-ovLnըݦ^X -Z^ЫuHct zLnag\f8le'*tCV!^vU!3\YvNb1HtUv; ->}Bk`P֐gi-oi5fI!A@zjraO2B&ɥ/ @ ^`jQvvsgo`yAvp iq"{[]Tş~Y\Ge4A܄+b#kCC<5"V\\S.w\qU ʏkEr\)^TV _yQvi=o!P+ҵ+$Aohp4Mp35ʈ'4,WIo4궱L+)@dPB6Rvvb>ղ7 -to#|0y]Jj}se&ށq*jL=&׈;XA2-S]iyEEhu9jb5NՌ:g̱a `0G㥎zX o|# c8*իՏb*UFeFDjWcud,ؒÌ3)ղ8s8n7I2 -X7ju-w.cЀ=Nחe3ev,@{مI4VϤy֭h8?R⋒.`kespa&X$+$<,U$2HA)jmfhTN{tAPz -"":Zu&Ƥ=jFM[.6,Vjjrkkks+4~CWؚߩک٩ݩp:55HFmܭ7nw[#ygCú -{=;Џy}?=;lOI U=W.- .H.Ϊ kWvm;H >gW -16Y|*U`l QvqYCZtz`4X@vo`Of$q!QkcG*iEar ^/||9.Lf\NՒ'\dhCA2~:RCl,I\!:vy݆uǙu\ktW^ÓoA2_4Ư7Oc>>ZQ;Ϻyt# -]juV#ܞ){>b&iyj)]:VyLȔI5@nbnAb-不G!Mٳ+tӮ=A8UʭN&*;y# -= -UM/DƪZlMRtxMv^ѦB0Swg ->v%OX,|b\/]Ul{ǃ\I#Ŝ"bE~ \q*tաڀLQK%sEkV?)ox_c "1z͠5{λ&'ˇ{jzC! 1Z<ŨN $ϯ%U9o.ZӔZK^)fA -@{h}͆ɻ)4Ps=û7#7u3/Z~1pWS9>Fi/RoMՈP /TNkWTǙڄWp[A6ƤY߭n`Lt7Ybf#0bV5Fw;g?vDdzcvmK"6(Ɏ3t9.Ҙj]ѤuE-挈8QE%V/ĺvG)EKMnVtj6F DnuM*U7/'ōO%[uhn^[xCJ|kuE_tu:HDaƮ3?mfދF;sm|FۆM57cnldV1=> s4jzd?3Gf0O'jcP0ՠZuu -?G)Xt!4Kj *t9?6K")zobr;B>WXAwP!͡%h ̝@c!6vzUiPV08g[s!B,Zf-jJP[g Te6"weЦCmU 3>2WSAƘ&(M>>f¦16kJ} SX( PJAojA&ى8J;j}?k^ATw!̹Wȵ䇼dYmYtHV7bل/J_;n."ikkoO)vU`m$̐뾹f漽\K5hfeAw)_j.q`Η-׭bpKׄݲA.w1U2b:9a߮Z<\h׳juXلmtʡFSI: -:"yt7J䰄y,ݚ`n\_S0P"]h!]^4q΂˩In|WXUL/^1wf櫟|pss"T 9,-oqUC@TG+iChM%ērM߿{3h!SDU*Lpx>egIc¹*tȿyQ7π fMa!<h@ޕpe !B5š"9Pgr 'aD;T - -"߲B>yl& 0yx72 \ up@w/vA[fW.-;@ ~ #~[ըfVvvZH4!{8w{},poi+FkҌ5kfϮsgv;y̏,n_jюE[e?lw;9imu~Hg˸ezg)/g8JFPQ?5(MkPy^M_^FPW%nDu7i=j~O*q,% ugQѺX -J\+q -Z)q-S|J\f۲J\(q#倫8-%}$ؕ8RGR%})q#b%}> -'8Q%}ġGi\OUcqiK@F.Lh'mMvj*w4~G9BA?AQ4^C?49oиXmI6ZVhͨuA(#pD4 -p -+D4~ NGsg 6w,);Q3'hd"-P^*¿J+zoCx%0Lߺv½ч4-p3iP>ɽJkAx@ȗ&ZCA=%x2fJR6ɥMkO6ZFjߟ"hWi EM +PO{K+!yJuUJ|@d: -B.ɷjw8L)8hH"ZBG hp@i -;&Z8QqIQi[X)[S{\%Jm2;i%ڒJvѺv;LS:iYݴL2¶z"cU Djd8Sm_]zh+)֡&emcX)BfmLҧ]2Sh\ -D^BIeitZDž>ZFהx"T0ڮtD"# -%AQNZf2ei -Te,IΉ1A`]R]衭8w1u(x=0Q/e8lWq#rI#7iYaHBW)Na"KYiC -~T[RiK-q:l)VAEi]D+tt\vPZ+>饥 -?fv)} -ޑau/V`4lnU*C@` \<S -0<vS+%wR>0n -A'/M!TkÐ,P1#3 -۠,܇)% "Z-+@2N -wOPl>eܪP_+$-9+Je+Ӷ)sX' -2fmWJ蘆sa)_#sB7Qݧ\w> 2l2㒱7NHڬ`k@iX%2fn:w~0R\~x1*:)>ɥtyҥ6*e . eJIk4H!ۧPE+t|˔M!-_"'N.MICRhdyr$WPy9 AP{'#k*voS yT -*1IM/šעIXH̅2g745LE{ue}P ޓ% -P^[K!K(:~7s`=@XB+u]a42Dl) - tR\i>'0r8- -,u»Pp_אiDAR皮~~M}}û#iWpe`02m7zM_wtȐ' -mym!+J=0ǀ]#rIohsؽ4Gښlfwڕ٦2֟6s[OvІau%2"3?⮞~eW.pvʅ˗KΞl\ms.lIoӱ31`Hbt@ ,mU4Eoyk`'%2ʒr)C-^4 ޻2킁+Q Q:i3e^-=2x:a(EC59J(wvP943<팸 -F$ݕV@JH) -t"@ngww0KtN%% -[JK.T߶>i>2.eL0&=o|ʒ -P]5[TХXyqdASڮԛfZ -7䃞qEoP-0>& -TjUx ۦJAfaՊ6TMiⴺ&bV-\]]iiƆbCѤQw#UG!T$bwcuʸTUݲ⎽}gNOG?ZXha壅VG +-|G +-|G +-|/V.~L;izD/"s\f?)UUjjj܋|+e3ȭYDE*9K9?Ii7sKc24>kil#5Wџb_ѷFm&H'cD_cp1Hb1z} C+yMz(ȆIĨZچ NEu.`uGR! ܃peZNRGGcvg\*}ҷ;qwo#!4y~ -B/__$<B^%n% Ix{';BV@o s\,;Hbmrs<}g? ۃTJ np)E Z^:oBhyAԃQf4fYA~2Fd[efG0Z -Z -Z -\ׅ0C/8nX5F>H<{LW̜xZ]tG崜-:i}sz1꣝cEG֣t,:TMNu172reڈ#72=Rsv753}~h'MX HTpVCΒQ 8,x/;byᑼ?co#7,"> -iWsI 3\ V`p/pFʦ5*Y_U7Z.q>9ƹlV+V?lāЉ4stǕsqe4t%$Ę.suP$ *ʑ "fL_IxH%1I`$j]jM \=ۈCc;!SOmz~BWkwRk?萃4#:DKĠ:qA7 sD7ȷQ -UjGn!zҎ؎u6oj|=L:-]`3iT*F~9iGX+P 2HSmd;'Ft'W֎a~Kq8'ا/:d/.^Ԩ~^vImGիĕHM\d ^WW"ճ.j^07qum[=̦A^C:ٮF6 -_eU5:T]V7uTz1yiTܠ| qђqͺ&]\]\}nWZZ-d*Ͳ,KCd"0{rne"9;W`,,ޱSBjlZIéks8eg*(%F ( o|lOSJ{_fiʺZ ɀuw Ѽ{rj~?۾jˎc(mddZj,c=kEl98  l}Y8D؈٪$l$D6mXd -M!fy@ ft:̆PZ<-*KDgJCEiMO'Kt^GY^҇κdx ̴:q`!9%Zr -[?|9ut2Kܐ,> -endobj - -85 0 obj -<> -stream -x]ݎ0y -.+])͏>'Ej"o_9n+"a83~my׷KzLYsOn2VY=/#t9|ʊs~O?|_%/:%L_[(4x) )V -Qڱ i אruw3|i6sh-K_GmUZT{_%W]B0Cң -y㺚e)OXא_Pǐ_4N~ 5א_i>kߢ'Ve#v%6KZ v =kh;ђROWOCZ'> -:]_ %%C%B~o$0H@_'ZwZK~AKG}q`N]\G}G~t> -endobj - -87 0 obj -<> -stream -xܼy\׽7|Ι}FhG !"H -c€ -Ǝm[4d$NZN,MRm^Mm4ms:pn$8}< ͙3Ggo~猦o9?3{JI> =4ں32xq|޾uǁ@/4>:Rpe@w=u*|3sz<1yl};=C];Gdދ{V&vOmKxXz{sǸ\(zn,hkty\sLOb!q#>dk+˺>.*KJN(AGV9f'IgVh\c -Ь 1+{Ş>[2\$pIz. pig5yia޹vOJvε!]}Ī r8's3kN094DZbZO̬\t S -2KZlh_5ˣX1LlWwxLfMV&ivhvx~if=ϦVi~3皎$qu$= s>*%ʤ0վӾB6{ Ҁ!X ?s X C:.ץsc'u8>NK/ S=_{rsk{z =V0IZHv}d֓:"kWV7Lc|u-Mk7[ّr8N8ggr 9(cK@ӱuX+kCkO[Kkn٬GSɅs.$HBIp.,b`09H>\䪪*r /ICy -, [R%a$\^V^ &bq{}^_9d0rḧ́ĎCnyIE|[)/ɧ5ޢ3}meWx!CK<vcS刧!(0nS -E -SzhF:-캀CGA1t<6yIf:uܭ׷y X; -iEEMY0\0%Nuj -{?2)=v!CϹm3[Mz<1/g3c~li7$79\<|+.5 <ɇ2g6nwwn9g!&e202EGyU䋘x ̌V`2}Fx$E*/-aF( *!L化4ߕ3dt@a <@\Y̸|aĻG/A(Ail}eBŲ#{k(̡Q4ꀯ뻊y3V ڬ\[rmԫp[@7Ifvr4hWt -EODh6M^<yo^M5]ii/3g*t{MUFZ|tQ -lEq bW!H83*k`{o -_{-e޲2,*S}3%?gOq> ˲Sk!o22꒏H2Øb&|&QI&''Agb-D -u -.59 &_`byK#>oO3Q8D -Zɨ4VSvk&Z .|AjAcn{44pCU⦬h8lsEEKxR -Vz#sXZi "aq0)cwZ|V4Ē'/$ -ZR1XvĊE -(sk=‘|+\[~0quu{:PV_nS%]K ;l?ʅ6-/^n_h ;)]Ma6*mT3xdrcbOτφχx)YQI3 լvd?`!wևA%Wqvo9rrZfZ*'l%2\͵@U-AbΈߙ\H2Ҙ-T @ .RVH&!J-%`ZHO%c -qdD|]QiڠF#ejŮò lID\u}!M ŗt!MuHs}ޢ#IDSjNw]{XVJ2fܨ?㛢-dreSԥYZǰxHsY);]x>Z3E''յUbOb$a0.yjDsR͌wj?0L܃mm -ʼnQ;=:Kcըz{#fY?tbˈR~'chxv}vBg;( ;2v='1ȹAg #C ZȮ GaIa!*K*Hö;pq0Fi - m4$8ŒV4 >l= -6DjPh kx|.HVzAbq%\ CɓzS=e<eWn+JږjihRFPo\栅Sm*%6K.v* eu-A,kASr*Ĩ^S7}mMYŹ]VP*^!!h{TU -@%ITdKX\xyy5 -vclG;dt\ik::m,]BWl>d{Ͷk^FfFл#ZHXnh)n,.l,ɍDzܩBߩ&et}LT /' vw0"& mb8 vccId.|ebXuIكr -kys2I|qbǜ"J_JAeYa64$&s, CRXշRώWZ]1+rfk/sSP%W}X4$ifl"Ae$~ -uC1m?o7Zc@{KjYRYuz^U}c - jZϋZebE 3=麺2~Q1Z#K$+Un!d.=aNv̱8ә'0sԵz@|,/TPzbH'Y`2rP@-t@NIڤ "<~q9CBnߔBwAF gP-bk1 -kgyIzm*L -n$^*uuɒ.,DN\cE>ܥAj4a[j ʃyySBn4b!7bT -]J8HU;.DF*H(= -b2$xvIx@3%Q@]Qf%Ndаs:[$dڣY|"D+O 3%UDJ,2|ʥ -_ -BB:fUn#-'E"oԢQ7 *yP%e9,è:WcQiA=۲x0U7Ȃ26X݂$EN0 #">R$p/N}ie(vr-}75pdz[\Wʜ_:`d99:lW-Vͯzijd,socg2d3iϥcY$sC ?,Wielb@XEb|_I?@QcɤNQ!(1tJ~+P_Ҭ!ԇ7bhJ|^&`UIq -yNnukRxȒqm8):B4@$Dw꺡Z -32ƦL6kddSNnX?r_H |908~^Mf'_pw9(-2oVYʪ&Ӏˎ[kx[ c'.$;UF'ʉjīY#(X_uRjO׿TO׏ϸfׁsLI3QiN:/1!).uIC)bt6JƆ>Q%4$/Q44"A%`Ӥd6.%2X(3,,3B%C`$0RqjNھl6hNvٴ;E_{G=FN>wm8^TRD1㮊~lW+F 8 /ר t:Kw _~GPŠtC&>CLka7p볦gڨ[~BݭrGj3~z_tP?7v/ZW:U?4DzKVU}gsWx[<:A+:a}J]e}պdY+jFys^dRĹGmDGu2ҼzxFŅﮆG -Z@c鬕c ʼB2>/+ FL\7_.cF}*#VL'($#8}%lT<Uf8tJ*ûr -.`3ʼnb=q -6oY|(p9 -VVZoآ-wqj$A/*U $!(CECW~ C^Rpuũ9 B$5j[:hst냋_F$FZ!T\Bx!) ϲPbu&lJ"*"a S _D -ۅ$C^ -^,X踷;I,Y7O漴 Vy""s(h8wBޔtCɤ'eY,Yanڿca*)^o$ BTWHF}PYƸ2oQv_rM%`rxkǡ5ZZL%_;:Wv޾vP%28:sn2N񥖖>@ -i -^_?;+֧+0HhQmX>IĐLrdZORG#JKK6(㲻5*3x8ZIXleSu?I*GD`26 2HvCkִ҄}Z*҈HjBFWL4o*ނuX>AIYRhb/^ZxDIf?#ZRWcj>kf0DץЩ -i.vNj dr1*/"6hQLe,UmFVԊT{,̟e2XZ6:Ϟ.}禗sρ;{أw\?:uqcʧ3>c]0:n;~Ʃ|W6Lwxr>P%OzK-7@_W=p>ԧ/SSns\*M(tSLMM)L$sEr5G`app>[Xѽ{Wyxg6݄6UbxT`Pq!؁`Gaf( 8MK4&v&JV< -Qv-Vkx_E}e%X.4DD|Y=^bJ,Qc- -RYp-%rTҮ̼c{4yנbg@-3SB ]Z4@Mm,L9H6!+RB3scȠ5Zί4 uԅ&=dD^{˼ξk5t!_m-ZTtK)lhC1ب*VR]玀sjuԀ#d^b8VMa:Fclw -o}H~5ocA%0QMsKs*o7~gҩhY# -aԙɶ\wm/Ԅk ۢh,FUqvH4YY5cʑ_B0w+d5#pg FǮlX݉$J'*xs"8#EB -9cL:Rr$ 8"N6R2{=RCla)\Z -CSxq(m|O:ئ&\nLKѤ2|rWTbZ,xz0027ԬI"[XK۶@s>#֤Qૃ\A4=r6IrCg 2+ q? -d|<A.GwobhH~ eZ IEG;c$<_Ҟ{wkL >|#ȰA!sp*GHz% Y$L s~jP8/Ǝ?eUee[_׻&O57bGoJ~ǝ~zfaA׻zzْugX`fAN"fnb*767G{`A#E1coWr$R~|wftvQy5 errL!O@ ?OoG%rdSRX'42VC(geT%,/A- e9XE -;)Z /^!%ɕn>lP,*+ɶ/3NKE{+Fcڳ$FYf:s*㧛7O'TE͍07wP#pc][>};ް~;JZeIne;v1d٘?pM}b´5ƮFDQ!D -тD;Q[MfOdLMPpbbĚUՒ՗?Y\VlS+_F< ?}-/g9~ ==c=T׆FsI F~i|.=#9x<>BKt9#a? c4Hxi8>++֙GYQ˨nobYpcQ -"E)ӭxZo {LlOϿsmA&=z 8ȩ=pO(SpT'+V؅sBcg$R&<'| - r2E/l_zj$7+2WM)e$V R ->pLD)KqTJẄ́dIޟË?ǷGO9^bZ-1pϴes -tH20cY:qHs; D6J ٴc,J曷:h Ʋ -*>Fb -+0 -sڷ?7*Fj0ZWw,8FvCmo;]׊-> z2,ɰ8A4|0[Ԥ0k nhqMvʱ-Ʊ-v|澦XS`@u1epA0R'XRPS OՉN"bwEQpQ n*=ZzKϗϖ][6ƀD(Ò5ۛzi7A)ihiӮ9[e݌G8L%9t.Te v V~3b1m@#FݔzK?s%6r$.O` ˭,Z-]K"\n1d;ܿjREۄ1dtKM;_3ʩ816ڤ$V=-1f]]ϫ(ιUj^fE4/H*Jmewa]=Cp˼`RDTͼʪpq}#>b\8[3=^Rc8\- -{*VQh4(Bd{]m0S5_/t&S2X]p}iWff]1Vzoߡ -DÜd/ --_YV@}P7AܼmXDQǐ}- -nSWN4^AE^XӁaEx-9s*~UPE~v -SQY;cXryhۀf -Y@dsFP80Op{{.)fI~h@uVƼa]WU>:ݰ5jeTgMw8^Xz)ekE}uV ʲ`L;tC|P%{9D+;DQ0&ۄeL:HDiF'FUFkwڸkmak2E -#<śU^YUb߰6sZ3s;muG] QXi4rY{/_GxKW.劷_^+xhvEBL^>p+ȹYE}1 Ҡ,V9 4WV]G$g,ƕawO{$cJ ^^LyTXSr˽"ެ+D3ܸ9jDEFV|#(ga"Dcq]YGSh,[8^֢/6:5er1^Tkx^,nkg_#PSo(tO-S70p*j燮^:/x,g&~M.j9F%aÚRgF םͿv5knש]gw9wv]Ŏk&x:%2əȭ{ef"={7&NNp{.do0ՔGL *j -1+r@ETTM粖1]2.-=(_IP m7q,RPy+S E -K -Y`NK&$$I|4,I#FX-eJf+cms}fYNdѺ$H֬lZOkc$NUŽK֦6pkZko 3 Uh5;3b e͋k[OJ124-f -dp0hƎf7"0=s7KiASdxs-2Z:rb]ӓcR͎VΝE,[wW(c\Hf;s(ev(̉̎ &dq H*#VBte -ד5^Y^ - AʼnJvpeM瀆2%"x%2QNs+=3flnc/=n >t*Xpl,07`sc}y3f|WNo:hȈ,>Q>{Q)tuAVz^cQD -6jȷ0*r-.VehzC"^[%L&zӋ7Re[GAN"ʥu'kumbg3^N$$eS%ܖ[&N_^gg39Iwvu}܎#U8S ^r^ tIp!…Kku-UyWrTLQt"YW|EY2NFd=$Mަ5:׺?$C -7V%GSiqiS [}jACe_nmQF耡̀^5B@Z`xDgU7O;BE/.kZ2 nZJ%8$MY}Zi -vSyvRAQt@: -N-Y<07s-X\<ʡ-Q#BW1ŧ5&dR˜i5KPW19A#`YR -Lg(kC؋g;"Aiw -u-vmB@5tP{=Ï={ ?6imeg動Vҕ e2ϘOxr'I̠,$ۻ&DBd:5N{ӘL ^YIPON^zG=y|+7sol -5Wn9iӈXy׮/l79tՉ48D1t@ֱ;oFzni4:23lǺm/榀ͩt{WyNbxʵO׷Zsw,z/6F ٸbx+Y mMk&DR>/!"l0G;qKuu:zŸv^=P-~ P -7'CnL7tvwu:w1`!I"A2{V(`2LV`'HB7ⱖҿBF> -SI8^/K)**3|ėBMs;ySϭy-$>cYZmPmC'Hs)dM|{KLvhWmV^3i̬pbXf Y9QVВB6 h)w/u-I"-E ܧ%: -y ?QtO(ڀUu_&)~eh W~`Qqx p/iĤVJ}⻟M6> ?*I1m‘kH"PZz!4.}bڍ?T1`=i:n߄8dp}沥?vlL|?:t˱_&HLv 3zG/w+zzdz7˯:{T*Y-2e5?o`TYvqAWѣ|QF%'?AF)V1X"Ttisi!\//q34뼿L3@L|i7nG*4yWV(4A9 -+c -M542KF@Cu-(i2`>޿L4eaeZvW˴HaL%0&iXҏeZ6my --g1GZ7(F' 1oTh -mTTha6+w*U7 -Bg+uN)C}+T|)t?Z.WKE ,böۦ]>Źexzعy"u`ji皉]RΞSé[hq!ޕ9kwp*w;FwNRɍS;'vmyйms9=5eteΉuƷmw>ōnݶ{zt -n.ѩa|ܾgj-6Ooصh[G1L.nq[ԋ<hVƟq [&u]ND~sJ5K8PaNУP+|5C+Q7T)(¥w;w+g8)M gP1\MzZܩԻ MO}߇Kq4i>(wnUuZoz춁]ʸ28RnQZ#Mz?n=xlHx~_U{[ n_=}j6;ܣ<῎ſנ\ߧe+>c1ctYؓo_Ǖz|{Y\ǝ6rne (9Y.MiSNO1(ß~>Pɾo}U";[q\~l>qEJ][ۖ&M){Y~6RZ|7Sw)%:OmGu؏a -%=JV,$3]c@29QXI0O 6~3ϦI6QFJY'kYǶ֙L)?E5)4OIۄ4sνa`i*s߹{Ϲ\=M4V5^/({9NʑM ti+O;ESQ -QҺmQs[[f/^ RE1d&\{{I{ta@ke/c;7ԲK^&;8VB9x"=ܝkH8vrdHd:wO>`P1StGzPE:D=j6GGDwHӌii3sSKɚ#'}_E=WIL#Ҥ+6&R2z qڅAR4!Fir>sV1i,n)i)c&<*fJKIǓ7Yb;~I-NHIRהA^*6ģ 9h:EL{[Yj -LЊ䝳紾Rӎ2ٔ_uiSଋ92)k4yze}<{eB#5$]sa1u3F"ȎƑXY/uпs-n39]}ɡyۖf*`UGl&9rb8eN'|}uFc6(%$R FfXBף[GW9=!;} -vC;Ln:Nv?|^[ -V,!ZPJcRw4#=Zd\Voϐťdܰ9uI7lceU{,X_'L:]| -iSXiNV8SBl/,-,-xB炂=S9+T#(ѥ -wb7p2+7͍[[WTl}>Ԅnƚn - lBcwЏ{TB |aP5\o!s4K_uKjobuʑ \Ÿ-Vbki<0?BZALlj@MVkZZ])ͩƔ&JnI" -i!(^<*wX?8GC>qttI:'Ш@=#P@ - ]|yÃ0)n> s?x y @ - 8M|@Ih@UymWp|t_}u}u>b~_S{`8ş?K~ğ?ϟVWuuڬ6jPRTU^UQxԚaфn}1[^n5DYdo*^# -Zӷ9P-T 2X -N V4}k -5vljr?ŏ~tׯ=k~EGR?O&^;r4~}9!d)}^Xmwm֡@5Oj:mV-y)C08/9vOk'C9r=蓙,G[`Y>7g3rlf6#˚9!frQgSׇ-GB$> -endobj - -90 0 obj -<> -stream -x]n0E|";64REj 0I3Rc9t};4S@jRG:>F5m=#yחOX{_[,-]pWe!I_BCg5Xp/TjyBTMM\n4=)#c -kW5ʟ)YdY]oYB2gF8dV1;a1Hm1?%?Gc^b~üe /{ny 0fQ0kf9/wj[ -wod;qlٌc_p[4𷼧峘_<ߕJc-=zN];/]U|dH} -endstream -endobj - -91 0 obj -<> -endobj - -92 0 obj -<> -stream -x}y|[̽W\";$K^dY-NtoNb'v0&'rlgcIL mM(e+(N'h>_qRҤmB`]y!I{{H>3gfΜs̙33ג=:14h HY5$f9B?G{6 -|)>Z>ẋ -Owَ ds]7zB%hT<8C9or[7P~ʙ.F(#][~b2(W( ]>}-B|n(42z'C2tÛ4Ia9\T4Z7_/CP*YLJm=az -! >*AՇ (!m؁v[~ =&t7]yqz -eA F{7(+~4GG>&"8p`#ڄ?kay1RVw9 h=݉@rk"D~u??b"{g Dw8^#/WnC8lc@YvdZJP]^ \Tdבߍ*vz'wt WKqy=K@=7?$oG2(֢F)4B\T3̭=K췸m03"n-I VXr$xP -Z:``~F>0 -p߀{Qe$ ^6Vߧtz$A}Ylbl3{{=}}[==CCGގ*r -yP#X`D?A?a^Gic6f̓l-Ys"wʴaӑH{s_7:a(xA6Ɲ|~ ?e8Jn`ecaqNZ-٦oM"#]ȌQhzBz@0`Stp/QQ|`1˘01/3Ǚ߰Sq.[ʭ/|{ZdBϟ|}SL3YE$5 Ry)r"X\kzffuc0׿G 8R|%,} ;ax?O>'y ˸/h|%\<μLql*{VA -Q/?t\<ʹ w$w^V'[*,7"ѹ0~vX3+V _b{<^~oD:ZT]!e@{EOᷙ;`O :oe@49~q:L'Qf|+p DS~q[0/?۶A09t -,6BmFry+jvAA2/913`}=y] <FeajDË :8H{\H=$=/6|ekˊMV |\O;;+3LwmՒ 5Ŝ`7xNS -crjB\.󐲣 *TtO:)0Rʾ/PQJqB5!|!LF]Rs.ZBfBMj!;pu;k:8u*8@ '9E"LRM~)U8Q]6; -aYn^VSj{r¸Fa**&, -+ .9 uw5ޮ+lW;appҵ'mTvgMr@;w{mx@_Y۹DAEd(A5j!r,vyu'LH0Z6"D)56-HuwU/oB;Wl=`O~~^B4ڹHpb`+f̉Fzp#&mH I%hgO Cp/LCXUչ/#Xsq5]R"XN 1v/U0"Z.l`:x20jnne^Ff uC!<-ZPw80IZZVXLNAzqI+]3?z>1f]Y'`Ѹ|uPSmcRdMUml*#aL*K[!&6MszrB HkP;/jKv!h6MR3\_.Wf' -s.uΝ/s5ΰ ^::;u+BXIImoڅ6!ܚ -"LE{8 JR奧2Mpɘt7Bvz*a6P<9n6 - Tq&% @_uӟ$gLF|s$BCG֙NV9WԼ6F%{Dٶº -7Viѕiv `b?PCReY갵OD"$R0N4n&.!A@[ [ΝvgήXC;lΡ"=5\{G;:\A;֖mx[[^չ}:i-3SKJ)F Fg)mh-L`D딱:z&hO YpGp"Pr"W:wEj 2)*w#d2lҩegK - l'$qs=(Cn8e>ށJCH4T@!lqSIR<6b@s=gRVwYjm['4'o22󗾿_4GfmB<92(,Rȕ+ -Hi)-::}V&޳/Ub,.N&⢄$AXoY"4de!7.sؓRKǪ:uleỀhtc͢LRzY-Nk_|;˟u(r1ǺA^_v͝)pWxKe|yy\#G -&Hffև͢RfOK9ݒ3oIS$mp4eL0+EOfE/I XH)J6%lF?IO0D'|W1o.칞ƒ -$TT|P[ > -KOONgO0|#1WwVR̶8\vW%Ê dZV[a7x#o*K\D]w -NCԡ6{Խ  I(**Gxr~aWLExu -@= - X `LXsnå^R{Mns774կxÑ贸?0}qyyZiR9"cаLϲ?(M~fBPE|oI Bz7b!F(5$⡅~0dF4|/bLܗr8jX9{7?l*NdT۱sMAqEn"9odeI+oy>f~Ckr,j]F`Ks*04rfE\ENMwk -(ZNCAQ=a0=#/{ߑkz#G?36~no}NMW\msvM,Z,. LdFG6@Z֣&d$͖l|eGa8j4ot;'a2S\!vxQhgEov{)^;`A,={,):.yff[)34wi>i?q -LMQeH -Xs qLDEDE9(O%d(Wp?'<| ,Y%v}6}? -. -׿>;TY_ -/ԶjU^ -:'b(/4 |AܗrV~;Շyg5y -j)TL_.֫L'FÜAFztEYHEBonG޽yCW(c5*ƗgҤ%[)>cq~+ߔ -IؗjԈs+m|~I4d=R!&/+TG3ZTmhn!eh;w}8 -} @5e YQAƗkrY[Zt -ia5FhS#ּpaq}s!M'Ys@Elu=UT~!ޔ4Zfj͖zrdq -:Ӧ aB -^!(| -QѬ+l:HANTPK|#q2tb$Q''nvᖮ01{Lʩ.%3 --U/*RLeCRA"V̌(f8K2λOtMgVpX+Yz -%?Hp|ᎀ3"`[8sWWwffql|]w=$3Ly?eg`7oNX7ac C2&͹2Ν7E>Ո^R h I N~/fD G$Z͈9TI?{^ 4 L93Cs_;h]> ba r(Q9 =uT2!AWUMϊhnPd7ߒ# -^ jFTmMn99Y&ѓ7͢Ria[uжƎ)Ҥ>zQ_X -sIY.KNQGTEyѳ C ɮpMçF\j_|'|\;S))&)q.Ih *_:G'H$抝ٌHbK/y?⣎kBWYd*5.hn -KRW5<_w6喥ksS\I|]ӫtPŒ4,|nYD9qhu&"Ll!36M,<9a4pJJuGѕfI@&35:MCIC%3LfaG(L"Tbwu - -uqFxYlv{ڣ[uB-jIƟ=ݛ 2˅ɞ_1Z^lU)4o#[Ki,5&Nу;RWى!LB}|t3> 3:L70 p#+ċf}@ $K 'Na KJ\vOt!Ҏ>ֱ!ߟp뱐qd2tҢtQ`=gM?$Fyy+±bBT!{ RKrsK%oP6EjRjFjq*w 3zX0>)L3< Zٝ ^>$%j4\'/@/:4_!e>]K[ ),Boz0Ӗ}brsrgXEC|3dom?6}4>=$!Zr*vtGZ`>QBf"=;$ .T"1>"i^9U*rQ]* ZFq -PZdğ #y U_#C&BDW3(@?qڼşfGʾ~ޕK^zkݎZ5v~qDWeWdV䱕wނ;?G>&46*<{4*6n8䪤ѕDP/Dg~FZd-Yqd@vop7ȘR)nMFfgf BT gz &Ǔz^hFC&ԌPɀp72Ց ѪT\~-j2-=Iv (vr'SFaarZg/ X4B䑪ac^0!w#AcPK]:!ǁtAwKOEpŬ@6k~'䖿Wtֲd^RηcYDqE I *,jE#}n`jtgf?U5wf>{k 0M fVZ]i ^ըeC 1̪q#OH Nk2B|fnܧ:grqJp^>On ! l8ǏʟL{2Cs4=tr[cݓ;iU)'K&LPtB,: KJ+^`]Cp>U涡D'zY#oVEhQ:GeOzGIŕ"@]ET;nqœ]SllYX,/583Ib~!$ -EK?v{:w'r |F4X -EXVrg3.`@BetvE\\k5\qqɅ|9}b*S{'O)A6ŅX_>VUe^Q.6BrE\iǞAn\v T1Ө -ܯ?5q<]iQ@bZiY%J(rWLAHDҁ+ z$DBHFHFA~y* o* gvUGMإ 9Uz:AHNSj85T% -Y -s\RNSڔ4LA3*tD$y$z<-и(e!Wg$^ -rhp!b^p^y]AFvBO[vẫE^;iB:y"4U'^eyΜMg\o\3-:=UQ<N|ww -k*% +COGOpH%}W?1uk,;"w4F;bt/D>A7vt73tK(aze?+ϫ:KտFc WS 2 yQBIZD>C^4ef^Jlp!I %.G.YkeJ]zv5H8Q5 N,,׶J8H iߖp9~_E+QN)*ӥJuY%3*J]Hu(x4.>K9/ !{Zˡ^s -2/?pg(zM[ΡP\E$pVOYa~l<np߄G$7 M&&0$7u MXa~+% -!%l%xNpe א%UQ\G<#ʴP'|lJ8g< ~Mqv^A Po{%C9DBoI8fJ(J|; xǡpǑ@q]2@ޱk$|q -ų}$㸗 I8Õ38)H85>*P8 WV - C]r=ЊQ|) -A QJ@UdC4~J!@worh&h@ghF>kAQkF :lR?27C'z/йL2wdFC! (2|)/o~hfglv:ڽP^0.L PKaZRme-70Xh45QF`<J}CV=C0F3t)'2Ӄ.: c\7Sgxb$G9,qTt4Z/uG}u팬?= -^@t']ԛ"pl#`EC" xl=T^*{9Z͙]iA7*iRB_HyRYxZe6CGFT(C[YUZmGOsh2*^G޹sl6u=P (tQ4HA:ܙ>gem -Α 5_ox -B@M ė7kཔֶ"-RS z;A>h֙VKx#JIFiN,HF(OԯS&dP]"HR. >.I[(]Eo_2GA%͆7Rx1{qhĘYy1yR%~MTTnif% :Ɲ B3u]{z=B^Rv.~rz\DiN4]T!j~ -{Ԝ /Ҩ0Yd7쥖Ƌh<snșSKKqp6fŷyQk6BR]nwJ'\&;Dn+LAk%^EN_cm/Xof?l: -O`hPhk?4( - -]]K -fD~y>$BaEp$8)[87/ -8ͩHC٦[2 FB}Y_$|M-ʾU:\5|kGF^P v:`Oph!!~@hp⡍CG&A0H0 -t~lJ{ -RezC=GMs׍y7o]/.'޻ntw(cB#kz n%-_ieMUM˄ZaI}UͲnEMҚeZVݺNCC0[o\dz7 m -m$={Bl>`#I0 1Fum - -nR! -~lX * -0Z$r_/pQ` -j3R;3OuSƮP{d$8:wrp 82BOGc 8M02`Xqpp-OdƆR=Lm F@ѨgR:o#QעI+Ct6v#rW뻶 -?LVbY DQ7;†*AiÒޔxd]h@/M\8|B31B73FP v1XuRg:@3ZFVT -!_%x|~OZ<bTĪztG,ѭlzl3jmZج>$,E)AjEч[ؗ!)y4_=!WzC~𫇀_=!WzCWE@x~Rh2rZ - ~ uͧR1Y)v)he4mwKΧjvt{z%{^v/=yT[ĕsU\W‰B+TϋҶ[,E?EXf)5`shu7_v_/.f>roua(?Vib!vT  `q&;;^Z_&@1[ +4c2{u ]9v$E{N`2*OZ+ I gR~,RN/)_$ B#y5c?WJ H A<t=0Pwq>aX%f -VLx 6  Oo7)7כM&~-q:x~rkWU -| -TE>S.#$Z@:֍\г6R+[e94/=^r }̀R2h)JPJ5}C OpeDaMM;I4=IӫhZAS\1E |nܶ}v٩q[7dOGȊ0n -jlq[dmUUMpX[c` -JqgA[7Z*UYBۓVO&'Z2^=ݩSv+vg+vi -Ҩ:FV*r%dHi"/.|$I&HQgH/|!+Ԁ:3 ᘰp?SgƖŸ1|5v ZX|uXXFغ=64[n`Ǫx+hHu{E ϗp2 N=\nPDVK܍aUm1f;̭mGHͩ B[oF*#7%n -$ I:t_oKE止Z(olO+v(vDD+nli G``"\v 0 k1Hvȼ Ԑ/{a3t8@k3 !'C/ٙE.dQ:;ϣ_goh(M|iR -͡/A6Jc/%h2.Js?G^ŗl‡ -<|w @gMc݂pI?Y:{֑+8'pZؿbӅMyz?Tڶ_!qtUhZ'a0 YMi MD5@d5MTVM?Y}mhq{ՕL/N%PnKޖzCqnkZT&XIGԔܖz?.5Pmp,F.xTȗx}JkM鯞C{=?3шT1:Fi:3:s:NKi'/z -CjxAG\"ȟ#8amnBH.5 o -endstream -endobj - -93 0 obj -15232 -endobj - -94 0 obj -<> -endobj - -95 0 obj -<> -stream -x]n <P6m(R.Re{i!C~wg=քOcyz c̹6*ܢtw,nd[/3ܳk^GŸ:#*a<!KUcلe-S,5i]eT W{(Q*n_EΉ:qF$^'R~\>w)'M| 8O -# z@Ǽ2_o?~F8ִ4Ok79t -T -endstream -endobj - -96 0 obj -<> -endobj - -97 0 obj -<> -stream -xy|TE8^u}ݝ/$! 0!B$[$#q|n⎎sQ\B@m\p}QHTY@c7Uu~ΩsNսiz6D#[;!^DZ7 : -q^սBkB6doؼʷ e}&jYǴ59+ :!NGWkߗ[$|AwHS"4;ºΈ핿!GQ:n#=!?z0|G JZ -dXmv$x}?LLJNIMC?p@!-ȋP>^"Gb1M\/Sߛi\)jCNtpe -#_C,~*C;&:Z`@%hM,h _{0hU^E)cCtƿFK=Q1=AzRˉ}sZ2 -QPض؝HN c:Ԅ6a7%3bWÜ 8! "6Eo05;=ku4-@Pp%s.{.0EǼw=ڈ.@vFbQ3aF\sz=a%.q_b6rؗgS߀vMC#@S;q/+:|?32-e/>S=㺑 ( -8S~> \ʄ sڱh4?6+%tMD)PUÚ碥02t=m_B/@% h! ^ -0Wxfy -/qKGFWXlwl ؋`*@#Fc`;Ɛcu6ç@%CL-gsNhgP 6dE2DҴ5@߿jރ 9x>/Mx -x=_ T}]%1r -t -1̯^3"v1]^`r}#aL;Q̱9 - -  x -Ђ*(ߪ`saKq^5x-пƃ |?/W gvff73 -of 6ggM+٫`=q grY+k");"{N/tDdþ<`;.aϘ2eWI;&?% LS|Y;~ ^D`ng2٥\2E}s.sӄOlK.f%D[`LwUWzP&(2QdO:]J`9?s(^؀Zu(yB:v RTgab\ځ5DAb؏=xE@ n&[a$2V\,| i'چ <4ap9Sx;'zz -# r%3l2HM11 FF[|1Ӂm}L%"l/So~U@M%J$+%pO pd&0*{"GWЅ@٠ݶ^6|^Ř:.;fދٱ_bâpN x}L'`vnw9lIКW`Mt<tO;؈ -au3LJsl:ihUhZ.q[,EWk@܂GadfUFaew5-Fh!6E%&*ܠ `>Q~syBpŌ%Ey9YԔ`/ ۬:FR*2e0ʨ 6 M\rpL6yi@T:B&LNkkb^(CeBMPx:( s.`00JNa~?4jk$ n\ۣQW" GPЀ=ؽg` -0{\g`MinXpYMoU9`*3 PavMؓqx5m8"--_`_v\1{+"\c,˸T -{ #rEty|M=[7q{ׅjV&Ju5i.:{ҕwsRrK¶26=dfN Jqiyni> -4> ŭ:u:V7Ϩƀhd!|`D*2M._,P1m% -s0yj -f#`2ZL "F@c-uR5[VɃa613 -FxEf -&c22bLOGQ"NW܁ۀ'|q?1 -Jh-*ʲeՑ+$q 8wј -̞?-{z1 qf\^\Jm g]Ce>ӷ06ܱ2W4{˱F٣0܇'!qQl'v%l=ó - ->C?L?{A?Oynṇt@؉AF9~ifkz`2m;8 -{}Z0Ü{A24R+ R~XQX@Ÿ5Xhhrri̱/.lYy}[J@!3)Zߞ郥;5z7)nDpI7ֹ]n^>կGԲ+7?yC#+pOت82yj$S6 R\wj,W| lPd3{Oph(3aƑ2nNOEr Tt=Qia˭h\*R>B8tD?IBT;SmQȩ&|Q[!Sx%YtC'|~#; vdv-T2%_9 -L6A@*]%%`SP>sk,=I_GNO$OlnͿPwqkJ!wڮ^=$ꠅuLT -:.޻#/C~#Y,eXS,ռjj@TU+Ud*Wa?=+8rAgAz]?W x@wP#`iGѩzQqE~A] ʼ^%\2$i|̴e>+m,.+zEgCSD3 -iBs$?ڔbO|+_?k_`R!?{NzۇQ_qK/2AmTGg&7[:li<^5BQt__%11\AJ7W]zAUatYYX3&:!ԟ;Jkq͝#Bw?abOcC~ -hrgږ@~R^Pƽ}4ڸ\'+T9sYQӆW:4y7=ؗdp=^T -Y-(HP|3I鷽9Czy!dgHgef,ݢu -\vljkrgך66"ˬͬdbV8VI4DjOiz"SY:1 -)V_++YDCpAPF_AguqUMAG%[TDd9SUr'](j6Jgm&0؁iӤMHN!\akx0SSwӬ֛΢p:xa'ٖnZq -sеlwxOvo Ҳ -VOfg54?)4I7(ҕא0?aeBW̛lR+2bl͞!Lzp=78)Ah$+avx}}jp_{cO~p͋-dz_{[_c[n_hϾh 8LqXDo8^9 -;]12\u%sD~Dܣ*~ӪhSٝE!a=>aaJxai:SZ6e[Ɗ@Q#ފ豾Vkxţ$>IZ!]o60/7WZ,83'# -'oJ-9s'OG~!w{ή&Y2yZ+c'?y3ӋC#S*r%#\>V&09nm" Q m&kܗ+݈ˮkh_|u ׯbB򕴌mP6gqk6\Tu?&Y_~4vTTx*٨W?$= UZVCJ#M1¢VR*Z -Ԟ'b { TbpLPV8g0!Q1VQjX oDEidrڃwݻkWڎGPv,K). z fG.]އ-fr*.-)2߹"8$~dg3s 9zv3!n~8U{?}ϯ$g%rwyg)DkZ47eИtnZZg{Nm8Mli0c=?iUw.䭮4>͔oqz -&ō;=v]e)4CvP/U6>ʰQ~W26$'БIt2ܧ>:bw0/J$f|}cq1, U>qNNDJ7{{!zk^xyBew{^b7fg_Htl@k2+kPi|@l_qf1Q!yHZ&=\f(2K -erCPeQӴ{݃\ -%EOMSyj5% -YzǦ3O/(^^17}m␉7MvʱG>jô39فiaUUU@fܛcEzQ˯RiӒj^¾[JN -)$ܟ$*qh ,r>q@l<RQ6:v峞k\SNXubOwf%RNiҸɝj}ءuQB Ĭq[FؗcN{f+ -2 BJgVW'wlap}MdU -P4!MLr1MSgSqq_ w]??/^|12(A`Q6UMUA>y_M,\ L&/L).5js_*rKJK3KJ K JKUU`JVVJE`gɛneZߦʐ -l K\5yP>#DHi0$dKhYZv`rJD:8@vB OHk$AH 9Qɮ -Qy1<̫0 -^g!K*I2I!فo++=3%,A~31^h{aV>ngt ñO!U.}~* -r~ðʤ0z5 -a,j}Qm4ͨ*0< -L"7DUȯNf ʳ83xWRV -ǎ [u qw٦1rۋE<—&[ ._*l_y]s24`?"O۰'7#R^MKϊHgSxQ|)_}bU:FaaЦQ" !'mFtz:c/^!h$x¢۲t c/>Ġ`[!}؉LeZ - `ẹWzMǾLgdO0u*)2] 2e&L*G̋&9=忋6*Eed9NS&^SSӒӓ9F֪JB+cb fWIaeqcdmFe1!+>KQ'?A,&{j">0;bOԧOAXl: b-PvTCd#P'|`}QvDCb^N!O]x8m\)kL짗F8벬_gyy[}U3dֵBԒb}%\\Z迱W0OelRy?g"&>B {MJp쇰(GJ;^`ZTHwUVkR2#NJ`ބǑL:ARa5Zm4U'nA/>.=F3N -rCܿ Npr!9y6T%C1 g:)06v|{<Ĩ߯+ۧxFKRmga,+0~ȫF֭PtjUo5]4 ŋb,y\Zj#N*ýġ+C9Gsҗҋ5,5F)InӇ] -x(:">)<,6Jg\%GqŸh-W8WwنdY5~q¦/N;Nbts6yp9L@HB|]~\g>+1^` p~goo#L`%_eeI}0~@Ҡ lɂ -N` 2CzHiXV[YuM>,0>q/ -9 &pcl$=!WLR$01ldI06ˬaXFLOΐ7/FmXO'\_Io;>2y޲n~r:gqKoc;~]OVa}nb~m/+|jCQ o:_:"e > -c pNl -?X5Ze>8r2Wx_8C -geaW'$a+x0/k`agZ -Hgc%2L!_R}H^&om#Ճ݆rsc!ΟI8e^ů>ZK8ʈ.+ٔS/E5969?B(h*O@e2m]mi;u|P:ۈp Am>%ѓ@$G#aUB9ǩQryWXe/Wyyrt샚$N =AQkŗ::&>}Jᑩ<288T aT'$p(Ը^('BKnuUo^zuhup/LЙlY⣈h۾~(L*LNӵkxɤ^>'L 0R`yZ<,.0f\66GÚ| \;HD(oRd}F+0XY -8@LevmF8F^ZbI H΁9 L 8V@Q\I1Lyw~]vEoin7mlyٖy敿+(,Yزѭ- ck[v*w]j:2pq*a1VcrOO;V܇fςQJ<01%ў٭J -SXExd+#K, `n -ɺ|b[bKxAAa- v -)0O"dS InuSJYNaşOa'mnZG[s3}-i)N$;CtSK8֊(,eգͨE*ԌZ! -E]h> 0NkYUS|eO3b(@nx9Db+EjCmЃ6BFr'ynVşD?< RvoBXD?D/Skum/gM)( U IWq>ȸKss  OR {ifKh6:.,TMzh]TFz\⻌̹K|(@n2mPZuB:G\NjA{dC5FlZ; fCui$׋VJutYmknd(|#s@怴VRx>`k!>ɯ-,^57鐚۩txQ/tS--z K:wLx$](>Q:i}q&dwPPkմȸdnF[i.G\Ke)բ>=.ͬJc;ŷR -{ѫKZWl$}K䰅)q-gI=R誦RJ;gJř#k֍tmCv/'΢cK{|/D>M$i3ꦔmڰg\dq - 71.mҢI$ cv$?R̮S҃:s~띢&4D.B5Y' _Uݒ|ĥtw+9tgrPw|5v<9=uQ[&يTn~{Ս7&X3(RK\A}?k>֫W#J>F<'ďD,K\ȑ߲+ i Tb(ͥY)E(i5 -Ig-c,4ݑUͭ~MD۵PBUWOwWOs_{:5Knk*e΄]W喔dBT%TvtWEz#=#mU]z#=¼ȦE:{OT4}c U#moZ՗69Hh.X<^=(4E:{Vۅ=}HоNh5kú>7k!kuOsͳ65 uHOu}:h+4 ꦞvP^#̙97CTm=͛ -ʶuBmPr5i%6G:"0VG&"aU0`w{_!tvel ڄގ*u>lI/%D:}׽Τ'[˄M]@So_u:: -u}Ykggoڴ)S"]VkWgΎ>ٝ+[Erl"%?զH`#ɼsjTUϙ?O_+=fr֢5uj~M{/]eA{ϛl{Ar7F6wm -[6R)ٰ -hDZuN:޼'!ٚ9vGhkwlVtuN ׵:Bl@n{[6A0MI JO -dgۉnlMn%,Y5IY펴)y\ŕC\2eyt#~ -e?a! -Nd>v=<$?< t ItP_QFpVBE°qb!```*a}0!gbW.v 0 -6䇾ϓҕRz=nkm>C -}q ksp(*8f`|NN՝0;aVw¬C;;w?삮iRWp&aT -9p ˤt){`Pe~ƻzJϧZ]p+$ٓb -$fa3؅Y4]֠$HC94΢ـw@ZLWC:$Vr*!a0j \ac-B`iMV÷ -l%Ca( # -÷3PRu!eteP F*ZAe2`ORe l!ʁB2`^0B/?s -@*Hنzm^_RE 4A GfCa%-(%K`3Y;m,ԓ ZWM2!04r,5A`@tR!G!@HbS} -%@ShkIl*`R! -mRn*`TRhC8$0p6 - - AFe"|P\ Լv-ll(j\Q2v?|T뇯_ mnnX - -1+ -^_xwᣅ -f61Ma5@%JW%pha8Lc{صB7B -+t7-[BWBB7[ݐn{HwNH7-+ C҈RL8@tPTO?Q㔽K}9p!)>+X]XSlυHYj -C27Hgͤt2֬aR<0a2֬,:zK%PBLoigPi.;.q=҄:(2.#EzqIEKJRhcp&rԴWÿ^ z{{=_og݇`Zj|nކ>Iz7 [&:6@ϸwʏ:nĦC!t$^ - -endstream -endobj - -98 0 obj -17067 -endobj - -99 0 obj -<> -endobj - -100 0 obj -<> -stream -x]n0y -CxLVB(ö>@H8 ~xw>1_׻s;ݞgs|2^CgL?tsZown,e2e7sg[9 d>_gSdMcz>s~k{\v}ClMlHVUvZlYYnMƾH-cՆ1Zm" -.R3+pZ~ҌJOgvkfz2 XkV'u/_I&|$5ܬWRW`߉[}/w'wR7JORRsTXjÓ[PdWX`n!Qt -4NL -endstream -endobj - -101 0 obj -<> -endobj - -102 0 obj -<> -endobj - -103 0 obj -<> -endobj - -1 0 obj -<>/Contents 2 0 R>> -endobj - -4 0 obj -<>/Contents 5 0 R>> -endobj - -7 0 obj -<>/Contents 8 0 R>> -endobj - -10 0 obj -<>/Contents 11 0 R>> -endobj - -13 0 obj -<>/Contents 14 0 R>> -endobj - -16 0 obj -<>/Contents 17 0 R>> -endobj - -19 0 obj -<>/Contents 20 0 R>> -endobj - -22 0 obj -<>/Contents 23 0 R>> -endobj - -25 0 obj -<>/Contents 26 0 R>> -endobj - -28 0 obj -<>/Contents 29 0 R>> -endobj - -31 0 obj -<>/Contents 32 0 R>> -endobj - -34 0 obj -<>/Contents 35 0 R>> -endobj - -37 0 obj -<>/Contents 38 0 R>> -endobj - -40 0 obj -<>/Contents 41 0 R>> -endobj - -43 0 obj -<>/Contents 44 0 R>> -endobj - -46 0 obj -<>/Contents 47 0 R>> -endobj - -51 0 obj -<> -endobj - -49 0 obj -<> ->> -endobj - -50 0 obj -<> ->> -endobj - -104 0 obj -<> -endobj - -105 0 obj -< -/Producer -/CreationDate(D:20090714221828-04'00')>> -endobj - -xref -0 106 -0000000000 65535 f -0000226265 00000 n -0000000019 00000 n -0000000380 00000 n -0000226428 00000 n -0000000400 00000 n -0000001576 00000 n -0000226591 00000 n -0000001597 00000 n -0000002522 00000 n -0000226736 00000 n -0000002542 00000 n -0000003873 00000 n -0000226883 00000 n -0000003895 00000 n -0000007544 00000 n -0000227030 00000 n -0000007566 00000 n -0000010906 00000 n -0000227177 00000 n -0000010928 00000 n -0000013803 00000 n -0000227324 00000 n -0000013825 00000 n -0000017140 00000 n -0000227471 00000 n -0000017162 00000 n -0000020039 00000 n -0000227618 00000 n -0000020061 00000 n -0000022077 00000 n -0000227765 00000 n -0000022099 00000 n -0000023705 00000 n -0000227912 00000 n -0000023727 00000 n -0000024506 00000 n -0000228059 00000 n -0000024527 00000 n -0000027796 00000 n -0000228206 00000 n -0000027818 00000 n -0000031017 00000 n -0000228353 00000 n -0000031039 00000 n -0000033572 00000 n -0000228500 00000 n -0000033594 00000 n -0000035289 00000 n -0000228852 00000 n -0000228999 00000 n -0000228647 00000 n -0000035311 00000 n -0000035970 00000 n -0000035991 00000 n -0000036181 00000 n -0000036472 00000 n -0000036633 00000 n -0000054673 00000 n -0000054696 00000 n -0000054899 00000 n -0000055351 00000 n -0000055657 00000 n -0000075588 00000 n -0000075611 00000 n -0000075805 00000 n -0000076322 00000 n -0000076686 00000 n -0000083565 00000 n -0000083587 00000 n -0000083781 00000 n -0000084147 00000 n -0000084371 00000 n -0000106354 00000 n -0000106377 00000 n -0000106566 00000 n -0000107083 00000 n -0000107442 00000 n -0000128623 00000 n -0000128646 00000 n -0000128855 00000 n -0000129326 00000 n -0000129658 00000 n -0000169160 00000 n -0000169183 00000 n -0000169382 00000 n -0000170008 00000 n -0000170481 00000 n -0000190736 00000 n -0000190759 00000 n -0000190947 00000 n -0000191426 00000 n -0000191750 00000 n -0000207069 00000 n -0000207092 00000 n -0000207291 00000 n -0000207665 00000 n -0000207904 00000 n -0000225058 00000 n -0000225081 00000 n -0000225275 00000 n -0000225753 00000 n -0000226081 00000 n -0000226208 00000 n -0000229137 00000 n -0000229223 00000 n -trailer -< - ] -/DocChecksum /2E16B381986633E52516A39438BA68AD ->> -startxref -229411 -%%EOF Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/adv_jtag_bridge.odt =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/adv_jtag_bridge.odt =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/adv_jtag_bridge.odt (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/adv_jtag_bridge.odt (nonexistent)

ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/adv_jtag_bridge.odt Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/ajb_block_diagram.odg =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/ajb_block_diagram.odg =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/ajb_block_diagram.odg (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/ajb_block_diagram.odg (nonexistent)
ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/doc/src/ajb_block_diagram.odg Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_parallel.h =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_parallel.h (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_parallel.h (nonexistent) @@ -1,19 +0,0 @@ - -#ifndef _CABLE_PARALLEL_H_ -#define _CABLE_PARALLEL_H_ - -#include - -int cable_parallel_init(); -int cable_parallel_opt(int c, char *str); -void cable_parallel_phys_wait(); - -int cable_xpc3_inout(uint8_t value, uint8_t *inval); -int cable_xpc3_out(uint8_t value); - -int cable_xess_inout(uint8_t value, uint8_t *inval); -int cable_xess_out(uint8_t value); - - - -#endif Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/spr-defs.h =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/spr-defs.h (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/spr-defs.h (nonexistent) @@ -1,581 +0,0 @@ -/* spr-defs.h -- Defines OR1K architecture specific special-purpose registers - - Copyright (C) 1999 Damjan Lampret, lampret@opencores.org - Copyright (C) 2008 Embecosm Limited - - Contributor Jeremy Bennett - - This file is part of 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 SPR_DEFS__H -#define SPR_DEFS__H - -/* Definition of special-purpose registers (SPRs). */ - -#define MAX_GRPS (32) -#define MAX_SPRS_PER_GRP_BITS (11) -#define MAX_SPRS_PER_GRP (1 << MAX_SPRS_PER_GRP_BITS) -#define MAX_SPRS (0x10000) - -/* Base addresses for the groups */ -#define SPRGROUP_SYS (0<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_DMMU (1<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_IMMU (2<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_DC (3<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_IC (4<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_MAC (5<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_D (6<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_PC (7<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_PM (8<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_PIC (9<< MAX_SPRS_PER_GRP_BITS) -#define SPRGROUP_TT (10<< MAX_SPRS_PER_GRP_BITS) - -/* System control and status group */ -#define SPR_VR (SPRGROUP_SYS + 0) -#define SPR_UPR (SPRGROUP_SYS + 1) -#define SPR_CPUCFGR (SPRGROUP_SYS + 2) -#define SPR_DMMUCFGR (SPRGROUP_SYS + 3) -#define SPR_IMMUCFGR (SPRGROUP_SYS + 4) -#define SPR_DCCFGR (SPRGROUP_SYS + 5) -#define SPR_ICCFGR (SPRGROUP_SYS + 6) -#define SPR_DCFGR (SPRGROUP_SYS + 7) -#define SPR_PCCFGR (SPRGROUP_SYS + 8) -#define SPR_NPC (SPRGROUP_SYS + 16) /* CZ 21/06/01 */ -#define SPR_SR (SPRGROUP_SYS + 17) /* CZ 21/06/01 */ -#define SPR_PPC (SPRGROUP_SYS + 18) /* CZ 21/06/01 */ -#define SPR_EPCR_BASE (SPRGROUP_SYS + 32) /* CZ 21/06/01 */ -#define SPR_EPCR_LAST (SPRGROUP_SYS + 47) /* CZ 21/06/01 */ -#define SPR_EEAR_BASE (SPRGROUP_SYS + 48) -#define SPR_EEAR_LAST (SPRGROUP_SYS + 63) -#define SPR_ESR_BASE (SPRGROUP_SYS + 64) -#define SPR_ESR_LAST (SPRGROUP_SYS + 79) -#define SPR_GPR_BASE (SPRGROUP_SYS + 1024) -#define SPR_GPR_LAST (SPRGROUP_SYS + 1535) -#define MAX_GPRS 32 // Does this really belong here? No. --NAY - -/* Data MMU group */ -#define SPR_DMMUCR (SPRGROUP_DMMU + 0) -#define SPR_DTLBMR_BASE(WAY) (SPRGROUP_DMMU + 0x200 + (WAY) * 0x100) -#define SPR_DTLBMR_LAST(WAY) (SPRGROUP_DMMU + 0x27f + (WAY) * 0x100) -#define SPR_DTLBTR_BASE(WAY) (SPRGROUP_DMMU + 0x280 + (WAY) * 0x100) -#define SPR_DTLBTR_LAST(WAY) (SPRGROUP_DMMU + 0x2ff + (WAY) * 0x100) - -/* Instruction MMU group */ -#define SPR_IMMUCR (SPRGROUP_IMMU + 0) -#define SPR_ITLBMR_BASE(WAY) (SPRGROUP_IMMU + 0x200 + (WAY) * 0x100) -#define SPR_ITLBMR_LAST(WAY) (SPRGROUP_IMMU + 0x27f + (WAY) * 0x100) -#define SPR_ITLBTR_BASE(WAY) (SPRGROUP_IMMU + 0x280 + (WAY) * 0x100) -#define SPR_ITLBTR_LAST(WAY) (SPRGROUP_IMMU + 0x2ff + (WAY) * 0x100) - -/* Data cache group */ -#define SPR_DCCR (SPRGROUP_DC + 0) -#define SPR_DCBPR (SPRGROUP_DC + 1) -#define SPR_DCBFR (SPRGROUP_DC + 2) -#define SPR_DCBIR (SPRGROUP_DC + 3) -#define SPR_DCBWR (SPRGROUP_DC + 4) -#define SPR_DCBLR (SPRGROUP_DC + 5) -#define SPR_DCR_BASE(WAY) (SPRGROUP_DC + 0x200 + (WAY) * 0x200) -#define SPR_DCR_LAST(WAY) (SPRGROUP_DC + 0x3ff + (WAY) * 0x200) - -/* Instruction cache group */ -#define SPR_ICCR (SPRGROUP_IC + 0) -#define SPR_ICBPR (SPRGROUP_IC + 1) -#define SPR_ICBIR (SPRGROUP_IC + 2) -#define SPR_ICBLR (SPRGROUP_IC + 3) -#define SPR_ICR_BASE(WAY) (SPRGROUP_IC + 0x200 + (WAY) * 0x200) -#define SPR_ICR_LAST(WAY) (SPRGROUP_IC + 0x3ff + (WAY) * 0x200) - -/* MAC group */ -#define SPR_MACLO (SPRGROUP_MAC + 1) -#define SPR_MACHI (SPRGROUP_MAC + 2) - -/* Debug group */ -#define SPR_DVR(N) (SPRGROUP_D + (N)) -#define SPR_DCR(N) (SPRGROUP_D + 8 + (N)) -#define SPR_DMR1 (SPRGROUP_D + 16) -#define SPR_DMR2 (SPRGROUP_D + 17) -#define SPR_DWCR0 (SPRGROUP_D + 18) -#define SPR_DWCR1 (SPRGROUP_D + 19) -#define SPR_DSR (SPRGROUP_D + 20) -#define SPR_DRR (SPRGROUP_D + 21) - -/* Performance counters group */ -#define SPR_PCCR(N) (SPRGROUP_PC + (N)) -#define SPR_PCMR(N) (SPRGROUP_PC + 8 + (N)) - -/* Power management group */ -#define SPR_PMR (SPRGROUP_PM + 0) - -/* PIC group */ -#define SPR_PICMR (SPRGROUP_PIC + 0) -#define SPR_PICPR (SPRGROUP_PIC + 1) -#define SPR_PICSR (SPRGROUP_PIC + 2) - -/* Tick Timer group */ -#define SPR_TTMR (SPRGROUP_TT + 0) -#define SPR_TTCR (SPRGROUP_TT + 1) - -/* - * Bit definitions for the Version Register - * - */ -#define SPR_VR_VER 0xff000000 /* Processor version */ -#define SPR_VR_CFG 0x00ff0000 /* Processor configuration */ -#define SPR_VR_RES 0x00ff0000 /* Reserved */ -#define SPR_VR_REV 0x0000003f /* Processor revision */ - -#define SPR_VR_VER_OFF 24 -#define SPR_VR_CFG_OFF 16 -#define SPR_VR_REV_OFF 0 - -/* - * Bit definitions for the Unit Present Register - * - */ -#define SPR_UPR_UP 0x00000001 /* UPR present */ -#define SPR_UPR_DCP 0x00000002 /* Data cache present */ -#define SPR_UPR_ICP 0x00000004 /* Instruction cache present */ -#define SPR_UPR_DMP 0x00000008 /* Data MMU present */ -#define SPR_UPR_IMP 0x00000010 /* Instruction MMU present */ -#define SPR_UPR_MP 0x00000020 /* MAC present */ -#define SPR_UPR_DUP 0x00000040 /* Debug unit present */ -#define SPR_UPR_PCUP 0x00000080 /* Performance counters unit present */ -#define SPR_UPR_PMP 0x00000100 /* Power management present */ -#define SPR_UPR_PICP 0x00000200 /* PIC present */ -#define SPR_UPR_TTP 0x00000400 /* Tick timer present */ -#define SPR_UPR_RES 0x00fe0000 /* Reserved */ -#define SPR_UPR_CUP 0xff000000 /* Context units present */ - -/* - * JPB: Bit definitions for the CPU configuration register - * - */ -#define SPR_CPUCFGR_NSGF 0x0000000f /* Number of shadow GPR files */ -#define SPR_CPUCFGR_CGF 0x00000010 /* Custom GPR file */ -#define SPR_CPUCFGR_OB32S 0x00000020 /* ORBIS32 supported */ -#define SPR_CPUCFGR_OB64S 0x00000040 /* ORBIS64 supported */ -#define SPR_CPUCFGR_OF32S 0x00000080 /* ORFPX32 supported */ -#define SPR_CPUCFGR_OF64S 0x00000100 /* ORFPX64 supported */ -#define SPR_CPUCFGR_OV64S 0x00000200 /* ORVDX64 supported */ -#define SPR_CPUCFGR_RES 0xfffffc00 /* Reserved */ - -/* - * JPB: Bit definitions for the Debug configuration register and other - * constants. - * - */ - -#define SPR_DCFGR_NDP 0x00000007 /* Number of matchpoints mask */ -#define SPR_DCFGR_NDP1 0x00000000 /* One matchpoint supported */ -#define SPR_DCFGR_NDP2 0x00000001 /* Two matchpoints supported */ -#define SPR_DCFGR_NDP3 0x00000002 /* Three matchpoints supported */ -#define SPR_DCFGR_NDP4 0x00000003 /* Four matchpoints supported */ -#define SPR_DCFGR_NDP5 0x00000004 /* Five matchpoints supported */ -#define SPR_DCFGR_NDP6 0x00000005 /* Six matchpoints supported */ -#define SPR_DCFGR_NDP7 0x00000006 /* Seven matchpoints supported */ -#define SPR_DCFGR_NDP8 0x00000007 /* Eight matchpoints supported */ -#define SPR_DCFGR_WPCI 0x00000008 /* Watchpoint counters implemented */ - -#define MATCHPOINTS_TO_NDP(n) (1 == n ? SPR_DCFGR_NDP1 : \ - 2 == n ? SPR_DCFGR_NDP2 : \ - 3 == n ? SPR_DCFGR_NDP3 : \ - 4 == n ? SPR_DCFGR_NDP4 : \ - 5 == n ? SPR_DCFGR_NDP5 : \ - 6 == n ? SPR_DCFGR_NDP6 : \ - 7 == n ? SPR_DCFGR_NDP7 : SPR_DCFGR_NDP8) -#define MAX_MATCHPOINTS 8 -#define MAX_WATCHPOINTS (MAX_MATCHPOINTS + 2) - -/* - * Bit definitions for the Supervision Register - * - */ -#define SPR_SR_SM 0x00000001 /* Supervisor Mode */ -#define SPR_SR_TEE 0x00000002 /* Tick timer Exception Enable */ -#define SPR_SR_IEE 0x00000004 /* Interrupt Exception Enable */ -#define SPR_SR_DCE 0x00000008 /* Data Cache Enable */ -#define SPR_SR_ICE 0x00000010 /* Instruction Cache Enable */ -#define SPR_SR_DME 0x00000020 /* Data MMU Enable */ -#define SPR_SR_IME 0x00000040 /* Instruction MMU Enable */ -#define SPR_SR_LEE 0x00000080 /* Little Endian Enable */ -#define SPR_SR_CE 0x00000100 /* CID Enable */ -#define SPR_SR_F 0x00000200 /* Condition Flag */ -#define SPR_SR_CY 0x00000400 /* Carry flag */ -#define SPR_SR_OV 0x00000800 /* Overflow flag */ -#define SPR_SR_OVE 0x00001000 /* Overflow flag Exception */ -#define SPR_SR_DSX 0x00002000 /* Delay Slot Exception */ -#define SPR_SR_EPH 0x00004000 /* Exception Prefix High */ -#define SPR_SR_FO 0x00008000 /* Fixed one */ -#define SPR_SR_SUMRA 0x00010000 /* Supervisor SPR read access */ -#define SPR_SR_RES 0x0ffe0000 /* Reserved */ -#define SPR_SR_CID 0xf0000000 /* Context ID */ - -/* - * Bit definitions for the Data MMU Control Register - * - */ -#define SPR_DMMUCR_P2S 0x0000003e /* Level 2 Page Size */ -#define SPR_DMMUCR_P1S 0x000007c0 /* Level 1 Page Size */ -#define SPR_DMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */ -#define SPR_DMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */ - -/* - * Bit definitions for the Instruction MMU Control Register - * - */ -#define SPR_IMMUCR_P2S 0x0000003e /* Level 2 Page Size */ -#define SPR_IMMUCR_P1S 0x000007c0 /* Level 1 Page Size */ -#define SPR_IMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */ -#define SPR_IMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */ - -/* - * Bit definitions for the Data TLB Match Register - * - */ -#define SPR_DTLBMR_V 0x00000001 /* Valid */ -#define SPR_DTLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */ -#define SPR_DTLBMR_CID 0x0000003c /* Context ID */ -#define SPR_DTLBMR_LRU 0x000000c0 /* Least Recently Used */ -#define SPR_DTLBMR_VPN 0xfffff000 /* Virtual Page Number */ - -/* - * Bit definitions for the Data TLB Translate Register - * - */ -#define SPR_DTLBTR_CC 0x00000001 /* Cache Coherency */ -#define SPR_DTLBTR_CI 0x00000002 /* Cache Inhibit */ -#define SPR_DTLBTR_WBC 0x00000004 /* Write-Back Cache */ -#define SPR_DTLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */ -#define SPR_DTLBTR_A 0x00000010 /* Accessed */ -#define SPR_DTLBTR_D 0x00000020 /* Dirty */ -#define SPR_DTLBTR_URE 0x00000040 /* User Read Enable */ -#define SPR_DTLBTR_UWE 0x00000080 /* User Write Enable */ -#define SPR_DTLBTR_SRE 0x00000100 /* Supervisor Read Enable */ -#define SPR_DTLBTR_SWE 0x00000200 /* Supervisor Write Enable */ -#define SPR_DTLBTR_PPN 0xfffff000 /* Physical Page Number */ - -/* - * Bit definitions for the Instruction TLB Match Register - * - */ -#define SPR_ITLBMR_V 0x00000001 /* Valid */ -#define SPR_ITLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */ -#define SPR_ITLBMR_CID 0x0000003c /* Context ID */ -#define SPR_ITLBMR_LRU 0x000000c0 /* Least Recently Used */ -#define SPR_ITLBMR_VPN 0xfffff000 /* Virtual Page Number */ - -/* - * Bit definitions for the Instruction TLB Translate Register - * - */ -#define SPR_ITLBTR_CC 0x00000001 /* Cache Coherency */ -#define SPR_ITLBTR_CI 0x00000002 /* Cache Inhibit */ -#define SPR_ITLBTR_WBC 0x00000004 /* Write-Back Cache */ -#define SPR_ITLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */ -#define SPR_ITLBTR_A 0x00000010 /* Accessed */ -#define SPR_ITLBTR_D 0x00000020 /* Dirty */ -#define SPR_ITLBTR_SXE 0x00000040 /* User Read Enable */ -#define SPR_ITLBTR_UXE 0x00000080 /* User Write Enable */ -#define SPR_ITLBTR_PPN 0xfffff000 /* Physical Page Number */ - -/* - * Bit definitions for Data Cache Control register - * - */ -#define SPR_DCCR_EW 0x000000ff /* Enable ways */ - -/* - * Bit definitions for Insn Cache Control register - * - */ -#define SPR_ICCR_EW 0x000000ff /* Enable ways */ - -/* - * Bit definitions for Data Cache Configuration Register - * - */ - -#define SPR_DCCFGR_NCW 0x00000007 -#define SPR_DCCFGR_NCS 0x00000078 -#define SPR_DCCFGR_CBS 0x00000080 -#define SPR_DCCFGR_CWS 0x00000100 -#define SPR_DCCFGR_CCRI 0x00000200 -#define SPR_DCCFGR_CBIRI 0x00000400 -#define SPR_DCCFGR_CBPRI 0x00000800 -#define SPR_DCCFGR_CBLRI 0x00001000 -#define SPR_DCCFGR_CBFRI 0x00002000 -#define SPR_DCCFGR_CBWBRI 0x00004000 - -#define SPR_DCCFGR_NCW_OFF 0 -#define SPR_DCCFGR_NCS_OFF 3 -#define SPR_DCCFGR_CBS_OFF 7 - -/* - * Bit definitions for Instruction Cache Configuration Register - * - */ -#define SPR_ICCFGR_NCW 0x00000007 -#define SPR_ICCFGR_NCS 0x00000078 -#define SPR_ICCFGR_CBS 0x00000080 -#define SPR_ICCFGR_CCRI 0x00000200 -#define SPR_ICCFGR_CBIRI 0x00000400 -#define SPR_ICCFGR_CBPRI 0x00000800 -#define SPR_ICCFGR_CBLRI 0x00001000 - -#define SPR_ICCFGR_NCW_OFF 0 -#define SPR_ICCFGR_NCS_OFF 3 -#define SPR_ICCFGR_CBS_OFF 7 - -/* - * Bit definitions for Data MMU Configuration Register - * - */ - -#define SPR_DMMUCFGR_NTW 0x00000003 -#define SPR_DMMUCFGR_NTS 0x0000001C -#define SPR_DMMUCFGR_NAE 0x000000E0 -#define SPR_DMMUCFGR_CRI 0x00000100 -#define SPR_DMMUCFGR_PRI 0x00000200 -#define SPR_DMMUCFGR_TEIRI 0x00000400 -#define SPR_DMMUCFGR_HTR 0x00000800 - -#define SPR_DMMUCFGR_NTW_OFF 0 -#define SPR_DMMUCFGR_NTS_OFF 2 - -/* - * Bit definitions for Instruction MMU Configuration Register - * - */ - -#define SPR_IMMUCFGR_NTW 0x00000003 -#define SPR_IMMUCFGR_NTS 0x0000001C -#define SPR_IMMUCFGR_NAE 0x000000E0 -#define SPR_IMMUCFGR_CRI 0x00000100 -#define SPR_IMMUCFGR_PRI 0x00000200 -#define SPR_IMMUCFGR_TEIRI 0x00000400 -#define SPR_IMMUCFGR_HTR 0x00000800 - -#define SPR_IMMUCFGR_NTW_OFF 0 -#define SPR_IMMUCFGR_NTS_OFF 2 - -/* - * Bit definitions for Debug Control registers - * - */ -#define SPR_DCR_DP 0x00000001 /* DVR/DCR present */ -#define SPR_DCR_CC 0x0000000e /* Compare condition */ -#define SPR_DCR_SC 0x00000010 /* Signed compare */ -#define SPR_DCR_CT 0x000000e0 /* Compare to */ - -/* Bit results with SPR_DCR_CC mask */ -#define SPR_DCR_CC_MASKED 0x00000000 -#define SPR_DCR_CC_EQUAL 0x00000002 -#define SPR_DCR_CC_LESS 0x00000004 -#define SPR_DCR_CC_LESSE 0x00000006 -#define SPR_DCR_CC_GREAT 0x00000008 -#define SPR_DCR_CC_GREATE 0x0000000a -#define SPR_DCR_CC_NEQUAL 0x0000000c - -/* Bit results with SPR_DCR_CT mask */ -#define SPR_DCR_CT_DISABLED 0x00000000 -#define SPR_DCR_CT_IFEA 0x00000020 -#define SPR_DCR_CT_LEA 0x00000040 -#define SPR_DCR_CT_SEA 0x00000060 -#define SPR_DCR_CT_LD 0x00000080 -#define SPR_DCR_CT_SD 0x000000a0 -#define SPR_DCR_CT_LSEA 0x000000c0 -#define SPR_DCR_CT_LSD 0x000000e0 -/* SPR_DCR_CT_LSD doesn't seem to be implemented anywhere in or1ksim. 2004-1-30 HP */ - -/* - * Bit definitions for Debug Mode 1 register - * - */ -#define SPR_DMR1_CW 0x000fffff /* Chain register pair data */ -#define SPR_DMR1_CW0_AND 0x00000001 -#define SPR_DMR1_CW0_OR 0x00000002 -#define SPR_DMR1_CW0 (SPR_DMR1_CW0_AND | SPR_DMR1_CW0_OR) -#define SPR_DMR1_CW1_AND 0x00000004 -#define SPR_DMR1_CW1_OR 0x00000008 -#define SPR_DMR1_CW1 (SPR_DMR1_CW1_AND | SPR_DMR1_CW1_OR) -#define SPR_DMR1_CW2_AND 0x00000010 -#define SPR_DMR1_CW2_OR 0x00000020 -#define SPR_DMR1_CW2 (SPR_DMR1_CW2_AND | SPR_DMR1_CW2_OR) -#define SPR_DMR1_CW3_AND 0x00000040 -#define SPR_DMR1_CW3_OR 0x00000080 -#define SPR_DMR1_CW3 (SPR_DMR1_CW3_AND | SPR_DMR1_CW3_OR) -#define SPR_DMR1_CW4_AND 0x00000100 -#define SPR_DMR1_CW4_OR 0x00000200 -#define SPR_DMR1_CW4 (SPR_DMR1_CW4_AND | SPR_DMR1_CW4_OR) -#define SPR_DMR1_CW5_AND 0x00000400 -#define SPR_DMR1_CW5_OR 0x00000800 -#define SPR_DMR1_CW5 (SPR_DMR1_CW5_AND | SPR_DMR1_CW5_OR) -#define SPR_DMR1_CW6_AND 0x00001000 -#define SPR_DMR1_CW6_OR 0x00002000 -#define SPR_DMR1_CW6 (SPR_DMR1_CW6_AND | SPR_DMR1_CW6_OR) -#define SPR_DMR1_CW7_AND 0x00004000 -#define SPR_DMR1_CW7_OR 0x00008000 -#define SPR_DMR1_CW7 (SPR_DMR1_CW7_AND | SPR_DMR1_CW7_OR) -#define SPR_DMR1_CW8_AND 0x00010000 -#define SPR_DMR1_CW8_OR 0x00020000 -#define SPR_DMR1_CW8 (SPR_DMR1_CW8_AND | SPR_DMR1_CW8_OR) -#define SPR_DMR1_CW9_AND 0x00040000 -#define SPR_DMR1_CW9_OR 0x00080000 -#define SPR_DMR1_CW9 (SPR_DMR1_CW9_AND | SPR_DMR1_CW9_OR) -#define SPR_DMR1_RES1 0x00300000 /* Reserved */ -#define SPR_DMR1_ST 0x00400000 /* Single-step trace*/ -#define SPR_DMR1_BT 0x00800000 /* Branch trace */ -#define SPR_DMR1_RES2 0xff000000 /* Reserved */ - -/* - * Bit definitions for Debug Mode 2 register. AWTC and WGB corrected by JPB - * - */ -#define SPR_DMR2_WCE0 0x00000001 /* Watchpoint counter 0 enable */ -#define SPR_DMR2_WCE1 0x00000002 /* Watchpoint counter 0 enable */ -#define SPR_DMR2_AWTC 0x00000ffc /* Assign watchpoints to counters */ -#define SPR_DMR2_AWTC_OFF 2 /* Bit offset to AWTC field */ -#define SPR_DMR2_WGB 0x003ff000 /* Watchpoints generating breakpoint */ -#define SPR_DMR2_WGB_OFF 12 /* Bit offset to WGB field */ -#define SPR_DMR2_WBS 0xffc00000 /* JPB: Watchpoint status */ -#define SPR_DMR2_WBS_OFF 22 /* Bit offset to WBS field */ - -/* - * Bit definitions for Debug watchpoint counter registers - * - */ -#define SPR_DWCR_COUNT 0x0000ffff /* Count */ -#define SPR_DWCR_MATCH 0xffff0000 /* Match */ -#define SPR_DWCR_MATCH_OFF 16 /* Match bit offset */ - -/* - * Bit definitions for Debug stop register - * - */ -#define SPR_DSR_RSTE 0x00000001 /* Reset exception */ -#define SPR_DSR_BUSEE 0x00000002 /* Bus error exception */ -#define SPR_DSR_DPFE 0x00000004 /* Data Page Fault exception */ -#define SPR_DSR_IPFE 0x00000008 /* Insn Page Fault exception */ -#define SPR_DSR_TTE 0x00000010 /* Tick Timer exception */ -#define SPR_DSR_AE 0x00000020 /* Alignment exception */ -#define SPR_DSR_IIE 0x00000040 /* Illegal Instruction exception */ -#define SPR_DSR_IE 0x00000080 /* Interrupt exception */ -#define SPR_DSR_DME 0x00000100 /* DTLB miss exception */ -#define SPR_DSR_IME 0x00000200 /* ITLB miss exception */ -#define SPR_DSR_RE 0x00000400 /* Range exception */ -#define SPR_DSR_SCE 0x00000800 /* System call exception */ -#define SPR_DSR_FPE 0x00001000 /* Floating point Exception */ -#define SPR_DSR_TE 0x00002000 /* Trap exception */ - -/* - * Bit definitions for Debug reason register - * - */ -#define SPR_DRR_RSTE 0x00000001 /* Reset exception */ -#define SPR_DRR_BUSEE 0x00000002 /* Bus error exception */ -#define SPR_DRR_DPFE 0x00000004 /* Data Page Fault exception */ -#define SPR_DRR_IPFE 0x00000008 /* Insn Page Fault exception */ -#define SPR_DRR_TTE 0x00000010 /* Tick Timer exception */ -#define SPR_DRR_AE 0x00000020 /* Alignment exception */ -#define SPR_DRR_IIE 0x00000040 /* Illegal Instruction exception */ -#define SPR_DRR_IE 0x00000080 /* Interrupt exception */ -#define SPR_DRR_DME 0x00000100 /* DTLB miss exception */ -#define SPR_DRR_IME 0x00000200 /* ITLB miss exception */ -#define SPR_DRR_RE 0x00000400 /* Range exception */ -#define SPR_DRR_SCE 0x00000800 /* System call exception */ -#define SPR_DRR_FPE 0x00001000 /* Floating point exception */ -#define SPR_DRR_TE 0x00002000 /* Trap exception */ - -/* - * Bit definitions for Performance counters mode registers - * - */ -#define SPR_PCMR_CP 0x00000001 /* Counter present */ -#define SPR_PCMR_UMRA 0x00000002 /* User mode read access */ -#define SPR_PCMR_CISM 0x00000004 /* Count in supervisor mode */ -#define SPR_PCMR_CIUM 0x00000008 /* Count in user mode */ -#define SPR_PCMR_LA 0x00000010 /* Load access event */ -#define SPR_PCMR_SA 0x00000020 /* Store access event */ -#define SPR_PCMR_IF 0x00000040 /* Instruction fetch event*/ -#define SPR_PCMR_DCM 0x00000080 /* Data cache miss event */ -#define SPR_PCMR_ICM 0x00000100 /* Insn cache miss event */ -#define SPR_PCMR_IFS 0x00000200 /* Insn fetch stall event */ -#define SPR_PCMR_LSUS 0x00000400 /* LSU stall event */ -#define SPR_PCMR_BS 0x00000800 /* Branch stall event */ -#define SPR_PCMR_DTLBM 0x00001000 /* DTLB miss event */ -#define SPR_PCMR_ITLBM 0x00002000 /* ITLB miss event */ -#define SPR_PCMR_DDS 0x00004000 /* Data dependency stall event */ -#define SPR_PCMR_WPE 0x03ff8000 /* Watchpoint events */ - -/* - * Bit definitions for the Power management register - * - */ -#define SPR_PMR_SDF 0x0000000f /* Slow down factor */ -#define SPR_PMR_DME 0x00000010 /* Doze mode enable */ -#define SPR_PMR_SME 0x00000020 /* Sleep mode enable */ -#define SPR_PMR_DCGE 0x00000040 /* Dynamic clock gating enable */ -#define SPR_PMR_SUME 0x00000080 /* Suspend mode enable */ - -/* - * Bit definitions for PICMR - * - */ -#define SPR_PICMR_IUM 0xfffffffc /* Interrupt unmask */ - -/* - * Bit definitions for PICPR - * - */ -#define SPR_PICPR_IPRIO 0xfffffffc /* Interrupt priority */ - -/* - * Bit definitions for PICSR - * - */ -#define SPR_PICSR_IS 0xffffffff /* Interrupt status */ - -/* - * Bit definitions for Tick Timer Control Register - * - */ -#define SPR_TTCR_PERIOD 0x0fffffff /* Time Period */ -#define SPR_TTMR_PERIOD SPR_TTCR_PERIOD -#define SPR_TTMR_IP 0x10000000 /* Interrupt Pending */ -#define SPR_TTMR_IE 0x20000000 /* Interrupt Enable */ -#define SPR_TTMR_RT 0x40000000 /* Restart tick */ -#define SPR_TTMR_SR 0x80000000 /* Single run */ -#define SPR_TTMR_CR 0xc0000000 /* Continuous run */ -#define SPR_TTMR_M 0xc0000000 /* Tick mode */ - -/* - * l.nop constants - * - */ -#define NOP_NOP 0x0000 /* Normal nop instruction */ -#define NOP_EXIT 0x0001 /* End of simulation */ -#define NOP_REPORT 0x0002 /* Simple report */ -#define NOP_PRINTF 0x0003 /* Simprintf instruction */ -#define NOP_PUTC 0x0004 /* JPB: Simputc instruction */ -#define NOP_CNT_RESET 0x0005 /* Reset statistics counters */ -#define NOP_REPORT_FIRST 0x0400 /* Report with number */ -#define NOP_REPORT_LAST 0x03ff /* Report with number */ - -#endif /* SPR_DEFS__H */ Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/adv_jtag_bridge.c =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/adv_jtag_bridge.c (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/adv_jtag_bridge.c (nonexistent) @@ -1,532 +0,0 @@ -/* adv_jtag_bridge.c -- JTAG protocol bridge between GDB and Advanced debug module. - Copyright(C) 2001 Marko Mlinar, markom@opencores.org - Code for TCP/IP copied from gdb, by Chris Ziomkowski - Refactoring by Nathan Yawn, nyawn@opencores.org - - This file was part of the OpenRISC 1000 Architectural Simulator. - It is now also used to connect GDB to a running hardware OpenCores / OR1200 - advanced debug unit. - - 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. */ - -/* Establishes jtag proxy server and communicates with parallel - port directly. Requires root access. */ - -#include -#include // for exit(), atoi(), strtoul() -#include -#include -#include // for strstr() -#include - - -#include "adv_jtag_bridge.h" -#include "rsp-server.h" -#include "chain_commands.h" -#include "cable_common.h" -#include "or32_selftest.h" -#include "bsdl.h" -#include "errcodes.h" - -#define debug(...) //fprintf(stderr, __VA_ARGS__ ) - -// How many command-line IR length settings to create by default -#define IR_START_SETS 16 - -////////////////////////////////////////////////// -// Command line option flags / values - -/* Which device in the scan chain we want to target. - * 0 is the first device we find, which is nearest the data input of the cable. - */ -unsigned int target_dev_pos = 0; - -// Do test before setting up server? -unsigned char do_selftest = 0; - -// IR register length in TAP of -// Can override autoprobe, or set if IDCODE not supported -typedef struct { - int dev_index; - int ir_length; -} irset; - -#define START_IR_SETS 16 -int reallocs = 0; -int num_ir_sets = 0; -irset * cmd_line_ir_sizes = NULL; - -// DEBUG command for target device TAP -// May actually be USER1, for Xilinx devices using internal BSCAN modules -// Can override autoprobe, or set if unable to find in BSDL files -int cmd_line_cmd_debug = -1; // 0 is a valid debug command, so use -1 - -// TCP port to set up the server for GDB on -char *port; -char default_port[] = "9999"; - -// Force altera virtual jtag mode on(1) or off(-1) -int force_alt_vjtag = 0; - - -// Pointer to the command line arg used as the cable name -char * cable_name = NULL; - -//////////////////////////////////////////////////////// -// List of IDCODES of devices on the JTAG scan chain -// The array is dynamically allocated in chain_commands/jtag_enumerate_chain() - -uint32_t *idcodes = NULL; -int num_devices = 0; - - -const char *name_not_found = "(unknown)"; - -/////////////////////////////////////////////////////////// -// JTAG constants - -// Defines for Altera JTAG constants -#define ALTERA_MANUFACTURER_ID 0x6E - -// Defines for Xilinx JTAG constants -#define XILINX_MANUFACTURER_ID 0x49 - - -/////////////////////////////////////////////////// -// Prototypes for local / helper functions -int get_IR_size(int devidx); -uint32_t get_debug_cmd(int devidx); -void configure_chain(void); -void print_usage(char *func); -void parse_args(int argc, char **argv); -void get_ir_opts(char *optstr, int *idx, int *val); - - -////////////////////////////////////////////////////////////////////////////////////// -/*----------------------------------------------------------------------------------*/ -// Functions -///////////////////////////////////////////////////////////////////////////////////// - -// Resets JTAG, and sets up DEBUG scan chain -void configure_chain(void) -{ - int i; - unsigned int manuf_id; - uint32_t cmd; - const char *name; - int irlen; - int err = APP_ERR_NONE; - - err |= tap_reset(); - err |= jtag_enumerate_chain(&idcodes, &num_devices); - - if(err != APP_ERR_NONE) { - printf("Error %s enumerating JTAG chain, aborting.\n", get_err_string(err)); - exit(1); - } - - printf("\nDevices on JTAG chain:\n"); - printf("Index\tName\t\tID Code\t\tIR Length\n"); - printf("----------------------------------------------------------------\n"); - for(i = 0; i < num_devices; i++) - { - if(idcodes[i] != IDCODE_INVALID) { - name = bsdl_get_name(idcodes[i]); - irlen = bsdl_get_IR_size(idcodes[i]); - if(name == NULL) - name = name_not_found; - } else { - name = name_not_found; - irlen = -1; - } - printf("%d: \t%s \t0x%08X \t%d\n", i, name, idcodes[i], irlen); - } - printf("\n"); - -#ifdef __LEGACY__ -// The legacy debug interface cannot support multi-device chains. If there is more than -// one device on this chain, pull the cord. -if(num_devices > 1) { - fprintf(stderr, "\n*** ERROR: The legacy debug hardware cannot support JTAG chains with\n"); - fprintf(stderr, "*** more than one device. Reconnect the JTAG cable to ONLY the legacy\n"); - fprintf(stderr, "*** debug unit, or change your SoC to use the Advanced Debug Unit.\n"); - exit(0); -} -#endif - - - if(target_dev_pos >= num_devices) { - printf("ERROR: Requested target device (%i) beyond highest device index (%i).\n", target_dev_pos, num_devices-1); - exit(1); - } else { - printf("Target device %i, JTAG ID = 0x%08x\n", target_dev_pos, idcodes[target_dev_pos]); - } - - manuf_id = (idcodes[target_dev_pos] >> 1) & 0x7FF; - - // Use BSDL files to determine prefix bits, postfix bits, debug command, IR length - config_set_IR_size(get_IR_size(target_dev_pos)); - - // Set the IR prefix / postfix bits - int total = 0; - for(i = 0; i < num_devices; i++) { - if(i == target_dev_pos) { - config_set_IR_postfix_bits(total); - //debug("Postfix bits: %d\n", total); - total = 0; - continue; - } - - total += get_IR_size(i); - debug("Adding %i to total for devidx %i\n", get_IR_size(i), i); - } - config_set_IR_prefix_bits(total); - debug("Prefix bits: %d\n", total); - - - // Note that there's a little translation here, since device index 0 is actually closest to the cable data input - config_set_DR_prefix_bits(num_devices - target_dev_pos - 1); // number of devices between cable data out and target device - config_set_DR_postfix_bits(target_dev_pos); // number of devices between target device and cable data in - - // Set the DEBUG command for the IR of the target device. - // If this is a Xilinx device, use USER1 instead of DEBUG - // If we Altera Virtual JTAG mode, we don't care. - if((force_alt_vjtag == -1) || ((force_alt_vjtag == 0) && (manuf_id != ALTERA_MANUFACTURER_ID))) { - cmd = get_debug_cmd(target_dev_pos); - if(cmd == TAP_CMD_INVALID) { - printf("Unable to find DEBUG command, aborting.\n"); - exit(1); - } - config_set_debug_cmd(cmd); // This may have to be USER1 if this is a Xilinx device - } - - // Enable the kludge for Xilinx BSCAN, if necessary. - // Safe, but slower, for non-BSCAN TAPs. - if(manuf_id == XILINX_MANUFACTURER_ID) { - config_set_xilinx_bscan(1); - } - - // Set Altera Virtual JTAG mode on or off. If not forced, then enable - // if the target device has an Altera manufacturer IDCODE - if(force_alt_vjtag == 1) { - config_set_alt_vjtag(1); - } else if(force_alt_vjtag == -1) { - config_set_alt_vjtag(0); - } else { - if(manuf_id == ALTERA_MANUFACTURER_ID) { - config_set_alt_vjtag(1); - } else { - config_set_alt_vjtag(0); - } - } - - // Do a sanity test - cmd = bsdl_get_idcode_cmd(idcodes[target_dev_pos]); - if(cmd != TAP_CMD_INVALID) { - uint32_t id_read; - err |= jtag_get_idcode(cmd, &id_read); - - if(err != APP_ERR_NONE) { - printf("Error %s checking IDCODE, aborting.\n", get_err_string(err)); - exit(1); - } - - if(id_read == idcodes[target_dev_pos]) { - printf("IDCODE sanity test passed, chain OK!\n"); - } else { - printf("Warning: IDCODE sanity test failed. Read IDCODE 0x%08X, expected 0x%08X\n", id_read, idcodes[target_dev_pos]); - } - } - - if(err |= tap_enable_debug_module()) { // Select the debug unit in the TAP. - printf("Error %s enabling debug module, aborting.\n", get_err_string(err)); - exit(1); - } -} - - -void print_usage(char *func) -{ - printf("JTAG connection between GDB and the SoC debug interface.\n"); -#ifdef __LEGACY__ - printf("Compiled with support for the Legacy debug unit (debug_if).\n"); -#else - printf("Compiled with support for the Advanced Debug Interface (adv_dbg_if).\n"); -#endif - printf("Copyright (C) 2008 Nathan Yawn, nathan.yawn@opencores.org\n\n"); - printf("Usage: %s (options) [cable] (cable options)\n", func); - printf("Options:\n"); - printf("\t-g [port] : port number for GDB (default: 9999)\n"); - printf("\t-x [index] : Position of the target device in the scan chain\n"); - printf("\t-a [0 / 1] : force Altera virtual JTAG mode off (0) or on (1)\n"); - printf("\t-l [:] : Specify length of IR register for device\n"); - printf("\t , override autodetect (if any)\n"); - printf("\t-c [hex cmd] : Debug command for target TAP, override autodetect\n"); - printf("\t (ignored for Altera targets)\n"); - printf("\t-v [hex cmd] : VIR command for target TAP, override autodetect\n"); - printf("\t (Altera virtual JTAG targets only)\n"); - printf("\t-r [hex cmd] : VDR for target TAP, override autodetect\n"); - printf("\t (Altera virtual JTAG targets only)\n"); - printf("\t-b [dirname] : Add a directory to search for BSDL files\n"); - printf("\t-t : perform CPU / memory self-test before starting server\n"); - printf("\t-h : show help\n\n"); - cable_print_help(); -} - - -void parse_args(int argc, char **argv) -{ - int c; - int i; - int idx, val; - const char *valid_cable_args = NULL; - port = NULL; - force_alt_vjtag = 0; - cmd_line_cmd_debug = -1; - - /* Parse the global arguments (if-any) */ - while((c = getopt(argc, argv, "+g:x:a:l:c:v:r:b:th")) != -1) { - switch(c) { - case 'h': - print_usage(argv[0]); - exit(0); - break; - case 'g': - port = optarg; - break; - case 'x': - target_dev_pos = atoi(optarg); - break; - case 'l': - get_ir_opts(optarg, &idx, &val); // parse the option - if(num_ir_sets >= (IR_START_SETS< 0) && (retval != cmd_line_ir_sizes[i].ir_length)) - printf("Warning: overriding autoprobed IR length (%i) with command line value (%i) for device %i\n", retval, - cmd_line_ir_sizes[i].ir_length, devidx); - retval = cmd_line_ir_sizes[i].ir_length; - } - } - - if(retval < 0) { // Make sure we have a value - printf("ERROR! Unable to autoprobe IR length for device index %i; Must set IR size on command line. Aborting.\n", devidx); - exit(1); - } - - return retval; -} - - -uint32_t get_debug_cmd(int devidx) -{ - int retval = TAP_CMD_INVALID; - uint32_t manuf_id = (idcodes[devidx] >> 1) & 0x7FF; - - if(idcodes[devidx] != IDCODE_INVALID) { - if(manuf_id == XILINX_MANUFACTURER_ID) { - retval = bsdl_get_user1_cmd(idcodes[devidx]); - if(cmd_line_cmd_debug < 0) printf("Xilinx IDCODE, assuming internal BSCAN mode\n\t(using USER1 instead of DEBUG TAP command)\n"); - } else { - retval = bsdl_get_debug_cmd(idcodes[devidx]); - } - } - - if(cmd_line_cmd_debug >= 0) { - if(retval != TAP_CMD_INVALID) { - printf("Warning: overriding autoprobe debug command (0x%X) with command line value (0x%X)\n", retval, cmd_line_cmd_debug); - } else { - printf("Using command-line debug command 0x%X\n", cmd_line_cmd_debug); - } - retval = cmd_line_cmd_debug; - } - - if(retval == TAP_CMD_INVALID) { - printf("ERROR! Unable to find DEBUG command for device index %i, device ID 0x%0X\n", devidx, idcodes[devidx]); - } - - return retval; -} - - -// Extracts two values from an option string -// of the form ":", where both args -// are in base 10 -void get_ir_opts(char *optstr, int *idx, int *val) -{ - char *ptr; - - ptr = strstr(optstr, ":"); - if(ptr == NULL) { - printf("Error: badly formatted IR length option. Use format \':\', without spaces, where both args are in base 10\n"); - exit(1); - } - - *ptr = '\0'; - ptr++; // This now points to the second (value) arg string - - *idx = strtoul(optstr, NULL, 10); - *val = strtoul(ptr, NULL, 10); - // ***CHECK FOR SUCCESS -} - Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/Makefile =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/Makefile (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/Makefile (nonexistent) @@ -1,104 +0,0 @@ -prefix = /usr/local - -# Your build environment. selects libs, lib dirs, and include dirs -# Supported: linux, cygwin -BUILD_ENVIRONMENT=cygwin - -# Set this to 'true' if you want to build for the legacy debug unit ('debug_if' core), -# leave 'false' if you are building for the Advanced Debug Unit. -SUPPORT_LEGACY=false - -# Set this to 'true' to include support for cables which require libusb -# currently includes Altera USB-Blaster and Xilinx XPC DLC8 -SUPPORT_USB_CABLES=true - -# Set this to 'true' to support cables which require libFTDI -# SUPPORT_USB_CABLES must also be set to 'true' to support FTDI-based cables. -SUPPORT_FTDI_CABLES=true - - -# ---------------------------------------------------------------------------- -# Most people shouldn't have to change anything below this line - -ifeq ($(BUILD_ENVIRONMENT),linux) -# These are for native Linux. You may need to put the path to libusb into the LIBS variable -# with the -L command. -CFLAGS = -g -O2 -Wall -CC = gcc -LIBS = -lpthread -INCLUDEDIRS = -I/usr/local/include/libusb-1.0/ -I/usr/local/include/ - -else - -ifeq ($(BUILD_ENVIRONMENT),cygwin) -# These are for cygwin. It assumes libusb.a is in the current directory. -CFLAGS = -g -O2 -Wall -CC = gcc -LIBS = -L. -lioperm -lpthread -INCLUDEDIRS = -I/usr/local/include/ -endif - -endif - -ifeq ($(SUPPORT_LEGACY),true) -CFLAGS += -D__LEGACY__ -endif - - -PROGRAMS = adv_jtag_bridge - -HEADERS = adv_jtag_bridge.h chain_commands.h opencores_tap.h \ - altera_virtual_jtag.h rsp-server.h bsdl.h or32_selftest.c cable_common.h \ - cable_parallel.h cable_sim.h \ - bsdl_parse.h errcodes.h spr-defs.h except.h adv_dbg_commands.h dbg_api.h \ - legacy_dbg_commands.h - -SOURCES = adv_jtag_bridge.c rsp-server.c chain_commands.c cable_common.c bsdl.c \ - or32_selftest.c cable_parallel.c cable_sim.c \ - bsdl_parse.c errcodes.c adv_dbg_commands.c dbg_api.c legacy_dbg_commands.c - -OBJECTS = adv_jtag_bridge.o rsp-server.o chain_commands.o cable_common.o bsdl.o \ - or32_selftest.o cable_parallel.o cable_sim.o \ - bsdl_parse.o errcodes.o adv_dbg_commands.o dbg_api.o legacy_dbg_commands.o - - -ifeq ($(SUPPORT_USB_CABLES),true) -CFLAGS += -D__SUPPORT_USB_CABLES__ -HEADERS += cable_usbblaster.h cable_xpc_dlc9.h -SOURCES += cable_usbblaster.c cable_xpc_dlc9.c -OBJECTS += cable_usbblaster.o cable_xpc_dlc9.o - -ifeq ($(SUPPORT_FTDI_CABLES),true) -CFLAGS += -D__SUPPORT_FTDI_CABLES__ -LIBS += -lftdi -HEADERS += cable_ft2232.h -SOURCES += cable_ft2232.c -OBJECTS += cable_ft2232.o -endif - -# libusb must follow libftdi in the list of libraries -LIBS += -lusb -endif - - -all: $(PROGRAMS) - -default: $(PROGRAMS) - -.c.o: - $(CC) $(CFLAGS) -c $< - -adv_jtag_bridge: Makefile $(OBJECTS) $(HEADERS) - rm -f $@ - $(CC) -o $@ $(CFLAGS) $(OBJECTS) $(LIBS) $(INCLUDEDIRS) - - -install: all - [ -d $(prefix)/bin ] || mkdir -p $(prefix)/bin - for p in $(PROGRAMS) ; do \ - /bin/rm -f $(prefix)/bin/$$p; \ - /bin/cp -p $$p $(prefix)/bin/$$p; \ - done - -clean: Makefile - rm -f $(PROGRAMS) *.o *~ Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/except.h =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/except.h (revision 27) +++ ADS_RELEASE_1_2_0/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/Software/adv_jtag_bridge/or32_selftest.c =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/or32_selftest.c (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/or32_selftest.c (nonexistent) @@ -1,633 +0,0 @@ -/* or32_selftest.c -- JTAG protocol bridge between GDB and Advanced debug module. - Copyright(C) 2001 Marko Mlinar, markom@opencores.org - Code for TCP/IP copied from gdb, by Chris Ziomkowski - Refactoring and USB support by Nathan Yawn - - 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 exit() - -#include "or32_selftest.h" -#include "dbg_api.h" -#include "errcodes.h" - - -// Define your system parameters here -//#define HAS_CPU1 // stall cpu1 (as well as cpu0) -//#define HAS_MEMORY_CONTROLLER // init the SDRAM controller -#define MC_BASE_ADDR 0x93000000 -#define SDRAM_BASE 0x00000000 -//#define SDRAM_SIZE 0x04000000 -#define SDRAM_SIZE 0x400 -#define SRAM_BASE 0x00000000 -#define SRAM_SIZE 0x04000000 -#define FLASH_BASE_ADDR 0xf0000000 - -// Define the tests to be performed here -#define TEST_SRAM -//#define TEST_SDRAM -#define TEST_OR1K -//#define TEST_8051 // run a test on an 8051 on CPU1 - - -// Defines which depend on user-defined values, don't change these -#define FLASH_BAR_VAL FLASH_BASE_ADDR -#define SDRAM_BASE_ADDR SDRAM_BASE -#define SDRAM_BAR_VAL SDRAM_BASE_ADDR -#define SDRAM_AMR_VAL (~(SDRAM_SIZE -1)) - -#define CHECK(x) check(__FILE__, __LINE__, (x)) -void check(char *fn, int l, int i); - -void check(char *fn, int l, int i) { - if (i != 0) { - fprintf(stderr, "%s:%d: Jtag error %d occured; exiting.\n", fn, l, i); - exit(1); - } -} - - -//////////////////////////////////////////////////////////// -// Self-test functions -/////////////////////////////////////////////////////////// -int dbg_test() -{ - int success; - - success = stall_cpus(); - if(success == APP_ERR_NONE) { - -#ifdef HAS_MEMORY_CONTROLLER - // Init the memory contloller - init_mc(); - // Init the SRAM addresses in the MC - init_sram(); -#endif - - - -#ifdef TEST_SDRAM - success |= test_sdram(); - success |= test_sdram_2(); -#endif - -#ifdef TEST_SRAM - success |= test_sram(); -#endif - -#ifdef TEST_OR1K - success |= test_or1k_cpu0(); -#endif - -#if ((defined TEST_8051) && (defined HAS_CPU1)) - success |= test_8051_cpu1(); -#endif - - return success; - } - - return APP_ERR_TEST_FAIL; -} - - -int stall_cpus(void) -{ - unsigned char stalled; - -#ifdef HAS_CPU1 - printf("Stall 8051 - "); - CHECK(dbg_cpu1_write_reg(0, 0x01)); // stall 8051 -#endif - - printf("Stall or1k - "); - CHECK(dbg_cpu0_write_ctrl(0, 0x01)); // stall or1k - - -#ifdef HAS_CPU1 - CHECK(dbg_cpu1_read_ctrl(0, &stalled)); - if (!(stalled & 0x1)) { - printf("8051 is not stalled!\n"); // check stall 8051 - return APP_ERR_TEST_FAIL; - } -#endif - - CHECK(dbg_cpu0_read_ctrl(0, &stalled)); - if (!(stalled & 0x1)) { - printf("or1k is not stalled!\n"); // check stall or1k - return APP_ERR_TEST_FAIL; - } - - printf("CPU(s) stalled.\n"); - - return APP_ERR_NONE; -} - - -void init_mc(void) -{ - unsigned long insn; - - printf("Initialize Memory Controller (SDRAM)\n"); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_BAR_0, FLASH_BAR_VAL & 0xffff0000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_AMR_0, FLASH_AMR_VAL & 0xffff0000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_WTR_0, FLASH_WTR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RTR_0, FLASH_RTR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_OSR, 0x40000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_BAR_4, SDRAM_BAR_VAL & 0xffff0000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_AMR_4, SDRAM_AMR_VAL & 0xffff0000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_CCR_4, 0x00bf0005)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RATR, SDRAM_RATR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RCDR, SDRAM_RCDR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RCTR, SDRAM_RCTR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_REFCTR, SDRAM_REFCTR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_PTR, SDRAM_PTR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RRDR, SDRAM_RRDR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RIR, SDRAM_RIR_VAL)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_OSR, 0x5e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x5e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_OSR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_OSR, 0x7e000033)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x7e000033)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_CCR_4, 0xc0bf0005)); - - CHECK(dbg_wb_read32(MC_BASE_ADDR+MC_CCR_4, &insn)); - printf("expected %x, read %lx\n", 0xc0bf0005, insn); -} - - -void init_sram(void) -{ - // SRAM initialized to 0x40000000 - printf("Initialize Memory Controller (SRAM)\n"); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_BAR_1, SRAM_BASE & 0xffff0000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_AMR_1, ~(SRAM_SIZE - 1) & 0xffff0000)); - CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_CCR_1, 0xc020001f)); -} - - - -int test_sdram(void) -{ - unsigned long insn; - unsigned long i; - unsigned long data4_out[0x08]; - unsigned long data4_in[0x08]; - unsigned short data2_out[0x10]; - unsigned short data2_in[0x10]; - unsigned char data1_out[0x20]; - unsigned char data1_in[0x20]; - - printf("Start SDRAM WR\n"); - for (i=0x10; i<(SDRAM_SIZE+SDRAM_BASE); i=i<<1) { - //printf("0x%x: 0x%x\n", SDRAM_BASE+i, i); - CHECK(dbg_wb_write32(SDRAM_BASE+i, i)); - } - - printf("Start SDRAM RD\n"); - for (i=0x10; i<(SDRAM_SIZE+SDRAM_BASE); i=i<<1) { - CHECK(dbg_wb_read32(SDRAM_BASE+i, &insn)); - //printf("0x%x: 0x%x\n", SDRAM_BASE+i, insn); - if (i != insn) { - printf("SDRAM test FAIL\n"); - return APP_ERR_TEST_FAIL; - } - } - - printf("32-bit block write from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20); - for (i=0; i<(0x20/4); i++) { - data4_out[i] = data4_in[i] = ((4*i+3)<<24) | ((4*i+2)<<16) | ((4*i+1)<<8) | (4*i); - //printf("data_out = %0x\n", data4_out[i]); - } - - //printf("Press a key for write\n"); getchar(); - CHECK(dbg_wb_write_block32(SDRAM_BASE, &data4_out[0], 0x20)); - - // 32-bit block read is used for checking - printf("32-bit block read from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20); - CHECK(dbg_wb_read_block32(SDRAM_BASE, &data4_out[0], 0x20)); - for (i=0; i<(0x20/4); i++) { - //printf("0x%x: 0x%x\n", SDRAM_BASE+(i*4), data_out[i]); - if (data4_in[i] != data4_out[i]) { - printf("SDRAM data differs. Expected: 0x%0lx, read: 0x%0lx\n", data4_in[i], data4_out[i]); - return APP_ERR_TEST_FAIL; - } - } - - - printf("16-bit block write from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20); - for (i=0; i<(0x20/2); i++) { - data2_out[i] = data2_in[i] = ((4*i+1)<<8) | (4*i); - //printf("data_out = %0x\n", data_out[i]); - } - CHECK(dbg_wb_write_block16(SDRAM_BASE, &data2_out[0], 0x20)); - - // 16-bit block read is used for checking - printf("16-bit block read from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20); - CHECK(dbg_wb_read_block16(SDRAM_BASE, &data2_out[0], 0x20)); - for (i=0; i<(0x20/2); i++) { - //printf("0x%x: 0x%x\n", SDRAM_BASE+(i*4), data_out[i]); - if (data2_in[i] != data2_out[i]) { - printf("SDRAM data differs. Expected: 0x%0x, read: 0x%0x\n", data2_in[i], data2_out[i]); - return APP_ERR_TEST_FAIL; - } - } - - printf("8-bit block write from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20); - for (i=0; i<(0x20/1); i++) { - data1_out[i] = data1_in[i] = (4*i); - //printf("data_out = %0x\n", data_out[i]); - } - CHECK(dbg_wb_write_block8(SDRAM_BASE, &data1_out[0], 0x20)); - - // 32-bit block read is used for checking - printf("8-bit block read from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20); - CHECK(dbg_wb_read_block8(SDRAM_BASE, &data1_out[0], 0x20)); - for (i=0; i<(0x20/1); i++) { - //printf("0x%x: 0x%x\n", SDRAM_BASE+(i*4), data_out[i]); - if (data1_in[i] != data1_out[i]) { - printf("SDRAM data differs. Expected: 0x%0x, read: 0x%0x\n", data1_in[i], data1_out[i]); - return APP_ERR_TEST_FAIL; - } - } - - printf("SDRAM OK!\n"); - return APP_ERR_NONE; -} - - -int test_sdram_2(void) -{ - unsigned long insn; - - printf("SDRAM test 2: \n"); - CHECK(dbg_wb_write32(SDRAM_BASE+0x00, 0x12345678)); - CHECK(dbg_wb_read32(SDRAM_BASE+0x00, &insn)); - printf("expected %x, read %lx\n", 0x12345678, insn); - if (insn != 0x12345678) return APP_ERR_TEST_FAIL; - - CHECK(dbg_wb_write32(SDRAM_BASE+0x0000, 0x11112222)); - CHECK(dbg_wb_read32(SDRAM_BASE+0x0000, &insn)); - printf("expected %x, read %lx\n", 0x11112222, insn); - if (insn != 0x11112222) return APP_ERR_TEST_FAIL; - - CHECK(dbg_wb_write32(SDRAM_BASE+0x0004, 0x33334444)); - CHECK(dbg_wb_write32(SDRAM_BASE+0x0008, 0x55556666)); - CHECK(dbg_wb_write32(SDRAM_BASE+0x000c, 0x77778888)); - CHECK(dbg_wb_write32(SDRAM_BASE+0x0010, 0x9999aaaa)); - CHECK(dbg_wb_write32(SDRAM_BASE+0x0014, 0xbbbbcccc)); - CHECK(dbg_wb_write32(SDRAM_BASE+0x0018, 0xddddeeee)); - CHECK(dbg_wb_write32(SDRAM_BASE+0x001c, 0xffff0000)); - CHECK(dbg_wb_write32(SDRAM_BASE+0x0020, 0xdeadbeef)); - - CHECK(dbg_wb_read32(SDRAM_BASE+0x0000, &insn)); - printf("expected %x, read %lx\n", 0x11112222, insn); - CHECK(dbg_wb_read32(SDRAM_BASE+0x0004, &insn)); - printf("expected %x, read %lx\n", 0x33334444, insn); - CHECK(dbg_wb_read32(SDRAM_BASE+0x0008, &insn)); - printf("expected %x, read %lx\n", 0x55556666, insn); - CHECK(dbg_wb_read32(SDRAM_BASE+0x000c, &insn)); - printf("expected %x, read %lx\n", 0x77778888, insn); - CHECK(dbg_wb_read32(SDRAM_BASE+0x0010, &insn)); - printf("expected %x, read %lx\n", 0x9999aaaa, insn); - CHECK(dbg_wb_read32(SDRAM_BASE+0x0014, &insn)); - printf("expected %x, read %lx\n", 0xbbbbcccc, insn); - CHECK(dbg_wb_read32(SDRAM_BASE+0x0018, &insn)); - printf("expected %x, read %lx\n", 0xddddeeee, insn); - CHECK(dbg_wb_read32(SDRAM_BASE+0x001c, &insn)); - printf("expected %x, read %lx\n", 0xffff0000, insn); - CHECK(dbg_wb_read32(SDRAM_BASE+0x0020, &insn)); - printf("expected %x, read %lx\n", 0xdeadbeef, insn); - - if (insn != 0xdeadbeef) { - printf("SDRAM test 2 FAILED\n"); - return APP_ERR_TEST_FAIL; - } - else - printf("SDRAM test 2 passed\n"); - - return APP_ERR_NONE; -} - - -int test_sram(void) -{ - //unsigned long insn; - unsigned long ins; - unsigned long insn[9]; - insn[0] = 0x11112222; - insn[1] = 0x33334444; - insn[2] = 0x55556666; - insn[3] = 0x77778888; - insn[4] = 0x9999aaaa; - insn[5] = 0xbbbbcccc; - insn[6] = 0xddddeeee; - insn[7] = 0xffff0000; - insn[8] = 0xdedababa; - - printf("SRAM test: \n"); - //dbg_wb_write_block32(0x0, insn, 9); - - CHECK(dbg_wb_write32(SRAM_BASE+0x0000, 0x11112222)); - CHECK(dbg_wb_write32(SRAM_BASE+0x0004, 0x33334444)); - CHECK(dbg_wb_write32(SRAM_BASE+0x0008, 0x55556666)); - CHECK(dbg_wb_write32(SRAM_BASE+0x000c, 0x77778888)); - CHECK(dbg_wb_write32(SRAM_BASE+0x0010, 0x9999aaaa)); - CHECK(dbg_wb_write32(SRAM_BASE+0x0014, 0xbbbbcccc)); - CHECK(dbg_wb_write32(SRAM_BASE+0x0018, 0xddddeeee)); - CHECK(dbg_wb_write32(SRAM_BASE+0x001c, 0xffff0000)); - CHECK(dbg_wb_write32(SRAM_BASE+0x0020, 0xdedababa)); - - - CHECK(dbg_wb_read32(SRAM_BASE+0x0000, &ins)); - printf("expected %x, read %lx\n", 0x11112222, ins); - CHECK(dbg_wb_read32(SRAM_BASE+0x0004, &ins)); - printf("expected %x, read %lx\n", 0x33334444, ins); - CHECK(dbg_wb_read32(SRAM_BASE+0x0008, &ins)); - printf("expected %x, read %lx\n", 0x55556666, ins); - CHECK(dbg_wb_read32(SRAM_BASE+0x000c, &ins)); - printf("expected %x, read %lx\n", 0x77778888, ins); - CHECK(dbg_wb_read32(SRAM_BASE+0x0010, &ins)); - printf("expected %x, read %lx\n", 0x9999aaaa, ins); - CHECK(dbg_wb_read32(SRAM_BASE+0x0014, &ins)); - printf("expected %x, read %lx\n", 0xbbbbcccc, ins); - CHECK(dbg_wb_read32(SRAM_BASE+0x0018, &ins)); - printf("expected %x, read %lx\n", 0xddddeeee, ins); - CHECK(dbg_wb_read32(SRAM_BASE+0x001c, &ins)); - printf("expected %x, read %lx\n", 0xffff0000, ins); - CHECK(dbg_wb_read32(SRAM_BASE+0x0020, &ins)); - printf("expected %x, read %lx\n", 0xdedababa, ins); - - if (ins != 0xdedababa) { - printf("SRAM test failed!!!\n"); - return APP_ERR_TEST_FAIL; - } - else - printf("SRAM test passed\n"); - - return APP_ERR_NONE; -} - - - -int test_or1k_cpu0(void) -{ - unsigned long npc, ppc, r1, insn; - unsigned char stalled; - unsigned long result; - int i; - - printf("Testing CPU0 (or1k) - writing instructions\n"); - CHECK(dbg_wb_write32(SDRAM_BASE+0x00, 0xe0000005)); /* l.xor r0,r0,r0 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x04, 0x9c200000)); /* l.addi r1,r0,0x0 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x08, 0x18400000)); /* l.movhi r2,0x4000 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x0c, 0xa8420030)); /* l.ori r2,r2,0x30 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x10, 0x9c210001)); /* l.addi r1,r1,1 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x14, 0x9c210001)); /* l.addi r1,r1,1 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x18, 0xd4020800)); /* l.sw 0(r2),r1 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x1c, 0x9c210001)); /* l.addi r1,r1,1 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x20, 0x84620000)); /* l.lwz r3,0(r2) */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x24, 0x03fffffb)); /* l.j loop2 */ - CHECK(dbg_wb_write32(SDRAM_BASE+0x28, 0xe0211800)); /* l.add r1,r1,r3 */ - - printf("Setting up CPU0\n"); - CHECK(dbg_cpu0_write((0 << 11) + 17, 0x01)); /* Enable exceptions */ - CHECK(dbg_cpu0_write((6 << 11) + 20, 0x2000)); /* Trap causes stall */ - CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE)); /* Set PC */ - CHECK(dbg_cpu0_write((6 << 11) + 16, 1 << 22)); /* Set step bit */ - printf("Starting CPU0!\n"); - for(i = 0; i < 11; i++) { - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); /* 11x Unstall */ - //printf("Starting CPU, waiting for trap...\n"); - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - //printf("Got trap.\n"); - } - - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); /* Read NPC */ - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); /* Read PPC */ - CHECK(dbg_cpu0_read(0x401, &r1)); /* Read R1 */ - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000010, 0x00000028, 5); - result = npc + ppc + r1; - - CHECK(dbg_cpu0_write((6 << 11) + 16, 0)); // Reset step bit - CHECK(dbg_wb_read32(SDRAM_BASE + 0x28, &insn)); // Set trap insn in delay slot - CHECK(dbg_wb_write32(SDRAM_BASE + 0x28, 0x21000001)); - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); // Unstall - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); // Read NPC - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); // Read PPC - CHECK(dbg_cpu0_read(0x401, &r1)); // Read R1 - CHECK(dbg_wb_write32(SDRAM_BASE + 0x28, insn)); // Set back original insn - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000010, 0x00000028, 8); - result = npc + ppc + r1 + result; - - CHECK(dbg_wb_read32(SDRAM_BASE + 0x24, &insn)); // Set trap insn in place of branch insn - CHECK(dbg_wb_write32(SDRAM_BASE + 0x24, 0x21000001)); - CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x10)); // Set PC - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); // Unstall - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); // Read NPC - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); // Read PPC - CHECK(dbg_cpu0_read(0x401, &r1)); // Read R1 - CHECK(dbg_wb_write32(SDRAM_BASE + 0x24, insn)); // Set back original insn - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000028, 0x00000024, 11); - result = npc + ppc + r1 + result; - - CHECK(dbg_wb_read32(SDRAM_BASE + 0x20, &insn)); /* Set trap insn before branch insn */ - CHECK(dbg_wb_write32(SDRAM_BASE + 0x20, 0x21000001)); - CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x24)); /* Set PC */ - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); /* Unstall */ - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); /* Read NPC */ - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); /* Read PPC */ - CHECK(dbg_cpu0_read(0x401, &r1)); /* Read R1 */ - CHECK(dbg_wb_write32(SDRAM_BASE + 0x20, insn)); /* Set back original insn */ - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000024, 0x00000020, 24); - result = npc + ppc + r1 + result; - - CHECK(dbg_wb_read32(SDRAM_BASE + 0x1c, &insn)); /* Set trap insn behind lsu insn */ - CHECK(dbg_wb_write32(SDRAM_BASE + 0x1c, 0x21000001)); - CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x20)); /* Set PC */ - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); /* Unstall */ - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); /* Read NPC */ - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); /* Read PPC */ - CHECK(dbg_cpu0_read(0x401, &r1)); /* Read R1 */ - CHECK(dbg_wb_write32(SDRAM_BASE + 0x1c, insn)); /* Set back original insn */ - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000020, 0x0000001c, 49); - result = npc + ppc + r1 + result; - - CHECK(dbg_wb_read32(SDRAM_BASE + 0x20, &insn)); /* Set trap insn very near previous one */ - CHECK(dbg_wb_write32(SDRAM_BASE + 0x20, 0x21000001)); - CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x1c)); /* Set PC */ - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); /* Unstall */ - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); /* Read NPC */ - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); /* Read PPC */ - CHECK(dbg_cpu0_read(0x401, &r1)); /* Read R1 */ - CHECK(dbg_wb_write32(SDRAM_BASE + 0x20, insn)); /* Set back original insn */ - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000024, 0x00000020, 50); - result = npc + ppc + r1 + result; - - CHECK(dbg_wb_read32(SDRAM_BASE + 0x10, &insn)); /* Set trap insn to the start */ - CHECK(dbg_wb_write32(SDRAM_BASE + 0x10, 0x21000001)); - CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x20) /* Set PC */); - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); /* Unstall */ - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); /* Read NPC */ - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); /* Read PPC */ - CHECK(dbg_cpu0_read(0x401, &r1)); /* Read R1 */ - CHECK(dbg_wb_write32(SDRAM_BASE + 0x10, insn)); /* Set back original insn */ - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000014, 0x00000010, 99); - result = npc + ppc + r1 + result; - - CHECK(dbg_cpu0_write((6 << 11) + 16, 1 << 22)); /* Set step bit */ - for(i = 0; i < 5; i++) { - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); /* Unstall */ - //printf("Waiting for trap..."); - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - //printf("got trap.\n"); - } - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); /* Read NPC */ - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); /* Read PPC */ - CHECK(dbg_cpu0_read(0x401, &r1)); /* Read R1 */ - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000028, 0x00000024, 101); - result = npc + ppc + r1 + result; - - CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x24)); /* Set PC */ - for(i = 0; i < 2; i++) { - CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00)); /* Unstall */ - //printf("Waiting for trap...\n"); - do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1)); - //printf("Got trap.\n"); - } - CHECK(dbg_cpu0_read((0 << 11) + 16, &npc)); /* Read NPC */ - CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc)); /* Read PPC */ - CHECK(dbg_cpu0_read(0x401, &r1)); /* Read R1 */ - printf("Read npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1); - printf("Expected npc = %.8x ppc = %.8x r1 = %.8x\n", 0x00000010, 0x00000028, 201); - result = npc + ppc + r1 + result; - printf("result = %.8lx\n", result ^ 0xdeaddae1); - - if((result ^ 0xdeaddae1) != 0xdeaddead) - return APP_ERR_TEST_FAIL; - - return APP_ERR_NONE; -} - - -// This function does not currently return a useful value -/* -unsigned char test_8051_cpu1(void) -{ - int retval = 1; - unsigned long result = 0; - unsigned long npc[3], tmp; - - printf("Testing CPU1 (8051)\n"); - - // WRITE ACC - CHECK(dbg_cpu1_write(0x20e0, 0xa6)); - - // READ ACC - CHECK(dbg_cpu1_read(0x20e0, &tmp)); // select SFR space - printf("Read 8051 ACC = %0x (expected a6)\n", tmp); - result = result + tmp; - - // set exception to single step to jump over a loop - CHECK(dbg_cpu1_write(0x3010, 0xa0)); // set single step and global enable in EER - CHECK(dbg_cpu1_write(0x3011, 0x40)); // set evec = 24'h000040 - CHECK(dbg_cpu1_write(0x3012, 0x00)); // (already reset value) - CHECK(dbg_cpu1_write(0x3013, 0x00)); // (already reset value) - - // set HW breakpoint at PC == 0x41 - CHECK(dbg_cpu1_write(0x3020, 0x41)); // DVR0 = 24'h000041 - CHECK(dbg_cpu1_write(0x3023, 0x39)); // DCR0 = valid, == PC - CHECK(dbg_cpu1_write(0x3001, 0x04)); // DSR = watchpoint - - // flush 8051 instruction cache - CHECK(dbg_cpu1_write(0x209f, 0x00)); - - // Put some instructions in ram (8-bit mode on wishbone) - CHECK(dbg_wb_write8 (0x40, 0x04)); // inc a - CHECK(dbg_wb_write8 (0x41, 0x03)); // rr a; - CHECK(dbg_wb_write8 (0x42, 0x14)); // dec a; - CHECK(dbg_wb_write8 (0x43, 0xf5)); // mov 0e5h, a; - CHECK(dbg_wb_write8 (0x44, 0xe5)); - - // unstall just 8051 - CHECK(dbg_cpu1_write_reg(0, 0)); - - // read PC - CHECK(dbg_cpu1_read(0, &npc[0])); - CHECK(dbg_cpu1_read(1, &npc[1])); - CHECK(dbg_cpu1_read(2, &npc[2])); - printf("Read 8051 npc = %02x%02x%02x (expected 41)\n", npc[2], npc[1], npc[0]); - result = result + (npc[2] << 16) + (npc[1] << 8) + npc[0]; - - // READ ACC - CHECK(dbg_cpu1_read(0x20e0, &tmp)); // select SFR space - printf("Read 8051 ACC = %0x (expected a7)\n", tmp); - result = result + tmp; - - // set sigle step to stop execution - CHECK(dbg_cpu1_write(0x3001, 0x20)); // set single step and global enable in DSR - - // clear DRR - CHECK(dbg_cpu1_write(0x3000, 0x00)); // set single step and global enable in DRR - - // unstall just 8051 - CHECK(dbg_cpu1_write_reg(0, 0)); - - // read PC - CHECK(dbg_cpu1_read(0, &npc[0])); - CHECK(dbg_cpu1_read(1, &npc[1])); - CHECK(dbg_cpu1_read(2, &npc[2])); - printf("Read 8051 npc = %02x%02x%02x (expected 42)\n", npc[2], npc[1], npc[0]); - result = result + (npc[2] << 16) + (npc[1] << 8) + npc[0]; - - // READ ACC - CHECK(dbg_cpu1_read(0x20e0, &tmp)); // select SFR space - printf("Read 8051 ACC = %0x (expected d3)\n", tmp); - result = result + tmp; - - printf("report (%x)\n", result ^ 0x6c1 ^ 0xdeaddead); - - return APP_ERR_NONE; -} -*/ Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/adv_jtag_bridge.h =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/adv_jtag_bridge.h (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/adv_jtag_bridge.h (nonexistent) @@ -1,18 +0,0 @@ -#ifndef _ADV_JTAG_BRIDGE_H_ -#define _ADV_JTAG_BRIDGE_H_ - -//#ifndef Boolean -//#define Boolean int -//#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - - -#endif /* _ADV_JTAG_BRIDGE_H_ */ - Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/legacy_dbg_commands.c =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/legacy_dbg_commands.c (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/legacy_dbg_commands.c (nonexistent) @@ -1,393 +0,0 @@ -/* legacy_dbg_commands.c -- JTAG protocol bridge between GDB and OpenCores debug module. - Copyright(C) 2001 Marko Mlinar, markom@opencores.org - Code for TCP/IP copied from gdb, by Chris Ziomkowski - Adapted for the Advanced JTAG Bridge by Nathan Yawn, 2009 - - This file was part of the OpenRISC 1000 Architectural Simulator. - It is now also used to connect GDB to a running hardware OpenCores / OR1200 - debug unit. - - 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 // for htonl - -#include "chain_commands.h" -#include "cable_common.h" -#include "errcodes.h" -#include "legacy_dbg_commands.h" - -#define debug(...) //fprintf(stderr, __VA_ARGS__ ) - -#define LEGACY_CRC_POLY 0x04c11db7 -#define DBG_CRC_SIZE 32 - -/* Crc of current read or written data. */ -static int legacy_crc_r, legacy_crc_w = 0; - - -/*----------------------------------------------------------------------------------*/ -// Helper Functions - -/* Generates new crc, sending in new bit input_bit */ -static unsigned long legacy_crc_calc(unsigned long crc, int input_bit) { - unsigned long d = (input_bit&1) ? 0xfffffff : 0x0000000; - unsigned long crc_32 = ((crc >> 31)&1) ? 0xfffffff : 0x0000000; - crc <<= 1; - return crc ^ ((d ^ crc_32) & LEGACY_CRC_POLY); -} - -/* Writes bitstream. LS bit first if len < 0, MS bit first if len > 0. */ -static void legacy_write_stream(uint32_t stream, int len, int set_last_bit) { - int i; - uint32_t err; - uint32_t outdata = 0; - uint32_t datacpy = stream; - - // MSB needs to be transferred first, lower levels do LSB first. Reverse. - for(i = 0; i < len; i++) { - outdata |= stream & 0x1; - if(i < (len-1)) { - outdata <<= 1; - stream >>= 1; - } - } - - // Call the lower level, in case the driver has a high-speed transfer capability. - // *** This always transfers LS bit first. - err = jtag_write_stream(&outdata, len, set_last_bit); - - debug("legacy_write_stream, stream = 0x%X (0x%X), len = %d, set_last_bit = %d, ret = 0x%X\n", datacpy, outdata, len, set_last_bit, err); - - if(err != APP_ERR_NONE) { - fprintf(stderr, "Error in legacy_write_stream: %s\n", get_err_string(err)); - } - - // The low level call does not compute - // a CRC. Do so here. Remember, CRC is only calculated using data bits. - if(len < 0) { - fprintf(stderr, "Program error: legacy debug JTAG read with negative length!\n"); - /* - len = -len; - for(i = 0; i < len; i++) { - legacy_crc_w = legacy_crc_calc(legacy_crc_w, stream&1); - datacpy >>= 1; - } - */ - } - else { - for(i = len-1; i >= 0; i--) { - legacy_crc_w = legacy_crc_calc(legacy_crc_w, (datacpy>>i)&1); - } - } - -} - -/* Gets bitstream. LS bit first if len < 0, MS bit first if len > 0. */ -static uint32_t legacy_read_stream(unsigned long stream, int len, int set_last_bit) { - int i; - uint32_t data = 0, datacpy = 0; - uint32_t outdata = stream; - uint32_t indata; - uint32_t err; - - // *** WARNING: We assume that the input ("stream") will always be 0. - // If it's ever not, then we probably need to reverse the bit order (as - // is done in legacy_write_stream) before sending. - - // Call the lower level, in case the driver has a high-speed transfer capability. - // This always transfers LS bit first. - err = jtag_read_write_stream(&outdata, &indata, len, 0, set_last_bit); - - // Data comes from the legacy debug unit MSB first, so we need to - // reverse the bit order. - for(i = 0; i < len; i++) { - data |= indata & 0x1; - if(i < (len-1)) { - data <<= 1; - indata >>= 1; - } - } - - datacpy = data; - - debug("legacy_read_stream: write 0x%X, read 0x%X, len %i, set_last_bit = %d\n", outdata, data, len, set_last_bit); - - if(err != APP_ERR_NONE) { - fprintf(stderr, "Error in legacy_read_stream: %s\n", get_err_string(err)); - } - - // The low level call does not compute - // a CRC. Do so here. Remember, CRC is only calculated using data bits. - if(len < 0) { - fprintf(stderr, "Program error: legacy debug JTAG read with negative length!\n"); - /* - len = -len; - for(i = 0; i < len; i++) { - legacy_crc_w = legacy_crc_calc(legacy_crc_w, stream&1); - stream >>= 1; - legacy_crc_r = legacy_crc_calc(legacy_crc_r, datacpy&1); - datacpy >>= 1; - } - */ - } - else { - for(i = len-1; i >= 0; i--) { - legacy_crc_w = legacy_crc_calc(legacy_crc_w, (stream>>i)&1); - legacy_crc_r = legacy_crc_calc(legacy_crc_r, (datacpy>>i)&1); - } - } - - return data; -} - -////////////////////////////////////////////////////////////////////////// -// Actual operations on the legacy debug unit - -/* Sets scan chain. */ -int legacy_dbg_set_chain(int chain) { - int status, crc_generated, legacy_crc_read; - desired_chain = chain; - -try_again: - if (current_chain == chain) return APP_ERR_NONE; - current_chain = -1; - debug("\nset_chain %i\n", chain); - tap_set_shift_dr(); /* SHIFT_DR */ - - /* write data, EXIT1_DR */ - legacy_crc_w = 0xffffffff; - legacy_write_stream(((chain & 0xf) | (1<= 0 */ -int legacy_dbg_command(int type, unsigned long adr, int len) { - int status, crc_generated, legacy_crc_read; - -try_again: - legacy_dbg_set_chain(desired_chain); - debug("\ncomm %i\n", type); - - /***** WRITEx *****/ - tap_set_shift_dr(); /* SHIFT_DR */ - - /* write data, EXIT1_DR */ - legacy_crc_w = 0xffffffff; - legacy_write_stream(((DI_WRITE_CMD & 0xf) | (0< 0); - legacy_write_stream(len - 1, 16, 0); - legacy_write_stream(legacy_crc_w, DBG_CRC_SIZE, 0); - - legacy_crc_r = 0xffffffff; - status = legacy_read_stream(0, DC_STATUS_SIZE, 0); - crc_generated = legacy_crc_r; - legacy_crc_read = legacy_read_stream(0, DBG_CRC_SIZE, 1); - - /* CRCs must match, otherwise retry */ - if (legacy_crc_read != crc_generated) { - if (retry_do()) goto try_again; - else return APP_ERR_CRC; - } - /* we should read expected status value, otherwise retry */ - if (status != 0) { - if (retry_do()) goto try_again; - else return APP_ERR_BAD_PARAM; - } - - tap_exit_to_idle(); // Transition the TAP back to state IDLE - - /* reset retry counter */ - retry_ok(); - return APP_ERR_NONE; -} - -/* writes a ctrl reg */ -int legacy_dbg_ctrl(int reset, int stall) { - int status, crc_generated, legacy_crc_read; - -try_again: - legacy_dbg_set_chain(desired_chain); - debug("\nctrl\n"); - - /***** WRITEx *****/ - tap_set_shift_dr(); /* SHIFT_DR */ - - /* write data, EXIT1_DR */ - legacy_crc_w = 0xffffffff; - legacy_write_stream(((DI_WRITE_CTRL & 0xf) | (0< -#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/Software/adv_jtag_bridge/gdb-6.8-bz436037-reg-no-longer-active.patch =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/gdb-6.8-bz436037-reg-no-longer-active.patch (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/gdb-6.8-bz436037-reg-no-longer-active.patch (nonexistent) @@ -1,24 +0,0 @@ -diff -d -urpN src.0/gdb/valops.c src.1/gdb/valops.c ---- src.0/gdb/valops.c 2008-07-27 04:00:03.000000000 +0200 -+++ src.1/gdb/valops.c 2008-07-31 15:17:42.000000000 +0200 -@@ -813,10 +813,18 @@ value_assign (struct value *toval, struc - struct frame_info *frame; - int value_reg; - -- /* Figure out which frame this is in currently. */ -- frame = frame_find_by_id (VALUE_FRAME_ID (toval)); - value_reg = VALUE_REGNUM (toval); - -+ /* Figure out which frame this is in currently. */ -+ frame = frame_find_by_id (VALUE_FRAME_ID (toval)); -+ /* "set $reg+=1" should work on programs with no debug info, -+ but frame_find_by_id returns NULL here (RH bug 436037). -+ Use current frame, it represents CPU state in this case. -+ If frame_find_by_id is changed to do it internally -+ (it is contemplated there), remove this. */ -+ if (!frame) -+ frame = get_current_frame (); -+ /* Probably never happens. */ - if (!frame) - error (_("Value being assigned to is no longer active.")); - Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/legacy_dbg_commands.h =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/legacy_dbg_commands.h (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/legacy_dbg_commands.h (nonexistent) @@ -1,26 +0,0 @@ - -#ifndef _LEGACY_DBG_COMMANDS_H_ -#define _LEGACY_DBG_COMMANDS_H_ - -#define DC_SIZE 4 -#define DC_STATUS_SIZE 4 - -#define DC_WISHBONE 0 -#define DC_CPU0 1 -#define DC_CPU1 2 - -#define DI_GO 0 -#define DI_READ_CMD 1 -#define DI_WRITE_CMD 2 -#define DI_READ_CTRL 3 -#define DI_WRITE_CTRL 4 - - -// Interface to send commands to the legacy debug interface -int legacy_dbg_set_chain(int chain); -int legacy_dbg_command(int type, unsigned long adr, int len); -int legacy_dbg_ctrl(int reset, int stall); -int legacy_dbg_ctrl_read(int *reset, int *stall); -int legacy_dbg_go(unsigned char *data, unsigned short len, int read); - -#endif Index: ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/adv_dbg_commands.c =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/adv_dbg_commands.c (revision 27) +++ ADS_RELEASE_1_2_0/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/Software/adv_jtag_bridge/cable_ft2232.c =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_ft2232.c (revision 27) +++ ADS_RELEASE_1_2_0/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/Software/adv_jtag_bridge/chain_commands.h =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/chain_commands.h (revision 27) +++ ADS_RELEASE_1_2_0/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/Software/adv_jtag_bridge/rsp-server.c =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/rsp-server.c (revision 27) +++ ADS_RELEASE_1_2_0/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/Software/adv_jtag_bridge/README =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/README (revision 27) +++ ADS_RELEASE_1_2_0/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/Software/adv_jtag_bridge/adv_dbg_commands.h =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/adv_dbg_commands.h (revision 27) +++ ADS_RELEASE_1_2_0/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/Software/adv_jtag_bridge/cable_ft2232.h =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/cable_ft2232.h (revision 27) +++ ADS_RELEASE_1_2_0/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/Software/adv_jtag_bridge/rsp-server.h =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/rsp-server.h (revision 27) +++ ADS_RELEASE_1_2_0/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/Software/adv_jtag_bridge/bsdl.c =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/bsdl.c (revision 27) +++ ADS_RELEASE_1_2_0/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/Software/adv_jtag_bridge/dbg_api.c =================================================================== --- ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/dbg_api.c (revision 27) +++ ADS_RELEASE_1_2_0/Software/adv_jtag_bridge/dbg_api.c (nonexistent) @@ -1,669 +0,0 @@ -/* dbg_api.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 API functions which may be called from the GDB - interface server. These functions call the appropriate hardware- - specific functions for the advanced debug interface or the legacy - debug interface, depending on which is selected. - - 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 mutexes -#include // for ntohl() - -#include "adv_dbg_commands.h" -#include "legacy_dbg_commands.h" -#include "cable_common.h" -#include "errcodes.h" - -#define debug(...) //fprintf(stderr, __VA_ARGS__ ) - -#define DBG_HW_ADVANCED 1 -#define DBG_HW_LEGACY 2 -#ifdef __LEGACY__ -#warning Compiling for LEGACY debug hardware! -#define DEBUG_HARDWARE DBG_HW_LEGACY -#else -#warning Compiling for ADVANCED debug unit! -#define DEBUG_HARDWARE DBG_HW_ADVANCED -#endif - -pthread_mutex_t dbg_access_mutex = PTHREAD_MUTEX_INITIALIZER; - -/* read a word from wishbone */ -int dbg_wb_read32(unsigned long adr, unsigned long *data) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_read(4, 1, adr, (void *)data); // All WB reads / writes are bursts - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x6, adr, 4))) - err = legacy_dbg_go((unsigned char*)data, 4, 1); - *data = ntohl(*data); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - -/* write a word to wishbone */ -int dbg_wb_write32(unsigned long adr, unsigned long data) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)&data, 4, 1, adr); - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - data = ntohl(data); - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x2, adr, 4))) - err = legacy_dbg_go((unsigned char*)&data, 4, 0); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - -// write a word to wishbone -// Never actually called from the GDB interface -int dbg_wb_write16(unsigned long adr, uint16_t data) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)&data, 2, 1, adr); - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - data = ntohs(data); - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x1, adr, 2))) - err = legacy_dbg_go((unsigned char*)&data, 2, 0); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - -// write a word to wishbone -// Never actually called from the GDB interface -int dbg_wb_write8(unsigned long adr, uint8_t data) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)&data, 1, 1, adr); - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x0, adr, 1))) - err = legacy_dbg_go((unsigned char*)&data, 1, 0); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - -int dbg_wb_read_block32(unsigned long adr, unsigned long *data, int len) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(!len) - return APP_ERR_NONE; // GDB may issue a 0-length transaction to test if a feature is supported - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_read(4, len, adr, (void *)data); // 'len' is words. - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - int i; - int bytelen = len<<2; - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x6, adr, bytelen))) - if (APP_ERR_NONE == (err = legacy_dbg_go((unsigned char*)data, bytelen, 1))) // 'len' is words, call wants bytes - for (i = 0; i < len; i ++) data[i] = ntohl(data[i]); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - -// Never actually called from the GDB interface -int dbg_wb_read_block16(unsigned long adr, uint16_t *data, int len) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(!len) - return APP_ERR_NONE; // GDB may issue a 0-length transaction to test if a feature is supported - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_read(2, len, adr, (void *)data); // 'len' is 16-bit halfwords - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - int i; - int bytelen = len<<1; - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x5, adr, bytelen))) - if (APP_ERR_NONE == (err = legacy_dbg_go((unsigned char*)data, bytelen, 1))) // 'len' is halfwords, call wants bytes - for (i = 0; i < len; i ++) data[i] = ntohs(data[i]); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - -// Never actually called from the GDB interface -int dbg_wb_read_block8(unsigned long adr, uint8_t *data, int len) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(!len) - return APP_ERR_NONE; // GDB may issue a 0-length transaction to test if a feature is supported - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_read(1, len, adr, (void *)data); // *** is 'len' bits or words?? Call wants words... - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x4, adr, len))) - err = legacy_dbg_go((unsigned char*)data, len, 1); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - - -// write a block to wishbone -int dbg_wb_write_block32(unsigned long adr, unsigned long *data, int len) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(!len) - return APP_ERR_NONE; // GDB may issue a 0-length transaction to test if a feature is supported - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)data, 4, len, adr); // 'len' is words. - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - int i; - int bytelen = len << 2; - for (i = 0; i < len; i ++) data[i] = ntohl(data[i]); - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x2, adr, bytelen))) - err = legacy_dbg_go((unsigned char*)data, bytelen, 0); // 'len' is words, call wants bytes - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - -// write a block to wishbone -// Never actually called from the GDB interface -int dbg_wb_write_block16(unsigned long adr, uint16_t *data, int len) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(!len) - return APP_ERR_NONE; // GDB may issue a 0-length transaction to test if a feature is supported - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)data, 2, len, adr); // 'len' is (half)words - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - int i; - int bytelen = len<<1; - for (i = 0; i < len; i ++) data[i] = ntohs(data[i]); - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x1, adr, bytelen))) - err = legacy_dbg_go((unsigned char*)data, bytelen, 0); // 'len' is 16-bit halfwords, call wants bytes - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - -// write a block to wishbone -int dbg_wb_write_block8(unsigned long adr, uint8_t *data, int len) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(!len) - return APP_ERR_NONE; // GDB may issue a 0-length transaction to test if a feature is supported - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_WISHBONE))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)data, 1, len, adr); // 'len' is in words... - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_WISHBONE))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x0, adr, len))) - err = legacy_dbg_go((unsigned char*)data, len, 0); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - -/* read a register from cpu0. This is assumed to be an OR32 CPU, with 32-bit regs. */ -int dbg_cpu0_read(unsigned long adr, unsigned long *data) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU0))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_read(4, 1, adr, (void *) data); // All CPU register reads / writes are bursts - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_CPU0))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x6, adr, 4))) - if (APP_ERR_NONE == (err = legacy_dbg_go((unsigned char*)data, 4, 1))) - *data = ntohl(*data); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - debug("dbg_cpu_read(), addr 0x%X, data[0] = 0x%X\n", adr, data[0]); - return err; -} - -/* read multiple registers from cpu0. This is assumed to be an OR32 CPU, with 32-bit regs. */ -int dbg_cpu0_read_block(unsigned long adr, unsigned long *data, int count) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU0))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_read(4, count, adr, (void *) data); // All CPU register reads / writes are bursts - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - int i; - unsigned long readaddr = adr; - err = APP_ERR_NONE; - for(i = 0; i < count; i++) { - err |= dbg_cpu0_read(readaddr++, &data[i]); - } - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - debug("dbg_cpu_read_block(), addr 0x%X, count %i, data[0] = 0x%X\n", adr, count, data[0]); - return err; -} - -/* write a cpu register to cpu0. This is assumed to be an OR32 CPU, with 32-bit regs. */ -int dbg_cpu0_write(unsigned long adr, unsigned long data) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU0))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)&data, 4, 1, adr); - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - data = ntohl(data); - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_CPU0))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x2, adr, 4))) - err = legacy_dbg_go((unsigned char*)&data, 4, 0); - } - debug("cpu0_write, adr 0x%X, data 0x%X, ret %i\n", adr, data, err); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - -/* write multiple cpu registers to cpu0. This is assumed to be an OR32 CPU, with 32-bit regs. */ -int dbg_cpu0_write_block(unsigned long adr, unsigned long *data, int count) { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU0))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)data, 4, count, adr); - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - int i; - unsigned long writeaddr = adr; - err = APP_ERR_NONE; - for(i = 0; i < count; i++) { - err |= dbg_cpu0_write(writeaddr++, data[i]); - } - } - debug("cpu0_write_block, adr 0x%X, data[0] 0x%X, count %i, ret %i\n", adr, data[0], count, err); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - -/* write a debug unit cpu module register - * Since OR32 debug module has only 1 register, - * adr is ignored (for now) */ -int dbg_cpu0_write_ctrl(unsigned long adr, unsigned char data) { - int err = APP_ERR_NONE; - uint32_t dataword = data; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU0))) { - printf("Failed to set chain to 0x%X\n", DC_CPU0); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - if((err = adbg_ctrl_write(DBG_CPU0_REG_STATUS, &dataword, 2))) { - printf("Failed to write chain to 0x%X control reg 0x%X\n", DC_CPU0,DBG_CPU0_REG_STATUS ); // Only 2 bits: Reset, Stall - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_CPU0))) - err = legacy_dbg_ctrl(data & 2, data &1); - } - debug("cpu0_write_ctrl(): set reg to 0x%X\n", data); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - -/* read a register from cpu module of the debug unit. - * Currently, there is only 1 register, so we do not need to select it, adr is ignored - */ -int dbg_cpu0_read_ctrl(unsigned long adr, unsigned char *data) { - int err = APP_ERR_NONE; - uint32_t dataword; - pthread_mutex_lock(&dbg_access_mutex); - - // reset is bit 1, stall is bit 0 in *data - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU0))) { - printf("Failed to set chain to 0x%X\n", DC_CPU0); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - if ((err = adbg_ctrl_read(DBG_CPU0_REG_STATUS, &dataword, 2))) { - printf("Failed to read chain 0x%X control reg 0x%X\n", DC_CPU0, DBG_CPU0_REG_STATUS); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - *data = dataword; - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - int r, s; - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_CPU0))) - err = legacy_dbg_ctrl_read(&r, &s); - *data = (r << 1) | s; - debug("api cpu0 read ctrl: r = %i, s = %i, data = %i\n", r, s, *data); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - -// CPU1 Functions. Note that 2 CPUs are not currently supported by GDB, so these are never actually -// called from the GDB interface. They are included for completeness and future use. -// read a register from cpu1 -int dbg_cpu1_read(unsigned long adr, unsigned long *data) - { - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU1))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_read(4, 1, adr, (void *) data); // All CPU register reads / writes are bursts - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_CPU1))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x6, adr, 4))) - err = legacy_dbg_go((unsigned char*)data, 4, 1); - *data = ntohl(*data); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - -// write a cpu register -int dbg_cpu1_write(unsigned long adr, unsigned long data) -{ - int err; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU0))) - { - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - err = adbg_wb_burst_write((void *)&data, 4, 1, adr); - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - data = ntohl(data); - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_CPU1))) - if (APP_ERR_NONE == (err = legacy_dbg_command(0x2, adr, 4))) - err = legacy_dbg_go((unsigned char*)&data, 4, 0); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - -// write a debug unit cpu module register -int dbg_cpu1_write_ctrl(unsigned long adr, unsigned char data) { - int err; - uint32_t dataword = data; - pthread_mutex_lock(&dbg_access_mutex); - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU1))) { - printf("Failed to set chain to 0x%X\n", DC_CPU1); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - if((err = adbg_ctrl_write(DBG_CPU1_REG_STATUS, &dataword, 2))) { - printf("Failed to write chain to 0x%X control reg 0x%X\n", DC_CPU1,DBG_CPU0_REG_STATUS ); // Only 2 bits: Reset, Stall - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_CPU1))) - err = legacy_dbg_ctrl(data & 2, data & 1); - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - -// read a debug unit cpu module register -int dbg_cpu1_read_ctrl(unsigned long adr, unsigned char *data) { - int err; - uint32_t dataword; - pthread_mutex_lock(&dbg_access_mutex); - - // reset is bit 1, stall is bit 0 in *data - - if(DEBUG_HARDWARE == DBG_HW_ADVANCED) - { - if ((err = adbg_select_module(DC_CPU1))) { - printf("Failed to set chain to 0x%X\n", DC_CPU1); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - if ((err = adbg_ctrl_read(DBG_CPU1_REG_STATUS, &dataword, 2))) { - printf("Failed to read chain 0x%X control reg 0x%X\n", DC_CPU0, DBG_CPU1_REG_STATUS); - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; - } - *data = dataword; - } - else if(DEBUG_HARDWARE == DBG_HW_LEGACY) - { - int r, s; - if (APP_ERR_NONE == (err = legacy_dbg_set_chain(DC_CPU1))) - err = legacy_dbg_ctrl_read(&r, &s); - *data = (r << 1) | s; - } - cable_flush(); - pthread_mutex_unlock(&dbg_access_mutex); - return err; -} - - - Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_parallel.c =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_parallel.c (nonexistent) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_parallel.c (revision 26) @@ -0,0 +1,191 @@ +/* cable_parallel.c - Parallel cable drivers (XPC3 and XESS) for the Advanced JTAG Bridge + Copyright (C) 2001 Marko Mlinar, markom@opencores.org + Copyright (C) 2004 Gyrgy 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 // for inb(), outb() +#include +#include + +#include "cable_common.h" +#include "errcodes.h" + + +#define LPT_READ (base+1) +#define LPT_WRITE base + +// Common functions used by both cable types +static int cable_parallel_out(uint8_t value); +static int cable_parallel_inout(uint8_t value, uint8_t *inval); + + +static int base = 0x378; + + + +///////////////////////////////////////////////////////////////////////////////// +/*-------------------------------------[ Parallel port specific functions ]---*/ +/////////////////////////////////////////////////////////////////////////////// + +int cable_parallel_init() +{ + + //#ifndef WIN32 + if (ioperm(base, 3, 1)) { + fprintf(stderr, "Couldn't get the port at %x\n", base); + perror("Root privileges are required.\n"); + return APP_ERR_INIT_FAILED; + } + printf("Connected to parallel port at %x\n", base); + printf("Dropping root privileges.\n"); + setreuid(getuid(), getuid()); + //#endif + + return APP_ERR_NONE; +} + + +int cable_parallel_opt(int c, char *str) +{ + switch(c) { + case 'p': + if(!sscanf(str, "%x", &base)) { + fprintf(stderr, "p parameter must have a hex number as parameter\n"); + return APP_ERR_BAD_PARAM; + } + break; + default: + fprintf(stderr, "Unknown parameter '%c'\n", c); + return APP_ERR_BAD_PARAM; + } + return APP_ERR_NONE; +} + +/*-----------------------------------------[ Physical board wait function ]---*/ +void cable_parallel_phys_wait() +{ + usleep(10); +} + +/*----------------------------------------------[ xpc3 specific functions ]---*/ +int cable_xpc3_out(uint8_t value) +{ + uint8_t out = 0; + + /* First convert the bits in value byte to the ones that the cable wants */ + if(value & TCLK_BIT) + out |= 0x02; /* D1 pin 3 */ + if(value & TRST_BIT) + out |= 0x10; /* Not used */ + if(value & TDI_BIT) + out |= 0x01; /* D0 pin 2 */ + if(value & TMS_BIT) + out |= 0x04; /* D2 pin 4 */ + + return cable_parallel_out(out); +} + +int cable_xpc3_inout(uint8_t value, uint8_t *inval) +{ + uint8_t in; + int retval; + uint8_t out = 0; + + /* First convert the bits in value byte to the ones that the cable wants */ + if(value & TCLK_BIT) + out |= 0x02; /* D1 pin 3 */ + if(value & TRST_BIT) + out |= 0x10; /* Not used */ + if(value & TDI_BIT) + out |= 0x01; /* D0 pin 2 */ + if(value & TMS_BIT) + out |= 0x04; /* D2 pin 4 */ + + retval = cable_parallel_inout(out, &in); + + if(in & 0x10) /* S6 pin 13 */ + *inval = 1; + else + *inval = 0; + + return retval; +} + +/*----------------------------------------------[ xess specific functions ]---*/ +int cable_xess_out(uint8_t value) +{ + uint8_t out = 0; + + /* First convert the bits in value byte to the ones that the cable wants */ + if(value & TCLK_BIT) + out |= 0x04; /* D2 pin 4 */ + if(value & TRST_BIT) + out |= 0x08; /* D3 pin 5 */ + if(value & TDI_BIT) + out |= 0x10; /* D4 pin 6 */ + if(value & TMS_BIT) + out |= 0x20; /* D3 pin 5 */ + + return cable_parallel_out(out); +} + +uint8_t cable_xess_inout(uint8_t value, uint8_t *inval) +{ + uint8_t in; + int retval; + uint8_t out = 0; + + /* First convert the bits in value byte to the ones that the cable wants */ + if(value & TCLK_BIT) + out |= 0x04; /* D2 pin 4 */ + if(value & TRST_BIT) + out |= 0x08; /* D3 pin 5 */ + if(value & TDI_BIT) + out |= 0x10; /* D4 pin 6 */ + if(value & TMS_BIT) + out |= 0x20; /* D3 pin 5 */ + + retval = cable_parallel_inout(out, &in); + + if(in & 0x20) /* S5 pin 12*/ + *inval = 1; + else + *inval = 0; + + return retval; +} + + +/*----------------------------------------------[ common helper functions ]---*/ +// 'static' for internal access only + +static int cable_parallel_out(uint8_t value) +{ + outb(value, LPT_WRITE); + return APP_ERR_NONE; +} + +static int cable_parallel_inout(uint8_t value, uint8_t *inval) +{ + *inval = inb(LPT_READ); + outb(value, LPT_WRITE); + + return APP_ERR_NONE; +} Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_common.c =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_common.c (nonexistent) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_common.c (revision 26) @@ -0,0 +1,358 @@ +/* cable_common.c -- Interface to the low-level cable drivers + Copyright (C) 2001 Marko Mlinar, markom@opencores.org + Copyright (C) 2004 Gyrgy Jeney, nog@sdf.lonestar.org + Copyright (C) 2008 Nathan Yawn, nathan.yawn@opencores.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 "cable_common.h" +#include "cable_parallel.h" +#include "cable_sim.h" +#include "cable_usbblaster.h" +#include "cable_ft2232.h" +#include "cable_xpc_dlc9.h" +#include "errcodes.h" + +#define debug(...) //fprintf(stderr, __VA_ARGS__ ) + +static struct jtag_cable { + const char *name; + int (*inout_func)(uint8_t, uint8_t *); + int (*out_func)(uint8_t); + int (*init_func)(); + void (*wait_func)(); + int (*opt_func)(int, char *); + int (*bit_out_func)(uint8_t); + int (*bit_inout_func)(uint8_t, uint8_t *); + int (*stream_out_func)(uint32_t *, int, int); + int (*stream_inout_func)(uint32_t *, uint32_t *, int, int); + int (*flush_func)(); + const char *opts; + const char *help; +} jtag_cables[] = { + { "rtl_sim", + cable_rtl_sim_inout, + cable_rtl_sim_out, + cable_rtl_sim_init, + NULL, + cable_rtl_sim_opt, + cable_common_write_bit, + cable_common_read_write_bit, + cable_common_write_stream, + cable_common_read_stream, + NULL, + "d:", + "-d [directory] Directory in which gdb_in.dat/gdb_out.dat may be found\n" }, + { "vpi", + cable_vpi_inout, + cable_vpi_out, + cable_vpi_init, + cable_vpi_wait, + cable_vpi_opt, + cable_common_write_bit, + cable_common_read_write_bit, + cable_common_write_stream, + cable_common_read_stream, + NULL, + "s:p:", + "-p [port] Port number that the VPI module is listening on\n\t-s [server] Server that the VPI module is running on\n" }, + { "xpc3", + cable_xpc3_inout, + cable_xpc3_out, + cable_parallel_init, + cable_parallel_phys_wait, + cable_parallel_opt, + cable_common_write_bit, + cable_common_read_write_bit, + cable_common_write_stream, + cable_common_read_stream, + NULL, + "p:", + "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n" }, + { "xess", + cable_xess_inout, + cable_xess_out, + cable_parallel_init, + cable_parallel_phys_wait, + cable_parallel_opt, + cable_common_write_bit, + cable_common_read_write_bit, + cable_common_write_stream, + cable_common_read_stream, + NULL, + "p:", + "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n" }, +#ifdef __SUPPORT_USB_CABLES__ + { "usbblaster", + cable_usbblaster_inout, + cable_usbblaster_out, + cable_usbblaster_init, + NULL, + cable_usbblaster_opt, + cable_common_write_bit, + cable_common_read_write_bit, + cable_usbblaster_write_stream, + cable_usbblaster_read_stream, + NULL, + "", + "no options\n" }, + { "xpc_usb", + cable_xpcusb_inout, + cable_xpcusb_out, + cable_xpcusb_init, + NULL, + cable_xpcusb_opt, + cable_common_write_bit, + cable_xpcusb_read_write_bit, + cable_common_write_stream, + cable_common_read_stream, + NULL, + "", + "no options\n" }, +#ifdef __SUPPORT_FTDI_CABLES__ + { "ft2232", + NULL, + NULL, + cable_ftdi_init, + NULL, + cable_ftdi_opt, + cable_ftdi_write_bit, + cable_ftdi_read_write_bit, + cable_ftdi_write_stream, + cable_ftdi_read_stream, + cable_ftdi_flush, + "", + "no options\n" }, +#endif // __SUPPORT_FTDI_CABLES__ +#endif // __SUPPORT_USB_CABLES__ + { NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL } }; + +static struct jtag_cable *jtag_cable_in_use = NULL; /* The currently selected cable */ + + +///////////////////////////////////////////////////////////////////////////////////// +// Cable subsystem / init functions + + +/* Selects a cable for use */ +int cable_select(const char *cable) +{ + int i; + + for(i = 0; jtag_cables[i].name; i++) { + if(!strcmp(cable, jtag_cables[i].name)) { + jtag_cable_in_use = &jtag_cables[i]; + return APP_ERR_NONE; + } + } + + return APP_ERR_CABLE_INVALID; +} + +/* Calls the init function of the cable + */ +int cable_init() +{ + return jtag_cable_in_use->init_func(); +} + +/* Parses command-line options specific to the selected cable */ +int cable_parse_opt(int c, char *str) +{ + return jtag_cable_in_use->opt_func(c, str); +} + +const char *cable_get_args() +{ + if(jtag_cable_in_use != NULL) + return jtag_cable_in_use->opts; + else + return NULL; +} + +/* Prints a (short) useage message for each available cable */ +void cable_print_help() +{ + int i; + printf("Available cables: "); + + for(i = 0; jtag_cables[i].name; i++) { + if(i) + printf(", "); + printf("%s", jtag_cables[i].name); + } + + printf("\n\nOptions availible for the cables:\n"); + for(i = 0; jtag_cables[i].name; i++) { + if(!jtag_cables[i].help) + continue; + printf(" %s:\n %s", jtag_cables[i].name, jtag_cables[i].help); + } +} + + +///////////////////////////////////////////////////////////////////////////////// +// Cable API Functions + +int cable_write_stream(uint32_t *stream, int len_bits, int set_last_bit) { + return jtag_cable_in_use->stream_out_func(stream, len_bits, set_last_bit); +} + +int cable_read_write_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit) { + return jtag_cable_in_use->stream_inout_func(outstream, instream, len_bits, set_last_bit); +} + +int cable_write_bit(uint8_t packet) { + return jtag_cable_in_use->bit_out_func(packet); +} + +int cable_read_write_bit(uint8_t packet_out, uint8_t *bit_in) { + return jtag_cable_in_use->bit_inout_func(packet_out, bit_in); +} + +int cable_flush(void) { + if(jtag_cable_in_use->flush_func != NULL) + return jtag_cable_in_use->flush_func(); + return APP_ERR_NONE; +} + + +///////////////////////////////////////////////////////////////////////////////////// +// Common functions which may or may not be used by individual drivers + + +/* Note that these make no assumption as to the starting state of the clock, + * and they leave the clock HIGH. But, these need to interface with other routines (like + * the byte-shift mode in the USB-Blaster), which begin by assuming that a new + * data bit is available at TDO, which only happens after a FALLING edge of TCK. + * So, routines which assume new data is available will need to start by dropping + * the clock. + */ +int cable_common_write_bit(uint8_t packet) { + uint8_t data = TRST_BIT; // TRST is active low, don't clear unless /set/ in 'packet' + int err = APP_ERR_NONE; + + /* Write data, drop clock */ + if(packet & TDO) data |= TDI_BIT; + if(packet & TMS) data |= TMS_BIT; + if(packet & TRST) data &= ~TRST_BIT; + + err |= jtag_cable_in_use->out_func(data); + if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func(); + + /* raise clock, to do write */ + err |= jtag_cable_in_use->out_func(data | TCLK_BIT); + if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func(); + + return err; +} + +int cable_common_read_write_bit(uint8_t packet_out, uint8_t *bit_in) { + uint8_t data = TRST_BIT; // TRST is active low, don't clear unless /set/ in 'packet' + int err = APP_ERR_NONE; + + /* Write data, drop clock */ + if(packet_out & TDO) data |= TDI_BIT; + if(packet_out & TMS) data |= TMS_BIT; + if(packet_out & TRST) data &= ~TRST_BIT; + + err |= jtag_cable_in_use->out_func(data); // drop the clock to make data available, set the out data + if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func(); + err |= jtag_cable_in_use->inout_func((data | TCLK_BIT), bit_in); // read in bit, clock high for out bit. + if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func(); + + return err; +} + + +/* Writes bitstream via bit-bang. Can be used by any driver which does not have a high-speed transfer function. + * Transfers LSB to MSB of stream[0], then LSB to MSB of stream[1], etc. + */ +int cable_common_write_stream(uint32_t *stream, int len_bits, int set_last_bit) { + int i; + int index = 0; + int bits_this_index = 0; + uint8_t out; + int err = APP_ERR_NONE; + + debug("writeSrrm%d(", len_bits); + for(i = 0; i < len_bits - 1; i++) { + out = (stream[index] >> bits_this_index) & 1; + err |= cable_write_bit(out); + debug("%i", out); + bits_this_index++; + if(bits_this_index >= 32) { + index++; + bits_this_index = 0; + } + } + + out = (stream[index] >>(len_bits - 1)) & 0x1; + if(set_last_bit) out |= TMS; + err |= cable_write_bit(out); + debug("%i)\n", out); + return err; +} + +/* Gets bitstream via bit-bang. Can be used by any driver which does not have a high-speed transfer function. + * Transfers LSB to MSB of stream[0], then LSB to MSB of stream[1], etc. + */ +int cable_common_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit) { + int i; + int index = 0; + int bits_this_index = 0; + uint8_t inval, outval; + int err = APP_ERR_NONE; + + instream[0] = 0; + + debug("readStrm%d(", len_bits); + for(i = 0; i < (len_bits - 1); i++) { + outval = (outstream[index] >> bits_this_index) & 0x1; + err |= cable_read_write_bit(outval, &inval); + debug("%i", inval); + instream[index] |= (inval << bits_this_index); + bits_this_index++; + if(bits_this_index >= 32) { + index++; + bits_this_index = 0; + instream[index] = 0; // It's safe to do this, because there's always at least one more bit + } + } + + if (set_last_bit) + outval = ((outstream[index] >> (len_bits - 1)) & 1) | TMS; + else + outval = (outstream[index] >> (len_bits - 1)) & 1; + + err |= cable_read_write_bit(outval, &inval); + debug("%i", inval); + instream[index] |= (inval << bits_this_index); + + debug(") = 0x%lX\n", instream[0]); + + return err; +} + + + Index: ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_common.h =================================================================== --- ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_common.h (nonexistent) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/cable_common.h (revision 26) @@ -0,0 +1,44 @@ + +#ifndef _CABLE_COMMON_H_ +#define _CABLE_COMMON_H_ + +#include + +// Defines to use in the 'packet' args of cable_write_bit() +// and cable_read_write_bit(). Note that while TRST is +// active low for JTAG hardware, here the TRST bit +// should be set when you want the TRST wire active +// (JTAG TAP to be reset). +#define TRST (0x04) +#define TMS (0x02) +#define TDO (0x01) + +// These should only be used in the cable_* files. +#define TCLK_BIT (0x01) +#define TRST_BIT (0x02) +#define TDI_BIT (0x04) +#define TMS_BIT (0x08) +#define TDO_BIT (0x20) + +// Cable subsystem / init routines +int cable_select(const char *cable); +int cable_init(); +int cable_parse_opt(int c, char *str); +const char *cable_get_args(); +void cable_print_help(); + + +// Cable API routines +int cable_write_bit(uint8_t packet); +int cable_read_write_bit(uint8_t packet_out, uint8_t *bit_in); +int cable_write_stream(uint32_t *stream, int len_bits, int set_last_bit); +int cable_read_write_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit); +int cable_flush(void); + +// Common functions for lower-level drivers to use as desired +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); + +#endif 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 (nonexistent) +++ ADS_RELEASE_1_2_0/trunk/Software/adv_jtag_bridge/doc/adv_jtag_bridge.pdf (revision 26) @@ -0,0 +1,2502 @@ +%PDF-1.4 +%äüöß +2 0 obj +<> +stream +xmN0 E +8F"y a>[`Jch :03v^>؞ÛF-CzrK$z}(H\;.k *وJTs\i8 #zUZEjB?7f3݂lpB&.qܬ| +"h9} z3rX"Y(ר#Dž:.q3+^$j<尐;##8Ezod u.sz9i11y +BF0<;T} +endstream +endobj + +3 0 obj +290 +endobj + +5 0 obj +<> +stream +xVF ty3޶ +Pz J{#p<I;CqM5ҳd<]}q6Gr ]2\n}tܦ%4}O;`!~Y{n!.!p%Dހ(~"j0m +5 &5~̈́mY&0<*dd# q Y!!?:faE,XQ, W)d'PHk!2*&g J!N (ݖͤgHI4/XZ +SZфFUdZ""rd4{* +ͻCcoQ9m(Vhjs"C+9B=7hJ6%L㸃]ryBFBCJ˭P+yѽUBly*;BQ?R.LwkEl9g!D'x{92W +VE+]< +sƌ:y,,XDI5ȸT49}r +r A^ #+}oB>]X_z +endstream +endobj + +6 0 obj +1105 +endobj + +8 0 obj +<> +stream +xV +8F,%RoF^JK0 fNe3y#[%6w!AUOIiۯ d +-Э^o=AVCȶ#8 +*P2P^*ow>GA>[|<bnyrH`" f#h6F49\d{Ed GZd*+{F^8C|:~z0 ;_?5kҼ3YT0\ ǵ|gor:|~ƘXH2)N +)a\P^FJ(h"EeRR¸L)\P"DRˤ8)q2RBd)D:LD&3iƸl iFt iFiABbTr]QQ4W꽊W +s_A^פt~(}mh]m޳fbټ"O6tm~ +BCW&s}^F(W7&ޏ܏Ksbw̻h.Y,DO.ѡ0U./Nhyih9)8`.Jk[)I5kQ0х-CC`n?eFVU84%pՏʏ^zGEx\;g0BjpINf6@ ԭC +.%N +`?ՠFఇBY1T¹Oj-ll[F¦`: \ySδDtNg +-صp`iCZQ'گ2E5?*DwR^*dK*F +4+n1iy,9.%|Ti³QasSNL;YY+6˅ P +endstream +endobj + +9 0 obj +854 +endobj + +11 0 obj +<> +stream +xK6:K_"@X[z(zk%_3${yĔBX{)z?΋d}}XgRstw/ݿM|/;}gz~/S^:fK_n>dGe qr,@1Ξ( wF?%>ͪra^̔~|DF6"THS\ %qs' +JMe@{0/ +/^!1΋iS?OL(8yŌ O{n +_{IfZ_d`KR +~V?.uAV8yb,|szpS*AQWk6B]nkpgDEG?,i"FO޲)5{%nuĊ/[kѾ[N";.I¢)D({BF,F +O%Bsj٫ڲrpȃ.g܏̐2#6E潎N:JT aFGur2r 'mAݬ<9?Oy0W-U(cKpA<5 +O\]ĦkD0 j CWbu)1CZIOzVn!3ps=?s^gSkHWnٮgpfc1 +|G>Mv[ޭcbGǚ٦d'7yTc<=yJoϤ7ǶwQk=%XHwkݵP&N8CPhfbw,NZ&`Eo&ߒ`?wP9GQYyޔp(;\k6{/ufqI/ Qq{b\K%#Zk&v,+9H6u rSypŃsc6s\^ȉ)/daE+ja.""dJݤ1խ +Fs[">(eճk/N¨yz9Wwаl'Mmh(7tk~WNK kJ$iqk0qB!|FCS螊HKNAL iYvY $ܜ[aJ0c% bsϾpQ>2n r]&]52z뉚KCiMO{D-10BJlW,dø9VunPȟ32jÓPU#+q=@sD2 +endstream +endobj + +12 0 obj +1258 +endobj + +14 0 obj +<> +stream +x\I#ϯ0\k!.=|0]K3`ZReeKzӗ~E]v&{|?e?}旷-.tU}ܾ۫:no~.]>~W/{|L+wsU&h /`Y} +,o%lݖrk>ކ 7{Y}shWc/agjy8Vxtz})ct8vZC>^FǫSo`K.0Kxtpyg\ݥkzʫx\K\s~fL*kioQd|vKC7776g*jAWXUӁ (+Xx7`DT{E= I8m`d-[ojkF7*2R8Mn3(t0ծ7c4_PAh?n5.~G@*Fw ah|x`ligFNd7G.#Hwe;a Q $^k,'pcw:P6n~* Y=Fx`#^G-] + *@(t& +;LւD uINDCPY z.IA#f1z<2\k;==j*,~\ + m|}ϧa`u54$X,B+$I${u~~01%)p`Z8<Z@2@!m.gf9K76$2yMJx׷ڙZ >,uRe9ȃ_Y\AsHek&T6#gÈHsǥN3`7k`}{SIUax) (f5O 旋_©:'`3ꂿ@zzWK +5:t4p :&p;ay3CrC^Q͸kkEFʃ ̭/lAXɂLWO)+,MϋKl\ x!o[5̐"O)$8jV<Q{ċn$$ٵI-WhHf ˸*y~V-? +U'xsK#U5,\灟1r2钩9q)8R^qN*6@R #e)1! +^ I fjJrrX_6/hIα2JJ!A=K+C!)IVV+d!yJ I>XI;0U{SmNCD.gW*mgFŀ ZXT2Yj'#FaۢlA~9I3Wx,uI'~8 +sǺC´GtBsT ;NAS +>.a +endstream +endobj + +15 0 obj +3576 +endobj + +17 0 obj +<> +stream +x[ˎ߯:@w,mw/,2 E~ /} +KYij/b./>.uK?]_~׏qy^V\.]q9> vYnZ 7uf>,xΙYzƛyM7mﶎDn`,L[ L(M+]/qË8ȃm <" Ơ@+p -?`~ICė0rzzQpZ4C: E߿/-f1h0'ek^}2[k1)fhZs`-} gaQm`;!wɜ.,V~8 +J&%' +"K+;']yХ3+V@9T&.҈3}|]@ lkl;כ+>ZD|ɂ?$1JF(E˿~71c&Xq.,,54ND"_~T̞%N7eD1QRCv +?\ʈ:hXk(+y=ϼh K@x}H%K0٣ c8? +-N' Y&eGWɦ&ŧ\Fwh+U6q] +ReLӦUɆBl6yɞ,̌w/5TL&}srHQKO~Wѫ+f[6wqʞ9@AX|B&iUBT,iPs0s(rm`Dr [d"iUH$$e fzW_TؔL#$0zS):I`@ kC FuE ZJ2-#|GP-pFkw$Y6͎B6Ԧ>쟄 R*u?I(Ͼ:go='-vTlj#]@) `4 +JQu0^X.6z,Ɵg<:m_ͼ#89gM+ +L`a ]e(AyI06@jj˃#AscdZ"̨CF͡[Պ$Ӑ#"n6-E}GXfSz*%G.ʔAYʊCvwewX1_ gFg+Eۀˈ;kOW#Bu__w74M:RãB5+p}J56rJ%~2х'~s&@rWRqC*6EwnQ,{"34ϲ-z֢6 +J0К!<=' HnϒQyGTXnm5 ;A$Ve: +Y_mgҪiSb.t"~ %ȧΩ ],LaF+ܥ˅(ĔriL_ώ. YI;RJ\Fv`zI4dK_q00(7 aԦb\6{"V(n%/^䫶Q&:?iEiĭYWU[9 0Y@M]9Sݚdm . *}xyTkNVFI2R]*J~={^[SH|[}Ǟl Ƣ$m90oQv> վ 0i[H[*^ڻhNmn6=\gz7>pfnUZ*0CXqW1gw{mƓjy@-꽯;0fWE#>2Cy=YS8Kl)8Z(^û|Hj6tUvD"%~yWN{ژ+#+d~jcv Y6oG٨!yץUKm.Dp~rQҢy<L?a$)?4(նZUG}Ć_e +N8]]cL;Ss]w2p ;KQ{9u&|Tr*֒JQq] ldA@8p-헕7?=FH4G7?#&d7NJBHB;jYd"*h (:Rgef#으g;:dɭキ`oҩsy<|+rd|)o?[ٜd3S!:8"jAc鸋ġ`si[;i-6l)!~iB;$3<8dXWwsϑ)|?muܬv:MBsv\Y=~N_փ[͖I0*G涖r2"v#[r/lWL +endstream +endobj + +18 0 obj +3267 +endobj + +20 0 obj +<> +stream +xZI4Zs";@7/߱i2x4TWe*"!㗋\|y_~.?M_p^f.|6nfʩj2F+ W̓h]W>]+5)Z_gnj7.?4/Fom<9OF匟Cq]min]yiuaej^;>`3VvNrȻaQ< +مY|x~TY˛c,\uO2k6.o2lI=ݵu07 L`xXًn<⺩^,/, +1s`ALC5n?kՃ& +;9d8Nn/تڱىu0,#1i=¢da3508A:o2MS])" +aIAwZ/8N +8"ɊةU'lb†-֯Afe+"`nSN lʣ,"[P +gwO)X13YYUe@Q,WN$ 0@(9]hRY?2l e "]R!8OGwy wfJɌ +ń9S/0I̲vL3m^:S4z a(;i΂iP+- "/c)!8Q:ۄ1+2cCFpʖ1Ai: `?ZEĻ5ƙܤ|0Ucy iJ=x$23Tutݙ$B uIU\1%$1tnc3i$uy'FR6YY, +yFahjČ +@rgBE$Q# Q +,?[mf+N؊Z +BWT>"ӥLhG%t< +=oFInA_CEsn`AK0$0BfLF*>{`JZNxiK-_B& pErs&*3LT*,!IGF+xkTqnnKEox5iz.W!BMg=~W뫽ȵPjSΣlԿn6H^WH27+̊-=$X=k^{ć 33` R$Dts+`Uv */Gܪm[@uX> +stream +x[j+fg?`{Ƌ.&E wOR%u{|C0nTԩƼ^}1WN뼦~||,]f._3\|/Wq{uWnOw?/]ޖhp|͚5i ~x0oMWɀlLi~fr|=f+o&bhYc˸45]t6MЅr!k- p| o]pxAOqޠ{ΥGׄ•k2 +;NgÅ pr+7 +">}`B0rg V[H&6>Vu[Z{/x(ie[5azS^VM,fcBou!x/rݫi<&.}Oe0_vDdt 87F>n>^a>R#|\3.Us@8#'dF}5,5f08 -t$v2G8͊;{f.i4)ajV$)^dlm umNu|IQԷ]UYfoQyPƧ%3U-{X3aT{UUJMx} S&);{jUX>-B*-'Ӵ2/(l1q"} + Vdu$]0!RZT֊G=mt;Tep]Ok3# " ijn$%F)]]R2xOˁZCYl8Rz0:b).JYDP^qL +gļ4XgF4"B*JNt;Awrjc0"{IreU7SRɂxӰwhN*ݑvILWtHD+i<{$v$̽V7@fА iG/Gmg=\56Wu\-BqAUp.YG˚jhjK> M+qS=?xBvG +V +\n:8AkWPVFԑH>_.o͗iU4$)[uh:[u8# +d,RMcʧ +tp?`sl +0'Huiʼi{֬2Q}]SyMɰ9S[&uk1lZu'9bbFAT'`מ&(^ KhaH KѲy +zuOFpZ0rǯLlk0o +%TW==gہ ٶ;ŽV^Mäɑݟt# yfzq`lm7̛L`hnG68D΂L%6Fюkоl!ŽCϻDw X[;yN6zVݯ{I|=}v7׋vmwGӓ&P֦**VSF +VboVuRj.(xs6IGqZhN\m{Q5!LNL^q0oJ&oO zB$XuHkF8S pjlը|q +endstream +endobj + +24 0 obj +3242 +endobj + +26 0 obj +<> +stream +xZɊWlh9Z@Ko +>߼3#3"2#*uiRUV/^D~˻69^˯>'{qhsnm||k[<5cN9>ݔ ީSipmhɘx_&\u{P+&tQp՛V7ą_Q$5 9M*Lnozf-:qIX=d  +Dv3m<} +XEr}om=(Ba53 +L.I"K{U.\$?UnHAAN{ɕ')\W}R'7j:ωCuʡEjɁd%Mnh +Άl׃3YJ&f|ȤA)M TTn4Ћ uʙs+/@8!]*/w$JC`CgT)RLzƽøh=jOYHFr|NpHh(YÃ^%·9NgZ)Ǟf1A=V;2㯞Mc +(75sҦ)54H3\#9[":JO'Z(u[>*Tɓ9uҙWoHNHtE:/MBuiCȔ0.z +& +8Pуw 7 +dh +ڂ˟r(uu5 5о:s, xdqUL{Tb.Zyh ?yѭQ$3|[ԪpuVPV~gvpޕGr5҆ BL+ +Yܮ|^ŭ4AuPTx)a>ԪGpgX0룰&c"bPTҞmT&:Er3N c'DSaסE}MPб9=|RO7hA할f^.Զ=f7mXi?͝)CbN np!'.JAu`{ {}y{pS^![ib-]ijӍvx1GL)# +l)L!Ot< 3q)gn:/dKy$LMAMatߋj&^vz8SNi"fK%F2n/9b$pqlV|Gwl`z{<,'~#)KXfp`֥g1MU2|B-@8o r +)u +wL3hK&׺kn'Dj*i0`x-<2ɬna6TdǕ,0ֱc+Q,Nn5Tz汹- OHbX+pؠw6li6qR&~'\27\#pcSPqzPc7 +^,8~yCˍRM&bL SX,VbW5!0 + +3Ga"CD Xw E@lF"-1gl_k1CڙОa +ߜ^ük,ݰZڱ䑉9\dA)p:#HImshM|dnXSO 8|}/Rq+Z_ҵBڭߪ[ir"%HlSƭ:ͭǒϿ[ѝR7@O?5y<(![לrZ}JR߅*r(10hiut D\Stվ{j^?bN@oJ+*/+7 +endstream +endobj + +27 0 obj +2804 +endobj + +29 0 obj +<> +stream +xY=#7 WH}xvRr "@%K.]pow~Gͺt(wk:>~]fÍ~20+V^?~{~}j6{9N?-u}wr¢etyQD(MOwkpYpE~^h+^xF-Yt͘#$K|U=6ADxŪ g#X}ħ23P0G/PP-[P|`sn`]ߢEhDaD +D\ z<9*Mm9`";Vi KWt&v:vPL!jwN7= MVDPraF -`:jԊŞL̗−4RߍBIz@@\<թNGS&xu#^K܍J9ze6b3>簀EI%MpiG$>`Dzy dx;G $dG{;-c VsוC5RK +Hq@y&eW_Hym7i 9ȴ̚bKk @le6;*QG+XLa퓲IEp%)Ae\^V{ozmz/ݸZ5S׺]M(L@{G7U%g)JZ5se~*zP ZIT8iMa([ pVt8y!!׵W96`u -&ݡN/텏Lb@.Ym;-.uشdэë(3npoDd RaFj:rQԗsx_1sW;X9-sf44e@Ã&ȷUK!ŷK%T}.!J #kr E@q@kM}f?$y]UL6]qJ2S<1}z-קpk0$r'v*0<ωW,OUεK*7[b)VJIknq  +n٫&v>lU[h}FYߠf/z"Tje.V-av9,TLHShzJcVܫ࣢cD +wg-э0ZS}Β,6#; +Ġ.êvfJN5w-cZf` +m&Q%C?_nR;<_=2 (`jὉk ^`#ovP#;W{&~n3gC睞"Sd-3@J>[ +/*7n}ЙzR(PT-} *mfK4eaQ(+/ ߗH0xբ].i;Kq*ѵ< n"۱4!OYtZ*(kCڳ]ό}to$k>м^a 1o{ڼV> /`$'I ++o@- ږ5=i>Nf21 +endstream +endobj + +30 0 obj +1943 +endobj + +32 0 obj +<> +stream +xXˎ6 Wx] Hl0΢ Ew}]ˇd#vN0NlsxH\4C? co4?~!7׶诶y5ƚDL;6}{8-.>p==mF0p O?MJ&DSMi` 7\ھeZc `-qADOȧiM--hUOKy]Bp~yE tNY>!JH27@Ɛ=9#7|H}CVA;tc2kp&*:Ngc<2jE廇) sdž~D?:Nl[ϑfB@oPDYBhTןXab +b8c {+ 玸htEjjID8wa@ +kk6uj |^TKه&Fy>M|6ҙqrNfhbv[\e,o wRKcaTW[ֲآ;KO?R>c{Z#4Edc&MA&?jo`f{Jb]<<n[!Q\IT$RZ[T(nSS&X{x̛ݿQϥ֖z Oq > +stream +xUM@ W\+i><`{Co Joz(t/}ؙHޓF? +5Gcde]_Q?b65p_zi?N?k+88]{l +=`Եfj2"Kx5,$r@LDzF& |/!~0]_ze 3v\LzTw±R>e;(7NW%ߥJuMbx{(p͌"'aɐB>K8U{:( RvGCBIĢNCZBWcJ'٠5yxMKPqX9m "tӱ<0 al0bUעnm@P`*P(QQG'rBgdҀȁ)l]t%"HnVJHu ) KŭњJ`o^tD%Bnw/Ux%djXEӪ(QPބk(G5dv +ukw]}# 8b*z3D!=ء}~滈WzMJuw*ocۂz-Og/BhNTB +S>6MF) 22e y"8ʶ.>6M +endstream +endobj + +36 0 obj +706 +endobj + +38 0 obj +<> +stream +x[Ikݿ_u;c辶}АE.dȷOIUJA?^Iuj8u$<&॓ +?/up\ \vUo~}qRʿ^;McW/&|H? +?=Ia#|O~ +VGKUBau%kUJݍ000ge2RwD)vݤT>>]w9ěvxi񶇿p-\Eӫ387ݻ #EYu SUhu S# _ó:\+'p5|0&=AVGWR +LT)& S;UP*Z^9|,_aMh:OjqP0~dNhJ nљdvEO'|= +ad&xi7x-RZa!Vv!Yahm%1n676{)G4)£"^]7GV̅]L2"7Xfl)+"Sz`KGja.|Fr a38s_CvAyJNmMS3MN'U`~u59$_F\#-=ۖE_Un9.& LCU yJ*؍2}R۰ri&!T"2̢Cl9-FcUzPhG$ 0Ҁ[ڼ[tf%@R=clcH +8L ధUBJ S Ś4^TQOVZUY2Rݦ#kӜ#yyFZ/CJJ A%{3 N=ĘhH-n+]5L2njYJaċyP󘟷B9۱!wb_ʮ2ECl.|ћT +lۑZ8 +~r ҙKtù>JڸΨs懏H0Ntd#*fVm <$Ym#-IefHnǛ|ed8l+z3hV/[YXJ,kƓ"|]:or񡒺s%1*Ya]XJV`|@N̄JɱqKu# +G>Y[4_`΂^mӇ־&BF79ۻ9]bF'|F3YNI4MhQR?תէ㹃ƇCmtA3cFہ{D{wՌ\q^2j]%o kLju=j'b V9 +H&j},=b *k&nj?i`.ˆuU=5X< 'R)fN+K[͕Bߕ$%E#="hScHDfuu J;;'_ Q),;Q +GGUSYѴT5=^l}ZM!͏ݵ_DD'$ݲ^"u +o鹆|r6:lOynB-l1\n^3N[V1A/yeWnM] %,^/b@{Ƨg1nQiԦmSky@äS)Hr;fv4VA!9l`ؑURo +%*&;**T-/3eDx, Hv^ZI]ԛD [HC UAHQ? T_het qy]z}bGy'w.nehB> +f?c .=ZB HϝӀO7w/l⺈c.Q(KͥhUma Ƴ,#0kzNـ4,> +stream +x[ˎ߯:@;|J6`pKEv4E]&0Y_,T:UU_E]Tx;i^{|r1~v |s˛~,o>R~hqE?"Zu>=\MjZT6eVSeu[/nBH7b*BRwٺ(bAe&V-HqT狲gd$J&Q7i:io,&z-X"iJM@ 13||܂ +&T^9FE^ɨh׾ihF#PoNV4,VH#Je ^IO}Ҩw4|n7,.m֑:E~FzzLL u`z/-ы_EDdYٞ83mA_X uXQ dmԺӪ]B6Jw_R +p,LH)|+żjQ"/z0 װgueDD|7Re827'*n+ }1^=h +ϖUwu咳2 mVsLzU~2)"WRd_ +~_D)]>;dLֆ elxOauhGZFXH֘/*vLRQ*N[*=6,.5/wMYβ4{$KLBwA@xv(xܽVu P8 5=0r5'7zfX׊@9>Vq==s +$yZ  I݋ +!BmzKgGs-Z9jQZົkdٽS0fSEm1I[wSTL4b!q4dALa@hEv}95'r*b6Zfdi; ;n2m='Luf!Z2e8󭶷b,X {?kʷZuÀa{3H$tFvShT{C^4=)0Ps Q:m"㰆EFLCΩ<,9zHEqFO삥MZw[˩$2EnDY8 +nH!EMO`f8l\>okk}3^M3ÌΊ[ ǟav"5Z*uZWᜪUL %,bvp0ST,Z6%lfIggiWpKFqn5r#SE3ǻʺV^'W15Ix\*0KcTaOBđJ {BG0woM]gDp(;<~c^1zK*՗ϯUTmA\a,A:ZfqbL|YH:c &zJ$h$jϐ6*A [Lskyhg[AXR`݅+7~lFÃ&m1V FW(8>b +<_C3b3rE# ==52>.5bp{#S_lqQ1侎ꨧ50:׾rTl;Ϸ y*բ6ٵ?e>'b:kH[?8G&%iϜHQͣ+LrW9ɑL.Q&vm[ݾDBY @Ϙ\(j;ckS<{zL·:+diݙvΫDI'iLCyTTS/bR]mĜ=X/ +endstream +endobj + +42 0 obj +3126 +endobj + +44 0 obj +<> +stream +xZKo#7W9n@` 1 l6K֋f$g,#wUEz̳~`h?Ǚ>?KOoO!>Oh&dxeןv:aafG?䘐Vȟô7^<ǧӗp{nd0X( C7vqo}Mo-xo,lJsz܃UYM@[Q艖^YZ{,P:O2BVQ-=Ob?HBe+waI'Ңs/"owuʾRy )z@ǷWW=K9X 0#;(Wi ql]=s]/*DJ"+:(= bX`ktq9kz :5zgahg]t|g{C؃xV +m݌:hɲSDqӑ\ +g,MhJHC+ +ءCzKIdKQBtYb&-}L +sݳ J=4TƑj~-}LmX2voAQꮧ%%$RW5> +s QPK=z^tˣrd'kS<^mHc靶!I'QM491lhRu=z,T F"[ìePjC%- +{(x+t"еb mwn}M]KJEJ7enV}`& ԧNdh1m, [ +ا%AmZ̝E`s VW'|_ɗ髽M5ՖZM +&BjGa3H2TrInYIȭ +jHo!U^pn9*B5UM5sJD<U{(|u[10Q[Mb=U$G}֝eA rz8#"} + 'yYtsƤP$9Y1h+mO&XtL8'7@r +Cua)CrX\ѫGRu}clK׹?mndsħZš%qfR)!5f3l+v ɉo,h@`HV4mxo#ݪB0 0_)a^,/KYx@&SZp +QG(`:Բ _y:Aa \ǦR 3Hcqf,ݒ.S䎏ǹRH<*x8eRro_K-<}D%s#/xO`a]n(lַ]t'|ltuͥ5acA3k)6PQ +vj-}Zao38ܱpCPoCULi/Zj;3dQ3`..̨>dk3|x?xj)_W߅-(cbF;| +̀9\Tיў +r}Y;ج +b/Tŷ*s\;U윅;+U5]_׵To^mَ42p~]R!:A +<ѓ[iD쉳RӶ>L zn:h^gcVTI&6'CmҸM}ˋ8eѩ\gyy=;/q=b4ӟF)jn?TIPi"fpјn_h@2048+2mj8ҧdhvxWv4Cܗ, +endstream +endobj + +45 0 obj +2460 +endobj + +47 0 obj +<> +stream +xYK$7 ϯs;n( +f- r&C {ߏd.?f]jᇬO'ɣ.˿'u:+|5sӯ? ?_/o/_ ,xNN6+_5rpǏ羜⮳̠3F+rÔeh-*5 +TpjJo7}S_7^!O镄xXu^ +9b٪)tzL/^NF48@MS:!ot(a_wQ@x=\n5-IjHځ@kÜdٵE +B7s{ak$}gD!vX NX|@dq;`A0t0 K3=€{ +S#:FqL# I27/):V)g3,̈́P \Ҭ֕JSzR +\I\?HT#fC%39BNCrЂ>W[䱌E? +5٠&8k\:w#Ʊ?Ȃ)y/RD{p+qxK|yQ\]J)-ɹQ22#Ih`y$YR,t18*i2bA0؆M`ypP8߯eJ3 8ꐓkVvNN(Kre]Hb@DՂ ˾po_V +2IqڻDTGǤP[<".cG+A% qOkwCGa A["Oǥ?>IvQ[=Jek/;ݚY|<ȏ7gD6 +@i?E5T)+mG,,Q:銮 Q+r;ux"ٷ 颃 }e?BFRF&|PR5NNW޴RVFQ(ꤡ] CMn3T)qOLG +endstream +endobj + +48 0 obj +1622 +endobj + +52 0 obj +<> +stream +xSKkQf2ZSkS&jI.Кm0u2<`af" +B۸rƅ;ADpQut!W".jIOȝ9 BPuKk$ 4?rA"vu*GuC|jӀ!_Sx~|?BA>SC);ck1\KlNNښed=x~ ['LmvW*=RhɌZlj|[O]l[e\7j-Ss k8JCcDI2DE`C{.xhÀŧHUlhsLOTj`BQd)FOQY{3|ݐa +endstream +endobj + +53 0 obj +573 +endobj + +54 0 obj +<> +endobj + +55 0 obj +<> +stream +x]AO 96&f&=?´؁L)VM<@x7kQ13.qe0H|pPewMJ oKƹ16ү-78=8Y;{@ޯ~Mg j[8=O6=u.;"_mKd USU-4[? }Xd-ISSNc2K2{?'ŴSe}~my +endstream +endobj + +56 0 obj +<> +endobj + +57 0 obj +<> +stream +x}y|TEpUݭݝ;k&Kl$$ [D1 ICZ/ #eF}qE& Aq)Π2*8.tSuo޼{}?[V:uYݝ=!dAԆw"G;t+On0B+W̹- !$|y'xB ʻ)TOf*U&(>Yep}9&gR-p?;!1)9ūƥ? Jd^gDNCҺhл}`Vυ؏=v8=FQroIRDAY,j?ڎy~,=m ao|; TzqFx_̑+rZ^bTt;z _d52{HP;zdR3ԂzG,r3뇲P+r.DB aZt1 FB#JBh6jP (~;}h)90Zuq8/^oO] hGϠaݜ8d9wwN8O$I-i"{%Bn%ς$Qrq\.7%4n:{;nv%_+O ҄,BJ/`s1Cl//$^Km錄b m0L ?vpgj/VWD;\vr )XGhݏ0ܯ +h t9_J?AЭ>.JfbP n< ܚ'Yh.yp܍$_Sz y ]~w +*Bp]-|/ȋ0$g/ ;ȐI*sx\ŭ 0Oea' +d5 Ea|~א%2f<\?~hiK?rL_Oчp%H&.ҍ8$Y2L ncoѿP=w[܃ѳɣ(M8MDgA9z й.9$_;Cw?~Xp +tAV^} +{>eҿ'H5A\ zY:6 +#m}z+A/8 +owoAoہO0A`3l _=6s=!ĩ1a4UH-zfS'O**X?!/7';+HOKS)I w\l6l2$Q98nLjEO.BɧS&J-%u+cԦ-$l|} ʕ-"eI;cЖU%쬝CN],ֱ@hA B F؉)Es@ "J,KLda2CH#,C8bQEBi.*[N Xc^R DA*#p$T.@Tv_f,ImȀ}j4 <^5pp2^A+:Z&v10\3Ҽ.a_F #riJDuHXZqeJ:N'*>85'$ne 3Sua׌e\" ȱ@l,оt}ceXfkjm$ØFCi+6ӧ(|ESsTzjBnISGpl#6De3Q'3 KS3Sf$fΗǧW_mrn;2n^n;f]g &㈏uyJE}̸ +? +Y29e,y9EyJ (w>*34f8dzk+g1$} :69R*&N1x):i$ +*L$󆁡iƧL2JF٠8El|I qJavt]w}㗰=uvv||?F`aR-Ou/^jbcTOVa +Uh~:(ܒS5tq@l9;пLF: