summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKevin Lim <ktlim@umich.edu>2006-11-10 12:44:15 -0500
committerKevin Lim <ktlim@umich.edu>2006-11-10 12:44:15 -0500
commitb5e68fb54677f601bb00c23af52db8fd6571301f (patch)
treedc3c17198ba4010d907ecd8cb7189aa7959948d4 /src
parent264f9ce374ff4689fec3c32d8289fe76b0b65078 (diff)
parent9ef51f2dbaba88c10366d708f0ca872bb39064e4 (diff)
downloadgem5-b5e68fb54677f601bb00c23af52db8fd6571301f.tar.xz
Merge ktlim@zizzer:/bk/newmem
into zamp.eecs.umich.edu:/z/ktlim2/clean/o3-merge/newmem --HG-- extra : convert_revision : 0c2db1e1b5fdb91c1ac5705ab872a6bfb575a67a
Diffstat (limited to 'src')
-rw-r--r--src/SConscript137
-rw-r--r--src/arch/SConscript35
-rw-r--r--src/arch/alpha/SConscript18
-rw-r--r--src/arch/alpha/arguments.cc6
-rw-r--r--src/arch/alpha/arguments.hh30
-rw-r--r--src/arch/alpha/ev5.cc29
-rw-r--r--src/arch/alpha/faults.cc2
-rw-r--r--src/arch/alpha/floatregfile.cc49
-rw-r--r--src/arch/alpha/floatregfile.hh68
-rw-r--r--src/arch/alpha/idle_event.cc45
-rw-r--r--src/arch/alpha/idle_event.hh47
-rw-r--r--src/arch/alpha/interrupts.hh166
-rw-r--r--src/arch/alpha/intregfile.cc65
-rw-r--r--src/arch/alpha/intregfile.hh78
-rw-r--r--src/arch/alpha/ipr.cc140
-rw-r--r--src/arch/alpha/ipr.hh237
-rw-r--r--src/arch/alpha/isa/decoder.isa36
-rw-r--r--src/arch/alpha/isa/fp.isa4
-rw-r--r--src/arch/alpha/isa/main.isa11
-rw-r--r--src/arch/alpha/isa_traits.hh106
-rw-r--r--src/arch/alpha/kernel_stats.cc211
-rw-r--r--src/arch/alpha/kernel_stats.hh96
-rw-r--r--src/arch/alpha/kgdb.h (renamed from src/base/kgdb.h)11
-rw-r--r--src/arch/alpha/linux/system.cc1
-rw-r--r--src/arch/alpha/linux/system.hh1
-rw-r--r--src/arch/alpha/locked_mem.hh12
-rw-r--r--src/arch/alpha/miscregfile.cc161
-rw-r--r--src/arch/alpha/miscregfile.hh123
-rw-r--r--src/arch/alpha/pagetable.cc63
-rw-r--r--src/arch/alpha/regfile.cc101
-rw-r--r--src/arch/alpha/regfile.hh146
-rw-r--r--src/arch/alpha/remote_gdb.cc309
-rw-r--r--src/arch/alpha/remote_gdb.hh74
-rw-r--r--src/arch/alpha/stacktrace.cc518
-rw-r--r--src/arch/alpha/stacktrace.hh130
-rw-r--r--src/arch/alpha/system.cc6
-rw-r--r--src/arch/alpha/tlb.cc926
-rw-r--r--src/arch/alpha/tlb.hh158
-rw-r--r--src/arch/alpha/utility.hh12
-rw-r--r--src/arch/mips/regfile/misc_regfile.hh10
-rw-r--r--src/arch/mips/regfile/regfile.hh34
-rw-r--r--src/arch/mips/stacktrace.hh5
-rw-r--r--src/arch/sparc/SConscript6
-rw-r--r--src/arch/sparc/arguments.cc73
-rw-r--r--src/arch/sparc/arguments.hh149
-rw-r--r--src/arch/sparc/asi.hh2
-rw-r--r--src/arch/sparc/faults.cc686
-rw-r--r--src/arch/sparc/faults.hh633
-rw-r--r--src/arch/sparc/floatregfile.cc4
-rw-r--r--src/arch/sparc/interrupts.hh92
-rw-r--r--src/arch/sparc/intregfile.cc4
-rw-r--r--src/arch/sparc/isa/decoder.isa197
-rw-r--r--src/arch/sparc/isa/formats/priv.isa24
-rw-r--r--src/arch/sparc/isa/includes.isa1
-rw-r--r--src/arch/sparc/isa/operands.isa50
-rw-r--r--src/arch/sparc/kernel_stats.hh57
-rw-r--r--src/arch/sparc/miscregfile.cc248
-rw-r--r--src/arch/sparc/miscregfile.hh323
-rw-r--r--src/arch/sparc/process.cc3
-rw-r--r--src/arch/sparc/regfile.cc31
-rw-r--r--src/arch/sparc/regfile.hh28
-rw-r--r--src/arch/sparc/remote_gdb.cc203
-rw-r--r--src/arch/sparc/remote_gdb.hh78
-rw-r--r--src/arch/sparc/stacktrace.cc372
-rw-r--r--src/arch/sparc/stacktrace.hh131
-rw-r--r--src/arch/sparc/system.cc47
-rw-r--r--src/arch/sparc/system.hh18
-rw-r--r--src/arch/sparc/tlb.cc79
-rw-r--r--src/arch/sparc/tlb.hh42
-rw-r--r--src/arch/sparc/utility.hh15
-rw-r--r--src/arch/sparc/vtophys.cc132
-rw-r--r--src/base/loader/object_file.cc6
-rw-r--r--src/base/loader/object_file.hh4
-rw-r--r--src/base/loader/raw_object.cc72
-rw-r--r--src/base/loader/raw_object.hh53
-rw-r--r--src/base/pollevent.cc3
-rw-r--r--src/base/random.cc24
-rw-r--r--src/base/random.hh1
-rw-r--r--src/base/remote_gdb.cc476
-rw-r--r--src/base/remote_gdb.hh126
-rw-r--r--src/base/statistics.hh4
-rw-r--r--src/base/stats/flags.hh2
-rw-r--r--src/base/time.hh44
-rw-r--r--src/cpu/base.cc63
-rw-r--r--src/cpu/base.hh34
-rw-r--r--src/cpu/checker/cpu.cc22
-rw-r--r--src/cpu/checker/cpu.hh30
-rw-r--r--src/cpu/checker/cpu_impl.hh5
-rw-r--r--src/cpu/checker/thread_context.hh28
-rw-r--r--src/cpu/cpuevent.hh2
-rw-r--r--src/cpu/exec_context.hh10
-rw-r--r--src/cpu/exetrace.cc133
-rw-r--r--src/cpu/exetrace.hh1
-rw-r--r--src/cpu/inst_seq.hh2
-rw-r--r--src/cpu/m5legion_interface.h50
-rw-r--r--src/cpu/memtest/memtest.hh2
-rw-r--r--src/cpu/o3/alpha/cpu.hh23
-rw-r--r--src/cpu/o3/alpha/cpu_builder.cc10
-rw-r--r--src/cpu/o3/alpha/cpu_impl.hh96
-rw-r--r--src/cpu/o3/alpha/dyn_inst.hh15
-rw-r--r--src/cpu/o3/alpha/dyn_inst_impl.hh23
-rw-r--r--src/cpu/o3/alpha/params.hh11
-rw-r--r--src/cpu/o3/alpha/thread_context.hh9
-rw-r--r--src/cpu/o3/checker_builder.cc4
-rw-r--r--src/cpu/o3/commit_impl.hh7
-rw-r--r--src/cpu/o3/cpu.cc2
-rw-r--r--src/cpu/o3/cpu.hh3
-rw-r--r--src/cpu/o3/fetch.hh2
-rw-r--r--src/cpu/o3/fetch_impl.hh23
-rw-r--r--src/cpu/o3/lsq_unit_impl.hh1
-rw-r--r--src/cpu/o3/mem_dep_unit.hh2
-rw-r--r--src/cpu/o3/mem_dep_unit_impl.hh13
-rwxr-xr-xsrc/cpu/o3/mips/cpu.hh7
-rw-r--r--src/cpu/o3/mips/cpu_builder.cc6
-rw-r--r--src/cpu/o3/mips/cpu_impl.hh31
-rwxr-xr-xsrc/cpu/o3/mips/dyn_inst.hh11
-rwxr-xr-xsrc/cpu/o3/params.hh2
-rw-r--r--src/cpu/o3/regfile.hh23
-rwxr-xr-xsrc/cpu/o3/thread_context.hh10
-rwxr-xr-xsrc/cpu/o3/thread_context_impl.hh15
-rw-r--r--src/cpu/o3/thread_state.hh7
-rw-r--r--src/cpu/ozone/checker_builder.cc4
-rw-r--r--src/cpu/ozone/cpu.hh39
-rw-r--r--src/cpu/ozone/cpu_builder.cc9
-rw-r--r--src/cpu/ozone/cpu_impl.hh45
-rw-r--r--src/cpu/ozone/dyn_inst.hh9
-rw-r--r--src/cpu/ozone/dyn_inst_impl.hh38
-rw-r--r--src/cpu/ozone/front_end.hh2
-rw-r--r--src/cpu/ozone/front_end_impl.hh14
-rw-r--r--src/cpu/ozone/inorder_back_end_impl.hh6
-rw-r--r--src/cpu/ozone/lw_back_end_impl.hh3
-rw-r--r--src/cpu/ozone/lw_lsq.hh2
-rw-r--r--src/cpu/ozone/lw_lsq_impl.hh2
-rw-r--r--src/cpu/ozone/simple_cpu_builder.cc4
-rw-r--r--src/cpu/ozone/simple_params.hh11
-rw-r--r--src/cpu/ozone/thread_state.hh18
-rw-r--r--src/cpu/pc_event.hh1
-rw-r--r--src/cpu/profile.hh4
-rw-r--r--src/cpu/simple/atomic.cc28
-rw-r--r--src/cpu/simple/atomic.hh2
-rw-r--r--src/cpu/simple/base.cc62
-rw-r--r--src/cpu/simple/base.hh25
-rw-r--r--src/cpu/simple/timing.cc25
-rw-r--r--src/cpu/simple/timing.hh4
-rw-r--r--src/cpu/simple_thread.cc40
-rw-r--r--src/cpu/simple_thread.hh34
-rw-r--r--src/cpu/thread_context.hh49
-rw-r--r--src/cpu/thread_state.cc64
-rw-r--r--src/cpu/thread_state.hh33
-rw-r--r--src/dev/SConscript79
-rw-r--r--src/dev/alpha/SConscript68
-rw-r--r--src/dev/alpha/access.h (renamed from src/dev/alpha_access.h)0
-rw-r--r--src/dev/alpha/console.cc (renamed from src/dev/alpha_console.cc)2
-rw-r--r--src/dev/alpha/console.hh (renamed from src/dev/alpha_console.hh)2
-rw-r--r--src/dev/alpha/tsunami.cc (renamed from src/dev/tsunami.cc)8
-rw-r--r--src/dev/alpha/tsunami.hh (renamed from src/dev/tsunami.hh)0
-rw-r--r--src/dev/alpha/tsunami_cchip.cc (renamed from src/dev/tsunami_cchip.cc)6
-rw-r--r--src/dev/alpha/tsunami_cchip.hh (renamed from src/dev/tsunami_cchip.hh)2
-rw-r--r--src/dev/alpha/tsunami_io.cc (renamed from src/dev/tsunami_io.cc)8
-rw-r--r--src/dev/alpha/tsunami_io.hh (renamed from src/dev/tsunami_io.hh)2
-rw-r--r--src/dev/alpha/tsunami_pchip.cc (renamed from src/dev/tsunami_pchip.cc)6
-rw-r--r--src/dev/alpha/tsunami_pchip.hh (renamed from src/dev/tsunami_pchip.hh)2
-rw-r--r--src/dev/alpha/tsunamireg.h (renamed from src/dev/tsunamireg.h)0
-rw-r--r--src/dev/ide_disk.cc4
-rw-r--r--src/dev/io_device.cc6
-rw-r--r--src/dev/isa_fake.cc75
-rw-r--r--src/dev/isa_fake.hh17
-rw-r--r--src/dev/ns_gige.cc1
-rw-r--r--src/dev/pcidev.cc2
-rw-r--r--src/dev/sparc/SConscript46
-rw-r--r--src/dev/uart8250.cc1
-rw-r--r--src/dev/uart8250.hh2
-rw-r--r--src/kern/SConscript48
-rw-r--r--src/kern/kernel_stats.cc156
-rw-r--r--src/kern/kernel_stats.hh36
-rw-r--r--src/kern/linux/events.cc2
-rw-r--r--src/kern/linux/printk.cc2
-rw-r--r--src/kern/linux/printk.hh6
-rw-r--r--src/kern/system_events.cc24
-rw-r--r--src/kern/system_events.hh11
-rw-r--r--src/kern/tru64/dump_mbuf.cc2
-rw-r--r--src/kern/tru64/dump_mbuf.hh2
-rw-r--r--src/kern/tru64/printf.cc2
-rw-r--r--src/kern/tru64/printf.hh2
-rw-r--r--src/kern/tru64/tru64.hh6
-rw-r--r--src/kern/tru64/tru64_events.cc6
-rw-r--r--src/mem/bus.cc54
-rw-r--r--src/mem/bus.hh15
-rw-r--r--src/mem/cache/base_cache.cc28
-rw-r--r--src/mem/cache/base_cache.hh33
-rw-r--r--src/mem/physical.cc4
-rw-r--r--src/mem/port.hh31
-rw-r--r--src/mem/port_impl.hh7
-rw-r--r--src/mem/tport.hh4
-rw-r--r--src/python/m5/__init__.py7
-rw-r--r--src/python/m5/main.py3
-rw-r--r--src/python/m5/objects/BaseCPU.py15
-rw-r--r--src/python/m5/objects/Bus.py10
-rw-r--r--src/python/m5/objects/Pci.py3
-rw-r--r--src/python/m5/objects/SparcTLB.py14
-rw-r--r--src/python/m5/objects/System.py19
-rw-r--r--src/python/m5/objects/Tsunami.py7
-rw-r--r--src/python/m5/params.py5
-rw-r--r--src/sim/byteswap.hh6
-rw-r--r--src/sim/host.hh2
-rw-r--r--src/sim/main.cc12
-rw-r--r--src/sim/pseudo_inst.cc16
-rw-r--r--src/sim/pseudo_inst.hh2
-rw-r--r--src/sim/system.cc2
-rw-r--r--src/sim/system.hh7
210 files changed, 7165 insertions, 4060 deletions
diff --git a/src/SConscript b/src/SConscript
index 28f39bc29..44bcb5320 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -30,7 +30,7 @@
import os
import sys
-from os.path import isdir
+from os.path import isfile, join as joinpath
# This file defines how to build a particular configuration of M5
# based on variable settings in the 'env' build environment.
@@ -74,6 +74,7 @@ base_sources = Split('''
base/loader/aout_object.cc
base/loader/ecoff_object.cc
base/loader/elf_object.cc
+ base/loader/raw_object.cc
base/loader/object_file.cc
base/loader/symtab.cc
base/stats/events.cc
@@ -146,45 +147,6 @@ base_sources = Split('''
sim/trace_context.cc
''')
-# Old FullCPU sources
-full_cpu_sources = Split('''
- encumbered/cpu/full/bpred.cc
- encumbered/cpu/full/commit.cc
- encumbered/cpu/full/cpu.cc
- encumbered/cpu/full/create_vector.cc
- encumbered/cpu/full/cv_spec_state.cc
- encumbered/cpu/full/dd_queue.cc
- encumbered/cpu/full/dep_link.cc
- encumbered/cpu/full/dispatch.cc
- encumbered/cpu/full/dyn_inst.cc
- encumbered/cpu/full/execute.cc
- encumbered/cpu/full/fetch.cc
- encumbered/cpu/full/floss_reasons.cc
- encumbered/cpu/full/fu_pool.cc
- encumbered/cpu/full/inst_fifo.cc
- encumbered/cpu/full/instpipe.cc
- encumbered/cpu/full/issue.cc
- encumbered/cpu/full/ls_queue.cc
- encumbered/cpu/full/machine_queue.cc
- encumbered/cpu/full/pipetrace.cc
- encumbered/cpu/full/readyq.cc
- encumbered/cpu/full/reg_info.cc
- encumbered/cpu/full/rob_station.cc
- encumbered/cpu/full/spec_memory.cc
- encumbered/cpu/full/spec_state.cc
- encumbered/cpu/full/storebuffer.cc
- encumbered/cpu/full/writeback.cc
- encumbered/cpu/full/iq/iq_station.cc
- encumbered/cpu/full/iq/iqueue.cc
- encumbered/cpu/full/iq/segmented/chain_info.cc
- encumbered/cpu/full/iq/segmented/chain_wire.cc
- encumbered/cpu/full/iq/segmented/iq_seg.cc
- encumbered/cpu/full/iq/segmented/iq_segmented.cc
- encumbered/cpu/full/iq/segmented/seg_chain.cc
- encumbered/cpu/full/iq/seznec/iq_seznec.cc
- encumbered/cpu/full/iq/standard/iq_standard.cc
- ''')
-
trace_reader_sources = Split('''
cpu/trace/reader/mem_trace_reader.cc
cpu/trace/reader/ibm_reader.cc
@@ -211,42 +173,9 @@ full_system_sources = Split('''
cpu/intr_control.cc
cpu/profile.cc
- dev/alpha_console.cc
- dev/baddev.cc
- dev/disk_image.cc
- dev/etherbus.cc
- dev/etherdump.cc
- dev/etherint.cc
- dev/etherlink.cc
- dev/etherpkt.cc
- dev/ethertap.cc
- dev/ide_ctrl.cc
- dev/ide_disk.cc
- dev/io_device.cc
- dev/isa_fake.cc
- dev/ns_gige.cc
- dev/pciconfigall.cc
- dev/pcidev.cc
- dev/pcifake.cc
- dev/pktfifo.cc
- dev/platform.cc
- dev/simconsole.cc
- dev/simple_disk.cc
- dev/tsunami.cc
- dev/tsunami_cchip.cc
- dev/tsunami_io.cc
- dev/tsunami_fake.cc
- dev/tsunami_pchip.cc
-
dev/uart.cc
dev/uart8250.cc
- kern/kernel_stats.cc
- kern/system_events.cc
- kern/linux/events.cc
- kern/linux/linux_syscalls.cc
- kern/linux/printk.cc
-
mem/vport.cc
sim/pseudo_inst.cc
@@ -254,7 +183,6 @@ full_system_sources = Split('''
#dev/sinic.cc
#dev/i8254xGBe.cc
-
if env['TARGET_ISA'] == 'alpha':
full_system_sources += Split('''
kern/tru64/dump_mbuf.cc
@@ -263,26 +191,6 @@ if env['TARGET_ISA'] == 'alpha':
kern/tru64/tru64_syscalls.cc
''')
-# turbolaser encumbered sources
-turbolaser_sources = Split('''
- encumbered/dev/dma.cc
- encumbered/dev/etherdev.cc
- encumbered/dev/scsi.cc
- encumbered/dev/scsi_ctrl.cc
- encumbered/dev/scsi_disk.cc
- encumbered/dev/scsi_none.cc
- encumbered/dev/tlaser_clock.cc
- encumbered/dev/tlaser_ipi.cc
- encumbered/dev/tlaser_mbox.cc
- encumbered/dev/tlaser_mc146818.cc
- encumbered/dev/tlaser_node.cc
- encumbered/dev/tlaser_pcia.cc
- encumbered/dev/tlaser_pcidev.cc
- encumbered/dev/tlaser_serial.cc
- encumbered/dev/turbolaser.cc
- encumbered/dev/uart8530.cc
- ''')
-
# Syscall emulation (non-full-system) sources
syscall_emulation_sources = Split('''
mem/translating_port.cc
@@ -296,15 +204,6 @@ syscall_emulation_sources = Split('''
# kern/tru64/tru64.cc
# ''')
-alpha_eio_sources = Split('''
- encumbered/eio/exolex.cc
- encumbered/eio/libexo.cc
- encumbered/eio/eio.cc
- ''')
-
-if env['TARGET_ISA'] == 'alpha':
- syscall_emulation_sources += alpha_eio_sources
-
memtest_sources = Split('''
cpu/memtest/memtest.cc
''')
@@ -318,22 +217,29 @@ env.Append(CPPPATH=Dir('.'))
# Add a flag defining what THE_ISA should be for all compilation
env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())])
-arch_sources = SConscript('arch/SConscript', exports = 'env')
+arch_sources = SConscript(os.path.join('arch', 'SConscript'), exports = 'env')
-cpu_sources = SConscript('cpu/SConscript', exports = 'env')
+cpu_sources = SConscript(os.path.join('cpu', 'SConscript'), exports = 'env')
+
+if env['FULL_SYSTEM']:
+ dev_sources = SConscript(os.path.join('dev', 'SConscript'),
+ exports = 'env')
+ full_system_sources += dev_sources
-# This is outside of cpu/SConscript since the source directory isn't
-# underneath 'cpu'.
-if 'FullCPU' in env['CPU_MODELS']:
- cpu_sources += full_cpu_sources
+ kern_sources = SConscript(os.path.join('kern', 'SConscript'),
+ exports = 'env')
+ full_system_sources += kern_sources
# Set up complete list of sources based on configuration.
sources = base_sources + arch_sources + cpu_sources
+# encumbered should be last because we're adding to some of the other groups
+if isfile(joinpath(env['SRCDIR'], 'encumbered/SConscript')):
+ sources += SConscript('encumbered/SConscript', exports = 'env')
+
+
if env['FULL_SYSTEM']:
sources += full_system_sources
- if env['ALPHA_TLASER']:
- sources += turbolaser_sources
else:
sources += syscall_emulation_sources
@@ -401,8 +307,15 @@ def makeEnv(label, objsfx, strip = False, **kwargs):
envList.append(newEnv)
# Debug binary
+# Solaris seems to have some issue with DWARF2 debugging information, it's ok
+# with stabs though
+if sys.platform == 'sunos5':
+ debug_flag = '-gstabs+'
+else:
+ debug_flag = '-ggdb3'
+
makeEnv('debug', '.do',
- CCFLAGS = Split('-g3 -gdwarf-2 -O0'),
+ CCFLAGS = Split('%s -O0' % debug_flag),
CPPDEFINES = 'DEBUG')
# Optimized binary
diff --git a/src/arch/SConscript b/src/arch/SConscript
index dda1dea53..bbe3c4e3a 100644
--- a/src/arch/SConscript
+++ b/src/arch/SConscript
@@ -49,10 +49,13 @@ sources = []
isa_switch_hdrs = Split('''
arguments.hh
faults.hh
+ interrupts.hh
isa_traits.hh
+ kernel_stats.hh
locked_mem.hh
process.hh
regfile.hh
+ remote_gdb.hh
stacktrace.hh
syscallreturn.hh
tlb.hh
@@ -61,36 +64,8 @@ isa_switch_hdrs = Split('''
vtophys.hh
''')
-# Generate the header. target[0] is the full path of the output
-# header to generate. 'source' is a dummy variable, since we get the
-# list of ISAs from env['ALL_ISA_LIST'].
-def gen_switch_hdr(target, source, env):
- fname = str(target[0])
- basename = os.path.basename(fname)
- f = open(fname, 'w')
- f.write('#include "arch/isa_specific.hh"\n')
- cond = '#if'
- for isa in env['ALL_ISA_LIST']:
- f.write('%s THE_ISA == %s_ISA\n#include "arch/%s/%s"\n'
- % (cond, isa.upper(), isa, basename))
- cond = '#elif'
- f.write('#else\n#error "THE_ISA not set"\n#endif\n')
- f.close()
- return 0
-
-# String to print when generating header
-def gen_switch_hdr_string(target, source, env):
- return "Generating ISA switch header " + str(target[0])
-
-# Build SCons Action object. 'varlist' specifies env vars that this
-# action depends on; when env['ALL_ISA_LIST'] changes these actions
-# should get re-executed.
-switch_hdr_action = Action(gen_switch_hdr, gen_switch_hdr_string,
- varlist=['ALL_ISA_LIST'])
-
-# Instantiate actions for each header
-for hdr in isa_switch_hdrs:
- env.Command(hdr, [], switch_hdr_action)
+# Set up this directory to support switching headers
+env.make_switching_dir('arch', isa_switch_hdrs, env)
#################################################################
#
diff --git a/src/arch/alpha/SConscript b/src/arch/alpha/SConscript
index 216c88cc7..3cc5ec270 100644
--- a/src/arch/alpha/SConscript
+++ b/src/arch/alpha/SConscript
@@ -48,21 +48,29 @@ Import('env')
# Base sources used by all configurations.
base_sources = Split('''
faults.cc
- isa_traits.cc
+ floatregfile.cc
+ intregfile.cc
+ miscregfile.cc
+ regfile.cc
''')
# Full-system sources
full_system_sources = Split('''
- tlb.cc
arguments.cc
ev5.cc
+ freebsd/system.cc
+ idle_event.cc
+ ipr.cc
+ kernel_stats.cc
+ linux/system.cc
osfpal.cc
+ pagetable.cc
stacktrace.cc
- vtophys.cc
+ remote_gdb.cc
system.cc
- freebsd/system.cc
- linux/system.cc
+ tlb.cc
tru64/system.cc
+ vtophys.cc
''')
diff --git a/src/arch/alpha/arguments.cc b/src/arch/alpha/arguments.cc
index 9f9002003..e89bd70b0 100644
--- a/src/arch/alpha/arguments.cc
+++ b/src/arch/alpha/arguments.cc
@@ -35,7 +35,7 @@
using namespace AlphaISA;
-AlphaArguments::Data::~Data()
+Arguments::Data::~Data()
{
while (!data.empty()) {
delete [] data.front();
@@ -44,7 +44,7 @@ AlphaArguments::Data::~Data()
}
char *
-AlphaArguments::Data::alloc(size_t size)
+Arguments::Data::alloc(size_t size)
{
char *buf = new char[size];
data.push_back(buf);
@@ -52,7 +52,7 @@ AlphaArguments::Data::alloc(size_t size)
}
uint64_t
-AlphaArguments::getArg(bool fp)
+Arguments::getArg(bool fp)
{
if (number < 6) {
if (fp)
diff --git a/src/arch/alpha/arguments.hh b/src/arch/alpha/arguments.hh
index d977d48d6..c44181a8d 100644
--- a/src/arch/alpha/arguments.hh
+++ b/src/arch/alpha/arguments.hh
@@ -41,7 +41,7 @@ class ThreadContext;
namespace AlphaISA {
-class AlphaArguments
+class Arguments
{
protected:
ThreadContext *tc;
@@ -65,62 +65,62 @@ class AlphaArguments
RefCountingPtr<Data> data;
public:
- AlphaArguments(ThreadContext *ctx, int n = 0)
+ Arguments(ThreadContext *ctx, int n = 0)
: tc(ctx), number(n), data(NULL)
{ assert(number >= 0); data = new Data;}
- AlphaArguments(const AlphaArguments &args)
+ Arguments(const Arguments &args)
: tc(args.tc), number(args.number), data(args.data) {}
- ~AlphaArguments() {}
+ ~Arguments() {}
ThreadContext *getThreadContext() const { return tc; }
- const AlphaArguments &operator=(const AlphaArguments &args) {
+ const Arguments &operator=(const Arguments &args) {
tc = args.tc;
number = args.number;
data = args.data;
return *this;
}
- AlphaArguments &operator++() {
+ Arguments &operator++() {
++number;
assert(number >= 0);
return *this;
}
- AlphaArguments operator++(int) {
- AlphaArguments args = *this;
+ Arguments operator++(int) {
+ Arguments args = *this;
++number;
assert(number >= 0);
return args;
}
- AlphaArguments &operator--() {
+ Arguments &operator--() {
--number;
assert(number >= 0);
return *this;
}
- AlphaArguments operator--(int) {
- AlphaArguments args = *this;
+ Arguments operator--(int) {
+ Arguments args = *this;
--number;
assert(number >= 0);
return args;
}
- const AlphaArguments &operator+=(int index) {
+ const Arguments &operator+=(int index) {
number += index;
assert(number >= 0);
return *this;
}
- const AlphaArguments &operator-=(int index) {
+ const Arguments &operator-=(int index) {
number -= index;
assert(number >= 0);
return *this;
}
- AlphaArguments operator[](int index) {
- return AlphaArguments(tc, index);
+ Arguments operator[](int index) {
+ return Arguments(tc, index);
}
template <class T>
diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc
index 7595423c3..3d71fbda5 100644
--- a/src/arch/alpha/ev5.cc
+++ b/src/arch/alpha/ev5.cc
@@ -31,16 +31,16 @@
#include "arch/alpha/faults.hh"
#include "arch/alpha/isa_traits.hh"
+#include "arch/alpha/kernel_stats.hh"
#include "arch/alpha/osfpal.hh"
#include "arch/alpha/tlb.hh"
-#include "base/kgdb.h"
+#include "arch/alpha/kgdb.h"
#include "base/remote_gdb.hh"
#include "base/stats/events.hh"
#include "config/full_system.hh"
#include "cpu/base.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
-#include "kern/kernel_stats.hh"
#include "sim/debug.hh"
#include "sim/sim_exit.hh"
@@ -60,7 +60,7 @@ AlphaISA::initCPU(ThreadContext *tc, int cpuId)
tc->setIntReg(16, cpuId);
tc->setIntReg(0, cpuId);
- AlphaFault *reset = new ResetFault;
+ AlphaISA::AlphaFault *reset = new AlphaISA::ResetFault;
tc->setPC(tc->readMiscReg(IPR_PAL_BASE) + reset->vect());
tc->setNextPC(tc->readPC() + sizeof(MachInst));
@@ -147,7 +147,7 @@ AlphaISA::zeroRegisters(CPU *cpu)
Fault
SimpleThread::hwrei()
{
- if (!inPalMode())
+ if (!(readPC() & 0x3))
return new UnimplementedOpcodeFault;
setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR));
@@ -176,7 +176,7 @@ AlphaISA::MiscRegFile::getDataAsid()
}
AlphaISA::MiscReg
-AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ThreadContext *tc)
+AlphaISA::MiscRegFile::readIpr(int idx, ThreadContext *tc)
{
uint64_t retval = 0; // return value, default 0
@@ -269,12 +269,12 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ThreadContext *tc)
case AlphaISA::IPR_DTB_IAP:
case AlphaISA::IPR_ITB_IA:
case AlphaISA::IPR_ITB_IAP:
- fault = new UnimplementedOpcodeFault;
+ panic("Tried to read write only register %d\n", idx);
break;
default:
// invalid IPR
- fault = new UnimplementedOpcodeFault;
+ panic("Tried to read from invalid ipr %d\n", idx);
break;
}
@@ -286,13 +286,13 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ThreadContext *tc)
int break_ipl = -1;
#endif
-Fault
+void
AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
{
uint64_t old;
if (tc->misspeculating())
- return NoFault;
+ return;
switch (idx) {
case AlphaISA::IPR_PALtemp0:
@@ -379,10 +379,10 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
case AlphaISA::IPR_DTB_CM:
if (val & 0x18) {
if (tc->getKernelStats())
- tc->getKernelStats()->mode(Kernel::user, tc);
+ tc->getKernelStats()->mode(TheISA::Kernel::user, tc);
} else {
if (tc->getKernelStats())
- tc->getKernelStats()->mode(Kernel::kernel, tc);
+ tc->getKernelStats()->mode(TheISA::Kernel::kernel, tc);
}
case AlphaISA::IPR_ICM:
@@ -443,7 +443,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
case AlphaISA::IPR_ITB_PTE_TEMP:
case AlphaISA::IPR_DTB_PTE_TEMP:
// read-only registers
- return new UnimplementedOpcodeFault;
+ panic("Tried to write read only ipr %d\n", idx);
case AlphaISA::IPR_HWINT_CLR:
case AlphaISA::IPR_SL_XMIT:
@@ -547,18 +547,17 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
default:
// invalid IPR
- return new UnimplementedOpcodeFault;
+ panic("Tried to write to invalid ipr %d\n", idx);
}
// no error...
- return NoFault;
}
void
AlphaISA::copyIprs(ThreadContext *src, ThreadContext *dest)
{
- for (int i = IPR_Base_DepTag; i < NumInternalProcRegs; ++i) {
+ for (int i = 0; i < NumInternalProcRegs; ++i) {
dest->setMiscReg(i, src->readMiscReg(i));
}
}
diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc
index 7179bf025..5efcf92e4 100644
--- a/src/arch/alpha/faults.cc
+++ b/src/arch/alpha/faults.cc
@@ -125,7 +125,7 @@ void AlphaFault::invoke(ThreadContext * tc)
countStat()++;
// exception restart address
- if (setRestartAddress() || !tc->inPalMode())
+ if (setRestartAddress() || !(tc->readPC() & 0x3))
tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, tc->readPC());
if (skipFaultingInstruction()) {
diff --git a/src/arch/alpha/floatregfile.cc b/src/arch/alpha/floatregfile.cc
new file mode 100644
index 000000000..512b0df95
--- /dev/null
+++ b/src/arch/alpha/floatregfile.cc
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Steve Reinhardt
+ * Gabe Black
+ * Kevin Lim
+ */
+
+#include "arch/alpha/floatregfile.hh"
+#include "sim/serialize.hh"
+
+namespace AlphaISA
+{
+ void
+ FloatRegFile::serialize(std::ostream &os)
+ {
+ SERIALIZE_ARRAY(q, NumFloatRegs);
+ }
+
+ void
+ FloatRegFile::unserialize(Checkpoint *cp, const std::string &section)
+ {
+ UNSERIALIZE_ARRAY(q, NumFloatRegs);
+ }
+}
diff --git a/src/arch/alpha/floatregfile.hh b/src/arch/alpha/floatregfile.hh
new file mode 100644
index 000000000..d289f5785
--- /dev/null
+++ b/src/arch/alpha/floatregfile.hh
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Steve Reinhardt
+ * Gabe Black
+ */
+
+#ifndef __ARCH_ALPHA_FLOATREGFILE_HH__
+#define __ARCH_ALPHA_FLOATREGFILE_HH__
+
+#include "arch/alpha/isa_traits.hh"
+#include "arch/alpha/types.hh"
+
+#include <string.h>
+#include <iostream>
+
+class Checkpoint;
+
+namespace AlphaISA
+{
+ static inline std::string getFloatRegName(RegIndex)
+ {
+ return "";
+ }
+
+ class FloatRegFile
+ {
+ public:
+
+ union {
+ uint64_t q[NumFloatRegs]; // integer qword view
+ double d[NumFloatRegs]; // double-precision floating point view
+ };
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+
+ void clear()
+ { bzero(d, sizeof(d)); }
+ };
+}
+
+#endif
diff --git a/src/arch/alpha/idle_event.cc b/src/arch/alpha/idle_event.cc
new file mode 100644
index 000000000..0f6806319
--- /dev/null
+++ b/src/arch/alpha/idle_event.cc
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Lisa Hsu
+ * Nathan Binkert
+ */
+
+#include "arch/alpha/idle_event.hh"
+#include "arch/alpha/kernel_stats.hh"
+#include "cpu/thread_context.hh"
+
+using namespace TheISA;
+
+void
+IdleStartEvent::process(ThreadContext *tc)
+{
+ if (tc->getKernelStats())
+ tc->getKernelStats()->setIdleProcess(
+ tc->readMiscReg(AlphaISA::IPR_PALtemp23), tc);
+ remove();
+}
diff --git a/src/arch/alpha/idle_event.hh b/src/arch/alpha/idle_event.hh
new file mode 100644
index 000000000..97d5bdd6e
--- /dev/null
+++ b/src/arch/alpha/idle_event.hh
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ * Lisa Hsu
+ * Ali Saidi
+ */
+
+#ifndef __KERN_ALPHA_IDLE_EVENT_HH__
+#define __KERN_ALPHA_IDLE_EVENT_HH__
+
+#include "cpu/pc_event.hh"
+
+class IdleStartEvent : public PCEvent
+{
+ public:
+ IdleStartEvent(PCEventQueue *q, const std::string &desc, Addr addr)
+ : PCEvent(q, desc, addr)
+ {}
+ virtual void process(ThreadContext *tc);
+};
+
+#endif // __KERN_ALPHA_IDLE_EVENT_HH__
diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh
new file mode 100644
index 000000000..75031ae47
--- /dev/null
+++ b/src/arch/alpha/interrupts.hh
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Steve Reinhardt
+ * Kevin Lim
+ */
+
+#ifndef __ARCH_ALPHA_INTERRUPT_HH__
+#define __ARCH_ALPHA_INTERRUPT_HH__
+
+#include "arch/alpha/faults.hh"
+#include "arch/alpha/isa_traits.hh"
+#include "cpu/thread_context.hh"
+
+namespace AlphaISA
+{
+ class Interrupts
+ {
+ protected:
+ uint64_t interrupts[NumInterruptLevels];
+ uint64_t intstatus;
+
+ public:
+ Interrupts()
+ {
+ memset(interrupts, 0, sizeof(interrupts));
+ intstatus = 0;
+ }
+
+ void post(int int_num, int index)
+ {
+ DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
+
+ if (int_num < 0 || int_num >= NumInterruptLevels)
+ panic("int_num out of bounds\n");
+
+ if (index < 0 || index >= sizeof(uint64_t) * 8)
+ panic("int_num out of bounds\n");
+
+ interrupts[int_num] |= 1 << index;
+ intstatus |= (ULL(1) << int_num);
+ }
+
+ void clear(int int_num, int index)
+ {
+ DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
+
+ if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
+ panic("int_num out of bounds\n");
+
+ if (index < 0 || index >= sizeof(uint64_t) * 8)
+ panic("int_num out of bounds\n");
+
+ interrupts[int_num] &= ~(1 << index);
+ if (interrupts[int_num] == 0)
+ intstatus &= ~(ULL(1) << int_num);
+ }
+
+ void clear_all()
+ {
+ DPRINTF(Interrupt, "Interrupts all cleared\n");
+
+ memset(interrupts, 0, sizeof(interrupts));
+ intstatus = 0;
+ }
+
+ void serialize(std::ostream &os)
+ {
+ SERIALIZE_ARRAY(interrupts, NumInterruptLevels);
+ SERIALIZE_SCALAR(intstatus);
+ }
+
+ void unserialize(Checkpoint *cp, const std::string &section)
+ {
+ UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels);
+ UNSERIALIZE_SCALAR(intstatus);
+ }
+
+ bool check_interrupts(ThreadContext * tc) const
+ {
+ return (intstatus != 0) && !(tc->readPC() & 0x3);
+ }
+
+ Fault getInterrupt(ThreadContext * tc)
+ {
+ int ipl = 0;
+ int summary = 0;
+
+ if (tc->readMiscReg(IPR_ASTRR))
+ panic("asynchronous traps not implemented\n");
+
+ if (tc->readMiscReg(IPR_SIRR)) {
+ for (int i = INTLEVEL_SOFTWARE_MIN;
+ i < INTLEVEL_SOFTWARE_MAX; i++) {
+ if (tc->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
+ // See table 4-19 of 21164 hardware reference
+ ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
+ summary |= (ULL(1) << i);
+ }
+ }
+ }
+
+ uint64_t interrupts = intstatus;
+ if (interrupts) {
+ for (int i = INTLEVEL_EXTERNAL_MIN;
+ i < INTLEVEL_EXTERNAL_MAX; i++) {
+ if (interrupts & (ULL(1) << i)) {
+ // See table 4-19 of 21164 hardware reference
+ ipl = i;
+ summary |= (ULL(1) << i);
+ }
+ }
+ }
+
+ if (ipl && ipl > tc->readMiscReg(IPR_IPLR)) {
+ tc->setMiscReg(IPR_ISR, summary);
+ tc->setMiscReg(IPR_INTID, ipl);
+
+ /* The following needs to be added back in somehow */
+ // Checker needs to know these two registers were updated.
+/*#if USE_CHECKER
+ if (this->checker) {
+ this->checker->threadBase()->setMiscReg(IPR_ISR, summary);
+ this->checker->threadBase()->setMiscReg(IPR_INTID, ipl);
+ }
+#endif*/
+
+ DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
+ tc->readMiscReg(IPR_IPLR), ipl, summary);
+
+ return new InterruptFault;
+ } else {
+ return NoFault;
+ }
+ }
+
+ private:
+ };
+}
+
+#endif
+
diff --git a/src/arch/alpha/intregfile.cc b/src/arch/alpha/intregfile.cc
new file mode 100644
index 000000000..0188cb2cd
--- /dev/null
+++ b/src/arch/alpha/intregfile.cc
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Steve Reinhardt
+ * Gabe Black
+ * Kevin Lim
+ */
+
+#include "arch/alpha/isa_traits.hh"
+#include "arch/alpha/intregfile.hh"
+#include "sim/serialize.hh"
+
+namespace AlphaISA
+{
+#if FULL_SYSTEM
+ const int reg_redir[AlphaISA::NumIntRegs] = {
+ /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7,
+ /* 8 */ 32, 33, 34, 35, 36, 37, 38, 15,
+ /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23,
+ /* 24 */ 24, 39, 26, 27, 28, 29, 30, 31 };
+#else
+ const int reg_redir[AlphaISA::NumIntRegs] = {
+ /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7,
+ /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15,
+ /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23,
+ /* 24 */ 24, 25, 26, 27, 28, 29, 30, 31 };
+#endif
+
+ void
+ IntRegFile::serialize(std::ostream &os)
+ {
+ SERIALIZE_ARRAY(regs, NumIntRegs);
+ }
+
+ void
+ IntRegFile::unserialize(Checkpoint *cp, const std::string &section)
+ {
+ UNSERIALIZE_ARRAY(regs, NumIntRegs);
+ }
+}
+
diff --git a/src/arch/alpha/intregfile.hh b/src/arch/alpha/intregfile.hh
new file mode 100644
index 000000000..0d65f69e0
--- /dev/null
+++ b/src/arch/alpha/intregfile.hh
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Steve Reinhardt
+ * Gabe Black
+ */
+
+#ifndef __ARCH_ALPHA_INTREGFILE_HH__
+#define __ARCH_ALPHA_INTREGFILE_HH__
+
+#include "arch/alpha/types.hh"
+
+#include <iostream>
+#include <strings.h>
+
+class Checkpoint;
+
+namespace AlphaISA
+{
+ static inline std::string getIntRegName(RegIndex)
+ {
+ return "";
+ }
+
+ // redirected register map, really only used for the full system case.
+ extern const int reg_redir[NumIntRegs];
+
+ class IntRegFile
+ {
+ protected:
+ IntReg regs[NumIntRegs];
+
+ public:
+
+ IntReg readReg(int intReg)
+ {
+ return regs[intReg];
+ }
+
+ void setReg(int intReg, const IntReg &val)
+ {
+ regs[intReg] = val;
+ }
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+
+ void clear()
+ { bzero(regs, sizeof(regs)); }
+ };
+}
+
+#endif
diff --git a/src/arch/alpha/ipr.cc b/src/arch/alpha/ipr.cc
new file mode 100644
index 000000000..8e83102eb
--- /dev/null
+++ b/src/arch/alpha/ipr.cc
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include "arch/alpha/ipr.hh"
+
+namespace AlphaISA
+{
+ md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs] =
+ {
+ //Write only
+ RAW_IPR_HWINT_CLR, // H/W interrupt clear register
+ RAW_IPR_SL_XMIT, // serial line transmit register
+ RAW_IPR_DC_FLUSH,
+ RAW_IPR_IC_FLUSH, // instruction cache flush control
+ RAW_IPR_ALT_MODE, // alternate mode register
+ RAW_IPR_DTB_IA, // DTLB invalidate all register
+ RAW_IPR_DTB_IAP, // DTLB invalidate all process register
+ RAW_IPR_ITB_IA, // ITLB invalidate all register
+ RAW_IPR_ITB_IAP, // ITLB invalidate all process register
+
+ //Read only
+ RAW_IPR_INTID, // interrupt ID register
+ RAW_IPR_SL_RCV, // serial line receive register
+ RAW_IPR_MM_STAT, // data MMU fault status register
+ RAW_IPR_ITB_PTE_TEMP, // ITLB page table entry temp register
+ RAW_IPR_DTB_PTE_TEMP, // DTLB page table entry temporary register
+
+ RAW_IPR_ISR, // interrupt summary register
+ RAW_IPR_ITB_TAG, // ITLB tag register
+ RAW_IPR_ITB_PTE, // ITLB page table entry register
+ RAW_IPR_ITB_ASN, // ITLB address space register
+ RAW_IPR_ITB_IS, // ITLB invalidate select register
+ RAW_IPR_SIRR, // software interrupt request register
+ RAW_IPR_ASTRR, // asynchronous system trap request register
+ RAW_IPR_ASTER, // asynchronous system trap enable register
+ RAW_IPR_EXC_ADDR, // exception address register
+ RAW_IPR_EXC_SUM, // exception summary register
+ RAW_IPR_EXC_MASK, // exception mask register
+ RAW_IPR_PAL_BASE, // PAL base address register
+ RAW_IPR_ICM, // instruction current mode
+ RAW_IPR_IPLR, // interrupt priority level register
+ RAW_IPR_IFAULT_VA_FORM, // formatted faulting virtual addr register
+ RAW_IPR_IVPTBR, // virtual page table base register
+ RAW_IPR_ICSR, // instruction control and status register
+ RAW_IPR_IC_PERR_STAT, // inst cache parity error status register
+ RAW_IPR_PMCTR, // performance counter register
+
+ // PAL temporary registers...
+ // register meanings gleaned from osfpal.s source code
+ RAW_IPR_PALtemp0, // local scratch
+ RAW_IPR_PALtemp1, // local scratch
+ RAW_IPR_PALtemp2, // entUna
+ RAW_IPR_PALtemp3, // CPU specific impure area pointer
+ RAW_IPR_PALtemp4, // memory management temp
+ RAW_IPR_PALtemp5, // memory management temp
+ RAW_IPR_PALtemp6, // memory management temp
+ RAW_IPR_PALtemp7, // entIF
+ RAW_IPR_PALtemp8, // intmask
+ RAW_IPR_PALtemp9, // entSys
+ RAW_IPR_PALtemp10, // ??
+ RAW_IPR_PALtemp11, // entInt
+ RAW_IPR_PALtemp12, // entArith
+ RAW_IPR_PALtemp13, // reserved for platform specific PAL
+ RAW_IPR_PALtemp14, // reserved for platform specific PAL
+ RAW_IPR_PALtemp15, // reserved for platform specific PAL
+ RAW_IPR_PALtemp16, // scratch / whami<7:0> / mces<4:0>
+ RAW_IPR_PALtemp17, // sysval
+ RAW_IPR_PALtemp18, // usp
+ RAW_IPR_PALtemp19, // ksp
+ RAW_IPR_PALtemp20, // PTBR
+ RAW_IPR_PALtemp21, // entMM
+ RAW_IPR_PALtemp22, // kgp
+ RAW_IPR_PALtemp23, // PCBB
+
+ RAW_IPR_DTB_ASN, // DTLB address space number register
+ RAW_IPR_DTB_CM, // DTLB current mode register
+ RAW_IPR_DTB_TAG, // DTLB tag register
+ RAW_IPR_DTB_PTE, // DTLB page table entry register
+
+ RAW_IPR_VA, // fault virtual address register
+ RAW_IPR_VA_FORM, // formatted virtual address register
+ RAW_IPR_MVPTBR, // MTU virtual page table base register
+ RAW_IPR_DTB_IS, // DTLB invalidate single register
+ RAW_IPR_CC, // cycle counter register
+ RAW_IPR_CC_CTL, // cycle counter control register
+ RAW_IPR_MCSR, // MTU control register
+
+ RAW_IPR_DC_PERR_STAT, // Dcache parity error status register
+ RAW_IPR_DC_TEST_CTL, // Dcache test tag control register
+ RAW_IPR_DC_TEST_TAG, // Dcache test tag register
+ RAW_IPR_DC_TEST_TAG_TEMP, // Dcache test tag temporary register
+ RAW_IPR_DC_MODE, // Dcache mode register
+ RAW_IPR_MAF_MODE // miss address file mode register
+ };
+
+ int IprToMiscRegIndex[MaxInternalProcRegs];
+
+ void initializeIprTable()
+ {
+ static bool initialized = false;
+ if(initialized)
+ return;
+
+ memset(IprToMiscRegIndex, -1, MaxInternalProcRegs * sizeof(int));
+
+ for(int x = 0; x < NumInternalProcRegs; x++)
+ IprToMiscRegIndex[MiscRegIndexToIpr[x]] = x;
+ }
+}
+
diff --git a/src/arch/alpha/ipr.hh b/src/arch/alpha/ipr.hh
new file mode 100644
index 000000000..b55154764
--- /dev/null
+++ b/src/arch/alpha/ipr.hh
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Steve Reinhardt
+ * Gabe Black
+ */
+
+#ifndef __ARCH_ALPHA_IPR_HH__
+#define __ARCH_ALPHA_IPR_HH__
+
+namespace AlphaISA
+{
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Internal Processor Reigsters
+ //
+ enum md_ipr_names
+ {
+ RAW_IPR_ISR = 0x100, // interrupt summary register
+ RAW_IPR_ITB_TAG = 0x101, // ITLB tag register
+ RAW_IPR_ITB_PTE = 0x102, // ITLB page table entry register
+ RAW_IPR_ITB_ASN = 0x103, // ITLB address space register
+ RAW_IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp register
+ RAW_IPR_ITB_IA = 0x105, // ITLB invalidate all register
+ RAW_IPR_ITB_IAP = 0x106, // ITLB invalidate all process register
+ RAW_IPR_ITB_IS = 0x107, // ITLB invalidate select register
+ RAW_IPR_SIRR = 0x108, // software interrupt request register
+ RAW_IPR_ASTRR = 0x109, // asynchronous system trap request register
+ RAW_IPR_ASTER = 0x10a, // asynchronous system trap enable register
+ RAW_IPR_EXC_ADDR = 0x10b, // exception address register
+ RAW_IPR_EXC_SUM = 0x10c, // exception summary register
+ RAW_IPR_EXC_MASK = 0x10d, // exception mask register
+ RAW_IPR_PAL_BASE = 0x10e, // PAL base address register
+ RAW_IPR_ICM = 0x10f, // instruction current mode
+ RAW_IPR_IPLR = 0x110, // interrupt priority level register
+ RAW_IPR_INTID = 0x111, // interrupt ID register
+ RAW_IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr register
+ RAW_IPR_IVPTBR = 0x113, // virtual page table base register
+ RAW_IPR_HWINT_CLR = 0x115, // H/W interrupt clear register
+ RAW_IPR_SL_XMIT = 0x116, // serial line transmit register
+ RAW_IPR_SL_RCV = 0x117, // serial line receive register
+ RAW_IPR_ICSR = 0x118, // instruction control and status register
+ RAW_IPR_IC_FLUSH = 0x119, // instruction cache flush control
+ RAW_IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status register
+ RAW_IPR_PMCTR = 0x11c, // performance counter register
+
+ // PAL temporary registers...
+ // register meanings gleaned from osfpal.s source code
+ RAW_IPR_PALtemp0 = 0x140, // local scratch
+ RAW_IPR_PALtemp1 = 0x141, // local scratch
+ RAW_IPR_PALtemp2 = 0x142, // entUna
+ RAW_IPR_PALtemp3 = 0x143, // CPU specific impure area pointer
+ RAW_IPR_PALtemp4 = 0x144, // memory management temp
+ RAW_IPR_PALtemp5 = 0x145, // memory management temp
+ RAW_IPR_PALtemp6 = 0x146, // memory management temp
+ RAW_IPR_PALtemp7 = 0x147, // entIF
+ RAW_IPR_PALtemp8 = 0x148, // intmask
+ RAW_IPR_PALtemp9 = 0x149, // entSys
+ RAW_IPR_PALtemp10 = 0x14a, // ??
+ RAW_IPR_PALtemp11 = 0x14b, // entInt
+ RAW_IPR_PALtemp12 = 0x14c, // entArith
+ RAW_IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL
+ RAW_IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL
+ RAW_IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL
+ RAW_IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0>
+ RAW_IPR_PALtemp17 = 0x151, // sysval
+ RAW_IPR_PALtemp18 = 0x152, // usp
+ RAW_IPR_PALtemp19 = 0x153, // ksp
+ RAW_IPR_PALtemp20 = 0x154, // PTBR
+ RAW_IPR_PALtemp21 = 0x155, // entMM
+ RAW_IPR_PALtemp22 = 0x156, // kgp
+ RAW_IPR_PALtemp23 = 0x157, // PCBB
+
+ RAW_IPR_DTB_ASN = 0x200, // DTLB address space number register
+ RAW_IPR_DTB_CM = 0x201, // DTLB current mode register
+ RAW_IPR_DTB_TAG = 0x202, // DTLB tag register
+ RAW_IPR_DTB_PTE = 0x203, // DTLB page table entry register
+ RAW_IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary register
+
+ RAW_IPR_MM_STAT = 0x205, // data MMU fault status register
+ RAW_IPR_VA = 0x206, // fault virtual address register
+ RAW_IPR_VA_FORM = 0x207, // formatted virtual address register
+ RAW_IPR_MVPTBR = 0x208, // MTU virtual page table base register
+ RAW_IPR_DTB_IAP = 0x209, // DTLB invalidate all process register
+ RAW_IPR_DTB_IA = 0x20a, // DTLB invalidate all register
+ RAW_IPR_DTB_IS = 0x20b, // DTLB invalidate single register
+ RAW_IPR_ALT_MODE = 0x20c, // alternate mode register
+ RAW_IPR_CC = 0x20d, // cycle counter register
+ RAW_IPR_CC_CTL = 0x20e, // cycle counter control register
+ RAW_IPR_MCSR = 0x20f, // MTU control register
+
+ RAW_IPR_DC_FLUSH = 0x210,
+ RAW_IPR_DC_PERR_STAT = 0x212, // Dcache parity error status register
+ RAW_IPR_DC_TEST_CTL = 0x213, // Dcache test tag control register
+ RAW_IPR_DC_TEST_TAG = 0x214, // Dcache test tag register
+ RAW_IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary register
+ RAW_IPR_DC_MODE = 0x216, // Dcache mode register
+ RAW_IPR_MAF_MODE = 0x217, // miss address file mode register
+
+ MaxInternalProcRegs // number of IPR registers
+ };
+
+ enum MiscRegIpr
+ {
+ //Write only
+ MinWriteOnlyIpr,
+ IPR_HWINT_CLR = MinWriteOnlyIpr,
+ IPR_SL_XMIT,
+ IPR_DC_FLUSH,
+ IPR_IC_FLUSH,
+ IPR_ALT_MODE,
+ IPR_DTB_IA,
+ IPR_DTB_IAP,
+ IPR_ITB_IA,
+ MaxWriteOnlyIpr,
+ IPR_ITB_IAP = MaxWriteOnlyIpr,
+
+ //Read only
+ MinReadOnlyIpr,
+ IPR_INTID = MinReadOnlyIpr,
+ IPR_SL_RCV,
+ IPR_MM_STAT,
+ IPR_ITB_PTE_TEMP,
+ MaxReadOnlyIpr,
+ IPR_DTB_PTE_TEMP = MaxReadOnlyIpr,
+
+ IPR_ISR,
+ IPR_ITB_TAG,
+ IPR_ITB_PTE,
+ IPR_ITB_ASN,
+ IPR_ITB_IS,
+ IPR_SIRR,
+ IPR_ASTRR,
+ IPR_ASTER,
+ IPR_EXC_ADDR,
+ IPR_EXC_SUM,
+ IPR_EXC_MASK,
+ IPR_PAL_BASE,
+ IPR_ICM,
+ IPR_IPLR,
+ IPR_IFAULT_VA_FORM,
+ IPR_IVPTBR,
+ IPR_ICSR,
+ IPR_IC_PERR_STAT,
+ IPR_PMCTR,
+
+ // PAL temporary registers...
+ // register meanings gleaned from osfpal.s source code
+ IPR_PALtemp0,
+ IPR_PALtemp1,
+ IPR_PALtemp2,
+ IPR_PALtemp3,
+ IPR_PALtemp4,
+ IPR_PALtemp5,
+ IPR_PALtemp6,
+ IPR_PALtemp7,
+ IPR_PALtemp8,
+ IPR_PALtemp9,
+ IPR_PALtemp10,
+ IPR_PALtemp11,
+ IPR_PALtemp12,
+ IPR_PALtemp13,
+ IPR_PALtemp14,
+ IPR_PALtemp15,
+ IPR_PALtemp16,
+ IPR_PALtemp17,
+ IPR_PALtemp18,
+ IPR_PALtemp19,
+ IPR_PALtemp20,
+ IPR_PALtemp21,
+ IPR_PALtemp22,
+ IPR_PALtemp23,
+
+ IPR_DTB_ASN,
+ IPR_DTB_CM,
+ IPR_DTB_TAG,
+ IPR_DTB_PTE,
+
+ IPR_VA,
+ IPR_VA_FORM,
+ IPR_MVPTBR,
+ IPR_DTB_IS,
+ IPR_CC,
+ IPR_CC_CTL,
+ IPR_MCSR,
+
+ IPR_DC_PERR_STAT,
+ IPR_DC_TEST_CTL,
+ IPR_DC_TEST_TAG,
+ IPR_DC_TEST_TAG_TEMP,
+ IPR_DC_MODE,
+ IPR_MAF_MODE,
+
+ NumInternalProcRegs // number of IPR registers
+ };
+
+ inline bool IprIsWritable(int index)
+ {
+ return index < MinReadOnlyIpr || index > MaxReadOnlyIpr;
+ }
+
+ inline bool IprIsReadable(int index)
+ {
+ return index < MinWriteOnlyIpr || index > MaxWriteOnlyIpr;
+ }
+
+ extern md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs];
+ extern int IprToMiscRegIndex[MaxInternalProcRegs];
+
+ void initializeIprTable();
+}
+
+#endif
diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa
index 5bd19b677..7014d4c22 100644
--- a/src/arch/alpha/isa/decoder.isa
+++ b/src/arch/alpha/isa/decoder.isa
@@ -629,7 +629,7 @@ decode OPCODE default Unknown::unknown() {
/* Rb is a fake dependency so here is a fun way to get
* the parser to understand that.
*/
- Ra = xc->readMiscRegWithEffect(AlphaISA::IPR_CC, fault) + (Rb & 0);
+ Ra = xc->readMiscRegWithEffect(AlphaISA::IPR_CC) + (Rb & 0);
#else
Ra = curTick;
@@ -661,12 +661,12 @@ decode OPCODE default Unknown::unknown() {
#if FULL_SYSTEM
format BasicOperate {
0xe000: rc({{
- Ra = xc->readIntrFlag();
- xc->setIntrFlag(0);
+ Ra = IntrFlag;
+ IntrFlag = 0;
}}, IsNonSpeculative, IsUnverifiable);
0xf000: rs({{
- Ra = xc->readIntrFlag();
- xc->setIntrFlag(1);
+ Ra = IntrFlag;
+ IntrFlag = 1;
}}, IsNonSpeculative, IsUnverifiable);
}
#else
@@ -681,7 +681,7 @@ decode OPCODE default Unknown::unknown() {
0x00: CallPal::call_pal({{
if (!palValid ||
(palPriv
- && xc->readMiscRegWithEffect(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) {
+ && xc->readMiscRegWithEffect(AlphaISA::IPR_ICM) != AlphaISA::mode_kernel)) {
// invalid pal function code, or attempt to do privileged
// PAL call in non-kernel mode
fault = new UnimplementedOpcodeFault;
@@ -693,7 +693,7 @@ decode OPCODE default Unknown::unknown() {
if (dopal) {
xc->setMiscRegWithEffect(AlphaISA::IPR_EXC_ADDR, NPC);
- NPC = xc->readMiscRegWithEffect(AlphaISA::IPR_PAL_BASE, fault) + palOffset;
+ NPC = xc->readMiscRegWithEffect(AlphaISA::IPR_PAL_BASE) + palOffset;
}
}
}}, IsNonSpeculative);
@@ -745,7 +745,13 @@ decode OPCODE default Unknown::unknown() {
0: OpcdecFault::hw_mfpr();
format HwMoveIPR {
1: hw_mfpr({{
- Ra = xc->readMiscRegWithEffect(ipr_index, fault);
+ int miscRegIndex = (ipr_index < MaxInternalProcRegs) ?
+ IprToMiscRegIndex[ipr_index] : -1;
+ if(miscRegIndex < 0 || !IprIsReadable(miscRegIndex) ||
+ miscRegIndex >= NumInternalProcRegs)
+ fault = new UnimplementedOpcodeFault;
+ else
+ Ra = xc->readMiscRegWithEffect(miscRegIndex);
}}, IsIprAccess);
}
}
@@ -754,7 +760,13 @@ decode OPCODE default Unknown::unknown() {
0: OpcdecFault::hw_mtpr();
format HwMoveIPR {
1: hw_mtpr({{
- xc->setMiscRegWithEffect(ipr_index, Ra);
+ int miscRegIndex = (ipr_index < MaxInternalProcRegs) ?
+ IprToMiscRegIndex[ipr_index] : -1;
+ if(miscRegIndex < 0 || !IprIsWritable(miscRegIndex) ||
+ miscRegIndex >= NumInternalProcRegs)
+ fault = new UnimplementedOpcodeFault;
+ else
+ xc->setMiscRegWithEffect(miscRegIndex, Ra);
if (traceData) { traceData->setData(Ra); }
}}, IsIprAccess);
}
@@ -783,12 +795,6 @@ decode OPCODE default Unknown::unknown() {
0x04: quiesceTime({{
R0 = AlphaPseudo::quiesceTime(xc->tcBase());
}}, IsNonSpeculative, IsUnverifiable);
- 0x10: ivlb({{
- AlphaPseudo::ivlb(xc->tcBase());
- }}, No_OpClass, IsNonSpeculative);
- 0x11: ivle({{
- AlphaPseudo::ivle(xc->tcBase());
- }}, No_OpClass, IsNonSpeculative);
0x20: m5exit_old({{
AlphaPseudo::m5exit_old(xc->tcBase());
}}, No_OpClass, IsNonSpeculative);
diff --git a/src/arch/alpha/isa/fp.isa b/src/arch/alpha/isa/fp.isa
index b4339a1b7..3b5575f62 100644
--- a/src/arch/alpha/isa/fp.isa
+++ b/src/arch/alpha/isa/fp.isa
@@ -46,7 +46,7 @@ output exec {{
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
{
Fault fault = NoFault; // dummy... this ipr access should not fault
- if (!EV5::ICSR_FPE(xc->readMiscRegWithEffect(AlphaISA::IPR_ICSR, fault))) {
+ if (!EV5::ICSR_FPE(xc->readMiscRegWithEffect(AlphaISA::IPR_ICSR))) {
fault = new FloatEnableFault;
}
return fault;
@@ -229,7 +229,7 @@ def template FloatingPointExecute {{
%(code)s;
} else {
fesetround(getC99RoundingMode(
- xc->readMiscReg(AlphaISA::Fpcr_DepTag)));
+ xc->readMiscReg(AlphaISA::MISCREG_FPCR)));
%(code)s;
fesetround(FE_TONEAREST);
}
diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa
index 2024b1117..6e65cf9d3 100644
--- a/src/arch/alpha/isa/main.isa
+++ b/src/arch/alpha/isa/main.isa
@@ -71,6 +71,7 @@ output exec {{
#if FULL_SYSTEM
#include "sim/pseudo_inst.hh"
#endif
+#include "arch/alpha/ipr.hh"
#include "base/fenv.hh"
#include "config/ss_compatible_fp.hh"
#include "cpu/base.hh"
@@ -183,8 +184,9 @@ def operands {{
'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3),
'Mem': ('Mem', 'uq', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
'NPC': ('NPC', 'uq', None, ( None, None, 'IsControl' ), 4),
- 'Runiq': ('ControlReg', 'uq', 'TheISA::Uniq_DepTag', None, 1),
- 'FPCR': (' ControlReg', 'uq', 'TheISA::Fpcr_DepTag', None, 1),
+ 'Runiq': ('ControlReg', 'uq', 'MISCREG_UNIQ', None, 1),
+ 'FPCR': ('ControlReg', 'uq', 'MISCREG_FPCR', None, 1),
+ 'IntrFlag': ('ControlReg', 'uq', 'MISCREG_INTR', None, 1),
# The next two are hacks for non-full-system call-pal emulation
'R0': ('IntReg', 'uq', '0', None, 1),
'R16': ('IntReg', 'uq', '16', None, 1),
@@ -214,11 +216,6 @@ output header {{
/// live here and not in the AlphaISA namespace.
enum DependenceTags {
FP_Base_DepTag = AlphaISA::FP_Base_DepTag,
- Fpcr_DepTag = AlphaISA::Fpcr_DepTag,
- Uniq_DepTag = AlphaISA::Uniq_DepTag,
- Lock_Flag_DepTag = AlphaISA::Lock_Flag_DepTag,
- Lock_Addr_DepTag = AlphaISA::Lock_Addr_DepTag,
- IPR_Base_DepTag = AlphaISA::IPR_Base_DepTag
};
/// Constructor.
diff --git a/src/arch/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh
index 4f439b8df..35d9ce843 100644
--- a/src/arch/alpha/isa_traits.hh
+++ b/src/arch/alpha/isa_traits.hh
@@ -34,6 +34,7 @@
namespace LittleEndianGuest {}
+#include "arch/alpha/ipr.hh"
#include "arch/alpha/types.hh"
#include "config/full_system.hh"
#include "sim/host.hh"
@@ -49,12 +50,7 @@ namespace AlphaISA
// 0..31 are the integer regs 0..31
// 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
FP_Base_DepTag = 40,
- Ctrl_Base_DepTag = 72,
- Fpcr_DepTag = 72, // floating point control register
- Uniq_DepTag = 73,
- Lock_Flag_DepTag = 74,
- Lock_Addr_DepTag = 75,
- IPR_Base_DepTag = 76
+ Ctrl_Base_DepTag = 72
};
StaticInstPtr decodeInst(ExtMachInst);
@@ -118,7 +114,6 @@ namespace AlphaISA
NumInterruptLevels = INTLEVEL_EXTERNAL_MAX
};
-
// EV5 modes
enum mode_type
{
@@ -131,100 +126,6 @@ namespace AlphaISA
#endif
-#if FULL_SYSTEM
- ////////////////////////////////////////////////////////////////////////
- //
- // Internal Processor Reigsters
- //
- enum md_ipr_names
- {
- IPR_ISR = 0x100, // interrupt summary register
- IPR_ITB_TAG = 0x101, // ITLB tag register
- IPR_ITB_PTE = 0x102, // ITLB page table entry register
- IPR_ITB_ASN = 0x103, // ITLB address space register
- IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp register
- IPR_ITB_IA = 0x105, // ITLB invalidate all register
- IPR_ITB_IAP = 0x106, // ITLB invalidate all process register
- IPR_ITB_IS = 0x107, // ITLB invalidate select register
- IPR_SIRR = 0x108, // software interrupt request register
- IPR_ASTRR = 0x109, // asynchronous system trap request register
- IPR_ASTER = 0x10a, // asynchronous system trap enable register
- IPR_EXC_ADDR = 0x10b, // exception address register
- IPR_EXC_SUM = 0x10c, // exception summary register
- IPR_EXC_MASK = 0x10d, // exception mask register
- IPR_PAL_BASE = 0x10e, // PAL base address register
- IPR_ICM = 0x10f, // instruction current mode
- IPR_IPLR = 0x110, // interrupt priority level register
- IPR_INTID = 0x111, // interrupt ID register
- IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr register
- IPR_IVPTBR = 0x113, // virtual page table base register
- IPR_HWINT_CLR = 0x115, // H/W interrupt clear register
- IPR_SL_XMIT = 0x116, // serial line transmit register
- IPR_SL_RCV = 0x117, // serial line receive register
- IPR_ICSR = 0x118, // instruction control and status register
- IPR_IC_FLUSH = 0x119, // instruction cache flush control
- IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status register
- IPR_PMCTR = 0x11c, // performance counter register
-
- // PAL temporary registers...
- // register meanings gleaned from osfpal.s source code
- IPR_PALtemp0 = 0x140, // local scratch
- IPR_PALtemp1 = 0x141, // local scratch
- IPR_PALtemp2 = 0x142, // entUna
- IPR_PALtemp3 = 0x143, // CPU specific impure area pointer
- IPR_PALtemp4 = 0x144, // memory management temp
- IPR_PALtemp5 = 0x145, // memory management temp
- IPR_PALtemp6 = 0x146, // memory management temp
- IPR_PALtemp7 = 0x147, // entIF
- IPR_PALtemp8 = 0x148, // intmask
- IPR_PALtemp9 = 0x149, // entSys
- IPR_PALtemp10 = 0x14a, // ??
- IPR_PALtemp11 = 0x14b, // entInt
- IPR_PALtemp12 = 0x14c, // entArith
- IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL
- IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL
- IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL
- IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0>
- IPR_PALtemp17 = 0x151, // sysval
- IPR_PALtemp18 = 0x152, // usp
- IPR_PALtemp19 = 0x153, // ksp
- IPR_PALtemp20 = 0x154, // PTBR
- IPR_PALtemp21 = 0x155, // entMM
- IPR_PALtemp22 = 0x156, // kgp
- IPR_PALtemp23 = 0x157, // PCBB
-
- IPR_DTB_ASN = 0x200, // DTLB address space number register
- IPR_DTB_CM = 0x201, // DTLB current mode register
- IPR_DTB_TAG = 0x202, // DTLB tag register
- IPR_DTB_PTE = 0x203, // DTLB page table entry register
- IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary register
-
- IPR_MM_STAT = 0x205, // data MMU fault status register
- IPR_VA = 0x206, // fault virtual address register
- IPR_VA_FORM = 0x207, // formatted virtual address register
- IPR_MVPTBR = 0x208, // MTU virtual page table base register
- IPR_DTB_IAP = 0x209, // DTLB invalidate all process register
- IPR_DTB_IA = 0x20a, // DTLB invalidate all register
- IPR_DTB_IS = 0x20b, // DTLB invalidate single register
- IPR_ALT_MODE = 0x20c, // alternate mode register
- IPR_CC = 0x20d, // cycle counter register
- IPR_CC_CTL = 0x20e, // cycle counter control register
- IPR_MCSR = 0x20f, // MTU control register
-
- IPR_DC_FLUSH = 0x210,
- IPR_DC_PERR_STAT = 0x212, // Dcache parity error status register
- IPR_DC_TEST_CTL = 0x213, // Dcache test tag control register
- IPR_DC_TEST_TAG = 0x214, // Dcache test tag register
- IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary register
- IPR_DC_MODE = 0x216, // Dcache mode register
- IPR_MAF_MODE = 0x217, // miss address file mode register
-
- NumInternalProcRegs // number of IPR registers
- };
-#else
- const int NumInternalProcRegs = 0;
-#endif
-
// Constants Related to the number of registers
const int NumIntArchRegs = 32;
@@ -279,9 +180,6 @@ namespace AlphaISA
// Alpha UNOP (ldq_u r31,0(r0))
const ExtMachInst NoopMachInst = 0x2ffe0000;
- // redirected register map, really only used for the full system case.
- extern const int reg_redir[NumIntRegs];
-
};
#endif // __ARCH_ALPHA_ISA_TRAITS_HH__
diff --git a/src/arch/alpha/kernel_stats.cc b/src/arch/alpha/kernel_stats.cc
new file mode 100644
index 000000000..6fc3cb72f
--- /dev/null
+++ b/src/arch/alpha/kernel_stats.cc
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Lisa Hsu
+ * Nathan Binkert
+ */
+
+#include <map>
+#include <stack>
+#include <string>
+
+#include "arch/alpha/kernel_stats.hh"
+#include "arch/alpha/osfpal.hh"
+#include "base/trace.hh"
+#include "cpu/thread_context.hh"
+#include "kern/tru64/tru64_syscalls.hh"
+#include "sim/system.hh"
+
+using namespace std;
+using namespace Stats;
+
+namespace AlphaISA {
+namespace Kernel {
+
+const char *modestr[] = { "kernel", "user", "idle" };
+
+Statistics::Statistics(System *system)
+ : ::Kernel::Statistics(system),
+ idleProcess((Addr)-1), themode(kernel), lastModeTick(0)
+{
+}
+
+void
+Statistics::regStats(const string &_name)
+{
+ ::Kernel::Statistics::regStats(_name);
+
+ _callpal
+ .init(256)
+ .name(name() + ".callpal")
+ .desc("number of callpals executed")
+ .flags(total | pdf | nozero | nonan)
+ ;
+
+ for (int i = 0; i < PAL::NumCodes; ++i) {
+ const char *str = PAL::name(i);
+ if (str)
+ _callpal.subname(i, str);
+ }
+
+ _hwrei
+ .name(name() + ".inst.hwrei")
+ .desc("number of hwrei instructions executed")
+ ;
+
+ _mode
+ .init(cpu_mode_num)
+ .name(name() + ".mode_switch")
+ .desc("number of protection mode switches")
+ ;
+
+ for (int i = 0; i < cpu_mode_num; ++i)
+ _mode.subname(i, modestr[i]);
+
+ _modeGood
+ .init(cpu_mode_num)
+ .name(name() + ".mode_good")
+ ;
+
+ for (int i = 0; i < cpu_mode_num; ++i)
+ _modeGood.subname(i, modestr[i]);
+
+ _modeFraction
+ .name(name() + ".mode_switch_good")
+ .desc("fraction of useful protection mode switches")
+ .flags(total)
+ ;
+
+ for (int i = 0; i < cpu_mode_num; ++i)
+ _modeFraction.subname(i, modestr[i]);
+
+ _modeFraction = _modeGood / _mode;
+
+ _modeTicks
+ .init(cpu_mode_num)
+ .name(name() + ".mode_ticks")
+ .desc("number of ticks spent at the given mode")
+ .flags(pdf)
+ ;
+ for (int i = 0; i < cpu_mode_num; ++i)
+ _modeTicks.subname(i, modestr[i]);
+
+ _swap_context
+ .name(name() + ".swap_context")
+ .desc("number of times the context was actually changed")
+ ;
+}
+
+void
+Statistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc)
+{
+ assert(themode == kernel);
+ idleProcess = idlepcbb;
+ themode = idle;
+ changeMode(themode, tc);
+}
+
+void
+Statistics::changeMode(cpu_mode newmode, ThreadContext *tc)
+{
+ _mode[newmode]++;
+
+ if (newmode == themode)
+ return;
+
+ DPRINTF(Context, "old mode=%-8s new mode=%-8s\n",
+ modestr[themode], modestr[newmode]);
+
+ _modeGood[newmode]++;
+ _modeTicks[themode] += curTick - lastModeTick;
+
+ lastModeTick = curTick;
+ themode = newmode;
+}
+
+void
+Statistics::mode(cpu_mode newmode, ThreadContext *tc)
+{
+ Addr pcbb = tc->readMiscReg(AlphaISA::IPR_PALtemp23);
+
+ if (newmode == kernel && pcbb == idleProcess)
+ newmode = idle;
+
+ changeMode(newmode, tc);
+}
+
+void
+Statistics::context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc)
+{
+ assert(themode != user);
+
+ _swap_context++;
+ changeMode(newpcbb == idleProcess ? idle : kernel, tc);
+}
+
+void
+Statistics::callpal(int code, ThreadContext *tc)
+{
+ if (!PAL::name(code))
+ return;
+
+ _callpal[code]++;
+
+ switch (code) {
+ case PAL::callsys: {
+ int number = tc->readIntReg(0);
+ if (SystemCalls<Tru64>::validSyscallNumber(number)) {
+ int cvtnum = SystemCalls<Tru64>::convert(number);
+ _syscall[cvtnum]++;
+ }
+ } break;
+ }
+}
+
+void
+Statistics::serialize(ostream &os)
+{
+ ::Kernel::Statistics::serialize(os);
+ int exemode = themode;
+ SERIALIZE_SCALAR(exemode);
+ SERIALIZE_SCALAR(idleProcess);
+ SERIALIZE_SCALAR(lastModeTick);
+}
+
+void
+Statistics::unserialize(Checkpoint *cp, const string &section)
+{
+ ::Kernel::Statistics::unserialize(cp, section);
+ int exemode;
+ UNSERIALIZE_SCALAR(exemode);
+ UNSERIALIZE_SCALAR(idleProcess);
+ UNSERIALIZE_SCALAR(lastModeTick);
+ themode = (cpu_mode)exemode;
+}
+
+} /* end namespace AlphaISA::Kernel */
+} /* end namespace AlphaISA */
diff --git a/src/arch/alpha/kernel_stats.hh b/src/arch/alpha/kernel_stats.hh
new file mode 100644
index 000000000..7b8640ad7
--- /dev/null
+++ b/src/arch/alpha/kernel_stats.hh
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Lisa Hsu
+ * Nathan Binkert
+ */
+
+#ifndef __ARCH_ALPHA_KERNEL_STATS_HH__
+#define __ARCH_ALPHA_KERNEL_STATS_HH__
+
+#include <map>
+#include <stack>
+#include <string>
+#include <vector>
+
+#include "cpu/static_inst.hh"
+#include "kern/kernel_stats.hh"
+
+class BaseCPU;
+class ThreadContext;
+class FnEvent;
+// What does kernel stats expect is included?
+class System;
+
+namespace AlphaISA {
+namespace Kernel {
+
+enum cpu_mode { kernel, user, idle, cpu_mode_num };
+extern const char *modestr[];
+
+class Statistics : public ::Kernel::Statistics
+{
+ protected:
+ Addr idleProcess;
+ cpu_mode themode;
+ Tick lastModeTick;
+
+ void changeMode(cpu_mode newmode, ThreadContext *tc);
+
+ private:
+ Stats::Vector<> _callpal;
+// Stats::Vector<> _faults;
+
+ Stats::Vector<> _mode;
+ Stats::Vector<> _modeGood;
+ Stats::Formula _modeFraction;
+ Stats::Vector<> _modeTicks;
+
+ Stats::Scalar<> _swap_context;
+
+ public:
+ Statistics(System *system);
+
+ void regStats(const std::string &name);
+
+ public:
+ void mode(cpu_mode newmode, ThreadContext *tc);
+ void context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc);
+ void callpal(int code, ThreadContext *tc);
+ void hwrei() { _hwrei++; }
+
+ void setIdleProcess(Addr idle, ThreadContext *tc);
+
+ public:
+ void serialize(std::ostream &os);
+ void unserialize(Checkpoint *cp, const std::string &section);
+};
+
+} /* end namespace AlphaISA::Kernel */
+} /* end namespace AlphaISA */
+
+#endif // __ARCH_ALPHA_KERNEL_STATS_HH__
diff --git a/src/base/kgdb.h b/src/arch/alpha/kgdb.h
index 104244d0b..912cf6d45 100644
--- a/src/base/kgdb.h
+++ b/src/arch/alpha/kgdb.h
@@ -160,15 +160,4 @@
/* Too much? Must be large enough for register transfer. */
#define KGDB_BUFLEN 1024
-/*
- * Kernel Entry Vectors. [OSF/1 PALcode Specific]
- */
-
-#define ALPHA_KENTRY_INT 0
-#define ALPHA_KENTRY_ARITH 1
-#define ALPHA_KENTRY_MM 2
-#define ALPHA_KENTRY_IF 3
-#define ALPHA_KENTRY_UNA 4
-#define ALPHA_KENTRY_SYS 5
-
#endif /* __KGDB_H__ */
diff --git a/src/arch/alpha/linux/system.cc b/src/arch/alpha/linux/system.cc
index 7cf234eeb..9a452e10f 100644
--- a/src/arch/alpha/linux/system.cc
+++ b/src/arch/alpha/linux/system.cc
@@ -42,6 +42,7 @@
#include "arch/arguments.hh"
#include "arch/vtophys.hh"
+#include "arch/alpha/idle_event.hh"
#include "arch/alpha/linux/system.hh"
#include "arch/alpha/linux/threadinfo.hh"
#include "arch/alpha/system.hh"
diff --git a/src/arch/alpha/linux/system.hh b/src/arch/alpha/linux/system.hh
index 6921ba820..14396f8ab 100644
--- a/src/arch/alpha/linux/system.hh
+++ b/src/arch/alpha/linux/system.hh
@@ -38,6 +38,7 @@ class ThreadContext;
class BreakPCEvent;
class IdleStartEvent;
+#include "arch/alpha/idle_event.hh"
#include "arch/alpha/system.hh"
#include "kern/linux/events.hh"
diff --git a/src/arch/alpha/locked_mem.hh b/src/arch/alpha/locked_mem.hh
index 368ea2895..52fe24173 100644
--- a/src/arch/alpha/locked_mem.hh
+++ b/src/arch/alpha/locked_mem.hh
@@ -37,7 +37,7 @@
* ISA-specific helper functions for locked memory accesses.
*/
-#include "arch/isa_traits.hh"
+#include "arch/alpha/miscregfile.hh"
#include "base/misc.hh"
#include "mem/request.hh"
@@ -48,8 +48,8 @@ template <class XC>
inline void
handleLockedRead(XC *xc, Request *req)
{
- xc->setMiscReg(Lock_Addr_DepTag, req->getPaddr() & ~0xf);
- xc->setMiscReg(Lock_Flag_DepTag, true);
+ xc->setMiscReg(MISCREG_LOCKADDR, req->getPaddr() & ~0xf);
+ xc->setMiscReg(MISCREG_LOCKFLAG, true);
}
@@ -63,13 +63,13 @@ handleLockedWrite(XC *xc, Request *req)
req->setScResult(2);
} else {
// standard store conditional
- bool lock_flag = xc->readMiscReg(Lock_Flag_DepTag);
- Addr lock_addr = xc->readMiscReg(Lock_Addr_DepTag);
+ bool lock_flag = xc->readMiscReg(MISCREG_LOCKFLAG);
+ Addr lock_addr = xc->readMiscReg(MISCREG_LOCKADDR);
if (!lock_flag || (req->getPaddr() & ~0xf) != lock_addr) {
// Lock flag not set or addr mismatch in CPU;
// don't even bother sending to memory system
req->setScResult(0);
- xc->setMiscReg(Lock_Flag_DepTag, false);
+ xc->setMiscReg(MISCREG_LOCKFLAG, false);
// the rest of this code is not architectural;
// it's just a debugging aid to help detect
// livelock by warning on long sequences of failed
diff --git a/src/arch/alpha/miscregfile.cc b/src/arch/alpha/miscregfile.cc
new file mode 100644
index 000000000..4cf57a690
--- /dev/null
+++ b/src/arch/alpha/miscregfile.cc
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Steve Reinhardt
+ * Gabe Black
+ * Kevin Lim
+ */
+
+#include "arch/alpha/miscregfile.hh"
+#include "base/misc.hh"
+
+namespace AlphaISA
+{
+
+ void
+ MiscRegFile::serialize(std::ostream &os)
+ {
+ SERIALIZE_SCALAR(fpcr);
+ SERIALIZE_SCALAR(uniq);
+ SERIALIZE_SCALAR(lock_flag);
+ SERIALIZE_SCALAR(lock_addr);
+#if FULL_SYSTEM
+ SERIALIZE_ARRAY(ipr, NumInternalProcRegs);
+#endif
+ }
+
+ void
+ MiscRegFile::unserialize(Checkpoint *cp, const std::string &section)
+ {
+ UNSERIALIZE_SCALAR(fpcr);
+ UNSERIALIZE_SCALAR(uniq);
+ UNSERIALIZE_SCALAR(lock_flag);
+ UNSERIALIZE_SCALAR(lock_addr);
+#if FULL_SYSTEM
+ UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs);
+#endif
+ }
+
+ MiscReg
+ MiscRegFile::readReg(int misc_reg)
+ {
+ switch(misc_reg) {
+ case MISCREG_FPCR:
+ return fpcr;
+ case MISCREG_UNIQ:
+ return uniq;
+ case MISCREG_LOCKFLAG:
+ return lock_flag;
+ case MISCREG_LOCKADDR:
+ return lock_addr;
+ case MISCREG_INTR:
+ return intr_flag;
+#if FULL_SYSTEM
+ default:
+ assert(misc_reg < NumInternalProcRegs);
+ return ipr[misc_reg];
+#else
+ default:
+ panic("Attempt to read an invalid misc register!");
+ return 0;
+#endif
+ }
+ }
+
+ MiscReg
+ MiscRegFile::readRegWithEffect(int misc_reg, ThreadContext *tc)
+ {
+#if FULL_SYSTEM
+ return readIpr(misc_reg, tc);
+#else
+ panic("No faulting misc regs in SE mode!");
+ return 0;
+#endif
+ }
+
+ void
+ MiscRegFile::setReg(int misc_reg, const MiscReg &val)
+ {
+ switch(misc_reg) {
+ case MISCREG_FPCR:
+ fpcr = val;
+ return;
+ case MISCREG_UNIQ:
+ uniq = val;
+ return;
+ case MISCREG_LOCKFLAG:
+ lock_flag = val;
+ return;
+ case MISCREG_LOCKADDR:
+ lock_addr = val;
+ return;
+ case MISCREG_INTR:
+ intr_flag = val;
+ return;
+#if FULL_SYSTEM
+ default:
+ assert(misc_reg < NumInternalProcRegs);
+ ipr[misc_reg] = val;
+ return;
+#else
+ default:
+ panic("Attempt to write to an invalid misc register!");
+#endif
+ }
+ }
+
+ void
+ MiscRegFile::setRegWithEffect(int misc_reg, const MiscReg &val,
+ ThreadContext *tc)
+ {
+#if FULL_SYSTEM
+ switch(misc_reg) {
+ case MISCREG_FPCR:
+ fpcr = val;
+ return;
+ case MISCREG_UNIQ:
+ uniq = val;
+ return;
+ case MISCREG_LOCKFLAG:
+ lock_flag = val;
+ return;
+ case MISCREG_LOCKADDR:
+ lock_addr = val;
+ return;
+ case MISCREG_INTR:
+ intr_flag = val;
+ return;
+ default:
+ return setIpr(misc_reg, val, tc);
+ }
+#else
+ //panic("No registers with side effects in SE mode!");
+ return;
+#endif
+ }
+
+}
diff --git a/src/arch/alpha/miscregfile.hh b/src/arch/alpha/miscregfile.hh
new file mode 100644
index 000000000..31b3e59b3
--- /dev/null
+++ b/src/arch/alpha/miscregfile.hh
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Steve Reinhardt
+ * Gabe Black
+ */
+
+#ifndef __ARCH_ALPHA_MISCREGFILE_HH__
+#define __ARCH_ALPHA_MISCREGFILE_HH__
+
+#include "arch/alpha/ipr.hh"
+#include "arch/alpha/types.hh"
+#include "config/full_system.hh"
+#include "sim/host.hh"
+#include "sim/serialize.hh"
+
+#include <iostream>
+
+class Checkpoint;
+class ThreadContext;
+
+namespace AlphaISA
+{
+ enum MiscRegIndex
+ {
+ MISCREG_FPCR = NumInternalProcRegs,
+ MISCREG_UNIQ,
+ MISCREG_LOCKFLAG,
+ MISCREG_LOCKADDR,
+ MISCREG_INTR
+ };
+
+ static inline std::string getMiscRegName(RegIndex)
+ {
+ return "";
+ }
+
+ class MiscRegFile {
+ protected:
+ uint64_t fpcr; // floating point condition codes
+ uint64_t uniq; // process-unique register
+ bool lock_flag; // lock flag for LL/SC
+ Addr lock_addr; // lock address for LL/SC
+ int intr_flag;
+
+ public:
+ MiscRegFile()
+ {
+#if FULL_SYSTEM
+ initializeIprTable();
+#endif
+ }
+
+ MiscReg readReg(int misc_reg);
+
+ MiscReg readRegWithEffect(int misc_reg, ThreadContext *tc);
+
+ //These functions should be removed once the simplescalar cpu model
+ //has been replaced.
+ int getInstAsid();
+ int getDataAsid();
+
+ void setReg(int misc_reg, const MiscReg &val);
+
+ void setRegWithEffect(int misc_reg, const MiscReg &val,
+ ThreadContext *tc);
+
+ void clear()
+ {
+ fpcr = uniq = 0;
+ lock_flag = 0;
+ lock_addr = 0;
+ intr_flag = 0;
+ }
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+#if FULL_SYSTEM
+ protected:
+ typedef uint64_t InternalProcReg;
+
+ InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
+
+ private:
+ InternalProcReg readIpr(int idx, ThreadContext *tc);
+
+ void setIpr(int idx, InternalProcReg val, ThreadContext *tc);
+#endif
+ friend class RegFile;
+ };
+
+#if FULL_SYSTEM
+ void copyIprs(ThreadContext *src, ThreadContext *dest);
+#endif
+
+}
+
+#endif
diff --git a/src/arch/alpha/pagetable.cc b/src/arch/alpha/pagetable.cc
new file mode 100644
index 000000000..0c26ccbe3
--- /dev/null
+++ b/src/arch/alpha/pagetable.cc
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "arch/alpha/pagetable.hh"
+#include "sim/serialize.hh"
+
+namespace AlphaISA
+{
+ void
+ PTE::serialize(std::ostream &os)
+ {
+ SERIALIZE_SCALAR(tag);
+ SERIALIZE_SCALAR(ppn);
+ SERIALIZE_SCALAR(xre);
+ SERIALIZE_SCALAR(xwe);
+ SERIALIZE_SCALAR(asn);
+ SERIALIZE_SCALAR(asma);
+ SERIALIZE_SCALAR(fonr);
+ SERIALIZE_SCALAR(fonw);
+ SERIALIZE_SCALAR(valid);
+ }
+
+ void
+ PTE::unserialize(Checkpoint *cp, const std::string &section)
+ {
+ UNSERIALIZE_SCALAR(tag);
+ UNSERIALIZE_SCALAR(ppn);
+ UNSERIALIZE_SCALAR(xre);
+ UNSERIALIZE_SCALAR(xwe);
+ UNSERIALIZE_SCALAR(asn);
+ UNSERIALIZE_SCALAR(asma);
+ UNSERIALIZE_SCALAR(fonr);
+ UNSERIALIZE_SCALAR(fonw);
+ UNSERIALIZE_SCALAR(valid);
+ }
+}
diff --git a/src/arch/alpha/regfile.cc b/src/arch/alpha/regfile.cc
new file mode 100644
index 000000000..92e1b07df
--- /dev/null
+++ b/src/arch/alpha/regfile.cc
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Steve Reinhardt
+ * Gabe Black
+ * Kevin Lim
+ */
+
+#include "arch/alpha/regfile.hh"
+#include "cpu/thread_context.hh"
+
+namespace AlphaISA
+{
+ void
+ RegFile::serialize(std::ostream &os)
+ {
+ intRegFile.serialize(os);
+ floatRegFile.serialize(os);
+ miscRegFile.serialize(os);
+ SERIALIZE_SCALAR(pc);
+ SERIALIZE_SCALAR(npc);
+#if FULL_SYSTEM
+ SERIALIZE_SCALAR(intrflag);
+#endif
+ }
+
+ void
+ RegFile::unserialize(Checkpoint *cp, const std::string &section)
+ {
+ intRegFile.unserialize(cp, section);
+ floatRegFile.unserialize(cp, section);
+ miscRegFile.unserialize(cp, section);
+ UNSERIALIZE_SCALAR(pc);
+ UNSERIALIZE_SCALAR(npc);
+#if FULL_SYSTEM
+ UNSERIALIZE_SCALAR(intrflag);
+#endif
+ }
+
+ void
+ copyRegs(ThreadContext *src, ThreadContext *dest)
+ {
+ // First loop through the integer registers.
+ for (int i = 0; i < NumIntRegs; ++i) {
+ dest->setIntReg(i, src->readIntReg(i));
+ }
+
+ // Then loop through the floating point registers.
+ for (int i = 0; i < TheISA::NumFloatRegs; ++i) {
+ dest->setFloatRegBits(i, src->readFloatRegBits(i));
+ }
+
+ // Copy misc. registers
+ copyMiscRegs(src, dest);
+
+ // Lastly copy PC/NPC
+ dest->setPC(src->readPC());
+ dest->setNextPC(src->readNextPC());
+ }
+
+ void
+ copyMiscRegs(ThreadContext *src, ThreadContext *dest)
+ {
+ dest->setMiscReg(AlphaISA::MISCREG_FPCR,
+ src->readMiscReg(AlphaISA::MISCREG_FPCR));
+ dest->setMiscReg(AlphaISA::MISCREG_UNIQ,
+ src->readMiscReg(AlphaISA::MISCREG_UNIQ));
+ dest->setMiscReg(AlphaISA::MISCREG_LOCKFLAG,
+ src->readMiscReg(AlphaISA::MISCREG_LOCKFLAG));
+ dest->setMiscReg(AlphaISA::MISCREG_LOCKADDR,
+ src->readMiscReg(AlphaISA::MISCREG_LOCKADDR));
+
+#if FULL_SYSTEM
+ copyIprs(src, dest);
+#endif
+ }
+}
diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh
index 43b48a0ab..ff5830822 100644
--- a/src/arch/alpha/regfile.hh
+++ b/src/arch/alpha/regfile.hh
@@ -31,8 +31,11 @@
#ifndef __ARCH_ALPHA_REGFILE_HH__
#define __ARCH_ALPHA_REGFILE_HH__
-#include "arch/alpha/types.hh"
#include "arch/alpha/isa_traits.hh"
+#include "arch/alpha/floatregfile.hh"
+#include "arch/alpha/intregfile.hh"
+#include "arch/alpha/miscregfile.hh"
+#include "arch/alpha/types.hh"
#include "sim/faults.hh"
#include <string>
@@ -45,111 +48,6 @@ class ThreadContext;
namespace AlphaISA
{
- static inline std::string getIntRegName(RegIndex)
- {
- return "";
- }
-
- static inline std::string getFloatRegName(RegIndex)
- {
- return "";
- }
-
- static inline std::string getMiscRegName(RegIndex)
- {
- return "";
- }
-
- class IntRegFile
- {
- protected:
- IntReg regs[NumIntRegs];
-
- public:
-
- IntReg readReg(int intReg)
- {
- return regs[intReg];
- }
-
- Fault setReg(int intReg, const IntReg &val)
- {
- regs[intReg] = val;
- return NoFault;
- }
-
- void serialize(std::ostream &os);
-
- void unserialize(Checkpoint *cp, const std::string &section);
-
- void clear()
- { bzero(regs, sizeof(regs)); }
- };
-
- class FloatRegFile
- {
- public:
-
- union {
- uint64_t q[NumFloatRegs]; // integer qword view
- double d[NumFloatRegs]; // double-precision floating point view
- };
-
- void serialize(std::ostream &os);
-
- void unserialize(Checkpoint *cp, const std::string &section);
-
- void clear()
- { bzero(d, sizeof(d)); }
- };
-
- class MiscRegFile {
- protected:
- uint64_t fpcr; // floating point condition codes
- uint64_t uniq; // process-unique register
- bool lock_flag; // lock flag for LL/SC
- Addr lock_addr; // lock address for LL/SC
-
- public:
- MiscReg readReg(int misc_reg);
-
- MiscReg readRegWithEffect(int misc_reg, Fault &fault,
- ThreadContext *tc);
-
- //These functions should be removed once the simplescalar cpu model
- //has been replaced.
- int getInstAsid();
- int getDataAsid();
-
- Fault setReg(int misc_reg, const MiscReg &val);
-
- Fault setRegWithEffect(int misc_reg, const MiscReg &val,
- ThreadContext *tc);
-
- void clear()
- {
- fpcr = uniq = 0;
- lock_flag = 0;
- lock_addr = 0;
- }
-
- void serialize(std::ostream &os);
-
- void unserialize(Checkpoint *cp, const std::string &section);
-#if FULL_SYSTEM
- protected:
- typedef uint64_t InternalProcReg;
-
- InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
-
- private:
- InternalProcReg readIpr(int idx, Fault &fault, ThreadContext *tc);
-
- Fault setIpr(int idx, InternalProcReg val, ThreadContext *tc);
-#endif
- friend class RegFile;
- };
-
class RegFile {
protected:
@@ -215,22 +113,20 @@ namespace AlphaISA
return miscRegFile.readReg(miscReg);
}
- MiscReg readMiscRegWithEffect(int miscReg,
- Fault &fault, ThreadContext *tc)
+ MiscReg readMiscRegWithEffect(int miscReg, ThreadContext *tc)
{
- fault = NoFault;
- return miscRegFile.readRegWithEffect(miscReg, fault, tc);
+ return miscRegFile.readRegWithEffect(miscReg, tc);
}
- Fault setMiscReg(int miscReg, const MiscReg &val)
+ void setMiscReg(int miscReg, const MiscReg &val)
{
- return miscRegFile.setReg(miscReg, val);
+ miscRegFile.setReg(miscReg, val);
}
- Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
+ void setMiscRegWithEffect(int miscReg, const MiscReg &val,
ThreadContext * tc)
{
- return miscRegFile.setRegWithEffect(miscReg, val, tc);
+ miscRegFile.setRegWithEffect(miscReg, val, tc);
}
FloatReg readFloatReg(int floatReg)
@@ -253,26 +149,24 @@ namespace AlphaISA
return readFloatRegBits(floatReg);
}
- Fault setFloatReg(int floatReg, const FloatReg &val)
+ void setFloatReg(int floatReg, const FloatReg &val)
{
floatRegFile.d[floatReg] = val;
- return NoFault;
}
- Fault setFloatReg(int floatReg, const FloatReg &val, int width)
+ void setFloatReg(int floatReg, const FloatReg &val, int width)
{
- return setFloatReg(floatReg, val);
+ setFloatReg(floatReg, val);
}
- Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
+ void setFloatRegBits(int floatReg, const FloatRegBits &val)
{
floatRegFile.q[floatReg] = val;
- return NoFault;
}
- Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
+ void setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
{
- return setFloatRegBits(floatReg, val);
+ setFloatRegBits(floatReg, val);
}
IntReg readIntReg(int intReg)
@@ -280,9 +174,9 @@ namespace AlphaISA
return intRegFile.readReg(intReg);
}
- Fault setIntReg(int intReg, const IntReg &val)
+ void setIntReg(int intReg, const IntReg &val)
{
- return intRegFile.setReg(intReg, val);
+ intRegFile.setReg(intReg, val);
}
void serialize(std::ostream &os);
@@ -298,10 +192,6 @@ namespace AlphaISA
void copyRegs(ThreadContext *src, ThreadContext *dest);
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
-
-#if FULL_SYSTEM
- void copyIprs(ThreadContext *src, ThreadContext *dest);
-#endif
} // namespace AlphaISA
#endif
diff --git a/src/arch/alpha/remote_gdb.cc b/src/arch/alpha/remote_gdb.cc
new file mode 100644
index 000000000..f23fc3205
--- /dev/null
+++ b/src/arch/alpha/remote_gdb.cc
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ */
+
+/*
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratories.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
+ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * $NetBSD: kgdb_stub.c,v 1.8 2001/07/07 22:58:00 wdk Exp $
+ *
+ * Taken from NetBSD
+ *
+ * "Stub" to allow remote cpu to debug over a serial line using gdb.
+ */
+
+#include <sys/signal.h>
+
+#include <string>
+#include <unistd.h>
+
+#include "arch/alpha/kgdb.h"
+#include "arch/alpha/remote_gdb.hh"
+#include "arch/vtophys.hh"
+#include "base/intmath.hh"
+#include "base/remote_gdb.hh"
+#include "base/socket.hh"
+#include "base/trace.hh"
+#include "config/full_system.hh"
+#include "cpu/thread_context.hh"
+#include "cpu/static_inst.hh"
+#include "mem/physical.hh"
+#include "mem/port.hh"
+#include "sim/system.hh"
+
+using namespace std;
+using namespace TheISA;
+
+RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
+ : BaseRemoteGDB(_system, c, KGDB_NUMREGS)
+{
+ memset(gdbregs.regs, 0, gdbregs.bytes());
+}
+
+///////////////////////////////////////////////////////////
+// RemoteGDB::acc
+//
+// Determine if the mapping at va..(va+len) is valid.
+//
+bool
+RemoteGDB::acc(Addr va, size_t len)
+{
+ Addr last_va;
+
+ va = TheISA::TruncPage(va);
+ last_va = TheISA::RoundPage(va + len);
+
+ do {
+ if (TheISA::IsK0Seg(va)) {
+ if (va < (TheISA::K0SegBase + pmem->size())) {
+ DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= "
+ "%#x < K0SEG + size\n", va);
+ return true;
+ } else {
+ DPRINTF(GDBAcc, "acc: Mapping invalid %#x > K0SEG + size\n",
+ va);
+ return false;
+ }
+ }
+
+ /**
+ * This code says that all accesses to palcode (instruction and data)
+ * are valid since there isn't a va->pa mapping because palcode is
+ * accessed physically. At some point this should probably be cleaned up
+ * but there is no easy way to do it.
+ */
+
+ if (AlphaISA::PcPAL(va) || va < 0x10000)
+ return true;
+
+ Addr ptbr = context->readMiscReg(AlphaISA::IPR_PALtemp20);
+ TheISA::PageTableEntry pte = TheISA::kernel_pte_lookup(context->getPhysPort(), ptbr, va);
+ if (!pte.valid()) {
+ DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
+ return false;
+ }
+ va += TheISA::PageBytes;
+ } while (va < last_va);
+
+ DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va);
+ return true;
+}
+
+///////////////////////////////////////////////////////////
+// RemoteGDB::getregs
+//
+// Translate the kernel debugger register format into
+// the GDB register format.
+void
+RemoteGDB::getregs()
+{
+ memset(gdbregs.regs, 0, gdbregs.bytes());
+
+ gdbregs.regs[KGDB_REG_PC] = context->readPC();
+
+ // @todo: Currently this is very Alpha specific.
+ if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) {
+ for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
+ gdbregs.regs[i] = context->readIntReg(AlphaISA::reg_redir[i]);
+ }
+ } else {
+ for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
+ gdbregs.regs[i] = context->readIntReg(i);
+ }
+ }
+
+#ifdef KGDB_FP_REGS
+ for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) {
+ gdbregs.regs[i + KGDB_REG_F0] = context->readFloatRegBits(i);
+ }
+#endif
+}
+
+///////////////////////////////////////////////////////////
+// RemoteGDB::setregs
+//
+// Translate the GDB register format into the kernel
+// debugger register format.
+//
+void
+RemoteGDB::setregs()
+{
+ // @todo: Currently this is very Alpha specific.
+ if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) {
+ for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
+ context->setIntReg(AlphaISA::reg_redir[i], gdbregs.regs[i]);
+ }
+ } else {
+ for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
+ context->setIntReg(i, gdbregs.regs[i]);
+ }
+ }
+
+#ifdef KGDB_FP_REGS
+ for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) {
+ context->setFloatRegBits(i, gdbregs.regs[i + KGDB_REG_F0]);
+ }
+#endif
+ context->setPC(gdbregs.regs[KGDB_REG_PC]);
+}
+
+void
+RemoteGDB::clearSingleStep()
+{
+ DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n",
+ takenBkpt, notTakenBkpt);
+
+ if (takenBkpt != 0)
+ clearTempBreakpoint(takenBkpt);
+
+ if (notTakenBkpt != 0)
+ clearTempBreakpoint(notTakenBkpt);
+}
+
+void
+RemoteGDB::setSingleStep()
+{
+ Addr pc = context->readPC();
+ Addr npc, bpc;
+ bool set_bt = false;
+
+ npc = pc + sizeof(MachInst);
+
+ // User was stopped at pc, e.g. the instruction at pc was not
+ // executed.
+ MachInst inst = read<MachInst>(pc);
+ StaticInstPtr si(inst);
+ if (si->hasBranchTarget(pc, context, bpc)) {
+ // Don't bother setting a breakpoint on the taken branch if it
+ // is the same as the next pc
+ if (bpc != npc)
+ set_bt = true;
+ }
+
+ DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n",
+ takenBkpt, notTakenBkpt);
+
+ setTempBreakpoint(notTakenBkpt = npc);
+
+ if (set_bt)
+ setTempBreakpoint(takenBkpt = bpc);
+}
+
+// Write bytes to kernel address space for debugger.
+bool
+RemoteGDB::write(Addr vaddr, size_t size, const char *data)
+{
+ if (BaseRemoteGDB::write(vaddr, size, data)) {
+#ifdef IMB
+ alpha_pal_imb();
+#endif
+ return true;
+ } else {
+ return false;
+ }
+}
+
diff --git a/src/arch/alpha/remote_gdb.hh b/src/arch/alpha/remote_gdb.hh
new file mode 100644
index 000000000..7bef183c3
--- /dev/null
+++ b/src/arch/alpha/remote_gdb.hh
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ */
+
+#ifndef __ARCH_ALPHA_REMOTE_GDB_HH__
+#define __ARCH_ALPHA_REMOTE_GDB_HH__
+
+#include <map>
+
+#include "arch/alpha/types.hh"
+#include "arch/alpha/kgdb.h"
+#include "base/remote_gdb.hh"
+#include "cpu/pc_event.hh"
+#include "base/pollevent.hh"
+#include "base/socket.hh"
+
+class System;
+class ThreadContext;
+class PhysicalMemory;
+
+namespace AlphaISA
+{
+ class RemoteGDB : public BaseRemoteGDB
+ {
+ protected:
+ // Machine memory
+ bool write(Addr addr, size_t size, const char *data);
+
+ public:
+ RemoteGDB(System *system, ThreadContext *context);
+
+ bool acc(Addr addr, size_t len);
+
+ protected:
+ void getregs();
+ void setregs();
+
+ void clearSingleStep();
+ void setSingleStep();
+
+ protected:
+
+ Addr notTakenBkpt;
+ Addr takenBkpt;
+ };
+}
+
+#endif /* __ARCH_ALPHA_REMOTE_GDB_H__ */
diff --git a/src/arch/alpha/stacktrace.cc b/src/arch/alpha/stacktrace.cc
index d70a4d6dd..c4612e156 100644
--- a/src/arch/alpha/stacktrace.cc
+++ b/src/arch/alpha/stacktrace.cc
@@ -40,329 +40,331 @@
#include "sim/system.hh"
using namespace std;
-using namespace AlphaISA;
-ProcessInfo::ProcessInfo(ThreadContext *_tc)
- : tc(_tc)
+namespace AlphaISA
{
- Addr addr = 0;
+ ProcessInfo::ProcessInfo(ThreadContext *_tc)
+ : tc(_tc)
+ {
+ Addr addr = 0;
- VirtualPort *vp;
+ VirtualPort *vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtPort();
- if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
- panic("thread info not compiled into kernel\n");
- thread_info_size = vp->readGtoH<int32_t>(addr);
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
+ panic("thread info not compiled into kernel\n");
+ thread_info_size = vp->readGtoH<int32_t>(addr);
- if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
- panic("thread info not compiled into kernel\n");
- task_struct_size = vp->readGtoH<int32_t>(addr);
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
+ panic("thread info not compiled into kernel\n");
+ task_struct_size = vp->readGtoH<int32_t>(addr);
- if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
- panic("thread info not compiled into kernel\n");
- task_off = vp->readGtoH<int32_t>(addr);
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
+ panic("thread info not compiled into kernel\n");
+ task_off = vp->readGtoH<int32_t>(addr);
- if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
- panic("thread info not compiled into kernel\n");
- pid_off = vp->readGtoH<int32_t>(addr);
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
+ panic("thread info not compiled into kernel\n");
+ pid_off = vp->readGtoH<int32_t>(addr);
- if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
- panic("thread info not compiled into kernel\n");
- name_off = vp->readGtoH<int32_t>(addr);
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
+ panic("thread info not compiled into kernel\n");
+ name_off = vp->readGtoH<int32_t>(addr);
- tc->delVirtPort(vp);
-}
-
-Addr
-ProcessInfo::task(Addr ksp) const
-{
- Addr base = ksp & ~0x3fff;
- if (base == ULL(0xfffffc0000000000))
- return 0;
+ tc->delVirtPort(vp);
+ }
- Addr tsk;
+ Addr
+ ProcessInfo::task(Addr ksp) const
+ {
+ Addr base = ksp & ~0x3fff;
+ if (base == ULL(0xfffffc0000000000))
+ return 0;
- VirtualPort *vp;
+ Addr tsk;
- vp = tc->getVirtPort();
- tsk = vp->readGtoH<Addr>(base + task_off);
- tc->delVirtPort(vp);
+ VirtualPort *vp;
- return tsk;
-}
+ vp = tc->getVirtPort();
+ tsk = vp->readGtoH<Addr>(base + task_off);
+ tc->delVirtPort(vp);
-int
-ProcessInfo::pid(Addr ksp) const
-{
- Addr task = this->task(ksp);
- if (!task)
- return -1;
+ return tsk;
+ }
- uint16_t pd;
+ int
+ ProcessInfo::pid(Addr ksp) const
+ {
+ Addr task = this->task(ksp);
+ if (!task)
+ return -1;
- VirtualPort *vp;
+ uint16_t pd;
- vp = tc->getVirtPort();
- pd = vp->readGtoH<uint16_t>(task + pid_off);
- tc->delVirtPort(vp);
+ VirtualPort *vp;
- return pd;
-}
+ vp = tc->getVirtPort();
+ pd = vp->readGtoH<uint16_t>(task + pid_off);
+ tc->delVirtPort(vp);
-string
-ProcessInfo::name(Addr ksp) const
-{
- Addr task = this->task(ksp);
- if (!task)
- return "console";
+ return pd;
+ }
- char comm[256];
- CopyStringOut(tc, comm, task + name_off, sizeof(comm));
- if (!comm[0])
- return "startup";
+ string
+ ProcessInfo::name(Addr ksp) const
+ {
+ Addr task = this->task(ksp);
+ if (!task)
+ return "console";
- return comm;
-}
+ char comm[256];
+ CopyStringOut(tc, comm, task + name_off, sizeof(comm));
+ if (!comm[0])
+ return "startup";
-StackTrace::StackTrace()
- : tc(0), stack(64)
-{
-}
+ return comm;
+ }
-StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst)
- : tc(0), stack(64)
-{
- trace(_tc, inst);
-}
+ StackTrace::StackTrace()
+ : tc(0), stack(64)
+ {
+ }
-StackTrace::~StackTrace()
-{
-}
+ StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst)
+ : tc(0), stack(64)
+ {
+ trace(_tc, inst);
+ }
-void
-StackTrace::trace(ThreadContext *_tc, bool is_call)
-{
- tc = _tc;
+ StackTrace::~StackTrace()
+ {
+ }
- bool usermode = (tc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
+ void
+ StackTrace::trace(ThreadContext *_tc, bool is_call)
+ {
+ tc = _tc;
- Addr pc = tc->readNextPC();
- bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
- pc <= tc->getSystemPtr()->kernelEnd;
+ bool usermode = (tc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
- if (usermode) {
- stack.push_back(user);
- return;
- }
+ Addr pc = tc->readNextPC();
+ bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
+ pc <= tc->getSystemPtr()->kernelEnd;
- if (!kernel) {
- stack.push_back(console);
- return;
- }
+ if (usermode) {
+ stack.push_back(user);
+ return;
+ }
- SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
- Addr ksp = tc->readIntReg(TheISA::StackPointerReg);
- Addr bottom = ksp & ~0x3fff;
- Addr addr;
+ if (!kernel) {
+ stack.push_back(console);
+ return;
+ }
- if (is_call) {
- if (!symtab->findNearestAddr(pc, addr))
- panic("could not find address %#x", pc);
+ SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
+ Addr ksp = tc->readIntReg(TheISA::StackPointerReg);
+ Addr bottom = ksp & ~0x3fff;
+ Addr addr;
- stack.push_back(addr);
- pc = tc->readPC();
- }
+ if (is_call) {
+ if (!symtab->findNearestAddr(pc, addr))
+ panic("could not find address %#x", pc);
- Addr ra;
- int size;
+ stack.push_back(addr);
+ pc = tc->readPC();
+ }
- while (ksp > bottom) {
- if (!symtab->findNearestAddr(pc, addr))
- panic("could not find symbol for pc=%#x", pc);
- assert(pc >= addr && "symbol botch: callpc < func");
+ Addr ra;
+ int size;
- stack.push_back(addr);
+ while (ksp > bottom) {
+ if (!symtab->findNearestAddr(pc, addr))
+ panic("could not find symbol for pc=%#x", pc);
+ assert(pc >= addr && "symbol botch: callpc < func");
- if (isEntry(addr))
- return;
+ stack.push_back(addr);
- if (decodePrologue(ksp, pc, addr, size, ra)) {
- if (!ra)
+ if (isEntry(addr))
return;
- if (size <= 0) {
+ if (decodePrologue(ksp, pc, addr, size, ra)) {
+ if (!ra)
+ return;
+
+ if (size <= 0) {
+ stack.push_back(unknown);
+ return;
+ }
+
+ pc = ra;
+ ksp += size;
+ } else {
stack.push_back(unknown);
return;
}
- pc = ra;
- ksp += size;
- } else {
- stack.push_back(unknown);
- return;
- }
+ bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
+ pc <= tc->getSystemPtr()->kernelEnd;
+ if (!kernel)
+ return;
- bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
- pc <= tc->getSystemPtr()->kernelEnd;
- if (!kernel)
- return;
+ if (stack.size() >= 1000)
+ panic("unwinding too far");
+ }
- if (stack.size() >= 1000)
- panic("unwinding too far");
+ panic("unwinding too far");
}
- panic("unwinding too far");
-}
+ bool
+ StackTrace::isEntry(Addr addr)
+ {
+ if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp12))
+ return true;
-bool
-StackTrace::isEntry(Addr addr)
-{
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp12))
- return true;
+ if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp7))
+ return true;
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp7))
- return true;
+ if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp11))
+ return true;
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp11))
- return true;
+ if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp21))
+ return true;
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp21))
- return true;
+ if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp9))
+ return true;
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp9))
- return true;
-
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp2))
- return true;
+ if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp2))
+ return true;
- return false;
-}
-
-bool
-StackTrace::decodeStack(MachInst inst, int &disp)
-{
- // lda $sp, -disp($sp)
- //
- // Opcode<31:26> == 0x08
- // RA<25:21> == 30
- // RB<20:16> == 30
- // Disp<15:0>
- const MachInst mem_mask = 0xffff0000;
- const MachInst lda_pattern = 0x23de0000;
- const MachInst lda_disp_mask = 0x0000ffff;
-
- // subq $sp, disp, $sp
- // addq $sp, disp, $sp
- //
- // Opcode<31:26> == 0x10
- // RA<25:21> == 30
- // Lit<20:13>
- // One<12> = 1
- // Func<11:5> == 0x20 (addq)
- // Func<11:5> == 0x29 (subq)
- // RC<4:0> == 30
- const MachInst intop_mask = 0xffe01fff;
- const MachInst addq_pattern = 0x43c0141e;
- const MachInst subq_pattern = 0x43c0153e;
- const MachInst intop_disp_mask = 0x001fe000;
- const int intop_disp_shift = 13;
-
- if ((inst & mem_mask) == lda_pattern)
- disp = -sext<16>(inst & lda_disp_mask);
- else if ((inst & intop_mask) == addq_pattern)
- disp = -int((inst & intop_disp_mask) >> intop_disp_shift);
- else if ((inst & intop_mask) == subq_pattern)
- disp = int((inst & intop_disp_mask) >> intop_disp_shift);
- else
return false;
+ }
- return true;
-}
+ bool
+ StackTrace::decodeStack(MachInst inst, int &disp)
+ {
+ // lda $sp, -disp($sp)
+ //
+ // Opcode<31:26> == 0x08
+ // RA<25:21> == 30
+ // RB<20:16> == 30
+ // Disp<15:0>
+ const MachInst mem_mask = 0xffff0000;
+ const MachInst lda_pattern = 0x23de0000;
+ const MachInst lda_disp_mask = 0x0000ffff;
+
+ // subq $sp, disp, $sp
+ // addq $sp, disp, $sp
+ //
+ // Opcode<31:26> == 0x10
+ // RA<25:21> == 30
+ // Lit<20:13>
+ // One<12> = 1
+ // Func<11:5> == 0x20 (addq)
+ // Func<11:5> == 0x29 (subq)
+ // RC<4:0> == 30
+ const MachInst intop_mask = 0xffe01fff;
+ const MachInst addq_pattern = 0x43c0141e;
+ const MachInst subq_pattern = 0x43c0153e;
+ const MachInst intop_disp_mask = 0x001fe000;
+ const int intop_disp_shift = 13;
+
+ if ((inst & mem_mask) == lda_pattern)
+ disp = -sext<16>(inst & lda_disp_mask);
+ else if ((inst & intop_mask) == addq_pattern)
+ disp = -int((inst & intop_disp_mask) >> intop_disp_shift);
+ else if ((inst & intop_mask) == subq_pattern)
+ disp = int((inst & intop_disp_mask) >> intop_disp_shift);
+ else
+ return false;
-bool
-StackTrace::decodeSave(MachInst inst, int &reg, int &disp)
-{
- // lda $stq, disp($sp)
- //
- // Opcode<31:26> == 0x08
- // RA<25:21> == ?
- // RB<20:16> == 30
- // Disp<15:0>
- const MachInst stq_mask = 0xfc1f0000;
- const MachInst stq_pattern = 0xb41e0000;
- const MachInst stq_disp_mask = 0x0000ffff;
- const MachInst reg_mask = 0x03e00000;
- const int reg_shift = 21;
-
- if ((inst & stq_mask) == stq_pattern) {
- reg = (inst & reg_mask) >> reg_shift;
- disp = sext<16>(inst & stq_disp_mask);
- } else {
- return false;
+ return true;
}
- return true;
-}
+ bool
+ StackTrace::decodeSave(MachInst inst, int &reg, int &disp)
+ {
+ // lda $stq, disp($sp)
+ //
+ // Opcode<31:26> == 0x08
+ // RA<25:21> == ?
+ // RB<20:16> == 30
+ // Disp<15:0>
+ const MachInst stq_mask = 0xfc1f0000;
+ const MachInst stq_pattern = 0xb41e0000;
+ const MachInst stq_disp_mask = 0x0000ffff;
+ const MachInst reg_mask = 0x03e00000;
+ const int reg_shift = 21;
+
+ if ((inst & stq_mask) == stq_pattern) {
+ reg = (inst & reg_mask) >> reg_shift;
+ disp = sext<16>(inst & stq_disp_mask);
+ } else {
+ return false;
+ }
-/*
- * Decode the function prologue for the function we're in, and note
- * which registers are stored where, and how large the stack frame is.
- */
-bool
-StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
- int &size, Addr &ra)
-{
- size = 0;
- ra = 0;
-
- for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
- MachInst inst;
- CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst));
-
- int reg, disp;
- if (decodeStack(inst, disp)) {
- if (size) {
- // panic("decoding frame size again");
- return true;
- }
- size += disp;
- } else if (decodeSave(inst, reg, disp)) {
- if (!ra && reg == ReturnAddressReg) {
- CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr));
- if (!ra) {
- // panic("no return address value pc=%#x\n", pc);
- return false;
+ return true;
+ }
+
+ /*
+ * Decode the function prologue for the function we're in, and note
+ * which registers are stored where, and how large the stack frame is.
+ */
+ bool
+ StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
+ int &size, Addr &ra)
+ {
+ size = 0;
+ ra = 0;
+
+ for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
+ MachInst inst;
+ CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst));
+
+ int reg, disp;
+ if (decodeStack(inst, disp)) {
+ if (size) {
+ // panic("decoding frame size again");
+ return true;
+ }
+ size += disp;
+ } else if (decodeSave(inst, reg, disp)) {
+ if (!ra && reg == ReturnAddressReg) {
+ CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr));
+ if (!ra) {
+ // panic("no return address value pc=%#x\n", pc);
+ return false;
+ }
}
}
}
- }
- return true;
-}
+ return true;
+ }
#if TRACING_ON
-void
-StackTrace::dump()
-{
- StringWrap name(tc->getCpuPtr()->name());
- SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
-
- DPRINTFN("------ Stack ------\n");
-
- string symbol;
- for (int i = 0, size = stack.size(); i < size; ++i) {
- Addr addr = stack[size - i - 1];
- if (addr == user)
- symbol = "user";
- else if (addr == console)
- symbol = "console";
- else if (addr == unknown)
- symbol = "unknown";
- else
- symtab->findSymbol(addr, symbol);
-
- DPRINTFN("%#x: %s\n", addr, symbol);
+ void
+ StackTrace::dump()
+ {
+ StringWrap name(tc->getCpuPtr()->name());
+ SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
+
+ DPRINTFN("------ Stack ------\n");
+
+ string symbol;
+ for (int i = 0, size = stack.size(); i < size; ++i) {
+ Addr addr = stack[size - i - 1];
+ if (addr == user)
+ symbol = "user";
+ else if (addr == console)
+ symbol = "console";
+ else if (addr == unknown)
+ symbol = "unknown";
+ else
+ symtab->findSymbol(addr, symbol);
+
+ DPRINTFN("%#x: %s\n", addr, symbol);
+ }
}
-}
#endif
+}
diff --git a/src/arch/alpha/stacktrace.hh b/src/arch/alpha/stacktrace.hh
index d12aee211..834abbc2f 100644
--- a/src/arch/alpha/stacktrace.hh
+++ b/src/arch/alpha/stacktrace.hh
@@ -35,87 +35,91 @@
#include "cpu/static_inst.hh"
class ThreadContext;
-class StackTrace;
-class ProcessInfo
+namespace AlphaISA
{
- private:
- ThreadContext *tc;
+ class StackTrace;
- int thread_info_size;
- int task_struct_size;
- int task_off;
- int pid_off;
- int name_off;
+ class ProcessInfo
+ {
+ private:
+ ThreadContext *tc;
- public:
- ProcessInfo(ThreadContext *_tc);
+ int thread_info_size;
+ int task_struct_size;
+ int task_off;
+ int pid_off;
+ int name_off;
- Addr task(Addr ksp) const;
- int pid(Addr ksp) const;
- std::string name(Addr ksp) const;
-};
+ public:
+ ProcessInfo(ThreadContext *_tc);
-class StackTrace
-{
- protected:
- typedef TheISA::MachInst MachInst;
- private:
- ThreadContext *tc;
- std::vector<Addr> stack;
-
- private:
- bool isEntry(Addr addr);
- bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
- bool decodeSave(MachInst inst, int &reg, int &disp);
- bool decodeStack(MachInst inst, int &disp);
-
- void trace(ThreadContext *tc, bool is_call);
-
- public:
- StackTrace();
- StackTrace(ThreadContext *tc, StaticInstPtr inst);
- ~StackTrace();
-
- void clear()
+ Addr task(Addr ksp) const;
+ int pid(Addr ksp) const;
+ std::string name(Addr ksp) const;
+ };
+
+ class StackTrace
{
- tc = 0;
- stack.clear();
- }
+ protected:
+ typedef TheISA::MachInst MachInst;
+ private:
+ ThreadContext *tc;
+ std::vector<Addr> stack;
+
+ private:
+ bool isEntry(Addr addr);
+ bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
+ bool decodeSave(MachInst inst, int &reg, int &disp);
+ bool decodeStack(MachInst inst, int &disp);
+
+ void trace(ThreadContext *tc, bool is_call);
- bool valid() const { return tc != NULL; }
- bool trace(ThreadContext *tc, StaticInstPtr inst);
+ public:
+ StackTrace();
+ StackTrace(ThreadContext *tc, StaticInstPtr inst);
+ ~StackTrace();
- public:
- const std::vector<Addr> &getstack() const { return stack; }
+ void clear()
+ {
+ tc = 0;
+ stack.clear();
+ }
- static const int user = 1;
- static const int console = 2;
- static const int unknown = 3;
+ bool valid() const { return tc != NULL; }
+ bool trace(ThreadContext *tc, StaticInstPtr inst);
+
+ public:
+ const std::vector<Addr> &getstack() const { return stack; }
+
+ static const int user = 1;
+ static const int console = 2;
+ static const int unknown = 3;
#if TRACING_ON
- private:
- void dump();
+ private:
+ void dump();
- public:
- void dprintf() { if (DTRACE(Stack)) dump(); }
+ public:
+ void dprintf() { if (DTRACE(Stack)) dump(); }
#else
- public:
- void dprintf() {}
+ public:
+ void dprintf() {}
#endif
-};
+ };
-inline bool
-StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
-{
- if (!inst->isCall() && !inst->isReturn())
- return false;
+ inline bool
+ StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
+ {
+ if (!inst->isCall() && !inst->isReturn())
+ return false;
- if (valid())
- clear();
+ if (valid())
+ clear();
- trace(tc, !inst->isReturn());
- return true;
+ trace(tc, !inst->isReturn());
+ return true;
+ }
}
#endif // __ARCH_ALPHA_STACKTRACE_HH__
diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc
index 5597eaedc..cd923948c 100644
--- a/src/arch/alpha/system.cc
+++ b/src/arch/alpha/system.cc
@@ -29,10 +29,12 @@
* Nathan Binkert
*/
+#include <sys/signal.h>
+
#include "arch/alpha/ev5.hh"
#include "arch/alpha/system.hh"
+#include "arch/alpha/remote_gdb.hh"
#include "arch/vtophys.hh"
-#include "base/remote_gdb.hh"
#include "base/loader/object_file.hh"
#include "base/loader/symtab.hh"
#include "base/trace.hh"
@@ -196,7 +198,7 @@ AlphaSystem::setAlphaAccess(Addr access)
bool
AlphaSystem::breakpoint()
{
- return remoteGDB[0]->trap(ALPHA_KENTRY_INT);
+ return remoteGDB[0]->trap(SIGTRAP);
}
void
diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc
index bab44c434..ae302e686 100644
--- a/src/arch/alpha/tlb.cc
+++ b/src/arch/alpha/tlb.cc
@@ -46,589 +46,591 @@
using namespace std;
using namespace EV5;
-///////////////////////////////////////////////////////////////////////
-//
-// Alpha TLB
-//
+namespace AlphaISA
+{
+ ///////////////////////////////////////////////////////////////////////
+ //
+ // Alpha TLB
+ //
#ifdef DEBUG
-bool uncacheBit39 = false;
-bool uncacheBit40 = false;
+ bool uncacheBit39 = false;
+ bool uncacheBit40 = false;
#endif
#define MODE2MASK(X) (1 << (X))
-AlphaTLB::AlphaTLB(const string &name, int s)
- : SimObject(name), size(s), nlu(0)
-{
- table = new AlphaISA::PTE[size];
- memset(table, 0, sizeof(AlphaISA::PTE[size]));
-}
+ TLB::TLB(const string &name, int s)
+ : SimObject(name), size(s), nlu(0)
+ {
+ table = new PTE[size];
+ memset(table, 0, sizeof(PTE[size]));
+ }
-AlphaTLB::~AlphaTLB()
-{
- if (table)
- delete [] table;
-}
+ TLB::~TLB()
+ {
+ if (table)
+ delete [] table;
+ }
-// look up an entry in the TLB
-AlphaISA::PTE *
-AlphaTLB::lookup(Addr vpn, uint8_t asn) const
-{
- // assume not found...
- AlphaISA::PTE *retval = NULL;
+ // look up an entry in the TLB
+ PTE *
+ TLB::lookup(Addr vpn, uint8_t asn) const
+ {
+ // assume not found...
+ PTE *retval = NULL;
+
+ PageTable::const_iterator i = lookupTable.find(vpn);
+ if (i != lookupTable.end()) {
+ while (i->first == vpn) {
+ int index = i->second;
+ PTE *pte = &table[index];
+ assert(pte->valid);
+ if (vpn == pte->tag && (pte->asma || pte->asn == asn)) {
+ retval = pte;
+ break;
+ }
- PageTable::const_iterator i = lookupTable.find(vpn);
- if (i != lookupTable.end()) {
- while (i->first == vpn) {
- int index = i->second;
- AlphaISA::PTE *pte = &table[index];
- assert(pte->valid);
- if (vpn == pte->tag && (pte->asma || pte->asn == asn)) {
- retval = pte;
- break;
+ ++i;
}
-
- ++i;
}
- }
- DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
- retval ? "hit" : "miss", retval ? retval->ppn : 0);
- return retval;
-}
+ DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
+ retval ? "hit" : "miss", retval ? retval->ppn : 0);
+ return retval;
+ }
-Fault
-AlphaTLB::checkCacheability(RequestPtr &req)
-{
- // in Alpha, cacheability is controlled by upper-level bits of the
- // physical address
+ Fault
+ TLB::checkCacheability(RequestPtr &req)
+ {
+ // in Alpha, cacheability is controlled by upper-level bits of the
+ // physical address
- /*
- * We support having the uncacheable bit in either bit 39 or bit 40.
- * The Turbolaser platform (and EV5) support having the bit in 39, but
- * Tsunami (which Linux assumes uses an EV6) generates accesses with
- * the bit in 40. So we must check for both, but we have debug flags
- * to catch a weird case where both are used, which shouldn't happen.
- */
+ /*
+ * We support having the uncacheable bit in either bit 39 or bit 40.
+ * The Turbolaser platform (and EV5) support having the bit in 39, but
+ * Tsunami (which Linux assumes uses an EV6) generates accesses with
+ * the bit in 40. So we must check for both, but we have debug flags
+ * to catch a weird case where both are used, which shouldn't happen.
+ */
#if ALPHA_TLASER
- if (req->getPaddr() & PAddrUncachedBit39) {
+ if (req->getPaddr() & PAddrUncachedBit39) {
#else
- if (req->getPaddr() & PAddrUncachedBit43) {
+ if (req->getPaddr() & PAddrUncachedBit43) {
#endif
- // IPR memory space not implemented
- if (PAddrIprSpace(req->getPaddr())) {
- return new UnimpFault("IPR memory space not implemented!");
- } else {
- // mark request as uncacheable
- req->setFlags(req->getFlags() | UNCACHEABLE);
+ // IPR memory space not implemented
+ if (PAddrIprSpace(req->getPaddr())) {
+ return new UnimpFault("IPR memory space not implemented!");
+ } else {
+ // mark request as uncacheable
+ req->setFlags(req->getFlags() | UNCACHEABLE);
#if !ALPHA_TLASER
- // Clear bits 42:35 of the physical address (10-2 in Tsunami manual)
- req->setPaddr(req->getPaddr() & PAddrUncachedMask);
+ // Clear bits 42:35 of the physical address (10-2 in Tsunami manual)
+ req->setPaddr(req->getPaddr() & PAddrUncachedMask);
#endif
+ }
}
+ return NoFault;
}
- return NoFault;
-}
-// insert a new TLB entry
-void
-AlphaTLB::insert(Addr addr, AlphaISA::PTE &pte)
-{
- AlphaISA::VAddr vaddr = addr;
- if (table[nlu].valid) {
- Addr oldvpn = table[nlu].tag;
- PageTable::iterator i = lookupTable.find(oldvpn);
+ // insert a new TLB entry
+ void
+ TLB::insert(Addr addr, PTE &pte)
+ {
+ VAddr vaddr = addr;
+ if (table[nlu].valid) {
+ Addr oldvpn = table[nlu].tag;
+ PageTable::iterator i = lookupTable.find(oldvpn);
- if (i == lookupTable.end())
- panic("TLB entry not found in lookupTable");
-
- int index;
- while ((index = i->second) != nlu) {
- if (table[index].tag != oldvpn)
+ if (i == lookupTable.end())
panic("TLB entry not found in lookupTable");
- ++i;
+ int index;
+ while ((index = i->second) != nlu) {
+ if (table[index].tag != oldvpn)
+ panic("TLB entry not found in lookupTable");
+
+ ++i;
+ }
+
+ DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn);
+
+ lookupTable.erase(i);
}
- DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn);
+ DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn);
- lookupTable.erase(i);
- }
+ table[nlu] = pte;
+ table[nlu].tag = vaddr.vpn();
+ table[nlu].valid = true;
- DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn);
+ lookupTable.insert(make_pair(vaddr.vpn(), nlu));
+ nextnlu();
+ }
- table[nlu] = pte;
- table[nlu].tag = vaddr.vpn();
- table[nlu].valid = true;
+ void
+ TLB::flushAll()
+ {
+ DPRINTF(TLB, "flushAll\n");
+ memset(table, 0, sizeof(PTE[size]));
+ lookupTable.clear();
+ nlu = 0;
+ }
- lookupTable.insert(make_pair(vaddr.vpn(), nlu));
- nextnlu();
-}
+ void
+ TLB::flushProcesses()
+ {
+ PageTable::iterator i = lookupTable.begin();
+ PageTable::iterator end = lookupTable.end();
+ while (i != end) {
+ int index = i->second;
+ PTE *pte = &table[index];
+ assert(pte->valid);
-void
-AlphaTLB::flushAll()
-{
- DPRINTF(TLB, "flushAll\n");
- memset(table, 0, sizeof(AlphaISA::PTE[size]));
- lookupTable.clear();
- nlu = 0;
-}
+ // we can't increment i after we erase it, so save a copy and
+ // increment it to get the next entry now
+ PageTable::iterator cur = i;
+ ++i;
-void
-AlphaTLB::flushProcesses()
-{
- PageTable::iterator i = lookupTable.begin();
- PageTable::iterator end = lookupTable.end();
- while (i != end) {
- int index = i->second;
- AlphaISA::PTE *pte = &table[index];
- assert(pte->valid);
-
- // we can't increment i after we erase it, so save a copy and
- // increment it to get the next entry now
- PageTable::iterator cur = i;
- ++i;
-
- if (!pte->asma) {
- DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn);
- pte->valid = false;
- lookupTable.erase(cur);
+ if (!pte->asma) {
+ DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn);
+ pte->valid = false;
+ lookupTable.erase(cur);
+ }
}
}
-}
-void
-AlphaTLB::flushAddr(Addr addr, uint8_t asn)
-{
- AlphaISA::VAddr vaddr = addr;
+ void
+ TLB::flushAddr(Addr addr, uint8_t asn)
+ {
+ VAddr vaddr = addr;
- PageTable::iterator i = lookupTable.find(vaddr.vpn());
- if (i == lookupTable.end())
- return;
+ PageTable::iterator i = lookupTable.find(vaddr.vpn());
+ if (i == lookupTable.end())
+ return;
- while (i->first == vaddr.vpn()) {
- int index = i->second;
- AlphaISA::PTE *pte = &table[index];
- assert(pte->valid);
+ while (i->first == vaddr.vpn()) {
+ int index = i->second;
+ PTE *pte = &table[index];
+ assert(pte->valid);
- if (vaddr.vpn() == pte->tag && (pte->asma || pte->asn == asn)) {
- DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(),
- pte->ppn);
+ if (vaddr.vpn() == pte->tag && (pte->asma || pte->asn == asn)) {
+ DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(),
+ pte->ppn);
- // invalidate this entry
- pte->valid = false;
+ // invalidate this entry
+ pte->valid = false;
- lookupTable.erase(i);
- }
+ lookupTable.erase(i);
+ }
- ++i;
+ ++i;
+ }
}
-}
-void
-AlphaTLB::serialize(ostream &os)
-{
- SERIALIZE_SCALAR(size);
- SERIALIZE_SCALAR(nlu);
+ void
+ TLB::serialize(ostream &os)
+ {
+ SERIALIZE_SCALAR(size);
+ SERIALIZE_SCALAR(nlu);
- for (int i = 0; i < size; i++) {
- nameOut(os, csprintf("%s.PTE%d", name(), i));
- table[i].serialize(os);
+ for (int i = 0; i < size; i++) {
+ nameOut(os, csprintf("%s.PTE%d", name(), i));
+ table[i].serialize(os);
+ }
}
-}
-void
-AlphaTLB::unserialize(Checkpoint *cp, const string &section)
-{
- UNSERIALIZE_SCALAR(size);
- UNSERIALIZE_SCALAR(nlu);
+ void
+ TLB::unserialize(Checkpoint *cp, const string &section)
+ {
+ UNSERIALIZE_SCALAR(size);
+ UNSERIALIZE_SCALAR(nlu);
- for (int i = 0; i < size; i++) {
- table[i].unserialize(cp, csprintf("%s.PTE%d", section, i));
- if (table[i].valid) {
- lookupTable.insert(make_pair(table[i].tag, i));
+ for (int i = 0; i < size; i++) {
+ table[i].unserialize(cp, csprintf("%s.PTE%d", section, i));
+ if (table[i].valid) {
+ lookupTable.insert(make_pair(table[i].tag, i));
+ }
}
}
-}
-
-///////////////////////////////////////////////////////////////////////
-//
-// Alpha ITB
-//
-AlphaITB::AlphaITB(const std::string &name, int size)
- : AlphaTLB(name, size)
-{}
-
-void
-AlphaITB::regStats()
-{
- hits
- .name(name() + ".hits")
- .desc("ITB hits");
- misses
- .name(name() + ".misses")
- .desc("ITB misses");
- acv
- .name(name() + ".acv")
- .desc("ITB acv");
- accesses
- .name(name() + ".accesses")
- .desc("ITB accesses");
-
- accesses = hits + misses;
-}
-
-
-Fault
-AlphaITB::translate(RequestPtr &req, ThreadContext *tc) const
-{
- if (AlphaISA::PcPAL(req->getVaddr())) {
- // strip off PAL PC marker (lsb is 1)
- req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask);
- hits++;
- return NoFault;
+ ///////////////////////////////////////////////////////////////////////
+ //
+ // Alpha ITB
+ //
+ ITB::ITB(const std::string &name, int size)
+ : TLB(name, size)
+ {}
+
+
+ void
+ ITB::regStats()
+ {
+ hits
+ .name(name() + ".hits")
+ .desc("ITB hits");
+ misses
+ .name(name() + ".misses")
+ .desc("ITB misses");
+ acv
+ .name(name() + ".acv")
+ .desc("ITB acv");
+ accesses
+ .name(name() + ".accesses")
+ .desc("ITB accesses");
+
+ accesses = hits + misses;
}
- if (req->getFlags() & PHYSICAL) {
- req->setPaddr(req->getVaddr());
- } else {
- // verify that this is a good virtual address
- if (!validVirtualAddress(req->getVaddr())) {
- acv++;
- return new ItbAcvFault(req->getVaddr());
+
+ Fault
+ ITB::translate(RequestPtr &req, ThreadContext *tc) const
+ {
+ if (PcPAL(req->getVaddr())) {
+ // strip off PAL PC marker (lsb is 1)
+ req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask);
+ hits++;
+ return NoFault;
}
+ if (req->getFlags() & PHYSICAL) {
+ req->setPaddr(req->getVaddr());
+ } else {
+ // verify that this is a good virtual address
+ if (!validVirtualAddress(req->getVaddr())) {
+ acv++;
+ return new ItbAcvFault(req->getVaddr());
+ }
+
- // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13> for EV5
- // VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6
+ // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13> for EV5
+ // VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6
#if ALPHA_TLASER
- if ((MCSR_SP(tc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) &&
- VAddrSpaceEV5(req->getVaddr()) == 2) {
+ if ((MCSR_SP(tc->readMiscReg(IPR_MCSR)) & 2) &&
+ VAddrSpaceEV5(req->getVaddr()) == 2) {
#else
- if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
+ if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
#endif
- // only valid in kernel mode
- if (ICM_CM(tc->readMiscReg(AlphaISA::IPR_ICM)) !=
- AlphaISA::mode_kernel) {
- acv++;
- return new ItbAcvFault(req->getVaddr());
- }
+ // only valid in kernel mode
+ if (ICM_CM(tc->readMiscReg(IPR_ICM)) !=
+ mode_kernel) {
+ acv++;
+ return new ItbAcvFault(req->getVaddr());
+ }
- req->setPaddr(req->getVaddr() & PAddrImplMask);
+ req->setPaddr(req->getVaddr() & PAddrImplMask);
#if !ALPHA_TLASER
- // sign extend the physical address properly
- if (req->getPaddr() & PAddrUncachedBit40)
- req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
- else
- req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
+ // sign extend the physical address properly
+ if (req->getPaddr() & PAddrUncachedBit40)
+ req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
+ else
+ req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
#endif
- } else {
- // not a physical address: need to look up pte
- int asn = DTB_ASN_ASN(tc->readMiscReg(AlphaISA::IPR_DTB_ASN));
- AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(),
- asn);
-
- if (!pte) {
- misses++;
- return new ItbPageFault(req->getVaddr());
- }
+ } else {
+ // not a physical address: need to look up pte
+ int asn = DTB_ASN_ASN(tc->readMiscReg(IPR_DTB_ASN));
+ PTE *pte = lookup(VAddr(req->getVaddr()).vpn(),
+ asn);
+
+ if (!pte) {
+ misses++;
+ return new ItbPageFault(req->getVaddr());
+ }
- req->setPaddr((pte->ppn << AlphaISA::PageShift) +
- (AlphaISA::VAddr(req->getVaddr()).offset()
- & ~3));
+ req->setPaddr((pte->ppn << PageShift) +
+ (VAddr(req->getVaddr()).offset()
+ & ~3));
- // check permissions for this access
- if (!(pte->xre &
- (1 << ICM_CM(tc->readMiscReg(AlphaISA::IPR_ICM))))) {
- // instruction access fault
- acv++;
- return new ItbAcvFault(req->getVaddr());
- }
+ // check permissions for this access
+ if (!(pte->xre &
+ (1 << ICM_CM(tc->readMiscReg(IPR_ICM))))) {
+ // instruction access fault
+ acv++;
+ return new ItbAcvFault(req->getVaddr());
+ }
- hits++;
+ hits++;
+ }
}
- }
-
- // check that the physical address is ok (catch bad physical addresses)
- if (req->getPaddr() & ~PAddrImplMask)
- return genMachineCheckFault();
- return checkCacheability(req);
-
-}
+ // check that the physical address is ok (catch bad physical addresses)
+ if (req->getPaddr() & ~PAddrImplMask)
+ return genMachineCheckFault();
-///////////////////////////////////////////////////////////////////////
-//
-// Alpha DTB
-//
-AlphaDTB::AlphaDTB(const std::string &name, int size)
- : AlphaTLB(name, size)
-{}
+ return checkCacheability(req);
-void
-AlphaDTB::regStats()
-{
- read_hits
- .name(name() + ".read_hits")
- .desc("DTB read hits")
- ;
-
- read_misses
- .name(name() + ".read_misses")
- .desc("DTB read misses")
- ;
-
- read_acv
- .name(name() + ".read_acv")
- .desc("DTB read access violations")
- ;
-
- read_accesses
- .name(name() + ".read_accesses")
- .desc("DTB read accesses")
- ;
-
- write_hits
- .name(name() + ".write_hits")
- .desc("DTB write hits")
- ;
-
- write_misses
- .name(name() + ".write_misses")
- .desc("DTB write misses")
- ;
-
- write_acv
- .name(name() + ".write_acv")
- .desc("DTB write access violations")
- ;
-
- write_accesses
- .name(name() + ".write_accesses")
- .desc("DTB write accesses")
- ;
-
- hits
- .name(name() + ".hits")
- .desc("DTB hits")
- ;
-
- misses
- .name(name() + ".misses")
- .desc("DTB misses")
- ;
-
- acv
- .name(name() + ".acv")
- .desc("DTB access violations")
- ;
-
- accesses
- .name(name() + ".accesses")
- .desc("DTB accesses")
- ;
-
- hits = read_hits + write_hits;
- misses = read_misses + write_misses;
- acv = read_acv + write_acv;
- accesses = read_accesses + write_accesses;
-}
+ }
-Fault
-AlphaDTB::translate(RequestPtr &req, ThreadContext *tc, bool write) const
-{
- Addr pc = tc->readPC();
+ ///////////////////////////////////////////////////////////////////////
+ //
+ // Alpha DTB
+ //
+ DTB::DTB(const std::string &name, int size)
+ : TLB(name, size)
+ {}
+
+ void
+ DTB::regStats()
+ {
+ read_hits
+ .name(name() + ".read_hits")
+ .desc("DTB read hits")
+ ;
+
+ read_misses
+ .name(name() + ".read_misses")
+ .desc("DTB read misses")
+ ;
+
+ read_acv
+ .name(name() + ".read_acv")
+ .desc("DTB read access violations")
+ ;
+
+ read_accesses
+ .name(name() + ".read_accesses")
+ .desc("DTB read accesses")
+ ;
+
+ write_hits
+ .name(name() + ".write_hits")
+ .desc("DTB write hits")
+ ;
+
+ write_misses
+ .name(name() + ".write_misses")
+ .desc("DTB write misses")
+ ;
+
+ write_acv
+ .name(name() + ".write_acv")
+ .desc("DTB write access violations")
+ ;
+
+ write_accesses
+ .name(name() + ".write_accesses")
+ .desc("DTB write accesses")
+ ;
+
+ hits
+ .name(name() + ".hits")
+ .desc("DTB hits")
+ ;
+
+ misses
+ .name(name() + ".misses")
+ .desc("DTB misses")
+ ;
+
+ acv
+ .name(name() + ".acv")
+ .desc("DTB access violations")
+ ;
+
+ accesses
+ .name(name() + ".accesses")
+ .desc("DTB accesses")
+ ;
+
+ hits = read_hits + write_hits;
+ misses = read_misses + write_misses;
+ acv = read_acv + write_acv;
+ accesses = read_accesses + write_accesses;
+ }
- AlphaISA::mode_type mode =
- (AlphaISA::mode_type)DTB_CM_CM(tc->readMiscReg(AlphaISA::IPR_DTB_CM));
+ Fault
+ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) const
+ {
+ Addr pc = tc->readPC();
+ mode_type mode =
+ (mode_type)DTB_CM_CM(tc->readMiscReg(IPR_DTB_CM));
- /**
- * Check for alignment faults
- */
- if (req->getVaddr() & (req->getSize() - 1)) {
- DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(),
- req->getSize());
- uint64_t flags = write ? MM_STAT_WR_MASK : 0;
- return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags);
- }
- if (pc & 0x1) {
- mode = (req->getFlags() & ALTMODE) ?
- (AlphaISA::mode_type)ALT_MODE_AM(
- tc->readMiscReg(AlphaISA::IPR_ALT_MODE))
- : AlphaISA::mode_kernel;
- }
+ /**
+ * Check for alignment faults
+ */
+ if (req->getVaddr() & (req->getSize() - 1)) {
+ DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(),
+ req->getSize());
+ uint64_t flags = write ? MM_STAT_WR_MASK : 0;
+ return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags);
+ }
- if (req->getFlags() & PHYSICAL) {
- req->setPaddr(req->getVaddr());
- } else {
- // verify that this is a good virtual address
- if (!validVirtualAddress(req->getVaddr())) {
- if (write) { write_acv++; } else { read_acv++; }
- uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
- MM_STAT_BAD_VA_MASK |
- MM_STAT_ACV_MASK;
- return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
+ if (pc & 0x1) {
+ mode = (req->getFlags() & ALTMODE) ?
+ (mode_type)ALT_MODE_AM(
+ tc->readMiscReg(IPR_ALT_MODE))
+ : mode_kernel;
}
- // Check for "superpage" mapping
+ if (req->getFlags() & PHYSICAL) {
+ req->setPaddr(req->getVaddr());
+ } else {
+ // verify that this is a good virtual address
+ if (!validVirtualAddress(req->getVaddr())) {
+ if (write) { write_acv++; } else { read_acv++; }
+ uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
+ MM_STAT_BAD_VA_MASK |
+ MM_STAT_ACV_MASK;
+ return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
+ }
+
+ // Check for "superpage" mapping
#if ALPHA_TLASER
- if ((MCSR_SP(tc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) &&
- VAddrSpaceEV5(req->getVaddr()) == 2) {
+ if ((MCSR_SP(tc->readMiscReg(IPR_MCSR)) & 2) &&
+ VAddrSpaceEV5(req->getVaddr()) == 2) {
#else
- if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
+ if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
#endif
- // only valid in kernel mode
- if (DTB_CM_CM(tc->readMiscReg(AlphaISA::IPR_DTB_CM)) !=
- AlphaISA::mode_kernel) {
- if (write) { write_acv++; } else { read_acv++; }
- uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) |
- MM_STAT_ACV_MASK);
- return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
- }
+ // only valid in kernel mode
+ if (DTB_CM_CM(tc->readMiscReg(IPR_DTB_CM)) !=
+ mode_kernel) {
+ if (write) { write_acv++; } else { read_acv++; }
+ uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) |
+ MM_STAT_ACV_MASK);
+ return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
+ }
- req->setPaddr(req->getVaddr() & PAddrImplMask);
+ req->setPaddr(req->getVaddr() & PAddrImplMask);
#if !ALPHA_TLASER
- // sign extend the physical address properly
- if (req->getPaddr() & PAddrUncachedBit40)
- req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
- else
- req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
+ // sign extend the physical address properly
+ if (req->getPaddr() & PAddrUncachedBit40)
+ req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
+ else
+ req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
#endif
- } else {
- if (write)
- write_accesses++;
- else
- read_accesses++;
-
- int asn = DTB_ASN_ASN(tc->readMiscReg(AlphaISA::IPR_DTB_ASN));
-
- // not a physical address: need to look up pte
- AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(),
- asn);
-
- if (!pte) {
- // page fault
- if (write) { write_misses++; } else { read_misses++; }
- uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
- MM_STAT_DTB_MISS_MASK;
- return (req->getFlags() & VPTE) ?
- (Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(),
- flags)) :
- (Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(),
- flags));
- }
-
- req->setPaddr((pte->ppn << AlphaISA::PageShift) +
- AlphaISA::VAddr(req->getVaddr()).offset());
-
- if (write) {
- if (!(pte->xwe & MODE2MASK(mode))) {
- // declare the instruction access fault
- write_acv++;
- uint64_t flags = MM_STAT_WR_MASK |
- MM_STAT_ACV_MASK |
- (pte->fonw ? MM_STAT_FONW_MASK : 0);
- return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
- }
- if (pte->fonw) {
- write_acv++;
- uint64_t flags = MM_STAT_WR_MASK |
- MM_STAT_FONW_MASK;
- return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
- }
} else {
- if (!(pte->xre & MODE2MASK(mode))) {
- read_acv++;
- uint64_t flags = MM_STAT_ACV_MASK |
- (pte->fonr ? MM_STAT_FONR_MASK : 0);
- return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
+ if (write)
+ write_accesses++;
+ else
+ read_accesses++;
+
+ int asn = DTB_ASN_ASN(tc->readMiscReg(IPR_DTB_ASN));
+
+ // not a physical address: need to look up pte
+ PTE *pte = lookup(VAddr(req->getVaddr()).vpn(),
+ asn);
+
+ if (!pte) {
+ // page fault
+ if (write) { write_misses++; } else { read_misses++; }
+ uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
+ MM_STAT_DTB_MISS_MASK;
+ return (req->getFlags() & VPTE) ?
+ (Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(),
+ flags)) :
+ (Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(),
+ flags));
}
- if (pte->fonr) {
- read_acv++;
- uint64_t flags = MM_STAT_FONR_MASK;
- return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
+
+ req->setPaddr((pte->ppn << PageShift) +
+ VAddr(req->getVaddr()).offset());
+
+ if (write) {
+ if (!(pte->xwe & MODE2MASK(mode))) {
+ // declare the instruction access fault
+ write_acv++;
+ uint64_t flags = MM_STAT_WR_MASK |
+ MM_STAT_ACV_MASK |
+ (pte->fonw ? MM_STAT_FONW_MASK : 0);
+ return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
+ }
+ if (pte->fonw) {
+ write_acv++;
+ uint64_t flags = MM_STAT_WR_MASK |
+ MM_STAT_FONW_MASK;
+ return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
+ }
+ } else {
+ if (!(pte->xre & MODE2MASK(mode))) {
+ read_acv++;
+ uint64_t flags = MM_STAT_ACV_MASK |
+ (pte->fonr ? MM_STAT_FONR_MASK : 0);
+ return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
+ }
+ if (pte->fonr) {
+ read_acv++;
+ uint64_t flags = MM_STAT_FONR_MASK;
+ return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
+ }
}
}
+
+ if (write)
+ write_hits++;
+ else
+ read_hits++;
}
- if (write)
- write_hits++;
- else
- read_hits++;
+ // check that the physical address is ok (catch bad physical addresses)
+ if (req->getPaddr() & ~PAddrImplMask)
+ return genMachineCheckFault();
+
+ return checkCacheability(req);
}
- // check that the physical address is ok (catch bad physical addresses)
- if (req->getPaddr() & ~PAddrImplMask)
- return genMachineCheckFault();
+ PTE &
+ TLB::index(bool advance)
+ {
+ PTE *pte = &table[nlu];
- return checkCacheability(req);
-}
+ if (advance)
+ nextnlu();
-AlphaISA::PTE &
-AlphaTLB::index(bool advance)
-{
- AlphaISA::PTE *pte = &table[nlu];
+ return *pte;
+ }
- if (advance)
- nextnlu();
+ DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", TLB)
- return *pte;
-}
+ BEGIN_DECLARE_SIM_OBJECT_PARAMS(ITB)
-DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", AlphaTLB)
+ Param<int> size;
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaITB)
+ END_DECLARE_SIM_OBJECT_PARAMS(ITB)
- Param<int> size;
+ BEGIN_INIT_SIM_OBJECT_PARAMS(ITB)
-END_DECLARE_SIM_OBJECT_PARAMS(AlphaITB)
+ INIT_PARAM_DFLT(size, "TLB size", 48)
-BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaITB)
+ END_INIT_SIM_OBJECT_PARAMS(ITB)
- INIT_PARAM_DFLT(size, "TLB size", 48)
-
-END_INIT_SIM_OBJECT_PARAMS(AlphaITB)
+ CREATE_SIM_OBJECT(ITB)
+ {
+ return new ITB(getInstanceName(), size);
+ }
-CREATE_SIM_OBJECT(AlphaITB)
-{
- return new AlphaITB(getInstanceName(), size);
-}
+ REGISTER_SIM_OBJECT("AlphaITB", ITB)
-REGISTER_SIM_OBJECT("AlphaITB", AlphaITB)
+ BEGIN_DECLARE_SIM_OBJECT_PARAMS(DTB)
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB)
+ Param<int> size;
- Param<int> size;
+ END_DECLARE_SIM_OBJECT_PARAMS(DTB)
-END_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB)
+ BEGIN_INIT_SIM_OBJECT_PARAMS(DTB)
-BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDTB)
+ INIT_PARAM_DFLT(size, "TLB size", 64)
- INIT_PARAM_DFLT(size, "TLB size", 64)
+ END_INIT_SIM_OBJECT_PARAMS(DTB)
-END_INIT_SIM_OBJECT_PARAMS(AlphaDTB)
+ CREATE_SIM_OBJECT(DTB)
+ {
+ return new DTB(getInstanceName(), size);
+ }
-CREATE_SIM_OBJECT(AlphaDTB)
-{
- return new AlphaDTB(getInstanceName(), size);
+ REGISTER_SIM_OBJECT("AlphaDTB", DTB)
}
-
-REGISTER_SIM_OBJECT("AlphaDTB", AlphaDTB)
-
diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh
index 955460649..ea5ba5539 100644
--- a/src/arch/alpha/tlb.hh
+++ b/src/arch/alpha/tlb.hh
@@ -36,6 +36,7 @@
#include "arch/alpha/ev5.hh"
#include "arch/alpha/isa_traits.hh"
+#include "arch/alpha/pagetable.hh"
#include "arch/alpha/utility.hh"
#include "arch/alpha/vtophys.hh"
#include "base/statistics.hh"
@@ -45,82 +46,87 @@
class ThreadContext;
-class AlphaTLB : public SimObject
+namespace AlphaISA
{
- protected:
- typedef std::multimap<Addr, int> PageTable;
- PageTable lookupTable; // Quick lookup into page table
-
- AlphaISA::PTE *table; // the Page Table
- int size; // TLB Size
- int nlu; // not last used entry (for replacement)
-
- void nextnlu() { if (++nlu >= size) nlu = 0; }
- AlphaISA::PTE *lookup(Addr vpn, uint8_t asn) const;
-
- public:
- AlphaTLB(const std::string &name, int size);
- virtual ~AlphaTLB();
-
- int getsize() const { return size; }
-
- AlphaISA::PTE &index(bool advance = true);
- void insert(Addr vaddr, AlphaISA::PTE &pte);
-
- void flushAll();
- void flushProcesses();
- void flushAddr(Addr addr, uint8_t asn);
-
- // static helper functions... really EV5 VM traits
- static bool validVirtualAddress(Addr vaddr) {
- // unimplemented bits must be all 0 or all 1
- Addr unimplBits = vaddr & EV5::VAddrUnImplMask;
- return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask);
- }
-
- static Fault checkCacheability(RequestPtr &req);
-
- // Checkpointing
- virtual void serialize(std::ostream &os);
- virtual void unserialize(Checkpoint *cp, const std::string &section);
-};
-
-class AlphaITB : public AlphaTLB
-{
- protected:
- mutable Stats::Scalar<> hits;
- mutable Stats::Scalar<> misses;
- mutable Stats::Scalar<> acv;
- mutable Stats::Formula accesses;
-
- public:
- AlphaITB(const std::string &name, int size);
- virtual void regStats();
-
- Fault translate(RequestPtr &req, ThreadContext *tc) const;
-};
-
-class AlphaDTB : public AlphaTLB
-{
- protected:
- mutable Stats::Scalar<> read_hits;
- mutable Stats::Scalar<> read_misses;
- mutable Stats::Scalar<> read_acv;
- mutable Stats::Scalar<> read_accesses;
- mutable Stats::Scalar<> write_hits;
- mutable Stats::Scalar<> write_misses;
- mutable Stats::Scalar<> write_acv;
- mutable Stats::Scalar<> write_accesses;
- Stats::Formula hits;
- Stats::Formula misses;
- Stats::Formula acv;
- Stats::Formula accesses;
-
- public:
- AlphaDTB(const std::string &name, int size);
- virtual void regStats();
-
- Fault translate(RequestPtr &req, ThreadContext *tc, bool write) const;
-};
+ class PTE;
+
+ class TLB : public SimObject
+ {
+ protected:
+ typedef std::multimap<Addr, int> PageTable;
+ PageTable lookupTable; // Quick lookup into page table
+
+ PTE *table; // the Page Table
+ int size; // TLB Size
+ int nlu; // not last used entry (for replacement)
+
+ void nextnlu() { if (++nlu >= size) nlu = 0; }
+ PTE *lookup(Addr vpn, uint8_t asn) const;
+
+ public:
+ TLB(const std::string &name, int size);
+ virtual ~TLB();
+
+ int getsize() const { return size; }
+
+ PTE &index(bool advance = true);
+ void insert(Addr vaddr, PTE &pte);
+
+ void flushAll();
+ void flushProcesses();
+ void flushAddr(Addr addr, uint8_t asn);
+
+ // static helper functions... really EV5 VM traits
+ static bool validVirtualAddress(Addr vaddr) {
+ // unimplemented bits must be all 0 or all 1
+ Addr unimplBits = vaddr & EV5::VAddrUnImplMask;
+ return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask);
+ }
+
+ static Fault checkCacheability(RequestPtr &req);
+
+ // Checkpointing
+ virtual void serialize(std::ostream &os);
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
+ };
+
+ class ITB : public TLB
+ {
+ protected:
+ mutable Stats::Scalar<> hits;
+ mutable Stats::Scalar<> misses;
+ mutable Stats::Scalar<> acv;
+ mutable Stats::Formula accesses;
+
+ public:
+ ITB(const std::string &name, int size);
+ virtual void regStats();
+
+ Fault translate(RequestPtr &req, ThreadContext *tc) const;
+ };
+
+ class DTB : public TLB
+ {
+ protected:
+ mutable Stats::Scalar<> read_hits;
+ mutable Stats::Scalar<> read_misses;
+ mutable Stats::Scalar<> read_acv;
+ mutable Stats::Scalar<> read_accesses;
+ mutable Stats::Scalar<> write_hits;
+ mutable Stats::Scalar<> write_misses;
+ mutable Stats::Scalar<> write_acv;
+ mutable Stats::Scalar<> write_accesses;
+ Stats::Formula hits;
+ Stats::Formula misses;
+ Stats::Formula acv;
+ Stats::Formula accesses;
+
+ public:
+ DTB(const std::string &name, int size);
+ virtual void regStats();
+
+ Fault translate(RequestPtr &req, ThreadContext *tc, bool write) const;
+ };
+}
#endif // __ALPHA_MEMORY_HH__
diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh
index 0304d1c3a..100736555 100644
--- a/src/arch/alpha/utility.hh
+++ b/src/arch/alpha/utility.hh
@@ -42,12 +42,18 @@
namespace AlphaISA
{
+ static inline bool
+ inUserMode(ThreadContext *tc)
+ {
+ return (tc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
+ }
+
static inline ExtMachInst
- makeExtMI(MachInst inst, ThreadContext * xc) {
+ makeExtMI(MachInst inst, Addr pc) {
#if FULL_SYSTEM
ExtMachInst ext_inst = inst;
- if (xc->readPC() && 0x1)
- return ext_inst|=(static_cast<ExtMachInst>(xc->readPC() & 0x1) << 32);
+ if (pc && 0x1)
+ return ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
else
return ext_inst;
#else
diff --git a/src/arch/mips/regfile/misc_regfile.hh b/src/arch/mips/regfile/misc_regfile.hh
index a4527a203..368925e00 100644
--- a/src/arch/mips/regfile/misc_regfile.hh
+++ b/src/arch/mips/regfile/misc_regfile.hh
@@ -220,20 +220,20 @@ namespace MipsISA
return miscRegFile[misc_reg];
}
- MiscReg readRegWithEffect(int misc_reg, Fault &fault, ThreadContext *tc)
+ MiscReg readRegWithEffect(int misc_reg, ThreadContext *tc)
{
return miscRegFile[misc_reg];
}
- Fault setReg(int misc_reg, const MiscReg &val)
+ void setReg(int misc_reg, const MiscReg &val)
{
- miscRegFile[misc_reg] = val; return NoFault;
+ miscRegFile[misc_reg] = val;
}
- Fault setRegWithEffect(int misc_reg, const MiscReg &val,
+ void setRegWithEffect(int misc_reg, const MiscReg &val,
ThreadContext *tc)
{
- miscRegFile[misc_reg] = val; return NoFault;
+ miscRegFile[misc_reg] = val;
}
friend class RegFile;
diff --git a/src/arch/mips/regfile/regfile.hh b/src/arch/mips/regfile/regfile.hh
index 3a18c681b..dee883c4a 100644
--- a/src/arch/mips/regfile/regfile.hh
+++ b/src/arch/mips/regfile/regfile.hh
@@ -62,22 +62,20 @@ namespace MipsISA
return miscRegFile.readReg(miscReg);
}
- MiscReg readMiscRegWithEffect(int miscReg,
- Fault &fault, ThreadContext *tc)
+ MiscReg readMiscRegWithEffect(int miscReg, ThreadContext *tc)
{
- fault = NoFault;
- return miscRegFile.readRegWithEffect(miscReg, fault, tc);
+ return miscRegFile.readRegWithEffect(miscReg, tc);
}
- Fault setMiscReg(int miscReg, const MiscReg &val)
+ void setMiscReg(int miscReg, const MiscReg &val)
{
- return miscRegFile.setReg(miscReg, val);
+ miscRegFile.setReg(miscReg, val);
}
- Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
+ void setMiscRegWithEffect(int miscReg, const MiscReg &val,
ThreadContext * tc)
{
- return miscRegFile.setRegWithEffect(miscReg, val, tc);
+ miscRegFile.setRegWithEffect(miscReg, val, tc);
}
FloatRegVal readFloatReg(int floatReg)
@@ -100,24 +98,24 @@ namespace MipsISA
return floatRegFile.readRegBits(floatReg,width);
}
- Fault setFloatReg(int floatReg, const FloatRegVal &val)
+ void setFloatReg(int floatReg, const FloatRegVal &val)
{
- return floatRegFile.setReg(floatReg, val, SingleWidth);
+ floatRegFile.setReg(floatReg, val, SingleWidth);
}
- Fault setFloatReg(int floatReg, const FloatRegVal &val, int width)
+ void setFloatReg(int floatReg, const FloatRegVal &val, int width)
{
- return floatRegFile.setReg(floatReg, val, width);
+ floatRegFile.setReg(floatReg, val, width);
}
- Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
+ void setFloatRegBits(int floatReg, const FloatRegBits &val)
{
- return floatRegFile.setRegBits(floatReg, val, SingleWidth);
+ floatRegFile.setRegBits(floatReg, val, SingleWidth);
}
- Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
+ void setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
{
- return floatRegFile.setRegBits(floatReg, val, width);
+ floatRegFile.setRegBits(floatReg, val, width);
}
IntReg readIntReg(int intReg)
@@ -125,9 +123,9 @@ namespace MipsISA
return intRegFile.readReg(intReg);
}
- Fault setIntReg(int intReg, const IntReg &val)
+ void setIntReg(int intReg, const IntReg &val)
{
- return intRegFile.setReg(intReg, val);
+ intRegFile.setReg(intReg, val);
}
protected:
diff --git a/src/arch/mips/stacktrace.hh b/src/arch/mips/stacktrace.hh
index f9e092dbd..c854f63ca 100644
--- a/src/arch/mips/stacktrace.hh
+++ b/src/arch/mips/stacktrace.hh
@@ -37,6 +37,9 @@
class ThreadContext;
class StackTrace;
+namespace MipsISA
+{
+
class ProcessInfo
{
private:
@@ -118,4 +121,6 @@ StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
return true;
}
+}
+
#endif // __ARCH_MIPS_STACKTRACE_HH__
diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript
index e317502e0..281c166c0 100644
--- a/src/arch/sparc/SConscript
+++ b/src/arch/sparc/SConscript
@@ -54,7 +54,11 @@ base_sources = Split('''
# Full-system sources
full_system_sources = Split('''
- ua2005.cc
+ arguments.cc
+ remote_gdb.cc
+ stacktrace.cc
+ system.cc
+ tlb.cc
vtophys.cc
''')
diff --git a/src/arch/sparc/arguments.cc b/src/arch/sparc/arguments.cc
new file mode 100644
index 000000000..44adf4a15
--- /dev/null
+++ b/src/arch/sparc/arguments.cc
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ */
+
+#include "arch/sparc/arguments.hh"
+#include "arch/sparc/vtophys.hh"
+#include "cpu/thread_context.hh"
+#include "mem/vport.hh"
+
+using namespace SparcISA;
+
+Arguments::Data::~Data()
+{
+ while (!data.empty()) {
+ delete [] data.front();
+ data.pop_front();
+ }
+}
+
+char *
+Arguments::Data::alloc(size_t size)
+{
+ char *buf = new char[size];
+ data.push_back(buf);
+ return buf;
+}
+
+uint64_t
+Arguments::getArg(bool fp)
+{
+ //The caller uses %o0-%05 for the first 6 arguments even if their floating
+ //point. Double precision floating point values take two registers/args.
+ //Quads, structs, and unions are passed as pointers. All arguments beyond
+ //the sixth are passed on the stack past the 16 word window save area,
+ //space for the struct/union return pointer, and space reserved for the
+ //first 6 arguments which the caller may use but doesn't have to.
+ if (number < 6) {
+ return tc->readIntReg(8 + number);
+ } else {
+ Addr sp = tc->readIntReg(14);
+ VirtualPort *vp = tc->getVirtPort(tc);
+ uint64_t arg = vp->read<uint64_t>(sp + 92 + (number-6) * sizeof(uint64_t));
+ tc->delVirtPort(vp);
+ return arg;
+ }
+}
+
diff --git a/src/arch/sparc/arguments.hh b/src/arch/sparc/arguments.hh
new file mode 100644
index 000000000..8f925dd25
--- /dev/null
+++ b/src/arch/sparc/arguments.hh
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ */
+
+#ifndef __ARCH_SPARC_ARGUMENTS_HH__
+#define __ARCH_SPARC_ARGUMENTS_HH__
+
+#include <assert.h>
+
+#include "arch/sparc/vtophys.hh"
+#include "base/refcnt.hh"
+#include "sim/host.hh"
+
+class ThreadContext;
+
+namespace SparcISA {
+
+class Arguments
+{
+ protected:
+ ThreadContext *tc;
+ int number;
+ uint64_t getArg(bool fp = false);
+
+ protected:
+ class Data : public RefCounted
+ {
+ public:
+ Data(){}
+ ~Data();
+
+ private:
+ std::list<char *> data;
+
+ public:
+ char *alloc(size_t size);
+ };
+
+ RefCountingPtr<Data> data;
+
+ public:
+ Arguments(ThreadContext *ctx, int n = 0)
+ : tc(ctx), number(n), data(NULL)
+ { assert(number >= 0); data = new Data;}
+ Arguments(const Arguments &args)
+ : tc(args.tc), number(args.number), data(args.data) {}
+ ~Arguments() {}
+
+ ThreadContext *getThreadContext() const { return tc; }
+
+ const Arguments &operator=(const Arguments &args) {
+ tc = args.tc;
+ number = args.number;
+ data = args.data;
+ return *this;
+ }
+
+ Arguments &operator++() {
+ ++number;
+ assert(number >= 0);
+ return *this;
+ }
+
+ Arguments operator++(int) {
+ Arguments args = *this;
+ ++number;
+ assert(number >= 0);
+ return args;
+ }
+
+ Arguments &operator--() {
+ --number;
+ assert(number >= 0);
+ return *this;
+ }
+
+ Arguments operator--(int) {
+ Arguments args = *this;
+ --number;
+ assert(number >= 0);
+ return args;
+ }
+
+ const Arguments &operator+=(int index) {
+ number += index;
+ assert(number >= 0);
+ return *this;
+ }
+
+ const Arguments &operator-=(int index) {
+ number -= index;
+ assert(number >= 0);
+ return *this;
+ }
+
+ Arguments operator[](int index) {
+ return Arguments(tc, index);
+ }
+
+ template <class T>
+ operator T() {
+ assert(sizeof(T) <= sizeof(uint64_t));
+ T data = static_cast<T>(getArg());
+ return data;
+ }
+
+ template <class T>
+ operator T *() {
+ T *buf = (T *)data->alloc(sizeof(T));
+ CopyData(tc, buf, getArg(), sizeof(T));
+ return buf;
+ }
+
+ operator char *() {
+ char *buf = data->alloc(2048);
+ CopyStringOut(tc, buf, getArg(), 2048);
+ return buf;
+ }
+};
+
+}; // namespace SparcISA
+
+#endif // __ARCH_SPARC_ARGUMENTS_HH__
diff --git a/src/arch/sparc/asi.hh b/src/arch/sparc/asi.hh
index 876567225..6677b23df 100644
--- a/src/arch/sparc/asi.hh
+++ b/src/arch/sparc/asi.hh
@@ -219,4 +219,4 @@ namespace SparcISA
};
-#endif // __ARCH_SPARC_TLB_HH__
+#endif // __ARCH_SPARC_ASI_HH__
diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc
index 2c8da44c5..57ee040f1 100644
--- a/src/arch/sparc/faults.cc
+++ b/src/arch/sparc/faults.cc
@@ -33,12 +33,14 @@
#include "arch/sparc/faults.hh"
#include "arch/sparc/isa_traits.hh"
-#include "arch/sparc/process.hh"
+#include "arch/sparc/types.hh"
#include "base/bitfield.hh"
#include "base/trace.hh"
+#include "config/full_system.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#if !FULL_SYSTEM
+#include "arch/sparc/process.hh"
#include "mem/page_table.hh"
#include "sim/process.hh"
#endif
@@ -48,214 +50,352 @@ using namespace std;
namespace SparcISA
{
-FaultName InternalProcessorError::_name = "intprocerr";
-TrapType InternalProcessorError::_trapType = 0x029;
-FaultPriority InternalProcessorError::_priority = 4;
-FaultStat InternalProcessorError::_count;
-
-FaultName MemAddressNotAligned::_name = "unalign";
-TrapType MemAddressNotAligned::_trapType = 0x034;
-FaultPriority MemAddressNotAligned::_priority = 10;
-FaultStat MemAddressNotAligned::_count;
-
-FaultName PowerOnReset::_name = "pow_reset";
-TrapType PowerOnReset::_trapType = 0x001;
-FaultPriority PowerOnReset::_priority = 0;
-FaultStat PowerOnReset::_count;
-
-FaultName WatchDogReset::_name = "watch_dog_reset";
-TrapType WatchDogReset::_trapType = 0x002;
-FaultPriority WatchDogReset::_priority = 1;
-FaultStat WatchDogReset::_count;
-
-FaultName ExternallyInitiatedReset::_name = "extern_reset";
-TrapType ExternallyInitiatedReset::_trapType = 0x003;
-FaultPriority ExternallyInitiatedReset::_priority = 1;
-FaultStat ExternallyInitiatedReset::_count;
-
-FaultName SoftwareInitiatedReset::_name = "software_reset";
-TrapType SoftwareInitiatedReset::_trapType = 0x004;
-FaultPriority SoftwareInitiatedReset::_priority = 1;
-FaultStat SoftwareInitiatedReset::_count;
-
-FaultName REDStateException::_name = "red_counte";
-TrapType REDStateException::_trapType = 0x005;
-FaultPriority REDStateException::_priority = 1;
-FaultStat REDStateException::_count;
-
-FaultName InstructionAccessException::_name = "inst_access";
-TrapType InstructionAccessException::_trapType = 0x008;
-FaultPriority InstructionAccessException::_priority = 5;
-FaultStat InstructionAccessException::_count;
-
-FaultName InstructionAccessMMUMiss::_name = "inst_mmu";
-TrapType InstructionAccessMMUMiss::_trapType = 0x009;
-FaultPriority InstructionAccessMMUMiss::_priority = 2;
-FaultStat InstructionAccessMMUMiss::_count;
-
-FaultName InstructionAccessError::_name = "inst_error";
-TrapType InstructionAccessError::_trapType = 0x00A;
-FaultPriority InstructionAccessError::_priority = 3;
-FaultStat InstructionAccessError::_count;
-
-FaultName IllegalInstruction::_name = "illegal_inst";
-TrapType IllegalInstruction::_trapType = 0x010;
-FaultPriority IllegalInstruction::_priority = 7;
-FaultStat IllegalInstruction::_count;
-
-FaultName PrivilegedOpcode::_name = "priv_opcode";
-TrapType PrivilegedOpcode::_trapType = 0x011;
-FaultPriority PrivilegedOpcode::_priority = 6;
-FaultStat PrivilegedOpcode::_count;
-
-FaultName UnimplementedLDD::_name = "unimp_ldd";
-TrapType UnimplementedLDD::_trapType = 0x012;
-FaultPriority UnimplementedLDD::_priority = 6;
-FaultStat UnimplementedLDD::_count;
-
-FaultName UnimplementedSTD::_name = "unimp_std";
-TrapType UnimplementedSTD::_trapType = 0x013;
-FaultPriority UnimplementedSTD::_priority = 6;
-FaultStat UnimplementedSTD::_count;
-
-FaultName FpDisabled::_name = "fp_disabled";
-TrapType FpDisabled::_trapType = 0x020;
-FaultPriority FpDisabled::_priority = 8;
-FaultStat FpDisabled::_count;
-
-FaultName FpExceptionIEEE754::_name = "fp_754";
-TrapType FpExceptionIEEE754::_trapType = 0x021;
-FaultPriority FpExceptionIEEE754::_priority = 11;
-FaultStat FpExceptionIEEE754::_count;
-
-FaultName FpExceptionOther::_name = "fp_other";
-TrapType FpExceptionOther::_trapType = 0x022;
-FaultPriority FpExceptionOther::_priority = 11;
-FaultStat FpExceptionOther::_count;
-
-FaultName TagOverflow::_name = "tag_overflow";
-TrapType TagOverflow::_trapType = 0x023;
-FaultPriority TagOverflow::_priority = 14;
-FaultStat TagOverflow::_count;
-
-FaultName DivisionByZero::_name = "div_by_zero";
-TrapType DivisionByZero::_trapType = 0x028;
-FaultPriority DivisionByZero::_priority = 15;
-FaultStat DivisionByZero::_count;
-
-FaultName DataAccessException::_name = "data_access";
-TrapType DataAccessException::_trapType = 0x030;
-FaultPriority DataAccessException::_priority = 12;
-FaultStat DataAccessException::_count;
-
-FaultName DataAccessMMUMiss::_name = "data_mmu";
-TrapType DataAccessMMUMiss::_trapType = 0x031;
-FaultPriority DataAccessMMUMiss::_priority = 12;
-FaultStat DataAccessMMUMiss::_count;
-
-FaultName DataAccessError::_name = "data_error";
-TrapType DataAccessError::_trapType = 0x032;
-FaultPriority DataAccessError::_priority = 12;
-FaultStat DataAccessError::_count;
-
-FaultName DataAccessProtection::_name = "data_protection";
-TrapType DataAccessProtection::_trapType = 0x033;
-FaultPriority DataAccessProtection::_priority = 12;
-FaultStat DataAccessProtection::_count;
-
-FaultName LDDFMemAddressNotAligned::_name = "unalign_lddf";
-TrapType LDDFMemAddressNotAligned::_trapType = 0x035;
-FaultPriority LDDFMemAddressNotAligned::_priority = 10;
-FaultStat LDDFMemAddressNotAligned::_count;
-
-FaultName STDFMemAddressNotAligned::_name = "unalign_stdf";
-TrapType STDFMemAddressNotAligned::_trapType = 0x036;
-FaultPriority STDFMemAddressNotAligned::_priority = 10;
-FaultStat STDFMemAddressNotAligned::_count;
-
-FaultName PrivilegedAction::_name = "priv_action";
-TrapType PrivilegedAction::_trapType = 0x037;
-FaultPriority PrivilegedAction::_priority = 11;
-FaultStat PrivilegedAction::_count;
-
-FaultName LDQFMemAddressNotAligned::_name = "unalign_ldqf";
-TrapType LDQFMemAddressNotAligned::_trapType = 0x038;
-FaultPriority LDQFMemAddressNotAligned::_priority = 10;
-FaultStat LDQFMemAddressNotAligned::_count;
-
-FaultName STQFMemAddressNotAligned::_name = "unalign_stqf";
-TrapType STQFMemAddressNotAligned::_trapType = 0x039;
-FaultPriority STQFMemAddressNotAligned::_priority = 10;
-FaultStat STQFMemAddressNotAligned::_count;
-
-FaultName AsyncDataError::_name = "async_data";
-TrapType AsyncDataError::_trapType = 0x040;
-FaultPriority AsyncDataError::_priority = 2;
-FaultStat AsyncDataError::_count;
-
-FaultName CleanWindow::_name = "clean_win";
-TrapType CleanWindow::_trapType = 0x024;
-FaultPriority CleanWindow::_priority = 10;
-FaultStat CleanWindow::_count;
-
-//The enumerated faults
-
-FaultName InterruptLevelN::_name = "interrupt_n";
-TrapType InterruptLevelN::_baseTrapType = 0x041;
-FaultStat InterruptLevelN::_count;
-
-FaultName SpillNNormal::_name = "spill_n_normal";
-TrapType SpillNNormal::_baseTrapType = 0x080;
-FaultPriority SpillNNormal::_priority = 9;
-FaultStat SpillNNormal::_count;
-
-FaultName SpillNOther::_name = "spill_n_other";
-TrapType SpillNOther::_baseTrapType = 0x0A0;
-FaultPriority SpillNOther::_priority = 9;
-FaultStat SpillNOther::_count;
-
-FaultName FillNNormal::_name = "fill_n_normal";
-TrapType FillNNormal::_baseTrapType = 0x0C0;
-FaultPriority FillNNormal::_priority = 9;
-FaultStat FillNNormal::_count;
-
-FaultName FillNOther::_name = "fill_n_other";
-TrapType FillNOther::_baseTrapType = 0x0E0;
-FaultPriority FillNOther::_priority = 9;
-FaultStat FillNOther::_count;
-
-FaultName TrapInstruction::_name = "trap_inst_n";
-TrapType TrapInstruction::_baseTrapType = 0x100;
-FaultPriority TrapInstruction::_priority = 16;
-FaultStat TrapInstruction::_count;
+template<> SparcFaultBase::FaultVals
+ SparcFault<PowerOnReset>::vals =
+ {"power_on_reset", 0x001, 0, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<WatchDogReset>::vals =
+ {"watch_dog_reset", 0x002, 120, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<ExternallyInitiatedReset>::vals =
+ {"externally_initiated_reset", 0x003, 110, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<SoftwareInitiatedReset>::vals =
+ {"software_initiated_reset", 0x004, 130, {SH, SH, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<REDStateException>::vals =
+ {"RED_state_exception", 0x005, 1, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<StoreError>::vals =
+ {"store_error", 0x007, 201, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<InstructionAccessException>::vals =
+ {"instruction_access_exception", 0x008, 300, {H, H, H}};
+
+//XXX This trap is apparently dropped from ua2005
+/*template<> SparcFaultBase::FaultVals
+ SparcFault<InstructionAccessMMUMiss>::vals =
+ {"inst_mmu", 0x009, 2, {H, H, H}};*/
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<InstructionAccessError>::vals =
+ {"instruction_access_error", 0x00A, 400, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<IllegalInstruction>::vals =
+ {"illegal_instruction", 0x010, 620, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<PrivilegedOpcode>::vals =
+ {"privileged_opcode", 0x011, 700, {P, SH, SH}};
+
+//XXX This trap is apparently dropped from ua2005
+/*template<> SparcFaultBase::FaultVals
+ SparcFault<UnimplementedLDD>::vals =
+ {"unimp_ldd", 0x012, 6, {H, H, H}};*/
+
+//XXX This trap is apparently dropped from ua2005
+/*template<> SparcFaultBase::FaultVals
+ SparcFault<UnimplementedSTD>::vals =
+ {"unimp_std", 0x013, 6, {H, H, H}};*/
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<FpDisabled>::vals =
+ {"fp_disabled", 0x020, 800, {P, P, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<FpExceptionIEEE754>::vals =
+ {"fp_exception_ieee_754", 0x021, 1110, {P, P, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<FpExceptionOther>::vals =
+ {"fp_exception_other", 0x022, 1110, {P, P, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<TagOverflow>::vals =
+ {"tag_overflow", 0x023, 1400, {P, P, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<CleanWindow>::vals =
+ {"clean_window", 0x024, 1010, {P, P, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<DivisionByZero>::vals =
+ {"division_by_zero", 0x028, 1500, {P, P, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<InternalProcessorError>::vals =
+ {"internal_processor_error", 0x029, 4, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<InstructionInvalidTSBEntry>::vals =
+ {"instruction_invalid_tsb_entry", 0x02A, 210, {H, H, SH}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<DataInvalidTSBEntry>::vals =
+ {"data_invalid_tsb_entry", 0x02B, 1203, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<DataAccessException>::vals =
+ {"data_access_exception", 0x030, 1201, {H, H, H}};
+
+//XXX This trap is apparently dropped from ua2005
+/*template<> SparcFaultBase::FaultVals
+ SparcFault<DataAccessMMUMiss>::vals =
+ {"data_mmu", 0x031, 12, {H, H, H}};*/
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<DataAccessError>::vals =
+ {"data_access_error", 0x032, 1210, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<DataAccessProtection>::vals =
+ {"data_access_protection", 0x033, 1207, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<MemAddressNotAligned>::vals =
+ {"mem_address_not_aligned", 0x034, 1020, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<LDDFMemAddressNotAligned>::vals =
+ {"LDDF_mem_address_not_aligned", 0x035, 1010, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<STDFMemAddressNotAligned>::vals =
+ {"STDF_mem_address_not_aligned", 0x036, 1010, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<PrivilegedAction>::vals =
+ {"privileged_action", 0x037, 1110, {H, H, SH}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<LDQFMemAddressNotAligned>::vals =
+ {"LDQF_mem_address_not_aligned", 0x038, 1010, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<STQFMemAddressNotAligned>::vals =
+ {"STQF_mem_address_not_aligned", 0x039, 1010, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<InstructionRealTranslationMiss>::vals =
+ {"instruction_real_translation_miss", 0x03E, 208, {H, H, SH}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<DataRealTranslationMiss>::vals =
+ {"data_real_translation_miss", 0x03F, 1203, {H, H, H}};
+
+//XXX This trap is apparently dropped from ua2005
+/*template<> SparcFaultBase::FaultVals
+ SparcFault<AsyncDataError>::vals =
+ {"async_data", 0x040, 2, {H, H, H}};*/
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<InterruptLevelN>::vals =
+ {"interrupt_level_n", 0x041, 0, {P, P, SH}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<HstickMatch>::vals =
+ {"hstick_match", 0x05E, 1601, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<TrapLevelZero>::vals =
+ {"trap_level_zero", 0x05F, 202, {H, H, SH}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<PAWatchpoint>::vals =
+ {"PA_watchpoint", 0x061, 1209, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<VAWatchpoint>::vals =
+ {"VA_watchpoint", 0x062, 1120, {P, P, SH}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<FastInstructionAccessMMUMiss>::vals =
+ {"fast_instruction_access_MMU_miss", 0x064, 208, {H, H, SH}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<FastDataAccessMMUMiss>::vals =
+ {"fast_data_access_MMU_miss", 0x068, 1203, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<FastDataAccessProtection>::vals =
+ {"fast_data_access_protection", 0x06C, 1207, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<InstructionBreakpoint>::vals =
+ {"instruction_break", 0x076, 610, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<CpuMondo>::vals =
+ {"cpu_mondo", 0x07C, 1608, {P, P, SH}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<DevMondo>::vals =
+ {"dev_mondo", 0x07D, 1611, {P, P, SH}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<ResumeableError>::vals =
+ {"resume_error", 0x07E, 3330, {P, P, SH}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<SpillNNormal>::vals =
+ {"spill_n_normal", 0x080, 900, {P, P, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<SpillNOther>::vals =
+ {"spill_n_other", 0x0A0, 900, {P, P, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<FillNNormal>::vals =
+ {"fill_n_normal", 0x0C0, 900, {P, P, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<FillNOther>::vals =
+ {"fill_n_other", 0x0E0, 900, {P, P, H}};
+
+template<> SparcFaultBase::FaultVals
+ SparcFault<TrapInstruction>::vals =
+ {"trap_instruction", 0x100, 1602, {P, P, H}};
#if !FULL_SYSTEM
-FaultName PageTableFault::_name = "page_table_fault";
-TrapType PageTableFault::_trapType = 0x0000;
-FaultPriority PageTableFault::_priority = 0;
-FaultStat PageTableFault::_count;
+template<> SparcFaultBase::FaultVals
+ SparcFault<PageTableFault>::vals =
+ {"page_table_fault", 0x0000, 0, {SH, SH, SH}};
#endif
/**
+ * This causes the thread context to enter RED state. This causes the side
+ * effects which go with entering RED state because of a trap.
+ */
+
+void enterREDState(ThreadContext *tc)
+{
+ //@todo Disable the mmu?
+ //@todo Disable watchpoints?
+ MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
+ //HPSTATE.red = 1
+ HPSTATE |= (1 << 5);
+ //HPSTATE.hpriv = 1
+ HPSTATE |= (1 << 2);
+ tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
+}
+
+/**
+ * This sets everything up for a RED state trap except for actually jumping to
+ * the handler.
+ */
+
+void doREDFault(ThreadContext *tc, TrapType tt)
+{
+ MiscReg TL = tc->readMiscReg(MISCREG_TL);
+ MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE);
+ MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
+ MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
+ MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
+ MiscReg ASI = tc->readMiscReg(MISCREG_ASI);
+ MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
+ MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
+ MiscReg GL = tc->readMiscReg(MISCREG_GL);
+ MiscReg PC = tc->readPC();
+ MiscReg NPC = tc->readNextPC();
+
+ TL++;
+
+ //set TSTATE.gl to gl
+ replaceBits(TSTATE, 42, 40, GL);
+ //set TSTATE.ccr to ccr
+ replaceBits(TSTATE, 39, 32, CCR);
+ //set TSTATE.asi to asi
+ replaceBits(TSTATE, 31, 24, ASI);
+ //set TSTATE.pstate to pstate
+ replaceBits(TSTATE, 20, 8, PSTATE);
+ //set TSTATE.cwp to cwp
+ replaceBits(TSTATE, 4, 0, CWP);
+
+ //Write back TSTATE
+ tc->setMiscReg(MISCREG_TSTATE, TSTATE);
+
+ //set TPC to PC
+ tc->setMiscReg(MISCREG_TPC, PC);
+ //set TNPC to NPC
+ tc->setMiscReg(MISCREG_TNPC, NPC);
+
+ //set HTSTATE.hpstate to hpstate
+ tc->setMiscReg(MISCREG_HTSTATE, HPSTATE);
+
+ //TT = trap type;
+ tc->setMiscReg(MISCREG_TT, tt);
+
+ //Update GL
+ tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL));
+
+ //set PSTATE.mm to 00
+ //set PSTATE.pef to 1
+ PSTATE |= (1 << 4);
+ //set PSTATE.am to 0
+ PSTATE &= ~(1 << 3);
+ //set PSTATE.priv to 0
+ PSTATE &= ~(1 << 2);
+ //set PSTATE.ie to 0
+ PSTATE &= ~(1 << 1);
+ //set PSTATE.cle to 0
+ PSTATE &= ~(1 << 9);
+ //PSTATE.tle is unchanged
+ //XXX Where is the tct bit?
+ //set PSTATE.tct to 0
+ tc->setMiscReg(MISCREG_PSTATE, PSTATE);
+
+ //set HPSTATE.red to 1
+ HPSTATE |= (1 << 5);
+ //set HPSTATE.hpriv to 1
+ HPSTATE |= (1 << 2);
+ //set HPSTATE.ibe to 0
+ HPSTATE &= ~(1 << 10);
+ //set HPSTATE.tlz to 0
+ HPSTATE &= ~(1 << 0);
+ tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
+
+ bool changedCWP = true;
+ if(tt == 0x24)
+ CWP++;
+ else if(0x80 <= tt && tt <= 0xbf)
+ CWP += (CANSAVE + 2);
+ else if(0xc0 <= tt && tt <= 0xff)
+ CWP--;
+ else
+ changedCWP = false;
+
+ if(changedCWP)
+ {
+ CWP = (CWP + NWindows) % NWindows;
+ tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
+ }
+}
+
+/**
* This sets everything up for a normal trap except for actually jumping to
- * the handler. It will need to be expanded to include the state machine in
- * the manual. Right now it assumes that traps will always be to the
- * privileged level.
+ * the handler.
*/
-void doNormalFault(ThreadContext *tc, TrapType tt)
+void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
{
- uint64_t TL = tc->readMiscReg(MISCREG_TL);
- uint64_t TSTATE = tc->readMiscReg(MISCREG_TSTATE);
- uint64_t PSTATE = tc->readMiscReg(MISCREG_PSTATE);
- uint64_t HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
- uint64_t CCR = tc->readMiscReg(MISCREG_CCR);
- uint64_t ASI = tc->readMiscReg(MISCREG_ASI);
- uint64_t CWP = tc->readMiscReg(MISCREG_CWP);
- uint64_t CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
- uint64_t GL = tc->readMiscReg(MISCREG_GL);
- uint64_t PC = tc->readPC();
- uint64_t NPC = tc->readNextPC();
+ MiscReg TL = tc->readMiscReg(MISCREG_TL);
+ MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE);
+ MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
+ MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
+ MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
+ MiscReg ASI = tc->readMiscReg(MISCREG_ASI);
+ MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
+ MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
+ MiscReg GL = tc->readMiscReg(MISCREG_GL);
+ MiscReg PC = tc->readPC();
+ MiscReg NPC = tc->readNextPC();
//Increment the trap level
TL++;
@@ -289,10 +429,10 @@ void doNormalFault(ThreadContext *tc, TrapType tt)
tc->setMiscReg(MISCREG_TT, tt);
//Update the global register level
- if(1/*We're delivering the trap in priveleged mode*/)
- tc->setMiscReg(MISCREG_GL, max<int>(GL+1, MaxGL));
+ if(!gotoHpriv)
+ tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxPGL));
else
- tc->setMiscReg(MISCREG_GL, max<int>(GL+1, MaxPGL));
+ tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL));
//PSTATE.mm is unchanged
//PSTATE.pef = whether or not an fpu is present
@@ -301,7 +441,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt)
PSTATE |= (1 << 4);
//PSTATE.am = 0
PSTATE &= ~(1 << 3);
- if(1/*We're delivering the trap in priveleged mode*/)
+ if(!gotoHpriv)
{
//PSTATE.priv = 1
PSTATE |= (1 << 2);
@@ -322,7 +462,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt)
//XXX Where exactly is this field?
tc->setMiscReg(MISCREG_PSTATE, PSTATE);
- if(0/*We're delivering the trap in hyperprivileged mode*/)
+ if(gotoHpriv)
{
//HPSTATE.red = 0
HPSTATE &= ~(1 << 5);
@@ -351,47 +491,135 @@ void doNormalFault(ThreadContext *tc, TrapType tt)
}
}
+void getREDVector(Addr & PC, Addr & NPC)
+{
+ //XXX The following constant might belong in a header file.
+ const Addr RSTVAddr = 0xFFFFFFFFF0000000ULL;
+ PC = RSTVAddr | 0xA0;
+ NPC = PC + sizeof(MachInst);
+}
+
+void getHyperVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT)
+{
+ Addr HTBA = tc->readMiscReg(MISCREG_HTBA);
+ PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14));
+ NPC = PC + sizeof(MachInst);
+}
+
+void getPrivVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT, MiscReg TL)
+{
+ Addr TBA = tc->readMiscReg(MISCREG_TBA);
+ PC = (TBA & ~mask(15)) |
+ (TL > 1 ? (1 << 14) : 0) |
+ ((TT << 5) & mask(14));
+ NPC = PC + sizeof(MachInst);
+}
+
#if FULL_SYSTEM
-void SparcFault::invoke(ThreadContext * tc)
+void SparcFaultBase::invoke(ThreadContext * tc)
{
FaultBase::invoke(tc);
countStat()++;
- //Use the SPARC trap state machine
- /*// exception restart address
- if (setRestartAddress() || !tc->inPalMode())
- tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, tc->regs.pc);
+ //We can refer to this to see what the trap level -was-, but something
+ //in the middle could change it in the regfile out from under us.
+ MiscReg TL = tc->readMiscReg(MISCREG_TL);
+ MiscReg TT = tc->readMiscReg(MISCREG_TT);
+ MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
+ MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
- if (skipFaultingInstruction()) {
- // traps... skip faulting instruction.
- tc->setMiscReg(AlphaISA::IPR_EXC_ADDR,
- tc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4);
- }
+ Addr PC, NPC;
- if (!tc->inPalMode())
- AlphaISA::swap_palshadow(&(tc->regs), true);
+ PrivilegeLevel current;
+ if(!(PSTATE & (1 << 2)))
+ current = User;
+ else if(!(HPSTATE & (1 << 2)))
+ current = Privileged;
+ else
+ current = Hyperprivileged;
- tc->regs.pc = tc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect();
- tc->regs.npc = tc->regs.pc + sizeof(MachInst);*/
-}
+ PrivilegeLevel level = getNextLevel(current);
-#endif
+ if(HPSTATE & (1 << 5) || TL == MaxTL - 1)
+ {
+ getREDVector(PC, NPC);
+ enterREDState(tc);
+ doREDFault(tc, TT);
+ }
+ else if(TL == MaxTL)
+ {
+ //Do error_state somehow?
+ //Probably inject a WDR fault using the interrupt mechanism.
+ //What should the PC and NPC be set to?
+ }
+ else if(TL > MaxPTL && level == Privileged)
+ {
+ //guest_watchdog fault
+ doNormalFault(tc, trapType(), true);
+ getHyperVector(tc, PC, NPC, 2);
+ }
+ else if(level == Hyperprivileged)
+ {
+ doNormalFault(tc, trapType(), true);
+ getHyperVector(tc, PC, NPC, trapType());
+ }
+ else
+ {
+ doNormalFault(tc, trapType(), false);
+ getPrivVector(tc, PC, NPC, trapType(), TL+1);
+ }
-#if !FULL_SYSTEM
+ tc->setPC(PC);
+ tc->setNextPC(NPC);
+ tc->setNextNPC(NPC + sizeof(MachInst));
+}
-void TrapInstruction::invoke(ThreadContext * tc)
+void PowerOnReset::invoke(ThreadContext * tc)
{
- // Should be handled in ISA.
+ //First, enter RED state.
+ enterREDState(tc);
+
+ //For SPARC, when a system is first started, there is a power
+ //on reset Trap which sets the processor into the following state.
+ //Bits that aren't set aren't defined on startup.
+ /*
+ tl = MaxTL;
+ gl = MaxGL;
+
+ tickFields.counter = 0; //The TICK register is unreadable bya
+ tickFields.npt = 1; //The TICK register is unreadable by by !priv
+
+ softint = 0; // Clear all the soft interrupt bits
+ tick_cmprFields.int_dis = 1; // disable timer compare interrupts
+ tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
+ stickFields.npt = 1; //The TICK register is unreadable by by !priv
+ stick_cmprFields.int_dis = 1; // disable timer compare interrupts
+ stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
+
+ tt[tl] = _trapType;
+ pstate = 0; // fields 0 but pef
+ pstateFields.pef = 1;
+
+ hpstate = 0;
+ hpstateFields.red = 1;
+ hpstateFields.hpriv = 1;
+ hpstateFields.tlz = 0; // this is a guess
+ hintp = 0; // no interrupts pending
+ hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
+ hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
+ */
}
+#else // !FULL_SYSTEM
+
void SpillNNormal::invoke(ThreadContext *tc)
{
- doNormalFault(tc, trapType());
+ doNormalFault(tc, trapType(), false);
Process *p = tc->getProcessPtr();
- //This will only work in faults from a SparcLiveProcess
+ //XXX This will only work in faults from a SparcLiveProcess
SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
assert(lp);
@@ -404,15 +632,15 @@ void SpillNNormal::invoke(ThreadContext *tc)
void FillNNormal::invoke(ThreadContext *tc)
{
- doNormalFault(tc, trapType());
+ doNormalFault(tc, trapType(), false);
Process * p = tc->getProcessPtr();
- //This will only work in faults from a SparcLiveProcess
+ //XXX This will only work in faults from a SparcLiveProcess
SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
assert(lp);
- //The adjust the PC and NPC
+ //Then adjust the PC and NPC
Addr fillStart = lp->readFillStart();
tc->setPC(fillStart);
tc->setNextPC(fillStart + sizeof(MachInst));
diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh
index 394a06294..e632502aa 100644
--- a/src/arch/sparc/faults.hh
+++ b/src/arch/sparc/faults.hh
@@ -42,579 +42,240 @@ namespace SparcISA
typedef uint32_t TrapType;
typedef uint32_t FaultPriority;
-class SparcFault : public FaultBase
-{
- public:
+class SparcFaultBase : public FaultBase
+{
+ public:
+ enum PrivilegeLevel
+ {
+ U, User = U,
+ P, Privileged = P,
+ H, Hyperprivileged = H,
+ NumLevels,
+ SH = -1,
+ ShouldntHappen = SH
+ };
+ struct FaultVals
+ {
+ const FaultName name;
+ const TrapType trapType;
+ const FaultPriority priority;
+ const PrivilegeLevel nextPrivilegeLevel[NumLevels];
+ FaultStat count;
+ };
#if FULL_SYSTEM
void invoke(ThreadContext * tc);
#endif
+ virtual FaultName name() = 0;
virtual TrapType trapType() = 0;
virtual FaultPriority priority() = 0;
virtual FaultStat & countStat() = 0;
+ virtual PrivilegeLevel getNextLevel(PrivilegeLevel current) = 0;
};
-class InternalProcessorError : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
- bool isMachineCheckFault() {return true;}
-};
-
-class MemAddressNotAligned : public SparcFault
+template<typename T>
+class SparcFault : public SparcFaultBase
{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
+ protected:
+ static FaultVals vals;
public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
- bool isAlignmentFault() {return true;}
+ FaultName name() {return vals.name;}
+ TrapType trapType() {return vals.trapType;}
+ FaultPriority priority() {return vals.priority;}
+ FaultStat & countStat() {return vals.count;}
+ PrivilegeLevel getNextLevel(PrivilegeLevel current)
+ {
+ return vals.nextPrivilegeLevel[current];
+ }
};
-#if !FULL_SYSTEM
-class PageTableFault : public SparcFault
+class PowerOnReset : public SparcFault<PowerOnReset>
{
- private:
- Addr vaddr;
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- PageTableFault(Addr va)
- : vaddr(va) {}
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
void invoke(ThreadContext * tc);
};
-static inline Fault genPageTableFault(Addr va)
-{
- return new PageTableFault(va);
-}
-#endif
+class WatchDogReset : public SparcFault<WatchDogReset> {};
-static inline Fault genMachineCheckFault()
-{
- return new InternalProcessorError;
-}
+class ExternallyInitiatedReset : public SparcFault<ExternallyInitiatedReset> {};
-static inline Fault genAlignmentFault()
-{
- return new MemAddressNotAligned;
-}
+class SoftwareInitiatedReset : public SparcFault<SoftwareInitiatedReset> {};
-class PowerOnReset : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class REDStateException : public SparcFault<REDStateException> {};
-class WatchDogReset : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class StoreError : public SparcFault<StoreError> {};
-class ExternallyInitiatedReset : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class InstructionAccessException : public SparcFault<InstructionAccessException> {};
-class SoftwareInitiatedReset : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+//class InstructionAccessMMUMiss : public SparcFault<InstructionAccessMMUMiss> {};
-class REDStateException : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class InstructionAccessError : public SparcFault<InstructionAccessError> {};
-class InstructionAccessException : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class IllegalInstruction : public SparcFault<IllegalInstruction> {};
-class InstructionAccessMMUMiss : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class PrivilegedOpcode : public SparcFault<PrivilegedOpcode> {};
-class InstructionAccessError : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+//class UnimplementedLDD : public SparcFault<UnimplementedLDD> {};
-class IllegalInstruction : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+//class UnimplementedSTD : public SparcFault<UnimplementedSTD> {};
-class PrivilegedOpcode : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class FpDisabled : public SparcFault<FpDisabled> {};
-class UnimplementedLDD : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class FpExceptionIEEE754 : public SparcFault<FpExceptionIEEE754> {};
-class UnimplementedSTD : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class FpExceptionOther : public SparcFault<FpExceptionOther> {};
-class FpDisabled : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class TagOverflow : public SparcFault<TagOverflow> {};
-class FpExceptionIEEE754 : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class CleanWindow : public SparcFault<CleanWindow> {};
-class FpExceptionOther : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class DivisionByZero : public SparcFault<DivisionByZero> {};
-class TagOverflow : public SparcFault
+class InternalProcessorError :
+ public SparcFault<InternalProcessorError>
{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
+ bool isMachineCheckFault() {return true;}
};
-class DivisionByZero : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class InstructionInvalidTSBEntry : public SparcFault<InstructionInvalidTSBEntry> {};
-class DataAccessException : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class DataInvalidTSBEntry : public SparcFault<DataInvalidTSBEntry> {};
-class DataAccessMMUMiss : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class DataAccessException : public SparcFault<DataAccessException> {};
-class DataAccessError : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+//class DataAccessMMUMiss : public SparcFault<DataAccessMMUMiss> {};
-class DataAccessProtection : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class DataAccessError : public SparcFault<DataAccessError> {};
-class LDDFMemAddressNotAligned : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class DataAccessProtection : public SparcFault<DataAccessProtection> {};
-class STDFMemAddressNotAligned : public SparcFault
+class MemAddressNotAligned :
+ public SparcFault<MemAddressNotAligned>
{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
+ bool isAlignmentFault() {return true;}
};
-class PrivilegedAction : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class LDDFMemAddressNotAligned : public SparcFault<LDDFMemAddressNotAligned> {};
-class LDQFMemAddressNotAligned : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class STDFMemAddressNotAligned : public SparcFault<STDFMemAddressNotAligned> {};
-class STQFMemAddressNotAligned : public SparcFault
-{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
- public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-};
+class PrivilegedAction : public SparcFault<PrivilegedAction> {};
+
+class LDQFMemAddressNotAligned : public SparcFault<LDQFMemAddressNotAligned> {};
+
+class STQFMemAddressNotAligned : public SparcFault<STQFMemAddressNotAligned> {};
+
+class InstructionRealTranslationMiss :
+ public SparcFault<InstructionRealTranslationMiss> {};
+
+class DataRealTranslationMiss : public SparcFault<DataRealTranslationMiss> {};
-class AsyncDataError : public SparcFault
+//class AsyncDataError : public SparcFault<AsyncDataError> {};
+
+template <class T>
+class EnumeratedFault : public SparcFault<T>
{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
+ protected:
+ uint32_t _n;
public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
+ EnumeratedFault(uint32_t n) : SparcFault<T>(), _n(n) {}
+ TrapType trapType() {return SparcFault<T>::trapType() + _n;}
};
-class CleanWindow : public SparcFault
+class InterruptLevelN : public EnumeratedFault<InterruptLevelN>
{
- private:
- static FaultName _name;
- static TrapType _trapType;
- static FaultPriority _priority;
- static FaultStat _count;
public:
- FaultName name() {return _name;}
- TrapType trapType() {return _trapType;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
+ InterruptLevelN(uint32_t n) : EnumeratedFault<InterruptLevelN>(n) {;}
+ FaultPriority priority() {return 3200 - _n*100;}
};
-class EnumeratedFault : public SparcFault
+class HstickMatch : public SparcFault<HstickMatch> {};
+
+class TrapLevelZero : public SparcFault<TrapLevelZero> {};
+
+class PAWatchpoint : public SparcFault<PAWatchpoint> {};
+
+class VAWatchpoint : public SparcFault<VAWatchpoint> {};
+
+class FastInstructionAccessMMUMiss :
+ public SparcFault<FastInstructionAccessMMUMiss> {};
+
+class FastDataAccessMMUMiss : public SparcFault<FastDataAccessMMUMiss> {};
+
+class FastDataAccessProtection : public SparcFault<FastDataAccessProtection> {};
+
+class InstructionBreakpoint : public SparcFault<InstructionBreakpoint> {};
+
+class CpuMondo : public SparcFault<CpuMondo> {};
+
+class DevMondo : public SparcFault<DevMondo> {};
+
+class ResumeableError : public SparcFault<ResumeableError> {};
+
+class SpillNNormal : public EnumeratedFault<SpillNNormal>
{
- protected:
- uint32_t _n;
- virtual TrapType baseTrapType() = 0;
public:
- EnumeratedFault(uint32_t n) : SparcFault() {_n = n;}
- TrapType trapType() {return baseTrapType() + _n;}
+ SpillNNormal(uint32_t n) : EnumeratedFault<SpillNNormal>(n) {;}
+ //These need to be handled specially to enable spill traps in SE
+#if !FULL_SYSTEM
+ void invoke(ThreadContext * tc);
+#endif
};
-class InterruptLevelN : public EnumeratedFault
+class SpillNOther : public EnumeratedFault<SpillNOther>
{
- private:
- static FaultName _name;
- static TrapType _baseTrapType;
- static FaultStat _count;
- TrapType baseTrapType() {return _baseTrapType;}
public:
- InterruptLevelN(uint32_t n) : EnumeratedFault(n) {;}
- FaultName name() {return _name;}
- FaultPriority priority() {return 32 - _n;}
- FaultStat & countStat() {return _count;}
+ SpillNOther(uint32_t n) : EnumeratedFault<SpillNOther>(n) {;}
};
-class SpillNNormal : public EnumeratedFault
+class FillNNormal : public EnumeratedFault<FillNNormal>
{
- private:
- static FaultName _name;
- static TrapType _baseTrapType;
- static FaultPriority _priority;
- static FaultStat _count;
- TrapType baseTrapType() {return _baseTrapType;}
public:
- SpillNNormal(uint32_t n) : EnumeratedFault(n) {;}
- FaultName name() {return _name;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
+ FillNNormal(uint32_t n) : EnumeratedFault<FillNNormal>(n) {;}
+ //These need to be handled specially to enable fill traps in SE
+#if !FULL_SYSTEM
void invoke(ThreadContext * tc);
+#endif
};
-class SpillNOther : public EnumeratedFault
+class FillNOther : public EnumeratedFault<FillNOther>
{
- private:
- static FaultName _name;
- static TrapType _baseTrapType;
- static FaultPriority _priority;
- static FaultStat _count;
- TrapType baseTrapType() {return _baseTrapType;}
public:
- SpillNOther(uint32_t n) : EnumeratedFault(n) {;}
- FaultName name() {return _name;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
+ FillNOther(uint32_t n) : EnumeratedFault<FillNOther>(n) {;}
};
-class FillNNormal : public EnumeratedFault
+class TrapInstruction : public EnumeratedFault<TrapInstruction>
{
- private:
- static FaultName _name;
- static TrapType _baseTrapType;
- static FaultPriority _priority;
- static FaultStat _count;
- TrapType baseTrapType() {return _baseTrapType;}
+
public:
- FillNNormal(uint32_t n) : EnumeratedFault(n) {;}
- FaultName name() {return _name;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
+ TrapInstruction(uint32_t n) : EnumeratedFault<TrapInstruction>(n) {;}
};
-class FillNOther : public EnumeratedFault
+#if !FULL_SYSTEM
+class PageTableFault : public SparcFault<PageTableFault>
{
private:
- static FaultName _name;
- static TrapType _baseTrapType;
- static FaultPriority _priority;
- static FaultStat _count;
- TrapType baseTrapType() {return _baseTrapType;}
+ Addr vaddr;
public:
- FillNOther(uint32_t n) : EnumeratedFault(n) {;}
- FaultName name() {return _name;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
+ PageTableFault(Addr va) : vaddr(va) {}
+ void invoke(ThreadContext * tc);
};
-class TrapInstruction : public EnumeratedFault
+static inline Fault genPageTableFault(Addr va)
{
- private:
- static FaultName _name;
- static TrapType _baseTrapType;
- static FaultPriority _priority;
- static FaultStat _count;
- uint64_t syscall_num;
- TrapType baseTrapType() {return _baseTrapType;}
- public:
- TrapInstruction(uint32_t n, uint64_t syscall) :
- EnumeratedFault(n), syscall_num(syscall) {;}
- FaultName name() {return _name;}
- FaultPriority priority() {return _priority;}
- FaultStat & countStat() {return _count;}
-#if !FULL_SYSTEM
- void invoke(ThreadContext * tc);
+ return new PageTableFault(va);
+}
#endif
-};
+
+static inline Fault genMachineCheckFault()
+{
+ return new InternalProcessorError;
+}
+
+static inline Fault genAlignmentFault()
+{
+ return new MemAddressNotAligned;
+}
} // SparcISA namespace
diff --git a/src/arch/sparc/floatregfile.cc b/src/arch/sparc/floatregfile.cc
index 3afe6ef54..7f3d5a758 100644
--- a/src/arch/sparc/floatregfile.cc
+++ b/src/arch/sparc/floatregfile.cc
@@ -34,6 +34,8 @@
#include "sim/byteswap.hh"
#include "sim/serialize.hh"
+#include <string.h>
+
using namespace SparcISA;
using namespace std;
@@ -55,7 +57,7 @@ string SparcISA::getFloatRegName(RegIndex index)
void FloatRegFile::clear()
{
- bzero(regSpace, sizeof(regSpace));
+ memset(regSpace, 0, sizeof(regSpace));
}
FloatReg FloatRegFile::readReg(int floatReg, int width)
diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh
new file mode 100644
index 000000000..0072f4184
--- /dev/null
+++ b/src/arch/sparc/interrupts.hh
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_SPARC_INTERRUPT_HH__
+#define __ARCH_SPARC_INTERRUPT_HH__
+
+#include "arch/sparc/faults.hh"
+
+namespace SparcISA
+{
+ class Interrupts
+ {
+ protected:
+ Fault interrupts[NumInterruptLevels];
+ bool requested[NumInterruptLevels];
+
+ public:
+ Interrupts()
+ {
+ for(int x = 0; x < NumInterruptLevels; x++)
+ {
+ interrupts[x] = new InterruptLevelN(x);
+ requested[x] = false;
+ }
+ }
+ void post(int int_num, int index)
+ {
+ if(int_num < 0 || int_num >= NumInterruptLevels)
+ panic("int_num out of bounds\n");
+
+ requested[int_num] = true;
+ }
+
+ void clear(int int_num, int index)
+ {
+ requested[int_num] = false;
+ }
+
+ void clear_all()
+ {
+ for(int x = 0; x < NumInterruptLevels; x++)
+ requested[x] = false;
+ }
+
+ bool check_interrupts(ThreadContext * tc) const
+ {
+ return true;
+ }
+
+ Fault getInterrupt(ThreadContext * tc)
+ {
+ return NoFault;
+ }
+
+ void serialize(std::ostream &os)
+ {
+ }
+
+ void unserialize(Checkpoint *cp, const std::string &section)
+ {
+ }
+ };
+}
+
+#endif // __ARCH_SPARC_INTERRUPT_HH__
diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc
index 164f194dd..0e313dc94 100644
--- a/src/arch/sparc/intregfile.cc
+++ b/src/arch/sparc/intregfile.cc
@@ -33,6 +33,8 @@
#include "base/trace.hh"
#include "sim/serialize.hh"
+#include <string.h>
+
using namespace SparcISA;
using namespace std;
@@ -62,7 +64,7 @@ void IntRegFile::clear()
for (x = 0; x < MaxGL; x++)
memset(regGlobals[x], 0, sizeof(IntReg) * RegsPerFrame);
for(int x = 0; x < 2 * NWindows; x++)
- bzero(regSegments[x], sizeof(IntReg) * RegsPerFrame);
+ memset(regSegments[x], 0, sizeof(IntReg) * RegsPerFrame);
}
IntRegFile::IntRegFile()
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index a64ff09bb..4f3ea7810 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -346,22 +346,93 @@ decode OP default Unknown::unknown()
0x0: sra({{Rd = Rs1.sw >> (I ? SHCNT32 : Rs2<4:0>);}});
0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}});
}
- // XXX might want a format rdipr thing here
0x28: decode RS1 {
- 0xF: decode I {
+ 0x00: NoPriv::rdy({{Rd = Y;}});
+ //1 should cause an illegal instruction exception
+ 0x02: NoPriv::rdccr({{Rd = Ccr;}});
+ 0x03: NoPriv::rdasi({{Rd = Asi;}});
+ 0x04: PrivCheck::rdtick({{Rd = Tick;}}, {{Tick<63:>}});
+ 0x05: NoPriv::rdpc({{
+ if(Pstate<3:>)
+ Rd = (xc->readPC())<31:0>;
+ else
+ Rd = xc->readPC();}});
+ 0x06: NoPriv::rdfprs({{
+ //Wait for all fpops to finish.
+ Rd = Fprs;
+ }});
+ //7-14 should cause an illegal instruction exception
+ 0x0F: decode I {
0x0: Nop::stbar({{/*stuff*/}});
0x1: Nop::membar({{/*stuff*/}});
}
- default: rdasr({{
- Rd = xc->readMiscRegWithEffect(RS1 + AsrStart, fault);
+ 0x10: Priv::rdpcr({{Rd = Pcr;}});
+ 0x11: PrivCheck::rdpic({{Rd = Pic;}}, {{Pcr<0:>}});
+ //0x12 should cause an illegal instruction exception
+ 0x13: NoPriv::rdgsr({{
+ if(Fprs<2:> == 0 || Pstate<4:> == 0)
+ Rd = Gsr;
+ else
+ fault = new FpDisabled;
}});
+ //0x14-0x15 should cause an illegal instruction exception
+ 0x16: Priv::rdsoftint({{Rd = Softint;}});
+ 0x17: Priv::rdtick_cmpr({{Rd = TickCmpr;}});
+ 0x18: PrivCheck::rdstick({{Rd = Stick}}, {{Stick<63:>}});
+ 0x19: Priv::rdstick_cmpr({{Rd = StickCmpr;}});
+ //0x1A-0x1F should cause an illegal instruction exception
+ }
+ 0x29: decode RS1 {
+ 0x00: HPriv::rdhprhpstate({{Rd = Hpstate;}});
+ 0x01: HPriv::rdhprhtstate({{
+ if(Tl == 0)
+ return new IllegalInstruction;
+ Rd = Htstate;
+ }});
+ //0x02 should cause an illegal instruction exception
+ 0x03: HPriv::rdhprhintp({{Rd = Hintp;}});
+ //0x04 should cause an illegal instruction exception
+ 0x05: HPriv::rdhprhtba({{Rd = Htba;}});
+ 0x06: HPriv::rdhprhver({{Rd = Hver;}});
+ //0x07-0x1E should cause an illegal instruction exception
+ 0x1F: HPriv::rdhprhstick_cmpr({{Rd = HstickCmpr;}});
+ }
+ 0x2A: decode RS1 {
+ 0x00: Priv::rdprtpc({{
+ if(Tl == 0)
+ return new IllegalInstruction;
+ Rd = Tpc;
+ }});
+ 0x01: Priv::rdprtnpc({{
+ if(Tl == 0)
+ return new IllegalInstruction;
+ Rd = Tnpc;
+ }});
+ 0x02: Priv::rdprtstate({{
+ if(Tl == 0)
+ return new IllegalInstruction;
+ Rd = Tstate;
+ }});
+ 0x03: Priv::rdprtt({{
+ if(Tl == 0)
+ return new IllegalInstruction;
+ Rd = Tt;
+ }});
+ 0x04: Priv::rdprtick({{Rd = Tick;}});
+ 0x05: Priv::rdprtba({{Rd = Tba;}});
+ 0x06: Priv::rdprpstate({{Rd = Pstate;}});
+ 0x07: Priv::rdprtl({{Rd = Tl;}});
+ 0x08: Priv::rdprpil({{Rd = Pil;}});
+ 0x09: Priv::rdprcwp({{Rd = Cwp;}});
+ 0x0A: Priv::rdprcansave({{Rd = Cansave;}});
+ 0x0B: Priv::rdprcanrestore({{Rd = Canrestore;}});
+ 0x0C: Priv::rdprcleanwin({{Rd = Cleanwin;}});
+ 0x0D: Priv::rdprotherwin({{Rd = Otherwin;}});
+ 0x0E: Priv::rdprwstate({{Rd = Wstate;}});
+ //0x0F should cause an illegal instruction exception
+ 0x10: Priv::rdprgl({{Rd = Gl;}});
+ //0x11-0x1F should cause an illegal instruction exception
}
- 0x29: HPriv::rdhpr({{
- Rd = xc->readMiscRegWithEffect(RS1 + HprStart, fault);
- }});
- 0x2A: Priv::rdpr({{
- Rd = xc->readMiscRegWithEffect(RS1 + PrStart, fault);
- }});
0x2B: BasicOperate::flushw({{
if(NWindows - 2 - Cansave == 0)
{
@@ -417,9 +488,35 @@ decode OP default Unknown::unknown()
0x6: movrg({{Rd = (Rs1.sdw > 0) ? Rs2_or_imm10 : Rd;}});
0x7: movrge({{Rd = (Rs1.sdw >= 0) ? Rs2_or_imm10 : Rd;}});
}
- 0x30: wrasr({{
- xc->setMiscRegWithEffect(RD + AsrStart, Rs1 ^ Rs2_or_imm13);
- }});
+ 0x30: decode RD {
+ 0x00: NoPriv::wry({{Y = Rs1 ^ Rs2_or_imm13;}});
+ //0x01 should cause an illegal instruction exception
+ 0x02: NoPriv::wrccr({{Ccr = Rs1 ^ Rs2_or_imm13;}});
+ 0x03: NoPriv::wrasi({{Ccr = Rs1 ^ Rs2_or_imm13;}});
+ //0x04-0x05 should cause an illegal instruction exception
+ 0x06: NoPriv::wrfprs({{Fprs = Rs1 ^ Rs2_or_imm13;}});
+ //0x07-0x0E should cause an illegal instruction exception
+ 0x0F: Trap::softreset({{fault = new SoftwareInitiatedReset;}});
+ 0x10: Priv::wrpcr({{Pcr = Rs1 ^ Rs2_or_imm13;}});
+ 0x11: PrivCheck::wrpic({{Pic = Rs1 ^ Rs2_or_imm13;}}, {{Pcr<0:>}});
+ //0x12 should cause an illegal instruction exception
+ 0x13: NoPriv::wrgsr({{
+ if(Fprs<2:> == 0 || Pstate<4:> == 0)
+ return new FpDisabled;
+ Gsr = Rs1 ^ Rs2_or_imm13;
+ }});
+ 0x14: Priv::wrsoftint_set({{SoftintSet = Rs1 ^ Rs2_or_imm13;}});
+ 0x15: Priv::wrsoftint_clr({{SoftintClr = Rs1 ^ Rs2_or_imm13;}});
+ 0x16: Priv::wrsoftint({{Softint = Rs1 ^ Rs2_or_imm13;}});
+ 0x17: Priv::wrtick_cmpr({{TickCmpr = Rs1 ^ Rs2_or_imm13;}});
+ 0x18: NoPriv::wrstick({{
+ if(!Hpstate<2:>)
+ return new IllegalInstruction;
+ Stick = Rs1 ^ Rs2_or_imm13;
+ }});
+ 0x19: Priv::wrstick_cmpr({{StickCmpr = Rs1 ^ Rs2_or_imm13;}});
+ //0x1A-0x1F should cause an illegal instruction exception
+ }
0x31: decode FCN {
0x0: Priv::saved({{
assert(Cansave < NWindows - 2);
@@ -440,16 +537,70 @@ decode OP default Unknown::unknown()
Otherwin = Otherwin - 1;
}});
}
- 0x32: Priv::wrpr({{
- // XXX Need to protect with format that traps non-priv
- // access
- xc->setMiscRegWithEffect(RD + PrStart, Rs1 ^ Rs2_or_imm13);
- }});
- 0x33: HPriv::wrhpr({{
- // XXX Need to protect with format that traps non-priv/priv
- // access
- xc->setMiscRegWithEffect(RD + HprStart, Rs1 ^ Rs2_or_imm13);
- }});
+ 0x32: decode RD {
+ 0x00: Priv::wrprtpc({{
+ if(Tl == 0)
+ return new IllegalInstruction;
+ else
+ Tpc = Rs1 ^ Rs2_or_imm13;
+ }});
+ 0x01: Priv::wrprtnpc({{
+ if(Tl == 0)
+ return new IllegalInstruction;
+ else
+ Tnpc = Rs1 ^ Rs2_or_imm13;
+ }});
+ 0x02: Priv::wrprtstate({{
+ if(Tl == 0)
+ return new IllegalInstruction;
+ else
+ Tstate = Rs1 ^ Rs2_or_imm13;
+ }});
+ 0x03: Priv::wrprtt({{
+ if(Tl == 0)
+ return new IllegalInstruction;
+ else
+ Tt = Rs1 ^ Rs2_or_imm13;
+ }});
+ 0x04: HPriv::wrprtick({{Tick = Rs1 ^ Rs2_or_imm13;}});
+ 0x05: Priv::wrprtba({{Tba = Rs1 ^ Rs2_or_imm13;}});
+ 0x06: Priv::wrprpstate({{Pstate = Rs1 ^ Rs2_or_imm13;}});
+ 0x07: Priv::wrprtl({{
+ if(Pstate<2:> && !Hpstate<2:>)
+ Tl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxPTL);
+ else
+ Tl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxTL);
+ }});
+ 0x08: Priv::wrprpil({{Pil = Rs1 ^ Rs2_or_imm13;}});
+ 0x09: Priv::wrprcwp({{Cwp = Rs1 ^ Rs2_or_imm13;}});
+ 0x0A: Priv::wrprcansave({{Cansave = Rs1 ^ Rs2_or_imm13;}});
+ 0x0B: Priv::wrprcanrestore({{Canrestore = Rs1 ^ Rs2_or_imm13;}});
+ 0x0C: Priv::wrprcleanwin({{Cleanwin = Rs1 ^ Rs2_or_imm13;}});
+ 0x0D: Priv::wrprotherwin({{Otherwin = Rs1 ^ Rs2_or_imm13;}});
+ 0x0E: Priv::wrprwstate({{Wstate = Rs1 ^ Rs2_or_imm13;}});
+ //0x0F should cause an illegal instruction exception
+ 0x10: Priv::wrprgl({{
+ if(Pstate<2:> && !Hpstate<2:>)
+ Gl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxPGL);
+ else
+ Gl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxGL);
+ }});
+ //0x11-0x1F should cause an illegal instruction exception
+ }
+ 0x33: decode RD {
+ 0x00: HPriv::wrhprhpstate({{Hpstate = Rs1 ^ Rs2_or_imm13;}});
+ 0x01: HPriv::wrhprhtstate({{
+ if(Tl == 0)
+ return new IllegalInstruction;
+ Htstate = Rs1 ^ Rs2_or_imm13;
+ }});
+ //0x02 should cause an illegal instruction exception
+ 0x03: HPriv::wrhprhintp({{Hintp = Rs1 ^ Rs2_or_imm13;}});
+ //0x04 should cause an illegal instruction exception
+ 0x05: HPriv::wrhprhtba({{Htba = Rs1 ^ Rs2_or_imm13;}});
+ //0x06-0x01D should cause an illegal instruction exception
+ 0x1F: HPriv::wrhprhstick_cmpr({{HstickCmpr = Rs1 ^ Rs2_or_imm13;}});
+ }
0x34: decode OPF{
format BasicOperate{
0x01: fmovs({{
diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa
index 04c67d332..55bf968f4 100644
--- a/src/arch/sparc/isa/formats/priv.isa
+++ b/src/arch/sparc/isa/formats/priv.isa
@@ -119,18 +119,34 @@ let {{
return (header_output, decoder_output, exec_output, decode_block)
}};
-// Primary format for integer operate instructions:
def format Priv(code, *opt_flags) {{
- checkCode = "!(Pstate<2:2> || Hpstate<2:2>)"
+ checkCode = "!(Pstate<2:> || Hpstate<2:>)"
(header_output, decoder_output,
exec_output, decode_block) = doPrivFormat(code,
- checkCode, name, Name, opt_flags + ('IprAccessOp',))
+ checkCode, name, Name, opt_flags)
+}};
+
+def format NoPriv(code, *opt_flags) {{
+ #Instructions which use this format don't really check for
+ #any particular mode, but the disassembly is performed
+ #using the control registers actual name
+ checkCode = "false"
+ (header_output, decoder_output,
+ exec_output, decode_block) = doPrivFormat(code,
+ checkCode, name, Name, opt_flags)
+}};
+
+def format PrivCheck(code, extraCheckCode, *opt_flags) {{
+ checkCode = "(%s) && !(Pstate<2:> || Hpstate<2:>)" % extraCheckCode
+ (header_output, decoder_output,
+ exec_output, decode_block) = doPrivFormat(code,
+ checkCode, name, Name, opt_flags)
}};
def format HPriv(code, *opt_flags) {{
checkCode = "!Hpstate<2:2>"
(header_output, decoder_output,
exec_output, decode_block) = doPrivFormat(code,
- checkCode, name, Name, opt_flags + ('IprAccessOp',))
+ checkCode, name, Name, opt_flags)
}};
diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa
index a324756ec..624afb693 100644
--- a/src/arch/sparc/isa/includes.isa
+++ b/src/arch/sparc/isa/includes.isa
@@ -54,6 +54,7 @@ output decoder {{
#if defined(linux)
#include <fenv.h>
#endif
+#include <algorithm>
using namespace SparcISA;
}};
diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa
index 80b499b91..caee20b0c 100644
--- a/src/arch/sparc/isa/operands.isa
+++ b/src/arch/sparc/isa/operands.isa
@@ -80,8 +80,6 @@ def operands {{
'Frs2': ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12),
'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31),
'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32),
- #'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1),
- #'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1),
'R0': ('IntReg', 'udw', '0', None, 6),
'R1': ('IntReg', 'udw', '1', None, 7),
'R15': ('IntReg', 'udw', '15', 'IsInteger', 8),
@@ -91,24 +89,42 @@ def operands {{
'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40),
'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41),
'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 42),
+ 'Fprs': ('ControlReg', 'udw', 'MISCREG_FPRS', None, 43),
+ 'Pcr': ('ControlReg', 'udw', 'MISCREG_PCR', None, 44),
+ 'Pic': ('ControlReg', 'udw', 'MISCREG_PIC', None, 45),
+ 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 46),
+ 'Softint': ('ControlReg', 'udw', 'MISCREG_SOFTINT', None, 47),
+ 'SoftintSet': ('ControlReg', 'udw', 'MISCREG_SOFTINT_SET', None, 48),
+ 'SoftintClr': ('ControlReg', 'udw', 'MISCREG_SOFTINT_CLR', None, 49),
+ 'TickCmpr': ('ControlReg', 'udw', 'MISCREG_TICK_CMPR', None, 50),
+ 'Stick': ('ControlReg', 'udw', 'MISCREG_STICK', None, 51),
+ 'StickCmpr': ('ControlReg', 'udw', 'MISCREG_STICK_CMPR', None, 52),
- 'Tpc': ('ControlReg', 'udw', 'MISCREG_TPC', None, 43),
- 'Tnpc': ('ControlReg', 'udw', 'MISCREG_TNPC', None, 44),
- 'Tstate': ('ControlReg', 'udw', 'MISCREG_TSTATE', None, 45),
- 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 46),
- 'Hpstate': ('ControlReg', 'udw', 'MISCREG_HPSTATE', None, 47),
- 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 48),
+ 'Tpc': ('ControlReg', 'udw', 'MISCREG_TPC', None, 53),
+ 'Tnpc': ('ControlReg', 'udw', 'MISCREG_TNPC', None, 54),
+ 'Tstate': ('ControlReg', 'udw', 'MISCREG_TSTATE', None, 55),
+ 'Tt': ('ControlReg', 'udw', 'MISCREG_TT', None, 56),
+ 'Tick': ('ControlReg', 'udw', 'MISCREG_TICK', None, 57),
+ 'Tba': ('ControlReg', 'udw', 'MISCREG_TBA', None, 58),
+ 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 59),
+ 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 60),
+ 'Pil': ('ControlReg', 'udw', 'MISCREG_PIL', None, 61),
+ 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 62),
+ 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63),
+ 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64),
+ 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65),
+ 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66),
+ 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67),
+ 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 68),
- 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 49),
- 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 50),
- 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 51),
- 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 52),
- 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 53),
- 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 54),
- 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 55),
+ 'Hpstate': ('ControlReg', 'udw', 'MISCREG_HPSTATE', None, 69),
+ 'Htstate': ('ControlReg', 'udw', 'MISCREG_HTSTATE', None, 70),
+ 'Hintp': ('ControlReg', 'udw', 'MISCREG_HINTP', None, 71),
+ 'Htba': ('ControlReg', 'udw', 'MISCREG_HTBA', None, 72),
+ 'HstickCmpr': ('ControlReg', 'udw', 'MISCREG_HSTICK_CMPR', None, 73),
+ 'Hver': ('ControlReg', 'udw', 'MISCREG_HVER', None, 74),
- 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 56),
- 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 57),
+ 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 80),
# Mem gets a large number so it's always last
'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100)
diff --git a/src/arch/sparc/kernel_stats.hh b/src/arch/sparc/kernel_stats.hh
new file mode 100644
index 000000000..c007c54c2
--- /dev/null
+++ b/src/arch/sparc/kernel_stats.hh
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_SPARC_KERNEL_STATS_HH__
+#define __ARCH_SPARC_KERNEL_STATS_HH__
+
+#include <map>
+#include <stack>
+#include <string>
+#include <vector>
+
+#include "kern/kernel_stats.hh"
+
+namespace SparcISA {
+namespace Kernel {
+
+enum cpu_mode { hypervisor, kernel, user, idle, cpu_mode_num };
+extern const char *modestr[];
+
+class Statistics : public ::Kernel::Statistics
+{
+ public:
+ Statistics(System *system) : ::Kernel::Statistics(system)
+ {}
+};
+
+} /* end namespace AlphaISA::Kernel */
+} /* end namespace AlphaISA */
+
+#endif // __ARCH_SPARC_KERNEL_STATS_HH__
diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc
index bf4572878..d52e3983f 100644
--- a/src/arch/sparc/miscregfile.cc
+++ b/src/arch/sparc/miscregfile.cc
@@ -29,11 +29,18 @@
* Ali Saidi
*/
+#include "arch/sparc/asi.hh"
#include "arch/sparc/miscregfile.hh"
+#include "base/bitfield.hh"
#include "base/trace.hh"
+#include "config/full_system.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
+#if FULL_SYSTEM
+#include "arch/sparc/system.hh"
+#endif
+
using namespace SparcISA;
using namespace std;
@@ -55,66 +62,41 @@ string SparcISA::getMiscRegName(RegIndex index)
return miscRegName[index];
}
-#if FULL_SYSTEM
-
-//XXX These need an implementation someplace
-/** Fullsystem only register version of ReadRegWithEffect() */
-MiscReg MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
-/** Fullsystem only register version of SetRegWithEffect() */
-Fault MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
- ThreadContext * tc);
-#endif
-
void MiscRegFile::reset()
{
- pstateFields.pef = 0; //No FPU
- //pstateFields.pef = 1; //FPU
-#if FULL_SYSTEM
- //For SPARC, when a system is first started, there is a power
- //on reset Trap which sets the processor into the following state.
- //Bits that aren't set aren't defined on startup.
- tl = MaxTL;
- gl = MaxGL;
-
- tickFields.counter = 0; //The TICK register is unreadable bya
- tickFields.npt = 1; //The TICK register is unreadable by by !priv
-
- softint = 0; // Clear all the soft interrupt bits
- tick_cmprFields.int_dis = 1; // disable timer compare interrupts
- tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
- stickFields.npt = 1; //The TICK register is unreadable by by !priv
- stick_cmprFields.int_dis = 1; // disable timer compare interrupts
- stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
-
-
- tt[tl] = power_on_reset;
- pstate = 0; // fields 0 but pef
- pstateFields.pef = 1;
-
+ y = 0;
+ ccr = 0;
+ asi = 0;
+ tick = 0;
+ fprs = 0;
+ gsr = 0;
+ softint = 0;
+ tick_cmpr = 0;
+ stick = 0;
+ stick_cmpr = 0;
+ memset(tpc, 0, sizeof(tpc));
+ memset(tnpc, 0, sizeof(tnpc));
+ memset(tstate, 0, sizeof(tstate));
+ memset(tt, 0, sizeof(tt));
+ pstate = 0;
+ tl = 0;
+ pil = 0;
+ cwp = 0;
+ cansave = 0;
+ canrestore = 0;
+ cleanwin = 0;
+ otherwin = 0;
+ wstate = 0;
+ gl = 0;
hpstate = 0;
- hpstateFields.red = 1;
- hpstateFields.hpriv = 1;
- hpstateFields.tlz = 0; // this is a guess
- hintp = 0; // no interrupts pending
- hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
- hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
-#else
-/* //This sets up the initial state of the processor for usermode processes
- pstateFields.priv = 0; //Process runs in user mode
- pstateFields.ie = 1; //Interrupts are enabled
- fsrFields.rd = 0; //Round to nearest
- fsrFields.tem = 0; //Floating point traps not enabled
- fsrFields.ns = 0; //Non standard mode off
- fsrFields.qne = 0; //Floating point queue is empty
- fsrFields.aexc = 0; //No accrued exceptions
- fsrFields.cexc = 0; //No current exceptions
-
- //Register window management registers
- otherwin = 0; //No windows contain info from other programs
- canrestore = 0; //There are no windows to pop
- cansave = MaxTL - 2; //All windows are available to save into
- cleanwin = MaxTL;*/
-#endif
+ memset(htstate, 0, sizeof(htstate));
+ hintp = 0;
+ htba = 0;
+ hstick_cmpr = 0;
+ strandStatusReg = 0;
+ fsr = 0;
+ implicitInstAsi = ASI_PRIMARY;
+ implicitDataAsi = ASI_PRIMARY;
}
MiscReg MiscRegFile::readReg(int miscReg)
@@ -131,8 +113,9 @@ MiscReg MiscRegFile::readReg(int miscReg)
case MISCREG_TICK:
return tick;
case MISCREG_PCR:
+ panic("PCR not implemented\n");
case MISCREG_PIC:
- panic("ASR number %d not implemented\n", miscReg - AsrStart);
+ panic("PIC not implemented\n");
case MISCREG_GSR:
return gsr;
case MISCREG_SOFTINT:
@@ -207,17 +190,27 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc)
switch (miscReg) {
case MISCREG_TICK:
case MISCREG_PRIVTICK:
- return tc->getCpuPtr()->curCycle() - tickFields.counter |
- tickFields.npt << 63;
+ return tc->getCpuPtr()->curCycle() - (tick & mask(63)) |
+ (tick & ~(mask(63))) << 63;
case MISCREG_FPRS:
panic("FPU not implemented\n");
case MISCREG_PCR:
case MISCREG_PIC:
panic("Performance Instrumentation not impl\n");
-
/** Floating Point Status Register */
case MISCREG_FSR:
panic("Floating Point not implemented\n");
+//We'll include this only in FS so we don't need the SparcSystem type around
+//in SE.
+#if FULL_SYSTEM
+ case MISCREG_STICK:
+ SparcSystem *sys;
+ sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
+ assert(sys != NULL);
+ return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63)));
+#endif
+ case MISCREG_HVER:
+ return NWindows | MaxTL << 8 | MaxGL << 16;
}
return readReg(miscReg);
}
@@ -241,8 +234,9 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val)
tick = val;
break;
case MISCREG_PCR:
+ panic("PCR not implemented\n");
case MISCREG_PIC:
- panic("ASR number %d not implemented\n", miscReg - AsrStart);
+ panic("PIC not implemented\n");
case MISCREG_GSR:
gsr = val;
break;
@@ -337,14 +331,42 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val)
}
}
+inline void MiscRegFile::setImplicitAsis()
+{
+ //The spec seems to use trap level to indicate the privilege level of the
+ //processor. It's unclear whether the implicit ASIs should directly depend
+ //on the trap level, or if they should really be based on the privelege
+ //bits
+ if(tl == 0)
+ {
+ implicitInstAsi = implicitDataAsi =
+ (pstate & (1 << 9)) ? ASI_PRIMARY_LITTLE : ASI_PRIMARY;
+ }
+ else if(tl <= MaxPTL)
+ {
+ implicitInstAsi = ASI_NUCLEUS;
+ implicitDataAsi = (pstate & (1 << 9)) ? ASI_NUCLEUS_LITTLE : ASI_NUCLEUS;
+ }
+ else
+ {
+ //This is supposed to force physical addresses to match the spec.
+ //It might not because of context values and partition values.
+ implicitInstAsi = implicitDataAsi = ASI_REAL;
+ }
+}
+
void MiscRegFile::setRegWithEffect(int miscReg,
const MiscReg &val, ThreadContext * tc)
{
const uint64_t Bit64 = (1ULL << 63);
+#if FULL_SYSTEM
+ uint64_t time;
+ SparcSystem *sys;
+#endif
switch (miscReg) {
case MISCREG_TICK:
- tickFields.counter = tc->getCpuPtr()->curCycle() - val & ~Bit64;
- tickFields.npt = val & Bit64 ? 1 : 0;
+ tick = tc->getCpuPtr()->curCycle() - val & ~Bit64;
+ tick |= val & Bit64;
break;
case MISCREG_FPRS:
//Configure the fpu based on the fprs
@@ -352,12 +374,84 @@ void MiscRegFile::setRegWithEffect(int miscReg,
case MISCREG_PCR:
//Set up performance counting based on pcr value
break;
+ case MISCREG_PSTATE:
+ pstate = val;
+ setImplicitAsis();
+ return;
+ case MISCREG_TL:
+ tl = val;
+ setImplicitAsis();
+ return;
case MISCREG_CWP:
tc->changeRegFileContext(CONTEXT_CWP, val);
break;
case MISCREG_GL:
tc->changeRegFileContext(CONTEXT_GLOBALS, val);
break;
+ case MISCREG_SOFTINT:
+ //We need to inject interrupts, and or notify the interrupt
+ //object that it needs to use a different interrupt level.
+ //Any newly appropriate interrupts will happen when the cpu gets
+ //around to checking for them. This might not be quite what we
+ //want.
+ break;
+ case MISCREG_SOFTINT_CLR:
+ //Do whatever this is supposed to do...
+ break;
+ case MISCREG_SOFTINT_SET:
+ //Do whatever this is supposed to do...
+ break;
+#if FULL_SYSTEM
+ case MISCREG_TICK_CMPR:
+ if (tickCompare == NULL)
+ tickCompare = new TickCompareEvent(this, tc);
+ setReg(miscReg, val);
+ if ((tick_cmpr & mask(63)) && tickCompare->scheduled())
+ tickCompare->deschedule();
+ time = (tick_cmpr & mask(63)) - (tick & mask(63));
+ if (!(tick_cmpr & ~mask(63)) && time > 0)
+ tickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
+ break;
+#endif
+ case MISCREG_PIL:
+ //We need to inject interrupts, and or notify the interrupt
+ //object that it needs to use a different interrupt level.
+ //Any newly appropriate interrupts will happen when the cpu gets
+ //around to checking for them. This might not be quite what we
+ //want.
+ break;
+//We'll include this only in FS so we don't need the SparcSystem type around
+//in SE.
+#if FULL_SYSTEM
+ case MISCREG_STICK:
+ sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
+ assert(sys != NULL);
+ sys->sysTick = curTick/Clock::Int::ns - val & ~Bit64;
+ stick |= val & Bit64;
+ break;
+ case MISCREG_STICK_CMPR:
+ if (sTickCompare == NULL)
+ sTickCompare = new STickCompareEvent(this, tc);
+ sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
+ assert(sys != NULL);
+ if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled())
+ sTickCompare->deschedule();
+ time = (stick_cmpr & mask(63)) - sys->sysTick;
+ if (!(stick_cmpr & ~mask(63)) && time > 0)
+ sTickCompare->schedule(time * Clock::Int::ns);
+ break;
+ case MISCREG_HSTICK_CMPR:
+ if (hSTickCompare == NULL)
+ hSTickCompare = new HSTickCompareEvent(this, tc);
+ sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
+ assert(sys != NULL);
+ if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled())
+ hSTickCompare->deschedule();
+ int64_t time = (hstick_cmpr & mask(63)) - sys->sysTick;
+ if (!(hstick_cmpr & ~mask(63)) && time > 0)
+ hSTickCompare->schedule(time * Clock::Int::ns);
+ break;
+#endif
}
setReg(miscReg, val);
}
@@ -389,6 +483,8 @@ void MiscRegFile::serialize(std::ostream & os)
SERIALIZE_ARRAY(htstate, MaxTL);
SERIALIZE_SCALAR(htba);
SERIALIZE_SCALAR(hstick_cmpr);
+ SERIALIZE_SCALAR((int)implicitInstAsi);
+ SERIALIZE_SCALAR((int)implicitDataAsi);
}
void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
@@ -418,5 +514,29 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
UNSERIALIZE_ARRAY(htstate, MaxTL);
UNSERIALIZE_SCALAR(htba);
UNSERIALIZE_SCALAR(hstick_cmpr);
+ int temp;
+ UNSERIALIZE_SCALAR(temp);
+ implicitInstAsi = (ASI)temp;
+ UNSERIALIZE_SCALAR(temp);
+ implicitDataAsi = (ASI)temp;
}
+#if FULL_SYSTEM
+void
+MiscRegFile::processTickCompare(ThreadContext *tc)
+{
+ panic("tick compare not implemented\n");
+}
+
+void
+MiscRegFile::processSTickCompare(ThreadContext *tc)
+{
+ panic("tick compare not implemented\n");
+}
+
+void
+MiscRegFile::processHSTickCompare(ThreadContext *tc)
+{
+ panic("tick compare not implemented\n");
+}
+#endif
diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh
index 771cb1ed6..f74943256 100644
--- a/src/arch/sparc/miscregfile.hh
+++ b/src/arch/sparc/miscregfile.hh
@@ -32,9 +32,11 @@
#ifndef __ARCH_SPARC_MISCREGFILE_HH__
#define __ARCH_SPARC_MISCREGFILE_HH__
+#include "arch/sparc/asi.hh"
#include "arch/sparc/faults.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/types.hh"
+#include "cpu/cpuevent.hh"
#include <string>
@@ -44,59 +46,53 @@ namespace SparcISA
//These functions map register indices to names
std::string getMiscRegName(RegIndex);
- const int AsrStart = 0;
- const int PrStart = 32;
- const int HprStart = 64;
- const int MiscStart = 96;
-
enum MiscRegIndex
{
/** Ancillary State Registers */
- MISCREG_Y = AsrStart + 0,
- MISCREG_CCR = AsrStart + 2,
- MISCREG_ASI = AsrStart + 3,
- MISCREG_TICK = AsrStart + 4,
- MISCREG_FPRS = AsrStart + 6,
- MISCREG_PCR = AsrStart + 16,
- MISCREG_PIC = AsrStart + 17,
- MISCREG_GSR = AsrStart + 19,
- MISCREG_SOFTINT_SET = AsrStart + 20,
- MISCREG_SOFTINT_CLR = AsrStart + 21,
- MISCREG_SOFTINT = AsrStart + 22,
- MISCREG_TICK_CMPR = AsrStart + 23,
- MISCREG_STICK = AsrStart + 24,
- MISCREG_STICK_CMPR = AsrStart + 25,
+ MISCREG_Y,
+ MISCREG_CCR,
+ MISCREG_ASI,
+ MISCREG_TICK,
+ MISCREG_FPRS,
+ MISCREG_PCR,
+ MISCREG_PIC,
+ MISCREG_GSR,
+ MISCREG_SOFTINT_SET,
+ MISCREG_SOFTINT_CLR,
+ MISCREG_SOFTINT,
+ MISCREG_TICK_CMPR,
+ MISCREG_STICK,
+ MISCREG_STICK_CMPR,
/** Privilged Registers */
- MISCREG_TPC = PrStart + 0,
- MISCREG_TNPC = PrStart + 1,
- MISCREG_TSTATE = PrStart + 2,
- MISCREG_TT = PrStart + 3,
- MISCREG_PRIVTICK = PrStart + 4,
- MISCREG_TBA = PrStart + 5,
- MISCREG_PSTATE = PrStart + 6,
- MISCREG_TL = PrStart + 7,
- MISCREG_PIL = PrStart + 8,
- MISCREG_CWP = PrStart + 9,
- MISCREG_CANSAVE = PrStart + 10,
- MISCREG_CANRESTORE = PrStart + 11,
- MISCREG_CLEANWIN = PrStart + 12,
- MISCREG_OTHERWIN = PrStart + 13,
- MISCREG_WSTATE = PrStart + 14,
- MISCREG_GL = PrStart + 16,
+ MISCREG_TPC,
+ MISCREG_TNPC,
+ MISCREG_TSTATE,
+ MISCREG_TT,
+ MISCREG_PRIVTICK,
+ MISCREG_TBA,
+ MISCREG_PSTATE,
+ MISCREG_TL,
+ MISCREG_PIL,
+ MISCREG_CWP,
+ MISCREG_CANSAVE,
+ MISCREG_CANRESTORE,
+ MISCREG_CLEANWIN,
+ MISCREG_OTHERWIN,
+ MISCREG_WSTATE,
+ MISCREG_GL,
/** Hyper privileged registers */
- MISCREG_HPSTATE = HprStart + 0,
- MISCREG_HTSTATE = HprStart + 1,
- MISCREG_HINTP = HprStart + 3,
- MISCREG_HTBA = HprStart + 5,
- MISCREG_HVER = HprStart + 6,
- MISCREG_STRAND_STS_REG = HprStart + 16,
- MISCREG_HSTICK_CMPR = HprStart + 31,
+ MISCREG_HPSTATE,
+ MISCREG_HTSTATE,
+ MISCREG_HINTP,
+ MISCREG_HTBA,
+ MISCREG_HVER,
+ MISCREG_STRAND_STS_REG,
+ MISCREG_HSTICK_CMPR,
/** Floating Point Status Register */
- MISCREG_FSR = MiscStart + 0
-
+ MISCREG_FSR
};
// The control registers, broken out into fields
@@ -105,93 +101,16 @@ namespace SparcISA
private:
/* ASR Registers */
- union {
- uint64_t y; // Y (used in obsolete multiplication)
- struct {
- uint64_t value:32; // The actual value stored in y
- uint64_t :32; // reserved bits
- } yFields;
- };
- union {
- uint8_t ccr; // Condition Code Register
- struct {
- union {
- uint8_t icc:4; // 32-bit condition codes
- struct {
- uint8_t c:1; // Carry
- uint8_t v:1; // Overflow
- uint8_t z:1; // Zero
- uint8_t n:1; // Negative
- } iccFields;
- };
- union {
- uint8_t xcc:4; // 64-bit condition codes
- struct {
- uint8_t c:1; // Carry
- uint8_t v:1; // Overflow
- uint8_t z:1; // Zero
- uint8_t n:1; // Negative
- } xccFields;
- };
- } ccrFields;
- };
+ uint64_t y; // Y (used in obsolete multiplication)
+ uint8_t ccr; // Condition Code Register
uint8_t asi; // Address Space Identifier
- union {
- uint64_t tick; // Hardware clock-tick counter
- struct {
- int64_t counter:63; // Clock-tick count
- uint64_t npt:1; // Non-priveleged trap
- } tickFields;
- };
- union {
- uint8_t fprs; // Floating-Point Register State
- struct {
- uint8_t dl:1; // Dirty lower
- uint8_t du:1; // Dirty upper
- uint8_t fef:1; // FPRS enable floating-Point
- } fprsFields;
- };
- union {
- uint64_t gsr; //General Status Register
- struct {
- uint64_t mask:32;
- uint64_t :4;
- uint64_t im:1;
- uint64_t irnd:2;
- uint64_t :17;
- uint64_t scale:5;
- uint64_t align:3;
- } gsrFields;
- };
- union {
- uint64_t softint;
- struct {
- uint64_t tm:1;
- uint64_t int_level:14;
- uint64_t sm:1;
- } softintFields;
- };
- union {
- uint64_t tick_cmpr; // Hardware tick compare registers
- struct {
- uint64_t tick_cmpr:63; // Clock-tick count
- uint64_t int_dis:1; // Non-priveleged trap
- } tick_cmprFields;
- };
- union {
- uint64_t stick; // Hardware clock-tick counter
- struct {
- int64_t :63; // Not used, storage in SparcSystem
- uint64_t npt:1; // Non-priveleged trap
- } stickFields;
- };
- union {
- uint64_t stick_cmpr; // Hardware tick compare registers
- struct {
- uint64_t tick_cmpr:63; // Clock-tick count
- uint64_t int_dis:1; // Non-priveleged trap
- } stick_cmprFields;
- };
+ uint64_t tick; // Hardware clock-tick counter
+ uint8_t fprs; // Floating-Point Register State
+ uint64_t gsr; // General Status Register
+ uint64_t softint;
+ uint64_t tick_cmpr; // Hardware tick compare registers
+ uint64_t stick; // Hardware clock-tick counter
+ uint64_t stick_cmpr; // Hardware tick compare registers
/* Privileged Registers */
@@ -199,37 +118,12 @@ namespace SparcISA
// previous trap level)
uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
// previous trap level)
- union {
- uint64_t tstate[MaxTL]; // Trap State
- struct {
- //Values are from previous trap level
- uint64_t cwp:5; // Current Window Pointer
- uint64_t :3; // Reserved bits
- uint64_t pstate:13; // Process State
- uint64_t :3; // Reserved bits
- uint64_t asi:8; // Address Space Identifier
- uint64_t ccr:8; // Condition Code Register
- uint64_t gl:8; // Global level
- } tstateFields[MaxTL];
- };
+ uint64_t tstate[MaxTL]; // Trap State
uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
// on the previous level)
uint64_t tba; // Trap Base Address
- union {
- uint16_t pstate; // Process State Register
- struct {
- uint16_t :1; // reserved
- uint16_t ie:1; // Interrupt enable
- uint16_t priv:1; // Privelege mode
- uint16_t am:1; // Address mask
- uint16_t pef:1; // PSTATE enable floating-point
- uint16_t :1; // reserved2
- uint16_t mm:2; // Memory Model
- uint16_t tle:1; // Trap little-endian
- uint16_t cle:1; // Current little-endian
- } pstateFields;
- };
+ uint16_t pstate; // Process State Register
uint8_t tl; // Trap Level
uint8_t pil; // Process Interrupt Register
uint8_t cwp; // Current Window Pointer
@@ -237,97 +131,23 @@ namespace SparcISA
uint8_t canrestore; // Restorable windows
uint8_t cleanwin; // Clean windows
uint8_t otherwin; // Other windows
- union {
- uint8_t wstate; // Window State
- struct {
- uint8_t normal:3; // Bits TT<4:2> are set to on a normal
- // register window trap
- uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin"
- // register window trap
- } wstateFields;
- };
+ uint8_t wstate; // Window State
uint8_t gl; // Global level register
-
/** Hyperprivileged Registers */
- union {
- uint64_t hpstate; // Hyperprivileged State Register
- struct {
- uint8_t tlz: 1;
- uint8_t :1;
- uint8_t hpriv:1;
- uint8_t :2;
- uint8_t red:1;
- uint8_t :4;
- uint8_t ibe:1;
- uint8_t id:1;
- } hpstateFields;
- };
-
- uint64_t htstate[MaxTL]; // Hyperprivileged Trap State Register
+ uint64_t hpstate; // Hyperprivileged State Register
+ uint64_t htstate[MaxTL];// Hyperprivileged Trap State Register
uint64_t hintp;
- uint64_t htba; // Hyperprivileged Trap Base Address register
- union {
- uint64_t hstick_cmpr; // Hardware tick compare registers
- struct {
- uint64_t tick_cmpr:63; // Clock-tick count
- uint64_t int_dis:1; // Non-priveleged trap
- } hstick_cmprFields;
- };
-
- uint64_t strandStatusReg; // Per strand status register
+ uint64_t htba; // Hyperprivileged Trap Base Address register
+ uint64_t hstick_cmpr; // Hardware tick compare registers
+ uint64_t strandStatusReg;// Per strand status register
/** Floating point misc registers. */
- union {
- uint64_t fsr; // Floating-Point State Register
- struct {
- union {
- uint64_t cexc:5; // Current excpetion
- struct {
- uint64_t nxc:1; // Inexact
- uint64_t dzc:1; // Divide by zero
- uint64_t ufc:1; // Underflow
- uint64_t ofc:1; // Overflow
- uint64_t nvc:1; // Invalid operand
- } cexcFields;
- };
- union {
- uint64_t aexc:5; // Accrued exception
- struct {
- uint64_t nxc:1; // Inexact
- uint64_t dzc:1; // Divide by zero
- uint64_t ufc:1; // Underflow
- uint64_t ofc:1; // Overflow
- uint64_t nvc:1; // Invalid operand
- } aexcFields;
- };
- uint64_t fcc0:2; // Floating-Point condtion codes
- uint64_t :1; // Reserved bits
- uint64_t qne:1; // Deferred trap queue not empty
- // with no queue, it should read 0
- uint64_t ftt:3; // Floating-Point trap type
- uint64_t ver:3; // Version (of the FPU)
- uint64_t :2; // Reserved bits
- uint64_t ns:1; // Nonstandard floating point
- union {
- uint64_t tem:5; // Trap Enable Mask
- struct {
- uint64_t nxm:1; // Inexact
- uint64_t dzm:1; // Divide by zero
- uint64_t ufm:1; // Underflow
- uint64_t ofm:1; // Overflow
- uint64_t nvm:1; // Invalid operand
- } temFields;
- };
- uint64_t :2; // Reserved bits
- uint64_t rd:2; // Rounding direction
- uint64_t fcc1:2; // Floating-Point condition codes
- uint64_t fcc2:2; // Floating-Point condition codes
- uint64_t fcc3:2; // Floating-Point condition codes
- uint64_t :26; // Reserved bits
- } fsrFields;
- };
+ uint64_t fsr; // Floating-Point State Register
+
+ ASI implicitInstAsi;
+ ASI implicitDataAsi;
// These need to check the int_dis field and if 0 then
// set appropriate bit in softint and checkinterrutps on the cpu
@@ -349,12 +169,6 @@ namespace SparcISA
typedef CpuEventWrapper<MiscRegFile,
&MiscRegFile::processHSTickCompare> HSTickCompareEvent;
HSTickCompareEvent *hSTickCompare;
-
- /** Fullsystem only register version of ReadRegWithEffect() */
- MiscReg readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
- /** Fullsystem only register version of SetRegWithEffect() */
- Fault setFSRegWithEffect(int miscReg, const MiscReg &val,
- ThreadContext * tc);
#endif
public:
@@ -374,6 +188,16 @@ namespace SparcISA
void setRegWithEffect(int miscReg,
const MiscReg &val, ThreadContext * tc);
+ ASI getInstAsid()
+ {
+ return implicitInstAsi;
+ }
+
+ ASI getDataAsid()
+ {
+ return implicitDataAsi;
+ }
+
void serialize(std::ostream & os);
void unserialize(Checkpoint * cp, const std::string & section);
@@ -382,9 +206,10 @@ namespace SparcISA
protected:
- bool isHyperPriv() { return hpstateFields.hpriv; }
- bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; }
+ bool isHyperPriv() { return (hpstate & (1 << 2)); }
+ bool isPriv() { return (hpstate & (1 << 2)) || (pstate & (1 << 2)); }
bool isNonPriv() { return !isPriv(); }
+ inline void setImplicitAsis();
};
}
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index a3b7dde7c..11a799ccb 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -29,6 +29,7 @@
* Ali Saidi
*/
+#include "arch/sparc/asi.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/process.hh"
#include "base/loader/object_file.hh"
@@ -105,6 +106,8 @@ SparcLiveProcess::startup()
threadContexts[0]->setMiscReg(MISCREG_WSTATE, 0);
//Set the trap level to 0
threadContexts[0]->setMiscReg(MISCREG_TL, 0);
+ //Set the ASI register to something fixed
+ threadContexts[0]->setMiscReg(MISCREG_ASI, ASI_PRIMARY);
}
m5_auxv_t buildAuxVect(int64_t type, int64_t val)
diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc
index 5eb874d39..65e6017da 100644
--- a/src/arch/sparc/regfile.cc
+++ b/src/arch/sparc/regfile.cc
@@ -79,24 +79,20 @@ MiscReg RegFile::readMiscReg(int miscReg)
return miscRegFile.readReg(miscReg);
}
-MiscReg RegFile::readMiscRegWithEffect(int miscReg,
- Fault &fault, ThreadContext *tc)
+MiscReg RegFile::readMiscRegWithEffect(int miscReg, ThreadContext *tc)
{
- fault = NoFault;
return miscRegFile.readRegWithEffect(miscReg, tc);
}
-Fault RegFile::setMiscReg(int miscReg, const MiscReg &val)
+void RegFile::setMiscReg(int miscReg, const MiscReg &val)
{
miscRegFile.setReg(miscReg, val);
- return NoFault;
}
-Fault RegFile::setMiscRegWithEffect(int miscReg, const MiscReg &val,
+void RegFile::setMiscRegWithEffect(int miscReg, const MiscReg &val,
ThreadContext * tc)
{
miscRegFile.setRegWithEffect(miscReg, val, tc);
- return NoFault;
}
FloatReg RegFile::readFloatReg(int floatReg, int width)
@@ -122,27 +118,26 @@ FloatRegBits RegFile::readFloatRegBits(int floatReg)
FloatRegFile::SingleWidth);
}
-Fault RegFile::setFloatReg(int floatReg, const FloatReg &val, int width)
+void RegFile::setFloatReg(int floatReg, const FloatReg &val, int width)
{
- return floatRegFile.setReg(floatReg, val, width);
+ floatRegFile.setReg(floatReg, val, width);
}
-Fault RegFile::setFloatReg(int floatReg, const FloatReg &val)
+void RegFile::setFloatReg(int floatReg, const FloatReg &val)
{
//Use the "natural" width of a single float
- return setFloatReg(floatReg, val, FloatRegFile::SingleWidth);
+ setFloatReg(floatReg, val, FloatRegFile::SingleWidth);
}
-Fault RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
+void RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
{
- return floatRegFile.setRegBits(floatReg, val, width);
+ floatRegFile.setRegBits(floatReg, val, width);
}
-Fault RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val)
+void RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val)
{
//Use the "natural" width of a single float
- return floatRegFile.setRegBits(floatReg, val,
- FloatRegFile::SingleWidth);
+ floatRegFile.setRegBits(floatReg, val, FloatRegFile::SingleWidth);
}
IntReg RegFile::readIntReg(int intReg)
@@ -150,9 +145,9 @@ IntReg RegFile::readIntReg(int intReg)
return intRegFile.readReg(intReg);
}
-Fault RegFile::setIntReg(int intReg, const IntReg &val)
+void RegFile::setIntReg(int intReg, const IntReg &val)
{
- return intRegFile.setReg(intReg, val);
+ intRegFile.setReg(intReg, val);
}
void RegFile::serialize(std::ostream &os)
diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh
index 500fbbba4..9f33435f6 100644
--- a/src/arch/sparc/regfile.hh
+++ b/src/arch/sparc/regfile.hh
@@ -32,7 +32,6 @@
#ifndef __ARCH_SPARC_REGFILE_HH__
#define __ARCH_SPARC_REGFILE_HH__
-#include "arch/sparc/faults.hh"
#include "arch/sparc/floatregfile.hh"
#include "arch/sparc/intregfile.hh"
#include "arch/sparc/isa_traits.hh"
@@ -76,14 +75,23 @@ namespace SparcISA
MiscReg readMiscReg(int miscReg);
- MiscReg readMiscRegWithEffect(int miscReg,
- Fault &fault, ThreadContext *tc);
+ MiscReg readMiscRegWithEffect(int miscReg, ThreadContext *tc);
- Fault setMiscReg(int miscReg, const MiscReg &val);
+ void setMiscReg(int miscReg, const MiscReg &val);
- Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
+ void setMiscRegWithEffect(int miscReg, const MiscReg &val,
ThreadContext * tc);
+ ASI instAsid()
+ {
+ return miscRegFile.getInstAsid();
+ }
+
+ ASI dataAsid()
+ {
+ return miscRegFile.getDataAsid();
+ }
+
FloatReg readFloatReg(int floatReg, int width);
FloatReg readFloatReg(int floatReg);
@@ -92,17 +100,17 @@ namespace SparcISA
FloatRegBits readFloatRegBits(int floatReg);
- Fault setFloatReg(int floatReg, const FloatReg &val, int width);
+ void setFloatReg(int floatReg, const FloatReg &val, int width);
- Fault setFloatReg(int floatReg, const FloatReg &val);
+ void setFloatReg(int floatReg, const FloatReg &val);
- Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width);
+ void setFloatRegBits(int floatReg, const FloatRegBits &val, int width);
- Fault setFloatRegBits(int floatReg, const FloatRegBits &val);
+ void setFloatRegBits(int floatReg, const FloatRegBits &val);
IntReg readIntReg(int intReg);
- Fault setIntReg(int intReg, const IntReg &val);
+ void setIntReg(int intReg, const IntReg &val);
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc
new file mode 100644
index 000000000..c76f8b820
--- /dev/null
+++ b/src/arch/sparc/remote_gdb.cc
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ */
+
+/*
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratories.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
+ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * $NetBSD: kgdb_stub.c,v 1.8 2001/07/07 22:58:00 wdk Exp $
+ *
+ * Taken from NetBSD
+ *
+ * "Stub" to allow remote cpu to debug over a serial line using gdb.
+ */
+
+#include <sys/signal.h>
+
+#include <string>
+#include <unistd.h>
+
+#include "arch/vtophys.hh"
+#include "arch/sparc/remote_gdb.hh"
+#include "base/intmath.hh"
+#include "base/remote_gdb.hh"
+#include "base/socket.hh"
+#include "base/trace.hh"
+#include "config/full_system.hh"
+#include "cpu/thread_context.hh"
+#include "cpu/static_inst.hh"
+#include "mem/physical.hh"
+#include "mem/port.hh"
+#include "sim/system.hh"
+
+using namespace std;
+using namespace TheISA;
+
+RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
+ : BaseRemoteGDB(_system, c, NumGDBRegs)
+{}
+
+///////////////////////////////////////////////////////////
+// RemoteGDB::acc
+//
+// Determine if the mapping at va..(va+len) is valid.
+//
+bool
+RemoteGDB::acc(Addr va, size_t len)
+{
+ //@Todo In NetBSD, this function checks if all addresses
+ //from va to va + len have valid page mape entries. Not
+ //sure how this will work for other OSes or in general.
+ return true;
+}
+
+///////////////////////////////////////////////////////////
+// RemoteGDB::getregs
+//
+// Translate the kernel debugger register format into
+// the GDB register format.
+void
+RemoteGDB::getregs()
+{
+ memset(gdbregs.regs, 0, gdbregs.size);
+
+ gdbregs.regs[RegPc] = context->readPC();
+ gdbregs.regs[RegNpc] = context->readNextPC();
+ for(int x = RegG0; x <= RegI0 + 7; x++)
+ gdbregs.regs[x] = context->readIntReg(x - RegG0);
+ //Floating point registers are left at 0 in netbsd
+ //All registers other than the pc, npc and int regs
+ //are ignored as well.
+}
+
+///////////////////////////////////////////////////////////
+// RemoteGDB::setregs
+//
+// Translate the GDB register format into the kernel
+// debugger register format.
+//
+void
+RemoteGDB::setregs()
+{
+ context->setPC(gdbregs.regs[RegPc]);
+ context->setNextPC(gdbregs.regs[RegNpc]);
+ for(int x = RegG0; x <= RegI0 + 7; x++)
+ context->setIntReg(x - RegG0, gdbregs.regs[x]);
+ //Only the integer registers, pc and npc are set in netbsd
+}
+
+void
+RemoteGDB::clearSingleStep()
+{
+ panic("SPARC does not support hardware single stepping\n");
+}
+
+void
+RemoteGDB::setSingleStep()
+{
+ panic("SPARC does not support hardware single stepping\n");
+}
diff --git a/src/arch/sparc/remote_gdb.hh b/src/arch/sparc/remote_gdb.hh
new file mode 100644
index 000000000..e4b66b783
--- /dev/null
+++ b/src/arch/sparc/remote_gdb.hh
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ */
+
+#ifndef __ARCH_ALPHA_REMOTE_GDB_HH__
+#define __ARCH_ALPHA_REMOTE_GDB_HH__
+
+#include <map>
+
+#include "arch/types.hh"
+#include "base/remote_gdb.hh"
+#include "cpu/pc_event.hh"
+#include "base/pollevent.hh"
+
+class System;
+class ThreadContext;
+class PhysicalMemory;
+
+namespace SparcISA
+{
+ class RemoteGDB : public BaseRemoteGDB
+ {
+ protected:
+ enum RegisterConstants
+ {
+ RegG0 = 0, RegO0 = 8, RegL0 = 16, RegI0 = 24,
+ RegF0 = 32, RegF32 = 64,
+ RegPc = 80, RegNpc, RegCcr, RegFsr, RegFprs, RegY, RegAsi,
+ RegVer, RegTick, RegPil, RegPstate,
+ RegTstate, RegTba, RegTl, RegTt, RegTpc, RegTnpc, RegWstate,
+ RegCwp, RegCansave, RegCanrestore, RegCleanwin, RegOtherwin,
+ RegAsr16 = 103,
+ RegIcc = 119, RegXcc,
+ RegFcc0 = 121,
+ NumGDBRegs
+ };
+
+ public:
+ RemoteGDB(System *system, ThreadContext *context);
+
+ bool acc(Addr addr, size_t len);
+
+ protected:
+ void getregs();
+ void setregs();
+
+ void clearSingleStep();
+ void setSingleStep();
+ };
+}
+
+#endif /* __ARCH_ALPHA_REMOTE_GDB_H__ */
diff --git a/src/arch/sparc/stacktrace.cc b/src/arch/sparc/stacktrace.cc
new file mode 100644
index 000000000..2eb697bf2
--- /dev/null
+++ b/src/arch/sparc/stacktrace.cc
@@ -0,0 +1,372 @@
+/*
+ * Copyright (c) 2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ */
+
+#include <string>
+
+#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/stacktrace.hh"
+#include "arch/sparc/vtophys.hh"
+#include "base/bitfield.hh"
+#include "base/trace.hh"
+#include "cpu/base.hh"
+#include "cpu/thread_context.hh"
+#include "sim/system.hh"
+
+using namespace std;
+namespace SparcISA
+{
+ ProcessInfo::ProcessInfo(ThreadContext *_tc)
+ : tc(_tc)
+ {
+ Addr addr = 0;
+
+ VirtualPort *vp;
+
+ vp = tc->getVirtPort();
+
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
+ panic("thread info not compiled into kernel\n");
+ thread_info_size = vp->readGtoH<int32_t>(addr);
+
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
+ panic("thread info not compiled into kernel\n");
+ task_struct_size = vp->readGtoH<int32_t>(addr);
+
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
+ panic("thread info not compiled into kernel\n");
+ task_off = vp->readGtoH<int32_t>(addr);
+
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
+ panic("thread info not compiled into kernel\n");
+ pid_off = vp->readGtoH<int32_t>(addr);
+
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
+ panic("thread info not compiled into kernel\n");
+ name_off = vp->readGtoH<int32_t>(addr);
+
+ tc->delVirtPort(vp);
+ }
+
+ Addr
+ ProcessInfo::task(Addr ksp) const
+ {
+ Addr base = ksp & ~0x3fff;
+ if (base == ULL(0xfffffc0000000000))
+ return 0;
+
+ Addr tsk;
+
+ VirtualPort *vp;
+
+ vp = tc->getVirtPort();
+ tsk = vp->readGtoH<Addr>(base + task_off);
+ tc->delVirtPort(vp);
+
+ return tsk;
+ }
+
+ int
+ ProcessInfo::pid(Addr ksp) const
+ {
+ Addr task = this->task(ksp);
+ if (!task)
+ return -1;
+
+ uint16_t pd;
+
+ VirtualPort *vp;
+
+ vp = tc->getVirtPort();
+ pd = vp->readGtoH<uint16_t>(task + pid_off);
+ tc->delVirtPort(vp);
+
+ return pd;
+ }
+
+ string
+ ProcessInfo::name(Addr ksp) const
+ {
+ Addr task = this->task(ksp);
+ if (!task)
+ return "console";
+
+ char comm[256];
+ CopyStringOut(tc, comm, task + name_off, sizeof(comm));
+ if (!comm[0])
+ return "startup";
+
+ return comm;
+ }
+
+ StackTrace::StackTrace()
+ : tc(0), stack(64)
+ {
+ }
+
+ StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst)
+ : tc(0), stack(64)
+ {
+ trace(_tc, inst);
+ }
+
+ StackTrace::~StackTrace()
+ {
+ }
+
+ void
+ StackTrace::trace(ThreadContext *_tc, bool is_call)
+ {
+#if 0
+ tc = _tc;
+
+ bool usermode = (tc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
+
+ Addr pc = tc->readNextPC();
+ bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
+ pc <= tc->getSystemPtr()->kernelEnd;
+
+ if (usermode) {
+ stack.push_back(user);
+ return;
+ }
+
+ if (!kernel) {
+ stack.push_back(console);
+ return;
+ }
+
+ SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
+ Addr ksp = tc->readIntReg(TheISA::StackPointerReg);
+ Addr bottom = ksp & ~0x3fff;
+ Addr addr;
+
+ if (is_call) {
+ if (!symtab->findNearestAddr(pc, addr))
+ panic("could not find address %#x", pc);
+
+ stack.push_back(addr);
+ pc = tc->readPC();
+ }
+
+ Addr ra;
+ int size;
+
+ while (ksp > bottom) {
+ if (!symtab->findNearestAddr(pc, addr))
+ panic("could not find symbol for pc=%#x", pc);
+ assert(pc >= addr && "symbol botch: callpc < func");
+
+ stack.push_back(addr);
+
+ if (isEntry(addr))
+ return;
+
+ if (decodePrologue(ksp, pc, addr, size, ra)) {
+ if (!ra)
+ return;
+
+ if (size <= 0) {
+ stack.push_back(unknown);
+ return;
+ }
+
+ pc = ra;
+ ksp += size;
+ } else {
+ stack.push_back(unknown);
+ return;
+ }
+
+ bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
+ pc <= tc->getSystemPtr()->kernelEnd;
+ if (!kernel)
+ return;
+
+ if (stack.size() >= 1000)
+ panic("unwinding too far");
+ }
+
+ panic("unwinding too far");
+#endif
+ }
+
+ bool
+ StackTrace::isEntry(Addr addr)
+ {
+#if 0
+ if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp12))
+ return true;
+
+ if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp7))
+ return true;
+
+ if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp11))
+ return true;
+
+ if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp21))
+ return true;
+
+ if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp9))
+ return true;
+
+ if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp2))
+ return true;
+#endif
+ return false;
+ }
+
+ bool
+ StackTrace::decodeStack(MachInst inst, int &disp)
+ {
+ // lda $sp, -disp($sp)
+ //
+ // Opcode<31:26> == 0x08
+ // RA<25:21> == 30
+ // RB<20:16> == 30
+ // Disp<15:0>
+ const MachInst mem_mask = 0xffff0000;
+ const MachInst lda_pattern = 0x23de0000;
+ const MachInst lda_disp_mask = 0x0000ffff;
+
+ // subq $sp, disp, $sp
+ // addq $sp, disp, $sp
+ //
+ // Opcode<31:26> == 0x10
+ // RA<25:21> == 30
+ // Lit<20:13>
+ // One<12> = 1
+ // Func<11:5> == 0x20 (addq)
+ // Func<11:5> == 0x29 (subq)
+ // RC<4:0> == 30
+ const MachInst intop_mask = 0xffe01fff;
+ const MachInst addq_pattern = 0x43c0141e;
+ const MachInst subq_pattern = 0x43c0153e;
+ const MachInst intop_disp_mask = 0x001fe000;
+ const int intop_disp_shift = 13;
+
+ if ((inst & mem_mask) == lda_pattern)
+ disp = -sext<16>(inst & lda_disp_mask);
+ else if ((inst & intop_mask) == addq_pattern)
+ disp = -int((inst & intop_disp_mask) >> intop_disp_shift);
+ else if ((inst & intop_mask) == subq_pattern)
+ disp = int((inst & intop_disp_mask) >> intop_disp_shift);
+ else
+ return false;
+
+ return true;
+ }
+
+ bool
+ StackTrace::decodeSave(MachInst inst, int &reg, int &disp)
+ {
+ // lda $stq, disp($sp)
+ //
+ // Opcode<31:26> == 0x08
+ // RA<25:21> == ?
+ // RB<20:16> == 30
+ // Disp<15:0>
+ const MachInst stq_mask = 0xfc1f0000;
+ const MachInst stq_pattern = 0xb41e0000;
+ const MachInst stq_disp_mask = 0x0000ffff;
+ const MachInst reg_mask = 0x03e00000;
+ const int reg_shift = 21;
+
+ if ((inst & stq_mask) == stq_pattern) {
+ reg = (inst & reg_mask) >> reg_shift;
+ disp = sext<16>(inst & stq_disp_mask);
+ } else {
+ return false;
+ }
+
+ return true;
+ }
+
+ /*
+ * Decode the function prologue for the function we're in, and note
+ * which registers are stored where, and how large the stack frame is.
+ */
+ bool
+ StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
+ int &size, Addr &ra)
+ {
+ size = 0;
+ ra = 0;
+
+ for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
+ MachInst inst;
+ CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst));
+
+ int reg, disp;
+ if (decodeStack(inst, disp)) {
+ if (size) {
+ // panic("decoding frame size again");
+ return true;
+ }
+ size += disp;
+ } else if (decodeSave(inst, reg, disp)) {
+ if (!ra && reg == ReturnAddressReg) {
+ CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr));
+ if (!ra) {
+ // panic("no return address value pc=%#x\n", pc);
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+#if TRACING_ON
+ void
+ StackTrace::dump()
+ {
+ StringWrap name(tc->getCpuPtr()->name());
+ SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
+
+ DPRINTFN("------ Stack ------\n");
+
+ string symbol;
+ for (int i = 0, size = stack.size(); i < size; ++i) {
+ Addr addr = stack[size - i - 1];
+ if (addr == user)
+ symbol = "user";
+ else if (addr == console)
+ symbol = "console";
+ else if (addr == unknown)
+ symbol = "unknown";
+ else
+ symtab->findSymbol(addr, symbol);
+
+ DPRINTFN("%#x: %s\n", addr, symbol);
+ }
+ }
+#endif
+}
diff --git a/src/arch/sparc/stacktrace.hh b/src/arch/sparc/stacktrace.hh
index 54d3d17be..4bc5d779b 100644
--- a/src/arch/sparc/stacktrace.hh
+++ b/src/arch/sparc/stacktrace.hh
@@ -35,87 +35,90 @@
#include "cpu/static_inst.hh"
class ThreadContext;
-class StackTrace;
-
-class ProcessInfo
+namespace SparcISA
{
- private:
- ThreadContext *tc;
+ class StackTrace;
- int thread_info_size;
- int task_struct_size;
- int task_off;
- int pid_off;
- int name_off;
+ class ProcessInfo
+ {
+ private:
+ ThreadContext *tc;
- public:
- ProcessInfo(ThreadContext *_tc);
+ int thread_info_size;
+ int task_struct_size;
+ int task_off;
+ int pid_off;
+ int name_off;
- Addr task(Addr ksp) const;
- int pid(Addr ksp) const;
- std::string name(Addr ksp) const;
-};
+ public:
+ ProcessInfo(ThreadContext *_tc);
-class StackTrace
-{
- protected:
- typedef TheISA::MachInst MachInst;
- private:
- ThreadContext *tc;
- std::vector<Addr> stack;
-
- private:
- bool isEntry(Addr addr);
- bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
- bool decodeSave(MachInst inst, int &reg, int &disp);
- bool decodeStack(MachInst inst, int &disp);
-
- void trace(ThreadContext *tc, bool is_call);
-
- public:
- StackTrace();
- StackTrace(ThreadContext *tc, StaticInstPtr inst);
- ~StackTrace();
-
- void clear()
+ Addr task(Addr ksp) const;
+ int pid(Addr ksp) const;
+ std::string name(Addr ksp) const;
+ };
+
+ class StackTrace
{
- tc = 0;
- stack.clear();
- }
+ protected:
+ typedef TheISA::MachInst MachInst;
+ private:
+ ThreadContext *tc;
+ std::vector<Addr> stack;
+
+ private:
+ bool isEntry(Addr addr);
+ bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
+ bool decodeSave(MachInst inst, int &reg, int &disp);
+ bool decodeStack(MachInst inst, int &disp);
- bool valid() const { return tc != NULL; }
- bool trace(ThreadContext *tc, StaticInstPtr inst);
+ void trace(ThreadContext *tc, bool is_call);
- public:
- const std::vector<Addr> &getstack() const { return stack; }
+ public:
+ StackTrace();
+ StackTrace(ThreadContext *tc, StaticInstPtr inst);
+ ~StackTrace();
- static const int user = 1;
- static const int console = 2;
- static const int unknown = 3;
+ void clear()
+ {
+ tc = 0;
+ stack.clear();
+ }
+
+ bool valid() const { return tc != NULL; }
+ bool trace(ThreadContext *tc, StaticInstPtr inst);
+
+ public:
+ const std::vector<Addr> &getstack() const { return stack; }
+
+ static const int user = 1;
+ static const int console = 2;
+ static const int unknown = 3;
#if TRACING_ON
- private:
- void dump();
+ private:
+ void dump();
- public:
- void dprintf() { if (DTRACE(Stack)) dump(); }
+ public:
+ void dprintf() { if (DTRACE(Stack)) dump(); }
#else
- public:
- void dprintf() {}
+ public:
+ void dprintf() {}
#endif
-};
+ };
-inline bool
-StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
-{
- if (!inst->isCall() && !inst->isReturn())
- return false;
+ inline bool
+ StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
+ {
+ if (!inst->isCall() && !inst->isReturn())
+ return false;
- if (valid())
- clear();
+ if (valid())
+ clear();
- trace(tc, !inst->isReturn());
- return true;
+ trace(tc, !inst->isReturn());
+ return true;
+ }
}
#endif // __ARCH_SPARC_STACKTRACE_HH__
diff --git a/src/arch/sparc/system.cc b/src/arch/sparc/system.cc
index ef6443d17..4e907f002 100644
--- a/src/arch/sparc/system.cc
+++ b/src/arch/sparc/system.cc
@@ -42,42 +42,49 @@
using namespace BigEndianGuest;
SparcSystem::SparcSystem(Params *p)
- : System(p), sysTick(0)
+ : System(p), sysTick(0),funcRomPort(p->name + "-fport")
{
resetSymtab = new SymbolTable;
hypervisorSymtab = new SymbolTable;
openbootSymtab = new SymbolTable;
+ Port *rom_port;
+ rom_port = params()->rom->getPort("functional");
+ funcRomPort.setPeer(rom_port);
+ rom_port->setPeer(&funcRomPort);
/**
* Load the boot code, and hypervisor into memory.
*/
// Read the reset binary
- reset = createObjectFile(params()->reset_bin);
+ reset = createObjectFile(params()->reset_bin, true);
if (reset == NULL)
fatal("Could not load reset binary %s", params()->reset_bin);
// Read the openboot binary
- openboot = createObjectFile(params()->openboot_bin);
+ openboot = createObjectFile(params()->openboot_bin, true);
if (openboot == NULL)
fatal("Could not load openboot bianry %s", params()->openboot_bin);
// Read the hypervisor binary
- hypervisor = createObjectFile(params()->hypervisor_bin);
+ hypervisor = createObjectFile(params()->hypervisor_bin, true);
if (hypervisor == NULL)
fatal("Could not load hypervisor binary %s", params()->hypervisor_bin);
// Load reset binary into memory
- reset->loadSections(&functionalPort, SparcISA::LoadAddrMask);
+ reset->setTextBase(params()->reset_addr);
+ reset->loadSections(&funcRomPort);
// Load the openboot binary
- openboot->loadSections(&functionalPort, SparcISA::LoadAddrMask);
+ openboot->setTextBase(params()->openboot_addr);
+ openboot->loadSections(&funcRomPort);
// Load the hypervisor binary
- hypervisor->loadSections(&functionalPort, SparcISA::LoadAddrMask);
+ hypervisor->setTextBase(params()->hypervisor_addr);
+ hypervisor->loadSections(&funcRomPort);
// load symbols
- if (!reset->loadGlobalSymbols(reset))
+ if (!reset->loadGlobalSymbols(resetSymtab))
panic("could not load reset symbols\n");
if (!openboot->loadGlobalSymbols(openbootSymtab))
@@ -141,13 +148,19 @@ SparcSystem::unserialize(Checkpoint *cp, const std::string &section)
BEGIN_DECLARE_SIM_OBJECT_PARAMS(SparcSystem)
SimObjectParam<PhysicalMemory *> physmem;
+ SimObjectParam<PhysicalMemory *> rom;
SimpleEnumParam<System::MemoryMode> mem_mode;
+ Param<Addr> reset_addr;
+ Param<Addr> hypervisor_addr;
+ Param<Addr> openboot_addr;
+
Param<std::string> kernel;
Param<std::string> reset_bin;
Param<std::string> hypervisor_bin;
Param<std::string> openboot_bin;
+ Param<Tick> boot_cpu_frequency;
Param<std::string> boot_osflags;
Param<std::string> readfile;
Param<unsigned int> init_param;
@@ -156,20 +169,24 @@ END_DECLARE_SIM_OBJECT_PARAMS(SparcSystem)
BEGIN_INIT_SIM_OBJECT_PARAMS(SparcSystem)
- INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
INIT_PARAM(physmem, "phsyical memory"),
+ INIT_PARAM(rom, "ROM for boot code"),
INIT_ENUM_PARAM(mem_mode, "Memory Mode, (1=atomic, 2=timing)",
System::MemoryModeStrings),
+
+ INIT_PARAM(reset_addr, "Address that reset should be loaded at"),
+ INIT_PARAM(hypervisor_addr, "Address that hypervisor should be loaded at"),
+ INIT_PARAM(openboot_addr, "Address that openboot should be loaded at"),
+
INIT_PARAM(kernel, "file that contains the kernel code"),
INIT_PARAM(reset_bin, "file that contains the reset code"),
INIT_PARAM(hypervisor_bin, "file that contains the hypervisor code"),
INIT_PARAM(openboot_bin, "file that contains the openboot code"),
+ INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
"a"),
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
- INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
- INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
- INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10)
+ INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0)
END_INIT_SIM_OBJECT_PARAMS(SparcSystem)
@@ -179,16 +196,18 @@ CREATE_SIM_OBJECT(SparcSystem)
p->name = getInstanceName();
p->boot_cpu_frequency = boot_cpu_frequency;
p->physmem = physmem;
+ p->rom = rom;
p->mem_mode = mem_mode;
p->kernel_path = kernel;
+ p->reset_addr = reset_addr;
+ p->hypervisor_addr = hypervisor_addr;
+ p->openboot_addr = openboot_addr;
p->reset_bin = reset_bin;
p->hypervisor_bin = hypervisor_bin;
p->openboot_bin = openboot_bin;
p->boot_osflags = boot_osflags;
p->init_param = init_param;
p->readfile = readfile;
- p->system_type = system_type;
- p->system_rev = system_rev;
return new SparcSystem(p);
}
diff --git a/src/arch/sparc/system.hh b/src/arch/sparc/system.hh
index 614707f6c..9cf3bb568 100644
--- a/src/arch/sparc/system.hh
+++ b/src/arch/sparc/system.hh
@@ -45,12 +45,14 @@ class SparcSystem : public System
public:
struct Params : public System::Params
{
+ PhysicalMemory *rom;
+ Addr reset_addr;
+ Addr hypervisor_addr;
+ Addr openboot_addr;
std::string reset_bin;
- std::string hypervison_bin;
+ std::string hypervisor_bin;
std::string openboot_bin;
std::string boot_osflags;
- uint64_t system_type;
- uint64_t system_rev;
};
SparcSystem(Params *p);
@@ -87,6 +89,9 @@ class SparcSystem : public System
/** System Tick for syncronized tick across all cpus. */
Tick sysTick;
+ /** functional port to ROM */
+ FunctionalPort funcRomPort;
+
protected:
const Params *params() const { return (const Params *)_params; }
@@ -111,8 +116,11 @@ class SparcSystem : public System
return addFuncEvent<T>(openbootSymtab, lbl);
}
- virtual Addr fixFuncEventAddr(Addr addr);
-
+ virtual Addr fixFuncEventAddr(Addr addr)
+ {
+ //XXX This may eventually have to do something useful.
+ return addr;
+ }
};
#endif
diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc
new file mode 100644
index 000000000..0b1a2ff5f
--- /dev/null
+++ b/src/arch/sparc/tlb.cc
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2001-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ * Steve Reinhardt
+ * Andrew Schultz
+ */
+
+#include "arch/sparc/tlb.hh"
+#include "sim/builder.hh"
+
+namespace SparcISA
+{
+ DEFINE_SIM_OBJECT_CLASS_NAME("SparcTLB", TLB)
+
+ BEGIN_DECLARE_SIM_OBJECT_PARAMS(ITB)
+
+ Param<int> size;
+
+ END_DECLARE_SIM_OBJECT_PARAMS(ITB)
+
+ BEGIN_INIT_SIM_OBJECT_PARAMS(ITB)
+
+ INIT_PARAM_DFLT(size, "TLB size", 48)
+
+ END_INIT_SIM_OBJECT_PARAMS(ITB)
+
+
+ CREATE_SIM_OBJECT(ITB)
+ {
+ return new ITB(getInstanceName(), size);
+ }
+
+ REGISTER_SIM_OBJECT("SparcITB", ITB)
+
+ BEGIN_DECLARE_SIM_OBJECT_PARAMS(DTB)
+
+ Param<int> size;
+
+ END_DECLARE_SIM_OBJECT_PARAMS(DTB)
+
+ BEGIN_INIT_SIM_OBJECT_PARAMS(DTB)
+
+ INIT_PARAM_DFLT(size, "TLB size", 64)
+
+ END_INIT_SIM_OBJECT_PARAMS(DTB)
+
+
+ CREATE_SIM_OBJECT(DTB)
+ {
+ return new DTB(getInstanceName(), size);
+ }
+
+ REGISTER_SIM_OBJECT("SparcDTB", DTB)
+}
diff --git a/src/arch/sparc/tlb.hh b/src/arch/sparc/tlb.hh
index 35ff08b43..0fdba6baf 100644
--- a/src/arch/sparc/tlb.hh
+++ b/src/arch/sparc/tlb.hh
@@ -31,5 +31,47 @@
#ifndef __ARCH_SPARC_TLB_HH__
#define __ARCH_SPARC_TLB_HH__
+#include "mem/request.hh"
+#include "sim/faults.hh"
+#include "sim/sim_object.hh"
+
+class ThreadContext;
+
+namespace SparcISA
+{
+ class TLB : public SimObject
+ {
+ public:
+ TLB(const std::string &name, int size) : SimObject(name)
+ {
+ }
+ };
+
+ class ITB : public TLB
+ {
+ public:
+ ITB(const std::string &name, int size) : TLB(name, size)
+ {
+ }
+
+ Fault translate(RequestPtr &req, ThreadContext *tc) const
+ {
+ return NoFault;
+ }
+ };
+
+ class DTB : public TLB
+ {
+ public:
+ DTB(const std::string &name, int size) : TLB(name, size)
+ {
+ }
+
+ Fault translate(RequestPtr &req, ThreadContext *tc, bool write) const
+ {
+ return NoFault;
+ }
+ };
+}
#endif // __ARCH_SPARC_TLB_HH__
diff --git a/src/arch/sparc/utility.hh b/src/arch/sparc/utility.hh
index 23fddf0e9..e51677cdf 100644
--- a/src/arch/sparc/utility.hh
+++ b/src/arch/sparc/utility.hh
@@ -31,6 +31,7 @@
#ifndef __ARCH_SPARC_UTILITY_HH__
#define __ARCH_SPARC_UTILITY_HH__
+#include "arch/sparc/faults.hh"
#include "arch/sparc/isa_traits.hh"
#include "base/misc.hh"
#include "base/bitfield.hh"
@@ -38,6 +39,14 @@
namespace SparcISA
{
+
+ static inline bool
+ inUserMode(ThreadContext *tc)
+ {
+ return !(tc->readMiscReg(MISCREG_PSTATE & (1 << 2)) ||
+ tc->readMiscReg(MISCREG_HPSTATE & (1 << 2)));
+ }
+
inline ExtMachInst
makeExtMI(MachInst inst, ThreadContext * xc) {
ExtMachInst emi = (unsigned MachInst) inst;
@@ -99,6 +108,12 @@ namespace SparcISA
template <class TC>
void zeroRegisters(TC *tc);
+ inline void initCPU(ThreadContext *tc, int cpuId)
+ {
+ static Fault por = new PowerOnReset();
+ por->invoke(tc);
+ }
+
} // namespace SparcISA
#endif
diff --git a/src/arch/sparc/vtophys.cc b/src/arch/sparc/vtophys.cc
index f7fd92c15..429126b70 100644
--- a/src/arch/sparc/vtophys.cc
+++ b/src/arch/sparc/vtophys.cc
@@ -32,135 +32,47 @@
#include <string>
-#include "arch/alpha/ev5.hh"
-#include "arch/alpha/vtophys.hh"
+#include "arch/sparc/vtophys.hh"
#include "base/chunk_generator.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "mem/vport.hh"
using namespace std;
-using namespace AlphaISA;
-AlphaISA::PageTableEntry
-AlphaISA::kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr)
+namespace SparcISA
{
- Addr level1_pte = ptbr + vaddr.level1();
- AlphaISA::PageTableEntry level1 = mem->read<uint64_t>(level1_pte);
- if (!level1.valid()) {
- DPRINTF(VtoPhys, "level 1 PTE not valid, va = %#\n", vaddr);
- return 0;
+ PageTableEntry kernel_pte_lookup(FunctionalPort *mem,
+ Addr ptbr, VAddr vaddr)
+ {
+ PageTableEntry pte(4);
+ return pte;
}
- Addr level2_pte = level1.paddr() + vaddr.level2();
- AlphaISA::PageTableEntry level2 = mem->read<uint64_t>(level2_pte);
- if (!level2.valid()) {
- DPRINTF(VtoPhys, "level 2 PTE not valid, va = %#x\n", vaddr);
- return 0;
+ Addr vtophys(Addr vaddr)
+ {
+ return vaddr;
}
- Addr level3_pte = level2.paddr() + vaddr.level3();
- AlphaISA::PageTableEntry level3 = mem->read<uint64_t>(level3_pte);
- if (!level3.valid()) {
- DPRINTF(VtoPhys, "level 3 PTE not valid, va = %#x\n", vaddr);
- return 0;
+ Addr vtophys(ThreadContext *tc, Addr addr)
+ {
+ return addr;
}
- return level3;
-}
-Addr
-AlphaISA::vtophys(Addr vaddr)
-{
- Addr paddr = 0;
- if (AlphaISA::IsUSeg(vaddr))
- DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr);
- else if (AlphaISA::IsK0Seg(vaddr))
- paddr = AlphaISA::K0Seg2Phys(vaddr);
- else
- panic("vtophys: ptbr is not set on virtual lookup");
- DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr);
-
- return paddr;
-}
-
-Addr
-AlphaISA::vtophys(ThreadContext *tc, Addr addr)
-{
- AlphaISA::VAddr vaddr = addr;
- Addr ptbr = tc->readMiscReg(AlphaISA::IPR_PALtemp20);
- Addr paddr = 0;
- //@todo Andrew couldn't remember why he commented some of this code
- //so I put it back in. Perhaps something to do with gdb debugging?
- if (AlphaISA::PcPAL(vaddr) && (vaddr < EV5::PalMax)) {
- paddr = vaddr & ~ULL(1);
- } else {
- if (AlphaISA::IsK0Seg(vaddr)) {
- paddr = AlphaISA::K0Seg2Phys(vaddr);
- } else if (!ptbr) {
- paddr = vaddr;
- } else {
- AlphaISA::PageTableEntry pte =
- kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr);
- if (pte.valid())
- paddr = pte.paddr() | vaddr.offset();
- }
+ void CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
+ {
}
+ void CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
+ {
+ }
- DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr);
-
- return paddr;
-}
-
-
-void
-AlphaISA::CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
-{
- uint8_t *dst = (uint8_t *)dest;
- VirtualPort *vp = tc->getVirtPort(tc);
-
- vp->readBlob(src, dst, cplen);
-
- tc->delVirtPort(vp);
-
-}
-
-void
-AlphaISA::CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
-{
- uint8_t *src = (uint8_t *)source;
- VirtualPort *vp = tc->getVirtPort(tc);
-
- vp->writeBlob(dest, src, cplen);
-
- tc->delVirtPort(vp);
-}
-
-void
-AlphaISA::CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
-{
- int len = 0;
- VirtualPort *vp = tc->getVirtPort(tc);
-
- do {
- vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
- len++;
- } while (len < maxlen && dst[len] != 0 );
-
- tc->delVirtPort(vp);
- dst[len] = 0;
-}
+ void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
+ {
+ }
-void
-AlphaISA::CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
-{
- VirtualPort *vp = tc->getVirtPort(tc);
- for (ChunkGenerator gen(vaddr, strlen(src), AlphaISA::PageBytes); !gen.done();
- gen.next())
+ void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
{
- vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size());
- src += gen.size();
}
- tc->delVirtPort(vp);
}
diff --git a/src/base/loader/object_file.cc b/src/base/loader/object_file.cc
index 42c74d418..ad2cd34ba 100644
--- a/src/base/loader/object_file.cc
+++ b/src/base/loader/object_file.cc
@@ -45,6 +45,7 @@
#include "base/loader/ecoff_object.hh"
#include "base/loader/aout_object.hh"
#include "base/loader/elf_object.hh"
+#include "base/loader/raw_object.hh"
#include "mem/translating_port.hh"
@@ -107,7 +108,7 @@ ObjectFile::close()
ObjectFile *
-createObjectFile(const string &fname)
+createObjectFile(const string &fname, bool raw)
{
// open the file
int fd = open(fname.c_str(), O_RDONLY);
@@ -141,6 +142,9 @@ createObjectFile(const string &fname)
return fileObj;
}
+ if (raw)
+ return RawObject::tryFile(fname, fd, len, fileData);
+
// don't know what it is
close(fd);
munmap(fileData, len);
diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh
index 79fa394c6..64085185d 100644
--- a/src/base/loader/object_file.hh
+++ b/src/base/loader/object_file.hh
@@ -114,9 +114,11 @@ class ObjectFile
size_t textSize() const { return text.size; }
size_t dataSize() const { return data.size; }
size_t bssSize() const { return bss.size; }
+
+ void setTextBase(Addr a) { text.baseAddr = a; }
};
-ObjectFile *createObjectFile(const std::string &fname);
+ObjectFile *createObjectFile(const std::string &fname, bool raw = false);
#endif // __OBJECT_FILE_HH__
diff --git a/src/base/loader/raw_object.cc b/src/base/loader/raw_object.cc
new file mode 100644
index 000000000..79ddb81fe
--- /dev/null
+++ b/src/base/loader/raw_object.cc
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Steve Reinhardt
+ */
+
+#include "base/loader/raw_object.hh"
+#include "base/trace.hh"
+
+ObjectFile *
+RawObject::tryFile(const std::string &fname, int fd, size_t len, uint8_t *data)
+{
+ return new RawObject(fname, fd, len, data, ObjectFile::UnknownArch,
+ ObjectFile::UnknownOpSys);
+}
+
+RawObject::RawObject(const std::string &_filename, int _fd, size_t _len,
+ uint8_t *_data, Arch _arch, OpSys _opSys)
+ : ObjectFile(_filename, _fd, _len, _data, _arch, _opSys)
+{
+ text.baseAddr = 0;
+ text.size = len;
+ text.fileImage = fileData;
+
+ data.baseAddr = 0;
+ data.size = 0;
+ data.fileImage = NULL;
+
+ bss.baseAddr = 0;
+ bss.size = 0;
+ bss.fileImage = NULL;
+
+ DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n",
+ text.baseAddr, text.size, data.baseAddr, data.size,
+ bss.baseAddr, bss.size);
+}
+
+bool
+RawObject::loadGlobalSymbols(SymbolTable *symtab)
+{
+ return true;
+}
+
+bool
+RawObject::loadLocalSymbols(SymbolTable *symtab)
+{
+ return true;
+}
diff --git a/src/base/loader/raw_object.hh b/src/base/loader/raw_object.hh
new file mode 100644
index 000000000..c7fff4e66
--- /dev/null
+++ b/src/base/loader/raw_object.hh
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ */
+
+#ifndef __BASE_LOADER_RAW_OBJECT_HH__
+#define __BASE_LOADER_RAW_OBJECT_HH__
+
+#include "base/loader/object_file.hh"
+
+class RawObject: public ObjectFile
+{
+ protected:
+ RawObject(const std::string &_filename, int _fd, size_t _len,
+ uint8_t *_data, Arch _arch, OpSys _opSys);
+ public:
+ virtual ~RawObject() {}
+
+ virtual bool loadGlobalSymbols(SymbolTable *symtab);
+ virtual bool loadLocalSymbols(SymbolTable *symtab);
+
+ static ObjectFile *tryFile(const std::string &fname, int fd, size_t len,
+ uint8_t *data);
+};
+
+
+
+#endif // __BASE_LOADER_RAW_OBJECT_HH__
diff --git a/src/base/pollevent.cc b/src/base/pollevent.cc
index 2743cd95d..fd5b09d28 100644
--- a/src/base/pollevent.cc
+++ b/src/base/pollevent.cc
@@ -30,6 +30,9 @@
#include <sys/ioctl.h>
#include <sys/types.h>
+#if defined(__sun__)
+#include <sys/file.h>
+#endif
#include <fcntl.h>
#include <signal.h>
diff --git a/src/base/random.cc b/src/base/random.cc
index e135b55f5..82c9e3566 100644
--- a/src/base/random.cc
+++ b/src/base/random.cc
@@ -32,6 +32,10 @@
#include <cstdlib>
#include <cmath>
+#if defined(__sun__)
+#include <ieeefp.h>
+#endif
+
#include "sim/param.hh"
#include "base/random.hh"
#include "base/trace.hh"
@@ -65,12 +69,27 @@ getLong()
return mrand48();
}
+double
+m5round(double r)
+{
+#if defined(__sun__)
+ double val;
+ fp_rnd oldrnd = fpsetround(FP_RN);
+ val = rint(r);
+ fpsetround(oldrnd);
+ return val;
+#else
+ return round(r);
+#endif
+}
+
int64_t
getUniform(int64_t min, int64_t max)
{
double r;
r = drand48() * (max-min) + min;
- return (int64_t)round(r);
+
+ return (int64_t)m5round(r);
}
uint64_t
@@ -78,7 +97,8 @@ getUniformPos(uint64_t min, uint64_t max)
{
double r;
r = drand48() * (max-min) + min;
- return (uint64_t)round(r);
+
+ return (uint64_t)m5round(r);
}
diff --git a/src/base/random.hh b/src/base/random.hh
index b5eb39f94..40d62da7f 100644
--- a/src/base/random.hh
+++ b/src/base/random.hh
@@ -36,6 +36,7 @@
long getLong();
double getDouble();
+double m5random(double r);
uint64_t getUniformPos(uint64_t min, uint64_t max);
int64_t getUniform(int64_t min, int64_t max);
diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc
index e4efa31e3..55fb97ce9 100644
--- a/src/base/remote_gdb.cc
+++ b/src/base/remote_gdb.cc
@@ -123,7 +123,6 @@
#include "arch/vtophys.hh"
#include "base/intmath.hh"
-#include "base/kgdb.h"
#include "base/remote_gdb.hh"
#include "base/socket.hh"
#include "base/trace.hh"
@@ -138,18 +137,18 @@ using namespace std;
using namespace TheISA;
#ifndef NDEBUG
-vector<RemoteGDB *> debuggers;
-int current_debugger = -1;
+vector<BaseRemoteGDB *> debuggers;
void
debugger()
{
+ static int current_debugger = -1;
if (current_debugger >= 0 && current_debugger < debuggers.size()) {
- RemoteGDB *gdb = debuggers[current_debugger];
+ BaseRemoteGDB *gdb = debuggers[current_debugger];
if (!gdb->isattached())
gdb->listener->accept();
if (gdb->isattached())
- gdb->trap(ALPHA_KENTRY_IF);
+ gdb->trap(SIGILL);
}
}
#endif
@@ -169,7 +168,7 @@ GDBListener::Event::process(int revent)
listener->accept();
}
-GDBListener::GDBListener(RemoteGDB *g, int p)
+GDBListener::GDBListener(BaseRemoteGDB *g, int p)
: event(NULL), gdb(g), port(p)
{
assert(!gdb->listener);
@@ -229,55 +228,46 @@ GDBListener::accept()
}
}
-///////////////////////////////////////////////////////////
-//
-//
-//
-int digit2i(char);
-char i2digit(int);
-void mem2hex(void *, const void *, int);
-const char *hex2mem(void *, const char *, int);
-Addr hex2i(const char **);
-
-RemoteGDB::Event::Event(RemoteGDB *g, int fd, int e)
+BaseRemoteGDB::Event::Event(BaseRemoteGDB *g, int fd, int e)
: PollEvent(fd, e), gdb(g)
{}
void
-RemoteGDB::Event::process(int revent)
+BaseRemoteGDB::Event::process(int revent)
{
if (revent & POLLIN)
- gdb->trap(ALPHA_KENTRY_IF);
+ gdb->trap(SIGILL);
else if (revent & POLLNVAL)
gdb->detach();
}
-RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
+BaseRemoteGDB::BaseRemoteGDB(System *_system, ThreadContext *c, size_t cacheSize)
: event(NULL), listener(NULL), number(-1), fd(-1),
active(false), attached(false),
- system(_system), pmem(_system->physmem), context(c)
+ system(_system), pmem(_system->physmem), context(c),
+ gdbregs(cacheSize)
{
- memset(gdbregs, 0, sizeof(gdbregs));
+ memset(gdbregs.regs, 0, gdbregs.bytes());
}
-RemoteGDB::~RemoteGDB()
+BaseRemoteGDB::~BaseRemoteGDB()
{
if (event)
delete event;
}
string
-RemoteGDB::name()
+BaseRemoteGDB::name()
{
return system->name() + ".remote_gdb";
}
bool
-RemoteGDB::isattached()
+BaseRemoteGDB::isattached()
{ return attached; }
void
-RemoteGDB::attach(int f)
+BaseRemoteGDB::attach(int f)
{
fd = f;
@@ -289,7 +279,7 @@ RemoteGDB::attach(int f)
}
void
-RemoteGDB::detach()
+BaseRemoteGDB::detach()
{
attached = false;
close(fd);
@@ -300,250 +290,50 @@ RemoteGDB::detach()
}
const char *
-gdb_command(char cmd)
+BaseRemoteGDB::gdb_command(char cmd)
{
switch (cmd) {
- case KGDB_SIGNAL: return "KGDB_SIGNAL";
- case KGDB_SET_BAUD: return "KGDB_SET_BAUD";
- case KGDB_SET_BREAK: return "KGDB_SET_BREAK";
- case KGDB_CONT: return "KGDB_CONT";
- case KGDB_ASYNC_CONT: return "KGDB_ASYNC_CONT";
- case KGDB_DEBUG: return "KGDB_DEBUG";
- case KGDB_DETACH: return "KGDB_DETACH";
- case KGDB_REG_R: return "KGDB_REG_R";
- case KGDB_REG_W: return "KGDB_REG_W";
- case KGDB_SET_THREAD: return "KGDB_SET_THREAD";
- case KGDB_CYCLE_STEP: return "KGDB_CYCLE_STEP";
- case KGDB_SIG_CYCLE_STEP: return "KGDB_SIG_CYCLE_STEP";
- case KGDB_KILL: return "KGDB_KILL";
- case KGDB_MEM_W: return "KGDB_MEM_W";
- case KGDB_MEM_R: return "KGDB_MEM_R";
- case KGDB_SET_REG: return "KGDB_SET_REG";
- case KGDB_READ_REG: return "KGDB_READ_REG";
- case KGDB_QUERY_VAR: return "KGDB_QUERY_VAR";
- case KGDB_SET_VAR: return "KGDB_SET_VAR";
- case KGDB_RESET: return "KGDB_RESET";
- case KGDB_STEP: return "KGDB_STEP";
- case KGDB_ASYNC_STEP: return "KGDB_ASYNC_STEP";
- case KGDB_THREAD_ALIVE: return "KGDB_THREAD_ALIVE";
- case KGDB_TARGET_EXIT: return "KGDB_TARGET_EXIT";
- case KGDB_BINARY_DLOAD: return "KGDB_BINARY_DLOAD";
- case KGDB_CLR_HW_BKPT: return "KGDB_CLR_HW_BKPT";
- case KGDB_SET_HW_BKPT: return "KGDB_SET_HW_BKPT";
- case KGDB_START: return "KGDB_START";
- case KGDB_END: return "KGDB_END";
- case KGDB_GOODP: return "KGDB_GOODP";
- case KGDB_BADP: return "KGDB_BADP";
+ case GDBSignal: return "KGDB_SIGNAL";
+ case GDBSetBaud: return "KGDB_SET_BAUD";
+ case GDBSetBreak: return "KGDB_SET_BREAK";
+ case GDBCont: return "KGDB_CONT";
+ case GDBAsyncCont: return "KGDB_ASYNC_CONT";
+ case GDBDebug: return "KGDB_DEBUG";
+ case GDBDetach: return "KGDB_DETACH";
+ case GDBRegR: return "KGDB_REG_R";
+ case GDBRegW: return "KGDB_REG_W";
+ case GDBSetThread: return "KGDB_SET_THREAD";
+ case GDBCycleStep: return "KGDB_CYCLE_STEP";
+ case GDBSigCycleStep: return "KGDB_SIG_CYCLE_STEP";
+ case GDBKill: return "KGDB_KILL";
+ case GDBMemW: return "KGDB_MEM_W";
+ case GDBMemR: return "KGDB_MEM_R";
+ case GDBSetReg: return "KGDB_SET_REG";
+ case GDBReadReg: return "KGDB_READ_REG";
+ case GDBQueryVar: return "KGDB_QUERY_VAR";
+ case GDBSetVar: return "KGDB_SET_VAR";
+ case GDBReset: return "KGDB_RESET";
+ case GDBStep: return "KGDB_STEP";
+ case GDBAsyncStep: return "KGDB_ASYNC_STEP";
+ case GDBThreadAlive: return "KGDB_THREAD_ALIVE";
+ case GDBTargetExit: return "KGDB_TARGET_EXIT";
+ case GDBBinaryDload: return "KGDB_BINARY_DLOAD";
+ case GDBClrHwBkpt: return "KGDB_CLR_HW_BKPT";
+ case GDBSetHwBkpt: return "KGDB_SET_HW_BKPT";
+ case GDBStart: return "KGDB_START";
+ case GDBEnd: return "KGDB_END";
+ case GDBGoodP: return "KGDB_GOODP";
+ case GDBBadP: return "KGDB_BADP";
default: return "KGDB_UNKNOWN";
}
}
-///////////////////////////////////////////////////////////
-// RemoteGDB::acc
-//
-// Determine if the mapping at va..(va+len) is valid.
-//
-bool
-RemoteGDB::acc(Addr va, size_t len)
-{
- Addr last_va;
-
- va = TheISA::TruncPage(va);
- last_va = TheISA::RoundPage(va + len);
-
- do {
- if (TheISA::IsK0Seg(va)) {
- if (va < (TheISA::K0SegBase + pmem->size())) {
- DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= "
- "%#x < K0SEG + size\n", va);
- return true;
- } else {
- DPRINTF(GDBAcc, "acc: Mapping invalid %#x > K0SEG + size\n",
- va);
- return false;
- }
- }
-
- /**
- * This code says that all accesses to palcode (instruction and data)
- * are valid since there isn't a va->pa mapping because palcode is
- * accessed physically. At some point this should probably be cleaned up
- * but there is no easy way to do it.
- */
-
- if (AlphaISA::PcPAL(va) || va < 0x10000)
- return true;
-
- Addr ptbr = context->readMiscReg(AlphaISA::IPR_PALtemp20);
- TheISA::PageTableEntry pte = TheISA::kernel_pte_lookup(context->getPhysPort(), ptbr, va);
- if (!pte.valid()) {
- DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
- return false;
- }
- va += TheISA::PageBytes;
- } while (va < last_va);
-
- DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va);
- return true;
-}
-
-///////////////////////////////////////////////////////////
-// RemoteGDB::signal
-//
-// Translate a trap number into a Unix-compatible signal number.
-// (GDB only understands Unix signal numbers.)
-//
-int
-RemoteGDB::signal(int type)
-{
- switch (type) {
- case ALPHA_KENTRY_INT:
- return (SIGTRAP);
-
- case ALPHA_KENTRY_UNA:
- return (SIGBUS);
-
- case ALPHA_KENTRY_ARITH:
- return (SIGFPE);
-
- case ALPHA_KENTRY_IF:
- return (SIGILL);
-
- case ALPHA_KENTRY_MM:
- return (SIGSEGV);
-
- default:
- panic("unknown signal type");
- return 0;
- }
-}
-
-///////////////////////////////////////////////////////////
-// RemoteGDB::getregs
-//
-// Translate the kernel debugger register format into
-// the GDB register format.
-void
-RemoteGDB::getregs()
-{
- memset(gdbregs, 0, sizeof(gdbregs));
-
- gdbregs[KGDB_REG_PC] = context->readPC();
-
- // @todo: Currently this is very Alpha specific.
- if (AlphaISA::PcPAL(gdbregs[KGDB_REG_PC])) {
- for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
- gdbregs[i] = context->readIntReg(AlphaISA::reg_redir[i]);
- }
- } else {
- for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
- gdbregs[i] = context->readIntReg(i);
- }
- }
-
-#ifdef KGDB_FP_REGS
- for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) {
- gdbregs[i + KGDB_REG_F0] = context->readFloatRegBits(i);
- }
-#endif
-}
-
-///////////////////////////////////////////////////////////
-// RemoteGDB::setregs
-//
-// Translate the GDB register format into the kernel
-// debugger register format.
-//
-void
-RemoteGDB::setregs()
-{
- // @todo: Currently this is very Alpha specific.
- if (AlphaISA::PcPAL(gdbregs[KGDB_REG_PC])) {
- for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
- context->setIntReg(AlphaISA::reg_redir[i], gdbregs[i]);
- }
- } else {
- for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
- context->setIntReg(i, gdbregs[i]);
- }
- }
-
-#ifdef KGDB_FP_REGS
- for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) {
- context->setFloatRegBits(i, gdbregs[i + KGDB_REG_F0]);
- }
-#endif
- context->setPC(gdbregs[KGDB_REG_PC]);
-}
-
-void
-RemoteGDB::setTempBreakpoint(TempBreakpoint &bkpt, Addr addr)
-{
- DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", addr);
-
- bkpt.address = addr;
- insertHardBreak(addr, 4);
-}
-
-void
-RemoteGDB::clearTempBreakpoint(TempBreakpoint &bkpt)
-{
- DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n",
- bkpt.address);
-
-
- removeHardBreak(bkpt.address, 4);
- bkpt.address = 0;
-}
-
-void
-RemoteGDB::clearSingleStep()
-{
- DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n",
- takenBkpt.address, notTakenBkpt.address);
-
- if (takenBkpt.address != 0)
- clearTempBreakpoint(takenBkpt);
-
- if (notTakenBkpt.address != 0)
- clearTempBreakpoint(notTakenBkpt);
-}
-
-void
-RemoteGDB::setSingleStep()
-{
- Addr pc = context->readPC();
- Addr npc, bpc;
- bool set_bt = false;
-
- npc = pc + sizeof(MachInst);
-
- // User was stopped at pc, e.g. the instruction at pc was not
- // executed.
- MachInst inst = read<MachInst>(pc);
- StaticInstPtr si(inst);
- if (si->hasBranchTarget(pc, context, bpc)) {
- // Don't bother setting a breakpoint on the taken branch if it
- // is the same as the next pc
- if (bpc != npc)
- set_bt = true;
- }
-
- DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n",
- takenBkpt.address, notTakenBkpt.address);
-
- setTempBreakpoint(notTakenBkpt, npc);
-
- if (set_bt)
- setTempBreakpoint(takenBkpt, bpc);
-}
-
/////////////////////////
//
//
uint8_t
-RemoteGDB::getbyte()
+BaseRemoteGDB::getbyte()
{
uint8_t b;
::read(fd, &b, 1);
@@ -551,14 +341,14 @@ RemoteGDB::getbyte()
}
void
-RemoteGDB::putbyte(uint8_t b)
+BaseRemoteGDB::putbyte(uint8_t b)
{
::write(fd, &b, 1);
}
// Send a packet to gdb
void
-RemoteGDB::send(const char *bp)
+BaseRemoteGDB::send(const char *bp)
{
const char *p;
uint8_t csum, c;
@@ -567,20 +357,26 @@ RemoteGDB::send(const char *bp)
do {
p = bp;
- putbyte(KGDB_START);
+ //Start sending a packet
+ putbyte(GDBStart);
+ //Send the contents, and also keep a check sum.
for (csum = 0; (c = *p); p++) {
putbyte(c);
csum += c;
}
- putbyte(KGDB_END);
+ //Send the ending character.
+ putbyte(GDBEnd);
+ //Sent the checksum.
putbyte(i2digit(csum >> 4));
putbyte(i2digit(csum));
- } while ((c = getbyte() & 0x7f) == KGDB_BADP);
+ //Try transmitting over and over again until the other end doesn't send an
+ //error back.
+ } while ((c = getbyte() & 0x7f) == GDBBadP);
}
// Receive a packet from gdb
int
-RemoteGDB::recv(char *bp, int maxlen)
+BaseRemoteGDB::recv(char *bp, int maxlen)
{
char *p;
int c, csum;
@@ -589,28 +385,37 @@ RemoteGDB::recv(char *bp, int maxlen)
do {
p = bp;
csum = len = 0;
- while ((c = getbyte()) != KGDB_START)
+ //Find the beginning of a packet
+ while ((c = getbyte()) != GDBStart)
;
- while ((c = getbyte()) != KGDB_END && len < maxlen) {
+ //Read until you find the end of the data in the packet, and keep
+ //track of the check sum.
+ while ((c = getbyte()) != GDBEnd && len < maxlen) {
c &= 0x7f;
csum += c;
*p++ = c;
len++;
}
+
+ //Mask the check sum, and terminate the command string.
csum &= 0xff;
*p = '\0';
+ //If the command was too long, report an error.
if (len >= maxlen) {
- putbyte(KGDB_BADP);
+ putbyte(GDBBadP);
continue;
}
+ //Bring in the checksum. If the check sum matches, csum will be 0.
csum -= digit2i(getbyte()) * 16;
csum -= digit2i(getbyte());
+ //If the check sum was correct
if (csum == 0) {
- putbyte(KGDB_GOODP);
+ //Report that the packet was received correctly
+ putbyte(GDBGoodP);
// Sequence present?
if (bp[2] == ':') {
putbyte(bp[0]);
@@ -620,7 +425,8 @@ RemoteGDB::recv(char *bp, int maxlen)
}
break;
}
- putbyte(KGDB_BADP);
+ //Otherwise, report that there was a mistake.
+ putbyte(GDBBadP);
} while (1);
DPRINTF(GDBRecv, "recv: %s: %s\n", gdb_command(*bp), bp);
@@ -630,7 +436,7 @@ RemoteGDB::recv(char *bp, int maxlen)
// Read bytes from kernel address space for debugger.
bool
-RemoteGDB::read(Addr vaddr, size_t size, char *data)
+BaseRemoteGDB::read(Addr vaddr, size_t size, char *data)
{
static Addr lastaddr = 0;
static size_t lastsize = 0;
@@ -662,7 +468,7 @@ RemoteGDB::read(Addr vaddr, size_t size, char *data)
// Write bytes to kernel address space for debugger.
bool
-RemoteGDB::write(Addr vaddr, size_t size, const char *data)
+BaseRemoteGDB::write(Addr vaddr, size_t size, const char *data)
{
static Addr lastaddr = 0;
static size_t lastsize = 0;
@@ -685,21 +491,15 @@ RemoteGDB::write(Addr vaddr, size_t size, const char *data)
vp->writeBlob(vaddr, (uint8_t*)data, size);
context->delVirtPort(vp);
-#ifdef IMB
- alpha_pal_imb();
-#endif
-
return true;
}
-
-PCEventQueue *RemoteGDB::getPcEventQueue()
+PCEventQueue *BaseRemoteGDB::getPcEventQueue()
{
return &system->pcEventQueue;
}
-
-RemoteGDB::HardBreakpoint::HardBreakpoint(RemoteGDB *_gdb, Addr pc)
+BaseRemoteGDB::HardBreakpoint::HardBreakpoint(BaseRemoteGDB *_gdb, Addr pc)
: PCEvent(_gdb->getPcEventQueue(), "HardBreakpoint Event", pc),
gdb(_gdb), refcount(0)
{
@@ -707,25 +507,25 @@ RemoteGDB::HardBreakpoint::HardBreakpoint(RemoteGDB *_gdb, Addr pc)
}
void
-RemoteGDB::HardBreakpoint::process(ThreadContext *tc)
+BaseRemoteGDB::HardBreakpoint::process(ThreadContext *tc)
{
DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc());
if (tc == gdb->context)
- gdb->trap(ALPHA_KENTRY_INT);
+ gdb->trap(SIGTRAP);
}
bool
-RemoteGDB::insertSoftBreak(Addr addr, size_t len)
+BaseRemoteGDB::insertSoftBreak(Addr addr, size_t len)
{
- if (len != sizeof(MachInst))
+ if (len != sizeof(TheISA::MachInst))
panic("invalid length\n");
return insertHardBreak(addr, len);
}
bool
-RemoteGDB::removeSoftBreak(Addr addr, size_t len)
+BaseRemoteGDB::removeSoftBreak(Addr addr, size_t len)
{
if (len != sizeof(MachInst))
panic("invalid length\n");
@@ -734,7 +534,7 @@ RemoteGDB::removeSoftBreak(Addr addr, size_t len)
}
bool
-RemoteGDB::insertHardBreak(Addr addr, size_t len)
+BaseRemoteGDB::insertHardBreak(Addr addr, size_t len)
{
if (len != sizeof(MachInst))
panic("invalid length\n");
@@ -751,7 +551,7 @@ RemoteGDB::insertHardBreak(Addr addr, size_t len)
}
bool
-RemoteGDB::removeHardBreak(Addr addr, size_t len)
+BaseRemoteGDB::removeHardBreak(Addr addr, size_t len)
{
if (len != sizeof(MachInst))
panic("invalid length\n");
@@ -771,8 +571,23 @@ RemoteGDB::removeHardBreak(Addr addr, size_t len)
return true;
}
+void
+BaseRemoteGDB::setTempBreakpoint(Addr bkpt)
+{
+ DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt);
+ insertHardBreak(bkpt, sizeof(TheISA::MachInst));
+}
+
+void
+BaseRemoteGDB::clearTempBreakpoint(Addr &bkpt)
+{
+ DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt);
+ removeHardBreak(bkpt, sizeof(TheISA::MachInst));
+ bkpt = 0;
+}
+
const char *
-break_type(char c)
+BaseRemoteGDB::break_type(char c)
{
switch(c) {
case '0': return "software breakpoint";
@@ -790,12 +605,12 @@ break_type(char c)
// makes sense to use POSIX errno values, because that is what the
// gdb/remote.c functions want to return.
bool
-RemoteGDB::trap(int type)
+BaseRemoteGDB::trap(int type)
{
uint64_t val;
size_t datalen, len;
- char data[KGDB_BUFLEN + 1];
- char buffer[sizeof(gdbregs) * 2 + 256];
+ char data[GDBPacketBufLen + 1];
+ char buffer[gdbregs.bytes() * 2 + 256];
const char *p;
char command, subcmd;
string var;
@@ -823,7 +638,7 @@ RemoteGDB::trap(int type)
active = true;
else
// Tell remote host that an exception has occurred.
- snprintf((char *)buffer, sizeof(buffer), "S%02x", signal(type));
+ snprintf((char *)buffer, sizeof(buffer), "S%02x", type);
send(buffer);
// Stick frame regs into our reg cache.
@@ -837,24 +652,25 @@ RemoteGDB::trap(int type)
p = data + 1;
switch (command) {
- case KGDB_SIGNAL:
+ case GDBSignal:
// if this command came from a running gdb, answer it --
// the other guy has no way of knowing if we're in or out
// of this loop when he issues a "remote-signal".
- snprintf((char *)buffer, sizeof(buffer), "S%02x", signal(type));
+ snprintf((char *)buffer, sizeof(buffer),
+ "S%02x", type);
send(buffer);
continue;
- case KGDB_REG_R:
- if (2 * sizeof(gdbregs) > sizeof(buffer))
+ case GDBRegR:
+ if (2 * gdbregs.bytes() > sizeof(buffer))
panic("buffer too small");
- mem2hex(buffer, gdbregs, sizeof(gdbregs));
+ mem2hex(buffer, gdbregs.regs, gdbregs.bytes());
send(buffer);
continue;
- case KGDB_REG_W:
- p = hex2mem(gdbregs, p, sizeof(gdbregs));
+ case GDBRegW:
+ p = hex2mem(gdbregs.regs, p, gdbregs.bytes());
if (p == NULL || *p != '\0')
send("E01");
else {
@@ -864,7 +680,7 @@ RemoteGDB::trap(int type)
continue;
#if 0
- case KGDB_SET_REG:
+ case GDBSetReg:
val = hex2i(&p);
if (*p++ != '=') {
send("E01");
@@ -875,14 +691,14 @@ RemoteGDB::trap(int type)
continue;
}
- gdbregs[val] = hex2i(&p);
+ gdbregs.regs[val] = hex2i(&p);
setregs();
send("OK");
continue;
#endif
- case KGDB_MEM_R:
+ case GDBMemR:
val = hex2i(&p);
if (*p++ != ',') {
send("E02");
@@ -914,7 +730,7 @@ RemoteGDB::trap(int type)
}
continue;
- case KGDB_MEM_W:
+ case GDBMemW:
val = hex2i(&p);
if (*p++ != ',') {
send("E06");
@@ -944,7 +760,7 @@ RemoteGDB::trap(int type)
send("E0B");
continue;
- case KGDB_SET_THREAD:
+ case GDBSetThread:
subcmd = *p++;
val = hex2i(&p);
if (val == 0)
@@ -953,14 +769,14 @@ RemoteGDB::trap(int type)
send("E01");
continue;
- case KGDB_DETACH:
- case KGDB_KILL:
+ case GDBDetach:
+ case GDBKill:
active = false;
clearSingleStep();
detach();
goto out;
- case KGDB_ASYNC_CONT:
+ case GDBAsyncCont:
subcmd = hex2i(&p);
if (*p++ == ';') {
val = hex2i(&p);
@@ -970,7 +786,7 @@ RemoteGDB::trap(int type)
clearSingleStep();
goto out;
- case KGDB_CONT:
+ case GDBCont:
if (p - data < datalen) {
val = hex2i(&p);
context->setPC(val);
@@ -979,7 +795,7 @@ RemoteGDB::trap(int type)
clearSingleStep();
goto out;
- case KGDB_ASYNC_STEP:
+ case GDBAsyncStep:
subcmd = hex2i(&p);
if (*p++ == ';') {
val = hex2i(&p);
@@ -989,7 +805,7 @@ RemoteGDB::trap(int type)
setSingleStep();
goto out;
- case KGDB_STEP:
+ case GDBStep:
if (p - data < datalen) {
val = hex2i(&p);
context->setPC(val);
@@ -998,7 +814,7 @@ RemoteGDB::trap(int type)
setSingleStep();
goto out;
- case KGDB_CLR_HW_BKPT:
+ case GDBClrHwBkpt:
subcmd = *p++;
if (*p++ != ',') send("E0D");
val = hex2i(&p);
@@ -1030,7 +846,7 @@ RemoteGDB::trap(int type)
send(ret ? "OK" : "E0C");
continue;
- case KGDB_SET_HW_BKPT:
+ case GDBSetHwBkpt:
subcmd = *p++;
if (*p++ != ',') send("E0D");
val = hex2i(&p);
@@ -1062,7 +878,7 @@ RemoteGDB::trap(int type)
send(ret ? "OK" : "E0C");
continue;
- case KGDB_QUERY_VAR:
+ case GDBQueryVar:
var = string(p, datalen - 1);
if (var == "C")
send("QC0");
@@ -1070,17 +886,17 @@ RemoteGDB::trap(int type)
send("");
continue;
- case KGDB_SET_BAUD:
- case KGDB_SET_BREAK:
- case KGDB_DEBUG:
- case KGDB_CYCLE_STEP:
- case KGDB_SIG_CYCLE_STEP:
- case KGDB_READ_REG:
- case KGDB_SET_VAR:
- case KGDB_RESET:
- case KGDB_THREAD_ALIVE:
- case KGDB_TARGET_EXIT:
- case KGDB_BINARY_DLOAD:
+ case GDBSetBaud:
+ case GDBSetBreak:
+ case GDBDebug:
+ case GDBCycleStep:
+ case GDBSigCycleStep:
+ case GDBReadReg:
+ case GDBSetVar:
+ case GDBReset:
+ case GDBThreadAlive:
+ case GDBTargetExit:
+ case GDBBinaryDload:
// Unsupported command
DPRINTF(GDBMisc, "Unsupported command: %s\n",
gdb_command(command));
@@ -1106,7 +922,7 @@ RemoteGDB::trap(int type)
// Convert a hex digit into an integer.
// This returns -1 if the argument passed is no valid hex digit.
int
-digit2i(char c)
+BaseRemoteGDB::digit2i(char c)
{
if (c >= '0' && c <= '9')
return (c - '0');
@@ -1121,14 +937,14 @@ digit2i(char c)
// Convert the low 4 bits of an integer into an hex digit.
char
-i2digit(int n)
+BaseRemoteGDB::i2digit(int n)
{
return ("0123456789abcdef"[n & 0x0f]);
}
// Convert a byte array into an hex string.
void
-mem2hex(void *vdst, const void *vsrc, int len)
+BaseRemoteGDB::mem2hex(void *vdst, const void *vsrc, int len)
{
char *dst = (char *)vdst;
const char *src = (const char *)vsrc;
@@ -1145,7 +961,7 @@ mem2hex(void *vdst, const void *vsrc, int len)
// hex digit. If the string ends in the middle of a byte, NULL is
// returned.
const char *
-hex2mem(void *vdst, const char *src, int maxlen)
+BaseRemoteGDB::hex2mem(void *vdst, const char *src, int maxlen)
{
char *dst = (char *)vdst;
int msb, lsb;
@@ -1166,7 +982,7 @@ hex2mem(void *vdst, const char *src, int maxlen)
// This returns a pointer to the character following the last valid
// hex digit.
Addr
-hex2i(const char **srcp)
+BaseRemoteGDB::hex2i(const char **srcp)
{
const char *src = *srcp;
Addr r = 0;
diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh
index 8c3ce7572..9a3201c95 100644
--- a/src/base/remote_gdb.hh
+++ b/src/base/remote_gdb.hh
@@ -34,7 +34,6 @@
#include <map>
#include "arch/types.hh"
-#include "base/kgdb.h"
#include "cpu/pc_event.hh"
#include "base/pollevent.hh"
#include "base/socket.hh"
@@ -44,22 +43,72 @@ class ThreadContext;
class PhysicalMemory;
class GDBListener;
-class RemoteGDB
+
+enum GDBCommands
+{
+ GDBSignal = '?', // last signal
+ GDBSetBaud = 'b', // set baud (depracated)
+ GDBSetBreak = 'B', // set breakpoint (depracated)
+ GDBCont = 'c', // resume
+ GDBAsyncCont = 'C', // continue with signal
+ GDBDebug = 'd', // toggle debug flags (deprecated)
+ GDBDetach = 'D', // detach remote gdb
+ GDBRegR = 'g', // read general registers
+ GDBRegW = 'G', // write general registers
+ GDBSetThread = 'H', // set thread
+ GDBCycleStep = 'i', // step a single cycle
+ GDBSigCycleStep = 'I', // signal then cycle step
+ GDBKill = 'k', // kill program
+ GDBMemR = 'm', // read memory
+ GDBMemW = 'M', // write memory
+ GDBReadReg = 'p', // read register
+ GDBSetReg = 'P', // write register
+ GDBQueryVar = 'q', // query variable
+ GDBSetVar = 'Q', // set variable
+ GDBReset = 'r', // reset system. (Deprecated)
+ GDBStep = 's', // step
+ GDBAsyncStep = 'S', // signal and step
+ GDBThreadAlive = 'T', // find out if the thread is alive
+ GDBTargetExit = 'W', // target exited
+ GDBBinaryDload = 'X', // write memory
+ GDBClrHwBkpt = 'z', // remove breakpoint or watchpoint
+ GDBSetHwBkpt = 'Z' // insert breakpoint or watchpoint
+};
+
+const char GDBStart = '$';
+const char GDBEnd = '#';
+const char GDBGoodP = '+';
+const char GDBBadP = '-';
+
+const int GDBPacketBufLen = 1024;
+
+class BaseRemoteGDB
{
- protected:
- typedef TheISA::MachInst MachInst;
private:
friend void debugger();
friend class GDBListener;
+ //Helper functions
+ protected:
+ int digit2i(char);
+ char i2digit(int);
+ Addr hex2i(const char **);
+ //Address formats, break types, and gdb commands may change
+ //between architectures, so they're defined as virtual
+ //functions.
+ virtual void mem2hex(void *, const void *, int);
+ virtual const char * hex2mem(void *, const char *, int);
+ virtual const char * break_type(char c);
+ virtual const char * gdb_command(char cmd);
+
protected:
class Event : public PollEvent
{
protected:
- RemoteGDB *gdb;
+ BaseRemoteGDB *gdb;
public:
- Event(RemoteGDB *g, int fd, int e);
+ Event(BaseRemoteGDB *g, int fd, int e);
void process(int revent);
};
@@ -69,8 +118,8 @@ class RemoteGDB
int number;
protected:
+ //The socket commands come in through
int fd;
- uint64_t gdbregs[KGDB_NUMREGS];
protected:
#ifdef notyet
@@ -84,6 +133,24 @@ class RemoteGDB
ThreadContext *context;
protected:
+ class GdbRegCache
+ {
+ public:
+ GdbRegCache(size_t newSize) : regs(new uint64_t[newSize]), size(newSize)
+ {}
+ ~GdbRegCache()
+ {
+ delete [] regs;
+ }
+
+ uint64_t * regs;
+ size_t size;
+ size_t bytes() { return size * sizeof(uint64_t); }
+ };
+
+ GdbRegCache gdbregs;
+
+ protected:
uint8_t getbyte();
void putbyte(uint8_t b);
@@ -92,15 +159,15 @@ class RemoteGDB
protected:
// Machine memory
- bool read(Addr addr, size_t size, char *data);
- bool write(Addr addr, size_t size, const char *data);
+ virtual bool read(Addr addr, size_t size, char *data);
+ virtual bool write(Addr addr, size_t size, const char *data);
template <class T> T read(Addr addr);
template <class T> void write(Addr addr, T data);
public:
- RemoteGDB(System *system, ThreadContext *context);
- ~RemoteGDB();
+ BaseRemoteGDB(System *system, ThreadContext *context, size_t cacheSize);
+ virtual ~BaseRemoteGDB();
void replaceThreadContext(ThreadContext *tc) { context = tc; }
@@ -108,16 +175,15 @@ class RemoteGDB
void detach();
bool isattached();
- bool acc(Addr addr, size_t len);
- static int signal(int type);
+ virtual bool acc(Addr addr, size_t len) = 0;
bool trap(int type);
protected:
- void getregs();
- void setregs();
+ virtual void getregs() = 0;
+ virtual void setregs() = 0;
- void clearSingleStep();
- void setSingleStep();
+ virtual void clearSingleStep() = 0;
+ virtual void setSingleStep() = 0;
PCEventQueue *getPcEventQueue();
@@ -125,13 +191,13 @@ class RemoteGDB
class HardBreakpoint : public PCEvent
{
private:
- RemoteGDB *gdb;
+ BaseRemoteGDB *gdb;
public:
int refcount;
public:
- HardBreakpoint(RemoteGDB *_gdb, Addr addr);
+ HardBreakpoint(BaseRemoteGDB *_gdb, Addr addr);
std::string name() { return gdb->name() + ".hwbkpt"; }
virtual void process(ThreadContext *tc);
@@ -148,18 +214,8 @@ class RemoteGDB
bool removeHardBreak(Addr addr, size_t len);
protected:
- struct TempBreakpoint {
- Addr address; // set here
- MachInst bkpt_inst; // saved instruction at bkpt
- int init_count; // number of times to skip bkpt
- int count; // current count
- };
-
- TempBreakpoint notTakenBkpt;
- TempBreakpoint takenBkpt;
-
- void clearTempBreakpoint(TempBreakpoint &bkpt);
- void setTempBreakpoint(TempBreakpoint &bkpt, Addr addr);
+ void clearTempBreakpoint(Addr &bkpt);
+ void setTempBreakpoint(Addr bkpt);
public:
std::string name();
@@ -167,7 +223,7 @@ class RemoteGDB
template <class T>
inline T
-RemoteGDB::read(Addr addr)
+BaseRemoteGDB::read(Addr addr)
{
T temp;
read(addr, sizeof(T), (char *)&temp);
@@ -176,7 +232,7 @@ RemoteGDB::read(Addr addr)
template <class T>
inline void
-RemoteGDB::write(Addr addr, T data)
+BaseRemoteGDB::write(Addr addr, T data)
{ write(addr, sizeof(T), (const char *)&data); }
class GDBListener
@@ -197,11 +253,11 @@ class GDBListener
protected:
ListenSocket listener;
- RemoteGDB *gdb;
+ BaseRemoteGDB *gdb;
int port;
public:
- GDBListener(RemoteGDB *g, int p);
+ GDBListener(BaseRemoteGDB *g, int p);
~GDBListener();
void accept();
diff --git a/src/base/statistics.hh b/src/base/statistics.hh
index 59f219c07..577ea5eab 100644
--- a/src/base/statistics.hh
+++ b/src/base/statistics.hh
@@ -696,7 +696,7 @@ class ScalarBase : public DataAccess
protected:
/** The storage of this stat. */
- char storage[sizeof(Storage)];
+ char storage[sizeof(Storage)] __attribute__ ((aligned (8)));
/** The parameters for this stat. */
Params params;
@@ -1637,7 +1637,7 @@ class DistBase : public DataAccess
protected:
/** The storage for this stat. */
- char storage[sizeof(Storage)];
+ char storage[sizeof(Storage)] __attribute__ ((aligned (8)));
/** The parameters for this stat. */
Params params;
diff --git a/src/base/stats/flags.hh b/src/base/stats/flags.hh
index ada1a4a87..69f73f66a 100644
--- a/src/base/stats/flags.hh
+++ b/src/base/stats/flags.hh
@@ -36,7 +36,7 @@ namespace Stats {
* Define the storage for format flags.
* @todo Can probably shrink this.
*/
-typedef u_int32_t StatFlags;
+typedef uint32_t StatFlags;
/** Nothing extra to print. */
const StatFlags none = 0x00000000;
diff --git a/src/base/time.hh b/src/base/time.hh
index 24e8a8a53..7aa4c50db 100644
--- a/src/base/time.hh
+++ b/src/base/time.hh
@@ -65,4 +65,48 @@ Time operator-(const Time &l, const Time &r);
std::ostream &operator<<(std::ostream &out, const Time &time);
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)time.h 8.2 (Berkeley) 7/10/94
+ */
+
+#if defined(__sun__)
+#define timersub(tvp, uvp, vvp) \
+ do { \
+ (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
+ (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
+ if ((vvp)->tv_usec < 0) { \
+ (vvp)->tv_sec--; \
+ (vvp)->tv_usec += 1000000; \
+ } \
+ } while (0)
+#endif
+
#endif // __SIM_TIME_HH__
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index ea4b03bf2..4c243a2e9 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -168,11 +168,6 @@ BaseCPU::BaseCPU(Params *p)
p->max_loads_all_threads, *counter);
}
-#if FULL_SYSTEM
- memset(interrupts, 0, sizeof(interrupts));
- intstatus = 0;
-#endif
-
functionTracingEnabled = false;
if (p->functionTrace) {
functionTraceStream = simout.find(csprintf("ftrace.%s", name()));
@@ -259,6 +254,26 @@ BaseCPU::regStats()
#endif
}
+Tick
+BaseCPU::nextCycle()
+{
+ Tick next_tick = curTick + clock - 1;
+ next_tick -= (next_tick % clock);
+ return next_tick;
+}
+
+Tick
+BaseCPU::nextCycle(Tick begin_tick)
+{
+ Tick next_tick = begin_tick;
+
+ while (next_tick < curTick)
+ next_tick += clock;
+
+ next_tick -= (next_tick % clock);
+ assert(next_tick >= curTick);
+ return next_tick;
+}
void
BaseCPU::registerThreadContexts()
@@ -314,9 +329,7 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
}
#if FULL_SYSTEM
- for (int i = 0; i < TheISA::NumInterruptLevels; ++i)
- interrupts[i] = oldCPU->interrupts[i];
- intstatus = oldCPU->intstatus;
+ interrupts = oldCPU->interrupts;
checkInterrupts = oldCPU->checkInterrupts;
for (int i = 0; i < threadContexts.size(); ++i)
@@ -348,57 +361,33 @@ BaseCPU::ProfileEvent::process()
void
BaseCPU::post_interrupt(int int_num, int index)
{
- DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
-
- if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
- panic("int_num out of bounds\n");
-
- if (index < 0 || index >= sizeof(uint64_t) * 8)
- panic("int_num out of bounds\n");
-
checkInterrupts = true;
- interrupts[int_num] |= 1 << index;
- intstatus |= (ULL(1) << int_num);
+ interrupts.post(int_num, index);
}
void
BaseCPU::clear_interrupt(int int_num, int index)
{
- DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
-
- if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
- panic("int_num out of bounds\n");
-
- if (index < 0 || index >= sizeof(uint64_t) * 8)
- panic("int_num out of bounds\n");
-
- interrupts[int_num] &= ~(1 << index);
- if (interrupts[int_num] == 0)
- intstatus &= ~(ULL(1) << int_num);
+ interrupts.clear(int_num, index);
}
void
BaseCPU::clear_interrupts()
{
- DPRINTF(Interrupt, "Interrupts all cleared\n");
-
- memset(interrupts, 0, sizeof(interrupts));
- intstatus = 0;
+ interrupts.clear_all();
}
void
BaseCPU::serialize(std::ostream &os)
{
- SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
- SERIALIZE_SCALAR(intstatus);
+ interrupts.serialize(os);
}
void
BaseCPU::unserialize(Checkpoint *cp, const std::string &section)
{
- UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
- UNSERIALIZE_SCALAR(intstatus);
+ interrupts.unserialize(cp, section);
}
#endif // FULL_SYSTEM
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index 75e0d86af..9257778ef 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -40,6 +40,10 @@
#include "mem/mem_object.hh"
#include "arch/isa_traits.hh"
+#if FULL_SYSTEM
+#include "arch/interrupts.hh"
+#endif
+
class BranchPred;
class CheckerCPU;
class ThreadContext;
@@ -73,10 +77,25 @@ class BaseCPU : public MemObject
inline Tick cycles(int numCycles) const { return clock * numCycles; }
inline Tick curCycle() const { return curTick / clock; }
+ /** The next cycle the CPU should be scheduled, given a cache
+ * access or quiesce event returning on this cycle. This function
+ * may return curTick if the CPU should run on the current cycle.
+ */
+ Tick nextCycle();
+
+ /** The next cycle the CPU should be scheduled, given a cache
+ * access or quiesce event returning on the given Tick. This
+ * function may return curTick if the CPU should run on the
+ * current cycle.
+ * @param begin_tick The tick that the event is completing on.
+ */
+ Tick nextCycle(Tick begin_tick);
+
#if FULL_SYSTEM
protected:
- uint64_t interrupts[TheISA::NumInterruptLevels];
- uint64_t intstatus;
+// uint64_t interrupts[TheISA::NumInterruptLevels];
+// uint64_t intstatus;
+ TheISA::Interrupts interrupts;
public:
virtual void post_interrupt(int int_num, int index);
@@ -84,15 +103,8 @@ class BaseCPU : public MemObject
virtual void clear_interrupts();
bool checkInterrupts;
- bool check_interrupt(int int_num) const {
- if (int_num > TheISA::NumInterruptLevels)
- panic("int_num out of bounds\n");
-
- return interrupts[int_num] != 0;
- }
-
- bool check_interrupts() const { return intstatus != 0; }
- uint64_t intr_status() const { return intstatus; }
+ bool check_interrupts(ThreadContext * tc) const
+ { return interrupts.check_interrupts(tc); }
class ProfileEvent : public Event
{
diff --git a/src/cpu/checker/cpu.cc b/src/cpu/checker/cpu.cc
index 9cb6b032e..d6cd9409b 100644
--- a/src/cpu/checker/cpu.cc
+++ b/src/cpu/checker/cpu.cc
@@ -38,8 +38,8 @@
#include "cpu/thread_context.hh"
#if FULL_SYSTEM
+#include "arch/kernel_stats.hh"
#include "arch/vtophys.hh"
-#include "kern/kernel_stats.hh"
#endif // FULL_SYSTEM
using namespace std;
@@ -72,6 +72,12 @@ CheckerCPU::CheckerCPU(Params *p)
systemPtr = NULL;
#else
process = p->process;
+ thread = new SimpleThread(this, /* thread_num */ 0, process,
+ /* asid */ 0);
+
+ thread->setStatus(ThreadContext::Suspended);
+ tc = thread->getTC();
+ threadContexts.push_back(tc);
#endif
result.integer = 0;
@@ -82,20 +88,6 @@ CheckerCPU::~CheckerCPU()
}
void
-CheckerCPU::setMemory(MemObject *mem)
-{
-#if !FULL_SYSTEM
- memPtr = mem;
- thread = new SimpleThread(this, /* thread_num */ 0, process,
- /* asid */ 0, mem);
-
- thread->setStatus(ThreadContext::Suspended);
- tc = thread->getTC();
- threadContexts.push_back(tc);
-#endif
-}
-
-void
CheckerCPU::setSystem(System *system)
{
#if FULL_SYSTEM
diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh
index 00b01171f..9be54529f 100644
--- a/src/cpu/checker/cpu.hh
+++ b/src/cpu/checker/cpu.hh
@@ -47,9 +47,12 @@
// forward declarations
#if FULL_SYSTEM
+namespace TheISA
+{
+ class ITB;
+ class DTB;
+}
class Processor;
-class AlphaITB;
-class AlphaDTB;
class PhysicalMemory;
class RemoteGDB;
@@ -96,8 +99,8 @@ class CheckerCPU : public BaseCPU
struct Params : public BaseCPU::Params
{
#if FULL_SYSTEM
- AlphaITB *itb;
- AlphaDTB *dtb;
+ TheISA::ITB *itb;
+ TheISA::DTB *dtb;
#else
Process *process;
#endif
@@ -112,10 +115,6 @@ class CheckerCPU : public BaseCPU
Process *process;
- void setMemory(MemObject *mem);
-
- MemObject *memPtr;
-
void setSystem(System *system);
System *systemPtr;
@@ -140,8 +139,8 @@ class CheckerCPU : public BaseCPU
ThreadContext *tc;
- AlphaITB *itb;
- AlphaDTB *dtb;
+ TheISA::ITB *itb;
+ TheISA::DTB *dtb;
#if FULL_SYSTEM
Addr dbg_vtophys(Addr addr);
@@ -301,19 +300,19 @@ class CheckerCPU : public BaseCPU
return thread->readMiscReg(misc_reg);
}
- MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
+ MiscReg readMiscRegWithEffect(int misc_reg)
{
- return thread->readMiscRegWithEffect(misc_reg, fault);
+ return thread->readMiscRegWithEffect(misc_reg);
}
- Fault setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{
result.integer = val;
miscRegIdxs.push(misc_reg);
return thread->setMiscReg(misc_reg, val);
}
- Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{
miscRegIdxs.push(misc_reg);
return thread->setMiscRegWithEffect(misc_reg, val);
@@ -328,9 +327,6 @@ class CheckerCPU : public BaseCPU
#if FULL_SYSTEM
Fault hwrei() { return thread->hwrei(); }
- int readIntrFlag() { return thread->readIntrFlag(); }
- void setIntrFlag(int val) { thread->setIntrFlag(val); }
- bool inPalMode() { return thread->inPalMode(); }
void ev5_trap(Fault fault) { fault->invoke(tc); }
bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
#else
diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh
index 36c7349e6..56e13dd1e 100644
--- a/src/cpu/checker/cpu_impl.hh
+++ b/src/cpu/checker/cpu_impl.hh
@@ -199,8 +199,13 @@ Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
// Checks both the machine instruction and the PC.
validateInst(inst);
+#if THE_ISA == ALPHA_ISA
+ curStaticInst = StaticInst::decode(makeExtMI(machInst,
+ thread->readPC()));
+#elif THE_ISA == SPARC_ISA
curStaticInst = StaticInst::decode(makeExtMI(machInst,
thread->getTC()));
+#endif
#if FULL_SYSTEM
thread->setInst(machInst);
diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh
index b2806d40b..cf36d8392 100644
--- a/src/cpu/checker/thread_context.hh
+++ b/src/cpu/checker/thread_context.hh
@@ -37,8 +37,10 @@
#include "cpu/thread_context.hh"
class EndQuiesceEvent;
-namespace Kernel {
- class Statistics;
+namespace TheISA {
+ namespace Kernel {
+ class Statistics;
+ };
};
/**
@@ -87,11 +89,12 @@ class CheckerThreadContext : public ThreadContext
PhysicalMemory *getPhysMemPtr() { return actualTC->getPhysMemPtr(); }
- AlphaITB *getITBPtr() { return actualTC->getITBPtr(); }
+ TheISA::ITB *getITBPtr() { return actualTC->getITBPtr(); }
- AlphaDTB *getDTBPtr() { return actualTC->getDTBPtr(); }
+ TheISA::DTB *getDTBPtr() { return actualTC->getDTBPtr(); }
- Kernel::Statistics *getKernelStats() { return actualTC->getKernelStats(); }
+ TheISA::Kernel::Statistics *getKernelStats()
+ { return actualTC->getKernelStats(); }
FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); }
@@ -248,19 +251,19 @@ class CheckerThreadContext : public ThreadContext
MiscReg readMiscReg(int misc_reg)
{ return actualTC->readMiscReg(misc_reg); }
- MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
- { return actualTC->readMiscRegWithEffect(misc_reg, fault); }
+ MiscReg readMiscRegWithEffect(int misc_reg)
+ { return actualTC->readMiscRegWithEffect(misc_reg); }
- Fault setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{
checkerTC->setMiscReg(misc_reg, val);
- return actualTC->setMiscReg(misc_reg, val);
+ actualTC->setMiscReg(misc_reg, val);
}
- Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{
checkerTC->setMiscRegWithEffect(misc_reg, val);
- return actualTC->setMiscRegWithEffect(misc_reg, val);
+ actualTC->setMiscRegWithEffect(misc_reg, val);
}
unsigned readStCondFailures()
@@ -271,9 +274,6 @@ class CheckerThreadContext : public ThreadContext
checkerTC->setStCondFailures(sc_failures);
actualTC->setStCondFailures(sc_failures);
}
-#if FULL_SYSTEM
- bool inPalMode() { return actualTC->inPalMode(); }
-#endif
// @todo: Fix this!
bool misspeculating() { return actualTC->misspeculating(); }
diff --git a/src/cpu/cpuevent.hh b/src/cpu/cpuevent.hh
index 9dfae27cf..3339f8252 100644
--- a/src/cpu/cpuevent.hh
+++ b/src/cpu/cpuevent.hh
@@ -44,7 +44,7 @@ class ThreadContext;
* */
class CpuEvent : public Event
{
- private:
+ protected:
/** type of global list of cpu events. */
typedef std::vector<CpuEvent *> CpuEventList;
diff --git a/src/cpu/exec_context.hh b/src/cpu/exec_context.hh
index f6e8d7c25..13f70fa79 100644
--- a/src/cpu/exec_context.hh
+++ b/src/cpu/exec_context.hh
@@ -101,14 +101,14 @@ class ExecContext {
/** Reads a miscellaneous register, handling any architectural
* side effects due to reading that register. */
- MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault);
+ MiscReg readMiscRegWithEffect(int misc_reg);
/** Sets a miscellaneous register. */
- Fault setMiscReg(int misc_reg, const MiscReg &val);
+ void setMiscReg(int misc_reg, const MiscReg &val);
/** Sets a miscellaneous register, handling any architectural
* side effects due to writing that register. */
- Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val);
+ void setMiscRegWithEffect(int misc_reg, const MiscReg &val);
/** Records the effective address of the instruction. Only valid
* for memory ops. */
@@ -144,10 +144,6 @@ class ExecContext {
/** Somewhat Alpha-specific function that handles returning from
* an error or interrupt. */
Fault hwrei();
- /** Reads the interrupt flags. */
- int readIntrFlag();
- /** Sets the interrupt flags to a value. */
- void setIntrFlag(int val);
/**
* Check for special simulator handling of specific PAL calls. If
diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc
index 9d85311bb..ef06e0699 100644
--- a/src/cpu/exetrace.cc
+++ b/src/cpu/exetrace.cc
@@ -33,8 +33,11 @@
#include <fstream>
#include <iomanip>
+#include <sys/ipc.h>
+#include <sys/shm.h>
#include "arch/regfile.hh"
+#include "arch/utility.hh"
#include "base/loader/symtab.hh"
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
@@ -44,10 +47,15 @@
//XXX This is temporary
#include "arch/isa_specific.hh"
+#include "cpu/m5legion_interface.h"
using namespace std;
using namespace TheISA;
+namespace Trace {
+SharedData *shared_data = NULL;
+}
+
////////////////////////////////////////////////////////////////////////
//
// Methods for the InstRecord object
@@ -75,23 +83,19 @@ Trace::InstRecord::dump(ostream &outs)
uint64_t newVal;
static const char * prefixes[4] = {"G", "O", "L", "I"};
- char buf[256];
- sprintf(buf, "PC = 0x%016llx", thread->readNextPC());
- outs << buf;
- sprintf(buf, " NPC = 0x%016llx", thread->readNextNPC());
- outs << buf;
+ outs << hex;
+ outs << "PC = " << thread->readNextPC();
+ outs << " NPC = " << thread->readNextNPC();
newVal = thread->readMiscReg(SparcISA::MISCREG_CCR);
if(newVal != ccr)
{
- sprintf(buf, " CCR = 0x%016llx", newVal);
- outs << buf;
+ outs << " CCR = " << newVal;
ccr = newVal;
}
newVal = thread->readMiscReg(SparcISA::MISCREG_Y);
if(newVal != y)
{
- sprintf(buf, " Y = 0x%016llx", newVal);
- outs << buf;
+ outs << " Y = " << newVal;
y = newVal;
}
for(int y = 0; y < 4; y++)
@@ -102,8 +106,7 @@ Trace::InstRecord::dump(ostream &outs)
newVal = thread->readIntReg(index);
if(regs[index] != newVal)
{
- sprintf(buf, " %s%d = 0x%016llx", prefixes[y], x, newVal);
- outs << buf;
+ outs << " " << prefixes[y] << dec << x << " = " << hex << newVal;
regs[index] = newVal;
}
}
@@ -113,12 +116,11 @@ Trace::InstRecord::dump(ostream &outs)
newVal = thread->readFloatRegBits(2 * y, 64);
if(floats[y] != newVal)
{
- sprintf(buf, " F%d = 0x%016llx", 2 * y, newVal);
- outs << buf;
+ outs << " F" << dec << (2 * y) << " = " << hex << newVal;
floats[y] = newVal;
}
}
- outs << endl;
+ outs << dec << endl;
}
#endif
}
@@ -222,6 +224,85 @@ Trace::InstRecord::dump(ostream &outs)
//
outs << endl;
}
+#if THE_ISA == SPARC_ISA
+ // Compare
+ if (flags[LEGION_LOCKSTEP])
+ {
+ bool compared = false;
+ bool diffPC = false;
+ bool diffInst = false;
+ bool diffRegs = false;
+
+ if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) {
+ while (!compared) {
+ if (shared_data->flags == OWN_M5) {
+ if (shared_data->pc != PC)
+ diffPC = true;
+ if (shared_data->instruction != staticInst->machInst)
+ diffInst = true;
+ for (int i = 0; i < TheISA::NumIntRegs; i++) {
+ if (thread->readIntReg(i) != shared_data->intregs[i])
+ diffRegs = true;
+ }
+
+ if (diffPC || diffInst || diffRegs ) {
+ outs << "Differences found between M5 and Legion:";
+ if (diffPC)
+ outs << " [PC]";
+ if (diffInst)
+ outs << " [Instruction]";
+ if (diffRegs)
+ outs << " [IntRegs]";
+ outs << endl << endl;;
+
+ outs << setfill(' ') << setw(15)
+ << "M5 PC: " << "0x"<< setw(16) << setfill('0')
+ << hex << PC << endl;
+ outs << setfill(' ') << setw(15)
+ << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex
+ << shared_data->pc << endl << endl;
+
+ outs << setfill(' ') << setw(15)
+ << "M5 Inst: " << "0x"<< setw(8)
+ << setfill('0') << hex << staticInst->machInst
+ << staticInst->disassemble(PC, debugSymbolTable)
+ << endl;
+
+ StaticInstPtr legionInst = StaticInst::decode(makeExtMI(shared_data->instruction, thread));
+ outs << setfill(' ') << setw(15)
+ << " Legion Inst: "
+ << "0x" << setw(8) << setfill('0') << hex
+ << shared_data->instruction
+ << legionInst->disassemble(shared_data->pc, debugSymbolTable)
+ << endl;
+
+ outs << endl;
+
+ static const char * regtypes[4] = {"%g", "%o", "%l", "%i"};
+ for(int y = 0; y < 4; y++)
+ {
+ for(int x = 0; x < 8; x++)
+ {
+ outs << regtypes[y] << x << " " ;
+ outs << "0x" << hex << setw(16) << thread->readIntReg(y*8+x);
+ if (thread->readIntReg(y*8 + x) != shared_data->intregs[y*8+x])
+ outs << " X ";
+ else
+ outs << " | ";
+ outs << "0x" << setw(16) << hex << shared_data->intregs[y*8+x]
+ << endl;
+ }
+ }
+ fatal("Differences found between Legion and M5\n");
+ }
+
+ compared = true;
+ shared_data->flags = OWN_LEGION;
+ }
+ } // while
+ } // if not microop
+ }
+#endif
}
@@ -271,6 +352,9 @@ Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol",
"Use symbols for the PC if available", true);
Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format",
"print trace in intel compatible format", false);
+Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep",
+ "Compare sim state to legion state every cycle",
+ false);
Param<string> exe_trace_system(&exeTraceParams, "trace_system",
"print trace of which system (client or server)",
"client");
@@ -296,7 +380,28 @@ Trace::InstRecord::setParams()
flags[PRINT_REG_DELTA] = exe_trace_print_reg_delta;
flags[PC_SYMBOL] = exe_trace_pc_symbol;
flags[INTEL_FORMAT] = exe_trace_intel_format;
+ flags[LEGION_LOCKSTEP] = exe_trace_legion_lockstep;
trace_system = exe_trace_system;
+
+ // If were going to be in lockstep with Legion
+ // Setup shared memory, and get otherwise ready
+ if (flags[LEGION_LOCKSTEP]) {
+ int shmfd = shmget(getuid(), sizeof(SharedData), 0777);
+ if (shmfd < 0)
+ fatal("Couldn't get shared memory fd. Is Legion running?");
+
+ shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND);
+ if (shared_data == (SharedData*)-1)
+ fatal("Couldn't allocate shared memory");
+
+ if (shared_data->flags != OWN_M5)
+ fatal("Shared memory has invalid owner");
+
+ if (shared_data->version != VERSION)
+ fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION,
+ shared_data->version);
+
+ }
}
void
diff --git a/src/cpu/exetrace.hh b/src/cpu/exetrace.hh
index 02ea162f0..6562e5265 100644
--- a/src/cpu/exetrace.hh
+++ b/src/cpu/exetrace.hh
@@ -150,6 +150,7 @@ class InstRecord : public Record
PRINT_REG_DELTA,
PC_SYMBOL,
INTEL_FORMAT,
+ LEGION_LOCKSTEP,
NUM_BITS
};
diff --git a/src/cpu/inst_seq.hh b/src/cpu/inst_seq.hh
index e7acd215f..21e04ed25 100644
--- a/src/cpu/inst_seq.hh
+++ b/src/cpu/inst_seq.hh
@@ -32,8 +32,6 @@
#ifndef __STD_TYPES_HH__
#define __STD_TYPES_HH__
-#include <stdint.h>
-
// inst sequence type, used to order instructions in the ready list,
// if this rolls over the ready list order temporarily will get messed
// up, but execution will continue and complete correctly
diff --git a/src/cpu/m5legion_interface.h b/src/cpu/m5legion_interface.h
new file mode 100644
index 000000000..9338d9ca0
--- /dev/null
+++ b/src/cpu/m5legion_interface.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ */
+
+#include <unistd.h>
+
+#define VERSION 0xA1000002
+#define OWN_M5 0x000000AA
+#define OWN_LEGION 0x00000055
+
+/** !!! VVV Increment VERSION on change VVV !!! **/
+
+typedef struct {
+ uint32_t flags;
+ uint32_t version;
+
+ uint64_t pc;
+ uint32_t instruction;
+ uint64_t intregs[32];
+
+} SharedData;
+
+/** !!! ^^^ Increment VERSION on change ^^^ !!! **/
+
diff --git a/src/cpu/memtest/memtest.hh b/src/cpu/memtest/memtest.hh
index edde4a3b2..2694efd39 100644
--- a/src/cpu/memtest/memtest.hh
+++ b/src/cpu/memtest/memtest.hh
@@ -97,7 +97,7 @@ class MemTest : public MemObject
public:
CpuPort(const std::string &_name, MemTest *_memtest)
- : Port(_name), memtest(_memtest)
+ : Port(_name, _memtest), memtest(_memtest)
{ }
protected:
diff --git a/src/cpu/o3/alpha/cpu.hh b/src/cpu/o3/alpha/cpu.hh
index 9d97f9701..b62550062 100644
--- a/src/cpu/o3/alpha/cpu.hh
+++ b/src/cpu/o3/alpha/cpu.hh
@@ -37,6 +37,12 @@
#include "cpu/o3/cpu.hh"
#include "sim/byteswap.hh"
+namespace TheISA
+{
+ class ITB;
+ class DTB;
+}
+
class EndQuiesceEvent;
namespace Kernel {
class Statistics;
@@ -73,9 +79,9 @@ class AlphaO3CPU : public FullO3CPU<Impl>
#if FULL_SYSTEM
/** ITB pointer. */
- AlphaITB *itb;
+ AlphaISA::ITB *itb;
/** DTB pointer. */
- AlphaDTB *dtb;
+ AlphaISA::DTB *dtb;
#endif
/** Registers statistics. */
@@ -126,15 +132,15 @@ class AlphaO3CPU : public FullO3CPU<Impl>
/** Reads a misc. register, including any side effects the read
* might have as defined by the architecture.
*/
- MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault, unsigned tid);
+ MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid);
/** Sets a miscellaneous register. */
- Fault setMiscReg(int misc_reg, const MiscReg &val, unsigned tid);
+ void setMiscReg(int misc_reg, const MiscReg &val, unsigned tid);
/** Sets a misc. register, including any side effects the write
* might have as defined by the architecture.
*/
- Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val, unsigned tid);
+ void setMiscRegWithEffect(int misc_reg, const MiscReg &val, unsigned tid);
/** Initiates a squash of all in-flight instructions for a given
* thread. The source of the squash is an external update of
@@ -145,15 +151,8 @@ class AlphaO3CPU : public FullO3CPU<Impl>
#if FULL_SYSTEM
/** Posts an interrupt. */
void post_interrupt(int int_num, int index);
- /** Reads the interrupt flag. */
- int readIntrFlag();
- /** Sets the interrupt flags. */
- void setIntrFlag(int val);
/** HW return from error interrupt. */
Fault hwrei(unsigned tid);
- /** Returns if a specific PC is a PAL mode PC. */
- bool inPalMode(uint64_t PC)
- { return AlphaISA::PcPAL(PC); }
bool simPalCheck(int palFunc, unsigned tid);
diff --git a/src/cpu/o3/alpha/cpu_builder.cc b/src/cpu/o3/alpha/cpu_builder.cc
index ff123a6f7..be8ad8de6 100644
--- a/src/cpu/o3/alpha/cpu_builder.cc
+++ b/src/cpu/o3/alpha/cpu_builder.cc
@@ -54,15 +54,13 @@ Param<int> activity;
#if FULL_SYSTEM
SimObjectParam<System *> system;
Param<int> cpu_id;
-SimObjectParam<AlphaITB *> itb;
-SimObjectParam<AlphaDTB *> dtb;
+SimObjectParam<AlphaISA::ITB *> itb;
+SimObjectParam<AlphaISA::DTB *> dtb;
Param<Tick> profile;
#else
SimObjectVectorParam<Process *> workload;
#endif // FULL_SYSTEM
-SimObjectParam<MemObject *> mem;
-
SimObjectParam<BaseCPU *> checker;
Param<Counter> max_insts_any_thread;
@@ -169,8 +167,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivO3CPU)
INIT_PARAM(workload, "Processes to run"),
#endif // FULL_SYSTEM
- INIT_PARAM(mem, "Memory"),
-
INIT_PARAM_DFLT(checker, "Checker CPU", NULL),
INIT_PARAM_DFLT(max_insts_any_thread,
@@ -314,8 +310,6 @@ CREATE_SIM_OBJECT(DerivO3CPU)
params->workload = workload;
#endif // FULL_SYSTEM
- params->mem = mem;
-
params->checker = checker;
params->max_insts_any_thread = max_insts_any_thread;
diff --git a/src/cpu/o3/alpha/cpu_impl.hh b/src/cpu/o3/alpha/cpu_impl.hh
index 8c3d7ee32..618716fc6 100644
--- a/src/cpu/o3/alpha/cpu_impl.hh
+++ b/src/cpu/o3/alpha/cpu_impl.hh
@@ -48,8 +48,8 @@
#if FULL_SYSTEM
#include "arch/alpha/osfpal.hh"
#include "arch/isa_traits.hh"
+#include "arch/kernel_stats.hh"
#include "cpu/quiesce_event.hh"
-#include "kern/kernel_stats.hh"
#include "sim/sim_exit.hh"
#include "sim/system.hh"
#endif
@@ -77,24 +77,10 @@ AlphaO3CPU<Impl>::AlphaO3CPU(Params *params)
if (i < params->workload.size()) {
DPRINTF(O3CPU, "Workload[%i] process is %#x",
i, this->thread[i]);
- this->thread[i] = new Thread(this, i, params->workload[i],
- i, params->mem);
+ this->thread[i] = new Thread(this, i, params->workload[i], i);
this->thread[i]->setStatus(ThreadContext::Suspended);
-#if !FULL_SYSTEM
- /* Use this port to for syscall emulation writes to memory. */
- Port *mem_port;
- TranslatingPort *trans_port;
- trans_port = new TranslatingPort(csprintf("%s-%d-funcport",
- name(), i),
- params->workload[i]->pTable,
- false);
- mem_port = params->mem->getPort("functional");
- mem_port->setPeer(trans_port);
- trans_port->setPeer(mem_port);
- this->thread[i]->setMemPort(trans_port);
-#endif
//usedTids[i] = true;
//threadMap[i] = i;
} else {
@@ -102,7 +88,7 @@ AlphaO3CPU<Impl>::AlphaO3CPU(Params *params)
//when scheduling threads to CPU
Process* dummy_proc = NULL;
- this->thread[i] = new Thread(this, i, dummy_proc, i, params->mem);
+ this->thread[i] = new Thread(this, i, dummy_proc, i);
//usedTids[i] = false;
}
#endif // !FULL_SYSTEM
@@ -198,25 +184,24 @@ AlphaO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
template <class Impl>
TheISA::MiscReg
-AlphaO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, Fault &fault,
- unsigned tid)
+AlphaO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, unsigned tid)
{
- return this->regFile.readMiscRegWithEffect(misc_reg, fault, tid);
+ return this->regFile.readMiscRegWithEffect(misc_reg, tid);
}
template <class Impl>
-Fault
+void
AlphaO3CPU<Impl>::setMiscReg(int misc_reg, const MiscReg &val, unsigned tid)
{
- return this->regFile.setMiscReg(misc_reg, val, tid);
+ this->regFile.setMiscReg(misc_reg, val, tid);
}
template <class Impl>
-Fault
+void
AlphaO3CPU<Impl>::setMiscRegWithEffect(int misc_reg, const MiscReg &val,
unsigned tid)
{
- return this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
+ this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
}
template <class Impl>
@@ -242,20 +227,6 @@ AlphaO3CPU<Impl>::post_interrupt(int int_num, int index)
}
template <class Impl>
-int
-AlphaO3CPU<Impl>::readIntrFlag()
-{
- return this->regFile.readIntrFlag();
-}
-
-template <class Impl>
-void
-AlphaO3CPU<Impl>::setIntrFlag(int val)
-{
- this->regFile.setIntrFlag(val);
-}
-
-template <class Impl>
Fault
AlphaO3CPU<Impl>::hwrei(unsigned tid)
{
@@ -299,7 +270,6 @@ template <class Impl>
void
AlphaO3CPU<Impl>::processInterrupts()
{
- using namespace TheISA;
// Check for interrupts here. For now can copy the code that
// exists within isa_fullsys_traits.hh. Also assume that thread 0
// is the one that handles the interrupts.
@@ -308,51 +278,11 @@ AlphaO3CPU<Impl>::processInterrupts()
// Check if there are any outstanding interrupts
//Handle the interrupts
- int ipl = 0;
- int summary = 0;
-
- this->checkInterrupts = false;
-
- if (this->readMiscReg(IPR_ASTRR, 0))
- panic("asynchronous traps not implemented\n");
-
- if (this->readMiscReg(IPR_SIRR, 0)) {
- for (int i = INTLEVEL_SOFTWARE_MIN;
- i < INTLEVEL_SOFTWARE_MAX; i++) {
- if (this->readMiscReg(IPR_SIRR, 0) & (ULL(1) << i)) {
- // See table 4-19 of the 21164 hardware reference
- ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
- summary |= (ULL(1) << i);
- }
- }
- }
-
- uint64_t interrupts = this->intr_status();
+ Fault interrupt = this->interrupts.getInterrupt(this->tcBase(0));
- if (interrupts) {
- for (int i = INTLEVEL_EXTERNAL_MIN;
- i < INTLEVEL_EXTERNAL_MAX; i++) {
- if (interrupts & (ULL(1) << i)) {
- // See table 4-19 of the 21164 hardware reference
- ipl = i;
- summary |= (ULL(1) << i);
- }
- }
- }
-
- if (ipl && ipl > this->readMiscReg(IPR_IPLR, 0)) {
- this->setMiscReg(IPR_ISR, summary, 0);
- this->setMiscReg(IPR_INTID, ipl, 0);
- // Checker needs to know these two registers were updated.
-#if USE_CHECKER
- if (this->checker) {
- this->checker->threadBase()->setMiscReg(IPR_ISR, summary);
- this->checker->threadBase()->setMiscReg(IPR_INTID, ipl);
- }
-#endif
- this->trap(Fault(new InterruptFault), 0);
- DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
- this->readMiscReg(IPR_IPLR, 0), ipl, summary);
+ if (interrupt != NoFault) {
+ this->checkInterrupts = false;
+ this->trap(interrupt, 0);
}
}
diff --git a/src/cpu/o3/alpha/dyn_inst.hh b/src/cpu/o3/alpha/dyn_inst.hh
index 294aadde8..31df8ff78 100644
--- a/src/cpu/o3/alpha/dyn_inst.hh
+++ b/src/cpu/o3/alpha/dyn_inst.hh
@@ -102,14 +102,13 @@ class AlphaDynInst : public BaseDynInst<Impl>
/** Reads a misc. register, including any side-effects the read
* might have as defined by the architecture.
*/
- MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
+ MiscReg readMiscRegWithEffect(int misc_reg)
{
- return this->cpu->readMiscRegWithEffect(misc_reg, fault,
- this->threadNumber);
+ return this->cpu->readMiscRegWithEffect(misc_reg, this->threadNumber);
}
/** Sets a misc. register. */
- Fault setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{
this->instResult.integer = val;
return this->cpu->setMiscReg(misc_reg, val, this->threadNumber);
@@ -118,7 +117,7 @@ class AlphaDynInst : public BaseDynInst<Impl>
/** Sets a misc. register, including any side-effects the write
* might have as defined by the architecture.
*/
- Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{
return this->cpu->setMiscRegWithEffect(misc_reg, val,
this->threadNumber);
@@ -127,12 +126,6 @@ class AlphaDynInst : public BaseDynInst<Impl>
#if FULL_SYSTEM
/** Calls hardware return from error interrupt. */
Fault hwrei();
- /** Reads interrupt flag. */
- int readIntrFlag();
- /** Sets interrupt flag. */
- void setIntrFlag(int val);
- /** Checks if system is in PAL mode. */
- bool inPalMode();
/** Traps to handle specified fault. */
void trap(Fault fault);
bool simPalCheck(int palFunc);
diff --git a/src/cpu/o3/alpha/dyn_inst_impl.hh b/src/cpu/o3/alpha/dyn_inst_impl.hh
index b273a7b9b..6fc548a85 100644
--- a/src/cpu/o3/alpha/dyn_inst_impl.hh
+++ b/src/cpu/o3/alpha/dyn_inst_impl.hh
@@ -113,7 +113,7 @@ Fault
AlphaDynInst<Impl>::hwrei()
{
// Can only do a hwrei when in pal mode.
- if (!this->cpu->inPalMode(this->readPC()))
+ if (!(this->readPC() & 0x3))
return new AlphaISA::UnimplementedOpcodeFault;
// Set the next PC based on the value of the EXC_ADDR IPR.
@@ -128,27 +128,6 @@ AlphaDynInst<Impl>::hwrei()
}
template <class Impl>
-int
-AlphaDynInst<Impl>::readIntrFlag()
-{
- return this->cpu->readIntrFlag();
-}
-
-template <class Impl>
-void
-AlphaDynInst<Impl>::setIntrFlag(int val)
-{
- this->cpu->setIntrFlag(val);
-}
-
-template <class Impl>
-bool
-AlphaDynInst<Impl>::inPalMode()
-{
- return this->cpu->inPalMode(this->PC);
-}
-
-template <class Impl>
void
AlphaDynInst<Impl>::trap(Fault fault)
{
diff --git a/src/cpu/o3/alpha/params.hh b/src/cpu/o3/alpha/params.hh
index c618cee08..b6b84b2a1 100644
--- a/src/cpu/o3/alpha/params.hh
+++ b/src/cpu/o3/alpha/params.hh
@@ -35,8 +35,11 @@
#include "cpu/o3/params.hh"
//Forward declarations
-class AlphaDTB;
-class AlphaITB;
+namespace AlphaISA
+{
+ class DTB;
+ class ITB;
+}
class MemObject;
class Process;
class System;
@@ -52,8 +55,8 @@ class AlphaSimpleParams : public O3Params
public:
#if FULL_SYSTEM
- AlphaITB *itb;
- AlphaDTB *dtb;
+ AlphaISA::ITB *itb;
+ AlphaISA::DTB *dtb;
#endif
};
diff --git a/src/cpu/o3/alpha/thread_context.hh b/src/cpu/o3/alpha/thread_context.hh
index 70a09940f..bcecb7087 100644
--- a/src/cpu/o3/alpha/thread_context.hh
+++ b/src/cpu/o3/alpha/thread_context.hh
@@ -37,21 +37,16 @@ class AlphaTC : public O3ThreadContext<Impl>
public:
#if FULL_SYSTEM
/** Returns a pointer to the ITB. */
- virtual AlphaITB *getITBPtr() { return this->cpu->itb; }
+ virtual AlphaISA::ITB *getITBPtr() { return this->cpu->itb; }
/** Returns a pointer to the DTB. */
- virtual AlphaDTB *getDTBPtr() { return this->cpu->dtb; }
+ virtual AlphaISA::DTB *getDTBPtr() { return this->cpu->dtb; }
/** Returns pointer to the quiesce event. */
virtual EndQuiesceEvent *getQuiesceEvent()
{
return this->thread->quiesceEvent;
}
-
- /** Returns if the thread is currently in PAL mode, based on
- * the PC's value. */
- virtual bool inPalMode()
- { return TheISA::PcPAL(this->cpu->readPC(this->thread->readTid())); }
#endif
virtual uint64_t readNextNPC()
diff --git a/src/cpu/o3/checker_builder.cc b/src/cpu/o3/checker_builder.cc
index 02c817499..8b028e3a0 100644
--- a/src/cpu/o3/checker_builder.cc
+++ b/src/cpu/o3/checker_builder.cc
@@ -67,8 +67,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(O3Checker)
Param<Tick> progress_interval;
#if FULL_SYSTEM
- SimObjectParam<AlphaITB *> itb;
- SimObjectParam<AlphaDTB *> dtb;
+ SimObjectParam<TheISA::ITB *> itb;
+ SimObjectParam<TheISA::DTB *> dtb;
SimObjectParam<System *> system;
Param<int> cpu_id;
Param<Tick> profile;
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index ecf6ed632..30052a148 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -35,6 +35,7 @@
#include <algorithm>
#include <string>
+#include "arch/utility.hh"
#include "base/loader/symtab.hh"
#include "base/timebuf.hh"
#include "cpu/exetrace.hh"
@@ -638,8 +639,7 @@ DefaultCommit<Impl>::commit()
// and no other traps or external squashes are currently pending.
// @todo: Allow other threads to handle interrupts.
if (cpu->checkInterrupts &&
- cpu->check_interrupts() &&
- !cpu->inPalMode(readPC()) &&
+ cpu->check_interrupts(cpu->tcBase(0)) &&
!trapSquash[0] &&
!tcSquash[0]) {
// Tell fetch that there is an interrupt pending. This will
@@ -1085,8 +1085,7 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
#if FULL_SYSTEM
if (thread[tid]->profile) {
-// bool usermode =
-// (cpu->readMiscReg(AlphaISA::IPR_DTB_CM, tid) & 0x18) != 0;
+// bool usermode = TheISA::inUserMode(thread[tid]->getTC());
// thread[tid]->profilePC = usermode ? 1 : head_inst->readPC();
thread[tid]->profilePC = head_inst->readPC();
ProfileNode *node = thread[tid]->profile->consume(thread[tid]->getTC(),
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index 367508288..dfe42d882 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -187,7 +187,6 @@ FullO3CPU<Impl>::FullO3CPU(Params *params)
system(params->system),
physmem(system->physmem),
#endif // FULL_SYSTEM
- mem(params->mem),
drainCount(0),
deferRegistration(params->deferRegistration),
numThreads(number_of_threads)
@@ -204,7 +203,6 @@ FullO3CPU<Impl>::FullO3CPU(Params *params)
#if USE_CHECKER
BaseCPU *temp_checker = params->checker;
checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
- checker->setMemory(mem);
#if FULL_SYSTEM
checker->setSystem(params->system);
#endif
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index fe510519c..2bf9cb23b 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -620,9 +620,6 @@ class FullO3CPU : public BaseO3CPU
PhysicalMemory *physmem;
#endif
- /** Pointer to memory. */
- MemObject *mem;
-
/** Event to call process() on once draining has completed. */
Event *drainEvent;
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index 5555bff85..cc9a8abf5 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -329,8 +329,6 @@ class DefaultFetch
/** Wire used to write any information heading to decode. */
typename TimeBuffer<FetchStruct>::wire toDecode;
- MemObject *mem;
-
/** Icache interface. */
IcachePort *icachePort;
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index f1d6cb64f..350ecd52d 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -45,7 +45,6 @@
#if FULL_SYSTEM
#include "arch/tlb.hh"
#include "arch/vtophys.hh"
-#include "base/remote_gdb.hh"
#include "sim/system.hh"
#endif // FULL_SYSTEM
@@ -98,8 +97,7 @@ DefaultFetch<Impl>::IcachePort::recvRetry()
template<class Impl>
DefaultFetch<Impl>::DefaultFetch(Params *params)
- : mem(params->mem),
- branchPred(params),
+ : branchPred(params),
decodeToFetchDelay(params->decodeToFetchDelay),
renameToFetchDelay(params->renameToFetchDelay),
iewToFetchDelay(params->iewToFetchDelay),
@@ -562,14 +560,9 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
{
Fault fault = NoFault;
-#if FULL_SYSTEM
- // Flag to say whether or not address is physical addr.
- unsigned flags = cpu->inPalMode(fetch_PC) ? PHYSICAL : 0;
-#else
- unsigned flags = 0;
-#endif // FULL_SYSTEM
-
- if (cacheBlocked || isSwitchedOut() || (interruptPending && flags == 0)) {
+ //AlphaDep
+ if (cacheBlocked || isSwitchedOut() ||
+ (interruptPending && (fetch_PC & 0x3))) {
// Hold off fetch from getting new instructions when:
// Cache is blocked, or
// while an interrupt is pending and we're not in PAL mode, or
@@ -588,7 +581,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
// Setup the memReq to do a read of the first instruction's address.
// Set the appropriate read size and flags as well.
// Build request here.
- RequestPtr mem_req = new Request(tid, fetch_PC, cacheBlkSize, flags,
+ RequestPtr mem_req = new Request(tid, fetch_PC, cacheBlkSize, 0,
fetch_PC, cpu->readCpuId(), tid);
memReq[tid] = mem_req;
@@ -1120,7 +1113,11 @@ DefaultFetch<Impl>::fetch(bool &status_change)
inst = TheISA::gtoh(*reinterpret_cast<TheISA::MachInst *>
(&cacheData[tid][offset]));
- ext_inst = TheISA::makeExtMI(inst, cpu->tcBase(tid));
+#if THE_ISA == ALPHA_ISA
+ ext_inst = TheISA::makeExtMI(inst, fetch_PC);
+#elif THE_ISA == SPARC_ISA
+ ext_inst = TheISA::makeExtMI(inst, cpu->thread[tid]->getTC());
+#endif
// Create a new DynInst from the instruction fetched.
DynInstPtr instruction = new DynInst(ext_inst, fetch_PC,
diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh
index 8a63ff011..4facea9f9 100644
--- a/src/cpu/o3/lsq_unit_impl.hh
+++ b/src/cpu/o3/lsq_unit_impl.hh
@@ -132,6 +132,7 @@ LSQUnit<Impl>::init(Params *params, LSQ *lsq_ptr, unsigned maxLQEntries,
usedPorts = 0;
cachePorts = params->cachePorts;
+ retryPkt = NULL;
memDepViolator = NULL;
blockedLoadSeqNum = 0;
diff --git a/src/cpu/o3/mem_dep_unit.hh b/src/cpu/o3/mem_dep_unit.hh
index e399f0133..a12a3001b 100644
--- a/src/cpu/o3/mem_dep_unit.hh
+++ b/src/cpu/o3/mem_dep_unit.hh
@@ -69,7 +69,7 @@ class MemDepUnit {
typedef typename Impl::DynInstPtr DynInstPtr;
/** Empty constructor. Must call init() prior to using in this case. */
- MemDepUnit() {}
+ MemDepUnit();
/** Constructs a MemDepUnit with given parameters. */
MemDepUnit(Params *params);
diff --git a/src/cpu/o3/mem_dep_unit_impl.hh b/src/cpu/o3/mem_dep_unit_impl.hh
index c649ca385..f19980fd5 100644
--- a/src/cpu/o3/mem_dep_unit_impl.hh
+++ b/src/cpu/o3/mem_dep_unit_impl.hh
@@ -34,6 +34,13 @@
#include "cpu/o3/mem_dep_unit.hh"
template <class MemDepPred, class Impl>
+MemDepUnit<MemDepPred, Impl>::MemDepUnit()
+ : loadBarrier(false), loadBarrierSN(0), storeBarrier(false),
+ storeBarrierSN(0), iqPtr(NULL)
+{
+}
+
+template <class MemDepPred, class Impl>
MemDepUnit<MemDepPred, Impl>::MemDepUnit(Params *params)
: depPred(params->SSITSize, params->LFSTSize), loadBarrier(false),
loadBarrierSN(0), storeBarrier(false), storeBarrierSN(0), iqPtr(NULL)
@@ -160,8 +167,12 @@ MemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst)
// producing memrefs/stores.
InstSeqNum producing_store;
if (inst->isLoad() && loadBarrier) {
+ DPRINTF(MemDepUnit, "Load barrier [sn:%lli] in flight\n",
+ loadBarrierSN);
producing_store = loadBarrierSN;
} else if (inst->isStore() && storeBarrier) {
+ DPRINTF(MemDepUnit, "Store barrier [sn:%lli] in flight\n",
+ storeBarrierSN);
producing_store = storeBarrierSN;
} else {
producing_store = depPred.checkInst(inst->readPC());
@@ -171,10 +182,12 @@ MemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst)
// If there is a producing store, try to find the entry.
if (producing_store != 0) {
+ DPRINTF(MemDepUnit, "Searching for producer\n");
MemDepHashIt hash_it = memDepHash.find(producing_store);
if (hash_it != memDepHash.end()) {
store_entry = (*hash_it).second;
+ DPRINTF(MemDepUnit, "Proucer found\n");
}
}
diff --git a/src/cpu/o3/mips/cpu.hh b/src/cpu/o3/mips/cpu.hh
index bf04b9f69..7e6268cdf 100755
--- a/src/cpu/o3/mips/cpu.hh
+++ b/src/cpu/o3/mips/cpu.hh
@@ -92,16 +92,15 @@ class MipsO3CPU : public FullO3CPU<Impl>
/** Reads a misc. register, including any side effects the read
* might have as defined by the architecture.
*/
- TheISA::MiscReg readMiscRegWithEffect(int misc_reg,
- Fault &fault, unsigned tid);
+ TheISA::MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid);
/** Sets a miscellaneous register. */
- Fault setMiscReg(int misc_reg, const TheISA::MiscReg &val, unsigned tid);
+ void setMiscReg(int misc_reg, const TheISA::MiscReg &val, unsigned tid);
/** Sets a misc. register, including any side effects the write
* might have as defined by the architecture.
*/
- Fault setMiscRegWithEffect(int misc_reg,
+ void setMiscRegWithEffect(int misc_reg,
const TheISA::MiscReg &val, unsigned tid);
/** Initiates a squash of all in-flight instructions for a given
diff --git a/src/cpu/o3/mips/cpu_builder.cc b/src/cpu/o3/mips/cpu_builder.cc
index f1c3b33a5..ee9f2b48d 100644
--- a/src/cpu/o3/mips/cpu_builder.cc
+++ b/src/cpu/o3/mips/cpu_builder.cc
@@ -54,8 +54,6 @@ Param<int> activity;
SimObjectVectorParam<Process *> workload;
-SimObjectParam<MemObject *> mem;
-
SimObjectParam<BaseCPU *> checker;
Param<Counter> max_insts_any_thread;
@@ -153,8 +151,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivO3CPU)
INIT_PARAM(workload, "Processes to run"),
- INIT_PARAM(mem, "Memory"),
-
INIT_PARAM_DFLT(checker, "Checker CPU", NULL),
INIT_PARAM_DFLT(max_insts_any_thread,
@@ -284,8 +280,6 @@ CREATE_SIM_OBJECT(DerivO3CPU)
params->workload = workload;
- params->mem = mem;
-
params->checker = checker;
params->max_insts_any_thread = max_insts_any_thread;
diff --git a/src/cpu/o3/mips/cpu_impl.hh b/src/cpu/o3/mips/cpu_impl.hh
index e08741626..08e9ba483 100644
--- a/src/cpu/o3/mips/cpu_impl.hh
+++ b/src/cpu/o3/mips/cpu_impl.hh
@@ -58,24 +58,10 @@ MipsO3CPU<Impl>::MipsO3CPU(Params *params)
if (i < params->workload.size()) {
DPRINTF(O3CPU, "Workload[%i] process is %#x",
i, this->thread[i]);
- this->thread[i] = new Thread(this, i, params->workload[i],
- i, params->mem);
+ this->thread[i] = new Thread(this, i, params->workload[i], i);
this->thread[i]->setStatus(ThreadContext::Suspended);
-
- /* Use this port to for syscall emulation writes to memory. */
- Port *mem_port;
- TranslatingPort *trans_port;
- trans_port = new TranslatingPort(csprintf("%s-%d-funcport",
- name(), i),
- params->workload[i]->pTable,
- false);
- mem_port = params->mem->getPort("functional");
- mem_port->setPeer(trans_port);
- trans_port->setPeer(mem_port);
- this->thread[i]->setMemPort(trans_port);
-
//usedTids[i] = true;
//threadMap[i] = i;
} else {
@@ -83,7 +69,7 @@ MipsO3CPU<Impl>::MipsO3CPU(Params *params)
//when scheduling threads to CPU
Process* dummy_proc = NULL;
- this->thread[i] = new Thread(this, i, dummy_proc, i, params->mem);
+ this->thread[i] = new Thread(this, i, dummy_proc, i);
//usedTids[i] = false;
}
@@ -156,25 +142,24 @@ MipsO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
template <class Impl>
MiscReg
-MipsO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, Fault &fault,
- unsigned tid)
+MipsO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, unsigned tid)
{
- return this->regFile.readMiscRegWithEffect(misc_reg, fault, tid);
+ return this->regFile.readMiscRegWithEffect(misc_reg, tid);
}
template <class Impl>
-Fault
+void
MipsO3CPU<Impl>::setMiscReg(int misc_reg, const MiscReg &val, unsigned tid)
{
- return this->regFile.setMiscReg(misc_reg, val, tid);
+ this->regFile.setMiscReg(misc_reg, val, tid);
}
template <class Impl>
-Fault
+void
MipsO3CPU<Impl>::setMiscRegWithEffect(int misc_reg, const MiscReg &val,
unsigned tid)
{
- return this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
+ this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
}
template <class Impl>
diff --git a/src/cpu/o3/mips/dyn_inst.hh b/src/cpu/o3/mips/dyn_inst.hh
index aa30bfa1e..9e95b2bfb 100755
--- a/src/cpu/o3/mips/dyn_inst.hh
+++ b/src/cpu/o3/mips/dyn_inst.hh
@@ -103,23 +103,22 @@ class MipsDynInst : public BaseDynInst<Impl>
/** Reads a misc. register, including any side-effects the read
* might have as defined by the architecture.
*/
- MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
+ MiscReg readMiscRegWithEffect(int misc_reg)
{
- return this->cpu->readMiscRegWithEffect(misc_reg, fault,
- this->threadNumber);
+ return this->cpu->readMiscRegWithEffect(misc_reg, this->threadNumber);
}
/** Sets a misc. register. */
- Fault setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{
this->instResult.integer = val;
- return this->cpu->setMiscReg(misc_reg, val, this->threadNumber);
+ this->cpu->setMiscReg(misc_reg, val, this->threadNumber);
}
/** Sets a misc. register, including any side-effects the write
* might have as defined by the architecture.
*/
- Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{
return this->cpu->setMiscRegWithEffect(misc_reg, val,
this->threadNumber);
diff --git a/src/cpu/o3/params.hh b/src/cpu/o3/params.hh
index 1c234bcd7..b487778c6 100755
--- a/src/cpu/o3/params.hh
+++ b/src/cpu/o3/params.hh
@@ -54,8 +54,6 @@ class O3Params : public BaseO3CPU::Params
Process *process;
#endif // FULL_SYSTEM
- MemObject *mem;
-
BaseCPU *checker;
//
diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh
index 512cf0721..598af123e 100644
--- a/src/cpu/o3/regfile.hh
+++ b/src/cpu/o3/regfile.hh
@@ -37,11 +37,9 @@
#include "base/trace.hh"
#include "config/full_system.hh"
#include "cpu/o3/comm.hh"
-#include "sim/faults.hh"
#if FULL_SYSTEM
-#include "kern/kernel_stats.hh"
-
+#include "arch/kernel_stats.hh"
#endif
#include <vector>
@@ -232,31 +230,24 @@ class PhysRegFile
return miscRegs[thread_id].readReg(misc_reg);
}
- MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault,
- unsigned thread_id)
+ MiscReg readMiscRegWithEffect(int misc_reg, unsigned thread_id)
{
- return miscRegs[thread_id].readRegWithEffect(misc_reg, fault,
+ return miscRegs[thread_id].readRegWithEffect(misc_reg,
cpu->tcBase(thread_id));
}
- Fault setMiscReg(int misc_reg, const MiscReg &val, unsigned thread_id)
+ void setMiscReg(int misc_reg, const MiscReg &val, unsigned thread_id)
{
- return miscRegs[thread_id].setReg(misc_reg, val);
+ miscRegs[thread_id].setReg(misc_reg, val);
}
- Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val,
+ void setMiscRegWithEffect(int misc_reg, const MiscReg &val,
unsigned thread_id)
{
- return miscRegs[thread_id].setRegWithEffect(misc_reg, val,
+ miscRegs[thread_id].setRegWithEffect(misc_reg, val,
cpu->tcBase(thread_id));
}
-#if FULL_SYSTEM
- int readIntrFlag() { return intrflag; }
- /** Sets an interrupt flag. */
- void setIntrFlag(int val) { intrflag = val; }
-#endif
-
public:
/** (signed) integer register file. */
IntReg *intRegFile;
diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh
index 9ca02b9f3..daee2fc7d 100755
--- a/src/cpu/o3/thread_context.hh
+++ b/src/cpu/o3/thread_context.hh
@@ -83,7 +83,7 @@ class O3ThreadContext : public ThreadContext
virtual PhysicalMemory *getPhysMemPtr() { return cpu->physmem; }
/** Returns a pointer to this thread's kernel statistics. */
- virtual Kernel::Statistics *getKernelStats()
+ virtual TheISA::Kernel::Statistics *getKernelStats()
{ return thread->kernelStats; }
virtual FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
@@ -201,15 +201,15 @@ class O3ThreadContext : public ThreadContext
/** Reads a misc. register, including any side-effects the
* read might have as defined by the architecture. */
- virtual MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
- { return cpu->readMiscRegWithEffect(misc_reg, fault, thread->readTid()); }
+ virtual MiscReg readMiscRegWithEffect(int misc_reg)
+ { return cpu->readMiscRegWithEffect(misc_reg, thread->readTid()); }
/** Sets a misc. register. */
- virtual Fault setMiscReg(int misc_reg, const MiscReg &val);
+ virtual void setMiscReg(int misc_reg, const MiscReg &val);
/** Sets a misc. register, including any side-effects the
* write might have as defined by the architecture. */
- virtual Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val);
+ virtual void setMiscRegWithEffect(int misc_reg, const MiscReg &val);
/** Returns the number of consecutive store conditional failures. */
// @todo: Figure out where these store cond failures should go.
diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh
index 2bc194d53..8d623f5b8 100755
--- a/src/cpu/o3/thread_context_impl.hh
+++ b/src/cpu/o3/thread_context_impl.hh
@@ -194,7 +194,7 @@ void
O3ThreadContext<Impl>::regStats(const std::string &name)
{
#if FULL_SYSTEM
- thread->kernelStats = new Kernel::Statistics(cpu->system);
+ thread->kernelStats = new TheISA::Kernel::Statistics(cpu->system);
thread->kernelStats->regStats(name + ".kern");
#endif
}
@@ -439,33 +439,28 @@ O3ThreadContext<Impl>::setNextPC(uint64_t val)
}
template <class Impl>
-Fault
+void
O3ThreadContext<Impl>::setMiscReg(int misc_reg, const MiscReg &val)
{
- Fault ret_fault = cpu->setMiscReg(misc_reg, val, thread->readTid());
+ cpu->setMiscReg(misc_reg, val, thread->readTid());
// Squash if we're not already in a state update mode.
if (!thread->trapPending && !thread->inSyscall) {
cpu->squashFromTC(thread->readTid());
}
-
- return ret_fault;
}
template <class Impl>
-Fault
+void
O3ThreadContext<Impl>::setMiscRegWithEffect(int misc_reg,
const MiscReg &val)
{
- Fault ret_fault = cpu->setMiscRegWithEffect(misc_reg, val,
- thread->readTid());
+ cpu->setMiscRegWithEffect(misc_reg, val, thread->readTid());
// Squash if we're not already in a state update mode.
if (!thread->trapPending && !thread->inSyscall) {
cpu->squashFromTC(thread->readTid());
}
-
- return ret_fault;
}
#if !FULL_SYSTEM
diff --git a/src/cpu/o3/thread_state.hh b/src/cpu/o3/thread_state.hh
index 5fe7bb94d..d8720b3ab 100644
--- a/src/cpu/o3/thread_state.hh
+++ b/src/cpu/o3/thread_state.hh
@@ -77,7 +77,7 @@ struct O3ThreadState : public ThreadState {
#if FULL_SYSTEM
O3ThreadState(O3CPU *_cpu, int _thread_num)
- : ThreadState(-1, _thread_num),
+ : ThreadState(_cpu, -1, _thread_num),
cpu(_cpu), inSyscall(0), trapPending(0)
{
if (cpu->params->profile) {
@@ -95,9 +95,8 @@ struct O3ThreadState : public ThreadState {
profilePC = 3;
}
#else
- O3ThreadState(O3CPU *_cpu, int _thread_num, Process *_process, int _asid,
- MemObject *mem)
- : ThreadState(-1, _thread_num, _process, _asid, mem),
+ O3ThreadState(O3CPU *_cpu, int _thread_num, Process *_process, int _asid)
+ : ThreadState(_cpu, -1, _thread_num, _process, _asid),
cpu(_cpu), inSyscall(0), trapPending(0)
{ }
#endif
diff --git a/src/cpu/ozone/checker_builder.cc b/src/cpu/ozone/checker_builder.cc
index b4c4686b7..9ad1e639f 100644
--- a/src/cpu/ozone/checker_builder.cc
+++ b/src/cpu/ozone/checker_builder.cc
@@ -68,8 +68,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(OzoneChecker)
Param<Tick> progress_interval;
#if FULL_SYSTEM
- SimObjectParam<AlphaITB *> itb;
- SimObjectParam<AlphaDTB *> dtb;
+ SimObjectParam<TheISA::ITB *> itb;
+ SimObjectParam<TheISA::DTB *> dtb;
SimObjectParam<System *> system;
Param<int> cpu_id;
Param<Tick> profile;
diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh
index 70ec1d101..c1373944d 100644
--- a/src/cpu/ozone/cpu.hh
+++ b/src/cpu/ozone/cpu.hh
@@ -51,16 +51,21 @@
#if FULL_SYSTEM
#include "arch/alpha/tlb.hh"
-class AlphaITB;
-class AlphaDTB;
+namespace TheISA
+{
+ class ITB;
+ class DTB;
+}
class PhysicalMemory;
class MemoryController;
class RemoteGDB;
class GDBListener;
-namespace Kernel {
- class Statistics;
+namespace TheISA {
+ namespace Kernel {
+ class Statistics;
+ };
};
#else
@@ -120,11 +125,11 @@ class OzoneCPU : public BaseCPU
PhysicalMemory *getPhysMemPtr() { return cpu->physmem; }
- AlphaITB *getITBPtr() { return cpu->itb; }
+ TheISA::ITB *getITBPtr() { return cpu->itb; }
- AlphaDTB * getDTBPtr() { return cpu->dtb; }
+ TheISA::DTB * getDTBPtr() { return cpu->dtb; }
- Kernel::Statistics *getKernelStats()
+ TheISA::Kernel::Statistics *getKernelStats()
{ return thread->getKernelStats(); }
FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
@@ -224,11 +229,11 @@ class OzoneCPU : public BaseCPU
// ISA stuff:
MiscReg readMiscReg(int misc_reg);
- MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault);
+ MiscReg readMiscRegWithEffect(int misc_reg);
- Fault setMiscReg(int misc_reg, const MiscReg &val);
+ void setMiscReg(int misc_reg, const MiscReg &val);
- Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val);
+ void setMiscRegWithEffect(int misc_reg, const MiscReg &val);
unsigned readStCondFailures()
{ return thread->storeCondFailures; }
@@ -236,10 +241,6 @@ class OzoneCPU : public BaseCPU
void setStCondFailures(unsigned sc_failures)
{ thread->storeCondFailures = sc_failures; }
-#if FULL_SYSTEM
- bool inPalMode() { return cpu->inPalMode(); }
-#endif
-
bool misspeculating() { return false; }
#if !FULL_SYSTEM
@@ -360,16 +361,14 @@ class OzoneCPU : public BaseCPU
bool interval_stats;
- AlphaITB *itb;
- AlphaDTB *dtb;
+ TheISA::ITB *itb;
+ TheISA::DTB *dtb;
System *system;
PhysicalMemory *physmem;
#endif
virtual Port *getPort(const std::string &name, int idx);
- MemObject *mem;
-
FrontEnd *frontEnd;
BackEnd *backEnd;
@@ -583,10 +582,6 @@ class OzoneCPU : public BaseCPU
#if FULL_SYSTEM
Fault hwrei();
- int readIntrFlag() { return thread.intrflag; }
- void setIntrFlag(int val) { thread.intrflag = val; }
- bool inPalMode() { return AlphaISA::PcPAL(thread.PC); }
- bool inPalMode(Addr pc) { return AlphaISA::PcPAL(pc); }
bool simPalCheck(int palFunc);
void processInterrupts();
#else
diff --git a/src/cpu/ozone/cpu_builder.cc b/src/cpu/ozone/cpu_builder.cc
index 730158258..39337dbff 100644
--- a/src/cpu/ozone/cpu_builder.cc
+++ b/src/cpu/ozone/cpu_builder.cc
@@ -61,16 +61,14 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(DerivOzoneCPU)
#if FULL_SYSTEM
SimObjectParam<System *> system;
Param<int> cpu_id;
-SimObjectParam<AlphaITB *> itb;
-SimObjectParam<AlphaDTB *> dtb;
+SimObjectParam<TheISA::ITB *> itb;
+SimObjectParam<TheISA::DTB *> dtb;
Param<Tick> profile;
#else
SimObjectVectorParam<Process *> workload;
//SimObjectParam<PageTable *> page_table;
#endif // FULL_SYSTEM
-SimObjectParam<MemObject *> mem;
-
SimObjectParam<BaseCPU *> checker;
Param<Counter> max_insts_any_thread;
@@ -191,8 +189,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivOzoneCPU)
// INIT_PARAM(page_table, "Page table"),
#endif // FULL_SYSTEM
- INIT_PARAM_DFLT(mem, "Memory", NULL),
-
INIT_PARAM_DFLT(checker, "Checker CPU", NULL),
INIT_PARAM_DFLT(max_insts_any_thread,
@@ -350,7 +346,6 @@ CREATE_SIM_OBJECT(DerivOzoneCPU)
// params->pTable = page_table;
#endif // FULL_SYSTEM
- params->mem = mem;
params->checker = checker;
params->max_insts_any_thread = max_insts_any_thread;
params->max_insts_all_threads = max_insts_all_threads;
diff --git a/src/cpu/ozone/cpu_impl.hh b/src/cpu/ozone/cpu_impl.hh
index bf547bf94..86c973a0f 100644
--- a/src/cpu/ozone/cpu_impl.hh
+++ b/src/cpu/ozone/cpu_impl.hh
@@ -47,12 +47,12 @@
#if FULL_SYSTEM
#include "arch/faults.hh"
#include "arch/alpha/osfpal.hh"
-#include "arch/alpha/tlb.hh"
-#include "arch/alpha/types.hh"
+#include "arch/tlb.hh"
+#include "arch/types.hh"
+#include "arch/kernel_stats.hh"
#include "arch/vtophys.hh"
#include "base/callback.hh"
#include "cpu/profile.hh"
-#include "kern/kernel_stats.hh"
#include "mem/physical.hh"
#include "sim/faults.hh"
#include "sim/sim_events.hh"
@@ -93,10 +93,10 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
#if FULL_SYSTEM
: BaseCPU(p), thread(this, 0), tickEvent(this, p->width),
#else
- : BaseCPU(p), thread(this, 0, p->workload[0], 0, p->mem),
+ : BaseCPU(p), thread(this, 0, p->workload[0], 0),
tickEvent(this, p->width),
#endif
- mem(p->mem), comm(5, 5)
+ comm(5, 5)
{
frontEnd = new FrontEnd(p);
backEnd = new BackEnd(p);
@@ -107,7 +107,6 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
#if USE_CHECKER
BaseCPU *temp_checker = p->checker;
checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
- checker->setMemory(mem);
#if FULL_SYSTEM
checker->setSystem(p->system);
#endif
@@ -198,19 +197,7 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
frontEnd->renameTable.copyFrom(thread.renameTable);
backEnd->renameTable.copyFrom(thread.renameTable);
-#if !FULL_SYSTEM
- /* Use this port to for syscall emulation writes to memory. */
- Port *mem_port;
- TranslatingPort *trans_port;
- trans_port = new TranslatingPort(csprintf("%s-%d-funcport",
- name(), 0),
- p->workload[0]->pTable,
- false);
- mem_port = p->mem->getPort("functional");
- mem_port->setPeer(trans_port);
- trans_port->setPeer(mem_port);
- thread.setMemPort(trans_port);
-#else
+#if FULL_SYSTEM
Port *mem_port;
FunctionalPort *phys_port;
VirtualPort *virt_port;
@@ -904,7 +891,7 @@ void
OzoneCPU<Impl>::OzoneTC::regStats(const std::string &name)
{
#if FULL_SYSTEM
- thread->kernelStats = new Kernel::Statistics(cpu->system);
+ thread->kernelStats = new TheISA::Kernel::Statistics(cpu->system);
thread->kernelStats->regStats(name + ".kern");
#endif
}
@@ -1156,37 +1143,31 @@ OzoneCPU<Impl>::OzoneTC::readMiscReg(int misc_reg)
template <class Impl>
TheISA::MiscReg
-OzoneCPU<Impl>::OzoneTC::readMiscRegWithEffect(int misc_reg, Fault &fault)
+OzoneCPU<Impl>::OzoneTC::readMiscRegWithEffect(int misc_reg)
{
- return thread->miscRegFile.readRegWithEffect(misc_reg,
- fault, this);
+ return thread->miscRegFile.readRegWithEffect(misc_reg, this);
}
template <class Impl>
-Fault
+void
OzoneCPU<Impl>::OzoneTC::setMiscReg(int misc_reg, const MiscReg &val)
{
// Needs to setup a squash event unless we're in syscall mode
- Fault ret_fault = thread->miscRegFile.setReg(misc_reg, val);
+ thread->miscRegFile.setReg(misc_reg, val);
if (!thread->inSyscall) {
cpu->squashFromTC();
}
-
- return ret_fault;
}
template <class Impl>
-Fault
+void
OzoneCPU<Impl>::OzoneTC::setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{
// Needs to setup a squash event unless we're in syscall mode
- Fault ret_fault = thread->miscRegFile.setRegWithEffect(misc_reg, val,
- this);
+ thread->miscRegFile.setRegWithEffect(misc_reg, val, this);
if (!thread->inSyscall) {
cpu->squashFromTC();
}
-
- return ret_fault;
}
diff --git a/src/cpu/ozone/dyn_inst.hh b/src/cpu/ozone/dyn_inst.hh
index e7390626e..9445a5309 100644
--- a/src/cpu/ozone/dyn_inst.hh
+++ b/src/cpu/ozone/dyn_inst.hh
@@ -230,17 +230,14 @@ class OzoneDynInst : public BaseDynInst<Impl>
// ISA stuff
MiscReg readMiscReg(int misc_reg);
- MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault);
+ MiscReg readMiscRegWithEffect(int misc_reg);
- Fault setMiscReg(int misc_reg, const MiscReg &val);
+ void setMiscReg(int misc_reg, const MiscReg &val);
- Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val);
+ void setMiscRegWithEffect(int misc_reg, const MiscReg &val);
#if FULL_SYSTEM
Fault hwrei();
- int readIntrFlag();
- void setIntrFlag(int val);
- bool inPalMode();
void trap(Fault fault);
bool simPalCheck(int palFunc);
#else
diff --git a/src/cpu/ozone/dyn_inst_impl.hh b/src/cpu/ozone/dyn_inst_impl.hh
index 9d42ab05b..05a66d77a 100644
--- a/src/cpu/ozone/dyn_inst_impl.hh
+++ b/src/cpu/ozone/dyn_inst_impl.hh
@@ -31,7 +31,10 @@
#include "sim/faults.hh"
#include "config/full_system.hh"
#include "cpu/ozone/dyn_inst.hh"
+
+#if FULL_SYSTEM
#include "kern/kernel_stats.hh"
+#endif
template <class Impl>
OzoneDynInst<Impl>::OzoneDynInst(OzoneCPU *cpu)
@@ -223,24 +226,24 @@ OzoneDynInst<Impl>::readMiscReg(int misc_reg)
template <class Impl>
TheISA::MiscReg
-OzoneDynInst<Impl>::readMiscRegWithEffect(int misc_reg, Fault &fault)
+OzoneDynInst<Impl>::readMiscRegWithEffect(int misc_reg)
{
- return this->thread->readMiscRegWithEffect(misc_reg, fault);
+ return this->thread->readMiscRegWithEffect(misc_reg);
}
template <class Impl>
-Fault
+void
OzoneDynInst<Impl>::setMiscReg(int misc_reg, const MiscReg &val)
{
this->setIntResult(val);
- return this->thread->setMiscReg(misc_reg, val);
+ this->thread->setMiscReg(misc_reg, val);
}
template <class Impl>
-Fault
+void
OzoneDynInst<Impl>::setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{
- return this->thread->setMiscRegWithEffect(misc_reg, val);
+ this->thread->setMiscRegWithEffect(misc_reg, val);
}
#if FULL_SYSTEM
@@ -249,7 +252,7 @@ template <class Impl>
Fault
OzoneDynInst<Impl>::hwrei()
{
- if (!this->cpu->inPalMode(this->readPC()))
+ if (!(this->readPC() & 0x3))
return new AlphaISA::UnimplementedOpcodeFault;
this->setNextPC(this->thread->readMiscReg(AlphaISA::IPR_EXC_ADDR));
@@ -261,27 +264,6 @@ OzoneDynInst<Impl>::hwrei()
}
template <class Impl>
-int
-OzoneDynInst<Impl>::readIntrFlag()
-{
-return this->cpu->readIntrFlag();
-}
-
-template <class Impl>
-void
-OzoneDynInst<Impl>::setIntrFlag(int val)
-{
- this->cpu->setIntrFlag(val);
-}
-
-template <class Impl>
-bool
-OzoneDynInst<Impl>::inPalMode()
-{
- return this->cpu->inPalMode();
-}
-
-template <class Impl>
void
OzoneDynInst<Impl>::trap(Fault fault)
{
diff --git a/src/cpu/ozone/front_end.hh b/src/cpu/ozone/front_end.hh
index 2bdca35b9..e09e4de9c 100644
--- a/src/cpu/ozone/front_end.hh
+++ b/src/cpu/ozone/front_end.hh
@@ -208,8 +208,6 @@ class FrontEnd
IcachePort icachePort;
- MemObject *mem;
-
RequestPtr memReq;
/** Mask to get a cache block's address. */
diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh
index 60c954517..73ca6afbe 100644
--- a/src/cpu/ozone/front_end_impl.hh
+++ b/src/cpu/ozone/front_end_impl.hh
@@ -91,7 +91,6 @@ template <class Impl>
FrontEnd<Impl>::FrontEnd(Params *params)
: branchPred(params),
icachePort(this),
- mem(params->mem),
numInstsReady(params->frontEndLatency, 0),
instBufferSize(0),
maxInstBufferSize(params->maxInstBufferSize),
@@ -463,15 +462,10 @@ Fault
FrontEnd<Impl>::fetchCacheLine()
{
// Read a cache line, based on the current PC.
-#if FULL_SYSTEM
- // Flag to say whether or not address is physical addr.
- unsigned flags = cpu->inPalMode(PC) ? PHYSICAL : 0;
-#else
- unsigned flags = 0;
-#endif // FULL_SYSTEM
Fault fault = NoFault;
- if (interruptPending && flags == 0) {
+ //AlphaDep
+ if (interruptPending && (PC & 0x3)) {
return fault;
}
@@ -883,7 +877,11 @@ FrontEnd<Impl>::getInstFromCacheline()
// Get the instruction from the array of the cache line.
inst = htog(*reinterpret_cast<MachInst *>(&cacheData[offset]));
+#if THE_ISA == ALPHA_ISA
+ ExtMachInst decode_inst = TheISA::makeExtMI(inst, PC);
+#elif THE_ISA == SPARC_ISA
ExtMachInst decode_inst = TheISA::makeExtMI(inst, tc);
+#endif
// Create a new DynInst from the instruction fetched.
DynInstPtr instruction = new DynInst(decode_inst, PC, PC+sizeof(MachInst),
diff --git a/src/cpu/ozone/inorder_back_end_impl.hh b/src/cpu/ozone/inorder_back_end_impl.hh
index 8aef9c074..87bf0a7a2 100644
--- a/src/cpu/ozone/inorder_back_end_impl.hh
+++ b/src/cpu/ozone/inorder_back_end_impl.hh
@@ -152,11 +152,11 @@ InorderBackEnd<Impl>::tick()
#if FULL_SYSTEM
if (interruptBlocked ||
(cpu->checkInterrupts &&
- cpu->check_interrupts() &&
- !cpu->inPalMode())) {
+ cpu->check_interrupts(tc))) {
if (!robEmpty()) {
interruptBlocked = true;
- } else if (robEmpty() && cpu->inPalMode()) {
+ //AlphaDep
+ } else if (robEmpty() && (PC & 0x3)) {
// Will need to let the front end continue a bit until
// we're out of pal mode. Hopefully we never get into an
// infinite loop...
diff --git a/src/cpu/ozone/lw_back_end_impl.hh b/src/cpu/ozone/lw_back_end_impl.hh
index c39b9e08b..a181c93f4 100644
--- a/src/cpu/ozone/lw_back_end_impl.hh
+++ b/src/cpu/ozone/lw_back_end_impl.hh
@@ -526,8 +526,7 @@ void
LWBackEnd<Impl>::checkInterrupts()
{
if (cpu->checkInterrupts &&
- cpu->check_interrupts() &&
- !cpu->inPalMode(thread->readPC()) &&
+ cpu->check_interrupts(tc) &&
!trapSquash &&
!tcSquash) {
frontEnd->interruptPending = true;
diff --git a/src/cpu/ozone/lw_lsq.hh b/src/cpu/ozone/lw_lsq.hh
index dc58a8285..7e6849668 100644
--- a/src/cpu/ozone/lw_lsq.hh
+++ b/src/cpu/ozone/lw_lsq.hh
@@ -239,8 +239,6 @@ class OzoneLWLSQ {
/** Pointer to the back-end stage. */
BackEnd *be;
- MemObject *mem;
-
class DcachePort : public Port
{
protected:
diff --git a/src/cpu/ozone/lw_lsq_impl.hh b/src/cpu/ozone/lw_lsq_impl.hh
index 1f3f18502..ee1968626 100644
--- a/src/cpu/ozone/lw_lsq_impl.hh
+++ b/src/cpu/ozone/lw_lsq_impl.hh
@@ -154,8 +154,6 @@ OzoneLWLSQ<Impl>::init(Params *params, unsigned maxLQEntries,
SQIndices.push(i);
}
- mem = params->mem;
-
usedPorts = 0;
cachePorts = params->cachePorts;
diff --git a/src/cpu/ozone/simple_cpu_builder.cc b/src/cpu/ozone/simple_cpu_builder.cc
index baaf7c708..e7214d2ba 100644
--- a/src/cpu/ozone/simple_cpu_builder.cc
+++ b/src/cpu/ozone/simple_cpu_builder.cc
@@ -64,8 +64,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleOzoneCPU)
#if FULL_SYSTEM
SimObjectParam<System *> system;
Param<int> cpu_id;
-SimObjectParam<AlphaITB *> itb;
-SimObjectParam<AlphaDTB *> dtb;
+SimObjectParam<TheISA::ITB *> itb;
+SimObjectParam<TheISA::DTB *> dtb;
#else
SimObjectVectorParam<Process *> workload;
//SimObjectParam<PageTable *> page_table;
diff --git a/src/cpu/ozone/simple_params.hh b/src/cpu/ozone/simple_params.hh
index 3f63d2e1d..d5ba6a923 100644
--- a/src/cpu/ozone/simple_params.hh
+++ b/src/cpu/ozone/simple_params.hh
@@ -34,8 +34,11 @@
#include "cpu/ozone/cpu.hh"
//Forward declarations
-class AlphaDTB;
-class AlphaITB;
+namespace TheISA
+{
+ class DTB;
+ class ITB;
+}
class FUPool;
class MemObject;
class PageTable;
@@ -53,7 +56,7 @@ class SimpleParams : public BaseCPU::Params
public:
#if FULL_SYSTEM
- AlphaITB *itb; AlphaDTB *dtb;
+ TheISA::ITB *itb; TheISA::DTB *dtb;
#else
std::vector<Process *> workload;
#endif // FULL_SYSTEM
@@ -61,8 +64,6 @@ class SimpleParams : public BaseCPU::Params
//Page Table
PageTable *pTable;
- MemObject *mem;
-
//
// Caches
//
diff --git a/src/cpu/ozone/thread_state.hh b/src/cpu/ozone/thread_state.hh
index 985e09b52..a71795851 100644
--- a/src/cpu/ozone/thread_state.hh
+++ b/src/cpu/ozone/thread_state.hh
@@ -67,7 +67,7 @@ struct OzoneThreadState : public ThreadState {
#if FULL_SYSTEM
OzoneThreadState(CPUType *_cpu, int _thread_num)
- : ThreadState(-1, _thread_num),
+ : ThreadState(_cpu, -1, _thread_num),
intrflag(0), cpu(_cpu), inSyscall(0), trapPending(0)
{
if (cpu->params->profile) {
@@ -87,8 +87,8 @@ struct OzoneThreadState : public ThreadState {
}
#else
OzoneThreadState(CPUType *_cpu, int _thread_num, Process *_process,
- int _asid, MemObject *mem)
- : ThreadState(-1, _thread_num, _process, _asid, mem),
+ int _asid)
+ : ThreadState(_cpu, -1, _thread_num, _process, _asid),
cpu(_cpu), inSyscall(0), trapPending(0)
{
miscRegFile.clear();
@@ -120,19 +120,19 @@ struct OzoneThreadState : public ThreadState {
return miscRegFile.readReg(misc_reg);
}
- MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
+ MiscReg readMiscRegWithEffect(int misc_reg)
{
- return miscRegFile.readRegWithEffect(misc_reg, fault, tc);
+ return miscRegFile.readRegWithEffect(misc_reg, tc);
}
- Fault setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{
- return miscRegFile.setReg(misc_reg, val);
+ miscRegFile.setReg(misc_reg, val);
}
- Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{
- return miscRegFile.setRegWithEffect(misc_reg, val, tc);
+ miscRegFile.setRegWithEffect(misc_reg, val, tc);
}
uint64_t readPC()
diff --git a/src/cpu/pc_event.hh b/src/cpu/pc_event.hh
index 6b048b2c2..3709dcd59 100644
--- a/src/cpu/pc_event.hh
+++ b/src/cpu/pc_event.hh
@@ -35,6 +35,7 @@
#include <vector>
#include "base/misc.hh"
+#include "sim/host.hh"
class ThreadContext;
class PCEventQueue;
diff --git a/src/cpu/profile.hh b/src/cpu/profile.hh
index 7f9625241..27bb4efec 100644
--- a/src/cpu/profile.hh
+++ b/src/cpu/profile.hh
@@ -33,9 +33,9 @@
#include <map>
+#include "arch/stacktrace.hh"
#include "cpu/static_inst.hh"
#include "sim/host.hh"
-#include "arch/stacktrace.hh"
class ThreadContext;
@@ -66,7 +66,7 @@ class FunctionProfile
const SymbolTable *symtab;
ProfileNode top;
std::map<Addr, Counter> pc_count;
- StackTrace trace;
+ TheISA::StackTrace trace;
public:
FunctionProfile(const SymbolTable *symtab);
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index 11e4d2acb..4f68cfd6f 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -72,15 +72,6 @@ AtomicSimpleCPU::getPort(const std::string &if_name, int idx)
void
AtomicSimpleCPU::init()
{
- //Create Memory Ports (conect them up)
-// Port *mem_dport = mem->getPort("");
-// dcachePort.setPeer(mem_dport);
-// mem_dport->setPeer(&dcachePort);
-
-// Port *mem_iport = mem->getPort("");
-// icachePort.setPeer(mem_iport);
-// mem_iport->setPeer(&icachePort);
-
BaseCPU::init();
#if FULL_SYSTEM
for (int i = 0; i < threadContexts.size(); ++i) {
@@ -189,9 +180,7 @@ AtomicSimpleCPU::resume()
changeState(SimObject::Running);
if (thread->status() == ThreadContext::Active) {
if (!tickEvent.scheduled()) {
- Tick nextTick = curTick + cycles(1) - 1;
- nextTick -= (nextTick % (cycles(1)));
- tickEvent.schedule(nextTick);
+ tickEvent.schedule(nextCycle());
}
}
}
@@ -220,9 +209,7 @@ AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
ThreadContext *tc = threadContexts[i];
if (tc->status() == ThreadContext::Active && _status != Running) {
_status = Running;
- Tick nextTick = curTick + cycles(1) - 1;
- nextTick -= (nextTick % (cycles(1)));
- tickEvent.schedule(nextTick);
+ tickEvent.schedule(nextCycle());
break;
}
}
@@ -240,9 +227,7 @@ AtomicSimpleCPU::activateContext(int thread_num, int delay)
notIdleFraction++;
//Make sure ticks are still on multiples of cycles
- Tick nextTick = curTick + cycles(delay + 1) - 1;
- nextTick -= (nextTick % (cycles(1)));
- tickEvent.schedule(nextTick);
+ tickEvent.schedule(nextCycle(curTick + cycles(delay)));
_status = Running;
}
@@ -508,13 +493,12 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AtomicSimpleCPU)
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
Param<Tick> progress_interval;
- SimObjectParam<MemObject *> mem;
SimObjectParam<System *> system;
Param<int> cpu_id;
#if FULL_SYSTEM
- SimObjectParam<AlphaITB *> itb;
- SimObjectParam<AlphaDTB *> dtb;
+ SimObjectParam<TheISA::ITB *> itb;
+ SimObjectParam<TheISA::DTB *> dtb;
Param<Tick> profile;
#else
SimObjectParam<Process *> workload;
@@ -541,7 +525,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AtomicSimpleCPU)
INIT_PARAM(max_loads_all_threads,
"terminate when all threads have reached this load count"),
INIT_PARAM(progress_interval, "Progress interval"),
- INIT_PARAM(mem, "memory"),
INIT_PARAM(system, "system object"),
INIT_PARAM(cpu_id, "processor ID"),
@@ -579,7 +562,6 @@ CREATE_SIM_OBJECT(AtomicSimpleCPU)
params->functionTraceStart = function_trace_start;
params->width = width;
params->simulate_stalls = simulate_stalls;
- params->mem = mem;
params->system = system;
params->cpu_id = cpu_id;
diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh
index 0edca9369..166a18127 100644
--- a/src/cpu/simple/atomic.hh
+++ b/src/cpu/simple/atomic.hh
@@ -87,7 +87,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU
public:
CpuPort(const std::string &_name, AtomicSimpleCPU *_cpu)
- : Port(_name), cpu(_cpu)
+ : Port(_name, _cpu), cpu(_cpu)
{ }
protected:
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index 253d33243..ab438aa77 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -46,7 +46,6 @@
#include "cpu/smt.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
-#include "kern/kernel_stats.hh"
#include "mem/packet.hh"
#include "sim/builder.hh"
#include "sim/byteswap.hh"
@@ -58,10 +57,11 @@
#include "sim/system.hh"
#if FULL_SYSTEM
-#include "base/remote_gdb.hh"
-#include "arch/tlb.hh"
+#include "arch/kernel_stats.hh"
#include "arch/stacktrace.hh"
+#include "arch/tlb.hh"
#include "arch/vtophys.hh"
+#include "base/remote_gdb.hh"
#else // !FULL_SYSTEM
#include "mem/mem_object.hh"
#endif // FULL_SYSTEM
@@ -70,13 +70,13 @@ using namespace std;
using namespace TheISA;
BaseSimpleCPU::BaseSimpleCPU(Params *p)
- : BaseCPU(p), mem(p->mem), thread(NULL)
+ : BaseCPU(p), thread(NULL)
{
#if FULL_SYSTEM
thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
#else
thread = new SimpleThread(this, /* thread_num */ 0, p->process,
- /* asid */ 0, mem);
+ /* asid */ 0);
#endif // !FULL_SYSTEM
thread->setStatus(ThreadContext::Suspended);
@@ -311,43 +311,12 @@ void
BaseSimpleCPU::checkForInterrupts()
{
#if FULL_SYSTEM
- if (checkInterrupts && check_interrupts() && !thread->inPalMode()) {
- int ipl = 0;
- int summary = 0;
- checkInterrupts = false;
-
- if (thread->readMiscReg(IPR_SIRR)) {
- for (int i = INTLEVEL_SOFTWARE_MIN;
- i < INTLEVEL_SOFTWARE_MAX; i++) {
- if (thread->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
- // See table 4-19 of 21164 hardware reference
- ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
- summary |= (ULL(1) << i);
- }
- }
- }
-
- uint64_t interrupts = thread->cpu->intr_status();
- for (int i = INTLEVEL_EXTERNAL_MIN;
- i < INTLEVEL_EXTERNAL_MAX; i++) {
- if (interrupts & (ULL(1) << i)) {
- // See table 4-19 of 21164 hardware reference
- ipl = i;
- summary |= (ULL(1) << i);
- }
- }
-
- if (thread->readMiscReg(IPR_ASTRR))
- panic("asynchronous traps not implemented\n");
-
- if (ipl && ipl > thread->readMiscReg(IPR_IPLR)) {
- thread->setMiscReg(IPR_ISR, summary);
- thread->setMiscReg(IPR_INTID, ipl);
+ if (checkInterrupts && check_interrupts(tc)) {
+ Fault interrupt = interrupts.getInterrupt(tc);
- Fault(new InterruptFault)->invoke(tc);
-
- DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
- thread->readMiscReg(IPR_IPLR), ipl, summary);
+ if (interrupt != NoFault) {
+ checkInterrupts = false;
+ interrupt->invoke(tc);
}
}
#endif
@@ -398,7 +367,15 @@ BaseSimpleCPU::preExecute()
inst = gtoh(inst);
//If we're not in the middle of a macro instruction
if (!curMacroStaticInst) {
+#if THE_ISA == ALPHA_ISA
+ StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->readPC()));
+#elif THE_ISA == SPARC_ISA
StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC()));
+#elif THE_ISA == MIPS_ISA
+ //Mips doesn't do anything in it's MakeExtMI function right now,
+ //so it won't be called.
+ StaticInstPtr instPtr = StaticInst::decode(inst);
+#endif
if (instPtr->isMacroOp()) {
curMacroStaticInst = instPtr;
curStaticInst = curMacroStaticInst->
@@ -430,8 +407,7 @@ BaseSimpleCPU::postExecute()
{
#if FULL_SYSTEM
if (thread->profile) {
- bool usermode =
- (thread->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
+ bool usermode = TheISA::inUserMode(tc);
thread->profilePC = usermode ? 1 : thread->readPC();
ProfileNode *node = thread->profile->consume(tc, inst);
if (node)
diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh
index af6b6f835..efb884325 100644
--- a/src/cpu/simple/base.hh
+++ b/src/cpu/simple/base.hh
@@ -47,8 +47,11 @@
// forward declarations
#if FULL_SYSTEM
class Processor;
-class AlphaITB;
-class AlphaDTB;
+namespace TheISA
+{
+ class ITB;
+ class DTB;
+}
class MemObject;
class RemoteGDB;
@@ -76,8 +79,6 @@ class BaseSimpleCPU : public BaseCPU
typedef TheISA::FloatReg FloatReg;
typedef TheISA::FloatRegBits FloatRegBits;
- MemObject *mem;
-
protected:
Trace::InstRecord *traceData;
@@ -95,10 +96,9 @@ class BaseSimpleCPU : public BaseCPU
public:
struct Params : public BaseCPU::Params
{
- MemObject *mem;
#if FULL_SYSTEM
- AlphaITB *itb;
- AlphaDTB *dtb;
+ TheISA::ITB *itb;
+ TheISA::DTB *dtb;
#else
Process *process;
#endif
@@ -285,26 +285,23 @@ class BaseSimpleCPU : public BaseCPU
return thread->readMiscReg(misc_reg);
}
- MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
+ MiscReg readMiscRegWithEffect(int misc_reg)
{
- return thread->readMiscRegWithEffect(misc_reg, fault);
+ return thread->readMiscRegWithEffect(misc_reg);
}
- Fault setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{
return thread->setMiscReg(misc_reg, val);
}
- Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{
return thread->setMiscRegWithEffect(misc_reg, val);
}
#if FULL_SYSTEM
Fault hwrei() { return thread->hwrei(); }
- int readIntrFlag() { return thread->readIntrFlag(); }
- void setIntrFlag(int val) { thread->setIntrFlag(val); }
- bool inPalMode() { return thread->inPalMode(); }
void ev5_trap(Fault fault) { fault->invoke(tc); }
bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
#else
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index fe6775ea4..abf316095 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -532,14 +532,13 @@ TimingSimpleCPU::IcachePort::recvTiming(PacketPtr pkt)
{
if (pkt->isResponse()) {
// delay processing of returned data until next CPU clock edge
- Tick time = pkt->req->getTime();
- while (time < curTick)
- time += lat;
+ Tick mem_time = pkt->req->getTime();
+ Tick next_tick = cpu->nextCycle(mem_time);
- if (time == curTick)
+ if (next_tick == curTick)
cpu->completeIfetch(pkt);
else
- tickEvent.schedule(pkt, time);
+ tickEvent.schedule(pkt, next_tick);
return true;
}
@@ -610,14 +609,13 @@ TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
{
if (pkt->isResponse()) {
// delay processing of returned data until next CPU clock edge
- Tick time = pkt->req->getTime();
- while (time < curTick)
- time += lat;
+ Tick mem_time = pkt->req->getTime();
+ Tick next_tick = cpu->nextCycle(mem_time);
- if (time == curTick)
+ if (next_tick == curTick)
cpu->completeDataAccess(pkt);
else
- tickEvent.schedule(pkt, time);
+ tickEvent.schedule(pkt, next_tick);
return true;
}
@@ -660,13 +658,12 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(TimingSimpleCPU)
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
Param<Tick> progress_interval;
- SimObjectParam<MemObject *> mem;
SimObjectParam<System *> system;
Param<int> cpu_id;
#if FULL_SYSTEM
- SimObjectParam<AlphaITB *> itb;
- SimObjectParam<AlphaDTB *> dtb;
+ SimObjectParam<TheISA::ITB *> itb;
+ SimObjectParam<TheISA::DTB *> dtb;
Param<Tick> profile;
#else
SimObjectParam<Process *> workload;
@@ -693,7 +690,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(TimingSimpleCPU)
INIT_PARAM(max_loads_all_threads,
"terminate when all threads have reached this load count"),
INIT_PARAM(progress_interval, "Progress interval"),
- INIT_PARAM(mem, "memory"),
INIT_PARAM(system, "system object"),
INIT_PARAM(cpu_id, "processor ID"),
@@ -729,7 +725,6 @@ CREATE_SIM_OBJECT(TimingSimpleCPU)
params->clock = clock;
params->functionTrace = function_trace;
params->functionTraceStart = function_trace_start;
- params->mem = mem;
params->system = system;
params->cpu_id = cpu_id;
diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh
index 577e13e40..408fa315e 100644
--- a/src/cpu/simple/timing.hh
+++ b/src/cpu/simple/timing.hh
@@ -79,7 +79,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
public:
CpuPort(const std::string &_name, TimingSimpleCPU *_cpu, Tick _lat)
- : Port(_name), cpu(_cpu), lat(_lat)
+ : Port(_name, _cpu), cpu(_cpu), lat(_lat)
{ }
protected:
@@ -166,6 +166,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
PacketPtr ifetch_pkt;
PacketPtr dcache_pkt;
+
+
int cpu_id;
Tick previousTick;
diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc
index 4fc47c982..1edcbf352 100644
--- a/src/cpu/simple_thread.cc
+++ b/src/cpu/simple_thread.cc
@@ -39,13 +39,13 @@
#include "cpu/thread_context.hh"
#if FULL_SYSTEM
+#include "arch/kernel_stats.hh"
#include "base/callback.hh"
#include "base/cprintf.hh"
#include "base/output.hh"
#include "base/trace.hh"
#include "cpu/profile.hh"
#include "cpu/quiesce_event.hh"
-#include "kern/kernel_stats.hh"
#include "sim/serialize.hh"
#include "sim/sim_exit.hh"
#include "arch/stacktrace.hh"
@@ -60,9 +60,9 @@ using namespace std;
// constructor
#if FULL_SYSTEM
SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
- AlphaITB *_itb, AlphaDTB *_dtb,
+ TheISA::ITB *_itb, TheISA::DTB *_dtb,
bool use_kernel_stats)
- : ThreadState(-1, _thread_num), cpu(_cpu), system(_sys), itb(_itb),
+ : ThreadState(_cpu, -1, _thread_num), cpu(_cpu), system(_sys), itb(_itb),
dtb(_dtb)
{
@@ -87,7 +87,7 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
profilePC = 3;
if (use_kernel_stats) {
- kernelStats = new Kernel::Statistics(system);
+ kernelStats = new TheISA::Kernel::Statistics(system);
} else {
kernelStats = NULL;
}
@@ -106,19 +106,10 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
}
#else
SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num,
- Process *_process, int _asid, MemObject* memobj)
- : ThreadState(-1, _thread_num, _process, _asid, memobj),
+ Process *_process, int _asid)
+ : ThreadState(_cpu, -1, _thread_num, _process, _asid),
cpu(_cpu)
{
- /* Use this port to for syscall emulation writes to memory. */
- Port *mem_port;
- port = new TranslatingPort(csprintf("%s-%d-funcport",
- cpu->name(), tid),
- process->pTable, false);
- mem_port = memobj->getPort("functional");
- mem_port->setPeer(port);
- port->setPeer(mem_port);
-
regs.clear();
tc = new ProxyThreadContext<SimpleThread>(this);
}
@@ -127,9 +118,9 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num,
SimpleThread::SimpleThread()
#if FULL_SYSTEM
- : ThreadState(-1, -1)
+ : ThreadState(NULL, -1, -1)
#else
- : ThreadState(-1, -1, NULL, -1, NULL)
+ : ThreadState(NULL, -1, -1, NULL, -1)
#endif
{
tc = new ProxyThreadContext<SimpleThread>(this);
@@ -138,6 +129,10 @@ SimpleThread::SimpleThread()
SimpleThread::~SimpleThread()
{
+#if FULL_SYSTEM
+ delete physPort;
+ delete virtPort;
+#endif
delete tc;
}
@@ -163,7 +158,7 @@ SimpleThread::takeOverFrom(ThreadContext *oldContext)
quiesceEvent->tc = tc;
}
- Kernel::Statistics *stats = oldContext->getKernelStats();
+ TheISA::Kernel::Statistics *stats = oldContext->getKernelStats();
if (stats) {
kernelStats = stats;
}
@@ -184,7 +179,7 @@ SimpleThread::copyTC(ThreadContext *context)
if (quiesce) {
quiesceEvent = quiesce;
}
- Kernel::Statistics *stats = context->getKernelStats();
+ TheISA::Kernel::Statistics *stats = context->getKernelStats();
if (stats) {
kernelStats = stats;
}
@@ -313,11 +308,9 @@ SimpleThread::getVirtPort(ThreadContext *src_tc)
if (!src_tc)
return virtPort;
- VirtualPort *vp;
- Port *mem_port;
+ VirtualPort *vp = new VirtualPort("tc-vport", src_tc);
+ Port *mem_port = getMemFuncPort();
- vp = new VirtualPort("tc-vport", src_tc);
- mem_port = system->physmem->getPort("functional");
mem_port->setPeer(vp);
vp->setPeer(mem_port);
return vp;
@@ -332,6 +325,5 @@ SimpleThread::delVirtPort(VirtualPort *vp)
}
}
-
#endif
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index fe22e6c43..e8757c8c2 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.hh
@@ -55,8 +55,10 @@ class ProfileNode;
class FunctionalPort;
class PhysicalPort;
-namespace Kernel {
- class Statistics;
+namespace TheISA {
+ namespace Kernel {
+ class Statistics;
+ };
};
#else // !FULL_SYSTEM
@@ -107,18 +109,17 @@ class SimpleThread : public ThreadState
System *system;
#if FULL_SYSTEM
- AlphaITB *itb;
- AlphaDTB *dtb;
+ TheISA::ITB *itb;
+ TheISA::DTB *dtb;
#endif
// constructor: initialize SimpleThread from given process structure
#if FULL_SYSTEM
SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
- AlphaITB *_itb, AlphaDTB *_dtb,
+ TheISA::ITB *_itb, TheISA::DTB *_dtb,
bool use_kernel_stats = true);
#else
- SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid,
- MemObject *memobj);
+ SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid);
#endif
SimpleThread();
@@ -168,12 +169,11 @@ class SimpleThread : public ThreadState
void dumpFuncProfile();
- int readIntrFlag() { return regs.intrflag; }
- void setIntrFlag(int val) { regs.intrflag = val; }
Fault hwrei();
bool simPalCheck(int palFunc);
#else
+
Fault translateInstReq(RequestPtr &req)
{
return process->pTable->translate(req);
@@ -201,9 +201,9 @@ class SimpleThread : public ThreadState
#if FULL_SYSTEM
System *getSystemPtr() { return system; }
- AlphaITB *getITBPtr() { return itb; }
+ TheISA::ITB *getITBPtr() { return itb; }
- AlphaDTB *getDTBPtr() { return dtb; }
+ TheISA::DTB *getDTBPtr() { return dtb; }
FunctionalPort *getPhysPort() { return physPort; }
@@ -422,17 +422,17 @@ class SimpleThread : public ThreadState
return regs.readMiscReg(misc_reg);
}
- MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
+ MiscReg readMiscRegWithEffect(int misc_reg)
{
- return regs.readMiscRegWithEffect(misc_reg, fault, tc);
+ return regs.readMiscRegWithEffect(misc_reg, tc);
}
- Fault setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{
return regs.setMiscReg(misc_reg, val);
}
- Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{
return regs.setMiscRegWithEffect(misc_reg, val, tc);
}
@@ -442,10 +442,6 @@ class SimpleThread : public ThreadState
void setStCondFailures(unsigned sc_failures)
{ storeCondFailures = sc_failures; }
-#if FULL_SYSTEM
- bool inPalMode() { return AlphaISA::PcPAL(regs.readPC()); }
-#endif
-
#if !FULL_SYSTEM
TheISA::IntReg getSyscallArg(int i)
{
diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh
index 73046097d..1e6a907f8 100644
--- a/src/cpu/thread_context.hh
+++ b/src/cpu/thread_context.hh
@@ -31,9 +31,9 @@
#ifndef __CPU_THREAD_CONTEXT_HH__
#define __CPU_THREAD_CONTEXT_HH__
-#include "arch/types.hh"
#include "arch/regfile.hh"
#include "arch/syscallreturn.hh"
+#include "arch/types.hh"
#include "config/full_system.hh"
#include "mem/request.hh"
#include "sim/faults.hh"
@@ -43,8 +43,11 @@
// @todo: Figure out a more architecture independent way to obtain the ITB and
// DTB pointers.
-class AlphaDTB;
-class AlphaITB;
+namespace TheISA
+{
+ class DTB;
+ class ITB;
+}
class BaseCPU;
class EndQuiesceEvent;
class Event;
@@ -53,8 +56,10 @@ class FunctionalPort;
class VirtualPort;
class Process;
class System;
-namespace Kernel {
- class Statistics;
+namespace TheISA {
+ namespace Kernel {
+ class Statistics;
+ };
};
/**
@@ -117,11 +122,11 @@ class ThreadContext
#if FULL_SYSTEM
virtual System *getSystemPtr() = 0;
- virtual AlphaITB *getITBPtr() = 0;
+ virtual TheISA::ITB *getITBPtr() = 0;
- virtual AlphaDTB * getDTBPtr() = 0;
+ virtual TheISA::DTB *getDTBPtr() = 0;
- virtual Kernel::Statistics *getKernelStats() = 0;
+ virtual TheISA::Kernel::Statistics *getKernelStats() = 0;
virtual FunctionalPort *getPhysPort() = 0;
@@ -221,11 +226,11 @@ class ThreadContext
virtual MiscReg readMiscReg(int misc_reg) = 0;
- virtual MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) = 0;
+ virtual MiscReg readMiscRegWithEffect(int misc_reg) = 0;
- virtual Fault setMiscReg(int misc_reg, const MiscReg &val) = 0;
+ virtual void setMiscReg(int misc_reg, const MiscReg &val) = 0;
- virtual Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) = 0;
+ virtual void setMiscRegWithEffect(int misc_reg, const MiscReg &val) = 0;
// Also not necessarily the best location for these two. Hopefully will go
// away once we decide upon where st cond failures goes.
@@ -233,10 +238,6 @@ class ThreadContext
virtual void setStCondFailures(unsigned sc_failures) = 0;
-#if FULL_SYSTEM
- virtual bool inPalMode() = 0;
-#endif
-
// Only really makes sense for old CPU model. Still could be useful though.
virtual bool misspeculating() = 0;
@@ -292,11 +293,12 @@ class ProxyThreadContext : public ThreadContext
#if FULL_SYSTEM
System *getSystemPtr() { return actualTC->getSystemPtr(); }
- AlphaITB *getITBPtr() { return actualTC->getITBPtr(); }
+ TheISA::ITB *getITBPtr() { return actualTC->getITBPtr(); }
- AlphaDTB *getDTBPtr() { return actualTC->getDTBPtr(); }
+ TheISA::DTB *getDTBPtr() { return actualTC->getDTBPtr(); }
- Kernel::Statistics *getKernelStats() { return actualTC->getKernelStats(); }
+ TheISA::Kernel::Statistics *getKernelStats()
+ { return actualTC->getKernelStats(); }
FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); }
@@ -407,13 +409,13 @@ class ProxyThreadContext : public ThreadContext
MiscReg readMiscReg(int misc_reg)
{ return actualTC->readMiscReg(misc_reg); }
- MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
- { return actualTC->readMiscRegWithEffect(misc_reg, fault); }
+ MiscReg readMiscRegWithEffect(int misc_reg)
+ { return actualTC->readMiscRegWithEffect(misc_reg); }
- Fault setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{ return actualTC->setMiscReg(misc_reg, val); }
- Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{ return actualTC->setMiscRegWithEffect(misc_reg, val); }
unsigned readStCondFailures()
@@ -421,9 +423,6 @@ class ProxyThreadContext : public ThreadContext
void setStCondFailures(unsigned sc_failures)
{ actualTC->setStCondFailures(sc_failures); }
-#if FULL_SYSTEM
- bool inPalMode() { return actualTC->inPalMode(); }
-#endif
// @todo: Fix this!
bool misspeculating() { return actualTC->misspeculating(); }
diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc
index e6ebcc525..8602f8a50 100644
--- a/src/cpu/thread_state.cc
+++ b/src/cpu/thread_state.cc
@@ -29,25 +29,29 @@
*/
#include "base/output.hh"
+#include "cpu/base.hh"
#include "cpu/profile.hh"
#include "cpu/thread_state.hh"
+#include "mem/port.hh"
+#include "mem/translating_port.hh"
#include "sim/serialize.hh"
#if FULL_SYSTEM
+#include "arch/kernel_stats.hh"
#include "cpu/quiesce_event.hh"
-#include "kern/kernel_stats.hh"
#endif
#if FULL_SYSTEM
-ThreadState::ThreadState(int _cpuId, int _tid)
- : cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
+ThreadState::ThreadState(BaseCPU *cpu, int _cpuId, int _tid)
+ : baseCpu(cpu), cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL),
+ physPort(NULL), virtPort(NULL),
microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0)
#else
-ThreadState::ThreadState(int _cpuId, int _tid, Process *_process,
- short _asid, MemObject *mem)
- : cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
- process(_process), asid(_asid),
+ThreadState::ThreadState(BaseCPU *cpu, int _cpuId, int _tid, Process *_process,
+ short _asid)
+ : baseCpu(cpu), cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
+ port(NULL), process(_process), asid(_asid),
microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0)
#endif
{
@@ -55,6 +59,16 @@ ThreadState::ThreadState(int _cpuId, int _tid, Process *_process,
numLoad = 0;
}
+ThreadState::~ThreadState()
+{
+#if !FULL_SYSTEM
+ if (port) {
+ delete port->getPeer();
+ delete port;
+ }
+#endif
+}
+
void
ThreadState::serialize(std::ostream &os)
{
@@ -112,4 +126,40 @@ ThreadState::profileSample()
profile->sample(profileNode, profilePC);
}
+#else
+TranslatingPort *
+ThreadState::getMemPort()
+{
+ if (port != NULL)
+ return port;
+
+ /* Use this port to for syscall emulation writes to memory. */
+ port = new TranslatingPort(csprintf("%s-%d-funcport",
+ baseCpu->name(), tid),
+ process->pTable, false);
+
+ Port *func_port = getMemFuncPort();
+
+ func_port->setPeer(port);
+ port->setPeer(func_port);
+
+ return port;
+}
#endif
+
+Port *
+ThreadState::getMemFuncPort()
+{
+ Port *dcache_port, *func_mem_port;
+
+ dcache_port = baseCpu->getPort("dcache_port");
+ assert(dcache_port != NULL);
+
+ MemObject *mem_object = dcache_port->getPeer()->getOwner();
+ assert(mem_object != NULL);
+
+ func_mem_port = mem_object->getPort("functional");
+ assert(func_mem_port != NULL);
+
+ return func_mem_port;
+}
diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh
index 60353760c..0a0af8b71 100644
--- a/src/cpu/thread_state.hh
+++ b/src/cpu/thread_state.hh
@@ -37,7 +37,6 @@
#if !FULL_SYSTEM
#include "mem/mem_object.hh"
-#include "mem/translating_port.hh"
#include "sim/process.hh"
#endif
@@ -45,12 +44,17 @@
class EndQuiesceEvent;
class FunctionProfile;
class ProfileNode;
-namespace Kernel {
- class Statistics;
+namespace TheISA {
+ namespace Kernel {
+ class Statistics;
+ };
};
#endif
+class BaseCPU;
class Checkpoint;
+class Port;
+class TranslatingPort;
/**
* Struct for holding general thread state that is needed across CPU
@@ -62,12 +66,14 @@ struct ThreadState {
typedef ThreadContext::Status Status;
#if FULL_SYSTEM
- ThreadState(int _cpuId, int _tid);
+ ThreadState(BaseCPU *cpu, int _cpuId, int _tid);
#else
- ThreadState(int _cpuId, int _tid, Process *_process,
- short _asid, MemObject *mem);
+ ThreadState(BaseCPU *cpu, int _cpuId, int _tid, Process *_process,
+ short _asid);
#endif
+ ~ThreadState();
+
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
@@ -93,7 +99,7 @@ struct ThreadState {
void profileSample();
- Kernel::Statistics *getKernelStats() { return kernelStats; }
+ TheISA::Kernel::Statistics *getKernelStats() { return kernelStats; }
FunctionalPort *getPhysPort() { return physPort; }
@@ -105,7 +111,7 @@ struct ThreadState {
#else
Process *getProcessPtr() { return process; }
- TranslatingPort *getMemPort() { return port; }
+ TranslatingPort *getMemPort();
void setMemPort(TranslatingPort *_port) { port = _port; }
@@ -135,6 +141,12 @@ struct ThreadState {
/** Sets the status of this thread. */
void setStatus(Status new_status) { _status = new_status; }
+ protected:
+ /** Gets a functional port from the memory object that's connected
+ * to the CPU. */
+ Port *getMemFuncPort();
+
+ public:
/** Number of instructions committed. */
Counter numInst;
/** Stat for number instructions committed. */
@@ -153,6 +165,9 @@ struct ThreadState {
protected:
ThreadContext::Status _status;
+ // Pointer to the base CPU.
+ BaseCPU *baseCpu;
+
// ID of this context w.r.t. the System or Process object to which
// it belongs. For full-system mode, this is the system CPU ID.
int cpuId;
@@ -174,7 +189,7 @@ struct ThreadState {
Addr profilePC;
EndQuiesceEvent *quiesceEvent;
- Kernel::Statistics *kernelStats;
+ TheISA::Kernel::Statistics *kernelStats;
protected:
/** A functional port outgoing only for functional accesses to physical
* addresses.*/
diff --git a/src/dev/SConscript b/src/dev/SConscript
new file mode 100644
index 000000000..951bc29d1
--- /dev/null
+++ b/src/dev/SConscript
@@ -0,0 +1,79 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2006 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Steve Reinhardt
+# Gabe Black
+
+import os.path, sys
+
+# Import build environment variable from SConstruct.
+Import('env')
+
+# Right now there are no source files immediately in this directory
+sources = []
+
+#
+# Now include other ISA-specific sources from the ISA subdirectories.
+#
+
+isa = env['TARGET_ISA'] # someday this may be a list of ISAs
+
+#
+# These source files can be used by any architecture
+#
+
+sources += Split('''
+ baddev.cc
+ disk_image.cc
+ etherbus.cc
+ etherdump.cc
+ etherint.cc
+ etherlink.cc
+ etherpkt.cc
+ ethertap.cc
+ ide_ctrl.cc
+ ide_disk.cc
+ io_device.cc
+ isa_fake.cc
+ ns_gige.cc
+ pciconfigall.cc
+ pcidev.cc
+ pktfifo.cc
+ platform.cc
+ simconsole.cc
+ simple_disk.cc
+ ''')
+
+# Let the target architecture define what additional sources it needs
+sources += SConscript(os.path.join(isa, 'SConscript'), exports = 'env')
+
+# Convert file names to SCons File objects. This takes care of the
+# path relative to the top of the directory tree.
+sources = [File(s) for s in sources]
+
+Return('sources')
diff --git a/src/dev/alpha/SConscript b/src/dev/alpha/SConscript
new file mode 100644
index 000000000..fb0e626d3
--- /dev/null
+++ b/src/dev/alpha/SConscript
@@ -0,0 +1,68 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2006 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Steve Reinhardt
+# Gabe Black
+
+import os.path, sys
+
+# Import build environment variable from SConstruct.
+Import('env')
+
+sources = Split('''
+ console.cc
+ tsunami.cc
+ tsunami_cchip.cc
+ tsunami_io.cc
+ tsunami_pchip.cc
+ ''')
+# baddev.cc
+# disk_image.cc
+# etherbus.cc
+# etherdump.cc
+# etherint.cc
+# etherlink.cc
+# etherpkt.cc
+# ethertap.cc
+# ide_ctrl.cc
+# ide_disk.cc
+# io_device.cc
+# isa_fake.cc
+# ns_gige.cc
+# pciconfigall.cc
+# pcidev.cc
+# pktfifo.cc
+# platform.cc
+# simconsole.cc
+# simple_disk.cc
+
+# Convert file names to SCons File objects. This takes care of the
+# path relative to the top of the directory tree.
+sources = [File(s) for s in sources]
+
+Return('sources')
diff --git a/src/dev/alpha_access.h b/src/dev/alpha/access.h
index 4adeaf84b..4adeaf84b 100644
--- a/src/dev/alpha_access.h
+++ b/src/dev/alpha/access.h
diff --git a/src/dev/alpha_console.cc b/src/dev/alpha/console.cc
index 40868de51..f077efe6c 100644
--- a/src/dev/alpha_console.cc
+++ b/src/dev/alpha/console.cc
@@ -44,7 +44,7 @@
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
-#include "dev/alpha_console.hh"
+#include "dev/alpha/console.hh"
#include "dev/platform.hh"
#include "dev/simconsole.hh"
#include "dev/simple_disk.hh"
diff --git a/src/dev/alpha_console.hh b/src/dev/alpha/console.hh
index 7d6d1e679..b8d21ad5d 100644
--- a/src/dev/alpha_console.hh
+++ b/src/dev/alpha/console.hh
@@ -36,7 +36,7 @@
#define __ALPHA_CONSOLE_HH__
#include "base/range.hh"
-#include "dev/alpha_access.h"
+#include "dev/alpha/access.h"
#include "dev/io_device.hh"
#include "sim/host.hh"
#include "sim/sim_object.hh"
diff --git a/src/dev/tsunami.cc b/src/dev/alpha/tsunami.cc
index 8e740a72f..608e88846 100644
--- a/src/dev/tsunami.cc
+++ b/src/dev/alpha/tsunami.cc
@@ -38,10 +38,10 @@
#include "cpu/intr_control.hh"
#include "dev/simconsole.hh"
-#include "dev/tsunami_cchip.hh"
-#include "dev/tsunami_pchip.hh"
-#include "dev/tsunami_io.hh"
-#include "dev/tsunami.hh"
+#include "dev/alpha/tsunami_cchip.hh"
+#include "dev/alpha/tsunami_pchip.hh"
+#include "dev/alpha/tsunami_io.hh"
+#include "dev/alpha/tsunami.hh"
#include "sim/builder.hh"
#include "sim/system.hh"
diff --git a/src/dev/tsunami.hh b/src/dev/alpha/tsunami.hh
index 6fbfac851..6fbfac851 100644
--- a/src/dev/tsunami.hh
+++ b/src/dev/alpha/tsunami.hh
diff --git a/src/dev/tsunami_cchip.cc b/src/dev/alpha/tsunami_cchip.cc
index 74a68566c..924e1d462 100644
--- a/src/dev/tsunami_cchip.cc
+++ b/src/dev/alpha/tsunami_cchip.cc
@@ -41,9 +41,9 @@
#include "base/trace.hh"
#include "cpu/intr_control.hh"
#include "cpu/thread_context.hh"
-#include "dev/tsunami.hh"
-#include "dev/tsunami_cchip.hh"
-#include "dev/tsunamireg.h"
+#include "dev/alpha/tsunami.hh"
+#include "dev/alpha/tsunami_cchip.hh"
+#include "dev/alpha/tsunamireg.h"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "mem/port.hh"
diff --git a/src/dev/tsunami_cchip.hh b/src/dev/alpha/tsunami_cchip.hh
index 297a94129..004c3cd29 100644
--- a/src/dev/tsunami_cchip.hh
+++ b/src/dev/alpha/tsunami_cchip.hh
@@ -35,7 +35,7 @@
#ifndef __TSUNAMI_CCHIP_HH__
#define __TSUNAMI_CCHIP_HH__
-#include "dev/tsunami.hh"
+#include "dev/alpha/tsunami.hh"
#include "base/range.hh"
#include "dev/io_device.hh"
diff --git a/src/dev/tsunami_io.cc b/src/dev/alpha/tsunami_io.cc
index 73af6c2ef..def214a95 100644
--- a/src/dev/tsunami_io.cc
+++ b/src/dev/alpha/tsunami_io.cc
@@ -43,10 +43,10 @@
#include "base/trace.hh"
#include "dev/pitreg.h"
#include "dev/rtcreg.h"
-#include "dev/tsunami_cchip.hh"
-#include "dev/tsunami.hh"
-#include "dev/tsunami_io.hh"
-#include "dev/tsunamireg.h"
+#include "dev/alpha/tsunami_cchip.hh"
+#include "dev/alpha/tsunami.hh"
+#include "dev/alpha/tsunami_io.hh"
+#include "dev/alpha/tsunamireg.h"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "mem/port.hh"
diff --git a/src/dev/tsunami_io.hh b/src/dev/alpha/tsunami_io.hh
index 5ea3628c1..54acefc25 100644
--- a/src/dev/tsunami_io.hh
+++ b/src/dev/alpha/tsunami_io.hh
@@ -39,7 +39,7 @@
#include "dev/io_device.hh"
#include "base/range.hh"
-#include "dev/tsunami.hh"
+#include "dev/alpha/tsunami.hh"
#include "sim/eventq.hh"
/**
diff --git a/src/dev/tsunami_pchip.cc b/src/dev/alpha/tsunami_pchip.cc
index 549db1a50..94a7f96e5 100644
--- a/src/dev/tsunami_pchip.cc
+++ b/src/dev/alpha/tsunami_pchip.cc
@@ -38,9 +38,9 @@
#include <vector>
#include "base/trace.hh"
-#include "dev/tsunami_pchip.hh"
-#include "dev/tsunamireg.h"
-#include "dev/tsunami.hh"
+#include "dev/alpha/tsunami_pchip.hh"
+#include "dev/alpha/tsunamireg.h"
+#include "dev/alpha/tsunami.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "sim/builder.hh"
diff --git a/src/dev/tsunami_pchip.hh b/src/dev/alpha/tsunami_pchip.hh
index d0a9c3157..1632a36d4 100644
--- a/src/dev/tsunami_pchip.hh
+++ b/src/dev/alpha/tsunami_pchip.hh
@@ -35,7 +35,7 @@
#ifndef __TSUNAMI_PCHIP_HH__
#define __TSUNAMI_PCHIP_HH__
-#include "dev/tsunami.hh"
+#include "dev/alpha/tsunami.hh"
#include "base/range.hh"
#include "dev/io_device.hh"
diff --git a/src/dev/tsunamireg.h b/src/dev/alpha/tsunamireg.h
index d603972be..d603972be 100644
--- a/src/dev/tsunamireg.h
+++ b/src/dev/alpha/tsunamireg.h
diff --git a/src/dev/ide_disk.cc b/src/dev/ide_disk.cc
index 5d3346b1e..5083c9c8d 100644
--- a/src/dev/ide_disk.cc
+++ b/src/dev/ide_disk.cc
@@ -44,8 +44,8 @@
#include "dev/disk_image.hh"
#include "dev/ide_disk.hh"
#include "dev/ide_ctrl.hh"
-#include "dev/tsunami.hh"
-#include "dev/tsunami_pchip.hh"
+#include "dev/alpha/tsunami.hh"
+#include "dev/alpha/tsunami_pchip.hh"
#include "sim/builder.hh"
#include "sim/sim_object.hh"
#include "sim/root.hh"
diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc
index 9671d77cc..a1285fefc 100644
--- a/src/dev/io_device.cc
+++ b/src/dev/io_device.cc
@@ -37,7 +37,7 @@
PioPort::PioPort(PioDevice *dev, System *s, std::string pname)
- : SimpleTimingPort(dev->name() + pname), device(dev)
+ : SimpleTimingPort(dev->name() + pname, dev), device(dev)
{ }
@@ -92,8 +92,8 @@ BasicPioDevice::addressRanges(AddrRangeList &range_list)
DmaPort::DmaPort(DmaDevice *dev, System *s)
- : Port(dev->name() + "-dmaport"), device(dev), sys(s), pendingCount(0),
- actionInProgress(0), drainEvent(NULL)
+ : Port(dev->name() + "-dmaport", dev), device(dev), sys(s),
+ pendingCount(0), actionInProgress(0), drainEvent(NULL)
{ }
bool
diff --git a/src/dev/isa_fake.cc b/src/dev/isa_fake.cc
index 23761cd10..40909c6a1 100644
--- a/src/dev/isa_fake.cc
+++ b/src/dev/isa_fake.cc
@@ -25,18 +25,13 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * Authors: Miguel Serrano
- * Ali Saidi
+ * Authors: Ali Saidi
*/
/** @file
* Isa Fake Device implementation
*/
-#include <deque>
-#include <string>
-#include <vector>
-
#include "base/trace.hh"
#include "dev/isa_fake.hh"
#include "mem/packet.hh"
@@ -49,42 +44,58 @@ using namespace std;
IsaFake::IsaFake(Params *p)
: BasicPioDevice(p)
{
- pioSize = p->pio_size;
+ if (!params()->retBadAddr)
+ pioSize = p->pio_size;
+
+ memset(&retData, p->retData, sizeof(retData));
}
Tick
IsaFake::read(PacketPtr pkt)
{
assert(pkt->result == Packet::Unknown);
- assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
-
- DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize());
-
- switch (pkt->getSize()) {
- case sizeof(uint64_t):
- pkt->set(0xFFFFFFFFFFFFFFFFULL);
- break;
- case sizeof(uint32_t):
- pkt->set((uint32_t)0xFFFFFFFF);
- break;
- case sizeof(uint16_t):
- pkt->set((uint16_t)0xFFFF);
- break;
- case sizeof(uint8_t):
- pkt->set((uint8_t)0xFF);
- break;
- default:
- panic("invalid access size(?) for PCI configspace!\n");
+
+ if (params()->retBadAddr) {
+ DPRINTF(Tsunami, "read to bad address va=%#x size=%d\n",
+ pkt->getAddr(), pkt->getSize());
+ pkt->result = Packet::BadAddress;
+ } else {
+ assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
+ DPRINTF(Tsunami, "read va=%#x size=%d\n",
+ pkt->getAddr(), pkt->getSize());
+ switch (pkt->getSize()) {
+ case sizeof(uint64_t):
+ pkt->set(retData);
+ break;
+ case sizeof(uint32_t):
+ pkt->set((uint32_t)retData);
+ break;
+ case sizeof(uint16_t):
+ pkt->set((uint16_t)retData);
+ break;
+ case sizeof(uint8_t):
+ pkt->set((uint8_t)retData);
+ break;
+ default:
+ panic("invalid access size!\n");
+ }
+ pkt->result = Packet::Success;
}
- pkt->result = Packet::Success;
return pioDelay;
}
Tick
IsaFake::write(PacketPtr pkt)
{
- DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize());
- pkt->result = Packet::Success;
+ if (params()->retBadAddr) {
+ DPRINTF(Tsunami, "write to bad address va=%#x size=%d \n",
+ pkt->getAddr(), pkt->getSize());
+ pkt->result = Packet::BadAddress;
+ } else {
+ DPRINTF(Tsunami, "write - va=%#x size=%d \n",
+ pkt->getAddr(), pkt->getSize());
+ pkt->result = Packet::Success;
+ }
return pioDelay;
}
@@ -93,6 +104,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(IsaFake)
Param<Addr> pio_addr;
Param<Tick> pio_latency;
Param<Addr> pio_size;
+ Param<bool> ret_bad_addr;
+ Param<uint8_t> ret_data;
SimObjectParam<Platform *> platform;
SimObjectParam<System *> system;
@@ -103,6 +116,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(IsaFake)
INIT_PARAM(pio_addr, "Device Address"),
INIT_PARAM(pio_latency, "Programmed IO latency"),
INIT_PARAM(pio_size, "Size of address range"),
+ INIT_PARAM(ret_bad_addr, "Return pkt status BadAddr"),
+ INIT_PARAM(ret_data, "Data to return if not bad addr"),
INIT_PARAM(platform, "platform"),
INIT_PARAM(system, "system object")
@@ -115,6 +130,8 @@ CREATE_SIM_OBJECT(IsaFake)
p->pio_addr = pio_addr;
p->pio_delay = pio_latency;
p->pio_size = pio_size;
+ p->retBadAddr = ret_bad_addr;
+ p->retData = ret_data;
p->platform = platform;
p->system = system;
return new IsaFake(p);
diff --git a/src/dev/isa_fake.hh b/src/dev/isa_fake.hh
index 366061c25..fee41e325 100644
--- a/src/dev/isa_fake.hh
+++ b/src/dev/isa_fake.hh
@@ -25,8 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * Authors: Miguel Serrano
- * Ali Saidi
+ * Authors: Ali Saidi
*/
/** @file
@@ -38,14 +37,15 @@
#include "base/range.hh"
#include "dev/io_device.hh"
-#include "dev/tsunami.hh"
+#include "dev/alpha/tsunami.hh"
#include "mem/packet.hh"
/**
- * IsaFake is a device that returns -1 on all reads and
- * accepts all writes. It is meant to be placed at an address range
+ * IsaFake is a device that returns, BadAddr, 1 or 0 on all reads and
+ * rites. It is meant to be placed at an address range
* so that an mcheck doesn't occur when an os probes a piece of hw
- * that doesn't exist (e.g. UARTs1-3).
+ * that doesn't exist (e.g. UARTs1-3), or catch requests in the memory system
+ * that have no responders..
*/
class IsaFake : public BasicPioDevice
{
@@ -53,9 +53,12 @@ class IsaFake : public BasicPioDevice
struct Params : public BasicPioDevice::Params
{
Addr pio_size;
+ bool retBadAddr;
+ uint8_t retData;
};
protected:
const Params *params() const { return (const Params*)_params; }
+ uint64_t retData;
public:
/**
@@ -79,4 +82,4 @@ class IsaFake : public BasicPioDevice
virtual Tick write(PacketPtr pkt);
};
-#endif // __TSUNAMI_FAKE_HH__
+#endif // __ISA_FAKE_HH__
diff --git a/src/dev/ns_gige.cc b/src/dev/ns_gige.cc
index 19c553d87..74f9d88d1 100644
--- a/src/dev/ns_gige.cc
+++ b/src/dev/ns_gige.cc
@@ -36,7 +36,6 @@
#include <deque>
#include <string>
-#include "arch/alpha/ev5.hh"
#include "base/inet.hh"
#include "cpu/thread_context.hh"
#include "dev/etherlink.hh"
diff --git a/src/dev/pcidev.cc b/src/dev/pcidev.cc
index 8c0d03817..383fc494f 100644
--- a/src/dev/pcidev.cc
+++ b/src/dev/pcidev.cc
@@ -45,7 +45,7 @@
#include "base/trace.hh"
#include "dev/pciconfigall.hh"
#include "dev/pcidev.hh"
-#include "dev/tsunamireg.h"
+#include "dev/alpha/tsunamireg.h"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "sim/builder.hh"
diff --git a/src/dev/sparc/SConscript b/src/dev/sparc/SConscript
new file mode 100644
index 000000000..701e533a8
--- /dev/null
+++ b/src/dev/sparc/SConscript
@@ -0,0 +1,46 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2006 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Steve Reinhardt
+# Gabe Black
+
+import os.path, sys
+
+# Import build environment variable from SConstruct.
+Import('env')
+
+sources = []
+
+sources += Split('''
+ ''')
+
+# Convert file names to SCons File objects. This takes care of the
+# path relative to the top of the directory tree.
+sources = [File(s) for s in sources]
+
+Return('sources')
diff --git a/src/dev/uart8250.cc b/src/dev/uart8250.cc
index 9051a26a2..ddee33695 100644
--- a/src/dev/uart8250.cc
+++ b/src/dev/uart8250.cc
@@ -35,7 +35,6 @@
#include <string>
#include <vector>
-#include "arch/alpha/ev5.hh"
#include "base/inifile.hh"
#include "base/str.hh" // for to_number
#include "base/trace.hh"
diff --git a/src/dev/uart8250.hh b/src/dev/uart8250.hh
index 2e768216a..a0620c7e0 100644
--- a/src/dev/uart8250.hh
+++ b/src/dev/uart8250.hh
@@ -35,7 +35,7 @@
#ifndef __DEV_UART8250_HH__
#define __DEV_UART8250_HH__
-#include "dev/tsunamireg.h"
+#include "dev/alpha/tsunamireg.h"
#include "base/range.hh"
#include "dev/io_device.hh"
#include "dev/uart.hh"
diff --git a/src/kern/SConscript b/src/kern/SConscript
new file mode 100644
index 000000000..12df28836
--- /dev/null
+++ b/src/kern/SConscript
@@ -0,0 +1,48 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2006 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Steve Reinhardt
+
+import os.path, sys
+
+# Import build environment variable from SConstruct.
+Import('env')
+
+sources = Split('''
+ kernel_stats.cc
+ system_events.cc
+ linux/events.cc
+ linux/linux_syscalls.cc
+ linux/printk.cc
+ ''')
+
+# Convert file names to SCons File objects. This takes care of the
+# path relative to the top of the directory tree.
+sources = [File(s) for s in sources]
+
+Return('sources')
diff --git a/src/kern/kernel_stats.cc b/src/kern/kernel_stats.cc
index f7868b50f..29c77b3d9 100644
--- a/src/kern/kernel_stats.cc
+++ b/src/kern/kernel_stats.cc
@@ -29,11 +29,8 @@
* Nathan Binkert
*/
-#include <map>
-#include <stack>
#include <string>
-#include "arch/alpha/osfpal.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "kern/kernel_stats.hh"
@@ -45,11 +42,8 @@ using namespace Stats;
namespace Kernel {
-const char *modestr[] = { "kernel", "user", "idle" };
-
Statistics::Statistics(System *system)
- : idleProcess((Addr)-1), themode(kernel), lastModeTick(0),
- iplLast(0), iplLastTick(0)
+ : iplLast(0), iplLastTick(0)
{
}
@@ -68,21 +62,6 @@ Statistics::regStats(const string &_name)
.desc("number of quiesce instructions executed")
;
- _ivlb
- .name(name() + ".inst.ivlb")
- .desc("number of ivlb instructions executed")
- ;
-
- _ivle
- .name(name() + ".inst.ivle")
- .desc("number of ivle instructions executed")
- ;
-
- _hwrei
- .name(name() + ".inst.hwrei")
- .desc("number of hwrei instructions executed")
- ;
-
_iplCount
.init(32)
.name(name() + ".ipl_count")
@@ -112,19 +91,6 @@ Statistics::regStats(const string &_name)
_iplUsed = _iplGood / _iplCount;
- _callpal
- .init(256)
- .name(name() + ".callpal")
- .desc("number of callpals executed")
- .flags(total | pdf | nozero | nonan)
- ;
-
- for (int i = 0; i < PAL::NumCodes; ++i) {
- const char *str = PAL::name(i);
- if (str)
- _callpal.subname(i, str);
- }
-
_syscall
.init(SystemCalls<Tru64>::Number)
.name(name() + ".syscall")
@@ -132,81 +98,15 @@ Statistics::regStats(const string &_name)
.flags(total | pdf | nozero | nonan)
;
+ //@todo This needs to get the names of syscalls from an appropriate place.
+#if 0
for (int i = 0; i < SystemCalls<Tru64>::Number; ++i) {
const char *str = SystemCalls<Tru64>::name(i);
if (str) {
_syscall.subname(i, str);
}
}
-
- _mode
- .init(cpu_mode_num)
- .name(name() + ".mode_switch")
- .desc("number of protection mode switches")
- ;
-
- for (int i = 0; i < cpu_mode_num; ++i)
- _mode.subname(i, modestr[i]);
-
- _modeGood
- .init(cpu_mode_num)
- .name(name() + ".mode_good")
- ;
-
- for (int i = 0; i < cpu_mode_num; ++i)
- _modeGood.subname(i, modestr[i]);
-
- _modeFraction
- .name(name() + ".mode_switch_good")
- .desc("fraction of useful protection mode switches")
- .flags(total)
- ;
-
- for (int i = 0; i < cpu_mode_num; ++i)
- _modeFraction.subname(i, modestr[i]);
-
- _modeFraction = _modeGood / _mode;
-
- _modeTicks
- .init(cpu_mode_num)
- .name(name() + ".mode_ticks")
- .desc("number of ticks spent at the given mode")
- .flags(pdf)
- ;
- for (int i = 0; i < cpu_mode_num; ++i)
- _modeTicks.subname(i, modestr[i]);
-
- _swap_context
- .name(name() + ".swap_context")
- .desc("number of times the context was actually changed")
- ;
-}
-
-void
-Statistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc)
-{
- assert(themode == kernel);
- idleProcess = idlepcbb;
- themode = idle;
- changeMode(themode, tc);
-}
-
-void
-Statistics::changeMode(cpu_mode newmode, ThreadContext *tc)
-{
- _mode[newmode]++;
-
- if (newmode == themode)
- return;
-
- DPRINTF(Context, "old mode=%-8s new mode=%-8s\n",
- modestr[themode], modestr[newmode]);
-
- _modeGood[newmode]++;
- _modeTicks[themode] += curTick - lastModeTick;
-
- lastModeTick = curTick;
- themode = newmode;
+#endif
}
void
@@ -226,65 +126,17 @@ Statistics::swpipl(int ipl)
}
void
-Statistics::mode(cpu_mode newmode, ThreadContext *tc)
-{
- Addr pcbb = tc->readMiscReg(AlphaISA::IPR_PALtemp23);
-
- if (newmode == kernel && pcbb == idleProcess)
- newmode = idle;
-
- changeMode(newmode, tc);
-}
-
-void
-Statistics::context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc)
-{
- assert(themode != user);
-
- _swap_context++;
- changeMode(newpcbb == idleProcess ? idle : kernel, tc);
-}
-
-void
-Statistics::callpal(int code, ThreadContext *tc)
-{
- if (!PAL::name(code))
- return;
-
- _callpal[code]++;
-
- switch (code) {
- case PAL::callsys: {
- int number = tc->readIntReg(0);
- if (SystemCalls<Tru64>::validSyscallNumber(number)) {
- int cvtnum = SystemCalls<Tru64>::convert(number);
- _syscall[cvtnum]++;
- }
- } break;
- }
-}
-
-void
Statistics::serialize(ostream &os)
{
- int exemode = themode;
- SERIALIZE_SCALAR(exemode);
- SERIALIZE_SCALAR(idleProcess);
SERIALIZE_SCALAR(iplLast);
SERIALIZE_SCALAR(iplLastTick);
- SERIALIZE_SCALAR(lastModeTick);
}
void
Statistics::unserialize(Checkpoint *cp, const string &section)
{
- int exemode;
- UNSERIALIZE_SCALAR(exemode);
- UNSERIALIZE_SCALAR(idleProcess);
UNSERIALIZE_SCALAR(iplLast);
UNSERIALIZE_SCALAR(iplLastTick);
- UNSERIALIZE_SCALAR(lastModeTick);
- themode = (cpu_mode)exemode;
}
/* end namespace Kernel */ }
diff --git a/src/kern/kernel_stats.hh b/src/kern/kernel_stats.hh
index c691ad8cf..66248c9c8 100644
--- a/src/kern/kernel_stats.hh
+++ b/src/kern/kernel_stats.hh
@@ -32,12 +32,10 @@
#ifndef __KERNEL_STATS_HH__
#define __KERNEL_STATS_HH__
-#include <map>
-#include <stack>
#include <string>
-#include <vector>
#include "cpu/static_inst.hh"
+#include "sim/serialize.hh"
class BaseCPU;
class ThreadContext;
@@ -47,25 +45,14 @@ class System;
namespace Kernel {
-enum cpu_mode { kernel, user, idle, cpu_mode_num };
-extern const char *modestr[];
-
class Statistics : public Serializable
{
- private:
+ protected:
std::string myname;
- Addr idleProcess;
- cpu_mode themode;
- Tick lastModeTick;
-
- void changeMode(cpu_mode newmode, ThreadContext *tc);
-
- private:
+ protected:
Stats::Scalar<> _arm;
Stats::Scalar<> _quiesce;
- Stats::Scalar<> _ivlb;
- Stats::Scalar<> _ivle;
Stats::Scalar<> _hwrei;
Stats::Vector<> _iplCount;
@@ -73,23 +60,16 @@ class Statistics : public Serializable
Stats::Vector<> _iplTicks;
Stats::Formula _iplUsed;
- Stats::Vector<> _callpal;
Stats::Vector<> _syscall;
// Stats::Vector<> _faults;
- Stats::Vector<> _mode;
- Stats::Vector<> _modeGood;
- Stats::Formula _modeFraction;
- Stats::Vector<> _modeTicks;
-
- Stats::Scalar<> _swap_context;
-
private:
int iplLast;
Tick iplLastTick;
public:
Statistics(System *system);
+ virtual ~Statistics() {}
const std::string name() const { return myname; }
void regStats(const std::string &name);
@@ -97,15 +77,7 @@ class Statistics : public Serializable
public:
void arm() { _arm++; }
void quiesce() { _quiesce++; }
- void ivlb() { _ivlb++; }
- void ivle() { _ivle++; }
- void hwrei() { _hwrei++; }
void swpipl(int ipl);
- void mode(cpu_mode newmode, ThreadContext *tc);
- void context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc);
- void callpal(int code, ThreadContext *tc);
-
- void setIdleProcess(Addr idle, ThreadContext *tc);
public:
virtual void serialize(std::ostream &os);
diff --git a/src/kern/linux/events.cc b/src/kern/linux/events.cc
index 289ece5ce..ba52e040a 100644
--- a/src/kern/linux/events.cc
+++ b/src/kern/linux/events.cc
@@ -49,7 +49,7 @@ DebugPrintkEvent::process(ThreadContext *tc)
DPRINTFN("");
}
- AlphaISA::AlphaArguments args(tc);
+ TheISA::Arguments args(tc);
Printk(args);
SkipFuncEvent::process(tc);
}
diff --git a/src/kern/linux/printk.cc b/src/kern/linux/printk.cc
index 004d1be2f..ea3d59f19 100644
--- a/src/kern/linux/printk.cc
+++ b/src/kern/linux/printk.cc
@@ -39,7 +39,7 @@ using namespace std;
void
-Printk(AlphaISA::AlphaArguments args)
+Printk(TheISA::Arguments args)
{
char *p = (char *)args++;
diff --git a/src/kern/linux/printk.hh b/src/kern/linux/printk.hh
index 5ddf0a018..17d59b765 100644
--- a/src/kern/linux/printk.hh
+++ b/src/kern/linux/printk.hh
@@ -32,8 +32,10 @@
#ifndef __PRINTK_HH__
#define __PRINTK_HH__
-class AlphaISA::AlphaArguments;
+#include "arch/isa_specific.hh"
-void Printk(AlphaISA::AlphaArguments args);
+class TheISA::Arguments;
+
+void Printk(TheISA::Arguments args);
#endif // __PRINTK_HH__
diff --git a/src/kern/system_events.cc b/src/kern/system_events.cc
index 177ce96d1..6fd9e1563 100644
--- a/src/kern/system_events.cc
+++ b/src/kern/system_events.cc
@@ -29,11 +29,11 @@
* Nathan Binkert
*/
-#include "cpu/base.hh"
+//For ISA_HAS_DELAY_SLOT
+#include "arch/isa_traits.hh"
+#include "base/trace.hh"
#include "cpu/thread_context.hh"
-#include "kern/kernel_stats.hh"
#include "kern/system_events.hh"
-#include "sim/system.hh"
using namespace TheISA;
@@ -47,19 +47,7 @@ SkipFuncEvent::process(ThreadContext *tc)
tc->setPC(newpc);
tc->setNextPC(tc->readPC() + sizeof(TheISA::MachInst));
-/*
- BranchPred *bp = tc->getCpuPtr()->getBranchPred();
- if (bp != NULL) {
- bp->popRAS(tc->getThreadNum());
- }
-*/
-}
-
-void
-IdleStartEvent::process(ThreadContext *tc)
-{
- if (tc->getKernelStats())
- tc->getKernelStats()->setIdleProcess(
- tc->readMiscReg(AlphaISA::IPR_PALtemp23), tc);
- remove();
+#if ISA_HAS_DELAY_SLOT
+ tc->setNextPC(tc->readNextPC() + sizeof(TheISA::MachInst));
+#endif
}
diff --git a/src/kern/system_events.hh b/src/kern/system_events.hh
index 93b5eb528..58cbc4808 100644
--- a/src/kern/system_events.hh
+++ b/src/kern/system_events.hh
@@ -35,8 +35,6 @@
#include "cpu/pc_event.hh"
-class System;
-
class SkipFuncEvent : public PCEvent
{
public:
@@ -46,13 +44,4 @@ class SkipFuncEvent : public PCEvent
virtual void process(ThreadContext *tc);
};
-class IdleStartEvent : public PCEvent
-{
- public:
- IdleStartEvent(PCEventQueue *q, const std::string &desc, Addr addr)
- : PCEvent(q, desc, addr)
- {}
- virtual void process(ThreadContext *tc);
-};
-
#endif // __SYSTEM_EVENTS_HH__
diff --git a/src/kern/tru64/dump_mbuf.cc b/src/kern/tru64/dump_mbuf.cc
index 8f88f8904..22d2228f0 100644
--- a/src/kern/tru64/dump_mbuf.cc
+++ b/src/kern/tru64/dump_mbuf.cc
@@ -47,7 +47,7 @@ using namespace TheISA;
namespace tru64 {
void
-DumpMbuf(AlphaArguments args)
+DumpMbuf(Arguments args)
{
ThreadContext *tc = args.getThreadContext();
Addr addr = (Addr)args;
diff --git a/src/kern/tru64/dump_mbuf.hh b/src/kern/tru64/dump_mbuf.hh
index 25c6fd31d..30b1102b9 100644
--- a/src/kern/tru64/dump_mbuf.hh
+++ b/src/kern/tru64/dump_mbuf.hh
@@ -34,7 +34,7 @@
#include "arch/arguments.hh"
namespace tru64 {
- void DumpMbuf(AlphaISA::AlphaArguments args);
+ void DumpMbuf(TheISA::Arguments args);
}
#endif // __DUMP_MBUF_HH__
diff --git a/src/kern/tru64/printf.cc b/src/kern/tru64/printf.cc
index 29dd443d2..2c767c4d2 100644
--- a/src/kern/tru64/printf.cc
+++ b/src/kern/tru64/printf.cc
@@ -42,7 +42,7 @@ using namespace std;
namespace tru64 {
void
-Printf(AlphaISA::AlphaArguments args)
+Printf(TheISA::Arguments args)
{
char *p = (char *)args++;
diff --git a/src/kern/tru64/printf.hh b/src/kern/tru64/printf.hh
index f6a4544ad..ff453b1c1 100644
--- a/src/kern/tru64/printf.hh
+++ b/src/kern/tru64/printf.hh
@@ -34,7 +34,7 @@
#include "arch/arguments.hh"
namespace tru64 {
- void Printf(AlphaISA::AlphaArguments args);
+ void Printf(TheISA::Arguments args);
}
#endif // __PRINTF_HH__
diff --git a/src/kern/tru64/tru64.hh b/src/kern/tru64/tru64.hh
index 6d6d0d96d..82db34bf6 100644
--- a/src/kern/tru64/tru64.hh
+++ b/src/kern/tru64/tru64.hh
@@ -511,7 +511,7 @@ class Tru64 : public OperatingSystem
tc->setFloatRegBits(i, htog(sc->sc_fpregs[i]));
}
- tc->setMiscReg(TheISA::Fpcr_DepTag, htog(sc->sc_fpcr));
+ tc->setMiscReg(AlphaISA::MISCREG_FPCR, htog(sc->sc_fpcr));
return 0;
}
@@ -653,7 +653,7 @@ class Tru64 : public OperatingSystem
ssp->nxm_sysevent = htog(0);
if (i == 0) {
- uint64_t uniq = tc->readMiscReg(TheISA::Uniq_DepTag);
+ uint64_t uniq = tc->readMiscReg(AlphaISA::MISCREG_UNIQ);
ssp->nxm_u.pth_id = htog(uniq + gtoh(attrp->nxm_uniq_offset));
ssp->nxm_u.nxm_active = htog(uniq | 1);
}
@@ -693,7 +693,7 @@ class Tru64 : public OperatingSystem
tc->setIntReg(TheISA::ArgumentReg0, gtoh(attrp->registers.a0));
tc->setIntReg(27/*t12*/, gtoh(attrp->registers.pc));
tc->setIntReg(TheISA::StackPointerReg, gtoh(attrp->registers.sp));
- tc->setMiscReg(TheISA::Uniq_DepTag, uniq_val);
+ tc->setMiscReg(AlphaISA::MISCREG_UNIQ, uniq_val);
tc->setPC(gtoh(attrp->registers.pc));
tc->setNextPC(gtoh(attrp->registers.pc) + sizeof(TheISA::MachInst));
diff --git a/src/kern/tru64/tru64_events.cc b/src/kern/tru64/tru64_events.cc
index 69638bde1..851b3a526 100644
--- a/src/kern/tru64/tru64_events.cc
+++ b/src/kern/tru64/tru64_events.cc
@@ -81,7 +81,7 @@ PrintfEvent::process(ThreadContext *tc)
if (DTRACE(Printf)) {
DebugOut() << curTick << ": " << tc->getCpuPtr()->name() << ": ";
- AlphaArguments args(tc);
+ Arguments args(tc);
tru64::Printf(args);
}
}
@@ -93,7 +93,7 @@ DebugPrintfEvent::process(ThreadContext *tc)
if (!raw)
DebugOut() << curTick << ": " << tc->getCpuPtr()->name() << ": ";
- AlphaArguments args(tc);
+ Arguments args(tc);
tru64::Printf(args);
}
}
@@ -102,7 +102,7 @@ void
DumpMbufEvent::process(ThreadContext *tc)
{
if (DTRACE(DebugPrintf)) {
- AlphaArguments args(tc);
+ Arguments args(tc);
tru64::DumpMbuf(args);
}
}
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index 86a148f87..7b65d252b 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -42,13 +42,14 @@
Port *
Bus::getPort(const std::string &if_name, int idx)
{
- if (if_name == "default")
+ if (if_name == "default") {
if (defaultPort == NULL) {
defaultPort = new BusPort(csprintf("%s-default",name()), this,
- defaultId);
+ defaultId);
return defaultPort;
} else
fatal("Default port already set\n");
+ }
// if_name ignored? forced to be empty?
int id = interfaces.size();
@@ -240,6 +241,9 @@ Bus::recvRetry(int id)
}
}
}
+ //If we weren't able to drain before, we might be able to now.
+ if (drainEvent && retryList.size() == 0 && curTick >= tickNextIdle)
+ drainEvent->process();
}
Port *
@@ -269,7 +273,16 @@ Bus::findPort(Addr addr, int id)
return defaultPort;
}
}
- panic("Unable to find destination for addr: %#llx", addr);
+
+ if (responderSet) {
+ panic("Unable to find destination for addr (user set default "
+ "responder): %#llx", addr);
+ } else {
+ DPRINTF(Bus, "Unable to find destination for addr: %#llx, will use "
+ "default port", addr);
+
+ return defaultPort;
+ }
}
@@ -392,12 +405,15 @@ Bus::recvStatusChange(Port::Status status, int id)
if (id == defaultId) {
defaultRange.clear();
- defaultPort->getPeerAddressRanges(ranges, snoops);
- assert(snoops.size() == 0);
- for(iter = ranges.begin(); iter != ranges.end(); iter++) {
- defaultRange.push_back(*iter);
- DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for default range\n",
- iter->start, iter->end);
+ // Only try to update these ranges if the user set a default responder.
+ if (responderSet) {
+ defaultPort->getPeerAddressRanges(ranges, snoops);
+ assert(snoops.size() == 0);
+ for(iter = ranges.begin(); iter != ranges.end(); iter++) {
+ defaultRange.push_back(*iter);
+ DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for default range\n",
+ iter->start, iter->end);
+ }
}
} else {
@@ -498,23 +514,39 @@ Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id)
}
}
+unsigned int
+Bus::drain(Event * de)
+{
+ //We should check that we're not "doing" anything, and that noone is
+ //waiting. We might be idle but have someone waiting if the device we
+ //contacted for a retry didn't actually retry.
+ if (curTick >= tickNextIdle && retryList.size() == 0) {
+ return 0;
+ } else {
+ drainEvent = de;
+ return 1;
+ }
+}
+
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bus)
Param<int> bus_id;
Param<int> clock;
Param<int> width;
+ Param<bool> responder_set;
END_DECLARE_SIM_OBJECT_PARAMS(Bus)
BEGIN_INIT_SIM_OBJECT_PARAMS(Bus)
INIT_PARAM(bus_id, "a globally unique bus id"),
INIT_PARAM(clock, "bus clock speed"),
- INIT_PARAM(width, "width of the bus (bits)")
+ INIT_PARAM(width, "width of the bus (bits)"),
+ INIT_PARAM(responder_set, "Is a default responder set by the user")
END_INIT_SIM_OBJECT_PARAMS(Bus)
CREATE_SIM_OBJECT(Bus)
{
- return new Bus(getInstanceName(), bus_id, clock, width);
+ return new Bus(getInstanceName(), bus_id, clock, width, responder_set);
}
REGISTER_SIM_OBJECT("Bus", Bus)
diff --git a/src/mem/bus.hh b/src/mem/bus.hh
index 9fb33b7c3..ff1d2545d 100644
--- a/src/mem/bus.hh
+++ b/src/mem/bus.hh
@@ -59,6 +59,8 @@ class Bus : public MemObject
/** the next tick at which the bus will be idle */
Tick tickNextIdle;
+ Event * drainEvent;
+
static const int defaultId = -3; //Make it unique from Broadcast
struct DevMap {
@@ -144,7 +146,7 @@ class Bus : public MemObject
/** Constructor for the BusPort.*/
BusPort(const std::string &_name, Bus *_bus, int _id)
- : Port(_name), _onRetryList(false), bus(_bus), id(_id)
+ : Port(_name, _bus), _onRetryList(false), bus(_bus), id(_id)
{ }
bool onRetryList()
@@ -240,6 +242,9 @@ class Bus : public MemObject
/** Port that handles requests that don't match any of the interfaces.*/
BusPort *defaultPort;
+ /** Has the user specified their own default responder? */
+ bool responderSet;
+
public:
/** A function used to return the port associated with this bus object. */
@@ -247,9 +252,13 @@ class Bus : public MemObject
virtual void init();
- Bus(const std::string &n, int bus_id, int _clock, int _width)
+ unsigned int drain(Event *de);
+
+ Bus(const std::string &n, int bus_id, int _clock, int _width,
+ bool responder_set)
: MemObject(n), busId(bus_id), clock(_clock), width(_width),
- tickNextIdle(0), busIdle(this), inRetry(false), defaultPort(NULL)
+ tickNextIdle(0), drainEvent(NULL), busIdle(this), inRetry(false),
+ defaultPort(NULL), responderSet(responder_set)
{
//Both the width and clock period must be positive
if (width <= 0)
diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc
index 599958222..c26d7782b 100644
--- a/src/mem/cache/base_cache.cc
+++ b/src/mem/cache/base_cache.cc
@@ -42,7 +42,7 @@ using namespace std;
BaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache,
bool _isCpuSide)
- : Port(_name), cache(_cache), isCpuSide(_isCpuSide)
+ : Port(_name, _cache), cache(_cache), isCpuSide(_isCpuSide)
{
blocked = false;
waitingOnRetry = false;
@@ -140,6 +140,9 @@ BaseCache::CachePort::recvRetry()
}
waitingOnRetry = false;
}
+ // Check if we're done draining once this list is empty
+ if (drainList.empty())
+ cache->checkDrain();
}
else if (!isCpuSide)
{
@@ -338,6 +341,10 @@ BaseCache::CacheEvent::process()
cachePort->drainList.push_back(pkt);
cachePort->waitingOnRetry = true;
}
+
+ // Check if we're done draining once this list is empty
+ if (cachePort->drainList.empty())
+ cachePort->cache->checkDrain();
}
const char *
@@ -357,9 +364,7 @@ BaseCache::getPort(const std::string &if_name, int idx)
}
else if (if_name == "functional")
{
- if(cpuSidePort == NULL)
- cpuSidePort = new CachePort(name() + "-cpu_side_port", this, true);
- return cpuSidePort;
+ return new CachePort(name() + "-cpu_side_port", this, true);
}
else if (if_name == "cpu_side")
{
@@ -601,3 +606,18 @@ BaseCache::regStats()
;
}
+
+unsigned int
+BaseCache::drain(Event *de)
+{
+ // Set status
+ if (!canDrain()) {
+ drainEvent = de;
+
+ changeState(SimObject::Draining);
+ return 1;
+ }
+
+ changeState(SimObject::Drained);
+ return 0;
+}
diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh
index 565280aef..ea7544fbb 100644
--- a/src/mem/cache/base_cache.hh
+++ b/src/mem/cache/base_cache.hh
@@ -105,6 +105,8 @@ class BaseCache : public MemObject
void clearBlocked();
+ bool canDrain() { return drainList.empty(); }
+
bool blocked;
bool mustSendRetry;
@@ -227,6 +229,9 @@ class BaseCache : public MemObject
/** The number of misses to trigger an exit event. */
Counter missCount;
+ /** The drain event. */
+ Event *drainEvent;
+
public:
// Statistics
/**
@@ -340,7 +345,7 @@ class BaseCache : public MemObject
BaseCache(const std::string &name, Params &params)
: MemObject(name), blocked(0), blockedSnoop(0), masterRequests(0),
slaveRequests(0), blkSize(params.blkSize),
- missCount(params.maxMisses)
+ missCount(params.maxMisses), drainEvent(NULL)
{
//Start ports at null if more than one is created we should panic
cpuSidePort = NULL;
@@ -477,6 +482,7 @@ class BaseCache : public MemObject
{
uint8_t flag = 1<<cause;
masterRequests &= ~flag;
+ checkDrain();
}
/**
@@ -512,6 +518,7 @@ class BaseCache : public MemObject
{
uint8_t flag = 1<<cause;
slaveRequests &= ~flag;
+ checkDrain();
}
/**
@@ -589,6 +596,30 @@ class BaseCache : public MemObject
return;
}
}
+
+ virtual unsigned int drain(Event *de);
+
+ void checkDrain()
+ {
+ if (drainEvent && canDrain()) {
+ drainEvent->process();
+ changeState(SimObject::Drained);
+ // Clear the drain event
+ drainEvent = NULL;
+ }
+ }
+
+ bool canDrain()
+ {
+ if (doMasterRequest() || doSlaveRequest()) {
+ return false;
+ } else if (memSidePort && !memSidePort->canDrain()) {
+ return false;
+ } else if (cpuSidePort && !cpuSidePort->canDrain()) {
+ return false;
+ }
+ return true;
+ }
};
#endif //__BASE_CACHE_HH__
diff --git a/src/mem/physical.cc b/src/mem/physical.cc
index 0302f7351..39eb63108 100644
--- a/src/mem/physical.cc
+++ b/src/mem/physical.cc
@@ -191,7 +191,9 @@ PhysicalMemory::checkLockedAddrList(Request *req)
void
PhysicalMemory::doFunctionalAccess(PacketPtr pkt)
{
- assert(pkt->getAddr() + pkt->getSize() <= params()->addrRange.size());
+ assert(pkt->getAddr() + pkt->getSize() > params()->addrRange.start &&
+ pkt->getAddr() + pkt->getSize() <= params()->addrRange.start +
+ params()->addrRange.size());
if (pkt->isRead()) {
if (pkt->req->isLocked()) {
diff --git a/src/mem/port.hh b/src/mem/port.hh
index b6eeb9db3..75afc04e6 100644
--- a/src/mem/port.hh
+++ b/src/mem/port.hh
@@ -58,6 +58,8 @@
typedef std::list<Range<Addr> > AddrRangeList;
typedef std::list<Range<Addr> >::iterator AddrRangeIter;
+class MemObject;
+
/**
* Ports are used to interface memory objects to
* each other. They will always come in pairs, and we refer to the other
@@ -81,10 +83,13 @@ class Port
memory objects. */
Port *peer;
+ /** A pointer to the MemObject that owns this port. This may not be set. */
+ MemObject *owner;
+
public:
Port()
- : peer(NULL)
+ : peer(NULL), owner(NULL)
{ }
/**
@@ -92,9 +97,11 @@ class Port
*
* @param _name Port name for DPRINTF output. Should include name
* of memory system object to which the port belongs.
+ * @param _owner Pointer to the MemObject that owns this port.
+ * Will not necessarily be set.
*/
- Port(const std::string &_name)
- : portName(_name), peer(NULL)
+ Port(const std::string &_name, MemObject *_owner = NULL)
+ : portName(_name), peer(NULL), owner(_owner)
{ }
/** Return port name (for DPRINTF). */
@@ -112,16 +119,18 @@ class Port
void setName(const std::string &name)
{ portName = name; }
- /** Function to set the pointer for the peer port.
- @todo should be called by the configuration stuff (python).
- */
+ /** Function to set the pointer for the peer port. */
void setPeer(Port *port);
- /** Function to set the pointer for the peer port.
- @todo should be called by the configuration stuff (python).
- */
+ /** Function to get the pointer to the peer port. */
Port *getPeer() { return peer; }
+ /** Function to set the owner of this port. */
+ void setOwner(MemObject *_owner) { owner = _owner; }
+
+ /** Function to return the owner of this port. */
+ MemObject *getOwner() { return owner; }
+
protected:
/** These functions are protected because they should only be
@@ -247,8 +256,8 @@ class Port
class FunctionalPort : public Port
{
public:
- FunctionalPort(const std::string &_name)
- : Port(_name)
+ FunctionalPort(const std::string &_name, MemObject *_owner = NULL)
+ : Port(_name, _owner)
{}
protected:
diff --git a/src/mem/port_impl.hh b/src/mem/port_impl.hh
index b7980bdd2..989cfd338 100644
--- a/src/mem/port_impl.hh
+++ b/src/mem/port_impl.hh
@@ -28,6 +28,9 @@
* Authors: Ali Saidi
*/
+//To get endianness
+#include "arch/isa_traits.hh"
+
#include "mem/port.hh"
#include "sim/byteswap.hh"
@@ -35,7 +38,7 @@ template <typename T>
void
FunctionalPort::writeHtoG(Addr addr, T d)
{
- d = htog(d);
+ d = TheISA::htog(d);
writeBlob(addr, (uint8_t*)&d, sizeof(T));
}
@@ -46,6 +49,6 @@ FunctionalPort::readGtoH(Addr addr)
{
T d;
readBlob(addr, (uint8_t*)&d, sizeof(T));
- return gtoh(d);
+ return TheISA::gtoh(d);
}
diff --git a/src/mem/tport.hh b/src/mem/tport.hh
index 438ec56dc..3d28ea3e5 100644
--- a/src/mem/tport.hh
+++ b/src/mem/tport.hh
@@ -114,8 +114,8 @@ class SimpleTimingPort : public Port
public:
- SimpleTimingPort(std::string pname)
- : Port(pname), sendEvent(this), drainEvent(NULL)
+ SimpleTimingPort(std::string pname, MemObject *_owner = NULL)
+ : Port(pname, _owner), sendEvent(this), drainEvent(NULL)
{}
/** Hook for draining timing accesses from the system. The
diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py
index d41fd5a61..579562b38 100644
--- a/src/python/m5/__init__.py
+++ b/src/python/m5/__init__.py
@@ -39,6 +39,9 @@ from cc_main import simulate, SimLoopExitEvent
# import the m5 compile options
import defines
+# define a MaxTick parameter
+MaxTick = 2**63 - 1
+
# define this here so we can use it right away if necessary
def panic(string):
print >>sys.stderr, 'panic:', string
@@ -171,10 +174,10 @@ def switchCpus(cpuList):
for cpu in old_cpus:
if not isinstance(cpu, objects.BaseCPU):
- raise TypeError, "%s is not of type BaseCPU", cpu
+ raise TypeError, "%s is not of type BaseCPU" % cpu
for cpu in new_cpus:
if not isinstance(cpu, objects.BaseCPU):
- raise TypeError, "%s is not of type BaseCPU", cpu
+ raise TypeError, "%s is not of type BaseCPU" % cpu
# Drain all of the individual CPUs
drain_event = cc_main.createCountedDrain()
diff --git a/src/python/m5/main.py b/src/python/m5/main.py
index ccd6c5807..ef37f62ac 100644
--- a/src/python/m5/main.py
+++ b/src/python/m5/main.py
@@ -181,6 +181,8 @@ bool_option("print-cpseq", default=False,
help="Print correct path sequence numbers in trace output")
#bool_option("print-reg-delta", default=False,
# help="Print which registers changed to what in trace output")
+bool_option("legion-lock", default=False,
+ help="Compare simulator state with Legion simulator every cycle")
options = attrdict()
arguments = []
@@ -296,6 +298,7 @@ def main():
objects.ExecutionTrace.print_fetchseq = options.print_fetch_seq
objects.ExecutionTrace.print_cpseq = options.print_cpseq
#objects.ExecutionTrace.print_reg_delta = options.print_reg_delta
+ objects.ExecutionTrace.legion_lockstep = options.legion_lock
sys.argv = arguments
sys.path = [ os.path.dirname(sys.argv[0]) ] + sys.path
diff --git a/src/python/m5/objects/BaseCPU.py b/src/python/m5/objects/BaseCPU.py
index b6dc08e46..b6e05627d 100644
--- a/src/python/m5/objects/BaseCPU.py
+++ b/src/python/m5/objects/BaseCPU.py
@@ -3,19 +3,27 @@ from m5.params import *
from m5.proxy import *
from m5 import build_env
from AlphaTLB import AlphaDTB, AlphaITB
+from SparcTLB import SparcDTB, SparcITB
from Bus import Bus
+import sys
class BaseCPU(SimObject):
type = 'BaseCPU'
abstract = True
- mem = Param.MemObject("memory")
system = Param.System(Parent.any, "system object")
cpu_id = Param.Int("CPU identifier")
if build_env['FULL_SYSTEM']:
- dtb = Param.AlphaDTB(AlphaDTB(), "Data TLB")
- itb = Param.AlphaITB(AlphaITB(), "Instruction TLB")
+ if build_env['TARGET_ISA'] == 'sparc':
+ dtb = Param.SparcDTB(SparcDTB(), "Data TLB")
+ itb = Param.SparcITB(SparcITB(), "Instruction TLB")
+ elif build_env['TARGET_ISA'] == 'alpha':
+ dtb = Param.AlphaDTB(AlphaDTB(), "Data TLB")
+ itb = Param.AlphaITB(AlphaITB(), "Instruction TLB")
+ else:
+ print "Unknown architecture, can't pick TLBs"
+ sys.exit(1)
else:
workload = VectorParam.Process("processes to run")
@@ -47,7 +55,6 @@ class BaseCPU(SimObject):
self.icache_port = ic.cpu_side
self.dcache_port = dc.cpu_side
self._mem_ports = ['icache.mem_side', 'dcache.mem_side']
-# self.mem = dc
def addTwoLevelCacheHierarchy(self, ic, dc, l2c):
self.addPrivateSplitL1Caches(ic, dc)
diff --git a/src/python/m5/objects/Bus.py b/src/python/m5/objects/Bus.py
index 6710111e5..e7019f3ac 100644
--- a/src/python/m5/objects/Bus.py
+++ b/src/python/m5/objects/Bus.py
@@ -1,10 +1,18 @@
+from m5 import build_env
from m5.params import *
+from m5.proxy import *
from MemObject import MemObject
+from Tsunami import BadAddr
class Bus(MemObject):
type = 'Bus'
port = VectorPort("vector port for connecting devices")
- default = Port("Default port for requests that aren't handeled by a device.")
bus_id = Param.Int(0, "blah")
clock = Param.Clock("1GHz", "bus clock speed")
width = Param.Int(64, "bus width (bytes)")
+ responder_set = Param.Bool(False, "Did the user specify a default responder.")
+ if build_env['FULL_SYSTEM']:
+ default = Port(Self.responder.pio, "Default port for requests that aren't handled by a device.")
+ responder = BadAddr(pio_addr=0x0, pio_latency="1ps")
+ else:
+ default = Port("Default port for requests that aren't handled by a device.")
diff --git a/src/python/m5/objects/Pci.py b/src/python/m5/objects/Pci.py
index 55bf23534..9d40adbfe 100644
--- a/src/python/m5/objects/Pci.py
+++ b/src/python/m5/objects/Pci.py
@@ -57,6 +57,3 @@ class PciDevice(DmaDevice):
pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
configdata = Param.PciConfigData(Parent.any, "PCI Config data")
config_latency = Param.Latency('20ns', "Config read or write latency")
-
-class PciFake(PciDevice):
- type = 'PciFake'
diff --git a/src/python/m5/objects/SparcTLB.py b/src/python/m5/objects/SparcTLB.py
new file mode 100644
index 000000000..de732e8de
--- /dev/null
+++ b/src/python/m5/objects/SparcTLB.py
@@ -0,0 +1,14 @@
+from m5.SimObject import SimObject
+from m5.params import *
+class SparcTLB(SimObject):
+ type = 'SparcTLB'
+ abstract = True
+ size = Param.Int("TLB size")
+
+class SparcDTB(SparcTLB):
+ type = 'SparcDTB'
+ size = 64
+
+class SparcITB(SparcTLB):
+ type = 'SparcITB'
+ size = 48
diff --git a/src/python/m5/objects/System.py b/src/python/m5/objects/System.py
index e7dd1bc60..908c3d4ad 100644
--- a/src/python/m5/objects/System.py
+++ b/src/python/m5/objects/System.py
@@ -2,6 +2,7 @@ from m5.SimObject import SimObject
from m5.params import *
from m5.proxy import *
from m5 import build_env
+from PhysicalMemory import *
class MemoryMode(Enum): vals = ['invalid', 'atomic', 'timing']
@@ -24,3 +25,21 @@ class AlphaSystem(System):
pal = Param.String("file that contains palcode")
system_type = Param.UInt64("Type of system we are emulating")
system_rev = Param.UInt64("Revision of system we are emulating")
+
+class SparcSystem(System):
+ type = 'SparcSystem'
+ _rom_base = 0xfff0000000
+ # ROM for OBP/Reset/Hypervisor
+ rom = Param.PhysicalMemory(PhysicalMemory(range = AddrRange(_rom_base, size = '8MB')),
+ "Memory to hold the ROM data")
+
+ reset_addr = Param.Addr(_rom_base, "Address to load ROM at")
+ hypervisor_addr = Param.Addr(Addr('64kB') + _rom_base,
+ "Address to load hypervisor at")
+ openboot_addr = Param.Addr(Addr('512kB') + _rom_base,
+ "Address to load openboot at")
+
+ reset_bin = Param.String("file that contains the reset code")
+ hypervisor_bin = Param.String("file that contains the hypervisor code")
+ openboot_bin = Param.String("file that contains the openboot code")
+
diff --git a/src/python/m5/objects/Tsunami.py b/src/python/m5/objects/Tsunami.py
index 0b53153a0..ffe93727b 100644
--- a/src/python/m5/objects/Tsunami.py
+++ b/src/python/m5/objects/Tsunami.py
@@ -14,6 +14,11 @@ class TsunamiCChip(BasicPioDevice):
class IsaFake(BasicPioDevice):
type = 'IsaFake'
pio_size = Param.Addr(0x8, "Size of address range")
+ ret_data = Param.UInt8(0xFF, "Default data to return")
+ ret_bad_addr = Param.Bool(False, "Return pkt status bad address on access")
+
+class BadAddr(IsaFake):
+ ret_bad_addr = Param.Bool(True, "Return pkt status bad address on access")
class TsunamiIO(BasicPioDevice):
type = 'TsunamiIO'
@@ -70,6 +75,8 @@ class Tsunami(Platform):
self.cchip.pio = bus.port
self.pchip.pio = bus.port
self.pciconfig.pio = bus.default
+ bus.responder_set = True
+ bus.responder = self.pciconfig
self.fake_sm_chip.pio = bus.port
self.fake_uart1.pio = bus.port
self.fake_uart2.pio = bus.port
diff --git a/src/python/m5/params.py b/src/python/m5/params.py
index 93d784181..4b5953bcb 100644
--- a/src/python/m5/params.py
+++ b/src/python/m5/params.py
@@ -369,6 +369,11 @@ class Addr(CheckedInt):
except TypeError:
self.value = long(value)
self._check()
+ def __add__(self, other):
+ if isinstance(other, Addr):
+ return self.value + other.value
+ else:
+ return self.value + other
class MetaRange(type):
diff --git a/src/sim/byteswap.hh b/src/sim/byteswap.hh
index 7648b8fcd..7b1ae701e 100644
--- a/src/sim/byteswap.hh
+++ b/src/sim/byteswap.hh
@@ -47,6 +47,8 @@
// If one doesn't exist, we pretty much get what is listed below, so it all
// works out
#include <byteswap.h>
+#elif defined (__sun__)
+#include <sys/isa_defs.h>
#else
#include <machine/endian.h>
#endif
@@ -128,12 +130,12 @@ template <typename T> static inline T letobe(T value) {return swap_byte(value);}
//For conversions not involving the guest system, we can define the functions
//conditionally based on the BYTE_ORDER macro and outside of the namespaces
-#if BYTE_ORDER == BIG_ENDIAN
+#if defined(_BIG_ENDIAN) || BYTE_ORDER == BIG_ENDIAN
template <typename T> static inline T htole(T value) {return swap_byte(value);}
template <typename T> static inline T letoh(T value) {return swap_byte(value);}
template <typename T> static inline T htobe(T value) {return value;}
template <typename T> static inline T betoh(T value) {return value;}
-#elif BYTE_ORDER == LITTLE_ENDIAN
+#elif defined(_LITTLE_ENDIAN) || BYTE_ORDER == LITTLE_ENDIAN
template <typename T> static inline T htole(T value) {return value;}
template <typename T> static inline T letoh(T value) {return value;}
template <typename T> static inline T htobe(T value) {return swap_byte(value);}
diff --git a/src/sim/host.hh b/src/sim/host.hh
index 9c79580b1..a2faa206b 100644
--- a/src/sim/host.hh
+++ b/src/sim/host.hh
@@ -56,7 +56,7 @@ typedef int64_t Counter;
*/
typedef int64_t Tick;
-const Tick MaxTick = (1LL << 62);
+const Tick MaxTick = (1LL << 63) - 1;
/**
* Address type
diff --git a/src/sim/main.cc b/src/sim/main.cc
index 133141e57..5b44102a8 100644
--- a/src/sim/main.cc
+++ b/src/sim/main.cc
@@ -309,18 +309,14 @@ finalInit()
* @return The SimLoopExitEvent that caused the loop to exit.
*/
SimLoopExitEvent *
-simulate(Tick num_cycles = -1)
+simulate(Tick num_cycles = MaxTick)
{
warn("Entering event queue @ %d. Starting simulation...\n", curTick);
- // Fix up num_cycles. Special default value -1 means simulate
- // "forever"... schedule event at MaxTick just to be safe.
- // Otherwise it's a delta for additional cycles to simulate past
- // curTick, and thus must be non-negative.
- if (num_cycles == -1)
- num_cycles = MaxTick;
- else if (num_cycles < 0)
+ if (num_cycles < 0)
fatal("simulate: num_cycles must be >= 0 (was %d)\n", num_cycles);
+ else if (curTick + num_cycles < 0) //Overflow
+ num_cycles = MaxTick;
else
num_cycles = curTick + num_cycles;
diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc
index d913e159b..66036def1 100644
--- a/src/sim/pseudo_inst.cc
+++ b/src/sim/pseudo_inst.cc
@@ -34,14 +34,14 @@
#include <string>
-#include "sim/pseudo_inst.hh"
#include "arch/vtophys.hh"
#include "base/annotate.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "cpu/quiesce_event.hh"
-#include "kern/kernel_stats.hh"
+#include "arch/kernel_stats.hh"
#include "sim/param.hh"
+#include "sim/pseudo_inst.hh"
#include "sim/serialize.hh"
#include "sim/sim_exit.hh"
#include "sim/stat_control.hh"
@@ -134,18 +134,6 @@ namespace AlphaPseudo
}
void
- ivlb(ThreadContext *tc)
- {
- if (tc->getKernelStats())
- tc->getKernelStats()->ivlb();
- }
-
- void
- ivle(ThreadContext *tc)
- {
- }
-
- void
m5exit_old(ThreadContext *tc)
{
exitSimLoop("m5_exit_old instruction encountered");
diff --git a/src/sim/pseudo_inst.hh b/src/sim/pseudo_inst.hh
index d211de44e..bc71a7e64 100644
--- a/src/sim/pseudo_inst.hh
+++ b/src/sim/pseudo_inst.hh
@@ -47,8 +47,6 @@ namespace AlphaPseudo
void quiesceNs(ThreadContext *tc, uint64_t ns);
void quiesceCycles(ThreadContext *tc, uint64_t cycles);
uint64_t quiesceTime(ThreadContext *tc);
- void ivlb(ThreadContext *tc);
- void ivle(ThreadContext *tc);
void m5exit(ThreadContext *tc, Tick delay);
void m5exit_old(ThreadContext *tc);
void loadsymbol(ThreadContext *xc);
diff --git a/src/sim/system.cc b/src/sim/system.cc
index 11ae492b9..4b42d41fc 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -43,7 +43,7 @@
#include "sim/system.hh"
#if FULL_SYSTEM
#include "arch/vtophys.hh"
-#include "base/remote_gdb.hh"
+#include "arch/remote_gdb.hh"
#include "kern/kernel_stats.hh"
#endif
diff --git a/src/sim/system.hh b/src/sim/system.hh
index 827fe5c78..b3a67bf7a 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -56,7 +56,10 @@ class PhysicalMemory;
#if FULL_SYSTEM
class Platform;
class GDBListener;
-class RemoteGDB;
+namespace TheISA
+{
+ class RemoteGDB;
+}
#endif
class System : public SimObject
@@ -157,7 +160,7 @@ class System : public SimObject
#endif
public:
#if FULL_SYSTEM
- std::vector<RemoteGDB *> remoteGDB;
+ std::vector<TheISA::RemoteGDB *> remoteGDB;
std::vector<GDBListener *> gdbListen;
virtual bool breakpoint() = 0;
#endif // FULL_SYSTEM