OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 220 to Rev 221
    Reverse comparison

Rev 220 → Rev 221

/trunk/gen_or1k_isa/sources/or32.c
27,9 → 27,12
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "parse.h"
#include "opcode/or32.h"
 
#ifndef debug
#define debug
#endif
 
/* **INDENT-OFF** */
 
CONST struct or32_letter or32_letters[] =
267,8 → 270,8
{ "l.or", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x4", EF(l_or), 0 },
{ "l.xor", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x5", EF(l_xor), 0 },
{ "l.mul", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-11 ---- 0x6", EF(l_mul), 0 },
{ "l.mac", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 0--- 0x7", EF(l_mac), 0 }, /*MM*/
{ "l.msb", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 1--- 0x7", EF(l_msb), 0 }, /*MM*/
{ "l.mac", "rA,rB", "11 0x8 ----- AAAAA BBBB B-00 0--- 0x7", EF(l_mac), 0 }, /*MM*/
{ "l.msb", "rA,rB", "11 0x8 ----- AAAAA BBBB B-00 1--- 0x7", EF(l_msb), 0 }, /*MM*/
{ "l.sll", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 00-- 0x8", EF(l_sll), 0 },
{ "l.srl", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 01-- 0x8", EF(l_srl), 0 },
{ "l.sra", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 10-- 0x8", EF(l_sra), 0 },
301,6 → 304,26
{ "l.cust7", "", "11 0xE ----- ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust8", "", "11 0xF ----- ----- ---- ---- ---- ----", EFI, 0 },
 
/* This section should not be defined in or1ksim, since it contains duplicates,
which would cause machine builder to complain. */
#ifndef HAS_EXECUTION
{ "l.cust5_1", "rD", "11 0xC DDDDD ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust5_2", "rD,rA" , "11 0xC DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
{ "l.cust5_3", "rD,rA,rB", "11 0xC DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
 
{ "l.cust6_1", "rD", "11 0xD DDDDD ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust6_2", "rD,rA" , "11 0xD DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
{ "l.cust6_3", "rD,rA,rB", "11 0xD DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
 
{ "l.cust7_1", "rD", "11 0xE DDDDD ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust7_2", "rD,rA" , "11 0xE DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
{ "l.cust7_3", "rD,rA,rB", "11 0xE DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
 
{ "l.cust8_1", "rD", "11 0xF DDDDD ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust8_2", "rD,rA" , "11 0xF DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
{ "l.cust8_3", "rD,rA,rB", "11 0xF DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
#endif
 
{ "", "", "", EFI, 0 } /* Dummy entry, not included in num_opcodes. This
lets code examine entry i+1 without checking
if we've run off the end of the table. */
/trunk/gen_or1k_isa/sources/opcode/or32.c
27,9 → 27,12
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "parse.h"
#include "opcode/or32.h"
 
#ifndef debug
#define debug
#endif
 
/* **INDENT-OFF** */
 
CONST struct or32_letter or32_letters[] =
267,8 → 270,8
{ "l.or", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x4", EF(l_or), 0 },
{ "l.xor", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x5", EF(l_xor), 0 },
{ "l.mul", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-11 ---- 0x6", EF(l_mul), 0 },
{ "l.mac", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 0--- 0x7", EF(l_mac), 0 }, /*MM*/
{ "l.msb", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 1--- 0x7", EF(l_msb), 0 }, /*MM*/
{ "l.mac", "rA,rB", "11 0x8 ----- AAAAA BBBB B-00 0--- 0x7", EF(l_mac), 0 }, /*MM*/
{ "l.msb", "rA,rB", "11 0x8 ----- AAAAA BBBB B-00 1--- 0x7", EF(l_msb), 0 }, /*MM*/
{ "l.sll", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 00-- 0x8", EF(l_sll), 0 },
{ "l.srl", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 01-- 0x8", EF(l_srl), 0 },
{ "l.sra", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 10-- 0x8", EF(l_sra), 0 },
301,6 → 304,26
{ "l.cust7", "", "11 0xE ----- ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust8", "", "11 0xF ----- ----- ---- ---- ---- ----", EFI, 0 },
 
/* This section should not be defined in or1ksim, since it contains duplicates,
which would cause machine builder to complain. */
#ifndef HAS_EXECUTION
{ "l.cust5_1", "rD", "11 0xC DDDDD ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust5_2", "rD,rA" , "11 0xC DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
{ "l.cust5_3", "rD,rA,rB", "11 0xC DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
 
{ "l.cust6_1", "rD", "11 0xD DDDDD ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust6_2", "rD,rA" , "11 0xD DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
{ "l.cust6_3", "rD,rA,rB", "11 0xD DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
 
{ "l.cust7_1", "rD", "11 0xE DDDDD ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust7_2", "rD,rA" , "11 0xE DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
{ "l.cust7_3", "rD,rA,rB", "11 0xE DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
 
{ "l.cust8_1", "rD", "11 0xF DDDDD ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust8_2", "rD,rA" , "11 0xF DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
{ "l.cust8_3", "rD,rA,rB", "11 0xF DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
#endif
 
{ "", "", "", EFI, 0 } /* Dummy entry, not included in num_opcodes. This
lets code examine entry i+1 without checking
if we've run off the end of the table. */
/trunk/insight/opcodes/or32.c
27,9 → 27,12
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "parse.h"
#include "opcode/or32.h"
 
#ifndef debug
#define debug
#endif
 
/* **INDENT-OFF** */
 
CONST struct or32_letter or32_letters[] =
267,8 → 270,8
{ "l.or", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x4", EF(l_or), 0 },
{ "l.xor", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x5", EF(l_xor), 0 },
{ "l.mul", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-11 ---- 0x6", EF(l_mul), 0 },
{ "l.mac", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 0--- 0x7", EF(l_mac), 0 }, /*MM*/
{ "l.msb", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 1--- 0x7", EF(l_msb), 0 }, /*MM*/
{ "l.mac", "rA,rB", "11 0x8 ----- AAAAA BBBB B-00 0--- 0x7", EF(l_mac), 0 }, /*MM*/
{ "l.msb", "rA,rB", "11 0x8 ----- AAAAA BBBB B-00 1--- 0x7", EF(l_msb), 0 }, /*MM*/
{ "l.sll", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 00-- 0x8", EF(l_sll), 0 },
{ "l.srl", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 01-- 0x8", EF(l_srl), 0 },
{ "l.sra", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 10-- 0x8", EF(l_sra), 0 },
301,6 → 304,26
{ "l.cust7", "", "11 0xE ----- ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust8", "", "11 0xF ----- ----- ---- ---- ---- ----", EFI, 0 },
 
/* This section should not be defined in or1ksim, since it contains duplicates,
which would cause machine builder to complain. */
#ifndef HAS_EXECUTION
{ "l.cust5_1", "rD", "11 0xC DDDDD ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust5_2", "rD,rA" , "11 0xC DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
{ "l.cust5_3", "rD,rA,rB", "11 0xC DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
 
{ "l.cust6_1", "rD", "11 0xD DDDDD ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust6_2", "rD,rA" , "11 0xD DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
{ "l.cust6_3", "rD,rA,rB", "11 0xD DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
 
{ "l.cust7_1", "rD", "11 0xE DDDDD ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust7_2", "rD,rA" , "11 0xE DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
{ "l.cust7_3", "rD,rA,rB", "11 0xE DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
 
{ "l.cust8_1", "rD", "11 0xF DDDDD ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust8_2", "rD,rA" , "11 0xF DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
{ "l.cust8_3", "rD,rA,rB", "11 0xF DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
#endif
 
{ "", "", "", EFI, 0 } /* Dummy entry, not included in num_opcodes. This
lets code examine entry i+1 without checking
if we've run off the end of the table. */
/trunk/or1ksim/sim-config.h
21,7 → 21,7
 
/* Simulator configuration macros. Eventually this one will be a lot bigger. */
 
#define NR_UARTS 4 /* Number of UARTs simulated */
#define NR_UARTS 4 /* Number of UARTs simulated */
#define NR_DMAS 1 /* Number of DMA controllers */
#define NONE 0
#define VIRTUAL 1
51,16 → 51,12
int jitter; /* CZ 250801 - in msecs...time to block */
unsigned long baseaddr; /* Naturally aligned base address */
} uarts[NR_UARTS];
struct {
unsigned long baseaddr;
} dmas[NR_DMAS];
struct {
unsigned long startaddr;
unsigned long endaddr;
} ram;
struct {
unsigned long baseaddr;
} dmas[NR_DMAS];
int simdebug; /* Simulator debugging */
int profile; /* Is profiler running */
FILE *fprof; /* profiler file */
int profile; /* Is profiler running */
FILE *fprof; /* profiler file */
int iprompt; /* Interactive prompt */
int dependstats;/* Calculation of dependency statistics */
int dependency; /* Calculation of dependency (implied by dependstats) */
/trunk/or1ksim/configure
2010,7 → 2010,7
INCLUDES="-I\${top_srcdir}/cpu/common -I\${top_srcdir}/cpu/or1k \
-I\${top_srcdir}/cpu/$CPU_ARCH -I\${top_srcdir}/cache -I\${top_srcdir}/mmu \
-I\${top_srcdir}/bpb -I\${top_srcdir}/peripheral -I\${top_srcdir}/tick \
-I\${top_srcdir}/pm -I\${top_srcdir}/pic"
-I\${top_srcdir}/pm -I\${top_srcdir}/pic -I\${top_srcdir}/debug"
 
 
test -n "$profile" && CFLAGS="$CFLAGS $profile" LDFLAGS="$LDFLAGS $profile"
2120,9 → 2120,9
 
trap 'rm -fr `echo "Makefile bpb/Makefile cache/Makefile cpu/Makefile
cpu/common/Makefile cpu/or32/Makefile cpu/or16/Makefile
cpu/or1k/Makefile cpu/dlx/Makefile
cpu/or1k/Makefile cpu/dlx/Makefile debug/Makefile
support/Makefile mmu/Makefile peripheral/Makefile tick/Makefile
pm/Makefile pic/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
pm/Makefile pic/Makefile debug/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
EOF
cat >> $CONFIG_STATUS <<EOF
 
2238,9 → 2238,9
 
CONFIG_FILES=\${CONFIG_FILES-"Makefile bpb/Makefile cache/Makefile cpu/Makefile
cpu/common/Makefile cpu/or32/Makefile cpu/or16/Makefile
cpu/or1k/Makefile cpu/dlx/Makefile
cpu/or1k/Makefile cpu/dlx/Makefile debug/Makefile
support/Makefile mmu/Makefile peripheral/Makefile tick/Makefile
pm/Makefile pic/Makefile"}
pm/Makefile pic/Makefile debug/Makefile"}
EOF
cat >> $CONFIG_STATUS <<\EOF
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
/trunk/or1ksim/Makefile.in
75,6 → 75,7
CC = @CC@
CFLAGS = @CFLAGS@
CPU_ARCH = @CPU_ARCH@
FPM = @FPM@
INCLUDES = @INCLUDES@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
LOCAL_DEFS = @LOCAL_DEFS@
90,13 → 91,13
host_cpu = @host_cpu@
host_os = @host_os@
 
SUBDIRS = cpu bpb support cache mmu peripheral tick pm pic
SUBDIRS = cpu bpb support cache mmu peripheral tick pm pic debug
 
noinst_PROGRAMS = sim
EXTRA_PROGRAMS = profiler
 
sim_SOURCES = toplevel.c sim-config.c
sim_LDADD = cpu/common/libcommon.a cpu/$(CPU_ARCH)/libarch.a cpu/or1k/libor1k.a support/libsupport.a mmu/libmmu.a bpb/libbpb.a cache/libcache.a peripheral/libperipheral.a tick/libtick.a pm/libpm.a pic/libpic.a
sim_LDADD = cpu/common/libcommon.a cpu/$(CPU_ARCH)/libarch.a cpu/or1k/libor1k.a support/libsupport.a mmu/libmmu.a bpb/libbpb.a cache/libcache.a peripheral/libperipheral.a tick/libtick.a pm/libpm.a pic/libpic.a debug/libdebug.a
 
sim_LDFLAGS = #-lreadline
profiler_SOURCES = profiler.c
119,13 → 120,14
sim_DEPENDENCIES = cpu/common/libcommon.a cpu/$(CPU_ARCH)/libarch.a \
cpu/or1k/libor1k.a support/libsupport.a mmu/libmmu.a bpb/libbpb.a \
cache/libcache.a peripheral/libperipheral.a tick/libtick.a pm/libpm.a \
pic/libpic.a
pic/libpic.a debug/libdebug.a
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
DIST_COMMON = ./stamp-h.in ChangeLog Makefile.am Makefile.in acconfig.h \
aclocal.m4 config.guess config.h.in config.sub configure configure.in \
install-sh missing mkinstalldirs
DIST_COMMON = README ./stamp-h.in AUTHORS COPYING ChangeLog INSTALL \
Makefile.am Makefile.in NEWS TODO acconfig.h aclocal.m4 config.guess \
config.h.in config.sub configure configure.in install-sh missing \
mkinstalldirs
 
 
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
/trunk/or1ksim/debug/Makefile.in
0,0 → 1,333
# Makefile.in generated automatically by automake 1.4 from Makefile.am
 
# Copyright (C) 1994, 1995-8, 1999 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.
 
# 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
 
DESTDIR =
 
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
 
top_builddir = ..
 
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
 
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
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@
AR = @AR@
ARFLAGS = @ARFLAGS@
BUILD_DIR = @BUILD_DIR@
CC = @CC@
CFLAGS = @CFLAGS@
CPU_ARCH = @CPU_ARCH@
FPM = @FPM@
INCLUDES = @INCLUDES@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
LOCAL_DEFS = @LOCAL_DEFS@
LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
MAKEINFO = @MAKEINFO@
MAKE_SHELL = @MAKE_SHELL@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
SUMVERSION = @SUMVERSION@
TERMCAP_LIB = @TERMCAP_LIB@
VERSION = @VERSION@
host = @host@
host_cpu = @host_cpu@
host_os = @host_os@
 
noinst_LIBRARIES = libdebug.a
libdebug_a_SOURCES = debug_unit.c debug_unit.h
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../config.h
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
 
 
DEFS = @DEFS@ -I. -I$(srcdir) -I..
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libdebug_a_LIBADD =
libdebug_a_OBJECTS = debug_unit.o
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
DIST_COMMON = Makefile.am Makefile.in
 
 
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
TAR = gtar
GZIP_ENV = --best
DEP_FILES = .deps/debug_unit.P
SOURCES = $(libdebug_a_SOURCES)
OBJECTS = $(libdebug_a_OBJECTS)
 
all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .o .s
$(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 $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
 
mostlyclean-noinstLIBRARIES:
 
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
 
distclean-noinstLIBRARIES:
 
maintainer-clean-noinstLIBRARIES:
 
.s.o:
$(COMPILE) -c $<
 
.S.o:
$(COMPILE) -c $<
 
mostlyclean-compile:
-rm -f *.o core *.core
 
clean-compile:
 
distclean-compile:
-rm -f *.tab.c
 
maintainer-clean-compile:
 
libdebug.a: $(libdebug_a_OBJECTS) $(libdebug_a_DEPENDENCIES)
-rm -f libdebug.a
$(AR) cru libdebug.a $(libdebug_a_OBJECTS) $(libdebug_a_LIBADD)
$(RANLIB) libdebug.a
 
tags: TAGS
 
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
 
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
 
mostlyclean-tags:
 
clean-tags:
 
distclean-tags:
-rm -f TAGS ID
 
maintainer-clean-tags:
 
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 
subdir = debug
 
distdir: $(DISTFILES)
here=`cd $(top_builddir) && pwd`; \
top_distdir=`cd $(top_distdir) && pwd`; \
distdir=`cd $(distdir) && pwd`; \
cd $(top_srcdir) \
&& $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu debug/Makefile
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
 
DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
 
-include $(DEP_FILES)
 
mostlyclean-depend:
 
clean-depend:
 
distclean-depend:
-rm -rf .deps
 
maintainer-clean-depend:
 
%.o: %.c
@echo '$(COMPILE) -c $<'; \
$(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
@-cp .deps/$(*F).pp .deps/$(*F).P; \
tr ' ' '\012' < .deps/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*F).P; \
rm .deps/$(*F).pp
 
%.lo: %.c
@echo '$(LTCOMPILE) -c $<'; \
$(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
< .deps/$(*F).pp > .deps/$(*F).P; \
tr ' ' '\012' < .deps/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*F).P; \
rm -f .deps/$(*F).pp
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
install-exec-am:
install-exec: install-exec-am
 
install-data-am:
install-data: install-data-am
 
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am:
uninstall: uninstall-am
all-am: Makefile $(LIBRARIES)
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
 
 
mostlyclean-generic:
 
clean-generic:
 
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
 
maintainer-clean-generic:
mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \
mostlyclean-tags mostlyclean-depend mostlyclean-generic
 
mostlyclean: mostlyclean-am
 
clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-depend \
clean-generic mostlyclean-am
 
clean: clean-am
 
distclean-am: distclean-noinstLIBRARIES distclean-compile \
distclean-tags distclean-depend distclean-generic \
clean-am
 
distclean: distclean-am
 
maintainer-clean-am: maintainer-clean-noinstLIBRARIES \
maintainer-clean-compile maintainer-clean-tags \
maintainer-clean-depend maintainer-clean-generic \
distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
 
maintainer-clean: maintainer-clean-am
 
.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile tags mostlyclean-tags distclean-tags \
clean-tags maintainer-clean-tags distdir mostlyclean-depend \
distclean-depend clean-depend maintainer-clean-depend info-am info \
dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
install-exec install-data-am install-data install-am install \
uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
 
# 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:
/trunk/or1ksim/debug/debug_unit.c.bak
0,0 → 1,715
/* 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.
*/
 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
 
#include "debug_unit.h"
#include "sim-config.h"
#include "except.h"
#include "arch.h"
#include "abstract.h"
#include "parse.h"
#include "trace.h"
#include "sprs.h"
#include "../gdb.h"
#include "../cpu/or1k/except.h"
#include "opcode/or32.h"
 
DebugUnit debug_unit;
DevelopmentInterface development;
 
typedef enum {
false = 0,
true = 1,
} Boolean;
static void ExecuteInducedInstruction(unsigned long);
 
/* External STALL signal to debug interface */
int cpu_stalled = false;
int in_reset = false;
 
/* An induced instruction has been written to the DIR register */
static Boolean induced = false;
static unsigned long induced_insn;
 
/* A flag to indicate that we must perform an ic mmu cycle */
static Boolean lookup_physical_address = false;
 
/* Variables for implementing ExecuteInducedInstruction */
extern unsigned long pc;
extern unsigned long pcnext;
extern unsigned long pcdelay;
extern unsigned long pc_phy;
extern int delay_insn;
static void GetIQueueEntry(struct iqueue_entry*);
 
static int CalculateWatchpoints(void);
 
static int watchpoint[10];
 
/* This function returns true if an induced instruction has
been inserted into the instruction stream. It will remove
that instruction and return the result. This function is
called from the fetch() routine. */
int OverrideFetch(unsigned long* insn)
{
int valid = induced;
induced = false;
 
if(valid)
*insn = induced_insn;
return valid;
}
 
void InduceImmediateInstruction(unsigned long insn)
{
induced = true;
induced_insn = insn;
 
if(in_reset)
return;
 
if(cpu_stalled)
{
ExecuteInducedInstruction(insn);
induced_insn = 0;
induced = false;
}
}
 
void SetCPUStallState(int state)
{
if(debug_unit.DMR1.DXFW) /* If debugger disabled */
state = false;
 
if(state == cpu_stalled)
return;
 
if(state && induced)
{
ExecuteInducedInstruction(induced_insn);
induced_insn = 0;
induced = false;
}
 
cpu_stalled = state;
}
 
void ResetDebugUnit()
{
memset(&debug_unit,'\0',sizeof(DebugUnit));
cpu_stalled = 0;
}
 
#ifdef DEBUGMOD_OFF
#define CheckDebugUnit(x,y) 0
#else
inline int CheckDebugUnit(DebugUnitAction action,unsigned long udata)
{
int i;
DCR_CT_Settings condition = DCR_CT_Disabled;
long data = (long)udata;
int match;
 
if(in_reset)
return 0;
 
/* If we're single stepping, always stop */
if(debug_unit.DMR1.ST && action == DebugInstructionFetch)
return 1;
 
switch(action)
{
case DebugInstructionFetch: condition = DCR_CT_InsnAddress; break;
case DebugLoadAddress: condition = DCR_CT_LoadAddress; break;
case DebugStoreAddress: condition = DCR_CT_StoreAddress; break;
case DebugLoadData: condition = DCR_CT_LoadData; break;
case DebugStoreData: condition = DCR_CT_StoreData; break;
}
 
for(i=0;i<8;i++)
{
if(debug_unit.DCR[i].DP == DCR_DP_Absent)
continue;
 
if(debug_unit.DCR[i].CT == condition)
{
if(debug_unit.DCR[i].SC == DCR_SC_Signed)
{
switch(debug_unit.DCR[i].CC)
{
case DCR_CC_Equal: match = data == (int)debug_unit.DVR[i]; break;
case DCR_CC_LessThan: match = data < (int)debug_unit.DVR[i]; break;
case DCR_CC_LessEqual: match = data <= (int)debug_unit.DVR[i]; break;
case DCR_CC_GreaterThan: match = data > (int)debug_unit.DVR[i]; break;
case DCR_CC_GreaterEqual: match = data >= (int)debug_unit.DVR[i]; break;
case DCR_CC_NotEqual: match = data != (int)debug_unit.DVR[i]; break;
default: match = 0; break;
}
}
else
{
switch(debug_unit.DCR[i].CC)
{
case DCR_CC_Equal: match = udata == debug_unit.DVR[i]; break;
case DCR_CC_LessThan: match = udata < debug_unit.DVR[i]; break;
case DCR_CC_LessEqual: match = udata <= debug_unit.DVR[i]; break;
case DCR_CC_GreaterThan: match = udata > debug_unit.DVR[i]; break;
case DCR_CC_GreaterEqual: match = udata >= debug_unit.DVR[i]; break;
case DCR_CC_NotEqual: match = udata != debug_unit.DVR[i]; break;
default: match = 0; break;
}
}
}
match <<= i;
debug_unit.DCR_hit &= ~match; /* Clear DCR compare if it has changed */
debug_unit.DCR_hit |= match; /* Save the state of each DCR compare */
}
 
return CalculateWatchpoints();
}
#endif
 
static int CalculateWatchpoints()
{
int spec[11];
int breakpoint = 0;
int i,bit;
 
spec[0] = debug_unit.DMR1.CW0;
spec[1] = debug_unit.DMR1.CW1;
spec[2] = debug_unit.DMR1.CW2;
spec[3] = debug_unit.DMR1.CW3;
spec[4] = debug_unit.DMR1.CW4;
spec[5] = debug_unit.DMR1.CW5;
spec[6] = debug_unit.DMR1.CW6;
spec[7] = debug_unit.DMR1.CW7;
spec[8] = debug_unit.DMR1.CW8;
spec[9] = debug_unit.DMR1.CW9;
spec[10] = debug_unit.DMR1.CW10;
 
for(i=0,bit=1;i<11;i++,bit<<=1)
{
int chain1,chain2;
int match = 0;
 
switch(i)
{
case 0:
chain1 = chain2 = debug_unit.DCR_hit & 0x01;
break;
case 8:
chain1 = debug_unit.DWCR[0].COUNT == debug_unit.DWCR[0].MATCH;
chain2 = debug_unit.watchpoint & (1 << 7);
break;
case 9:
chain1 = debug_unit.DWCR[1].COUNT == debug_unit.DWCR[1].MATCH;
chain2 = debug_unit.watchpoint & (1 << 8);
break;
case 10:
chain1 = debug_unit.DCR_hit & 0x100; /* External hit */
chain2 = debug_unit.watchpoint & (1 << 9);
break;
default:
chain1 = debug_unit.DCR_hit & bit;
chain2 = debug_unit.watchpoint & (bit >> 1);
break;
}
 
switch(spec[i])
{
case 0: match = chain1; break;
case 1: match = chain1 && chain2; break;
case 2: match = chain1 || chain2; break;
default:
break;
}
 
if(match & !(debug_unit.watchpoint & bit))
{
int counter = (debug_unit.DMR2.AWPC & bit) ? 1 : 0;
int enabled = counter ? debug_unit.DMR2.WCE1 : debug_unit.DMR2.WCE0;
 
if(enabled)
debug_unit.DWCR[counter].COUNT++;
 
if(debug_unit.DMR2.WGB & bit)
breakpoint = 1;
}
debug_unit.watchpoint &= ~bit;
debug_unit.watchpoint |= bit;
}
 
return breakpoint;
}
 
static void GetIQueueEntry(struct iqueue_entry* iq_entry)
{
iq_entry->insn = induced_insn;
iq_entry->insn_index = insn_decode(induced_insn);
iq_entry->insn_addr = pc_phy;
iq_entry->op[0] = 0;
iq_entry->op[MAX_OPERANDS] = OPTYPE_LAST;
}
 
static void ExecuteInducedInstruction(unsigned long insn)
{
struct iqueue_entry iq_entry;
unsigned long pc_saved = pc;
unsigned long pcnext_saved = pcnext;
unsigned long pcdelay_saved = pcdelay;
unsigned long pc_phy_saved = pc_phy;
 
GetIQueueEntry(&iq_entry);
decode_execute(&iq_entry);
 
pc = pc_saved;
pcnext = pcnext_saved;
pcdelay = pcdelay_saved;
pc_phy = pc_phy_saved;
}
 
static DebugScanChainIDs current_scan_chain = JTAG_CHAIN_GLOBAL;
 
int DebugGetRegister(unsigned int address,int32_t* data)
{
int err;
printf("Debug get register %x\n",address);
fflush(stdout);
switch(current_scan_chain)
{
case JTAG_CHAIN_DEBUG_UNIT:
err = GetDebugUnitRegister(address,data);
break;
case JTAG_CHAIN_TRACE:
*data = 0; /* Scan chain not yet implemented */
err = 0;
break;
case JTAG_CHAIN_DEVELOPMENT:
err = GetDevelopmentInterfaceRegister(address,data);
break;
}
printf("!get reg %x\n", *data);
fflush(stdout);
return err;
}
 
int DebugSetRegister(unsigned int address,int32_t data)
{
int err;
printf("Debug set register %x <- %x\n",address, data);
fflush(stdout);
switch(current_scan_chain)
{
case JTAG_CHAIN_DEBUG_UNIT:
err = SetDebugUnitRegister(address,data);
break;
case JTAG_CHAIN_TRACE:
err = JTAG_PROXY_ACCESS_EXCEPTION;
break;
case JTAG_CHAIN_DEVELOPMENT:
err = SetDevelopmentInterfaceRegister(address,data);
break;
}
printf("!set reg\n");
fflush(stdout);
return err;
}
 
int DebugSetChain(int chain)
{
printf("Debug set chain %x\n",chain);
fflush(stdout);
switch(chain)
{
case JTAG_CHAIN_DEBUG_UNIT:
case JTAG_CHAIN_TRACE:
case JTAG_CHAIN_DEVELOPMENT:
current_scan_chain = chain;
break;
default: /* All other chains not implemented */
return JTAG_PROXY_INVALID_CHAIN;
}
 
printf("!set chain\n");
fflush(stdout);
return 0;
}
 
/* Nearly all compilers today store these bit fields as a packed structure
in network byte order (Big Endian). If you happen to be unlucky enough
to be working in a non standard environment, you may need to rewrite
this routine or the SET_REG32 macro. */
int SetDevelopmentInterfaceRegister(unsigned int address,uint32_t data)
{
int err = 0;
uint32_t value = data;
int old_value;
char *t_ptr = (char*)&development.RISCOP;
 
switch(address)
{
case DEVELOPINT_MODER:
SET_REG32(development.MODER,value);
break;
case DEVELOPINT_TSEL:
SET_REG32(development.TSEL,value);
break;
case DEVELOPINT_QSEL:
SET_REG32(development.QSEL,value);
break;
case DEVELOPINT_SSEL:
SET_REG32(development.SSEL,value);
break;
case DEVELOPINT_RISCOP:
old_value = development.RISCOP.RESET;
SET_REG32(development.RISCOP,value);
in_reset = development.RISCOP.RESET;
 
/* Reset the cpu on the negative edge of RESET */
if(old_value && !development.RISCOP.RESET)
{
uart_reset();
tick_reset();
pm_reset();
pic_reset();
reset(); /* Old or new mode */
}
 
SetCPUStallState(development.RISCOP.RISCSTALL);
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:
SET_REG32(development.RECWP[address-DEVELOPINT_RECWP0],value);
break;
case DEVELOPINT_RECBP0:
SET_REG32(development.RECBP[0],value);
break;
default:
err = JTAG_PROXY_INVALID_ADDRESS;
break;
}
return err;
}
 
int GetDevelopmentInterfaceRegister(unsigned int address,uint32_t *data)
{
int err = 0;
uint32_t value = 0;
 
switch(address)
{
case DEVELOPINT_MODER: GET_REG32(development.MODER,value); break;
case DEVELOPINT_TSEL: GET_REG32(development.TSEL,value); break;
case DEVELOPINT_QSEL: GET_REG32(development.QSEL,value); break;
case DEVELOPINT_SSEL: GET_REG32(development.SSEL,value); break;
case DEVELOPINT_RISCOP: GET_REG32(development.RISCOP,value); 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: GET_REG32(development.RECWP[address-DEVELOPINT_RECWP0],value); break;
case DEVELOPINT_RECBP0: GET_REG32(development.RECBP[0],value); break;
default: err = JTAG_PROXY_INVALID_ADDRESS; break;
}
*data = value;
return err;
}
 
/* Nearly all compilers today store these bit fields as a packed structure
in network byte order (Big Endian). If you happen to be unlucky enough
to be working in a non standard environment, you may need to rewrite
this routine or the SET_REG32 macro. */
int SetDebugUnitRegister(unsigned int address,uint32_t data)
{
int err = 0;
uint32_t value = data;
int old_value;
int group = address >> 11;
 
/* This is a memory location */
if(address & 0x80000000)
{
address &= 0x7FFFFFFF;
address <<= 2;
 
if(!verify_memoryarea(address))
err = JTAG_PROXY_INVALID_ADDRESS;
else
{
unsigned char t_data[4];
int *tmp = (int*)t_data;
extern char null_str[1]; /* From cpu/common/parse.c */
int i;
 
*tmp = htonl(data); /* We have already converted to host order */
 
setsim_mem8(address++, t_data[0]); /* Back to network byte order */
setsim_mem8(address++, t_data[1]);
setsim_mem8(address++, t_data[2]);
setsim_mem8(address++, t_data[3]);
}
return err;
}
 
address &= 0x07FF;
/*****************************************************/
/* TEMPORARY!!!! */
/*****************************************************/
if(group == 6)
address -= 32;
 
if(group == 6)
{
switch(address)
{
case DEBUGINT_DVR0:
case DEBUGINT_DVR1:
case DEBUGINT_DVR2:
case DEBUGINT_DVR3:
case DEBUGINT_DVR4:
case DEBUGINT_DVR5:
case DEBUGINT_DVR6:
case DEBUGINT_DVR7:
printf("DVR %d set to 0x%08x\n",address-DEBUGINT_DVR0,value);
SET_REG32(debug_unit.DVR[address-DEBUGINT_DVR0],value);
break;
case DEBUGINT_DCR0:
case DEBUGINT_DCR1:
case DEBUGINT_DCR2:
case DEBUGINT_DCR3:
case DEBUGINT_DCR4:
case DEBUGINT_DCR5:
case DEBUGINT_DCR6:
case DEBUGINT_DCR7:
printf("DCR %d set to 0x%08x\n",address-DEBUGINT_DCR0,value);
SET_REG32(debug_unit.DCR[address-DEBUGINT_DCR0],value);
break;
case DEBUGINT_DMR1:
SET_REG32(debug_unit.DMR1,value);
break;
case DEBUGINT_DMR2:
SET_REG32(debug_unit.DMR2,value);
break;
case DEBUGINT_DWCR0:
SET_REG32(debug_unit.DWCR[0],value);
break;
case DEBUGINT_DWCR1:
SET_REG32(debug_unit.DWCR[1],value);
break;
case DEBUGINT_DSR:
SET_REG32(debug_unit.DSR,value);
break;
case DEBUGINT_DRR:
SET_REG32(debug_unit.DRR,value);
break;
case DEBUGINT_DIR:
InduceImmediateInstruction(value);
break;
default:
err = JTAG_PROXY_INVALID_ADDRESS;
break;
}
}
else if(group == 0)
{
extern unsigned long reg[32];
 
if(!address)
err = JTAG_PROXY_ACCESS_EXCEPTION;
else if(address < 32)
{
/* Assume that a write to the PC implies
that the debugging software has recognized
the exception and wants to do something
else instead. */
 
if(address == SPR_PC)
{
ClearPendingException();
ClearPreparedPCState();
}
mtspr(address,data);
}
else if(address >= 0x0400 && address < 0x0420)
reg[address - 0x0400] = data;
else if(address < 0x0600 || address >= 0x0620)
err = JTAG_PROXY_INVALID_ADDRESS;
}
else
err = JTAG_PROXY_INVALID_ADDRESS;
 
return err;
}
 
int GetDebugUnitRegister(unsigned int address,uint32_t *data)
{
int err = 0;
uint32_t value = 0;
int group = address >> 11;
 
/* This is a memory location */
if(address & 0x80000000)
{
address &= 0x7FFFFFFF;
address <<= 2;
if(!verify_memoryarea(address))
err = JTAG_PROXY_INVALID_ADDRESS;
else
{
unsigned char t_data[4];
int *tmp = (int*)t_data;
int bp;
 
t_data[0] = evalsim_mem8(address++);
t_data[1] = evalsim_mem8(address++);
t_data[2] = evalsim_mem8(address++);
t_data[3] = evalsim_mem8(address++); /* Already in network byte order */
*data = ntohl(*tmp); /* But we assume it is in host order later */
}
return err;
}
address &= 0x07FF;
/*****************************************************/
/* TEMPORARY!!!! */
/*****************************************************/
if(group == 6)
address -= 32;
 
if(group == 6)
{
switch(address)
{
case DEBUGINT_DVR0:
case DEBUGINT_DVR1:
case DEBUGINT_DVR2:
case DEBUGINT_DVR3:
case DEBUGINT_DVR4:
case DEBUGINT_DVR5:
case DEBUGINT_DVR6:
case DEBUGINT_DVR7: GET_REG32(debug_unit.DVR[address-DEBUGINT_DVR0],value); break;
case DEBUGINT_DCR0:
case DEBUGINT_DCR1:
case DEBUGINT_DCR2:
case DEBUGINT_DCR3:
case DEBUGINT_DCR4:
case DEBUGINT_DCR5:
case DEBUGINT_DCR6:
case DEBUGINT_DCR7: GET_REG32(debug_unit.DCR[address-DEBUGINT_DCR0],value); break;
case DEBUGINT_DMR1: GET_REG32(debug_unit.DMR1,value); break;
case DEBUGINT_DMR2: GET_REG32(debug_unit.DMR2,value); break;
case DEBUGINT_DWCR0: GET_REG32(debug_unit.DWCR[0],value); break;
case DEBUGINT_DWCR1: GET_REG32(debug_unit.DWCR[1],value); break;
case DEBUGINT_DSR: GET_REG32(debug_unit.DSR,value); break;
case DEBUGINT_DRR: GET_REG32(debug_unit.DRR,value); break;
case DEBUGINT_DIR: err = JTAG_PROXY_ACCESS_EXCEPTION; break;
default: err = JTAG_PROXY_INVALID_ADDRESS; break;
}
}
else if(group == 0)
{
extern unsigned long reg[32];
 
if(address < 32)
value = mfspr(address);
else if(address >= 0x0400 && address < 0x0420)
value = reg[address - 0x400];
else if(address >= 0x0600 && address < 0x0620)
value = 0;
else
err = JTAG_PROXY_INVALID_ADDRESS;
}
else
err = JTAG_PROXY_INVALID_ADDRESS;
 
*data = value;
return err;
}
 
/* DebugCheckException returns 1 if the exception should be ignored.
Currently, this is true only if the exception is a breakpoint
exception and debug_unit.DMR1.ST is set. Sorry, this is a quick
hack to disable processing of breakpoint exceptions on single
stepping. Just one of those historical accidents. Feel free
to rewrite the behavior. */
int DebugCheckException(int exception)
{
int result = 0;
 
switch(exception)
{
case EXCEPT_RESET: result = debug_unit.DRR.RSTE = debug_unit.DSR.RSTE; break;
case EXCEPT_BUSERR: result = debug_unit.DRR.BUSEE = debug_unit.DSR.BUSEE; break;
case EXCEPT_DPF: result = debug_unit.DRR.DPFE = debug_unit.DSR.DPFE; break;
case EXCEPT_IPF: result = debug_unit.DRR.IPFE = debug_unit.DSR.IPFE; break;
case EXCEPT_LPINT: result = debug_unit.DRR.LPINTE = debug_unit.DSR.LPINTE; break;
case EXCEPT_ALIGN: result = debug_unit.DRR.AE = debug_unit.DSR.AE; break;
case EXCEPT_ILLEGAL: result = debug_unit.DRR.IIE = debug_unit.DSR.IIE; break;
case EXCEPT_HPINT: result = debug_unit.DRR.HPINTE = debug_unit.DSR.HPINTE; break;
case EXCEPT_DTLBMISS: result = debug_unit.DRR.DME = debug_unit.DSR.DME; break;
case EXCEPT_ITLBMISS: result = debug_unit.DRR.IME = debug_unit.DSR.IME; break;
case EXCEPT_RANGE: result = debug_unit.DRR.RE = debug_unit.DSR.RE; break;
case EXCEPT_SYSCALL: result = debug_unit.DRR.SCE = debug_unit.DSR.SCE; break;
case EXCEPT_BREAK: result = debug_unit.DRR.BE = debug_unit.DSR.BE; break;
case EXCEPT_TRAP: result = debug_unit.DRR.TE = debug_unit.DSR.TE; break;
default:
break;
}
 
if(result)
SetCPUStallState(true);
 
return (debug_unit.DMR1.ST && exception == EXCEPT_BREAK);
}
trunk/or1ksim/debug/debug_unit.c.bak Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: trunk/or1ksim/debug/debug_unit.c =================================================================== --- trunk/or1ksim/debug/debug_unit.c (nonexistent) +++ trunk/or1ksim/debug/debug_unit.c (revision 221) @@ -0,0 +1,743 @@ +/* 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. +*/ + +#include +#include +#include +#include + +#include "debug_unit.h" +#include "sim-config.h" +#include "except.h" +#include "arch.h" +#include "abstract.h" +#include "parse.h" +#include "trace.h" +#include "sprs.h" +#include "../gdb.h" +#include "../cpu/or1k/except.h" +#include "opcode/or32.h" + +DebugUnit debug_unit; +DevelopmentInterface development; + +typedef enum { + false = 0, + true = 1, +} Boolean; +static void ExecuteInducedInstruction(unsigned long); + +/* External STALL signal to debug interface */ +int cpu_stalled = false; +int in_reset = false; + +/* An induced instruction has been written to the DIR register */ +static Boolean induced = false; +static unsigned long induced_insn; + +/* A flag to indicate that we must perform an ic mmu cycle */ +static Boolean lookup_physical_address = false; + +/* Variables for implementing ExecuteInducedInstruction */ +extern unsigned long pc; +extern unsigned long pcnext; +extern unsigned long pcdelay; +extern unsigned long pc_phy; +extern int delay_insn; +static void GetIQueueEntry(struct iqueue_entry*); + +static int CalculateWatchpoints(void); + +static int watchpoint[10]; + +/* This function returns true if an induced instruction has + been inserted into the instruction stream. It will remove + that instruction and return the result. This function is + called from the fetch() routine. */ +int OverrideFetch(unsigned long* insn) +{ + int valid = induced; + induced = false; + + if(valid) + *insn = induced_insn; + return valid; +} + +void InduceImmediateInstruction(unsigned long insn) +{ + induced = true; + induced_insn = insn; + + if(in_reset) + return; + + if(cpu_stalled) + { + ExecuteInducedInstruction(insn); + induced_insn = 0; + induced = false; + } +} + +void SetCPUStallState(int state) +{ + if(debug_unit.DMR1.DXFW) /* If debugger disabled */ + state = false; + + if(state == cpu_stalled) + return; + + if(state && induced) + { + ExecuteInducedInstruction(induced_insn); + induced_insn = 0; + induced = false; + } + + cpu_stalled = state; +} + +void ResetDebugUnit() +{ + memset(&debug_unit,'\0',sizeof(DebugUnit)); + cpu_stalled = 0; +} + +#ifdef DEBUGMOD_OFF +#define CheckDebugUnit(x,y) 0 +#else +inline int CheckDebugUnit(DebugUnitAction action,unsigned long udata) +{ + int i; + DCR_CT_Settings condition = DCR_CT_Disabled; + long data = (long)udata; + int match; + + if(in_reset) + return 0; + + /* If we're single stepping, always stop */ + if(debug_unit.DMR1.ST && action == DebugInstructionFetch) + return 1; + + switch(action) + { + case DebugInstructionFetch: condition = DCR_CT_InsnAddress; break; + case DebugLoadAddress: condition = DCR_CT_LoadAddress; break; + case DebugStoreAddress: condition = DCR_CT_StoreAddress; break; + case DebugLoadData: condition = DCR_CT_LoadData; break; + case DebugStoreData: condition = DCR_CT_StoreData; break; + } + + for(i=0;i<8;i++) + { + if(debug_unit.DCR[i].DP == DCR_DP_Absent) + continue; + + if(debug_unit.DCR[i].CT == condition) + { + if(debug_unit.DCR[i].SC == DCR_SC_Signed) + { + switch(debug_unit.DCR[i].CC) + { + case DCR_CC_Equal: match = data == (int)debug_unit.DVR[i]; break; + case DCR_CC_LessThan: match = data < (int)debug_unit.DVR[i]; break; + case DCR_CC_LessEqual: match = data <= (int)debug_unit.DVR[i]; break; + case DCR_CC_GreaterThan: match = data > (int)debug_unit.DVR[i]; break; + case DCR_CC_GreaterEqual: match = data >= (int)debug_unit.DVR[i]; break; + case DCR_CC_NotEqual: match = data != (int)debug_unit.DVR[i]; break; + default: match = 0; break; + } + } + else + { + switch(debug_unit.DCR[i].CC) + { + case DCR_CC_Equal: match = udata == debug_unit.DVR[i]; break; + case DCR_CC_LessThan: match = udata < debug_unit.DVR[i]; break; + case DCR_CC_LessEqual: match = udata <= debug_unit.DVR[i]; break; + case DCR_CC_GreaterThan: match = udata > debug_unit.DVR[i]; break; + case DCR_CC_GreaterEqual: match = udata >= debug_unit.DVR[i]; break; + case DCR_CC_NotEqual: match = udata != debug_unit.DVR[i]; break; + default: match = 0; break; + } + } + } + match <<= i; + debug_unit.DCR_hit &= ~match; /* Clear DCR compare if it has changed */ + debug_unit.DCR_hit |= match; /* Save the state of each DCR compare */ + } + + return CalculateWatchpoints(); +} +#endif + +static int CalculateWatchpoints() +{ + int spec[11]; + int breakpoint = 0; + int i,bit; + + spec[0] = debug_unit.DMR1.CW0; + spec[1] = debug_unit.DMR1.CW1; + spec[2] = debug_unit.DMR1.CW2; + spec[3] = debug_unit.DMR1.CW3; + spec[4] = debug_unit.DMR1.CW4; + spec[5] = debug_unit.DMR1.CW5; + spec[6] = debug_unit.DMR1.CW6; + spec[7] = debug_unit.DMR1.CW7; + spec[8] = debug_unit.DMR1.CW8; + spec[9] = debug_unit.DMR1.CW9; + spec[10] = debug_unit.DMR1.CW10; + + for(i=0,bit=1;i<11;i++,bit<<=1) + { + int chain1,chain2; + int match = 0; + + switch(i) + { + case 0: + chain1 = chain2 = debug_unit.DCR_hit & 0x01; + break; + case 8: + chain1 = debug_unit.DWCR[0].COUNT == debug_unit.DWCR[0].MATCH; + chain2 = debug_unit.watchpoint & (1 << 7); + break; + case 9: + chain1 = debug_unit.DWCR[1].COUNT == debug_unit.DWCR[1].MATCH; + chain2 = debug_unit.watchpoint & (1 << 8); + break; + case 10: + chain1 = debug_unit.DCR_hit & 0x100; /* External hit */ + chain2 = debug_unit.watchpoint & (1 << 9); + break; + default: + chain1 = debug_unit.DCR_hit & bit; + chain2 = debug_unit.watchpoint & (bit >> 1); + break; + } + + switch(spec[i]) + { + case 0: match = chain1; break; + case 1: match = chain1 && chain2; break; + case 2: match = chain1 || chain2; break; + default: + break; + } + + if(match & !(debug_unit.watchpoint & bit)) + { + int counter = (debug_unit.DMR2.AWPC & bit) ? 1 : 0; + int enabled = counter ? debug_unit.DMR2.WCE1 : debug_unit.DMR2.WCE0; + + if(enabled) + debug_unit.DWCR[counter].COUNT++; + + if(debug_unit.DMR2.WGB & bit) + breakpoint = 1; + } + + debug_unit.watchpoint &= ~bit; + debug_unit.watchpoint |= bit; + } + + return breakpoint; +} + +static void GetIQueueEntry(struct iqueue_entry* iq_entry) +{ + iq_entry->insn = induced_insn; + iq_entry->insn_index = insn_decode(induced_insn); + iq_entry->insn_addr = pc_phy; + iq_entry->op[0] = 0; + iq_entry->op[MAX_OPERANDS] = OPTYPE_LAST; +} + +static void ExecuteInducedInstruction(unsigned long insn) +{ + struct iqueue_entry iq_entry; + unsigned long pc_saved = pc; + unsigned long pcnext_saved = pcnext; + unsigned long pcdelay_saved = pcdelay; + unsigned long pc_phy_saved = pc_phy; + + GetIQueueEntry(&iq_entry); + decode_execute(&iq_entry); + + pc = pc_saved; + pcnext = pcnext_saved; + pcdelay = pcdelay_saved; + pc_phy = pc_phy_saved; +} + +static DebugScanChainIDs current_scan_chain = JTAG_CHAIN_GLOBAL; + +int DebugGetRegister(unsigned int address,int32_t* data) +{ + int err; +#ifdef DEBUG_JTAG + printf("Debug get register %x\n",address); + fflush(stdout); +#endif + switch(current_scan_chain) + { + case JTAG_CHAIN_DEBUG_UNIT: + err = GetDebugUnitRegister(address,data); + break; + case JTAG_CHAIN_TRACE: + *data = 0; /* Scan chain not yet implemented */ + err = 0; + break; + case JTAG_CHAIN_DEVELOPMENT: + err = GetDevelopmentInterfaceRegister(address,data); + break; + case JTAG_CHAIN_WISHBONE: + err = GetWishboneMemory(address,data); + break; + } +#ifdef DEBUG_JTAG + printf("!get reg %x\n", *data); + fflush(stdout); +#endif + return err; +} + +int DebugSetRegister(unsigned int address,int32_t data) +{ + int err; +#ifdef DEBUG_JTAG + printf("Debug set register %x <- %x\n",address, data); + fflush(stdout); +#endif + switch(current_scan_chain) + { + case JTAG_CHAIN_DEBUG_UNIT: + err = SetDebugUnitRegister(address,data); + break; + case JTAG_CHAIN_TRACE: + err = JTAG_PROXY_ACCESS_EXCEPTION; + break; + case JTAG_CHAIN_DEVELOPMENT: + err = SetDevelopmentInterfaceRegister(address,data); + break; + case JTAG_CHAIN_WISHBONE: + err = SetWishboneMemory(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; +} + +/* Nearly all compilers today store these bit fields as a packed structure + in network byte order (Big Endian). If you happen to be unlucky enough + to be working in a non standard environment, you may need to rewrite + this routine or the SET_REG32 macro. */ +int SetDevelopmentInterfaceRegister(unsigned int address,uint32_t data) +{ + int err = 0; + uint32_t value = data; + int old_value; + char *t_ptr = (char*)&development.RISCOP; + + switch(address) + { + case DEVELOPINT_MODER: + SET_REG32(development.MODER,value); + break; + case DEVELOPINT_TSEL: + SET_REG32(development.TSEL,value); + break; + case DEVELOPINT_QSEL: + SET_REG32(development.QSEL,value); + break; + case DEVELOPINT_SSEL: + SET_REG32(development.SSEL,value); + break; + case DEVELOPINT_RISCOP: + old_value = development.RISCOP.RESET; + SET_REG32(development.RISCOP,value); + + in_reset = development.RISCOP.RESET; + + /* Reset the cpu on the negative edge of RESET */ + if(old_value && !development.RISCOP.RESET) + { + uart_reset(); + tick_reset(); + pm_reset(); + pic_reset(); + reset(); /* Old or new mode */ + } + + SetCPUStallState(development.RISCOP.RISCSTALL); + 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: + SET_REG32(development.RECWP[address-DEVELOPINT_RECWP0],value); + break; + case DEVELOPINT_RECBP0: + SET_REG32(development.RECBP[0],value); + break; + default: + err = JTAG_PROXY_INVALID_ADDRESS; + break; + } + return err; +} + +int GetDevelopmentInterfaceRegister(unsigned int address,uint32_t *data) +{ + int err = 0; + uint32_t value = 0; + + switch(address) + { + case DEVELOPINT_MODER: GET_REG32(development.MODER,value); break; + case DEVELOPINT_TSEL: GET_REG32(development.TSEL,value); break; + case DEVELOPINT_QSEL: GET_REG32(development.QSEL,value); break; + case DEVELOPINT_SSEL: GET_REG32(development.SSEL,value); break; + case DEVELOPINT_RISCOP: GET_REG32(development.RISCOP,value); 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: GET_REG32(development.RECWP[address-DEVELOPINT_RECWP0],value); break; + case DEVELOPINT_RECBP0: GET_REG32(development.RECBP[0],value); break; + default: err = JTAG_PROXY_INVALID_ADDRESS; break; + } + + *data = value; + return err; +} + +/* Nearly all compilers today store these bit fields as a packed structure + in network byte order (Big Endian). If you happen to be unlucky enough + to be working in a non standard environment, you may need to rewrite + this routine or the SET_REG32 macro. */ +int SetDebugUnitRegister(unsigned int address,uint32_t data) +{ + int err = 0; + uint32_t value = data; + int old_value; + int group = address >> 11; + + address &= 0x07FF; + + /*****************************************************/ + /* TEMPORARY!!!! */ + /*****************************************************/ + if(group == 6) + address -= 32; + + if(group == 6) + { + switch(address) + { + case DEBUGINT_DVR0: + case DEBUGINT_DVR1: + case DEBUGINT_DVR2: + case DEBUGINT_DVR3: + case DEBUGINT_DVR4: + case DEBUGINT_DVR5: + case DEBUGINT_DVR6: + case DEBUGINT_DVR7: + printf("DVR %d set to 0x%08x\n",address-DEBUGINT_DVR0,value); + SET_REG32(debug_unit.DVR[address-DEBUGINT_DVR0],value); + break; + case DEBUGINT_DCR0: + case DEBUGINT_DCR1: + case DEBUGINT_DCR2: + case DEBUGINT_DCR3: + case DEBUGINT_DCR4: + case DEBUGINT_DCR5: + case DEBUGINT_DCR6: + case DEBUGINT_DCR7: + printf("DCR %d set to 0x%08x\n",address-DEBUGINT_DCR0,value); + SET_REG32(debug_unit.DCR[address-DEBUGINT_DCR0],value); + break; + case DEBUGINT_DMR1: + SET_REG32(debug_unit.DMR1,value); + break; + case DEBUGINT_DMR2: + SET_REG32(debug_unit.DMR2,value); + break; + case DEBUGINT_DWCR0: + SET_REG32(debug_unit.DWCR[0],value); + break; + case DEBUGINT_DWCR1: + SET_REG32(debug_unit.DWCR[1],value); + break; + case DEBUGINT_DSR: + SET_REG32(debug_unit.DSR,value); + break; + case DEBUGINT_DRR: + SET_REG32(debug_unit.DRR,value); + break; + case DEBUGINT_DIR: + InduceImmediateInstruction(value); + break; + default: + err = JTAG_PROXY_INVALID_ADDRESS; + break; + } + } + else if(group == 0) + { + extern unsigned long reg[32]; + + if(!address) + err = JTAG_PROXY_ACCESS_EXCEPTION; + else if(address < 32) + { + /* Assume that a write to the PC implies + that the debugging software has recognized + the exception and wants to do something + else instead. */ + + if(address == SPR_PC) + { + ClearPendingException(); + ClearPreparedPCState(); + } + mtspr(address,data); + } + else if(address >= 0x0400 && address < 0x0420) + reg[address - 0x0400] = data; + else if(address < 0x0600 || address >= 0x0620) + err = JTAG_PROXY_INVALID_ADDRESS; + } + else + err = JTAG_PROXY_INVALID_ADDRESS; + + return err; +} + +int GetDebugUnitRegister(unsigned int address,uint32_t *data) +{ + int err = 0; + uint32_t value = 0; + int group = address >> 11; + + address &= 0x07FF; + + /*****************************************************/ + /* TEMPORARY!!!! */ + /*****************************************************/ + if(group == 6) + address -= 32; + + if(group == 6) + { + switch(address) + { + case DEBUGINT_DVR0: + case DEBUGINT_DVR1: + case DEBUGINT_DVR2: + case DEBUGINT_DVR3: + case DEBUGINT_DVR4: + case DEBUGINT_DVR5: + case DEBUGINT_DVR6: + case DEBUGINT_DVR7: GET_REG32(debug_unit.DVR[address-DEBUGINT_DVR0],value); break; + case DEBUGINT_DCR0: + case DEBUGINT_DCR1: + case DEBUGINT_DCR2: + case DEBUGINT_DCR3: + case DEBUGINT_DCR4: + case DEBUGINT_DCR5: + case DEBUGINT_DCR6: + case DEBUGINT_DCR7: GET_REG32(debug_unit.DCR[address-DEBUGINT_DCR0],value); break; + case DEBUGINT_DMR1: GET_REG32(debug_unit.DMR1,value); break; + case DEBUGINT_DMR2: GET_REG32(debug_unit.DMR2,value); break; + case DEBUGINT_DWCR0: GET_REG32(debug_unit.DWCR[0],value); break; + case DEBUGINT_DWCR1: GET_REG32(debug_unit.DWCR[1],value); break; + case DEBUGINT_DSR: GET_REG32(debug_unit.DSR,value); break; + case DEBUGINT_DRR: GET_REG32(debug_unit.DRR,value); break; + case DEBUGINT_DIR: err = JTAG_PROXY_ACCESS_EXCEPTION; break; + default: err = JTAG_PROXY_INVALID_ADDRESS; break; + } + } + else if(group == 0) + { + extern unsigned long reg[32]; + + if(address < 32) + value = mfspr(address); + else if(address >= 0x0400 && address < 0x0420) + value = reg[address - 0x400]; + else if(address >= 0x0600 && address < 0x0620) + value = 0; + else + err = JTAG_PROXY_INVALID_ADDRESS; + } + else + err = JTAG_PROXY_INVALID_ADDRESS; + + *data = value; + return err; +} + +/* Nearly all compilers today store these bit fields as a packed structure + in network byte order (Big Endian). If you happen to be unlucky enough + to be working in a non standard environment, you may need to rewrite + this routine or the SET_REG32 macro. */ +int SetWishboneMemory(unsigned int address,uint32_t data) +{ + int err = 0; + uint32_t value = data; + int old_value; + int group = address >> 11; + + address <<= 2; + + if(!verify_memoryarea(address)) + err = JTAG_PROXY_INVALID_ADDRESS; + else + { + unsigned char t_data[4]; + int *tmp = (int*)t_data; + extern char null_str[1]; /* From cpu/common/parse.c */ + int i; + + *tmp = htonl(data); /* We have already converted to host order */ + + setsim_mem8(address++, t_data[0]); /* Back to network byte order */ + setsim_mem8(address++, t_data[1]); + setsim_mem8(address++, t_data[2]); + setsim_mem8(address++, t_data[3]); + } + return err; +} + +int GetWishboneMemory(unsigned int address,uint32_t *data) +{ + int err = 0; + uint32_t value = 0; + int group = address >> 11; + + address <<= 2; + + if(!verify_memoryarea(address)) + err = JTAG_PROXY_INVALID_ADDRESS; + else + { + unsigned char t_data[4]; + int *tmp = (int*)t_data; + int bp; + + t_data[0] = evalsim_mem8(address++); + t_data[1] = evalsim_mem8(address++); + t_data[2] = evalsim_mem8(address++); + t_data[3] = evalsim_mem8(address++); /* Already in network byte order */ + + *data = ntohl(*tmp); /* But we assume it is in host order later */ + } + return err; +} + +/* DebugCheckException returns 1 if the exception should be ignored. + Currently, this is true only if the exception is a breakpoint + exception and debug_unit.DMR1.ST is set. Sorry, this is a quick + hack to disable processing of breakpoint exceptions on single + stepping. Just one of those historical accidents. Feel free + to rewrite the behavior. */ +int DebugCheckException(int exception) +{ + int result = 0; + + switch(exception) + { + case EXCEPT_RESET: result = debug_unit.DRR.RSTE = debug_unit.DSR.RSTE; break; + case EXCEPT_BUSERR: result = debug_unit.DRR.BUSEE = debug_unit.DSR.BUSEE; break; + case EXCEPT_DPF: result = debug_unit.DRR.DPFE = debug_unit.DSR.DPFE; break; + case EXCEPT_IPF: result = debug_unit.DRR.IPFE = debug_unit.DSR.IPFE; break; + case EXCEPT_LPINT: result = debug_unit.DRR.LPINTE = debug_unit.DSR.LPINTE; break; + case EXCEPT_ALIGN: result = debug_unit.DRR.AE = debug_unit.DSR.AE; break; + case EXCEPT_ILLEGAL: result = debug_unit.DRR.IIE = debug_unit.DSR.IIE; break; + case EXCEPT_HPINT: result = debug_unit.DRR.HPINTE = debug_unit.DSR.HPINTE; break; + case EXCEPT_DTLBMISS: result = debug_unit.DRR.DME = debug_unit.DSR.DME; break; + case EXCEPT_ITLBMISS: result = debug_unit.DRR.IME = debug_unit.DSR.IME; break; + case EXCEPT_RANGE: result = debug_unit.DRR.RE = debug_unit.DSR.RE; break; + case EXCEPT_SYSCALL: result = debug_unit.DRR.SCE = debug_unit.DSR.SCE; break; + case EXCEPT_BREAK: result = debug_unit.DRR.BE = debug_unit.DSR.BE; break; + case EXCEPT_TRAP: result = debug_unit.DRR.TE = debug_unit.DSR.TE; break; + default: + break; + } + + if(result) + SetCPUStallState(true); + + return (debug_unit.DMR1.ST && exception == EXCEPT_BREAK); +}
trunk/or1ksim/debug/debug_unit.c Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: trunk/or1ksim/debug/Makefile.am =================================================================== --- trunk/or1ksim/debug/Makefile.am (nonexistent) +++ trunk/or1ksim/debug/Makefile.am (revision 221) @@ -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
trunk/or1ksim/debug/Makefile.am Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: trunk/or1ksim/debug/debug_unit.h =================================================================== --- trunk/or1ksim/debug/debug_unit.h (nonexistent) +++ trunk/or1ksim/debug/debug_unit.h (revision 221) @@ -0,0 +1,490 @@ +/* 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. */ + +/* Registers */ + +/* In general, little endian machines should pack bits from the LSB to + the MSB, while big endian machines should do the reverse. The bit + structures are declared in both orders, and we select which structure + definition to use based on this macro assignment. If your architecture + is special, you may have to redefine the algorithm defined in the + SET_REG32 and GET_REG32 macros below. */ + +#if (defined (__arm__) && ! defined (__ARMEB__)) || defined (__i386__) || defined (__i860__) || defined (__ns32000__) || defined (__vax__) +#define LITTLE_ENDIAN_BIT_FILL +#else +#define BIG_ENDIAN_BIT_FILL +#endif + +typedef enum { + DCR_CT_Disabled = 0, + DCR_CT_InsnAddress = 1, + DCR_CT_LoadAddress = 2, + DCR_CT_StoreAddress = 3, + DCR_CT_LoadData = 4, + DCR_CT_StoreData = 5, + DCR_CT_Reserved1 = 6, + DCR_CT_Reserved2 = 7, +} DCR_CT_Settings; + +typedef enum { + DCR_SC_Signed = 0, + DCR_SC_Unsigned = 1, +} DCR_SC_Settings; + +typedef enum { + DCR_CC_Masked = 0, + DCR_CC_Equal = 1, + DCR_CC_LessThan = 2, + DCR_CC_LessEqual = 3, + DCR_CC_GreaterThan = 4, + DCR_CC_GreaterEqual = 5, + DCR_CC_NotEqual = 6, + DCR_CC_Reserved = 7, +} DCR_CC_Settings; + +typedef enum { + DCR_DP_Absent = 0, + DCR_DP_Present = 1, +} DCR_DP_Settings; + +#ifdef LITTLE_ENDIAN_BIT_FILL + +typedef struct { + DCR_DP_Settings DP:1; + DCR_CC_Settings CC:3; + DCR_SC_Settings SC:1; + DCR_CT_Settings CT:3; + unsigned int reserved:24; +} DCRregister; + +typedef struct { + unsigned int CW0:2; + unsigned int CW1:2; + unsigned int CW2:2; + unsigned int CW3:2; + unsigned int CW4:2; + unsigned int CW5:2; + unsigned int CW6:2; + unsigned int CW7:2; + unsigned int CW8:2; + unsigned int CW9:2; + unsigned int CW10:2; + unsigned int ST:1; + unsigned int BT:1; + unsigned int DXFW:1; + unsigned int reserved:7; +} DMR1register; + +typedef struct { + unsigned int WCE0:1; + unsigned int WCE1:1; + unsigned int AWPC:11; + unsigned int WGB:11; + unsigned int reserved:8; +} DMR2register; + +typedef struct { + unsigned int COUNT:16; + unsigned int MATCH:16; +} DWCRregister; + +typedef struct { + unsigned int RSTE:1; + unsigned int BUSEE:1; + unsigned int DPFE:1; + unsigned int IPFE:1; + unsigned int LPINTE:1; + unsigned int AE:1; + unsigned int IIE:1; + unsigned int HPINTE:1; + unsigned int DME:1; + unsigned int IME:1; + unsigned int RE:1; + unsigned int SCE:1; + unsigned int BE:1; + unsigned int TE:1; + unsigned int reserved:18; +} DSRregister; + +typedef struct { + unsigned int RSTE:1; + unsigned int BUSEE:1; + unsigned int DPFE:1; + unsigned int IPFE:1; + unsigned int LPINTE:1; + unsigned int AE:1; + unsigned int IIE:1; + unsigned int HPINTE:1; + unsigned int DME:1; + unsigned int IME:1; + unsigned int RE:1; + unsigned int SCE:1; + unsigned int BE:1; + unsigned int TE:1; + unsigned int reserved:18; +} DRRregister; + +typedef struct { + unsigned int CONTIN:1; + unsigned int ENABLE:1; + unsigned int RECSELDEPEND:1; + unsigned int reserved:29; +} MODERregister; + +typedef struct { + unsigned int WPTRIG:11; + unsigned int WPTRIGVALID:1; + unsigned int BPTRIG:1; + unsigned int BPTRIGVALID:1; + unsigned int reserved2:2; + unsigned int LSSTRIG:4; + unsigned int LSSTRIGVALID:1; + unsigned int ISTRIG:4; + unsigned int ISTRIGVALID:1; + unsigned int reserved1:4; + unsigned int TRIGOP:2; +} TSELregister; + +typedef struct { + unsigned int WPQUALIF:11; + unsigned int WPQUALIFVALID:1; + unsigned int BPQUALIF:1; + unsigned int BPQUALIFVALID:1; + unsigned int reserved2:2; + unsigned int LSSQUALIF:4; + unsigned int LSSQUALIFVALID:1; + unsigned int ISTQUALIF:4; + unsigned int ISTQUALIFVALID:1; + unsigned int reserved1:4; + unsigned int QUALIFOP:2; +} QSELregister; + +typedef struct { + unsigned int WPSTOP:11; + unsigned int WPSTOPVALID:1; + unsigned int BPSTOP:1; + unsigned int BPSTOPVALID:1; + unsigned int reserved2:2; + unsigned int LSSSTOP:4; + unsigned int LSSSTOPVALID:1; + unsigned int ISTSTOP:4; + unsigned int ISTSTOPVALID:1; + unsigned int reserved1:4; + unsigned int STOPOP:2; +} SSELregister; + +typedef struct { + unsigned int RISCSTALL:1; + volatile unsigned int RESET:1; + unsigned int reserved:30; +} RISCOPregister; + + +typedef struct { + unsigned int RECPC:1; + unsigned int RECLSEA:1; + unsigned int RECLDATA:1; + unsigned int RECSDATA:1; + unsigned int RECREADSPR:1; + unsigned int RECWRITESPR:1; + unsigned int RECINSTR:1; + unsigned int reserved:25; +} RECWPregister; + +typedef struct { + unsigned int RECPC:1; + unsigned int RECLSEA:1; + unsigned int RECLDATA:1; + unsigned int RECSDATA:1; + unsigned int RECREADSPR:1; + unsigned int RECWRITESPR:1; + unsigned int RECINSTR:1; + unsigned int reserved:25; +} RECBPregister; + +#else /* BIG_ENDIAN_BIT_FILL */ + +typedef struct { + unsigned int reserved:24; + DCR_CT_Settings CT:3; + DCR_SC_Settings SC:1; + DCR_CC_Settings CC:3; + DCR_DP_Settings DP:1; +} DCRregister; + +typedef struct { + unsigned int reserved:7; + unsigned int DXFW:1; + unsigned int BT:1; + unsigned int ST:1; + unsigned int CW10:2; + unsigned int CW9:2; + unsigned int CW8:2; + unsigned int CW7:2; + unsigned int CW6:2; + unsigned int CW5:2; + unsigned int CW4:2; + unsigned int CW3:2; + unsigned int CW2:2; + unsigned int CW1:2; + unsigned int CW0:2; +} DMR1register; + +typedef struct { + unsigned int reserved:8; + unsigned int WGB:11; + unsigned int AWPC:11; + unsigned int WCE1:1; + unsigned int WCE0:1; +} DMR2register; + +typedef struct { + unsigned int MATCH:16; + unsigned int COUNT:16; +} DWCRregister; + +typedef struct { + unsigned int reserved:18; + unsigned int TE:1; + unsigned int BE:1; + unsigned int SCE:1; + unsigned int RE:1; + unsigned int IME:1; + unsigned int DME:1; + unsigned int HPINTE:1; + unsigned int IIE:1; + unsigned int AE:1; + unsigned int LPINTE:1; + unsigned int IPFE:1; + unsigned int DPFE:1; + unsigned int BUSEE:1; + unsigned int RSTE:1; +} DSRregister; + +typedef struct { + unsigned int reserved:18; + unsigned int TE:1; + unsigned int BE:1; + unsigned int SCE:1; + unsigned int RE:1; + unsigned int IME:1; + unsigned int DME:1; + unsigned int HPINTE:1; + unsigned int IIE:1; + unsigned int AE:1; + unsigned int LPINTE:1; + unsigned int IPFE:1; + unsigned int DPFE:1; + unsigned int BUSEE:1; + unsigned int RSTE:1; +} DRRregister; + +typedef struct { + unsigned int reserved:29; + unsigned int RECSELDEPEND:1; + unsigned int ENABLE:1; + unsigned int CONTIN:1; +} MODERregister; + +typedef struct { + unsigned int TRIGOP:2; + unsigned int reserved1:4; + unsigned int ISTRIGVALID:1; + unsigned int ISTRIG:4; + unsigned int LSSTRIGVALID:1; + unsigned int LSSTRIG:4; + unsigned int reserved2:2; + unsigned int BPTRIGVALID:1; + unsigned int BPTRIG:1; + unsigned int WPTRIGVALID:1; + unsigned int WPTRIG:11; +} TSELregister; + +typedef struct { + unsigned int QUALIFOP:2; + unsigned int reserved1:4; + unsigned int ISTQUALIFVALID:1; + unsigned int ISTQUALIF:4; + unsigned int LSSQUALIFVALID:1; + unsigned int LSSQUALIF:4; + unsigned int reserved2:2; + unsigned int BPQUALIFVALID:1; + unsigned int BPQUALIF:1; + unsigned int WPQUALIFVALID:1; + unsigned int WPQUALIF:11; +} QSELregister; + +typedef struct { + unsigned int STOPOP:2; + unsigned int reserved1:4; + unsigned int ISTSTOPVALID:1; + unsigned int ISTSTOP:4; + unsigned int LSSSTOPVALID:1; + unsigned int LSSSTOP:4; + unsigned int reserved2:2; + unsigned int BPSTOPVALID:1; + unsigned int BPSTOP:1; + unsigned int WPSTOPVALID:1; + unsigned int WPSTOP:11; +} SSELregister; + +typedef struct { + unsigned int reserved:30; + unsigned int RESET:1; + unsigned int RISCSTALL:1; +} RISCOPregister; + +typedef struct { + unsigned int reserved:25; + unsigned int RECINSTR:1; + unsigned int RECWRITESPR:1; + unsigned int RECREADSPR:1; + unsigned int RECSDATA:1; + unsigned int RECLDATA:1; + unsigned int RECLSEA:1; + unsigned int RECPC:1; +} RECWPregister; + +typedef struct { + unsigned int reserved:25; + unsigned int RECINSTR:1; + unsigned int RECWRITESPR:1; + unsigned int RECREADSPR:1; + unsigned int RECSDATA:1; + unsigned int RECLDATA:1; + unsigned int RECLSEA:1; + unsigned int RECPC:1; +} RECBPregister; + +#endif /* LITTLE_ENDIAN_BIT_FILL */ + +typedef struct { + unsigned int DVR[8]; + DCRregister DCR[8]; + unsigned int DCR_hit; + unsigned int watchpoint; + DMR1register DMR1; + DMR2register DMR2; + DWCRregister DWCR[2]; + DSRregister DSR; + DRRregister DRR; + unsigned int DIR; +} DebugUnit; + +typedef enum { + DebugInstructionFetch = 1, + DebugLoadAddress = 2, + DebugStoreAddress = 3, + DebugLoadData = 4, + DebugStoreData = 5, +} DebugUnitAction; + +extern DebugUnit debug_unit; +void InitializeDebugUnit(void); +void InduceImmediateInstruction(unsigned long); +void SetCPUStallState(int state); + +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 { + MODERregister MODER; + TSELregister TSEL; + QSELregister QSEL; + SSELregister SSEL; + RISCOPregister RISCOP; + RECWPregister RECWP[11]; + RECBPregister RECBP[1]; +} 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; + +typedef enum { + DEBUGINT_DVR0 = 0, + DEBUGINT_DVR1 = 1, + DEBUGINT_DVR2 = 2, + DEBUGINT_DVR3 = 3, + DEBUGINT_DVR4 = 4, + DEBUGINT_DVR5 = 5, + DEBUGINT_DVR6 = 6, + DEBUGINT_DVR7 = 7, + DEBUGINT_DCR0 = 8, + DEBUGINT_DCR1 = 9, + DEBUGINT_DCR2 = 10, + DEBUGINT_DCR3 = 11, + DEBUGINT_DCR4 = 12, + DEBUGINT_DCR5 = 13, + DEBUGINT_DCR6 = 14, + DEBUGINT_DCR7 = 15, + DEBUGINT_DMR1 = 16, + DEBUGINT_DMR2 = 17, + DEBUGINT_DWCR0 = 18, + DEBUGINT_DWCR1 = 19, + DEBUGINT_DSR = 20, + DEBUGINT_DRR = 21, + DEBUGINT_DIR = 22, +} DebugInterfaceAddressSpace; + +/* This assumes a pointer to a 32 bit aligned bit field has + been passed and that the compiler aligns bit fields on + 32 bit boundaries in big endian order. If either one of + these two conditions are not true for your architecture + you may need to adjust this macro. */ +#define SET_REG32(x,y) *((uint32_t*)&x) = (uint32_t)y +#define GET_REG32(x,y) y = *((uint32_t*)&x) + +#ifdef DEBUGMOD_OFF +#define CheckDebugUnit(x,y) 0 +#endif +
trunk/or1ksim/debug/debug_unit.h Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: trunk/or1ksim/cpu/Makefile.in =================================================================== --- trunk/or1ksim/cpu/Makefile.in (revision 220) +++ trunk/or1ksim/cpu/Makefile.in (revision 221) @@ -73,6 +73,7 @@ CC = @CC@ CFLAGS = @CFLAGS@ CPU_ARCH = @CPU_ARCH@ +FPM = @FPM@ INCLUDES = @INCLUDES@ LOCAL_CFLAGS = @LOCAL_CFLAGS@ LOCAL_DEFS = @LOCAL_DEFS@ Index: trunk/or1ksim/cpu/or32/Makefile.in =================================================================== --- trunk/or1ksim/cpu/or32/Makefile.in (revision 220) +++ trunk/or1ksim/cpu/or32/Makefile.in (revision 221) @@ -89,6 +89,7 @@ CC = @CC@ CFLAGS = @CFLAGS@ CPU_ARCH = @CPU_ARCH@ +FPM = @FPM@ INCLUDES = @INCLUDES@ LOCAL_CFLAGS = @LOCAL_CFLAGS@ LOCAL_DEFS = @LOCAL_DEFS@ Index: trunk/or1ksim/cpu/or32/execute.c =================================================================== --- trunk/or1ksim/cpu/or32/execute.c (revision 220) +++ trunk/or1ksim/cpu/or32/execute.c (revision 221) @@ -247,7 +247,7 @@ /* Implementation specific. Evaluates source operand op_no. */ -unsigned long eval_operand (int op_no, int *breakpoint) +unsigned long eval_operand32 (int op_no, int *breakpoint) { debug ("%i %08X\n", op_no, op[op_no + MAX_OPERANDS]); if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) @@ -259,10 +259,38 @@ } /* Implementation specific. + Evaluates source operand op_no. */ + +unsigned long eval_operand16 (int op_no, int *breakpoint) +{ + debug ("%i %08X\n", op_no, op[op_no + MAX_OPERANDS]); + if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) + return eval_mem16 (op[op_no], breakpoint); + else { + fprintf (stderr, "Invalid operand type.\n"); + exit (1); + } +} + +/* Implementation specific. + Evaluates source operand op_no. */ + +unsigned long eval_operand8 (int op_no, int *breakpoint) +{ + debug ("%i %08X\n", op_no, op[op_no + MAX_OPERANDS]); + if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) + return eval_mem8 (op[op_no], breakpoint); + else { + fprintf (stderr, "Invalid operand type.\n"); + exit (1); + } +} + +/* Implementation specific. Set destination operand (register direct, register indirect (with displacement) with value. */ -void set_operand(int op_no, unsigned long value, int* breakpoint) +void set_operand32(int op_no, unsigned long value, int* breakpoint) { /* Mark this as destination operand. */ op[op_no + MAX_OPERANDS] |= OPTYPE_DST; @@ -277,6 +305,40 @@ } } +/* Implementation specific. + Set destination operand (register direct, register indirect + (with displacement) with value. */ + +void set_operand16(int op_no, unsigned long value, int* breakpoint) +{ + /* Mark this as destination operand. */ + op[op_no + MAX_OPERANDS] |= OPTYPE_DST; + if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) + set_mem16(op[op_no], value, breakpoint); + else + { + fprintf (stderr, "Invalid operand type.\n"); + exit (1); + } +} + +/* Implementation specific. + Set destination operand (register direct, register indirect + (with displacement) with value. */ + +void set_operand8(int op_no, unsigned long value, int* breakpoint) +{ + /* Mark this as destination operand. */ + op[op_no + MAX_OPERANDS] |= OPTYPE_DST; + if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) + set_mem8(op[op_no], value, breakpoint); + else + { + fprintf (stderr, "Invalid operand type.\n"); + exit (1); + } +} + void reset() { cycles = 0; @@ -287,36 +349,17 @@ memset(iqueue, 0, sizeof(iqueue)); memset(icomplet, 0, sizeof(icomplet)); mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_EXR | SPR_SR_SUPV); - if(!GlobalMode) /* Original code */ - { /* Search for _reset label if exists, otherwise call 0x100 */ - int i; - pcnext = 0x0100; - for(i = 0; i < (MEMORY_START + MEMORY_LEN); i++) { - struct label_entry *tmp; - for(tmp = mem[i].label; tmp; tmp = tmp->next) - if (!strcmp("_reset", tmp->name)) { - pcnext = i; - break; - } - } - } - else - pcnext = 0x0000; /* New mode */ + + pcnext = 0x0; /* MM1409: All programs should start at reset vector entry! */ printf ("Starting at 0x%08x\n", pcnext); pc = pcnext; pc_phy = pc; pcnext += 4; ResetDebugUnit(); - debug("reset ..."); - if(!GlobalMode) /* Original mode */ - set_reg32(STACK_REGNO, (MEMORY_START + MEMORY_LEN) - STACK_SIZE); - /* MM: does not reset, but jumps to _reset label instead. */ - /* If we are in old mode, this behavior is acceptable. However, - in the new mode, there are no labels defined, and therefore - it is impossible to jump to a label. I have reenabled this - if we are running with gdb. CZ 21/06/01 */ - if(GlobalMode) - except_handle(EXCEPT_RESET, 0); + debug("reset ..."); + + /* MM1409: All programs should set their stack pointer! */ + except_handle(EXCEPT_RESET, 0); } int DIR_insn_injected = 0; /* CZ 21/06/01 */ @@ -323,7 +366,8 @@ /* Modified by CZ 26/05/01 for new mode execution */ /* Fetch returns nonzero if instruction should NOT be executed. */ inline int fetch() { - debug("fetch()\n"); + struct mem_entry *entry; + debug("fetch()\n"); /* Do this here rather than update_pc so the reset exception will happen normally. NOTE: During debugging and @@ -339,9 +383,10 @@ PrepareException(); /* Update the pc for pending exceptions */ /* MM: Check for breakpoint. This has to be done in fetch cycle, - because of peripheria. */ - if (mem[pc_phy].brk) - return 1; /* Breakpoint set. */ + because of peripheria. + MM1709: if we cannot access the memory entry, we could not set the breakpoint earlier. */ + if(verify_memoryarea(pc_phy) && cur_area->getentry && (entry = cur_area->getentry(pc_phy)) && entry->brk) + return 1; /* Breakpoint set. */ /* Cycles after reset. */ cycles++; @@ -352,9 +397,11 @@ except_handle(EXCEPT_ALIGN,0); return 0; /* We will fetch exception wrapper at new location. */ } - + +#if 0 if(pc_phy > MEMORY_START + MEMORY_LEN) pc_phy %= MEMORY_START + MEMORY_LEN; +#endif /* Fetch instruction. */ /* CZ 21/06/01: If there is an instruction waiting in the @@ -393,7 +440,7 @@ /* Simulate instruction cache and IMMU. */ pc_phy = simulate_ic_mmu_fetch(pc); - if ((pc_phy < MEMORY_START) || (pc_phy > MEMORY_START + MEMORY_LEN)) + if(!verify_memoryarea(pc_phy)) except_handle(EXCEPT_BUSERR, pc); } @@ -411,7 +458,6 @@ unsigned long t_pc = pcnext; unsigned long t_pcnext = delay_insn ? pcdelay : pcnext+4; extern int cpu_stalled; /* CZ from debug_interface */ - extern int NewStyleExceptions; /* CZ 11/09/01 */ /* If an insn was injected, don't increment the PC value, as it should not affect the existing instruction stream */ @@ -422,7 +468,7 @@ } DIR_insn_injected = 0; - if(!cpu_stalled || NewStyleExceptions) + if(!cpu_stalled) _execute_update_pc(t_pc,t_pcnext); else PrepareExceptionPC(t_pc,t_pcnext); @@ -478,8 +524,10 @@ if (temp_disable_except > 0) temp_disable_except--; +#ifndef DEBUGMOD_OFF if(CheckDebugUnit(DebugInstructionFetch,pc_phy)) breakpoint++; +#endif cur = current; cur->func_unit = unknown; @@ -574,12 +622,12 @@ void l_sfne() { cur->func_unit = compare; - flag = eval_operand(0, &breakpoint) != eval_operand(1, &breakpoint); + flag = eval_operand32(0, &breakpoint) != eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } void l_bf() { cur->func_unit = branch; - if (eval_operand(0, &breakpoint) >= pc) + if (eval_operand32(0, &breakpoint) >= pc) mstats.bnez.forward++; else mstats.bnez.backward++; @@ -586,9 +634,9 @@ mstats.sbp_bf.all++; if (flag) { debug("\nl.bf relative: pc=%x pcnext=%x\n", pc, pcnext); - pcdelay = pc + (signed)eval_operand(0, &breakpoint) * 4; + pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4; - if (eval_operand(0, &breakpoint) < pc) + if (eval_operand32(0, &breakpoint) < pc) mstats.sbp_bf.correct++; mstats.bnez.taken++; bpb_update(cur->insn_addr, 1); @@ -601,80 +649,68 @@ } } void l_add() { - signed long temp3, temp2, temp1; + signed long temp1; signed char temp4; - cur->func_unit = arith; - temp3 = eval_operand(2, &breakpoint); - temp2 = eval_operand(1, &breakpoint); - temp1 = temp2 + temp3; - set_operand(0, temp1, &breakpoint); + cur->func_unit = arith; + temp1 = (signed long)eval_operand32(2, &breakpoint)+(signed long)eval_operand32(1, &breakpoint); + set_operand32(0, temp1, &breakpoint); temp4 = temp1; if (temp4 == temp1) mstats.byteadd++; } -void l_sw() { - unsigned long value = eval_operand(1, &breakpoint); +void l_sw() { cur->func_unit = store; - set_operand(0, value, &breakpoint); + set_operand32(0, eval_operand32(1, &breakpoint), &breakpoint); } void l_sb() { cur->func_unit = store; - set_operand(0, (eval_operand(1, &breakpoint) << 24) + (eval_operand(0, &breakpoint) & 0xffffff), &breakpoint); + set_operand8(0, eval_operand32(1, &breakpoint), &breakpoint); } void l_sh() { cur->func_unit = store; - set_operand(0, (eval_operand(1, &breakpoint) << 16) + (eval_operand(0, &breakpoint) & 0xffff), &breakpoint); + set_operand16(0, eval_operand32(1, &breakpoint), &breakpoint); } void l_lwz() { cur->func_unit = load; - set_operand(0, eval_operand(1, &breakpoint), &breakpoint); + set_operand32(0, (unsigned long) eval_operand32(1, &breakpoint), &breakpoint); } void l_lbs() { - signed char temp = (eval_operand(1, &breakpoint) >> 24); cur->func_unit = load; - set_operand(0, temp, &breakpoint); + set_operand32(0, (signed char) eval_operand8(1, &breakpoint), &breakpoint); } -void l_lbz() { - unsigned char temp = (eval_operand(1, &breakpoint) >> 24); +void l_lbz() { cur->func_unit = load; - set_operand(0, temp, &breakpoint); + set_operand32(0, (unsigned char)eval_operand8(1, &breakpoint), &breakpoint); } -void l_lhs() { - signed short temp = (eval_operand(1, &breakpoint) >> 16); +void l_lhs() { cur->func_unit = load; - set_operand(0, temp, &breakpoint); + set_operand32(0, (signed short)eval_operand16(1, &breakpoint), &breakpoint); } -void l_lhz() { - unsigned short temp = (eval_operand(1, &breakpoint) >> 16); +void l_lhz() { cur->func_unit = load; - set_operand(0, temp, &breakpoint); + set_operand32(0, (unsigned short)eval_operand16(1, &breakpoint), &breakpoint); } void l_movhi() { cur->func_unit = movimm; - set_operand(0, eval_operand(1, &breakpoint) << 16, &breakpoint); + set_operand32(0, eval_operand32(1, &breakpoint) << 16, &breakpoint); } void l_and() { cur->func_unit = arith; - set_operand(0, eval_operand(1, &breakpoint) & (unsigned)eval_operand(2, &breakpoint), &breakpoint); + set_operand32(0, eval_operand32(1, &breakpoint) & (unsigned)eval_operand32(2, &breakpoint), &breakpoint); } void l_or() { cur->func_unit = arith; - set_operand(0, eval_operand(1, &breakpoint) | (unsigned)eval_operand(2, &breakpoint), &breakpoint); + set_operand32(0, eval_operand32(1, &breakpoint) | (unsigned)eval_operand32(2, &breakpoint), &breakpoint); } void l_xor() { cur->func_unit = arith; - set_operand(0, eval_operand(1, &breakpoint) ^ (signed)eval_operand(2, &breakpoint), &breakpoint); + set_operand32(0, eval_operand32(1, &breakpoint) ^ (signed)eval_operand32(2, &breakpoint), &breakpoint); } void l_sub() { - signed long temp3, temp2, temp1; - cur->func_unit = arith; - temp3 = eval_operand(2, &breakpoint); - temp2 = eval_operand(1, &breakpoint); - temp1 = temp2 - temp3; - set_operand(0, temp1, &breakpoint); + set_operand32(0, (signed long)eval_operand32(1, &breakpoint) - (signed long)eval_operand32(2, &breakpoint), &breakpoint); } /*int mcount = 0;*/ void l_mul() { @@ -681,10 +717,7 @@ signed long temp3, temp2, temp1; cur->func_unit = arith; - temp3 = eval_operand(2, &breakpoint); - temp2 = eval_operand(1, &breakpoint); - temp1 = temp2 * temp3; - set_operand(0, temp1, &breakpoint); + set_operand32(0, (signed long)eval_operand32(1, &breakpoint) * (signed long)eval_operand32(2, &breakpoint), &breakpoint); /*if (!(mcount++ & 1023)) { printf ("[%i]\n",mcount); }*/ @@ -693,55 +726,55 @@ signed long temp3, temp2, temp1; cur->func_unit = arith; - temp3 = eval_operand(2, &breakpoint); - temp2 = eval_operand(1, &breakpoint); + temp3 = eval_operand32(2, &breakpoint); + temp2 = eval_operand32(1, &breakpoint); if (temp3) temp1 = temp2 / temp3; else except_handle(EXCEPT_ILLEGAL, 0); - set_operand(0, temp1, &breakpoint); + set_operand32(0, temp1, &breakpoint); } void l_divu() { unsigned long temp3, temp2, temp1; cur->func_unit = arith; - temp3 = eval_operand(2, &breakpoint); - temp2 = eval_operand(1, &breakpoint); + temp3 = eval_operand32(2, &breakpoint); + temp2 = eval_operand32(1, &breakpoint); temp1 = temp2 / temp3; /* cycles += 16; */ - set_operand(0, temp1, &breakpoint); + set_operand32(0, temp1, &breakpoint); } void l_sll() { int sign = 1; cur->func_unit = shift; - if ((signed)eval_operand(1, &breakpoint) < 0) + if ((signed)eval_operand32(1, &breakpoint) < 0) sign = -1; /* cycles += 2; */ - set_operand(0, eval_operand(1, &breakpoint) << eval_operand(2, &breakpoint), &breakpoint); + set_operand32(0, eval_operand32(1, &breakpoint) << eval_operand32(2, &breakpoint), &breakpoint); } void l_sra() { unsigned long sign = 0; cur->func_unit = shift; - if ((signed)eval_operand(1, &breakpoint) < 0) + if ((signed)eval_operand32(1, &breakpoint) < 0) sign = -1; /* cycles += 2; */ - set_operand(0, (signed)eval_operand(1, &breakpoint) >> eval_operand(2, &breakpoint), &breakpoint); + set_operand32(0, (signed)eval_operand32(1, &breakpoint) >> eval_operand32(2, &breakpoint), &breakpoint); } void l_srl() { cur->func_unit = shift; /* cycles += 2; */ - set_operand(0, eval_operand(1, &breakpoint) >> eval_operand(2, &breakpoint), &breakpoint); + set_operand32(0, eval_operand32(1, &breakpoint) >> eval_operand32(2, &breakpoint), &breakpoint); } void l_j() { debug("\nl.j relative: pc=%x pcnext=%x\n", pc, pcnext); - pcdelay = pc + (signed)eval_operand(0, &breakpoint) * 4; + pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4; cur->func_unit = jump; next_delay_insn = 1; } void l_jal() { debug("\nl.jal relative: pc=%x pcnext=%x\n", pc, pcnext); - pcdelay = pc + (signed)eval_operand(0, &breakpoint) * 4; + pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4; cur->func_unit = jump; set_reg32(LINK_REGNO, pc + 8); @@ -748,16 +781,17 @@ slp_func_entry(); next_delay_insn = 1; if (config.profile) { - struct label_entry *tmp = mem[pcdelay].label; - if (tmp) + struct mem_entry *entry; + struct label_entry *tmp; + if (verify_memoryarea(pcdelay) && cur_area->getentry && (entry = cur_area->getentry(pcdelay)) && (tmp = entry->label)) fprintf (config.fprof, "+%08X %08X %08X %s\n",cycles, pc + 8, pcdelay, tmp->name); - /*else - fprintf (config.fprof, "+%08X %08X %08X @%08X\n",cycles, pc + 8, pcdelay, pcdelay);*/ + else + fprintf (config.fprof, "+%08X %08X %08X @%08X\n",cycles, pc + 8, pcdelay, pcdelay ); } } void l_jalr() { cur->func_unit = jump; - pcdelay = eval_operand(0, &breakpoint); + pcdelay = eval_operand32(0, &breakpoint); set_reg32(LINK_REGNO, pc + 8); slp_func_exit(); next_delay_insn = 1; @@ -768,35 +802,17 @@ } void l_jr() { cur->func_unit = jump; - pcdelay = eval_operand(0, &breakpoint); + pcdelay = eval_operand32(0, &breakpoint); next_delay_insn = 1; } void l_rfe() { - /* I'm really confused...this is not following - the documentation at all. Guess I'll go with - the flow... */ -#if 0 - unsigned int esr = mfspr(SPR_ESR_BASE); - cur->func_unit = exception; pcdelay = mfspr(SPR_EPCR_BASE); - if(!(esr & 0x2000)) - pcdelay += 4; /* According to table 9-3 */ - mtspr(SPR_SR, esr); + mtspr(SPR_SR, mfspr(SPR_ESR_BASE)); next_delay_insn = 1; if (temp_disable_except == 0) temp_disable_except = 1; -#endif - unsigned int esr = mfspr(SPR_ESR_BASE); - - cur->func_unit = exception; - pcdelay = mfspr(SPR_EPCR_BASE); - mtspr(SPR_SR, esr); - next_delay_insn = 1; - if (temp_disable_except == 0) - temp_disable_except = 1; } - void l_nop() { cur->func_unit = nop; if (nop_period > nop_maxperiod) @@ -806,7 +822,7 @@ } void l_bnf() { cur->func_unit = branch; - if (eval_operand(0, &breakpoint) >= pc) + if (eval_operand32(0, &breakpoint) >= pc) mstats.beqz.forward++; else mstats.beqz.backward++; @@ -813,7 +829,7 @@ mstats.sbp_bnf.all++; if (flag == 0) { debug("\nl.bnf relative: pc=%x pcnext=%x\n", pc, pcnext); - pcdelay = pc + (signed)eval_operand(0, &breakpoint) * 4; + pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4; mstats.beqz.taken++; bpb_update(cur->insn_addr, 1); @@ -820,7 +836,7 @@ btic_update(pcnext); next_delay_insn = 1; } else { - if (eval_operand(0, &breakpoint) >= pc) + if (eval_operand32(0, &breakpoint) >= pc) mstats.sbp_bnf.correct++; mstats.beqz.nottaken++; bpb_update(cur->insn_addr, 0); @@ -829,53 +845,53 @@ } void l_sfeq() { cur->func_unit = compare; - flag = eval_operand(0, &breakpoint) == eval_operand(1, &breakpoint); + flag = eval_operand32(0, &breakpoint) == eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } void l_sfgts() { cur->func_unit = compare; - flag = (signed)eval_operand(0, &breakpoint) > (signed)eval_operand(1, &breakpoint); + flag = (signed)eval_operand32(0, &breakpoint) > (signed)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } void l_sfges() { cur->func_unit = compare; - flag = (signed)eval_operand(0, &breakpoint) >= (signed)eval_operand(1, &breakpoint); + flag = (signed)eval_operand32(0, &breakpoint) >= (signed)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } void l_sflts() { cur->func_unit = compare; - flag = (signed)eval_operand(0, &breakpoint) < (signed)eval_operand(1, &breakpoint); + flag = (signed)eval_operand32(0, &breakpoint) < (signed)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } void l_sfles() { cur->func_unit = compare; - flag = (signed)eval_operand(0, &breakpoint) <= (signed)eval_operand(1, &breakpoint); + flag = (signed)eval_operand32(0, &breakpoint) <= (signed)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } void l_sfgtu() { cur->func_unit = compare; - flag = (unsigned)eval_operand(0, &breakpoint) > (unsigned)eval_operand(1, &breakpoint); + flag = (unsigned)eval_operand32(0, &breakpoint) > (unsigned)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } void l_sfgeu() { cur->func_unit = compare; - flag = (unsigned)eval_operand(0, &breakpoint) >= (unsigned) eval_operand(1, &breakpoint); + flag = (unsigned)eval_operand32(0, &breakpoint) >= (unsigned) eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } void l_sfltu() { cur->func_unit = compare; - flag = (unsigned)eval_operand(0, &breakpoint) < (unsigned)eval_operand(1, &breakpoint); + flag = (unsigned)eval_operand32(0, &breakpoint) < (unsigned)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } void l_sfleu() { cur->func_unit = compare; - flag = (unsigned)eval_operand(0, &breakpoint) <= (unsigned)eval_operand(1, &breakpoint); + flag = (unsigned)eval_operand32(0, &breakpoint) <= (unsigned)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } void l_mtspr() { cur->func_unit = move; if (mfspr(SPR_SR) & SPR_SR_SUPV) - mtspr(eval_operand(0, &breakpoint) + eval_operand(2, &breakpoint), eval_operand(1, &breakpoint)); + mtspr(eval_operand32(0, &breakpoint) + eval_operand32(2, &breakpoint), eval_operand32(1, &breakpoint)); else { printf("WARNING: trying to write SPR while SR[SUPV] is cleared.\n"); cont_run = 0; @@ -884,9 +900,9 @@ void l_mfspr() { cur->func_unit = move; if (mfspr(SPR_SR) & SPR_SR_SUPV) - set_operand(0, mfspr(eval_operand(1, &breakpoint) + eval_operand(2, &breakpoint)), &breakpoint); + set_operand32(0, mfspr(eval_operand32(1, &breakpoint) + eval_operand32(2, &breakpoint)), &breakpoint); else { - set_operand(0, 0, &breakpoint); + set_operand32(0, 0, &breakpoint); printf("WARNING: trying to read SPR while SR[SUPV] is cleared.\n"); cont_run = 0; } @@ -893,9 +909,13 @@ } void l_sys() { - if (!GlobalMode && eval_operand(0, &breakpoint) > 200) { + if ( +#ifdef DEBUGMOD_OFF + !GlobalMode && +#endif + eval_operand32(0, &breakpoint) > 200) { unsigned long stackaddr, fmtaddr, args; - switch (eval_operand(0, &breakpoint)) { + switch (eval_operand32(0, &breakpoint)) { case 201: set_reg32 (RETURNV_REGNO, cycles + loadcycles + storecycles); break; @@ -935,32 +955,37 @@ void l_mac() { sprword lo, hi; LONGEST l; + long x, y; cur->func_unit = mac; lo = mfspr (SPR_MACLO); hi = mfspr (SPR_MACHI); - l = (ULONGEST)lo | ((LONGEST)hi) << 32ULL; - l = (LONGEST) eval_operand(0, &breakpoint) * (LONGEST)eval_operand(1, &breakpoint); + x = eval_operand32(0, &breakpoint); + y = eval_operand32(1, &breakpoint); + //printf ("[%08x,%08x]\t", (unsigned long)(x), (unsigned long)(y)); + l = (ULONGEST)lo | ((LONGEST)hi << 32); + l += (LONGEST) x * (LONGEST) y; /* This implementation is very fast - it needs only one cycle for mac. */ - lo = l & 0xFFFFFFFF; - hi = l >> 32ULL; + lo = ((ULONGEST)l) & 0xFFFFFFFF; + hi = ((LONGEST)l) >> 32; mtspr (SPR_MACLO, lo); mtspr (SPR_MACHI, hi); + //printf ("(%08x,%08x)\n", hi, lo); } void l_msb() { - sprword lo, hi; + sprword lo, hi; LONGEST l; cur->func_unit = mac; lo = mfspr (SPR_MACLO); hi = mfspr (SPR_MACHI); - l = (ULONGEST)lo | ((LONGEST)hi) << 32ULL; - l -= (LONGEST) eval_operand(0, &breakpoint) * (LONGEST)eval_operand(1, &breakpoint); + l = (ULONGEST)lo | ((LONGEST)hi << 32); + l -= (LONGEST) eval_operand32(0, &breakpoint) * (LONGEST)eval_operand32(1, &breakpoint); /* This implementation is very fast - it needs only one cycle for msb. */ - lo = l & 0xFFFFFFFF; - hi = l >> 32ULL; + lo = ((ULONGEST)l) & 0xFFFFFFFF; + hi = ((LONGEST)l) >> 32; mtspr (SPR_MACLO, lo); - mtspr (SPR_MACHI, hi); + mtspr (SPR_MACHI, hi); } void l_macrc() { sprword lo, hi; @@ -967,8 +992,13 @@ LONGEST l; /* No need for synchronization here -- all MAC instructions are 1 cycle long. */ lo = mfspr (SPR_MACLO); - set_operand(0, lo, &breakpoint); + hi = mfspr (SPR_MACHI); + l = (ULONGEST) lo | ((LONGEST)hi << 32); + l >>= 28; + //printf ("<%08x>\n", (unsigned long)l); + set_operand32(0, (long)l, &breakpoint); mtspr (SPR_MACLO, 0); + mtspr (SPR_MACHI, 0); } void l_cust1() { /*int destr = cur->insn >> 21;
/trunk/or1ksim/cpu/or32/or32.c
27,9 → 27,12
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "parse.h"
#include "opcode/or32.h"
 
#ifndef debug
#define debug
#endif
 
/* **INDENT-OFF** */
 
CONST struct or32_letter or32_letters[] =
267,8 → 270,8
{ "l.or", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x4", EF(l_or), 0 },
{ "l.xor", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x5", EF(l_xor), 0 },
{ "l.mul", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-11 ---- 0x6", EF(l_mul), 0 },
{ "l.mac", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 0--- 0x7", EF(l_mac), 0 }, /*MM*/
{ "l.msb", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 1--- 0x7", EF(l_msb), 0 }, /*MM*/
{ "l.mac", "rA,rB", "11 0x8 ----- AAAAA BBBB B-00 0--- 0x7", EF(l_mac), 0 }, /*MM*/
{ "l.msb", "rA,rB", "11 0x8 ----- AAAAA BBBB B-00 1--- 0x7", EF(l_msb), 0 }, /*MM*/
{ "l.sll", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 00-- 0x8", EF(l_sll), 0 },
{ "l.srl", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 01-- 0x8", EF(l_srl), 0 },
{ "l.sra", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 10-- 0x8", EF(l_sra), 0 },
301,6 → 304,26
{ "l.cust7", "", "11 0xE ----- ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust8", "", "11 0xF ----- ----- ---- ---- ---- ----", EFI, 0 },
 
/* This section should not be defined in or1ksim, since it contains duplicates,
which would cause machine builder to complain. */
#ifndef HAS_EXECUTION
{ "l.cust5_1", "rD", "11 0xC DDDDD ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust5_2", "rD,rA" , "11 0xC DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
{ "l.cust5_3", "rD,rA,rB", "11 0xC DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
 
{ "l.cust6_1", "rD", "11 0xD DDDDD ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust6_2", "rD,rA" , "11 0xD DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
{ "l.cust6_3", "rD,rA,rB", "11 0xD DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
 
{ "l.cust7_1", "rD", "11 0xE DDDDD ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust7_2", "rD,rA" , "11 0xE DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
{ "l.cust7_3", "rD,rA,rB", "11 0xE DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
 
{ "l.cust8_1", "rD", "11 0xF DDDDD ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust8_2", "rD,rA" , "11 0xF DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
{ "l.cust8_3", "rD,rA,rB", "11 0xF DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
#endif
 
{ "", "", "", EFI, 0 } /* Dummy entry, not included in num_opcodes. This
lets code examine entry i+1 without checking
if we've run off the end of the table. */
/trunk/or1ksim/cpu/dlx/Makefile.in
89,6 → 89,7
CC = @CC@
CFLAGS = @CFLAGS@
CPU_ARCH = @CPU_ARCH@
FPM = @FPM@
INCLUDES = @INCLUDES@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
LOCAL_DEFS = @LOCAL_DEFS@
/trunk/or1ksim/cpu/or16/Makefile.in
89,6 → 89,7
CC = @CC@
CFLAGS = @CFLAGS@
CPU_ARCH = @CPU_ARCH@
FPM = @FPM@
INCLUDES = @INCLUDES@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
LOCAL_DEFS = @LOCAL_DEFS@
/trunk/or1ksim/cpu/common/stats.c
163,7 → 163,7
if (!config.slp)
return;
if ((addr < (MEMORY_START + MEMORY_LEN - 4000)) &&
if (/*(addr < (MEMORY_START + MEMORY_LEN - 4000)) && MM1709: we have no knowledge of this anymore */
slp_stats.supercnt && (type == SLP_MEMWRITE)) {
slp_stats.supercalls++;
slp_stats.supercnt = 0;
/trunk/or1ksim/cpu/common/trace.c
34,14 → 34,15
 
void set_insnbrkpoint(unsigned long addr)
{
addr &= 0xfffffffc; /* 32-bit aligned */
struct mem_entry *entry;
addr &= 0xfffffffc; /* 32-bit aligned */
if (addr < (MEMORY_START + MEMORY_LEN))
if (mem[addr].brk) {
mem[addr].brk = 0;
if (verify_memoryarea(addr) && cur_area->getentry && (entry = cur_area->getentry(addr)))
if (entry->brk) {
entry->brk = 0;
printf("\nBreakpoint at 0x%.8lx cleared.\n", addr);
} else {
mem[addr].brk = 1;
entry->brk = 1;
printf("\nBreakpoint at 0x%.8lx set.\n", addr);
}
else
/trunk/or1ksim/cpu/common/parse.h
33,5 → 33,3
void addlabel(char*,unsigned long,int*);
void addprogram(unsigned long, unsigned long, int*);
void parseline(char*,int*);
 
 
/trunk/or1ksim/cpu/common/Makefile.in
89,6 → 89,7
CC = @CC@
CFLAGS = @CFLAGS@
CPU_ARCH = @CPU_ARCH@
FPM = @FPM@
INCLUDES = @INCLUDES@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
LOCAL_DEFS = @LOCAL_DEFS@
/trunk/or1ksim/cpu/common/abstract.c
21,6 → 21,7
add all sorts of other abstract entities. Currently we have
only memory. */
 
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
40,150 → 41,79
#include "opcode/or32.h"
 
extern unsigned long reg[];
extern unsigned long pc_phy;
extern char *disassembled;
 
static char* build_format(int len,char* buffer,int offset,unsigned char* data)
{
int i;
char sTemp[256];
 
sprintf(buffer," %4x: ",offset);
 
for(i=0;i<16;i++)
{
if(i < len)
{
sprintf(sTemp,"%02x",data[i]);
strcat(buffer,sTemp);
}
else
strcat(buffer," ");
 
if(i & 0x01)
strcat(buffer," ");
}
 
strcat(buffer," %s\n");
}
 
static char* BytesToAscii(char* s,int len,char* buffer)
{
int i;
 
for(i=0;i<len;i++)
buffer[i] = isprint(s[i]) ? s[i] : '.';
buffer[i] = '\0';
 
return buffer;
}
 
static void DumpAsciiToDescriptor(int fd,char* buffer,int len)
{
int i;
char format_buf[256];
char ascii_buf[256];
char* format;
char sTemp[256];
 
sprintf(sTemp," 00 02 04 06 08 0A 0C 0E ASCII\n");
write(fd,sTemp,strlen(sTemp));
sprintf(sTemp," ----- ---- ---- ---- ---- ---- ---- ---- ---- ----------------\n");
write(fd,sTemp,strlen(sTemp));
for(i=0;i<len;i+=16,buffer+=16)
{
int max = len-i;
 
if(max > 16) max = 16;
format = build_format(max,format_buf,i,buffer);
sprintf(sTemp,format,BytesToAscii((char*)buffer,max,ascii_buf));
write(fd,sTemp,strlen(sTemp));
}
}
 
static void DebugDump()
{
char buffer[1024];
unsigned long startmem = reg[1];
int i;
 
printf(" r0 r1 r2 r3 r4 r5 r6 r7\n");
printf("-------- -------- -------- -------- -------- -------- -------- --------\n");
printf("%08x %08x %08x %08x %08x %08x %08x %08x\n\n",reg[0],reg[1],reg[2],
reg[3],reg[4],reg[5],reg[6],reg[7]);
printf(" r8 r9 r10 r11 r12 r13 r14 r15\n");
printf("-------- -------- -------- -------- -------- -------- -------- --------\n");
printf("%08x %08x %08x %08x %08x %08x %08x %08x\n\n",reg[8],reg[9],reg[10],
reg[11],reg[12],reg[13],reg[14],reg[15]);
 
for(i=0;i<sizeof(buffer);i++)
{
if(startmem+i >= MEMORY_START + MEMORY_LEN)
break;
buffer[i] = mem[startmem+i].data;
}
printf("Hex dump of stack memory:\n");
DumpAsciiToDescriptor(fileno(stdout),buffer,i);
}
 
/* This is an abstract+physical memory array rather than only physical
memory array */
struct mem_entry mem[MEMORY_LEN];
static struct mem_entry *simmem;
 
/* Pointer to memory area descriptions that are assigned to individual
peripheral devices. */
struct dev_memarea *dev_list;
 
/* Temporary variable to increase speed. */
struct dev_memarea *cur_area;
 
void dumpmemory(unsigned int from, unsigned int to, int disasm)
{
unsigned int i, j;
struct label_entry *tmp;
int breakpoint = 0;
for(i = from; i < to && i < (MEMORY_START + MEMORY_LEN);) {
int breakpoint;
unsigned int _insn = eval_mem32(i, &breakpoint);
int index = insn_decode (_insn);
int len = insn_len(index);
if (!len) len = 8;
printf("\n%.8x: ", i);
for (j = 0; j < len; j++) {
if (disasm) {
tmp = mem[i+j].label;
for(; tmp; tmp = tmp->next)
printf(" %s%s", tmp->name, LABELEND_CHAR);
printf("%02x", (unsigned char)mem[i+j].data);
int ilen = disasm ? 4 : 16;
 
for(i = from; i < to; i += ilen) {
for (j = 0; j < ilen;) {
int data = -1;
if (!disasm) {
tmp = NULL;
if (verify_memoryarea(i+j)) {
if (cur_area->getentry)
tmp = cur_area->getentry(i+j)->label;
for(; tmp; tmp = tmp->next)
printf(" %s%s", tmp->name, LABELEND_CHAR);
printf("%02x ", data = (unsigned char)cur_area->readfunc(i+j));
} else printf("XX ");
j++;
} else {
/* don't print ascii chars below 0x20. */
if (mem[i+j].data < 0x20)
printf("%02x ", (unsigned char)mem[i+j].data);
else
printf("%02x'%c' ", (unsigned char)mem[i+j].data, mem[i+j].data);
}
int breakpoint;
unsigned int _insn = eval_mem32(i, &breakpoint);
int index = insn_decode (_insn);
int len = insn_len (index);
tmp = NULL;
if (verify_memoryarea(i+j)) {
if (cur_area->getentry)
tmp = cur_area->getentry(i+j)->label;
for(; tmp; tmp = tmp->next)
printf(" %s%s", tmp->name, LABELEND_CHAR);
printf("%.8x: ", i);
 
printf("%08x ", (unsigned char)_insn);
if (index >= 0) {
disassemble_insn (_insn);
printf(" %s", disassembled);
} else
printf("<invalid>");
} else printf("XXXXXXXX");
j += len;
}
}
if (disasm && index >= 0) {
disassemble_insn (_insn);
printf(" %s", disassembled);
}
i += len;
}
}
 
 
/* Searches mem array for a particular label and returns label's address.
If label does not exist, returns 0. */
 
unsigned long eval_label(char *label)
{
int i;
char *plus;
char *plus;
char *minus;
int positive_offset = 0;
int negative_offset = 0;
struct label_entry *tmp;
 
if (plus = strchr(label, '+')) {
*plus = '\0';
positive_offset = atoi(++plus);
193,19 → 123,24
*minus = '\0';
negative_offset = atoi(++minus);
}
for(i = 0; i < (MEMORY_START + MEMORY_LEN); i++) {
tmp = mem[i].label;
for(; tmp; tmp = tmp->next)
if (strcmp(label, tmp->name) == 0) {
debug("eval_label(%s) => 0x%x\n", label, i+positive_offset-negative_offset);
return i+positive_offset-negative_offset;
}
}
printf("\nINTERNAL ERROR: undefined label %s\n", label);
cont_run = 0;
return 0;
for (cur_area = dev_list; cur_area; cur_area = cur_area->next) {
for(i = 0; i < cur_area->size; i++) if (cur_area->getentry) {
int mi = i + cur_area->start;
struct mem_entry *entry = cur_area->getentry(mi);
if (entry) {
struct label_entry *tmp = entry->label;
for(; tmp; tmp = tmp->next)
if (strcmp(label, tmp->name) == 0) {
debug("eval_label(%s) => 0x%x\n", label, i + positive_offset - negative_offset + cur_area->start);
return i + positive_offset - negative_offset + cur_area->start;
}
}
}
}
 
printf("\nINTERNAL ERROR: undefined label %s\n", label);
cont_run = 0;
return 0;
}
 
/* Calls IMMU translation routines before simulating insn
230,7 → 165,7
printf("INTERNAL ERROR: Unknown insn cache type.\n");
cont_run = 0;
}
 
return -1;
}
 
256,7 → 191,7
printf("INTERNAL ERROR: Unknown data cache type.\n");
cont_run = 0;
}
 
return -1;
}
 
282,26 → 217,29
printf("INTERNAL ERROR: Unknown data cache type.\n");
cont_run = 0;
}
 
return -1;
}
 
/* Register read and write function for a memory area (used by peripheral
devices like 16450 UART etc.) */
void register_memoryarea(unsigned long baseaddr, unsigned long size, unsigned long (readfunc)(unsigned long), void (writefunc)(unsigned long, unsigned long))
void register_memoryarea(unsigned long start, unsigned long size, unsigned char (readfunc)(unsigned long),
void (writefunc)(unsigned long, unsigned char), struct mem_entry *(getentry)(unsigned long))
{
struct dev_memarea **pptmp;
 
/* Go to the end of the list. */
for(pptmp = &dev_list; *pptmp; pptmp = &(*pptmp)->next);
*pptmp = (struct dev_memarea *)malloc(sizeof(struct dev_memarea));
(*pptmp)->baseaddr = baseaddr;
 
cur_area = *pptmp = (struct dev_memarea *)malloc(sizeof(struct dev_memarea));
(*pptmp)->start = start;
(*pptmp)->size = size;
(*pptmp)->end = start + size;
(*pptmp)->readfunc = readfunc;
(*pptmp)->writefunc = writefunc;
(*pptmp)->getentry = getentry;
(*pptmp)->next = NULL;
 
return;
}
 
309,13 → 247,13
struct dev_memarea *verify_memoryarea(unsigned long addr)
{
struct dev_memarea *ptmp;
 
/* Check list of registered devices. */
for(ptmp = dev_list; ptmp; ptmp = ptmp->next)
if (addr >= ptmp->baseaddr &&
addr < (ptmp->baseaddr + ptmp->size))
return ptmp;
return NULL;
if (addr >= ptmp->start &&
addr < (ptmp->end))
return cur_area = ptmp;
return cur_area = NULL;
}
 
/* Returns 32-bit values from mem array. Big endian version. */
325,35 → 263,28
unsigned long temp;
struct dev_memarea *dev;
 
 
slp_checkaccess(memaddr, SLP_MEMREAD);
memaddr = simulate_dc_mmu_load(memaddr);
*breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
 
return evalsim_mem32(memaddr,breakpoint);
temp = evalsim_mem32(memaddr);
*breakpoint += CheckDebugUnit(DebugLoadData,temp); /* MM170901 */
return temp;
}
 
unsigned long evalsim_mem32(unsigned long memaddr,int* breakpoint)
unsigned long evalsim_mem32(unsigned long memaddr)
{
unsigned long temp;
struct dev_memarea *dev;
if (memaddr < (MEMORY_START + MEMORY_LEN)) {
temp = mem[memaddr].data << 24;
temp += mem[memaddr + 1].data << 16;
temp += mem[memaddr + 2].data << 8;
temp += mem[memaddr + 3].data;
} else if (dev = verify_memoryarea(memaddr)) {
temp = dev->readfunc(memaddr);
 
if (verify_memoryarea(memaddr)) {
temp = cur_area->readfunc(memaddr) << 24;
temp |= cur_area->readfunc(memaddr + 1) << 16;
temp |= cur_area->readfunc(memaddr + 2) << 8;
temp |= cur_area->readfunc(memaddr + 3);
} else {
printf("EXCEPTION @ <0x%06x>: read out of memory (32-bit access to %.8lx)\n", pc_phy, memaddr);
DebugDump();
printf("EXCEPTION: read out of memory (32-bit access to %.8lx)\n", memaddr);
cont_run = 0;
temp = 0;
}
 
*breakpoint += CheckDebugUnit(DebugLoadData,temp); /* 28/05/01 CZ */
 
return temp;
}
 
361,30 → 292,27
 
unsigned short eval_mem16(unsigned long memaddr,int* breakpoint)
{
 
unsigned short temp;
memaddr = simulate_dc_mmu_load(memaddr);
*breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
*breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
 
return evalsim_mem16(memaddr,breakpoint);
temp = evalsim_mem16(memaddr);
*breakpoint += CheckDebugUnit(DebugLoadData,temp); /* MM170901 */
return temp;
}
 
unsigned short evalsim_mem16(unsigned long memaddr,int* breakpoint)
unsigned short evalsim_mem16(unsigned long memaddr)
{
unsigned short temp;
if (memaddr < (MEMORY_START + MEMORY_LEN)) {
temp = ((unsigned short)(mem[memaddr].data << 8) & 0xff00);
temp += ((unsigned short)mem[memaddr + 1].data & 0x00ff);
 
if (verify_memoryarea(memaddr)) {
temp = cur_area->readfunc(memaddr) << 8;
temp |= cur_area->readfunc(memaddr + 1);
} else {
printf("EXCEPTION @ <0x%06x>: read out of memory (16-bit access to %.8lx)\n", pc_phy,memaddr);
DebugDump();
printf("EXCEPTION: read out of memory (16-bit access to %.8lx)\n", memaddr);
cont_run = 0;
temp = 0;
}
 
*breakpoint += CheckDebugUnit(DebugLoadData,temp); /* 28/05/01 CZ */
 
return temp;
}
 
392,29 → 320,27
/* Returns 8-bit values from mem array. */
 
unsigned char eval_mem8(unsigned long memaddr,int* breakpoint)
{
 
{
unsigned char temp;
memaddr = simulate_dc_mmu_load(memaddr);
*breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
 
return evalsim_mem8(memaddr,breakpoint);
temp = evalsim_mem8(memaddr);
*breakpoint += CheckDebugUnit(DebugLoadData,temp); /* MM170901 */
return temp;
}
 
unsigned char evalsim_mem8(unsigned long memaddr,int* breakpoint)
{
unsigned char evalsim_mem8(unsigned long memaddr)
{
unsigned char temp;
 
if (memaddr < (MEMORY_START + MEMORY_LEN)) {
temp = (unsigned char)mem[memaddr].data;
if (verify_memoryarea(memaddr)) {
temp = cur_area->readfunc(memaddr);
} else {
printf("EXCEPTION @ <0x%06x>: read out of memory (8-bit access to %.8lx)\n", pc_phy,memaddr);
DebugDump();
printf("EXCEPTION: read out of memory (8-bit access to %.8lx)\n", memaddr);
cont_run = 0;
temp = 0;
}
 
*breakpoint += CheckDebugUnit(DebugLoadData,temp); /* 28/05/01 CZ */
 
return temp;
}
 
424,7 → 350,7
{
slp_checkaccess(memaddr, SLP_MEMWRITE);
memaddr = simulate_dc_mmu_store(memaddr);
 
*breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr); /* 28/05/01 CZ */
*breakpoint += CheckDebugUnit(DebugStoreData,value);
 
437,16 → 363,13
{
struct dev_memarea *dev;
 
if (memaddr < (MEMORY_START + MEMORY_LEN)) {
mem[memaddr].data = (value >> 24);
mem[memaddr + 1].data = (char)(value >> 16);
mem[memaddr + 2].data = (char)(value >> 8);
mem[memaddr + 3].data = (char)(value);
} else if (dev = verify_memoryarea(memaddr)) {
dev->writefunc(memaddr, value);
if (verify_memoryarea(memaddr)) {
cur_area->writefunc(memaddr, value >> 24);
cur_area->writefunc(memaddr + 1, (unsigned char)(value >> 16));
cur_area->writefunc(memaddr + 2, (unsigned char)(value >> 8));
cur_area->writefunc(memaddr + 3, (unsigned char)value);
} else {
printf("EXCEPTION @ <0x%06x>: write out of memory (32-bit access to %.8lx)\n", pc_phy, memaddr);
DebugDump();
printf("EXCEPTION: write out of memory (32-bit access to %.8lx)\n", memaddr);
cont_run = 0;
}
 
458,23 → 381,22
void set_mem16(unsigned long memaddr, unsigned short value,int* breakpoint)
{
memaddr = simulate_dc_mmu_store(memaddr);
 
*breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr); /* 28/05/01 CZ */
*breakpoint += CheckDebugUnit(DebugStoreData,value);
 
setsim_mem16(memaddr, value);
 
return;
}
 
void setsim_mem16(unsigned long memaddr, unsigned short value)
{
if (memaddr < (MEMORY_START + MEMORY_LEN)) {
mem[memaddr].data = (value >> 8);
mem[memaddr + 1].data = (char)(value);
if (verify_memoryarea(memaddr)) {
cur_area->writefunc(memaddr, (unsigned char) (value >> 8));
cur_area->writefunc(memaddr + 1, (unsigned char)value);
} else {
printf("EXCEPTION @ <0x%06x>: write out of memory (16-bit access to %.8lx)\n",pc_phy, memaddr);
DebugDump();
printf("EXCEPTION: write out of memory (16-bit access to %.8lx)\n", memaddr);
cont_run = 0;
}
 
486,7 → 408,7
void set_mem8(unsigned long memaddr, unsigned char value,int* breakpoint)
{
memaddr = simulate_dc_mmu_store(memaddr);
 
*breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr); /* 28/05/01 CZ */
*breakpoint += CheckDebugUnit(DebugStoreData,value);
 
497,11 → 419,10
 
void setsim_mem8(unsigned long memaddr, unsigned char value)
{
if (memaddr < (MEMORY_START + MEMORY_LEN)) {
mem[memaddr].data = value;
if (verify_memoryarea(memaddr)) {
cur_area->writefunc(memaddr, (unsigned char)value);
} else {
printf("EXCEPTION @ <0x%06x>: write out of memory (8-bit access to %.8lx)\n", pc_phy,memaddr);
DebugDump();
printf("EXCEPTION: write out of memory (8-bit access to %.8lx)\n", memaddr);
cont_run = 0;
}
 
508,3 → 429,44
return;
}
 
unsigned char simmem_readfunc(unsigned long addr) {
return simmem[cur_area->misc + addr - cur_area->start].data;
}
 
void simmem_writefunc(unsigned long addr, unsigned char value) {
simmem[cur_area->misc + addr - cur_area->start].data = value;
}
 
struct mem_entry * simmem_getentry(unsigned long addr) {
return &simmem[cur_area->misc + addr - cur_area->start];
}
 
void sim_read_memory_table (char *filename)
{
FILE *f;
unsigned long memory_needed = 0;
char *home = getenv("HOME");
char ctmp[256];
int local = 1;
sprintf(ctmp, "%s/.or1k/%s", home, filename);
if ((f = fopen (filename, "rt")) != NULL
|| home != NULL && !(local = 0) && (f = fopen (ctmp, "rt")) != NULL) {
unsigned long start, length;
char type[100];
printf ("Reading memory table from '%s':\n", local ? filename : ctmp);
while (fscanf (f, "%08x %08x %s\n", &start, &length, &type) == 3) {
printf ("%08X %08X (%i KB): %s\n", start, length, length >> 10, type);
register_memoryarea(start, length, &simmem_readfunc, &simmem_writefunc, &simmem_getentry);
cur_area->misc = memory_needed;
memory_needed += DEFAULT_MEMORY_LEN;
}
fclose (f);
printf ("\n");
} else {
fprintf (stderr, "Cannot read memory table from '%s',\nneither '%s', assuming standard configuration.\n", filename, ctmp);
register_memoryarea(DEFAULT_MEMORY_START, DEFAULT_MEMORY_LEN, &simmem_readfunc, &simmem_writefunc, &simmem_getentry);
memory_needed += DEFAULT_MEMORY_LEN;
}
simmem = (struct mem_entry *) malloc (sizeof (struct mem_entry) * memory_needed);
}
/trunk/or1ksim/cpu/common/abstract.h
17,8 → 17,8
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
#define MEMORY_START 0
#define MEMORY_LEN 0x800000
#define DEFAULT_MEMORY_START 0
#define DEFAULT_MEMORY_LEN 0x800000
#define STACK_SIZE 20
#define LABELNAME_LEN 50
#define INSNAME_LEN 15
56,11 → 56,15
 
/* Memory regions assigned to devices */
struct dev_memarea {
struct dev_memarea *next;
unsigned long baseaddr;
struct dev_memarea *next;
unsigned long start;
unsigned long end;
unsigned long size;
unsigned long (*readfunc)(unsigned long);
void (*writefunc)(unsigned long, unsigned long);
unsigned char (*readfunc)(unsigned long);
void (*writefunc)(unsigned long, unsigned char);
struct mem_entry* (*getentry) (unsigned long);
/* private data */
unsigned long misc;
};
 
extern struct iqueue_entry iqueue[20];
67,7 → 71,6
extern struct iqueue_entry icomplet[20];
extern unsigned long pc;
 
extern struct mem_entry mem[MEMORY_LEN];
extern void dumpmemory(unsigned int from, unsigned int to, int disasm);
extern unsigned long eval_label(char *label);
extern unsigned long eval_mem32(unsigned long memaddr,int*);
77,13 → 80,24
extern void set_mem16(unsigned long memaddr, unsigned short value,int*);
extern void set_mem8(unsigned long memaddr, unsigned char value,int*);
 
unsigned long evalsim_mem32(unsigned long,int*);
unsigned short evalsim_mem16(unsigned long,int*);
unsigned char evalsim_mem8(unsigned long,int*);
unsigned long evalsim_mem32(unsigned long);
unsigned short evalsim_mem16(unsigned long);
unsigned char evalsim_mem8(unsigned long);
void setsim_mem32(unsigned long,unsigned long);
void setsim_mem16(unsigned long,unsigned short);
void setsim_mem8(unsigned long,unsigned char);
 
void sim_read_memory_table (char *filename);
 
/* Register read and write function for a memory area (used by peripheral
devices like 16450 UART etc.) */
void register_memoryarea(unsigned long start, unsigned long size, unsigned char (readfunc)(unsigned long),
void (writefunc)(unsigned long, unsigned char), struct mem_entry *(getentry)(unsigned long));
/* Check if access is to registered area of memory. */
struct dev_memarea *verify_memoryarea(unsigned long addr);
/* Temporary variable to increase speed. */
extern struct dev_memarea *cur_area;
 
#ifndef DEBUGMOD_OFF
extern int GlobalMode; /* Added by CZ 26/05/01 */
#else /* DEBUGMOD_OFF */
92,29 → 106,6
 
/* Added by MM */
#ifndef LONGEST
 
#ifdef BFD64
 
#define LONGEST BFD_HOST_64_BIT
#define ULONGEST BFD_HOST_U_64_BIT
 
#else /* No BFD64 */
 
#ifdef CC_HAS_LONG_LONG
#define LONGEST long long
#define ULONGEST unsigned long long
#else
#ifdef BFD_HOST_64_BIT
/* BFD_HOST_64_BIT is defined for some hosts that don't have long long
(e.g. i386-windows) so try it. */
#define LONGEST BFD_HOST_64_BIT
#define ULONGEST BFD_HOST_U_64_BIT
#else
#define LONGEST long
#define ULONGEST unsigned long
#endif
#endif
 
#endif /* No BFD64 */
 
#endif /* ! LONGEST */
/trunk/or1ksim/cpu/common/parse.c
30,6 → 30,7
#include "opcode/or32.h"
#include "parse.h"
 
#define MEMORY_LEN 0x100000000
#define MAXLINE_LEN 18000
 
extern char *disassembled;
87,7 → 88,7
return(out);
}
 
/* Used only by the simulator loader to translate logical addresses int ophysical.
/* Used only by the simulator loader to translate logical addresses into physical.
If loadcode() is called with valid virtphy_transl pointer to a table of
translations then translate() performs translation otherwise phy address is
equal to logical. */
103,23 → 104,23
/* Try to find our translation in the table. */
for(i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
if ((laddr & ~(PAGE_SIZE - 1)) == evalsim_mem32(transl_table + i,breakpoint)) {
if ((laddr & ~(PAGE_SIZE - 1)) == evalsim_mem32(transl_table + i)) {
setsim_mem32(transl_table + i + 8, -2); /* Page modified */
printf("found paddr=%x\n", evalsim_mem32(transl_table + i + 4,breakpoint) | (laddr & (PAGE_SIZE - 1)));
return (unsigned long)evalsim_mem32(transl_table + i + 4,breakpoint) | (laddr & (unsigned long)(PAGE_SIZE - 1));
printf("found paddr=%x\n", evalsim_mem32(transl_table + i + 4) | (laddr & (PAGE_SIZE - 1)));
return (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (unsigned long)(PAGE_SIZE - 1));
}
 
/* Allocate new phy page for us. */
for(i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
if (evalsim_mem32(transl_table + i + 8,breakpoint) == 0) {
if (evalsim_mem32(transl_table + i + 8) == 0) {
setsim_mem32(transl_table + i, laddr & ~(PAGE_SIZE - 1)); /* VPN */
setsim_mem32(transl_table + i + 4, (i/16) * PAGE_SIZE); /* PPN */
setsim_mem32(transl_table + i + 8, -2); /* Page modified */
printf("newly allocated ppn=%x\n", (unsigned long)evalsim_mem32(transl_table + i + 4,breakpoint));
printf("newly allocated ppn=%x\n", (unsigned long)evalsim_mem32(transl_table + i + 4));
printf("newly allocated .ppn=%x\n", (unsigned long)transl_table + i + 4);
printf("newly allocated ofs=%x\n", (unsigned long)(laddr & (PAGE_SIZE - 1)));
printf("newly allocated paddr=%x\n", (unsigned long)evalsim_mem32(transl_table + i + 4,breakpoint) | (laddr & (PAGE_SIZE - 1)));
return (unsigned long)evalsim_mem32(transl_table + i + 4,breakpoint) | (laddr & (unsigned long)(PAGE_SIZE - 1));
printf("newly allocated paddr=%x\n", (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (PAGE_SIZE - 1)));
return (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (unsigned long)(PAGE_SIZE - 1));
}
/* If we come this far then all phy memory is used and we can't find our page
nor allocate new page. */
140,18 → 141,18
for(; *str && *str != '\"'; str++, translate(freemem++,breakpoint))
if (*str == '\\')
switch (*++str) {
case 'n': mem[translate(freemem,breakpoint)].data = '\n';
case 'n': setsim_mem8(translate(freemem,breakpoint), '\n');
break;
case 't': mem[translate(freemem,breakpoint)].data = '\t';
case 't': setsim_mem8(translate(freemem,breakpoint), '\t');
break;
case 'r': mem[translate(freemem,breakpoint)].data = '\r';
case 'r': setsim_mem8(translate(freemem,breakpoint), '\r');
break;
case '0': mem[translate(freemem,breakpoint)].data = '\0';
case '0': setsim_mem8(translate(freemem,breakpoint), '\0');
break;
default: break;
}
else
mem[translate(freemem,breakpoint)].data = *str;
setsim_mem8(translate(freemem,breakpoint), *str);
}
 
/* Modified by CZ 26/05/01 */
166,10 → 167,7
num = eval_label(item);
debug("adddataword: [0x%x] <= %x\n", translate(freemem,breakpoint), num);
mem[translate(freemem,breakpoint)].data = (char) (num >> 24);
mem[translate(freemem + 1,breakpoint)].data = (char) (num >> 16);
mem[translate(freemem + 2,breakpoint)].data = (char) (num >> 8);
mem[translate(freemem + 3,breakpoint)].data = (char) (num);
setsim_mem32(translate(freemem,breakpoint), num);
if(!GlobalMode)
freemem += 4;
184,8 → 182,7
else
num = eval_label(item);
mem[translate(freemem,breakpoint)].data = (char) (num >> 8);
mem[translate(freemem + 1,breakpoint)].data = (char) (num);
setsim_mem16(translate(freemem,breakpoint), num);
freemem += 2;
}
199,7 → 196,7
else
num = eval_label(item);
 
mem[translate(freemem,breakpoint)].data = (char) (num);
setsim_mem8(translate(freemem,breakpoint),num);
freemem++;
}
212,9 → 209,12
void addlabel(char *label, unsigned long freemem,int* breakpoint)
{
struct label_entry **tmp;
struct mem_entry *entry;
debug("Adding label %s at 0x%x\n", label, translate(freemem,breakpoint));
if(!verify_memoryarea(freemem) || !cur_area->getentry) return;
debug("Adding label %s at 0x%x\n", label, translate(freemem,breakpoint));
tmp = &mem[translate(freemem,breakpoint)].label;
entry = cur_area->getentry(translate(freemem,breakpoint));
tmp = &(entry->label);
for (; *tmp; tmp = &((*tmp)->next));
*tmp = malloc(sizeof(**tmp));
(*tmp)->name = malloc(strlen(label)+1);
221,7 → 221,7
strcpy((*tmp)->name, label);
(*tmp)->next = NULL;
return;
return;
}
 
char null_str[1] = "\0";
298,6 → 298,7
printf(" scnptr: 0x%.8x\n", COFF_LONG_H(coffscnhdr.s_scnptr));
sectsize = COFF_LONG_H(coffscnhdr.s_size);
#if 0
/* A couple of sanity checks. */
if (translate(COFF_LONG_H(coffscnhdr.s_vaddr),&breakpoint) < MEMORY_START) {
printf("Section %s starts out of ", coffscnhdr.s_name);
310,6 → 311,7
printf("memory.\n");
exit(1);
}
#endif
#if 0
if (++firstthree == 1 && strcmp(coffscnhdr.s_name, ".text") != 0) {
printf("First section should be .text (%s instead)\n", coffscnhdr.s_name);
/trunk/or1ksim/cpu/or1k/Makefile.in
89,6 → 89,7
CC = @CC@
CFLAGS = @CFLAGS@
CPU_ARCH = @CPU_ARCH@
FPM = @FPM@
INCLUDES = @INCLUDES@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
LOCAL_DEFS = @LOCAL_DEFS@
/trunk/or1ksim/cpu/or1k/except.c
101,8 → 101,8
pc = delayed_pc;
pcnext = delayed_pcnext;
pc_phy = simulate_ic_mmu_fetch(pc);
if ((pc_phy < MEMORY_START) || (pc_phy > MEMORY_START + MEMORY_LEN))
except_handle(EXCEPT_BUSERR, pc);
if (verify_memoryarea(pc_phy))
except_handle(EXCEPT_BUSERR, pc);
delayed_pc_valid = delayed_pc = delayed_pcnext = 0;
}
 
/trunk/or1ksim/cpu/or1k/spr_defs.h
43,13 → 43,6
/* System control and status group */
#define SPR_VR (SPRGROUP_SYS + 0)
#define SPR_UPR (SPRGROUP_SYS + 1)
#define SPR_CPUCFGR (SPRGROUP_SYS + 2)
#define SPR_DMMUCFGR (SPRGROUP_SYS + 3)
#define SPR_IMMUCFGR (SPRGROUP_SYS + 4)
#define SPR_DCCFGR (SPRGROUP_SYS + 5)
#define SPR_ICCFGR (SPRGROUP_SYS + 6)
#define SPR_DCFGR (SPRGROUP_SYS + 7)
#define SPR_PCCFGR (SPRGROUP_SYS + 8)
#define SPR_PC (SPRGROUP_SYS + 16) /* CZ 21/06/01 */
#define SPR_SR (SPRGROUP_SYS + 17) /* CZ 21/06/01 */
#define SPR_EPCR_BASE (SPRGROUP_SYS + 32) /* CZ 21/06/01 */
154,86 → 147,6
#define SPR_UPR_CUST 0xff000000 /* Custom units */
 
/*
* Bit definitions for the CPU Configuration register
*
*/
#define SPR_CPUCFGR_NSGF 0x0000000f /* Number of shadow GPR files */
#define SPR_CPUCFGR_HGF 0x00000010 /* Half GPR File */
#define SPR_CPUCFGR_OB32S 0x00000020 /* ORBIS32 Supported */
#define SPR_CPUCFGR_OB64S 0x00000040 /* ORBIS64 Supported */
#define SPR_CPUCFGR_OF32S 0x00000080 /* ORFPX32 Supported */
#define SPR_CPUCFGR_OF64S 0x00000100 /* ORFP64P Supported */
#define SPR_CPUCFGR_OV64S 0x00000200 /* ORVDX64 Supported */
 
/*
* Bit definitions for the DMMU Configuration register
*
*/
#define SPR_DMMUCFGR_NTW 0x00000003 /* Number of TLB Ways */
#define SPR_DMMUCFGR_NTS 0x0000001c /* Number of TLB Sets (entries per way) */
#define SPR_DMMUCFGR_NAE 0x000000e0 /* Number of ATB Entries */
#define SPR_DMMUCFGR_CRI 0x00000100 /* Control Register Implemented */
#define SPR_DMMUCFGR_PRI 0x00000200 /* Protection Register Implemented */
#define SPR_DMMUCFGR_TEIRI 0x00000400 /* TLB Entry Invalidate Register Implemented */
#define SPR_DMMUCFGR_HTR 0x00000800 /* Hardware TLB Reload */
 
/*
* Bit definitions for the IMMU Configuration register
*
*/
#define SPR_IMMUCFGR_NTW 0x00000003 /* Number of TLB Ways */
#define SPR_IMMUCFGR_NTS 0x0000001c /* Number of TLB Sets (entries per way) */
#define SPR_IMMUCFGR_NAE 0x000000e0 /* Number of ATB Entries */
#define SPR_IMMUCFGR_CRI 0x00000100 /* Control Register Implemented */
#define SPR_IMMUCFGR_PRI 0x00000200 /* Protection Register Implemented */
#define SPR_IMMUCFGR_TEIRI 0x00000400 /* TLB Entry Invalidate Register Implemented */
#define SPR_IMMUCFGR_HTR 0x00000800 /* Hardware TLB Reload */
 
/*
* Bit definitions for the DC Configuration register
*
*/
#define SPR_DCCFGR_NCW 0x00000007 /* Number of Cache Ways */
#define SPR_DCCFGR_NCS 0x00000078 /* Number of Cache Sets (cache blocks per way) */
#define SPR_DCCFGR_CBS 0x00000080 /* Cache Block Size */
#define SPR_DCCFGR_CWS 0x00000100 /* Cache Write Strategy */
#define SPR_DCCFGR_CCRI 0x00000200 /* Cache Control Register Implemented */
#define SPR_DCCFGR_CBIRI 0x00000400 /* Cache Block Invalidate Register Implemented */
#define SPR_DCCFGR_CBPRI 0x00000800 /* Cache Block Prefetch Register Implemented */
#define SPR_DCCFGR_CBLRI 0x00001000 /*Cache Block Lock Register Implemented */
#define SPR_DCCFGR_CBFRI 0x00002000 /* Cache Block Flush Register Implemented */
#define SPR_DCCFGR_CBWBRI 0x00004000 /* Cache Block Write-Back Register Implemented */
 
/*
* Bit definitions for the IC Configuration register
*
*/
#define SPR_ICCFGR_NCW 0x00000007 /* Number of Cache Ways */
#define SPR_ICCFGR_NCS 0x00000078 /* Number of Cache Sets (cache blocks per way) */
#define SPR_ICCFGR_CBS 0x00000080 /* Cache Block Size */
#define SPR_ICCFGR_CWS 0x00000100 /* Cache Write Strategy */
#define SPR_ICCFGR_CCRI 0x00000200 /* Cache Control Register Implemented */
#define SPR_ICCFGR_CBIRI 0x00000400 /* Cache Block Invalidate Register Implemented */
#define SPR_ICCFGR_CBPRI 0x00000800 /* Cache Block Prefetch Register Implemented */
#define SPR_ICCFGR_CBLRI 0x00001000 /*Cache Block Lock Register Implemented */
#define SPR_ICCFGR_CBFRI 0x00002000 /* Cache Block Flush Register Implemented */
#define SPR_ICCFGR_CBWBRI 0x00004000 /* Cache Block Write-Back Register Implemented */
 
/*
* Bit definitions for the Debug Configuration register
*
*/
#define SPR_DCFGR_NDP 0x00000007 /* Number of Debug Pairs */
#define SPR_DCFGR_WPCI 0x00000008 /* Watchpoint Counters Implemented */
 
/*
* Bit definitions for the Performance Counters Configuration register
*
*/
#define SPR_PCCFGR_NDP 0x00000007 /* Number of Performance Counters */
 
 
/*
* Bit definitions for the Supervision Register
*
*/
442,11 → 355,11
* Bit definitions for the Power management register
*
*/
#define SPR_PMR_SDF 0x0000000f /* Slow down factor */
#define SPR_PMR_DME 0x00000010 /* Doze mode enable */
#define SPR_PMR_SME 0x00000020 /* Sleep mode enable */
#define SPR_PMR_DCGE 0x00000040 /* Dynamic clock gating enable */
#define SPR_PMR_SUME 0x00000080 /* Suspend mode enable */
#define SPR_PMR_SDF 0x00000001 /* Slow down factor */
#define SPR_PMR_DME 0x00000002 /* Doze mode enable */
#define SPR_PMR_SME 0x00000004 /* Sleep mode enable */
#define SPR_PMR_DCGE 0x00000008 /* Dynamic clock gating enable */
#define SPR_PMR_SUME 0x00000010 /* Suspend mode enable */
 
/*
* Bit definitions for PICMR
/trunk/or1ksim/tick/Makefile.in
89,6 → 89,7
CC = @CC@
CFLAGS = @CFLAGS@
CPU_ARCH = @CPU_ARCH@
FPM = @FPM@
INCLUDES = @INCLUDES@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
LOCAL_DEFS = @LOCAL_DEFS@
/trunk/or1ksim/cache/Makefile.in
89,6 → 89,7
CC = @CC@
CFLAGS = @CFLAGS@
CPU_ARCH = @CPU_ARCH@
FPM = @FPM@
INCLUDES = @INCLUDES@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
LOCAL_DEFS = @LOCAL_DEFS@
/trunk/or1ksim/pic/Makefile.in
89,6 → 89,7
CC = @CC@
CFLAGS = @CFLAGS@
CPU_ARCH = @CPU_ARCH@
FPM = @FPM@
INCLUDES = @INCLUDES@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
LOCAL_DEFS = @LOCAL_DEFS@
/trunk/or1ksim/pm/Makefile.in
89,6 → 89,7
CC = @CC@
CFLAGS = @CFLAGS@
CPU_ARCH = @CPU_ARCH@
FPM = @FPM@
INCLUDES = @INCLUDES@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
LOCAL_DEFS = @LOCAL_DEFS@
trunk/or1ksim/testbench/uos/spr_defs.h Property changes : Deleted: svn:executable ## -1 +0,0 ## -* \ No newline at end of property Index: trunk/or1ksim/testbench/uos/int.h =================================================================== --- trunk/or1ksim/testbench/uos/int.h (revision 220) +++ trunk/or1ksim/testbench/uos/int.h (nonexistent) @@ -1,16 +0,0 @@ - -/* Number of interrupt handlers */ -#define MAX_INT_HANDLERS 32 - -/* High - low priority */ -#define INT_HIGH_PRI 1 -#define INT_LOW_PRI 0 - -/* Interrupt vectors */ -#define V_TICK 3 - -/* Handler entry */ -struct ihnd { - void (*handler)(void *); - void *arg; -}; Index: trunk/or1ksim/testbench/uos/Makefile =================================================================== --- trunk/or1ksim/testbench/uos/Makefile (revision 220) +++ trunk/or1ksim/testbench/uos/Makefile (nonexistent) @@ -1,60 +0,0 @@ -# Makefile -- Makefile for the Micro OS -# Copyright (C) 2000 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. */ -## - -# SEARCHDIR = /home/simons/or1k/lib/gcc-lib/or32-rtems/2.95.2/ -SEARCHDIR = /home/simons/or1k-elf-test/lib/gcc-lib/or32-elf/2.95.2/ - -# CC = or32-elf-gcc -# LD = or32-elf-ld -CC = or32-rtems-gcc -LD = or32-rtems-ld - -CFLAGS = -O2 -# CFLAGS = -O2 -DOR32 -# LDFLAGS = -nostdlib - -LDFLAGS = -L/home/simons/or1k/lib/gcc-lib/or32-rtems/2.95.2/ -lgcc -# LDFLAGS = -L/home/simons/or1k/lib/gcc-lib/or32-elf/2.95.2/ -lgcc - -UOS_OBJECTS = except_or32.o \ - uos.o \ - task.o \ - int.o \ - tick.o - -## - -uos.or32: $(UOS_OBJECTS) Makefile - $(LD) -o $@ $(UOS_OBJECTS) $(LDFLAGS) - -uos.o: uos.c spr_defs.h uos.h ipc.h Makefile - $(CC) $(CFLAGS) -c -o $@ $< - -except_or32.o: except_or32.S spr_defs.h Makefile - $(CC) $(CFLAGS) -c -o $@ $< - -task.o: task.c uos.h Makefile - $(CC) $(CFLAGS) -c -o $@ $< - -tick.o: tick.c uos.h Makefile - $(CC) $(CFLAGS) -c -o $@ $< - -clean: - rm -rf *.o *.s *.i uos.or32 Index: trunk/or1ksim/testbench/uos/task.c =================================================================== --- trunk/or1ksim/testbench/uos/task.c (revision 220) +++ trunk/or1ksim/testbench/uos/task.c (nonexistent) @@ -1,52 +0,0 @@ -/* This file is part of test microkernel for OpenRISC 1000. */ -/* (C) 2000 Damjan Lampret, lampret@opencores.org */ - -#include "uos.h" -#include "ipc.h" - -extern struct tcb tasks[MAX_TASKS+1]; - -int task(int id) -{ - int rc; - struct _msg { - char id; - unsigned long count; - } msg; - - printf("Task %d started\n", id); - - if(id == 1) { - msg.id = 1; - msg.count = 0; - uos_msgsnd(2, (char *)&msg, sizeof(msg)); - } - - for(;;) { - rc = uos_msgrcv(0, (char *)&msg, sizeof(msg)); - - if(rc != 0) { - printf("Task %d: Waiting for massage\n", id); - } else { - printf("Task %d: Got massage from task %d: 0x%.8x. Sending message to task %d: 0x%.8x \n", id, msg.id, msg.count, (id == 3 ? 1 : (id + 1)), (msg.count + 1)); - msg.id = id; - - if((id == 1) && (msg.count > 15)) { - report(msg.count + 0xdeadde9c); - exit(0); - } - - msg.count += 1; - uos_msgsnd((id == 3 ? 1 : (id + 1)), (char *)&msg, sizeof(msg)); - } - } -} - -/* Called by kernel_init to collect all tasks entries. */ -void tasks_entries() -{ - tasks[1].regs.pc = (unsigned long)task; - tasks[2].regs.pc = (unsigned long)task; - tasks[3].regs.pc = (unsigned long)task; -} - Index: trunk/or1ksim/testbench/uos/Makefile.in =================================================================== --- trunk/or1ksim/testbench/uos/Makefile.in (nonexistent) +++ trunk/or1ksim/testbench/uos/Makefile.in (revision 221) @@ -0,0 +1,341 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 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. + +# +# 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 + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CC = @CC@ +CFLAGS = @CFLAGS@ +DLLTOOL = @DLLTOOL@ +INCLUDES = @INCLUDES@ +LD = @LD@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +MAKE_SHELL = @MAKE_SHELL@ +OBJDUMP = @OBJDUMP@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ + +LDADD = ../support/libsupport.a +LDFLAGS = -T${top_srcdir}/except.ld + +bin_PROGRAMS = uos +uos_SOURCES = except_or32.S support.h sprdefs.h task.c int.h int.c ipc.h tick.c uos.h uos.c +mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs +CONFIG_CLEAN_FILES = +PROGRAMS = $(bin_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LIBS = @LIBS@ +uos_OBJECTS = except_or32.o task.o int.o tick.o uos.o +uos_LDADD = $(LDADD) +uos_DEPENDENCIES = ../support/libsupport.a +uos_LDFLAGS = +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = README Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +DEP_FILES = .deps/except_or32.P .deps/int.P .deps/task.P .deps/tick.P \ +.deps/uos.P +SOURCES = $(uos_SOURCES) +OBJECTS = $(uos_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --foreign uos/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-binPROGRAMS: + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +distclean-binPROGRAMS: + +maintainer-clean-binPROGRAMS: + +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(bin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +uos: $(uos_OBJECTS) $(uos_DEPENDENCIES) + @rm -f uos + $(LINK) $(uos_LDFLAGS) $(uos_OBJECTS) $(uos_LDADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = uos + +distdir: $(DISTFILES) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(top_distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign uos/Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-include $(DEP_FILES) + +mostlyclean-depend: + +clean-depend: + +distclean-depend: + -rm -rf .deps + +maintainer-clean-depend: + +%.o: %.c + @echo '$(COMPILE) -c $<'; \ + $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.c + @echo '$(LTCOMPILE) -c $<'; \ + $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-binPROGRAMS +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-binPROGRAMS +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(bindir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \ + mostlyclean-tags mostlyclean-depend mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-binPROGRAMS clean-compile clean-tags clean-depend \ + clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-binPROGRAMS distclean-compile distclean-tags \ + distclean-depend distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-binPROGRAMS \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-depend maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ +maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir mostlyclean-depend \ +distclean-depend clean-depend maintainer-clean-depend info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +again: clean all + +# 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: trunk/or1ksim/testbench/uos/Makefile.am =================================================================== --- trunk/or1ksim/testbench/uos/Makefile.am (nonexistent) +++ trunk/or1ksim/testbench/uos/Makefile.am (revision 221) @@ -0,0 +1,28 @@ +## Makefile for or1ksim subdirectory test +## (c) Marko Mlinar, 2001 +## To add new test, edit between marked areas only +# +# 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. +# + +LDADD = ../support/libsupport.a +LDFLAGS = -T${top_srcdir}/except.ld + +bin_PROGRAMS = uos +uos_SOURCES = except_or32.S support.h sprdefs.h task.c int.h int.c ipc.h tick.c uos.h uos.c + +again: clean all
trunk/or1ksim/testbench/uos/Makefile.am Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: trunk/or1ksim/configure.in =================================================================== --- trunk/or1ksim/configure.in (revision 220) +++ trunk/or1ksim/configure.in (revision 221) @@ -150,7 +150,7 @@ INCLUDES="-I\${top_srcdir}/cpu/common -I\${top_srcdir}/cpu/or1k \ -I\${top_srcdir}/cpu/$CPU_ARCH -I\${top_srcdir}/cache -I\${top_srcdir}/mmu \ -I\${top_srcdir}/bpb -I\${top_srcdir}/peripheral -I\${top_srcdir}/tick \ --I\${top_srcdir}/pm -I\${top_srcdir}/pic" +-I\${top_srcdir}/pm -I\${top_srcdir}/pic -I\${top_srcdir}/debug" AC_SUBST(INCLUDES) test -n "$profile" && CFLAGS="$CFLAGS $profile" LDFLAGS="$LDFLAGS $profile" @@ -159,9 +159,9 @@ AC_OUTPUT([Makefile bpb/Makefile cache/Makefile cpu/Makefile cpu/common/Makefile cpu/or32/Makefile cpu/or16/Makefile - cpu/or1k/Makefile cpu/dlx/Makefile + cpu/or1k/Makefile cpu/dlx/Makefile debug/Makefile support/Makefile mmu/Makefile peripheral/Makefile tick/Makefile - pm/Makefile pic/Makefile], + pm/Makefile pic/Makefile debug/Makefile], [ # Makefile uses this timestamp file to record whether config.h is up to date. echo > stamp-h
/trunk/or1ksim/peripheral/16450.c
30,13 → 30,6
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h> /* CZ 250801 */
#include <sys/stat.h> /* CZ 250801 */
#include <fcntl.h> /* CZ 250801 */
#include <sys/poll.h> /* CZ 250801 */
#include <sys/time.h> /* CZ 250801 */
#include <unistd.h> /* CZ 250801 */
#include <errno.h> /* CZ 250801 */
 
#include "16450.h"
#include "sim-config.h"
43,6 → 36,7
#include "pic.h"
 
static struct dev_16450 uarts[NR_UARTS];
static int thre_int;
 
/* Number of clock cycles (one clock cycle is one call to the uart_clock())
before a single character is transmitted or received. */
66,17 → 60,13
uarts[uartchip].char_clks *= bauds_per_char;
}
 
/* CZ 260801 --- The simulator expects to access only 32
bit words. Since we only have an 8 bit data space, simply
ignore the bottom 24 bits. */
/* Set a specific UART register with value. */
void uart_write(unsigned long addr, unsigned int arg_value)
void uart_write(unsigned long addr, unsigned long value)
{
int chipsel;
unsigned char value = arg_value >> 24;
 
debug("uart_write(%x,%x)\n", addr, value);
debug("uart_write(%x,%x)\n", addr, (value >> 24));
for(chipsel = 0; chipsel < NR_UARTS; chipsel++)
if ((addr & ~(UART_ADDR_SPACE-1)) == uarts[chipsel].baseaddr)
break;
83,41 → 73,43
else if (chipsel == NR_UARTS)
return;
 
if (uarts[chipsel].regs.lcr & UART_LCR_DLAB)
{
switch (addr % UART_ADDR_SPACE)
{
case UART_DLL:
uarts[chipsel].regs.dll = value;
if (uarts[chipsel].regs.lcr & UART_LCR_DLAB) {
switch (addr % UART_ADDR_SPACE) {
case UART_DLL:
uarts[chipsel].regs.dll = (value >> 24);
break;
case UART_DLH:
uarts[chipsel].regs.dlh = (value >> 24);
break;
case UART_LCR:
uarts[chipsel].regs.lcr = (value >> 24) & UART_VALID_LCR;
break;
default:
debug("write out of range (addr %x, DLAB=1)\n", addr);
}
set_char_clks(chipsel);
return;
case UART_DLH:
uarts[chipsel].regs.dlh = value;
set_char_clks(chipsel);
return;
default: /* Fall through to normal processing */
break;
}
}
}
switch (addr % UART_ADDR_SPACE) {
case UART_TXBUF:
uarts[chipsel].regs.txbuf = value;
uarts[chipsel].regs.txbuf = (value >> 24);
uarts[chipsel].istat.txbuf = FULL;
uarts[chipsel].regs.lsr &= ~UART_LSR_TXBUFE;
uarts[chipsel].regs.lsr &= ~UART_LSR_TXSERE;
uarts[chipsel].istat.thre_int = 0;
break;
case UART_IER:
uarts[chipsel].regs.ier = value & UART_VALID_IER;
uarts[chipsel].regs.ier = (value >> 24) & UART_VALID_IER;
break;
case UART_LCR:
uarts[chipsel].regs.lcr = value & UART_VALID_LCR;
uarts[chipsel].regs.lcr = (value >> 24) & UART_VALID_LCR;
break;
case UART_MCR:
uarts[chipsel].regs.mcr = value & UART_VALID_MCR;
uarts[chipsel].regs.mcr = (value >> 24) & UART_VALID_MCR;
break;
case UART_SCR:
uarts[chipsel].regs.scr = value;
uarts[chipsel].regs.scr = (value >> 24);
break;
default:
debug("write out of range (addr %x)\n", addr);
126,17 → 118,14
return;
}
 
/* CZ 260801 --- The simulator expects to access only 32
bit words. Since we only have an 8 bit data space, simply
fill in the bottom 24 bits with zero */
/* Read a specific UART register. */
unsigned int uart_read(unsigned long addr)
unsigned long uart_read(unsigned long addr)
{
unsigned char value = 0;
int chipsel;
debug("uart_read(%x)\n", addr);
 
for(chipsel = 0; chipsel < NR_UARTS; chipsel++)
if ((addr & ~(UART_ADDR_SPACE-1)) == uarts[chipsel].baseaddr)
break;
143,18 → 132,19
else if (chipsel == NR_UARTS)
return 0;
 
if (uarts[chipsel].regs.lcr & UART_LCR_DLAB)
{
switch (addr % UART_ADDR_SPACE)
{
case UART_DLL:
return uarts[chipsel].regs.dll << 24;
case UART_DLH:
return uarts[chipsel].regs.dlh << 24;
default: /* Fall through to normal processing */
break;
}
}
if (uarts[chipsel].regs.lcr & UART_LCR_DLAB) {
switch (addr % UART_ADDR_SPACE) {
case UART_DLL:
value = uarts[chipsel].regs.dll;
break;
case UART_DLH:
value = uarts[chipsel].regs.dlh;
break;
default:
debug("read out of range (addr %x, DLAB=1)\n", addr);
}
return (value << 24);
}
switch (addr % UART_ADDR_SPACE) {
case UART_RXBUF:
167,6 → 157,7
break;
case UART_IIR:
value = uarts[chipsel].regs.iir & UART_VALID_IIR;
uarts[chipsel].istat.thre_int = 0;
break;
case UART_LCR:
value = uarts[chipsel].regs.lcr & UART_VALID_LCR;
190,10 → 181,9
default:
debug("read out of range (addr %x)\n", addr);
}
return value << 24;
return (value << 24);
}
 
 
/* Reset. It initializes all registers of all UART devices to zero values,
(re)opens all RX/TX file streams and places devices in memory address
space. */
200,104 → 190,25
void uart_reset()
{
int i;
static int initialized = 0; /* If we're not initialized, don't close it */
int saved_tx_fds[NR_UARTS];
int saved_rx_fds[NR_UARTS];
 
if(initialized)
{
for(i = 0; i < NR_UARTS; i++)
{
struct stat buf;
if(uarts[i].txfd >= 0)
{
if(fstat(uarts[i].txfd,&buf) ||
(!S_ISFIFO(buf.st_mode) &&
!S_ISSOCK(buf.st_mode)))
{
close(uarts[i].txfd);
saved_tx_fds[i] = -1;
}
else
saved_tx_fds[i] = uarts[i].txfd;
}
else
saved_tx_fds[i] = -1;
if(uarts[i].rxfd >= 0)
{
if(fstat(uarts[i].rxfd,&buf) ||
(!S_ISFIFO(buf.st_mode) &&
!S_ISSOCK(buf.st_mode)))
{
close(uarts[i].rxfd);
saved_rx_fds[i] = -1;
}
else
saved_rx_fds[i] = uarts[i].txfd;
}
else
saved_rx_fds[i] = -1;
}
}
else
{
for(i=0;i<NR_UARTS;i++)
saved_tx_fds[i] = saved_rx_fds[i] = -1;
initialized = 1;
}
 
printf("Resetting %u UART(s).\n", NR_UARTS);
memset(uarts, 0, sizeof(uarts));
for(i=0;i<NR_UARTS;i++)
{
uarts[i].txfd = saved_tx_fds[i];
uarts[i].rxfd = saved_rx_fds[i];
}
for(i = 0; i < NR_UARTS; i++)
if (config.uarts[i].txfile) { /* MM: Try to create stream. */
/* CZ changed this to use descriptors and non blocking I/O */
if ((uarts[i].rxfd = open(config.uarts[i].rxfile,
O_RDONLY | O_NONBLOCK)) < 0)
{
char sTemp[256];
 
sprintf(sTemp,"UART%d RX - \"%s\"",i,config.uarts[i].rxfile);
perror(sTemp);
continue;
}
if((uarts[i].txfd = open(config.uarts[i].txfile,
O_WRONLY | O_NONBLOCK)) < 0)
{
char sTemp[256];
 
if(errno == ENXIO)
{
/* In this case, we're a pipe, and the user has
forgotten to start the read process first. Help
him out by writing an error message and exiting */
 
fprintf(stderr,"Please start the serial port reader "
"before starting the simulator.\nIf you wish "
"to continue without this, please remove the "
"file \"%s\" and restart.\n",config.uarts[i].txfile);
fflush(stderr);
exit(1);
}
sprintf(sTemp,"UART%d TX - \"%s\"",i,config.uarts[i].txfile);
perror(sTemp);
close(uarts[i].rxfd);
uarts[i].rxfd = -1;
continue;
}
if (!(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r"))
&& !(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r+"))) {
printf("UART%d has problems with RX file stream.\n", i);
continue;
}
uarts[i].txfs = fopen(config.uarts[i].txfile, "a");
uarts[i].baseaddr = config.uarts[i].baseaddr;
printf("UART%d at 0x%.8x uses ", i, uarts[i].baseaddr);
printf("%s for RX and %s for TX.\n", config.uarts[i].rxfile,
config.uarts[i].txfile);
register_memoryarea(uarts[i].baseaddr, UART_ADDR_SPACE,
uart_read, uart_write);
if (uarts[i].txfs && uarts[i].txfs) {
printf("UART%d at 0x%.8x uses ", i, uarts[i].baseaddr);
printf("%s for RX and %s for TX.\n", config.uarts[i].rxfile, config.uarts[i].txfile);
} else
printf("UART%d has problems with TX file stream.\n", i);
register_memoryarea(uarts[i].baseaddr, UART_ADDR_SPACE, uart_read, uart_write);
}
}
305,133 → 216,101
devices. It does internal functional UART simulation. */
void uart_clock()
{
int i;
int i, retval;
for(i = 0; i < NR_UARTS; i++) {
if(uarts[i].txfd < 0)
continue;
if (!uarts[i].txfs) {
continue;
}
 
/* Transmit */
if (uarts[i].istat.txser == EMPTY)
{
uarts[i].regs.lsr |= UART_LSR_TXBUFE;
if (uarts[i].istat.txbuf == FULL)
{
uarts[i].iregs.txser = uarts[i].regs.txbuf;
uarts[i].istat.txser = FULL;
uarts[i].istat.txbuf = EMPTY;
uarts[i].regs.lsr &= ~UART_LSR_TXSERE;
}
else
uarts[i].regs.lsr |= UART_LSR_TXSERE;
}
else if (uarts[i].char_clks == uarts[i].istat.txser_clks++)
{
debug("TX \'%c\' via UART%d...\n", uarts[i].iregs.txser, i);
if (uarts[i].regs.mcr & UART_MCR_LOOP)
uarts[i].iregs.loopback = uarts[i].iregs.txser;
else
switch(send_byte(uarts[i].txfd,config.uarts[i].jitter,
i,(int)uarts[i].iregs.txser))
{
case -1: /* An error occurred */
close(uarts[i].txfd);
close(uarts[i].rxfd);
uarts[i].txfd = uarts[i].rxfd = -1;
continue;
case 0: /* The device wasn't ready */
uarts[i].istat.txser_clks = 0; /* Try again later */
break;
case 1: /* OK...it got sent */
uarts[i].istat.txser = EMPTY;
uarts[i].istat.txser_clks = 0;
break;
}
}
/* Transmit */
if (uarts[i].istat.txser == EMPTY) {
uarts[i].regs.lsr |= UART_LSR_TXBUFE;
if (uarts[i].istat.txbuf == FULL) {
uarts[i].iregs.txser = uarts[i].regs.txbuf;
uarts[i].istat.txser = FULL;
uarts[i].istat.txbuf = EMPTY;
uarts[i].regs.lsr &= ~UART_LSR_TXSERE;
uarts[i].istat.thre_int = 1;
} else
uarts[i].regs.lsr |= UART_LSR_TXSERE;
} else if (uarts[i].char_clks == uarts[i].istat.txser_clks++) {
debug("TX \'%c\' via UART%d...\n", uarts[i].iregs.txser, i);
if (uarts[i].regs.mcr & UART_MCR_LOOP)
uarts[i].iregs.loopback = uarts[i].iregs.txser;
else {
fputc((int)uarts[i].iregs.txser, uarts[i].txfs);
fflush(uarts[i].txfs);
}
uarts[i].istat.txser = EMPTY;
uarts[i].istat.txser_clks = 0;
}
 
/* Receive */
if (uarts[i].istat.rxser == EMPTY)
uarts[i].istat.rxser = FULL;
else if (uarts[i].char_clks == uarts[i].istat.rxser_clks++)
{
debug("Receiving via UART%d...\n", i);
if (uarts[i].regs.mcr & UART_MCR_LOOP)
uarts[i].iregs.rxser = uarts[i].iregs.loopback;
else
switch(receive_byte(uarts[i].rxfd,config.uarts[i].jitter,
i,&uarts[i].iregs.rxser))
{
case -1: /* An error occurred */
close(uarts[i].txfd);
close(uarts[i].rxfd);
uarts[i].txfd = uarts[i].rxfd = -1;
continue;
case 0:
uarts[i].istat.rxser_clks = 0;
break;
case 1:
uarts[i].istat.rxser = EMPTY;
uarts[i].istat.rxser_clks = 0;
if (uarts[i].istat.rxbuf == FULL)
uarts[i].regs.lsr |= UART_LSR_OVRRUN;
uarts[i].regs.lsr |= UART_LSR_RDRDY;
uarts[i].regs.rxbuf = uarts[i].iregs.rxser;
uarts[i].istat.rxbuf = FULL;
break;
}
}
 
/* Loopback */
if (uarts[i].regs.mcr & UART_MCR_LOOP)
{
debug("uart_clock: Loopback\n");
if ((uarts[i].regs.mcr & UART_MCR_AUX2) !=
((uarts[i].regs.msr & UART_MSR_DCD) >> 4))
uarts[i].regs.msr |= UART_MSR_DDCD;
if ((uarts[i].regs.mcr & UART_MCR_AUX1) <
((uarts[i].regs.msr & UART_MSR_RI) >> 4))
uarts[i].regs.msr |= UART_MSR_TERI;
if ((uarts[i].regs.mcr & UART_MCR_RTS) !=
((uarts[i].regs.msr & UART_MSR_CTS) >> 3))
uarts[i].regs.msr |= UART_MSR_DCTS;
if ((uarts[i].regs.mcr & UART_MCR_DTR) !=
((uarts[i].regs.msr & UART_MSR_DSR) >> 5))
uarts[i].regs.msr |= UART_MSR_DDSR;
uarts[i].regs.msr &= ~(UART_MSR_DCD | UART_MSR_RI
| UART_MSR_DSR | UART_MSR_CTS);
uarts[i].regs.msr |= ((uarts[i].regs.mcr & UART_MCR_AUX2) << 4);
uarts[i].regs.msr |= ((uarts[i].regs.mcr & UART_MCR_AUX1) << 4);
uarts[i].regs.msr |= ((uarts[i].regs.mcr & UART_MCR_RTS) << 3);
uarts[i].regs.msr |= ((uarts[i].regs.mcr & UART_MCR_DTR) << 5);
}
/* Receive */
if (uarts[i].istat.rxser == EMPTY)
uarts[i].istat.rxser = FULL;
else if (uarts[i].char_clks == uarts[i].istat.rxser_clks++) {
debug("Receiving via UART%d...\n", i);
if (uarts[i].regs.mcr & UART_MCR_LOOP)
uarts[i].iregs.rxser = uarts[i].iregs.loopback;
else if((retval = fgetc(uarts[i].rxfs)) != EOF) {
uarts[i].iregs.rxser = (char)retval;
if (uarts[i].istat.rxbuf == FULL)
uarts[i].regs.lsr |= UART_LSR_OVRRUN;
uarts[i].regs.lsr |= UART_LSR_RDRDY;
uarts[i].regs.rxbuf = uarts[i].iregs.rxser;
uarts[i].istat.rxbuf = FULL;
}
uarts[i].istat.rxser = EMPTY;
uarts[i].istat.rxser_clks = 0;
}
/* Interrupt detection in proper priority order. */
uarts[i].regs.iir = UART_IIR_NO_INT;
if (uarts[i].regs.ier & UART_IER_RLSI &&
uarts[i].regs.lsr & (UART_LSR_OVRRUN | UART_LSR_PARITY
| UART_LSR_FRAME | UART_LSR_BREAK))
{
uarts[i].regs.iir = UART_IIR_RLSI;
}
else if (uarts[i].regs.ier & UART_IER_RDI &&
uarts[i].regs.lsr & UART_LSR_RDRDY)
{
uarts[i].regs.iir = UART_IIR_RDI;
}
else if (uarts[i].regs.ier & UART_IER_THRI &&
uarts[i].regs.lsr & UART_LSR_TXBUFE)
{
uarts[i].regs.iir = UART_IIR_THRI;
}
else if (uarts[i].regs.ier & UART_IER_MSI &&
uarts[i].regs.msr & (UART_MSR_DCTS | UART_MSR_DDSR
| UART_MSR_TERI | UART_MSR_DDCD))
{
uarts[i].regs.iir = UART_IIR_MSI;
}
if (!(uarts[i].regs.iir & UART_IIR_NO_INT))
report_interrupt(INT_UART);
/* Loopback */
if (uarts[i].regs.mcr & UART_MCR_LOOP) {
debug("uart_clock: Loopback\n");
if ((uarts[i].regs.mcr & UART_MCR_AUX2) !=
((uarts[i].regs.msr & UART_MSR_DCD) >> 4))
uarts[i].regs.msr |= UART_MSR_DDCD;
if ((uarts[i].regs.mcr & UART_MCR_AUX1) <
((uarts[i].regs.msr & UART_MSR_RI) >> 4))
uarts[i].regs.msr |= UART_MSR_TERI;
if ((uarts[i].regs.mcr & UART_MCR_RTS) !=
((uarts[i].regs.msr & UART_MSR_CTS) >> 3))
uarts[i].regs.msr |= UART_MSR_DCTS;
if ((uarts[i].regs.mcr & UART_MCR_DTR) !=
((uarts[i].regs.msr & UART_MSR_DSR) >> 5))
uarts[i].regs.msr |= UART_MSR_DDSR;
uarts[i].regs.msr &= ~(UART_MSR_DCD | UART_MSR_RI
| UART_MSR_DSR | UART_MSR_CTS);
uarts[i].regs.msr |= ((uarts[i].regs.mcr & UART_MCR_AUX2) << 4);
uarts[i].regs.msr |= ((uarts[i].regs.mcr & UART_MCR_AUX1) << 4);
uarts[i].regs.msr |= ((uarts[i].regs.mcr & UART_MCR_RTS) << 3);
uarts[i].regs.msr |= ((uarts[i].regs.mcr & UART_MCR_DTR) << 5);
}
/* Interrupt detection in proper priority order. */
uarts[i].regs.iir = UART_IIR_NO_INT;
if (uarts[i].regs.ier & UART_IER_RLSI &&
uarts[i].regs.lsr & (UART_LSR_OVRRUN | UART_LSR_PARITY
| UART_LSR_FRAME | UART_LSR_BREAK)) {
uarts[i].regs.iir = UART_IIR_RLSI;
}
else if (uarts[i].regs.ier & UART_IER_RDI &&
uarts[i].regs.lsr & UART_LSR_RDRDY) {
uarts[i].regs.iir = UART_IIR_RDI;
}
else if (uarts[i].regs.ier & UART_IER_THRI &&
uarts[i].regs.lsr & UART_LSR_TXBUFE &&
uarts[i].istat.thre_int == 1) {
uarts[i].regs.iir = UART_IIR_THRI;
}
else if (uarts[i].regs.ier & UART_IER_MSI &&
uarts[i].regs.msr & (UART_MSR_DCTS | UART_MSR_DDSR
| UART_MSR_TERI | UART_MSR_DDCD)) {
uarts[i].regs.iir = UART_IIR_MSI;
}
if (!(uarts[i].regs.iir & UART_IIR_NO_INT))
report_interrupt(INT_UART);
}
}
 
438,228 → 317,29
/* Print register values on stdout. */
void uart_status()
{
int i;
int i;
for(i = 0; i < NR_UARTS; i++) {
if (uarts[i].txfd < 0)
continue;
printf("\nUART%d visible registers at 0x%.8x:\n", i, uarts[i].baseaddr);
printf("RXBUF: %.2x TXBUF: %.2x\n", uarts[i].regs.rxbuf, uarts[i].regs.txbuf);
printf("DLL : %.2x DLH : %.2x\n", uarts[i].regs.dll, uarts[i].regs.dlh);
printf("IER : %.2x IIR : %.2x\n", uarts[i].regs.ier, uarts[i].regs.iir);
printf("LCR : %.2x MCR : %.2x\n", uarts[i].regs.lcr, uarts[i].regs.mcr);
printf("LSR : %.2x MSR : %.2x\n", uarts[i].regs.lsr, uarts[i].regs.msr);
printf("SCR : %.2x\n", uarts[i].regs.scr);
for(i = 0; i < NR_UARTS; i++) {
/* if (!uarts[i].txfs)
continue;
*/
printf("\nUART%d visible registers at 0x%.8x:\n", i, uarts[i].baseaddr);
printf("RXBUF: %.2x TXBUF: %.2x\n", uarts[i].regs.rxbuf, uarts[i].regs.txbuf);
printf("DLL : %.2x DLH : %.2x\n", uarts[i].regs.dll, uarts[i].regs.dlh);
printf("IER : %.2x IIR : %.2x\n", uarts[i].regs.ier, uarts[i].regs.iir);
printf("LCR : %.2x MCR : %.2x\n", uarts[i].regs.lcr, uarts[i].regs.mcr);
printf("LSR : %.2x MSR : %.2x\n", uarts[i].regs.lsr, uarts[i].regs.msr);
printf("SCR : %.2x\n", uarts[i].regs.scr);
 
printf("\nInternal registers (sim debug):\n");
printf("RXSER: %.2x TXSER: %.2x\n", uarts[i].iregs.rxser, uarts[i].iregs.txser);
printf("\nInternal registers (sim debug):\n");
printf("RXSER: %.2x TXSER: %.2x\n", uarts[i].iregs.rxser, uarts[i].iregs.txser);
 
printf("\nInternal status (sim debug):\n");
printf("char_clks: %d\n", uarts[i].char_clks);
printf("rxser_clks: %d txser_clks: %d\n", uarts[i].istat.rxser_clks, uarts[i].istat.txser_clks);
printf("rxser: %d txser: %d\n", uarts[i].istat.rxser, uarts[i].istat.txser);
printf("rxbuf: %d txbuf: %d\n", uarts[i].istat.rxbuf, uarts[i].istat.txbuf);
printf("\nInternal status (sim debug):\n");
printf("char_clks: %d\n", uarts[i].char_clks);
printf("rxser_clks: %d txser_clks: %d\n", uarts[i].istat.rxser_clks, uarts[i].istat.txser_clks);
printf("rxser: %d txser: %d\n", uarts[i].istat.rxser, uarts[i].istat.txser);
printf("rxbuf: %d txbuf: %d\n", uarts[i].istat.rxbuf, uarts[i].istat.txbuf);
 
printf("RX fd: %d TX fd: %d\n\n", uarts[i].rxfd, uarts[i].txfd);
}
}
 
/* Send a byte. Return 1 for OK. 0 for timeout. -1 if a
system error occurred. Asynchronous port is implied by
passing a negative number to the timeout field. In this
case, the function will return without generating an
error message if it can not send. This simulates
congestion control from the external source. */
int send_byte(int fd,int timeout,int uart_id,int byte)
{
struct timeval now;
struct timeval until;
struct pollfd set;
int msecs = 0;
unsigned char ch = byte;
 
if(gettimeofday(&now,NULL) < 0)
{
now.tv_sec = time(NULL);
now.tv_usec = 0;
}
 
until.tv_sec = now.tv_sec;
if(timeout > 0)
until.tv_usec = now.tv_usec + timeout*1000;
else
until.tv_usec = now.tv_usec;
 
if(until.tv_usec > 999999)
{
until.tv_sec++;
until.tv_usec -= 1000000;
}
msecs = timeout > 0 ? timeout : 0;
set.fd = fd;
set.events = POLLOUT;
set.revents = 0;
 
while(msecs >= 0)
{
char sTemp[256];
 
switch(poll(&set,1,msecs))
{
case 1: /* We're good, or we got an error */
switch(write(fd,&ch,1))
{
case -1:
sprintf(sTemp,"UART %d TX - write",uart_id);
perror(sTemp);
fflush(stderr);
return -1;
case 0:
fprintf(stderr,"UART %d TX EOF detected. Shutting down"
" to prevent endless loop.\n",uart_id);
fflush(stderr);
if(uarts[uart_id].txfd >= 0)
close(uarts[uart_id].txfd);
if(uarts[uart_id].rxfd >= 0)
close(uarts[uart_id].rxfd);
uarts[uart_id].txfd = uarts[uart_id].rxfd = -1;
return 0;
case 1:
return 1;
}
case 0: /* We timed out. Stop the loop. */
msecs = -1;
break;
case -1:
if(errno == EINTR)
{
if(gettimeofday(&now,NULL) < 0)
{
now.tv_sec = time(NULL);
now.tv_usec = 0;
}
msecs = (until.tv_sec - now.tv_sec)*1000 +
until.tv_usec - now.tv_usec;
continue;
}
else
{
char sTemp[256];
 
sprintf(sTemp,"UART %d TX - poll",uart_id);
perror(sTemp);
fflush(stderr);
return -1;
}
printf("RX fs: %p TX fs: %p\n\n", uarts[i].rxfs, uarts[i].txfs);
}
}
 
if(timeout >= 0)
{
fprintf(stderr,"Transmit timeout occurred on UART %d. Data "
"may be corrupt.\n",uart_id);
fflush(stderr);
}
return 0;
}
 
/* Receive a byte. Return 1 for OK. 0 for timeout. -1 if a
system error occurred. Asynchronous port is implied by
passing a negative number to the timeout field. In this
case, the function will return without generating an
error message. */
int receive_byte(int fd,int timeout,int uart_id,unsigned char* byte)
{
struct timeval now;
struct timeval until;
struct pollfd set;
int msecs = 0;
if(gettimeofday(&now,NULL) < 0)
{
now.tv_sec = time(NULL);
now.tv_usec = 0;
}
 
until.tv_sec = now.tv_sec;
if(timeout > 0)
until.tv_usec = now.tv_usec + timeout*1000;
else
until.tv_usec = now.tv_usec;
 
if(until.tv_usec > 999999)
{
until.tv_sec++;
until.tv_usec -= 1000000;
}
msecs = timeout > 0 ? timeout : 0;
set.fd = fd;
set.events = POLLIN;
set.revents = 0;
 
while(msecs >= 0)
{
char sTemp[256];
 
switch(poll(&set,1,msecs))
{
case 1: /* We're good, or we got an error */
switch(read(fd,byte,1))
{
case -1:
sprintf(sTemp,"UART %d RX - read",uart_id);
perror(sTemp);
fflush(stderr);
return -1;
case 0:
fprintf(stderr,"UART %d RX EOF detected. Shutting down"
" to prevent endless loop.\n",uart_id);
fflush(stderr);
if(uarts[uart_id].txfd >= 0)
close(uarts[uart_id].txfd);
if(uarts[uart_id].rxfd >= 0)
close(uarts[uart_id].rxfd);
uarts[uart_id].txfd = uarts[uart_id].rxfd = -1;
return 0;
case 1:
return 1;
}
case 0: /* We timed out. Stop the loop. */
*byte = 0xFF;
msecs = -1;
break;
case -1:
if(errno == EINTR)
{
if(gettimeofday(&now,NULL) < 0)
{
now.tv_sec = time(NULL);
now.tv_usec = 0;
}
msecs = (until.tv_sec - now.tv_sec)*1000 +
until.tv_usec - now.tv_usec;
continue;
}
else
{
char sTemp[256];
 
sprintf(sTemp,"UART %d RX - poll",uart_id);
perror(sTemp);
fflush(stderr);
return -1;
}
}
}
 
if(timeout >= 0)
{
fprintf(stderr,"Receive timeout occurred on UART %d. Data "
"may be corrupt.\n",uart_id);
fflush(stderr);
}
return 0;
}
/trunk/or1ksim/peripheral/Makefile.in
106,7 → 106,7
host_os = @host_os@
 
noinst_LIBRARIES = libperipheral.a
libperipheral_a_SOURCES = 16450.c debug_unit.c dma.c
libperipheral_a_SOURCES = 16450.c dma.c
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../config.h
CONFIG_CLEAN_FILES =
118,7 → 118,7
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libperipheral_a_LIBADD =
libperipheral_a_OBJECTS = 16450.o debug_unit.o dma.o
libperipheral_a_OBJECTS = 16450.o dma.o
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
129,7 → 129,7
 
TAR = gtar
GZIP_ENV = --best
DEP_FILES = .deps/16450.P .deps/debug_unit.P .deps/dma.P
DEP_FILES = .deps/16450.P .deps/dma.P
SOURCES = $(libperipheral_a_SOURCES)
OBJECTS = $(libperipheral_a_OBJECTS)
 
216,7 → 216,7
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$/$$file $(distdir)/$$file; \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
/trunk/or1ksim/peripheral/16450.h
18,8 → 18,8
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
/* Prototypes */
void uart_write(unsigned long addr, unsigned int value);
unsigned int uart_read(unsigned long addr);
void uart_write(unsigned long addr, unsigned long value);
unsigned long uart_read(unsigned long addr);
void uart_reset();
void uart_clock();
 
49,12 → 49,13
unsigned char rxser;
unsigned char txbuf;
unsigned char rxbuf;
unsigned char thre_int;
unsigned long txser_clks;
unsigned long rxser_clks;
} istat; /* Internal status */
unsigned long char_clks;
int rxfd; /* Changed by CZ for non blocking I/O */
int txfd; /* Changed by CZ for non blocking I/O */
FILE * rxfs;
FILE * txfs;
unsigned long baseaddr;
};
 
/trunk/or1ksim/peripheral/Makefile.am
19,4 → 19,4
#
 
noinst_LIBRARIES = libperipheral.a
libperipheral_a_SOURCES = 16450.c debug_unit.c dma.c
libperipheral_a_SOURCES = 16450.c dma.c
/trunk/or1ksim/mmu/Makefile.in
89,6 → 89,7
CC = @CC@
CFLAGS = @CFLAGS@
CPU_ARCH = @CPU_ARCH@
FPM = @FPM@
INCLUDES = @INCLUDES@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
LOCAL_DEFS = @LOCAL_DEFS@
/trunk/or1ksim/config.h.in
19,13 → 19,8
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
#undef STAT_MACROS_BROKEN
 
/* Some shared files require to know, whether we have
execution functions defined. */
#define HAS_EXECUTION
 
/* Whether the compiler supports 'long long'. */
#define CC_HAS_LONG_LONG
 
/* Define if you have the lstat function. */
#undef HAVE_LSTAT
 
/trunk/or1ksim/bpb/Makefile.in
89,6 → 89,7
CC = @CC@
CFLAGS = @CFLAGS@
CPU_ARCH = @CPU_ARCH@
FPM = @FPM@
INCLUDES = @INCLUDES@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
LOCAL_DEFS = @LOCAL_DEFS@
/trunk/or1ksim/Makefile.am
4,7 → 4,7
#
#
 
SUBDIRS = cpu bpb support cache mmu peripheral tick pm pic
SUBDIRS = cpu bpb support cache mmu peripheral tick pm pic debug
 
noinst_PROGRAMS = sim
EXTRA_PROGRAMS = profiler
13,6 → 13,6
sim_LDADD = cpu/common/libcommon.a cpu/$(CPU_ARCH)/libarch.a \
cpu/or1k/libor1k.a support/libsupport.a mmu/libmmu.a \
bpb/libbpb.a cache/libcache.a peripheral/libperipheral.a \
tick/libtick.a pm/libpm.a pic/libpic.a
tick/libtick.a pm/libpm.a pic/libpic.a debug/libdebug.a
sim_LDFLAGS = #-lreadline
profiler_SOURCES = profiler.c
/trunk/or1ksim/toplevel.c
78,10 → 78,6
void BlockJTAG(void);
 
#ifndef DEBUGMOD_OFF
int NewStyleExceptions = 1; /* Start off with the new style exception handlers */
/* This means GDB will expect the PC at 0xD00 when a
a breakpoint occurs, and will intercept AFTER the
exception vector is taken. */
int GlobalMode = 0; /* Start off in the orginal mode */
#else /* no DEBUGMOD_OFF */
#define GlobalMode 0
88,7 → 84,7
#endif /* no DEBUGMOD_OFF */
 
/* CVS revision number. */
const char rcsrev[] = "$Revision: 1.25 $";
const char rcsrev[] = "$Revision: 1.26 $";
 
/* Continuos run versus single step tracing switch. */
int cont_run;
239,13 → 235,11
unsigned long endaddr = 0xFFFFFFFF;
int first_prompt = 1;
int trace_fd = 0;
unsigned char trace_reg[32];
 
memset(trace_reg,'\0',sizeof(trace_reg));
srand(getpid());
init_defconfig();
if (parse_args(argc, argv)) {
printf("Usage: %s [options] <filename>\n", argv[0]);
printf("Usage: %s [options] <filename>\n", argv[0]);
printf("Options:\n");
printf(" -v: version and copyright note\n");
printf(" -i: enable interactive command prompt\n");
277,7 → 271,7
{
serverPort = config.server_port;
if(server_fd = GetServerSocket("or1ksim","tcp",serverPort))
printf("JTAG Proxy server started on port %d\n",serverPort);
printf("JTAG Proxy server started on port %d\n",serverPort);
}
 
if(config.profile) {
288,7 → 282,11
} else
fprintf(config.fprof, "+00000000 FFFFFFFF FFFFFFFF main\n");
}
 
/* Initialize memory table. */
sim_read_memory_table ("sim_memory_table");
print_config();
signal(SIGINT, ctrl_c);
initstats();
304,58 → 302,47
someone will attach to us over the JTAG Proxy interface
and begin debugging that way. */
 
if(config.filename)
{
endaddr = loadcode(config.filename, MEMORY_START, 0);
if (endaddr == -1) {
printf("Problems loading boot code.\n");
exit(1);
}
if(config.filename) {
endaddr = loadcode(config.filename, 0, 0); /* MM170901 always load at address zero. */
if (endaddr == -1) {
printf("Problems loading boot code.\n");
exit(1);
}
else
{
if(config.random_mem)
{
int n = 0;
int len = sizeof(mem);
unsigned int* mptr = (unsigned int*)mem;
unsigned int val = 0;
int seed = time(NULL);
} else {
extern struct dev_memarea *dev_list;
int i;
if(config.random_mem) {
unsigned int val = 0;
int seed = time(NULL);
 
srandom(seed);
/* Print out the seed just in case we ever need to debug */
printf("Seeding random generator with value %d\n",seed);
srandom(seed);
/* Print out the seed just in case we ever need to debug */
printf("Seeding random generator with value %d\n",seed);
for(n=0;n<len;n+=sizeof(unsigned int))
{
val = random();
if(random() > RAND_MAX/2)
val |= 0x80000000;
*mptr++ = val;
}
}
else if(config.pattern_mem)
{
int n = 0;
int len = sizeof(mem);
unsigned int* mptr = (unsigned int*)mem;
for(n=0;n<len;n+=sizeof(unsigned int))
*mptr++ = config.pattern_mem;
}
else
memset(mem,0,sizeof(mem));
if(config.memory)
{
MemoryBlock* block = config.memory;
for (cur_area = dev_list; cur_area; cur_area = cur_area->next)
for(i = 0; i < cur_area->size; i++) {
val = random();
if(random() > RAND_MAX/2)
val |= 0x80000000;
cur_area->writefunc(i + cur_area->start, val);
}
} else if(config.pattern_mem) {
for (cur_area = dev_list; cur_area; cur_area = cur_area->next)
for(i = 0; i < cur_area->size; i++)
cur_area->writefunc(i + cur_area->start, config.pattern_mem);
} else {
for (cur_area = dev_list; cur_area; cur_area = cur_area->next)
for(i = 0; i < cur_area->size; i++)
cur_area->writefunc(i + cur_area->start, 0);
}
if(config.memory) {
MemoryBlock* block = config.memory;
 
while(block)
{
while(block) {
int fd = open(block->file,O_RDONLY);
int len,i;
struct stat buf;
char *mptr = (char*)mem;
int len, i, j, mptr = 0;
struct stat buf;
char buffer[8192];
 
if(fd < 0)
370,7 → 357,7
sprintf(sTemp,"stat(\"%s\")",block->file);
perror(sTemp);
exit(1);
}
}
if(!S_ISREG(buf.st_mode))
{
fprintf(stderr,"File \"%s\" is not a regular file.\n",
396,7 → 383,8
block->file);
exit(1);
default:
memcpy(mptr,buffer,n);
for (j = 0; j < n; j++)
setsim_mem8(mptr++,buffer[j]);
i+= n;
break;
}
405,6 → 393,7
}
}
}
#ifndef DEBUGMOD_OFF
GlobalMode = config.filename == NULL; /* Old mode = 0, New mode = 1 */
#endif
413,8 → 402,7
dma_reset();
tick_reset();
pm_reset();
pic_reset();
mtspr(2,0x20); /* We are emulating a 32 bit processor/no FP */
pic_reset();
reset();
if(!GlobalMode) /* Only in old mode */
set_reg32(3, endaddr);
635,16 → 623,12
} else
if (!strcmp(item1, "trace")) { /* Added by CZ 210801 */
char item2[256];
char item3[256];
char *s,*q;
 
strtoken(linestr, item2, 2);
strtoken(linestr, item3, 3);
if(trace_fd)
{
close(trace_fd);
trace_fd = 0;
memset(trace_reg,'\0',sizeof(trace_reg));
}
if(strcmp(item2,"off")) /* if we're not being turned off */
{
659,21 → 643,6
trace_fd = 0;
}
}
if(!trace_fd && strlen(item3))
printf("Syntax error on trace: \"%s\" unexpected\n",item3);
else
for(s = item3;s && *s; s = q)
{
if(q = strchr(s,','))
*q++ = '\0';
if(strlen(s) < 4 && (s[0] == 'r' || s[0] == 'R') &&
isdigit(s[1]) && (isdigit(s[2]) || !s[2]))
trace_reg[atoi(&s[1])] = 1;
else
printf("Syntax error in format: \"%s\" not a valid register\n",s);
}
} else
if (strcmp(item1, "stats") == 0) { /* stats */
char item2[20];
697,7 → 666,7
dc_info();
uart_status();
sprs_status();
dma_status();
dma_status();
} else {
printf("%s: Unknown command.\n", linestr);
}
733,37 → 702,28
{
char sTemp[256];
char sTemp2[256];
char reg_value[16];
unsigned long value;
int first_register = 1;
int i;
extern char *disassembled;
extern unsigned long reg[];
 
value = (mem[0x0c].data << 24) +
(mem[0x0d].data << 16) +
(mem[0x0e].data << 8)
+ mem[0x0f].data;
/* The objects passed to the
trace command should not be
hardcoded like this...instead
what to dump should be passed
on the command line.
 
#if 0
FIX THIS LATER...
*/
value = (evalsim_mem8(0x306bc) << 24) +
(evalsim_mem8(0x306bd) << 16) +
(evalsim_mem8(0x306be) << 8)
+ evalsim_mem8(0x306bf);
 
sprintf(sTemp,"0x%06x: %s",addr,disassembled);
memset(sTemp2,' ',80);
memset(sTemp2,' ',sizeof(sTemp2));
strncpy(sTemp2,sTemp,strlen(sTemp));
sTemp[0] = '\0';
sTemp2[78] = '\0';
for(i=0;i<32;i++)
if(trace_reg[i])
{
sprintf(reg_value,"%c0x%08x",first_register?'<':',',
reg[i]);
strcat(sTemp,reg_value);
first_register = 0;
}
if(!first_register)
sprintf(&sTemp2[40],"%s>\n",sTemp);
#endif
sprintf(sTemp2,"0x%06x: %s <0x%08x>\n",addr,disassembled,value);
sprintf(&sTemp2[40],"<0x%08x,0x%08x> [0x%08x]\n",
reg[3],reg[4],value);
write(trace_fd,sTemp2,strlen(sTemp2));
}
update_pc();
912,20 → 872,16
int i;
printf("starting to dump mem...\n");
for(i=0; i<500; i++) {
struct mem_entry *entry;
unsigned int _insn;
printf("i=%x :: ", i);
if (mem[i].label)
printf("label: %s |", mem[i].label->name);
{
unsigned int _insn;
_insn = ((unsigned long)mem[i].data << 24);
_insn |= ((unsigned long)mem[i + 1].data << 16);
_insn |= ((unsigned long)mem[i + 2].data << 8);
_insn |= ((unsigned long)mem[i + 3].data);
iqueue[0].insn_index = insn_decode(_insn);
iqueue[0].insn = _insn;
disassemble_insn (_insn);
printf("%s\n", disassembled);
}
if (verify_memoryarea(i) && cur_area->getentry && (entry = cur_area->getentry(i)) && entry->label)
printf("label: %s |", entry->label->name);
iqueue[0].insn = _insn = evalsim_mem32(i);
iqueue[0].insn_index = insn_decode(_insn);
disassemble_insn (_insn);
printf("%08x %s\n", _insn, disassembled);
}
}
 
1334,7 → 1290,7
msg_bwrite->nRegisters = ntohl(msg_bwrite->nRegisters);
for(i=0;i<msg_bwrite->nRegisters;i++)
{
int t_err;
int t_err = 0;
 
msg_bwrite->data[i] = ntohl(msg_bwrite->data[i]);
t_err = DebugSetRegister(msg_bwrite->address+i,msg_bwrite->data[i]);
1404,7 → 1360,7
}
free(buf);
buf = NULL;
buf = NULL;
resp_bread = NULL;
break;
case JTAG_COMMAND_CHAIN:
if(length != sizeof(msg_chain) - 8)
/trunk/or1ksim/support/Makefile.in
89,6 → 89,7
CC = @CC@
CFLAGS = @CFLAGS@
CPU_ARCH = @CPU_ARCH@
FPM = @FPM@
INCLUDES = @INCLUDES@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
LOCAL_DEFS = @LOCAL_DEFS@
/trunk/or1ksim/support/dumpverilog.c
38,7 → 38,6
#include "dumpverilog.h"
#include "opcode/or32.h"
 
extern struct mem_entry mem[MEMORY_LEN];
extern char rcsrev[];
extern char *disassembled;
 
46,25 → 45,24
{
unsigned int i, done = 0;
struct label_entry *tmp;
char dis[DISWIDTH + 100];
int breakpoint = 0;
printf("// This file was generated by or1ksim %s\n", rcsrev);
char dis[DISWIDTH + 100];
struct mem_entry *entry;
printf("// This file was generated by or1ksim %s\n", rcsrev);
printf(OR1K_MEM_VERILOG_HEADER(verilog_modname, from/DWQ, to/DWQ, (DISWIDTH*8)));
for(i = from; i < to && i < (MEMORY_START + MEMORY_LEN); i++)
{
int bp;
unsigned int _insn = evalsim_mem32 (i, &bp);
for(i = from; i < to; i++)
{
unsigned int _insn = evalsim_mem32 (i);
int index = insn_decode(_insn);
if (index >= 0)
{
tmp = mem[i].label;
{
if (verify_memoryarea(i) && cur_area->getentry && (entry = cur_area->getentry(i)))
tmp = entry->label;
for(; tmp; tmp = tmp->next)
printf("\n//\t%s%s", tmp->name, LABELEND_CHAR);
printf("\n\tmem['h%x] = %d'h%.2x%.2x", i/DWQ, DW, mem[i].data, mem[i+1].data);
printf("%.2x%.2x;", mem[i+2].data, mem[i+3].data);
printf("\n\tmem['h%x] = %d'h%.2x%.2x", i/DWQ, DW, evalsim_mem8(i), evalsim_mem8(i + 1));
printf("%.2x%.2x;", evalsim_mem8(i + 2), evalsim_mem8(i + 3));
disassemble_insn (_insn);
strcpy (dis, disassembled);
75,13 → 73,11
printf("\n\tdis['h%x] = {\"%s\"};", i/DWQ, dis);
dis[0] = '\0';
i += insn_len(index) - 1;
}
else
{
} else {
if (i % 64 == 0)
printf("\n");
printf("\n\tmem['h%x] = 'h%.2x;", i/DWQ, (unsigned char)mem[i].data);
printf("\n\tmem['h%x] = 'h%.2x;", i/DWQ, evalsim_mem8(i));
}
done = 1;
}
100,10 → 96,10
printf("\n%.8x: ", i);
/* don't print ascii chars below 0x20. */
if (evalsim_mem32(i,&breakpoint) < 0x20)
printf("0x%.2x ", (unsigned char)evalsim_mem32(i,&breakpoint));
if (evalsim_mem32(i) < 0x20)
printf("0x%.2x ", (unsigned char)evalsim_mem32(i));
else
printf("0x%.2x'%c' ", (unsigned char)evalsim_mem32(i,&breakpoint), (unsigned char)evalsim_mem32(i,&breakpoint));
printf("0x%.2x'%c' ", (unsigned char)evalsim_mem32(i), (unsigned char)evalsim_mem32(i));
}
printf(OR1K_MEM_VERILOG_FOOTER);
}
111,18 → 107,18
void dumphex(unsigned int from, unsigned int to)
{
unsigned int i, done = 0;
int breakpoint = 0;
for(i = from; i < to && i < (MEMORY_START + MEMORY_LEN); i++) {
unsigned int _insn = evalsim_mem32 (i, &breakpoint);
for(i = from; i < to; i++) {
unsigned int _insn = evalsim_mem32 (i);
int index = insn_decode(_insn);
if (index >= 0)
{
printf("%.2x%.2x", mem[i].data, mem[i+1].data);
printf("%.2x%.2x\n", mem[i+2].data, mem[i+3].data);
i += insn_len(index) - 1;
{
printf("%.2x%.2x", evalsim_mem8(i), evalsim_mem8(i + 1));
printf("%.2x%.2x\n", evalsim_mem8(i + 2), evalsim_mem8(i + 3));
i += insn_len(index) - 1;
}
else
printf("%.2x\n", (unsigned char)mem[i].data);
printf("%.2x\n", evalsim_mem8(i));
}
}
/trunk/or1ksim/sim-config.c
40,9 → 40,7
config.uarts[0].txfile = "/tmp/uart0.tx";
config.uarts[0].baseaddr = 0x80000000;
config.uarts[0].jitter = -1; /* Async behavior */
config.dmas[0].baseaddr = 0x90000000;
config.ram.startaddr = MEMORY_START;
config.ram.endaddr = MEMORY_START + MEMORY_LEN;
config.dmas[0].baseaddr = 0x90000000;
config.simdebug = 0;
config.profile = 0;
config.iprompt = 0;
54,13 → 52,6
config.profile = 0;
 
mtspr(SPR_VR, SPR_VR_VER & 0x1200);
mtspr(SPR_CPUCFGR, SPR_CPUCFGR_OB32S);
mtspr(SPR_DMMUCFGR, (0 << 5) | (7 << 2) | (1 << 0));
mtspr(SPR_IMMUCFGR, (0 << 5) | (7 << 2) | (1 << 0));
mtspr(SPR_DCCFGR, (0 << 5) | (7 << 2) | (1 << 0));
mtspr(SPR_ICCFGR, (0 << 5) | (7 << 2) | (1 << 0));
mtspr(SPR_DCFGR, SPR_DCFGR_WPCI);
mtspr(SPR_PCCFGR, 1);
 
val = SPR_UPR_UP | SPR_UPR_DCP | SPR_UPR_ICP | SPR_UPR_DMP |
SPR_UPR_IMP | SPR_UPR_OB32P | SPR_UPR_DUP | SPR_UPR_PICP |
226,9 → 217,9
else
printf("BTIC simulation off.\n");
printf("Clock cycle: %d ns\n", config.clkcycle_ns);
printf("RAM: 0x%x to ", config.ram.startaddr);
printf("0x%x (", config.ram.endaddr);
printf("%d KB)\n\n", (config.ram.endaddr - config.ram.startaddr) / 1024);
/*printf("RAM: 0x%x to 0x%x (%d KB)\n\n", config.ram.startaddr, config.ram.endaddr);
(config.ram.endaddr - config.ram.startaddr) / 1024); MM170901 different memory scheme. */
if (config.simdebug)
printf("simdebug on, ");
else

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.