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_64/or1ksim/debug
- from Rev 1454 to Rev 1765
- ↔ Reverse comparison
Rev 1454 → Rev 1765
/debug_unit.c
0,0 → 1,490
/* 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 "gdb.h" |
#include "except.h" |
#include "opcode/or32.h" |
#include "spr_defs.h" |
#include "execute.h" |
#include "sprs.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: Makefile.in
===================================================================
--- Makefile.in (nonexistent)
+++ Makefile.in (revision 1765)
@@ -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:
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