AC_C_BIGENDIAN
AC_CHECK_FUNCS(strndup)
+AC_CHECK_FUNCS(strnlen)
+AC_CHECK_FUNCS(gettimeofday)
+AC_CHECK_FUNCS(usleep)
build_bitbang=no
is_cygwin=no
+is_mingw=no
+is_win32=no
AC_ARG_ENABLE(parport,
AS_HELP_STRING([--enable-parport], [Enable building the pc parallel port driver]),
[],
with_ftd2xx=search)
+case $host in
+ *-*-cygwin*)
+ is_cygwin=yes
+ is_win32=yes
+
+ AC_ARG_ENABLE(parport_giveio,
+ AS_HELP_STRING([--enable-parport_giveio], [Enable use of giveio for parport instead of ioperm]),
+ [parport_use_giveio=$enableval], [parport_use_giveio=no])
+
+ AC_DEFINE(IS_CYGWIN, 1, [1 if building for Cygwin.])
+ AC_DEFINE(IS_WIN32, 1, [1 if building for Win32.])
+ ;;
+ *-*-mingw*)
+ is_mingw=yes
+ is_win32=yes
+
+ parport_use_giveio=yes
+
+ AC_DEFINE(IS_MINGW, 1, [1 if building for MinGW.])
+ AC_DEFINE(IS_WIN32, 1, [1 if building for Win32.])
+ ;;
+ *)
+ parport_use_giveio=no
+ AC_DEFINE(IS_CYGWIN, 0, [0 if not building for Cygwin.])
+ AC_DEFINE(IS_WIN32, 0, [0 if not building for Win32.])
+ ;;
+esac
+
if test $build_parport = yes; then
build_bitbang=yes
AC_DEFINE(BUILD_PARPORT, 1, [1 if you want parport.])
AC_DEFINE(PARPORT_USE_PPDEV, 0, [0 if you don't want parport to use ppdev.])
fi
+if test $parport_use_giveio = yes; then
+ AC_DEFINE(PARPORT_USE_GIVEIO, 1, [1 if you want parport to use giveio.])
+else
+ AC_DEFINE(PARPORT_USE_GIVEIO, 0, [0 if you don't want parport to use giveio.])
+fi
+
if test $build_bitbang = yes; then
AC_DEFINE(BUILD_BITBANG, 1, [1 if you want a bitbang interface.])
else
AC_DEFINE(BUILD_AMTJTAGACCEL, 0, [0 if you don't want the Amontec JTAG-Accelerator driver.])
fi
-case $host in
- *-*-cygwin*)
- is_cygwin=yes
- AC_DEFINE(IS_CYGWIN, 1, [1 if building for Cygwin.])
- ;;
- *)
- AC_DEFINE(IS_CYGWIN, 0, [0 if not building for Cygwin.])
- ;;
-esac
-
AM_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE(openocd, 0.1)
AM_CONDITIONAL(PARPORT, test $build_parport = yes)
+AM_CONDITIONAL(GIVEIO, test $parport_use_giveio = yes)
AM_CONDITIONAL(EP93XX, test $build_ep93xx = yes)
AM_CONDITIONAL(BITBANG, test $build_bitbang = yes)
AM_CONDITIONAL(FTDI2232, test $build_ftdi2232 = yes)
AM_CONDITIONAL(FTD2XX, test $build_ftd2xx = yes)
AM_CONDITIONAL(AMTJTAGACCEL, test $build_amtjtagaccel = yes)
AM_CONDITIONAL(IS_CYGWIN, test $is_cygwin = yes)
+AM_CONDITIONAL(IS_MINGW, test $is_mingw = yes)
+AM_CONDITIONAL(IS_WIN32, test $is_win32 = yes)
AM_CONDITIONAL(FTD2XXDIR, test $with_ftd2xx != search)
AC_LANG_C
openocd_LDFLAGS = $(all_libraries)
SUBDIRS = helper jtag xsvf target server flash
+if IS_MINGW
+MINGWLDADD = -lwsock32
+else
+MINGWLDADD =
+endif
+
if FTDI2232
FTDI2232LIB = -lftdi
else
FTDI2232LIB =
endif
-if IS_CYGWIN
+if IS_WIN32
if FTD2XXDIR
FTD2XXLDADD = @WITH_FTD2XX@/FTD2XX.lib
else
$(top_builddir)/src/helper/libhelper.a \
$(top_builddir)/src/server/libserver.a $(top_builddir)/src/helper/libhelper.a \
$(top_builddir)/src/flash/libflash.a $(top_builddir)/src/target/libtarget.a \
- $(FTDI2232LIB) $(FTD2XXLIB)
+ $(FTDI2232LIB) $(FTD2XXLIB) $(MINGWLDADD)
* Lock regions (sectors) are 32 or 64 pages
*
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "replacements.h"
#include "at91sam7.h"
u32 at91sam7_get_flash_status(flash_bank_t *bank);
void at91sam7_set_flash_mode(flash_bank_t *bank,int mode);
u8 at91sam7_wait_status_busy(flash_bank_t *bank, int timeout);
-int at91sam7_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
flash_driver_t at91sam7_flash =
{
0x80000, /* 512K */
};
+int at91sam7_register_commands(struct command_context_s *cmd_ctx)
+{
+ command_t *at91sam7_cmd = register_command(cmd_ctx, NULL, "at91sam7", NULL, COMMAND_ANY, NULL);
+ register_command(cmd_ctx, at91sam7_cmd, "gpnvm", at91sam7_handle_gpnvm_command, COMMAND_EXEC,
+ "at91sam7 gpnvm <num> <bit> set|clear, set or clear at91sam7 gpnvm bit");
+
+ return ERROR_OK;
+}
+
u32 at91sam7_get_flash_status(flash_bank_t *bank)
{
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
return fsr;
}
+/** Read clock configuration and set at91sam7_info->usec_clocks*/
+void at91sam7_read_clock_info(flash_bank_t *bank)
+{
+ at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
+ target_t *target = at91sam7_info->target;
+ unsigned long mckr, mcfr, pllr, tmp, status, mainfreq;
+ unsigned int css, pres, mul, div;
+
+ /* Read main clock freqency register */
+ target->type->read_memory(target, CKGR_MCFR, 4, 1, (u8 *)&mcfr);
+ /* Read master clock register */
+ target->type->read_memory(target, PMC_MCKR, 4, 1, (u8 *)&mckr);
+ /* Read Clock Generator PLL Register */
+ target->type->read_memory(target, CKGR_PLLR, 4, 1, (u8 *)&pllr);
+
+ pres = (mckr>>2)&0x7;
+ mul = (pllr>>16)&0x7FF;
+ div = pllr&0xFF;
+
+ at91sam7_info->mck_valid = 0;
+ switch (mckr & PMC_MCKR_CSS) {
+ case 0: /* Slow Clock */
+ at91sam7_info->mck_valid = 1;
+ tmp = RC_FREQ;
+ break;
+ case 1: /* Main Clock */
+ if (mcfr & CKGR_MCFR_MAINRDY)
+ {
+ at91sam7_info->mck_valid = 1;
+ mainfreq = RC_FREQ / 16ul * (mcfr & 0xffff);
+ tmp = mainfreq;
+ }
+ break;
+
+ case 2: /* Reserved */
+ break;
+ case 3: /* PLL Clock */
+ if (mcfr & CKGR_MCFR_MAINRDY)
+ {
+ target->type->read_memory(target, CKGR_PLLR, 4, 1,
+ (u8 *)&pllr);
+ if (!(pllr & CKGR_PLLR_DIV))
+ break; /* 0 Hz */
+ at91sam7_info->mck_valid = 1;
+ mainfreq = RC_FREQ / 16ul * (mcfr & 0xffff);
+ /* Integer arithmetic should have sufficient precision
+ as long as PLL is properly configured. */
+ tmp = mainfreq / (pllr & CKGR_PLLR_DIV) *
+ (((pllr & CKGR_PLLR_MUL) >> 16) + 1);
+ }
+ break;
+ }
+
+ /* Prescaler adjust */
+ if (((mckr & PMC_MCKR_PRES) >> 2) == 7)
+ at91sam7_info->mck_valid = 0;
+ else
+ at91sam7_info->mck_freq = tmp >> ((mckr & PMC_MCKR_PRES) >> 2);
+
+ /* Forget old flash timing */
+ at91sam7_set_flash_mode(bank,0);
+}
+
/* Setup the timimg registers for nvbits or normal flash */
void at91sam7_set_flash_mode(flash_bank_t *bank,int mode)
{
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
target_t *target = at91sam7_info->target;
- if (mode != at91sam7_info->flashmode) {
- /* mainf contains the number of main clocks in approx 500uS */
+ if (mode && (mode != at91sam7_info->flashmode)) {
+ /* Always round up (ceil) */
if (mode==1)
/* main clocks in 1uS */
- fmcn = (at91sam7_info->mainf>>9)+1;
- else
+ fmcn = (at91sam7_info->mck_freq/1000000ul)+1;
+ else if (mode==2)
/* main clocks in 1.5uS */
- fmcn = (at91sam7_info->mainf>>9)+(at91sam7_info->mainf>>10)+1;
+ fmcn = (at91sam7_info->mck_freq/666666ul)+1;
+
+ /* Only allow fmcn=0 if clock period is > 30 us. */
+ if (at91sam7_info->mck_freq <= 33333)
+ fmcn = 0;
+
DEBUG("fmcn: %i", fmcn);
fmr = fmcn<<16;
target->type->write_memory(target, MC_FSR, 4, 1, (u8 *)&fmr);
- at91sam7_info->flashmode = mode;
}
+ at91sam7_info->flashmode = mode;
}
u8 at91sam7_wait_status_busy(flash_bank_t *bank, int timeout)
return status;
}
+/* Send one command to the AT91SAM flash controller */
int at91sam7_flash_command(struct flash_bank_s *bank,u8 cmd,u16 pagen)
{
u32 fcr;
at91sam7_info->cidr_eproc = (cidr>>5)&0x0007;
at91sam7_info->cidr_version = cidr&0x001F;
bank->size = NVPSIZ[at91sam7_info->cidr_nvpsiz];
+ at91sam7_info->target_name = "Unknown";
DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x, alt_id: 0x%4.4x, alt_addr: 0x%4.4x", at91sam7_info->cidr_nvptyp, at91sam7_info->cidr_arch );
- /* Read main clock freqency register */
- target->type->read_memory(target, CKGR_MCFR, 4, 1, (u8 *)&mcfr);
- if (mcfr&0x10000)
- {
- at91sam7_info->mainrdy = 1;
- at91sam7_info->mainf = mcfr&0xFFFF;
- at91sam7_info->usec_clocks = mcfr>>9;
- }
- else
- {
- at91sam7_info->mainrdy = 0;
- at91sam7_info->mainf = 0;
- at91sam7_info->usec_clocks = 0;
- }
+ /* Read main and master clock freqency register */
+ at91sam7_read_clock_info(bank);
status = at91sam7_get_flash_status(bank);
at91sam7_info->lockbits = status>>16;
bank->bus_width = 4;
if (bank->size==0x40000) /* AT91SAM7S256 */
{
+ at91sam7_info->target_name = "AT91SAM7S256";
at91sam7_info->num_lockbits = 16;
at91sam7_info->pagesize = 256;
at91sam7_info->pages_in_lockregion = 64;
}
if (bank->size==0x20000) /* AT91SAM7S128 */
{
+ at91sam7_info->target_name = "AT91SAM7S128";
at91sam7_info->num_lockbits = 8;
at91sam7_info->pagesize = 256;
at91sam7_info->pages_in_lockregion = 64;
}
if (bank->size==0x10000) /* AT91SAM7S64 */
{
+ at91sam7_info->target_name = "AT91SAM7S64";
at91sam7_info->num_lockbits = 16;
at91sam7_info->pagesize = 128;
at91sam7_info->pages_in_lockregion = 32;
}
if (bank->size==0x08000) /* AT91SAM7S321/32 */
{
+ at91sam7_info->target_name = "AT91SAM7S321/32";
at91sam7_info->num_lockbits = 8;
at91sam7_info->pagesize = 128;
at91sam7_info->pages_in_lockregion = 32;
bank->bus_width = 4;
if (bank->size==0x40000) /* AT91SAM7XC256 */
{
+ at91sam7_info->target_name = "AT91SAM7XC256";
at91sam7_info->num_lockbits = 16;
at91sam7_info->pagesize = 256;
at91sam7_info->pages_in_lockregion = 64;
}
if (bank->size==0x20000) /* AT91SAM7XC128 */
{
+ at91sam7_info->target_name = "AT91SAM7XC128";
at91sam7_info->num_lockbits = 8;
at91sam7_info->pagesize = 256;
at91sam7_info->pages_in_lockregion = 64;
bank->bus_width = 4;
if (bank->size==0x40000) /* AT91SAM7X256 */
{
+ at91sam7_info->target_name = "AT91SAM7X256";
at91sam7_info->num_lockbits = 16;
at91sam7_info->pagesize = 256;
at91sam7_info->pages_in_lockregion = 64;
}
if (bank->size==0x20000) /* AT91SAM7X128 */
{
+ at91sam7_info->target_name = "AT91SAM7X128";
at91sam7_info->num_lockbits = 8;
at91sam7_info->pagesize = 256;
at91sam7_info->pages_in_lockregion = 64;
if (bank->size == 0x40000) /* AT91SAM7A3 */
{
+ at91sam7_info->target_name = "AT91SAM7A3";
at91sam7_info->num_lockbits = 16;
at91sam7_info->pagesize = 256;
at91sam7_info->pages_in_lockregion = 64;
return ERROR_OK;
}
-
-int at91sam7_register_commands(struct command_context_s *cmd_ctx)
-{
- command_t *at91sam7_cmd = register_command(cmd_ctx, NULL, "at91sam7", NULL, COMMAND_ANY, "at91sam7 specific commands");
-
- return ERROR_OK;
-}
-
int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
{
at91sam7_flash_bank_t *at91sam7_info;
return ERROR_FLASH_SECTOR_INVALID;
}
+ /* Configure the flash controller timing */
+ at91sam7_read_clock_info(bank);
+ at91sam7_set_flash_mode(bank,2);
+
if ((first == 0) && (last == (at91sam7_info->num_lockbits-1)))
{
return at91sam7_flash_command(bank, EA, 0);
}
-
+
WARNING("Can only erase the whole flash area, pages are autoerased on write");
return ERROR_FLASH_OPERATION_FAILED;
}
return ERROR_FLASH_OPERATION_FAILED;
}
- /* Configure the flash controller timing */
+ /* Configure the flash controller timing */
+ at91sam7_read_clock_info(bank);
at91sam7_set_flash_mode(bank,1);
for (lockregion=first;lockregion<=last;lockregion++)
DEBUG("first_page: %i, last_page: %i, count %i", first_page, last_page, count);
/* Configure the flash controller timing */
+ at91sam7_read_clock_info(bank);
at91sam7_set_flash_mode(bank,2);
for (pagen=first_page; pagen<last_page; pagen++) {
int printed;
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
- if (at91sam7_info->cidr == 0)
- {
- at91sam7_read_part_info(bank);
- }
+ at91sam7_read_part_info(bank);
if (at91sam7_info->cidr == 0)
{
buf += printed;
buf_size -= printed;
- printed = snprintf(buf, buf_size, "main clock(estimated): %ikHz \n", at91sam7_info->mainf*2);
+ printed = snprintf(buf, buf_size, "master clock(estimated): %ikHz \n", at91sam7_info->mck_freq / 1000);
buf += printed;
buf_size -= printed;
return ERROR_OK;
}
+
+/*
+* On AT91SAM7S: When the gpnmv bits are set with
+* > at91sam7 gpnvm 0 bitnr set
+* the changes are not visible in the flash controller status register MC_FSR
+* until the processor has been reset.
+* On the Olimex board this requires a power cycle.
+* Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
+* The maximum number of write/erase cycles for Non Volatile Memory bits is 100. This includes
+* Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
+*/
+int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ flash_bank_t *bank;
+ int bit;
+ u8 flashcmd;
+ u32 status;
+ char *value;
+ at91sam7_flash_bank_t *at91sam7_info;
+
+ if (argc < 3)
+ {
+ command_print(cmd_ctx, "at91sam7 gpnvm <num> <bit> <set|clear>");
+ return ERROR_OK;
+ }
+
+ bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
+ bit = atoi(args[1]);
+ value = args[2];
+
+ if (!bank)
+ {
+ command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
+ return ERROR_OK;
+ }
+
+ at91sam7_info = bank->driver_priv;
+
+ if (at91sam7_info->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ if (at91sam7_info->cidr == 0)
+ {
+ at91sam7_read_part_info(bank);
+ }
+
+ if (at91sam7_info->cidr == 0)
+ {
+ WARNING("Cannot identify target as an AT91SAM");
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+
+ if ((bit<0) || (at91sam7_info->num_nvmbits <= bit))
+ {
+ command_print(cmd_ctx, "gpnvm bit '#%s' is out of bounds for target %s", args[1],at91sam7_info->target_name);
+ return ERROR_OK;
+ }
+
+ if (strcmp(value, "set") == 0)
+ {
+ flashcmd = SGPB;
+ }
+ else if (strcmp(value, "clear") == 0)
+ {
+ flashcmd = CGPB;
+ }
+ else
+ {
+ command_print(cmd_ctx, "usage: at91sam7 gpnvm <num> <bit> <set|clear>");
+ return ERROR_OK;
+ }
+
+ /* Configure the flash controller timing */
+ at91sam7_read_clock_info(bank);
+ at91sam7_set_flash_mode(bank,1);
+
+ if (at91sam7_flash_command(bank, flashcmd, (u16)(bit)) != ERROR_OK)
+ {
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+
+ status = at91sam7_get_flash_status(bank);
+ DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value 0x%x, status 0x%x \n",flashcmd,bit,status);
+ at91sam7_info->nvmbits = (status>>8)&((1<<at91sam7_info->num_nvmbits)-1);
+
+ return ERROR_OK;
+}
struct target_s *target;
u32 working_area;
u32 working_area_size;
-
+
/* chip id register */
u32 cidr;
u16 cidr_ext;
u16 cidr_nvpsiz2;
u16 cidr_eproc;
u16 cidr_version;
-
+ char * target_name;
+
/* flash geometry */
u16 num_pages;
u16 pagesize;
u16 nvmbits;
u8 securitybit;
u8 flashmode; /* 0: not init, 1: fmcn for nvbits (1uS), 2: fmcn for flash (1.5uS) */
-
+
/* main clock status */
- u8 mainrdy;
- u16 mainf;
- u16 usec_clocks;
+ u8 mck_valid;
+ u32 mck_freq;
} at91sam7_flash_bank_t;
/* AT91SAM7 control registers */
#define DBGU_CIDR 0xFFFFF240
#define CKGR_MCFR 0xFFFFFC24
+#define CKGR_MCFR_MAINRDY 0x10000
+#define CKGR_PLLR 0xFFFFFC2c
+#define CKGR_PLLR_DIV 0xff
+#define CKGR_PLLR_MUL 0x07ff0000
+#define PMC_MCKR 0xFFFFFC30
+#define PMC_MCKR_CSS 0x03
+#define PMC_MCKR_PRES 0x1c
#define MC_FMR 0xFFFFFF60
#define MC_FCR 0xFFFFFF64
#define MC_FSR 0xFFFFFF68
#define CGPB 0x0D
#define SSB 0x0F
+/* AT91SAM7 constants */
+#define RC_FREQ 32000
#endif /* AT91SAM7_H */
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "replacements.h"
+
#include "cfi.h"
#include "flash.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "flash.h"
#include "command.h"
#include "log.h"
return ERROR_OK;
}
- if (!(binary = fopen(args[1], "r")))
+ if (!(binary = fopen(args[1], "rb")))
{
ERROR("couldn't open %s: %s", args[1], strerror(errno));
command_print(cmd_ctx, "couldn't open %s", args[1]);
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "lpc2000.h"
#include "flash.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "replacements.h"
#include "str7x.h"
#include "flash.h"
INCLUDES = $(all_includes)
METASOURCES = AUTO
noinst_LIBRARIES = libhelper.a
-libhelper_a_SOURCES = binarybuffer.c configuration.c log.c interpreter.c command.c time_support.c
+libhelper_a_SOURCES = binarybuffer.c configuration.c log.c interpreter.c command.c time_support.c replacements.c
noinst_HEADERS = binarybuffer.h configuration.h types.h log.h command.h \
- interpreter.h time_support.h
+ interpreter.h time_support.h replacements.h
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
#include <stdlib.h>
#include <string.h>
for (i = 0; i < num_bytes; i++)
{
- if (buf1[i] != buf2[i])
- return 1;
+ /* last byte */
+ /* mask out bits that don't really belong to the buffer if size isn't a multiple of 8 bits */
+ if ((size % 8) && (i == num_bytes -1 ))
+ {
+ if ((buf1[i] & ((1 << (size % 8)) - 1)) != (buf2[i] & ((1 << (size % 8)) - 1)))
+ return 1;
+ }
+ else
+ {
+ if (buf1[i] != buf2[i])
+ return 1;
+ }
}
return 0;
for (i = 0; i < num_bytes; i++)
{
- if ((buf1[i] & mask[i]) != (buf2[i] & mask[i]))
- return 1;
+ /* last byte */
+ /* mask out bits that don't really belong to the buffer if size isn't a multiple of 8 bits */
+ if ((size % 8) && (i == num_bytes -1 ))
+ {
+ if (((buf1[i] & ((1 << (size % 8)) - 1)) & ((1 << (size % 8)) - 1)) !=
+ ((buf2[i] & ((1 << (size % 8)) - 1)) & ((1 << (size % 8)) - 1)))
+ return 1;
+ }
+ else
+ {
+ if ((buf1[i] & mask[i]) != (buf2[i] & mask[i]))
+ return 1;
+ }
}
return 0;
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "replacements.h"
+
#include "command.h"
#include "log.h"
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
-#include <config.h>
+#include "config.h"
#endif
#include "types.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "interpreter.h"
#include "binarybuffer.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "log.h"
#include "configuration.h"
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2006 by Dominic Rath *
+ * Dominic.Rath@gmx.de *
+ * *
+ * 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "replacements.h"
+
+#include <stdio.h>
+
+/* replacements for gettimeofday */
+#ifndef HAVE_GETTIMEOFDAY
+
+/* Windows */
+#ifdef _WIN32
+
+#ifndef __GNUC__
+#define EPOCHFILETIME (116444736000000000i64)
+#else
+#define EPOCHFILETIME (116444736000000000LL)
+#endif
+
+int gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+ FILETIME ft;
+ LARGE_INTEGER li;
+ __int64 t;
+ static int tzflag;
+
+ if (tv)
+ {
+ GetSystemTimeAsFileTime(&ft);
+ li.LowPart = ft.dwLowDateTime;
+ li.HighPart = ft.dwHighDateTime;
+ t = li.QuadPart; /* In 100-nanosecond intervals */
+ t -= EPOCHFILETIME; /* Offset to the Epoch time */
+ t /= 10; /* In microseconds */
+ tv->tv_sec = (long)(t / 1000000);
+ tv->tv_usec = (long)(t % 1000000);
+ }
+
+ if (tz)
+ {
+ if (!tzflag)
+ {
+ _tzset();
+ tzflag++;
+ }
+ tz->tz_minuteswest = _timezone / 60;
+ tz->tz_dsttime = _daylight;
+ }
+
+ return 0;
+}
+#endif /* _WIN32 */
+
+#endif /* HAVE_GETTIMEOFDAY */
+
+#ifndef HAVE_STRNLEN
+size_t strnlen(const char *s, size_t maxlen)
+{
+ const char *end= (const char *)memchr(s, '\0', maxlen);
+ return end ? (size_t) (end - s) : maxlen;
+}
+#endif
+
+#ifndef HAVE_STRNDUP
+char* strndup(const char *s, size_t n)
+{
+ size_t len = strnlen (s, n);
+ char *new = (char *) malloc (len + 1);
+
+ if (new == NULL)
+ return NULL;
+
+ new[len] = '\0';
+ return (char *) memcpy (new, s, len);
+}
+#endif
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2006 by Dominic Rath *
+ * Dominic.Rath@gmx.de *
+ * *
+ * 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef REPLACEMENTS_H
+#define REPLACEMENTS_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* include necessary headers for socket functionality */
+#ifdef _WIN32
+#include <winsock2.h>
+#else
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <fcntl.h>
+#endif
+
+/* gettimeofday() */
+#ifndef HAVE_GETTIMEOFDAY
+
+#ifndef _TIMEVAL_DEFINED
+#define _TIMEVAL_DEFINED
+
+struct timeval {
+ long tv_sec;
+ long tv_usec;
+};
+#endif /* _TIMEVAL_DEFINED */
+
+struct timezone {
+ int tz_minuteswest;
+ int tz_dsttime;
+};
+
+extern int gettimeofday(struct timeval *tv, struct timezone *tz);
+#endif
+
+/* GNU extensions to the C library that may be missing on some systems */
+#ifndef HAVE_STRNDUP
+extern char* strndup(const char *s, size_t n);
+#endif /* HAVE_STRNDUP */
+
+#ifndef HAVE_STRNLEN
+extern size_t strnlen(const char *s, size_t maxlen);
+#endif /* HAVE_STRNLEN */
+
+#ifndef HAVE_USLEEP
+static __inline unsigned usleep(unsigned int usecs)
+{
+#ifdef _WIN32
+ Sleep((usecs/1000));
+ return 0;
+#else
+#error no usleep defined for your platform
+#endif
+}
+#endif /* HAVE_USLEEP */
+
+/* Windows specific */
+#ifdef _WIN32
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <time.h>
+
+#undef ERROR
+
+#if IS_MINGW == 1
+static __inline unsigned char inb(unsigned short int port)
+{
+ unsigned char _v;
+ __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline void outb(unsigned char value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outb %b0,%w1": :"a" (value), "Nd" (port));
+}
+
+#endif /* IS_MINGW */
+#endif /* _WIN32 */
+
+/* generic socket functions for Windows and Posix */
+static __inline int write_socket( int handle, const void *buffer, unsigned int count )
+{
+#ifdef _WIN32
+ return send(handle, buffer, count, 0);
+#else
+ return write(handle, buffer, count);
+#endif
+}
+
+static __inline int read_socket( int handle, void *buffer, unsigned int count )
+{
+#ifdef _WIN32
+ return recv(handle, buffer, count, 0);
+#else
+ return read(handle, buffer, count);
+#endif
+}
+
+static __inline int close_socket(int sock)
+{
+#ifdef _WIN32
+ return closesocket(sock);
+#else
+ return close(sock);
+#endif
+}
+
+static __inline void socket_nonblock(int fd)
+{
+#ifdef _WIN32
+ long nonblock = 1;
+ ioctlsocket(fd, FIONBIO, &nonblock );
+#else
+ int oldopts = fcntl(fd, F_GETFL, 0);
+ fcntl(fd, F_SETFL, oldopts | O_NONBLOCK);
+#endif
+}
+
+#endif /* REPLACEMENTS_H */
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
#include "time_support.h"
if FTD2XXDIR
+if IS_MINGW
+FTD2XXINC = -I@WITH_FTD2XX@
+else
FTD2XXINC = -I@WITH_FTD2XX@/
+endif
else
FTD2XXINC =
endif
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
+
#include "log.h"
#include "jtag.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
#include "bitbang.h"
cur_state = end_state;
}
+void bitbang_path_move(pathmove_command_t *cmd)
+{
+ int num_states = cmd->num_states;
+ int state_count;
+
+ state_count = 0;
+ while (num_states)
+ {
+ if (tap_transitions[cur_state].low == cmd->path[state_count])
+ {
+ bitbang_interface->write(0, 0, 0);
+ bitbang_interface->write(1, 0, 0);
+ }
+ else if (tap_transitions[cur_state].high == cmd->path[state_count])
+ {
+ bitbang_interface->write(0, 1, 0);
+ bitbang_interface->write(1, 1, 0);
+ }
+ else
+ {
+ ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]);
+ exit(-1);
+ }
+
+ cur_state = cmd->path[state_count];
+ state_count++;
+ num_states--;
+ }
+
+ end_state = cur_state;
+}
+
void bitbang_runtest(int num_cycles)
{
int i;
bitbang_end_state(cmd->cmd.statemove->end_state);
bitbang_state_move();
break;
+ case JTAG_PATHMOVE:
+#ifdef _DEBUG_JTAG_IO_
+ DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
+#endif
+ bitbang_path_move(cmd->cmd.pathmove);
+ break;
case JTAG_SCAN:
#ifdef _DEBUG_JTAG_IO_
DEBUG("scan end in %i", cmd->cmd.scan->end_state);
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
+
#include "log.h"
#include "jtag.h"
#include "bitbang.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
+
#if IS_CYGWIN == 1
#include "windows.h"
#undef ERROR
#endif
+#include "replacements.h"
+
/* project specific includes */
#include "log.h"
#include "types.h"
#include "jtag.h"
#include "configuration.h"
+#include "time_support.h"
/* system includes */
#include <string.h>
#ifdef _DEBUG_USB_IO_
struct timeval start, inter, inter2, end;
+ struct timeval d_inter, d_inter2, d_end;
#endif
#ifdef _DEBUG_USB_COMMS_
#ifdef _DEBUG_USB_IO_
gettimeofday(&end, NULL);
- INFO("inter: %i.%i, inter2: %i.%i end: %i.%i", inter.tv_sec - start.tv_sec, inter.tv_usec - start.tv_usec,
- inter2.tv_sec - start.tv_sec, inter2.tv_usec - start.tv_usec,
- end.tv_sec - start.tv_sec, end.tv_usec - start.tv_usec);
+ timeval_subtract(&d_inter, &inter, &start);
+ timeval_subtract(&d_inter2, &inter2, &start);
+ timeval_subtract(&d_end, &end, &start);
+
+ INFO("inter: %i.%i, inter2: %i.%i end: %i.%i", d_inter.tv_sec, d_inter.tv_usec, d_inter2.tv_sec, d_inter2.tv_usec, d_end.tv_sec, d_end.tv_usec);
#endif
return ERROR_OK;
}
+void ftd2xx_add_pathmove(pathmove_command_t *cmd)
+{
+ int num_states = cmd->num_states;
+ u8 tms_byte;
+ int state_count;
+
+ state_count = 0;
+ while (num_states)
+ {
+ tms_byte = 0x0;
+ int bit_count = 0;
+
+ /* command "Clock Data to TMS/CS Pin (no Read)" */
+ BUFFER_ADD = 0x4b;
+ /* number of states remaining */
+ BUFFER_ADD = (num_states % 7) - 1;
+
+ while (num_states % 7)
+ {
+ if (tap_transitions[cur_state].low == cmd->path[state_count])
+ buf_set_u32(&tms_byte, bit_count++, 1, 0x0);
+ else if (tap_transitions[cur_state].high == cmd->path[state_count])
+ buf_set_u32(&tms_byte, bit_count++, 1, 0x1);
+ else
+ {
+ ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]);
+ exit(-1);
+ }
+
+ cur_state = cmd->path[state_count];
+ state_count++;
+ num_states--;
+ }
+
+ BUFFER_ADD = tms_byte;
+ }
+
+ end_state = cur_state;
+}
+
void ftd2xx_add_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)
{
int num_bytes = (scan_size + 7) / 8;
int cur_byte = 0;
int last_bit;
- /* command "Clock Data to TMS/CS Pin (no Read)" */
- BUFFER_ADD = 0x4b;
- /* scan 7 bit */
- BUFFER_ADD = 0x6;
- /* TMS data bits */
- if (ir_scan)
- {
- BUFFER_ADD = TAP_MOVE(cur_state, TAP_SI);
- cur_state = TAP_SI;
- }
- else
+ if ((!ir_scan && (cur_state != TAP_SD)) || (ir_scan && (cur_state != TAP_SI)))
{
- BUFFER_ADD = TAP_MOVE(cur_state, TAP_SD);
- cur_state = TAP_SD;
+ /* command "Clock Data to TMS/CS Pin (no Read)" */
+ BUFFER_ADD = 0x4b;
+ /* scan 7 bit */
+ BUFFER_ADD = 0x6;
+ /* TMS data bits */
+ if (ir_scan)
+ {
+ BUFFER_ADD = TAP_MOVE(cur_state, TAP_SI);
+ cur_state = TAP_SI;
+ }
+ else
+ {
+ BUFFER_ADD = TAP_MOVE(cur_state, TAP_SD);
+ cur_state = TAP_SD;
+ }
+ //DEBUG("added TMS scan (no read)");
}
- //DEBUG("added TMS scan (no read)");
-
+
/* add command for complete bytes */
if (num_bytes > 1)
{
//DEBUG("added TDI bytes (i %i)", num_bytes);
}
BUFFER_ADD = (num_bytes-2) & 0xff;
- BUFFER_ADD = (num_bytes >> 8) & 0xff;
+ BUFFER_ADD = ((num_bytes-2) >> 8) & 0xff;
}
if (type != SCAN_IN)
{
int ftd2xx_predict_scan_out(int scan_size, enum scan_type type)
{
- int predicted_size = 6;
+ int predicted_size = 3;
+
+ if (cur_state != TAP_SD)
+ predicted_size += 3;
+
if (type == SCAN_IN) /* only from device to host */
{
+ /* complete bytes */
predicted_size += (CEIL(scan_size, 8) > 1) ? 3 : 0;
+ /* remaining bits - 1 (up to 7) */
predicted_size += ((scan_size - 1) % 8) ? 2 : 0;
}
else /* host to device, or bidirectional */
{
+ /* complete bytes */
predicted_size += (CEIL(scan_size, 8) > 1) ? (CEIL(scan_size, 8) + 3 - 1) : 0;
+ /* remaining bits -1 (up to 7) */
predicted_size += ((scan_size - 1) % 8) ? 3 : 0;
}
layout->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
require_send = 1;
-
+
+#ifdef _DEBUG_JTAG_IO_
+ DEBUG("trst: %i, srst: %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+#endif
break;
case JTAG_RUNTEST:
/* only send the maximum buffer size that FT2232C can handle */
//DEBUG("added TMS scan (no read)");
}
require_send = 1;
+#ifdef _DEBUG_JTAG_IO_
+ DEBUG("runtest: %i, end in %i", cmd->cmd.runtest->num_cycles, end_state);
+#endif
break;
case JTAG_STATEMOVE:
/* only send the maximum buffer size that FT2232C can handle */
//DEBUG("added TMS scan (no read)");
cur_state = end_state;
require_send = 1;
+#ifdef _DEBUG_JTAG_IO_
+ DEBUG("statemove: %i", end_state);
+#endif
+ break;
+ case JTAG_PATHMOVE:
+ /* only send the maximum buffer size that FT2232C can handle */
+ predicted_size = 3 * CEIL(cmd->cmd.pathmove->num_states, 7);
+ if (ftd2xx_buffer_size + predicted_size + 1 > FTD2XX_BUFFER_SIZE)
+ {
+ ftd2xx_send_and_recv(first_unsent, cmd);
+ require_send = 0;
+ first_unsent = cmd;
+ }
+ ftd2xx_add_pathmove(cmd->cmd.pathmove);
+ require_send = 1;
+#ifdef _DEBUG_JTAG_IO_
+ DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
+#endif
break;
case JTAG_SCAN:
scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
require_send = 1;
if (buffer)
free(buffer);
+#ifdef _DEBUG_JTAG_IO_
+ DEBUG("%s scan, %i bit, end in %i", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size, end_state);
+#endif
break;
case JTAG_SLEEP:
ftd2xx_send_and_recv(first_unsent, cmd);
first_unsent = cmd->next;
jtag_sleep(cmd->cmd.sleep->us);
+#ifdef _DEBUG_JTAG_IO_
+ DEBUG("sleep %i usec", cmd->cmd.sleep->us);
+#endif
break;
default:
ERROR("BUG: unknown JTAG command type encountered");
ftd2xx_device_desc = "Dual RS232";
}
-#if IS_CYGWIN != 1
+#if IS_WIN32 == 0
/* Add JTAGkey Vid/Pid to the linux driver */
if ((status = FT_SetVIDPID(ftd2xx_vid, ftd2xx_pid)) != FT_OK)
{
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
/* project specific includes */
#include "log.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
+
+#include "replacements.h"
+
#include "jtag.h"
#include "command.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
-#include "log.h"
+#endif
+
+#include "replacements.h"
+
#include "jtag.h"
#include "bitbang.h"
/* system includes */
// -ino: 060521-1036
#ifdef __FreeBSD__
+
#include <sys/types.h>
#include <machine/sysarch.h>
#include <machine/cpufunc.h>
#define ioperm(startport,length,enable)\
i386_set_ioperm((startport), (length), (enable))
+
#else
+
+#ifndef _WIN32
#include <sys/io.h>
-#endif
+#else
+#include "errno.h"
+#endif /* _WIN32 */
+
+#endif /* __FreeBSD__ */
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#endif
+#if PARPORT_USE_GIVEIO == 1
+#if IS_CYGWIN == 1
+#include <windows.h>
+#include <errno.h>
+#undef ERROR
+#endif
+#endif
+
+#include "log.h"
+
/* parallel port cable description
*/
typedef struct cable_s
return ERROR_OK;
}
+#if PARPORT_USE_GIVEIO == 1
+int parport_get_giveio_access()
+{
+ HANDLE h;
+ OSVERSIONINFO version;
+
+ version.dwOSVersionInfoSize = sizeof version;
+ if (!GetVersionEx( &version )) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (version.dwPlatformId != VER_PLATFORM_WIN32_NT)
+ return 0;
+
+ h = CreateFile( "\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+ if (h == INVALID_HANDLE_VALUE) {
+ errno = ENODEV;
+ return -1;
+ }
+
+ CloseHandle( h );
+
+ return 0;
+}
+#endif
+
int parport_init(void)
{
cable_t *cur_cable;
dataport = parport_port;
statusport = parport_port + 1;
- if (ioperm(dataport, 3, 1) != 0) {
+#if PARPORT_USE_GIVEIO == 1
+ if (parport_get_giveio_access() != 0)
+#else /* PARPORT_USE_GIVEIO */
+ if (ioperm(dataport, 3, 1) != 0)
+#endif /* PARPORT_USE_GIVEIO */
+ {
ERROR("missing privileges for direct i/o");
return ERROR_JTAG_INIT_FAILED;
}
-#endif
+#endif /* PARPORT_USE_PPDEV */
parport_reset(0, 0);
parport_write(0, 0, 0);
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
-#define OPENOCD_VERSION "Open On-Chip Debugger (2006-06-25 23:00 CEST)"
+#define OPENOCD_VERSION "Open On-Chip Debugger (2006-07-15 12:00 CEST)"
#ifdef HAVE_CONFIG_H
-#include <config.h>
+#include "config.h"
#endif
#include "log.h"
#include <sys/time.h>
#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/poll.h>
#include <strings.h>
-#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
-#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
+
+#include "replacements.h"
#include "gdb_server.h"
#include <unistd.h>
#include <stdlib.h>
-#ifndef HAVE_STRNDUP
-#include <stdio.h>
-char* strndup(const char *s, size_t n)
-{
- size_t len = strnlen (s, n);
- char *new = (char *) malloc (len + 1);
-
- if (new == NULL)
- return NULL;
-
- new[len] = '\0';
- return (char *) memcpy (new, s, len);
-}
-#endif
-
#if 0
#define _DEBUG_GDB_IO_
#endif
return ERROR_OK;
}
- while ((gdb_con->buf_cnt = read(connection->fd, gdb_con->buffer, GDB_BUFFER_SIZE)) <= 0)
+ while ((gdb_con->buf_cnt = read_socket(connection->fd, gdb_con->buffer, GDB_BUFFER_SIZE)) <= 0)
{
if (gdb_con->buf_cnt == 0)
return ERROR_SERVER_REMOTE_CLOSED;
+#ifdef _WIN32
+ errno = WSAGetLastError();
+
+ switch(errno)
+ {
+ case WSAEWOULDBLOCK:
+ usleep(1000);
+ break;
+ case WSAECONNABORTED:
+ return ERROR_SERVER_REMOTE_CLOSED;
+ default:
+ ERROR("read: %d", strerror(errno));
+ exit(-1);
+ }
+#else
switch(errno)
{
case EAGAIN:
ERROR("read: %s", strerror(errno));
exit(-1);
}
+#endif
}
debug_buffer = malloc(gdb_con->buf_cnt + 1);
DEBUG("sending packet '$%s#%2.2x'", debug_buffer, my_checksum);
free(debug_buffer);
- write(connection->fd, "$", 1);
+ write_socket(connection->fd, "$", 1);
if (len > 0)
- write(connection->fd, buffer, len);
- write(connection->fd, "#", 1);
+ write_socket(connection->fd, buffer, len);
+ write_socket(connection->fd, "#", 1);
snprintf(checksum, 3, "%2.2x", my_checksum);
- write(connection->fd, checksum, 2);
+ write_socket(connection->fd, checksum, 2);
if ((retval = gdb_get_char(connection, &reply)) != ERROR_OK)
return retval;
if (my_checksum == strtoul(checksum, NULL, 16))
{
- write (connection->fd, "+", 1);
+ write_socket(connection->fd, "+", 1);
break;
}
WARNING("checksum error, requesting retransmission");
- write(connection->fd, "-", 1);
+ write_socket(connection->fd, "-", 1);
}
return ERROR_OK;
DEBUG("gdb service for target %s at port %i", target->type->name, gdb_port + i);
+ i++;
target = target->next;
}
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "replacements.h"
+
#include "server.h"
#include "log.h"
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
-#include <sys/socket.h>
#include <fcntl.h>
#include <signal.h>
}
else
{
- close(c->fd);
+ close_socket(c->fd);
INFO("attempted '%s' connection rejected", service->name);
free(c);
}
{
service->connections = next;
service->connection_closed(c);
- close(c->fd);
+ close_socket(c->fd);
command_done(c->cmd_ctx);
{
service_t *c, *p;
int so_reuseaddr_option = 1;
- int oldopts;
c = malloc(sizeof(service_t));
exit(-1);
}
- setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, &so_reuseaddr_option, sizeof(int));
+ setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, (void*)&so_reuseaddr_option, sizeof(int));
- oldopts = fcntl(c->fd, F_GETFL, 0);
- fcntl(c->fd, F_SETFL, oldopts | O_NONBLOCK);
+ socket_nonblock(c->fd);
memset(&c->sin, 0, sizeof(c->sin));
c->sin.sin_family = AF_INET;
return ERROR_OK;
}
+int remove_services()
+{
+ service_t *c = services;
+
+ /* loop service */
+ while(c)
+ {
+ service_t *next = c->next;
+
+ if (c->name)
+ free(c->name);
+
+ if (c->priv)
+ free(c->priv);
+
+ /* delete service */
+ free(c);
+
+ /* remember the last service for unlinking */
+ c = next;
+ }
+
+ return ERROR_OK;
+}
+
int server_loop(command_context_t *command_context)
{
service_t *service;
/* used in accept() */
int retval;
+#ifndef _WIN32
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
ERROR("couldn't set SIGPIPE to SIG_IGN");
+#endif
/* do regular tasks after at most 10ms */
tv.tv_sec = 0;
}
}
+#ifndef _WIN32
/* add STDIN to read_fds */
FD_SET(fileno(stdin), &read_fds);
+#endif
if ((retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv)) == -1)
{
+#ifdef _WIN32
+
+ errno = WSAGetLastError();
+
+ if (errno == WSAEINTR)
+ FD_ZERO(&read_fds);
+ else
+ {
+ ERROR("error during select: %d", strerror(errno));
+ exit(-1);
+ }
+#else
+
if (errno == EINTR)
FD_ZERO(&read_fds);
else
ERROR("error during select: %s", strerror(errno));
exit(-1);
}
+#endif
}
target_call_timer_callbacks();
unsigned int address_size = sizeof(sin);
int tmp_fd;
tmp_fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
- close(tmp_fd);
+ close_socket(tmp_fd);
INFO("rejected '%s' connection, no more connections allowed", service->name);
}
}
}
}
+#ifndef _WIN32
if (FD_ISSET(fileno(stdin), &read_fds))
{
if (getc(stdin) == 'x')
shutdown_openocd = 1;
}
}
+#endif
}
return ERROR_OK;
}
+#ifdef _WIN32
+BOOL WINAPI ControlHandler(DWORD dwCtrlType)
+{
+ shutdown_openocd = 1;
+ return TRUE;
+}
+#endif
+
int server_init()
{
+#ifdef _WIN32
+ WORD wVersionRequested;
+ WSADATA wsaData;
+
+ wVersionRequested = MAKEWORD( 2, 2 );
+
+ if (WSAStartup(wVersionRequested, &wsaData) != 0)
+ {
+ ERROR("Failed to Open Winsock");
+ exit(-1);
+ }
+
+ SetConsoleCtrlHandler( ControlHandler, TRUE );
+#endif
+
return ERROR_OK;
}
+int server_close()
+{
+ remove_services();
+
+#ifdef _WIN32
+ WSACleanup();
+ SetConsoleCtrlHandler( ControlHandler, FALSE );
+#endif
+
+ return ERROR_OK;
+}
+
int server_register_commands(command_context_t *context)
{
register_command(context, NULL, "shutdown", handle_shutdown_command,
#include "command.h"
#include "binarybuffer.h"
+#include "replacements.h"
#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
enum connection_type
{
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "replacements.h"
+
#include "telnet_server.h"
#include "server.h"
{
telnet_connection_t *t_con = connection->priv;
- write(connection->fd, t_con->prompt, strlen(t_con->prompt));
+ write_socket(connection->fd, t_con->prompt, strlen(t_con->prompt));
}
int telnet_output(struct command_context_s *cmd_ctx, char* line)
{
connection_t *connection = cmd_ctx->output_handler_priv;
- write(connection->fd, line, strlen(line));
- write(connection->fd, "\r\n\0", 3);
+ write_socket(connection->fd, line, strlen(line));
+ write_socket(connection->fd, "\r\n\0", 3);
return ERROR_OK;
}
command_set_output_handler(connection->cmd_ctx, telnet_output, connection);
/* negotiate telnet options */
- write(connection->fd, negotiate, strlen(negotiate));
+ write_socket(connection->fd, negotiate, strlen(negotiate));
/* print connection banner */
if (telnet_service->banner)
{
- write(connection->fd, telnet_service->banner, strlen(telnet_service->banner));
- write(connection->fd, "\r\n\0", 3);
+ write_socket(connection->fd, telnet_service->banner, strlen(telnet_service->banner));
+ write_socket(connection->fd, "\r\n\0", 3);
}
telnet_prompt(connection);
/* move to end of line */
if (t_con->line_cursor < t_con->line_size)
{
- write(connection->fd, t_con->line + t_con->line_cursor, t_con->line_size - t_con->line_cursor);
+ write_socket(connection->fd, t_con->line + t_con->line_cursor, t_con->line_size - t_con->line_cursor);
}
/* backspace, overwrite with space, backspace */
while (t_con->line_size > 0)
{
- write(connection->fd, "\b \b", 3);
+ write_socket(connection->fd, "\b \b", 3);
t_con->line_size--;
}
t_con->line_cursor = 0;
telnet_connection_t *t_con = connection->priv;
command_context_t *command_context = connection->cmd_ctx;
- bytes_read = read(connection->fd, buffer, TELNET_BUFFER_SIZE);
+ bytes_read = read_socket(connection->fd, buffer, TELNET_BUFFER_SIZE);
if (bytes_read == 0)
return ERROR_SERVER_REMOTE_CLOSED;
{
if (isprint(*buf_p)) /* printable character */
{
- write(connection->fd, buf_p, 1);
+ write_socket(connection->fd, buf_p, 1);
if (t_con->line_cursor == t_con->line_size)
{
t_con->line[t_con->line_size++] = *buf_p;
memmove(t_con->line + t_con->line_cursor + 1, t_con->line + t_con->line_cursor, t_con->line_size - t_con->line_cursor);
t_con->line[t_con->line_cursor++] = *buf_p;
t_con->line_size++;
- write(connection->fd, t_con->line + t_con->line_cursor, t_con->line_size - t_con->line_cursor);
+ write_socket(connection->fd, t_con->line + t_con->line_cursor, t_con->line_size - t_con->line_cursor);
for (i = t_con->line_cursor; i < t_con->line_size; i++)
{
- write(connection->fd, "\b", 1);
+ write_socket(connection->fd, "\b", 1);
}
}
}
}
t_con->line[t_con->line_size] = 0;
- write(connection->fd, "\r\n\x00", 3);
+ write_socket(connection->fd, "\r\n\x00", 3);
if (strcmp(t_con->line, "history") == 0)
{
{
if (t_con->history[i])
{
- write(connection->fd, t_con->history[i], strlen(t_con->history[i]));
- write(connection->fd, "\r\n\x00", 3);
+ write_socket(connection->fd, t_con->history[i], strlen(t_con->history[i]));
+ write_socket(connection->fd, "\r\n\x00", 3);
}
}
telnet_prompt(connection);
if (t_con->line_cursor != t_con->line_size)
{
int i;
- write(connection->fd, "\b", 1);
+ write_socket(connection->fd, "\b", 1);
t_con->line_cursor--;
t_con->line_size--;
memmove(t_con->line + t_con->line_cursor, t_con->line + t_con->line_cursor + 1, t_con->line_size - t_con->line_cursor);
- write(connection->fd, t_con->line + t_con->line_cursor, t_con->line_size - t_con->line_cursor);
- write(connection->fd, " \b", 2);
+ write_socket(connection->fd, t_con->line + t_con->line_cursor, t_con->line_size - t_con->line_cursor);
+ write_socket(connection->fd, " \b", 2);
for (i = t_con->line_cursor; i < t_con->line_size; i++)
{
- write(connection->fd, "\b", 1);
+ write_socket(connection->fd, "\b", 1);
}
}
else
t_con->line_size--;
t_con->line_cursor--;
/* back space: move the 'printer' head one char back, overwrite with space, move back again */
- write(connection->fd, "\b \b", 3);
+ write_socket(connection->fd, "\b \b", 3);
}
}
}
{
if (t_con->line_cursor > 0)
{
- write(connection->fd, "\b", 1);
+ write_socket(connection->fd, "\b", 1);
t_con->line_cursor--;
}
t_con->state = TELNET_STATE_DATA;
{
if (t_con->line_cursor < t_con->line_size)
{
- write(connection->fd, t_con->line + t_con->line_cursor++, 1);
+ write_socket(connection->fd, t_con->line + t_con->line_cursor++, 1);
}
t_con->state = TELNET_STATE_DATA;
}
{
if (t_con->line_cursor > 0)
{
- write(connection->fd, "\b", 1);
+ write_socket(connection->fd, "\b", 1);
t_con->line_cursor--;
}
t_con->state = TELNET_STATE_DATA;
{
if (t_con->line_cursor < t_con->line_size)
{
- write(connection->fd, t_con->line + t_con->line_cursor++, 1);
+ write_socket(connection->fd, t_con->line + t_con->line_cursor++, 1);
}
t_con->state = TELNET_STATE_DATA;
}
t_con->line_size = strlen(t_con->history[last_history]);
t_con->line_cursor = t_con->line_size;
memcpy(t_con->line, t_con->history[last_history], t_con->line_size + 1);
- write(connection->fd, t_con->line, t_con->line_size);
+ write_socket(connection->fd, t_con->line, t_con->line_size);
t_con->current_history = last_history;
}
t_con->state = TELNET_STATE_DATA;
t_con->line_size = strlen(t_con->history[next_history]);
t_con->line_cursor = t_con->line_size;
memcpy(t_con->line, t_con->history[next_history], t_con->line_size + 1);
- write(connection->fd, t_con->line, t_con->line_size);
+ write_socket(connection->fd, t_con->line, t_con->line_size);
t_con->current_history = next_history;
}
t_con->state = TELNET_STATE_DATA;
memmove(t_con->line + t_con->line_cursor, t_con->line + t_con->line_cursor + 1, t_con->line_size - t_con->line_cursor);
/* print remainder of buffer */
- write(connection->fd, t_con->line + t_con->line_cursor, t_con->line_size - t_con->line_cursor);
+ write_socket(connection->fd, t_con->line + t_con->line_cursor, t_con->line_size - t_con->line_cursor);
/* overwrite last char with whitespace */
- write(connection->fd, " \b", 2);
+ write_socket(connection->fd, " \b", 2);
/* move back to cursor position*/
for (i = t_con->line_cursor; i < t_con->line_size; i++)
{
- write(connection->fd, "\b", 1);
+ write_socket(connection->fd, "\b", 1);
}
}
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
+
#include "algorithm.h"
#include "log.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
#include "arm720t.h"
#include "jtag.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
+
+#include "replacements.h"
#include "embeddedice.h"
#include "target.h"
else
{
target->type->read_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
- target->type->write_memory(target, breakpoint->address, 2, 1, (u8*)(&arm7_9->arm_bkpt));
+ target->type->write_memory(target, breakpoint->address, 2, 1, (u8*)(&arm7_9->thumb_bkpt));
}
breakpoint->set = 1;
}
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
#include "arm7tdmi.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
#include "arm920t.h"
#include "jtag.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
#include "arm9tdmi.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "arm_disassembler.h"
#include "log.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
#include "arm_jtag.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
+
+#include "replacements.h"
#include "arm_disassembler.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "armv4_5_cache.h"
#include "log.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "arm7_9_common.h"
#include "log.h"
#include "command.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
#include <stdlib.h>
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
#include "embeddedice.h"
-/***************************************************************************\r
- * Copyright (C) 2005 by Dominic Rath *\r
- * Dominic.Rath@gmx.de *\r
- * *\r
- * This program is free software; you can redistribute it and/or modify *\r
- * it under the terms of the GNU General Public License as published by *\r
- * the Free Software Foundation; either version 2 of the License, or *\r
- * (at your option) any later version. *\r
- * *\r
- * This program is distributed in the hope that it will be useful, *\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
- * GNU General Public License for more details. *\r
- * *\r
- * You should have received a copy of the GNU General Public License *\r
- * along with this program; if not, write to the *\r
- * Free Software Foundation, Inc., *\r
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
- ***************************************************************************/\r
-#include "config.h"\r
-\r
-#include "etm.h"\r
-\r
-#include "armv4_5.h"\r
-#include "arm7_9_common.h"\r
-\r
-#include "log.h"\r
-#include "arm_jtag.h"\r
-#include "types.h"\r
-#include "binarybuffer.h"\r
-#include "target.h"\r
-#include "register.h"\r
-#include "jtag.h"\r
-\r
-#include <stdlib.h>\r
-\r
-bitfield_desc_t etm_comms_ctrl_bitfield_desc[] = \r
-{\r
- {"R", 1},\r
- {"W", 1},\r
- {"reserved", 26},\r
- {"version", 4}\r
-};\r
-\r
-int etm_reg_arch_info[] =\r
-{\r
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\r
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,\r
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, \r
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, \r
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,\r
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, \r
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,\r
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,\r
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, \r
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, \r
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,\r
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,\r
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x67, \r
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, \r
-};\r
-\r
-int etm_reg_arch_size_info[] =\r
-{\r
- 32, 32, 17, 8, 3, 9, 32, 17,\r
- 26, 16, 25, 8, 17, 32, 32, 17,\r
- 32, 32, 32, 32, 32, 32, 32, 32, \r
- 32, 32, 32, 32, 32, 32, 32, 32, \r
- 7, 7, 7, 7, 7, 7, 7, 7, \r
- 7, 7, 7, 7, 7, 7, 7, 7, \r
- 32, 32, 32, 32, 32, 32, 32, 32, \r
- 32, 32, 32, 32, 32, 32, 32, 32, \r
- 32, 32, 32, 32, 32, 32, 32, 32, \r
- 32, 32, 32, 32, 32, 32, 32, 32, \r
- 16, 16, 16, 16, 18, 18, 18, 18,\r
- 17, 17, 17, 17, 16, 16, 16, 16,\r
- 17, 17, 17, 17, 17, 17, 2, \r
- 17, 17, 17, 17, 32, 32, 32, 32 \r
-};\r
-\r
-char* etm_reg_list[] =\r
-{\r
- "ETM_CTRL",\r
- "ETM_CONFIG",\r
- "ETM_TRIG_EVENT",\r
- "ETM_MMD_CTRL",\r
- "ETM_STATUS",\r
- "ETM_SYS_CONFIG",\r
- "ETM_TRACE_RESOURCE_CTRL",\r
- "ETM_TRACE_EN_CTRL2",\r
- "ETM_TRACE_EN_EVENT",\r
- "ETM_TRACE_EN_CTRL1",\r
- "ETM_FIFOFULL_REGION",\r
- "ETM_FIFOFULL_LEVEL",\r
- "ETM_VIEWDATA_EVENT",\r
- "ETM_VIEWDATA_CTRL1",\r
- "ETM_VIEWDATA_CTRL2",\r
- "ETM_VIEWDATA_CTRL3",\r
- "ETM_ADDR_COMPARATOR_VALUE1",\r
- "ETM_ADDR_COMPARATOR_VALUE2",\r
- "ETM_ADDR_COMPARATOR_VALUE3",\r
- "ETM_ADDR_COMPARATOR_VALUE4",\r
- "ETM_ADDR_COMPARATOR_VALUE5",\r
- "ETM_ADDR_COMPARATOR_VALUE6",\r
- "ETM_ADDR_COMPARATOR_VALUE7",\r
- "ETM_ADDR_COMPARATOR_VALUE8",\r
- "ETM_ADDR_COMPARATOR_VALUE9",\r
- "ETM_ADDR_COMPARATOR_VALUE10",\r
- "ETM_ADDR_COMPARATOR_VALUE11",\r
- "ETM_ADDR_COMPARATOR_VALUE12",\r
- "ETM_ADDR_COMPARATOR_VALUE13",\r
- "ETM_ADDR_COMPARATOR_VALUE14",\r
- "ETM_ADDR_COMPARATOR_VALUE15",\r
- "ETM_ADDR_COMPARATOR_VALUE16",\r
- "ETM_ADDR_ACCESS_TYPE1",\r
- "ETM_ADDR_ACCESS_TYPE2",\r
- "ETM_ADDR_ACCESS_TYPE3",\r
- "ETM_ADDR_ACCESS_TYPE4",\r
- "ETM_ADDR_ACCESS_TYPE5",\r
- "ETM_ADDR_ACCESS_TYPE6",\r
- "ETM_ADDR_ACCESS_TYPE7",\r
- "ETM_ADDR_ACCESS_TYPE8",\r
- "ETM_ADDR_ACCESS_TYPE9",\r
- "ETM_ADDR_ACCESS_TYPE10",\r
- "ETM_ADDR_ACCESS_TYPE11",\r
- "ETM_ADDR_ACCESS_TYPE12",\r
- "ETM_ADDR_ACCESS_TYPE13",\r
- "ETM_ADDR_ACCESS_TYPE14",\r
- "ETM_ADDR_ACCESS_TYPE15",\r
- "ETM_ADDR_ACCESS_TYPE16",\r
- "ETM_DATA_COMPARATOR_VALUE1",\r
- "ETM_DATA_COMPARATOR_VALUE2",\r
- "ETM_DATA_COMPARATOR_VALUE3",\r
- "ETM_DATA_COMPARATOR_VALUE4",\r
- "ETM_DATA_COMPARATOR_VALUE5",\r
- "ETM_DATA_COMPARATOR_VALUE6",\r
- "ETM_DATA_COMPARATOR_VALUE7",\r
- "ETM_DATA_COMPARATOR_VALUE8",\r
- "ETM_DATA_COMPARATOR_VALUE9",\r
- "ETM_DATA_COMPARATOR_VALUE10",\r
- "ETM_DATA_COMPARATOR_VALUE11",\r
- "ETM_DATA_COMPARATOR_VALUE12",\r
- "ETM_DATA_COMPARATOR_VALUE13",\r
- "ETM_DATA_COMPARATOR_VALUE14",\r
- "ETM_DATA_COMPARATOR_VALUE15",\r
- "ETM_DATA_COMPARATOR_VALUE16",\r
- "ETM_DATA_COMPARATOR_MASK1",\r
- "ETM_DATA_COMPARATOR_MASK2",\r
- "ETM_DATA_COMPARATOR_MASK3",\r
- "ETM_DATA_COMPARATOR_MASK4",\r
- "ETM_DATA_COMPARATOR_MASK5",\r
- "ETM_DATA_COMPARATOR_MASK6",\r
- "ETM_DATA_COMPARATOR_MASK7",\r
- "ETM_DATA_COMPARATOR_MASK8",\r
- "ETM_DATA_COMPARATOR_MASK9",\r
- "ETM_DATA_COMPARATOR_MASK10",\r
- "ETM_DATA_COMPARATOR_MASK11",\r
- "ETM_DATA_COMPARATOR_MASK12",\r
- "ETM_DATA_COMPARATOR_MASK13",\r
- "ETM_DATA_COMPARATOR_MASK14",\r
- "ETM_DATA_COMPARATOR_MASK15",\r
- "ETM_DATA_COMPARATOR_MASK16",\r
- "ETM_COUNTER_INITAL_VALUE1",\r
- "ETM_COUNTER_INITAL_VALUE2",\r
- "ETM_COUNTER_INITAL_VALUE3",\r
- "ETM_COUNTER_INITAL_VALUE4",\r
- "ETM_COUNTER_ENABLE1",\r
- "ETM_COUNTER_ENABLE2",\r
- "ETM_COUNTER_ENABLE3",\r
- "ETM_COUNTER_ENABLE4",\r
- "ETM_COUNTER_RELOAD_VALUE1",\r
- "ETM_COUNTER_RELOAD_VALUE2",\r
- "ETM_COUNTER_RELOAD_VALUE3",\r
- "ETM_COUNTER_RELOAD_VALUE4",\r
- "ETM_COUNTER_VALUE1",\r
- "ETM_COUNTER_VALUE2",\r
- "ETM_COUNTER_VALUE3",\r
- "ETM_COUNTER_VALUE4",\r
- "ETM_SEQUENCER_CTRL1",\r
- "ETM_SEQUENCER_CTRL2",\r
- "ETM_SEQUENCER_CTRL3",\r
- "ETM_SEQUENCER_CTRL4",\r
- "ETM_SEQUENCER_CTRL5",\r
- "ETM_SEQUENCER_CTRL6",\r
- "ETM_SEQUENCER_STATE",\r
- "ETM_EXTERNAL_OUTPUT1",\r
- "ETM_EXTERNAL_OUTPUT2",\r
- "ETM_EXTERNAL_OUTPUT3",\r
- "ETM_EXTERNAL_OUTPUT4",\r
- "ETM_CONTEXTID_COMPARATOR_VALUE1",\r
- "ETM_CONTEXTID_COMPARATOR_VALUE2",\r
- "ETM_CONTEXTID_COMPARATOR_VALUE3",\r
- "ETM_CONTEXTID_COMPARATOR_MASK"\r
-}; \r
-\r
-int etm_reg_arch_type = -1;\r
-\r
-int etm_get_reg(reg_t *reg);\r
-int etm_set_reg(reg_t *reg, u32 value);\r
-\r
-int etm_write_reg(reg_t *reg, u32 value);\r
-int etm_read_reg(reg_t *reg);\r
-\r
-reg_cache_t* etm_build_reg_cache(target_t *target, arm_jtag_t *jtag_info, int extra_reg)\r
-{\r
- reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t));\r
- reg_t *reg_list = NULL;\r
- etm_reg_t *arch_info = NULL;\r
- int num_regs = sizeof(etm_reg_arch_info)/sizeof(int);\r
- int i;\r
- \r
- /* register a register arch-type for etm registers only once */\r
- if (etm_reg_arch_type == -1)\r
- etm_reg_arch_type = register_reg_arch_type(etm_get_reg, etm_set_reg_w_exec);\r
- \r
- /* the actual registers are kept in two arrays */\r
- reg_list = calloc(num_regs, sizeof(reg_t));\r
- arch_info = calloc(num_regs, sizeof(etm_reg_t));\r
- \r
- /* fill in values for the reg cache */\r
- reg_cache->name = "etm registers";\r
- reg_cache->next = NULL;\r
- reg_cache->reg_list = reg_list;\r
- reg_cache->num_regs = num_regs;\r
- \r
- /* set up registers */\r
- for (i = 0; i < num_regs; i++)\r
- {\r
- reg_list[i].name = etm_reg_list[i];\r
- reg_list[i].size = 32;\r
- reg_list[i].dirty = 0;\r
- reg_list[i].valid = 0;\r
- reg_list[i].bitfield_desc = NULL;\r
- reg_list[i].num_bitfields = 0;\r
- reg_list[i].value = calloc(1, 4);\r
- reg_list[i].arch_info = &arch_info[i];\r
- reg_list[i].arch_type = etm_reg_arch_type;\r
- reg_list[i].size = etm_reg_arch_size_info[i];\r
- arch_info[i].addr = etm_reg_arch_info[i];\r
- arch_info[i].jtag_info = jtag_info;\r
- }\r
- return reg_cache;\r
-}\r
-\r
-int etm_get_reg(reg_t *reg)\r
-{\r
- if (etm_read_reg(reg) != ERROR_OK)\r
- {\r
- ERROR("BUG: error scheduling etm register read");\r
- exit(-1);\r
- }\r
- \r
- if (jtag_execute_queue() != ERROR_OK)\r
- {\r
- ERROR("register read failed");\r
- }\r
- \r
- return ERROR_OK;\r
-}\r
-\r
-int etm_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)\r
-{\r
- etm_reg_t *etm_reg = reg->arch_info;\r
- u8 reg_addr = etm_reg->addr & 0x7f;\r
- scan_field_t fields[3];\r
- \r
- DEBUG("%i", etm_reg->addr);\r
-\r
- jtag_add_end_state(TAP_RTI);\r
- arm_jtag_scann(etm_reg->jtag_info, 0x6);\r
- arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr);\r
- \r
- fields[0].device = etm_reg->jtag_info->chain_pos;\r
- fields[0].num_bits = 32;\r
- fields[0].out_value = reg->value;\r
- fields[0].out_mask = NULL;\r
- fields[0].in_value = NULL;\r
- fields[0].in_check_value = NULL;\r
- fields[0].in_check_mask = NULL;\r
- fields[0].in_handler = NULL;\r
- fields[0].in_handler_priv = NULL;\r
- \r
- fields[1].device = etm_reg->jtag_info->chain_pos;\r
- fields[1].num_bits = 7;\r
- fields[1].out_value = malloc(1);\r
- buf_set_u32(fields[1].out_value, 0, 7, reg_addr);\r
- fields[1].out_mask = NULL;\r
- fields[1].in_value = NULL;\r
- fields[1].in_check_value = NULL;\r
- fields[1].in_check_mask = NULL;\r
- fields[1].in_handler = NULL;\r
- fields[1].in_handler_priv = NULL;\r
-\r
- fields[2].device = etm_reg->jtag_info->chain_pos;\r
- fields[2].num_bits = 1;\r
- fields[2].out_value = malloc(1);\r
- buf_set_u32(fields[2].out_value, 0, 1, 0);\r
- fields[2].out_mask = NULL;\r
- fields[2].in_value = NULL;\r
- fields[2].in_check_value = NULL;\r
- fields[2].in_check_mask = NULL;\r
- fields[2].in_handler = NULL;\r
- fields[2].in_handler_priv = NULL;\r
- \r
- jtag_add_dr_scan(3, fields, -1);\r
- \r
- fields[0].in_value = reg->value;\r
- fields[0].in_check_value = check_value;\r
- fields[0].in_check_mask = check_mask;\r
- \r
- jtag_add_dr_scan(3, fields, -1);\r
-\r
- free(fields[1].out_value);\r
- free(fields[2].out_value);\r
- \r
- return ERROR_OK;\r
-}\r
-\r
-int etm_read_reg(reg_t *reg)\r
-{\r
- return etm_read_reg_w_check(reg, NULL, NULL); \r
-}\r
-\r
-int etm_set_reg(reg_t *reg, u32 value)\r
-{\r
- if (etm_write_reg(reg, value) != ERROR_OK)\r
- {\r
- ERROR("BUG: error scheduling etm register write");\r
- exit(-1);\r
- }\r
- \r
- buf_set_u32(reg->value, 0, reg->size, value);\r
- reg->valid = 1;\r
- reg->dirty = 0;\r
- \r
- return ERROR_OK;\r
-}\r
-\r
-int etm_set_reg_w_exec(reg_t *reg, u32 value)\r
-{\r
- etm_set_reg(reg, value);\r
- \r
- if (jtag_execute_queue() != ERROR_OK)\r
- {\r
- ERROR("register write failed");\r
- exit(-1);\r
- }\r
- return ERROR_OK;\r
-}\r
-\r
-int etm_write_reg(reg_t *reg, u32 value)\r
-{\r
- etm_reg_t *etm_reg = reg->arch_info;\r
- u8 reg_addr = etm_reg->addr & 0x7f;\r
- scan_field_t fields[3];\r
- \r
- DEBUG("%i: 0x%8.8x", etm_reg->addr, value);\r
- \r
- jtag_add_end_state(TAP_RTI);\r
- arm_jtag_scann(etm_reg->jtag_info, 0x6);\r
- arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr);\r
- \r
- fields[0].device = etm_reg->jtag_info->chain_pos;\r
- fields[0].num_bits = 32;\r
- fields[0].out_value = malloc(4);\r
- buf_set_u32(fields[0].out_value, 0, 32, value);\r
- fields[0].out_mask = NULL;\r
- fields[0].in_value = NULL;\r
- fields[0].in_check_value = NULL;\r
- fields[0].in_check_mask = NULL;\r
- fields[0].in_handler = NULL;\r
- fields[0].in_handler_priv = NULL;\r
- \r
- fields[1].device = etm_reg->jtag_info->chain_pos;\r
- fields[1].num_bits = 7;\r
- fields[1].out_value = malloc(1);\r
- buf_set_u32(fields[1].out_value, 0, 7, reg_addr);\r
- fields[1].out_mask = NULL;\r
- fields[1].in_value = NULL;\r
- fields[1].in_check_value = NULL;\r
- fields[1].in_check_mask = NULL;\r
- fields[1].in_handler = NULL;\r
- fields[1].in_handler_priv = NULL;\r
-\r
- fields[2].device = etm_reg->jtag_info->chain_pos;\r
- fields[2].num_bits = 1;\r
- fields[2].out_value = malloc(1);\r
- buf_set_u32(fields[2].out_value, 0, 1, 1);\r
- fields[2].out_mask = NULL;\r
- fields[2].in_value = NULL;\r
- fields[2].in_check_value = NULL;\r
- fields[2].in_check_mask = NULL;\r
- fields[2].in_handler = NULL;\r
- fields[2].in_handler_priv = NULL;\r
- \r
- jtag_add_dr_scan(3, fields, -1);\r
- \r
- free(fields[0].out_value);\r
- free(fields[1].out_value);\r
- free(fields[2].out_value);\r
- \r
- return ERROR_OK;\r
-}\r
-\r
-int etm_store_reg(reg_t *reg)\r
-{\r
- return etm_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));\r
-}\r
-\r
+/***************************************************************************
+ * Copyright (C) 2005 by Dominic Rath *
+ * Dominic.Rath@gmx.de *
+ * *
+ * 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "etm.h"
+
+#include "armv4_5.h"
+#include "arm7_9_common.h"
+
+#include "log.h"
+#include "arm_jtag.h"
+#include "types.h"
+#include "binarybuffer.h"
+#include "target.h"
+#include "register.h"
+#include "jtag.h"
+
+#include <stdlib.h>
+
+bitfield_desc_t etm_comms_ctrl_bitfield_desc[] =
+{
+ {"R", 1},
+ {"W", 1},
+ {"reserved", 26},
+ {"version", 4}
+};
+
+int etm_reg_arch_info[] =
+{
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+};
+
+int etm_reg_arch_size_info[] =
+{
+ 32, 32, 17, 8, 3, 9, 32, 17,
+ 26, 16, 25, 8, 17, 32, 32, 17,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 16, 16, 16, 16, 18, 18, 18, 18,
+ 17, 17, 17, 17, 16, 16, 16, 16,
+ 17, 17, 17, 17, 17, 17, 2,
+ 17, 17, 17, 17, 32, 32, 32, 32
+};
+
+char* etm_reg_list[] =
+{
+ "ETM_CTRL",
+ "ETM_CONFIG",
+ "ETM_TRIG_EVENT",
+ "ETM_MMD_CTRL",
+ "ETM_STATUS",
+ "ETM_SYS_CONFIG",
+ "ETM_TRACE_RESOURCE_CTRL",
+ "ETM_TRACE_EN_CTRL2",
+ "ETM_TRACE_EN_EVENT",
+ "ETM_TRACE_EN_CTRL1",
+ "ETM_FIFOFULL_REGION",
+ "ETM_FIFOFULL_LEVEL",
+ "ETM_VIEWDATA_EVENT",
+ "ETM_VIEWDATA_CTRL1",
+ "ETM_VIEWDATA_CTRL2",
+ "ETM_VIEWDATA_CTRL3",
+ "ETM_ADDR_COMPARATOR_VALUE1",
+ "ETM_ADDR_COMPARATOR_VALUE2",
+ "ETM_ADDR_COMPARATOR_VALUE3",
+ "ETM_ADDR_COMPARATOR_VALUE4",
+ "ETM_ADDR_COMPARATOR_VALUE5",
+ "ETM_ADDR_COMPARATOR_VALUE6",
+ "ETM_ADDR_COMPARATOR_VALUE7",
+ "ETM_ADDR_COMPARATOR_VALUE8",
+ "ETM_ADDR_COMPARATOR_VALUE9",
+ "ETM_ADDR_COMPARATOR_VALUE10",
+ "ETM_ADDR_COMPARATOR_VALUE11",
+ "ETM_ADDR_COMPARATOR_VALUE12",
+ "ETM_ADDR_COMPARATOR_VALUE13",
+ "ETM_ADDR_COMPARATOR_VALUE14",
+ "ETM_ADDR_COMPARATOR_VALUE15",
+ "ETM_ADDR_COMPARATOR_VALUE16",
+ "ETM_ADDR_ACCESS_TYPE1",
+ "ETM_ADDR_ACCESS_TYPE2",
+ "ETM_ADDR_ACCESS_TYPE3",
+ "ETM_ADDR_ACCESS_TYPE4",
+ "ETM_ADDR_ACCESS_TYPE5",
+ "ETM_ADDR_ACCESS_TYPE6",
+ "ETM_ADDR_ACCESS_TYPE7",
+ "ETM_ADDR_ACCESS_TYPE8",
+ "ETM_ADDR_ACCESS_TYPE9",
+ "ETM_ADDR_ACCESS_TYPE10",
+ "ETM_ADDR_ACCESS_TYPE11",
+ "ETM_ADDR_ACCESS_TYPE12",
+ "ETM_ADDR_ACCESS_TYPE13",
+ "ETM_ADDR_ACCESS_TYPE14",
+ "ETM_ADDR_ACCESS_TYPE15",
+ "ETM_ADDR_ACCESS_TYPE16",
+ "ETM_DATA_COMPARATOR_VALUE1",
+ "ETM_DATA_COMPARATOR_VALUE2",
+ "ETM_DATA_COMPARATOR_VALUE3",
+ "ETM_DATA_COMPARATOR_VALUE4",
+ "ETM_DATA_COMPARATOR_VALUE5",
+ "ETM_DATA_COMPARATOR_VALUE6",
+ "ETM_DATA_COMPARATOR_VALUE7",
+ "ETM_DATA_COMPARATOR_VALUE8",
+ "ETM_DATA_COMPARATOR_VALUE9",
+ "ETM_DATA_COMPARATOR_VALUE10",
+ "ETM_DATA_COMPARATOR_VALUE11",
+ "ETM_DATA_COMPARATOR_VALUE12",
+ "ETM_DATA_COMPARATOR_VALUE13",
+ "ETM_DATA_COMPARATOR_VALUE14",
+ "ETM_DATA_COMPARATOR_VALUE15",
+ "ETM_DATA_COMPARATOR_VALUE16",
+ "ETM_DATA_COMPARATOR_MASK1",
+ "ETM_DATA_COMPARATOR_MASK2",
+ "ETM_DATA_COMPARATOR_MASK3",
+ "ETM_DATA_COMPARATOR_MASK4",
+ "ETM_DATA_COMPARATOR_MASK5",
+ "ETM_DATA_COMPARATOR_MASK6",
+ "ETM_DATA_COMPARATOR_MASK7",
+ "ETM_DATA_COMPARATOR_MASK8",
+ "ETM_DATA_COMPARATOR_MASK9",
+ "ETM_DATA_COMPARATOR_MASK10",
+ "ETM_DATA_COMPARATOR_MASK11",
+ "ETM_DATA_COMPARATOR_MASK12",
+ "ETM_DATA_COMPARATOR_MASK13",
+ "ETM_DATA_COMPARATOR_MASK14",
+ "ETM_DATA_COMPARATOR_MASK15",
+ "ETM_DATA_COMPARATOR_MASK16",
+ "ETM_COUNTER_INITAL_VALUE1",
+ "ETM_COUNTER_INITAL_VALUE2",
+ "ETM_COUNTER_INITAL_VALUE3",
+ "ETM_COUNTER_INITAL_VALUE4",
+ "ETM_COUNTER_ENABLE1",
+ "ETM_COUNTER_ENABLE2",
+ "ETM_COUNTER_ENABLE3",
+ "ETM_COUNTER_ENABLE4",
+ "ETM_COUNTER_RELOAD_VALUE1",
+ "ETM_COUNTER_RELOAD_VALUE2",
+ "ETM_COUNTER_RELOAD_VALUE3",
+ "ETM_COUNTER_RELOAD_VALUE4",
+ "ETM_COUNTER_VALUE1",
+ "ETM_COUNTER_VALUE2",
+ "ETM_COUNTER_VALUE3",
+ "ETM_COUNTER_VALUE4",
+ "ETM_SEQUENCER_CTRL1",
+ "ETM_SEQUENCER_CTRL2",
+ "ETM_SEQUENCER_CTRL3",
+ "ETM_SEQUENCER_CTRL4",
+ "ETM_SEQUENCER_CTRL5",
+ "ETM_SEQUENCER_CTRL6",
+ "ETM_SEQUENCER_STATE",
+ "ETM_EXTERNAL_OUTPUT1",
+ "ETM_EXTERNAL_OUTPUT2",
+ "ETM_EXTERNAL_OUTPUT3",
+ "ETM_EXTERNAL_OUTPUT4",
+ "ETM_CONTEXTID_COMPARATOR_VALUE1",
+ "ETM_CONTEXTID_COMPARATOR_VALUE2",
+ "ETM_CONTEXTID_COMPARATOR_VALUE3",
+ "ETM_CONTEXTID_COMPARATOR_MASK"
+};
+
+int etm_reg_arch_type = -1;
+
+int etm_get_reg(reg_t *reg);
+int etm_set_reg(reg_t *reg, u32 value);
+
+int etm_write_reg(reg_t *reg, u32 value);
+int etm_read_reg(reg_t *reg);
+
+reg_cache_t* etm_build_reg_cache(target_t *target, arm_jtag_t *jtag_info, int extra_reg)
+{
+ reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t));
+ reg_t *reg_list = NULL;
+ etm_reg_t *arch_info = NULL;
+ int num_regs = sizeof(etm_reg_arch_info)/sizeof(int);
+ int i;
+
+ /* register a register arch-type for etm registers only once */
+ if (etm_reg_arch_type == -1)
+ etm_reg_arch_type = register_reg_arch_type(etm_get_reg, etm_set_reg_w_exec);
+
+ /* the actual registers are kept in two arrays */
+ reg_list = calloc(num_regs, sizeof(reg_t));
+ arch_info = calloc(num_regs, sizeof(etm_reg_t));
+
+ /* fill in values for the reg cache */
+ reg_cache->name = "etm registers";
+ reg_cache->next = NULL;
+ reg_cache->reg_list = reg_list;
+ reg_cache->num_regs = num_regs;
+
+ /* set up registers */
+ for (i = 0; i < num_regs; i++)
+ {
+ reg_list[i].name = etm_reg_list[i];
+ reg_list[i].size = 32;
+ reg_list[i].dirty = 0;
+ reg_list[i].valid = 0;
+ reg_list[i].bitfield_desc = NULL;
+ reg_list[i].num_bitfields = 0;
+ reg_list[i].value = calloc(1, 4);
+ reg_list[i].arch_info = &arch_info[i];
+ reg_list[i].arch_type = etm_reg_arch_type;
+ reg_list[i].size = etm_reg_arch_size_info[i];
+ arch_info[i].addr = etm_reg_arch_info[i];
+ arch_info[i].jtag_info = jtag_info;
+ }
+ return reg_cache;
+}
+
+int etm_get_reg(reg_t *reg)
+{
+ if (etm_read_reg(reg) != ERROR_OK)
+ {
+ ERROR("BUG: error scheduling etm register read");
+ exit(-1);
+ }
+
+ if (jtag_execute_queue() != ERROR_OK)
+ {
+ ERROR("register read failed");
+ }
+
+ return ERROR_OK;
+}
+
+int etm_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
+{
+ etm_reg_t *etm_reg = reg->arch_info;
+ u8 reg_addr = etm_reg->addr & 0x7f;
+ scan_field_t fields[3];
+
+ DEBUG("%i", etm_reg->addr);
+
+ jtag_add_end_state(TAP_RTI);
+ arm_jtag_scann(etm_reg->jtag_info, 0x6);
+ arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr);
+
+ fields[0].device = etm_reg->jtag_info->chain_pos;
+ fields[0].num_bits = 32;
+ fields[0].out_value = reg->value;
+ fields[0].out_mask = NULL;
+ fields[0].in_value = NULL;
+ fields[0].in_check_value = NULL;
+ fields[0].in_check_mask = NULL;
+ fields[0].in_handler = NULL;
+ fields[0].in_handler_priv = NULL;
+
+ fields[1].device = etm_reg->jtag_info->chain_pos;
+ fields[1].num_bits = 7;
+ fields[1].out_value = malloc(1);
+ buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
+ fields[1].out_mask = NULL;
+ fields[1].in_value = NULL;
+ fields[1].in_check_value = NULL;
+ fields[1].in_check_mask = NULL;
+ fields[1].in_handler = NULL;
+ fields[1].in_handler_priv = NULL;
+
+ fields[2].device = etm_reg->jtag_info->chain_pos;
+ fields[2].num_bits = 1;
+ fields[2].out_value = malloc(1);
+ buf_set_u32(fields[2].out_value, 0, 1, 0);
+ fields[2].out_mask = NULL;
+ fields[2].in_value = NULL;
+ fields[2].in_check_value = NULL;
+ fields[2].in_check_mask = NULL;
+ fields[2].in_handler = NULL;
+ fields[2].in_handler_priv = NULL;
+
+ jtag_add_dr_scan(3, fields, -1);
+
+ fields[0].in_value = reg->value;
+ fields[0].in_check_value = check_value;
+ fields[0].in_check_mask = check_mask;
+
+ jtag_add_dr_scan(3, fields, -1);
+
+ free(fields[1].out_value);
+ free(fields[2].out_value);
+
+ return ERROR_OK;
+}
+
+int etm_read_reg(reg_t *reg)
+{
+ return etm_read_reg_w_check(reg, NULL, NULL);
+}
+
+int etm_set_reg(reg_t *reg, u32 value)
+{
+ if (etm_write_reg(reg, value) != ERROR_OK)
+ {
+ ERROR("BUG: error scheduling etm register write");
+ exit(-1);
+ }
+
+ buf_set_u32(reg->value, 0, reg->size, value);
+ reg->valid = 1;
+ reg->dirty = 0;
+
+ return ERROR_OK;
+}
+
+int etm_set_reg_w_exec(reg_t *reg, u32 value)
+{
+ etm_set_reg(reg, value);
+
+ if (jtag_execute_queue() != ERROR_OK)
+ {
+ ERROR("register write failed");
+ exit(-1);
+ }
+ return ERROR_OK;
+}
+
+int etm_write_reg(reg_t *reg, u32 value)
+{
+ etm_reg_t *etm_reg = reg->arch_info;
+ u8 reg_addr = etm_reg->addr & 0x7f;
+ scan_field_t fields[3];
+
+ DEBUG("%i: 0x%8.8x", etm_reg->addr, value);
+
+ jtag_add_end_state(TAP_RTI);
+ arm_jtag_scann(etm_reg->jtag_info, 0x6);
+ arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr);
+
+ fields[0].device = etm_reg->jtag_info->chain_pos;
+ fields[0].num_bits = 32;
+ fields[0].out_value = malloc(4);
+ buf_set_u32(fields[0].out_value, 0, 32, value);
+ fields[0].out_mask = NULL;
+ fields[0].in_value = NULL;
+ fields[0].in_check_value = NULL;
+ fields[0].in_check_mask = NULL;
+ fields[0].in_handler = NULL;
+ fields[0].in_handler_priv = NULL;
+
+ fields[1].device = etm_reg->jtag_info->chain_pos;
+ fields[1].num_bits = 7;
+ fields[1].out_value = malloc(1);
+ buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
+ fields[1].out_mask = NULL;
+ fields[1].in_value = NULL;
+ fields[1].in_check_value = NULL;
+ fields[1].in_check_mask = NULL;
+ fields[1].in_handler = NULL;
+ fields[1].in_handler_priv = NULL;
+
+ fields[2].device = etm_reg->jtag_info->chain_pos;
+ fields[2].num_bits = 1;
+ fields[2].out_value = malloc(1);
+ buf_set_u32(fields[2].out_value, 0, 1, 1);
+ fields[2].out_mask = NULL;
+ fields[2].in_value = NULL;
+ fields[2].in_check_value = NULL;
+ fields[2].in_check_mask = NULL;
+ fields[2].in_handler = NULL;
+ fields[2].in_handler_priv = NULL;
+
+ jtag_add_dr_scan(3, fields, -1);
+
+ free(fields[0].out_value);
+ free(fields[1].out_value);
+ free(fields[2].out_value);
+
+ return ERROR_OK;
+}
+
+int etm_store_reg(reg_t *reg)
+{
+ return etm_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
+}
+
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "register.h"
#include "log.h"
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
+
#include "target.h"
#include "log.h"
u8 *buffer;
u32 buf_cnt;
- struct timeval start, end;
+ struct timeval start, end, duration;
target_t *target = get_current_target(cmd_ctx);
return ERROR_OK;
}
- if (!(binary = fopen(args[0], "r")))
+ if (!(binary = fopen(args[0], "rb")))
{
ERROR("couldn't open %s: %s", args[0], strerror(errno));
command_print(cmd_ctx, "error accessing file %s", args[0]);
free(buffer);
- command_print(cmd_ctx, "downloaded %lli byte in %is %ius", (long long) binary_stat.st_size, end.tv_sec - start.tv_sec, end.tv_usec - start.tv_usec);
+ timeval_subtract(&duration, &end, &start);
+ command_print(cmd_ctx, "downloaded %lli byte in %is %ius", (long long) binary_stat.st_size, duration.tv_sec, duration.tv_usec);
fclose(binary);
address = strtoul(args[1], NULL, 0);
size = strtoul(args[2], NULL, 0);
- if (!(binary = fopen(args[0], "w")))
+ if (!(binary = fopen(args[0], "wb")))
{
ERROR("couldn't open %s for writing: %s", args[0], strerror(errno));
command_print(cmd_ctx, "error accessing file %s", args[0]);
-INCLUDES = -I$(top_srcdir)/src/gdb -I$(top_srcdir)/src/helper -I$(top_srcdir)/src/jtag $(all_includes)
+INCLUDES = -I$(top_srcdir)/src/server -I$(top_srcdir)/src/helper -I$(top_srcdir)/src/jtag $(all_includes)
METASOURCES = AUTO
noinst_LIBRARIES = libxsvf.a
noinst_HEADERS = xsvf.h
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "xsvf.h"
#include "jtag.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <netinet/in.h>
#include <string.h>
#include <sys/time.h>
int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
char c;
+ u8 buf4[4], buf2[2];
unsigned char uc, uc2;
unsigned int ui;
unsigned short us;
break;
case 0x04: /* XRUNTEST */
DEBUG("XRUNTEST");
- if (read(xsvf_fd, &ui, 4) < 0)
+ if (read(xsvf_fd, buf4, 4) < 0)
do_abort = 1;
else
{
- xruntest = ntohl(ui);
+ xruntest = be_to_h_u32(buf4);
}
break;
case 0x07: /* XREPEAT */
break;
case 0x08: /* XSDRSIZE */
DEBUG("XSDRSIZE");
- if (read(xsvf_fd, &ui, 4) < 0)
+ if (read(xsvf_fd, buf4, 4) < 0)
do_abort = 1;
else
{
- xsdrsize = ntohl(ui);
+ xsdrsize = be_to_h_u32(buf4);
free(dr_out_buf);
free(dr_in_buf);
free(dr_in_mask);
break;
case 0x15: /* XSIR2 */
DEBUG("XSIR2");
- if (read(xsvf_fd, &us, 2) < 0)
+ if (read(xsvf_fd, buf2, 2) < 0)
do_abort = 1;
else
{
u8 *ir_buf;
- us = ntohs(us);
+ us = be_to_h_u16(buf2);
ir_buf = malloc((us + 7) / 8);
if (xsvf_read_buffer(us, xsvf_fd, ir_buf) != ERROR_OK)
do_abort = 1;
break;
case 0x17: /* XWAIT */
DEBUG("XWAIT");
- if ((read(xsvf_fd, &uc, 1) < 0) || (read(xsvf_fd, &uc2, 1) < 0) || (read(xsvf_fd, &ui, 4) < 0))
+ if ((read(xsvf_fd, &uc, 1) < 0) || (read(xsvf_fd, &uc2, 1) < 0) || (read(xsvf_fd, buf4, 4) < 0))
do_abort = 1;
else
{
jtag_add_statemove(xsvf_to_tap[uc]);
- ui = ntohl(ui);
+ ui = be_to_h_u32(buf4);
jtag_add_sleep(ui);
jtag_add_statemove(xsvf_to_tap[uc2]);
}