URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/or1k/tags/nog_patch_39/or1ksim/debug
- from Rev 1403 to Rev 1765
- ↔ Reverse comparison
Rev 1403 → Rev 1765
/Makefile.in
0,0 → 1,332
# Makefile.in generated by automake 1.6.3 from Makefile.am. |
# @configure_input@ |
|
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 |
# 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. |
|
# This program is distributed in the hope that it will be useful, |
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without |
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
# PARTICULAR PURPOSE. |
|
@SET_MAKE@ |
|
# Makefile -- Makefile for peripherals simulation |
# Copyright (C) 1999 Damjan Lampret, lampret@opencores.org |
# |
# This file is part of OpenRISC 1000 Architectural Simulator. |
# |
# This program is free software; you can redistribute it and/or modify |
# it under the terms of the GNU General Public License as published by |
# the Free Software Foundation; either version 2 of the License, or |
# (at your option) any later version. |
# |
# This program is distributed in the hope that it will be useful, |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
# GNU General Public License for more details. |
# |
# You should have received a copy of the GNU General Public License |
# along with this program; if not, write to the Free Software |
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
# |
SHELL = @SHELL@ |
|
srcdir = @srcdir@ |
top_srcdir = @top_srcdir@ |
VPATH = @srcdir@ |
prefix = @prefix@ |
exec_prefix = @exec_prefix@ |
|
bindir = @bindir@ |
sbindir = @sbindir@ |
libexecdir = @libexecdir@ |
datadir = @datadir@ |
sysconfdir = @sysconfdir@ |
sharedstatedir = @sharedstatedir@ |
localstatedir = @localstatedir@ |
libdir = @libdir@ |
infodir = @infodir@ |
mandir = @mandir@ |
includedir = @includedir@ |
oldincludedir = /usr/include |
pkgdatadir = $(datadir)/@PACKAGE@ |
pkglibdir = $(libdir)/@PACKAGE@ |
pkgincludedir = $(includedir)/@PACKAGE@ |
top_builddir = .. |
|
ACLOCAL = @ACLOCAL@ |
AUTOCONF = @AUTOCONF@ |
AUTOMAKE = @AUTOMAKE@ |
AUTOHEADER = @AUTOHEADER@ |
|
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd |
INSTALL = @INSTALL@ |
INSTALL_PROGRAM = @INSTALL_PROGRAM@ |
INSTALL_DATA = @INSTALL_DATA@ |
install_sh_DATA = $(install_sh) -c -m 644 |
install_sh_PROGRAM = $(install_sh) -c |
install_sh_SCRIPT = $(install_sh) -c |
INSTALL_SCRIPT = @INSTALL_SCRIPT@ |
INSTALL_HEADER = $(INSTALL_DATA) |
transform = @program_transform_name@ |
NORMAL_INSTALL = : |
PRE_INSTALL = : |
POST_INSTALL = : |
NORMAL_UNINSTALL = : |
PRE_UNINSTALL = : |
POST_UNINSTALL = : |
build_alias = @build_alias@ |
build_triplet = @build@ |
host_alias = @host_alias@ |
host_triplet = @host@ |
target_alias = @target_alias@ |
target_triplet = @target@ |
|
EXEEXT = @EXEEXT@ |
OBJEXT = @OBJEXT@ |
PATH_SEPARATOR = @PATH_SEPARATOR@ |
AMTAR = @AMTAR@ |
AR = @AR@ |
ARFLAGS = @ARFLAGS@ |
AWK = @AWK@ |
BUILD_DIR = @BUILD_DIR@ |
CC = @CC@ |
CFLAGS = @CFLAGS@ |
CPU_ARCH = @CPU_ARCH@ |
DEPDIR = @DEPDIR@ |
INCLUDES = @INCLUDES@ |
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ |
LOCAL_CFLAGS = @LOCAL_CFLAGS@ |
LOCAL_DEFS = @LOCAL_DEFS@ |
MAKE_SHELL = @MAKE_SHELL@ |
PACKAGE = @PACKAGE@ |
RANLIB = @RANLIB@ |
STRIP = @STRIP@ |
SUMVERSION = @SUMVERSION@ |
TERMCAP_LIB = @TERMCAP_LIB@ |
VERSION = @VERSION@ |
am__include = @am__include@ |
am__quote = @am__quote@ |
host = @host@ |
host_cpu = @host_cpu@ |
host_os = @host_os@ |
install_sh = @install_sh@ |
|
noinst_LIBRARIES = libdebug.a |
libdebug_a_SOURCES = debug_unit.c debug_unit.h gdbcomm.c gdbcomm.h |
subdir = debug |
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs |
CONFIG_HEADER = $(top_builddir)/config.h |
CONFIG_CLEAN_FILES = |
LIBRARIES = $(noinst_LIBRARIES) |
|
libdebug_a_AR = $(AR) cru |
libdebug_a_LIBADD = |
am_libdebug_a_OBJECTS = debug_unit.$(OBJEXT) gdbcomm.$(OBJEXT) |
libdebug_a_OBJECTS = $(am_libdebug_a_OBJECTS) |
|
DEFS = @DEFS@ |
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) |
CPPFLAGS = @CPPFLAGS@ |
LDFLAGS = @LDFLAGS@ |
LIBS = @LIBS@ |
depcomp = $(SHELL) $(top_srcdir)/depcomp |
am__depfiles_maybe = depfiles |
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/debug_unit.Po ./$(DEPDIR)/gdbcomm.Po |
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ |
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) |
CCLD = $(CC) |
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ |
DIST_SOURCES = $(libdebug_a_SOURCES) |
DIST_COMMON = Makefile.am Makefile.in |
SOURCES = $(libdebug_a_SOURCES) |
|
all: all-am |
|
.SUFFIXES: |
.SUFFIXES: .c .o .obj |
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) |
cd $(top_srcdir) && \ |
$(AUTOMAKE) --gnu debug/Makefile |
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status |
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) |
|
clean-noinstLIBRARIES: |
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) |
libdebug.a: $(libdebug_a_OBJECTS) $(libdebug_a_DEPENDENCIES) |
-rm -f libdebug.a |
$(libdebug_a_AR) libdebug.a $(libdebug_a_OBJECTS) $(libdebug_a_LIBADD) |
$(RANLIB) libdebug.a |
|
mostlyclean-compile: |
-rm -f *.$(OBJEXT) core *.core |
|
distclean-compile: |
-rm -f *.tab.c |
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug_unit.Po@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdbcomm.Po@am__quote@ |
|
distclean-depend: |
-rm -rf ./$(DEPDIR) |
|
.c.o: |
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ |
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ |
@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
$(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< |
|
.c.obj: |
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ |
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ |
@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
$(COMPILE) -c `cygpath -w $<` |
CCDEPMODE = @CCDEPMODE@ |
uninstall-info-am: |
|
ETAGS = etags |
ETAGSFLAGS = |
|
tags: TAGS |
|
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) |
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ |
unique=`for i in $$list; do \ |
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ |
done | \ |
$(AWK) ' { files[$$0] = 1; } \ |
END { for (i in files) print i; }'`; \ |
mkid -fID $$unique |
|
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ |
$(TAGS_FILES) $(LISP) |
tags=; \ |
here=`pwd`; \ |
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ |
unique=`for i in $$list; do \ |
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ |
done | \ |
$(AWK) ' { files[$$0] = 1; } \ |
END { for (i in files) print i; }'`; \ |
test -z "$(ETAGS_ARGS)$$tags$$unique" \ |
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ |
$$tags $$unique |
|
GTAGS: |
here=`$(am__cd) $(top_builddir) && pwd` \ |
&& cd $(top_srcdir) \ |
&& gtags -i $(GTAGS_ARGS) $$here |
|
distclean-tags: |
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH |
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) |
|
top_distdir = .. |
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) |
|
distdir: $(DISTFILES) |
@list='$(DISTFILES)'; for file in $$list; do \ |
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ |
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ |
if test "$$dir" != "$$file" && test "$$dir" != "."; then \ |
dir="/$$dir"; \ |
$(mkinstalldirs) "$(distdir)$$dir"; \ |
else \ |
dir=''; \ |
fi; \ |
if test -d $$d/$$file; then \ |
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ |
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ |
fi; \ |
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ |
else \ |
test -f $(distdir)/$$file \ |
|| cp -p $$d/$$file $(distdir)/$$file \ |
|| exit 1; \ |
fi; \ |
done |
check-am: all-am |
check: check-am |
all-am: Makefile $(LIBRARIES) |
|
installdirs: |
|
install: install-am |
install-exec: install-exec-am |
install-data: install-data-am |
uninstall: uninstall-am |
|
install-am: all-am |
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am |
|
installcheck: installcheck-am |
install-strip: |
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ |
INSTALL_STRIP_FLAG=-s \ |
`test -z '$(STRIP)' || \ |
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install |
mostlyclean-generic: |
|
clean-generic: |
|
distclean-generic: |
-rm -f Makefile $(CONFIG_CLEAN_FILES) |
|
maintainer-clean-generic: |
@echo "This command is intended for maintainers to use" |
@echo "it deletes files that may require special tools to rebuild." |
clean: clean-am |
|
clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am |
|
distclean: distclean-am |
|
distclean-am: clean-am distclean-compile distclean-depend \ |
distclean-generic distclean-tags |
|
dvi: dvi-am |
|
dvi-am: |
|
info: info-am |
|
info-am: |
|
install-data-am: |
|
install-exec-am: |
|
install-info: install-info-am |
|
install-man: |
|
installcheck-am: |
|
maintainer-clean: maintainer-clean-am |
|
maintainer-clean-am: distclean-am maintainer-clean-generic |
|
mostlyclean: mostlyclean-am |
|
mostlyclean-am: mostlyclean-compile mostlyclean-generic |
|
uninstall-am: uninstall-info-am |
|
.PHONY: GTAGS all all-am check check-am clean clean-generic \ |
clean-noinstLIBRARIES distclean distclean-compile \ |
distclean-depend distclean-generic distclean-tags distdir dvi \ |
dvi-am info info-am install install-am install-data \ |
install-data-am install-exec install-exec-am install-info \ |
install-info-am install-man install-strip installcheck \ |
installcheck-am installdirs maintainer-clean \ |
maintainer-clean-generic mostlyclean mostlyclean-compile \ |
mostlyclean-generic tags uninstall uninstall-am \ |
uninstall-info-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
0,0 → 1,488
/* debug_unit.c -- Simulation of Or1k debug unit |
Copyright (C) 2001 Chris Ziomkowski, chris@asics.ws |
|
This file is part of OpenRISC 1000 Architectural Simulator. |
|
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation; either version 2 of the License, or |
(at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
|
/* |
This is an architectural level simulation of the Or1k debug |
unit as described in OpenRISC 1000 System Architecture Manual, |
v. 0.1 on 22 April, 2001. This unit is described in Section 13. |
|
Every attempt has been made to be as accurate as possible with |
respect to the registers and the behavior. There are no known |
limitations at this time. |
*/ |
|
//#define DEBUG_JTAG 0 |
|
#include <stdlib.h> |
#include <stdio.h> |
#include <string.h> |
|
#include "config.h" |
|
#ifdef HAVE_INTTYPES_H |
#include <inttypes.h> |
#endif |
|
#include "port.h" |
#include "arch.h" |
#include "debug_unit.h" |
#include "sim-config.h" |
#include "except.h" |
#include "abstract.h" |
#include "parse.h" |
#include "sprs.h" |
#include "gdb.h" |
#include "except.h" |
#include "opcode/or32.h" |
#include "debug.h" |
|
DevelopmentInterface development; |
|
/* External STALL signal to debug interface */ |
int in_reset = 0; |
|
/* Current watchpoint state */ |
unsigned long watchpoints = 0; |
|
static int calculate_watchpoints(DebugUnitAction action, unsigned long udata); |
|
void set_stall_state(int state) |
{ |
development.riscop &= ~RISCOP_STALL; |
development.riscop |= state ? RISCOP_STALL : 0; |
if(testsprbits(SPR_DMR1, SPR_DMR1_DXFW)) /* If debugger disabled */ |
state = 0; |
runtime.cpu.stalled = state; |
} |
|
void du_reset() |
{ |
development.riscop = 0; |
set_stall_state (0); |
} |
|
void du_clock() |
{ |
watchpoints=0; |
}; |
|
int CheckDebugUnit(DebugUnitAction action, unsigned long udata) |
{ |
/* Do not stop, if we have debug module disabled or during reset */ |
if(!config.debug.enabled || in_reset) |
return 0; |
|
/* If we're single stepping, always stop */ |
if((action == DebugInstructionFetch) && testsprbits (SPR_DMR1, SPR_DMR1_ST)) |
return 1; |
|
/* is any watchpoint enabled to generate a break or count? If not, ignore */ |
if(mfspr(SPR_DMR2) & (SPR_DMR2_WGB | SPR_DMR2_AWTC)) |
return calculate_watchpoints(action, udata); |
|
return 0; |
} |
|
/* Checks whether we should stall the RISC or cause an exception */ |
static int calculate_watchpoints(DebugUnitAction action, unsigned long udata) |
{ |
int breakpoint = 0; |
int i, bit; |
|
/* Hopefully this loop would be unrolled run at max. speed */ |
for(i = 0, bit = 1; i < 11; i++, bit <<= 1) { |
int chain1, chain2; |
int match = 0; |
int DCR_hit = 0; |
|
/* Calculate first 8 matchpoints, result is put into DCR_hit */ |
if (i < 8) { |
unsigned long dcr = mfspr(SPR_DCR(i)); |
unsigned long dcr_ct = dcr & SPR_DCR_CT; /* the CT field alone */ |
/* Is this matchpoint a propos for the current action? */ |
if ( ((dcr & SPR_DCR_DP) && dcr_ct) && /* DVR/DCP pair present */ |
(((action==DebugInstructionFetch) && (dcr_ct == SPR_DCR_CT_IFEA)) || |
((action==DebugLoadAddress) && ((dcr_ct == SPR_DCR_CT_LEA) || |
(dcr_ct == SPR_DCR_CT_LSEA))) || |
((action==DebugStoreAddress) && ((dcr_ct == SPR_DCR_CT_SEA) || |
(dcr_ct == SPR_DCR_CT_LSEA))) || |
((action==DebugLoadData) && ((dcr_ct == SPR_DCR_CT_LD) || |
(dcr_ct == SPR_DCR_CT_LSD))) || |
((action==DebugStoreData) && ((dcr_ct == SPR_DCR_CT_SD) || |
(dcr_ct == SPR_DCR_CT_LSD)))) ) { |
unsigned long op1 = udata; |
unsigned long op2 = mfspr (SPR_DVR(i)); |
/* Perform signed comparison? */ |
if (dcr & SPR_DCR_SC) { |
long sop1 = op1, sop2 = op2; /* Convert to signed */ |
switch(dcr & SPR_DCR_CC) { |
case SPR_DCR_CC_MASKED: DCR_hit = sop1 & sop2; break; |
case SPR_DCR_CC_EQUAL: DCR_hit = sop1 == sop2; break; |
case SPR_DCR_CC_NEQUAL: DCR_hit = sop1 != sop2; break; |
case SPR_DCR_CC_LESS: DCR_hit = sop1 < sop2; break; |
case SPR_DCR_CC_LESSE: DCR_hit = sop1 <= sop2; break; |
case SPR_DCR_CC_GREAT: DCR_hit = sop1 > sop2; break; |
case SPR_DCR_CC_GREATE: DCR_hit = sop1 >= sop2; break; |
} |
} else { |
switch(dcr & SPR_DCR_CC) { |
case SPR_DCR_CC_MASKED: DCR_hit = op1 & op2; break; |
case SPR_DCR_CC_EQUAL: DCR_hit = op1 == op2; break; |
case SPR_DCR_CC_NEQUAL: DCR_hit = op1 != op2; break; |
case SPR_DCR_CC_LESS: DCR_hit = op1 < op2; break; |
case SPR_DCR_CC_LESSE: DCR_hit = op1 <= op2; break; |
case SPR_DCR_CC_GREAT: DCR_hit = op1 > op2; break; |
case SPR_DCR_CC_GREATE: DCR_hit = op1 >= op2; break; |
} |
} |
} |
} |
|
/* Chain matchpoints */ |
switch(i) { |
case 0: |
chain1 = chain2 = DCR_hit; |
break; |
case 8: |
chain1 = getsprbits(SPR_DWCR0, SPR_DWCR_COUNT) == getsprbits(SPR_DWCR0, |
SPR_DWCR_MATCH); |
chain2 = watchpoints & (1 << 7); |
break; |
case 9: |
chain1 = getsprbits(SPR_DWCR1, SPR_DWCR_COUNT) == getsprbits (SPR_DWCR1, |
SPR_DWCR_MATCH); |
chain2 = watchpoints & (1 << 8); |
break; |
case 10: |
/* TODO: External watchpoint - not yet handled! */ |
#if 0 |
chain1 = external_watchpoint; |
chain2 = watchpoints & (1 << 9); |
#else |
chain1 = chain2 = 0; |
#endif |
break; |
default: |
chain1 = DCR_hit; |
chain2 = watchpoints & (bit >> 1); |
break; |
} |
|
switch(getsprbits(SPR_DMR1, SPR_DMR1_CW0 << i)) { |
case 0: match = chain1; break; |
case 1: match = chain1 && chain2; break; |
case 2: match = chain1 || chain2; break; |
} |
|
/* Increment counters & generate counter break */ |
if(match) { |
/* watchpoint did not appear before in this clock cycle */ |
if(!(watchpoints & bit)) { |
int counter = (getsprbits(SPR_DMR2, SPR_DMR2_AWTC) & bit) ? 1 : 0; |
int enabled = counter ? getsprbits(SPR_DMR2, SPR_DMR2_WCE1) : |
getsprbits(SPR_DMR2, SPR_DMR2_WCE0); |
if(enabled) |
setsprbits(SPR_DWCR0 + counter, SPR_DWCR_COUNT, |
getsprbits(SPR_DWCR0 + counter, SPR_DWCR_COUNT) + 1); |
watchpoints |= bit; |
} |
|
/* should this watchpoint generate a breakpoint? */ |
if(getsprbits(SPR_DMR2, SPR_DMR2_WGB) & bit) |
breakpoint = 1; |
} |
} |
|
return breakpoint; |
} |
|
static DebugScanChainIDs current_scan_chain = JTAG_CHAIN_GLOBAL; |
|
int DebugGetRegister(unsigned int address, unsigned long* data) |
{ |
int err=0; |
#ifdef DEBUG_JTAG |
PRINTF("Debug get register %x\n",address); |
fflush(stdout); |
#endif |
switch(current_scan_chain) |
{ |
case JTAG_CHAIN_DEBUG_UNIT: |
*data = mfspr (address); |
debug (2, "READ (%08x) = %08x\n", address, *data); |
if (runtime.sim.fspr_log) { |
fprintf(runtime.sim.fspr_log, "Read from SPR : [%08X] -> [%08lX]\n", |
address, *data); |
} |
break; |
case JTAG_CHAIN_TRACE: |
*data = 0; /* Scan chain not yet implemented */ |
break; |
case JTAG_CHAIN_DEVELOPMENT: |
err = get_devint_reg(address,data); |
break; |
case JTAG_CHAIN_WISHBONE: |
err = debug_get_mem(address,data); |
break; |
} |
#ifdef DEBUG_JTAG |
PRINTF("!get reg %x\n", *data); |
fflush(stdout); |
#endif |
return err; |
} |
|
int DebugSetRegister(unsigned int address,unsigned long data) |
{ |
int err=0; |
#ifdef DEBUG_JTAG |
PRINTF("Debug set register %x <- %x\n", address, data); |
fflush(stdout); |
#endif |
switch(current_scan_chain) |
{ |
case JTAG_CHAIN_DEBUG_UNIT: |
debug (2, "WRITE (%08x) = %08lx\n", address, data); |
if (runtime.sim.fspr_log) { |
fprintf(runtime.sim.fspr_log, "Write to SPR : [%08X] <- [%08lX]\n", |
address, data); |
} |
mtspr(address, data); |
break; |
case JTAG_CHAIN_TRACE: |
err = JTAG_PROXY_ACCESS_EXCEPTION; |
break; |
case JTAG_CHAIN_DEVELOPMENT: |
err = set_devint_reg (address, data); |
break; |
case JTAG_CHAIN_WISHBONE: |
err = debug_set_mem (address, data); |
break; |
} |
#ifdef DEBUG_JTAG |
PRINTF("!set reg\n"); |
fflush(stdout); |
#endif |
return err; |
} |
|
int DebugSetChain(int chain) |
{ |
#ifdef DEBUG_JTAG |
PRINTF("Debug set chain %x\n",chain); |
fflush(stdout); |
#endif |
switch(chain) |
{ |
case JTAG_CHAIN_DEBUG_UNIT: |
case JTAG_CHAIN_TRACE: |
case JTAG_CHAIN_DEVELOPMENT: |
case JTAG_CHAIN_WISHBONE: |
current_scan_chain = chain; |
break; |
default: /* All other chains not implemented */ |
return JTAG_PROXY_INVALID_CHAIN; |
} |
|
#ifdef DEBUG_JTAG |
PRINTF("!set chain\n"); |
fflush(stdout); |
#endif |
return 0; |
} |
|
void sim_reset (); |
|
/* Sets development interface register */ |
int set_devint_reg(unsigned int address, unsigned long data) |
{ |
int err = 0; |
unsigned long value = data; |
int old_value; |
|
switch(address) { |
case DEVELOPINT_MODER: development.moder = value; break; |
case DEVELOPINT_TSEL: development.tsel = value; break; |
case DEVELOPINT_QSEL: development.qsel = value; break; |
case DEVELOPINT_SSEL: development.ssel = value; break; |
case DEVELOPINT_RISCOP: |
old_value = (development.riscop & RISCOP_RESET) != 0; |
development.riscop = value; |
in_reset = (development.riscop & RISCOP_RESET) != 0; |
/* Reset the cpu on the negative edge of RESET */ |
if(old_value && !in_reset) |
sim_reset(); /* Reset all units */ |
set_stall_state((development.riscop & RISCOP_STALL) != 0); |
break; |
case DEVELOPINT_RECWP0: |
case DEVELOPINT_RECWP1: |
case DEVELOPINT_RECWP2: |
case DEVELOPINT_RECWP3: |
case DEVELOPINT_RECWP4: |
case DEVELOPINT_RECWP5: |
case DEVELOPINT_RECWP6: |
case DEVELOPINT_RECWP7: |
case DEVELOPINT_RECWP8: |
case DEVELOPINT_RECWP9: |
case DEVELOPINT_RECWP10: development.recwp[address - DEVELOPINT_RECWP0] = value; break; |
case DEVELOPINT_RECBP0: development.recbp = value; break; |
default: |
err = JTAG_PROXY_INVALID_ADDRESS; |
break; |
} |
#ifdef DEBUG_JTAG |
PRINTF("set_devint_reg %08x = %08x\n", address, data); |
fflush(stdout); |
#endif |
return err; |
} |
|
/* Gets development interface register */ |
int get_devint_reg(unsigned int address,unsigned long *data) |
{ |
int err = 0; |
unsigned long value = 0; |
|
switch(address) { |
case DEVELOPINT_MODER: value = development.moder; break; |
case DEVELOPINT_TSEL: value = development.tsel; break; |
case DEVELOPINT_QSEL: value = development.qsel; break; |
case DEVELOPINT_SSEL: value = development.ssel; break; |
case DEVELOPINT_RISCOP: value = development.riscop; break; |
case DEVELOPINT_RECWP0: |
case DEVELOPINT_RECWP1: |
case DEVELOPINT_RECWP2: |
case DEVELOPINT_RECWP3: |
case DEVELOPINT_RECWP4: |
case DEVELOPINT_RECWP5: |
case DEVELOPINT_RECWP6: |
case DEVELOPINT_RECWP7: |
case DEVELOPINT_RECWP8: |
case DEVELOPINT_RECWP9: |
case DEVELOPINT_RECWP10: value = development.recwp[address - DEVELOPINT_RECWP0]; break; |
case DEVELOPINT_RECBP0: value = development.recbp; break; |
default: err = JTAG_PROXY_INVALID_ADDRESS; break; |
} |
|
#ifdef DEBUG_JTAG |
PRINTF("get_devint_reg %08x = %08x\n", address, value); |
fflush(stdout); |
#endif |
*data = value; |
return err; |
} |
|
/* Writes to bus address */ |
int debug_set_mem (unsigned int address,unsigned long data) |
{ |
int err = 0; |
debug (2, "MEMWRITE (%08x) = %08lx\n", address, data); |
|
|
if(!verify_memoryarea(address)) |
err = JTAG_PROXY_INVALID_ADDRESS; |
else { |
// circumvent the read-only check usually done for mem accesses |
// data is in host order, because that's what set_direct32 needs |
set_direct32(address, data, NULL, 0, 0); |
} |
return err; |
} |
|
/* Reads from bus address */ |
int debug_get_mem(unsigned int address,unsigned long *data) |
{ |
int err = 0; |
if(!verify_memoryarea(address)) |
err = JTAG_PROXY_INVALID_ADDRESS; |
else |
{ |
*data=eval_direct32(address, NULL, 0, 0); |
} |
debug (2, "MEMREAD (%08x) = %08lx\n", address, *data); |
return err; |
} |
|
/* debug_ignore_exception returns 1 if the exception should be ignored. */ |
int debug_ignore_exception (unsigned long except) |
{ |
int result = 0; |
unsigned long dsr = mfspr (SPR_DSR); |
unsigned long drr = mfspr (SPR_DRR); |
|
#if DEBUG_JTAG |
PRINTF ("dsr 0x%08x drr 0x%08x \n", dsr, drr); |
#endif |
|
switch(except) { |
case EXCEPT_RESET: drr |= result = dsr & SPR_DSR_RSTE; break; |
case EXCEPT_BUSERR: drr |= result = dsr & SPR_DSR_BUSEE; break; |
case EXCEPT_DPF: drr |= result = dsr & SPR_DSR_DPFE; break; |
case EXCEPT_IPF: drr |= result = dsr & SPR_DSR_IPFE; break; |
case EXCEPT_TICK: drr |= result = dsr & SPR_DSR_TTE; break; |
case EXCEPT_ALIGN: drr |= result = dsr & SPR_DSR_AE; break; |
case EXCEPT_ILLEGAL: drr |= result = dsr & SPR_DSR_IIE; break; |
case EXCEPT_INT: drr |= result = dsr & SPR_DSR_IE; break; |
case EXCEPT_DTLBMISS: drr |= result = dsr & SPR_DSR_DME; break; |
case EXCEPT_ITLBMISS: drr |= result = dsr & SPR_DSR_IME; break; |
case EXCEPT_RANGE: drr |= result = dsr & SPR_DSR_RE; break; |
case EXCEPT_SYSCALL: drr |= result = dsr & SPR_DSR_SCE; break; |
case EXCEPT_TRAP: drr |= result = dsr & SPR_DSR_TE; break; |
default: |
break; |
} |
#if DEBUG_JTAG |
PRINTF ("dsr 0x%08x drr 0x%08x result %i\n", dsr, drr, result); |
#endif |
|
mtspr (SPR_DRR, drr); |
set_stall_state (result != 0); |
return (result != 0); |
} |
|
/*--------------------------------------------------[ Debug configuration ]---*/ |
void debug_enabled(union param_val val, void *dat) |
{ |
config.debug.enabled = val.int_val; |
} |
|
void debug_gdb_enabled(union param_val val, void *dat) |
{ |
config.debug.gdb_enabled = val.int_val; |
} |
|
void debug_server_port(union param_val val, void *dat) |
{ |
config.debug.server_port = val.int_val; |
} |
|
void debug_vapi_id(union param_val val, void *dat) |
{ |
config.debug.vapi_id = val.int_val; |
} |
|
void reg_debug_sec(void) |
{ |
struct config_section *sec = reg_config_sec("debug", NULL, NULL); |
|
reg_config_param(sec, "enabled", paramt_int, debug_enabled); |
reg_config_param(sec, "gdb_enabled", paramt_int, debug_gdb_enabled); |
reg_config_param(sec, "server_port", paramt_int, debug_server_port); |
reg_config_param(sec, "vapi_id", paramt_int, debug_server_port); |
} |
debug_unit.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: gdbcomm.c
===================================================================
--- gdbcomm.c (nonexistent)
+++ gdbcomm.c (revision 1765)
@@ -0,0 +1,670 @@
+/* gdbcomm.c -- Communication routines for gdb
+ Copyright (C) 2001 by Marko Mlinar, markom@opencores.org
+ Code copied from toplevel.c
+
+ This file is part of OpenRISC 1000 Architectural Simulator.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "config.h"
+
+#ifdef HAVE_INTTYPES_H
+#include
+#endif
+
+#include "port.h"
+#include "arch.h"
+#include "gdb.h"
+#include "gdbcomm.h"
+#include "vapi.h"
+#include "sim-config.h"
+#include "debug_unit.h"
+
+static int gdb_read(void* buf,int len);
+static int gdb_write(const void* buf,int len);
+
+static unsigned int serverIP = 0;
+static unsigned int serverPort = 0;
+static unsigned int server_fd = 0;
+static unsigned int gdb_fd = 0;
+
+static int tcp_level = 0;
+
+/* Added by CZ 24/05/01 */
+int GetServerSocket(const char* name,const char* proto,int port)
+{
+ struct servent *service;
+ struct protoent *protocol;
+ struct sockaddr_in sa;
+ struct hostent *hp;
+ int sockfd;
+ char myname[256];
+ int flags;
+ char sTemp[256];
+
+ /* First, get the protocol number of TCP */
+ if(!(protocol = getprotobyname(proto)))
+ {
+ sprintf(sTemp,"Unable to load protocol \"%s\"",proto);
+ perror(sTemp);
+ return 0;
+ }
+ tcp_level = protocol->p_proto; /* Save for later */
+
+ /* If we weren't passed a non standard port, get the port
+ from the services directory. */
+ if(!port)
+ {
+ if((service = getservbyname(name,protocol->p_name)))
+ port = ntohs(service->s_port);
+ }
+
+ /* Create the socket using the TCP protocol */
+ if((sockfd = socket(PF_INET,SOCK_STREAM,protocol->p_proto)) < 0)
+ {
+ perror("Unable to create socket");
+ return 0;
+ }
+
+ flags = 1;
+ if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(const char*)&flags,sizeof(int)) < 0)
+ {
+ sprintf(sTemp,"Can not set SO_REUSEADDR option on socket %d",sockfd);
+ perror(sTemp);
+ close(sockfd);
+ return 0;
+ }
+
+ /* The server should also be non blocking. Get the current flags. */
+ if(fcntl(sockfd,F_GETFL,&flags) < 0)
+ {
+ sprintf(sTemp,"Unable to get flags for socket %d",sockfd);
+ perror(sTemp);
+ close(sockfd);
+ return 0;
+ }
+
+ /* Set the nonblocking flag */
+ if(fcntl(sockfd,F_SETFL, flags | O_NONBLOCK) < 0)
+ {
+ sprintf(sTemp,"Unable to set flags for socket %d to value 0x%08x",
+ sockfd,flags | O_NONBLOCK);
+ perror(sTemp);
+ close(sockfd);
+ return 0;
+ }
+
+ /* Find out what our address is */
+ memset(&sa,0,sizeof(struct sockaddr_in));
+ gethostname(myname,sizeof(myname));
+ if(!(hp = gethostbyname(myname)))
+ {
+ perror("Unable to read hostname");
+ close(sockfd);
+ return 0;
+ }
+
+ /* Bind our socket to the appropriate address */
+ sa.sin_family = hp->h_addrtype;
+ sa.sin_port = htons(port);
+ if(bind(sockfd,(struct sockaddr*)&sa,sizeof(struct sockaddr_in)) < 0)
+ {
+ sprintf(sTemp,"Unable to bind socket %d to port %d",sockfd,port);
+ perror(sTemp);
+ close(sockfd);
+ return 0;
+ }
+ serverIP = sa.sin_addr.s_addr;
+ flags = sizeof(struct sockaddr_in);
+ if(getsockname(sockfd,(struct sockaddr*)&sa,&flags) < 0)
+ {
+ sprintf(sTemp,"Unable to get socket information for socket %d",sockfd);
+ perror(sTemp);
+ close(sockfd);
+ return 0;
+ }
+ serverPort = ntohs(sa.sin_port);
+
+ /* Set the backlog to 1 connections */
+ if(listen(sockfd,1) < 0)
+ {
+ sprintf(sTemp,"Unable to set backlog on socket %d to %d",sockfd,1);
+ perror(sTemp);
+ close(sockfd);
+ return 0;
+ }
+
+ return sockfd;
+}
+
+void BlockJTAG()
+{
+ struct pollfd fds[2];
+ int n = 0;
+
+ fds[n].fd = server_fd;
+ fds[n].events = POLLIN;
+ fds[n++].revents = 0;
+ if(gdb_fd)
+ {
+ fds[n].fd = gdb_fd;
+ fds[n].events = POLLIN;
+ fds[n++].revents = 0;
+ }
+ poll(fds,n,-1);
+}
+
+void HandleServerSocket(Boolean block)
+{
+ struct pollfd fds[3];
+ int n = 0;
+ int timeout = block ? -1 : 0;
+ Boolean data_on_stdin = false;
+ int o_serv_fd = server_fd;
+
+ if(!o_serv_fd && !gdb_fd)
+ return;
+
+ if(o_serv_fd)
+ {
+ fds[n].fd = o_serv_fd;
+ fds[n].events = POLLIN;
+ fds[n++].revents = 0;
+ }
+ if(gdb_fd)
+ {
+ fds[n].fd = gdb_fd;
+ fds[n].events = POLLIN;
+ fds[n++].revents = 0;
+ }
+ if(block)
+ {
+ fds[n].fd = 0;
+ fds[n].events = POLLIN;
+ fds[n++].revents = 0;
+ }
+
+ while(!data_on_stdin)
+ {
+ switch(poll(fds,n,timeout))
+ {
+ case -1:
+ if(errno == EINTR)
+ continue;
+ perror("poll");
+ server_fd = 0;
+ break;
+ case 0: /* Nothing interesting going on */
+ data_on_stdin = true; /* Can only get here if nonblocking */
+ break;
+ default:
+ /* Make sure to handle the gdb port first! */
+ if((fds[0].revents && (gdb_fd && !o_serv_fd) ||
+ fds[1].revents && (server_fd && gdb_fd)))
+ {
+ int revents = o_serv_fd ? fds[1].revents : fds[0].revents;
+
+ if(revents & POLLIN)
+ GDBRequest();
+ else /* Error Occurred */
+ {
+ fprintf(stderr,"Received flags 0x%08x on gdb socket. Shutting down.\n",revents);
+ close(gdb_fd);
+ gdb_fd = 0;
+ }
+ }
+ if(fds[0].revents && o_serv_fd)
+ {
+ if(fds[0].revents & POLLIN)
+ JTAGRequest();
+ else /* Error Occurred */
+ {
+ fprintf(stderr,"Received flags 0x%08x on server. Shutting down.\n",fds[0].revents);
+ close(o_serv_fd);
+ server_fd = 0;
+ serverPort = 0;
+ serverIP = 0;
+ }
+ }
+ if(fds[2].revents || (fds[1].revents && !gdb_fd))
+ data_on_stdin = true;
+ break;
+ } /* End of switch statement */
+ } /* End of while statement */
+}
+
+void JTAGRequest()
+{
+ struct sockaddr_in sa;
+ struct sockaddr* addr = (struct sockaddr*)&sa;
+ int n = sizeof(struct sockaddr_in);
+ int fd = accept(server_fd,addr,&n);
+ int on_off = 0; /* Turn off Nagel's algorithm on the socket */
+ int flags;
+ char sTemp[256];
+
+ if(fd < 0)
+ {
+ /* This is valid, because a connection could have started,
+ and then terminated due to a protocol error or user
+ initiation before the accept could take place. */
+ if(errno != EWOULDBLOCK && errno != EAGAIN)
+ {
+ perror("accept");
+ close(server_fd);
+ server_fd = 0;
+ serverPort = 0;
+ serverIP = 0;
+ }
+ return;
+ }
+
+ if(gdb_fd)
+ {
+ close(fd);
+ return;
+ }
+
+ if(fcntl(fd,F_GETFL,&flags) < 0)
+ {
+ sprintf(sTemp,"Unable to get flags for gdb socket %d",fd);
+ perror(sTemp);
+ close(fd);
+ return;
+ }
+
+ if(fcntl(fd,F_SETFL, flags | O_NONBLOCK) < 0)
+ {
+ sprintf(sTemp,"Unable to set flags for gdb socket %d to value 0x%08x",
+ fd,flags | O_NONBLOCK);
+ perror(sTemp);
+ close(fd);
+ return;
+ }
+
+ if(setsockopt(fd,tcp_level,TCP_NODELAY,&on_off,sizeof(int)) < 0)
+ {
+ sprintf(sTemp,"Unable to disable Nagel's algorithm for socket %d.\nsetsockopt",fd);
+ perror(sTemp);
+ close(fd);
+ return;
+ }
+
+ gdb_fd = fd;
+}
+
+void GDBRequest()
+{
+ JTAGProxyWriteMessage msg_write;
+ JTAGProxyReadMessage msg_read;
+ JTAGProxyChainMessage msg_chain;
+ JTAGProxyWriteResponse resp_write;
+ JTAGProxyReadResponse resp_read;
+ JTAGProxyChainResponse resp_chain;
+ JTAGProxyBlockWriteMessage *msg_bwrite;
+ JTAGProxyBlockReadMessage msg_bread;
+ JTAGProxyBlockWriteResponse resp_bwrite;
+ JTAGProxyBlockReadResponse *resp_bread;
+ char *buf;
+ int err = 0;
+ uint32_t command,length;
+ int len,i;
+
+ /* First, we must read the incomming command */
+ if(gdb_read(&command,sizeof(uint32_t)) < 0)
+ {
+ if(gdb_fd)
+ {
+ perror("gdb socket - 1");
+ close(gdb_fd);
+ gdb_fd = 0;
+ }
+ return;
+ }
+ if(gdb_read(&length,sizeof(uint32_t)) < 0)
+ {
+ if(gdb_fd)
+ {
+ perror("gdb socket - 2");
+ close(gdb_fd);
+ gdb_fd = 0;
+ }
+ return;
+ }
+ length = ntohl(length);
+
+ /* Now, verify the protocol and implement the command */
+ switch(ntohl(command))
+ {
+ case JTAG_COMMAND_WRITE:
+ if(length != sizeof(msg_write) - 8)
+ {
+ ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
+ return;
+ }
+ buf = (char*)&msg_write;
+ if(gdb_read(&buf[8],length) < 0)
+ {
+ if(gdb_fd)
+ {
+ perror("gdb socket - 3");
+ close(gdb_fd);
+ gdb_fd = 0;
+ }
+ return;
+ }
+ msg_write.address = ntohl(msg_write.address);
+ msg_write.data_H = ntohl(msg_write.data_H);
+ msg_write.data_L = ntohl(msg_write.data_L);
+ err = DebugSetRegister(msg_write.address,msg_write.data_L);
+ resp_write.status = htonl(err);
+ if(gdb_write(&resp_write,sizeof(resp_write)) < 0)
+ {
+ if(gdb_fd)
+ {
+ perror("gdb socket - 4");
+ close(gdb_fd);
+ gdb_fd = 0;
+ }
+ return;
+ }
+ break;
+ case JTAG_COMMAND_READ:
+ if(length != sizeof(msg_read) - 8)
+ {
+ ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
+ return;
+ }
+ buf = (char*)&msg_read;
+ if(gdb_read(&buf[8],length) < 0)
+ {
+ if(gdb_fd)
+ {
+ perror("gdb socket - 5");
+ close(gdb_fd);
+ gdb_fd = 0;
+ }
+ return;
+ }
+ msg_read.address = ntohl(msg_read.address);
+ err = DebugGetRegister(msg_read.address,&resp_read.data_L);
+ resp_read.status = htonl(err);
+ resp_read.data_H = 0;
+ resp_read.data_L = htonl(resp_read.data_L);
+ if(gdb_write(&resp_read,sizeof(resp_read)) < 0)
+ {
+ if(gdb_fd)
+ {
+ perror("gdb socket - 6");
+ close(gdb_fd);
+ gdb_fd = 0;
+ }
+ return;
+ }
+ break;
+ case JTAG_COMMAND_BLOCK_WRITE:
+ if(length < sizeof(JTAGProxyBlockWriteMessage)-8)
+ {
+ ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
+ return;
+ }
+ if(!(buf = (char*)malloc(8+length)))
+ {
+ ProtocolClean(length,JTAG_PROXY_OUT_OF_MEMORY);
+ return;
+ }
+ msg_bwrite = (JTAGProxyBlockWriteMessage*)buf;
+ if(gdb_read(&buf[8],length) < 0)
+ {
+ if(gdb_fd)
+ {
+ perror("gdb socket - 5");
+ close(gdb_fd);
+ gdb_fd = 0;
+ }
+ free(buf);
+ return;
+ }
+ msg_bwrite->address = ntohl(msg_bwrite->address);
+ msg_bwrite->nRegisters = ntohl(msg_bwrite->nRegisters);
+ for(i=0;inRegisters;i++)
+ {
+ int t_err = 0;
+
+ msg_bwrite->data[i] = ntohl(msg_bwrite->data[i]);
+ t_err = DebugSetRegister(msg_bwrite->address + 4 * i,msg_bwrite->data[i]);
+ err = err ? err : t_err;
+ }
+ resp_bwrite.status = htonl(err);
+ free(buf);
+ buf = NULL;
+ msg_bwrite = NULL;
+ if(gdb_write(&resp_bwrite,sizeof(resp_bwrite)) < 0)
+ {
+ if(gdb_fd)
+ {
+ perror("gdb socket - 4");
+ close(gdb_fd);
+ gdb_fd = 0;
+ }
+ return;
+ }
+ break;
+ case JTAG_COMMAND_BLOCK_READ:
+ if(length != sizeof(msg_bread) - 8)
+ {
+ ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
+ return;
+ }
+ buf = (char*)&msg_bread;
+ if(gdb_read(&buf[8],length) < 0)
+ {
+ if(gdb_fd)
+ {
+ perror("gdb socket - 5");
+ close(gdb_fd);
+ gdb_fd = 0;
+ }
+ return;
+ }
+ msg_bread.address = ntohl(msg_bread.address);
+ msg_bread.nRegisters = ntohl(msg_bread.nRegisters);
+ len = sizeof(JTAGProxyBlockReadResponse) + 4*(msg_bread.nRegisters-1);
+ if(!(buf = (char*)malloc(len)))
+ {
+ ProtocolClean(0,JTAG_PROXY_OUT_OF_MEMORY);
+ return;
+ }
+ resp_bread = (JTAGProxyBlockReadResponse*)buf;
+ for(i=0;idata[i]);
+ resp_bread->data[i] = htonl(resp_bread->data[i]);
+ err = err ? err : t_err;
+ }
+ resp_bread->status = htonl(err);
+ resp_bread->nRegisters = htonl(msg_bread.nRegisters);
+ if(gdb_write(resp_bread,len) < 0)
+ {
+ if(gdb_fd)
+ {
+ perror("gdb socket - 6");
+ close(gdb_fd);
+ gdb_fd = 0;
+ }
+ free(buf);
+ return;
+ }
+ free(buf);
+ buf = NULL;
+ resp_bread = NULL;
+ break;
+ case JTAG_COMMAND_CHAIN:
+ if(length != sizeof(msg_chain) - 8)
+ {
+ ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
+ return;
+ }
+ buf = (char*)&msg_chain;
+ if(gdb_read(&buf[8],sizeof(msg_chain)-8) < 0)
+ {
+ if(gdb_fd)
+ {
+ perror("gdb socket - 7");
+ close(gdb_fd);
+ gdb_fd = 0;
+ }
+ return;
+ }
+ msg_chain.chain = htonl(msg_chain.chain);
+ err = DebugSetChain(msg_chain.chain);
+ resp_chain.status = htonl(err);
+ if(gdb_write(&resp_chain,sizeof(resp_chain)) < 0)
+ {
+ if(gdb_fd)
+ {
+ perror("gdb socket - 8");
+ close(gdb_fd);
+ gdb_fd = 0;
+ }
+ return;
+ }
+ break;
+ default:
+ ProtocolClean(length,JTAG_PROXY_COMMAND_NOT_IMPLEMENTED);
+ break;
+ }
+}
+
+void ProtocolClean(int length,int32_t err)
+{
+ char buf[4096];
+
+ err = htonl(err);
+ if((gdb_read(buf,length) < 0) ||
+ (gdb_write(&err,sizeof(err)) < 0) && gdb_fd)
+ {
+ perror("gdb socket - 9");
+ close(gdb_fd);
+ gdb_fd = 0;
+ }
+}
+
+static int gdb_write(const void* buf,int len)
+{
+ int n, log_n = 0;
+ const char* w_buf = (const char*)buf;
+ const uint32_t* log_buf = (const uint32_t*)buf;
+ struct pollfd block;
+
+ while(len) {
+ if((n = write(gdb_fd,w_buf,len)) < 0) {
+ switch(errno) {
+ case EWOULDBLOCK: /* or EAGAIN */
+ /* We've been called on a descriptor marked
+ for nonblocking I/O. We better simulate
+ blocking behavior. */
+ block.fd = gdb_fd;
+ block.events = POLLOUT;
+ block.revents = 0;
+ poll(&block,1,-1);
+ continue;
+ case EINTR:
+ continue;
+ case EPIPE:
+ close(gdb_fd);
+ gdb_fd = 0;
+ return -1;
+ default:
+ return -1;
+ }
+ }
+ else {
+ len -= n;
+ w_buf += n;
+ if ( config.debug.vapi_id )
+ for ( log_n += n; log_n >= 4; log_n -= 4, ++ log_buf )
+ vapi_write_log_file( VAPI_COMMAND_SEND, config.debug.vapi_id, ntohl(*log_buf) );
+ }
+ }
+ return 0;
+}
+
+static int gdb_read(void* buf,int len)
+{
+ int n, log_n = 0;
+ char* r_buf = (char*)buf;
+ uint32_t* log_buf = (uint32_t*)buf;
+ struct pollfd block;
+
+ while(len) {
+ if((n = read(gdb_fd,r_buf,len)) < 0) {
+ switch(errno) {
+ case EWOULDBLOCK: /* or EAGAIN */
+ /* We've been called on a descriptor marked
+ for nonblocking I/O. We better simulate
+ blocking behavior. */
+ block.fd = gdb_fd;
+ block.events = POLLIN;
+ block.revents = 0;
+ poll(&block,1,-1);
+ continue;
+ case EINTR:
+ continue;
+ default:
+ return -1;
+ }
+ }
+ else if(n == 0) {
+ close(gdb_fd);
+ gdb_fd = 0;
+ return -1;
+ }
+ else {
+ len -= n;
+ r_buf += n;
+ if ( config.debug.vapi_id )
+ for ( log_n += n; log_n >= 4; log_n -= 4, ++ log_buf )
+ vapi_write_log_file( VAPI_COMMAND_REQUEST, config.debug.vapi_id, ntohl(*log_buf) );
+ }
+ }
+ return 0;
+}
+
+int gdbcomm_init ()
+{
+ serverPort = config.debug.server_port;
+ if((server_fd = GetServerSocket("or1ksim","tcp",serverPort)))
+ PRINTF("JTAG Proxy server started on port %d\n",serverPort);
+ else
+ PRINTF("Cannot start JTAG proxy server on port %d\n", serverPort);
+}
gdbcomm.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: gdb.h
===================================================================
--- gdb.h (nonexistent)
+++ gdb.h (revision 1765)
@@ -0,0 +1,132 @@
+/* config.h -- Simulator configuration header file
+ Copyright (C) 2001 Chris Ziomkowski, chris@asics.ws
+
+ This file is part of OpenRISC 1000 Architectural Simulator.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef GDB_H
+#define GDB_H
+
+#include
+
+#define DEBUG_SLOWDOWN (1)
+
+enum enum_errors /* modified CZ 24/05/01 */
+{
+ /* Codes > 0 are for system errors */
+
+ ERR_NONE = 0,
+ ERR_CRC = -1,
+ ERR_MEM = -2,
+ JTAG_PROXY_INVALID_COMMAND = -3,
+ JTAG_PROXY_SERVER_TERMINATED = -4,
+ JTAG_PROXY_NO_CONNECTION = -5,
+ JTAG_PROXY_PROTOCOL_ERROR = -6,
+ JTAG_PROXY_COMMAND_NOT_IMPLEMENTED = -7,
+ JTAG_PROXY_INVALID_CHAIN = -8,
+ JTAG_PROXY_INVALID_ADDRESS = -9,
+ JTAG_PROXY_ACCESS_EXCEPTION = -10, /* Write to ROM */
+ JTAG_PROXY_INVALID_LENGTH = -11,
+ JTAG_PROXY_OUT_OF_MEMORY = -12,
+};
+
+/* This is repeated from gdb tm-or1k.h There needs to be
+ a better mechanism for tracking this, but I don't see
+ an easy way to share files between modules. */
+
+typedef enum {
+ JTAG_COMMAND_READ = 1,
+ JTAG_COMMAND_WRITE = 2,
+ JTAG_COMMAND_BLOCK_READ = 3,
+ JTAG_COMMAND_BLOCK_WRITE = 4,
+ JTAG_COMMAND_CHAIN = 5,
+} JTAG_proxy_protocol_commands;
+
+/* Each transmit structure must begin with an integer
+ which specifies the type of command. Information
+ after this is variable. Make sure to have all information
+ aligned properly. If we stick with 32 bit integers, it
+ should be portable onto every platform. These structures
+ will be transmitted across the network in network byte
+ order.
+*/
+
+typedef struct {
+ uint32_t command;
+ uint32_t length;
+ uint32_t address;
+ uint32_t data_H;
+ uint32_t data_L;
+} JTAGProxyWriteMessage;
+
+typedef struct {
+ uint32_t command;
+ uint32_t length;
+ uint32_t address;
+} JTAGProxyReadMessage;
+
+typedef struct {
+ uint32_t command;
+ uint32_t length;
+ uint32_t address;
+ int32_t nRegisters;
+ uint32_t data[1];
+} JTAGProxyBlockWriteMessage;
+
+typedef struct {
+ uint32_t command;
+ uint32_t length;
+ uint32_t address;
+ int32_t nRegisters;
+} JTAGProxyBlockReadMessage;
+
+typedef struct {
+ uint32_t command;
+ uint32_t length;
+ uint32_t chain;
+} JTAGProxyChainMessage;
+
+/* The responses are messages specific, however convention
+ states the first word should be an error code. Again,
+ sticking with 32 bit integers should provide maximum
+ portability. */
+
+typedef struct {
+ int32_t status;
+} JTAGProxyWriteResponse;
+
+typedef struct {
+ int32_t status;
+ uint32_t data_H;
+ uint32_t data_L;
+} JTAGProxyReadResponse;
+
+typedef struct {
+ int32_t status;
+} JTAGProxyBlockWriteResponse;
+
+typedef struct {
+ int32_t status;
+ int32_t nRegisters;
+ uint32_t data[1];
+ /* uint32_t data[nRegisters-1] still unread */
+} JTAGProxyBlockReadResponse;
+
+typedef struct {
+ int32_t status;
+} JTAGProxyChainResponse;
+
+#endif /* GDB_H */
gdb.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: debug_unit.h
===================================================================
--- debug_unit.h (nonexistent)
+++ debug_unit.h (revision 1765)
@@ -0,0 +1,122 @@
+/* debug_unit.h -- Simulation of Or1k debug unit
+ Copyright (C) 2001 Chris Ziomkowski, chris@asics.ws
+
+This file is part of OpenRISC 1000 Architectural Simulator.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+typedef enum {
+ JTAG_CHAIN_GLOBAL = 0,
+ JTAG_CHAIN_DEBUG_UNIT = 1,
+ JTAG_CHAIN_TEST = 2,
+ JTAG_CHAIN_TRACE = 3,
+ JTAG_CHAIN_DEVELOPMENT = 4,
+ JTAG_CHAIN_WISHBONE = 5,
+ JTAG_CHAIN_BLOCK1 = 6,
+ JTAG_CHAIN_BLOCK2 = 7,
+ JTAG_CHAIN_OPTIONAL0 = 8,
+ JTAG_CHAIN_OPTIONAL1 = 9,
+ JTAG_CHAIN_OPTIONAL2 = 10,
+ JTAG_CHAIN_OPTIONAL3 = 11,
+ JTAG_CHAIN_OPTIONAL4 = 12,
+ JTAG_CHAIN_OPTIONAL5 = 13,
+ JTAG_CHAIN_OPTIONAL6 = 14,
+ JTAG_CHAIN_OPTIONAL7 = 15,
+} DebugScanChainIDs;
+
+
+typedef struct {
+ unsigned int DCR_hit;
+ unsigned int watchpoint;
+} DebugUnit;
+
+typedef enum {
+ DebugInstructionFetch = 1,
+ DebugLoadAddress = 2,
+ DebugStoreAddress = 3,
+ DebugLoadData = 4,
+ DebugStoreData = 5,
+} DebugUnitAction;
+
+
+/* Debug registers and their bits */
+typedef struct {
+ unsigned long moder;
+ unsigned long tsel;
+ unsigned long qsel;
+ unsigned long ssel;
+ unsigned long riscop;
+ unsigned long recwp[11];
+ unsigned long recbp;
+} DevelopmentInterface;
+
+typedef enum {
+ DEVELOPINT_MODER = 0,
+ DEVELOPINT_TSEL = 1,
+ DEVELOPINT_QSEL = 2,
+ DEVELOPINT_SSEL = 3,
+ DEVELOPINT_RISCOP = 4,
+ DEVELOPINT_RECWP0 = 16,
+ DEVELOPINT_RECWP1 = 17,
+ DEVELOPINT_RECWP2 = 18,
+ DEVELOPINT_RECWP3 = 19,
+ DEVELOPINT_RECWP4 = 20,
+ DEVELOPINT_RECWP5 = 21,
+ DEVELOPINT_RECWP6 = 22,
+ DEVELOPINT_RECWP7 = 23,
+ DEVELOPINT_RECWP8 = 24,
+ DEVELOPINT_RECWP9 = 25,
+ DEVELOPINT_RECWP10 = 26,
+ DEVELOPINT_RECBP0 = 27,
+} DevelopmentInterfaceAddressSpace;
+
+#define RISCOP_STALL 0x00000001
+#define RISCOP_RESET 0x00000002
+
+/* Resets the debug unit */
+void du_reset(void);
+
+/* do cycle-related initialisation (watchpoints etc.) */
+void du_clock();
+
+/* set cpu_stalled flag */
+void set_stall_state (int state);
+
+/* Whether debug unit should ignore exception */
+int debug_ignore_exception (unsigned long except);
+
+/* Gets development interface register */
+int get_devint_reg(unsigned int addr, unsigned long *data);
+
+/* Sets development interface register */
+int set_devint_reg(unsigned int addr, unsigned long data);
+
+/* Reads from bus address */
+int debug_get_mem(unsigned int address, unsigned long *data);
+
+/* Writes to bus address */
+int debug_set_mem(unsigned int address, unsigned long data);
+
+int DebugGetRegister(unsigned int address, unsigned long *data);
+
+int DebugSetRegister(unsigned int address, unsigned long data);
+
+int DebugSetChain(int chain);
+
+#ifdef DEBUGMOD_OFF
+#define CheckDebugUnit(x,y) 0
+#else
+int CheckDebugUnit(DebugUnitAction, unsigned long);
+#endif
debug_unit.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: gdbcomm.h
===================================================================
--- gdbcomm.h (nonexistent)
+++ gdbcomm.h (revision 1765)
@@ -0,0 +1,37 @@
+/* gdbcomm.h -- Communication routines for gdb
+ Copyright (C) 2001 by Marko Mlinar, markom@opencores.org
+ Code copied from toplevel.c
+
+ This file is part of OpenRISC 1000 Architectural Simulator.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "gdb.h"
+#include
+#include
+typedef enum {
+ false = 0,
+ true = 1,
+} Boolean;
+
+void HandleServerSocket(Boolean);
+void JTAGRequest(void);
+void GDBRequest(void);
+void ProtocolClean(int,int32_t);
+void BlockJTAG(void);
+int GetServerSocket(const char* name,const char* proto,int port);
+
+int gdbcomm_init ();
gdbcomm.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: Makefile.am
===================================================================
--- Makefile.am (nonexistent)
+++ Makefile.am (revision 1765)
@@ -0,0 +1,22 @@
+# Makefile -- Makefile for peripherals simulation
+# Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+#
+# This file is part of OpenRISC 1000 Architectural Simulator.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+noinst_LIBRARIES = libdebug.a
+libdebug_a_SOURCES = debug_unit.c debug_unit.h gdbcomm.c gdbcomm.h
Makefile.am
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: .
===================================================================
--- . (nonexistent)
+++ . (revision 1765)
.
Property changes :
Added: svn:ignore
## -0,0 +1,2 ##
+Makefile
+.deps