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

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/tags/or1ksim/or1ksim-0.4.0rc2/cpu/common
    from Rev 124 to Rev 128
    Reverse comparison

Rev 124 → Rev 128

/execute.h
0,0 → 1,107
/* execute.h -- Header file for architecture dependent execute.c
 
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
Copyright (C) 2008 Embecosm Limited
 
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
 
This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.
 
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
 
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>. */
 
/* This program is commented throughout in a fashion suitable for processing
with Doxygen. */
 
 
#ifndef EXECUTE__H
#define EXECUTE__H
 
#include "spr-defs.h"
#include "opcode/or32.h"
#include "abstract.h"
 
#if DYNAMIC_EXECUTION
#include "setjmp.h"
#include "dyn-rec.h"
#endif
 
 
#define CURINSN(INSN) (strcmp(cur->insn, (INSN)) == 0)
 
/*!The main structure holding the current execution state of the CPU
 
Not to be confused with @c runtime, which holds the state of the
simulation.
 
@c insn_ea field is only used to get dump_exe_log() correct.
 
@c iqueue and @c icomplet fields are only used in analysis().
 
The micro-operation queue, @c opqs, is only used to speed up
recompile_page(). */
struct cpu_state {
uorreg_t reg[MAX_GPRS]; /*!< General purpose registers */
uorreg_t sprs[MAX_SPRS]; /*!< Special purpose registers */
oraddr_t insn_ea; /*!< EA of instrs that have an EA */
int delay_insn; /*!< Is current instr in delay slot */
int npc_not_valid; /*!< NPC updated while stalled */
oraddr_t pc; /*!< PC (and translated PC) */
oraddr_t pc_delay; /*!< Delay instr EA register */
uint32_t pic_lines; /*!< State of PIC lines */
struct iqueue_entry iqueue; /*!< Decode of just executed instr */
struct iqueue_entry icomplet; /*!< Decode of instr before this */
 
#if DYNAMIC_EXECUTION
jmp_buf excpt_loc; /*!< Longjump here for exception */
struct dyn_page *curr_page; /*!< Current page in execution */
struct dyn_page **dyn_pages; /*!< Pointers to recompiled pages */
int32_t cycles_dec;
struct op_queue *opqs; /*!< Micro-operation queue */
#endif
};
 
/*! History of execution */
struct hist_exec
{
oraddr_t addr;
struct hist_exec *prev;
struct hist_exec *next;
};
 
