URL
https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk
Subversion Repositories openrisc_me
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/or1ksim/debug
- from Rev 80 to Rev 82
- ↔ Reverse comparison
Rev 80 → Rev 82
/Makefile.in
1,8 → 1,9
# Makefile.in generated by automake 1.10.1 from Makefile.am. |
# Makefile.in generated by automake 1.11.1 from Makefile.am. |
# @configure_input@ |
|
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, |
# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. |
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, |
# Inc. |
# This Makefile.in is free software; the Free Software Foundation |
# gives unlimited permission to copy and/or distribute it, |
# with or without modifications, as long as this notice is preserved. |
38,8 → 39,9
|
VPATH = @srcdir@ |
pkgdatadir = $(datadir)/@PACKAGE@ |
pkgincludedir = $(includedir)/@PACKAGE@ |
pkglibdir = $(libdir)/@PACKAGE@ |
pkgincludedir = $(includedir)/@PACKAGE@ |
pkglibexecdir = $(libexecdir)/@PACKAGE@ |
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd |
install_sh_DATA = $(install_sh) -c -m 644 |
install_sh_PROGRAM = $(install_sh) -c |
58,19 → 60,25
subdir = debug |
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in |
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 |
am__aclocal_m4_deps = $(top_srcdir)/configure.ac |
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ |
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ |
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ |
$(top_srcdir)/configure.ac |
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ |
$(ACLOCAL_M4) |
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs |
CONFIG_HEADER = $(top_builddir)/config.h |
CONFIG_CLEAN_FILES = |
CONFIG_CLEAN_VPATH_FILES = |
LTLIBRARIES = $(noinst_LTLIBRARIES) |
libdebug_la_LIBADD = |
am_libdebug_la_OBJECTS = debug-unit.lo gdbcomm.lo rsp-server.lo |
am_libdebug_la_OBJECTS = debug-unit.lo gdbcomm.lo jtag.lo \ |
rsp-server.lo |
libdebug_la_OBJECTS = $(am_libdebug_la_OBJECTS) |
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) |
depcomp = $(SHELL) $(top_srcdir)/depcomp |
am__depfiles_maybe = depfiles |
am__mv = mv -f |
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ |
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) |
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ |
95,27 → 103,26
AWK = @AWK@ |
BUILD_DIR = @BUILD_DIR@ |
CC = @CC@ |
CCAS = @CCAS@ |
CCASDEPMODE = @CCASDEPMODE@ |
CCASFLAGS = @CCASFLAGS@ |
CCDEPMODE = @CCDEPMODE@ |
CFLAGS = @CFLAGS@ |
CPP = @CPP@ |
CPPFLAGS = @CPPFLAGS@ |
CPU_ARCH = @CPU_ARCH@ |
CXX = @CXX@ |
CXXCPP = @CXXCPP@ |
CXXDEPMODE = @CXXDEPMODE@ |
CXXFLAGS = @CXXFLAGS@ |
CYGPATH_W = @CYGPATH_W@ |
DEBUGFLAGS = @DEBUGFLAGS@ |
DEFS = @DEFS@ |
DEPDIR = @DEPDIR@ |
ECHO = @ECHO@ |
DSYMUTIL = @DSYMUTIL@ |
DUMPBIN = @DUMPBIN@ |
ECHO_C = @ECHO_C@ |
ECHO_N = @ECHO_N@ |
ECHO_T = @ECHO_T@ |
EGREP = @EGREP@ |
EXEEXT = @EXEEXT@ |
F77 = @F77@ |
FFLAGS = @FFLAGS@ |
FGREP = @FGREP@ |
GREP = @GREP@ |
INCLUDES = @INCLUDES@ |
INSTALL = @INSTALL@ |
123,10 → 130,12
INSTALL_PROGRAM = @INSTALL_PROGRAM@ |
INSTALL_SCRIPT = @INSTALL_SCRIPT@ |
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ |
LD = @LD@ |
LDFLAGS = @LDFLAGS@ |
LIBOBJS = @LIBOBJS@ |
LIBS = @LIBS@ |
LIBTOOL = @LIBTOOL@ |
LIPO = @LIPO@ |
LN_S = @LN_S@ |
LOCAL_CFLAGS = @LOCAL_CFLAGS@ |
LOCAL_DEFS = @LOCAL_DEFS@ |
135,7 → 144,12
MAKEINFO = @MAKEINFO@ |
MAKE_SHELL = @MAKE_SHELL@ |
MKDIR_P = @MKDIR_P@ |
NM = @NM@ |
NMEDIT = @NMEDIT@ |
OBJDUMP = @OBJDUMP@ |
OBJEXT = @OBJEXT@ |
OTOOL = @OTOOL@ |
OTOOL64 = @OTOOL64@ |
PACKAGE = @PACKAGE@ |
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ |
PACKAGE_NAME = @PACKAGE_NAME@ |
152,13 → 166,13
SUMVERSION = @SUMVERSION@ |
TERMCAP_LIB = @TERMCAP_LIB@ |
VERSION = @VERSION@ |
_GNU_SOURCE = @_GNU_SOURCE@ |
abs_builddir = @abs_builddir@ |
abs_srcdir = @abs_srcdir@ |
abs_top_builddir = @abs_top_builddir@ |
abs_top_srcdir = @abs_top_srcdir@ |
ac_ct_CC = @ac_ct_CC@ |
ac_ct_CXX = @ac_ct_CXX@ |
ac_ct_F77 = @ac_ct_F77@ |
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ |
am__include = @am__include@ |
am__leading_dot = @am__leading_dot@ |
am__quote = @am__quote@ |
189,6 → 203,7
libexecdir = @libexecdir@ |
localedir = @localedir@ |
localstatedir = @localstatedir@ |
lt_ECHO = @lt_ECHO@ |
mandir = @mandir@ |
mkdir_p = @mkdir_p@ |
oldincludedir = @oldincludedir@ |
199,6 → 214,7
sbindir = @sbindir@ |
sharedstatedir = @sharedstatedir@ |
srcdir = @srcdir@ |
subdirs = @subdirs@ |
sysconfdir = @sysconfdir@ |
target = @target@ |
target_alias = @target_alias@ |
205,15 → 221,18
target_cpu = @target_cpu@ |
target_os = @target_os@ |
target_vendor = @target_vendor@ |
top_build_prefix = @top_build_prefix@ |
top_builddir = @top_builddir@ |
top_srcdir = @top_srcdir@ |
noinst_LTLIBRARIES = libdebug.la |
libdebug_la_SOURCES = debug-unit.c \ |
debug-unit.h \ |
gdb.h \ |
gdbcomm.c \ |
gdbcomm.h \ |
jtag.c \ |
jtag.h \ |
rsp-server.c \ |
debug-unit.h \ |
gdbcomm.h \ |
gdb.h \ |
rsp-server.h |
|
all: all-am |
224,14 → 243,14
@for dep in $?; do \ |
case '$(am__configure_deps)' in \ |
*$$dep*) \ |
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ |
&& exit 0; \ |
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ |
&& { if test -f $@; then exit 0; else break; fi; }; \ |
exit 1;; \ |
esac; \ |
done; \ |
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu debug/Makefile'; \ |
cd $(top_srcdir) && \ |
$(AUTOMAKE) --gnu debug/Makefile |
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu debug/Makefile'; \ |
$(am__cd) $(top_srcdir) && \ |
$(AUTOMAKE) --gnu debug/Makefile |
.PRECIOUS: Makefile |
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status |
@case '$?' in \ |
249,6 → 268,7
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh |
$(ACLOCAL_M4): $(am__aclocal_m4_deps) |
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh |
$(am__aclocal_m4_deps): |
|
clean-noinstLTLIBRARIES: |
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) |
269,11 → 289,12
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug-unit.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdbcomm.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jtag.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsp-server.Plo@am__quote@ |
|
.c.o: |
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< |
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po |
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
@am__fastdepCC_FALSE@ $(COMPILE) -c $< |
280,7 → 301,7
|
.c.obj: |
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` |
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po |
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` |
287,7 → 308,7
|
.c.lo: |
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< |
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo |
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< |
303,7 → 324,7
unique=`for i in $$list; do \ |
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ |
done | \ |
$(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ |
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \ |
END { if (nonempty) { for (i in files) print i; }; }'`; \ |
mkid -fID $$unique |
tags: TAGS |
310,7 → 331,7
|
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ |
$(TAGS_FILES) $(LISP) |
tags=; \ |
set x; \ |
here=`pwd`; \ |
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ |
unique=`for i in $$list; do \ |
318,15 → 339,20
done | \ |
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \ |
END { if (nonempty) { for (i in files) print i; }; }'`; \ |
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ |
shift; \ |
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ |
test -n "$$unique" || unique=$$empty_fix; \ |
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ |
$$tags $$unique; \ |
if test $$# -gt 0; then \ |
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ |
"$$@" $$unique; \ |
else \ |
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ |
$$unique; \ |
fi; \ |
fi |
ctags: CTAGS |
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ |
$(TAGS_FILES) $(LISP) |
tags=; \ |
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ |
unique=`for i in $$list; do \ |
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ |
333,14 → 359,14
done | \ |
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \ |
END { if (nonempty) { for (i in files) print i; }; }'`; \ |
test -z "$(CTAGS_ARGS)$$tags$$unique" \ |
test -z "$(CTAGS_ARGS)$$unique" \ |
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ |
$$tags $$unique |
$$unique |
|
GTAGS: |
here=`$(am__cd) $(top_builddir) && pwd` \ |
&& cd $(top_srcdir) \ |
&& gtags -i $(GTAGS_ARGS) $$here |
&& $(am__cd) $(top_srcdir) \ |
&& gtags -i $(GTAGS_ARGS) "$$here" |
|
distclean-tags: |
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags |
361,13 → 387,17
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ |
if test -d $$d/$$file; then \ |
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ |
if test -d "$(distdir)/$$file"; then \ |
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ |
fi; \ |
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ |
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ |
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ |
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ |
fi; \ |
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ |
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ |
else \ |
test -f $(distdir)/$$file \ |
|| cp -p $$d/$$file $(distdir)/$$file \ |
test -f "$(distdir)/$$file" \ |
|| cp -p $$d/$$file "$(distdir)/$$file" \ |
|| exit 1; \ |
fi; \ |
done |
395,6 → 425,7
|
distclean-generic: |
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) |
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) |
|
maintainer-clean-generic: |
@echo "This command is intended for maintainers to use" |
416,6 → 447,8
|
html: html-am |
|
html-am: |
|
info: info-am |
|
info-am: |
424,18 → 457,28
|
install-dvi: install-dvi-am |
|
install-dvi-am: |
|
install-exec-am: |
|
install-html: install-html-am |
|
install-html-am: |
|
install-info: install-info-am |
|
install-info-am: |
|
install-man: |
|
install-pdf: install-pdf-am |
|
install-pdf-am: |
|
install-ps: install-ps-am |
|
install-ps-am: |
|
installcheck-am: |
|
maintainer-clean: maintainer-clean-am |
473,6 → 516,7
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ |
pdf pdf-am ps ps-am tags uninstall uninstall-am |
|
|
# Tell versions [3.59,3.63) of GNU make to not export all variables. |
# Otherwise a system limit (for SysV at least) may be exceeded. |
.NOEXPORT: |
/debug-unit.c
208,8 → 208,8
unsigned char mp[MAX_MATCHPOINTS]; /* Which matchpoints matched */ |
unsigned char wp[MAX_WATCHPOINTS]; /* Which watchpoints matched */ |
|
memset (mp, sizeof (mp), 0); |
memset (wp, sizeof (wp), 0); |
memset (mp, 0, sizeof (mp)); |
memset (wp, 0, sizeof (wp)); |
|
/* First find the matchpoints */ |
|
/jtag.c
0,0 → 1,1626
/* jtag.c -- JTAG modeling |
|
Copyright (C) 2008 Embecosm Limited |
|
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com> |
|
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 <http://www.gnu.org/licenses/>. */ |
|
/* This program is commented throughout in a fashion suitable for processing |
with Doxygen. */ |
|
|
/* Autoconf and/or portability configuration */ |
#include "config.h" |
#include "port.h" |
|
/* System includes */ |
#include <stdlib.h> |
#include <unistd.h> |
#include <stddef.h> |
#include <stdint.h> |
#include <string.h> |
|
/* Package includes */ |
#include "sim-config.h" |
#include "sprs.h" |
#include "debug-unit.h" |
#include "spr-defs.h" |
#include "jtag.h" |
#include "abstract.h" |
#include "toplevel-support.h" |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Calculate an ongoing 32-bit CRC for a value |
|
Utility function. This is for a CRC, where the value is presented in normal |
order (i.e its most significant bit is at the most significant positions, |
it has not been reversed for incorporating ina JTAG register). |
|
The function can be used for values with more than 64 bits, but will treat |
the supplied value as the most-significant 64 bits, with all other bits |
zero. In practice this is only of use when shifting in a large number of |
zeros. |
|
The CRC used is the IEEE 802.3 32-bit CRC using the polynomial: |
|
x^32 + x^26 + x^23 +x^22 +x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + |
x^4 + x^2 + x^1 + 1 |
|
In this implementation, the CRC is initialized to all ones (outside this |
function), to catch leading zeros. |
|
The function is designed to be used in a continuing calculation if |
desired. It takes a partially computed CRC and shifts in the appropriate |
new bits for the value supplied. For a new calculation, this value should |
be 0xffffffff. |
|
@param[in] value The number whose CRC is wanted (MSB first) |
@param[in] num_bits The number of bits to use from value |
@param[in] crc_in The value of the CRC computed so far |
|
@return The updated CRC value */ |
/*---------------------------------------------------------------------------*/ |
static uint32_t |
crc32 (uint64_t value, |
int num_bits, |
uint32_t crc_in) |
{ |
static const uint32_t CRC32_POLY = 0x04c11db7; |
|
/* Incorporate the bits, MS bit first. */ |
int i; |
|
for (i = num_bits - 1; i >= 0; i--) |
{ |
uint32_t d = (1 == ((value >> i) & 1)) ? 0xfffffff : 0x0000000; |
uint32_t t = (1 == ((crc_in >> 31) & 1)) ? 0xfffffff : 0x0000000; |
|
crc_in <<= 1; |
crc_in ^= (d ^ t) & CRC32_POLY; |
} |
|
return crc_in; |
|
} /* crc32 () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Reverse up to 64 bits in a word |
|
Utility function. Uses the "reverse" algorithm from the University of |
Kentucky Aggregate Magic Algorithms. |
|
@param[in] val The long word to reverse |
@param[in] numBits Number of bits to reverse |
|
@return The reversed word. */ |
/*---------------------------------------------------------------------------*/ |
static uint64_t |
reverse_bits (uint64_t val, |
int numBits) |
{ |
val = (((val & 0xaaaaaaaaaaaaaaaaULL) >> 1) | |
((val & 0x5555555555555555ULL) << 1)); |
val = (((val & 0xccccccccccccccccULL) >> 2) | |
((val & 0x3333333333333333ULL) << 2)); |
val = (((val & 0xf0f0f0f0f0f0f0f0ULL) >> 4) | |
((val & 0x0f0f0f0f0f0f0f0fULL) << 4)); |
val = (((val & 0xff00ff00ff00ff00ULL) >> 8) | |
((val & 0x00ff00ff00ff00ffULL) << 8)); |
val = (((val & 0xffff0000ffff0000ULL) >> 16) | |
((val & 0x00000fff0000ffffULL) << 16)); |
val = ((val >> 32) | (val << 32)); |
|
return val >> (64 - numBits); /* Only the bits we want */ |
|
} /* reverse_bits () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Reverse a byte |
|
Utility function. Uses the "reverse" algorithm from the University of |
Kentucky Aggregate Magic Algorithms. |
|
@param[in] byte The byte to reverse |
|
@return The reversed byte. */ |
/*---------------------------------------------------------------------------*/ |
static uint8_t |
reverse_byte (uint8_t byte) |
{ |
byte = (((byte & 0xaa) >> 1) | ((byte & 0x55) << 1)); |
byte = (((byte & 0xcc) >> 2) | ((byte & 0x33) << 2)); |
|
return ((byte >> 4) | (byte << 4)); |
|
} /* reverse_byte () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Construct a response register to shift out. |
|
The generic format is: |
|
+-------+--------+---------+---------+ |
| | | | | |
TDI -> | CRC | Status | XX..XX | 00..00 | -> TDO |
| | | | | |
+-------+--------+---------+---------+ |
32 4 "ignored" "zero" |
bits bits bits bits |
|
|
Fields are always shifted in MS bit first, so must be reversed. The CRC is |
on the 4 status bits. Only the "zero" bits are zeroed. This allows for |
other fields to be specified in the "ignored" bits region, which are |
guaranteed to be left untouched. |
|
@param[out] jreg The buffer for the constructed register |
@param[in] status The status bits |
@param[in] crc_in CRC computed so far (set to 0xffffffff if none) |
@param[in] ign_bits The number of bits to ignore |
@param[in] zero_bits The number of bits to zero |
|
@return The register length in bits */ |
/*---------------------------------------------------------------------------*/ |
static int |
construct_response (unsigned char *jreg, |
uint8_t status, |
uint32_t crc_in, |
unsigned int ign_bits, |
unsigned int zero_bits) |
{ |
/* Construct the outgoing CRC */ |
uint32_t crc_out = crc32 (status, 4, crc_in); |
|
/* Reversed versions of fields ready for insertion */ |
uint8_t status_r = reverse_bits (status, 4); |
uint32_t crc_out_r = reverse_bits (crc_out, 32); |
|
/* Construct the response register */ |
unsigned int zero_bytes = zero_bits / 8; |
unsigned int zero_off = zero_bits % 8; |
|
/* Clear the zero bits */ |
if (zero_bytes > 0) |
{ |
memset (jreg, 0, zero_bytes); |
} |
|
jreg[zero_bytes] >>= zero_off; |
jreg[zero_bytes] <<= zero_off; |
|
/* Determine how much to skip in total */ |
unsigned int skip_bytes = ign_bits + zero_bits / 8; |
unsigned int bit_off = ign_bits + zero_bits % 8; |
|
/* Simplify by dealing separately with two cases: |
- the bit offset is less than or equal to 4, so the status goes in the |
first free byte, with some CRC. |
- the bit offset is greater than 4 but less than 8, so the status goes in |
the first and second free bytes. |
|
For completeness we deal with what should be the impossible case of |
bit_off > 7. */ |
if (bit_off <= 4) |
{ |
/* Note that this works even if bit_off == 4, since there will be no CRC |
remaining to OR into the first byte. */ |
jreg[skip_bytes] |= ((status_r & 0xf) << bit_off) | |
((crc_out_r << (4 + bit_off)) & 0xff); |
jreg[skip_bytes + 1] = (crc_out_r >> ( 4 - bit_off)) & 0xff; |
jreg[skip_bytes + 2] = (crc_out_r >> (12 - bit_off)) & 0xff; |
jreg[skip_bytes + 3] = (crc_out_r >> (20 - bit_off)) & 0xff; |
jreg[skip_bytes + 4] = (crc_out_r >> (28 - bit_off)) & 0xff; |
} |
else if (bit_off < 8) |
{ |
jreg[skip_bytes] |= status_r << bit_off; |
jreg[skip_bytes + 1] = (status_r >> (8 - bit_off)) | |
((crc_out_r << (bit_off - 4)) & 0xff); |
jreg[skip_bytes + 2] = (crc_out_r >> (12 - bit_off)) & 0xff; |
jreg[skip_bytes + 3] = (crc_out_r >> (20 - bit_off)) & 0xff; |
jreg[skip_bytes + 4] = (crc_out_r >> (28 - bit_off)) & 0xff; |
jreg[skip_bytes + 5] = (crc_out_r >> (36 - bit_off)) & 0xff; |
} |
else |
{ |
fprintf (stderr, "*** ABORT ***: construct_response: impossible bit " |
"offset: %u\n", bit_off); |
abort (); |
} |
|
/* Result is the register length in bits */ |
return 32 + 4 + skip_bytes; |
|
} /* construct_response () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Select a module for debug |
|
Process a module selection register. The format is: |
|
+---------+-------+--------+---+ |
| | | | | |
TDI -> | Ignored | CRC | Module | 1 | -> TDO |
| | | ID | | |
+---------+-------+--------+---+ |
36 32 4 |
bits bits bits |
|
The returned register has the format: |
|
+-------+--------+---------+ |
| | | | |
TDI -> | CRC | Status | 00..00 | -> TDO |
| | | | |
+-------+--------+---------+ |
32 4 37 |
bits bits bits |
|
|
Fields are always shifted in MS bit first, so must be reversed. The CRC in |
is computed on the first 5 bits, the CRC out on the 4 status bits. |
|
@param[in,out] jreg The register to shift in, and the register shifted |
back out. |
|
@return The number of cycles the shift took, which in turn is the number |
of bits in the register */ |
/*---------------------------------------------------------------------------*/ |
static int |
module_select (unsigned char *jreg) |
{ |
/* Break out the fields */ |
uint8_t mod_id = reverse_bits ((jreg[0] >> 1) & 0xf, 4); |
uint32_t crc_in = reverse_bits (((uint32_t ) jreg[0] & 0xe0 >> 5) | |
((uint32_t ) jreg[1] << 3) | |
((uint32_t ) jreg[2] << 11) | |
((uint32_t ) jreg[3] << 19) | |
((uint32_t ) (jreg[4] & 0x1f) << 27), 32); |
|
/* Compute the expected CRC */ |
uint32_t crc_computed; |
|
crc_computed = crc32 (1, 1, 0xffffffff); |
crc_computed = crc32 (mod_id, 4, crc_computed); |
|
/* Status flags */ |
enum jtag_status status = JS_OK; |
|
/* Validate the CRC */ |
if (crc_computed != crc_in) |
{ |
/* Mismatch: record the error */ |
status |= JS_CRC_IN_ERROR; |
} |
else |
{ |
/* Is it a valid module? */ |
switch (mod_id) |
{ |
case JM_WISHBONE: |
case JM_CPU0: |
case JM_CPU1: |
/* All valid. Record the module */ |
runtime.debug.mod_id = mod_id; |
|
break; |
|
default: |
/* Bad module: record the error */ |
status |= JS_MODULE_MISSING; |
break; |
} |
} |
|
/* Construct the outgoing register and return the JTAG cycles taken (the |
register length) */ |
return construct_response (jreg, status, 0xffffffff, 0, 37); |
|
} /* module_select */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Validate WRITE_COMMAND fields for WishBone |
|
Check that a WRITE_COMMAND's fields are valid for WishBone access. |
|
- 16 and 32-bit access must be correctly aligned. If not a warning is |
printed and validation fails. |
|
- size must be a multiple of 2 for 16-bit access, and a multiple of 4 for |
32-bit access |
|
Validation is carried out when executing a GO_COMMAND, rather than when |
setting the WRITE_COMMAND, because only the GO_COMMAND can set the status |
error if there is a problem. |
|
Warning messages are printed to explain any validation problems. |
|
@todo Should multiple SPR accesses be allowed in a single access? |
|
@note The size of the data is one greater than the length specified in the |
original WRITE_COMMAND. |
|
@return 1 (TRUE) if validation is OK, 0 (FALSE) if validation fails. */ |
/*---------------------------------------------------------------------------*/ |
static int |
validate_wb_fields () |
{ |
/* Determine the size of the access */ |
uint32_t access_bits; |
|
switch (runtime.debug.acc_type) |
{ |
case JAT_WRITE8: |
case JAT_READ8: |
access_bits = 8; |
break; |
|
case JAT_WRITE16: |
case JAT_READ16: |
access_bits = 16; |
break; |
|
case JAT_WRITE32: |
case JAT_READ32: |
access_bits = 32; |
break; |
|
default: |
fprintf (stderr, "*** ABORT ***: validate_wb_fields: unknown access " |
"type %u\n", runtime.debug.acc_type); |
abort (); |
} |
|
/* Check for validity. This works for 8-bit, although the tests will always |
pass. */ |
uint32_t access_bytes = access_bits / 8; |
|
if (0 != (runtime.debug.addr % access_bytes)) |
{ |
fprintf (stderr, "Warning: JTAG WishBone %d-bit access must be %d-byte " |
"aligned\n", access_bits, access_bytes); |
return 0; |
} |
else if (0 != (runtime.debug.size % access_bytes)) |
{ |
fprintf (stderr, "Warning: JTAG %d-bit WishBone access must be multiple " |
"of %d bytes in length\n", access_bits, access_bytes); |
return 0; |
} |
else |
{ |
return 1; /* No problems */ |
} |
} /* validate_wb_fields () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Read WishBone data |
|
Read memory from WishBone. The WRITE_COMMAND address is updated to reflect |
the completed read if successful. |
|
The result is the CRC of the data read. The status flag is supplied as a |
pointer, since this can also be updated if there is a problem reading the |
data. |
|
@note The size of the data is one greater than the length specified in the |
original WRITE_COMMAND. |
|
@todo For now we always read a byte a time. In the future, we ought to use |
16 and 32-bit accesses for greater efficiency. |
|
@todo The algorithm for ensuring we only set the bits of interest in the |
register is inefficient. We should instead clear the whole area |
before starting. |
|
@param[out] jreg The JTAG register buffer where data is to be |
stored. |
@param[in] skip_bits Bits to skip before storing data in jreg. |
@param[in] status_ptr Pointer to the status register. |
|
@return The CRC of the data read */ |
/*---------------------------------------------------------------------------*/ |
static uint32_t |
wishbone_read (unsigned char *jreg, |
unsigned int skip_bits, |
enum jtag_status *status_ptr) |
{ |
/* Compute the CRC as we go */ |
uint32_t crc_out = 0xffffffff; |
|
/* Validate the fields for the wishbone read. If this fails we stop here, |
setting an error in the status_ptr. */ |
if (!validate_wb_fields()) |
{ |
*status_ptr |= JS_WISHBONE_ERROR; |
return crc_out; |
} |
|
/* Transfer each byte in turn, computing the CRC as we go */ |
unsigned byte_off = skip_bits / 8; |
unsigned bit_off = skip_bits % 8; |
|
uint32_t i; /* Index into the data being read */ |
|
for (i = 0; i < runtime.debug.size; i++) |
{ |
/* Error if we can't access this byte */ |
if (NULL == verify_memoryarea (runtime.debug.addr + i)) |
{ |
*status_ptr |= JS_WISHBONE_ERROR; |
return crc_out; |
} |
|
/* Get the data with no cache or VM translation and update the CRC */ |
unsigned char byte = eval_direct8 (runtime.debug.addr + i, 0, 0); |
crc_out = crc32 (byte, 8, crc_out); |
|
/* Store the byte in the register, without trampling adjacent |
bits. Simplified version when the bit offset is zero. */ |
if (0 == bit_off) |
{ |
jreg[byte_off + i] = byte; |
} |
else |
{ |
/* Clear the bits (only) we are setting */ |
jreg[byte_off + i] <<= bit_off; |
jreg[byte_off + i] >>= bit_off; |
jreg[byte_off + i + 1] >>= 8 - bit_off; |
jreg[byte_off + i + 1] <<= 8 - bit_off; |
|
/* OR in the bits */ |
jreg[byte_off + i] |= (byte << bit_off) & 0xff; |
jreg[byte_off + i + 1] |= (byte >> (8 - bit_off)) & 0xff; |
} |
} |
|
runtime.debug.addr += runtime.debug.size; |
|
return crc_out; |
|
} /* wishbone_read () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Validate WRITE_COMMAND fields for SPR |
|
Check that a WRITE_COMMAND's fields are valid for SPR access. Only prints |
messages, since the protocol does not allow for any errors. |
|
- 8 and 16-bit access is only permitted for WishBone. If they are specified |
for SPR, they are treated as their 32 bit equivalent. A warning is |
printed. |
|
- size must be 1 word. If a larger value is specified that is treated as 1 |
with a warning. |
|
- address must be less than MAX_SPRS. If a larger value is specified, it is |
reduced module MAX_SPRS (which is hopefully a power of 2). |
|
Where errors are found, the data is updated. |
|
Validation is carried out with the GO_COMMAND, rather than with the |
WRITE_COMMAND, for consistency with WishBone error checking, for which |
only the GO_COMMAND can set the status error if there is a problem. |
|
Warning messages are printed to explain any validation problems. |
|
@todo Should multiple SPR accesses be allowed in a single access? |
|
@note The size of the data is one greater than the length specified in the |
original WRITE_COMMAND. */ |
/*---------------------------------------------------------------------------*/ |
static void |
validate_spr_fields () |
{ |
int access_bits; |
int is_read_p; |
|
switch (runtime.debug.acc_type) |
{ |
case JAT_WRITE8: access_bits = 8; is_read_p = 0; |
case JAT_READ8: access_bits = 8; is_read_p = 1; |
case JAT_WRITE16: access_bits = 16; is_read_p = 0; |
case JAT_READ16: access_bits = 16; is_read_p = 1; |
case JAT_WRITE32: access_bits = 32; is_read_p = 0; |
case JAT_READ32: access_bits = 32; is_read_p = 1; |
|
default: |
fprintf (stderr, "*** ABORT ***: validate_spr_fields: unknown access " |
"type %u\n", runtime.debug.acc_type); |
abort (); |
} |
|
/* Validate and correct if necessary access width */ |
if (32 != access_bits) |
{ |
fprintf (stderr, "Warning: JTAG %d-bit access not permitted for SPR: " |
"corrected\n", access_bits); |
runtime.debug.acc_type = is_read_p ? JAT_READ32 : JAT_WRITE32; |
} |
|
/* Validate and correct if necessary access size */ |
if (1 != runtime.debug.size) |
{ |
fprintf (stderr, "warning: JTAG SPR access must be 1 word in length: " |
"corrected\n"); |
runtime.debug.size = 1; |
} |
/* Validate and correct if necessary access size */ |
if (runtime.debug.addr >= MAX_SPRS) |
{ |
fprintf (stderr, "warning: JTAG SPR address exceeds MAX_SPRS: " |
"truncated\n"); |
runtime.debug.addr %= MAX_SPRS; |
} |
} /* validate_spr_fields () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Read SPR data |
|
Read memory from WishBone. The WRITE_COMMAND address is updated to reflect |
the completed read if successful. |
|
The result is the CRC of the data read. |
|
Unlike with Wishbone, there is no concept of any errors possible when |
reading an SPR. |
|
@todo The algorithm for ensuring we only set the bits of interest in the |
register is inefficient. We should instead clear the whole area |
before starting. |
|
@note The address is treated as a word address of the SPR. |
|
@note The debug unit is documented as being explicitly Big Endian. However |
that seems to be a poor basis for modeling, and more to do with the |
debug unit only ever being used with big-endian architectures. We |
transfer the bytes in the endianness of the OR1K. |
|
@param[out] jreg The JTAG register buffer where data is to be stored. |
@param[in] skip_bits Bits to skip before storing data in jreg. |
|
@return The CRC of the data read */ |
/*---------------------------------------------------------------------------*/ |
static uint32_t |
spr_read (unsigned char *jreg, |
unsigned int skip_bits) |
{ |
/* Compute the CRC as we go */ |
uint32_t crc_out = 0xffffffff; |
|
/* Validate the fields for the SPR read. This doesn't stop us - just prints |
out warnings and corrects the problems. */ |
validate_spr_fields(); |
|
/* Transfer the SPR */ |
uint32_t spr = mfspr (runtime.debug.addr); |
|
runtime.debug.addr++; |
|
/* Store the SPR in the register, without trampling adjacent |
bits. Simplified version when the bit offset is zero. Compute the CRC as |
we go. */ |
unsigned byte_off = skip_bits / 8; |
unsigned bit_off = skip_bits % 8; |
|
if (0 == bit_off) |
{ |
/* Each byte in turn */ |
int i; |
|
for (i = 0; i < 4; i++) |
{ |
#ifdef OR32_BIG_ENDIAN |
uint8_t byte = (spr >> 8 * i) & 0xff; |
#else /* !OR32_BIG_ENDIAN */ |
uint8_t byte = (spr >> (24 - (8 * i))) & 0xff; |
#endif /* OR32_BIG_ENDIAN */ |
|
jreg[byte_off + i] = byte; |
crc_out = crc32 (byte, 8, crc_out); |
} |
} |
else |
{ |
/* Each byte in turn */ |
int i; |
|
for (i = 0; i < 4; i++) |
{ |
#ifdef OR32_BIG_ENDIAN |
uint8_t byte = (spr >> 8 * i) & 0xff; |
#else /* !OR32_BIG_ENDIAN */ |
uint8_t byte = (spr >> (24 - (8 * i))) & 0xff; |
#endif /* OR32_BIG_ENDIAN */ |
|
/* Clear the bits (only) we are setting */ |
jreg[byte_off + i] <<= bit_off; |
jreg[byte_off + i] >>= bit_off; |
jreg[byte_off + i + 1] >>= 8 - bit_off; |
jreg[byte_off + i + 1] <<= 8 - bit_off; |
|
/* OR in the bits */ |
jreg[byte_off + i] |= (byte << bit_off) & 0xff; |
jreg[byte_off + i + 1] |= (byte >> (8 - bit_off)) & 0xff; |
|
crc_out = crc32 (byte, 8, crc_out); |
} |
} |
|
return crc_out; |
|
} /* spr_read () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Carry out a read from WishBone or SPR |
|
Process a GO_COMMAND register for read. The format is: |
|
+-------------+-------+---------+---+ |
| | | GO | | |
TDI -> | Ignored | CRC | COMMAND | 0 | -> TDO |
| | | (0x0) | | |
+-------------+-------+---------+---+ |
36 + 8 * size 32 4 |
bits bits bits |
|
The returned register has the format: |
|
+-------+--------+------------+---------+ |
| | | | | |
TDI -> | CRC | Status | Data | 00..00 | -> TDO |
| | | | | |
+-------+--------+------------+---------+ |
32 4 8 * size 37 |
bits bits bits bits |
|
Fields are always shifted in MS bit first, so must be reversed. The CRC in |
is computed on the first 5 bits, the CRC out on the 4 + 8 * size status and |
data bits. |
|
@note The size of the data is one greater than the length specified in the |
original WRITE_COMMAND. |
|
@param[in,out] jreg The register to shift in, and the register shifted |
back out. |
|
@return The number of cycles the shift took, which in turn is the number |
of bits in the register */ |
/*---------------------------------------------------------------------------*/ |
static int |
go_command_read (unsigned char *jreg) |
{ |
/* Break out the fields */ |
uint32_t crc_in = reverse_bits (((uint32_t) (jreg[0] & 0xe0) >> 5) | |
((uint32_t) jreg[1] << 3) | |
((uint32_t) jreg[2] << 11) | |
((uint32_t) jreg[3] << 19) | |
((uint32_t) (jreg[4] & 0x1f) << 27), 32); |
|
/* Compute the expected CRC */ |
uint32_t crc_computed; |
|
crc_computed = crc32 (0, 1, 0xffffffff); |
crc_computed = crc32 (JCMD_GO_COMMAND, 4, crc_computed); |
|
/* Status flags */ |
enum jtag_status status = JS_OK; |
|
/* CRC to go out */ |
uint32_t crc_out; |
|
/* Validate the CRC */ |
if (crc_computed == crc_in) |
{ |
/* Read the data. */ |
switch (runtime.debug.mod_id) |
{ |
case JM_WISHBONE: |
crc_out = wishbone_read (jreg, 37, &status); |
break; |
|
case JM_CPU0: |
crc_out = spr_read (jreg, 37); |
break; |
|
case JM_CPU1: |
fprintf (stderr, "Warning: JTAG attempt to read from CPU1: Not " |
"supported.\n"); |
break; |
|
default: |
fprintf (stderr, "*** ABORT ***: go_command_read: invalid " |
"module\n"); |
abort (); |
} |
} |
else |
{ |
/* Mismatch: record the error */ |
status |= JS_CRC_IN_ERROR; |
} |
|
/* Construct the outgoing register, skipping the data read and returning the |
number of JTAG cycles taken (the register length). */ |
return construct_response (jreg, status, crc_out, 8 * runtime.debug.size, |
37); |
|
} /* go_command_read () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Write WishBone data |
|
Write memory to WishBone. The WRITE_COMMAND address is updated to reflect |
the completed write if successful. |
|
@note The size of the data is one greater than the length specified in the |
original WRITE_COMMAND. |
|
@todo For now we always write a byte a time. In the future, we ought to use |
16 and 32-bit accesses for greater efficiency. |
|
@todo The algorithm for ensuring we only set the bits of interest in the |
register is inefficient. We should instead clear the whole area |
before starting. |
|
@param[out] jreg The JTAG register buffer where data is to be |
stored. |
@param[in] skip_bits Bits to skip before reading data from jreg. |
@param[in] status_ptr Pointer to the status register. */ |
/*---------------------------------------------------------------------------*/ |
static void |
wishbone_write (unsigned char *jreg, |
unsigned int skip_bits, |
enum jtag_status *status_ptr) |
{ |
/* Validate the fields for the wishbone write. If this fails we stop here, |
setting an error in the status_ptr. */ |
if (!validate_wb_fields()) |
{ |
*status_ptr |= JS_WISHBONE_ERROR; |
return; |
} |
|
/* Transfer each byte in turn, computing the CRC as we go */ |
unsigned byte_off = skip_bits / 8; |
unsigned bit_off = skip_bits % 8; |
|
uint32_t i; /* Index into the data being write */ |
|
for (i = 0; i < runtime.debug.size; i++) |
{ |
/* Error if we can't access this byte */ |
if (NULL == verify_memoryarea (runtime.debug.addr + i)) |
{ |
*status_ptr |= JS_WISHBONE_ERROR; |
return; |
} |
|
/* Extract the byte from the register. Simplified version when the bit |
offset is zero. */ |
unsigned char byte_r; |
|
if (0 == bit_off) |
{ |
byte_r = jreg[byte_off + i]; |
} |
else |
{ |
byte_r = jreg[byte_off + i] >> bit_off | |
jreg[byte_off + i + 1] >> (8 - bit_off); |
} |
|
/* Circumvent the read-only check usually done for mem accesses. */ |
set_program8 (runtime.debug.addr + i, reverse_byte (byte_r)); |
} |
|
runtime.debug.addr += runtime.debug.size; |
|
} /* wishbone_write () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Write SPR data |
|
Write memory to WishBone. The WRITE_COMMAND address is updated to reflect |
the completed write if successful. |
|
Unlike with Wishbone, there is no concept of any errors possible when |
writeing an SPR. |
|
@todo The algorithm for ensuring we only set the bits of interest in the |
register is inefficient. We should instead clear the whole area |
before starting. |
|
@note The address is treated as a word address of the SPR. |
|
@note The debug unit is documented as being explicitly Big Endian. However |
that seems to be a poor basis for modeling, and more to do with the |
debug unit only ever being used with big-endian architectures. We |
transfer the bytes in the endianness of the OR1K. |
|
@param[out] jreg The JTAG register buffer where data is to be stored. |
@param[in] skip_bits Bits to skip before reading data from jreg. */ |
/*---------------------------------------------------------------------------*/ |
static void |
spr_write (unsigned char *jreg, |
unsigned int skip_bits) |
{ |
/* Validate the fields for the SPR write. This doesn't stop us - just prints |
out warnings and corrects the problems. */ |
validate_spr_fields (); |
|
/* Construct the SPR value one byte at a time. */ |
uint32_t spr = 0; |
|
unsigned byte_off = skip_bits / 8; |
unsigned bit_off = skip_bits % 8; |
|
/* Each byte in turn */ |
int i; |
|
for (i = 0; i < 4; i++) |
{ |
uint8_t byte; |
|
/* Simplified version when the bit offset is zero */ |
if (0 == bit_off) |
{ |
byte = reverse_byte (jreg[byte_off + i]); |
} |
else |
{ |
byte = reverse_byte ((jreg[byte_off + i] >> bit_off) | |
(jreg[byte_off + i + 1] << (8 - bit_off))); |
} |
|
#ifdef OR32_BIG_ENDIAN |
spr |= ((uint32_t) (byte)) << (8 * i); |
#else /* !OR32_BIG_ENDIAN */ |
spr |= ((uint32_t) (byte)) << (24 - (8 * i)); |
#endif /* OR32_BIG_ENDIAN */ |
} |
|
/* Transfer the SPR */ |
mtspr (runtime.debug.addr, spr); |
runtime.debug.addr++; |
|
} /* spr_write () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Carry out a write to WishBone or SPR |
|
Process a GO_COMMAND register for write. The format is: |
|
+-------------+-------+------------+---------+---+ |
| | | | GO | | |
TDI -> | Ignored | CRC | Data | COMMAND | 0 | -> TDO |
| | | | (0x0) | | |
+-------------+-------+------------+---------+---+ |
36 32 8 * size 4 |
bits bits bits bits |
|
The returned register has the format: |
|
+-------+--------+-------------+ |
| | | | |
TDI -> | CRC | Status | 00......00 | -> TDO |
| | | | |
+-------+--------+-------------+ |
32 4 8 * size + 37 |
bits bits bits |
|
Fields are always shifted in MS bit first, so must be reversed. The CRC in |
is computed on the first 5 + 8 * size bits, the CRC out on the 4 status |
bits. |
|
@note The size of the data is one greater than the length specified in the |
original WRITE_COMMAND. |
|
@todo The rules say we look for errors in the WRITE_COMMAND spec |
here. However it would be better to do that at WRITE_COMMAND time and |
save the result for here, to avoid using duff data. |
|
@param[in,out] jreg The register to shift in, and the register shifted |
back out. |
|
@return The number of cycles the shift took, which in turn is the number |
of bits in the register */ |
/*---------------------------------------------------------------------------*/ |
static int |
go_command_write (unsigned char *jreg) |
{ |
/* Break out the fields */ |
uint32_t crc_in = |
reverse_bits (((uint32_t) (jreg[runtime.debug.size + 0] & 0xe0) >> 5) | |
((uint32_t) jreg[runtime.debug.size + 1] << 3) | |
((uint32_t) jreg[runtime.debug.size + 2] << 11) | |
((uint32_t) jreg[runtime.debug.size + 3] << 19) | |
((uint32_t) (jreg[runtime.debug.size + 4] & 0x1f) << 27), |
32); |
|
/* Compute the expected CRC */ |
uint32_t crc_computed; |
|
crc_computed = crc32 (0, 1, 0xffffffff); |
crc_computed = crc32 (JCMD_GO_COMMAND, 4, crc_computed); |
|
int i; |
|
for (i = 0; i < runtime.debug.size; i++) |
{ |
uint8_t byte = ((jreg[i] & 0xe0) >> 5) | ((jreg[i + 1] & 0x1f) << 3); |
crc_computed = crc32 (byte, 8, crc_computed); |
} |
|
/* Status flags */ |
enum jtag_status status = JS_OK; |
|
/* Validate the CRC */ |
if (crc_computed == crc_in) |
{ |
/* Read the data. */ |
switch (runtime.debug.mod_id) |
{ |
case JM_WISHBONE: |
wishbone_write (jreg, 5, &status); |
break; |
|
case JM_CPU0: |
spr_write (jreg, 5); |
break; |
|
case JM_CPU1: |
fprintf (stderr, "Warning: JTAG attempt to write to CPU1: Not " |
"supported.\n"); |
break; |
|
default: |
fprintf (stderr, "*** ABORT ***: go_command_write: invalid " |
"module\n"); |
abort (); |
} |
} |
else |
{ |
/* Mismatch: record the error */ |
status |= JS_CRC_IN_ERROR; |
} |
|
/* Construct the outgoing register, skipping the data read and returning the |
number of JTAG cycles taken (the register length). */ |
return construct_response (jreg, status, 0xffffffff, 0, |
37 + 8 * runtime.debug.size); |
|
} /* go_command_write () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Invoke the action specified by a prior WRITE_COMMAND register |
|
Process a GO_COMMAND register. |
|
How this is handled depends on whether a previous WRITE_COMMAND has |
selected a read access type or a write access type has been selected. |
|
This function breaks this out. |
|
@param[in,out] jreg The register to shift in, and the register shifted |
back out. |
|
@return The number of cycles the shift took, which in turn is the number |
of bits in the register */ |
/*---------------------------------------------------------------------------*/ |
static int |
go_command (unsigned char *jreg) |
{ |
/* Have we even had a WRITE_COMMAND? */ |
if (!runtime.debug.write_defined_p) |
{ |
fprintf (stderr, "Warning: JTAG GO_COMMAND with no prior WRITE_COMMAND: " |
"ignored\n"); |
return 4 + 1; /* Only the first 5 bits meaningful */ |
} |
|
/* Whether to read or write depends on the access type */ |
switch (runtime.debug.acc_type) |
{ |
case JAT_WRITE8: |
case JAT_WRITE16: |
case JAT_WRITE32: |
return go_command_write (jreg); |
|
case JAT_READ8: |
case JAT_READ16: |
case JAT_READ32: |
return go_command_read (jreg); |
|
default: |
fprintf (stderr, "Warning: JTAG GO_COMMAND: invalid access type: " |
"ignored\n"); |
return 4 + 1; /* Only the first 5 bits meaningful */ |
} |
} /* go_command () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Read a previouse WRITE_COMMAND register |
|
Process a READ_COMMAND register. The format is: |
|
+---------+-------+---------+---+ |
| | | READ | | |
TDI -> | Ignored | CRC | COMMAND | 0 | -> TDO |
| | | (0x1) | | |
+---------+-------+---------+---+ |
88 32 4 |
bits bits bits |
|
The returned register has the format: |
|
+-------+--------+--------+---------+--------+---------+ |
| | | | | | | |
TDI -> | CRC | Status | Length | Address | Access | 00..00 | -> TDO |
| | | | | Type | | |
+-------+--------+--------+---------+--------+---------+ |
32 4 16 32 4 37 |
bits bits bits bits bits bits |
|
Fields are always shifted in MS bit first, so must be reversed. The CRC in |
is computed on the first 5 bits, the CRC out on the 56 status, length, |
address and access type bits. |
|
@param[in,out] jreg The register to shift in, and the register shifted |
back out. |
|
@return The number of cycles the shift took, which in turn is the number |
of bits in the register */ |
/*---------------------------------------------------------------------------*/ |
static int |
read_command (unsigned char *jreg) |
{ |
/* Break out the fields */ |
uint32_t crc_in = reverse_bits (((uint32_t) (jreg[0] & 0xe0) >> 5) | |
((uint32_t) jreg[1] << 3) | |
((uint32_t) jreg[2] << 11) | |
((uint32_t) jreg[3] << 19) | |
((uint32_t) (jreg[4] & 0x1f) << 27), 32); |
|
/* Compute the expected CRC */ |
uint32_t crc_computed; |
|
crc_computed = crc32 (0, 1, 0xffffffff); |
crc_computed = crc32 (JCMD_READ_COMMAND, 4, crc_computed); |
|
/* CRC to go out */ |
uint32_t crc_out = 0xffffffff; |
|
/* Status flags */ |
enum jtag_status status = JS_OK; |
|
/* Validate the CRC */ |
if (crc_computed != crc_in) |
{ |
/* Mismatch: record the error */ |
status |= JS_CRC_IN_ERROR; |
} |
else if (runtime.debug.write_defined_p) |
{ |
/* Compute the CRC */ |
crc_out = crc32 (runtime.debug.acc_type, 4, crc_out); |
crc_out = crc32 (runtime.debug.addr, 32, crc_out); |
crc_out = crc32 (runtime.debug.size - 1, 16, crc_out); |
|
/* Construct the outgoing register. Fields can only be written if they |
are available */ |
uint8_t acc_type_r = reverse_bits (runtime.debug.acc_type, 4); |
uint32_t addr_r = reverse_bits (runtime.debug.addr, 32); |
uint16_t len_r = reverse_bits (runtime.debug.size - 1, 16); |
|
jreg[ 4] |= (acc_type_r << 5) & 0xf8; |
jreg[ 5] |= (acc_type_r >> 3) & 0x07; |
jreg[ 5] |= (addr_r << 1) & 0xfe; |
jreg[ 6] |= (addr_r >> 7) & 0xff; |
jreg[ 7] |= (addr_r >> 15) & 0xff; |
jreg[ 8] |= (addr_r >> 23) & 0xff; |
jreg[ 9] |= (addr_r >> 31) & 0x01; |
jreg[ 9] |= (len_r << 1) & 0xfe; |
jreg[10] |= (len_r >> 7) & 0xff; |
jreg[11] |= (len_r >> 15) & 0x01; |
} |
else |
{ |
fprintf (stderr, "Warning: JTAG attempt to READ_COMMAND without prior " |
"WRITE_COMMAND: no data returned\n"); |
} |
|
/* Construct the final response with the status, skipping the fields we've |
just (possibly) written. */ |
return construct_response (jreg, status, crc_out, 52, 37); |
|
} /* read_command () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Specify details for a subsequence GO_COMMAND |
|
Process a WRITE_COMMAND register. The format is: |
|
+---------+-------+--------+---------+--------+---------+---+ |
| | | | | | WRITE | | |
TDI -> | Ignored | CRC | Length | Address | Access | COMMAND | 0 | -> TDO |
| | | | | Type | (0x2) | | |
+---------+-------+--------+---------+--------+---------+---+ |
36 32 16 32 4 4 |
bits bits bits bits bits bits |
|
The returned register has the format: |
|
+-------+--------+---------+ |
| | | | |
TDI -> | CRC | Status | 00..00 | -> TDO |
| | | | |
+-------+--------+---------+ |
32 4 89 |
bits bits bits |
|
|
Fields are always shifted in MS bit first, so must be reversed. The CRC in |
is computed on the first 57 bits, the CRC out on the 4 status bits. |
|
@param[in,out] jreg The register to shift in, and the register shifted |
back out. |
|
@return The number of cycles the shift took, which in turn is the number |
of bits in the register */ |
/*---------------------------------------------------------------------------*/ |
static int |
write_command (unsigned char *jreg) |
{ |
/* Break out the fields */ |
uint8_t acc_type = reverse_bits (((jreg[0] & 0x0e) >> 5) | |
(jreg[1] & 0x01), 4); |
uint32_t addr = reverse_bits (((uint32_t) (jreg[ 1] & 0xfe) >> 1) | |
((uint32_t) jreg[ 2] << 7) | |
((uint32_t) jreg[ 3] << 15) | |
((uint32_t) jreg[ 4] << 23) | |
((uint32_t) (jreg[ 5] & 0x01) << 31), 32); |
uint16_t len = reverse_bits (((uint32_t) (jreg[ 5] & 0xfe) >> 1) | |
((uint32_t) jreg[ 6] << 7) | |
((uint32_t) (jreg[ 7] & 0x01) << 15), 16); |
uint32_t crc_in = reverse_bits (((uint32_t) (jreg[ 7] & 0xfe) >> 1) | |
((uint32_t) jreg[ 8] << 7) | |
((uint32_t) jreg[ 9] << 15) | |
((uint32_t) jreg[10] << 23) | |
((uint32_t) (jreg[11] & 0x01) << 31), 32); |
|
/* Compute the expected CRC */ |
uint32_t crc_computed; |
|
crc_computed = crc32 (0, 1, 0xffffffff); |
crc_computed = crc32 (JCMD_WRITE_COMMAND, 4, crc_computed); |
crc_computed = crc32 (acc_type, 4, crc_computed); |
crc_computed = crc32 (addr, 32, crc_computed); |
crc_computed = crc32 (len, 16, crc_computed); |
|
/* Status flags */ |
enum jtag_status status = JS_OK; |
|
/* Validate the CRC */ |
if (crc_computed != crc_in) |
{ |
/* Mismatch: record the error */ |
status |= JS_CRC_IN_ERROR; |
} |
else |
{ |
/* All OK. All other errors can only occur when the GO_COMMAND tries to |
execute the write. Record the information for next GO_COMMAND */ |
runtime.debug.write_defined_p = 1; |
runtime.debug.acc_type = acc_type; |
runtime.debug.addr = addr; |
runtime.debug.size = (unsigned long int) len + 1UL; |
} |
|
/* Construct the outgoing register and return the JTAG cycles taken (the |
register length) */ |
return construct_response (jreg, status, 0xffffffff, 0, 89); |
|
} /* write_command () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Read the control bits from a CPU. |
|
Process a READ_CONTROL register. The format is: |
|
+---------+-------+---------+---+ |
| | | READ | | |
TDI -> | Ignored | CRC | CONTROL | 0 | -> TDO |
| | | (0x3) | | |
+---------+-------+---------+---+ |
36 32 4 |
bits bits bits |
|
The returned register has the format: |
|
+-------+--------+--------+---------+ |
| | | | | |
TDI -> | CRC | Status | Data | 00..00 | -> TDO |
| | | | | |
+-------+--------+--------+---------+ |
32 4 52 37 |
bits bits bits bits |
|
Fields are always shifted in MS bit first, so must be reversed. The CRC in |
is computed on the first 57 bits, the CRC out on the 4 status bits. |
|
@param[in,out] jreg The register to shift in, and the register shifted |
back out. |
|
@return The number of cycles the shift took, which in turn is the number |
of bits in the register */ |
/*---------------------------------------------------------------------------*/ |
static int |
read_control (unsigned char *jreg) |
{ |
/* Break out the fields. */ |
uint32_t crc_in = reverse_bits (((uint32_t) (jreg[0] & 0xe0) >> 5) | |
((uint32_t) jreg[1] << 3) | |
((uint32_t) jreg[2] << 11) | |
((uint32_t) jreg[3] << 19) | |
((uint32_t) (jreg[4] & 0x1f) << 27), 32); |
|
/* Compute the expected CRC */ |
uint32_t crc_computed; |
|
crc_computed = crc32 (0, 1, 0xffffffff); |
crc_computed = crc32 (JCMD_READ_CONTROL, 4, crc_computed); |
|
/* CRC to go out */ |
uint32_t crc_out = 0xffffffff; |
|
/* Status flags */ |
enum jtag_status status = JS_OK; |
|
/* Validate the CRC */ |
if (crc_computed != crc_in) |
{ |
/* Mismatch: record the error */ |
status |= JS_CRC_IN_ERROR; |
} |
else if (JM_CPU0 == runtime.debug.mod_id) |
{ |
/* Valid module. Only bit we can sensibly read is the stall bit. */ |
uint64_t data = (uint64_t) runtime.cpu.stalled << JCB_STALL; |
|
/* Compute the CRC */ |
crc_out = crc32 (data, 52, crc_out); |
|
/* Construct the outgoing register. */ |
uint64_t data_r = reverse_bits (data, 52); |
|
jreg[ 4] |= (data_r << 5) & 0xf8; |
jreg[ 5] |= (data_r >> 3) & 0x07; |
jreg[ 5] |= (data_r >> 11) & 0xff; |
jreg[ 5] |= (data_r >> 19) & 0xff; |
jreg[ 5] |= (data_r >> 27) & 0xff; |
jreg[ 5] |= (data_r >> 35) & 0xff; |
jreg[ 5] |= (data_r >> 43) & 0xff; |
jreg[ 5] |= (data_r >> 51) & 0x01; |
} |
else |
{ |
/* Not a valid module */ |
fprintf (stderr, "ERROR: JTAG attempt to read control data for module " |
"other than CPU0: ignored\n"); |
} |
|
/* Construct the response with the status */ |
return construct_response (jreg, status, crc_out, 52, 37); |
|
} /* read_control () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Write the control bits to a CPU. |
|
Process a WRITE_CONTROL register. The format is: |
|
+---------+-------+--------+---------+---+ |
| | | | WRITE | | |
TDI -> | Ignored | CRC | Data | CONTROL | 0 | -> TDO |
| | | | (0x4) | | |
+---------+-------+--------+---------+---+ |
36 32 52 4 |
bits bits bits bits |
|
The returned register has the format: |
|
+-------+--------+---------+ |
| | | | |
TDI -> | CRC | Status | 00..00 | -> TDO |
| | | | |
+-------+--------+---------+ |
32 4 89 |
bits bits bits |
|
Fields are always shifted in MS bit first, so must be reversed. The CRC in |
is computed on the first 57 bits, the CRC out on the 4 status bits. |
|
@param[in,out] jreg The register to shift in, and the register shifted |
back out. |
|
@return The number of cycles the shift took, which in turn is the number |
of bits in the register */ |
/*---------------------------------------------------------------------------*/ |
static int |
write_control (unsigned char *jreg) |
{ |
/* Break out the fields. */ |
uint64_t data = reverse_bits (((uint64_t) (jreg[ 0] & 0xe0) >> 5) | |
((uint64_t) jreg[ 1] << 3) | |
((uint64_t) jreg[ 2] << 11) | |
((uint64_t) jreg[ 3] << 19) | |
((uint64_t) jreg[ 4] << 27) | |
((uint64_t) jreg[ 5] << 35) | |
((uint64_t) jreg[ 6] << 43) | |
((uint64_t) (jreg[ 7] & 0x01) << 51), 52); |
uint32_t crc_in = reverse_bits (((uint32_t) (jreg[ 7] & 0xfe) >> 1) | |
((uint32_t) jreg[ 8] << 7) | |
((uint32_t) jreg[ 9] << 15) | |
((uint32_t) jreg[10] << 23) | |
((uint32_t) (jreg[11] & 0x01) << 31), 32); |
|
/* Compute the expected CRC */ |
uint32_t crc_computed; |
|
crc_computed = crc32 (0, 1, 0xffffffff); |
crc_computed = crc32 (JCMD_WRITE_CONTROL, 4, crc_computed); |
crc_computed = crc32 (data, 52, crc_computed); |
|
/* Status flags */ |
enum jtag_status status = JS_OK; |
|
/* Validate the CRC */ |
if (crc_computed != crc_in) |
{ |
/* Mismatch: record the error */ |
status |= JS_CRC_IN_ERROR; |
} |
else if (JM_CPU0 == runtime.debug.mod_id) |
{ |
/* Good data and valid module. Reset, stall or unstall the register as |
required. If reset is requested, there is no point considering |
stalling! */ |
int reset_bit = (0x1 == ((data >> JCB_RESET) & 0x1)); |
int stall_bit = (0x1 == ((data >> JCB_STALL) & 0x1)); |
|
if (reset_bit) |
{ |
sim_reset (); |
} |
else |
{ |
set_stall_state (stall_bit); |
} |
} |
else |
{ |
/* Not a valid module */ |
fprintf (stderr, "ERROR: JTAG attempt to control module other than " |
"CPU0: ignored\n"); |
} |
|
/* Construct the response with the status */ |
return construct_response (jreg, status, 0xffffffff, 0, 89); |
|
} /* write_control () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Initialize the JTAG system |
|
For now just reset the JTAG interface */ |
/*---------------------------------------------------------------------------*/ |
void |
jtag_init () |
{ |
(void) jtag_reset (); |
|
} /* jtag_init () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Reset the JTAG interface |
|
Mark the current JTAG instruction as undefined. |
|
@return The number of cycles the reset took. */ |
/*---------------------------------------------------------------------------*/ |
int |
jtag_reset () |
{ |
runtime.debug.instr = JI_UNDEFINED; |
|
return JTAG_RESET_CYCLES; |
|
} /* jtag_reset () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Shift a JTAG instruction register |
|
@note Like all the JTAG interface functions, this must not be called |
re-entrantly while a call to any other function (e.g. or1kim_run ()) |
is in progress. It is the responsibility of the caller to ensure this |
constraint is met, for example by use of a SystemC mutex. |
|
The register is represented as a vector of bytes, with the byte at offset |
zero being shifted first, and the least significant bit in each byte being |
shifted first. Where the register will not fit in an exact number of bytes, |
the odd bits are in the highest numbered byte, shifted to the low end. |
|
The format is: |
|
+-------------+ |
| | |
TDI -> | Instruction | -> TDO |
| | |
+-------------+ |
4 |
bits |
|
With this debug interface, registers are shifted MS bit first, so we must |
reverse the bits to get the actual value. |
|
We record the selected instruction. For completeness the register is parsed |
and a warning given if any register other than DEBUG is shifted. |
|
@param[in,out] jreg The register to shift in, and the register shifted |
back out. |
|
@return The number of cycles the shift took, which in turn is the number |
of bits in the register */ |
/*---------------------------------------------------------------------------*/ |
int |
jtag_shift_ir (unsigned char *jreg) |
{ |
runtime.debug.instr = reverse_bits (jreg[0] & 0xf, 4); |
|
switch (runtime.debug.instr) |
{ |
case JI_EXTEST: |
fprintf (stderr, "Warning: JTAG EXTEST shifted\n"); |
break; |
|
case JI_SAMPLE_PRELOAD: |
fprintf (stderr, "Warning: JTAG SAMPLE/PRELOAD shifted\n"); |
break; |
|
case JI_IDCODE: |
fprintf (stderr, "Warning: JTAG IDCODE shifted\n"); |
break; |
|
case JI_DEBUG: |
/* Do nothing for this one */ |
break; |
|
case JI_MBIST: |
fprintf (stderr, "Warning: JTAG MBIST shifted\n"); |
break; |
|
case JI_BYPASS: |
fprintf (stderr, "Warning: JTAG BYPASS shifted\n"); |
break; |
|
default: |
fprintf (stderr, "Warning: Unknown JTAG instruction %04x shifted\n", |
runtime.debug.instr); |
break; |
} |
|
return 4; /* Register length */ |
|
} /* jtag_shift_ir () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Shift a JTAG data register |
|
@note Like all the JTAG interface functions, this must not be called |
re-entrantly while a call to any other function (e.g. or1kim_run ()) |
is in progress. It is the responsibility of the caller to ensure this |
constraint is met, for example by use of a SystemC mutex. |
|
The register is represented as a vector of bytes, with the byte at offset |
zero being shifted first, and the least significant bit in each byte being |
shifted first. Where the register will not fit in an exact number of bytes, |
the odd bits are in the highest numbered byte, shifted to the low end. |
|
This is only meaningful if the DEBUG register instruction is already |
selected. If not, the data register is rejected. |
|
The register is parsed to determine which of the six possible register |
types it could be. |
- MODULE_SELECT |
- WRITE_COMMNAND |
- READ_COMMAND |
- GO_COMMAND |
- WRITE_CONTROL |
- READ_CONTROL |
|
@note In practice READ_COMMAND is not used. However the functionality is |
provided for future compatibility. |
|
The parsing is hierarchical. The first bit determines if we have |
MODULE_SELECT, if not, the next 4 bits determine the command. |
|
@param[in,out] jreg The register to shift in, and the register shifted |
back out. |
|
@return The number of cycles the shift took, which in turn is the number |
of bits in the register */ |
/*---------------------------------------------------------------------------*/ |
int |
jtag_shift_dr (unsigned char *jreg) |
{ |
if (JI_DEBUG != runtime.debug.instr) |
{ |
fprintf (stderr, "ERROR: Attempt to shift JTAG data register when " |
"DEBUG not instruction: ignored\n"); |
return 0; |
} |
|
int module_select_p = (1 == (jreg[0] & 0x1)); |
|
if (module_select_p) |
{ |
return module_select (jreg); |
} |
else |
{ |
enum jtag_cmd cmd = reverse_bits ((jreg[0] >> 1) & 0xf, 4); |
|
switch (cmd) |
{ |
case JCMD_GO_COMMAND: return go_command (jreg); |
case JCMD_READ_COMMAND: return read_command (jreg); |
case JCMD_WRITE_COMMAND: return write_command (jreg); |
case JCMD_READ_CONTROL: return read_control (jreg); |
case JCMD_WRITE_CONTROL: return write_control (jreg); |
|
default: |
/* Not a command we recognize. Decide this after we've read just |
the module and command bits */ |
return 4 + 1; |
} |
} |
} /* jtag_shift_dr () */ |
jtag.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: Makefile.am
===================================================================
--- Makefile.am (revision 80)
+++ Makefile.am (revision 82)
@@ -24,9 +24,11 @@
noinst_LTLIBRARIES = libdebug.la
libdebug_la_SOURCES = debug-unit.c \
+ debug-unit.h \
+ gdb.h \
gdbcomm.c \
+ gdbcomm.h \
+ jtag.c \
+ jtag.h \
rsp-server.c \
- debug-unit.h \
- gdbcomm.h \
- gdb.h \
rsp-server.h
/jtag.h
0,0 → 1,93
/* jtag.c -- JTAG modeling |
|
Copyright (C) 2010 Embecosm Limited |
|
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com> |
|
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 <http://www.gnu.org/licenses/>. */ |
|
/* This program is commented throughout in a fashion suitable for processing |
with Doxygen. */ |
|
|
#ifndef JTAG__H |
#define JTAG__H |
|
/*! Number of JTAG clock cycles a reset sequence takes */ |
#define JTAG_RESET_CYCLES 5 |
|
/*! Enumeration of the JTAG instruction types */ |
enum jtag_instr { |
JI_UNDEFINED = -1, /* Won't fit in bitfield */ |
JI_EXTEST = 0x0, |
JI_SAMPLE_PRELOAD = 0x1, |
JI_IDCODE = 0x2, |
JI_DEBUG = 0x8, |
JI_MBIST = 0x9, |
JI_BYPASS = 0xf |
}; |
|
/*! Enumeration of the JTAG module IDs */ |
enum jtag_mod_id { |
JM_UNDEFINED = -1, /* Won't fit in bitfield */ |
JM_WISHBONE = 0x0, |
JM_CPU0 = 0x1, |
JM_CPU1 = 0x2 |
}; |
|
/*! Enumeration of the DEBUG command types */ |
enum jtag_cmd { |
JCMD_UNDEFINED = -1, /* Won't fit in bitfield */ |
JCMD_GO_COMMAND = 0x0, |
JCMD_READ_COMMAND = 0x1, |
JCMD_WRITE_COMMAND = 0x2, |
JCMD_READ_CONTROL = 0x3, |
JCMD_WRITE_CONTROL = 0x4 |
}; |
|
/*! Enumeration of the access types for WRITE_COMMAND */ |
enum jtag_acc_type { |
JAT_UNDEFINED = -1, /* Won't fit in bitfield */ |
JAT_WRITE8 = 0, /* WishBone only */ |
JAT_WRITE16 = 1, /* WishBone only */ |
JAT_WRITE32 = 2, |
JAT_READ8 = 4, /* WishBone only */ |
JAT_READ16 = 5, /* WishBone only */ |
JAT_READ32 = 6 |
}; |
|
/*! Enumeration of the status field bits */ |
enum jtag_status { |
JS_OK = 0x0, /*!< No error */ |
JS_CRC_IN_ERROR = 0x1, /*!< Supplied CRC error */ |
JS_MODULE_MISSING = 0x2, /*!< Non-existent module select */ |
JS_WISHBONE_ERROR = 0x4, /*!< Problem accessing Wishgone */ |
JS_OVER_UNDERRUN = 0x8 /*!< Over/under-run of data */ |
}; |
|
/*! Enumeration of the control bits */ |
enum jtag_control_bits { |
JCB_RESET = 51, /*!< Reset the processor */ |
JCB_STALL = 50, /*!< Stall the processor */ |
}; |
|
/* Function prototypes for external use */ |
extern void jtag_init (); |
extern int jtag_reset (); |
extern int jtag_shift_ir (unsigned char *jreg); |
extern int jtag_shift_dr (unsigned char *jreg); |
|
#endif /* JTAG__H */ |
jtag.h
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property