/* Globally visible data structures */
extern struct cpu_state cpu_state;
extern oraddr_t pcnext;
extern int sbuf_wait_cyc;
extern int sbuf_total_cyc;
extern int do_stats;
extern struct hist_exec *hist_exec_tail;
 
 
/* Prototypes for external use */
extern void dumpreg ();
extern void dump_exe_log ();
extern int cpu_clock ();
extern void cpu_reset ();
extern uorreg_t evalsim_reg (unsigned int regno);
extern void setsim_reg (unsigned int regno,
uorreg_t value);
extern uorreg_t eval_operand_val (uint32_t insn,
struct insn_op_struct *opd);
extern void analysis (struct iqueue_entry *current);
extern void cpu_reset ();
extern int cpu_clock ();
extern void exec_main ();
extern int depend_operands (struct iqueue_entry *prev,
struct iqueue_entry *next);
#endif /* EXECUTE__H */
execute.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: Makefile.in =================================================================== --- Makefile.in (nonexistent) +++ Makefile.in (revision 128) @@ -0,0 +1,527 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Makefile -- Makefile for cpu architecture independent simulation +# +# Copyright (C) 1999 Damjan Lampret, lampret@opencores.org +# Copyright (C) 2008 Embecosm Limited +# +# Contributor Jeremy Bennett +# +# 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 3 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = cpu/common +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libcommon_la_LIBADD = +am_libcommon_la_OBJECTS = abstract.lo parse.lo stats.lo trace.lo \ + labels.lo +libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libcommon_la_SOURCES) +DIST_SOURCES = $(libcommon_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ARFLAGS = @ARFLAGS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_DIR = @BUILD_DIR@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPU_ARCH = @CPU_ARCH@ +CYGPATH_W = @CYGPATH_W@ +DEBUGFLAGS = @DEBUGFLAGS@ +DEFS = @DEFS@ +DEJAGNU = @DEJAGNU@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INCLUDES = @INCLUDES@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOCAL_CFLAGS = @LOCAL_CFLAGS@ +LOCAL_DEFS = @LOCAL_DEFS@ +LOCAL_LDFLAGS = @LOCAL_LDFLAGS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POW_LIB = @POW_LIB@ +RANLIB = @RANLIB@ +RUNTESTDEFAULTFLAGS = @RUNTESTDEFAULTFLAGS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SUMVERSION = @SUMVERSION@ +TERMCAP_LIB = @TERMCAP_LIB@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = libcommon.la +libcommon_la_SOURCES = abstract.c \ + parse.c \ + stats.c \ + trace.c \ + labels.c \ + abstract.h \ + coff.h \ + elf.h \ + execute.h \ + labels.h \ + parse.h \ + stats.h \ + trace.h + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cpu/common/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu cpu/common/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libcommon.la: $(libcommon_la_OBJECTS) $(libcommon_la_DEPENDENCIES) + $(LINK) $(libcommon_la_OBJECTS) $(libcommon_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/abstract.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/labels.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stats.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: Index: labels.c =================================================================== --- labels.c (nonexistent) +++ labels.c (revision 128) @@ -0,0 +1,187 @@ +/* labels.c -- Abstract entities, handling labels + + Copyright (C) 2001 Marko Mlinar, markom@opencores.org + Copyright (C) 2008 Embecosm Limited + + Contributor Jeremy Bennett + + This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see . */ + +/* This program is commented throughout in a fashion suitable for processing + with Doxygen. */ + +/* Abstract memory and routines that go with this. I need to add all sorts of + other abstract entities. Currently we have only memory. */ + + +/* Autoconf and/or portability configuration */ +#include "config.h" +#include "port.h" + +/* System includes */ +#include + +/* Package includes */ +#include "labels.h" + +#define LABELS_HASH_SIZE 119 + +/* Globally visible list of breakpoints */ +struct breakpoint_entry *breakpoints; + +/* Local list of labels (symbols) */ +static struct label_entry *label_hash[LABELS_HASH_SIZE]; + + +void +init_labels () +{ + int i; + for (i = 0; i < LABELS_HASH_SIZE; i++) + label_hash[i] = NULL; +} + +void +add_label (oraddr_t addr, char *name) +{ + struct label_entry **tmp; + tmp = &(label_hash[addr % LABELS_HASH_SIZE]); + for (; *tmp; tmp = &((*tmp)->next)); // Find the next NULL label entry pointer (loop while the pointer de-refernce is non-NULL) + *tmp = malloc (sizeof (**tmp)); // allocate space for the pointer to the hash entry pointer + (*tmp)->name = malloc (strlen (name) + 1); // now allocate space for the name string + (*tmp)->addr = addr; + strcpy ((*tmp)->name, name); + (*tmp)->next = NULL; +} + +struct label_entry * +get_label (oraddr_t addr) +{ + struct label_entry *tmp = label_hash[addr % LABELS_HASH_SIZE]; + while (tmp) + { + if (tmp->addr == addr) + return tmp; + tmp = tmp->next; + } + return NULL; +} + +struct label_entry * +find_label (char *name) +{ + int i; + for (i = 0; i < LABELS_HASH_SIZE; i++) + { + struct label_entry *tmp = label_hash[i % LABELS_HASH_SIZE]; + while (tmp) + { + if (strcmp (tmp->name, name) == 0) + return tmp; + tmp = tmp->next; + } + } + return NULL; +} + +/* Searches mem array for a particular label and returns label's address. + If label does not exist, returns 0. */ +oraddr_t +eval_label (char *name) +{ + struct label_entry *le; + char *plus; + char *minus; + int positive_offset = 0; + int negative_offset = 0; + + if ((plus = strchr (name, '+'))) + { + *plus = '\0'; + positive_offset = atoi (++plus); + } + + if ((minus = strchr (name, '-'))) + { + *minus = '\0'; + negative_offset = atoi (++minus); + } + le = find_label (name); + if (!le) + return 0; + + return le->addr + positive_offset - negative_offset; +} + +void +init_breakpoints () +{ + breakpoints = 0; +} + +void +add_breakpoint (oraddr_t addr) +{ + struct breakpoint_entry *tmp; + tmp = (struct breakpoint_entry *) malloc (sizeof (struct breakpoint_entry)); + tmp->next = breakpoints; + tmp->addr = addr; + breakpoints = tmp; +} + +void +remove_breakpoint (oraddr_t addr) +{ + struct breakpoint_entry **tmp = &breakpoints; + while (*tmp) + { + if ((*tmp)->addr == addr) + { + struct breakpoint_entry *t = *tmp; + (*tmp) = t->next; + free (t); + } + else + tmp = &((*tmp)->next); + } +} + +void +print_breakpoints () +{ + struct breakpoint_entry **tmp = &breakpoints; + int i = 1; + printf ("---[breakpoints]------------------\n"); + while (*tmp) + { + printf ("Breakpoint %i at 0x%" PRIxADDR "\n", i, (*tmp)->addr); + tmp = &((*tmp)->next); + } + printf ("---[breakpoints end]--------------\n"); +} + +int +has_breakpoint (oraddr_t addr) +{ + struct breakpoint_entry *tmp = breakpoints; + while (tmp) + { + if (tmp->addr == addr) + return 1; + tmp = tmp->next; + } + return 0; +}
labels.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: abstract.c =================================================================== --- abstract.c (nonexistent) +++ abstract.c (revision 128) @@ -0,0 +1,1260 @@ +/* abstract.c -- Abstract entities + + Copyright (C) 1999 Damjan Lampret, lampret@opencores.org + Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org + Copyright (C) 2008 Embecosm Limited + + Contributor Jeremy Bennett + + 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 3 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see . */ + +/* This program is commented throughout in a fashion suitable for processing + with Doxygen. */ + +/* Abstract memory and routines that go with this. I need to add all sorts of + other abstract entities. Currently we have only memory. */ + + +/* Autoconf and/or portability configuration */ +#include "config.h" +#include "port.h" + +/* System includes */ +#include + +/* Package includes */ +#include "abstract.h" +#include "except.h" +#include "support/profile.h" +#include "debug-unit.h" +#include "icache-model.h" +#include "dcache-model.h" +#include "labels.h" +#include "opcode/or32.h" +#include "dmmu.h" +#include "immu.h" + +#if DYNAMIC_EXECUTION +#include "dyn-rec.h" +#endif + + +/*! Global temporary variable to increase speed. */ +struct dev_memarea *cur_area; + +/* Glboal variables set by MMU if cache inhibit bit is set for current + access. */ +int data_ci; /*!< Global var: data cache inhibit bit set */ +int insn_ci; /*!< Global var: instr cache inhibit bit set */ + +/* Pointer to memory area descriptions that are assigned to individual + peripheral devices. */ +static struct dev_memarea *dev_list; + +/* Pointer to memory controller device descriptor. */ +static struct dev_memarea *mc_area = NULL; + +/* Virtual address of current access. */ +static oraddr_t cur_vadd; + +/* Forward declarations */ +static uint32_t eval_mem_32_inv (oraddr_t, void *); +static uint16_t eval_mem_16_inv (oraddr_t, void *); +static uint8_t eval_mem_8_inv (oraddr_t, void *); +static uint32_t eval_mem_32_inv_direct (oraddr_t, void *); +static uint16_t eval_mem_16_inv_direct (oraddr_t, void *); +static uint8_t eval_mem_8_inv_direct (oraddr_t, void *); +static void set_mem_32_inv (oraddr_t, uint32_t, void *); +static void set_mem_16_inv (oraddr_t, uint16_t, void *); +static void set_mem_8_inv (oraddr_t, uint8_t, void *); +static void set_mem_32_inv_direct (oraddr_t, uint32_t, void *); +static void set_mem_16_inv_direct (oraddr_t, uint16_t, void *); +static void set_mem_8_inv_direct (oraddr_t, uint8_t, void *); + +/* Calculates bit mask to fit the data */ +static unsigned int +bit_mask (uint32_t data) +{ + int i = 0; + data--; + while (data >> i) + data |= 1 << i++; + return data; +} + +/* Register read and write function for a memory area. + addr is inside the area, if addr & addr_mask == addr_compare + (used also by peripheral devices like 16450 UART etc.) */ +static struct dev_memarea * +register_memoryarea_mask (oraddr_t addr_mask, + oraddr_t addr_compare, + uint32_t size, unsigned mc_dev) +{ + struct dev_memarea **pptmp; + unsigned int size_mask = bit_mask (size); + int found_error = 0; + addr_compare &= addr_mask; + + /* Go to the end of the list. */ + for (pptmp = &dev_list; *pptmp; pptmp = &(*pptmp)->next) + if (((addr_compare >= (*pptmp)->addr_compare) && + (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)) || + ((addr_compare + size > (*pptmp)->addr_compare) && + (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size))) + { + if (!found_error) + { + fprintf (stderr, "ERROR: Overlapping memory area(s):\n"); + fprintf (stderr, + "\taddr & %" PRIxADDR " == %" PRIxADDR " to %" PRIxADDR + ", size %08" PRIx32 "\n", addr_mask, addr_compare, + addr_compare | bit_mask (size), size); + } + found_error = 1; + fprintf (stderr, + "and\taddr & %" PRIxADDR " == %" PRIxADDR " to %" PRIxADDR + ", size %08" PRIx32 "\n", (*pptmp)->addr_mask, + (*pptmp)->addr_compare, + (*pptmp)->addr_compare | (*pptmp)->size_mask, + (*pptmp)->size); + } + + if (found_error) + exit (-1); + + cur_area = *pptmp = + (struct dev_memarea *) malloc (sizeof (struct dev_memarea)); + + if (mc_dev) + mc_area = *pptmp; + + (*pptmp)->addr_mask = addr_mask; + (*pptmp)->addr_compare = addr_compare; + (*pptmp)->size = size; + (*pptmp)->size_mask = size_mask; + (*pptmp)->log = NULL; + (*pptmp)->valid = 1; + (*pptmp)->next = NULL; + + return *pptmp; +} + +/* Register read and write function for a memory area. + Memory areas should be aligned. Memory area is rounded up to + fit the nearest 2^n aligment. + (used also by peripheral devices like 16450 UART etc.) + If mc_dev is 1, this device will be checked first for a match + and will be accessed in case of overlaping memory areas. + Only one device can have this set to 1 (used for memory controller) */ +struct dev_memarea * +reg_mem_area (oraddr_t addr, uint32_t size, unsigned mc_dev, + struct mem_ops *ops) +{ + unsigned int size_mask = bit_mask (size); + unsigned int addr_mask = ~size_mask; + struct dev_memarea *mem; + + mem = register_memoryarea_mask (addr_mask, addr & addr_mask, size_mask + 1, + mc_dev); + + memcpy (&mem->ops, ops, sizeof (struct mem_ops)); + memcpy (&mem->direct_ops, ops, sizeof (struct mem_ops)); + + if (!ops->readfunc32) + { + mem->ops.readfunc32 = eval_mem_32_inv; + mem->direct_ops.readfunc32 = eval_mem_32_inv_direct; + mem->direct_ops.read_dat32 = mem; + } + if (!ops->readfunc16) + { + mem->ops.readfunc16 = eval_mem_16_inv; + mem->direct_ops.readfunc16 = eval_mem_16_inv_direct; + mem->direct_ops.read_dat16 = mem; + } + if (!ops->readfunc8) + { + mem->ops.readfunc8 = eval_mem_8_inv; + mem->direct_ops.readfunc8 = eval_mem_8_inv_direct; + mem->direct_ops.read_dat8 = mem; + } + + if (!ops->writefunc32) + { + mem->ops.writefunc32 = set_mem_32_inv; + mem->direct_ops.writefunc32 = set_mem_32_inv_direct; + mem->direct_ops.write_dat32 = mem; + } + if (!ops->writefunc16) + { + mem->ops.writefunc16 = set_mem_16_inv; + mem->direct_ops.writefunc16 = set_mem_16_inv_direct; + mem->direct_ops.write_dat16 = mem; + } + if (!ops->writefunc8) + { + mem->ops.writefunc8 = set_mem_8_inv; + mem->direct_ops.writefunc8 = set_mem_8_inv_direct; + mem->direct_ops.write_dat8 = mem; + } + + if (!ops->writeprog8) + { + mem->ops.writeprog8 = mem->ops.writefunc8; + mem->ops.writeprog8_dat = mem->ops.write_dat8; + } + + if (!ops->writeprog32) + { + mem->ops.writeprog32 = mem->ops.writefunc32; + mem->ops.writeprog32_dat = mem->ops.write_dat32; + } + + if (ops->log) + { + if (!(mem->log = fopen (ops->log, "w"))) + PRINTF ("ERR: Unable to open %s to log memory acesses to\n", + ops->log); + } + + return mem; +} + +/* Check if access is to registered area of memory. */ +struct dev_memarea * +verify_memoryarea (oraddr_t addr) +{ + struct dev_memarea *ptmp; + + /* Check memory controller space first */ + if (mc_area + && (addr & mc_area->addr_mask) == + (mc_area->addr_compare & mc_area->addr_mask)) + { + return cur_area = mc_area; + } + + /* Check cached value */ + if (cur_area + && (addr & cur_area->addr_mask) == + (cur_area->addr_compare & cur_area->addr_mask)) + { + return cur_area; + } + + /* When mc is enabled, we must check valid also, otherwise we assume it is + nonzero */ + /* Check list of registered devices. */ + for (ptmp = dev_list; ptmp; ptmp = ptmp->next) + { + if ((addr & ptmp->addr_mask) == (ptmp->addr_compare & ptmp->addr_mask) + && ptmp->valid) + { + return cur_area = ptmp; + } + } + + return cur_area = NULL; +} + +/* Sets the valid bit (Used only by memory controllers) */ +void +set_mem_valid (struct dev_memarea *mem, int valid) +{ + mem->valid = valid; +} + +/* Adjusts the read and write delays for the memory area pointed to by mem. */ +void +adjust_rw_delay (struct dev_memarea *mem, int delayr, int delayw) +{ + mem->ops.delayr = delayr; + mem->ops.delayw = delayw; +} + +static uint8_t +eval_mem_8_inv (oraddr_t memaddr, void *dat) +{ + except_handle (EXCEPT_BUSERR, cur_vadd); + return 0; +} + +static uint16_t +eval_mem_16_inv (oraddr_t memaddr, void *dat) +{ + except_handle (EXCEPT_BUSERR, cur_vadd); + return 0; +} + +static uint32_t +eval_mem_32_inv (oraddr_t memaddr, void *dat) +{ + except_handle (EXCEPT_BUSERR, cur_vadd); + return 0; +} + +static void +set_mem_8_inv (oraddr_t memaddr, uint8_t val, void *dat) +{ + except_handle (EXCEPT_BUSERR, cur_vadd); +} + +static void +set_mem_16_inv (oraddr_t memaddr, uint16_t val, void *dat) +{ + except_handle (EXCEPT_BUSERR, cur_vadd); +} + +static void +set_mem_32_inv (oraddr_t memaddr, uint32_t val, void *dat) +{ + except_handle (EXCEPT_BUSERR, cur_vadd); +} + +uint8_t +eval_mem_8_inv_direct (oraddr_t memaddr, void *dat) +{ + struct dev_memarea *mem = dat; + + PRINTF ("ERROR: Invalid 8-bit direct read from memory %" PRIxADDR "\n", + mem->addr_compare | memaddr); + return 0; +} + +uint16_t +eval_mem_16_inv_direct (oraddr_t memaddr, void *dat) +{ + struct dev_memarea *mem = dat; + + PRINTF ("ERROR: Invalid 16-bit direct read from memory %" PRIxADDR "\n", + mem->addr_compare | memaddr); + return 0; +} + +uint32_t +eval_mem_32_inv_direct (oraddr_t memaddr, void *dat) +{ + struct dev_memarea *mem = dat; + + PRINTF ("ERROR: Invalid 32-bit direct read from memory %" PRIxADDR "\n", + mem->addr_compare | memaddr); + return 0; +} + +void +set_mem_8_inv_direct (oraddr_t memaddr, uint8_t val, void *dat) +{ + struct dev_memarea *mem = dat; + + PRINTF ("ERROR: Invalid 32-bit direct write to memory %" PRIxADDR "\n", + mem->addr_compare | memaddr); +} + +void +set_mem_16_inv_direct (oraddr_t memaddr, uint16_t val, void *dat) +{ + struct dev_memarea *mem = dat; + + PRINTF ("ERROR: Invalid 16-bit direct write to memory %" PRIxADDR "\n", + mem->addr_compare | memaddr); +} + +void +set_mem_32_inv_direct (oraddr_t memaddr, uint32_t val, void *dat) +{ + struct dev_memarea *mem = dat; + + PRINTF ("ERROR: Invalid 32-bit direct write to memory %" PRIxADDR "\n", + mem->addr_compare | memaddr); +} + +/* For cpu accesses + * + * NOTE: This function _is_ only called from eval_mem32 below and + * {i,d}c_simulate_read. _Don't_ call it from anywere else. + */ +uint32_t +evalsim_mem32 (oraddr_t memaddr, oraddr_t vaddr) +{ + struct dev_memarea *mem; + + if ((mem = verify_memoryarea (memaddr))) + { + runtime.sim.mem_cycles += mem->ops.delayr; + return mem->ops.readfunc32 (memaddr & mem->size_mask, + mem->ops.read_dat32); + } + else + { + PRINTF ("EXCEPTION: read out of memory (32-bit access to %" PRIxADDR + ")\n", memaddr); + except_handle (EXCEPT_BUSERR, vaddr); + } + + return 0; +} + +/* For cpu accesses + * + * NOTE: This function _is_ only called from eval_mem16 below and + * {i,d}c_simulate_read. _Don't_ call it from anywere else. + */ +uint16_t +evalsim_mem16 (oraddr_t memaddr, oraddr_t vaddr) +{ + struct dev_memarea *mem; + + if ((mem = verify_memoryarea (memaddr))) + { + runtime.sim.mem_cycles += mem->ops.delayr; + return mem->ops.readfunc16 (memaddr & mem->size_mask, + mem->ops.read_dat16); + } + else + { + PRINTF ("EXCEPTION: read out of memory (16-bit access to %" PRIxADDR + ")\n", memaddr); + except_handle (EXCEPT_BUSERR, vaddr); + } + + return 0; +} + +/* For cpu accesses + * + * NOTE: This function _is_ only called from eval_mem8 below and + * {i,d}c_simulate_read. _Don't_ call it from anywere else. + */ +uint8_t +evalsim_mem8 (oraddr_t memaddr, oraddr_t vaddr) +{ + struct dev_memarea *mem; + + if ((mem = verify_memoryarea (memaddr))) + { + runtime.sim.mem_cycles += mem->ops.delayr; + return mem->ops.readfunc8 (memaddr & mem->size_mask, + mem->ops.read_dat8); + } + else + { + PRINTF ("EXCEPTION: read out of memory (8-bit access to %" PRIxADDR + ")\n", memaddr); + except_handle (EXCEPT_BUSERR, vaddr); + } + + return 0; +} + +/* Returns 32-bit values from mem array. Big endian version. + * + * STATISTICS OK (only used for cpu_access, that is architectural access) + */ +uint32_t +eval_mem32 (oraddr_t memaddr, int *breakpoint) +{ + uint32_t temp; + oraddr_t phys_memaddr; + + if (config.sim.mprofile) + mprofile (memaddr, MPROF_32 | MPROF_READ); + + if (memaddr & 3) + { + except_handle (EXCEPT_ALIGN, memaddr); + return 0; + } + + if (config.debug.enabled) + *breakpoint += check_debug_unit (DebugLoadAddress, memaddr); /* 28/05/01 CZ */ + + phys_memaddr = dmmu_translate (memaddr, 0); + if (except_pending) + return 0; + + if (config.dc.enabled) + temp = dc_simulate_read (phys_memaddr, memaddr, 4); + else + temp = evalsim_mem32 (phys_memaddr, memaddr); + + if (config.debug.enabled) + *breakpoint += check_debug_unit (DebugLoadData, temp); /* MM170901 */ + + return temp; +} + +/* for simulator accesses, the ones that cpu wouldn't do + * + * STATISTICS OK + */ +uint32_t +eval_direct32 (oraddr_t memaddr, int through_mmu, int through_dc) +{ + oraddr_t phys_memaddr; + struct dev_memarea *mem; + + if (memaddr & 3) + { + PRINTF ("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, + __FUNCTION__); + return 0; + } + + phys_memaddr = memaddr; + + if (through_mmu) + phys_memaddr = peek_into_dtlb (memaddr, 0, through_dc); + + if (through_dc) + return dc_simulate_read (phys_memaddr, memaddr, 4); + else + { + if ((mem = verify_memoryarea (phys_memaddr))) + return mem->direct_ops.readfunc32 (phys_memaddr & mem->size_mask, + mem->direct_ops.read_dat32); + else + PRINTF ("ERR: 32-bit read out of memory area: %" PRIxADDR + " (physical: %" PRIxADDR ")\n", memaddr, phys_memaddr); + } + + return 0; +} + + +/* Returns 32-bit values from mem array. Big endian version. + * + * STATISTICS OK (only used for cpu_access, that is architectural access) + */ +uint32_t +eval_insn (oraddr_t memaddr, int *breakpoint) +{ + uint32_t temp; + oraddr_t phys_memaddr; + + if (config.sim.mprofile) + mprofile (memaddr, MPROF_32 | MPROF_FETCH); + + phys_memaddr = memaddr; +#if !(DYNAMIC_EXECUTION) + phys_memaddr = immu_translate (memaddr); + + if (except_pending) + return 0; +#endif + + if (config.debug.enabled) + *breakpoint += check_debug_unit (DebugInstructionFetch, memaddr); + + if ((NULL != ic_state) && ic_state->enabled) + temp = ic_simulate_fetch (phys_memaddr, memaddr); + else + temp = evalsim_mem32 (phys_memaddr, memaddr); + + if (config.debug.enabled) + *breakpoint += check_debug_unit (DebugLoadData, temp); + return temp; +} + +/* Returns 16-bit values from mem array. Big endian version. + * + * STATISTICS OK (only used for cpu_access, that is architectural access) + */ +uint16_t +eval_mem16 (oraddr_t memaddr, int *breakpoint) +{ + uint16_t temp; + oraddr_t phys_memaddr; + + if (config.sim.mprofile) + mprofile (memaddr, MPROF_16 | MPROF_READ); + + if (memaddr & 1) + { + except_handle (EXCEPT_ALIGN, memaddr); + return 0; + } + + if (config.debug.enabled) + *breakpoint += check_debug_unit (DebugLoadAddress, memaddr); /* 28/05/01 CZ */ + + phys_memaddr = dmmu_translate (memaddr, 0); + if (except_pending) + return 0; + + if (config.dc.enabled) + temp = dc_simulate_read (phys_memaddr, memaddr, 2); + else + temp = evalsim_mem16 (phys_memaddr, memaddr); + + if (config.debug.enabled) + *breakpoint += check_debug_unit (DebugLoadData, temp); /* MM170901 */ + + return temp; +} + +/* for simulator accesses, the ones that cpu wouldn't do + * + * STATISTICS OK. + */ +uint16_t +eval_direct16 (oraddr_t memaddr, int through_mmu, int through_dc) +{ + oraddr_t phys_memaddr; + struct dev_memarea *mem; + + if (memaddr & 1) + { + PRINTF ("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, + __FUNCTION__); + return 0; + } + + phys_memaddr = memaddr; + + if (through_mmu) + phys_memaddr = peek_into_dtlb (memaddr, 0, through_dc); + + if (through_dc) + return dc_simulate_read (phys_memaddr, memaddr, 2); + else + { + if ((mem = verify_memoryarea (phys_memaddr))) + return mem->direct_ops.readfunc16 (phys_memaddr & mem->size_mask, + mem->direct_ops.read_dat16); + else + PRINTF ("ERR: 16-bit read out of memory area: %" PRIxADDR + " (physical: %" PRIxADDR "\n", memaddr, phys_memaddr); + } + + return 0; +} + +/* Returns 8-bit values from mem array. + * + * STATISTICS OK (only used for cpu_access, that is architectural access) + */ +uint8_t +eval_mem8 (oraddr_t memaddr, int *breakpoint) +{ + uint8_t temp; + oraddr_t phys_memaddr; + + if (config.sim.mprofile) + mprofile (memaddr, MPROF_8 | MPROF_READ); + + if (config.debug.enabled) + *breakpoint += check_debug_unit (DebugLoadAddress, memaddr); /* 28/05/01 CZ */ + + phys_memaddr = dmmu_translate (memaddr, 0); + if (except_pending) + return 0; + + if (config.dc.enabled) + temp = dc_simulate_read (phys_memaddr, memaddr, 1); + else + temp = evalsim_mem8 (phys_memaddr, memaddr); + + if (config.debug.enabled) + *breakpoint += check_debug_unit (DebugLoadData, temp); /* MM170901 */ + return temp; +} + +/* for simulator accesses, the ones that cpu wouldn't do + * + * STATISTICS OK. + */ +uint8_t +eval_direct8 (oraddr_t memaddr, int through_mmu, int through_dc) +{ + oraddr_t phys_memaddr; + struct dev_memarea *mem; + + phys_memaddr = memaddr; + + if (through_mmu) + phys_memaddr = peek_into_dtlb (memaddr, 0, through_dc); + + if (through_dc) + return dc_simulate_read (phys_memaddr, memaddr, 1); + else + { + if ((mem = verify_memoryarea (phys_memaddr))) + return mem->direct_ops.readfunc8 (phys_memaddr & mem->size_mask, + mem->direct_ops.read_dat8); + else + PRINTF ("ERR: 8-bit read out of memory area: %" PRIxADDR + " (physical: %" PRIxADDR "\n", memaddr, phys_memaddr); + } + + return 0; +} + +/* For cpu accesses + * + * NOTE: This function _is_ only called from set_mem32 below and + * dc_simulate_write. _Don't_ call it from anywere else. + */ +void +setsim_mem32 (oraddr_t memaddr, oraddr_t vaddr, uint32_t value) +{ + struct dev_memarea *mem; + + if ((mem = verify_memoryarea (memaddr))) + { + cur_vadd = vaddr; + runtime.sim.mem_cycles += mem->ops.delayw; + mem->ops.writefunc32 (memaddr & mem->size_mask, value, + mem->ops.write_dat32); +#if DYNAMIC_EXECUTION + dyn_checkwrite (memaddr); +#endif + } + else + { + PRINTF ("EXCEPTION: write out of memory (32-bit access to %" PRIxADDR + ")\n", memaddr); + except_handle (EXCEPT_BUSERR, vaddr); + } +} + +/* For cpu accesses + * + * NOTE: This function _is_ only called from set_mem16 below and + * dc_simulate_write. _Don't_ call it from anywere else. + */ +void +setsim_mem16 (oraddr_t memaddr, oraddr_t vaddr, uint16_t value) +{ + struct dev_memarea *mem; + + if ((mem = verify_memoryarea (memaddr))) + { + cur_vadd = vaddr; + runtime.sim.mem_cycles += mem->ops.delayw; + mem->ops.writefunc16 (memaddr & mem->size_mask, value, + mem->ops.write_dat16); +#if DYNAMIC_EXECUTION + dyn_checkwrite (memaddr); +#endif + } + else + { + PRINTF ("EXCEPTION: write out of memory (16-bit access to %" PRIxADDR + ")\n", memaddr); + except_handle (EXCEPT_BUSERR, vaddr); + } +} + +/* For cpu accesses + * + * NOTE: This function _is_ only called from set_mem8 below and + * dc_simulate_write. _Don't_ call it from anywere else. + */ +void +setsim_mem8 (oraddr_t memaddr, oraddr_t vaddr, uint8_t value) +{ + struct dev_memarea *mem; + + if ((mem = verify_memoryarea (memaddr))) + { + cur_vadd = vaddr; + runtime.sim.mem_cycles += mem->ops.delayw; + mem->ops.writefunc8 (memaddr & mem->size_mask, value, + mem->ops.write_dat8); +#if DYNAMIC_EXECUTION + dyn_checkwrite (memaddr); +#endif + } + else + { + PRINTF ("EXCEPTION: write out of memory (8-bit access to %" PRIxADDR + ")\n", memaddr); + except_handle (EXCEPT_BUSERR, vaddr); + } +} + +/* Set mem, 32-bit. Big endian version. + * + * STATISTICS OK. (the only suspicious usage is in sim-cmd.c, + * where this instruction is used for patching memory, + * wether this is cpu or architectual access is yet to + * be decided) + */ +void +set_mem32 (oraddr_t memaddr, uint32_t value, int *breakpoint) +{ + oraddr_t phys_memaddr; + + if (config.sim.mprofile) + mprofile (memaddr, MPROF_32 | MPROF_WRITE); + + if (memaddr & 3) + { + except_handle (EXCEPT_ALIGN, memaddr); + return; + } + + phys_memaddr = dmmu_translate (memaddr, 1);; + /* If we produced exception don't set anything */ + if (except_pending) + return; + + if (config.debug.enabled) + { + *breakpoint += check_debug_unit (DebugStoreAddress, memaddr); /* 28/05/01 CZ */ + *breakpoint += check_debug_unit (DebugStoreData, value); + } + + if (config.dc.enabled) + dc_simulate_write (phys_memaddr, memaddr, value, 4); + else + setsim_mem32 (phys_memaddr, memaddr, value); + + if (cur_area && cur_area->log) + fprintf (cur_area->log, "[%" PRIxADDR "] -> write %08" PRIx32 "\n", + memaddr, value); +} + +/* + * STATISTICS NOT OK. + */ +void +set_direct32 (oraddr_t memaddr, uint32_t value, int through_mmu, + int through_dc) +{ + oraddr_t phys_memaddr; + struct dev_memarea *mem; + + if (memaddr & 3) + { + PRINTF ("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, + __FUNCTION__); + return; + } + + phys_memaddr = memaddr; + + if (through_mmu) + { + /* 0 - no write access, we do not want a DPF exception do we ;) + */ + phys_memaddr = peek_into_dtlb (memaddr, 1, through_dc); + } + + if (through_dc) + dc_simulate_write (memaddr, memaddr, value, 4); + else + { + if ((mem = verify_memoryarea (phys_memaddr))) + mem->direct_ops.writefunc32 (phys_memaddr & mem->size_mask, value, + mem->direct_ops.write_dat32); + else + PRINTF ("ERR: 32-bit write out of memory area: %" PRIxADDR + " (physical: %" PRIxADDR ")\n", memaddr, phys_memaddr); + } + + if (cur_area && cur_area->log) + fprintf (cur_area->log, "[%" PRIxADDR "] -> DIRECT write %08" PRIx32 "\n", + memaddr, value); +} + + +/* Set mem, 16-bit. Big endian version. */ + +void +set_mem16 (oraddr_t memaddr, uint16_t value, int *breakpoint) +{ + oraddr_t phys_memaddr; + + if (config.sim.mprofile) + mprofile (memaddr, MPROF_16 | MPROF_WRITE); + + if (memaddr & 1) + { + except_handle (EXCEPT_ALIGN, memaddr); + return; + } + + phys_memaddr = dmmu_translate (memaddr, 1);; + /* If we produced exception don't set anything */ + if (except_pending) + return; + + if (config.debug.enabled) + { + *breakpoint += check_debug_unit (DebugStoreAddress, memaddr); /* 28/05/01 CZ */ + *breakpoint += check_debug_unit (DebugStoreData, value); + } + + if (config.dc.enabled) + dc_simulate_write (phys_memaddr, memaddr, value, 2); + else + setsim_mem16 (phys_memaddr, memaddr, value); + + if (cur_area && cur_area->log) + fprintf (cur_area->log, "[%" PRIxADDR "] -> write %04" PRIx16 "\n", + memaddr, value); +} + +/* + * STATISTICS NOT OK. + */ +void +set_direct16 (oraddr_t memaddr, uint16_t value, int through_mmu, + int through_dc) +{ + oraddr_t phys_memaddr; + struct dev_memarea *mem; + + if (memaddr & 1) + { + PRINTF ("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, + __FUNCTION__); + return; + } + + phys_memaddr = memaddr; + + if (through_mmu) + { + /* 0 - no write access, we do not want a DPF exception do we ;) + */ + phys_memaddr = peek_into_dtlb (memaddr, 0, through_dc); + } + + if (through_dc) + dc_simulate_write (memaddr, memaddr, value, 2); + else + { + if ((mem = verify_memoryarea (phys_memaddr))) + mem->direct_ops.writefunc16 (phys_memaddr & mem->size_mask, value, + mem->direct_ops.write_dat16); + else + PRINTF ("ERR: 16-bit write out of memory area: %" PRIxADDR + " (physical: %" PRIxADDR "\n", memaddr, phys_memaddr); + } + + if (cur_area && cur_area->log) + fprintf (cur_area->log, "[%" PRIxADDR "] -> DIRECT write %04" PRIx16 "\n", + memaddr, value); +} + +/* Set mem, 8-bit. */ +void +set_mem8 (oraddr_t memaddr, uint8_t value, int *breakpoint) +{ + oraddr_t phys_memaddr; + + if (config.sim.mprofile) + mprofile (memaddr, MPROF_8 | MPROF_WRITE); + + phys_memaddr = memaddr; + + phys_memaddr = dmmu_translate (memaddr, 1);; + /* If we produced exception don't set anything */ + if (except_pending) + return; + + if (config.debug.enabled) + { + *breakpoint += check_debug_unit (DebugStoreAddress, memaddr); /* 28/05/01 CZ */ + *breakpoint += check_debug_unit (DebugStoreData, value); + } + + if (config.dc.enabled) + dc_simulate_write (phys_memaddr, memaddr, value, 1); + else + setsim_mem8 (phys_memaddr, memaddr, value); + + if (cur_area && cur_area->log) + fprintf (cur_area->log, "[%" PRIxADDR "] -> write %02" PRIx8 "\n", + memaddr, value); +} + +/* + * STATISTICS NOT OK. + */ +void +set_direct8 (oraddr_t memaddr, uint8_t value, int through_mmu, int through_dc) +{ + oraddr_t phys_memaddr; + struct dev_memarea *mem; + + phys_memaddr = memaddr; + + if (through_mmu) + { + /* 0 - no write access, we do not want a DPF exception do we ;) + */ + phys_memaddr = peek_into_dtlb (memaddr, 0, through_dc); + } + + if (through_dc) + dc_simulate_write (phys_memaddr, memaddr, value, 1); + else + { + if ((mem = verify_memoryarea (phys_memaddr))) + mem->direct_ops.writefunc8 (phys_memaddr & mem->size_mask, value, + mem->direct_ops.write_dat8); + else + PRINTF ("ERR: 8-bit write out of memory area: %" PRIxADDR + " (physical: %" PRIxADDR "\n", memaddr, phys_memaddr); + } + + if (cur_area && cur_area->log) + fprintf (cur_area->log, "[%" PRIxADDR "] -> DIRECT write %02" PRIx8 "\n", + memaddr, value); +} + + +/* set_program32 - same as set_direct32, but it also writes to memory that is + * non-writeable to the rest of the sim. Used to do program + * loading. + */ +void +set_program32 (oraddr_t memaddr, uint32_t value) +{ + struct dev_memarea *mem; + + if (memaddr & 3) + { + PRINTF ("%s(): ERR unaligned 32-bit program write\n", __FUNCTION__); + return; + } + + if ((mem = verify_memoryarea (memaddr))) + { + mem->ops.writeprog32 (memaddr & mem->size_mask, value, + mem->ops.writeprog32_dat); + } + else + PRINTF ("ERR: 32-bit program load out of memory area: %" PRIxADDR "\n", + memaddr); +} + +/* set_program8 - same as set_direct8, but it also writes to memory that is + * non-writeable to the rest of the sim. Used to do program + * loading. + */ +void +set_program8 (oraddr_t memaddr, uint8_t value) +{ + struct dev_memarea *mem; + + if ((mem = verify_memoryarea (memaddr))) + { + mem->ops.writeprog8 (memaddr & mem->size_mask, value, + mem->ops.writeprog8_dat); + } + else + PRINTF ("ERR: 8-bit program load out of memory area: %" PRIxADDR "\n", + memaddr); +} + + +/*---------------------------------------------------------------------------*/ +/*!Dump memory to the current output + + Output format is hex bytes, 16 bytes per line. Start each line with its + address and (optionally) its symbolic name. Always end with a newline. + + There are all sorts of ways to trip this up, but they are unlikely. The + validity of a memory area is taken from the address of the start of a line + to be printed, so assumes the following 15 bytes are present. This could be + fooled by ridiculous memory declarations. + + @param[in] from Start address of the area of memory + @param[in] to End address of the area of memory */ +/*---------------------------------------------------------------------------*/ +void +dump_memory (oraddr_t from, oraddr_t to) +{ + const int ROW_LEN = 16; + oraddr_t i; /* Row counter */ + + for (i = from; i < to; i += ROW_LEN) + { + struct label_entry *entry = get_label (i); + oraddr_t j; /* Index in row */ + + PRINTF ("%" PRIxADDR, i); + + if (NULL != entry) + { + int padding = 11 - strlen (entry->name); + + PRINTF (" <%s>: ", entry->name); + PRINTF ("%*s ", padding < 0 ? 0 : padding, " "); + } + else + { + PRINTF (": "); + } + + + for (j = 0; j < ROW_LEN; j++) + { + if (verify_memoryarea (i + j)) + { + PRINTF ("%02" PRIx8 " ", eval_direct8 (i + j, 0, 0)); + } + else + { + /* Not a valid memory area. Print Xs as required */ + PRINTF ("XX "); + } + } + + PRINTF ("\n"); + } +} /* dump_memory() */ + + +/*---------------------------------------------------------------------------*/ +/*!Disassemble memory to the current output + + Output format is symbolic disassembly, one instruction per line. Start each + line with its address and (optionally) its symbolic name. + + There are all sorts of ways to trip this up, but they are unlikely. The + validity of a memory area is taken from the address of the start of a line + to be printed, so assumes the following 3 bytes are present. This could be + fooled by ridiculous memory declarations. + + @param[in] from Start address of the area of memory + @param[in] to End address of the area of memory + @param[in] nl If non-zero (true) print a newline at the end of each + line */ +/*---------------------------------------------------------------------------*/ +void +disassemble_memory (oraddr_t from, oraddr_t to, int nl) +{ + const int INSTR_LEN = 4; + oraddr_t i; /* Row counter */ + + for (i = from; i < to; i += INSTR_LEN) + { + struct label_entry *entry = get_label (i); + + PRINTF ("%" PRIxADDR, i); + + if (NULL != entry) + { + int padding = 11 - strlen (entry->name); + + PRINTF (" <%s>: ", entry->name); + PRINTF ("%*s ", padding < 0 ? 0 : padding, " "); + } + else + { + PRINTF (": "); + } + + if (verify_memoryarea (i)) + { + uint32_t insn = eval_direct32 (i, 0, 0); + int index = insn_decode (insn); + + PRINTF ("%08" PRIx32 " ", insn); + + if (index >= 0) + { + disassemble_insn (insn); + PRINTF (" %s", disassembled); + } + else + { + PRINTF (""); + } + + } + else + { + /* Not a valid memory area. Print Xs as required */ + PRINTF ("XXXXXXXX"); + } + + if (nl) + { + PRINTF ("\n"); + } + } +} /* disassemble_memory() */ + + +/* Closes files, etc. */ + +void +done_memory_table () +{ + struct dev_memarea *ptmp; + + /* Check list of registered devices. */ + for (ptmp = dev_list; ptmp; ptmp = ptmp->next) + { + if (ptmp->log) + fclose (ptmp->log); + } +} + +/* Displays current memory configuration */ + +void +memory_table_status (void) +{ + struct dev_memarea *ptmp; + + /* Check list of registered devices. */ + for (ptmp = dev_list; ptmp; ptmp = ptmp->next) + { + PRINTF ("addr & %" PRIxADDR " == %" PRIxADDR " to %" PRIxADDR ", size %" + PRIx32 "\n", ptmp->addr_mask, ptmp->addr_compare, + ptmp->addr_compare | bit_mask (ptmp->size), ptmp->size); + PRINTF ("\t"); + if (ptmp->ops.delayr >= 0) + PRINTF ("read delay = %i cycles, ", ptmp->ops.delayr); + else + PRINTF ("reads not possible, "); + + if (ptmp->ops.delayw >= 0) + PRINTF ("write delay = %i cycles", ptmp->ops.delayw); + else + PRINTF ("writes not possible"); + + if (ptmp->log) + PRINTF (", (logged)\n"); + else + PRINTF ("\n"); + } +} + +/* Outputs time in pretty form to dest string */ + +char * +generate_time_pretty (char *dest, long time_ps) +{ + int exp3 = 0; + if (time_ps) + { + while ((time_ps % 1000) == 0) + { + time_ps /= 1000; + exp3++; + } + } + sprintf (dest, "%li%cs", time_ps, "pnum"[exp3]); + return dest; +}
abstract.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: parse.c =================================================================== --- parse.c (nonexistent) +++ parse.c (revision 128) @@ -0,0 +1,884 @@ +/* parse.c -- Architecture independent load + + Copyright (C) 1999 Damjan Lampret, lampret@opencores.org + Copyright (C) 2008 Embecosm Limited + + Contributor Jeremy Bennett + + This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see . */ + +/* This program is commented throughout in a fashion suitable for processing + with Doxygen. */ + + +/* Autoconf and/or portability configuration */ +#include "config.h" +#include "port.h" + +/* System includes */ +#include + +/* Package includes */ +#include "parse.h" +#include "sim-config.h" +#include "debug.h" +#include "abstract.h" +#include "opcode/or32.h" +#include "coff.h" +#include "elf.h" +#include "labels.h" + + +DECLARE_DEBUG_CHANNEL (coff) + +#define MEMORY_LEN 0x100000000ULL + +/*!Whether to do immediate statistics. This seems to be for local debugging + of parse.c */ +#define IMM_STATS 0 + +/*!Unused mem memory marker. It is used when allocating program and data + memory during parsing */ +static unsigned int freemem; + +/*!Translation table provided by microkernel. Only used if simulating + microkernel. */ +static oraddr_t transl_table; + +/*!Used to signal whether during loading of programs a translation fault + occured. */ +static uint32_t transl_error; + +#if IMM_STATS +static int bcnt[33][3] = { 0 }; +static int bsum[3] = { 0 }; +static uint32_t movhi = 0; +#endif /* IMM_STATS */ + +/*---------------------------------------------------------------------------*/ +/*!Copy a string with null termination + + This function is very similar to strncpy, except it null terminates the + string. A global function also used by the CUC. + + @param[in] dst The destination string + @param[in] src The source string + @param[in] n Number of chars to copy EXCLUDING the null terminator + (i.e. dst had better have room for n+1 chars) + + @return A pointer to dst */ +/*---------------------------------------------------------------------------*/ +char * +strstrip (char *dst, + const char *src, + int n) +{ + strncpy (dst, src, n); + *(dst + n) = '\0'; + + return dst; + +} /* strstrip () */ + +/*---------------------------------------------------------------------------*/ +/*!Translate logical to physical addresses for the loader + + Used only by the simulator loader to translate logical addresses into + physical. If loadcode() is called with valid @c virtphy_transl pointer to + a table of translations then translate() performs translation otherwise + physical address is equal to logical. + + @param[in] laddr Logical address + @param[in] breakpoint Unused + + @return The physical address */ +/*---------------------------------------------------------------------------*/ +static oraddr_t +translate (oraddr_t laddr, + int *breakpoint) +{ + int i; + + /* No translation (i.e. when loading kernel into simulator) */ + if (transl_table == 0) + { + return laddr; + } + + /* Try to find our translation in the table. */ + for (i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16) + { + if ((laddr & ~(PAGE_SIZE - 1)) == eval_direct32 (transl_table + i, 0, 0)) + { + /* Page modified */ + set_direct32 (transl_table + i + 8, -2, 0, 0); + PRINTF ("found paddr=%" PRIx32 "\n", + eval_direct32 (transl_table + i + 4, 0, 0) | + (laddr & (PAGE_SIZE - 1))); + return (oraddr_t) eval_direct32 (transl_table + i + 4, 0, 0) | + (laddr & (oraddr_t) (PAGE_SIZE - 1)); + } + } + + /* Allocate new phy page for us. */ + for (i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16) + { + if (eval_direct32 (transl_table + i + 8, 0, 0) == 0) + { + /* VPN */ + set_direct32 (transl_table + i, laddr & ~(PAGE_SIZE - 1), 0, 0); + /* PPN */ + set_direct32 (transl_table + i + 4, (i / 16) * PAGE_SIZE, 0, 0); + /* Page modified */ + set_direct32 (transl_table + i + 8, -2, 0, 0); + PRINTF ("newly allocated ppn=%" PRIx32 "\n", + eval_direct32 (transl_table + i + 4, 0, 0)); + PRINTF ("newly allocated .ppn=%" PRIxADDR "\n", transl_table + i + 4); + PRINTF ("newly allocated ofs=%" PRIxADDR "\n", + (laddr & (PAGE_SIZE - 1))); + PRINTF ("newly allocated paddr=%" PRIx32 "\n", + eval_direct32 (transl_table + i + 4, 0, + 0) | (laddr & (PAGE_SIZE - 1))); + return (oraddr_t) eval_direct32 (transl_table + i + 4, 0, 0) | + (laddr & (oraddr_t) (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. */ + transl_error = 1; + PRINTF ("can't translate %" PRIxADDR "\n", laddr); + exit (1); + + return -1; + +} /* translate() */ + +#if IMM_STATS +static int +bits (uint32_t val) +{ + int i = 1; + if (!val) + return 0; + while (val != 0 && (int32_t) val != -1) + { + i++; + val = (int32_t) val >> 1; + } + return i; +} + +static void +check_insn (uint32_t insn) +{ + int insn_index = insn_decode (insn); + struct insn_op_struct *opd = op_start[insn_index]; + uint32_t data = 0; + int dis = 0; + const char *name; + if (!insn || insn_index < 0) + return; + name = insn_name (insn_index); + if (strcmp (name, "l.nop") == 0 || strcmp (name, "l.sys") == 0) + return; + + while (1) + { + uint32_t tmp = 0 unsigned int nbits = 0; + while (1) + { + tmp |= + ((insn >> (opd->type & OPTYPE_SHR)) & ((1 << opd->data) - 1)) << + nbits; + nbits += opd->data; + if (opd->type & OPTYPE_OP) + break; + opd++; + } + + /* Do we have to sign extend? */ + if (opd->type & OPTYPE_SIG) + { + int sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR; + if (tmp & (1 << sbit)) + tmp |= 0xFFFFFFFF << sbit; + } + if (opd->type & OPTYPE_DIS) + { + /* We have to read register later. */ + data += tmp; + dis = 1; + } + else + { + if (!(opd->type & OPTYPE_REG) || dis) + { + if (!dis) + data = tmp; + if (strcmp (name, "l.movhi") == 0) + { + movhi = data << 16; + } + else + { + data |= movhi; + //PRINTF ("%08x %s\n", data, name); + if (!(or32_opcodes[insn_index].flags & OR32_IF_DELAY)) + { + bcnt[bits (data)][0]++; + bsum[0]++; + } + else + { + if (strcmp (name, "l.bf") == 0 + || strcmp (name, "l.bnf") == 0) + { + bcnt[bits (data)][1]++; + bsum[1]++; + } + else + { + bcnt[bits (data)][2]++; + bsum[2]++; + } + } + } + } + data = 0; + dis = 0; + } + if (opd->type & OPTYPE_LAST) + { + return; + } + opd++; + } +} +#endif + +/*---------------------------------------------------------------------------*/ +/*!Add an instruction to the program + + @note insn must be in big endian format + + @param[in] address The address to use + @param[in] insn The instruction to add + @param[in] breakpoint Not used (it is passed to the translate() function, + which also does not use it. */ +/*---------------------------------------------------------------------------*/ +static void +addprogram (oraddr_t address, + uint32_t insn, + int *breakpoint) +{ + int vaddr = (!runtime.sim.filename) ? translate (address, breakpoint) : + translate (freemem, breakpoint); + + /* We can't have set_program32 functions since it is not gauranteed that the + section we're loading is aligned on a 4-byte boundry */ + set_program8 (vaddr, (insn >> 24) & 0xff); + set_program8 (vaddr + 1, (insn >> 16) & 0xff); + set_program8 (vaddr + 2, (insn >> 8) & 0xff); + set_program8 (vaddr + 3, insn & 0xff); + +#if IMM_STATS + check_insn (insn); +#endif + + if (runtime.sim.filename) + { + freemem += insn_len (insn_decode (insn)); + } +} /* addprogram () */ + + +/*---------------------------------------------------------------------------*/ +/*!Load big-endian COFF file + + @param[in] filename File to load + @param[in] sections Number of sections in file */ +/*---------------------------------------------------------------------------*/ +static void +readfile_coff (char *filename, + short sections) +{ + FILE *inputfs; + char inputbuf[4]; + uint32_t insn; + int32_t sectsize; + COFF_AOUTHDR coffaouthdr; + struct COFF_scnhdr coffscnhdr; + int len; + int firstthree = 0; + int breakpoint = 0; + + if (!(inputfs = fopen (filename, "r"))) + { + perror ("readfile_coff"); + exit (1); + } + + if (fseek (inputfs, sizeof (struct COFF_filehdr), SEEK_SET) == -1) + { + fclose (inputfs); + perror ("readfile_coff"); + exit (1); + } + + if (fread (&coffaouthdr, sizeof (coffaouthdr), 1, inputfs) != 1) + { + fclose (inputfs); + perror ("readfile_coff"); + exit (1); + } + + while (sections--) + { + uint32_t scnhdr_pos = + sizeof (struct COFF_filehdr) + sizeof (coffaouthdr) + + sizeof (struct COFF_scnhdr) * firstthree; + if (fseek (inputfs, scnhdr_pos, SEEK_SET) == -1) + { + fclose (inputfs); + perror ("readfile_coff"); + exit (1); + } + if (fread (&coffscnhdr, sizeof (struct COFF_scnhdr), 1, inputfs) != 1) + { + fclose (inputfs); + perror ("readfile_coff"); + exit (1); + } + PRINTF ("Section: %s,", coffscnhdr.s_name); + PRINTF (" paddr: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_paddr)); + PRINTF (" vaddr: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_vaddr)); + PRINTF (" size: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_size)); + PRINTF (" scnptr: 0x%.8lx\n", COFF_LONG_H (coffscnhdr.s_scnptr)); + + sectsize = COFF_LONG_H (coffscnhdr.s_size); + ++firstthree; + + /* loading section */ + freemem = COFF_LONG_H (coffscnhdr.s_paddr); + if (fseek (inputfs, COFF_LONG_H (coffscnhdr.s_scnptr), SEEK_SET) == -1) + { + fclose (inputfs); + perror ("readfile_coff"); + exit (1); + } + while (sectsize > 0 + && (len = fread (&inputbuf, sizeof (inputbuf), 1, inputfs))) + { + insn = COFF_LONG_H (inputbuf); + len = insn_len (insn_decode (insn)); + if (len == 2) + { + fseek (inputfs, -2, SEEK_CUR); + } + + addprogram (freemem, insn, &breakpoint); + sectsize -= len; + } + } + if (firstthree < 3) + { + PRINTF ("One or more missing sections. At least"); + PRINTF (" three sections expected (.text, .data, .bss).\n"); + exit (1); + } + if (firstthree > 3) + { + PRINTF ("Warning: one or more extra sections. These"); + PRINTF (" sections were handled as .data sections.\n"); + } + + fclose (inputfs); + PRINTF ("Finished loading COFF.\n"); + return; + +} /* readfile_coff () */ + + +/* Load symbols from big-endian COFF file. */ + +static void +readsyms_coff (char *filename, uint32_t symptr, uint32_t syms) +{ + FILE *inputfs; + struct COFF_syment coffsymhdr; + int count = 0; + uint32_t nsyms = syms; + if (!(inputfs = fopen (filename, "r"))) + { + perror ("readsyms_coff"); + exit (1); + } + + if (fseek (inputfs, symptr, SEEK_SET) == -1) + { + fclose (inputfs); + perror ("readsyms_coff"); + exit (1); + } + + while (syms--) + { + int i, n; + if (fread (&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1) + { + fclose (inputfs); + perror ("readsyms_coff"); + exit (1); + } + + n = (unsigned char) coffsymhdr.e_numaux[0]; + + /* check whether this symbol belongs to a section and is external + symbol; ignore all others */ + if (COFF_SHORT_H (coffsymhdr.e_scnum) >= 0 + && coffsymhdr.e_sclass[0] == C_EXT) + { + uint32_t *ref = ((uint32_t *) coffsymhdr.e.e.e_zeroes); + if (*ref) + { + if (strlen (coffsymhdr.e.e_name) + && strlen (coffsymhdr.e.e_name) < 9) + add_label (COFF_LONG_H (coffsymhdr.e_value), + coffsymhdr.e.e_name); + } + else + { + uint32_t fpos = ftell (inputfs); + + if (fseek + (inputfs, + symptr + nsyms * COFF_SYMESZ + + COFF_LONG_H (coffsymhdr.e.e.e_offset), SEEK_SET) == 0) + { + char tmp[33], *s = &tmp[0]; + while (s != &tmp[32]) + if ((*(s++) = fgetc (inputfs)) == 0) + break; + tmp[32] = 0; + add_label (COFF_LONG_H (coffsymhdr.e_value), &tmp[0]); + } + fseek (inputfs, fpos, SEEK_SET); + } + } + + for (i = 0; i < n; i++) + if (fread (&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1) + { + fclose (inputfs); + perror ("readsyms_coff3"); + exit (1); + } + syms -= n; + count += n; + } + + fclose (inputfs); + PRINTF ("Finished loading symbols.\n"); + return; +} + +static void +readfile_elf (char *filename) +{ + + FILE *inputfs; + struct elf32_hdr elfhdr; + struct elf32_phdr *elf_phdata = NULL; + struct elf32_shdr *elf_spnt, *elf_shdata; + struct elf32_sym *sym_tbl = (struct elf32_sym *) 0; + uint32_t syms = 0; + char *str_tbl = (char *) 0; + char *s_str = (char *) 0; + int breakpoint = 0; + uint32_t inputbuf; + uint32_t padd; + uint32_t insn; + int i, j, sectsize, len; + + if (!(inputfs = fopen (filename, "r"))) + { + perror ("readfile_elf"); + exit (1); + } + + if (fread (&elfhdr, sizeof (elfhdr), 1, inputfs) != 1) + { + perror ("readfile_elf"); + exit (1); + } + + if ((elf_shdata = + (struct elf32_shdr *) malloc (ELF_SHORT_H (elfhdr.e_shentsize) * + ELF_SHORT_H (elfhdr.e_shnum))) == NULL) + { + perror ("readfile_elf"); + exit (1); + } + + if (fseek (inputfs, ELF_LONG_H (elfhdr.e_shoff), SEEK_SET) != 0) + { + perror ("readfile_elf"); + exit (1); + } + + if (fread + (elf_shdata, + ELF_SHORT_H (elfhdr.e_shentsize) * ELF_SHORT_H (elfhdr.e_shnum), 1, + inputfs) != 1) + { + perror ("readfile_elf"); + exit (1); + } + + if (ELF_LONG_H (elfhdr.e_phoff)) + { + if ((elf_phdata = + (struct elf32_phdr *) malloc (ELF_SHORT_H (elfhdr.e_phnum) * + ELF_SHORT_H (elfhdr.e_phentsize))) == + NULL) + { + perror ("readfile_elf"); + exit (1); + } + + if (fseek (inputfs, ELF_LONG_H (elfhdr.e_phoff), SEEK_SET) != 0) + { + perror ("readfile_elf"); + exit (1); + } + + if (fread + (elf_phdata, + ELF_SHORT_H (elfhdr.e_phnum) * ELF_SHORT_H (elfhdr.e_phentsize), + 1, inputfs) != 1) + { + perror ("readfile_elf"); + exit (1); + } + } + + for (i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H (elfhdr.e_shnum); + i++, elf_spnt++) + { + + if (ELF_LONG_H (elf_spnt->sh_type) == SHT_STRTAB) + { + if (NULL != str_tbl) + { + free (str_tbl); + } + + if ((str_tbl = + (char *) malloc (ELF_LONG_H (elf_spnt->sh_size))) == NULL) + { + perror ("readfile_elf"); + exit (1); + } + + if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) != + 0) + { + perror ("readfile_elf"); + exit (1); + } + + if (fread (str_tbl, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) != + 1) + { + perror ("readfile_elf"); + exit (1); + } + } + else if (ELF_LONG_H (elf_spnt->sh_type) == SHT_SYMTAB) + { + + if (NULL != sym_tbl) + { + free (sym_tbl); + } + + if ((sym_tbl = + (struct elf32_sym *) malloc (ELF_LONG_H (elf_spnt->sh_size))) + == NULL) + { + perror ("readfile_elf"); + exit (1); + } + + if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) != + 0) + { + perror ("readfile_elf"); + exit (1); + } + + if (fread (sym_tbl, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) != + 1) + { + perror ("readfile_elf"); + exit (1); + } + + syms = + ELF_LONG_H (elf_spnt->sh_size) / + ELF_LONG_H (elf_spnt->sh_entsize); + } + } + + if (ELF_SHORT_H (elfhdr.e_shstrndx) != SHN_UNDEF) + { + elf_spnt = &elf_shdata[ELF_SHORT_H (elfhdr.e_shstrndx)]; + + if ((s_str = (char *) malloc (ELF_LONG_H (elf_spnt->sh_size))) == NULL) + { + perror ("readfile_elf"); + exit (1); + } + + if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) != 0) + { + perror ("readfile_elf"); + exit (1); + } + + if (fread (s_str, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) != 1) + { + perror ("readfile_elf"); + exit (1); + } + } + + + for (i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H (elfhdr.e_shnum); + i++, elf_spnt++) + { + + if ((ELF_LONG_H (elf_spnt->sh_type) & SHT_PROGBITS) + && (ELF_LONG_H (elf_spnt->sh_flags) & SHF_ALLOC)) + { + + padd = ELF_LONG_H (elf_spnt->sh_addr); + for (j = 0; j < ELF_SHORT_H (elfhdr.e_phnum); j++) + { + if (ELF_LONG_H (elf_phdata[j].p_offset) && + ELF_LONG_H (elf_phdata[j].p_offset) <= + ELF_LONG_H (elf_spnt->sh_offset) + && (ELF_LONG_H (elf_phdata[j].p_offset) + + ELF_LONG_H (elf_phdata[j].p_memsz)) > + ELF_LONG_H (elf_spnt->sh_offset)) + padd = + ELF_LONG_H (elf_phdata[j].p_paddr) + + ELF_LONG_H (elf_spnt->sh_offset) - + ELF_LONG_H (elf_phdata[j].p_offset); + } + + + + if (ELF_LONG_H (elf_spnt->sh_name) && s_str) + PRINTF ("Section: %s,", &s_str[ELF_LONG_H (elf_spnt->sh_name)]); + else + PRINTF ("Section: noname,"); + PRINTF (" vaddr: 0x%.8lx,", ELF_LONG_H (elf_spnt->sh_addr)); + PRINTF (" paddr: 0x%" PRIx32, padd); + PRINTF (" offset: 0x%.8lx,", ELF_LONG_H (elf_spnt->sh_offset)); + PRINTF (" size: 0x%.8lx\n", ELF_LONG_H (elf_spnt->sh_size)); + + freemem = padd; + sectsize = ELF_LONG_H (elf_spnt->sh_size); + + if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) != + 0) + { + perror ("readfile_elf"); + free (elf_phdata); + exit (1); + } + + while (sectsize > 0 + && (len = fread (&inputbuf, sizeof (inputbuf), 1, inputfs))) + { + insn = ELF_LONG_H (inputbuf); + addprogram (freemem, insn, &breakpoint); + sectsize -= 4; + } + } + } + + if (str_tbl) + { + i = 0; + while (syms--) + { + if (sym_tbl[i].st_name && sym_tbl[i].st_info + && ELF_SHORT_H (sym_tbl[i].st_shndx) < 0x8000) + { + add_label (ELF_LONG_H (sym_tbl[i].st_value), + &str_tbl[ELF_LONG_H (sym_tbl[i].st_name)]); + } + i++; + } + } + + if (NULL != str_tbl) + { + free (str_tbl); + } + + if (NULL != sym_tbl) + { + free (sym_tbl); + } + + free (s_str); + free (elf_phdata); + free (elf_shdata); + +} + +/* Identify file type and call appropriate readfile_X routine. It only +handles orX-coff-big executables at the moment. */ + +static void +identifyfile (char *filename) +{ + FILE *inputfs; + struct COFF_filehdr coffhdr; + struct elf32_hdr elfhdr; + + if (!(inputfs = fopen (filename, "r"))) + { + perror (filename); + fflush (stdout); + fflush (stderr); + exit (1); + } + + if (fread (&coffhdr, sizeof (coffhdr), 1, inputfs) == 1) + { + if (COFF_SHORT_H (coffhdr.f_magic) == 0x17a) + { + uint32_t opthdr_size; + PRINTF ("COFF magic: 0x%.4x\n", COFF_SHORT_H (coffhdr.f_magic)); + PRINTF ("COFF flags: 0x%.4x\n", COFF_SHORT_H (coffhdr.f_flags)); + PRINTF ("COFF symptr: 0x%.8lx\n", COFF_LONG_H (coffhdr.f_symptr)); + if ((COFF_SHORT_H (coffhdr.f_flags) & COFF_F_EXEC) != COFF_F_EXEC) + { + PRINTF ("This COFF is not an executable.\n"); + exit (1); + } + opthdr_size = COFF_SHORT_H (coffhdr.f_opthdr); + if (opthdr_size != sizeof (COFF_AOUTHDR)) + { + PRINTF ("COFF optional header is missing or not recognized.\n"); + PRINTF ("COFF f_opthdr: 0x%" PRIx32 "\n", opthdr_size); + exit (1); + } + fclose (inputfs); + readfile_coff (filename, COFF_SHORT_H (coffhdr.f_nscns)); + readsyms_coff (filename, COFF_LONG_H (coffhdr.f_symptr), + COFF_LONG_H (coffhdr.f_nsyms)); + return; + } + else + { + PRINTF ("Not COFF file format\n"); + fseek (inputfs, 0, SEEK_SET); + } + } + if (fread (&elfhdr, sizeof (elfhdr), 1, inputfs) == 1) + { + if (elfhdr.e_ident[0] == 0x7f && elfhdr.e_ident[1] == 0x45 + && elfhdr.e_ident[2] == 0x4c && elfhdr.e_ident[3] == 0x46) + { + PRINTF ("ELF type: 0x%.4x\n", ELF_SHORT_H (elfhdr.e_type)); + PRINTF ("ELF machine: 0x%.4x\n", ELF_SHORT_H (elfhdr.e_machine)); + PRINTF ("ELF version: 0x%.8lx\n", ELF_LONG_H (elfhdr.e_version)); + PRINTF ("ELF sec = %d\n", ELF_SHORT_H (elfhdr.e_shnum)); + if (ELF_SHORT_H (elfhdr.e_type) != ET_EXEC) + { + PRINTF ("This ELF is not an executable.\n"); + exit (1); + } + fclose (inputfs); + readfile_elf (filename); + return; + } + else + { + PRINTF ("Not ELF file format.\n"); + fseek (inputfs, 0, SEEK_SET); + } + } + + perror ("identifyfile2"); + fclose (inputfs); + + return; +} + + +/*---------------------------------------------------------------------------*/ +/*!Load file to memory + + Loads file to memory starting at address startaddr and returns freemem. + + @param[in] filename File to load + @param[in] startaddr Start address at which to load + @param[in] virtphy_transl Virtual to physical transation table if + required. Only used for microkernel simulation, + and not used in Ork1sim at present (set to NULL) + + @return zero on success, negative on failure. */ +/*---------------------------------------------------------------------------*/ +uint32_t +loadcode (char *filename, oraddr_t startaddr, oraddr_t virtphy_transl) +{ + int breakpoint = 0; + + transl_error = 0; + transl_table = virtphy_transl; + freemem = startaddr; + PRINTF ("loadcode: filename %s startaddr=%" PRIxADDR " virtphy_transl=%" + PRIxADDR "\n", filename, startaddr, virtphy_transl); + identifyfile (filename); + +#if IMM_STATS + { + int i = 0, a = 0, b = 0, c = 0; + PRINTF ("index:arith/branch/jump\n"); + for (i = 0; i < 33; i++) + PRINTF ("%2i:\t%3.0f%% / %3.0f%%/ %3.0f%%\t%5i / %5i / %5i\n", i, + 100. * (a += bcnt[i][0]) / bsum[0], 100. * (b += + bcnt[i][1]) / + bsum[1], 100. * (c += + bcnt[i][2]) / bsum[2], bcnt[i][0], + bcnt[i][1], bcnt[i][2]); + PRINTF ("\nsum %i %i %i\n", bsum[0], bsum[1], bsum[2]); + } +#endif + + if (transl_error) + return -1; + else + return translate (freemem, &breakpoint); + +}
parse.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: stats.c =================================================================== --- stats.c (nonexistent) +++ stats.c (revision 128) @@ -0,0 +1,427 @@ +/* stats.c -- Various statistics about instruction scheduling etc. + + Copyright (C) 1999 Damjan Lampret, lampret@opencores.org + Copyright (C) 2008 Embecosm Limited + + Contributor Jeremy Bennett + + This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see . */ + +/* This program is commented throughout in a fashion suitable for processing + with Doxygen. */ + + +/* Autoconf and/or portability configuration */ +#include "config.h" +#include "port.h" + +/* Package includes */ +#include "stats.h" +#include "sim-config.h" +#include "icache-model.h" +#include "spr-defs.h" +#include "execute.h" + + +#define DSTATS_LEN 3000 +#define SSTATS_LEN 300 +#define FSTATS_LEN 200 + +/* Used by safe division - increment divisor by one if it is zero */ +#define SD(X) (X != 0 ? X : 1) + +struct branchstat +{ + int taken; + int nottaken; + int forward; + int backward; +}; + +/*! @see also enum insn_type in abstract.h */ +static const char func_unit_str[30][30] = { + "unknown", + "exception", + "arith", + "shift", + "compare", + "branch", + "jump", + "load", + "store", + "movimm", + "move", + "extend", + "nop", + "mac" +}; + +struct dstats_entry +{ + int insn1; + int insn2; + int cnt_dynamic; + int depend; +}; /*!< double stats */ + +struct sstats_entry +{ + int insn; + int cnt_dynamic; +}; /*!< single stats */ + +struct fstats_entry +{ + enum insn_type insn1; + enum insn_type insn2; + int cnt_dynamic; + int depend; +}; /*!< functional units stats */ + +/* Globally visible statistics data. Renamed mstats to or1k_mstats because Mac + OS X has a lib function called mstats */ +struct mstats_entry or1k_mstats = { 0 }; /*!< misc units stats */ +struct cachestats_entry ic_stats = { 0 }; /*!< instruction cache stats */ +struct cachestats_entry dc_stats = { 0 }; /*!< data cache stats */ +struct immustats_entry immu_stats = { 0 }; /*!< insn MMU stats */ +struct dmmustats_entry dmmu_stats = { 0 }; /*!< data MMU stats */ +struct raw_stats raw_stats; /*!< RAW hazard stats */ + +/* Statistics data strutures used just here */ +static struct dstats_entry dstats[DSTATS_LEN]; /*!< dependency stats */ +static struct sstats_entry sstats[SSTATS_LEN]; /*!< single stats */ +static struct fstats_entry fstats[FSTATS_LEN]; /*!< func units stats */ + + +void +addsstats (int item, int cnt_dynamic) +{ + int i = 0; + + while (sstats[i].insn != item && sstats[i].insn >= 0 && i < SSTATS_LEN) + i++; + + if (i >= SSTATS_LEN - 1) + return; + + if (sstats[i].insn >= 0) + { + sstats[i].cnt_dynamic += cnt_dynamic; + } + else + { + sstats[i].insn = item; + sstats[i].cnt_dynamic = cnt_dynamic; + } +} + +void +adddstats (int item1, int item2, int cnt_dynamic, int depend) +{ + int i = 0; + + while ((dstats[i].insn1 != item1 || dstats[i].insn2 != item2) + && (i < DSTATS_LEN) && dstats[i].insn1 >= 0) + i++; + + if (i >= DSTATS_LEN - 1) + return; + + if (dstats[i].insn1 >= 0) + { + dstats[i].cnt_dynamic += cnt_dynamic; + dstats[i].depend += depend; + } + else + { + dstats[i].insn1 = item1; + dstats[i].insn2 = item2; + dstats[i].cnt_dynamic = cnt_dynamic; + dstats[i].depend = depend; + } +} + +void +addfstats (enum insn_type item1, enum insn_type item2, int cnt_dynamic, + int depend) +{ + int i = 0; + + while (((fstats[i].insn1 != item1) || (fstats[i].insn2 != item2)) && + (fstats[i].insn1 != it_unknown) && (i < FSTATS_LEN)) + i++; + + if (i >= FSTATS_LEN - 1) + return; + + if ((fstats[i].insn1 == item1) && (fstats[i].insn2 == item2)) + { + fstats[i].cnt_dynamic += cnt_dynamic; + fstats[i].depend += depend; + } + else + { + fstats[i].insn1 = item1; + fstats[i].insn2 = item2; + fstats[i].cnt_dynamic = cnt_dynamic; + fstats[i].depend = depend; + } +} + +void +initstats () +{ + int i; + memset (sstats, 0, sizeof (sstats)); + for (i = 0; i < SSTATS_LEN; i++) + sstats[i].insn = -1; + memset (dstats, 0, sizeof (dstats)); + for (i = 0; i < DSTATS_LEN; i++) + dstats[i].insn1 = dstats[i].insn2 = -1; + memset (fstats, 0, sizeof (fstats)); + memset (&or1k_mstats, 0, sizeof (or1k_mstats)); + memset (&ic_stats, 0, sizeof (ic_stats)); + memset (&dc_stats, 0, sizeof (dc_stats)); + memset (&raw_stats, 0, sizeof (raw_stats)); +} + +static void +printotherstats (int which) +{ + PRINTF ("\n"); + if (config.bpb.enabled) + { + struct branchstat bf; + struct branchstat bnf; + long bf_all, bnf_all; + bf.taken = or1k_mstats.bf[1][0] + or1k_mstats.bf[1][1]; + bf.nottaken = or1k_mstats.bf[0][0] + or1k_mstats.bf[0][1]; + bf.forward = or1k_mstats.bf[0][1] + or1k_mstats.bf[1][1]; + bf.backward = or1k_mstats.bf[0][0] + or1k_mstats.bf[1][0]; + bf_all = bf.forward + bf.backward; + + bnf.taken = or1k_mstats.bnf[1][0] + or1k_mstats.bf[1][1]; + bnf.nottaken = or1k_mstats.bnf[0][0] + or1k_mstats.bf[0][1]; + bnf.forward = or1k_mstats.bnf[0][1] + or1k_mstats.bf[1][1]; + bnf.backward = or1k_mstats.bnf[0][0] + or1k_mstats.bf[1][0]; + bnf_all = bnf.forward + bnf.backward; + + PRINTF ("bnf: %d (%ld%%) taken,", bf.taken, + (bf.taken * 100) / SD (bf_all)); + PRINTF (" %d (%ld%%) not taken,", bf.nottaken, + (bf.nottaken * 100) / SD (bf_all)); + PRINTF (" %d (%ld%%) forward,", bf.forward, + (bf.forward * 100) / SD (bf_all)); + PRINTF (" %d (%ld%%) backward\n", bf.backward, + (bf.backward * 100) / SD (bf_all)); + PRINTF ("bf: %d (%ld%%) taken,", bnf.taken, + (bnf.taken * 100) / SD (bnf_all)); + PRINTF (" %d (%ld%%) not taken,", bnf.nottaken, + (bnf.nottaken * 100) / SD (bnf_all)); + PRINTF (" %d (%ld%%) forward,", bnf.forward, + (bnf.forward * 100) / SD (bnf_all)); + PRINTF (" %d (%ld%%) backward\n", bnf.backward, + (bnf.backward * 100) / SD (bnf_all)); + + PRINTF ("StaticBP bnf(%s): correct %ld%%\n", + config.bpb.sbp_bnf_fwd ? "forward" : "backward", + (or1k_mstats.bnf[0][config.bpb.sbp_bnf_fwd] * 100) / + SD (bnf_all)); + PRINTF ("StaticBP bf(%s): correct %ld%%\n", + config.bpb.sbp_bf_fwd ? "forward" : "backward", + (or1k_mstats.bnf[1][config.bpb.sbp_bf_fwd] * 100) / + SD (bf_all)); + PRINTF ("BPB: hit %d (correct %d%%), miss %d\n", or1k_mstats.bpb.hit, + (or1k_mstats.bpb.correct * 100) / SD (or1k_mstats.bpb.hit), + or1k_mstats.bpb.miss); + } + else + PRINTF ("BPB simulation disabled. Enable it to see BPB analysis\n"); + + if (config.bpb.btic) + { + PRINTF ("BTIC: hit %d(%d%%), miss %d\n", or1k_mstats.btic.hit, + (or1k_mstats.btic.hit * 100) / SD (or1k_mstats.btic.hit + + or1k_mstats.btic.miss), + or1k_mstats.btic.miss); + } + else + PRINTF ("BTIC simulation disabled. Enabled it to see BTIC analysis\n"); + + if ((NULL != ic_state) && ic_state->enabled) + { + PRINTF ("IC read: hit %d(%d%%), miss %d\n", ic_stats.readhit, + (ic_stats.readhit * 100) / SD (ic_stats.readhit + + ic_stats.readmiss), + ic_stats.readmiss); + } + else + PRINTF ("No ICache. Enable it to see IC results.\n"); + + if (config.dc.enabled) + { + PRINTF ("DC read: hit %d(%d%%), miss %d\n", dc_stats.readhit, + (dc_stats.readhit * 100) / SD (dc_stats.readhit + + dc_stats.readmiss), + dc_stats.readmiss); + PRINTF ("DC write: hit %d(%d%%), miss %d\n", dc_stats.writehit, + (dc_stats.writehit * 100) / SD (dc_stats.writehit + + dc_stats.writemiss), + dc_stats.writemiss); + } + else + PRINTF ("No DCache. Enable it to see DC results.\n"); + + if (cpu_state.sprs[SPR_UPR] & SPR_UPR_IMP) + { + PRINTF ("IMMU read: hit %d(%d%%), miss %d\n", immu_stats.fetch_tlbhit, + (immu_stats.fetch_tlbhit * 100) / SD (immu_stats.fetch_tlbhit + + immu_stats.fetch_tlbmiss), + immu_stats.fetch_tlbmiss); + } + else + PRINTF ("No IMMU. Set UPR[IMP]\n"); + + if (cpu_state.sprs[SPR_UPR] & SPR_UPR_DMP) + { + PRINTF ("DMMU read: hit %d(%d%%), miss %d\n", dmmu_stats.loads_tlbhit, + (dmmu_stats.loads_tlbhit * 100) / SD (dmmu_stats.loads_tlbhit + + dmmu_stats.loads_tlbmiss), + dmmu_stats.loads_tlbmiss); + } + else + PRINTF ("No DMMU. Set UPR[DMP]\n"); + + PRINTF ("Additional LOAD CYCLES: %u STORE CYCLES: %u\n", + runtime.sim.loadcycles, runtime.sim.storecycles); +} + +void +printstats (int which) +{ + int i, all = 0, dependall = 0; + + if (which > 1 && which <= 5 && !config.cpu.dependstats) + { + PRINTF + ("Hazard analysis disabled. Enable it to see analysis results.\n"); + return; + } + + switch (which) + { + case 1: + PRINTF ("stats 1: Misc stats\n"); + printotherstats (which); + break; + case 2: + PRINTF ("stats 2: Instruction usage\n"); + for (i = 0; i < SSTATS_LEN; i++) + all += sstats[i].cnt_dynamic; + + for (i = 0; i < SSTATS_LEN; i++) + if (sstats[i].cnt_dynamic) + PRINTF (" %-15s used %6dx (%5.1f%%)\n", insn_name (sstats[i].insn), + sstats[i].cnt_dynamic, + (sstats[i].cnt_dynamic * 100.) / SD (all)); + + PRINTF ("%d instructions (dynamic, single stats)\n", all); + break; + + case 3: + PRINTF ("stats 3: Instruction dependencies\n"); + for (i = 0; i < DSTATS_LEN; i++) + { + all += dstats[i].cnt_dynamic; + dependall += dstats[i].depend; + } + + for (i = 0; i < DSTATS_LEN; i++) + if (dstats[i].cnt_dynamic) + { + char temp[100]; + sprintf (temp, "%s, %s ", insn_name (dstats[i].insn1), + insn_name (dstats[i].insn2)); + PRINTF (" %-30s %6dx (%5.1f%%)", temp, dstats[i].cnt_dynamic, + (dstats[i].cnt_dynamic * 100.) / SD (all)); + PRINTF (" depend: %5.1f%%\n", + (dstats[i].depend * 100.) / dstats[i].cnt_dynamic); + } + + PRINTF ("%d instructions (dynamic, dependency stats) depend: %d%%\n", + all, (dependall * 100) / SD (all)); + break; + + case 4: + PRINTF ("stats 4: Functional units dependencies\n"); + for (i = 0; i < FSTATS_LEN; i++) + { + all += fstats[i].cnt_dynamic; + dependall += fstats[i].depend; + } + + for (i = 0; i < FSTATS_LEN; i++) + if (fstats[i].cnt_dynamic) + { + char temp[100]; + sprintf (temp, "%s, %s", func_unit_str[fstats[i].insn1], + func_unit_str[fstats[i].insn2]); + PRINTF (" %-30s %6dx (%5.1f%%)", temp, fstats[i].cnt_dynamic, + (fstats[i].cnt_dynamic * 100.) / SD (all)); + PRINTF (" depend: %5.1f%%\n", + (fstats[i].depend * 100.) / fstats[i].cnt_dynamic); + } + PRINTF + ("%d instructions (dynamic, functional units stats) depend: %d%%\n\n", + all, (dependall * 100) / SD (all)); + break; + + case 5: + PRINTF ("stats 5: Raw register usage over time\n"); +#if RAW_RANGE_STATS + for (i = 0; (i < RAW_RANGE); i++) + PRINTF (" Register set and reused in %d. cycle: %d cases\n", i, + raw_stats.range[i]); +#endif + break; + case 6: + if (config.cpu.sbuf_len) + { + extern int sbuf_total_cyc, sbuf_wait_cyc; + PRINTF ("stats 6: Store buffer analysis\n"); + PRINTF ("Using store buffer of length %i.\n", config.cpu.sbuf_len); + PRINTF ("Number of total memory store cycles: %i/%lli\n", + sbuf_total_cyc, + runtime.sim.cycles + sbuf_total_cyc - sbuf_wait_cyc); + PRINTF ("Number of cycles waiting for memory stores: %i\n", + sbuf_wait_cyc); + PRINTF ("Number of memory cycles spared: %i\n", + sbuf_total_cyc - sbuf_wait_cyc); + PRINTF ("Store speedup %3.2f%%, total speedup %3.2f%%\n", + 100. * (sbuf_total_cyc - sbuf_wait_cyc) / sbuf_total_cyc, + 100. * (sbuf_total_cyc - + sbuf_wait_cyc) / (runtime.sim.cycles + + sbuf_total_cyc - sbuf_wait_cyc)); + } + else + PRINTF + ("Store buffer analysis disabled. Enable it to see analysis results.\n"); + break; + default: + PRINTF ("Please specify a stats group (1-6).\n"); + break; + } +}
stats.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: trace.c =================================================================== --- trace.c (nonexistent) +++ trace.c (revision 128) @@ -0,0 +1,66 @@ +/* trace.c -- Simulator breakpoints + + Copyright (C) 1999 Damjan Lampret, lampret@opencores.org + Copyright (C) 2008 Embecosm Limited + + Contributor Jeremy Bennett + + This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see . */ + +/* This program is commented throughout in a fashion suitable for processing + with Doxygen. */ + + +/* Autoconf and/or portability configuration */ +#include "config.h" + +/* Package includes */ +#include "trace.h" +#include "sim-config.h" +#include "abstract.h" +#include "labels.h" + + +/*---------------------------------------------------------------------------*/ +/*!Set instruction execution breakpoint + + @param[in] addr The address for the breakpoint */ +/*---------------------------------------------------------------------------*/ +void +set_insnbrkpoint (oraddr_t addr) +{ + addr &= ~ADDR_C (3); /* 32-bit aligned */ + + if (!verify_memoryarea (addr)) + { + PRINTF + ("WARNING: This breakpoint is out of the simulated memory range.\n"); + } + + if (has_breakpoint (addr)) + { + remove_breakpoint (addr); + PRINTF ("\nBreakpoint at 0x%" PRIxADDR " cleared.\n", addr); + } + else + { + add_breakpoint (addr); + PRINTF ("\nBreakpoint at 0x%" PRIxADDR " set.\n", addr); + } + + return; + +} /* set_insnbrkpoint () */
trace.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: parse.h =================================================================== --- parse.h (nonexistent) +++ parse.h (revision 128) @@ -0,0 +1,41 @@ +/* parse.h -- Header file for parse.c + + Copyright (C) 1999 Damjan Lampret, lampret@opencores.org + Copyright (C) 2008 Embecosm Limited + + Contributor Jeremy Bennett + + This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see . */ + +/* Here we define some often used caharcters in assembly files. This wil + probably go into architecture dependent directory. */ + + +#ifndef PARSE__H +#define PARSE__H + +/* Package includes */ +#include "sim-config.h" + +/* Function prototypes for external use */ +char *strstrip (char *dst, + const char *src, + int n); +uint32_t loadcode (char *filename, + oraddr_t startaddr, + oraddr_t virtphy_transl); + +#endif /* PARSE__H */
parse.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: coff.h =================================================================== --- coff.h (nonexistent) +++ coff.h (revision 128) @@ -0,0 +1,457 @@ +#if HAVE_CONFIG_H +#include +#endif + +/* This file is derived from the GAS 2.1.4 assembler control file. + The GAS product is under the GNU Public License, version 2 or later. + As such, this file is also under that license. + + If the file format changes in the COFF object, this file should be + subsequently updated to reflect the changes. + + The actual loader module only uses a few of these structures. The full + set is documented here because I received the full set. If you wish + more information about COFF, then O'Reilly has a very excellent book. +*/ + +#define E_SYMNMLEN 8 /* Number of characters in a symbol name */ +#define E_FILNMLEN 14 /* Number of characters in a file name */ +#define E_DIMNUM 4 /* Number of array dimensions in auxiliary entry */ + +/* + * These defines are byte order independent. There is no alignment of fields + * permitted in the structures. Therefore they are declared as characters + * and the values loaded from the character positions. It also makes it + * nice to have it "endian" independent. + */ +#if !defined(WORDS_BIGENDIAN) +/* Load a short int from the following tables with little-endian formats */ +#define COFF_SHORT_L SWAP_ENDIAN_SHORT +/* Load a long int from the following tables with little-endian formats */ +#define COFF_LONG_L SWAP_ENDIAN_LONG +/* Load a short int from the following tables with big-endian formats */ +#define COFF_SHORT_H KEEP_ENDIAN_SHORT +/* Load a long int from the following tables with big-endian formats */ +#define COFF_LONG_H KEEP_ENDIAN_LONG +#else +#define COFF_SHORT_L KEEP_ENDIAN_SHORT +#define COFF_LONG_L KEEP_ENDIAN_LONG +#define COFF_SHORT_H SWAP_ENDIAN_SHORT +#define COFF_LONG_H SWAP_ENDIAN_LONG +#endif + +#define SWAP_ENDIAN_SHORT(ps) ((short)(((unsigned short)((unsigned char)ps[1])<<8)|\ + ((unsigned short)((unsigned char)ps[0])))) + +#define SWAP_ENDIAN_LONG(ps) (((long)(((unsigned long)((unsigned char)ps[3])<<24) |\ + ((unsigned long)((unsigned char)ps[2])<<16) |\ + ((unsigned long)((unsigned char)ps[1])<<8) |\ + ((unsigned long)((unsigned char)ps[0]))))) + +#define KEEP_ENDIAN_SHORT(ps) ((short)(((unsigned short)((unsigned char)ps[0])<<8)|\ + ((unsigned short)((unsigned char)ps[1])))) + +#define KEEP_ENDIAN_LONG(ps) (((long)(((unsigned long)((unsigned char)ps[0])<<24) |\ + ((unsigned long)((unsigned char)ps[1])<<16) |\ + ((unsigned long)((unsigned char)ps[2])<<8) |\ + ((unsigned long)((unsigned char)ps[3]))))) + +/* These may be overridden later by brain dead implementations which generate + a big-endian header with little-endian data. In that case, generate a + replacement macro which tests a flag and uses either of the two above + as appropriate. */ + +#define COFF_LONG(v) COFF_LONG_L(v) +#define COFF_SHORT(v) COFF_SHORT_L(v) + +/*** coff information for Intel 386/486. */ + +/********************** FILE HEADER **********************/ + +struct COFF_filehdr { + char f_magic[2]; /* magic number */ + char f_nscns[2]; /* number of sections */ + char f_timdat[4]; /* time & date stamp */ + char f_symptr[4]; /* file pointer to symtab */ + char f_nsyms[4]; /* number of symtab entries */ + char f_opthdr[2]; /* sizeof(optional hdr) */ + char f_flags[2]; /* flags */ +}; + +/* + * Bits for f_flags: + * + * F_RELFLG relocation info stripped from file + * F_EXEC file is executable (i.e. no unresolved external + * references) + * F_LNNO line numbers stripped from file + * F_LSYMS local symbols stripped from file + * F_MINMAL this is a minimal object file (".m") output of fextract + * F_UPDATE this is a fully bound update file, output of ogen + * F_SWABD this file has had its bytes swabbed (in names) + * F_AR16WR this file has the byte ordering of an AR16WR + * (e.g. 11/70) machine + * F_AR32WR this file has the byte ordering of an AR32WR machine + * (e.g. vax and iNTEL 386) + * F_AR32W this file has the byte ordering of an AR32W machine + * (e.g. 3b,maxi) + * F_PATCH file contains "patch" list in optional header + * F_NODF (minimal file only) no decision functions for + * replaced functions + */ + +#define COFF_F_RELFLG 0000001 +#define COFF_F_EXEC 0000002 +#define COFF_F_LNNO 0000004 +#define COFF_F_LSYMS 0000010 +#define COFF_F_MINMAL 0000020 +#define COFF_F_UPDATE 0000040 +#define COFF_F_SWABD 0000100 +#define COFF_F_AR16WR 0000200 +#define COFF_F_AR32WR 0000400 +#define COFF_F_AR32W 0001000 +#define COFF_F_PATCH 0002000 +#define COFF_F_NODF 0002000 + +#define COFF_I386MAGIC 0x14c /* Linux's system */ + +#if 0 /* Perhaps, someday, these formats may be used. */ +#define COFF_I386PTXMAGIC 0x154 +#define COFF_I386AIXMAGIC 0x175 /* IBM's AIX system */ +#define COFF_I386BADMAG(x) ((COFF_SHORT((x).f_magic) != COFF_I386MAGIC) \ + && COFF_SHORT((x).f_magic) != COFF_I386PTXMAGIC \ + && COFF_SHORT((x).f_magic) != COFF_I386AIXMAGIC) +#else +#define COFF_I386BADMAG(x) (COFF_SHORT((x).f_magic) != COFF_I386MAGIC) +#endif + +#define COFF_FILHDR struct COFF_filehdr +#define COFF_FILHSZ sizeof(COFF_FILHDR) + +/********************** AOUT "OPTIONAL HEADER" **********************/ + +/* Linux COFF must have this "optional" header. Standard COFF has no entry + location for the "entry" point. They normally would start with the first + location of the .text section. This is not a good idea for linux. So, + the use of this "optional" header is not optional. It is required. + + Do not be tempted to assume that the size of the optional header is + a constant and simply index the next byte by the size of this structure. + Use the 'f_opthdr' field in the main coff header for the size of the + structure actually written to the file!! +*/ + +typedef struct +{ + char magic[2]; /* type of file */ + char vstamp[2]; /* version stamp */ + char tsize[4]; /* text size in bytes, padded to FW bdry */ + char dsize[4]; /* initialized data " " */ + char bsize[4]; /* uninitialized data " " */ + char entry[4]; /* entry pt. */ + char text_start[4]; /* base of text used for this file */ + char data_start[4]; /* base of data used for this file */ +} +COFF_AOUTHDR; + +#define COFF_AOUTSZ (sizeof(COFF_AOUTHDR)) + +#define COFF_STMAGIC 0401 +#define COFF_OMAGIC 0404 +#define COFF_JMAGIC 0407 /* dirty text and data image, can't share */ +#define COFF_DMAGIC 0410 /* dirty text segment, data aligned */ +#define COFF_ZMAGIC 0413 /* The proper magic number for executables */ +#define COFF_SHMAGIC 0443 /* shared library header */ + +/********************** STORAGE CLASSES **********************/ + +/* This used to be defined as -1, but now n_sclass is unsigned. */ +#define C_EFCN 0xff /* physical end of function */ +#define C_NULL 0 +#define C_AUTO 1 /* automatic variable */ +#define C_EXT 2 /* external symbol */ +#define C_STAT 3 /* static */ +#define C_REG 4 /* register variable */ +#define C_EXTDEF 5 /* external definition */ +#define C_LABEL 6 /* label */ +#define C_ULABEL 7 /* undefined label */ +#define C_MOS 8 /* member of structure */ +#define C_ARG 9 /* function argument */ +#define C_STRTAG 10 /* structure tag */ +#define C_MOU 11 /* member of union */ +#define C_UNTAG 12 /* union tag */ +#define C_TPDEF 13 /* type definition */ +#define C_USTATIC 14 /* undefined static */ +#define C_ENTAG 15 /* enumeration tag */ +#define C_MOE 16 /* member of enumeration */ +#define C_REGPARM 17 /* register parameter */ +#define C_FIELD 18 /* bit field */ +#define C_AUTOARG 19 /* auto argument */ +#define C_LASTENT 20 /* dummy entry (end of block) */ +#define C_BLOCK 100 /* ".bb" or ".eb" */ +#define C_FCN 101 /* ".bf" or ".ef" */ +#define C_EOS 102 /* end of structure */ +#define C_FILE 103 /* file name */ +#define C_LINE 104 /* line # reformatted as symbol table entry */ +#define C_ALIAS 105 /* duplicate tag */ +#define C_HIDDEN 106 /* ext symbol in dmert public lib */ + +#define C_WEAKEXT 127 /* weak symbol -- GNU extension */ + +/* New storage classes for TI COFF */ +#define C_UEXT 19 /* Tentative external definition */ +#define C_STATLAB 20 /* Static load time label */ +#define C_EXTLAB 21 /* External load time label */ +#define C_SYSTEM 23 /* System Wide variable */ + +/* New storage classes for WINDOWS_NT */ +#define C_SECTION 104 /* section name */ +#define C_NT_WEAK 105 /* weak external */ + + /* New storage classes for 80960 */ + +/* C_LEAFPROC is obsolete. Use C_LEAFEXT or C_LEAFSTAT */ +#define C_LEAFPROC 108 /* Leaf procedure, "call" via BAL */ + +#define C_SCALL 107 /* Procedure reachable via system call */ +#define C_LEAFEXT 108 /* External leaf */ +#define C_LEAFSTAT 113 /* Static leaf */ +#define C_OPTVAR 109 /* Optimized variable */ +#define C_DEFINE 110 /* Preprocessor #define */ +#define C_PRAGMA 111 /* Advice to compiler or linker */ +#define C_SEGMENT 112 /* 80960 segment name */ + + /* Storage classes for m88k */ +#define C_SHADOW 107 /* shadow symbol */ +#define C_VERSION 108 /* coff version symbol */ + + /* New storage classes for RS/6000 */ +#define C_HIDEXT 107 /* Un-named external symbol */ +#define C_BINCL 108 /* Marks beginning of include file */ +#define C_EINCL 109 /* Marks ending of include file */ + + /* storage classes for stab symbols for RS/6000 */ +#define C_GSYM (0x80) +#define C_LSYM (0x81) +#define C_PSYM (0x82) +#define C_RSYM (0x83) +#define C_RPSYM (0x84) +#define C_STSYM (0x85) +#define C_TCSYM (0x86) +#define C_BCOMM (0x87) +#define C_ECOML (0x88) +#define C_ECOMM (0x89) +#define C_DECL (0x8c) +#define C_ENTRY (0x8d) +#define C_FUN (0x8e) +#define C_BSTAT (0x8f) +#define C_ESTAT (0x90) + +/* Storage classes for Thumb symbols */ +#define C_THUMBEXT (128 + C_EXT) /* 130 */ +#define C_THUMBSTAT (128 + C_STAT) /* 131 */ +#define C_THUMBLABEL (128 + C_LABEL) /* 134 */ +#define C_THUMBEXTFUNC (C_THUMBEXT + 20) /* 150 */ +#define C_THUMBSTATFUNC (C_THUMBSTAT + 20) /* 151 */ + +/********************** SECTION HEADER **********************/ + +struct COFF_scnhdr { + char s_name[8]; /* section name */ + char s_paddr[4]; /* physical address, aliased s_nlib */ + char s_vaddr[4]; /* virtual address */ + char s_size[4]; /* section size */ + char s_scnptr[4]; /* file ptr to raw data for section */ + char s_relptr[4]; /* file ptr to relocation */ + char s_lnnoptr[4]; /* file ptr to line numbers */ + char s_nreloc[2]; /* number of relocation entries */ + char s_nlnno[2]; /* number of line number entries */ + char s_flags[4]; /* flags */ +}; + +#define COFF_SCNHDR struct COFF_scnhdr +#define COFF_SCNHSZ sizeof(COFF_SCNHDR) + +/* + * names of "special" sections + */ + +#define COFF_TEXT ".text" +#define COFF_DATA ".data" +#define COFF_BSS ".bss" +#define COFF_COMMENT ".comment" +#define COFF_LIB ".lib" + +#define COFF_SECT_TEXT 0 /* Section for instruction code */ +#define COFF_SECT_DATA 1 /* Section for initialized globals */ +#define COFF_SECT_BSS 2 /* Section for un-initialized globals */ +#define COFF_SECT_REQD 3 /* Minimum number of sections for good file */ + +#define COFF_STYP_REG 0x00 /* regular segment */ +#define COFF_STYP_DSECT 0x01 /* dummy segment */ +#define COFF_STYP_NOLOAD 0x02 /* no-load segment */ +#define COFF_STYP_GROUP 0x04 /* group segment */ +#define COFF_STYP_PAD 0x08 /* .pad segment */ +#define COFF_STYP_COPY 0x10 /* copy section */ +#define COFF_STYP_TEXT 0x20 /* .text segment */ +#define COFF_STYP_DATA 0x40 /* .data segment */ +#define COFF_STYP_BSS 0x80 /* .bss segment */ +#define COFF_STYP_INFO 0x200 /* .comment section */ +#define COFF_STYP_OVER 0x400 /* overlay section */ +#define COFF_STYP_LIB 0x800 /* library section */ + +/* + * Shared libraries have the following section header in the data field for + * each library. + */ + +struct COFF_slib { + char sl_entsz[4]; /* Size of this entry */ + char sl_pathndx[4]; /* size of the header field */ +}; + +#define COFF_SLIBHD struct COFF_slib +#define COFF_SLIBSZ sizeof(COFF_SLIBHD) + +/********************** LINE NUMBERS **********************/ + +/* 1 line number entry for every "breakpointable" source line in a section. + * Line numbers are grouped on a per function basis; first entry in a function + * grouping will have l_lnno = 0 and in place of physical address will be the + * symbol table index of the function name. + */ + +struct COFF_lineno { + union { + char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ + char l_paddr[4]; /* (physical) address of line number */ + } l_addr; + char l_lnno[2]; /* line number */ +}; + +#define COFF_LINENO struct COFF_lineno +#define COFF_LINESZ 6 + +/********************** SYMBOLS **********************/ + +#define COFF_E_SYMNMLEN 8 /* # characters in a short symbol name */ +#define COFF_E_FILNMLEN 14 /* # characters in a file name */ +#define COFF_E_DIMNUM 4 /* # array dimensions in auxiliary entry */ + +/* + * All symbols and sections have the following definition + */ + +struct COFF_syment +{ + union { + char e_name[E_SYMNMLEN]; /* Symbol name (first 8 characters) */ + struct { + char e_zeroes[4]; /* Leading zeros */ + char e_offset[4]; /* Offset if this is a header section */ + } e; + } e; + + char e_value[4]; /* Value (address) of the segment */ + char e_scnum[2]; /* Section number */ + char e_type[2]; /* Type of section */ + char e_sclass[1]; /* Loader class */ + char e_numaux[1]; /* Number of auxiliary entries which follow */ +}; + +#define COFF_N_BTMASK (0xf) /* Mask for important class bits */ +#define COFF_N_TMASK (0x30) /* Mask for important type bits */ +#define COFF_N_BTSHFT (4) /* # bits to shift class field */ +#define COFF_N_TSHIFT (2) /* # bits to shift type field */ + +/* + * Auxiliary entries because the main table is too limiting. + */ + +union COFF_auxent { + +/* + * Debugger information + */ + + struct { + char x_tagndx[4]; /* str, un, or enum tag indx */ + union { + struct { + char x_lnno[2]; /* declaration line number */ + char x_size[2]; /* str/union/array size */ + } x_lnsz; + char x_fsize[4]; /* size of function */ + } x_misc; + + union { + struct { /* if ISFCN, tag, or .bb */ + char x_lnnoptr[4]; /* ptr to fcn line # */ + char x_endndx[4]; /* entry ndx past block end */ + } x_fcn; + + struct { /* if ISARY, up to 4 dimen. */ + char x_dimen[E_DIMNUM][2]; + } x_ary; + } x_fcnary; + + char x_tvndx[2]; /* tv index */ + } x_sym; + +/* + * Source file names (debugger information) + */ + + union { + char x_fname[E_FILNMLEN]; + struct { + char x_zeroes[4]; + char x_offset[4]; + } x_n; + } x_file; + +/* + * Section information + */ + + struct { + char x_scnlen[4]; /* section length */ + char x_nreloc[2]; /* # relocation entries */ + char x_nlinno[2]; /* # line numbers */ + } x_scn; + +/* + * Transfer vector (branch table) + */ + + struct { + char x_tvfill[4]; /* tv fill value */ + char x_tvlen[2]; /* length of .tv */ + char x_tvran[2][2]; /* tv range */ + } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ +}; + +#define COFF_SYMENT struct COFF_syment +#define COFF_SYMESZ 18 +#define COFF_AUXENT union COFF_auxent +#define COFF_AUXESZ 18 + +#define COFF_ETEXT "etext" + +/********************** RELOCATION DIRECTIVES **********************/ + +struct COFF_reloc { + char r_vaddr[4]; /* Virtual address of item */ + char r_symndx[4]; /* Symbol index in the symtab */ + char r_type[2]; /* Relocation type */ +}; + +#define COFF_RELOC struct COFF_reloc +#define COFF_RELSZ 10 + +#define COFF_DEF_DATA_SECTION_ALIGNMENT 4 +#define COFF_DEF_BSS_SECTION_ALIGNMENT 4 +#define COFF_DEF_TEXT_SECTION_ALIGNMENT 4 + +/* For new sections we haven't heard of before */ +#define COFF_DEF_SECTION_ALIGNMENT 4
coff.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: stats.h =================================================================== --- stats.h (nonexistent) +++ stats.h (revision 128) @@ -0,0 +1,105 @@ +/* stats.h -- Header file for stats.c + + Copyright (C) 1999 Damjan Lampret, lampret@opencores.org + Copyright (C) 2008 Embecosm Limited + + Contributor Jeremy Bennett + + This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see . */ + +/* This program is commented throughout in a fashion suitable for processing + with Doxygen. */ + + +#ifndef STATS__H +#define STATS__H + +/* Package includes */ +#include "opcode/or32.h" + +#define RAW_RANGE 1000 + +struct bpbstat +{ + int hit; + int miss; + int correct; + int incorrect; +}; + +struct bticstat +{ + int hit; + int miss; +}; + +struct mstats_entry +{ + int byteadd; + int bf[2][2]; /* [taken][fwd/bwd] */ + int bnf[2][2]; /* [taken][fwd/bwd] */ + struct bpbstat bpb; + struct bticstat btic; +}; /*!< misc units stats */ + +struct cachestats_entry +{ + int readhit; + int readmiss; + int writehit; + int writemiss; +}; /*!< cache stats */ + +struct immustats_entry +{ + int fetch_tlbhit; + int fetch_tlbmiss; + int fetch_pagefaults; +}; /*!< IMMU stats */ + +struct dmmustats_entry +{ + int loads_tlbhit; + int loads_tlbmiss; + int loads_pagefaults; + int stores_tlbhit; + int stores_tlbmiss; + int stores_pagefaults; +}; /*!< DMMU stats */ + +struct raw_stats +{ + int reg[64]; + int range[RAW_RANGE]; +}; /*!< RAW hazard stats */ + +/* Globally visible data structures */ +extern struct mstats_entry or1k_mstats; +extern struct cachestats_entry ic_stats; +extern struct cachestats_entry dc_stats; +extern struct immustats_entry immu_stats; +extern struct dmmustats_entry dmmu_stats; +extern struct raw_stats raw_stats; + +/* Function prototypes for external use */ +extern void addsstats (int item, int cnt_dynamic); +extern void adddstats (int item1, int item2, int cnt_dynamic, int depend); +extern void addfstats (enum insn_type item1, enum insn_type item2, + int cnt_dynamic, int depend); +extern void initstats (); +extern void printstats (); + +#endif /* STATS__H */
stats.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: trace.h =================================================================== --- trace.h (nonexistent) +++ trace.h (revision 128) @@ -0,0 +1,36 @@ +/* trace.h -- Simulator breakpoints header + + Copyright (C) 1999 Damjan Lampret, lampret@opencores.org + Copyright (C) 2008 Embecosm Limited + + Contributor Jeremy Bennett + + This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see . */ + +/* This program is commented throughout in a fashion suitable for processing + with Doxygen. */ + + +#ifndef TRACE__H +#define TRACE__H + +/* Package includes */ +#include "sim-config.h" + +/* Function prototype for external use */ +void set_insnbrkpoint (oraddr_t addr); + +#endif /* TRACE__H */
trace.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: labels.h =================================================================== --- labels.h (nonexistent) +++ labels.h (revision 128) @@ -0,0 +1,64 @@ +/* labels.h -- Abstract entities header file handling labels + + Copyright (C) 2001 Marko Mlinar, markom@opencores.org + Copyright (C) 2008 Embecosm Limited + + Contributor Jeremy Bennett + + This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see . */ + +/* This program is commented throughout in a fashion suitable for processing + with Doxygen. */ + + +#ifndef LABELS__H_ +#define LABELS__H_ + +/* Package include */ +#include "abstract.h" + +/*! Structure for holding one label per particular memory location */ +struct label_entry +{ + char *name; + oraddr_t addr; + struct label_entry *next; +}; + +/*! Structure repesenting a breakpoint */ +struct breakpoint_entry +{ + oraddr_t addr; + struct breakpoint_entry *next; +}; + +/* Globally visible variables */ +extern struct breakpoint_entry *breakpoints; + +/* Function prototypes for external use */ +extern void init_labels (); +extern void add_label (oraddr_t addr, + char *name); +extern struct label_entry *get_label (oraddr_t addr); +extern struct label_entry *find_label (char *name); +extern oraddr_t eval_label (char *name); +extern void add_breakpoint (oraddr_t addr); +extern void remove_breakpoint (oraddr_t addr); +extern void print_breakpoints (); +extern int has_breakpoint (oraddr_t addr); +extern void init_breakpoints (); + +#endif /* LABELS__H_ */
labels.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: Makefile.am =================================================================== --- Makefile.am (nonexistent) +++ Makefile.am (revision 128) @@ -0,0 +1,36 @@ +# Makefile -- Makefile for cpu architecture independent simulation +# +# Copyright (C) 1999 Damjan Lampret, lampret@opencores.org +# Copyright (C) 2008 Embecosm Limited +# +# Contributor Jeremy Bennett +# +# 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 3 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . + +noinst_LTLIBRARIES = libcommon.la +libcommon_la_SOURCES = abstract.c \ + parse.c \ + stats.c \ + trace.c \ + labels.c \ + abstract.h \ + coff.h \ + elf.h \ + execute.h \ + labels.h \ + parse.h \ + stats.h \ + trace.h
Makefile.am Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: abstract.h =================================================================== --- abstract.h (nonexistent) +++ abstract.h (revision 128) @@ -0,0 +1,189 @@ +/* abstract.h -- Abstract entities header file + + Copyright (C) 1999 Damjan Lampret, lampret@opencores.org + Copyright (C) 2008 Embecosm Limited + + Contributor Jeremy Bennett + + 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 3 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see . */ + +/* This program is commented throughout in a fashion suitable for processing + with Doxygen. */ + + +#ifndef ABSTRACT__H +#define ABSTRACT__H + +/* Autoconf and/or portability configuration */ +#include "port.h" + +/* System includes */ +#include + +/* Package includes */ +#include "arch.h" + +#define DEFAULT_MEMORY_START 0 +#define DEFAULT_MEMORY_LEN 0x800000 +#define STACK_SIZE 20 +#define LABELNAME_LEN 50 +#define INSNAME_LEN 15 +#define OPERANDNAME_LEN 50 +#define MAX_OPERANDS 5 + +#define OP_MEM_ACCESS 0x80000000 + +/* Cache tag types. */ +#define CT_NONE 0 +#define CT_VIRTUAL 1 +#define CT_PHYSICAL 2 + +/* History of execution */ +#define HISTEXEC_LEN 200 + +/* Added by MM */ +#ifndef LONGEST +#define LONGEST long long +#endif /* LONGEST */ + +#ifndef ULONGEST +#define ULONGEST unsigned long long +#endif /* ULONGEST */ + +/* Endianness convenience macros */ +#define LE16(x) bswap_16(x) + +/*! Instruction queue */ +struct iqueue_entry +{ + int insn_index; + uint32_t insn; + oraddr_t insn_addr; +}; + +/*! All the memory operations possible */ +struct mem_ops +{ + + /* Read functions */ + uint32_t (*readfunc32) (oraddr_t, void *); + uint16_t (*readfunc16) (oraddr_t, void *); + uint8_t (*readfunc8) (oraddr_t, void *); + + /* Read functions' data */ + void *read_dat8; + void *read_dat16; + void *read_dat32; + + /* Write functions */ + void (*writefunc32) (oraddr_t, uint32_t, void *); + void (*writefunc16) (oraddr_t, uint16_t, void *); + void (*writefunc8) (oraddr_t, uint8_t, void *); + + /* Write functions' data */ + void *write_dat8; + void *write_dat16; + void *write_dat32; + + /* Program load function. If you have unwritteable memory but you would like + * it if a program would be loaded here, make sure to set this. If this is + * not set, then writefunc8 will be called to load the program */ + void (*writeprog32) (oraddr_t, uint32_t, void *); + void (*writeprog8) (oraddr_t, uint8_t, void *); + + /* Program load functions' data */ + void *writeprog32_dat; + void *writeprog8_dat; + + /* Read/Write delays */ + int delayr; + int delayw; + + /* Name of log file */ + const char *log; +}; + +/*! Memory regions assigned to devices */ +struct dev_memarea +{ + struct dev_memarea *next; + oraddr_t addr_mask; + oraddr_t addr_compare; + uint32_t size; + oraddr_t size_mask; /* Addr mask, calculated out of size */ + int valid; /* Mirrors memory controler valid bit */ + FILE *log; /* log file (NULL if no logging) */ + struct mem_ops ops; + struct mem_ops direct_ops; +}; + +/* Externally visible data */ +extern struct dev_memarea *cur_area; +extern int data_ci; +extern int insn_ci; +extern struct hist_exec *hist_exec_tail; + +/* Function prototypes for external use */ +extern uint32_t eval_mem32 (oraddr_t memaddr, int *); +extern uint16_t eval_mem16 (oraddr_t memaddr, int *); +extern uint8_t eval_mem8 (oraddr_t memaddr, int *); +extern void set_mem32 (oraddr_t memaddr, uint32_t value, int *); +extern void set_mem16 (oraddr_t memaddr, uint16_t value, int *); +extern void set_mem8 (oraddr_t memaddr, uint8_t value, int *); +extern void dump_memory (oraddr_t from, + oraddr_t to); +extern void disassemble_memory (oraddr_t from, + oraddr_t to, + int nl); +extern uint32_t evalsim_mem32 (oraddr_t, oraddr_t); +extern uint16_t evalsim_mem16 (oraddr_t, oraddr_t); +extern uint8_t evalsim_mem8 (oraddr_t, oraddr_t); +extern void setsim_mem32 (oraddr_t, oraddr_t, uint32_t); +extern void setsim_mem16 (oraddr_t, oraddr_t, uint16_t); +extern void setsim_mem8 (oraddr_t, oraddr_t, uint8_t); +extern void done_memory_table (); +extern void memory_table_status (void); +extern struct dev_memarea *reg_mem_area (oraddr_t addr, + uint32_t size, + unsigned mc_dev, + struct mem_ops *ops); +extern void adjust_rw_delay (struct dev_memarea *mem, + int delayr, + int delayw); +extern void set_mem_valid (struct dev_memarea *mem, + int valid); +extern struct dev_memarea *verify_memoryarea (oraddr_t addr); +extern char *generate_time_pretty (char *dest, + long time_ps); +extern uint32_t eval_insn (oraddr_t, int *); +extern uint32_t eval_direct32 (oraddr_t addr, + int through_mmu, + int through_dc); +extern uint16_t eval_direct16 (oraddr_t memaddr, + int through_mmu, + int through_dc); +extern uint8_t eval_direct8 (oraddr_t memaddr, + int through_mmu, + int through_dc); +extern void set_direct8 (oraddr_t, uint8_t, int, int); +extern void set_direct16 (oraddr_t, uint16_t, int, int); +extern void set_direct32 (oraddr_t, uint32_t, int, int); +extern void set_program32 (oraddr_t memaddr, + uint32_t value); +extern void set_program8 (oraddr_t memaddr, + uint8_t value); + +#endif /* ABSTRACT__H */
abstract.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: elf.h =================================================================== --- elf.h (nonexistent) +++ elf.h (revision 128) @@ -0,0 +1,447 @@ +#ifndef _LINUX_ELF_H +#define _LINUX_ELF_H + +#if HAVE_CONFIG_H +#include +#endif + +#ifdef WORDS_BIGENDIAN +#define ELF_SHORT_H +#define ELF_LONG_H +#else +/* Load a short int from the following tables with big-endian formats */ +#define ELF_SHORT_H(ps) ((((unsigned short)(ps) >> 8) & 0xff) |\ + (((unsigned short)(ps) << 8) & 0xff00)) + +/* Load a long int from the following tables with big-endian formats */ +#define ELF_LONG_H(ps) ((((unsigned long)(ps) >> 24) & 0xff) |\ + (((unsigned long)(ps) >> 8) & 0xff00)|\ + (((unsigned long)(ps) << 8) & 0xff0000)|\ + (((unsigned long)(ps) << 24) & 0xff000000)) +#endif + +#ifdef OR32_TYPES +typedef uint32_t Elf32_Addr; +typedef uint16_t Elf32_Half; +typedef uint32_t Elf32_Off; +typedef int32_t Elf32_Sword; +typedef uint32_t Elf32_Word; +#else +typedef unsigned long Elf32_Addr; +typedef unsigned short Elf32_Half; +typedef unsigned long Elf32_Off; +typedef long Elf32_Sword; +typedef unsigned long Elf32_Word; +#endif + +/* These constants are for the segment types stored in the image headers */ +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff + +/* These constants define the different elf file types */ +#define ET_NONE 0 +#define ET_REL 1 +#define ET_EXEC 2 +#define ET_DYN 3 +#define ET_CORE 4 +#define ET_LOPROC 5 +#define ET_HIPROC 6 + +/* These constants define the various ELF target machines */ +#define EM_NONE 0 +#define EM_M32 1 +#define EM_SPARC 2 +#define EM_386 3 +#define EM_68K 4 +#define EM_88K 5 +#define EM_486 6 /* Perhaps disused */ +#define EM_860 7 + +#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */ + +#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */ + +#define EM_SPARC64 11 /* SPARC v9 (not official) 64-bit */ + +#define EM_PARISC 15 /* HPPA */ + +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ + +#define EM_PPC 20 /* PowerPC */ + +/* + * This is an interim value that we will use until the committee comes + * up with a final number. + */ +#define EM_ALPHA 0x9026 + + +/* This is the info that is needed to parse the dynamic section of the file */ +#define DT_NULL 0 +#define DT_NEEDED 1 +#define DT_PLTRELSZ 2 +#define DT_PLTGOT 3 +#define DT_HASH 4 +#define DT_STRTAB 5 +#define DT_SYMTAB 6 +#define DT_RELA 7 +#define DT_RELASZ 8 +#define DT_RELAENT 9 +#define DT_STRSZ 10 +#define DT_SYMENT 11 +#define DT_INIT 12 +#define DT_FINI 13 +#define DT_SONAME 14 +#define DT_RPATH 15 +#define DT_SYMBOLIC 16 +#define DT_REL 17 +#define DT_RELSZ 18 +#define DT_RELENT 19 +#define DT_PLTREL 20 +#define DT_DEBUG 21 +#define DT_TEXTREL 22 +#define DT_JMPREL 23 +#define DT_LOPROC 0x70000000 +#define DT_HIPROC 0x7fffffff + +/* This info is needed when parsing the symbol table */ +#define STB_LOCAL 0 +#define STB_GLOBAL 1 +#define STB_WEAK 2 + +#define STT_NOTYPE 0 +#define STT_OBJECT 1 +#define STT_FUNC 2 +#define STT_SECTION 3 +#define STT_FILE 4 + +#define ELF32_ST_BIND(x) ((x) >> 4) +#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf) + +/* Symbolic values for the entries in the auxiliary table + put on the initial stack */ +#define AT_NULL 0 /* end of vector */ +#define AT_IGNORE 1 /* entry should be ignored */ +#define AT_EXECFD 2 /* file descriptor of program */ +#define AT_PHDR 3 /* program headers for program */ +#define AT_PHENT 4 /* size of program header entry */ +#define AT_PHNUM 5 /* number of program headers */ +#define AT_PAGESZ 6 /* system page size */ +#define AT_BASE 7 /* base address of interpreter */ +#define AT_FLAGS 8 /* flags */ +#define AT_ENTRY 9 /* entry point of program */ +#define AT_NOTELF 10 /* program is not ELF */ +#define AT_UID 11 /* real uid */ +#define AT_EUID 12 /* effective uid */ +#define AT_GID 13 /* real gid */ +#define AT_EGID 14 /* effective gid */ + + +typedef struct dynamic{ + Elf32_Sword d_tag; + union{ + Elf32_Sword d_val; + Elf32_Addr d_ptr; + } d_un; +} Elf32_Dyn; + +typedef struct { + unsigned long long d_tag; /* entry tag value */ + union { + unsigned long long d_val; + unsigned long long d_ptr; + } d_un; +} Elf64_Dyn; + +/* The following are used with relocations */ +#define ELF32_R_SYM(x) ((x) >> 8) +#define ELF32_R_TYPE(x) ((x) & 0xff) + +#define R_386_NONE 0 +#define R_386_32 1 +#define R_386_PC32 2 +#define R_386_GOT32 3 +#define R_386_PLT32 4 +#define R_386_COPY 5 +#define R_386_GLOB_DAT 6 +#define R_386_JMP_SLOT 7 +#define R_386_RELATIVE 8 +#define R_386_GOTOFF 9 +#define R_386_GOTPC 10 +#define R_386_NUM 11 + +#define R_68K_NONE 0 +#define R_68K_32 1 +#define R_68K_16 2 +#define R_68K_8 3 +#define R_68K_PC32 4 +#define R_68K_PC16 5 +#define R_68K_PC8 6 +#define R_68K_GOT32 7 +#define R_68K_GOT16 8 +#define R_68K_GOT8 9 +#define R_68K_GOT32O 10 +#define R_68K_GOT16O 11 +#define R_68K_GOT8O 12 +#define R_68K_PLT32 13 +#define R_68K_PLT16 14 +#define R_68K_PLT8 15 +#define R_68K_PLT32O 16 +#define R_68K_PLT16O 17 +#define R_68K_PLT8O 18 +#define R_68K_COPY 19 +#define R_68K_GLOB_DAT 20 +#define R_68K_JMP_SLOT 21 +#define R_68K_RELATIVE 22 + +typedef struct elf32_rel { + Elf32_Addr r_offset; + Elf32_Word r_info; +} Elf32_Rel; + +typedef struct elf64_rel { + unsigned long long r_offset; /* Location at which to apply the action */ + unsigned long long r_info; /* index and type of relocation */ +} Elf64_Rel; + +typedef struct elf32_rela{ + Elf32_Addr r_offset; + Elf32_Word r_info; + Elf32_Sword r_addend; +} Elf32_Rela; + +typedef struct elf64_rela { + unsigned long long r_offset; /* Location at which to apply the action */ + unsigned long long r_info; /* index and type of relocation */ + unsigned long long r_addend; /* Constant addend used to compute value */ +} Elf64_Rela; + +typedef struct elf32_sym{ + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf32_Half st_shndx; +} Elf32_Sym; + +typedef struct elf64_sym { + unsigned int st_name; /* Symbol name, index in string tbl */ + unsigned char st_info; /* Type and binding attributes */ + unsigned char st_other; /* No defined meaning, 0 */ + unsigned short st_shndx; /* Associated section index */ + unsigned long long st_value; /* Value of the symbol */ + unsigned long long st_size; /* Associated symbol size */ +} Elf64_Sym; + + +#define EI_NIDENT 16 + +typedef struct elf32_hdr{ + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; /* Entry point */ + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} Elf32_Ehdr; + +typedef struct elf64_hdr { + unsigned char e_ident[16]; /* ELF "magic number" */ + short int e_type; + short unsigned int e_machine; + int e_version; + unsigned long long e_entry; /* Entry point virtual address */ + unsigned long long e_phoff; /* Program header table file offset */ + unsigned long long e_shoff; /* Section header table file offset */ + int e_flags; + short int e_ehsize; + short int e_phentsize; + short int e_phnum; + short int e_shentsize; + short int e_shnum; + short int e_shstrndx; +} Elf64_Ehdr; + +/* These constants define the permissions on sections in the program + header, p_flags. */ +#define PF_R 0x4 +#define PF_W 0x2 +#define PF_X 0x1 + +typedef struct elf32_phdr{ + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; +} Elf32_Phdr; + +typedef struct elf64_phdr { + int p_type; + int p_flags; + unsigned long long p_offset; /* Segment file offset */ + unsigned long long p_vaddr; /* Segment virtual address */ + unsigned long long p_paddr; /* Segment physical address */ + unsigned long long p_filesz; /* Segment size in file */ + unsigned long long p_memsz; /* Segment size in memory */ + unsigned long long p_align; /* Segment alignment, file & memory */ +} Elf64_Phdr; + +/* sh_type */ +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 +#define SHT_NUM 12 +#define SHT_LOPROC 0x70000000 +#define SHT_HIPROC 0x7fffffff +#define SHT_LOUSER 0x80000000 +#define SHT_HIUSER 0xffffffff + +/* sh_flags */ +#define SHF_WRITE 0x1 +#define SHF_ALLOC 0x2 +#define SHF_EXECINSTR 0x4 +#define SHF_MASKPROC 0xf0000000 + +/* special section indexes */ +#define SHN_UNDEF 0 +#define SHN_LORESERVE 0xff00 +#define SHN_LOPROC 0xff00 +#define SHN_HIPROC 0xff1f +#define SHN_ABS 0xfff1 +#define SHN_COMMON 0xfff2 +#define SHN_HIRESERVE 0xffff + +typedef struct elf32_shdr { + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; +} Elf32_Shdr; + +typedef struct elf64_shdr { + unsigned int sh_name; /* Section name, index in string tbl */ + unsigned int sh_type; /* Type of section */ + unsigned long long sh_flags; /* Miscellaneous section attributes */ + unsigned long long sh_addr; /* Section virtual addr at execution */ + unsigned long long sh_offset; /* Section file offset */ + unsigned long long sh_size; /* Size of section in bytes */ + unsigned int sh_link; /* Index of another section */ + unsigned int sh_info; /* Additional section information */ + unsigned long long sh_addralign; /* Section alignment */ + unsigned long long sh_entsize; /* Entry size if section holds table */ +} Elf64_Shdr; + +#define EI_MAG0 0 /* e_ident[] indexes */ +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_PAD 7 + +#define ELFMAG0 0x7f /* EI_MAG */ +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define ELFCLASSNONE 0 /* EI_CLASS */ +#define ELFCLASS32 1 +#define ELFCLASS64 2 +#define ELFCLASSNUM 3 + +#define ELFDATANONE 0 /* e_ident[EI_DATA] */ +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 + +#define EV_NONE 0 /* e_version, EI_VERSION */ +#define EV_CURRENT 1 +#define EV_NUM 2 + +/* Notes used in ET_CORE */ +#define NT_PRSTATUS 1 +#define NT_PRFPREG 2 +#define NT_PRPSINFO 3 +#define NT_TASKSTRUCT 4 + +/* Note header in a PT_NOTE section */ +typedef struct elf32_note { + Elf32_Word n_namesz; /* Name size */ + Elf32_Word n_descsz; /* Content size */ + Elf32_Word n_type; /* Content type */ +} Elf32_Nhdr; + +/* Note header in a PT_NOTE section */ +/* + * For now we use the 32 bit version of the structure until we figure + * out whether we need anything better. Note - on the Alpha, "unsigned int" + * is only 32 bits. + */ +typedef struct elf64_note { + unsigned int n_namesz; /* Name size */ + unsigned int n_descsz; /* Content size */ + unsigned int n_type; /* Content type */ +} Elf64_Nhdr; + +#ifdef __mc68000__ +#define ELF_START_MMAP 0xC0000000 +#endif +#ifdef __i386__ +#define ELF_START_MMAP 0x80000000 +#endif + +#if ELF_CLASS == ELFCLASS32 + +extern Elf32_Dyn _DYNAMIC []; +#define elfhdr elf32_hdr +#define elf_phdr elf32_phdr +#define elf_note elf32_note + +#else + +extern Elf64_Dyn _DYNAMIC []; +#define elfhdr elf64_hdr +#define elf_phdr elf64_phdr +#define elf_note elf64_note + +#endif + + +#endif /* _LINUX_ELF_H */
elf.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: .cvsignore =================================================================== --- .cvsignore (nonexistent) +++ .cvsignore (revision 128) @@ -0,0 +1,2 @@ +Makefile +.deps

powered by: WebSVN 2.1.0

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