summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/SConscript245
-rw-r--r--src/arch/SConscript24
-rw-r--r--src/arch/alpha/SConscript101
-rw-r--r--src/arch/alpha/SConsopts37
-rw-r--r--src/arch/alpha/arguments.hh1
-rw-r--r--src/arch/alpha/ev5.cc28
-rw-r--r--src/arch/alpha/faults.cc54
-rw-r--r--src/arch/alpha/faults.hh23
-rw-r--r--src/arch/alpha/idle_event.cc2
-rw-r--r--src/arch/alpha/interrupts.hh26
-rw-r--r--src/arch/alpha/isa/decoder.isa57
-rw-r--r--src/arch/alpha/isa/fp.isa4
-rw-r--r--src/arch/alpha/isa/mem.isa77
-rw-r--r--src/arch/alpha/kernel_stats.cc2
-rw-r--r--src/arch/alpha/linux/linux.hh18
-rw-r--r--src/arch/alpha/linux/process.hh3
-rw-r--r--src/arch/alpha/locked_mem.hh22
-rw-r--r--src/arch/alpha/miscregfile.cc8
-rw-r--r--src/arch/alpha/miscregfile.hh8
-rw-r--r--src/arch/alpha/predecoder.hh108
-rw-r--r--src/arch/alpha/regfile.cc16
-rw-r--r--src/arch/alpha/regfile.hh16
-rw-r--r--src/arch/alpha/remote_gdb.cc2
-rw-r--r--src/arch/alpha/stacktrace.cc14
-rw-r--r--src/arch/alpha/tlb.cc39
-rw-r--r--src/arch/alpha/tru64/tru64.hh18
-rw-r--r--src/arch/alpha/types.hh1
-rw-r--r--src/arch/alpha/utility.hh18
-rw-r--r--src/arch/alpha/vtophys.cc53
-rw-r--r--src/arch/alpha/vtophys.hh5
-rwxr-xr-xsrc/arch/isa_parser.py41
-rw-r--r--src/arch/isa_specific.hh11
-rw-r--r--src/arch/mips/SConscript73
-rw-r--r--src/arch/mips/SConsopts33
-rw-r--r--src/arch/mips/faults.cc26
-rw-r--r--src/arch/mips/faults.hh24
-rw-r--r--src/arch/mips/isa/decoder.isa7
-rw-r--r--src/arch/mips/isa/formats/mem.isa71
-rw-r--r--src/arch/mips/isa/formats/util.isa6
-rw-r--r--src/arch/mips/linux/linux.hh18
-rw-r--r--src/arch/mips/predecoder.hh100
-rw-r--r--src/arch/mips/regfile/misc_regfile.hh8
-rw-r--r--src/arch/mips/regfile/regfile.hh16
-rw-r--r--src/arch/mips/types.hh2
-rw-r--r--src/arch/mips/utility.hh16
-rw-r--r--src/arch/sparc/SConscript87
-rw-r--r--src/arch/sparc/SConsopts33
-rw-r--r--src/arch/sparc/arguments.hh2
-rw-r--r--src/arch/sparc/asi.cc7
-rw-r--r--src/arch/sparc/asi.hh1
-rw-r--r--src/arch/sparc/faults.cc156
-rw-r--r--src/arch/sparc/faults.hh19
-rw-r--r--src/arch/sparc/handlers.hh190
-rw-r--r--src/arch/sparc/interrupts.hh167
-rw-r--r--src/arch/sparc/intregfile.hh2
-rw-r--r--src/arch/sparc/isa/base.isa4
-rw-r--r--src/arch/sparc/isa/bitfields.isa1
-rw-r--r--src/arch/sparc/isa/decoder.isa365
-rw-r--r--src/arch/sparc/isa/formats/branch.isa10
-rw-r--r--src/arch/sparc/isa/formats/mem/basicmem.isa28
-rw-r--r--src/arch/sparc/isa/formats/mem/blockmem.isa212
-rw-r--r--src/arch/sparc/isa/formats/mem/mem.isa4
-rw-r--r--src/arch/sparc/isa/formats/mem/swap.isa183
-rw-r--r--src/arch/sparc/isa/formats/mem/util.isa16
-rw-r--r--src/arch/sparc/isa/includes.isa5
-rw-r--r--src/arch/sparc/isa/operands.isa8
-rw-r--r--src/arch/sparc/isa_traits.hh17
-rw-r--r--src/arch/sparc/linux/linux.hh28
-rw-r--r--src/arch/sparc/linux/process.cc424
-rw-r--r--src/arch/sparc/linux/process.hh61
-rw-r--r--src/arch/sparc/linux/syscalls.cc681
-rw-r--r--src/arch/sparc/miscregfile.cc42
-rw-r--r--src/arch/sparc/miscregfile.hh35
-rw-r--r--src/arch/sparc/pagetable.hh21
-rw-r--r--src/arch/sparc/predecoder.hh113
-rw-r--r--src/arch/sparc/process.cc437
-rw-r--r--src/arch/sparc/process.hh122
-rw-r--r--src/arch/sparc/regfile.cc263
-rw-r--r--src/arch/sparc/regfile.hh10
-rw-r--r--src/arch/sparc/remote_gdb.cc48
-rw-r--r--src/arch/sparc/remote_gdb.hh25
-rw-r--r--src/arch/sparc/stacktrace.cc14
-rw-r--r--src/arch/sparc/syscallreturn.hh4
-rw-r--r--src/arch/sparc/tlb.cc380
-rw-r--r--src/arch/sparc/tlb.hh19
-rw-r--r--src/arch/sparc/types.hh2
-rw-r--r--src/arch/sparc/ua2005.cc188
-rw-r--r--src/arch/sparc/utility.hh35
-rw-r--r--src/arch/sparc/vtophys.cc94
-rw-r--r--src/arch/sparc/vtophys.hh5
-rw-r--r--src/arch/x86/SConscript111
-rw-r--r--src/arch/x86/SConsopts60
-rw-r--r--src/arch/x86/arguments.hh67
-rw-r--r--src/arch/x86/faults.hh90
-rw-r--r--src/arch/x86/floatregfile.cc141
-rw-r--r--src/arch/x86/floatregfile.hh137
-rw-r--r--src/arch/x86/interrupts.hh67
-rw-r--r--src/arch/x86/intregfile.cc138
-rw-r--r--src/arch/x86/intregfile.hh130
-rw-r--r--src/arch/x86/intregs.hh85
-rw-r--r--src/arch/x86/isa/base.isa181
-rw-r--r--src/arch/x86/isa/bitfields.isa87
-rw-r--r--src/arch/x86/isa/decoder/decoder.isa89
-rw-r--r--src/arch/x86/isa/decoder/one_byte_opcodes.isa398
-rw-r--r--src/arch/x86/isa/decoder/two_byte_opcodes.isa393
-rw-r--r--src/arch/x86/isa/formats/basic.isa158
-rw-r--r--src/arch/x86/isa/formats/error.isa77
-rw-r--r--src/arch/x86/isa/formats/formats.isa100
-rw-r--r--src/arch/x86/isa/formats/multi.isa106
-rw-r--r--src/arch/x86/isa/formats/unimp.isa174
-rw-r--r--src/arch/x86/isa/formats/unknown.isa130
-rw-r--r--src/arch/x86/isa/includes.isa143
-rw-r--r--src/arch/x86/isa/main.isa88
-rw-r--r--src/arch/x86/isa/operands.isa102
-rw-r--r--src/arch/x86/isa_traits.hh129
-rw-r--r--src/arch/x86/kernel_stats.hh67
-rw-r--r--src/arch/x86/linux/linux.cc98
-rw-r--r--src/arch/x86/linux/linux.hh109
-rw-r--r--src/arch/x86/linux/process.cc109
-rw-r--r--src/arch/x86/linux/process.hh95
-rw-r--r--src/arch/x86/linux/syscalls.cc356
-rw-r--r--src/arch/x86/locked_mem.hh58
-rw-r--r--src/arch/x86/miscregfile.cc135
-rw-r--r--src/arch/x86/miscregfile.hh133
-rw-r--r--src/arch/x86/mmaped_ipr.hh90
-rw-r--r--src/arch/x86/pagetable.hh76
-rw-r--r--src/arch/x86/predecoder.cc358
-rw-r--r--src/arch/x86/predecoder.hh225
-rw-r--r--src/arch/x86/predecoder_tables.cc222
-rw-r--r--src/arch/x86/process.cc359
-rw-r--r--src/arch/x86/process.hh108
-rw-r--r--src/arch/x86/regfile.cc252
-rw-r--r--src/arch/x86/regfile.hh160
-rw-r--r--src/arch/x86/remote_gdb.cc189
-rw-r--r--src/arch/x86/remote_gdb.hh94
-rw-r--r--src/arch/x86/stacktrace.hh122
-rw-r--r--src/arch/x86/syscallreturn.hh75
-rw-r--r--src/arch/x86/tlb.hh67
-rw-r--r--src/arch/x86/types.hh198
-rw-r--r--src/arch/x86/utility.hh143
-rw-r--r--src/arch/x86/vtophys.hh79
-rw-r--r--src/arch/x86/x86_traits.hh70
-rw-r--r--src/base/SConscript83
-rw-r--r--src/base/annotate.cc2
-rw-r--r--src/base/bigint.cc47
-rw-r--r--src/base/bigint.hh97
-rw-r--r--src/base/bitfield.hh294
-rw-r--r--src/base/cprintf.cc427
-rw-r--r--src/base/cprintf.hh205
-rw-r--r--src/base/cprintf_formats.hh4
-rw-r--r--src/base/loader/elf_object.cc15
-rw-r--r--src/base/loader/object_file.hh6
-rw-r--r--src/base/misc.cc90
-rw-r--r--src/base/misc.hh71
-rw-r--r--src/base/pollevent.cc2
-rw-r--r--src/base/pollevent.hh2
-rw-r--r--src/base/random.cc48
-rw-r--r--src/base/random.hh18
-rw-r--r--src/base/statistics.hh19
-rw-r--r--src/base/stats/events.cc131
-rw-r--r--src/base/stats/events.hh10
-rw-r--r--src/base/stats/mysql.cc253
-rw-r--r--src/base/stats/mysql.hh60
-rw-r--r--src/base/stats/output.cc70
-rw-r--r--src/base/stats/output.hh1
-rw-r--r--src/base/stats/text.cc22
-rw-r--r--src/base/stats/text.hh6
-rw-r--r--src/base/trace.cc283
-rw-r--r--src/base/trace.hh175
-rw-r--r--src/base/traceflags.py304
-rw-r--r--src/base/varargs.hh292
-rw-r--r--src/cpu/SConscript116
-rw-r--r--src/cpu/base.cc35
-rw-r--r--src/cpu/base.hh12
-rw-r--r--src/cpu/checker/cpu.cc4
-rw-r--r--src/cpu/checker/cpu.hh16
-rw-r--r--src/cpu/checker/cpu_impl.hh10
-rw-r--r--src/cpu/checker/thread_context.hh16
-rw-r--r--src/cpu/exec_context.hh8
-rw-r--r--src/cpu/exetrace.cc388
-rw-r--r--src/cpu/exetrace.hh68
-rw-r--r--src/cpu/intr_control.cc22
-rw-r--r--src/cpu/intr_control.hh4
-rw-r--r--src/cpu/memtest/SConscript34
-rw-r--r--src/cpu/memtest/memtest.cc12
-rwxr-xr-xsrc/cpu/o3/SConscript86
-rw-r--r--src/cpu/o3/SConsopts34
-rw-r--r--src/cpu/o3/alpha/cpu.hh8
-rw-r--r--src/cpu/o3/alpha/cpu_impl.hh18
-rw-r--r--src/cpu/o3/alpha/dyn_inst.hh32
-rw-r--r--src/cpu/o3/alpha/dyn_inst_impl.hh2
-rw-r--r--src/cpu/o3/commit_impl.hh3
-rw-r--r--src/cpu/o3/cpu.cc41
-rw-r--r--src/cpu/o3/cpu.hh4
-rw-r--r--src/cpu/o3/dyn_inst.hh4
-rw-r--r--src/cpu/o3/fetch.hh4
-rw-r--r--src/cpu/o3/fetch_impl.hh16
-rw-r--r--src/cpu/o3/inst_queue_impl.hh2
-rw-r--r--src/cpu/o3/lsq.hh7
-rw-r--r--src/cpu/o3/lsq_impl.hh13
-rw-r--r--src/cpu/o3/lsq_unit.hh5
-rw-r--r--src/cpu/o3/lsq_unit_impl.hh3
-rwxr-xr-xsrc/cpu/o3/mips/cpu.hh8
-rw-r--r--src/cpu/o3/mips/cpu_impl.hh16
-rwxr-xr-xsrc/cpu/o3/mips/dyn_inst.hh16
-rw-r--r--src/cpu/o3/regfile.hh16
-rw-r--r--src/cpu/o3/sparc/cpu.hh8
-rw-r--r--src/cpu/o3/sparc/cpu_impl.hh16
-rw-r--r--src/cpu/o3/sparc/dyn_inst.hh32
-rwxr-xr-xsrc/cpu/o3/thread_context.hh12
-rwxr-xr-xsrc/cpu/o3/thread_context_impl.hh10
-rw-r--r--src/cpu/ozone/SConscript45
-rw-r--r--src/cpu/ozone/SConsopts33
-rw-r--r--src/cpu/ozone/cpu.hh6
-rw-r--r--src/cpu/ozone/cpu_impl.hh18
-rw-r--r--src/cpu/ozone/dyn_inst.hh6
-rw-r--r--src/cpu/ozone/dyn_inst_impl.hh18
-rw-r--r--src/cpu/ozone/inorder_back_end_impl.hh14
-rw-r--r--src/cpu/ozone/inst_queue_impl.hh2
-rw-r--r--src/cpu/ozone/lw_back_end_impl.hh2
-rw-r--r--src/cpu/ozone/lw_lsq_impl.hh6
-rw-r--r--src/cpu/ozone/thread_state.hh16
-rw-r--r--src/cpu/pc_event.cc4
-rw-r--r--src/cpu/simple/SConscript43
-rw-r--r--src/cpu/simple/SConsopts34
-rw-r--r--src/cpu/simple/atomic.cc105
-rw-r--r--src/cpu/simple/atomic.hh18
-rw-r--r--src/cpu/simple/base.cc62
-rw-r--r--src/cpu/simple/base.hh47
-rw-r--r--src/cpu/simple/timing.cc87
-rw-r--r--src/cpu/simple/timing.hh2
-rw-r--r--src/cpu/simple_thread.cc2
-rw-r--r--src/cpu/simple_thread.hh16
-rw-r--r--src/cpu/static_inst.cc2
-rw-r--r--src/cpu/static_inst.hh6
-rw-r--r--src/cpu/thread_context.hh21
-rw-r--r--src/cpu/thread_state.cc10
-rw-r--r--src/cpu/trace/SConscript40
-rw-r--r--src/dev/SConscript74
-rw-r--r--src/dev/alpha/SConscript43
-rw-r--r--src/dev/alpha/tsunami_cchip.cc12
-rw-r--r--src/dev/alpha/tsunamireg.h21
-rw-r--r--src/dev/etherbus.cc2
-rw-r--r--src/dev/etherdump.cc2
-rw-r--r--src/dev/etherlink.cc2
-rw-r--r--src/dev/i8254xGBe.cc1122
-rw-r--r--src/dev/i8254xGBe.hh420
-rw-r--r--src/dev/i8254xGBe_defs.hh957
-rw-r--r--src/dev/ide_disk.cc2
-rw-r--r--src/dev/io_device.hh14
-rw-r--r--src/dev/ns_gige.cc26
-rw-r--r--src/dev/pcidev.cc2
-rw-r--r--src/dev/platform.hh3
-rw-r--r--src/dev/simconsole.cc224
-rw-r--r--src/dev/simconsole.hh76
-rw-r--r--src/dev/sparc/SConscript23
-rw-r--r--src/dev/sparc/iob.cc402
-rw-r--r--src/dev/sparc/iob.hh153
-rw-r--r--src/dev/sparc/mm_disk.cc2
-rw-r--r--src/dev/uart.cc1
-rw-r--r--src/dev/uart8250.hh13
-rw-r--r--src/kern/SConscript27
-rw-r--r--src/kern/linux/printk.cc61
-rw-r--r--src/kern/tru64/dump_mbuf.cc9
-rw-r--r--src/kern/tru64/printf.cc62
-rw-r--r--src/kern/tru64/tru64.hh8
-rw-r--r--src/kern/tru64/tru64_events.cc9
-rw-r--r--src/mem/SConscript46
-rw-r--r--src/mem/bus.cc42
-rw-r--r--src/mem/bus.hh11
-rw-r--r--src/mem/cache/SConscript35
-rw-r--r--src/mem/cache/base_cache.cc61
-rw-r--r--src/mem/cache/base_cache.hh16
-rw-r--r--src/mem/cache/cache.hh1
-rw-r--r--src/mem/cache/cache_blk.hh4
-rw-r--r--src/mem/cache/cache_impl.hh76
-rw-r--r--src/mem/cache/coherence/SConscript35
-rw-r--r--src/mem/cache/coherence/coherence_protocol.cc146
-rw-r--r--src/mem/cache/coherence/coherence_protocol.hh10
-rw-r--r--src/mem/cache/coherence/simple_coherence.hh7
-rw-r--r--src/mem/cache/coherence/uni_coherence.cc8
-rw-r--r--src/mem/cache/coherence/uni_coherence.hh12
-rw-r--r--src/mem/cache/miss/SConscript37
-rw-r--r--src/mem/cache/miss/blocking_buffer.cc4
-rw-r--r--src/mem/cache/miss/blocking_buffer.hh2
-rw-r--r--src/mem/cache/miss/miss_buffer.hh2
-rw-r--r--src/mem/cache/miss/miss_queue.cc111
-rw-r--r--src/mem/cache/miss/miss_queue.hh20
-rw-r--r--src/mem/cache/miss/mshr.cc6
-rw-r--r--src/mem/cache/miss/mshr.hh4
-rw-r--r--src/mem/cache/miss/mshr_queue.cc8
-rw-r--r--src/mem/cache/miss/mshr_queue.hh2
-rw-r--r--src/mem/cache/prefetch/SConscript37
-rw-r--r--src/mem/cache/prefetch/base_prefetcher.cc2
-rw-r--r--src/mem/cache/tags/SConscript42
-rw-r--r--src/mem/cache/tags/iic.cc5
-rw-r--r--src/mem/cache/tags/lru.cc2
-rw-r--r--src/mem/cache/tags/split_lifo.cc2
-rw-r--r--src/mem/cache/tags/split_lru.cc2
-rw-r--r--src/mem/mem_object.cc5
-rw-r--r--src/mem/mem_object.hh4
-rw-r--r--src/mem/packet.cc141
-rw-r--r--src/mem/packet.hh224
-rw-r--r--src/mem/packet_access.hh1
-rw-r--r--src/mem/page_table.cc2
-rw-r--r--src/mem/physical.cc89
-rw-r--r--src/mem/physical.hh3
-rw-r--r--src/mem/port.cc18
-rw-r--r--src/mem/port.hh9
-rw-r--r--src/mem/request.hh33
-rw-r--r--src/mem/tport.cc2
-rw-r--r--src/mem/vport.cc51
-rw-r--r--src/mem/vport.hh7
-rw-r--r--src/python/SConscript55
-rw-r--r--src/python/m5/SimObject.py24
-rw-r--r--src/python/m5/__init__.py106
-rw-r--r--src/python/m5/convert.py23
-rw-r--r--src/python/m5/event.py42
-rw-r--r--src/python/m5/main.py142
-rw-r--r--src/python/m5/objects/BaseCPU.py4
-rw-r--r--src/python/m5/objects/IntrControl.py2
-rw-r--r--src/python/m5/objects/PhysicalMemory.py2
-rw-r--r--src/python/m5/objects/Root.py19
-rw-r--r--src/python/m5/objects/SimConsole.py5
-rw-r--r--src/python/m5/objects/T1000.py27
-rw-r--r--src/python/m5/params.py136
-rw-r--r--src/python/m5/stats.py46
-rw-r--r--src/python/m5/ticks.py89
-rw-r--r--src/python/swig/core.i65
-rw-r--r--src/python/swig/event.i40
-rw-r--r--src/python/swig/pyevent.cc9
-rw-r--r--src/python/swig/pyevent.hh26
-rw-r--r--src/python/swig/pyobject.cc137
-rw-r--r--src/python/swig/pyobject.hh94
-rw-r--r--src/python/swig/random.i55
-rw-r--r--src/python/swig/sim_object.i101
-rw-r--r--src/python/swig/stats.i61
-rw-r--r--src/python/swig/trace.i76
-rw-r--r--src/sim/SConscript54
-rw-r--r--src/sim/async.cc38
-rw-r--r--src/sim/async.hh4
-rw-r--r--src/sim/builder.cc4
-rw-r--r--src/sim/byteswap.hh19
-rw-r--r--src/sim/core.cc140
-rw-r--r--src/sim/core.hh85
-rw-r--r--src/sim/eventq.cc7
-rw-r--r--src/sim/eventq.hh22
-rw-r--r--src/sim/faults.cc28
-rw-r--r--src/sim/faults.hh12
-rw-r--r--src/sim/main.cc368
-rw-r--r--src/sim/param.cc109
-rw-r--r--src/sim/param.hh47
-rw-r--r--src/sim/process.cc53
-rw-r--r--src/sim/process.hh25
-rw-r--r--src/sim/pseudo_inst.cc12
-rw-r--r--src/sim/pseudo_inst.hh2
-rw-r--r--src/sim/root.cc99
-rw-r--r--src/sim/serialize.cc33
-rw-r--r--src/sim/sim_events.cc18
-rw-r--r--src/sim/sim_events.hh19
-rw-r--r--src/sim/sim_object.cc9
-rw-r--r--src/sim/sim_object.hh1
-rw-r--r--src/sim/simulate.cc121
-rw-r--r--src/sim/simulate.hh35
-rw-r--r--src/sim/stat_control.cc96
-rw-r--r--src/sim/stat_control.hh19
-rw-r--r--src/sim/syscall_emul.cc33
-rw-r--r--src/sim/syscall_emul.hh28
-rw-r--r--src/sim/system.cc39
-rw-r--r--src/unittest/Makefile3
-rw-r--r--src/unittest/cprintftime.cc90
371 files changed, 19916 insertions, 6642 deletions
diff --git a/src/SConscript b/src/SConscript
index 74bed9a7e..5efd2f794 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -30,187 +30,27 @@
import os
import sys
-from os.path import isfile, join as joinpath
+
+from os.path import join as joinpath
# This file defines how to build a particular configuration of M5
# based on variable settings in the 'env' build environment.
-# Import build environment variable from SConstruct.
-Import('env')
-
-###################################################
-#
-# Define needed sources.
-#
-###################################################
-
-# Base sources used by all configurations.
-
-base_sources = Split('''
- base/annotate.cc
- base/circlebuf.cc
- base/cprintf.cc
- base/fast_alloc.cc
- base/fifo_buffer.cc
- base/hostinfo.cc
- base/hybrid_pred.cc
- base/inifile.cc
- base/intmath.cc
- base/match.cc
- base/misc.cc
- base/output.cc
- base/pollevent.cc
- base/range.cc
- base/random.cc
- base/remote_gdb.cc
- base/sat_counter.cc
- base/socket.cc
- base/statistics.cc
- base/str.cc
- base/time.cc
- base/trace.cc
- base/traceflags.cc
- base/userinfo.cc
- base/compression/lzss_compression.cc
- 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
- base/stats/statdb.cc
- base/stats/visit.cc
- base/stats/text.cc
-
- cpu/activity.cc
- cpu/base.cc
- cpu/cpuevent.cc
- cpu/exetrace.cc
- cpu/func_unit.cc
- cpu/op_class.cc
- cpu/pc_event.cc
- cpu/quiesce_event.cc
- cpu/static_inst.cc
- cpu/simple_thread.cc
- cpu/thread_state.cc
-
- mem/bridge.cc
- mem/bus.cc
- mem/dram.cc
- mem/mem_object.cc
- mem/packet.cc
- mem/physical.cc
- mem/port.cc
- mem/tport.cc
-
- mem/cache/base_cache.cc
- mem/cache/cache.cc
- mem/cache/coherence/coherence_protocol.cc
- mem/cache/coherence/uni_coherence.cc
- mem/cache/miss/blocking_buffer.cc
- mem/cache/miss/miss_buffer.cc
- mem/cache/miss/miss_queue.cc
- mem/cache/miss/mshr.cc
- mem/cache/miss/mshr_queue.cc
- mem/cache/prefetch/base_prefetcher.cc
- mem/cache/prefetch/ghb_prefetcher.cc
- mem/cache/prefetch/stride_prefetcher.cc
- mem/cache/prefetch/tagged_prefetcher.cc
- mem/cache/tags/base_tags.cc
- mem/cache/tags/fa_lru.cc
- mem/cache/tags/iic.cc
- mem/cache/tags/lru.cc
- mem/cache/tags/repl/gen.cc
- mem/cache/tags/repl/repl.cc
- mem/cache/tags/split.cc
- mem/cache/tags/split_lifo.cc
- mem/cache/tags/split_lru.cc
-
- mem/cache/cache_builder.cc
-
- python/swig/init.cc
- python/swig/debug_wrap.cc
- python/swig/main_wrap.cc
- python/swig/event_wrap.cc
- python/swig/pyevent.cc
-
- sim/builder.cc
- sim/debug.cc
- sim/eventq.cc
- sim/faults.cc
- sim/main.cc
- sim/param.cc
- sim/root.cc
- sim/serialize.cc
- sim/sim_events.cc
- sim/sim_object.cc
- sim/startup.cc
- sim/stat_context.cc
- sim/stat_control.cc
- sim/system.cc
- sim/trace_context.cc
- ''')
-
-trace_reader_sources = Split('''
- cpu/trace/reader/mem_trace_reader.cc
- cpu/trace/reader/ibm_reader.cc
- cpu/trace/reader/itx_reader.cc
- cpu/trace/reader/m5_reader.cc
- cpu/trace/opt_cpu.cc
- cpu/trace/trace_cpu.cc
- ''')
-
-
-
-# MySql sources
-mysql_sources = Split('''
- base/mysql.cc
- base/stats/mysql.cc
- ''')
-
-# Full-system sources
-full_system_sources = Split('''
- base/crc.cc
- base/inet.cc
-
- cpu/intr_control.cc
- cpu/profile.cc
-
- dev/uart.cc
- dev/uart8250.cc
+Import('*')
- mem/vport.cc
-
- sim/pseudo_inst.cc
- ''')
- #dev/sinic.cc
- #dev/i8254xGBe.cc
-
-if env['TARGET_ISA'] == 'alpha':
- full_system_sources += Split('''
- kern/tru64/dump_mbuf.cc
- kern/tru64/printf.cc
- kern/tru64/tru64_events.cc
- kern/tru64/tru64_syscalls.cc
- ''')
-
-# Syscall emulation (non-full-system) sources
-syscall_emulation_sources = Split('''
- mem/translating_port.cc
- mem/page_table.cc
- sim/process.cc
- sim/syscall_emul.cc
- ''')
-
-#if env['TARGET_ISA'] == 'alpha':
-# syscall_emulation_sources += Split('''
-# kern/tru64/tru64.cc
-# ''')
+sources = []
+def Source(*args):
+ for arg in args:
+ if isinstance(arg, (list, tuple)):
+ # Recurse to load a list
+ Source(*arg)
+ elif isinstance(arg, str):
+ sources.extend([ File(f) for f in Split(arg) ])
+ else:
+ sources.append(File(arg))
-memtest_sources = Split('''
- cpu/memtest/memtest.cc
- ''')
+Export('env')
+Export('Source')
# Include file paths are rooted in this directory. SCons will
# automatically expand '.' to refer to both the source directory and
@@ -221,52 +61,23 @@ 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(os.path.join('arch', '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
-
- 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
-else:
- sources += syscall_emulation_sources
-
-if env['USE_MYSQL']:
- sources += mysql_sources
+# Walk the tree and execute all SConscripts
+scripts = []
+srcdir = env['SRCDIR']
+for root, dirs, files in os.walk(srcdir, topdown=True):
+ if root == srcdir:
+ # we don't want to recurse back into this SConscript
+ continue
+
+ if 'SConscript' in files:
+ # strip off the srcdir part since scons will try to find the
+ # script in the build directory
+ base = root[len(srcdir) + 1:]
+ SConscript(joinpath(base, 'SConscript'))
for opt in env.ExportOptions:
env.ConfigFile(opt)
-###################################################
-#
-# Special build rules.
-#
-###################################################
-
-# base/traceflags.{cc,hh} are generated from base/traceflags.py.
-# $TARGET.base will expand to "<build-dir>/base/traceflags".
-env.Command(Split('base/traceflags.hh base/traceflags.cc'),
- 'base/traceflags.py',
- 'python $SOURCE $TARGET.base')
-
-SConscript('python/SConscript', exports = ['env'])
-
# This function adds the specified sources to the given build
# environment, and returns a list of all the corresponding SCons
# Object nodes (including an extra one for date.cc). We explicitly
diff --git a/src/arch/SConscript b/src/arch/SConscript
index 74be5f8d1..0ac25b6c7 100644
--- a/src/arch/SConscript
+++ b/src/arch/SConscript
@@ -28,13 +28,9 @@
#
# Authors: Steve Reinhardt
-import os.path, sys
+import sys
-# Import build environment variable from SConstruct.
-Import('env')
-
-# Right now there are no source files immediately in this directory
-sources = []
+Import('*')
#################################################################
#
@@ -55,6 +51,7 @@ isa_switch_hdrs = Split('''
locked_mem.hh
mmaped_ipr.hh
process.hh
+ predecoder.hh
regfile.hh
remote_gdb.hh
stacktrace.hh
@@ -66,7 +63,7 @@ isa_switch_hdrs = Split('''
''')
# Set up this directory to support switching headers
-env.make_switching_dir('arch', isa_switch_hdrs, env)
+make_switching_dir('arch', isa_switch_hdrs, env)
#################################################################
#
@@ -100,7 +97,7 @@ execfile(cpu_models_file.srcnode().abspath)
# Several files are generated from the ISA description.
# We always get the basic decoder and header file.
-isa_desc_gen_files = Split('decoder.cc decoder.hh')
+isa_desc_gen_files = [ 'decoder.cc', 'decoder.hh' ]
# We also get an execute file for each selected CPU model.
isa_desc_gen_files += [CpuModel.dict[cpu].filename
for cpu in env['CPU_MODELS']]
@@ -128,14 +125,3 @@ else:
emitter = isa_desc_emitter)
env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder })
-
-#
-# Now include other ISA-specific sources from the ISA subdirectories.
-#
-
-isa = env['TARGET_ISA'] # someday this may be a list of ISAs
-
-# Let the target architecture define what additional sources it needs
-sources += SConscript(os.path.join(isa, 'SConscript'), exports = 'env')
-
-Return('sources')
diff --git a/src/arch/alpha/SConscript b/src/arch/alpha/SConscript
index addd49884..61611e9f6 100644
--- a/src/arch/alpha/SConscript
+++ b/src/arch/alpha/SConscript
@@ -29,76 +29,45 @@
# Authors: Gabe Black
# Steve Reinhardt
-import os
-import sys
-from os.path import isdir
+Import('*')
-# This file defines how to build a particular configuration of M5
-# based on variable settings in the 'env' build environment.
+if env['TARGET_ISA'] == 'alpha':
+ Source('faults.cc')
+ Source('floatregfile.cc')
+ Source('intregfile.cc')
+ Source('miscregfile.cc')
+ Source('regfile.cc')
+ Source('remote_gdb.cc')
-# Import build environment variable from SConstruct.
-Import('env')
+ if env['FULL_SYSTEM']:
+ Source('arguments.cc')
+ Source('ev5.cc')
+ Source('idle_event.cc')
+ Source('ipr.cc')
+ Source('kernel_stats.cc')
+ Source('osfpal.cc')
+ Source('pagetable.cc')
+ Source('stacktrace.cc')
+ Source('system.cc')
+ Source('tlb.cc')
+ Source('vtophys.cc')
-###################################################
-#
-# Define needed sources.
-#
-###################################################
-
-# Base sources used by all configurations.
-base_sources = Split('''
- faults.cc
- floatregfile.cc
- intregfile.cc
- miscregfile.cc
- regfile.cc
- remote_gdb.cc
- ''')
-
-# Full-system sources
-full_system_sources = Split('''
- arguments.cc
- ev5.cc
- freebsd/system.cc
- idle_event.cc
- ipr.cc
- kernel_stats.cc
- linux/system.cc
- osfpal.cc
- pagetable.cc
- stacktrace.cc
- system.cc
- tlb.cc
- tru64/system.cc
- vtophys.cc
- ''')
-
-
-# Syscall emulation (non-full-system) sources
-syscall_emulation_sources = Split('''
- linux/linux.cc
- linux/process.cc
- tru64/tru64.cc
- tru64/process.cc
- process.cc
- ''')
-
-# Set up complete list of sources based on configuration.
-sources = base_sources
+ Source('freebsd/system.cc')
+ Source('linux/system.cc')
+ Source('tru64/system.cc')
-if env['FULL_SYSTEM']:
- sources += full_system_sources
-else:
- sources += syscall_emulation_sources
+ else:
+ Source('process.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]
+ Source('linux/linux.cc')
+ Source('linux/process.cc')
-# Add in files generated by the ISA description.
-isa_desc_files = env.ISADesc('isa/main.isa')
-# Only non-header files need to be compiled.
-isa_desc_sources = [f for f in isa_desc_files if not f.path.endswith('.hh')]
-sources += isa_desc_sources
+ Source('tru64/tru64.cc')
+ Source('tru64/process.cc')
-Return('sources')
+ # Add in files generated by the ISA description.
+ isa_desc_files = env.ISADesc('isa/main.isa')
+ # Only non-header files need to be compiled.
+ for f in isa_desc_files:
+ if not f.path.endswith('.hh'):
+ Source(f)
diff --git a/src/arch/alpha/SConsopts b/src/arch/alpha/SConsopts
new file mode 100644
index 000000000..633eeb06f
--- /dev/null
+++ b/src/arch/alpha/SConsopts
@@ -0,0 +1,37 @@
+# -*- mode:python -*-
+
+# 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
+
+Import('*')
+
+all_isa_list.append('alpha')
+
+# Alpha can be compiled with Turbolaser support instead of Tsunami
+sticky_opts.Add(BoolOption('ALPHA_TLASER',
+ 'Model Alpha TurboLaser platform (vs. Tsunami)', False))
diff --git a/src/arch/alpha/arguments.hh b/src/arch/alpha/arguments.hh
index c44181a8d..4dba4901f 100644
--- a/src/arch/alpha/arguments.hh
+++ b/src/arch/alpha/arguments.hh
@@ -35,6 +35,7 @@
#include "arch/alpha/vtophys.hh"
#include "base/refcnt.hh"
+#include "mem/vport.hh"
#include "sim/host.hh"
class ThreadContext;
diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc
index 8d13511ac..ec5090eb8 100644
--- a/src/arch/alpha/ev5.cc
+++ b/src/arch/alpha/ev5.cc
@@ -62,7 +62,7 @@ AlphaISA::initCPU(ThreadContext *tc, int cpuId)
AlphaISA::AlphaFault *reset = new AlphaISA::ResetFault;
- tc->setPC(tc->readMiscReg(IPR_PAL_BASE) + reset->vect());
+ tc->setPC(tc->readMiscRegNoEffect(IPR_PAL_BASE) + reset->vect());
tc->setNextPC(tc->readPC() + sizeof(MachInst));
delete reset;
@@ -76,12 +76,12 @@ void
AlphaISA::initIPRs(ThreadContext *tc, int cpuId)
{
for (int i = 0; i < NumInternalProcRegs; ++i) {
- tc->setMiscReg(i, 0);
+ tc->setMiscRegNoEffect(i, 0);
}
- tc->setMiscReg(IPR_PAL_BASE, PalBase);
- tc->setMiscReg(IPR_MCSR, 0x6);
- tc->setMiscReg(IPR_PALtemp16, cpuId);
+ tc->setMiscRegNoEffect(IPR_PAL_BASE, PalBase);
+ tc->setMiscRegNoEffect(IPR_MCSR, 0x6);
+ tc->setMiscRegNoEffect(IPR_PALtemp16, cpuId);
}
@@ -94,13 +94,13 @@ AlphaISA::processInterrupts(CPU *cpu)
int ipl = 0;
int summary = 0;
- if (cpu->readMiscReg(IPR_ASTRR))
+ if (cpu->readMiscRegNoEffect(IPR_ASTRR))
panic("asynchronous traps not implemented\n");
- if (cpu->readMiscReg(IPR_SIRR)) {
+ if (cpu->readMiscRegNoEffect(IPR_SIRR)) {
for (int i = INTLEVEL_SOFTWARE_MIN;
i < INTLEVEL_SOFTWARE_MAX; i++) {
- if (cpu->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
+ if (cpu->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) {
// See table 4-19 of the 21164 hardware reference
ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
summary |= (ULL(1) << i);
@@ -121,12 +121,12 @@ AlphaISA::processInterrupts(CPU *cpu)
}
}
- if (ipl && ipl > cpu->readMiscReg(IPR_IPLR)) {
- cpu->setMiscReg(IPR_ISR, summary);
- cpu->setMiscReg(IPR_INTID, ipl);
+ if (ipl && ipl > cpu->readMiscRegNoEffect(IPR_IPLR)) {
+ cpu->setMiscRegNoEffect(IPR_ISR, summary);
+ cpu->setMiscRegNoEffect(IPR_INTID, ipl);
cpu->trap(new InterruptFault);
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
- cpu->readMiscReg(IPR_IPLR), ipl, summary);
+ cpu->readMiscRegNoEffect(IPR_IPLR), ipl, summary);
}
}
@@ -148,7 +148,7 @@ SimpleThread::hwrei()
if (!(readPC() & 0x3))
return new UnimplementedOpcodeFault;
- setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR));
+ setNextPC(readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR));
if (!misspeculating()) {
if (kernelStats)
@@ -554,7 +554,7 @@ void
AlphaISA::copyIprs(ThreadContext *src, ThreadContext *dest)
{
for (int i = 0; i < NumInternalProcRegs; ++i) {
- dest->setMiscReg(i, src->readMiscReg(i));
+ dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
}
}
diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc
index 5efcf92e4..149729351 100644
--- a/src/arch/alpha/faults.cc
+++ b/src/arch/alpha/faults.cc
@@ -59,12 +59,6 @@ FaultName ArithmeticFault::_name = "arith";
FaultVect ArithmeticFault::_vect = 0x0501;
FaultStat ArithmeticFault::_count;
-#if !FULL_SYSTEM
-FaultName PageTableFault::_name = "page_table_fault";
-FaultVect PageTableFault::_vect = 0x0000;
-FaultStat PageTableFault::_count;
-#endif
-
FaultName InterruptFault::_name = "interrupt";
FaultVect InterruptFault::_vect = 0x0101;
FaultStat InterruptFault::_count;
@@ -126,15 +120,15 @@ void AlphaFault::invoke(ThreadContext * tc)
// exception restart address
if (setRestartAddress() || !(tc->readPC() & 0x3))
- tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, tc->readPC());
+ tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR, tc->readPC());
if (skipFaultingInstruction()) {
// traps... skip faulting instruction.
- tc->setMiscReg(AlphaISA::IPR_EXC_ADDR,
- tc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4);
+ tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR,
+ tc->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR) + 4);
}
- tc->setPC(tc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect());
+ tc->setPC(tc->readMiscRegNoEffect(AlphaISA::IPR_PAL_BASE) + vect());
tc->setNextPC(tc->readPC() + sizeof(MachInst));
}
@@ -154,17 +148,17 @@ void DtbFault::invoke(ThreadContext * tc)
if (!tc->misspeculating()
&& !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) {
// set VA register with faulting address
- tc->setMiscReg(AlphaISA::IPR_VA, vaddr);
+ tc->setMiscRegNoEffect(AlphaISA::IPR_VA, vaddr);
// set MM_STAT register flags
- tc->setMiscReg(AlphaISA::IPR_MM_STAT,
+ tc->setMiscRegNoEffect(AlphaISA::IPR_MM_STAT,
(((EV5::Opcode(tc->getInst()) & 0x3f) << 11)
| ((EV5::Ra(tc->getInst()) & 0x1f) << 6)
| (flags & 0x3f)));
// set VA_FORM register with faulting formatted address
- tc->setMiscReg(AlphaISA::IPR_VA_FORM,
- tc->readMiscReg(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3));
+ tc->setMiscRegNoEffect(AlphaISA::IPR_VA_FORM,
+ tc->readMiscRegNoEffect(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3));
}
AlphaFault::invoke(tc);
@@ -173,41 +167,15 @@ void DtbFault::invoke(ThreadContext * tc)
void ItbFault::invoke(ThreadContext * tc)
{
if (!tc->misspeculating()) {
- tc->setMiscReg(AlphaISA::IPR_ITB_TAG, pc);
- tc->setMiscReg(AlphaISA::IPR_IFAULT_VA_FORM,
- tc->readMiscReg(AlphaISA::IPR_IVPTBR) |
+ tc->setMiscRegNoEffect(AlphaISA::IPR_ITB_TAG, pc);
+ tc->setMiscRegNoEffect(AlphaISA::IPR_IFAULT_VA_FORM,
+ tc->readMiscRegNoEffect(AlphaISA::IPR_IVPTBR) |
(AlphaISA::VAddr(pc).vpn() << 3));
}
AlphaFault::invoke(tc);
}
-#else //!FULL_SYSTEM
-
-void PageTableFault::invoke(ThreadContext *tc)
-{
- Process *p = tc->getProcessPtr();
-
- // address is higher than the stack region or in the current stack region
- if (vaddr > p->stack_base || vaddr > p->stack_min)
- FaultBase::invoke(tc);
-
- // We've accessed the next page
- if (vaddr > p->stack_min - PageBytes) {
- DPRINTF(Stack,
- "Increasing stack %#x:%#x to %#x:%#x because of access to %#x",
- p->stack_min, p->stack_base, p->stack_min - PageBytes,
- p->stack_base, vaddr);
- p->stack_min -= PageBytes;
- if (p->stack_base - p->stack_min > 8*1024*1024)
- fatal("Over max stack size for one thread\n");
- p->pTable->allocate(p->stack_min, PageBytes);
- } else {
- warn("Page fault on address %#x\n", vaddr);
- FaultBase::invoke(tc);
- }
-}
-
#endif
} // namespace AlphaISA
diff --git a/src/arch/alpha/faults.hh b/src/arch/alpha/faults.hh
index e2c3441e9..6342122c2 100644
--- a/src/arch/alpha/faults.hh
+++ b/src/arch/alpha/faults.hh
@@ -85,29 +85,6 @@ class AlignmentFault : public AlphaFault
bool isAlignmentFault() {return true;}
};
-#if !FULL_SYSTEM
-class PageTableFault : public AlphaFault
-{
- private:
- Addr vaddr;
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- PageTableFault(Addr va)
- : vaddr(va) {}
- FaultName name() {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-
-static inline Fault genPageTableFault(Addr va)
-{
- return new PageTableFault(va);
-}
-#endif
-
static inline Fault genMachineCheckFault()
{
return new MachineCheckFault;
diff --git a/src/arch/alpha/idle_event.cc b/src/arch/alpha/idle_event.cc
index 0f6806319..f0f1eab7a 100644
--- a/src/arch/alpha/idle_event.cc
+++ b/src/arch/alpha/idle_event.cc
@@ -40,6 +40,6 @@ IdleStartEvent::process(ThreadContext *tc)
{
if (tc->getKernelStats())
tc->getKernelStats()->setIdleProcess(
- tc->readMiscReg(AlphaISA::IPR_PALtemp23), tc);
+ tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23), tc);
remove();
}
diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh
index a522dec6c..6453edf97 100644
--- a/src/arch/alpha/interrupts.hh
+++ b/src/arch/alpha/interrupts.hh
@@ -34,6 +34,7 @@
#include "arch/alpha/faults.hh"
#include "arch/alpha/isa_traits.hh"
+#include "base/compiler.hh"
#include "cpu/thread_context.hh"
namespace AlphaISA
@@ -52,11 +53,6 @@ namespace AlphaISA
newInfoSet = false;
}
- void post(int int_type)
- {
- // sparc only
- }
-
void post(int int_num, int index)
{
DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
@@ -116,13 +112,13 @@ namespace AlphaISA
int ipl = 0;
int summary = 0;
- if (tc->readMiscReg(IPR_ASTRR))
+ if (tc->readMiscRegNoEffect(IPR_ASTRR))
panic("asynchronous traps not implemented\n");
- if (tc->readMiscReg(IPR_SIRR)) {
+ if (tc->readMiscRegNoEffect(IPR_SIRR)) {
for (int i = INTLEVEL_SOFTWARE_MIN;
i < INTLEVEL_SOFTWARE_MAX; i++) {
- if (tc->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
+ if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) {
// See table 4-19 of 21164 hardware reference
ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
summary |= (ULL(1) << i);
@@ -142,12 +138,12 @@ namespace AlphaISA
}
}
- if (ipl && ipl > tc->readMiscReg(IPR_IPLR)) {
+ if (ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR)) {
newIpl = ipl;
newSummary = summary;
newInfoSet = true;
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
- tc->readMiscReg(IPR_IPLR), ipl, summary);
+ tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary);
return new InterruptFault;
} else {
@@ -158,11 +154,17 @@ namespace AlphaISA
void updateIntrInfo(ThreadContext *tc)
{
assert(newInfoSet);
- tc->setMiscReg(IPR_ISR, newSummary);
- tc->setMiscReg(IPR_INTID, newIpl);
+ tc->setMiscRegNoEffect(IPR_ISR, newSummary);
+ tc->setMiscRegNoEffect(IPR_INTID, newIpl);
newInfoSet = false;
}
+ uint64_t get_vec(int int_num)
+ {
+ panic("Shouldn't be called for Alpha\n");
+ M5_DUMMY_RETURN
+ }
+
private:
bool newInfoSet;
int newIpl;
diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa
index 03c8cc29e..af1a91a62 100644
--- a/src/arch/alpha/isa/decoder.isa
+++ b/src/arch/alpha/isa/decoder.isa
@@ -84,6 +84,9 @@ decode OPCODE default Unknown::unknown() {
uint64_t tmp = write_result;
// see stq_c
Ra = (tmp == 0 || tmp == 1) ? tmp : Ra;
+ if (tmp == 1) {
+ xc->setStCondFailures(0);
+ }
}}, mem_flags = LOCKED, inst_flags = IsStoreConditional);
0x2f: stq_c({{ Mem.uq = Ra; }},
{{
@@ -96,6 +99,12 @@ decode OPCODE default Unknown::unknown() {
// mailbox access, and we don't update the
// result register at all.
Ra = (tmp == 0 || tmp == 1) ? tmp : Ra;
+ if (tmp == 1) {
+ // clear failure counter... this is
+ // non-architectural and for debugging
+ // only.
+ xc->setStCondFailures(0);
+ }
}}, mem_flags = LOCKED, inst_flags = IsStoreConditional);
}
@@ -629,7 +638,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) + (Rb & 0);
+ Ra = xc->readMiscReg(AlphaISA::IPR_CC) + (Rb & 0);
#else
Ra = curTick;
@@ -681,7 +690,7 @@ decode OPCODE default Unknown::unknown() {
0x00: CallPal::call_pal({{
if (!palValid ||
(palPriv
- && xc->readMiscRegWithEffect(AlphaISA::IPR_ICM) != AlphaISA::mode_kernel)) {
+ && xc->readMiscReg(AlphaISA::IPR_ICM) != AlphaISA::mode_kernel)) {
// invalid pal function code, or attempt to do privileged
// PAL call in non-kernel mode
fault = new UnimplementedOpcodeFault;
@@ -692,8 +701,8 @@ decode OPCODE default Unknown::unknown() {
bool dopal = xc->simPalCheck(palFunc);
if (dopal) {
- xc->setMiscRegWithEffect(AlphaISA::IPR_EXC_ADDR, NPC);
- NPC = xc->readMiscRegWithEffect(AlphaISA::IPR_PAL_BASE) + palOffset;
+ xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, NPC);
+ NPC = xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + palOffset;
}
}
}}, IsNonSpeculative);
@@ -753,7 +762,7 @@ decode OPCODE default Unknown::unknown() {
miscRegIndex >= NumInternalProcRegs)
fault = new UnimplementedOpcodeFault;
else
- Ra = xc->readMiscRegWithEffect(miscRegIndex);
+ Ra = xc->readMiscReg(miscRegIndex);
}}, IsIprAccess);
}
}
@@ -768,7 +777,7 @@ decode OPCODE default Unknown::unknown() {
miscRegIndex >= NumInternalProcRegs)
fault = new UnimplementedOpcodeFault;
else
- xc->setMiscRegWithEffect(miscRegIndex, Ra);
+ xc->setMiscReg(miscRegIndex, Ra);
if (traceData) { traceData->setData(Ra); }
}}, IsIprAccess);
}
@@ -783,19 +792,19 @@ decode OPCODE default Unknown::unknown() {
// M5 special opcodes use the reserved 0x01 opcode space
0x01: decode M5FUNC {
0x00: arm({{
- AlphaPseudo::arm(xc->tcBase());
+ PseudoInst::arm(xc->tcBase());
}}, IsNonSpeculative);
0x01: quiesce({{
- AlphaPseudo::quiesce(xc->tcBase());
+ PseudoInst::quiesce(xc->tcBase());
}}, IsNonSpeculative, IsQuiesce);
0x02: quiesceNs({{
- AlphaPseudo::quiesceNs(xc->tcBase(), R16);
+ PseudoInst::quiesceNs(xc->tcBase(), R16);
}}, IsNonSpeculative, IsQuiesce);
0x03: quiesceCycles({{
- AlphaPseudo::quiesceCycles(xc->tcBase(), R16);
+ PseudoInst::quiesceCycles(xc->tcBase(), R16);
}}, IsNonSpeculative, IsQuiesce, IsUnverifiable);
0x04: quiesceTime({{
- R0 = AlphaPseudo::quiesceTime(xc->tcBase());
+ R0 = PseudoInst::quiesceTime(xc->tcBase());
}}, IsNonSpeculative, IsUnverifiable);
0x10: ivlb({{
warn_once("Obsolete M5 instruction ivlb encountered.\n");
@@ -804,47 +813,47 @@ decode OPCODE default Unknown::unknown() {
warn_once("Obsolete M5 instruction ivlb encountered.\n");
}});
0x20: m5exit_old({{
- AlphaPseudo::m5exit_old(xc->tcBase());
+ PseudoInst::m5exit_old(xc->tcBase());
}}, No_OpClass, IsNonSpeculative);
0x21: m5exit({{
- AlphaPseudo::m5exit(xc->tcBase(), R16);
+ PseudoInst::m5exit(xc->tcBase(), R16);
}}, No_OpClass, IsNonSpeculative);
0x31: loadsymbol({{
- AlphaPseudo::loadsymbol(xc->tcBase());
+ PseudoInst::loadsymbol(xc->tcBase());
}}, No_OpClass, IsNonSpeculative);
0x30: initparam({{ Ra = xc->tcBase()->getCpuPtr()->system->init_param; }});
0x40: resetstats({{
- AlphaPseudo::resetstats(xc->tcBase(), R16, R17);
+ PseudoInst::resetstats(xc->tcBase(), R16, R17);
}}, IsNonSpeculative);
0x41: dumpstats({{
- AlphaPseudo::dumpstats(xc->tcBase(), R16, R17);
+ PseudoInst::dumpstats(xc->tcBase(), R16, R17);
}}, IsNonSpeculative);
0x42: dumpresetstats({{
- AlphaPseudo::dumpresetstats(xc->tcBase(), R16, R17);
+ PseudoInst::dumpresetstats(xc->tcBase(), R16, R17);
}}, IsNonSpeculative);
0x43: m5checkpoint({{
- AlphaPseudo::m5checkpoint(xc->tcBase(), R16, R17);
+ PseudoInst::m5checkpoint(xc->tcBase(), R16, R17);
}}, IsNonSpeculative);
0x50: m5readfile({{
- R0 = AlphaPseudo::readfile(xc->tcBase(), R16, R17, R18);
+ R0 = PseudoInst::readfile(xc->tcBase(), R16, R17, R18);
}}, IsNonSpeculative);
0x51: m5break({{
- AlphaPseudo::debugbreak(xc->tcBase());
+ PseudoInst::debugbreak(xc->tcBase());
}}, IsNonSpeculative);
0x52: m5switchcpu({{
- AlphaPseudo::switchcpu(xc->tcBase());
+ PseudoInst::switchcpu(xc->tcBase());
}}, IsNonSpeculative);
0x53: m5addsymbol({{
- AlphaPseudo::addsymbol(xc->tcBase(), R16, R17);
+ PseudoInst::addsymbol(xc->tcBase(), R16, R17);
}}, IsNonSpeculative);
0x54: m5panic({{
panic("M5 panic instruction called at pc=%#x.", xc->readPC());
}}, IsNonSpeculative);
0x55: m5anBegin({{
- AlphaPseudo::anBegin(xc->tcBase(), R16);
+ PseudoInst::anBegin(xc->tcBase(), R16);
}}, IsNonSpeculative);
0x56: m5anWait({{
- AlphaPseudo::anWait(xc->tcBase(), R16, R17);
+ PseudoInst::anWait(xc->tcBase(), R16, R17);
}}, IsNonSpeculative);
}
}
diff --git a/src/arch/alpha/isa/fp.isa b/src/arch/alpha/isa/fp.isa
index c845ea442..a350aa05f 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))) {
+ if (!EV5::ICSR_FPE(xc->readMiscReg(AlphaISA::IPR_ICSR))) {
fault = new FloatEnableFault;
}
return fault;
@@ -229,7 +229,7 @@ def template FloatingPointExecute {{
%(code)s;
} else {
fesetround(getC99RoundingMode(
- xc->readMiscReg(AlphaISA::MISCREG_FPCR)));
+ xc->readMiscRegNoEffect(AlphaISA::MISCREG_FPCR)));
%(code)s;
fesetround(FE_TONEAREST);
}
diff --git a/src/arch/alpha/isa/mem.isa b/src/arch/alpha/isa/mem.isa
index c0bdd2c05..fe0daf772 100644
--- a/src/arch/alpha/isa/mem.isa
+++ b/src/arch/alpha/isa/mem.isa
@@ -350,6 +350,41 @@ def template StoreMemAccExecute {{
{
Addr EA;
Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ EA = xc->getEA();
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, NULL);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+def template StoreCondMemAccExecute {{
+ Fault
+ %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
uint64_t write_result = 0;
%(fp_enable_check)s;
@@ -386,6 +421,40 @@ def template StoreExecute {{
{
Addr EA;
Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, NULL);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+def template StoreCondExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
uint64_t write_result = 0;
%(fp_enable_check)s;
@@ -475,7 +544,7 @@ def template StoreCondCompleteAcc {{
%(fp_enable_check)s;
%(op_dest_decl)s;
- uint64_t write_result = pkt->req->getScResult();
+ uint64_t write_result = pkt->req->getExtraData();
if (fault == NoFault) {
%(postacc_code)s;
@@ -614,10 +683,8 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
# select templates
- # define aliases... most StoreCond templates are the same as the
- # corresponding Store templates (only CompleteAcc is different).
- StoreCondMemAccExecute = StoreMemAccExecute
- StoreCondExecute = StoreExecute
+ # The InitiateAcc template is the same for StoreCond templates as the
+ # corresponding Store template..
StoreCondInitiateAcc = StoreInitiateAcc
memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
diff --git a/src/arch/alpha/kernel_stats.cc b/src/arch/alpha/kernel_stats.cc
index 6fc3cb72f..13dc95af7 100644
--- a/src/arch/alpha/kernel_stats.cc
+++ b/src/arch/alpha/kernel_stats.cc
@@ -150,7 +150,7 @@ Statistics::changeMode(cpu_mode newmode, ThreadContext *tc)
void
Statistics::mode(cpu_mode newmode, ThreadContext *tc)
{
- Addr pcbb = tc->readMiscReg(AlphaISA::IPR_PALtemp23);
+ Addr pcbb = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23);
if (newmode == kernel && pcbb == idleProcess)
newmode = idle;
diff --git a/src/arch/alpha/linux/linux.hh b/src/arch/alpha/linux/linux.hh
index 09988bab2..84c04ebc3 100644
--- a/src/arch/alpha/linux/linux.hh
+++ b/src/arch/alpha/linux/linux.hh
@@ -96,15 +96,15 @@ class AlphaLinux : public Linux
//@{
/// ioctl() command codes.
- static const unsigned TIOCGETP = 0x40067408;
- static const unsigned TIOCSETP = 0x80067409;
- static const unsigned TIOCSETN = 0x8006740a;
- static const unsigned TIOCSETC = 0x80067411;
- static const unsigned TIOCGETC = 0x40067412;
- static const unsigned FIONREAD = 0x4004667f;
- static const unsigned TIOCISATTY = 0x2000745e;
- static const unsigned TIOCGETS = 0x402c7413;
- static const unsigned TIOCGETA = 0x40127417;
+ static const unsigned TIOCGETP_ = 0x40067408;
+ static const unsigned TIOCSETP_ = 0x80067409;
+ static const unsigned TIOCSETN_ = 0x8006740a;
+ static const unsigned TIOCSETC_ = 0x80067411;
+ static const unsigned TIOCGETC_ = 0x40067412;
+ static const unsigned FIONREAD_ = 0x4004667f;
+ static const unsigned TIOCISATTY_ = 0x2000745e;
+ static const unsigned TIOCGETS_ = 0x402c7413;
+ static const unsigned TIOCGETA_ = 0x40127417;
//@}
/// For table().
diff --git a/src/arch/alpha/linux/process.hh b/src/arch/alpha/linux/process.hh
index 2076f6339..cb22f521b 100644
--- a/src/arch/alpha/linux/process.hh
+++ b/src/arch/alpha/linux/process.hh
@@ -53,9 +53,6 @@ class AlphaLinuxProcess : public AlphaLiveProcess
virtual SyscallDesc* getDesc(int callnum);
- /// The target system's hostname.
- static const char *hostname;
-
/// Array of syscall descriptors, indexed by call number.
static SyscallDesc syscallDescs[];
diff --git a/src/arch/alpha/locked_mem.hh b/src/arch/alpha/locked_mem.hh
index 52fe24173..df66b92bc 100644
--- a/src/arch/alpha/locked_mem.hh
+++ b/src/arch/alpha/locked_mem.hh
@@ -35,6 +35,14 @@
* @file
*
* ISA-specific helper functions for locked memory accesses.
+ *
+ * Note that these functions are not embedded in the ISA description
+ * because they operate on the *physical* address rather than the
+ * virtual address. In the current M5 design, the physical address is
+ * not accessible from the ISA description, only from the CPU model.
+ * Thus the CPU is responsible for calling back to the ISA (here)
+ * after the address translation has been performed to allow the ISA
+ * to do these manipulations based on the physical address.
*/
#include "arch/alpha/miscregfile.hh"
@@ -48,8 +56,8 @@ template <class XC>
inline void
handleLockedRead(XC *xc, Request *req)
{
- xc->setMiscReg(MISCREG_LOCKADDR, req->getPaddr() & ~0xf);
- xc->setMiscReg(MISCREG_LOCKFLAG, true);
+ xc->setMiscRegNoEffect(MISCREG_LOCKADDR, req->getPaddr() & ~0xf);
+ xc->setMiscRegNoEffect(MISCREG_LOCKFLAG, true);
}
@@ -60,16 +68,16 @@ handleLockedWrite(XC *xc, Request *req)
if (req->isUncacheable()) {
// Funky Turbolaser mailbox access...don't update
// result register (see stq_c in decoder.isa)
- req->setScResult(2);
+ req->setExtraData(2);
} else {
// standard store conditional
- bool lock_flag = xc->readMiscReg(MISCREG_LOCKFLAG);
- Addr lock_addr = xc->readMiscReg(MISCREG_LOCKADDR);
+ bool lock_flag = xc->readMiscRegNoEffect(MISCREG_LOCKFLAG);
+ Addr lock_addr = xc->readMiscRegNoEffect(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(MISCREG_LOCKFLAG, false);
+ req->setExtraData(0);
+ xc->setMiscRegNoEffect(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
index 67f6c98e4..1af97adcf 100644
--- a/src/arch/alpha/miscregfile.cc
+++ b/src/arch/alpha/miscregfile.cc
@@ -61,7 +61,7 @@ namespace AlphaISA
}
MiscReg
- MiscRegFile::readReg(int misc_reg)
+ MiscRegFile::readRegNoEffect(int misc_reg)
{
switch(misc_reg) {
case MISCREG_FPCR:
@@ -87,7 +87,7 @@ namespace AlphaISA
}
MiscReg
- MiscRegFile::readRegWithEffect(int misc_reg, ThreadContext *tc)
+ MiscRegFile::readReg(int misc_reg, ThreadContext *tc)
{
switch(misc_reg) {
case MISCREG_FPCR:
@@ -112,7 +112,7 @@ namespace AlphaISA
}
void
- MiscRegFile::setReg(int misc_reg, const MiscReg &val)
+ MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val)
{
switch(misc_reg) {
case MISCREG_FPCR:
@@ -143,7 +143,7 @@ namespace AlphaISA
}
void
- MiscRegFile::setRegWithEffect(int misc_reg, const MiscReg &val,
+ MiscRegFile::setReg(int misc_reg, const MiscReg &val,
ThreadContext *tc)
{
switch(misc_reg) {
diff --git a/src/arch/alpha/miscregfile.hh b/src/arch/alpha/miscregfile.hh
index 31b3e59b3..aea702849 100644
--- a/src/arch/alpha/miscregfile.hh
+++ b/src/arch/alpha/miscregfile.hh
@@ -75,18 +75,18 @@ namespace AlphaISA
#endif
}
- MiscReg readReg(int misc_reg);
+ MiscReg readRegNoEffect(int misc_reg);
- MiscReg readRegWithEffect(int misc_reg, ThreadContext *tc);
+ MiscReg readReg(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 setRegNoEffect(int misc_reg, const MiscReg &val);
- void setRegWithEffect(int misc_reg, const MiscReg &val,
+ void setReg(int misc_reg, const MiscReg &val,
ThreadContext *tc);
void clear()
diff --git a/src/arch/alpha/predecoder.hh b/src/arch/alpha/predecoder.hh
new file mode 100644
index 000000000..650f2bfa2
--- /dev/null
+++ b/src/arch/alpha/predecoder.hh
@@ -0,0 +1,108 @@
+/*
+ * 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_ALPHA_PREDECODER_HH__
+#define __ARCH_ALPHA_PREDECODER_HH__
+
+#include "arch/alpha/types.hh"
+#include "base/misc.hh"
+#include "config/full_system.hh"
+#include "sim/host.hh"
+
+class ThreadContext;
+
+namespace AlphaISA
+{
+ class Predecoder
+ {
+ protected:
+ ThreadContext * tc;
+ //The pc of the current instruction
+ Addr fetchPC;
+ //The extended machine instruction being generated
+ ExtMachInst ext_inst;
+
+ public:
+ Predecoder(ThreadContext * _tc) : tc(_tc)
+ {}
+
+ ThreadContext * getTC()
+ {
+ return tc;
+ }
+
+ void setTC(ThreadContext * _tc)
+ {
+ tc = _tc;
+ }
+
+ void process()
+ {
+ }
+
+ //Use this to give data to the predecoder. This should be used
+ //when there is control flow.
+ void moreBytes(Addr pc, Addr off, MachInst inst)
+ {
+ fetchPC = pc;
+ assert(off == 0);
+ ext_inst = inst;
+#if FULL_SYSTEM
+ if (pc && 0x1)
+ ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
+#endif
+ }
+
+ //Use this to give data to the predecoder. This should be used
+ //when instructions are executed in order.
+ void moreBytes(MachInst machInst)
+ {
+ moreBytes(fetchPC + sizeof(machInst), 0, machInst);
+ }
+
+ bool needMoreBytes()
+ {
+ return true;
+ }
+
+ bool extMachInstReady()
+ {
+ return true;
+ }
+
+ //This returns a constant reference to the ExtMachInst to avoid a copy
+ const ExtMachInst & getExtMachInst()
+ {
+ return ext_inst;
+ }
+ };
+};
+
+#endif // __ARCH_ALPHA_PREDECODER_HH__
diff --git a/src/arch/alpha/regfile.cc b/src/arch/alpha/regfile.cc
index 92e1b07df..3b42ca9bc 100644
--- a/src/arch/alpha/regfile.cc
+++ b/src/arch/alpha/regfile.cc
@@ -85,14 +85,14 @@ namespace AlphaISA
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));
+ dest->setMiscRegNoEffect(AlphaISA::MISCREG_FPCR,
+ src->readMiscRegNoEffect(AlphaISA::MISCREG_FPCR));
+ dest->setMiscRegNoEffect(AlphaISA::MISCREG_UNIQ,
+ src->readMiscRegNoEffect(AlphaISA::MISCREG_UNIQ));
+ dest->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG,
+ src->readMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG));
+ dest->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKADDR,
+ src->readMiscRegNoEffect(AlphaISA::MISCREG_LOCKADDR));
#if FULL_SYSTEM
copyIprs(src, dest);
diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh
index 54372da36..b93707181 100644
--- a/src/arch/alpha/regfile.hh
+++ b/src/arch/alpha/regfile.hh
@@ -106,25 +106,25 @@ namespace AlphaISA
miscRegFile.clear();
}
- MiscReg readMiscReg(int miscReg)
+ MiscReg readMiscRegNoEffect(int miscReg)
{
- return miscRegFile.readReg(miscReg);
+ return miscRegFile.readRegNoEffect(miscReg);
}
- MiscReg readMiscRegWithEffect(int miscReg, ThreadContext *tc)
+ MiscReg readMiscReg(int miscReg, ThreadContext *tc)
{
- return miscRegFile.readRegWithEffect(miscReg, tc);
+ return miscRegFile.readReg(miscReg, tc);
}
- void setMiscReg(int miscReg, const MiscReg &val)
+ void setMiscRegNoEffect(int miscReg, const MiscReg &val)
{
- miscRegFile.setReg(miscReg, val);
+ miscRegFile.setRegNoEffect(miscReg, val);
}
- void setMiscRegWithEffect(int miscReg, const MiscReg &val,
+ void setMiscReg(int miscReg, const MiscReg &val,
ThreadContext * tc)
{
- miscRegFile.setRegWithEffect(miscReg, val, tc);
+ miscRegFile.setReg(miscReg, val, tc);
}
FloatReg readFloatReg(int floatReg)
diff --git a/src/arch/alpha/remote_gdb.cc b/src/arch/alpha/remote_gdb.cc
index 4637bd7a6..a68e5218e 100644
--- a/src/arch/alpha/remote_gdb.cc
+++ b/src/arch/alpha/remote_gdb.cc
@@ -187,7 +187,7 @@ RemoteGDB::acc(Addr va, size_t len)
if (AlphaISA::PcPAL(va) || va < 0x10000)
return true;
- Addr ptbr = context->readMiscReg(AlphaISA::IPR_PALtemp20);
+ Addr ptbr = context->readMiscRegNoEffect(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);
diff --git a/src/arch/alpha/stacktrace.cc b/src/arch/alpha/stacktrace.cc
index c4612e156..c16498e72 100644
--- a/src/arch/alpha/stacktrace.cc
+++ b/src/arch/alpha/stacktrace.cc
@@ -146,7 +146,7 @@ namespace AlphaISA
{
tc = _tc;
- bool usermode = (tc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
+ bool usermode = (tc->readMiscRegNoEffect(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
Addr pc = tc->readNextPC();
bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
@@ -219,22 +219,22 @@ namespace AlphaISA
bool
StackTrace::isEntry(Addr addr)
{
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp12))
+ if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp12))
return true;
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp7))
+ if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp7))
return true;
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp11))
+ if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp11))
return true;
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp21))
+ if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp21))
return true;
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp9))
+ if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp9))
return true;
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp2))
+ if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp2))
return true;
return false;
diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc
index c21bf94f5..3ab65e664 100644
--- a/src/arch/alpha/tlb.cc
+++ b/src/arch/alpha/tlb.cc
@@ -46,8 +46,7 @@
using namespace std;
using namespace EV5;
-namespace AlphaISA
-{
+namespace AlphaISA {
///////////////////////////////////////////////////////////////////////
//
// Alpha TLB
@@ -116,10 +115,11 @@ TLB::checkCacheability(RequestPtr &req)
#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!");
@@ -312,13 +312,14 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) const
// 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(IPR_MCSR)) & 2) &&
- VAddrSpaceEV5(req->getVaddr()) == 2) {
+ if ((MCSR_SP(tc->readMiscRegNoEffect(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(IPR_ICM)) !=
+ if (ICM_CM(tc->readMiscRegNoEffect(IPR_ICM)) !=
mode_kernel) {
acv++;
return new ItbAcvFault(req->getVaddr());
@@ -336,7 +337,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) const
} else {
// not a physical address: need to look up pte
- int asn = DTB_ASN_ASN(tc->readMiscReg(IPR_DTB_ASN));
+ int asn = DTB_ASN_ASN(tc->readMiscRegNoEffect(IPR_DTB_ASN));
PTE *pte = lookup(VAddr(req->getVaddr()).vpn(),
asn);
@@ -351,7 +352,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) const
// check permissions for this access
if (!(pte->xre &
- (1 << ICM_CM(tc->readMiscReg(IPR_ICM))))) {
+ (1 << ICM_CM(tc->readMiscRegNoEffect(IPR_ICM))))) {
// instruction access fault
acv++;
return new ItbAcvFault(req->getVaddr());
@@ -452,7 +453,7 @@ 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));
+ (mode_type)DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM));
/**
@@ -468,7 +469,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) const
if (PcPAL(pc)) {
mode = (req->getFlags() & ALTMODE) ?
(mode_type)ALT_MODE_AM(
- tc->readMiscReg(IPR_ALT_MODE))
+ tc->readMiscRegNoEffect(IPR_ALT_MODE))
: mode_kernel;
}
@@ -486,14 +487,15 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) const
// Check for "superpage" mapping
#if ALPHA_TLASER
- if ((MCSR_SP(tc->readMiscReg(IPR_MCSR)) & 2) &&
- VAddrSpaceEV5(req->getVaddr()) == 2) {
+ if ((MCSR_SP(tc->readMiscRegNoEffect(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(IPR_DTB_CM)) !=
+ if (DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)) !=
mode_kernel) {
if (write) { write_acv++; } else { read_acv++; }
uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) |
@@ -517,7 +519,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) const
else
read_accesses++;
- int asn = DTB_ASN_ASN(tc->readMiscReg(IPR_DTB_ASN));
+ int asn = DTB_ASN_ASN(tc->readMiscRegNoEffect(IPR_DTB_ASN));
// not a physical address: need to look up pte
PTE *pte = lookup(VAddr(req->getVaddr()).vpn(),
@@ -592,6 +594,8 @@ TLB::index(bool advance)
return *pte;
}
+/* end namespace AlphaISA */ }
+
DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", TLB)
BEGIN_DECLARE_SIM_OBJECT_PARAMS(ITB)
@@ -633,4 +637,3 @@ CREATE_SIM_OBJECT(DTB)
}
REGISTER_SIM_OBJECT("AlphaDTB", DTB)
-}
diff --git a/src/arch/alpha/tru64/tru64.hh b/src/arch/alpha/tru64/tru64.hh
index f0711b995..90e5f12dc 100644
--- a/src/arch/alpha/tru64/tru64.hh
+++ b/src/arch/alpha/tru64/tru64.hh
@@ -91,15 +91,15 @@ class AlphaTru64 : public Tru64
//@{
/// ioctl() command codes.
- static const unsigned TIOCGETP = 0x40067408;
- static const unsigned TIOCSETP = 0x80067409;
- static const unsigned TIOCSETN = 0x8006740a;
- static const unsigned TIOCSETC = 0x80067411;
- static const unsigned TIOCGETC = 0x40067412;
- static const unsigned FIONREAD = 0x4004667f;
- static const unsigned TIOCISATTY = 0x2000745e;
- static const unsigned TIOCGETS = 0x402c7413;
- static const unsigned TIOCGETA = 0x40127417;
+ static const unsigned TIOCGETP_ = 0x40067408;
+ static const unsigned TIOCSETP_ = 0x80067409;
+ static const unsigned TIOCSETN_ = 0x8006740a;
+ static const unsigned TIOCSETC_ = 0x80067411;
+ static const unsigned TIOCGETC_ = 0x40067412;
+ static const unsigned FIONREAD_ = 0x4004667f;
+ static const unsigned TIOCISATTY_ = 0x2000745e;
+ static const unsigned TIOCGETS_ = 0x402c7413;
+ static const unsigned TIOCGETA_ = 0x40127417;
//@}
//@{
diff --git a/src/arch/alpha/types.hh b/src/arch/alpha/types.hh
index ae42552d8..6433ea3ca 100644
--- a/src/arch/alpha/types.hh
+++ b/src/arch/alpha/types.hh
@@ -42,6 +42,7 @@ namespace AlphaISA
typedef uint8_t RegIndex;
typedef uint64_t IntReg;
+ typedef uint64_t LargestRead;
// floating point register file entry type
typedef double FloatReg;
diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh
index 9a06cc2a4..c20394a92 100644
--- a/src/arch/alpha/utility.hh
+++ b/src/arch/alpha/utility.hh
@@ -45,20 +45,7 @@ namespace AlphaISA
static inline bool
inUserMode(ThreadContext *tc)
{
- return (tc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
- }
-
- static inline ExtMachInst
- makeExtMI(MachInst inst, Addr pc) {
-#if FULL_SYSTEM
- ExtMachInst ext_inst = inst;
- if (pc && 0x1)
- return ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
- else
- return ext_inst;
-#else
- return ExtMachInst(inst);
-#endif
+ return (tc->readMiscRegNoEffect(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
}
inline bool isCallerSaveIntegerRegister(unsigned int reg) {
@@ -123,6 +110,9 @@ namespace AlphaISA
// Alpha IPR register accessors
inline bool PcPAL(Addr addr) { return addr & 0x3; }
+ inline void startupCPU(ThreadContext *tc, int cpuId) {
+ tc->activate(0);
+ }
#if FULL_SYSTEM
////////////////////////////////////////////////////////////////////////
diff --git a/src/arch/alpha/vtophys.cc b/src/arch/alpha/vtophys.cc
index fd8f781e4..6ffbea181 100644
--- a/src/arch/alpha/vtophys.cc
+++ b/src/arch/alpha/vtophys.cc
@@ -88,7 +88,7 @@ Addr
AlphaISA::vtophys(ThreadContext *tc, Addr addr)
{
AlphaISA::VAddr vaddr = addr;
- Addr ptbr = tc->readMiscReg(AlphaISA::IPR_PALtemp20);
+ Addr ptbr = tc->readMiscRegNoEffect(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?
@@ -113,54 +113,3 @@ AlphaISA::vtophys(ThreadContext *tc, Addr addr)
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;
- char *start = dst;
- VirtualPort *vp = tc->getVirtPort(tc);
-
- do {
- vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
- } while (len < maxlen && start[len++] != 0 );
-
- tc->delVirtPort(vp);
- dst[len] = 0;
-}
-
-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())
- {
- vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size());
- src += gen.size();
- }
- tc->delVirtPort(vp);
-}
diff --git a/src/arch/alpha/vtophys.hh b/src/arch/alpha/vtophys.hh
index 32b999c37..bd2ee8468 100644
--- a/src/arch/alpha/vtophys.hh
+++ b/src/arch/alpha/vtophys.hh
@@ -47,11 +47,6 @@ namespace AlphaISA {
Addr vtophys(Addr vaddr);
Addr vtophys(ThreadContext *tc, Addr vaddr);
- void CopyOut(ThreadContext *tc, void *dst, Addr src, size_t len);
- void CopyIn(ThreadContext *tc, Addr dst, void *src, size_t len);
- void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen);
- void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr);
-
};
#endif // __ARCH_ALPHA_VTOPHYS_H__
diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py
index 07ae72cb8..f3981a6eb 100755
--- a/src/arch/isa_parser.py
+++ b/src/arch/isa_parser.py
@@ -81,12 +81,12 @@ tokens = reserved + (
# code literal
'CODELIT',
- # ( ) [ ] { } < > , ; : :: *
+ # ( ) [ ] { } < > , ; . : :: *
'LPAREN', 'RPAREN',
'LBRACKET', 'RBRACKET',
'LBRACE', 'RBRACE',
'LESS', 'GREATER', 'EQUALS',
- 'COMMA', 'SEMI', 'COLON', 'DBLCOLON',
+ 'COMMA', 'SEMI', 'DOT', 'COLON', 'DBLCOLON',
'ASTERISK',
# C preprocessor directives
@@ -113,6 +113,7 @@ t_GREATER = r'\>'
t_EQUALS = r'='
t_COMMA = r','
t_SEMI = r';'
+t_DOT = r'\.'
t_COLON = r':'
t_DBLCOLON = r'::'
t_ASTERISK = r'\*'
@@ -261,6 +262,7 @@ def p_defs_and_outputs_1(t):
def p_def_or_output(t):
'''def_or_output : def_format
| def_bitfield
+ | def_bitfield_struct
| def_template
| def_operand_types
| def_operands
@@ -363,6 +365,23 @@ def p_def_bitfield_1(t):
hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr)
t[0] = GenCode(header_output = hash_define)
+# alternate form for structure member: 'def bitfield <ID> <ID>'
+def p_def_bitfield_struct(t):
+ 'def_bitfield_struct : DEF opt_signed BITFIELD ID id_with_dot SEMI'
+ if (t[2] != ''):
+ error(t.lineno(1), 'error: structure bitfields are always unsigned.')
+ expr = 'machInst.%s' % t[5]
+ hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr)
+ t[0] = GenCode(header_output = hash_define)
+
+def p_id_with_dot_0(t):
+ 'id_with_dot : ID'
+ t[0] = t[1]
+
+def p_id_with_dot_1(t):
+ 'id_with_dot : ID DOT id_with_dot'
+ t[0] = t[1] + t[2] + t[3]
+
def p_opt_signed_0(t):
'opt_signed : SIGNED'
t[0] = t[1]
@@ -1124,6 +1143,12 @@ def buildOperandTypeMap(userDict, lineno):
ctype = 'float'
elif size == 64:
ctype = 'double'
+ elif desc == 'twin64 int':
+ is_signed = 0
+ ctype = 'Twin64_t'
+ elif desc == 'twin32 int':
+ is_signed = 0
+ ctype = 'Twin32_t'
if ctype == '':
error(lineno, 'Unrecognized type description "%s" in userDict')
operandTypeMap[ext] = (size, ctype, is_signed)
@@ -1156,7 +1181,10 @@ class Operand(object):
# template must be careful not to use it if it doesn't apply.
if self.isMem():
self.mem_acc_size = self.makeAccSize()
- self.mem_acc_type = self.ctype
+ if self.ctype in ['Twin32_t', 'Twin64_t']:
+ self.mem_acc_type = 'Twin'
+ else:
+ self.mem_acc_type = 'uint'
# Finalize additional fields (primarily code fields). This step
# is done separately since some of these fields may depend on the
@@ -1359,7 +1387,7 @@ class ControlRegOperand(Operand):
bit_select = 0
if (self.ctype == 'float' or self.ctype == 'double'):
error(0, 'Attempt to read control register as FP')
- base = 'xc->readMiscRegOperandWithEffect(this, %s)' % self.src_reg_idx
+ base = 'xc->readMiscRegOperand(this, %s)' % self.src_reg_idx
if self.size == self.dflt_size:
return '%s = %s;\n' % (self.base_name, base)
else:
@@ -1369,7 +1397,7 @@ class ControlRegOperand(Operand):
def makeWrite(self):
if (self.ctype == 'float' or self.ctype == 'double'):
error(0, 'Attempt to write control register as FP')
- wb = 'xc->setMiscRegOperandWithEffect(this, %s, %s);\n' % \
+ wb = 'xc->setMiscRegOperand(this, %s, %s);\n' % \
(self.dest_reg_idx, self.base_name)
wb += 'if (traceData) { traceData->setData(%s); }' % \
self.base_name
@@ -1386,6 +1414,9 @@ class MemOperand(Operand):
# Note that initializations in the declarations are solely
# to avoid 'uninitialized variable' errors from the compiler.
# Declare memory data variable.
+ if self.ctype in ['Twin32_t','Twin64_t']:
+ return "%s %s; %s.a = 0; %s.b = 0;\n" % (self.ctype, self.base_name,
+ self.base_name, self.base_name)
c = '%s %s = 0;\n' % (self.ctype, self.base_name)
return c
diff --git a/src/arch/isa_specific.hh b/src/arch/isa_specific.hh
index 181e81302..c241e5c62 100644
--- a/src/arch/isa_specific.hh
+++ b/src/arch/isa_specific.hh
@@ -32,22 +32,23 @@
#define __ARCH_ISA_SPECIFIC_HH__
//This file provides a mechanism for other source code to bring in
-//files from the ISA being compiled with
+//files from the ISA being compiled in.
-//These are constants so you can selective compile code based on the isa
-//To use them, do something like
+//These are constants so you can selectively compile code based on the isa.
+//To use them, do something like:
//
//#if THE_ISA == YOUR_FAVORITE_ISA
// conditional_code
//#endif
//
-//Note that this is how this file sets up the other isa "hooks"
+//Note that this is how this file sets up the TheISA macro.
//These macros have numerical values because otherwise the preprocessor
//would treat them as 0 in comparisons.
#define ALPHA_ISA 21064
#define SPARC_ISA 42
#define MIPS_ISA 34000
+#define X86_ISA 8086
//These tell the preprocessor where to find the files of a particular
//ISA, and set the "TheISA" macro for use elsewhere.
@@ -57,6 +58,8 @@
#define TheISA SparcISA
#elif THE_ISA == MIPS_ISA
#define TheISA MipsISA
+#elif THE_ISA == X86_ISA
+ #define TheISA X86ISA
#else
#error "THE_ISA not set"
#endif
diff --git a/src/arch/mips/SConscript b/src/arch/mips/SConscript
index 8353bcde7..f959951b3 100644
--- a/src/arch/mips/SConscript
+++ b/src/arch/mips/SConscript
@@ -30,54 +30,25 @@
# Steve Reinhardt
# Korey Sewell
-import os
-import sys
-from os.path import isdir
-
-# Import build environment variable from SConstruct.
-Import('env')
-
-###################################################
-#
-# Define needed sources.
-#
-###################################################
-
-# Base sources used by all configurations.
-base_sources = Split('''
- faults.cc
- isa_traits.cc
- utility.cc
- ''')
-
-# Full-system sources
-full_system_sources = Split('''
- #Insert Full-System Files Here
- ''')
-
-# Syscall emulation (non-full-system) sources
-syscall_emulation_sources = Split('''
- linux/linux.cc
- linux/process.cc
- process.cc
- ''')
-
-# Set up complete list of sources based on configuration.
-sources = base_sources
-
-if env['FULL_SYSTEM']:
- sources += full_system_sources
-else:
- sources += syscall_emulation_sources
-
-# 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]
-
-# Add in files generated by the ISA description.
-isa_desc_files = env.ISADesc('isa/main.isa')
-# Only non-header files need to be compiled.
-isa_desc_sources = [f for f in isa_desc_files if not f.path.endswith('.hh')]
-sources += isa_desc_sources
-
-Return('sources')
+Import('*')
+
+if env['TARGET_ISA'] == 'mips':
+ Source('faults.cc')
+ Source('isa_traits.cc')
+ Source('utility.cc')
+
+ if env['FULL_SYSTEM']:
+ #Insert Full-System Files Here
+ pass
+ else:
+ Source('process.cc')
+
+ Source('linux/linux.cc')
+ Source('linux/process.cc')
+
+ # Add in files generated by the ISA description.
+ isa_desc_files = env.ISADesc('isa/main.isa')
+ # Only non-header files need to be compiled.
+ for f in isa_desc_files:
+ if not f.path.endswith('.hh'):
+ Source(f)
diff --git a/src/arch/mips/SConsopts b/src/arch/mips/SConsopts
new file mode 100644
index 000000000..744fc9cca
--- /dev/null
+++ b/src/arch/mips/SConsopts
@@ -0,0 +1,33 @@
+# -*- 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: Nathan Binkert
+
+Import('*')
+
+all_isa_list.append('mips')
diff --git a/src/arch/mips/faults.cc b/src/arch/mips/faults.cc
index 2a8ab1df5..c9e6aa75b 100644
--- a/src/arch/mips/faults.cc
+++ b/src/arch/mips/faults.cc
@@ -58,12 +58,6 @@ FaultName ArithmeticFault::_name = "arith";
FaultVect ArithmeticFault::_vect = 0x0501;
FaultStat ArithmeticFault::_count;
-#if !FULL_SYSTEM
-FaultName PageTableFault::_name = "page_table_fault";
-FaultVect PageTableFault::_vect = 0x0000;
-FaultStat PageTableFault::_count;
-#endif
-
FaultName InterruptFault::_name = "interrupt";
FaultVect InterruptFault::_vect = 0x0101;
FaultStat InterruptFault::_count;
@@ -112,25 +106,5 @@ FaultName IntegerOverflowFault::_name = "intover";
FaultVect IntegerOverflowFault::_vect = 0x0501;
FaultStat IntegerOverflowFault::_count;
-void PageTableFault::invoke(ThreadContext *tc)
-{
- Process *p = tc->getProcessPtr();
-
- // address is higher than the stack region or in the current stack region
- if (vaddr > p->stack_base || vaddr > p->stack_min)
- FaultBase::invoke(tc);
-
- // We've accessed the next page
- if (vaddr > p->stack_min - PageBytes) {
- p->stack_min -= PageBytes;
- if (p->stack_base - p->stack_min > 8*1024*1024)
- fatal("Over max stack size for one thread\n");
- p->pTable->allocate(p->stack_min, PageBytes);
- warn("Increasing stack size by one page.");
- } else {
- FaultBase::invoke(tc);
- }
-}
-
} // namespace MipsISA
diff --git a/src/arch/mips/faults.hh b/src/arch/mips/faults.hh
index 9d2c5df32..86c742413 100644
--- a/src/arch/mips/faults.hh
+++ b/src/arch/mips/faults.hh
@@ -80,30 +80,6 @@ class AlignmentFault : public MipsFault
bool isAlignmentFault() {return true;}
};
-#if !FULL_SYSTEM
-class PageTableFault : public MipsFault
-{
- private:
- Addr vaddr;
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- PageTableFault(Addr va)
- : vaddr(va) {}
- FaultName name() {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-
-static inline Fault genPageTableFault(Addr va)
-{
- return new PageTableFault(va);
-}
-#endif
-
-
static inline Fault genMachineCheckFault()
{
return new MachineCheckFault;
diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa
index 99c9e1604..b5d1df4fc 100644
--- a/src/arch/mips/isa/decoder.isa
+++ b/src/arch/mips/isa/decoder.isa
@@ -289,8 +289,8 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: decode RS_MSB {
0x0: decode RS {
format CP0Control {
- 0x0: mfc0({{ Rt = xc->readMiscReg(RD << 5 | SEL); }});
- 0x4: mtc0({{ xc->setMiscReg(RD << 5 | SEL, Rt); }});
+ 0x0: mfc0({{ Rt = xc->readMiscRegNoEffect(RD << 5 | SEL); }});
+ 0x4: mtc0({{ xc->setMiscRegNoEffect(RD << 5 | SEL, Rt); }});
}
format MipsMT {
@@ -1093,6 +1093,9 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: StoreCond::sc({{ Mem.uw = Rt.uw;}},
{{ uint64_t tmp = write_result;
Rt.uw = (tmp == 0 || tmp == 1) ? tmp : Rt.uw;
+ if (tmp == 1) {
+ xc->setStCondFailures(0);
+ }
}}, mem_flags=LOCKED, inst_flags = IsStoreConditional);
format StoreMemory {
diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa
index fccda2775..df80e7a1f 100644
--- a/src/arch/mips/isa/formats/mem.isa
+++ b/src/arch/mips/isa/formats/mem.isa
@@ -325,6 +325,41 @@ def template StoreMemAccExecute {{
{
Addr EA;
Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ EA = xc->getEA();
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, NULL);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+def template StoreCondMemAccExecute {{
+ Fault
+ %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
uint64_t write_result = 0;
%(fp_enable_check)s;
@@ -361,6 +396,40 @@ def template StoreExecute {{
{
Addr EA;
Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, NULL);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+def template StoreCondExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
uint64_t write_result = 0;
%(fp_enable_check)s;
@@ -449,7 +518,7 @@ def template StoreCondCompleteAcc {{
%(fp_enable_check)s;
%(op_dest_decl)s;
- uint64_t write_result = pkt->req->getScResult();
+ uint64_t write_result = pkt->req->getExtraData();
if (fault == NoFault) {
%(postacc_code)s;
diff --git a/src/arch/mips/isa/formats/util.isa b/src/arch/mips/isa/formats/util.isa
index ec524113d..884e6f727 100644
--- a/src/arch/mips/isa/formats/util.isa
+++ b/src/arch/mips/isa/formats/util.isa
@@ -66,10 +66,8 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
# select templates
- # define aliases... most StoreCond templates are the same as the
- # corresponding Store templates (only CompleteAcc is different).
- StoreCondMemAccExecute = StoreMemAccExecute
- StoreCondExecute = StoreExecute
+ # The InitiateAcc template is the same for StoreCond templates as the
+ # corresponding Store template..
StoreCondInitiateAcc = StoreInitiateAcc
memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
diff --git a/src/arch/mips/linux/linux.hh b/src/arch/mips/linux/linux.hh
index f85935bb9..a20221e9b 100644
--- a/src/arch/mips/linux/linux.hh
+++ b/src/arch/mips/linux/linux.hh
@@ -91,15 +91,15 @@ class MipsLinux : public Linux
//@{
/// ioctl() command codes.
- static const unsigned TIOCGETP = 0x7408;
- static const unsigned TIOCSETP = 0x7409;
- static const unsigned TIOCSETN = 0x740a;
- static const unsigned TIOCSETC = 0x7411;
- static const unsigned TIOCGETC = 0x7412;
- static const unsigned FIONREAD = 0x467f;
- static const unsigned TIOCISATTY = 0x5480;
- static const unsigned TIOCGETS = 0x7413;
- static const unsigned TIOCGETA = 0x7417;
+ static const unsigned TIOCGETP_ = 0x7408;
+ static const unsigned TIOCSETP_ = 0x7409;
+ static const unsigned TIOCSETN_ = 0x740a;
+ static const unsigned TIOCSETC_ = 0x7411;
+ static const unsigned TIOCGETC_ = 0x7412;
+ static const unsigned FIONREAD_ = 0x467f;
+ static const unsigned TIOCISATTY_ = 0x5480;
+ static const unsigned TIOCGETS_ = 0x7413;
+ static const unsigned TIOCGETA_ = 0x7417;
//@}
/// For table().
diff --git a/src/arch/mips/predecoder.hh b/src/arch/mips/predecoder.hh
new file mode 100644
index 000000000..a25cce8a7
--- /dev/null
+++ b/src/arch/mips/predecoder.hh
@@ -0,0 +1,100 @@
+/*
+ * 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_MIPS_PREDECODER_HH__
+#define __ARCH_MIPS_PREDECODER_HH__
+
+#include "arch/mips/types.hh"
+#include "base/misc.hh"
+#include "sim/host.hh"
+
+class ThreadContext;
+
+namespace MipsISA
+{
+ class Predecoder
+ {
+ protected:
+ ThreadContext * tc;
+ //The extended machine instruction being generated
+ ExtMachInst emi;
+
+ public:
+ Predecoder(ThreadContext * _tc) : tc(_tc)
+ {}
+
+ ThreadContext * getTC()
+ {
+ return tc;
+ }
+
+ void setTC(ThreadContext * _tc)
+ {
+ tc = _tc;
+ }
+
+ void process()
+ {
+ }
+
+ //Use this to give data to the predecoder. This should be used
+ //when there is control flow.
+ void moreBytes(Addr currPC, Addr off, MachInst inst)
+ {
+ assert(off == 0);
+ emi = inst;
+ }
+
+ //Use this to give data to the predecoder. This should be used
+ //when instructions are executed in order.
+ void moreBytes(MachInst machInst)
+ {
+ moreBytes(0, 0, machInst);
+ }
+
+ bool needMoreBytes()
+ {
+ return true;
+ }
+
+ bool extMachInstReady()
+ {
+ return true;
+ }
+
+ //This returns a constant reference to the ExtMachInst to avoid a copy
+ const ExtMachInst & getExtMachInst()
+ {
+ return emi;
+ }
+ };
+};
+
+#endif // __ARCH_MIPS_PREDECODER_HH__
diff --git a/src/arch/mips/regfile/misc_regfile.hh b/src/arch/mips/regfile/misc_regfile.hh
index 368925e00..53ee09512 100644
--- a/src/arch/mips/regfile/misc_regfile.hh
+++ b/src/arch/mips/regfile/misc_regfile.hh
@@ -215,22 +215,22 @@ namespace MipsISA
void copyMiscRegs(ThreadContext *tc);
- MiscReg readReg(int misc_reg)
+ MiscReg readRegNoEffect(int misc_reg)
{
return miscRegFile[misc_reg];
}
- MiscReg readRegWithEffect(int misc_reg, ThreadContext *tc)
+ MiscReg readReg(int misc_reg, ThreadContext *tc)
{
return miscRegFile[misc_reg];
}
- void setReg(int misc_reg, const MiscReg &val)
+ void setRegNoEffect(int misc_reg, const MiscReg &val)
{
miscRegFile[misc_reg] = val;
}
- void setRegWithEffect(int misc_reg, const MiscReg &val,
+ void setReg(int misc_reg, const MiscReg &val,
ThreadContext *tc)
{
miscRegFile[misc_reg] = val;
diff --git a/src/arch/mips/regfile/regfile.hh b/src/arch/mips/regfile/regfile.hh
index 7b57b31f5..387fbd5c8 100644
--- a/src/arch/mips/regfile/regfile.hh
+++ b/src/arch/mips/regfile/regfile.hh
@@ -57,25 +57,25 @@ namespace MipsISA
bzero(&miscRegFile, sizeof(miscRegFile));
}
- MiscReg readMiscReg(int miscReg)
+ MiscReg readMiscRegNoEffect(int miscReg)
{
- return miscRegFile.readReg(miscReg);
+ return miscRegFile.readRegNoEffect(miscReg);
}
- MiscReg readMiscRegWithEffect(int miscReg, ThreadContext *tc)
+ MiscReg readMiscReg(int miscReg, ThreadContext *tc)
{
- return miscRegFile.readRegWithEffect(miscReg, tc);
+ return miscRegFile.readReg(miscReg, tc);
}
- void setMiscReg(int miscReg, const MiscReg &val)
+ void setMiscRegNoEffect(int miscReg, const MiscReg &val)
{
- miscRegFile.setReg(miscReg, val);
+ miscRegFile.setRegNoEffect(miscReg, val);
}
- void setMiscRegWithEffect(int miscReg, const MiscReg &val,
+ void setMiscReg(int miscReg, const MiscReg &val,
ThreadContext * tc)
{
- miscRegFile.setRegWithEffect(miscReg, val, tc);
+ miscRegFile.setReg(miscReg, val, tc);
}
FloatRegVal readFloatReg(int floatReg)
diff --git a/src/arch/mips/types.hh b/src/arch/mips/types.hh
index d4fa296fd..fc45ea253 100644
--- a/src/arch/mips/types.hh
+++ b/src/arch/mips/types.hh
@@ -40,6 +40,8 @@ namespace MipsISA
typedef uint8_t RegIndex;
typedef uint32_t IntReg;
+ typedef uint64_t LargestRead;
+
// floating point register file entry type
typedef uint32_t FloatReg32;
diff --git a/src/arch/mips/utility.hh b/src/arch/mips/utility.hh
index 56689ba4d..12db1de57 100644
--- a/src/arch/mips/utility.hh
+++ b/src/arch/mips/utility.hh
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007 MIPS Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,6 +28,7 @@
*
* Authors: Nathan Binkert
* Steve Reinhardt
+ * Korey Sewell
*/
#ifndef __ARCH_MIPS_UTILITY_HH__
@@ -86,17 +88,9 @@ namespace MipsISA {
return 0;
}
- static inline ExtMachInst
- makeExtMI(MachInst inst, ThreadContext * xc) {
-#if FULL_SYSTEM
- ExtMachInst ext_inst = inst;
- if (xc->readPC() && 0x1)
- return ext_inst|=(static_cast<ExtMachInst>(xc->readPC() & 0x1) << 32);
- else
- return ext_inst;
-#else
- return ExtMachInst(inst);
-#endif
+ inline void startupCPU(ThreadContext *tc, int cpuId)
+ {
+ tc->activate(0);
}
};
diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript
index 555bfba3d..e342c79cf 100644
--- a/src/arch/sparc/SConscript
+++ b/src/arch/sparc/SConscript
@@ -29,65 +29,38 @@
# Authors: Gabe Black
# Steve Reinhardt
-import os
-import sys
-from os.path import isdir
+Import('*')
-# Import build environment variable from SConstruct.
-Import('env')
+if env['TARGET_ISA'] == 'sparc':
+ Source('asi.cc')
+ Source('faults.cc')
+ Source('floatregfile.cc')
+ Source('intregfile.cc')
+ Source('miscregfile.cc')
+ Source('regfile.cc')
+ Source('remote_gdb.cc')
-###################################################
-#
-# Define needed sources.
-#
-###################################################
-
-# Base sources used by all configurations.
-base_sources = Split('''
- asi.cc
- faults.cc
- floatregfile.cc
- intregfile.cc
- miscregfile.cc
- regfile.cc
- remote_gdb.cc
- ''')
-
-# Full-system sources
-full_system_sources = Split('''
- arguments.cc
- pagetable.cc
- stacktrace.cc
- system.cc
- tlb.cc
- ua2005.cc
- vtophys.cc
- ''')
-
-# Syscall emulation (non-full-system) sources
-syscall_emulation_sources = Split('''
- linux/linux.cc
- linux/process.cc
- process.cc
- solaris/process.cc
- solaris/solaris.cc
- ''')
-
-sources = base_sources
-
-if env['FULL_SYSTEM']:
- sources += full_system_sources
-else:
- sources += syscall_emulation_sources
+ if env['FULL_SYSTEM']:
+ Source('arguments.cc')
+ Source('pagetable.cc')
+ Source('stacktrace.cc')
+ Source('system.cc')
+ Source('tlb.cc')
+ Source('ua2005.cc')
+ Source('vtophys.cc')
+ else:
+ Source('process.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]
+ Source('linux/linux.cc')
+ Source('linux/process.cc')
+ Source('linux/syscalls.cc')
-# Add in files generated by the ISA description.
-isa_desc_files = env.ISADesc('isa/main.isa')
-# Only non-header files need to be compiled.
-isa_desc_sources = [f for f in isa_desc_files if not f.path.endswith('.hh')]
-sources += isa_desc_sources
+ Source('solaris/process.cc')
+ Source('solaris/solaris.cc')
-Return('sources')
+ # Add in files generated by the ISA description.
+ isa_desc_files = env.ISADesc('isa/main.isa')
+ # Only non-header files need to be compiled.
+ for f in isa_desc_files:
+ if not f.path.endswith('.hh'):
+ Source(f)
diff --git a/src/arch/sparc/SConsopts b/src/arch/sparc/SConsopts
new file mode 100644
index 000000000..c35606281
--- /dev/null
+++ b/src/arch/sparc/SConsopts
@@ -0,0 +1,33 @@
+# -*- 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: Nathan Binkert
+
+Import('*')
+
+all_isa_list.append('sparc')
diff --git a/src/arch/sparc/arguments.hh b/src/arch/sparc/arguments.hh
index 8f925dd25..5596f7408 100644
--- a/src/arch/sparc/arguments.hh
+++ b/src/arch/sparc/arguments.hh
@@ -33,9 +33,9 @@
#include <assert.h>
-#include "arch/sparc/vtophys.hh"
#include "base/refcnt.hh"
#include "sim/host.hh"
+#include "mem/vport.hh"
class ThreadContext;
diff --git a/src/arch/sparc/asi.cc b/src/arch/sparc/asi.cc
index 3d553955f..254635bff 100644
--- a/src/arch/sparc/asi.cc
+++ b/src/arch/sparc/asi.cc
@@ -247,7 +247,8 @@ namespace SparcISA
bool AsiIsCmt(ASI asi)
{
return
- (asi == ASI_CMT_PER_STRAND);
+ (asi == ASI_CMT_PER_STRAND) ||
+ (asi == ASI_CMT_SHARED);
}
bool AsiIsQueue(ASI asi)
@@ -294,7 +295,9 @@ namespace SparcISA
bool AsiIsReg(ASI asi)
{
- return AsiIsMmu(asi) || AsiIsScratchPad(asi) | AsiIsSparcError(asi);
+ return AsiIsMmu(asi) || AsiIsScratchPad(asi) ||
+ AsiIsSparcError(asi) || AsiIsInterrupt(asi)
+ || AsiIsCmt(asi);
}
bool AsiIsSparcError(ASI asi)
diff --git a/src/arch/sparc/asi.hh b/src/arch/sparc/asi.hh
index 166c3867e..eba2d518f 100644
--- a/src/arch/sparc/asi.hh
+++ b/src/arch/sparc/asi.hh
@@ -115,6 +115,7 @@ namespace SparcISA
ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS1 = 0x3E,
ASI_IMMU_CTXT_NONZERO_CONFIG = 0x3F,
ASI_STREAM_MA = 0x40,
+ ASI_CMT_SHARED = 0x41,
//0x41 implementation dependent
ASI_SPARC_BIST_CONTROL = 0x42,
ASI_INST_MASK_REG = 0x42,
diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc
index a6f4343ae..88c086090 100644
--- a/src/arch/sparc/faults.cc
+++ b/src/arch/sparc/faults.cc
@@ -208,6 +208,10 @@ template<> SparcFaultBase::FaultVals
{"trap_level_zero", 0x05F, 202, {H, H, SH}};
template<> SparcFaultBase::FaultVals
+ SparcFault<InterruptVector>::vals =
+ {"interrupt_vector", 0x060, 2630, {H, H, H}};
+
+template<> SparcFaultBase::FaultVals
SparcFault<PAWatchpoint>::vals =
{"PA_watchpoint", 0x061, 1209, {H, H, H}};
@@ -263,12 +267,6 @@ template<> SparcFaultBase::FaultVals
SparcFault<TrapInstruction>::vals =
{"trap_instruction", 0x100, 1602, {P, P, H}};
-#if !FULL_SYSTEM
-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.
@@ -278,17 +276,17 @@ void enterREDState(ThreadContext *tc)
{
//@todo Disable the mmu?
//@todo Disable watchpoints?
- MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
+ MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
//HPSTATE.red = 1
HPSTATE |= (1 << 5);
//HPSTATE.hpriv = 1
HPSTATE |= (1 << 2);
- tc->setMiscRegWithEffect(MISCREG_HPSTATE, HPSTATE);
+ tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
//PSTATE.priv is set to 1 here. The manual says it should be 0, but
//Legion sets it to 1.
- MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
+ MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE);
PSTATE |= (1 << 2);
- tc->setMiscRegWithEffect(MISCREG_PSTATE, PSTATE);
+ tc->setMiscReg(MISCREG_PSTATE, PSTATE);
}
/**
@@ -298,17 +296,17 @@ void enterREDState(ThreadContext *tc)
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 TL = tc->readMiscRegNoEffect(MISCREG_TL);
+ MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
+ MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE);
+ MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
+ //MiscReg CCR = tc->readMiscRegNoEffect(MISCREG_CCR);
MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
- MiscReg ASI = tc->readMiscReg(MISCREG_ASI);
- MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
- //MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
- MiscReg CANSAVE = tc->readMiscReg(NumIntArchRegs + 3);
- MiscReg GL = tc->readMiscReg(MISCREG_GL);
+ MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
+ MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
+ //MiscReg CANSAVE = tc->readMiscRegNoEffect(MISCREG_CANSAVE);
+ MiscReg CANSAVE = tc->readMiscRegNoEffect(NumIntArchRegs + 3);
+ MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL);
MiscReg PC = tc->readPC();
MiscReg NPC = tc->readNextPC();
@@ -331,25 +329,25 @@ void doREDFault(ThreadContext *tc, TrapType tt)
replaceBits(TSTATE, 4, 0, CWP);
//Write back TSTATE
- tc->setMiscReg(MISCREG_TSTATE, TSTATE);
+ tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);
//set TPC to PC
- tc->setMiscReg(MISCREG_TPC, PC);
+ tc->setMiscRegNoEffect(MISCREG_TPC, PC);
//set TNPC to NPC
- tc->setMiscReg(MISCREG_TNPC, NPC);
+ tc->setMiscRegNoEffect(MISCREG_TNPC, NPC);
//set HTSTATE.hpstate to hpstate
- tc->setMiscReg(MISCREG_HTSTATE, HPSTATE);
+ tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE);
//TT = trap type;
- tc->setMiscReg(MISCREG_TT, tt);
+ tc->setMiscRegNoEffect(MISCREG_TT, tt);
//Update GL
- tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL));
+ tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL));
PSTATE = mbits(PSTATE, 2, 2); // just save the priv bit
PSTATE |= (1 << 4); //set PSTATE.pef to 1
- tc->setMiscReg(MISCREG_PSTATE, PSTATE);
+ tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE);
//set HPSTATE.red to 1
HPSTATE |= (1 << 5);
@@ -359,7 +357,7 @@ void doREDFault(ThreadContext *tc, TrapType tt)
HPSTATE &= ~(1 << 10);
//set HPSTATE.tlz to 0
HPSTATE &= ~(1 << 0);
- tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
+ tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE);
bool changedCWP = true;
if(tt == 0x24)
@@ -374,7 +372,7 @@ void doREDFault(ThreadContext *tc, TrapType tt)
if(changedCWP)
{
CWP = (CWP + NWindows) % NWindows;
- tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
+ tc->setMiscReg(MISCREG_CWP, CWP);
}
}
@@ -385,17 +383,17 @@ void doREDFault(ThreadContext *tc, TrapType tt)
void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
{
- 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 TL = tc->readMiscRegNoEffect(MISCREG_TL);
+ MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
+ MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE);
+ MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
+ //MiscReg CCR = tc->readMiscRegNoEffect(MISCREG_CCR);
MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
- MiscReg ASI = tc->readMiscReg(MISCREG_ASI);
- MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
- //MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
+ MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
+ MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
+ //MiscReg CANSAVE = tc->readMiscRegNoEffect(MISCREG_CANSAVE);
MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3);
- MiscReg GL = tc->readMiscReg(MISCREG_GL);
+ MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL);
MiscReg PC = tc->readPC();
MiscReg NPC = tc->readNextPC();
@@ -406,7 +404,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
//Increment the trap level
TL++;
- tc->setMiscReg(MISCREG_TL, TL);
+ tc->setMiscRegNoEffect(MISCREG_TL, TL);
//Save off state
@@ -422,24 +420,24 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
replaceBits(TSTATE, 4, 0, CWP);
//Write back TSTATE
- tc->setMiscReg(MISCREG_TSTATE, TSTATE);
+ tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);
//set TPC to PC
- tc->setMiscReg(MISCREG_TPC, PC);
+ tc->setMiscRegNoEffect(MISCREG_TPC, PC);
//set TNPC to NPC
- tc->setMiscReg(MISCREG_TNPC, NPC);
+ tc->setMiscRegNoEffect(MISCREG_TNPC, NPC);
//set HTSTATE.hpstate to hpstate
- tc->setMiscReg(MISCREG_HTSTATE, HPSTATE);
+ tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE);
//TT = trap type;
- tc->setMiscReg(MISCREG_TT, tt);
+ tc->setMiscRegNoEffect(MISCREG_TT, tt);
//Update the global register level
if (!gotoHpriv)
- tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxPGL));
+ tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxPGL));
else
- tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL));
+ tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL));
//PSTATE.mm is unchanged
PSTATE |= (1 << 4); //PSTATE.pef = whether or not an fpu is present
@@ -456,12 +454,12 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
HPSTATE |= (1 << 2); //HPSTATE.hpriv = 1
HPSTATE &= ~(1 << 10); //HPSTATE.ibe = 0
//HPSTATE.tlz is unchanged
- tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
+ tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE);
} else { // we are going to priv
PSTATE |= (1 << 2); //PSTATE.priv = 1
replaceBits(PSTATE, 9, 9, PSTATE >> 8); //PSTATE.cle = PSTATE.tle
}
- tc->setMiscReg(MISCREG_PSTATE, PSTATE);
+ tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE);
bool changedCWP = true;
@@ -477,7 +475,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
if (changedCWP)
{
CWP = (CWP + NWindows) % NWindows;
- tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
+ tc->setMiscReg(MISCREG_CWP, CWP);
}
}
@@ -491,14 +489,14 @@ void getREDVector(MiscReg TT, Addr & PC, Addr & NPC)
void getHyperVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT)
{
- Addr HTBA = tc->readMiscReg(MISCREG_HTBA);
+ Addr HTBA = tc->readMiscRegNoEffect(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);
+ Addr TBA = tc->readMiscRegNoEffect(MISCREG_TBA);
PC = (TBA & ~mask(15)) |
(TL > 1 ? (1 << 14) : 0) |
((TT << 5) & mask(14));
@@ -515,10 +513,10 @@ void SparcFaultBase::invoke(ThreadContext * tc)
//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);
+ MiscReg tl = tc->readMiscRegNoEffect(MISCREG_TL);
+ MiscReg tt = tc->readMiscRegNoEffect(MISCREG_TT);
+ MiscReg pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
+ MiscReg hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
Addr PC, NPC;
@@ -567,15 +565,15 @@ void PowerOnReset::invoke(ThreadContext * tc)
//on reset Trap which sets the processor into the following state.
//Bits that aren't set aren't defined on startup.
- tc->setMiscReg(MISCREG_TL, MaxTL);
- tc->setMiscReg(MISCREG_TT, trapType());
- tc->setMiscRegWithEffect(MISCREG_GL, MaxGL);
+ tc->setMiscRegNoEffect(MISCREG_TL, MaxTL);
+ tc->setMiscRegNoEffect(MISCREG_TT, trapType());
+ tc->setMiscReg(MISCREG_GL, MaxGL);
//Turn on pef and priv, set everything else to 0
- tc->setMiscReg(MISCREG_PSTATE, (1 << 4) | (1 << 2));
+ tc->setMiscRegNoEffect(MISCREG_PSTATE, (1 << 4) | (1 << 2));
//Turn on red and hpriv, set everything else to 0
- MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
+ MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
//HPSTATE.red = 1
HPSTATE |= (1 << 5);
//HPSTATE.hpriv = 1
@@ -584,10 +582,10 @@ void PowerOnReset::invoke(ThreadContext * tc)
HPSTATE &= ~(1 << 10);
//HPSTATE.tlz = 0
HPSTATE &= ~(1 << 0);
- tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
+ tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE);
//The tick register is unreadable by nonprivileged software
- tc->setMiscReg(MISCREG_TICK, 1ULL << 63);
+ tc->setMiscRegNoEffect(MISCREG_TICK, 1ULL << 63);
//Enter RED state. We do this last so that the actual state preserved in
//the trap stack is the state from before this fault.
@@ -605,7 +603,7 @@ void PowerOnReset::invoke(ThreadContext * tc)
// Clear all the soft interrupt bits
softint = 0;
// disable timer compare interrupts, reset tick_cmpr
- tc->setMiscReg(MISCREG_
+ tc->setMiscRegNoEffect(MISCREG_
tick_cmprFields.int_dis = 1;
tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
stickFields.npt = 1; //The TICK register is unreadable by by !priv
@@ -656,26 +654,24 @@ void FillNNormal::invoke(ThreadContext *tc)
tc->setNextNPC(fillStart + 2*sizeof(MachInst));
}
-void PageTableFault::invoke(ThreadContext *tc)
+void TrapInstruction::invoke(ThreadContext *tc)
{
+ //In SE, this mechanism is how the process requests a service from the
+ //operating system. We'll get the process object from the thread context
+ //and let it service the request.
+
Process *p = tc->getProcessPtr();
- // We've accessed the next page of the stack, so extend the stack
- // to cover it.
- if(vaddr < p->stack_min && vaddr >= p->stack_min - PageBytes)
- {
- p->stack_min -= PageBytes;
- if(p->stack_base - p->stack_min > 8*1024*1024)
- fatal("Over max stack size for one thread\n");
- p->pTable->allocate(p->stack_min, PageBytes);
- warn("Increasing stack size by one page.");
- }
- // Otherwise, we have an unexpected page fault. Report that fact,
- // and what address was accessed to cause the fault.
- else
- {
- panic("Page table fault when accessing virtual address %#x\n", vaddr);
- }
+ SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
+ assert(lp);
+
+ lp->handleTrap(_n, tc);
+
+ //We need to explicitly advance the pc, since that's not done for us
+ //on a faulting instruction
+ tc->setPC(tc->readNextPC());
+ tc->setNextPC(tc->readNextNPC());
+ tc->setNextNPC(tc->readNextNPC() + sizeof(MachInst));
}
#endif
diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh
index 3c0d9674f..10ef89279 100644
--- a/src/arch/sparc/faults.hh
+++ b/src/arch/sparc/faults.hh
@@ -193,6 +193,8 @@ class HstickMatch : public SparcFault<HstickMatch> {};
class TrapLevelZero : public SparcFault<TrapLevelZero> {};
+class InterruptVector : public SparcFault<InterruptVector> {};
+
class PAWatchpoint : public SparcFault<PAWatchpoint> {};
class VAWatchpoint : public SparcFault<VAWatchpoint> {};
@@ -246,26 +248,13 @@ class FillNOther : public EnumeratedFault<FillNOther>
class TrapInstruction : public EnumeratedFault<TrapInstruction>
{
-
public:
TrapInstruction(uint32_t n) : EnumeratedFault<TrapInstruction>(n) {;}
-};
-
+ //In SE, trap instructions are requesting services from the OS.
#if !FULL_SYSTEM
-class PageTableFault : public SparcFault<PageTableFault>
-{
- private:
- Addr vaddr;
- public:
- PageTableFault(Addr va) : vaddr(va) {}
void invoke(ThreadContext * tc);
-};
-
-static inline Fault genPageTableFault(Addr va)
-{
- return new PageTableFault(va);
-}
#endif
+};
static inline Fault genMachineCheckFault()
{
diff --git a/src/arch/sparc/handlers.hh b/src/arch/sparc/handlers.hh
new file mode 100644
index 000000000..ce5b69427
--- /dev/null
+++ b/src/arch/sparc/handlers.hh
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2003-2004 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_HANDLERS_HH__
+#define __ARCH_SPARC_HANDLERS_HH__
+
+#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/types.hh"
+#include "sim/byteswap.hh"
+
+namespace SparcISA {
+
+//We only use 19 instructions for the trap handlers, but there would be
+//space for 32 in a real SPARC trap table.
+const int numFillInsts = 32;
+const int numSpillInsts = 32;
+
+const MachInst fillHandler64[numFillInsts] =
+{
+ htog(0x87802018), //wr %g0, ASI_AIUP, %asi
+ htog(0xe0dba7ff), //ldxa [%sp + BIAS + (0*8)] %asi, %l0
+ htog(0xe2dba807), //ldxa [%sp + BIAS + (1*8)] %asi, %l1
+ htog(0xe4dba80f), //ldxa [%sp + BIAS + (2*8)] %asi, %l2
+ htog(0xe6dba817), //ldxa [%sp + BIAS + (3*8)] %asi, %l3
+ htog(0xe8dba81f), //ldxa [%sp + BIAS + (4*8)] %asi, %l4
+ htog(0xeadba827), //ldxa [%sp + BIAS + (5*8)] %asi, %l5
+ htog(0xecdba82f), //ldxa [%sp + BIAS + (6*8)] %asi, %l6
+ htog(0xeedba837), //ldxa [%sp + BIAS + (7*8)] %asi, %l7
+ htog(0xf0dba83f), //ldxa [%sp + BIAS + (8*8)] %asi, %i0
+ htog(0xf2dba847), //ldxa [%sp + BIAS + (9*8)] %asi, %i1
+ htog(0xf4dba84f), //ldxa [%sp + BIAS + (10*8)] %asi, %i2
+ htog(0xf6dba857), //ldxa [%sp + BIAS + (11*8)] %asi, %i3
+ htog(0xf8dba85f), //ldxa [%sp + BIAS + (12*8)] %asi, %i4
+ htog(0xfadba867), //ldxa [%sp + BIAS + (13*8)] %asi, %i5
+ htog(0xfcdba86f), //ldxa [%sp + BIAS + (14*8)] %asi, %i6
+ htog(0xfedba877), //ldxa [%sp + BIAS + (15*8)] %asi, %i7
+ htog(0x83880000), //restored
+ htog(0x83F00000), //retry
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000) //illtrap
+};
+
+const MachInst fillHandler32[numFillInsts] =
+{
+ htog(0x87802018), //wr %g0, ASI_AIUP, %asi
+ htog(0xe083a000), //lduwa [%sp + (0*4)] %asi, %l0
+ htog(0xe283a004), //lduwa [%sp + (1*4)] %asi, %l1
+ htog(0xe483a008), //lduwa [%sp + (2*4)] %asi, %l2
+ htog(0xe683a00c), //lduwa [%sp + (3*4)] %asi, %l3
+ htog(0xe883a010), //lduwa [%sp + (4*4)] %asi, %l4
+ htog(0xea83a014), //lduwa [%sp + (5*4)] %asi, %l5
+ htog(0xec83a018), //lduwa [%sp + (6*4)] %asi, %l6
+ htog(0xee83a01c), //lduwa [%sp + (7*4)] %asi, %l7
+ htog(0xf083a020), //lduwa [%sp + (8*4)] %asi, %i0
+ htog(0xf283a024), //lduwa [%sp + (9*4)] %asi, %i1
+ htog(0xf483a028), //lduwa [%sp + (10*4)] %asi, %i2
+ htog(0xf683a02c), //lduwa [%sp + (11*4)] %asi, %i3
+ htog(0xf883a030), //lduwa [%sp + (12*4)] %asi, %i4
+ htog(0xfa83a034), //lduwa [%sp + (13*4)] %asi, %i5
+ htog(0xfc83a038), //lduwa [%sp + (14*4)] %asi, %i6
+ htog(0xfe83a03c), //lduwa [%sp + (15*4)] %asi, %i7
+ htog(0x83880000), //restored
+ htog(0x83F00000), //retry
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000) //illtrap
+};
+
+const MachInst spillHandler64[numSpillInsts] =
+{
+ htog(0x87802018), //wr %g0, ASI_AIUP, %asi
+ htog(0xe0f3a7ff), //stxa %l0, [%sp + BIAS + (0*8)] %asi
+ htog(0xe2f3a807), //stxa %l1, [%sp + BIAS + (1*8)] %asi
+ htog(0xe4f3a80f), //stxa %l2, [%sp + BIAS + (2*8)] %asi
+ htog(0xe6f3a817), //stxa %l3, [%sp + BIAS + (3*8)] %asi
+ htog(0xe8f3a81f), //stxa %l4, [%sp + BIAS + (4*8)] %asi
+ htog(0xeaf3a827), //stxa %l5, [%sp + BIAS + (5*8)] %asi
+ htog(0xecf3a82f), //stxa %l6, [%sp + BIAS + (6*8)] %asi
+ htog(0xeef3a837), //stxa %l7, [%sp + BIAS + (7*8)] %asi
+ htog(0xf0f3a83f), //stxa %i0, [%sp + BIAS + (8*8)] %asi
+ htog(0xf2f3a847), //stxa %i1, [%sp + BIAS + (9*8)] %asi
+ htog(0xf4f3a84f), //stxa %i2, [%sp + BIAS + (10*8)] %asi
+ htog(0xf6f3a857), //stxa %i3, [%sp + BIAS + (11*8)] %asi
+ htog(0xf8f3a85f), //stxa %i4, [%sp + BIAS + (12*8)] %asi
+ htog(0xfaf3a867), //stxa %i5, [%sp + BIAS + (13*8)] %asi
+ htog(0xfcf3a86f), //stxa %i6, [%sp + BIAS + (14*8)] %asi
+ htog(0xfef3a877), //stxa %i7, [%sp + BIAS + (15*8)] %asi
+ htog(0x81880000), //saved
+ htog(0x83F00000), //retry
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000) //illtrap
+};
+
+const MachInst spillHandler32[numSpillInsts] =
+{
+ htog(0x87802018), //wr %g0, ASI_AIUP, %asi
+ htog(0xe0a3a000), //stwa %l0, [%sp + (0*4)] %asi
+ htog(0xe2a3a004), //stwa %l1, [%sp + (1*4)] %asi
+ htog(0xe4a3a008), //stwa %l2, [%sp + (2*4)] %asi
+ htog(0xe6a3a00c), //stwa %l3, [%sp + (3*4)] %asi
+ htog(0xe8a3a010), //stwa %l4, [%sp + (4*4)] %asi
+ htog(0xeaa3a014), //stwa %l5, [%sp + (5*4)] %asi
+ htog(0xeca3a018), //stwa %l6, [%sp + (6*4)] %asi
+ htog(0xeea3a01c), //stwa %l7, [%sp + (7*4)] %asi
+ htog(0xf0a3a020), //stwa %i0, [%sp + (8*4)] %asi
+ htog(0xf2a3a024), //stwa %i1, [%sp + (9*4)] %asi
+ htog(0xf4a3a028), //stwa %i2, [%sp + (10*4)] %asi
+ htog(0xf6a3a02c), //stwa %i3, [%sp + (11*4)] %asi
+ htog(0xf8a3a030), //stwa %i4, [%sp + (12*4)] %asi
+ htog(0xfaa3a034), //stwa %i5, [%sp + (13*4)] %asi
+ htog(0xfca3a038), //stwa %i6, [%sp + (14*4)] %asi
+ htog(0xfea3a03c), //stwa %i7, [%sp + (15*4)] %asi
+ htog(0x81880000), //saved
+ htog(0x83F00000), //retry
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000), //illtrap
+ htog(0x00000000) //illtrap
+};
+
+} // namespace SparcISA
+#endif // __ARCH_SPARC_HANDLERS_HH__
diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh
index dc3b235fe..4ad3385fb 100644
--- a/src/arch/sparc/interrupts.hh
+++ b/src/arch/sparc/interrupts.hh
@@ -24,82 +24,86 @@
* 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
+ * Lisa Hsu
*/
#ifndef __ARCH_SPARC_INTERRUPT_HH__
#define __ARCH_SPARC_INTERRUPT_HH__
#include "arch/sparc/faults.hh"
+#include "arch/sparc/isa_traits.hh"
#include "cpu/thread_context.hh"
namespace SparcISA
{
-enum interrupts_t {
- trap_level_zero,
- hstick_match,
- interrupt_vector,
- cpu_mondo,
- dev_mondo,
- resumable_error,
- soft_interrupt,
- num_interrupt_types
-};
-
class Interrupts
{
private:
- bool interrupts[num_interrupt_types];
- int numPosted;
+ uint64_t interrupts[NumInterruptTypes];
+ uint64_t intStatus;
public:
Interrupts()
{
- for (int i = 0; i < num_interrupt_types; ++i) {
- interrupts[i] = false;
- }
- numPosted = 0;
+ clear_all();
}
- void post(int int_type)
+ int InterruptLevel(uint64_t softint)
{
- if (int_type < 0 || int_type >= num_interrupt_types)
- panic("posting unknown interrupt!\n");
- if (interrupts[int_type] == false) {
- interrupts[int_type] = true;
- ++numPosted;
- }
+ if (softint & 0x10000 || softint & 0x1)
+ return 14;
+
+ int level = 15;
+ while (level > 0 && !(1 << level & softint))
+ level--;
+ if (1 << level & softint)
+ return level;
+ return 0;
}
void post(int int_num, int index)
{
+ DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
+ assert(int_num >= 0 && int_num < NumInterruptTypes);
+ assert(index >= 0 && index < 64);
+ interrupts[int_num] |= ULL(1) << index;
+ intStatus |= ULL(1) << int_num;
}
void clear(int int_num, int index)
{
+ DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
+ assert(int_num >= 0 && int_num < NumInterruptTypes);
+ assert(index >= 0 && index < 64);
+ interrupts[int_num] &= ~(ULL(1) << index);
+ if (!interrupts[int_num])
+ intStatus &= ~(ULL(1) << int_num);
}
void clear_all()
{
-
+ for (int i = 0; i < NumInterruptTypes; ++i) {
+ interrupts[i] = 0;
+ }
+ intStatus = 0;
}
bool check_interrupts(ThreadContext * tc) const
{
- if (numPosted)
- return true;
- else
- return false;
+ return intStatus;
}
Fault getInterrupt(ThreadContext * tc)
{
- int hpstate = tc->readMiscReg(MISCREG_HPSTATE);
- int pstate = tc->readMiscReg(MISCREG_PSTATE);
+ int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
+ int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
bool ie = pstate & PSTATE::ie;
// THESE ARE IN ORDER OF PRIORITY
@@ -109,84 +113,45 @@ class Interrupts
// in the right order of processing
if (hpstate & HPSTATE::hpriv) {
if (ie) {
- if (interrupts[hstick_match]) {
- if (tc->readMiscReg(MISCREG_HINTP) & 1) {
- interrupts[hstick_match] = false;
- --numPosted;
- return new HstickMatch;
- }
- }
- if (interrupts[interrupt_vector]) {
- interrupts[interrupt_vector] = false;
- --numPosted;
- //HAVEN'T IMPLed THIS YET
- return NoFault;
+ if (interrupts[IT_HINTP]) {
+ // This will be cleaned by a HINTP write
+ return new HstickMatch;
}
- } else {
- if (interrupts[hstick_match]) {
- return NoFault;
+ if (interrupts[IT_INT_VEC]) {
+ // this will be cleared by an ASI read (or write)
+ return new InterruptVector;
}
-
}
} else {
- if (interrupts[trap_level_zero]) {
- if ((pstate & HPSTATE::tlz) && (tc->readMiscReg(MISCREG_TL) == 0)) {
- interrupts[trap_level_zero] = false;
- --numPosted;
+ if (interrupts[IT_TRAP_LEVEL_ZERO]) {
+ // this is cleared by deasserting HPSTATE::tlz
return new TrapLevelZero;
- }
}
- if (interrupts[hstick_match]) {
- if (tc->readMiscReg(MISCREG_HINTP) & 1) {
- interrupts[hstick_match] = false;
- --numPosted;
- return new HstickMatch;
- }
+ // HStick matches always happen in priv mode (ie doesn't matter)
+ if (interrupts[IT_HINTP]) {
+ return new HstickMatch;
+ }
+ if (interrupts[IT_INT_VEC]) {
+ // this will be cleared by an ASI read (or write)
+ return new InterruptVector;
}
if (ie) {
- if (interrupts[cpu_mondo]) {
- interrupts[cpu_mondo] = false;
- --numPosted;
+ if (interrupts[IT_CPU_MONDO]) {
return new CpuMondo;
}
- if (interrupts[dev_mondo]) {
- interrupts[dev_mondo] = false;
- --numPosted;
+ if (interrupts[IT_DEV_MONDO]) {
return new DevMondo;
}
- if (interrupts[soft_interrupt]) {
- int il = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT));
- // it seems that interrupt vectors are right in
- // the middle of interrupt levels with regard to
- // priority, so have to check
- if ((il < 6) &&
- interrupts[interrupt_vector]) {
- // may require more details here since there
- // may be lots of interrupts embedded in an
- // platform interrupt vector
- interrupts[interrupt_vector] = false;
- --numPosted;
- //HAVEN'T IMPLed YET
- return NoFault;
- } else {
- if (il > tc->readMiscReg(MISCREG_PIL)) {
- uint64_t si = tc->readMiscReg(MISCREG_SOFTINT);
- uint64_t more = si & ~(1 << (il + 1));
- if (!InterruptLevel(more)) {
- interrupts[soft_interrupt] = false;
- --numPosted;
- }
- return new InterruptLevelN(il);
- }
- }
+ if (interrupts[IT_SOFT_INT]) {
+ return new
+ InterruptLevelN(InterruptLevel(interrupts[IT_SOFT_INT]));
}
- if (interrupts[resumable_error]) {
- interrupts[resumable_error] = false;
- --numPosted;
+
+ if (interrupts[IT_RES_ERROR]) {
return new ResumableError;
}
- }
- }
+ } // !hpriv && ie
+ } // !hpriv
return NoFault;
}
@@ -195,16 +160,22 @@ class Interrupts
}
+ uint64_t get_vec(int int_num)
+ {
+ assert(int_num >= 0 && int_num < NumInterruptTypes);
+ return interrupts[int_num];
+ }
+
void serialize(std::ostream &os)
{
- SERIALIZE_ARRAY(interrupts,num_interrupt_types);
- SERIALIZE_SCALAR(numPosted);
+ SERIALIZE_ARRAY(interrupts,NumInterruptTypes);
+ SERIALIZE_SCALAR(intStatus);
}
void unserialize(Checkpoint *cp, const std::string &section)
{
- UNSERIALIZE_ARRAY(interrupts,num_interrupt_types);
- UNSERIALIZE_SCALAR(numPosted);
+ UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes);
+ UNSERIALIZE_SCALAR(intStatus);
}
};
} // namespace SPARC_ISA
diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh
index 665c7aa31..83ef1d17b 100644
--- a/src/arch/sparc/intregfile.hh
+++ b/src/arch/sparc/intregfile.hh
@@ -82,7 +82,7 @@ namespace SparcISA
IntReg * regView[NumFrames];
static const int RegGlobalOffset = 0;
- static const int FrameOffset = MaxGL * RegsPerFrame;
+ static const int FrameOffset = (MaxGL + 1) * RegsPerFrame;
int offset[NumFrames];
public:
diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa
index 693cc6876..bba63f407 100644
--- a/src/arch/sparc/isa/base.isa
+++ b/src/arch/sparc/isa/base.isa
@@ -492,8 +492,8 @@ output exec {{
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
{
Fault fault = NoFault; // dummy... this ipr access should not fault
- if (xc->readMiscRegWithEffect(MISCREG_PSTATE) & PSTATE::pef &&
- xc->readMiscRegWithEffect(MISCREG_FPRS) & 0x4)
+ if (xc->readMiscReg(MISCREG_PSTATE) & PSTATE::pef &&
+ xc->readMiscReg(MISCREG_FPRS) & 0x4)
return NoFault;
else
return new FpDisabled;
diff --git a/src/arch/sparc/isa/bitfields.isa b/src/arch/sparc/isa/bitfields.isa
index e75680d2b..afa8f88a2 100644
--- a/src/arch/sparc/isa/bitfields.isa
+++ b/src/arch/sparc/isa/bitfields.isa
@@ -54,6 +54,7 @@ def bitfield FCN <29:25>;
def bitfield I <13>;
def bitfield IMM_ASI <12:5>;
def bitfield IMM22 <21:0>;
+def bitfield M5FUNC <15:7>;
def bitfield MMASK <3:0>;
def bitfield OP <31:30>;
def bitfield OP2 <24:22>;
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index fb606c7cc..556bb4bca 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -185,25 +185,25 @@ decode OP default Unknown::unknown()
}}, ',a');
}
default: decode BPCC {
- 0x0: fbpcc0(22, {{
+ 0x0: fbpfcc0(19, {{
if(passesFpCondition(Fsr<11:10>, COND2))
NNPC = xc->readPC() + disp;
else
handle_annul
}});
- 0x1: fbpcc1(22, {{
+ 0x1: fbpfcc1(19, {{
if(passesFpCondition(Fsr<33:32>, COND2))
NNPC = xc->readPC() + disp;
else
handle_annul
}});
- 0x2: fbpcc2(22, {{
+ 0x2: fbpfcc2(19, {{
if(passesFpCondition(Fsr<35:34>, COND2))
NNPC = xc->readPC() + disp;
else
handle_annul
}});
- 0x3: fbpcc3(22, {{
+ 0x3: fbpfcc3(19, {{
if(passesFpCondition(Fsr<37:36>, COND2))
NNPC = xc->readPC() + disp;
else
@@ -426,19 +426,22 @@ decode OP default Unknown::unknown()
{{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
);
0x24: mulscc({{
- int64_t resTemp, multiplicand = Rs2_or_imm13;
- int32_t multiplier = Rs1<31:0>;
int32_t savedLSB = Rs1<0:>;
- multiplier = multiplier<31:1> |
- ((Ccr<3:3> ^ Ccr<1:1>) << 32);
- if(!Y<0:>)
- multiplicand = 0;
- Rd = resTemp = multiplicand + multiplier;
+
+ //Step 1
+ int64_t multiplicand = Rs2_or_imm13;
+ //Step 2
+ int32_t partialP = Rs1<31:1> |
+ ((Ccr<3:3> ^ Ccr<1:1>) << 31);
+ //Step 3
+ int32_t added = Y<0:> ? multiplicand : 0;
+ Rd = partialP + added;
+ //Steps 4 & 5
Y = Y<31:1> | (savedLSB << 31);}},
- {{((multiplicand<31:0> + multiplier<31:0>)<32:0>)}},
- {{multiplicand<31:> == multiplier<31:> && multiplier<31:> != resTemp<31:>}},
- {{((multiplicand >> 1) + (multiplier >> 1) + (multiplicand & multiplier & 0x1))<63:>}},
- {{multiplicand<63:> == multiplier<63:> && multiplier<63:> != resTemp<63:>}}
+ {{((partialP<31:0> + added<31:0>)<32:0>)}},
+ {{partialP<31:> == added<31:> && added<31:> != Rd<31:>}},
+ {{((partialP >> 1) + (added >> 1) + (partialP & added & 0x1))<63:>}},
+ {{partialP<63:> == added<63:> && partialP<63:> != Rd<63:>}}
);
}
format IntOp
@@ -472,8 +475,8 @@ decode OP default Unknown::unknown()
}});
//7-14 should cause an illegal instruction exception
0x0F: decode I {
- 0x0: Nop::stbar({{/*stuff*/}});
- 0x1: Nop::membar({{/*stuff*/}});
+ 0x0: Nop::stbar({{/*stuff*/}}, IsWriteBarrier, MemWriteOp);
+ 0x1: Nop::membar({{/*stuff*/}}, IsMemBarrier, MemReadOp);
}
0x10: Priv::rdpcr({{Rd = Pcr;}});
0x11: PrivCheck::rdpic({{Rd = Pic;}}, {{Pcr<0:>}});
@@ -620,10 +623,6 @@ decode OP default Unknown::unknown()
}});
0x19: Priv::wrstick_cmpr({{StickCmpr = Rs1 ^ Rs2_or_imm13;}});
0x1A: Priv::wrstrand_sts_reg({{
- if(Pstate<2:> && !Hpstate<2:>)
- StrandStsReg = StrandStsReg<63:1> |
- (Rs1 ^ Rs2_or_imm13)<0:>;
- else
StrandStsReg = Rs1 ^ Rs2_or_imm13;
}});
//0x1A is supposed to be reserved, but it writes the strand
@@ -820,6 +819,58 @@ decode OP default Unknown::unknown()
}
0x35: decode OPF{
format FpBasic{
+ 0x01: fmovs_fcc0({{
+ if(passesFpCondition(Fsr<11:10>, COND4))
+ Frds = Frs2s;
+ else
+ Frds = Frds;
+ }});
+ 0x02: fmovd_fcc0({{
+ if(passesFpCondition(Fsr<11:10>, COND4))
+ Frd = Frs2;
+ else
+ Frd = Frd;
+ }});
+ 0x03: FpUnimpl::fmovq_fcc0();
+ 0x25: fmovrsz({{
+ if(Rs1 == 0)
+ Frds = Frs2s;
+ else
+ Frds = Frds;
+ }});
+ 0x26: fmovrdz({{
+ if(Rs1 == 0)
+ Frd = Frs2;
+ else
+ Frd = Frd;
+ }});
+ 0x27: FpUnimpl::fmovrqz();
+ 0x41: fmovs_fcc1({{
+ if(passesFpCondition(Fsr<33:32>, COND4))
+ Frds = Frs2s;
+ else
+ Frds = Frds;
+ }});
+ 0x42: fmovd_fcc1({{
+ if(passesFpCondition(Fsr<33:32>, COND4))
+ Frd = Frs2;
+ else
+ Frd = Frd;
+ }});
+ 0x43: FpUnimpl::fmovq_fcc1();
+ 0x45: fmovrslez({{
+ if(Rs1 <= 0)
+ Frds = Frs2s;
+ else
+ Frds = Frds;
+ }});
+ 0x46: fmovrdlez({{
+ if(Rs1 <= 0)
+ Frd = Frs2;
+ else
+ Frd = Frd;
+ }});
+ 0x47: FpUnimpl::fmovrqlez();
0x51: fcmps({{
uint8_t fcc;
if(isnan(Frs1s) || isnan(Frs2s))
@@ -878,6 +929,110 @@ decode OP default Unknown::unknown()
Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc);
}});
0x57: FpUnimpl::fcmpeq();
+ 0x65: fmovrslz({{
+ if(Rs1 < 0)
+ Frds = Frs2s;
+ else
+ Frds = Frds;
+ }});
+ 0x66: fmovrdlz({{
+ if(Rs1 < 0)
+ Frd = Frs2;
+ else
+ Frd = Frd;
+ }});
+ 0x67: FpUnimpl::fmovrqlz();
+ 0x81: fmovs_fcc2({{
+ if(passesFpCondition(Fsr<35:34>, COND4))
+ Frds = Frs2s;
+ else
+ Frds = Frds;
+ }});
+ 0x82: fmovd_fcc2({{
+ if(passesFpCondition(Fsr<35:34>, COND4))
+ Frd = Frs2;
+ else
+ Frd = Frd;
+ }});
+ 0x83: FpUnimpl::fmovq_fcc2();
+ 0xA5: fmovrsnz({{
+ if(Rs1 != 0)
+ Frds = Frs2s;
+ else
+ Frds = Frds;
+ }});
+ 0xA6: fmovrdnz({{
+ if(Rs1 != 0)
+ Frd = Frs2;
+ else
+ Frd = Frd;
+ }});
+ 0xA7: FpUnimpl::fmovrqnz();
+ 0xC1: fmovs_fcc3({{
+ if(passesFpCondition(Fsr<37:36>, COND4))
+ Frds = Frs2s;
+ else
+ Frds = Frds;
+ }});
+ 0xC2: fmovd_fcc3({{
+ if(passesFpCondition(Fsr<37:36>, COND4))
+ Frd = Frs2;
+ else
+ Frd = Frd;
+ }});
+ 0xC3: FpUnimpl::fmovq_fcc3();
+ 0xC5: fmovrsgz({{
+ if(Rs1 > 0)
+ Frds = Frs2s;
+ else
+ Frds = Frds;
+ }});
+ 0xC6: fmovrdgz({{
+ if(Rs1 > 0)
+ Frd = Frs2;
+ else
+ Frd = Frd;
+ }});
+ 0xC7: FpUnimpl::fmovrqgz();
+ 0xE5: fmovrsgez({{
+ if(Rs1 >= 0)
+ Frds = Frs2s;
+ else
+ Frds = Frds;
+ }});
+ 0xE6: fmovrdgez({{
+ if(Rs1 >= 0)
+ Frd = Frs2;
+ else
+ Frd = Frd;
+ }});
+ 0xE7: FpUnimpl::fmovrqgez();
+ 0x101: fmovs_icc({{
+ if(passesCondition(Ccr<3:0>, COND4))
+ Frds = Frs2s;
+ else
+ Frds = Frds;
+ }});
+ 0x102: fmovd_icc({{
+ if(passesCondition(Ccr<3:0>, COND4))
+ Frd = Frs2;
+ else
+ Frd = Frd;
+ }});
+ 0x103: FpUnimpl::fmovq_icc();
+ 0x181: fmovs_xcc({{
+ if(passesCondition(Ccr<7:4>, COND4))
+ Frds = Frs2s;
+ else
+ Frds = Frds;
+ }});
+ 0x182: fmovd_xcc({{
+ if(passesCondition(Ccr<7:4>, COND4))
+ Frd = Frs2;
+ else
+ Frd = Frd;
+ }});
+ 0x183: FpUnimpl::fmovq_xcc();
default: FailUnimpl::fpop2();
}
}
@@ -1009,7 +1164,25 @@ decode OP default Unknown::unknown()
0x80: Trap::shutdown({{fault = new IllegalInstruction;}});
0x81: FailUnimpl::siam();
}
- 0x37: Trap::impdep2({{fault = new IllegalInstruction;}});
+ // M5 special opcodes use the reserved IMPDEP2A opcode space
+ 0x37: decode M5FUNC {
+#if FULL_SYSTEM
+ format BasicOperate {
+ // we have 7 bits of space here to play with...
+ 0x21: m5exit({{PseudoInst::m5exit(xc->tcBase(), O0);
+ }}, No_OpClass, IsNonSpeculative);
+ 0x50: m5readfile({{
+ O0 = PseudoInst::readfile(xc->tcBase(), O0, O1, O2);
+ }}, IsNonSpeculative);
+ 0x51: m5break({{PseudoInst::debugbreak(xc->tcBase());
+ }}, IsNonSpeculative);
+ 0x54: m5panic({{
+ panic("M5 panic instruction called at pc=%#x.", xc->readPC());
+ }}, No_OpClass, IsNonSpeculative);
+ }
+#endif
+ default: Trap::impdep2({{fault = new IllegalInstruction;}});
+ }
0x38: Branch::jmpl({{
Addr target = Rs1 + Rs2_or_imm13;
if(target & 0x3)
@@ -1053,31 +1226,22 @@ decode OP default Unknown::unknown()
0x0: Trap::tcci({{
if(passesCondition(Ccr<3:0>, COND2))
{
-#if FULL_SYSTEM
int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2);
DPRINTF(Sparc, "The trap number is %d\n", lTrapNum);
fault = new TrapInstruction(lTrapNum);
-#else
- DPRINTF(Sparc, "The syscall number is %d\n", R1);
- xc->syscall(R1);
-#endif
}
}}, IsSerializeAfter, IsNonSpeculative);
0x2: Trap::tccx({{
if(passesCondition(Ccr<7:4>, COND2))
{
-#if FULL_SYSTEM
int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2);
DPRINTF(Sparc, "The trap number is %d\n", lTrapNum);
fault = new TrapInstruction(lTrapNum);
-#else
- DPRINTF(Sparc, "The syscall number is %d\n", R1);
- xc->syscall(R1);
-#endif
}
}}, IsSerializeAfter, IsNonSpeculative);
}
- 0x3B: Nop::flush({{/*Instruction memory flush*/}});
+ 0x3B: Nop::flush({{/*Instruction memory flush*/}}, IsWriteBarrier,
+ MemWriteOp);
0x3C: save({{
if(Cansave == 0)
{
@@ -1151,16 +1315,18 @@ decode OP default Unknown::unknown()
0x01: ldub({{Rd = Mem.ub;}});
0x02: lduh({{Rd = Mem.uhw;}});
0x03: ldtw({{
- uint64_t val = Mem.udw;
- RdLow = val<31:0>;
- RdHigh = val<63:32>;
+ RdLow = (Mem.tuw).a;
+ RdHigh = (Mem.tuw).b;
}});
}
format Store {
0x04: stw({{Mem.uw = Rd.sw;}});
0x05: stb({{Mem.ub = Rd.sb;}});
0x06: sth({{Mem.uhw = Rd.shw;}});
- 0x07: sttw({{Mem.udw = RdLow<31:0> | (RdHigh<31:0> << 32);}});
+ 0x07: sttw({{
+ (Mem.tuw).a = RdLow<31:0>;
+ (Mem.tuw).b = RdHigh<31:0>;
+ }});
}
format Load {
0x08: ldsw({{Rd = (int32_t)Mem.sw;}});
@@ -1168,15 +1334,17 @@ decode OP default Unknown::unknown()
0x0A: ldsh({{Rd = (int16_t)Mem.shw;}});
0x0B: ldx({{Rd = (int64_t)Mem.sdw;}});
}
- 0x0D: LoadStore::ldstub(
- {{uReg0 = Mem.ub;}},
- {{Rd.ub = uReg0;
- Mem.ub = 0xFF;}});
+ 0x0D: Swap::ldstub({{Mem.ub = 0xFF;}},
+ {{
+ uint8_t tmp = mem_data;
+ Rd.ub = tmp;
+ }}, MEM_SWAP);
0x0E: Store::stx({{Mem.udw = Rd}});
- 0x0F: LoadStore::swap(
- {{ uReg0 = Mem.uw}},
- {{ Mem.uw = Rd.uw;
- Rd.uw = uReg0;}});
+ 0x0F: Swap::swap({{Mem.uw = Rd.uw}},
+ {{
+ uint32_t tmp = mem_data;
+ Rd.uw = tmp;
+ }}, MEM_SWAP);
format LoadAlt {
0x10: lduwa({{Rd = Mem.uw;}}, {{EXT_ASI}});
0x11: lduba({{Rd = Mem.ub;}}, {{EXT_ASI}});
@@ -1184,38 +1352,63 @@ decode OP default Unknown::unknown()
0x13: decode EXT_ASI {
//ASI_LDTD_AIUP
0x22: TwinLoad::ldtx_aiup(
- {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
+ {{RdLow.udw = (Mem.tudw).a;
+ RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}});
//ASI_LDTD_AIUS
0x23: TwinLoad::ldtx_aius(
- {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
+ {{RdLow.udw = (Mem.tudw).a;
+ RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}});
//ASI_QUAD_LDD
0x24: TwinLoad::ldtx_quad_ldd(
- {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
+ {{RdLow.udw = (Mem.tudw).a;
+ RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}});
//ASI_LDTX_REAL
0x26: TwinLoad::ldtx_real(
- {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
- //ASI_LDTX_N
- 0x27: TwinLoad::ldtx_n(
- {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
- //ASI_LDTX_L
- 0x2C: TwinLoad::ldtx_l(
- {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
+ {{RdLow.udw = (Mem.tudw).a;
+ RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}});
+ //ASI_LDTX_N
+ 0x27: TwinLoad::ldtx_n(
+ {{RdLow.udw = (Mem.tudw).a;
+ RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}});
+ //ASI_LDTX_AIUP_L
+ 0x2A: TwinLoad::ldtx_aiup_l(
+ {{RdLow.udw = (Mem.tudw).a;
+ RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}});
+ //ASI_LDTX_AIUS_L
+ 0x2B: TwinLoad::ldtx_aius_l(
+ {{RdLow.udw = (Mem.tudw).a;
+ RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}});
+ //ASI_LDTX_L
+ 0x2C: TwinLoad::ldtx_l(
+ {{RdLow.udw = (Mem.tudw).a;
+ RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}});
//ASI_LDTX_REAL_L
0x2E: TwinLoad::ldtx_real_l(
- {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
+ {{RdLow.udw = (Mem.tudw).a;
+ RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}});
//ASI_LDTX_N_L
0x2F: TwinLoad::ldtx_n_l(
- {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
+ {{RdLow.udw = (Mem.tudw).a;
+ RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}});
//ASI_LDTX_P
0xE2: TwinLoad::ldtx_p(
- {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
+ {{RdLow.udw = (Mem.tudw).a;
+ RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}});
//ASI_LDTX_S
0xE3: TwinLoad::ldtx_s(
- {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
+ {{RdLow.udw = (Mem.tudw).a;
+ RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}});
+ //ASI_LDTX_PL
+ 0xEA: TwinLoad::ldtx_pl(
+ {{RdLow.udw = (Mem.tudw).a;
+ RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}});
+ //ASI_LDTX_SL
+ 0xEB: TwinLoad::ldtx_sl(
+ {{RdLow.udw = (Mem.tudw).a;
+ RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}});
default: ldtwa({{
- uint64_t val = Mem.udw;
- RdLow = val<31:0>;
- RdHigh = val<63:32>;
+ RdLow = (Mem.tuw).a;
+ RdHigh = (Mem.tuw).b;
}}, {{EXT_ASI}});
}
}
@@ -1223,7 +1416,10 @@ decode OP default Unknown::unknown()
0x14: stwa({{Mem.uw = Rd;}}, {{EXT_ASI}});
0x15: stba({{Mem.ub = Rd;}}, {{EXT_ASI}});
0x16: stha({{Mem.uhw = Rd;}}, {{EXT_ASI}});
- 0x17: sttwa({{Mem.udw = RdLow<31:0> | RdHigh<31:0> << 32;}}, {{EXT_ASI}});
+ 0x17: sttwa({{
+ (Mem.tuw).a = RdLow<31:0>;
+ (Mem.tuw).b = RdHigh<31:0>;
+ }}, {{EXT_ASI}});
}
format LoadAlt {
0x18: ldswa({{Rd = (int32_t)Mem.sw;}}, {{EXT_ASI}});
@@ -1231,15 +1427,18 @@ decode OP default Unknown::unknown()
0x1A: ldsha({{Rd = (int16_t)Mem.shw;}}, {{EXT_ASI}});
0x1B: ldxa({{Rd = (int64_t)Mem.sdw;}}, {{EXT_ASI}});
}
- 0x1D: LoadStoreAlt::ldstuba(
- {{uReg0 = Mem.ub;}},
- {{Rd.ub = uReg0;
- Mem.ub = 0xFF;}}, {{EXT_ASI}});
+ 0x1D: SwapAlt::ldstuba({{Mem.ub = 0xFF;}},
+ {{
+ uint8_t tmp = mem_data;
+ Rd.ub = tmp;
+ }}, {{EXT_ASI}}, MEM_SWAP);
0x1E: StoreAlt::stxa({{Mem.udw = Rd}}, {{EXT_ASI}});
- 0x1F: LoadStoreAlt::swapa(
- {{ uReg0 = Mem.uw}},
- {{ Mem.uw = Rd.uw;
- Rd.uw = uReg0;}}, {{EXT_ASI}});
+ 0x1F: SwapAlt::swapa({{Mem.uw = Rd.uw}},
+ {{
+ uint32_t tmp = mem_data;
+ Rd.uw = tmp;
+ }}, {{EXT_ASI}}, MEM_SWAP);
+
format Trap {
0x20: Load::ldf({{Frds.uw = Mem.uw;}});
0x21: decode RD {
@@ -1438,21 +1637,17 @@ decode OP default Unknown::unknown()
{{fault = new DataAccessException;}});
}
}
- 0x3C: Cas::casa(
- {{uReg0 = Mem.uw;}},
- {{if(Rs2.uw == uReg0)
- Mem.uw = Rd.uw;
- else
- storeCond = false;
- Rd.uw = uReg0;}}, {{EXT_ASI}});
+ 0x3C: CasAlt::casa({{
+ mem_data = htog(Rs2.uw);
+ Mem.uw = Rd.uw;}},
+ {{
+ uint32_t tmp = mem_data;
+ Rd.uw = tmp;
+ }}, {{EXT_ASI}}, MEM_SWAP_COND);
0x3D: Nop::prefetcha({{ }});
- 0x3E: Cas::casxa(
- {{uReg0 = Mem.udw;}},
- {{if(Rs2 == uReg0)
- Mem.udw = Rd;
- else
- storeCond = false;
- Rd = uReg0;}}, {{EXT_ASI}});
+ 0x3E: CasAlt::casxa({{mem_data = gtoh(Rs2);
+ Mem.udw = Rd.udw; }},
+ {{ Rd.udw = mem_data; }}, {{EXT_ASI}}, MEM_SWAP_COND);
}
}
}
diff --git a/src/arch/sparc/isa/formats/branch.isa b/src/arch/sparc/isa/formats/branch.isa
index 5cd3ab598..f5ab940bb 100644
--- a/src/arch/sparc/isa/formats/branch.isa
+++ b/src/arch/sparc/isa/formats/branch.isa
@@ -40,7 +40,7 @@ output header {{
{
protected:
// Constructor
- Branch(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ Branch(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
SparcStaticInst(mnem, _machInst, __opClass)
{
}
@@ -56,7 +56,7 @@ output header {{
{
protected:
// Constructor
- BranchDisp(const char *mnem, MachInst _machInst,
+ BranchDisp(const char *mnem, ExtMachInst _machInst,
OpClass __opClass) :
Branch(mnem, _machInst, __opClass)
{
@@ -76,7 +76,7 @@ output header {{
{
protected:
// Constructor
- BranchNBits(const char *mnem, MachInst _machInst,
+ BranchNBits(const char *mnem, ExtMachInst _machInst,
OpClass __opClass) :
BranchDisp(mnem, _machInst, __opClass)
{
@@ -91,7 +91,7 @@ output header {{
{
protected:
// Constructor
- BranchSplit(const char *mnem, MachInst _machInst,
+ BranchSplit(const char *mnem, ExtMachInst _machInst,
OpClass __opClass) :
BranchDisp(mnem, _machInst, __opClass)
{
@@ -107,7 +107,7 @@ output header {{
{
protected:
// Constructor
- BranchImm13(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ BranchImm13(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
Branch(mnem, _machInst, __opClass), imm(sext<13>(SIMM13))
{
}
diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa
index 1d9075a57..751262811 100644
--- a/src/arch/sparc/isa/formats/mem/basicmem.isa
+++ b/src/arch/sparc/isa/formats/mem/basicmem.isa
@@ -1,4 +1,4 @@
-// Copyright (c) 2006 The Regents of The University of Michigan
+// Copyright (c) 2006-2007 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -52,22 +52,20 @@ def template MemDeclare {{
}};
let {{
- def doMemFormat(code, execute, faultCode, name, Name, asi, opt_flags):
+ def doMemFormat(code, execute, faultCode, name, Name, asi, opt_flags, postacc_code = ''):
addrCalcReg = 'EA = Rs1 + Rs2;'
addrCalcImm = 'EA = Rs1 + imm;'
iop = InstObjParams(name, Name, 'Mem',
- {"code": code, "fault_check": faultCode,
- "ea_code": addrCalcReg},
- opt_flags)
+ {"code": code, "postacc_code" : postacc_code,
+ "fault_check": faultCode, "ea_code": addrCalcReg}, opt_flags)
iop_imm = InstObjParams(name, Name + "Imm", 'MemImm',
- {"code": code, "fault_check": faultCode,
- "ea_code": addrCalcImm},
- opt_flags)
+ {"code": code, "postacc_code" : postacc_code,
+ "fault_check": faultCode, "ea_code": addrCalcImm}, opt_flags)
header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm)
decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm)
decode_block = ROrImmDecode.subst(iop)
- exec_output = doDualSplitExecute(code, addrCalcReg, addrCalcImm,
- execute, faultCode, name, name + "Imm",
+ exec_output = doDualSplitExecute(code, postacc_code, addrCalcReg,
+ addrCalcImm, execute, faultCode, name, name + "Imm",
Name, Name + "Imm", asi, opt_flags)
return (header_output, decoder_output, exec_output, decode_block)
}};
@@ -103,3 +101,13 @@ def format Store(code, *opt_flags) {{
decode_block) = doMemFormat(code,
StoreFuncs, '', name, Name, 0, opt_flags)
}};
+
+def format TwinLoad(code, asi, *opt_flags) {{
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doMemFormat(code, LoadFuncs,
+ AlternateASIPrivFaultCheck + TwinAlignmentFaultCheck,
+ name, Name, asi, opt_flags)
+}};
+
diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa
index 9795d2342..499685a5c 100644
--- a/src/arch/sparc/isa/formats/mem/blockmem.isa
+++ b/src/arch/sparc/isa/formats/mem/blockmem.isa
@@ -91,65 +91,6 @@ output header {{
};
}};
-output header {{
-
- class TwinMem : public SparcMacroInst
- {
- protected:
-
- // Constructor
- // We make the assumption that all block memory operations
- // Will take 8 instructions to execute
- TwinMem(const char *mnem, ExtMachInst _machInst) :
- SparcMacroInst(mnem, _machInst, No_OpClass, 2)
- {}
- };
-
- class TwinMemImm : public BlockMem
- {
- protected:
-
- // Constructor
- TwinMemImm(const char *mnem, ExtMachInst _machInst) :
- BlockMem(mnem, _machInst)
- {}
- };
-
- class TwinMemMicro : public SparcMicroInst
- {
- protected:
-
- // Constructor
- TwinMemMicro(const char *mnem, ExtMachInst _machInst,
- OpClass __opClass, int8_t _offset) :
- SparcMicroInst(mnem, _machInst, __opClass),
- offset(_offset)
- {}
-
- std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const;
-
- const int8_t offset;
- };
-
- class TwinMemImmMicro : public BlockMemMicro
- {
- protected:
-
- // Constructor
- TwinMemImmMicro(const char *mnem, ExtMachInst _machInst,
- OpClass __opClass, int8_t _offset) :
- BlockMemMicro(mnem, _machInst, __opClass, _offset),
- imm(sext<13>(SIMM13))
- {}
-
- std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const;
-
- const int32_t imm;
- };
-}};
-
output decoder {{
std::string BlockMemMicro::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
@@ -208,64 +149,6 @@ output decoder {{
}};
-output decoder {{
- std::string TwinMemMicro::generateDisassembly(Addr pc,
- const SymbolTable *symtab) const
- {
- std::stringstream response;
- bool load = flags[IsLoad];
- bool save = flags[IsStore];
-
- printMnemonic(response, mnemonic);
- if(save)
- {
- printReg(response, _srcRegIdx[0]);
- ccprintf(response, ", ");
- }
- ccprintf(response, "[ ");
- printReg(response, _srcRegIdx[!save ? 0 : 1]);
- ccprintf(response, " + ");
- printReg(response, _srcRegIdx[!save ? 1 : 2]);
- ccprintf(response, " ]");
- if(load)
- {
- ccprintf(response, ", ");
- printReg(response, _destRegIdx[0]);
- }
-
- return response.str();
- }
-
- std::string TwinMemImmMicro::generateDisassembly(Addr pc,
- const SymbolTable *symtab) const
- {
- std::stringstream response;
- bool load = flags[IsLoad];
- bool save = flags[IsStore];
-
- printMnemonic(response, mnemonic);
- if(save)
- {
- printReg(response, _srcRegIdx[1]);
- ccprintf(response, ", ");
- }
- ccprintf(response, "[ ");
- printReg(response, _srcRegIdx[0]);
- if(imm >= 0)
- ccprintf(response, " + 0x%x ]", imm);
- else
- ccprintf(response, " + -0x%x ]", -imm);
- if(load)
- {
- ccprintf(response, ", ");
- printReg(response, _destRegIdx[0]);
- }
-
- return response.str();
- }
-
-}};
-
def template BlockMemDeclare {{
/**
* Static instruction class for a block memory operation
@@ -359,39 +242,6 @@ def template BlockMemDeclare {{
};
}};
-def template TwinMemDeclare {{
- /**
- * Static instruction class for a block memory operation
- */
- class %(class_name)s : public %(base_class)s
- {
- public:
- //Constructor
- %(class_name)s(ExtMachInst machInst);
-
- protected:
- class %(class_name)s_0 : public %(base_class)sMicro
- {
- public:
- //Constructor
- %(class_name)s_0(ExtMachInst machInst);
- %(BasicExecDeclare)s
- %(InitiateAccDeclare)s
- %(CompleteAccDeclare)s
- };
-
- class %(class_name)s_1 : public %(base_class)sMicro
- {
- public:
- //Constructor
- %(class_name)s_1(ExtMachInst machInst);
- %(BasicExecDeclare)s
- %(InitiateAccDeclare)s
- %(CompleteAccDeclare)s
- };
- };
-}};
-
// Basic instruction class constructor template.
def template BlockMemConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
@@ -409,17 +259,6 @@ def template BlockMemConstructor {{
}
}};
-// Basic instruction class constructor template.
-def template TwinMemConstructor {{
- inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
- : %(base_class)s("%(mnemonic)s", machInst)
- {
- %(constructor)s;
- microOps[0] = new %(class_name)s_0(machInst);
- microOps[1] = new %(class_name)s_1(machInst);
- }
-}};
-
def template BlockMemMicroConstructor {{
inline %(class_name)s::
%(class_name)s_%(micro_pc)s::
@@ -467,47 +306,7 @@ let {{
decoder_output += BlockMemMicroConstructor.subst(iop)
decoder_output += BlockMemMicroConstructor.subst(iop_imm)
exec_output += doDualSplitExecute(
- pcedCode, addrCalcReg, addrCalcImm, execute, faultCode,
- makeMicroName(name, microPc),
- makeMicroName(name + "Imm", microPc),
- makeMicroName(Name, microPc),
- makeMicroName(Name + "Imm", microPc),
- asi, opt_flags);
- faultCode = ''
- return (header_output, decoder_output, exec_output, decode_block)
-
- def doTwinLoadFormat(code, faultCode, name, Name, asi, opt_flags):
- addrCalcReg = 'EA = Rs1 + Rs2 + offset;'
- addrCalcImm = 'EA = Rs1 + imm + offset;'
- iop = InstObjParams(name, Name, 'TwinMem', code, opt_flags)
- iop_imm = InstObjParams(name, Name + 'Imm', 'TwinMemImm', code, opt_flags)
- header_output = TwinMemDeclare.subst(iop) + TwinMemDeclare.subst(iop_imm)
- decoder_output = TwinMemConstructor.subst(iop) + TwinMemConstructor.subst(iop_imm)
- decode_block = ROrImmDecode.subst(iop)
- matcher = re.compile(r'RdTwin')
- exec_output = ''
- for microPc in range(2):
- flag_code = ''
- pcedCode = ''
- if (microPc == 1):
- flag_code = "flags[IsLastMicroOp] = true;"
- pcedCode = "RdLow = uReg0;\n"
- pcedCode += matcher.sub("RdHigh", code)
- else:
- flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroOp] = true;"
- pcedCode = matcher.sub("uReg0", code)
- iop = InstObjParams(name, Name, 'TwinMem',
- {"code": pcedCode, "ea_code": addrCalcReg,
- "fault_check": faultCode, "micro_pc": microPc,
- "set_flags": flag_code}, opt_flags)
- iop_imm = InstObjParams(name, Name + 'Imm', 'TwinMemImm',
- {"code": pcedCode, "ea_code": addrCalcImm,
- "fault_check": faultCode, "micro_pc": microPc,
- "set_flags": flag_code}, opt_flags)
- decoder_output += BlockMemMicroConstructor.subst(iop)
- decoder_output += BlockMemMicroConstructor.subst(iop_imm)
- exec_output += doDualSplitExecute(
- pcedCode, addrCalcReg, addrCalcImm, LoadFuncs, faultCode,
+ pcedCode, '', addrCalcReg, addrCalcImm, execute, faultCode,
makeMicroName(name, microPc),
makeMicroName(name + "Imm", microPc),
makeMicroName(Name, microPc),
@@ -515,7 +314,6 @@ let {{
asi, opt_flags);
faultCode = ''
return (header_output, decoder_output, exec_output, decode_block)
-
}};
def format BlockLoad(code, asi, *opt_flags) {{
@@ -541,11 +339,3 @@ def format BlockStore(code, asi, *opt_flags) {{
decode_block) = doBlockMemFormat(code, faultCode,
StoreFuncs, name, Name, asi, opt_flags)
}};
-
-def format TwinLoad(code, asi, *opt_flags) {{
- faultCode = AlternateASIPrivFaultCheck + TwinAlignmentFaultCheck
- (header_output,
- decoder_output,
- exec_output,
- decode_block) = doTwinLoadFormat(code, faultCode, name, Name, asi, opt_flags)
-}};
diff --git a/src/arch/sparc/isa/formats/mem/mem.isa b/src/arch/sparc/isa/formats/mem/mem.isa
index fedece2b8..db45e226d 100644
--- a/src/arch/sparc/isa/formats/mem/mem.isa
+++ b/src/arch/sparc/isa/formats/mem/mem.isa
@@ -1,4 +1,4 @@
-// Copyright (c) 2006 The Regents of The University of Michigan
+// Copyright (c) 2006-2007 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -42,4 +42,4 @@
##include "blockmem.isa"
//Include the load/store and cas memory format
-##include "loadstore.isa"
+##include "swap.isa"
diff --git a/src/arch/sparc/isa/formats/mem/swap.isa b/src/arch/sparc/isa/formats/mem/swap.isa
new file mode 100644
index 000000000..818597a84
--- /dev/null
+++ b/src/arch/sparc/isa/formats/mem/swap.isa
@@ -0,0 +1,183 @@
+// Copyright (c) 2007 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
+// Ali Saidi
+
+//This template provides the execute functions for a swap
+def template SwapExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+ //This is to support the conditional store in cas instructions.
+ //It should be optomized out in all the others
+ bool storeCond = true;
+ Addr EA;
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ uint64_t mem_data;
+
+ %(op_rd)s;
+ %(ea_code)s;
+ DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
+ %(fault_check)s;
+ if(fault == NoFault)
+ {
+ %(code)s;
+ }
+ if(storeCond && fault == NoFault)
+ {
+ fault = xc->write((uint%(mem_acc_size)s_t)Mem,
+ EA, %(asi_val)s, &mem_data);
+ }
+ if(fault == NoFault)
+ {
+ //Handle the swapping
+ %(postacc_code)s;
+ }
+ if(fault == NoFault)
+ {
+ //Write the resulting state to the execution context
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template SwapInitiateAcc {{
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
+ Trace::InstRecord * traceData) const
+ {
+ Fault fault = NoFault;
+ Addr EA;
+ %(fp_enable_check)s;
+ uint64_t mem_data = 0;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
+ %(fault_check)s;
+
+ if(fault == NoFault)
+ {
+ %(code)s;
+ }
+ if(fault == NoFault)
+ {
+ fault = xc->write((uint%(mem_acc_size)s_t)Mem,
+ EA, %(asi_val)s, &mem_data);
+ }
+ return fault;
+ }
+}};
+
+
+
+def template SwapCompleteAcc {{
+ Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc,
+ Trace::InstRecord * traceData) const
+ {
+ Fault fault = NoFault;
+ %(op_decl)s;
+
+ uint64_t mem_data = pkt->get<uint%(mem_acc_size)s_t>();
+
+ if(fault == NoFault)
+ {
+ //Handle the swapping
+ %(postacc_code)s;
+ }
+ if(fault == NoFault)
+ {
+ //Write the resulting state to the execution context
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+let {{
+ SwapFuncs = [SwapExecute, SwapInitiateAcc, SwapCompleteAcc]
+}};
+
+
+def format Swap(code, postacc_code, mem_flags, *opt_flags) {{
+ mem_flags = makeList(mem_flags)
+ flags = string.join(mem_flags, '|')
+
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doMemFormat(code, SwapFuncs, '', name, Name, flags,
+ opt_flags, postacc_code)
+}};
+
+def format SwapAlt(code, postacc_code, asi, mem_flags, *opt_flags) {{
+ mem_flags = makeList(mem_flags)
+ mem_flags.append(asi)
+ flags = string.join(mem_flags, '|')
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doMemFormat(code, SwapFuncs, AlternateASIPrivFaultCheck,
+ name, Name, flags, opt_flags, postacc_code)
+}};
+
+
+let {{
+ def doCasFormat(code, execute, faultCode, name, Name, asi, opt_flags, postacc_code = ''):
+ addrCalcReg = 'EA = Rs1;'
+ iop = InstObjParams(name, Name, 'Mem',
+ {"code": code, "postacc_code" : postacc_code,
+ "fault_check": faultCode, "ea_code": addrCalcReg}, opt_flags)
+ header_output = MemDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ microParams = {"code": code, "postacc_code" : postacc_code,
+ "ea_code" : addrCalcReg, "fault_check" : faultCode}
+ exec_output = doSplitExecute(execute, name, Name, asi, opt_flags,
+ microParams);
+ return (header_output, decoder_output, exec_output, decode_block)
+}};
+
+
+def format CasAlt(code, postacc_code, asi, mem_flags, *opt_flags) {{
+ mem_flags = makeList(mem_flags)
+ mem_flags.append(asi)
+ flags = string.join(mem_flags, '|')
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doCasFormat(code, SwapFuncs, AlternateASIPrivFaultCheck,
+ name, Name, flags, opt_flags, postacc_code)
+}};
+
+
diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa
index dbaabdca4..dfe937371 100644
--- a/src/arch/sparc/isa/formats/mem/util.isa
+++ b/src/arch/sparc/isa/formats/mem/util.isa
@@ -149,7 +149,7 @@ def template LoadExecute {{
%(fault_check)s;
if(fault == NoFault)
{
- fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, %(asi_val)s);
+ fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, %(asi_val)s);
}
if(fault == NoFault)
{
@@ -179,7 +179,7 @@ def template LoadInitiateAcc {{
%(fault_check)s;
if(fault == NoFault)
{
- fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, %(asi_val)s);
+ fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, %(asi_val)s);
}
return fault;
}
@@ -224,7 +224,7 @@ def template StoreExecute {{
}
if(storeCond && fault == NoFault)
{
- fault = xc->write((uint%(mem_acc_size)s_t)Mem,
+ fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
EA, %(asi_val)s, 0);
}
if(fault == NoFault)
@@ -246,6 +246,7 @@ def template StoreInitiateAcc {{
Addr EA;
%(fp_enable_check)s;
%(op_decl)s;
+
%(op_rd)s;
%(ea_code)s;
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
@@ -256,7 +257,7 @@ def template StoreInitiateAcc {{
}
if(storeCond && fault == NoFault)
{
- fault = xc->write((uint%(mem_acc_size)s_t)Mem,
+ fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
EA, %(asi_val)s, 0);
}
if(fault == NoFault)
@@ -290,6 +291,7 @@ def template CompleteAccDeclare {{
let {{
LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc]
StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc]
+
# The LSB can be zero, since it's really the MSB in doubles and quads
# and we're dealing with doubles
BlockAlignmentFaultCheck = '''
@@ -337,14 +339,14 @@ let {{
return execf.subst(iop) + initf.subst(iop) + compf.subst(iop)
- def doDualSplitExecute(code, eaRegCode, eaImmCode, execute,
+ def doDualSplitExecute(code, postacc_code, eaRegCode, eaImmCode, execute,
faultCode, nameReg, nameImm, NameReg, NameImm, asi, opt_flags):
executeCode = ''
for (eaCode, name, Name) in (
(eaRegCode, nameReg, NameReg),
(eaImmCode, nameImm, NameImm)):
- microParams = {"code": code, "ea_code": eaCode,
- "fault_check": faultCode}
+ microParams = {"code": code, "postacc_code" : postacc_code,
+ "ea_code": eaCode, "fault_check": faultCode}
executeCode += doSplitExecute(execute, name, Name,
asi, opt_flags, microParams)
return executeCode
diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa
index d2ef67154..05e9e8731 100644
--- a/src/arch/sparc/isa/includes.isa
+++ b/src/arch/sparc/isa/includes.isa
@@ -70,10 +70,15 @@ output exec {{
#include <ieeefp.h>
#endif
+#if FULL_SYSTEM
+#include "sim/pseudo_inst.hh"
+#endif
+
#include <limits>
#include <cmath>
#include "arch/sparc/asi.hh"
+#include "base/bigint.hh"
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "sim/sim_exit.hh"
diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa
index 140055010..038919bd1 100644
--- a/src/arch/sparc/isa/operands.isa
+++ b/src/arch/sparc/isa/operands.isa
@@ -37,6 +37,8 @@ def operand_types {{
'uw' : ('unsigned int', 32),
'sdw' : ('signed int', 64),
'udw' : ('unsigned int', 64),
+ 'tudw' : ('twin64 int', 64),
+ 'tuw' : ('twin32 int', 32),
'sf' : ('float', 32),
'df' : ('float', 64),
'qf' : ('float', 128)
@@ -99,6 +101,12 @@ def operands {{
'R1': ('IntReg', 'udw', '1', None, 7),
'R15': ('IntReg', 'udw', '15', 'IsInteger', 8),
'R16': ('IntReg', 'udw', '16', None, 9),
+ 'O0': ('IntReg', 'udw', '8', 'IsInteger', 10),
+ 'O1': ('IntReg', 'udw', '9', 'IsInteger', 11),
+ 'O2': ('IntReg', 'udw', '10', 'IsInteger', 12),
+ 'O3': ('IntReg', 'udw', '11', 'IsInteger', 13),
+ 'O4': ('IntReg', 'udw', '12', 'IsInteger', 14),
+ 'O5': ('IntReg', 'udw', '13', 'IsInteger', 15),
# Control registers
# 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40),
diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh
index 64ae6abd8..d0b8827f3 100644
--- a/src/arch/sparc/isa_traits.hh
+++ b/src/arch/sparc/isa_traits.hh
@@ -87,6 +87,11 @@ namespace SparcISA
const int LogVMPageSize = 13;
const int VMPageSize = (1 << LogVMPageSize);
+ // real address virtual mapping
+ // sort of like alpha super page, but less frequently used
+ const Addr SegKPMEnd = ULL(0xfffffffc00000000);
+ const Addr SegKPMBase = ULL(0xfffffac000000000);
+
//Why does both the previous set of constants and this one exist?
const int PageShift = 13;
const int PageBytes = 1ULL << PageShift;
@@ -108,6 +113,18 @@ namespace SparcISA
const Addr PAddrImplMask = ULL(0x000000FFFFFFFFFF);
const Addr BytesInPageMask = ULL(0x1FFF);
+ enum InterruptTypes
+ {
+ IT_TRAP_LEVEL_ZERO,
+ IT_HINTP,
+ IT_INT_VEC,
+ IT_CPU_MONDO,
+ IT_DEV_MONDO,
+ IT_RES_ERROR,
+ IT_SOFT_INT,
+ NumInterruptTypes
+ };
+
#endif
}
diff --git a/src/arch/sparc/linux/linux.hh b/src/arch/sparc/linux/linux.hh
index fefd27197..f396eb5cd 100644
--- a/src/arch/sparc/linux/linux.hh
+++ b/src/arch/sparc/linux/linux.hh
@@ -79,4 +79,32 @@ class SparcLinux : public Linux
static const unsigned TGT_MAP_ANONYMOUS = 0x20;
};
+class Sparc32Linux : public SparcLinux
+{
+ public:
+
+ typedef struct {
+ uint64_t st_dev;
+ uint64_t st_ino;
+ uint32_t st_mode;
+ uint32_t st_nlink;
+ uint32_t st_uid;
+ uint32_t st_gid;
+ uint64_t st_rdev;
+ uint8_t __pad3[8];
+ int64_t st_size;
+ int32_t st_blksize;
+ uint8_t __pad4[8];
+ int64_t st_blocks;
+ uint64_t st_atimeX;
+ uint64_t st_atime_nsec;
+ uint64_t st_mtimeX;
+ uint64_t st_mtime_nsec;
+ uint64_t st_ctimeX;
+ uint64_t st_ctime_nsec;
+ uint32_t __unused4;
+ uint32_t __unused5;
+ } tgt_stat64;
+};
+
#endif
diff --git a/src/arch/sparc/linux/process.cc b/src/arch/sparc/linux/process.cc
index 565975fe0..9e3f74075 100644
--- a/src/arch/sparc/linux/process.cc
+++ b/src/arch/sparc/linux/process.cc
@@ -44,373 +44,89 @@
using namespace std;
using namespace SparcISA;
-
-/// Target uname() handler.
-static SyscallReturn
-unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
- ThreadContext *tc)
+SyscallDesc*
+SparcLinuxProcess::getDesc(int callnum)
{
- TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
-
- strcpy(name->sysname, "Linux");
- strcpy(name->nodename, "m5.eecs.umich.edu");
- strcpy(name->release, "2.4.20");
- strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
- strcpy(name->machine, "sparc");
-
- name.copyOut(tc->getMemPort());
-
- return 0;
+ if (callnum < 0 || callnum > Num_Syscall_Descs)
+ return NULL;
+ return &syscallDescs[callnum];
}
-
-SyscallReturn SparcISA::getresuidFunc(SyscallDesc *desc, int num,
- LiveProcess *p, ThreadContext *tc)
+SyscallDesc*
+SparcLinuxProcess::getDesc32(int callnum)
{
- const IntReg id = htog(100);
- Addr ruid = tc->getSyscallArg(0);
- Addr euid = tc->getSyscallArg(1);
- Addr suid = tc->getSyscallArg(2);
- //Handle the EFAULT case
- //Set the ruid
- if(ruid)
- {
- BufferArg ruidBuff(ruid, sizeof(IntReg));
- memcpy(ruidBuff.bufferPtr(), &id, sizeof(IntReg));
- ruidBuff.copyOut(tc->getMemPort());
- }
- //Set the euid
- if(euid)
- {
- BufferArg euidBuff(euid, sizeof(IntReg));
- memcpy(euidBuff.bufferPtr(), &id, sizeof(IntReg));
- euidBuff.copyOut(tc->getMemPort());
- }
- //Set the suid
- if(suid)
- {
- BufferArg suidBuff(suid, sizeof(IntReg));
- memcpy(suidBuff.bufferPtr(), &id, sizeof(IntReg));
- suidBuff.copyOut(tc->getMemPort());
- }
- return 0;
+ if (callnum < 0 || callnum > Num_Syscall32_Descs)
+ return NULL;
+ return &syscall32Descs[callnum];
}
-SyscallDesc SparcLinuxProcess::syscallDescs[] = {
- /* 0 */ SyscallDesc("restart_syscall", unimplementedFunc),
- /* 1 */ SyscallDesc("exit", exitFunc),
- /* 2 */ SyscallDesc("fork", unimplementedFunc),
- /* 3 */ SyscallDesc("read", readFunc),
- /* 4 */ SyscallDesc("write", writeFunc),
- /* 5 */ SyscallDesc("open", openFunc<SparcLinux>),
- /* 6 */ SyscallDesc("close", closeFunc),
- /* 7 */ SyscallDesc("wait4", unimplementedFunc),
- /* 8 */ SyscallDesc("creat", unimplementedFunc),
- /* 9 */ SyscallDesc("link", unimplementedFunc),
- /* 10 */ SyscallDesc("unlink", unlinkFunc),
- /* 11 */ SyscallDesc("execv", unimplementedFunc),
- /* 12 */ SyscallDesc("chdir", unimplementedFunc),
- /* 13 */ SyscallDesc("chown", chownFunc),
- /* 14 */ SyscallDesc("mknod", unimplementedFunc),
- /* 15 */ SyscallDesc("chmod", chmodFunc<Linux>),
- /* 16 */ SyscallDesc("lchown", unimplementedFunc),
- /* 17 */ SyscallDesc("brk", obreakFunc),
- /* 18 */ SyscallDesc("perfctr", unimplementedFunc),
- /* 19 */ SyscallDesc("lseek", lseekFunc),
- /* 20 */ SyscallDesc("getpid", getpidFunc),
- /* 21 */ SyscallDesc("capget", unimplementedFunc),
- /* 22 */ SyscallDesc("capset", unimplementedFunc),
- /* 23 */ SyscallDesc("setuid", setuidFunc),
- /* 24 */ SyscallDesc("getuid", getuidFunc),
- /* 25 */ SyscallDesc("time", unimplementedFunc),
- /* 26 */ SyscallDesc("ptrace", unimplementedFunc),
- /* 27 */ SyscallDesc("alarm", unimplementedFunc),
- /* 28 */ SyscallDesc("sigaltstack", unimplementedFunc),
- /* 29 */ SyscallDesc("pause", unimplementedFunc),
- /* 30 */ SyscallDesc("utime", unimplementedFunc),
- /* 31 */ SyscallDesc("lchown32", unimplementedFunc),
- /* 32 */ SyscallDesc("fchown32", unimplementedFunc),
- /* 33 */ SyscallDesc("access", unimplementedFunc),
- /* 34 */ SyscallDesc("nice", unimplementedFunc),
- /* 35 */ SyscallDesc("chown32", unimplementedFunc),
- /* 36 */ SyscallDesc("sync", unimplementedFunc),
- /* 37 */ SyscallDesc("kill", unimplementedFunc),
- /* 38 */ SyscallDesc("stat", unimplementedFunc),
- /* 39 */ SyscallDesc("sendfile", unimplementedFunc),
- /* 40 */ SyscallDesc("lstat", unimplementedFunc),
- /* 41 */ SyscallDesc("dup", unimplementedFunc),
- /* 42 */ SyscallDesc("pipe", pipePseudoFunc),
- /* 43 */ SyscallDesc("times", unimplementedFunc),
- /* 44 */ SyscallDesc("getuid32", unimplementedFunc),
- /* 45 */ SyscallDesc("umount2", unimplementedFunc),
- /* 46 */ SyscallDesc("setgid", unimplementedFunc),
- /* 47 */ SyscallDesc("getgid", getgidFunc),
- /* 48 */ SyscallDesc("signal", unimplementedFunc),
- /* 49 */ SyscallDesc("geteuid", geteuidFunc),
- /* 50 */ SyscallDesc("getegid", getegidFunc),
- /* 51 */ SyscallDesc("acct", unimplementedFunc),
- /* 52 */ SyscallDesc("memory_ordering", unimplementedFunc),
- /* 53 */ SyscallDesc("getgid32", unimplementedFunc),
- /* 54 */ SyscallDesc("ioctl", unimplementedFunc),
- /* 55 */ SyscallDesc("reboot", unimplementedFunc),
- /* 56 */ SyscallDesc("mmap2", unimplementedFunc),
- /* 57 */ SyscallDesc("symlink", unimplementedFunc),
- /* 58 */ SyscallDesc("readlink", unimplementedFunc),
- /* 59 */ SyscallDesc("execve", unimplementedFunc),
- /* 60 */ SyscallDesc("umask", unimplementedFunc),
- /* 61 */ SyscallDesc("chroot", unimplementedFunc),
- /* 62 */ SyscallDesc("fstat", fstatFunc<SparcLinux>),
- /* 63 */ SyscallDesc("fstat64", unimplementedFunc),
- /* 64 */ SyscallDesc("getpagesize", unimplementedFunc),
- /* 65 */ SyscallDesc("msync", unimplementedFunc),
- /* 66 */ SyscallDesc("vfork", unimplementedFunc),
- /* 67 */ SyscallDesc("pread64", unimplementedFunc),
- /* 68 */ SyscallDesc("pwrite64", unimplementedFunc),
- /* 69 */ SyscallDesc("geteuid32", unimplementedFunc),
- /* 70 */ SyscallDesc("getdgid32", unimplementedFunc),
- /* 71 */ SyscallDesc("mmap", mmapFunc<SparcLinux>),
- /* 72 */ SyscallDesc("setreuid32", unimplementedFunc),
- /* 73 */ SyscallDesc("munmap", munmapFunc),
- /* 74 */ SyscallDesc("mprotect", unimplementedFunc),
- /* 75 */ SyscallDesc("madvise", unimplementedFunc),
- /* 76 */ SyscallDesc("vhangup", unimplementedFunc),
- /* 77 */ SyscallDesc("truncate64", unimplementedFunc),
- /* 78 */ SyscallDesc("mincore", unimplementedFunc),
- /* 79 */ SyscallDesc("getgroups", unimplementedFunc),
- /* 80 */ SyscallDesc("setgroups", unimplementedFunc),
- /* 81 */ SyscallDesc("getpgrp", unimplementedFunc),
- /* 82 */ SyscallDesc("setgroups32", unimplementedFunc),
- /* 83 */ SyscallDesc("setitimer", unimplementedFunc),
- /* 84 */ SyscallDesc("ftruncate64", unimplementedFunc),
- /* 85 */ SyscallDesc("swapon", unimplementedFunc),
- /* 86 */ SyscallDesc("getitimer", unimplementedFunc),
- /* 87 */ SyscallDesc("setuid32", unimplementedFunc),
- /* 88 */ SyscallDesc("sethostname", unimplementedFunc),
- /* 89 */ SyscallDesc("setgid32", unimplementedFunc),
- /* 90 */ SyscallDesc("dup2", unimplementedFunc),
- /* 91 */ SyscallDesc("setfsuid32", unimplementedFunc),
- /* 92 */ SyscallDesc("fcntl", unimplementedFunc),
- /* 93 */ SyscallDesc("select", unimplementedFunc),
- /* 94 */ SyscallDesc("setfsgid32", unimplementedFunc),
- /* 95 */ SyscallDesc("fsync", unimplementedFunc),
- /* 96 */ SyscallDesc("setpriority", unimplementedFunc),
- /* 97 */ SyscallDesc("socket", unimplementedFunc),
- /* 98 */ SyscallDesc("connect", unimplementedFunc),
- /* 99 */ SyscallDesc("accept", unimplementedFunc),
- /* 100 */ SyscallDesc("getpriority", unimplementedFunc),
- /* 101 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
- /* 102 */ SyscallDesc("rt_sigaction", ignoreFunc),
- /* 103 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
- /* 104 */ SyscallDesc("rt_sigpending", unimplementedFunc),
- /* 105 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
- /* 106 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc),
- /* 107 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
- /* 108 */ SyscallDesc("setresuid", unimplementedFunc),
- /* 109 */ SyscallDesc("getresuid", getresuidFunc),
- /* 110 */ SyscallDesc("setresgid", unimplementedFunc),
- /* 111 */ SyscallDesc("getresgid", unimplementedFunc),
- /* 112 */ SyscallDesc("setregid32", unimplementedFunc),
- /* 113 */ SyscallDesc("recvmsg", unimplementedFunc),
- /* 114 */ SyscallDesc("sendmsg", unimplementedFunc),
- /* 115 */ SyscallDesc("getgroups32", unimplementedFunc),
- /* 116 */ SyscallDesc("gettimeofday", unimplementedFunc),
- /* 117 */ SyscallDesc("getrusage", unimplementedFunc),
- /* 118 */ SyscallDesc("getsockopt", unimplementedFunc),
- /* 119 */ SyscallDesc("getcwd", unimplementedFunc),
- /* 120 */ SyscallDesc("readv", unimplementedFunc),
- /* 121 */ SyscallDesc("writev", unimplementedFunc),
- /* 122 */ SyscallDesc("settimeofday", unimplementedFunc),
- /* 123 */ SyscallDesc("fchown", unimplementedFunc),
- /* 124 */ SyscallDesc("fchmod", unimplementedFunc),
- /* 125 */ SyscallDesc("recvfrom", unimplementedFunc),
- /* 126 */ SyscallDesc("setreuid", unimplementedFunc),
- /* 127 */ SyscallDesc("setregid", unimplementedFunc),
- /* 128 */ SyscallDesc("rename", unimplementedFunc),
- /* 129 */ SyscallDesc("truncate", unimplementedFunc),
- /* 130 */ SyscallDesc("ftruncate", unimplementedFunc),
- /* 131 */ SyscallDesc("flock", unimplementedFunc),
- /* 132 */ SyscallDesc("lstat64", unimplementedFunc),
- /* 133 */ SyscallDesc("sendto", unimplementedFunc),
- /* 134 */ SyscallDesc("shutdown", unimplementedFunc),
- /* 135 */ SyscallDesc("socketpair", unimplementedFunc),
- /* 136 */ SyscallDesc("mkdir", unimplementedFunc),
- /* 137 */ SyscallDesc("rmdir", unimplementedFunc),
- /* 138 */ SyscallDesc("utimes", unimplementedFunc),
- /* 139 */ SyscallDesc("stat64", unimplementedFunc),
- /* 140 */ SyscallDesc("sendfile64", unimplementedFunc),
- /* 141 */ SyscallDesc("getpeername", unimplementedFunc),
- /* 142 */ SyscallDesc("futex", unimplementedFunc),
- /* 143 */ SyscallDesc("gettid", unimplementedFunc),
- /* 144 */ SyscallDesc("getrlimit", unimplementedFunc),
- /* 145 */ SyscallDesc("setrlimit", unimplementedFunc),
- /* 146 */ SyscallDesc("pivot_root", unimplementedFunc),
- /* 147 */ SyscallDesc("prctl", unimplementedFunc),
- /* 148 */ SyscallDesc("pciconfig_read", unimplementedFunc),
- /* 149 */ SyscallDesc("pciconfig_write", unimplementedFunc),
- /* 150 */ SyscallDesc("getsockname", unimplementedFunc),
- /* 151 */ SyscallDesc("inotify_init", unimplementedFunc),
- /* 152 */ SyscallDesc("inotify_add_watch", unimplementedFunc),
- /* 153 */ SyscallDesc("poll", unimplementedFunc),
- /* 154 */ SyscallDesc("getdents64", unimplementedFunc),
- /* 155 */ SyscallDesc("fcntl64", unimplementedFunc),
- /* 156 */ SyscallDesc("inotify_rm_watch", unimplementedFunc),
- /* 157 */ SyscallDesc("statfs", unimplementedFunc),
- /* 158 */ SyscallDesc("fstatfs", unimplementedFunc),
- /* 159 */ SyscallDesc("umount", unimplementedFunc),
- /* 160 */ SyscallDesc("sched_set_affinity", unimplementedFunc),
- /* 161 */ SyscallDesc("sched_get_affinity", unimplementedFunc),
- /* 162 */ SyscallDesc("getdomainname", unimplementedFunc),
- /* 163 */ SyscallDesc("setdomainname", unimplementedFunc),
- /* 164 */ SyscallDesc("utrap_install", unimplementedFunc),
- /* 165 */ SyscallDesc("quotactl", unimplementedFunc),
- /* 166 */ SyscallDesc("set_tid_address", unimplementedFunc),
- /* 167 */ SyscallDesc("mount", unimplementedFunc),
- /* 168 */ SyscallDesc("ustat", unimplementedFunc),
- /* 169 */ SyscallDesc("setxattr", unimplementedFunc),
- /* 170 */ SyscallDesc("lsetxattr", unimplementedFunc),
- /* 171 */ SyscallDesc("fsetxattr", unimplementedFunc),
- /* 172 */ SyscallDesc("getxattr", unimplementedFunc),
- /* 173 */ SyscallDesc("lgetxattr", unimplementedFunc),
- /* 174 */ SyscallDesc("getdents", unimplementedFunc),
- /* 175 */ SyscallDesc("setsid", unimplementedFunc),
- /* 176 */ SyscallDesc("fchdir", unimplementedFunc),
- /* 177 */ SyscallDesc("fgetxattr", unimplementedFunc),
- /* 178 */ SyscallDesc("listxattr", unimplementedFunc),
- /* 179 */ SyscallDesc("llistxattr", unimplementedFunc),
- /* 180 */ SyscallDesc("flistxattr", unimplementedFunc),
- /* 181 */ SyscallDesc("removexattr", unimplementedFunc),
- /* 182 */ SyscallDesc("lremovexattr", unimplementedFunc),
- /* 183 */ SyscallDesc("sigpending", unimplementedFunc),
- /* 184 */ SyscallDesc("query_module", unimplementedFunc),
- /* 185 */ SyscallDesc("setpgid", unimplementedFunc),
- /* 186 */ SyscallDesc("fremovexattr", unimplementedFunc),
- /* 187 */ SyscallDesc("tkill", unimplementedFunc),
- /* 188 */ SyscallDesc("exit_group", exitFunc),
- /* 189 */ SyscallDesc("uname", unameFunc),
- /* 190 */ SyscallDesc("init_module", unimplementedFunc),
- /* 191 */ SyscallDesc("personality", unimplementedFunc),
- /* 192 */ SyscallDesc("remap_file_pages", unimplementedFunc),
- /* 193 */ SyscallDesc("epoll_create", unimplementedFunc),
- /* 194 */ SyscallDesc("epoll_ctl", unimplementedFunc),
- /* 195 */ SyscallDesc("epoll_wait", unimplementedFunc),
- /* 196 */ SyscallDesc("ioprio_set", unimplementedFunc),
- /* 197 */ SyscallDesc("getppid", getppidFunc),
- /* 198 */ SyscallDesc("sigaction", ignoreFunc),
- /* 199 */ SyscallDesc("sgetmask", unimplementedFunc),
- /* 200 */ SyscallDesc("ssetmask", unimplementedFunc),
- /* 201 */ SyscallDesc("sigsuspend", unimplementedFunc),
- /* 202 */ SyscallDesc("oldlstat", unimplementedFunc),
- /* 203 */ SyscallDesc("uselib", unimplementedFunc),
- /* 204 */ SyscallDesc("readdir", unimplementedFunc),
- /* 205 */ SyscallDesc("readahead", unimplementedFunc),
- /* 206 */ SyscallDesc("socketcall", unimplementedFunc),
- /* 207 */ SyscallDesc("syslog", unimplementedFunc),
- /* 208 */ SyscallDesc("lookup_dcookie", unimplementedFunc),
- /* 209 */ SyscallDesc("fadvise64", unimplementedFunc),
- /* 210 */ SyscallDesc("fadvise64_64", unimplementedFunc),
- /* 211 */ SyscallDesc("tgkill", unimplementedFunc),
- /* 212 */ SyscallDesc("waitpid", unimplementedFunc),
- /* 213 */ SyscallDesc("swapoff", unimplementedFunc),
- /* 214 */ SyscallDesc("sysinfo", unimplementedFunc),
- /* 215 */ SyscallDesc("ipc", unimplementedFunc),
- /* 216 */ SyscallDesc("sigreturn", unimplementedFunc),
- /* 217 */ SyscallDesc("clone", unimplementedFunc),
- /* 218 */ SyscallDesc("ioprio_get", unimplementedFunc),
- /* 219 */ SyscallDesc("adjtimex", unimplementedFunc),
- /* 220 */ SyscallDesc("sigprocmask", unimplementedFunc),
- /* 221 */ SyscallDesc("create_module", unimplementedFunc),
- /* 222 */ SyscallDesc("delete_module", unimplementedFunc),
- /* 223 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
- /* 224 */ SyscallDesc("getpgid", unimplementedFunc),
- /* 225 */ SyscallDesc("bdflush", unimplementedFunc),
- /* 226 */ SyscallDesc("sysfs", unimplementedFunc),
- /* 227 */ SyscallDesc("afs_syscall", unimplementedFunc),
- /* 228 */ SyscallDesc("setfsuid", unimplementedFunc),
- /* 229 */ SyscallDesc("setfsgid", unimplementedFunc),
- /* 230 */ SyscallDesc("_newselect", unimplementedFunc),
- /* 231 */ SyscallDesc("time", unimplementedFunc),
- /* 232 */ SyscallDesc("oldstat", unimplementedFunc),
- /* 233 */ SyscallDesc("stime", unimplementedFunc),
- /* 234 */ SyscallDesc("statfs64", unimplementedFunc),
- /* 235 */ SyscallDesc("fstatfs64", unimplementedFunc),
- /* 236 */ SyscallDesc("_llseek", unimplementedFunc),
- /* 237 */ SyscallDesc("mlock", unimplementedFunc),
- /* 238 */ SyscallDesc("munlock", unimplementedFunc),
- /* 239 */ SyscallDesc("mlockall", unimplementedFunc),
- /* 240 */ SyscallDesc("munlockall", unimplementedFunc),
- /* 241 */ SyscallDesc("sched_setparam", unimplementedFunc),
- /* 242 */ SyscallDesc("sched_getparam", unimplementedFunc),
- /* 243 */ SyscallDesc("sched_setscheduler", unimplementedFunc),
- /* 244 */ SyscallDesc("sched_getscheduler", unimplementedFunc),
- /* 245 */ SyscallDesc("sched_yield", unimplementedFunc),
- /* 246 */ SyscallDesc("sched_get_priority_max", unimplementedFunc),
- /* 247 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
- /* 248 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
- /* 249 */ SyscallDesc("nanosleep", unimplementedFunc),
- /* 250 */ SyscallDesc("mremap", unimplementedFunc),
- /* 251 */ SyscallDesc("_sysctl", unimplementedFunc),
- /* 252 */ SyscallDesc("getsid", unimplementedFunc),
- /* 253 */ SyscallDesc("fdatasync", unimplementedFunc),
- /* 254 */ SyscallDesc("nfsservctl", unimplementedFunc),
- /* 255 */ SyscallDesc("aplib", unimplementedFunc),
- /* 256 */ SyscallDesc("clock_settime", unimplementedFunc),
- /* 257 */ SyscallDesc("clock_gettime", unimplementedFunc),
- /* 258 */ SyscallDesc("clock_getres", unimplementedFunc),
- /* 259 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
- /* 260 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
- /* 261 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
- /* 262 */ SyscallDesc("timer_settime", unimplementedFunc),
- /* 263 */ SyscallDesc("timer_gettime", unimplementedFunc),
- /* 264 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
- /* 265 */ SyscallDesc("timer_delete", unimplementedFunc),
- /* 266 */ SyscallDesc("timer_create", unimplementedFunc),
- /* 267 */ SyscallDesc("vserver", unimplementedFunc),
- /* 268 */ SyscallDesc("io_setup", unimplementedFunc),
- /* 269 */ SyscallDesc("io_destroy", unimplementedFunc),
- /* 270 */ SyscallDesc("io_submit", unimplementedFunc),
- /* 271 */ SyscallDesc("io_cancel", unimplementedFunc),
- /* 272 */ SyscallDesc("io_getevents", unimplementedFunc),
- /* 273 */ SyscallDesc("mq_open", unimplementedFunc),
- /* 274 */ SyscallDesc("mq_unlink", unimplementedFunc),
- /* 275 */ SyscallDesc("mq_timedsend", unimplementedFunc),
- /* 276 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
- /* 277 */ SyscallDesc("mq_notify", unimplementedFunc),
- /* 278 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
- /* 279 */ SyscallDesc("waitid", unimplementedFunc),
- /* 280 */ SyscallDesc("sys_setaltroot", unimplementedFunc),
- /* 281 */ SyscallDesc("add_key", unimplementedFunc),
- /* 282 */ SyscallDesc("request_key", unimplementedFunc),
- /* 283 */ SyscallDesc("keyctl", unimplementedFunc)
-};
-
-SparcLinuxProcess::SparcLinuxProcess(const std::string &name,
- ObjectFile *objFile,
- System * system,
- int stdin_fd,
- int stdout_fd,
- int stderr_fd,
- std::vector<std::string> &argv,
- std::vector<std::string> &envp,
- const std::string &cwd,
- uint64_t _uid, uint64_t _euid,
- uint64_t _gid, uint64_t _egid,
- uint64_t _pid, uint64_t _ppid)
- : SparcLiveProcess(name, objFile, system,
- stdin_fd, stdout_fd, stderr_fd, argv, envp, cwd,
- _uid, _euid, _gid, _egid, _pid, _ppid),
- Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
+SparcLinuxProcess::SparcLinuxProcess() :
+ Num_Syscall_Descs(284), //sizeof(syscallDescs) / sizeof(SyscallDesc)),
+ Num_Syscall32_Descs(299) //sizeof(syscall32Descs) / sizeof(SyscallDesc))
{
// The sparc syscall table must be <= 284 entries because that is all there
// is space for.
assert(Num_Syscall_Descs <= 284);
+ // The sparc 32 bit syscall table bust be <= 299 entries because that is
+ // all there is space for.
+ assert(Num_Syscall_Descs <= 299);
}
+Sparc32LinuxProcess::Sparc32LinuxProcess(const std::string &name,
+ ObjectFile *objFile,
+ System * system,
+ int stdin_fd,
+ int stdout_fd,
+ int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp,
+ const std::string &cwd,
+ uint64_t _uid, uint64_t _euid,
+ uint64_t _gid, uint64_t _egid,
+ uint64_t _pid, uint64_t _ppid)
+ : Sparc32LiveProcess(name, objFile, system,
+ stdin_fd, stdout_fd, stderr_fd, argv, envp, cwd,
+ _uid, _euid, _gid, _egid, _pid, _ppid)
+{}
+void Sparc32LinuxProcess::handleTrap(int trapNum, ThreadContext *tc)
+{
+ switch(trapNum)
+ {
+ case 0x10: //Linux 32 bit syscall trap
+ tc->syscall(tc->readIntReg(1));
+ break;
+ default:
+ SparcLiveProcess::handleTrap(trapNum, tc);
+ }
+}
-SyscallDesc*
-SparcLinuxProcess::getDesc(int callnum)
+Sparc64LinuxProcess::Sparc64LinuxProcess(const std::string &name,
+ ObjectFile *objFile,
+ System * system,
+ int stdin_fd,
+ int stdout_fd,
+ int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp,
+ const std::string &cwd,
+ uint64_t _uid, uint64_t _euid,
+ uint64_t _gid, uint64_t _egid,
+ uint64_t _pid, uint64_t _ppid)
+ : Sparc64LiveProcess(name, objFile, system,
+ stdin_fd, stdout_fd, stderr_fd, argv, envp, cwd,
+ _uid, _euid, _gid, _egid, _pid, _ppid)
+{}
+
+void Sparc64LinuxProcess::handleTrap(int trapNum, ThreadContext *tc)
{
- if (callnum < 0 || callnum > Num_Syscall_Descs)
- return NULL;
- return &syscallDescs[callnum];
+ switch(trapNum)
+ {
+ //case 0x10: //Linux 32 bit syscall trap
+ case 0x6d: //Linux 64 bit syscall trap
+ tc->syscall(tc->readIntReg(1));
+ break;
+ default:
+ SparcLiveProcess::handleTrap(trapNum, tc);
+ }
}
diff --git a/src/arch/sparc/linux/process.hh b/src/arch/sparc/linux/process.hh
index e212de973..6c7f30a43 100644
--- a/src/arch/sparc/linux/process.hh
+++ b/src/arch/sparc/linux/process.hh
@@ -38,12 +38,34 @@
namespace SparcISA {
+//This contains all of the common elements of a SPARC Linux process which
+//are not shared by other operating systems. The rest come from the common
+//SPARC process class.
+class SparcLinuxProcess
+{
+ public:
+ SparcLinuxProcess();
+
+ /// Array of syscall descriptors, indexed by call number.
+ static SyscallDesc syscallDescs[];
+
+ /// Array of 32 bit compatibility syscall descriptors,
+ /// indexed by call number.
+ static SyscallDesc syscall32Descs[];
+
+ SyscallDesc* getDesc(int callnum);
+ SyscallDesc* getDesc32(int callnum);
+
+ const int Num_Syscall_Descs;
+ const int Num_Syscall32_Descs;
+};
+
/// A process with emulated SPARC/Linux syscalls.
-class SparcLinuxProcess : public SparcLiveProcess
+class Sparc32LinuxProcess : public SparcLinuxProcess, public Sparc32LiveProcess
{
public:
/// Constructor.
- SparcLinuxProcess(const std::string &name,
+ Sparc32LinuxProcess(const std::string &name,
ObjectFile *objFile,
System * system,
int stdin_fd, int stdout_fd, int stderr_fd,
@@ -54,19 +76,40 @@ class SparcLinuxProcess : public SparcLiveProcess
uint64_t _gid, uint64_t _egid,
uint64_t _pid, uint64_t _ppid);
- virtual SyscallDesc* getDesc(int callnum);
+ SyscallDesc* getDesc(int callnum)
+ {
+ return SparcLinuxProcess::getDesc32(callnum);
+ }
- /// The target system's hostname.
- static const char *hostname;
+ void handleTrap(int trapNum, ThreadContext *tc);
+};
- /// Array of syscall descriptors, indexed by call number.
- static SyscallDesc syscallDescs[];
+/// A process with emulated 32 bit SPARC/Linux syscalls.
+class Sparc64LinuxProcess : public SparcLinuxProcess, public Sparc64LiveProcess
+{
+ public:
+ /// Constructor.
+ Sparc64LinuxProcess(const std::string &name,
+ ObjectFile *objFile,
+ System * system,
+ int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp,
+ const std::string &cwd,
+ uint64_t _uid, uint64_t _euid,
+ uint64_t _gid, uint64_t _egid,
+ uint64_t _pid, uint64_t _ppid);
- const int Num_Syscall_Descs;
+ SyscallDesc* getDesc(int callnum)
+ {
+ return SparcLinuxProcess::getDesc(callnum);
+ }
+
+ void handleTrap(int trapNum, ThreadContext *tc);
};
SyscallReturn getresuidFunc(SyscallDesc *desc, int num,
LiveProcess *p, ThreadContext *tc);
} // namespace SparcISA
-#endif // __ALPHA_LINUX_PROCESS_HH__
+#endif // __SPARC_LINUX_PROCESS_HH__
diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc
new file mode 100644
index 000000000..03c8bafe2
--- /dev/null
+++ b/src/arch/sparc/linux/syscalls.cc
@@ -0,0 +1,681 @@
+/*
+ * 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 "arch/sparc/linux/process.hh"
+#include "arch/sparc/syscallreturn.hh"
+#include "sim/syscall_emul.hh"
+
+class LiveProcess;
+class ThreadContext;
+
+namespace SparcISA {
+
+/// Target uname() handler.
+static SyscallReturn
+unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+ ThreadContext *tc)
+{
+ TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
+
+ strcpy(name->sysname, "Linux");
+ strcpy(name->nodename, "m5.eecs.umich.edu");
+ strcpy(name->release, "2.6.12-9-sparc64");
+ strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
+ strcpy(name->machine, "sparc");
+
+ name.copyOut(tc->getMemPort());
+
+ return 0;
+}
+
+
+SyscallReturn getresuidFunc(SyscallDesc *desc, int num,
+ LiveProcess *p, ThreadContext *tc)
+{
+ const IntReg id = htog(100);
+ Addr ruid = tc->getSyscallArg(0);
+ Addr euid = tc->getSyscallArg(1);
+ Addr suid = tc->getSyscallArg(2);
+ //Handle the EFAULT case
+ //Set the ruid
+ if(ruid)
+ {
+ BufferArg ruidBuff(ruid, sizeof(IntReg));
+ memcpy(ruidBuff.bufferPtr(), &id, sizeof(IntReg));
+ ruidBuff.copyOut(tc->getMemPort());
+ }
+ //Set the euid
+ if(euid)
+ {
+ BufferArg euidBuff(euid, sizeof(IntReg));
+ memcpy(euidBuff.bufferPtr(), &id, sizeof(IntReg));
+ euidBuff.copyOut(tc->getMemPort());
+ }
+ //Set the suid
+ if(suid)
+ {
+ BufferArg suidBuff(suid, sizeof(IntReg));
+ memcpy(suidBuff.bufferPtr(), &id, sizeof(IntReg));
+ suidBuff.copyOut(tc->getMemPort());
+ }
+ return 0;
+}
+
+SyscallDesc SparcLinuxProcess::syscall32Descs[] = {
+ /* 0 */ SyscallDesc("restart_syscall", unimplementedFunc),
+ /* 1 */ SyscallDesc("exit", exitFunc), //32 bit
+ /* 2 */ SyscallDesc("fork", unimplementedFunc),
+ /* 3 */ SyscallDesc("read", readFunc),
+ /* 4 */ SyscallDesc("write", writeFunc),
+ /* 5 */ SyscallDesc("open", openFunc<Sparc32Linux>), //32 bit
+ /* 6 */ SyscallDesc("close", closeFunc),
+ /* 7 */ SyscallDesc("wait4", unimplementedFunc), //32 bit
+ /* 8 */ SyscallDesc("creat", unimplementedFunc), //32 bit
+ /* 9 */ SyscallDesc("link", unimplementedFunc),
+ /* 10 */ SyscallDesc("unlink", unlinkFunc),
+ /* 11 */ SyscallDesc("execv", unimplementedFunc),
+ /* 12 */ SyscallDesc("chdir", unimplementedFunc),
+ /* 13 */ SyscallDesc("chown", chownFunc), //32 bit
+ /* 14 */ SyscallDesc("mknod", unimplementedFunc),
+ /* 15 */ SyscallDesc("chmod", unimplementedFunc),
+ /* 16 */ SyscallDesc("lchown", unimplementedFunc), //32 bit
+ /* 17 */ SyscallDesc("brk", obreakFunc),
+ /* 18 */ SyscallDesc("perfctr", unimplementedFunc), //32 bit
+ /* 19 */ SyscallDesc("lseek", lseekFunc), //32 bit
+ /* 20 */ SyscallDesc("getpid", getpidFunc),
+ /* 21 */ SyscallDesc("capget", unimplementedFunc),
+ /* 22 */ SyscallDesc("capset", unimplementedFunc),
+ /* 23 */ SyscallDesc("setuid", setuidFunc), //32 bit
+ /* 24 */ SyscallDesc("getuid", getuidFunc), //32 bit
+ /* 25 */ SyscallDesc("time", unimplementedFunc),
+ /* 26 */ SyscallDesc("ptrace", unimplementedFunc),
+ /* 27 */ SyscallDesc("alarm", unimplementedFunc),
+ /* 28 */ SyscallDesc("sigaltstack", unimplementedFunc), //32 bit
+ /* 29 */ SyscallDesc("pause", unimplementedFunc), //32 bit
+ /* 30 */ SyscallDesc("utime", unimplementedFunc),
+ /* 31 */ SyscallDesc("lchown32", unimplementedFunc),
+ /* 32 */ SyscallDesc("fchown32", unimplementedFunc),
+ /* 33 */ SyscallDesc("access", unimplementedFunc), //32 bit
+ /* 34 */ SyscallDesc("nice", unimplementedFunc), //32 bit
+ /* 35 */ SyscallDesc("chown32", unimplementedFunc),
+ /* 36 */ SyscallDesc("sync", unimplementedFunc),
+ /* 37 */ SyscallDesc("kill", unimplementedFunc), //32 bit
+ /* 38 */ SyscallDesc("stat", unimplementedFunc),
+ /* 39 */ SyscallDesc("sendfile", unimplementedFunc), //32 bit
+ /* 40 */ SyscallDesc("lstat", unimplementedFunc),
+ /* 41 */ SyscallDesc("dup", unimplementedFunc),
+ /* 42 */ SyscallDesc("pipe", pipePseudoFunc),
+ /* 43 */ SyscallDesc("times", ignoreFunc),
+ /* 44 */ SyscallDesc("getuid32", unimplementedFunc),
+ /* 45 */ SyscallDesc("umount2", unimplementedFunc), //32 bit
+ /* 46 */ SyscallDesc("setgid", unimplementedFunc), //32 bit
+ /* 47 */ SyscallDesc("getgid", getgidFunc), //32 bit
+ /* 48 */ SyscallDesc("signal", unimplementedFunc), //32 bit
+ /* 49 */ SyscallDesc("geteuid", geteuidFunc), //32 bit
+ /* 50 */ SyscallDesc("getegid", getegidFunc), //32 bit
+ /* 51 */ SyscallDesc("acct", unimplementedFunc),
+ /* 52 */ SyscallDesc("memory_ordering", unimplementedFunc),
+ /* 53 */ SyscallDesc("getgid32", unimplementedFunc),
+ /* 54 */ SyscallDesc("ioctl", unimplementedFunc),
+ /* 55 */ SyscallDesc("reboot", unimplementedFunc), //32 bit
+ /* 56 */ SyscallDesc("mmap2", unimplementedFunc), //32 bit
+ /* 57 */ SyscallDesc("symlink", unimplementedFunc),
+ /* 58 */ SyscallDesc("readlink", unimplementedFunc), //32 bit
+ /* 59 */ SyscallDesc("execve", unimplementedFunc), //32 bit
+ /* 60 */ SyscallDesc("umask", unimplementedFunc), //32 bit
+ /* 61 */ SyscallDesc("chroot", unimplementedFunc),
+ /* 62 */ SyscallDesc("fstat", unimplementedFunc),
+ /* 63 */ SyscallDesc("fstat64", fstat64Func<Sparc32Linux>),
+ /* 64 */ SyscallDesc("getpagesize", unimplementedFunc),
+ /* 65 */ SyscallDesc("msync", unimplementedFunc), //32 bit
+ /* 66 */ SyscallDesc("vfork", unimplementedFunc),
+ /* 67 */ SyscallDesc("pread64", unimplementedFunc), //32 bit
+ /* 68 */ SyscallDesc("pwrite64", unimplementedFunc), //32 bit
+ /* 69 */ SyscallDesc("geteuid32", unimplementedFunc),
+ /* 70 */ SyscallDesc("getegid32", unimplementedFunc),
+ /* 71 */ SyscallDesc("mmap", mmapFunc<Sparc32Linux>),
+ /* 72 */ SyscallDesc("setreuid32", unimplementedFunc),
+ /* 73 */ SyscallDesc("munmap", munmapFunc),
+ /* 74 */ SyscallDesc("mprotect", unimplementedFunc),
+ /* 75 */ SyscallDesc("madvise", unimplementedFunc),
+ /* 76 */ SyscallDesc("vhangup", unimplementedFunc),
+ /* 77 */ SyscallDesc("truncate64", unimplementedFunc), //32 bit
+ /* 78 */ SyscallDesc("mincore", unimplementedFunc),
+ /* 79 */ SyscallDesc("getgroups", unimplementedFunc), //32 bit
+ /* 80 */ SyscallDesc("setgroups", unimplementedFunc), //32 bit
+ /* 81 */ SyscallDesc("getpgrp", unimplementedFunc),
+ /* 82 */ SyscallDesc("setgroups32", unimplementedFunc), //32 bit
+ /* 83 */ SyscallDesc("setitimer", unimplementedFunc), //32 bit
+ /* 84 */ SyscallDesc("ftruncate64", unimplementedFunc), //32 bit
+ /* 85 */ SyscallDesc("swapon", unimplementedFunc), //32 bit
+ /* 86 */ SyscallDesc("getitimer", unimplementedFunc), //32 bit
+ /* 87 */ SyscallDesc("setuid32", unimplementedFunc),
+ /* 88 */ SyscallDesc("sethostname", unimplementedFunc), //32 bit
+ /* 89 */ SyscallDesc("setgid32", unimplementedFunc),
+ /* 90 */ SyscallDesc("dup2", unimplementedFunc),
+ /* 91 */ SyscallDesc("setfsuid32", unimplementedFunc),
+ /* 92 */ SyscallDesc("fcntl", unimplementedFunc),
+ /* 93 */ SyscallDesc("select", unimplementedFunc), //32 bit
+ /* 94 */ SyscallDesc("setfsgid32", unimplementedFunc),
+ /* 95 */ SyscallDesc("fsync", unimplementedFunc),
+ /* 96 */ SyscallDesc("setpriority", unimplementedFunc), //32 bit
+ /* 97 */ SyscallDesc("socket", unimplementedFunc),
+ /* 98 */ SyscallDesc("connect", unimplementedFunc),
+ /* 99 */ SyscallDesc("accept", unimplementedFunc),
+ /* 100 */ SyscallDesc("getpriority", unimplementedFunc), //32 bit
+ /* 101 */ SyscallDesc("rt_sigreturn", unimplementedFunc), //32 bit
+ /* 102 */ SyscallDesc("rt_sigaction", ignoreFunc), //32 bit
+ /* 103 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), //32 bit
+ /* 104 */ SyscallDesc("rt_sigpending", unimplementedFunc), //32 bit
+ /* 105 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
+ /* 106 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc), //32 bit
+ /* 107 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
+ /* 108 */ SyscallDesc("setresuid32", unimplementedFunc),
+ /* 109 */ SyscallDesc("getresuid32", getresuidFunc),
+ /* 110 */ SyscallDesc("setresgid32", unimplementedFunc),
+ /* 111 */ SyscallDesc("getresgid32", unimplementedFunc),
+ /* 112 */ SyscallDesc("setregid32", unimplementedFunc),
+ /* 113 */ SyscallDesc("revcmsg", unimplementedFunc),
+ /* 114 */ SyscallDesc("sendmsg", unimplementedFunc),
+ /* 115 */ SyscallDesc("getgroups32", unimplementedFunc), //32 bit
+ /* 116 */ SyscallDesc("gettimeofday", unimplementedFunc), //32 bit
+ /* 117 */ SyscallDesc("getrusage", unimplementedFunc), //32 bit
+ /* 118 */ SyscallDesc("getsockopt", unimplementedFunc),
+ /* 119 */ SyscallDesc("getcwd", unimplementedFunc),
+ /* 120 */ SyscallDesc("readv", unimplementedFunc),
+ /* 121 */ SyscallDesc("writev", unimplementedFunc),
+ /* 122 */ SyscallDesc("settimeofday", unimplementedFunc), //32 bit
+ /* 123 */ SyscallDesc("fchown", unimplementedFunc), //32 bit
+ /* 124 */ SyscallDesc("fchmod", unimplementedFunc),
+ /* 125 */ SyscallDesc("recvfrom", unimplementedFunc),
+ /* 126 */ SyscallDesc("setreuid", unimplementedFunc), //32 bit
+ /* 127 */ SyscallDesc("setregid", unimplementedFunc), //32 bit
+ /* 128 */ SyscallDesc("rename", renameFunc),
+ /* 129 */ SyscallDesc("truncate", unimplementedFunc),
+ /* 130 */ SyscallDesc("ftruncate", unimplementedFunc),
+ /* 131 */ SyscallDesc("flock", unimplementedFunc),
+ /* 132 */ SyscallDesc("lstat64", unimplementedFunc),
+ /* 133 */ SyscallDesc("sendto", unimplementedFunc),
+ /* 134 */ SyscallDesc("shutdown", unimplementedFunc),
+ /* 135 */ SyscallDesc("socketpair", unimplementedFunc),
+ /* 136 */ SyscallDesc("mkdir", unimplementedFunc), //32 bit
+ /* 137 */ SyscallDesc("rmdir", unimplementedFunc),
+ /* 138 */ SyscallDesc("utimes", unimplementedFunc), //32 bit
+ /* 139 */ SyscallDesc("stat64", unimplementedFunc),
+ /* 140 */ SyscallDesc("sendfile64", unimplementedFunc), //32 bit
+ /* 141 */ SyscallDesc("getpeername", unimplementedFunc),
+ /* 142 */ SyscallDesc("futex", unimplementedFunc), //32 bit
+ /* 143 */ SyscallDesc("gettid", unimplementedFunc),
+ /* 144 */ SyscallDesc("getrlimit", unimplementedFunc),
+ /* 145 */ SyscallDesc("setrlimit", unimplementedFunc),
+ /* 146 */ SyscallDesc("pivot_root", unimplementedFunc),
+ /* 147 */ SyscallDesc("prctl", unimplementedFunc), //32 bit
+ /* 148 */ SyscallDesc("pciconfig_read", unimplementedFunc),
+ /* 149 */ SyscallDesc("pciconfig_write", unimplementedFunc),
+ /* 150 */ SyscallDesc("getsockname", unimplementedFunc),
+ /* 151 */ SyscallDesc("inotify_init", unimplementedFunc),
+ /* 152 */ SyscallDesc("inotify_add_watch", unimplementedFunc),
+ /* 153 */ SyscallDesc("poll", unimplementedFunc),
+ /* 154 */ SyscallDesc("getdents64", unimplementedFunc),
+ /* 155 */ SyscallDesc("fcntl64", unimplementedFunc),
+ /* 156 */ SyscallDesc("inotify_rm_watch", unimplementedFunc),
+ /* 157 */ SyscallDesc("statfs", unimplementedFunc),
+ /* 158 */ SyscallDesc("fstatfs", unimplementedFunc),
+ /* 159 */ SyscallDesc("umount", unimplementedFunc),
+ /* 160 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
+ /* 161 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
+ /* 162 */ SyscallDesc("getdomainname", unimplementedFunc), //32 bit
+ /* 163 */ SyscallDesc("setdomainname", unimplementedFunc), //32 bit
+ /* 164 */ SyscallDesc("ni_syscall", unimplementedFunc),
+ /* 165 */ SyscallDesc("quotactl", unimplementedFunc),
+ /* 166 */ SyscallDesc("set_tid_address", unimplementedFunc),
+ /* 167 */ SyscallDesc("mount", unimplementedFunc),
+ /* 168 */ SyscallDesc("ustat", unimplementedFunc),
+ /* 169 */ SyscallDesc("setxattr", unimplementedFunc), //32 bit
+ /* 170 */ SyscallDesc("lsetxattr", unimplementedFunc), //32 bit
+ /* 171 */ SyscallDesc("fsetxattr", unimplementedFunc), //32 bit
+ /* 172 */ SyscallDesc("getxattr", unimplementedFunc),
+ /* 173 */ SyscallDesc("lgetxattr", unimplementedFunc),
+ /* 174 */ SyscallDesc("getdents", unimplementedFunc),
+ /* 175 */ SyscallDesc("setsid", unimplementedFunc),
+ /* 176 */ SyscallDesc("fchdir", unimplementedFunc),
+ /* 177 */ SyscallDesc("fgetxattr", unimplementedFunc), //32 bit
+ /* 178 */ SyscallDesc("listxattr", unimplementedFunc),
+ /* 179 */ SyscallDesc("llistxattr", unimplementedFunc),
+ /* 180 */ SyscallDesc("flistxattr", unimplementedFunc), //32 bit
+ /* 181 */ SyscallDesc("removexattr", unimplementedFunc),
+ /* 182 */ SyscallDesc("lremovexattr", unimplementedFunc),
+ /* 183 */ SyscallDesc("sigpending", unimplementedFunc),
+ /* 184 */ SyscallDesc("query_module", unimplementedFunc),
+ /* 185 */ SyscallDesc("setpgid", unimplementedFunc), //32 bit
+ /* 186 */ SyscallDesc("fremovexattr", unimplementedFunc), //32 bit
+ /* 187 */ SyscallDesc("tkill", unimplementedFunc), //32 bit
+ /* 188 */ SyscallDesc("exit_group", exitFunc), //32 bit
+ /* 189 */ SyscallDesc("uname", unameFunc),
+ /* 190 */ SyscallDesc("init_module", unimplementedFunc), //32 bit
+ /* 191 */ SyscallDesc("personality", unimplementedFunc),
+ /* 192 */ SyscallDesc("remap_file_pages", unimplementedFunc),
+ /* 193 */ SyscallDesc("epoll_create", unimplementedFunc), //32 bit
+ /* 194 */ SyscallDesc("epoll_ctl", unimplementedFunc), //32 bit
+ /* 195 */ SyscallDesc("epoll_wait", unimplementedFunc), //32 bit
+ /* 196 */ SyscallDesc("ioprio_set", unimplementedFunc), //32 bit
+ /* 197 */ SyscallDesc("getppid", getppidFunc),
+ /* 198 */ SyscallDesc("sigaction", unimplementedFunc), //32 bit
+ /* 199 */ SyscallDesc("sgetmask", unimplementedFunc),
+ /* 200 */ SyscallDesc("ssetmask", unimplementedFunc),
+ /* 201 */ SyscallDesc("sigsuspend", unimplementedFunc),
+ /* 202 */ SyscallDesc("oldlstat", unimplementedFunc),
+ /* 203 */ SyscallDesc("uselib", unimplementedFunc),
+ /* 204 */ SyscallDesc("readdir", unimplementedFunc),
+ /* 205 */ SyscallDesc("readahead", unimplementedFunc), //32 bit
+ /* 206 */ SyscallDesc("socketcall", unimplementedFunc), //32 bit
+ /* 207 */ SyscallDesc("syslog", unimplementedFunc), //32 bit
+ /* 208 */ SyscallDesc("lookup_dcookie", unimplementedFunc), //32 bit
+ /* 209 */ SyscallDesc("fadvise64", unimplementedFunc), //32 bit
+ /* 210 */ SyscallDesc("fadvise64_64", unimplementedFunc), //32 bit
+ /* 211 */ SyscallDesc("tgkill", unimplementedFunc), //32 bit
+ /* 212 */ SyscallDesc("waitpid", unimplementedFunc), //32 bit
+ /* 213 */ SyscallDesc("swapoff", unimplementedFunc),
+ /* 214 */ SyscallDesc("sysinfo", unimplementedFunc), //32 bit
+ /* 215 */ SyscallDesc("ipc", unimplementedFunc), //32 bit
+ /* 216 */ SyscallDesc("sigreturn", unimplementedFunc), //32 bit
+ /* 217 */ SyscallDesc("clone", unimplementedFunc),
+ /* 218 */ SyscallDesc("ioprio_get", unimplementedFunc), //32 bit
+ /* 219 */ SyscallDesc("adjtimex", unimplementedFunc), //32 bit
+ /* 220 */ SyscallDesc("sigprocmask", unimplementedFunc), //32 bit
+ /* 221 */ SyscallDesc("create_module", unimplementedFunc),
+ /* 222 */ SyscallDesc("delete_module", unimplementedFunc), //32 bit
+ /* 223 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
+ /* 224 */ SyscallDesc("getpgid", unimplementedFunc), //32 bit
+ /* 225 */ SyscallDesc("bdflush", unimplementedFunc), //32 bit
+ /* 226 */ SyscallDesc("sysfs", unimplementedFunc), //32 bit
+ /* 227 */ SyscallDesc("afs_syscall", unimplementedFunc),
+ /* 228 */ SyscallDesc("setfsuid", unimplementedFunc), //32 bit
+ /* 229 */ SyscallDesc("setfsgid", unimplementedFunc), //32 bit
+ /* 230 */ SyscallDesc("_newselect", unimplementedFunc), //32 bit
+ /* 231 */ SyscallDesc("time", ignoreFunc),
+ /* 232 */ SyscallDesc("oldstat", unimplementedFunc),
+ /* 233 */ SyscallDesc("stime", unimplementedFunc),
+ /* 234 */ SyscallDesc("statfs64", unimplementedFunc),
+ /* 235 */ SyscallDesc("fstatfs64", unimplementedFunc),
+ /* 236 */ SyscallDesc("_llseek", _llseekFunc),
+ /* 237 */ SyscallDesc("mlock", unimplementedFunc),
+ /* 238 */ SyscallDesc("munlock", unimplementedFunc),
+ /* 239 */ SyscallDesc("mlockall", unimplementedFunc), //32 bit
+ /* 240 */ SyscallDesc("munlockall", unimplementedFunc),
+ /* 241 */ SyscallDesc("sched_setparam", unimplementedFunc), //32 bit
+ /* 242 */ SyscallDesc("sched_getparam", unimplementedFunc), //32 bit
+ /* 243 */ SyscallDesc("sched_setscheduler", unimplementedFunc), //32 bit
+ /* 244 */ SyscallDesc("sched_getscheduler", unimplementedFunc), //32 bit
+ /* 245 */ SyscallDesc("sched_yield", unimplementedFunc),
+ /* 246 */ SyscallDesc("sched_get_priority_max", unimplementedFunc), //32 bit
+ /* 247 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), //32 bit
+ /* 248 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), //32 bit
+ /* 249 */ SyscallDesc("nanosleep", unimplementedFunc),
+ /* 250 */ SyscallDesc("mremap", unimplementedFunc), //32 bit
+ /* 251 */ SyscallDesc("_sysctl", unimplementedFunc), //32 bit
+ /* 252 */ SyscallDesc("getsid", unimplementedFunc), //32 bit
+ /* 253 */ SyscallDesc("fdatasync", unimplementedFunc),
+ /* 254 */ SyscallDesc("nfsservctl", unimplementedFunc), //32 bit
+ /* 255 */ SyscallDesc("aplib", unimplementedFunc),
+ /* 256 */ SyscallDesc("clock_settime", unimplementedFunc),
+ /* 257 */ SyscallDesc("clock_gettime", unimplementedFunc),
+ /* 258 */ SyscallDesc("clock_getres", unimplementedFunc),
+ /* 259 */ SyscallDesc("clock_nanosleep", unimplementedFunc), //32 bit
+ /* 260 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
+ /* 261 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
+ /* 262 */ SyscallDesc("timer_settime", unimplementedFunc), //32 bit
+ /* 263 */ SyscallDesc("timer_gettime", unimplementedFunc),
+ /* 264 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
+ /* 265 */ SyscallDesc("timer_delete", unimplementedFunc),
+ /* 266 */ SyscallDesc("timer_create", unimplementedFunc),
+ /* 267 */ SyscallDesc("vserver", unimplementedFunc),
+ /* 268 */ SyscallDesc("io_setup", unimplementedFunc),
+ /* 269 */ SyscallDesc("io_destroy", unimplementedFunc),
+ /* 270 */ SyscallDesc("io_submit", unimplementedFunc), //32 bit
+ /* 271 */ SyscallDesc("io_cancel", unimplementedFunc),
+ /* 272 */ SyscallDesc("io_getevents", unimplementedFunc),
+ /* 273 */ SyscallDesc("mq_open", unimplementedFunc), //32 bit
+ /* 274 */ SyscallDesc("mq_unlink", unimplementedFunc),
+ /* 275 */ SyscallDesc("mq_timedsend", unimplementedFunc),
+ /* 276 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
+ /* 277 */ SyscallDesc("mq_notify", unimplementedFunc),
+ /* 278 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
+ /* 279 */ SyscallDesc("waitid", unimplementedFunc),
+ /* 280 */ SyscallDesc("sys_setaltroot", unimplementedFunc),
+ /* 281 */ SyscallDesc("add_key", unimplementedFunc),
+ /* 282 */ SyscallDesc("request_key", unimplementedFunc),
+ /* 283 */ SyscallDesc("keyctl", unimplementedFunc),
+ /* 284 */ SyscallDesc("openat", unimplementedFunc),
+ /* 285 */ SyscallDesc("mkdirat", unimplementedFunc),
+ /* 286 */ SyscallDesc("mknodat", unimplementedFunc),
+ /* 287 */ SyscallDesc("fchownat", unimplementedFunc),
+ /* 288 */ SyscallDesc("futimesat", unimplementedFunc),
+ /* 289 */ SyscallDesc("fstatat64", unimplementedFunc),
+ /* 290 */ SyscallDesc("unlinkat", unimplementedFunc),
+ /* 291 */ SyscallDesc("renameat", unimplementedFunc),
+ /* 292 */ SyscallDesc("linkat", unimplementedFunc),
+ /* 293 */ SyscallDesc("symlinkat", unimplementedFunc),
+ /* 294 */ SyscallDesc("readlinkat", unimplementedFunc),
+ /* 295 */ SyscallDesc("fchmodat", unimplementedFunc),
+ /* 296 */ SyscallDesc("faccessat", unimplementedFunc),
+ /* 297 */ SyscallDesc("pselect6", unimplementedFunc),
+ /* 298 */ SyscallDesc("ppoll", unimplementedFunc),
+ /* 299 */ SyscallDesc("unshare", unimplementedFunc)
+};
+
+SyscallDesc SparcLinuxProcess::syscallDescs[] = {
+ /* 0 */ SyscallDesc("restart_syscall", unimplementedFunc),
+ /* 1 */ SyscallDesc("exit", exitFunc),
+ /* 2 */ SyscallDesc("fork", unimplementedFunc),
+ /* 3 */ SyscallDesc("read", readFunc),
+ /* 4 */ SyscallDesc("write", writeFunc),
+ /* 5 */ SyscallDesc("open", openFunc<SparcLinux>),
+ /* 6 */ SyscallDesc("close", closeFunc),
+ /* 7 */ SyscallDesc("wait4", unimplementedFunc),
+ /* 8 */ SyscallDesc("creat", unimplementedFunc),
+ /* 9 */ SyscallDesc("link", unimplementedFunc),
+ /* 10 */ SyscallDesc("unlink", unlinkFunc),
+ /* 11 */ SyscallDesc("execv", unimplementedFunc),
+ /* 12 */ SyscallDesc("chdir", unimplementedFunc),
+ /* 13 */ SyscallDesc("chown", chownFunc),
+ /* 14 */ SyscallDesc("mknod", unimplementedFunc),
+ /* 15 */ SyscallDesc("chmod", chmodFunc<Linux>),
+ /* 16 */ SyscallDesc("lchown", unimplementedFunc),
+ /* 17 */ SyscallDesc("brk", obreakFunc),
+ /* 18 */ SyscallDesc("perfctr", unimplementedFunc),
+ /* 19 */ SyscallDesc("lseek", lseekFunc),
+ /* 20 */ SyscallDesc("getpid", getpidFunc),
+ /* 21 */ SyscallDesc("capget", unimplementedFunc),
+ /* 22 */ SyscallDesc("capset", unimplementedFunc),
+ /* 23 */ SyscallDesc("setuid", setuidFunc),
+ /* 24 */ SyscallDesc("getuid", getuidFunc),
+ /* 25 */ SyscallDesc("time", unimplementedFunc),
+ /* 26 */ SyscallDesc("ptrace", unimplementedFunc),
+ /* 27 */ SyscallDesc("alarm", unimplementedFunc),
+ /* 28 */ SyscallDesc("sigaltstack", unimplementedFunc),
+ /* 29 */ SyscallDesc("pause", unimplementedFunc),
+ /* 30 */ SyscallDesc("utime", unimplementedFunc),
+ /* 31 */ SyscallDesc("lchown32", unimplementedFunc),
+ /* 32 */ SyscallDesc("fchown32", unimplementedFunc),
+ /* 33 */ SyscallDesc("access", unimplementedFunc),
+ /* 34 */ SyscallDesc("nice", unimplementedFunc),
+ /* 35 */ SyscallDesc("chown32", unimplementedFunc),
+ /* 36 */ SyscallDesc("sync", unimplementedFunc),
+ /* 37 */ SyscallDesc("kill", unimplementedFunc),
+ /* 38 */ SyscallDesc("stat", unimplementedFunc),
+ /* 39 */ SyscallDesc("sendfile", unimplementedFunc),
+ /* 40 */ SyscallDesc("lstat", unimplementedFunc),
+ /* 41 */ SyscallDesc("dup", unimplementedFunc),
+ /* 42 */ SyscallDesc("pipe", pipePseudoFunc),
+ /* 43 */ SyscallDesc("times", ignoreFunc),
+ /* 44 */ SyscallDesc("getuid32", unimplementedFunc),
+ /* 45 */ SyscallDesc("umount2", unimplementedFunc),
+ /* 46 */ SyscallDesc("setgid", unimplementedFunc),
+ /* 47 */ SyscallDesc("getgid", getgidFunc),
+ /* 48 */ SyscallDesc("signal", unimplementedFunc),
+ /* 49 */ SyscallDesc("geteuid", geteuidFunc),
+ /* 50 */ SyscallDesc("getegid", getegidFunc),
+ /* 51 */ SyscallDesc("acct", unimplementedFunc),
+ /* 52 */ SyscallDesc("memory_ordering", unimplementedFunc),
+ /* 53 */ SyscallDesc("getgid32", unimplementedFunc),
+ /* 54 */ SyscallDesc("ioctl", unimplementedFunc),
+ /* 55 */ SyscallDesc("reboot", unimplementedFunc),
+ /* 56 */ SyscallDesc("mmap2", unimplementedFunc),
+ /* 57 */ SyscallDesc("symlink", unimplementedFunc),
+ /* 58 */ SyscallDesc("readlink", unimplementedFunc),
+ /* 59 */ SyscallDesc("execve", unimplementedFunc),
+ /* 60 */ SyscallDesc("umask", unimplementedFunc),
+ /* 61 */ SyscallDesc("chroot", unimplementedFunc),
+ /* 62 */ SyscallDesc("fstat", fstatFunc<SparcLinux>),
+ /* 63 */ SyscallDesc("fstat64", unimplementedFunc),
+ /* 64 */ SyscallDesc("getpagesize", unimplementedFunc),
+ /* 65 */ SyscallDesc("msync", unimplementedFunc),
+ /* 66 */ SyscallDesc("vfork", unimplementedFunc),
+ /* 67 */ SyscallDesc("pread64", unimplementedFunc),
+ /* 68 */ SyscallDesc("pwrite64", unimplementedFunc),
+ /* 69 */ SyscallDesc("geteuid32", unimplementedFunc),
+ /* 70 */ SyscallDesc("getegid32", unimplementedFunc),
+ /* 71 */ SyscallDesc("mmap", mmapFunc<SparcLinux>),
+ /* 72 */ SyscallDesc("setreuid32", unimplementedFunc),
+ /* 73 */ SyscallDesc("munmap", munmapFunc),
+ /* 74 */ SyscallDesc("mprotect", unimplementedFunc),
+ /* 75 */ SyscallDesc("madvise", unimplementedFunc),
+ /* 76 */ SyscallDesc("vhangup", unimplementedFunc),
+ /* 77 */ SyscallDesc("truncate64", unimplementedFunc),
+ /* 78 */ SyscallDesc("mincore", unimplementedFunc),
+ /* 79 */ SyscallDesc("getgroups", unimplementedFunc),
+ /* 80 */ SyscallDesc("setgroups", unimplementedFunc),
+ /* 81 */ SyscallDesc("getpgrp", unimplementedFunc),
+ /* 82 */ SyscallDesc("setgroups32", unimplementedFunc),
+ /* 83 */ SyscallDesc("setitimer", unimplementedFunc),
+ /* 84 */ SyscallDesc("ftruncate64", unimplementedFunc),
+ /* 85 */ SyscallDesc("swapon", unimplementedFunc),
+ /* 86 */ SyscallDesc("getitimer", unimplementedFunc),
+ /* 87 */ SyscallDesc("setuid32", unimplementedFunc),
+ /* 88 */ SyscallDesc("sethostname", unimplementedFunc),
+ /* 89 */ SyscallDesc("setgid32", unimplementedFunc),
+ /* 90 */ SyscallDesc("dup2", unimplementedFunc),
+ /* 91 */ SyscallDesc("setfsuid32", unimplementedFunc),
+ /* 92 */ SyscallDesc("fcntl", unimplementedFunc),
+ /* 93 */ SyscallDesc("select", unimplementedFunc),
+ /* 94 */ SyscallDesc("setfsgid32", unimplementedFunc),
+ /* 95 */ SyscallDesc("fsync", unimplementedFunc),
+ /* 96 */ SyscallDesc("setpriority", unimplementedFunc),
+ /* 97 */ SyscallDesc("socket", unimplementedFunc),
+ /* 98 */ SyscallDesc("connect", unimplementedFunc),
+ /* 99 */ SyscallDesc("accept", unimplementedFunc),
+ /* 100 */ SyscallDesc("getpriority", unimplementedFunc),
+ /* 101 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
+ /* 102 */ SyscallDesc("rt_sigaction", ignoreFunc),
+ /* 103 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
+ /* 104 */ SyscallDesc("rt_sigpending", unimplementedFunc),
+ /* 105 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
+ /* 106 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc),
+ /* 107 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
+ /* 108 */ SyscallDesc("setresuid", unimplementedFunc),
+ /* 109 */ SyscallDesc("getresuid", getresuidFunc),
+ /* 110 */ SyscallDesc("setresgid", unimplementedFunc),
+ /* 111 */ SyscallDesc("getresgid", unimplementedFunc),
+ /* 112 */ SyscallDesc("setregid32", unimplementedFunc),
+ /* 113 */ SyscallDesc("recvmsg", unimplementedFunc),
+ /* 114 */ SyscallDesc("sendmsg", unimplementedFunc),
+ /* 115 */ SyscallDesc("getgroups32", unimplementedFunc),
+ /* 116 */ SyscallDesc("gettimeofday", unimplementedFunc),
+ /* 117 */ SyscallDesc("getrusage", unimplementedFunc),
+ /* 118 */ SyscallDesc("getsockopt", unimplementedFunc),
+ /* 119 */ SyscallDesc("getcwd", unimplementedFunc),
+ /* 120 */ SyscallDesc("readv", unimplementedFunc),
+ /* 121 */ SyscallDesc("writev", unimplementedFunc),
+ /* 122 */ SyscallDesc("settimeofday", unimplementedFunc),
+ /* 123 */ SyscallDesc("fchown", unimplementedFunc),
+ /* 124 */ SyscallDesc("fchmod", unimplementedFunc),
+ /* 125 */ SyscallDesc("recvfrom", unimplementedFunc),
+ /* 126 */ SyscallDesc("setreuid", unimplementedFunc),
+ /* 127 */ SyscallDesc("setregid", unimplementedFunc),
+ /* 128 */ SyscallDesc("rename", renameFunc),
+ /* 129 */ SyscallDesc("truncate", unimplementedFunc),
+ /* 130 */ SyscallDesc("ftruncate", unimplementedFunc),
+ /* 131 */ SyscallDesc("flock", unimplementedFunc),
+ /* 132 */ SyscallDesc("lstat64", unimplementedFunc),
+ /* 133 */ SyscallDesc("sendto", unimplementedFunc),
+ /* 134 */ SyscallDesc("shutdown", unimplementedFunc),
+ /* 135 */ SyscallDesc("socketpair", unimplementedFunc),
+ /* 136 */ SyscallDesc("mkdir", unimplementedFunc),
+ /* 137 */ SyscallDesc("rmdir", unimplementedFunc),
+ /* 138 */ SyscallDesc("utimes", unimplementedFunc),
+ /* 139 */ SyscallDesc("stat64", unimplementedFunc),
+ /* 140 */ SyscallDesc("sendfile64", unimplementedFunc),
+ /* 141 */ SyscallDesc("getpeername", unimplementedFunc),
+ /* 142 */ SyscallDesc("futex", unimplementedFunc),
+ /* 143 */ SyscallDesc("gettid", unimplementedFunc),
+ /* 144 */ SyscallDesc("getrlimit", unimplementedFunc),
+ /* 145 */ SyscallDesc("setrlimit", unimplementedFunc),
+ /* 146 */ SyscallDesc("pivot_root", unimplementedFunc),
+ /* 147 */ SyscallDesc("prctl", unimplementedFunc),
+ /* 148 */ SyscallDesc("pciconfig_read", unimplementedFunc),
+ /* 149 */ SyscallDesc("pciconfig_write", unimplementedFunc),
+ /* 150 */ SyscallDesc("getsockname", unimplementedFunc),
+ /* 151 */ SyscallDesc("inotify_init", unimplementedFunc),
+ /* 152 */ SyscallDesc("inotify_add_watch", unimplementedFunc),
+ /* 153 */ SyscallDesc("poll", unimplementedFunc),
+ /* 154 */ SyscallDesc("getdents64", unimplementedFunc),
+ /* 155 */ SyscallDesc("fcntl64", unimplementedFunc),
+ /* 156 */ SyscallDesc("inotify_rm_watch", unimplementedFunc),
+ /* 157 */ SyscallDesc("statfs", unimplementedFunc),
+ /* 158 */ SyscallDesc("fstatfs", unimplementedFunc),
+ /* 159 */ SyscallDesc("umount", unimplementedFunc),
+ /* 160 */ SyscallDesc("sched_set_affinity", unimplementedFunc),
+ /* 161 */ SyscallDesc("sched_get_affinity", unimplementedFunc),
+ /* 162 */ SyscallDesc("getdomainname", unimplementedFunc),
+ /* 163 */ SyscallDesc("setdomainname", unimplementedFunc),
+ /* 164 */ SyscallDesc("utrap_install", unimplementedFunc),
+ /* 165 */ SyscallDesc("quotactl", unimplementedFunc),
+ /* 166 */ SyscallDesc("set_tid_address", unimplementedFunc),
+ /* 167 */ SyscallDesc("mount", unimplementedFunc),
+ /* 168 */ SyscallDesc("ustat", unimplementedFunc),
+ /* 169 */ SyscallDesc("setxattr", unimplementedFunc),
+ /* 170 */ SyscallDesc("lsetxattr", unimplementedFunc),
+ /* 171 */ SyscallDesc("fsetxattr", unimplementedFunc),
+ /* 172 */ SyscallDesc("getxattr", unimplementedFunc),
+ /* 173 */ SyscallDesc("lgetxattr", unimplementedFunc),
+ /* 174 */ SyscallDesc("getdents", unimplementedFunc),
+ /* 175 */ SyscallDesc("setsid", unimplementedFunc),
+ /* 176 */ SyscallDesc("fchdir", unimplementedFunc),
+ /* 177 */ SyscallDesc("fgetxattr", unimplementedFunc),
+ /* 178 */ SyscallDesc("listxattr", unimplementedFunc),
+ /* 179 */ SyscallDesc("llistxattr", unimplementedFunc),
+ /* 180 */ SyscallDesc("flistxattr", unimplementedFunc),
+ /* 181 */ SyscallDesc("removexattr", unimplementedFunc),
+ /* 182 */ SyscallDesc("lremovexattr", unimplementedFunc),
+ /* 183 */ SyscallDesc("sigpending", unimplementedFunc),
+ /* 184 */ SyscallDesc("query_module", unimplementedFunc),
+ /* 185 */ SyscallDesc("setpgid", unimplementedFunc),
+ /* 186 */ SyscallDesc("fremovexattr", unimplementedFunc),
+ /* 187 */ SyscallDesc("tkill", unimplementedFunc),
+ /* 188 */ SyscallDesc("exit_group", exitFunc),
+ /* 189 */ SyscallDesc("uname", unameFunc),
+ /* 190 */ SyscallDesc("init_module", unimplementedFunc),
+ /* 191 */ SyscallDesc("personality", unimplementedFunc),
+ /* 192 */ SyscallDesc("remap_file_pages", unimplementedFunc),
+ /* 193 */ SyscallDesc("epoll_create", unimplementedFunc),
+ /* 194 */ SyscallDesc("epoll_ctl", unimplementedFunc),
+ /* 195 */ SyscallDesc("epoll_wait", unimplementedFunc),
+ /* 196 */ SyscallDesc("ioprio_set", unimplementedFunc),
+ /* 197 */ SyscallDesc("getppid", getppidFunc),
+ /* 198 */ SyscallDesc("sigaction", ignoreFunc),
+ /* 199 */ SyscallDesc("sgetmask", unimplementedFunc),
+ /* 200 */ SyscallDesc("ssetmask", unimplementedFunc),
+ /* 201 */ SyscallDesc("sigsuspend", unimplementedFunc),
+ /* 202 */ SyscallDesc("oldlstat", unimplementedFunc),
+ /* 203 */ SyscallDesc("uselib", unimplementedFunc),
+ /* 204 */ SyscallDesc("readdir", unimplementedFunc),
+ /* 205 */ SyscallDesc("readahead", unimplementedFunc),
+ /* 206 */ SyscallDesc("socketcall", unimplementedFunc),
+ /* 207 */ SyscallDesc("syslog", unimplementedFunc),
+ /* 208 */ SyscallDesc("lookup_dcookie", unimplementedFunc),
+ /* 209 */ SyscallDesc("fadvise64", unimplementedFunc),
+ /* 210 */ SyscallDesc("fadvise64_64", unimplementedFunc),
+ /* 211 */ SyscallDesc("tgkill", unimplementedFunc),
+ /* 212 */ SyscallDesc("waitpid", unimplementedFunc),
+ /* 213 */ SyscallDesc("swapoff", unimplementedFunc),
+ /* 214 */ SyscallDesc("sysinfo", unimplementedFunc),
+ /* 215 */ SyscallDesc("ipc", unimplementedFunc),
+ /* 216 */ SyscallDesc("sigreturn", unimplementedFunc),
+ /* 217 */ SyscallDesc("clone", unimplementedFunc),
+ /* 218 */ SyscallDesc("ioprio_get", unimplementedFunc),
+ /* 219 */ SyscallDesc("adjtimex", unimplementedFunc),
+ /* 220 */ SyscallDesc("sigprocmask", unimplementedFunc),
+ /* 221 */ SyscallDesc("create_module", unimplementedFunc),
+ /* 222 */ SyscallDesc("delete_module", unimplementedFunc),
+ /* 223 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
+ /* 224 */ SyscallDesc("getpgid", unimplementedFunc),
+ /* 225 */ SyscallDesc("bdflush", unimplementedFunc),
+ /* 226 */ SyscallDesc("sysfs", unimplementedFunc),
+ /* 227 */ SyscallDesc("afs_syscall", unimplementedFunc),
+ /* 228 */ SyscallDesc("setfsuid", unimplementedFunc),
+ /* 229 */ SyscallDesc("setfsgid", unimplementedFunc),
+ /* 230 */ SyscallDesc("_newselect", unimplementedFunc),
+ /* 231 */ SyscallDesc("time", ignoreFunc),
+ /* 232 */ SyscallDesc("oldstat", unimplementedFunc),
+ /* 233 */ SyscallDesc("stime", unimplementedFunc),
+ /* 234 */ SyscallDesc("statfs64", unimplementedFunc),
+ /* 235 */ SyscallDesc("fstatfs64", unimplementedFunc),
+ /* 236 */ SyscallDesc("_llseek", _llseekFunc),
+ /* 237 */ SyscallDesc("mlock", unimplementedFunc),
+ /* 238 */ SyscallDesc("munlock", unimplementedFunc),
+ /* 239 */ SyscallDesc("mlockall", unimplementedFunc),
+ /* 240 */ SyscallDesc("munlockall", unimplementedFunc),
+ /* 241 */ SyscallDesc("sched_setparam", unimplementedFunc),
+ /* 242 */ SyscallDesc("sched_getparam", unimplementedFunc),
+ /* 243 */ SyscallDesc("sched_setscheduler", unimplementedFunc),
+ /* 244 */ SyscallDesc("sched_getscheduler", unimplementedFunc),
+ /* 245 */ SyscallDesc("sched_yield", unimplementedFunc),
+ /* 246 */ SyscallDesc("sched_get_priority_max", unimplementedFunc),
+ /* 247 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
+ /* 248 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
+ /* 249 */ SyscallDesc("nanosleep", unimplementedFunc),
+ /* 250 */ SyscallDesc("mremap", unimplementedFunc),
+ /* 251 */ SyscallDesc("_sysctl", unimplementedFunc),
+ /* 252 */ SyscallDesc("getsid", unimplementedFunc),
+ /* 253 */ SyscallDesc("fdatasync", unimplementedFunc),
+ /* 254 */ SyscallDesc("nfsservctl", unimplementedFunc),
+ /* 255 */ SyscallDesc("aplib", unimplementedFunc),
+ /* 256 */ SyscallDesc("clock_settime", unimplementedFunc),
+ /* 257 */ SyscallDesc("clock_gettime", unimplementedFunc),
+ /* 258 */ SyscallDesc("clock_getres", unimplementedFunc),
+ /* 259 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
+ /* 260 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
+ /* 261 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
+ /* 262 */ SyscallDesc("timer_settime", unimplementedFunc),
+ /* 263 */ SyscallDesc("timer_gettime", unimplementedFunc),
+ /* 264 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
+ /* 265 */ SyscallDesc("timer_delete", unimplementedFunc),
+ /* 266 */ SyscallDesc("timer_create", unimplementedFunc),
+ /* 267 */ SyscallDesc("vserver", unimplementedFunc),
+ /* 268 */ SyscallDesc("io_setup", unimplementedFunc),
+ /* 269 */ SyscallDesc("io_destroy", unimplementedFunc),
+ /* 270 */ SyscallDesc("io_submit", unimplementedFunc),
+ /* 271 */ SyscallDesc("io_cancel", unimplementedFunc),
+ /* 272 */ SyscallDesc("io_getevents", unimplementedFunc),
+ /* 273 */ SyscallDesc("mq_open", unimplementedFunc),
+ /* 274 */ SyscallDesc("mq_unlink", unimplementedFunc),
+ /* 275 */ SyscallDesc("mq_timedsend", unimplementedFunc),
+ /* 276 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
+ /* 277 */ SyscallDesc("mq_notify", unimplementedFunc),
+ /* 278 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
+ /* 279 */ SyscallDesc("waitid", unimplementedFunc),
+ /* 280 */ SyscallDesc("sys_setaltroot", unimplementedFunc),
+ /* 281 */ SyscallDesc("add_key", unimplementedFunc),
+ /* 282 */ SyscallDesc("request_key", unimplementedFunc),
+ /* 283 */ SyscallDesc("keyctl", unimplementedFunc)
+};
+
+} // namespace SparcISA
diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc
index 8b612e8b4..5bd572d38 100644
--- a/src/arch/sparc/miscregfile.cc
+++ b/src/arch/sparc/miscregfile.cc
@@ -54,7 +54,15 @@ string SparcISA::getMiscRegName(RegIndex index)
"wstate",*/ "gl",
"hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
"hstick_cmpr",
- "fsr"};
+ "fsr", "prictx", "secctx", "partId", "lsuCtrlReg", "itbTsbC0Ps0",
+ "itbTsbC0Ps1", "iTlbC0Cnfg", "itbTsbCXPs0", "itbTsbCXPs1",
+ "iTlbCXCnfg","iTlbSfsr", "iTlbTagAcs", "dtbTsbC0Ps0",
+ "dtbTsbC0Ps1", "dTlbC0Cnfg", "dtbTsbCXPs0", "dtbTsbCXPs1",
+ "dTlbCXCnfg","dTlbSfsr", "dTlbSfar", "dTlbTagAcs",
+ "scratch0", "scratch1", "scratch2", "scratch3", "scratch4",
+ "scratch5", "scratch6", "scratch7", "cpuMondoHead", "cpuMondoTail",
+ "devMondoHead", "devMondoTail", "resErrorHead", "resErrorTail",
+ "nresErrorHead", "nresErrorTail", "TlbData" };
return miscRegName[index];
}
@@ -132,7 +140,7 @@ void MiscRegFile::clear()
#endif
}
-MiscReg MiscRegFile::readReg(int miscReg)
+MiscReg MiscRegFile::readRegNoEffect(int miscReg)
{
switch (miscReg) {
case MISCREG_TLB_DATA:
@@ -223,8 +231,6 @@ MiscReg MiscRegFile::readReg(int miscReg)
return hintp;
case MISCREG_HTBA:
return htba;
- case MISCREG_HVER:
- return NWindows | MaxTL << 8 | MaxGL << 16;
case MISCREG_STRAND_STS_REG:
return strandStatusReg;
case MISCREG_HSTICK_CMPR:
@@ -317,7 +323,7 @@ MiscReg MiscRegFile::readReg(int miscReg)
}
}
-MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc)
+MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc)
{
switch (miscReg) {
// tick and stick are aliased to each other in niagra
@@ -360,7 +366,7 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc)
case MISCREG_QUEUE_NRES_ERROR_TAIL:
#if FULL_SYSTEM
case MISCREG_HPSTATE:
- return readFSRegWithEffect(miscReg, tc);
+ return readFSReg(miscReg, tc);
#else
case MISCREG_HPSTATE:
//HPSTATE is special because because sometimes in privilege checks for instructions
@@ -372,10 +378,10 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc)
#endif
}
- return readReg(miscReg);
+ return readRegNoEffect(miscReg);
}
-void MiscRegFile::setReg(int miscReg, const MiscReg &val)
+void MiscRegFile::setRegNoEffect(int miscReg, const MiscReg &val)
{
switch (miscReg) {
// case MISCREG_Y:
@@ -602,13 +608,12 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val)
case MISCREG_QUEUE_NRES_ERROR_TAIL:
nres_error_tail = val;
break;
-
default:
panic("Miscellaneous register %d not implemented\n", miscReg);
}
}
-void MiscRegFile::setRegWithEffect(int miscReg,
+void MiscRegFile::setReg(int miscReg,
const MiscReg &val, ThreadContext * tc)
{
MiscReg new_val = val;
@@ -633,9 +638,20 @@ void MiscRegFile::setRegWithEffect(int miscReg,
return;
case MISCREG_TL:
tl = val;
+#if FULL_SYSTEM
+ if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
+ tc->getCpuPtr()->post_interrupt(IT_TRAP_LEVEL_ZERO,0);
+ else
+ tc->getCpuPtr()->clear_interrupt(IT_TRAP_LEVEL_ZERO,0);
+#endif
return;
case MISCREG_CWP:
- new_val = val > NWindows ? NWindows - 1 : val;
+ new_val = val >= NWindows ? NWindows - 1 : val;
+ if (val >= NWindows) {
+ new_val = NWindows - 1;
+ warn("Attempted to set the CWP to %d with NWindows = %d\n",
+ val, NWindows);
+ }
tc->changeRegFileContext(CONTEXT_CWP, new_val);
break;
case MISCREG_GL:
@@ -663,7 +679,7 @@ void MiscRegFile::setRegWithEffect(int miscReg,
case MISCREG_QUEUE_NRES_ERROR_TAIL:
#if FULL_SYSTEM
case MISCREG_HPSTATE:
- setFSRegWithEffect(miscReg, val, tc);
+ setFSReg(miscReg, val, tc);
return;
#else
case MISCREG_HPSTATE:
@@ -673,7 +689,7 @@ void MiscRegFile::setRegWithEffect(int miscReg,
panic("Accessing Fullsystem register %s to %#x in SE mode\n", getMiscRegName(miscReg), val);
#endif
}
- setReg(miscReg, new_val);
+ setRegNoEffect(miscReg, new_val);
}
void MiscRegFile::serialize(std::ostream & os)
diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh
index 66c9f17df..867f959e1 100644
--- a/src/arch/sparc/miscregfile.hh
+++ b/src/arch/sparc/miscregfile.hh
@@ -39,6 +39,8 @@
#include <string>
+class Checkpoint;
+
namespace SparcISA
{
//These functions map register indices to names
@@ -161,6 +163,23 @@ namespace SparcISA
const static int ie = 0x2;
};
+ struct STS {
+ const static int st_idle = 0x00;
+ const static int st_wait = 0x01;
+ const static int st_halt = 0x02;
+ const static int st_run = 0x05;
+ const static int st_spec_run = 0x07;
+ const static int st_spec_rdy = 0x13;
+ const static int st_ready = 0x19;
+ const static int active = 0x01;
+ const static int speculative = 0x04;
+ const static int shft_id = 8;
+ const static int shft_fsm0 = 31;
+ const static int shft_fsm1 = 26;
+ const static int shft_fsm2 = 21;
+ const static int shft_fsm3 = 16;
+ };
+
const int NumMiscArchRegs = MISCREG_NUMMISCREGS;
const int NumMiscRegs = MISCREG_NUMMISCREGS;
@@ -255,9 +274,11 @@ namespace SparcISA
// These need to check the int_dis field and if 0 then
// set appropriate bit in softint and checkinterrutps on the cpu
#if FULL_SYSTEM
- void setFSRegWithEffect(int miscReg, const MiscReg &val,
- ThreadContext *tc);
- MiscReg readFSRegWithEffect(int miscReg, ThreadContext * tc);
+ void setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc);
+ MiscReg readFSReg(int miscReg, ThreadContext * tc);
+
+ // Update interrupt state on softint or pil change
+ void checkSoftInt(ThreadContext *tc);
/** Process a tick compare event and generate an interrupt on the cpu if
* appropriate. */
@@ -286,13 +307,13 @@ namespace SparcISA
clear();
}
- MiscReg readReg(int miscReg);
+ MiscReg readRegNoEffect(int miscReg);
- MiscReg readRegWithEffect(int miscReg, ThreadContext *tc);
+ MiscReg readReg(int miscReg, ThreadContext *tc);
- void setReg(int miscReg, const MiscReg &val);
+ void setRegNoEffect(int miscReg, const MiscReg &val);
- void setRegWithEffect(int miscReg,
+ void setReg(int miscReg,
const MiscReg &val, ThreadContext * tc);
int getInstAsid()
diff --git a/src/arch/sparc/pagetable.hh b/src/arch/sparc/pagetable.hh
index fc01e82da..980225052 100644
--- a/src/arch/sparc/pagetable.hh
+++ b/src/arch/sparc/pagetable.hh
@@ -45,6 +45,22 @@ struct VAddr
VAddr(Addr a) { panic("not implemented yet."); }
};
+class TteTag
+{
+ private:
+ uint64_t entry;
+ bool populated;
+
+ public:
+ TteTag() : entry(0), populated(false) {}
+ TteTag(uint64_t e) : entry(e), populated(true) {}
+ const TteTag &operator=(uint64_t e) { populated = true;
+ entry = e; return *this; }
+ bool valid() const {assert(populated); return !bits(entry,62,62); }
+ Addr va() const {assert(populated); return bits(entry,41,0); }
+};
+
+
class PageTableEntry
{
public:
@@ -110,13 +126,14 @@ class PageTableEntry
entry4u = e; return *this; }
const PageTableEntry &operator=(const PageTableEntry &e)
- { populated = true; entry4u = e.entry4u; return *this; }
+ { populated = true; entry4u = e.entry4u; type = e.type; return *this; }
bool valid() const { return bits(entry4u,63,63) && populated; }
uint8_t _size() const { assert(populated);
return bits(entry4u, 62,61) |
bits(entry4u, 48,48) << 2; }
Addr size() const { assert(_size() < 6); return pageSizes[_size()]; }
+ Addr sizeMask() const { assert(_size() < 6); return pageSizes[_size()]-1;}
bool ie() const { return bits(entry4u, 59,59); }
Addr pfn() const { assert(populated); return bits(entry4u,39,13); }
Addr paddr() const { assert(populated); return mbits(entry4u, 39,13);}
@@ -127,6 +144,8 @@ class PageTableEntry
bool writable() const { assert(populated); return bits(entry4u,1,1); }
bool nofault() const { assert(populated); return bits(entry4u,60,60); }
bool sideffect() const { assert(populated); return bits(entry4u,3,3); }
+ Addr paddrMask() const { assert(populated);
+ return mbits(entry4u, 39,13) & ~sizeMask(); }
};
struct TlbRange {
diff --git a/src/arch/sparc/predecoder.hh b/src/arch/sparc/predecoder.hh
new file mode 100644
index 000000000..4a8c9dc4a
--- /dev/null
+++ b/src/arch/sparc/predecoder.hh
@@ -0,0 +1,113 @@
+/*
+ * 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_PREDECODER_HH__
+#define __ARCH_SPARC_PREDECODER_HH__
+
+#include "arch/sparc/types.hh"
+#include "base/misc.hh"
+#include "cpu/thread_context.hh"
+#include "sim/host.hh"
+
+class ThreadContext;
+
+namespace SparcISA
+{
+ class Predecoder
+ {
+ protected:
+ ThreadContext * tc;
+ //The extended machine instruction being generated
+ ExtMachInst emi;
+
+ public:
+ Predecoder(ThreadContext * _tc) : tc(_tc)
+ {}
+
+ ThreadContext * getTC()
+ {
+ return tc;
+ }
+
+ void setTC(ThreadContext * _tc)
+ {
+ tc = _tc;
+ }
+
+ void process()
+ {
+ }
+
+ //Use this to give data to the predecoder. This should be used
+ //when there is control flow.
+ void moreBytes(Addr currPC, Addr off, MachInst inst)
+ {
+ assert(off == 0);
+
+ emi = inst;
+ //The I bit, bit 13, is used to figure out where the ASI
+ //should come from. Use that in the ExtMachInst. This is
+ //slightly redundant, but it removes the need to put a condition
+ //into all the execute functions
+ if(inst & (1 << 13))
+ emi |= (static_cast<ExtMachInst>(
+ tc->readMiscRegNoEffect(MISCREG_ASI))
+ << (sizeof(MachInst) * 8));
+ else
+ emi |= (static_cast<ExtMachInst>(bits(inst, 12, 5))
+ << (sizeof(MachInst) * 8));
+ }
+
+ //Use this to give data to the predecoder. This should be used
+ //when instructions are executed in order.
+ void moreBytes(MachInst machInst)
+ {
+ moreBytes(0, 0, machInst);
+ }
+
+ bool needMoreBytes()
+ {
+ return true;
+ }
+
+ bool extMachInstReady()
+ {
+ return true;
+ }
+
+ //This returns a constant reference to the ExtMachInst to avoid a copy
+ const ExtMachInst & getExtMachInst()
+ {
+ return emi;
+ }
+ };
+};
+
+#endif // __ARCH_SPARC_PREDECODER_HH__
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index 1e639b9a5..e4774ab54 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -30,6 +30,7 @@
*/
#include "arch/sparc/asi.hh"
+#include "arch/sparc/handlers.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/process.hh"
#include "arch/sparc/types.hh"
@@ -59,14 +60,6 @@ SparcLiveProcess::SparcLiveProcess(const std::string &nm, ObjectFile *objFile,
brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
brk_point = roundUp(brk_point, VMPageSize);
- // Set up stack. On SPARC Linux, stack goes from the top of memory
- // downward, less the hole for the kernel address space.
- stack_base = (Addr)0x80000000000ULL;
-
- // Set up region for mmaps. Tru64 seems to start just above 0 and
- // grow up from there.
- mmap_start = mmap_end = 0xfffff80000000000ULL;
-
// Set pointer for next thread stack. Reserve 8M for main stack.
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
@@ -75,136 +68,118 @@ SparcLiveProcess::SparcLiveProcess(const std::string &nm, ObjectFile *objFile,
spillStart = 0;
}
+void SparcLiveProcess::handleTrap(int trapNum, ThreadContext *tc)
+{
+ switch(trapNum)
+ {
+ case 0x03: //Flush window trap
+ warn("Ignoring request to flush register windows.\n");
+ break;
+ default:
+ panic("Unimplemented trap to operating system: trap number %#x.\n", trapNum);
+ }
+}
+
void
-SparcLiveProcess::startup()
+Sparc32LiveProcess::startup()
{
- argsInit(sizeof(IntReg), VMPageSize);
+ argsInit(32 / 8, VMPageSize);
//From the SPARC ABI
//The process runs in user mode
- threadContexts[0]->setMiscRegWithEffect(MISCREG_PSTATE, 0x02);
+ threadContexts[0]->setMiscReg(MISCREG_PSTATE, 0x02);
//Setup default FP state
- threadContexts[0]->setMiscReg(MISCREG_FSR, 0);
+ threadContexts[0]->setMiscRegNoEffect(MISCREG_FSR, 0);
- threadContexts[0]->setMiscReg(MISCREG_TICK, 0);
+ threadContexts[0]->setMiscRegNoEffect(MISCREG_TICK, 0);
//
/*
* Register window management registers
*/
//No windows contain info from other programs
- //threadContexts[0]->setMiscReg(MISCREG_OTHERWIN, 0);
+ //threadContexts[0]->setMiscRegNoEffect(MISCREG_OTHERWIN, 0);
threadContexts[0]->setIntReg(NumIntArchRegs + 6, 0);
//There are no windows to pop
- //threadContexts[0]->setMiscReg(MISCREG_CANRESTORE, 0);
+ //threadContexts[0]->setMiscRegNoEffect(MISCREG_CANRESTORE, 0);
threadContexts[0]->setIntReg(NumIntArchRegs + 4, 0);
//All windows are available to save into
- //threadContexts[0]->setMiscReg(MISCREG_CANSAVE, NWindows - 2);
+ //threadContexts[0]->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2);
threadContexts[0]->setIntReg(NumIntArchRegs + 3, NWindows - 2);
//All windows are "clean"
- //threadContexts[0]->setMiscReg(MISCREG_CLEANWIN, NWindows);
+ //threadContexts[0]->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows);
threadContexts[0]->setIntReg(NumIntArchRegs + 5, NWindows);
//Start with register window 0
- threadContexts[0]->setMiscReg(MISCREG_CWP, 0);
+ threadContexts[0]->setMiscRegNoEffect(MISCREG_CWP, 0);
//Always use spill and fill traps 0
- //threadContexts[0]->setMiscReg(MISCREG_WSTATE, 0);
+ //threadContexts[0]->setMiscRegNoEffect(MISCREG_WSTATE, 0);
threadContexts[0]->setIntReg(NumIntArchRegs + 7, 0);
//Set the trap level to 0
- threadContexts[0]->setMiscReg(MISCREG_TL, 0);
+ threadContexts[0]->setMiscRegNoEffect(MISCREG_TL, 0);
//Set the ASI register to something fixed
- threadContexts[0]->setMiscReg(MISCREG_ASI, ASI_PRIMARY);
+ threadContexts[0]->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY);
}
-m5_auxv_t buildAuxVect(int64_t type, int64_t val)
+void
+Sparc64LiveProcess::startup()
{
- m5_auxv_t result;
- result.a_type = TheISA::htog(type);
- result.a_val = TheISA::htog(val);
- return result;
-}
+ argsInit(sizeof(IntReg), VMPageSize);
+
+ //From the SPARC ABI
+
+ //The process runs in user mode
+ threadContexts[0]->setMiscReg(MISCREG_PSTATE, 0x02);
+
+ //Setup default FP state
+ threadContexts[0]->setMiscRegNoEffect(MISCREG_FSR, 0);
+
+ threadContexts[0]->setMiscRegNoEffect(MISCREG_TICK, 0);
+ //
+ /*
+ * Register window management registers
+ */
-//We only use 19 instructions for the trap handlers, but there would be
-//space for 32 in a real SPARC trap table.
-const int numFillInsts = 32;
-const int numSpillInsts = 32;
+ //No windows contain info from other programs
+ //threadContexts[0]->setMiscRegNoEffect(MISCREG_OTHERWIN, 0);
+ threadContexts[0]->setIntReg(NumIntArchRegs + 6, 0);
+ //There are no windows to pop
+ //threadContexts[0]->setMiscRegNoEffect(MISCREG_CANRESTORE, 0);
+ threadContexts[0]->setIntReg(NumIntArchRegs + 4, 0);
+ //All windows are available to save into
+ //threadContexts[0]->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2);
+ threadContexts[0]->setIntReg(NumIntArchRegs + 3, NWindows - 2);
+ //All windows are "clean"
+ //threadContexts[0]->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows);
+ threadContexts[0]->setIntReg(NumIntArchRegs + 5, NWindows);
+ //Start with register window 0
+ threadContexts[0]->setMiscRegNoEffect(MISCREG_CWP, 0);
+ //Always use spill and fill traps 0
+ //threadContexts[0]->setMiscRegNoEffect(MISCREG_WSTATE, 0);
+ threadContexts[0]->setIntReg(NumIntArchRegs + 7, 0);
+ //Set the trap level to 0
+ threadContexts[0]->setMiscRegNoEffect(MISCREG_TL, 0);
+ //Set the ASI register to something fixed
+ threadContexts[0]->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY);
+}
-MachInst fillHandler[numFillInsts] =
+M5_32_auxv_t::M5_32_auxv_t(int32_t type, int32_t val)
{
- htog(0x87802018), //wr %g0, ASI_AIUP, %asi
- htog(0xe0dba7ff), //ldxa [%sp + BIAS + (0*8)] %asi, %l0
- htog(0xe2dba807), //ldxa [%sp + BIAS + (1*8)] %asi, %l1
- htog(0xe4dba80f), //ldxa [%sp + BIAS + (2*8)] %asi, %l2
- htog(0xe6dba817), //ldxa [%sp + BIAS + (3*8)] %asi, %l3
- htog(0xe8dba81f), //ldxa [%sp + BIAS + (4*8)] %asi, %l4
- htog(0xeadba827), //ldxa [%sp + BIAS + (5*8)] %asi, %l5
- htog(0xecdba82f), //ldxa [%sp + BIAS + (6*8)] %asi, %l6
- htog(0xeedba837), //ldxa [%sp + BIAS + (7*8)] %asi, %l7
- htog(0xf0dba83f), //ldxa [%sp + BIAS + (8*8)] %asi, %i0
- htog(0xf2dba847), //ldxa [%sp + BIAS + (9*8)] %asi, %i1
- htog(0xf4dba84f), //ldxa [%sp + BIAS + (10*8)] %asi, %i2
- htog(0xf6dba857), //ldxa [%sp + BIAS + (11*8)] %asi, %i3
- htog(0xf8dba85f), //ldxa [%sp + BIAS + (12*8)] %asi, %i4
- htog(0xfadba867), //ldxa [%sp + BIAS + (13*8)] %asi, %i5
- htog(0xfcdba86f), //ldxa [%sp + BIAS + (14*8)] %asi, %i6
- htog(0xfedba877), //ldxa [%sp + BIAS + (15*8)] %asi, %i7
- htog(0x83880000), //restored
- htog(0x83F00000), //retry
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000) //illtrap
-};
-
-MachInst spillHandler[numSpillInsts] =
+ a_type = TheISA::htog(type);
+ a_val = TheISA::htog(val);
+}
+
+M5_64_auxv_t::M5_64_auxv_t(int64_t type, int64_t val)
{
- htog(0x87802018), //wr %g0, ASI_AIUP, %asi
- htog(0xe0f3a7ff), //stxa %l0, [%sp + BIAS + (0*8)] %asi
- htog(0xe2f3a807), //stxa %l1, [%sp + BIAS + (1*8)] %asi
- htog(0xe4f3a80f), //stxa %l2, [%sp + BIAS + (2*8)] %asi
- htog(0xe6f3a817), //stxa %l3, [%sp + BIAS + (3*8)] %asi
- htog(0xe8f3a81f), //stxa %l4, [%sp + BIAS + (4*8)] %asi
- htog(0xeaf3a827), //stxa %l5, [%sp + BIAS + (5*8)] %asi
- htog(0xecf3a82f), //stxa %l6, [%sp + BIAS + (6*8)] %asi
- htog(0xeef3a837), //stxa %l7, [%sp + BIAS + (7*8)] %asi
- htog(0xf0f3a83f), //stxa %i0, [%sp + BIAS + (8*8)] %asi
- htog(0xf2f3a847), //stxa %i1, [%sp + BIAS + (9*8)] %asi
- htog(0xf4f3a84f), //stxa %i2, [%sp + BIAS + (10*8)] %asi
- htog(0xf6f3a857), //stxa %i3, [%sp + BIAS + (11*8)] %asi
- htog(0xf8f3a85f), //stxa %i4, [%sp + BIAS + (12*8)] %asi
- htog(0xfaf3a867), //stxa %i5, [%sp + BIAS + (13*8)] %asi
- htog(0xfcf3a86f), //stxa %i6, [%sp + BIAS + (14*8)] %asi
- htog(0xfef3a877), //stxa %i7, [%sp + BIAS + (15*8)] %asi
- htog(0x81880000), //saved
- htog(0x83F00000), //retry
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000), //illtrap
- htog(0x00000000) //illtrap
-};
+ a_type = TheISA::htog(type);
+ a_val = TheISA::htog(val);
+}
void
-SparcLiveProcess::argsInit(int intSize, int pageSize)
+Sparc64LiveProcess::argsInit(int intSize, int pageSize)
{
+ typedef M5_64_auxv_t auxv_t;
Process::startup();
string filename;
@@ -265,34 +240,34 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
if(elfObject)
{
//Bits which describe the system hardware capabilities
- auxv.push_back(buildAuxVect(SPARC_AT_HWCAP, hwcap));
+ auxv.push_back(auxv_t(SPARC_AT_HWCAP, hwcap));
//The system page size
- auxv.push_back(buildAuxVect(SPARC_AT_PAGESZ, SparcISA::VMPageSize));
+ auxv.push_back(auxv_t(SPARC_AT_PAGESZ, SparcISA::VMPageSize));
//Defined to be 100 in the kernel source.
//Frequency at which times() increments
- auxv.push_back(buildAuxVect(SPARC_AT_CLKTCK, 100));
+ auxv.push_back(auxv_t(SPARC_AT_CLKTCK, 100));
// For statically linked executables, this is the virtual address of the
// program header tables if they appear in the executable image
- auxv.push_back(buildAuxVect(SPARC_AT_PHDR, elfObject->programHeaderTable()));
+ auxv.push_back(auxv_t(SPARC_AT_PHDR, elfObject->programHeaderTable()));
// This is the size of a program header entry from the elf file.
- auxv.push_back(buildAuxVect(SPARC_AT_PHENT, elfObject->programHeaderSize()));
+ auxv.push_back(auxv_t(SPARC_AT_PHENT, elfObject->programHeaderSize()));
// This is the number of program headers from the original elf file.
- auxv.push_back(buildAuxVect(SPARC_AT_PHNUM, elfObject->programHeaderCount()));
+ auxv.push_back(auxv_t(SPARC_AT_PHNUM, elfObject->programHeaderCount()));
//This is the address of the elf "interpreter", It should be set
//to 0 for regular executables. It should be something else
//(not sure what) for dynamic libraries.
- auxv.push_back(buildAuxVect(SPARC_AT_BASE, 0));
+ auxv.push_back(auxv_t(SPARC_AT_BASE, 0));
//This is hardwired to 0 in the elf loading code in the kernel
- auxv.push_back(buildAuxVect(SPARC_AT_FLAGS, 0));
+ auxv.push_back(auxv_t(SPARC_AT_FLAGS, 0));
//The entry point to the program
- auxv.push_back(buildAuxVect(SPARC_AT_ENTRY, objFile->entryPoint()));
+ auxv.push_back(auxv_t(SPARC_AT_ENTRY, objFile->entryPoint()));
//Different user and group IDs
- auxv.push_back(buildAuxVect(SPARC_AT_UID, uid()));
- auxv.push_back(buildAuxVect(SPARC_AT_EUID, euid()));
- auxv.push_back(buildAuxVect(SPARC_AT_GID, gid()));
- auxv.push_back(buildAuxVect(SPARC_AT_EGID, egid()));
+ auxv.push_back(auxv_t(SPARC_AT_UID, uid()));
+ auxv.push_back(auxv_t(SPARC_AT_EUID, euid()));
+ auxv.push_back(auxv_t(SPARC_AT_GID, gid()));
+ auxv.push_back(auxv_t(SPARC_AT_EGID, egid()));
//Whether to enable "secure mode" in the executable
- auxv.push_back(buildAuxVect(SPARC_AT_SECURE, 0));
+ auxv.push_back(auxv_t(SPARC_AT_SECURE, 0));
}
//Figure out how big the initial stack needs to be
@@ -419,8 +394,8 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
int spillSize = sizeof(MachInst) * numSpillInsts;
fillStart = stack_base;
spillStart = fillStart + fillSize;
- initVirtMem->writeBlob(fillStart, (uint8_t*)fillHandler, fillSize);
- initVirtMem->writeBlob(spillStart, (uint8_t*)spillHandler, spillSize);
+ initVirtMem->writeBlob(fillStart, (uint8_t*)fillHandler64, fillSize);
+ initVirtMem->writeBlob(spillStart, (uint8_t*)spillHandler64, spillSize);
//Set up the thread context to start running the process
threadContexts[0]->setIntReg(ArgumentReg0, argc);
@@ -437,3 +412,231 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
// num_processes++;
}
+
+void
+Sparc32LiveProcess::argsInit(int intSize, int pageSize)
+{
+ typedef M5_32_auxv_t auxv_t;
+ Process::startup();
+
+ string filename;
+ if(argv.size() < 1)
+ filename = "";
+ else
+ filename = argv[0];
+
+ //Even though this is a 32 bit process, the ABI says we still need to
+ //maintain double word alignment of the stack pointer.
+ Addr alignmentMask = ~(8 - 1);
+
+ // load object file into target memory
+ objFile->loadSections(initVirtMem);
+
+ //These are the auxilliary vector types
+ enum auxTypes
+ {
+ SPARC_AT_HWCAP = 16,
+ SPARC_AT_PAGESZ = 6,
+ SPARC_AT_CLKTCK = 17,
+ SPARC_AT_PHDR = 3,
+ SPARC_AT_PHENT = 4,
+ SPARC_AT_PHNUM = 5,
+ SPARC_AT_BASE = 7,
+ SPARC_AT_FLAGS = 8,
+ SPARC_AT_ENTRY = 9,
+ SPARC_AT_UID = 11,
+ SPARC_AT_EUID = 12,
+ SPARC_AT_GID = 13,
+ SPARC_AT_EGID = 14,
+ SPARC_AT_SECURE = 23
+ };
+
+ enum hardwareCaps
+ {
+ M5_HWCAP_SPARC_FLUSH = 1,
+ M5_HWCAP_SPARC_STBAR = 2,
+ M5_HWCAP_SPARC_SWAP = 4,
+ M5_HWCAP_SPARC_MULDIV = 8,
+ M5_HWCAP_SPARC_V9 = 16,
+ //This one should technically only be set
+ //if there is a cheetah or cheetah_plus tlb,
+ //but we'll use it all the time
+ M5_HWCAP_SPARC_ULTRA3 = 32
+ };
+
+ const int64_t hwcap =
+ M5_HWCAP_SPARC_FLUSH |
+ M5_HWCAP_SPARC_STBAR |
+ M5_HWCAP_SPARC_SWAP |
+ M5_HWCAP_SPARC_MULDIV |
+ M5_HWCAP_SPARC_V9 |
+ M5_HWCAP_SPARC_ULTRA3;
+
+
+ //Setup the auxilliary vectors. These will already have endian conversion.
+ //Auxilliary vectors are loaded only for elf formatted executables.
+ ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
+ if(elfObject)
+ {
+ //Bits which describe the system hardware capabilities
+ auxv.push_back(auxv_t(SPARC_AT_HWCAP, hwcap));
+ //The system page size
+ auxv.push_back(auxv_t(SPARC_AT_PAGESZ, SparcISA::VMPageSize));
+ //Defined to be 100 in the kernel source.
+ //Frequency at which times() increments
+ auxv.push_back(auxv_t(SPARC_AT_CLKTCK, 100));
+ // For statically linked executables, this is the virtual address of the
+ // program header tables if they appear in the executable image
+ auxv.push_back(auxv_t(SPARC_AT_PHDR, elfObject->programHeaderTable()));
+ // This is the size of a program header entry from the elf file.
+ auxv.push_back(auxv_t(SPARC_AT_PHENT, elfObject->programHeaderSize()));
+ // This is the number of program headers from the original elf file.
+ auxv.push_back(auxv_t(SPARC_AT_PHNUM, elfObject->programHeaderCount()));
+ //This is the address of the elf "interpreter", It should be set
+ //to 0 for regular executables. It should be something else
+ //(not sure what) for dynamic libraries.
+ auxv.push_back(auxv_t(SPARC_AT_BASE, 0));
+ //This is hardwired to 0 in the elf loading code in the kernel
+ auxv.push_back(auxv_t(SPARC_AT_FLAGS, 0));
+ //The entry point to the program
+ auxv.push_back(auxv_t(SPARC_AT_ENTRY, objFile->entryPoint()));
+ //Different user and group IDs
+ auxv.push_back(auxv_t(SPARC_AT_UID, uid()));
+ auxv.push_back(auxv_t(SPARC_AT_EUID, euid()));
+ auxv.push_back(auxv_t(SPARC_AT_GID, gid()));
+ auxv.push_back(auxv_t(SPARC_AT_EGID, egid()));
+ //Whether to enable "secure mode" in the executable
+ auxv.push_back(auxv_t(SPARC_AT_SECURE, 0));
+ }
+
+ //Figure out how big the initial stack needs to be
+
+ // The unaccounted for 8 byte 0 at the top of the stack
+ int mysterious_size = 8;
+
+ //This is the name of the file which is present on the initial stack
+ //It's purpose is to let the user space linker examine the original file.
+ int file_name_size = filename.size() + 1;
+
+ int env_data_size = 0;
+ for (int i = 0; i < envp.size(); ++i) {
+ env_data_size += envp[i].size() + 1;
+ }
+ int arg_data_size = 0;
+ for (int i = 0; i < argv.size(); ++i) {
+ arg_data_size += argv[i].size() + 1;
+ }
+
+ //The info_block - This seems to need an pad for some reason.
+ int info_block_size =
+ (mysterious_size +
+ file_name_size +
+ env_data_size +
+ arg_data_size + intSize);
+
+ //Each auxilliary vector is two 4 byte words
+ int aux_array_size = intSize * 2 * (auxv.size() + 1);
+
+ int envp_array_size = intSize * (envp.size() + 1);
+ int argv_array_size = intSize * (argv.size() + 1);
+
+ int argc_size = intSize;
+ int window_save_size = intSize * 16;
+
+ int space_needed =
+ info_block_size +
+ aux_array_size +
+ envp_array_size +
+ argv_array_size +
+ argc_size +
+ window_save_size;
+
+ stack_min = stack_base - space_needed;
+ stack_min &= alignmentMask;
+ stack_size = stack_base - stack_min;
+
+ // map memory
+ pTable->allocate(roundDown(stack_min, pageSize),
+ roundUp(stack_size, pageSize));
+
+ // map out initial stack contents
+ uint32_t window_save_base = stack_min;
+ uint32_t argc_base = window_save_base + window_save_size;
+ uint32_t argv_array_base = argc_base + argc_size;
+ uint32_t envp_array_base = argv_array_base + argv_array_size;
+ uint32_t auxv_array_base = envp_array_base + envp_array_size;
+ //The info block is pushed up against the top of the stack, while
+ //the rest of the initial stack frame is aligned to an 8 byte boudary.
+ uint32_t arg_data_base = stack_base - info_block_size + intSize;
+ uint32_t env_data_base = arg_data_base + arg_data_size;
+ uint32_t file_name_base = env_data_base + env_data_size;
+ uint32_t mysterious_base = file_name_base + file_name_size;
+
+ DPRINTF(Sparc, "The addresses of items on the initial stack:\n");
+ DPRINTF(Sparc, "0x%x - file name\n", file_name_base);
+ DPRINTF(Sparc, "0x%x - env data\n", env_data_base);
+ DPRINTF(Sparc, "0x%x - arg data\n", arg_data_base);
+ DPRINTF(Sparc, "0x%x - auxv array\n", auxv_array_base);
+ DPRINTF(Sparc, "0x%x - envp array\n", envp_array_base);
+ DPRINTF(Sparc, "0x%x - argv array\n", argv_array_base);
+ DPRINTF(Sparc, "0x%x - argc \n", argc_base);
+ DPRINTF(Sparc, "0x%x - window save\n", window_save_base);
+ DPRINTF(Sparc, "0x%x - stack min\n", stack_min);
+
+ // write contents to stack
+
+ // figure out argc
+ uint32_t argc = argv.size();
+ uint32_t guestArgc = TheISA::htog(argc);
+
+ //Write out the mysterious 0
+ uint64_t mysterious_zero = 0;
+ initVirtMem->writeBlob(mysterious_base,
+ (uint8_t*)&mysterious_zero, mysterious_size);
+
+ //Write the file name
+ initVirtMem->writeString(file_name_base, filename.c_str());
+
+ //Copy the aux stuff
+ for(int x = 0; x < auxv.size(); x++)
+ {
+ initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize,
+ (uint8_t*)&(auxv[x].a_type), intSize);
+ initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
+ (uint8_t*)&(auxv[x].a_val), intSize);
+ }
+ //Write out the terminating zeroed auxilliary vector
+ const uint64_t zero = 0;
+ initVirtMem->writeBlob(auxv_array_base + 2 * intSize * auxv.size(),
+ (uint8_t*)&zero, 2 * intSize);
+
+ copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
+ copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
+
+ initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
+
+ //Stuff the trap handlers into the processes address space.
+ //Since the stack grows down and is the highest area in the processes
+ //address space, we can put stuff above it and stay out of the way.
+ int fillSize = sizeof(MachInst) * numFillInsts;
+ int spillSize = sizeof(MachInst) * numSpillInsts;
+ fillStart = stack_base;
+ spillStart = fillStart + fillSize;
+ initVirtMem->writeBlob(fillStart, (uint8_t*)fillHandler32, fillSize);
+ initVirtMem->writeBlob(spillStart, (uint8_t*)spillHandler32, spillSize);
+
+ //Set up the thread context to start running the process
+ //threadContexts[0]->setIntReg(ArgumentReg0, argc);
+ //threadContexts[0]->setIntReg(ArgumentReg1, argv_array_base);
+ threadContexts[0]->setIntReg(StackPointerReg, stack_min);
+
+ uint32_t prog_entry = objFile->entryPoint();
+ threadContexts[0]->setPC(prog_entry);
+ threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
+ threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
+
+ //Align the "stack_min" to a page boundary.
+ stack_min = roundDown(stack_min, pageSize);
+
+// num_processes++;
+}
diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh
index 1cf7ec224..2512441c6 100644
--- a/src/arch/sparc/process.hh
+++ b/src/arch/sparc/process.hh
@@ -39,27 +39,13 @@
class ObjectFile;
class System;
-typedef struct
-{
- int64_t a_type;
- union {
- int64_t a_val;
- Addr a_ptr;
- Addr a_fcn;
- };
-} m5_auxv_t;
-
class SparcLiveProcess : public LiveProcess
{
protected:
- static const Addr StackBias = 2047;
-
//The locations of the fill and spill handlers
Addr fillStart, spillStart;
- std::vector<m5_auxv_t> auxv;
-
SparcLiveProcess(const std::string &nm, ObjectFile *objFile,
System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
std::vector<std::string> &argv,
@@ -69,11 +55,10 @@ class SparcLiveProcess : public LiveProcess
uint64_t _gid, uint64_t _egid,
uint64_t _pid, uint64_t _ppid);
- void startup();
-
public:
- void argsInit(int intSize, int pageSize);
+ //Handles traps which request services from the operating system
+ virtual void handleTrap(int trapNum, ThreadContext *tc);
Addr readFillStart()
{ return fillStart; }
@@ -83,4 +68,107 @@ class SparcLiveProcess : public LiveProcess
};
+struct M5_32_auxv_t
+{
+ int32_t a_type;
+ union {
+ int32_t a_val;
+ int32_t a_ptr;
+ int32_t a_fcn;
+ };
+
+ M5_32_auxv_t()
+ {}
+
+ M5_32_auxv_t(int32_t type, int32_t val);
+};
+
+class Sparc32LiveProcess : public SparcLiveProcess
+{
+ protected:
+
+ std::vector<M5_32_auxv_t> auxv;
+
+ Sparc32LiveProcess(const std::string &nm, ObjectFile *objFile,
+ System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp,
+ const std::string &cwd,
+ uint64_t _uid, uint64_t _euid,
+ uint64_t _gid, uint64_t _egid,
+ uint64_t _pid, uint64_t _ppid) :
+ SparcLiveProcess(nm, objFile, _system,
+ stdin_fd, stdout_fd, stderr_fd,
+ argv, envp, cwd,
+ _uid, _euid, _gid, _egid, _pid, _ppid)
+ {
+ // Set up stack. On SPARC Linux, stack goes from the top of memory
+ // downward, less the hole for the kernel address space.
+ stack_base = (Addr)0xf0000000ULL;
+
+ // Set up region for mmaps.
+ mmap_start = mmap_end = 0x70000000;
+ }
+
+ void startup();
+
+ public:
+
+ void argsInit(int intSize, int pageSize);
+
+};
+
+struct M5_64_auxv_t
+{
+ int64_t a_type;
+ union {
+ int64_t a_val;
+ int64_t a_ptr;
+ int64_t a_fcn;
+ };
+
+ M5_64_auxv_t()
+ {}
+
+ M5_64_auxv_t(int64_t type, int64_t val);
+};
+
+class Sparc64LiveProcess : public SparcLiveProcess
+{
+ protected:
+
+ static const Addr StackBias = 2047;
+
+ std::vector<M5_64_auxv_t> auxv;
+
+ Sparc64LiveProcess(const std::string &nm, ObjectFile *objFile,
+ System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp,
+ const std::string &cwd,
+ uint64_t _uid, uint64_t _euid,
+ uint64_t _gid, uint64_t _egid,
+ uint64_t _pid, uint64_t _ppid) :
+ SparcLiveProcess(nm, objFile, _system,
+ stdin_fd, stdout_fd, stderr_fd,
+ argv, envp, cwd,
+ _uid, _euid, _gid, _egid, _pid, _ppid)
+ {
+ // Set up stack. On SPARC Linux, stack goes from the top of memory
+ // downward, less the hole for the kernel address space.
+ stack_base = (Addr)0x80000000000ULL;
+
+ // Set up region for mmaps. Tru64 seems to start just above 0 and
+ // grow up from there.
+ mmap_start = mmap_end = 0xfffff80000000000ULL;
+ }
+
+ void startup();
+
+ public:
+
+ void argsInit(int intSize, int pageSize);
+
+};
+
#endif // __SPARC_PROCESS_HH__
diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc
index 827e22c31..667b1f002 100644
--- a/src/arch/sparc/regfile.cc
+++ b/src/arch/sparc/regfile.cc
@@ -75,25 +75,25 @@ void RegFile::clear()
miscRegFile.clear();
}
-MiscReg RegFile::readMiscReg(int miscReg)
+MiscReg RegFile::readMiscRegNoEffect(int miscReg)
{
- return miscRegFile.readReg(miscReg);
+ return miscRegFile.readRegNoEffect(miscReg);
}
-MiscReg RegFile::readMiscRegWithEffect(int miscReg, ThreadContext *tc)
+MiscReg RegFile::readMiscReg(int miscReg, ThreadContext *tc)
{
- return miscRegFile.readRegWithEffect(miscReg, tc);
+ return miscRegFile.readReg(miscReg, tc);
}
-void RegFile::setMiscReg(int miscReg, const MiscReg &val)
+void RegFile::setMiscRegNoEffect(int miscReg, const MiscReg &val)
{
- miscRegFile.setReg(miscReg, val);
+ miscRegFile.setRegNoEffect(miscReg, val);
}
-void RegFile::setMiscRegWithEffect(int miscReg, const MiscReg &val,
+void RegFile::setMiscReg(int miscReg, const MiscReg &val,
ThreadContext * tc)
{
- miscRegFile.setRegWithEffect(miscReg, val, tc);
+ miscRegFile.setReg(miscReg, val, tc);
}
FloatReg RegFile::readFloatReg(int floatReg, int width)
@@ -153,8 +153,8 @@ void RegFile::setIntReg(int intReg, const IntReg &val)
int SparcISA::flattenIntIndex(ThreadContext * tc, int reg)
{
- int gl = tc->readMiscReg(MISCREG_GL);
- int cwp = tc->readMiscReg(MISCREG_CWP);
+ int gl = tc->readMiscRegNoEffect(MISCREG_GL);
+ int cwp = tc->readMiscRegNoEffect(MISCREG_CWP);
//DPRINTF(Sparc, "Global Level = %d, Current Window Pointer = %d\n", gl, cwp);
int newReg;
//The total number of global registers
@@ -254,162 +254,149 @@ void RegFile::changeContext(RegContextParam param, RegContextVal val)
}
}
-int SparcISA::InterruptLevel(uint64_t softint)
-{
- if (softint & 0x10000 || softint & 0x1)
- return 14;
-
- int level = 15;
- while (level > 0 && !(1 << level & softint))
- level--;
- if (1 << level & softint)
- return level;
- return 0;
-}
-
void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
{
- uint8_t tl = src->readMiscReg(MISCREG_TL);
+ uint8_t tl = src->readMiscRegNoEffect(MISCREG_TL);
// Read all the trap level dependent registers and save them off
for(int i = 1; i <= MaxTL; i++)
{
- src->setMiscReg(MISCREG_TL, i);
- dest->setMiscReg(MISCREG_TL, i);
+ src->setMiscRegNoEffect(MISCREG_TL, i);
+ dest->setMiscRegNoEffect(MISCREG_TL, i);
- dest->setMiscReg(MISCREG_TT, src->readMiscReg(MISCREG_TT));
- dest->setMiscReg(MISCREG_TPC, src->readMiscReg(MISCREG_TPC));
- dest->setMiscReg(MISCREG_TNPC, src->readMiscReg(MISCREG_TNPC));
- dest->setMiscReg(MISCREG_TSTATE, src->readMiscReg(MISCREG_TSTATE));
+ dest->setMiscRegNoEffect(MISCREG_TT, src->readMiscRegNoEffect(MISCREG_TT));
+ dest->setMiscRegNoEffect(MISCREG_TPC, src->readMiscRegNoEffect(MISCREG_TPC));
+ dest->setMiscRegNoEffect(MISCREG_TNPC, src->readMiscRegNoEffect(MISCREG_TNPC));
+ dest->setMiscRegNoEffect(MISCREG_TSTATE, src->readMiscRegNoEffect(MISCREG_TSTATE));
}
// Save off the traplevel
- dest->setMiscReg(MISCREG_TL, tl);
- src->setMiscReg(MISCREG_TL, tl);
+ dest->setMiscRegNoEffect(MISCREG_TL, tl);
+ src->setMiscRegNoEffect(MISCREG_TL, tl);
// ASRs
-// dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y));
-// dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR));
- dest->setMiscReg(MISCREG_ASI, src->readMiscReg(MISCREG_ASI));
- dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK));
- dest->setMiscReg(MISCREG_FPRS, src->readMiscReg(MISCREG_FPRS));
- dest->setMiscReg(MISCREG_SOFTINT, src->readMiscReg(MISCREG_SOFTINT));
- dest->setMiscReg(MISCREG_TICK_CMPR, src->readMiscReg(MISCREG_TICK_CMPR));
- dest->setMiscReg(MISCREG_STICK, src->readMiscReg(MISCREG_STICK));
- dest->setMiscReg(MISCREG_STICK_CMPR, src->readMiscReg(MISCREG_STICK_CMPR));
+// dest->setMiscRegNoEffect(MISCREG_Y, src->readMiscRegNoEffect(MISCREG_Y));
+// dest->setMiscRegNoEffect(MISCREG_CCR, src->readMiscRegNoEffect(MISCREG_CCR));
+ dest->setMiscRegNoEffect(MISCREG_ASI, src->readMiscRegNoEffect(MISCREG_ASI));
+ dest->setMiscRegNoEffect(MISCREG_TICK, src->readMiscRegNoEffect(MISCREG_TICK));
+ dest->setMiscRegNoEffect(MISCREG_FPRS, src->readMiscRegNoEffect(MISCREG_FPRS));
+ dest->setMiscRegNoEffect(MISCREG_SOFTINT, src->readMiscRegNoEffect(MISCREG_SOFTINT));
+ dest->setMiscRegNoEffect(MISCREG_TICK_CMPR, src->readMiscRegNoEffect(MISCREG_TICK_CMPR));
+ dest->setMiscRegNoEffect(MISCREG_STICK, src->readMiscRegNoEffect(MISCREG_STICK));
+ dest->setMiscRegNoEffect(MISCREG_STICK_CMPR, src->readMiscRegNoEffect(MISCREG_STICK_CMPR));
// Priv Registers
- dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK));
- dest->setMiscReg(MISCREG_TBA, src->readMiscReg(MISCREG_TBA));
- dest->setMiscReg(MISCREG_PSTATE, src->readMiscReg(MISCREG_PSTATE));
- dest->setMiscReg(MISCREG_PIL, src->readMiscReg(MISCREG_PIL));
- dest->setMiscReg(MISCREG_CWP, src->readMiscReg(MISCREG_CWP));
-// dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE));
-// dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE));
-// dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN));
-// dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN));
-// dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE));
- dest->setMiscReg(MISCREG_GL, src->readMiscReg(MISCREG_GL));
+ dest->setMiscRegNoEffect(MISCREG_TICK, src->readMiscRegNoEffect(MISCREG_TICK));
+ dest->setMiscRegNoEffect(MISCREG_TBA, src->readMiscRegNoEffect(MISCREG_TBA));
+ dest->setMiscRegNoEffect(MISCREG_PSTATE, src->readMiscRegNoEffect(MISCREG_PSTATE));
+ dest->setMiscRegNoEffect(MISCREG_PIL, src->readMiscRegNoEffect(MISCREG_PIL));
+ dest->setMiscRegNoEffect(MISCREG_CWP, src->readMiscRegNoEffect(MISCREG_CWP));
+// dest->setMiscRegNoEffect(MISCREG_CANSAVE, src->readMiscRegNoEffect(MISCREG_CANSAVE));
+// dest->setMiscRegNoEffect(MISCREG_CANRESTORE, src->readMiscRegNoEffect(MISCREG_CANRESTORE));
+// dest->setMiscRegNoEffect(MISCREG_OTHERWIN, src->readMiscRegNoEffect(MISCREG_OTHERWIN));
+// dest->setMiscRegNoEffect(MISCREG_CLEANWIN, src->readMiscRegNoEffect(MISCREG_CLEANWIN));
+// dest->setMiscRegNoEffect(MISCREG_WSTATE, src->readMiscRegNoEffect(MISCREG_WSTATE));
+ dest->setMiscRegNoEffect(MISCREG_GL, src->readMiscRegNoEffect(MISCREG_GL));
// Hyperprivilged registers
- dest->setMiscReg(MISCREG_HPSTATE, src->readMiscReg(MISCREG_HPSTATE));
- dest->setMiscReg(MISCREG_HINTP, src->readMiscReg(MISCREG_HINTP));
- dest->setMiscReg(MISCREG_HTBA, src->readMiscReg(MISCREG_HTBA));
- dest->setMiscReg(MISCREG_STRAND_STS_REG,
- src->readMiscReg(MISCREG_STRAND_STS_REG));
- dest->setMiscReg(MISCREG_HSTICK_CMPR,
- src->readMiscReg(MISCREG_HSTICK_CMPR));
+ dest->setMiscRegNoEffect(MISCREG_HPSTATE, src->readMiscRegNoEffect(MISCREG_HPSTATE));
+ dest->setMiscRegNoEffect(MISCREG_HINTP, src->readMiscRegNoEffect(MISCREG_HINTP));
+ dest->setMiscRegNoEffect(MISCREG_HTBA, src->readMiscRegNoEffect(MISCREG_HTBA));
+ dest->setMiscRegNoEffect(MISCREG_STRAND_STS_REG,
+ src->readMiscRegNoEffect(MISCREG_STRAND_STS_REG));
+ dest->setMiscRegNoEffect(MISCREG_HSTICK_CMPR,
+ src->readMiscRegNoEffect(MISCREG_HSTICK_CMPR));
// FSR
- dest->setMiscReg(MISCREG_FSR, src->readMiscReg(MISCREG_FSR));
+ dest->setMiscRegNoEffect(MISCREG_FSR, src->readMiscRegNoEffect(MISCREG_FSR));
//Strand Status Register
- dest->setMiscReg(MISCREG_STRAND_STS_REG,
- src->readMiscReg(MISCREG_STRAND_STS_REG));
+ dest->setMiscRegNoEffect(MISCREG_STRAND_STS_REG,
+ src->readMiscRegNoEffect(MISCREG_STRAND_STS_REG));
// MMU Registers
- dest->setMiscReg(MISCREG_MMU_P_CONTEXT,
- src->readMiscReg(MISCREG_MMU_P_CONTEXT));
- dest->setMiscReg(MISCREG_MMU_S_CONTEXT,
- src->readMiscReg(MISCREG_MMU_S_CONTEXT));
- dest->setMiscReg(MISCREG_MMU_PART_ID,
- src->readMiscReg(MISCREG_MMU_PART_ID));
- dest->setMiscReg(MISCREG_MMU_LSU_CTRL,
- src->readMiscReg(MISCREG_MMU_LSU_CTRL));
-
- dest->setMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0,
- src->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0));
- dest->setMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1,
- src->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1));
- dest->setMiscReg(MISCREG_MMU_ITLB_C0_CONFIG,
- src->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG));
- dest->setMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0,
- src->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0));
- dest->setMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1,
- src->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1));
- dest->setMiscReg(MISCREG_MMU_ITLB_CX_CONFIG,
- src->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG));
- dest->setMiscReg(MISCREG_MMU_ITLB_SFSR,
- src->readMiscReg(MISCREG_MMU_ITLB_SFSR));
- dest->setMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS,
- src->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS));
-
- dest->setMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0,
- src->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0));
- dest->setMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1,
- src->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1));
- dest->setMiscReg(MISCREG_MMU_DTLB_C0_CONFIG,
- src->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG));
- dest->setMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0,
- src->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0));
- dest->setMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1,
- src->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1));
- dest->setMiscReg(MISCREG_MMU_DTLB_CX_CONFIG,
- src->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG));
- dest->setMiscReg(MISCREG_MMU_DTLB_SFSR,
- src->readMiscReg(MISCREG_MMU_DTLB_SFSR));
- dest->setMiscReg(MISCREG_MMU_DTLB_SFAR,
- src->readMiscReg(MISCREG_MMU_DTLB_SFAR));
- dest->setMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS,
- src->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS));
+ dest->setMiscRegNoEffect(MISCREG_MMU_P_CONTEXT,
+ src->readMiscRegNoEffect(MISCREG_MMU_P_CONTEXT));
+ dest->setMiscRegNoEffect(MISCREG_MMU_S_CONTEXT,
+ src->readMiscRegNoEffect(MISCREG_MMU_S_CONTEXT));
+ dest->setMiscRegNoEffect(MISCREG_MMU_PART_ID,
+ src->readMiscRegNoEffect(MISCREG_MMU_PART_ID));
+ dest->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL,
+ src->readMiscRegNoEffect(MISCREG_MMU_LSU_CTRL));
+
+ dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_C0_TSB_PS0,
+ src->readMiscRegNoEffect(MISCREG_MMU_ITLB_C0_TSB_PS0));
+ dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_C0_TSB_PS1,
+ src->readMiscRegNoEffect(MISCREG_MMU_ITLB_C0_TSB_PS1));
+ dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_C0_CONFIG,
+ src->readMiscRegNoEffect(MISCREG_MMU_ITLB_C0_CONFIG));
+ dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_CX_TSB_PS0,
+ src->readMiscRegNoEffect(MISCREG_MMU_ITLB_CX_TSB_PS0));
+ dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_CX_TSB_PS1,
+ src->readMiscRegNoEffect(MISCREG_MMU_ITLB_CX_TSB_PS1));
+ dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_CX_CONFIG,
+ src->readMiscRegNoEffect(MISCREG_MMU_ITLB_CX_CONFIG));
+ dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_SFSR,
+ src->readMiscRegNoEffect(MISCREG_MMU_ITLB_SFSR));
+ dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_TAG_ACCESS,
+ src->readMiscRegNoEffect(MISCREG_MMU_ITLB_TAG_ACCESS));
+
+ dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_C0_TSB_PS0,
+ src->readMiscRegNoEffect(MISCREG_MMU_DTLB_C0_TSB_PS0));
+ dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_C0_TSB_PS1,
+ src->readMiscRegNoEffect(MISCREG_MMU_DTLB_C0_TSB_PS1));
+ dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_C0_CONFIG,
+ src->readMiscRegNoEffect(MISCREG_MMU_DTLB_C0_CONFIG));
+ dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_CX_TSB_PS0,
+ src->readMiscRegNoEffect(MISCREG_MMU_DTLB_CX_TSB_PS0));
+ dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_CX_TSB_PS1,
+ src->readMiscRegNoEffect(MISCREG_MMU_DTLB_CX_TSB_PS1));
+ dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_CX_CONFIG,
+ src->readMiscRegNoEffect(MISCREG_MMU_DTLB_CX_CONFIG));
+ dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_SFSR,
+ src->readMiscRegNoEffect(MISCREG_MMU_DTLB_SFSR));
+ dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_SFAR,
+ src->readMiscRegNoEffect(MISCREG_MMU_DTLB_SFAR));
+ dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_TAG_ACCESS,
+ src->readMiscRegNoEffect(MISCREG_MMU_DTLB_TAG_ACCESS));
// Scratchpad Registers
- dest->setMiscReg(MISCREG_SCRATCHPAD_R0,
- src->readMiscReg(MISCREG_SCRATCHPAD_R0));
- dest->setMiscReg(MISCREG_SCRATCHPAD_R1,
- src->readMiscReg(MISCREG_SCRATCHPAD_R1));
- dest->setMiscReg(MISCREG_SCRATCHPAD_R2,
- src->readMiscReg(MISCREG_SCRATCHPAD_R2));
- dest->setMiscReg(MISCREG_SCRATCHPAD_R3,
- src->readMiscReg(MISCREG_SCRATCHPAD_R3));
- dest->setMiscReg(MISCREG_SCRATCHPAD_R4,
- src->readMiscReg(MISCREG_SCRATCHPAD_R4));
- dest->setMiscReg(MISCREG_SCRATCHPAD_R5,
- src->readMiscReg(MISCREG_SCRATCHPAD_R5));
- dest->setMiscReg(MISCREG_SCRATCHPAD_R6,
- src->readMiscReg(MISCREG_SCRATCHPAD_R6));
- dest->setMiscReg(MISCREG_SCRATCHPAD_R7,
- src->readMiscReg(MISCREG_SCRATCHPAD_R7));
+ dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R0,
+ src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R0));
+ dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R1,
+ src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R1));
+ dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R2,
+ src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R2));
+ dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R3,
+ src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R3));
+ dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R4,
+ src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R4));
+ dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R5,
+ src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R5));
+ dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R6,
+ src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R6));
+ dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R7,
+ src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R7));
// Queue Registers
- dest->setMiscReg(MISCREG_QUEUE_CPU_MONDO_HEAD,
- src->readMiscReg(MISCREG_QUEUE_CPU_MONDO_HEAD));
- dest->setMiscReg(MISCREG_QUEUE_CPU_MONDO_TAIL,
- src->readMiscReg(MISCREG_QUEUE_CPU_MONDO_TAIL));
- dest->setMiscReg(MISCREG_QUEUE_DEV_MONDO_HEAD,
- src->readMiscReg(MISCREG_QUEUE_DEV_MONDO_HEAD));
- dest->setMiscReg(MISCREG_QUEUE_DEV_MONDO_TAIL,
- src->readMiscReg(MISCREG_QUEUE_DEV_MONDO_TAIL));
- dest->setMiscReg(MISCREG_QUEUE_RES_ERROR_HEAD,
- src->readMiscReg(MISCREG_QUEUE_RES_ERROR_HEAD));
- dest->setMiscReg(MISCREG_QUEUE_RES_ERROR_TAIL,
- src->readMiscReg(MISCREG_QUEUE_RES_ERROR_TAIL));
- dest->setMiscReg(MISCREG_QUEUE_NRES_ERROR_HEAD,
- src->readMiscReg(MISCREG_QUEUE_NRES_ERROR_HEAD));
- dest->setMiscReg(MISCREG_QUEUE_NRES_ERROR_TAIL,
- src->readMiscReg(MISCREG_QUEUE_NRES_ERROR_TAIL));
+ dest->setMiscRegNoEffect(MISCREG_QUEUE_CPU_MONDO_HEAD,
+ src->readMiscRegNoEffect(MISCREG_QUEUE_CPU_MONDO_HEAD));
+ dest->setMiscRegNoEffect(MISCREG_QUEUE_CPU_MONDO_TAIL,
+ src->readMiscRegNoEffect(MISCREG_QUEUE_CPU_MONDO_TAIL));
+ dest->setMiscRegNoEffect(MISCREG_QUEUE_DEV_MONDO_HEAD,
+ src->readMiscRegNoEffect(MISCREG_QUEUE_DEV_MONDO_HEAD));
+ dest->setMiscRegNoEffect(MISCREG_QUEUE_DEV_MONDO_TAIL,
+ src->readMiscRegNoEffect(MISCREG_QUEUE_DEV_MONDO_TAIL));
+ dest->setMiscRegNoEffect(MISCREG_QUEUE_RES_ERROR_HEAD,
+ src->readMiscRegNoEffect(MISCREG_QUEUE_RES_ERROR_HEAD));
+ dest->setMiscRegNoEffect(MISCREG_QUEUE_RES_ERROR_TAIL,
+ src->readMiscRegNoEffect(MISCREG_QUEUE_RES_ERROR_TAIL));
+ dest->setMiscRegNoEffect(MISCREG_QUEUE_NRES_ERROR_HEAD,
+ src->readMiscRegNoEffect(MISCREG_QUEUE_NRES_ERROR_HEAD));
+ dest->setMiscRegNoEffect(MISCREG_QUEUE_NRES_ERROR_TAIL,
+ src->readMiscRegNoEffect(MISCREG_QUEUE_NRES_ERROR_TAIL));
}
void SparcISA::copyRegs(ThreadContext *src, ThreadContext *dest)
diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh
index d9af0757c..f3e253f7e 100644
--- a/src/arch/sparc/regfile.hh
+++ b/src/arch/sparc/regfile.hh
@@ -73,13 +73,13 @@ namespace SparcISA
int FlattenIntIndex(int reg);
- MiscReg readMiscReg(int miscReg);
+ MiscReg readMiscRegNoEffect(int miscReg);
- MiscReg readMiscRegWithEffect(int miscReg, ThreadContext *tc);
+ MiscReg readMiscReg(int miscReg, ThreadContext *tc);
- void setMiscReg(int miscReg, const MiscReg &val);
+ void setMiscRegNoEffect(int miscReg, const MiscReg &val);
- void setMiscRegWithEffect(int miscReg, const MiscReg &val,
+ void setMiscReg(int miscReg, const MiscReg &val,
ThreadContext * tc);
int instAsid()
@@ -126,8 +126,6 @@ namespace SparcISA
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
- int InterruptLevel(uint64_t softint);
-
} // namespace SparcISA
#endif
diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc
index 21c4a468c..85b0c03a3 100644
--- a/src/arch/sparc/remote_gdb.cc
+++ b/src/arch/sparc/remote_gdb.cc
@@ -138,7 +138,7 @@ using namespace std;
using namespace TheISA;
RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
- : BaseRemoteGDB(_system, c, NumGDBRegs)
+ : BaseRemoteGDB(_system, c, NumGDBRegs), nextBkpt(0)
{}
///////////////////////////////////////////////////////////
@@ -152,7 +152,9 @@ 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;
+ if (va)
+ return true;
+ return false;
}
///////////////////////////////////////////////////////////
@@ -165,10 +167,37 @@ 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);
+ if (context->readMiscReg(MISCREG_PSTATE) &
+ PSTATE::am) {
+ uint32_t *regs;
+ regs = (uint32_t*)gdbregs.regs;
+ regs[Reg32Pc] = htobe((uint32_t)context->readPC());
+ regs[Reg32Npc] = htobe((uint32_t)context->readNextPC());
+ for(int x = RegG0; x <= RegI0 + 7; x++)
+ regs[x] = htobe((uint32_t)context->readIntReg(x - RegG0));
+
+ regs[Reg32Y] = htobe((uint32_t)context->readIntReg(NumIntArchRegs + 1));
+ regs[Reg32Psr] = htobe((uint32_t)context->readMiscReg(MISCREG_PSTATE));
+ regs[Reg32Fsr] = htobe((uint32_t)context->readMiscReg(MISCREG_FSR));
+ regs[Reg32Csr] = htobe((uint32_t)context->readIntReg(NumIntArchRegs + 2));
+ } else {
+ gdbregs.regs[RegPc] = htobe(context->readPC());
+ gdbregs.regs[RegNpc] = htobe(context->readNextPC());
+ for(int x = RegG0; x <= RegI0 + 7; x++)
+ gdbregs.regs[x] = htobe(context->readIntReg(x - RegG0));
+
+ gdbregs.regs[RegFsr] = htobe(context->readMiscReg(MISCREG_FSR));
+ gdbregs.regs[RegFprs] = htobe(context->readMiscReg(MISCREG_FPRS));
+ gdbregs.regs[RegY] = htobe(context->readIntReg(NumIntArchRegs + 1));
+ gdbregs.regs[RegState] = htobe(
+ context->readMiscReg(MISCREG_CWP) |
+ context->readMiscReg(MISCREG_PSTATE) << 8 |
+ context->readMiscReg(MISCREG_ASI) << 24 |
+ context->readIntReg(NumIntArchRegs + 2) << 32);
+ }
+
+ DPRINTF(GDBRead, "PC=%#x\n", gdbregs.regs[RegPc]);
+
//Floating point registers are left at 0 in netbsd
//All registers other than the pc, npc and int regs
//are ignored as well.
@@ -193,12 +222,13 @@ RemoteGDB::setregs()
void
RemoteGDB::clearSingleStep()
{
- warn("SPARC single stepping not implemented, "
- "but clearSingleStep called\n");
+ if (nextBkpt)
+ clearTempBreakpoint(nextBkpt);
}
void
RemoteGDB::setSingleStep()
{
- panic("SPARC single stepping not implemented.\n");
+ nextBkpt = context->readNextPC();
+ setTempBreakpoint(nextBkpt);
}
diff --git a/src/arch/sparc/remote_gdb.hh b/src/arch/sparc/remote_gdb.hh
index e4b66b783..dbdf810c4 100644
--- a/src/arch/sparc/remote_gdb.hh
+++ b/src/arch/sparc/remote_gdb.hh
@@ -28,12 +28,12 @@
* Authors: Nathan Binkert
*/
-#ifndef __ARCH_ALPHA_REMOTE_GDB_HH__
-#define __ARCH_ALPHA_REMOTE_GDB_HH__
+#ifndef __ARCH_SPARC_REMOTE_GDB_HH__
+#define __ARCH_SPARC_REMOTE_GDB_HH__
#include <map>
-#include "arch/types.hh"
+#include "arch/sparc/types.hh"
#include "base/remote_gdb.hh"
#include "cpu/pc_event.hh"
#include "base/pollevent.hh"
@@ -50,15 +50,12 @@ namespace SparcISA
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
+ RegF0 = 32,
+ RegPc = 64, RegNpc, RegState, RegFsr, RegFprs, RegY,
+ /*RegState contains data in same format as tstate */
+ Reg32Y = 64, Reg32Psr = 65, Reg32Tbr = 66, Reg32Pc = 67,
+ Reg32Npc = 68, Reg32Fsr = 69, Reg32Csr = 70,
+ NumGDBRegs = RegY
};
public:
@@ -72,7 +69,9 @@ namespace SparcISA
void clearSingleStep();
void setSingleStep();
+
+ Addr nextBkpt;
};
}
-#endif /* __ARCH_ALPHA_REMOTE_GDB_H__ */
+#endif /* __ARCH_SPARC_REMOTE_GDB_H__ */
diff --git a/src/arch/sparc/stacktrace.cc b/src/arch/sparc/stacktrace.cc
index 2eb697bf2..2d7991267 100644
--- a/src/arch/sparc/stacktrace.cc
+++ b/src/arch/sparc/stacktrace.cc
@@ -146,7 +146,7 @@ namespace SparcISA
#if 0
tc = _tc;
- bool usermode = (tc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
+ bool usermode = (tc->readMiscRegNoEffect(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
Addr pc = tc->readNextPC();
bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
@@ -221,22 +221,22 @@ namespace SparcISA
StackTrace::isEntry(Addr addr)
{
#if 0
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp12))
+ if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp12))
return true;
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp7))
+ if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp7))
return true;
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp11))
+ if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp11))
return true;
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp21))
+ if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp21))
return true;
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp9))
+ if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp9))
return true;
- if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp2))
+ if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp2))
return true;
#endif
return false;
diff --git a/src/arch/sparc/syscallreturn.hh b/src/arch/sparc/syscallreturn.hh
index d92b12790..cf13fc3e8 100644
--- a/src/arch/sparc/syscallreturn.hh
+++ b/src/arch/sparc/syscallreturn.hh
@@ -49,13 +49,13 @@ namespace SparcISA
// no error, clear XCC.C
tc->setIntReg(NumIntArchRegs + 2,
tc->readIntReg(NumIntArchRegs + 2) & 0xEE);
- //tc->setMiscReg(MISCREG_CCR, tc->readMiscReg(MISCREG_CCR) & 0xEE);
+ //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) & 0xEE);
tc->setIntReg(ReturnValueReg, return_value.value());
} else {
// got an error, set XCC.C
tc->setIntReg(NumIntArchRegs + 2,
tc->readIntReg(NumIntArchRegs + 2) | 0x11);
- //tc->setMiscReg(MISCREG_CCR, tc->readMiscReg(MISCREG_CCR) | 0x11);
+ //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) | 0x11);
tc->setIntReg(ReturnValueReg, -return_value.value());
}
}
diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc
index 293f667d6..09266fd6e 100644
--- a/src/arch/sparc/tlb.cc
+++ b/src/arch/sparc/tlb.cc
@@ -40,11 +40,11 @@
#include "mem/packet_access.hh"
#include "mem/request.hh"
#include "sim/builder.hh"
+#include "sim/system.hh"
/* @todo remove some of the magic constants. -- ali
* */
-namespace SparcISA
-{
+namespace SparcISA {
TLB::TLB(const std::string &name, int s)
: SimObject(name), size(s), usedEntries(0), lastReplaced(0),
@@ -204,7 +204,8 @@ insertAllLocked:
TlbEntry*
-TLB::lookup(Addr va, int partition_id, bool real, int context_id)
+TLB::lookup(Addr va, int partition_id, bool real, int context_id, bool
+ update_used)
{
MapIter i;
TlbRange tr;
@@ -230,7 +231,10 @@ TLB::lookup(Addr va, int partition_id, bool real, int context_id)
t = i->second;
DPRINTF(TLB, "TLB: Valid entry found pa: %#x size: %#x\n", t->pte.paddr(),
t->pte.size());
- if (!t->used) {
+
+ // Update the used bits only if this is a real access (not a fake one from
+ // virttophys()
+ if (!t->used && update_used) {
t->used = true;
usedEntries++;
if (usedEntries == size) {
@@ -392,7 +396,7 @@ TLB::writeSfsr(ThreadContext *tc, int reg, bool write, ContextType ct,
bool se, FaultTypes ft, int asi)
{
uint64_t sfsr;
- sfsr = tc->readMiscReg(reg);
+ sfsr = tc->readMiscRegNoEffect(reg);
if (sfsr & 0x1)
sfsr = 0x3;
@@ -406,7 +410,7 @@ TLB::writeSfsr(ThreadContext *tc, int reg, bool write, ContextType ct,
sfsr |= 1 << 6;
sfsr |= ft << 7;
sfsr |= asi << 16;
- tc->setMiscRegWithEffect(reg, sfsr);
+ tc->setMiscReg(reg, sfsr);
}
void
@@ -415,7 +419,7 @@ TLB::writeTagAccess(ThreadContext *tc, int reg, Addr va, int context)
DPRINTF(TLB, "TLB: Writing Tag Access: va: %#X ctx: %#X value: %#X\n",
va, context, mbits(va, 63,13) | mbits(context,12,0));
- tc->setMiscRegWithEffect(reg, mbits(va, 63,13) | mbits(context,12,0));
+ tc->setMiscReg(reg, mbits(va, 63,13) | mbits(context,12,0));
}
void
@@ -440,7 +444,7 @@ DTB::writeSfr(ThreadContext *tc, Addr a, bool write, ContextType ct,
DPRINTF(TLB, "TLB: DTB Fault: A=%#x w=%d ct=%d ft=%d asi=%d\n",
a, (int)write, ct, ft, asi);
TLB::writeSfsr(tc, MISCREG_MMU_DTLB_SFSR, write, ct, se, ft, asi);
- tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_SFAR, a);
+ tc->setMiscReg(MISCREG_MMU_DTLB_SFAR, a);
}
void
@@ -454,7 +458,7 @@ DTB::writeTagAccess(ThreadContext *tc, Addr va, int context)
Fault
ITB::translate(RequestPtr &req, ThreadContext *tc)
{
- uint64_t tlbdata = tc->readMiscReg(MISCREG_TLB_DATA);
+ uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
Addr vaddr = req->getVaddr();
TlbEntry *e;
@@ -568,7 +572,7 @@ Fault
DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
{
/* @todo this could really use some profiling and fixing to make it faster! */
- uint64_t tlbdata = tc->readMiscReg(MISCREG_TLB_DATA);
+ uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
Addr vaddr = req->getVaddr();
Addr size = req->getSize();
ASI asi;
@@ -592,21 +596,36 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
// Be fast if we can!
if (cacheValid && cacheState == tlbdata) {
- if (cacheEntry[0] && cacheAsi[0] == asi && cacheEntry[0]->range.va < vaddr + size &&
- cacheEntry[0]->range.va + cacheEntry[0]->range.size > vaddr &&
- (!write || cacheEntry[0]->pte.writable())) {
- req->setPaddr(cacheEntry[0]->pte.paddr() & ~(cacheEntry[0]->pte.size()-1) |
- vaddr & cacheEntry[0]->pte.size()-1 );
- return NoFault;
- }
- if (cacheEntry[1] && cacheAsi[1] == asi && cacheEntry[1]->range.va < vaddr + size &&
- cacheEntry[1]->range.va + cacheEntry[1]->range.size > vaddr &&
- (!write || cacheEntry[1]->pte.writable())) {
- req->setPaddr(cacheEntry[1]->pte.paddr() & ~(cacheEntry[1]->pte.size()-1) |
- vaddr & cacheEntry[1]->pte.size()-1 );
- return NoFault;
- }
- }
+
+
+
+ if (cacheEntry[0]) {
+ TlbEntry *ce = cacheEntry[0];
+ Addr ce_va = ce->range.va;
+ if (cacheAsi[0] == asi &&
+ ce_va < vaddr + size && ce_va + ce->range.size > vaddr &&
+ (!write || ce->pte.writable())) {
+ req->setPaddr(ce->pte.paddrMask() | vaddr & ce->pte.sizeMask());
+ if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1)
+ req->setFlags(req->getFlags() | UNCACHEABLE);
+ DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr());
+ return NoFault;
+ } // if matched
+ } // if cache entry valid
+ if (cacheEntry[1]) {
+ TlbEntry *ce = cacheEntry[1];
+ Addr ce_va = ce->range.va;
+ if (cacheAsi[1] == asi &&
+ ce_va < vaddr + size && ce_va + ce->range.size > vaddr &&
+ (!write || ce->pte.writable())) {
+ req->setPaddr(ce->pte.paddrMask() | vaddr & ce->pte.sizeMask());
+ if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1)
+ req->setFlags(req->getFlags() | UNCACHEABLE);
+ DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr());
+ return NoFault;
+ } // if matched
+ } // if cache entry valid
+ }
bool red = bits(tlbdata,1,1);
bool priv = bits(tlbdata,2,2);
@@ -673,9 +692,12 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
if (AsiIsPartialStore(asi))
panic("Partial Store ASIs not supported\n");
- if (AsiIsInterrupt(asi))
- panic("Interrupt ASIs not supported\n");
+ if (AsiIsCmt(asi))
+ panic("Cmt ASI registers not implmented\n");
+
+ if (AsiIsInterrupt(asi))
+ goto handleIntRegAccess;
if (AsiIsMmu(asi))
goto handleMmuRegAccess;
if (AsiIsScratchPad(asi))
@@ -752,7 +774,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
}
- if (e->pte.sideffect())
+ if (e->pte.sideffect() || (e->pte.paddr() >> 39) & 1)
req->setFlags(req->getFlags() | UNCACHEABLE);
// cache translation date for next translation
@@ -775,7 +797,25 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
vaddr & e->pte.size()-1);
DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr());
return NoFault;
+
/** Normal flow ends here. */
+handleIntRegAccess:
+ if (!hpriv) {
+ writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
+ if (priv)
+ return new DataAccessException;
+ else
+ return new PrivilegedAction;
+ }
+
+ if (asi == ASI_SWVR_UDB_INTR_W && !write ||
+ asi == ASI_SWVR_UDB_INTR_R && write) {
+ writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
+ return new DataAccessException;
+ }
+
+ goto regAccessOk;
+
handleScratchRegAccess:
if (vaddr > 0x38 || (vaddr >= 0x20 && vaddr < 0x30 && !hpriv)) {
@@ -797,13 +837,11 @@ handleQueueRegAccess:
handleSparcErrorRegAccess:
if (!hpriv) {
- if (priv) {
- writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
+ writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
+ if (priv)
return new DataAccessException;
- } else {
- writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
+ else
return new PrivilegedAction;
- }
}
goto regAccessOk;
@@ -821,8 +859,7 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
{
Addr va = pkt->getAddr();
ASI asi = (ASI)pkt->req->getAsi();
- uint64_t temp, data;
- uint64_t tsbtemp, cnftemp;
+ uint64_t temp;
DPRINTF(IPR, "Memory Mapped IPR Read: asi=%#X a=%#x\n",
(uint32_t)pkt->req->getAsi(), pkt->getAddr());
@@ -830,90 +867,90 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
switch (asi) {
case ASI_LSU_CONTROL_REG:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_LSU_CTRL));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_LSU_CTRL));
break;
case ASI_MMU:
switch (va) {
case 0x8:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_P_CONTEXT));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_P_CONTEXT));
break;
case 0x10:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_S_CONTEXT));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_S_CONTEXT));
break;
default:
goto doMmuReadError;
}
break;
case ASI_QUEUE:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_QUEUE_CPU_MONDO_HEAD +
+ pkt->set(tc->readMiscReg(MISCREG_QUEUE_CPU_MONDO_HEAD +
(va >> 4) - 0x3c));
break;
case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS0));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0));
break;
case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS1:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS1));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1));
break;
case ASI_DMMU_CTXT_ZERO_CONFIG:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG));
break;
case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS0:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS0));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0));
break;
case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS1:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS1));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1));
break;
case ASI_IMMU_CTXT_ZERO_CONFIG:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG));
break;
case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS0));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0));
break;
case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS1:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS1));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1));
break;
case ASI_DMMU_CTXT_NONZERO_CONFIG:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG));
break;
case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS0:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS0));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0));
break;
case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS1:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS1));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1));
break;
case ASI_IMMU_CTXT_NONZERO_CONFIG:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG));
break;
case ASI_SPARC_ERROR_STATUS_REG:
pkt->set((uint64_t)0);
break;
case ASI_HYP_SCRATCHPAD:
case ASI_SCRATCHPAD:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_SCRATCHPAD_R0 + (va >> 3)));
+ pkt->set(tc->readMiscReg(MISCREG_SCRATCHPAD_R0 + (va >> 3)));
break;
case ASI_IMMU:
switch (va) {
case 0x0:
- temp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS);
+ temp = tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS);
pkt->set(bits(temp,63,22) | bits(temp,12,0) << 48);
break;
case 0x18:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_SFSR));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_SFSR));
break;
case 0x30:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS));
break;
default:
goto doMmuReadError;
@@ -922,86 +959,65 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
case ASI_DMMU:
switch (va) {
case 0x0:
- temp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS);
+ temp = tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS);
pkt->set(bits(temp,63,22) | bits(temp,12,0) << 48);
break;
case 0x18:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_SFSR));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_SFSR));
break;
case 0x20:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_SFAR));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_SFAR));
break;
case 0x30:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS));
break;
case 0x80:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_PART_ID));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_PART_ID));
break;
default:
goto doMmuReadError;
}
break;
case ASI_DMMU_TSB_PS0_PTR_REG:
- temp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS);
- if (bits(temp,12,0) == 0) {
- tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS0);
- cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG);
- } else {
- tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS0);
- cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG);
- }
- data = mbits(tsbtemp,63,13);
- data |= temp >> (9 + bits(cnftemp,2,0) * 3) &
- mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
- pkt->set(data);
+ pkt->set(MakeTsbPtr(Ps0,
+ tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS),
+ tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0),
+ tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG),
+ tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0),
+ tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG)));
break;
case ASI_DMMU_TSB_PS1_PTR_REG:
- temp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS);
- if (bits(temp,12,0) == 0) {
- tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS1);
- cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG);
- } else {
- tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS1);
- cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG);
- }
- data = mbits(tsbtemp,63,13);
- if (bits(tsbtemp,12,12))
- data |= ULL(1) << (13+bits(tsbtemp,3,0));
- data |= temp >> (9 + bits(cnftemp,10,8) * 3) &
- mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
- pkt->set(data);
+ pkt->set(MakeTsbPtr(Ps1,
+ tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS),
+ tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1),
+ tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG),
+ tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1),
+ tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG)));
break;
case ASI_IMMU_TSB_PS0_PTR_REG:
- temp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS);
- if (bits(temp,12,0) == 0) {
- tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS0);
- cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG);
- } else {
- tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS0);
- cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG);
- }
- data = mbits(tsbtemp,63,13);
- data |= temp >> (9 + bits(cnftemp,2,0) * 3) &
- mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
- pkt->set(data);
+ pkt->set(MakeTsbPtr(Ps0,
+ tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS),
+ tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0),
+ tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG),
+ tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0),
+ tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG)));
break;
case ASI_IMMU_TSB_PS1_PTR_REG:
- temp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS);
- if (bits(temp,12,0) == 0) {
- tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS1);
- cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG);
- } else {
- tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS1);
- cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG);
- }
- data = mbits(tsbtemp,63,13);
- if (bits(tsbtemp,12,12))
- data |= ULL(1) << (13+bits(tsbtemp,3,0));
- data |= temp >> (9 + bits(cnftemp,10,8) * 3) &
- mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
- pkt->set(data);
+ pkt->set(MakeTsbPtr(Ps1,
+ tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS),
+ tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1),
+ tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG),
+ tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1),
+ tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG)));
+ break;
+ case ASI_SWVR_INTR_RECEIVE:
+ pkt->set(tc->getCpuPtr()->get_interrupts(IT_INT_VEC));
+ break;
+ case ASI_SWVR_UDB_INTR_R:
+ temp = findMsbSet(tc->getCpuPtr()->get_interrupts(IT_INT_VEC));
+ tc->getCpuPtr()->clear_interrupt(IT_INT_VEC, temp);
+ pkt->set(temp);
break;
-
default:
doMmuReadError:
panic("need to impl DTB::doMmuRegRead() got asi=%#x, va=%#x\n",
@@ -1035,15 +1051,15 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
switch (asi) {
case ASI_LSU_CONTROL_REG:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_LSU_CTRL, data);
+ tc->setMiscReg(MISCREG_MMU_LSU_CTRL, data);
break;
case ASI_MMU:
switch (va) {
case 0x8:
- tc->setMiscRegWithEffect(MISCREG_MMU_P_CONTEXT, data);
+ tc->setMiscReg(MISCREG_MMU_P_CONTEXT, data);
break;
case 0x10:
- tc->setMiscRegWithEffect(MISCREG_MMU_S_CONTEXT, data);
+ tc->setMiscReg(MISCREG_MMU_S_CONTEXT, data);
break;
default:
goto doMmuWriteError;
@@ -1051,56 +1067,56 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
break;
case ASI_QUEUE:
assert(mbits(data,13,6) == data);
- tc->setMiscRegWithEffect(MISCREG_QUEUE_CPU_MONDO_HEAD +
+ tc->setMiscReg(MISCREG_QUEUE_CPU_MONDO_HEAD +
(va >> 4) - 0x3c, data);
break;
case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS0, data);
+ tc->setMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0, data);
break;
case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS1:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS1, data);
+ tc->setMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1, data);
break;
case ASI_DMMU_CTXT_ZERO_CONFIG:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG, data);
+ tc->setMiscReg(MISCREG_MMU_DTLB_C0_CONFIG, data);
break;
case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS0:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS0, data);
+ tc->setMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0, data);
break;
case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS1:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS1, data);
+ tc->setMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1, data);
break;
case ASI_IMMU_CTXT_ZERO_CONFIG:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG, data);
+ tc->setMiscReg(MISCREG_MMU_ITLB_C0_CONFIG, data);
break;
case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS0, data);
+ tc->setMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0, data);
break;
case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS1:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS1, data);
+ tc->setMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1, data);
break;
case ASI_DMMU_CTXT_NONZERO_CONFIG:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG, data);
+ tc->setMiscReg(MISCREG_MMU_DTLB_CX_CONFIG, data);
break;
case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS0:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS0, data);
+ tc->setMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0, data);
break;
case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS1:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS1, data);
+ tc->setMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1, data);
break;
case ASI_IMMU_CTXT_NONZERO_CONFIG:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG, data);
+ tc->setMiscReg(MISCREG_MMU_ITLB_CX_CONFIG, data);
break;
case ASI_SPARC_ERROR_EN_REG:
case ASI_SPARC_ERROR_STATUS_REG:
@@ -1108,16 +1124,16 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
break;
case ASI_HYP_SCRATCHPAD:
case ASI_SCRATCHPAD:
- tc->setMiscRegWithEffect(MISCREG_SCRATCHPAD_R0 + (va >> 3), data);
+ tc->setMiscReg(MISCREG_SCRATCHPAD_R0 + (va >> 3), data);
break;
case ASI_IMMU:
switch (va) {
case 0x18:
- tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_SFSR, data);
+ tc->setMiscReg(MISCREG_MMU_ITLB_SFSR, data);
break;
case 0x30:
sext<59>(bits(data, 59,0));
- tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS, data);
+ tc->setMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS, data);
break;
default:
goto doMmuWriteError;
@@ -1127,10 +1143,10 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
entry_insert = bits(va, 8,3);
case ASI_ITLB_DATA_IN_REG:
assert(entry_insert != -1 || mbits(va,10,9) == va);
- ta_insert = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS);
+ ta_insert = tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS);
va_insert = mbits(ta_insert, 63,13);
ct_insert = mbits(ta_insert, 12,0);
- part_insert = tc->readMiscRegWithEffect(MISCREG_MMU_PART_ID);
+ part_insert = tc->readMiscReg(MISCREG_MMU_PART_ID);
real_insert = bits(va, 9,9);
pte.populate(data, bits(va,10,10) ? PageTableEntry::sun4v :
PageTableEntry::sun4u);
@@ -1141,10 +1157,10 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
entry_insert = bits(va, 8,3);
case ASI_DTLB_DATA_IN_REG:
assert(entry_insert != -1 || mbits(va,10,9) == va);
- ta_insert = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS);
+ ta_insert = tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS);
va_insert = mbits(ta_insert, 63,13);
ct_insert = mbits(ta_insert, 12,0);
- part_insert = tc->readMiscRegWithEffect(MISCREG_MMU_PART_ID);
+ part_insert = tc->readMiscReg(MISCREG_MMU_PART_ID);
real_insert = bits(va, 9,9);
pte.populate(data, bits(va,10,10) ? PageTableEntry::sun4v :
PageTableEntry::sun4u);
@@ -1153,10 +1169,10 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
case ASI_IMMU_DEMAP:
ignore = false;
ctx_id = -1;
- part_id = tc->readMiscRegWithEffect(MISCREG_MMU_PART_ID);
+ part_id = tc->readMiscReg(MISCREG_MMU_PART_ID);
switch (bits(va,5,4)) {
case 0:
- ctx_id = tc->readMiscRegWithEffect(MISCREG_MMU_P_CONTEXT);
+ ctx_id = tc->readMiscReg(MISCREG_MMU_P_CONTEXT);
break;
case 1:
ignore = true;
@@ -1188,14 +1204,14 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
case ASI_DMMU:
switch (va) {
case 0x18:
- tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_SFSR, data);
+ tc->setMiscReg(MISCREG_MMU_DTLB_SFSR, data);
break;
case 0x30:
sext<59>(bits(data, 59,0));
- tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS, data);
+ tc->setMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS, data);
break;
case 0x80:
- tc->setMiscRegWithEffect(MISCREG_MMU_PART_ID, data);
+ tc->setMiscReg(MISCREG_MMU_PART_ID, data);
break;
default:
goto doMmuWriteError;
@@ -1204,13 +1220,13 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
case ASI_DMMU_DEMAP:
ignore = false;
ctx_id = -1;
- part_id = tc->readMiscRegWithEffect(MISCREG_MMU_PART_ID);
+ part_id = tc->readMiscReg(MISCREG_MMU_PART_ID);
switch (bits(va,5,4)) {
case 0:
- ctx_id = tc->readMiscRegWithEffect(MISCREG_MMU_P_CONTEXT);
+ ctx_id = tc->readMiscReg(MISCREG_MMU_P_CONTEXT);
break;
case 1:
- ctx_id = tc->readMiscRegWithEffect(MISCREG_MMU_S_CONTEXT);
+ ctx_id = tc->readMiscReg(MISCREG_MMU_S_CONTEXT);
break;
case 3:
ctx_id = 0;
@@ -1235,7 +1251,19 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
panic("Invalid type for IMMU demap\n");
}
break;
- default:
+ case ASI_SWVR_INTR_RECEIVE:
+ int msb;
+ // clear all the interrupts that aren't set in the write
+ while(tc->getCpuPtr()->get_interrupts(IT_INT_VEC) & data) {
+ msb = findMsbSet(tc->getCpuPtr()->get_interrupts(IT_INT_VEC) & data);
+ tc->getCpuPtr()->clear_interrupt(IT_INT_VEC, msb);
+ }
+ break;
+ case ASI_SWVR_UDB_INTR_W:
+ tc->getSystemPtr()->threadContexts[bits(data,12,8)]->getCpuPtr()->
+ post_interrupt(bits(data,5,0),0);
+ break;
+ default:
doMmuWriteError:
panic("need to impl DTB::doMmuRegWrite() got asi=%#x, va=%#x d=%#x\n",
(uint32_t)pkt->req->getAsi(), pkt->getAddr(), data);
@@ -1245,6 +1273,64 @@ doMmuWriteError:
}
void
+DTB::GetTsbPtr(ThreadContext *tc, Addr addr, int ctx, Addr *ptrs)
+{
+ uint64_t tag_access = mbits(addr,63,13) | mbits(ctx,12,0);
+ ptrs[0] = MakeTsbPtr(Ps0, tag_access,
+ tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0),
+ tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG),
+ tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0),
+ tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG));
+ ptrs[1] = MakeTsbPtr(Ps1, tag_access,
+ tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1),
+ tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG),
+ tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1),
+ tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG));
+ ptrs[2] = MakeTsbPtr(Ps0, tag_access,
+ tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0),
+ tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG),
+ tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0),
+ tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG));
+ ptrs[3] = MakeTsbPtr(Ps1, tag_access,
+ tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1),
+ tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG),
+ tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1),
+ tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG));
+}
+
+
+
+
+
+uint64_t
+DTB::MakeTsbPtr(TsbPageSize ps, uint64_t tag_access, uint64_t c0_tsb,
+ uint64_t c0_config, uint64_t cX_tsb, uint64_t cX_config)
+{
+ uint64_t tsb;
+ uint64_t config;
+
+ if (bits(tag_access, 12,0) == 0) {
+ tsb = c0_tsb;
+ config = c0_config;
+ } else {
+ tsb = cX_tsb;
+ config = cX_config;
+ }
+
+ uint64_t ptr = mbits(tsb,63,13);
+ bool split = bits(tsb,12,12);
+ int tsb_size = bits(tsb,3,0);
+ int page_size = (ps == Ps0) ? bits(config, 2,0) : bits(config,10,8);
+
+ if (ps == Ps1 && split)
+ ptr |= ULL(1) << (13 + tsb_size);
+ ptr |= (tag_access >> (9 + page_size * 3)) & mask(12+tsb_size, 4);
+
+ return ptr;
+}
+
+
+void
TLB::serialize(std::ostream &os)
{
SERIALIZE_SCALAR(size);
@@ -1298,6 +1384,9 @@ TLB::unserialize(Checkpoint *cp, const std::string &section)
}
}
+/* end namespace SparcISA */ }
+
+using namespace SparcISA;
DEFINE_SIM_OBJECT_CLASS_NAME("SparcTLB", TLB)
@@ -1340,4 +1429,3 @@ CREATE_SIM_OBJECT(DTB)
}
REGISTER_SIM_OBJECT("SparcDTB", DTB)
-}
diff --git a/src/arch/sparc/tlb.hh b/src/arch/sparc/tlb.hh
index 34e5f5feb..b5f02c62e 100644
--- a/src/arch/sparc/tlb.hh
+++ b/src/arch/sparc/tlb.hh
@@ -78,17 +78,25 @@ class TLB : public SimObject
Nucleus = 2
};
-
+ enum TsbPageSize {
+ Ps0,
+ Ps1
+ };
+ public:
/** lookup an entry in the TLB based on the partition id, and real bit if
* real is true or the partition id, and context id if real is false.
* @param va the virtual address not shifted (e.g. bottom 13 bits are 0)
* @param paritition_id partition this entry is for
* @param real is this a real->phys or virt->phys translation
* @param context_id if this is virt->phys what context
+ * @param update_used should ew update the used bits in the entries on not
+ * useful if we are trying to do a va->pa without mucking with any state for
+ * a debug read for example.
* @return A pointer to a tlb entry
*/
- TlbEntry *lookup(Addr va, int partition_id, bool real, int context_id = 0);
-
+ TlbEntry *lookup(Addr va, int partition_id, bool real, int context_id = 0,
+ bool update_used = true);
+ protected:
/** Insert a PTE into the TLB. */
void insert(Addr vpn, int partition_id, int context_id, bool real,
const PageTableEntry& PTE, int entry = -1);
@@ -163,12 +171,17 @@ class DTB : public TLB
Fault translate(RequestPtr &req, ThreadContext *tc, bool write);
Tick doMmuRegRead(ThreadContext *tc, Packet *pkt);
Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt);
+ void GetTsbPtr(ThreadContext *tc, Addr addr, int ctx, Addr *ptrs);
private:
void writeSfr(ThreadContext *tc, Addr a, bool write, ContextType ct,
bool se, FaultTypes ft, int asi);
void writeTagAccess(ThreadContext *tc, Addr va, int context);
+ uint64_t MakeTsbPtr(TsbPageSize ps, uint64_t tag_access, uint64_t c0_tsb,
+ uint64_t c0_config, uint64_t cX_tsb, uint64_t cX_config);
+
+
TlbEntry *cacheEntry[2];
ASI cacheAsi[2];
};
diff --git a/src/arch/sparc/types.hh b/src/arch/sparc/types.hh
index 88fb24153..15386adca 100644
--- a/src/arch/sparc/types.hh
+++ b/src/arch/sparc/types.hh
@@ -32,6 +32,7 @@
#define __ARCH_SPARC_TYPES_HH__
#include <inttypes.h>
+#include "base/bigint.hh"
namespace SparcISA
{
@@ -39,6 +40,7 @@ namespace SparcISA
typedef uint64_t ExtMachInst;
typedef uint64_t IntReg;
+ typedef Twin64_t LargestRead;
typedef uint64_t MiscReg;
typedef double FloatReg;
typedef uint64_t FloatRegBits;
diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc
index ecb63bb9a..48e97a531 100644
--- a/src/arch/sparc/ua2005.cc
+++ b/src/arch/sparc/ua2005.cc
@@ -26,106 +26,181 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "arch/sparc/kernel_stats.hh"
#include "arch/sparc/miscregfile.hh"
#include "base/bitfield.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
+#include "sim/system.hh"
using namespace SparcISA;
+
+void
+MiscRegFile::checkSoftInt(ThreadContext *tc)
+{
+ // If PIL < 14, copy over the tm and sm bits
+ if (pil < 14 && softint & 0x10000)
+ tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,16);
+ else
+ tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,16);
+ if (pil < 14 && softint & 0x1)
+ tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,0);
+ else
+ tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,0);
+
+ // Copy over any of the other bits that are set
+ for (int bit = 15; bit > 0; --bit) {
+ if (1 << bit & softint && bit > pil)
+ tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,bit);
+ else
+ tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,bit);
+ }
+}
+
+
void
-MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
- ThreadContext *tc)
+MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
{
int64_t time;
switch (miscReg) {
/* Full system only ASRs */
case MISCREG_SOFTINT:
- setReg(miscReg, val);;
+ setRegNoEffect(miscReg, val);;
+ checkSoftInt(tc);
break;
-
case MISCREG_SOFTINT_CLR:
- return setRegWithEffect(MISCREG_SOFTINT, ~val & softint, tc);
+ return setReg(MISCREG_SOFTINT, ~val & softint, tc);
case MISCREG_SOFTINT_SET:
- tc->getCpuPtr()->post_interrupt(soft_interrupt);
- return setRegWithEffect(MISCREG_SOFTINT, val | softint, tc);
+ return setReg(MISCREG_SOFTINT, val | softint, tc);
case MISCREG_TICK_CMPR:
if (tickCompare == NULL)
tickCompare = new TickCompareEvent(this, tc);
- setReg(miscReg, val);
- if ((tick_cmpr & mask(63)) && tickCompare->scheduled())
+ setRegNoEffect(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)
+ if (!(tick_cmpr & ~mask(63)) && time > 0) {
+ if (tickCompare->scheduled())
+ tickCompare->deschedule();
tickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
+ }
panic("writing to TICK compare register %#X\n", val);
break;
case MISCREG_STICK_CMPR:
if (sTickCompare == NULL)
sTickCompare = new STickCompareEvent(this, tc);
- setReg(miscReg, val);
+ setRegNoEffect(miscReg, val);
if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled())
sTickCompare->deschedule();
time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
tc->getCpuPtr()->instCount();
- if (!(stick_cmpr & ~mask(63)) && time > 0)
+ if (!(stick_cmpr & ~mask(63)) && time > 0) {
+ if (sTickCompare->scheduled())
+ sTickCompare->deschedule();
sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick);
+ }
DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val);
break;
case MISCREG_PSTATE:
- setReg(miscReg, val);
+ setRegNoEffect(miscReg, val);
case MISCREG_PIL:
- setReg(miscReg, val);
+ setRegNoEffect(miscReg, val);
+ checkSoftInt(tc);
break;
case MISCREG_HVER:
panic("Shouldn't be writing HVER\n");
case MISCREG_HINTP:
- setReg(miscReg, val);
+ setRegNoEffect(miscReg, val);
+ if (hintp)
+ tc->getCpuPtr()->post_interrupt(IT_HINTP,0);
+ else
+ tc->getCpuPtr()->clear_interrupt(IT_HINTP,0);
+ break;
case MISCREG_HTBA:
// clear lower 7 bits on writes.
- setReg(miscReg, val & ULL(~0x7FFF));
+ setRegNoEffect(miscReg, val & ULL(~0x7FFF));
break;
case MISCREG_QUEUE_CPU_MONDO_HEAD:
case MISCREG_QUEUE_CPU_MONDO_TAIL:
+ setRegNoEffect(miscReg, val);
+ if (cpu_mondo_head != cpu_mondo_tail)
+ tc->getCpuPtr()->post_interrupt(IT_CPU_MONDO,0);
+ else
+ tc->getCpuPtr()->clear_interrupt(IT_CPU_MONDO,0);
+ break;
case MISCREG_QUEUE_DEV_MONDO_HEAD:
case MISCREG_QUEUE_DEV_MONDO_TAIL:
+ setRegNoEffect(miscReg, val);
+ if (dev_mondo_head != dev_mondo_tail)
+ tc->getCpuPtr()->post_interrupt(IT_DEV_MONDO,0);
+ else
+ tc->getCpuPtr()->clear_interrupt(IT_DEV_MONDO,0);
+ break;
case MISCREG_QUEUE_RES_ERROR_HEAD:
case MISCREG_QUEUE_RES_ERROR_TAIL:
+ setRegNoEffect(miscReg, val);
+ if (res_error_head != res_error_tail)
+ tc->getCpuPtr()->post_interrupt(IT_RES_ERROR,0);
+ else
+ tc->getCpuPtr()->clear_interrupt(IT_RES_ERROR,0);
+ break;
case MISCREG_QUEUE_NRES_ERROR_HEAD:
case MISCREG_QUEUE_NRES_ERROR_TAIL:
- setReg(miscReg, val);
- //do something to post mondo interrupt
+ setRegNoEffect(miscReg, val);
+ // This one doesn't have an interrupt to report to the guest OS
break;
case MISCREG_HSTICK_CMPR:
if (hSTickCompare == NULL)
hSTickCompare = new HSTickCompareEvent(this, tc);
- setReg(miscReg, val);
+ setRegNoEffect(miscReg, val);
if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled())
hSTickCompare->deschedule();
time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
tc->getCpuPtr()->instCount();
- if (!(hstick_cmpr & ~mask(63)) && time > 0)
+ if (!(hstick_cmpr & ~mask(63)) && time > 0) {
+ if (hSTickCompare->scheduled())
+ hSTickCompare->deschedule();
hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->cycles(1));
+ }
DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val);
break;
case MISCREG_HPSTATE:
// T1000 spec says impl. dependent val must always be 1
- setReg(miscReg, val | HPSTATE::id);
+ setRegNoEffect(miscReg, val | HPSTATE::id);
+#if FULL_SYSTEM
+ if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
+ tc->getCpuPtr()->post_interrupt(IT_TRAP_LEVEL_ZERO,0);
+ else
+ tc->getCpuPtr()->clear_interrupt(IT_TRAP_LEVEL_ZERO,0);
+#endif
break;
case MISCREG_HTSTATE:
+ setRegNoEffect(miscReg, val);
+ break;
+
case MISCREG_STRAND_STS_REG:
- setReg(miscReg, val);
+ if (bits(val,2,2))
+ panic("No support for setting spec_en bit\n");
+ setRegNoEffect(miscReg, bits(val,0,0));
+ if (!bits(val,0,0)) {
+ DPRINTF(Quiesce, "Cpu executed quiescing instruction\n");
+ // Time to go to sleep
+ tc->suspend();
+ if (tc->getKernelStats())
+ tc->getKernelStats()->quiesce();
+ }
break;
default:
@@ -134,8 +209,10 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
}
MiscReg
-MiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc)
+MiscRegFile::readFSReg(int miscReg, ThreadContext * tc)
{
+ uint64_t temp;
+
switch (miscReg) {
/* Privileged registers. */
case MISCREG_QUEUE_CPU_MONDO_HEAD:
@@ -153,15 +230,52 @@ MiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc)
case MISCREG_HPSTATE:
case MISCREG_HINTP:
case MISCREG_HTSTATE:
- case MISCREG_STRAND_STS_REG:
case MISCREG_HSTICK_CMPR:
- return readReg(miscReg) ;
+ return readRegNoEffect(miscReg) ;
case MISCREG_HTBA:
- return readReg(miscReg) & ULL(~0x7FFF);
+ return readRegNoEffect(miscReg) & ULL(~0x7FFF);
case MISCREG_HVER:
- return NWindows | MaxTL << 8 | MaxGL << 16;
+ // XXX set to match Legion
+ return ULL(0x3e) << 48 |
+ ULL(0x23) << 32 |
+ ULL(0x20) << 24 |
+ //MaxGL << 16 | XXX For some reason legion doesn't set GL
+ MaxTL << 8 |
+ (NWindows -1) << 0;
+ case MISCREG_STRAND_STS_REG:
+ System *sys;
+ int x;
+ sys = tc->getSystemPtr();
+
+ temp = readRegNoEffect(miscReg) & (STS::active | STS::speculative);
+ // Check that the CPU array is fully populated (by calling getNumCPus())
+ assert(sys->getNumCPUs() > tc->readCpuId());
+
+ temp |= tc->readCpuId() << STS::shft_id;
+
+ for (x = tc->readCpuId() & ~3; x < sys->threadContexts.size(); x++) {
+ switch (sys->threadContexts[x]->status()) {
+ case ThreadContext::Active:
+ temp |= STS::st_run << (STS::shft_fsm0 -
+ ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
+ break;
+ case ThreadContext::Suspended:
+ // should this be idle?
+ temp |= STS::st_idle << (STS::shft_fsm0 -
+ ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
+ break;
+ case ThreadContext::Halted:
+ temp |= STS::st_halt << (STS::shft_fsm0 -
+ ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
+ break;
+ default:
+ panic("What state are we in?!\n");
+ } // switch
+ } // for
+
+ return temp;
default:
panic("Invalid read to FS misc register\n");
}
@@ -194,12 +308,11 @@ MiscRegFile::processSTickCompare(ThreadContext *tc)
tc->getCpuPtr()->instCount();
assert(ticks >= 0 && "stick compare missed interrupt cycle");
- if (ticks == 0) {
+ if (ticks == 0 || tc->status() == ThreadContext::Suspended) {
DPRINTF(Timer, "STick compare cycle reached at %#x\n",
(stick_cmpr & mask(63)));
- if (!(tc->readMiscReg(MISCREG_STICK_CMPR) & (ULL(1) << 63))) {
- tc->getCpuPtr()->post_interrupt(soft_interrupt);
- setRegWithEffect(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc);
+ if (!(tc->readMiscRegNoEffect(MISCREG_STICK_CMPR) & (ULL(1) << 63))) {
+ setReg(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc);
}
} else
sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick);
@@ -212,19 +325,22 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc)
// we're actually at the correct cycle or we need to wait a little while
// more
int ticks;
+ if ( tc->status() == ThreadContext::Halted ||
+ tc->status() == ThreadContext::Unallocated)
+ return;
+
ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
tc->getCpuPtr()->instCount();
assert(ticks >= 0 && "hstick compare missed interrupt cycle");
- if (ticks == 0) {
+ if (ticks == 0 || tc->status() == ThreadContext::Suspended) {
DPRINTF(Timer, "HSTick compare cycle reached at %#x\n",
(stick_cmpr & mask(63)));
- if (!(tc->readMiscReg(MISCREG_HSTICK_CMPR) & (ULL(1) << 63))) {
- setRegWithEffect(MISCREG_HINTP, 1, tc);
- tc->getCpuPtr()->post_interrupt(hstick_match);
+ if (!(tc->readMiscRegNoEffect(MISCREG_HSTICK_CMPR) & (ULL(1) << 63))) {
+ setReg(MISCREG_HINTP, 1, tc);
}
// Need to do something to cause interrupt to happen here !!! @todo
} else
- sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick);
+ hSTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick);
}
diff --git a/src/arch/sparc/utility.hh b/src/arch/sparc/utility.hh
index 3c8bdcd01..1458231f2 100644
--- a/src/arch/sparc/utility.hh
+++ b/src/arch/sparc/utility.hh
@@ -44,24 +44,8 @@ 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 = (MachInst) inst;
- //The I bit, bit 13, is used to figure out where the ASI
- //should come from. Use that in the ExtMachInst. This is
- //slightly redundant, but it removes the need to put a condition
- //into all the execute functions
- if(inst & (1 << 13))
- emi |= (static_cast<ExtMachInst>(xc->readMiscReg(MISCREG_ASI))
- << (sizeof(MachInst) * 8));
- else
- emi |= (static_cast<ExtMachInst>(bits(inst, 12, 5))
- << (sizeof(MachInst) * 8));
- return emi;
+ return !(tc->readMiscRegNoEffect(MISCREG_PSTATE & (1 << 2)) ||
+ tc->readMiscRegNoEffect(MISCREG_HPSTATE & (1 << 2)));
}
inline bool isCallerSaveIntegerRegister(unsigned int reg) {
@@ -112,7 +96,20 @@ namespace SparcISA
inline void initCPU(ThreadContext *tc, int cpuId)
{
static Fault por = new PowerOnReset();
- por->invoke(tc);
+ if (cpuId == 0)
+ por->invoke(tc);
+
+ }
+
+ inline void startupCPU(ThreadContext *tc, int cpuId)
+ {
+#if FULL_SYSTEM
+ // Other CPUs will get activated by IPIs
+ if (cpuId == 0)
+ tc->activate(0);
+#else
+ tc->activate(0);
+#endif
}
} // namespace SparcISA
diff --git a/src/arch/sparc/vtophys.cc b/src/arch/sparc/vtophys.cc
index 429126b70..9a93950d2 100644
--- a/src/arch/sparc/vtophys.cc
+++ b/src/arch/sparc/vtophys.cc
@@ -25,14 +25,14 @@
* (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
- * Ali Saidi
+ * Authors: Ali Saidi
*/
#include <string>
#include "arch/sparc/vtophys.hh"
+#include "arch/sparc/tlb.hh"
+#include "base/compiler.hh"
#include "base/chunk_generator.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
@@ -42,37 +42,83 @@ using namespace std;
namespace SparcISA
{
- PageTableEntry kernel_pte_lookup(FunctionalPort *mem,
- Addr ptbr, VAddr vaddr)
- {
- PageTableEntry pte(4);
- return pte;
- }
-
Addr vtophys(Addr vaddr)
{
- return vaddr;
+ // In SPARC it's almost always impossible to turn a VA->PA w/o a context
+ // The only times we can kinda do it are if we have a SegKPM mapping
+ // and can find the real address in the tlb or we have a physical
+ // adddress already (beacuse we are looking at the hypervisor)
+ // Either case is rare, so we'll just panic.
+
+ panic("vtophys() without context on SPARC largly worthless\n");
+ M5_DUMMY_RETURN
}
Addr vtophys(ThreadContext *tc, Addr addr)
{
- return addr;
- }
+ // Here we have many options and are really implementing something like
+ // a fill handler to find the address since there isn't a multilevel
+ // table for us to walk around.
+ //
+ // 1. We are currently hyperpriv, return the address unmodified
+ // 2. The mmu is off return(ra->pa)
+ // 3. We are currently priv, use ctx0* tsbs to find the page
+ // 4. We are not priv, use ctxN0* tsbs to find the page
+ // For all accesses we check the tlbs first since it's possible that
+ // long standing pages (e.g. locked kernel mappings) won't be in the tsb
+ uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
+ bool hpriv = bits(tlbdata,0,0);
+ //bool priv = bits(tlbdata,2,2);
+ bool addr_mask = bits(tlbdata,3,3);
+ bool data_real = !bits(tlbdata,5,5);
+ bool inst_real = !bits(tlbdata,4,4);
+ bool ctx_zero = bits(tlbdata,18,16) > 0;
+ int part_id = bits(tlbdata,15,8);
+ int pri_context = bits(tlbdata,47,32);
+ //int sec_context = bits(tlbdata,63,48);
- void CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
- {
- }
+ FunctionalPort *mem = tc->getPhysPort();
+ ITB* itb = tc->getITBPtr();
+ DTB* dtb = tc->getDTBPtr();
+ TlbEntry* tbe;
+ PageTableEntry pte;
+ Addr tsbs[4];
+ Addr va_tag;
+ TteTag ttetag;
- void CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
- {
- }
+ if (hpriv)
+ return addr;
- void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
- {
- }
+ if (addr_mask)
+ addr = addr & VAddrAMask;
- void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
- {
+ tbe = dtb->lookup(addr, part_id, data_real, ctx_zero ? 0 : pri_context , false);
+ if (tbe) goto foundtbe;
+
+ tbe = itb->lookup(addr, part_id, inst_real, ctx_zero ? 0 : pri_context, false);
+ if (tbe) goto foundtbe;
+
+ // We didn't find it in the tlbs, so lets look at the TSBs
+ dtb->GetTsbPtr(tc, addr, ctx_zero ? 0 : pri_context, tsbs);
+ va_tag = bits(addr, 63, 22);
+ for (int x = 0; x < 4; x++) {
+ ttetag = betoh(mem->read<uint64_t>(tsbs[x]));
+ if (ttetag.valid() && ttetag.va() == va_tag) {
+ pte.populate(betoh(mem->read<uint64_t>(tsbs[x]) + sizeof(uint64_t)),
+ PageTableEntry::sun4v); // I think it's sun4v at least!
+ DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TTE\n", addr,
+ pte.paddrMask() | addr & pte.sizeMask());
+ goto foundpte;
+ }
+ }
+ panic("couldn't translate %#x\n", addr);
+
+foundtbe:
+ pte = tbe->pte;
+ DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TLB\n", addr,
+ pte.paddrMask() | addr & pte.sizeMask());
+foundpte:
+ return pte.paddrMask() | addr & pte.sizeMask();
}
}
diff --git a/src/arch/sparc/vtophys.hh b/src/arch/sparc/vtophys.hh
index 66679a565..f55967b53 100644
--- a/src/arch/sparc/vtophys.hh
+++ b/src/arch/sparc/vtophys.hh
@@ -46,11 +46,6 @@ kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, SparcISA::VAddr vaddr);
Addr vtophys(Addr vaddr);
Addr vtophys(ThreadContext *tc, Addr vaddr);
-void CopyOut(ThreadContext *tc, void *dst, Addr src, size_t len);
-void CopyIn(ThreadContext *tc, Addr dst, void *src, size_t len);
-void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen);
-void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr);
-
};
#endif // __ARCH_SPARC_VTOPHYS_H__
diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript
new file mode 100644
index 000000000..2e2c5b006
--- /dev/null
+++ b/src/arch/x86/SConscript
@@ -0,0 +1,111 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2005-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
+
+# Copyright (c) 2007 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use of this software in source and binary forms,
+# with or without modification, are permitted provided that the
+# following conditions are met:
+#
+# The software must be used only for Non-Commercial Use which means any
+# use which is NOT directed to receiving any direct monetary
+# compensation for, or commercial advantage from such use. Illustrative
+# examples of non-commercial use are academic research, personal study,
+# teaching, education and corporate research & development.
+# Illustrative examples of commercial use are distributing products for
+# commercial advantage and providing services using the software for
+# commercial advantage.
+#
+# If you wish to use this software or functionality therein that may be
+# covered by patents for commercial use, please contact:
+# Director of Intellectual Property Licensing
+# Office of Strategy and Technology
+# Hewlett-Packard Company
+# 1501 Page Mill Road
+# Palo Alto, California 94304
+#
+# 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission. No right of
+# sublicense is granted herewith. Derivatives of the software and
+# output created using the software may be prepared, but only for
+# Non-Commercial Uses. Derivatives of the software may be shared with
+# others provided: (i) the others agree to abide by the list of
+# conditions herein which includes the Non-Commercial Use restrictions;
+# and (ii) such Derivatives of the software include the above copyright
+# notice to acknowledge the contribution from this software where
+# applicable, this list of conditions and the disclaimer below.
+#
+# 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
+
+Import('*')
+if env['TARGET_ISA'] == 'x86':
+ Source('floatregfile.cc')
+ Source('intregfile.cc')
+ Source('miscregfile.cc')
+ Source('predecoder.cc')
+ Source('predecoder_tables.cc')
+ Source('regfile.cc')
+ Source('remote_gdb.cc')
+
+ if env['FULL_SYSTEM']:
+ # Full-system sources
+ pass
+ else:
+ Source('process.cc')
+
+ Source('linux/linux.cc')
+ Source('linux/process.cc')
+ Source('linux/syscalls.cc')
+
+ # Add in files generated by the ISA description.
+ isa_desc_files = env.ISADesc('isa/main.isa')
+ # Only non-header files need to be compiled.
+ for f in isa_desc_files:
+ if not f.path.endswith('.hh'):
+ Source(f)
diff --git a/src/arch/x86/SConsopts b/src/arch/x86/SConsopts
new file mode 100644
index 000000000..d8b7cbed1
--- /dev/null
+++ b/src/arch/x86/SConsopts
@@ -0,0 +1,60 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2007 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use of this software in source and binary forms,
+# with or without modification, are permitted provided that the
+# following conditions are met:
+#
+# The software must be used only for Non-Commercial Use which means any
+# use which is NOT directed to receiving any direct monetary
+# compensation for, or commercial advantage from such use. Illustrative
+# examples of non-commercial use are academic research, personal study,
+# teaching, education and corporate research & development.
+# Illustrative examples of commercial use are distributing products for
+# commercial advantage and providing services using the software for
+# commercial advantage.
+#
+# If you wish to use this software or functionality therein that may be
+# covered by patents for commercial use, please contact:
+# Director of Intellectual Property Licensing
+# Office of Strategy and Technology
+# Hewlett-Packard Company
+# 1501 Page Mill Road
+# Palo Alto, California 94304
+#
+# 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission. No right of
+# sublicense is granted herewith. Derivatives of the software and
+# output created using the software may be prepared, but only for
+# Non-Commercial Uses. Derivatives of the software may be shared with
+# others provided: (i) the others agree to abide by the list of
+# conditions herein which includes the Non-Commercial Use restrictions;
+# and (ii) such Derivatives of the software include the above copyright
+# notice to acknowledge the contribution from this software where
+# applicable, this list of conditions and the disclaimer below.
+#
+# 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
+
+Import('*')
+
+all_isa_list.append('x86')
diff --git a/src/arch/x86/arguments.hh b/src/arch/x86/arguments.hh
new file mode 100644
index 000000000..e645766bf
--- /dev/null
+++ b/src/arch/x86/arguments.hh
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_ARGUMENTS_HH__
+#define __ARCH_X86_ARGUMENTS_HH__
+
+#error X86 is not yet supported!
+
+namespace X86ISA
+{
+};
+
+#endif // __ARCH_X86_ARGUMENTS_HH__
diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh
new file mode 100644
index 000000000..6d89c273a
--- /dev/null
+++ b/src/arch/x86/faults.hh
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_FAULTS_HH__
+#define __ARCH_X86_FAULTS_HH__
+
+#include "base/misc.hh"
+#include "sim/faults.hh"
+
+namespace X86ISA
+{
+ class X86Fault : public FaultBase
+ {
+ void invoke(ThreadContext * tc)
+ {
+ panic("X86 faults are not implemented!");
+ }
+ };
+
+ static inline Fault genPageTableFault(Addr va)
+ {
+ panic("Page table fault not implemented in x86!\n");
+ }
+
+ static inline Fault genMachineCheckFault()
+ {
+ panic("Machine check fault not implemented in x86!\n");
+ }
+
+ static inline Fault genAlignmentFault()
+ {
+ panic("Alignment fault not implemented (or for the most part existant) in x86!\n");
+ }
+};
+
+#endif // __ARCH_X86_FAULTS_HH__
diff --git a/src/arch/x86/floatregfile.cc b/src/arch/x86/floatregfile.cc
new file mode 100644
index 000000000..515ed0958
--- /dev/null
+++ b/src/arch/x86/floatregfile.cc
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2003-2007 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
+ */
+
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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/x86/floatregfile.hh"
+#include "sim/serialize.hh"
+
+#include <string.h>
+
+using namespace X86ISA;
+using namespace std;
+
+class Checkpoint;
+
+string X86ISA::getFloatRegName(RegIndex index)
+{
+ static std::string floatRegName[NumFloatRegs] =
+ {"mmx0", "mmx1", "mmx2", "mmx3", "mmx4", "mmx5", "mmx6", "mmx7",
+ "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
+ "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"};
+ return floatRegName[index];
+}
+
+void FloatRegFile::clear()
+{
+ memset(q, 0, sizeof(FloatReg) * NumFloatRegs);
+}
+
+FloatReg FloatRegFile::readReg(int floatReg, int width)
+{
+ panic("Floating point not implemented for x86!\n");
+}
+
+FloatRegBits FloatRegFile::readRegBits(int floatReg, int width)
+{
+ panic("Floating point not implemented for x86!\n");
+}
+
+Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width)
+{
+ panic("Floating point not implemented for x86!\n");
+}
+
+Fault FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width)
+{
+ panic("Floating point not implemented for x86!\n");
+}
+
+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/x86/floatregfile.hh b/src/arch/x86/floatregfile.hh
new file mode 100644
index 000000000..18371280d
--- /dev/null
+++ b/src/arch/x86/floatregfile.hh
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2003-2007 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
+ */
+
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_FLOATREGFILE_HH__
+#define __ARCH_X86_FLOATREGFILE_HH__
+
+#include <string>
+
+#include "arch/x86/faults.hh"
+#include "arch/x86/types.hh"
+#include "arch/x86/x86_traits.hh"
+
+class Checkpoint;
+
+namespace X86ISA
+{
+ std::string getFloatRegName(RegIndex);
+
+ const int NumFloatArchRegs = NumMMXRegs + NumXMMRegs;
+ const int NumFloatRegs = NumFloatArchRegs;
+
+ class FloatRegFile
+ {
+ public:
+ static const int SingleWidth = 32;
+ static const int DoubleWidth = 64;
+ static const int QuadWidth = 128;
+
+ protected:
+ union
+ {
+ uint64_t q[NumFloatRegs];
+ double d[NumFloatRegs];
+ };
+
+ public:
+ void clear();
+
+ FloatReg readReg(int floatReg, int width);
+
+ FloatRegBits readRegBits(int floatReg, int width);
+
+ Fault setReg(int floatReg, const FloatReg &val, int width);
+
+ Fault setRegBits(int floatReg, const FloatRegBits &val, int width);
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+ };
+}
+
+#endif //__ARCH_X86_FLOATREGFILE_HH__
diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh
new file mode 100644
index 000000000..3f33b8d85
--- /dev/null
+++ b/src/arch/x86/interrupts.hh
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_INTERRUPTS_HH__
+#define __ARCH_X86_INTERRUPTS_HH__
+
+#error X86 is not yet supported!
+
+namespace X86ISA
+{
+};
+
+#endif // __ARCH_X86_INTERRUPTS_HH__
diff --git a/src/arch/x86/intregfile.cc b/src/arch/x86/intregfile.cc
new file mode 100644
index 000000000..15e86d88b
--- /dev/null
+++ b/src/arch/x86/intregfile.cc
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2003-2007 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
+ */
+
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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/x86/intregfile.hh"
+#include "base/misc.hh"
+#include "sim/serialize.hh"
+
+#include <string.h>
+
+using namespace X86ISA;
+using namespace std;
+
+class Checkpoint;
+
+string X86ISA::getIntRegName(RegIndex index)
+{
+ //These might appear to be out of order, but they match
+ //the encoding for the registers. Who knows why the indexes
+ //are out of order
+ static std::string intRegName[NumIntArchRegs] =
+ {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"};
+ return intRegName[index];
+}
+
+int IntRegFile::flattenIndex(int reg)
+{
+ return reg;
+}
+
+void IntRegFile::clear()
+{
+ memset(regs, 0, sizeof(IntReg) * NumIntRegs);
+}
+
+IntReg IntRegFile::readReg(int intReg)
+{
+ return regs[intReg];
+}
+
+void IntRegFile::setReg(int intReg, const IntReg &val)
+{
+ regs[intReg] = val;
+}
+
+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/x86/intregfile.hh b/src/arch/x86/intregfile.hh
new file mode 100644
index 000000000..f7b03f0f0
--- /dev/null
+++ b/src/arch/x86/intregfile.hh
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2003-2007 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
+ */
+
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_INTREGFILE_HH__
+#define __ARCH_X86_INTREGFILE_HH__
+
+#include "arch/x86/intregs.hh"
+#include "arch/x86/types.hh"
+#include "arch/x86/x86_traits.hh"
+
+#include <string>
+
+class Checkpoint;
+
+namespace X86ISA
+{
+ class Regfile;
+
+ //This function translates integer register file indices into names
+ std::string getIntRegName(RegIndex);
+
+ const int NumIntArchRegs = NUM_INTREGS;
+ const int NumIntRegs = NumIntArchRegs + NumMicroIntRegs;
+
+ class IntRegFile
+ {
+ protected:
+ IntReg regs[NumIntRegs];
+
+ public:
+
+ int flattenIndex(int reg);
+
+ void clear();
+
+ IntReg readReg(int intReg);
+
+ void setReg(int intReg, const IntReg &val);
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+ };
+}
+
+#endif //__ARCH_X86_INTREGFILE__
diff --git a/src/arch/x86/intregs.hh b/src/arch/x86/intregs.hh
new file mode 100644
index 000000000..ed801cc48
--- /dev/null
+++ b/src/arch/x86/intregs.hh
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_INTREGS_HH__
+#define __ARCH_X86_INTREGS_HH__
+
+namespace X86ISA
+{
+ enum IntRegIndex
+ {
+ INTREG_RAX,
+ INTREG_RCX,
+ INTREG_RDX,
+ INTREG_RBX,
+ INTREG_RSP,
+ INTREG_RBP,
+ INTREG_RSI,
+ INTREG_RDI,
+ INTREG_R8W,
+ INTREG_R9W,
+ INTREG_R10W,
+ INTREG_R11W,
+ INTREG_R12W,
+ INTREG_R13W,
+ INTREG_R14W,
+ INTREG_R15W,
+ NUM_INTREGS
+ };
+};
+
+#endif // __ARCH_X86_INTERRUPTS_HH__
diff --git a/src/arch/x86/isa/base.isa b/src/arch/x86/isa/base.isa
new file mode 100644
index 000000000..4776f7a7e
--- /dev/null
+++ b/src/arch/x86/isa/base.isa
@@ -0,0 +1,181 @@
+// Copyright (c) 2007 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Base class for sparc instructions, and some support functions
+//
+
+output header {{
+
+ /**
+ * Base class for all X86 static instructions.
+ */
+ class X86StaticInst : public StaticInst
+ {
+ protected:
+ // Constructor.
+ X86StaticInst(const char *mnem,
+ ExtMachInst _machInst, OpClass __opClass)
+ : StaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
+ void printReg(std::ostream &os, int reg) const;
+ void printSrcReg(std::ostream &os, int reg) const;
+ void printDestReg(std::ostream &os, int reg) const;
+ };
+}};
+
+output decoder {{
+
+ inline void printMnemonic(std::ostream &os, const char * mnemonic)
+ {
+ ccprintf(os, "\t%s ", mnemonic);
+ }
+
+ void
+ X86StaticInst::printSrcReg(std::ostream &os, int reg) const
+ {
+ if(_numSrcRegs > reg)
+ printReg(os, _srcRegIdx[reg]);
+ }
+
+ void
+ X86StaticInst::printDestReg(std::ostream &os, int reg) const
+ {
+ if(_numDestRegs > reg)
+ printReg(os, _destRegIdx[reg]);
+ }
+
+ void
+ X86StaticInst::printReg(std::ostream &os, int reg) const
+ {
+ if (reg < FP_Base_DepTag) {
+ //FIXME These should print differently depending on the
+ //mode etc, but for now this will get the point across
+ switch (reg) {
+ case INTREG_RAX:
+ ccprintf(os, "rax");
+ break;
+ case INTREG_RBX:
+ ccprintf(os, "rbx");
+ break;
+ case INTREG_RCX:
+ ccprintf(os, "rcx");
+ break;
+ case INTREG_RDX:
+ ccprintf(os, "rdx");
+ break;
+ case INTREG_RSP:
+ ccprintf(os, "rsp");
+ break;
+ case INTREG_RBP:
+ ccprintf(os, "rbp");
+ break;
+ case INTREG_RSI:
+ ccprintf(os, "rsi");
+ break;
+ case INTREG_RDI:
+ ccprintf(os, "rdi");
+ break;
+ case INTREG_R8W:
+ ccprintf(os, "r8");
+ break;
+ case INTREG_R9W:
+ ccprintf(os, "r9");
+ break;
+ case INTREG_R10W:
+ ccprintf(os, "r10");
+ break;
+ case INTREG_R11W:
+ ccprintf(os, "r11");
+ break;
+ case INTREG_R12W:
+ ccprintf(os, "r12");
+ break;
+ case INTREG_R13W:
+ ccprintf(os, "r13");
+ break;
+ case INTREG_R14W:
+ ccprintf(os, "r14");
+ break;
+ case INTREG_R15W:
+ ccprintf(os, "r15");
+ break;
+ }
+ } else if (reg < Ctrl_Base_DepTag) {
+ ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
+ } else {
+ switch (reg - Ctrl_Base_DepTag) {
+ default:
+ ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag);
+ }
+ }
+ }
+
+ std::string X86StaticInst::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+
+ printMnemonic(ss, mnemonic);
+
+ return ss.str();
+ }
+}};
diff --git a/src/arch/x86/isa/bitfields.isa b/src/arch/x86/isa/bitfields.isa
new file mode 100644
index 000000000..fff324caa
--- /dev/null
+++ b/src/arch/x86/isa/bitfields.isa
@@ -0,0 +1,87 @@
+// Copyright (c) 2007 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Bitfield definitions.
+//
+
+//Prefixes
+def bitfield REX rex;
+def bitfield LEGACY legacy;
+
+// Pieces of the opcode
+def bitfield OPCODE_NUM opcode.num;
+def bitfield OPCODE_PREFIXA opcode.prefixA;
+def bitfield OPCODE_PREFIXB opcode.prefixB;
+def bitfield OPCODE_OP opcode.op;
+//The top 5 bits of the opcode tend to split the instructions into groups
+def bitfield OPCODE_OP_TOP5 opcode.op.top5;
+def bitfield OPCODE_OP_BOTTOM3 opcode.op.bottom3;
+
+// Immediate fields
+def bitfield IMMEDIATE immediate;
+def bitfield DISPLACEMENT displacement;
+
+//Modifier bytes
+def bitfield MODRM modRM;
+def bitfield MODRM_MOD modRM.mod;
+def bitfield MODRM_REG modRM.reg;
+def bitfield MODRM_RM modRM.rm;
+
+def bitfield SIB sib;
+def bitfield SIB_SCALE sib.scale;
+def bitfield SIB_INDEX sib.index;
+def bitfield SIB_BASE sib.base;
diff --git a/src/arch/x86/isa/decoder/decoder.isa b/src/arch/x86/isa/decoder/decoder.isa
new file mode 100644
index 000000000..20f31f882
--- /dev/null
+++ b/src/arch/x86/isa/decoder/decoder.isa
@@ -0,0 +1,89 @@
+// Copyright (c) 2007 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// The actual decoder specification
+//
+
+decode OPCODE_NUM default Unknown::unknown()
+{
+ 0x0: M5InternalError::error(
+ {{"Saw an ExtMachInst with zero opcode bytes!"}});
+ //1 byte opcodes
+ ##include "one_byte_opcodes.isa"
+ //2 byte opcodes
+ ##include "two_byte_opcodes.isa"
+ //3 byte opcodes
+ 0x3: decode OPCODE_PREFIXA {
+ 0xF0: decode OPCODE_PREFIXB {
+ //We don't handle these properly in the predecoder yet, so there's
+ //no reason to implement them for now.
+ 0x38: decode OPCODE_OP {
+ default: FailUnimpl::sseThreeEight();
+ }
+ 0x3A: decode OPCODE_OP {
+ default: FailUnimpl::sseThreeA();
+ }
+ 0xF0: decode OPCODE_OP {
+ default: FailUnimpl::threednow();
+ }
+ default: M5InternalError::error(
+ {{"Unexpected second opcode byte in three byte opcode!"}});
+ }
+ default: M5InternalError::error(
+ {{"Unexpected first opcode byte in three byte opcode!"}});
+ }
+}
diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
new file mode 100644
index 000000000..c56a8bf92
--- /dev/null
+++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
@@ -0,0 +1,398 @@
+// Copyright (c) 2007 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Decode the one byte opcodes
+//
+
+0x1: decode OPCODE_OP_TOP5 {
+ format WarnUnimpl {
+ 0x00: decode OPCODE_OP_BOTTOM3 {
+ 0x6: push_ES();
+ 0x7: pop_ES();
+ default: MultiOp::add(
+ {{out1 = in1 + in2}},
+ OPCODE_OP_BOTTOM3,
+ [[Eb,Gb],[Ev,Gv],
+ [Gb,Eb],[Gv,Ev],
+ [Al,Ib],[rAx,Iz]]);
+ }
+ 0x01: decode OPCODE_OP_BOTTOM3 {
+ 0x0: or_Eb_Gb();
+ 0x1: or_Ev_Gv();
+ 0x2: or_Gb_Eb();
+ 0x3: or_Gv_Ev();
+ 0x4: or_Al_Ib();
+ 0x5: or_rAX_Iz();
+ 0x6: push_CS();
+ //Any time this is seen, it should generate a two byte opcode
+ 0x7: M5InternalError::error(
+ {{"Saw a one byte opcode whose value was 0x0F!"}});
+ }
+ 0x02: decode OPCODE_OP_BOTTOM3 {
+ 0x0: adc_Eb_Gb();
+ 0x1: adc_Ev_Gv();
+ 0x2: adc_Gb_Eb();
+ 0x3: adc_Gv_Ev();
+ 0x4: adc_Al_Ib();
+ 0x5: adc_rAX_Iz();
+ 0x6: push_SS();
+ 0x7: pop_SS();
+ }
+ 0x03: decode OPCODE_OP_BOTTOM3 {
+ 0x0: sbb_Eb_Gb();
+ 0x1: sbb_Ev_Gv();
+ 0x2: sbb_Gb_Eb();
+ 0x3: sbb_Gv_Ev();
+ 0x4: sbb_Al_Ib();
+ 0x5: sbb_rAX_Iz();
+ 0x6: push_DS();
+ 0x7: pop_DS();
+ }
+ 0x04: decode OPCODE_OP_BOTTOM3 {
+ 0x0: and_Eb_Gb();
+ 0x1: and_Ev_Gv();
+ 0x2: and_Gb_Eb();
+ 0x3: and_Gv_Ev();
+ 0x4: and_Al_Ib();
+ 0x5: and_rAX_Iz();
+ 0x6: M5InternalError::error(
+ {{"Tried to execute the ES segment override prefix!"}});
+ 0x7: daa();
+ }
+ 0x05: decode OPCODE_OP_BOTTOM3 {
+ 0x0: sub_Eb_Gb();
+ 0x1: sub_Ev_Gv();
+ 0x2: sub_Gb_Eb();
+ 0x3: sub_Gv_Ev();
+ 0x4: sub_Al_Ib();
+ 0x5: sub_rAX_Iz();
+ 0x6: M5InternalError::error(
+ {{"Tried to execute the CS segment override prefix!"}});
+ 0x7: das();
+ }
+ 0x06: decode OPCODE_OP_BOTTOM3 {
+ 0x0: xor_Eb_Gb();
+ 0x1: xor_Ev_Gv();
+ 0x2: xor_Gb_Eb();
+ 0x3: xor_Gv_Ev();
+ 0x4: xor_Al_Ib();
+ 0x5: xor_rAX_Iz();
+ 0x6: M5InternalError::error(
+ {{"Tried to execute the SS segment override prefix!"}});
+ 0x7: aaa();
+ }
+ 0x07: decode OPCODE_OP_BOTTOM3 {
+ 0x0: cmp_Eb_Gb();
+ 0x1: cmp_Ev_Gv();
+ 0x2: cmp_Gb_Eb();
+ 0x3: cmp_Gv_Ev();
+ 0x4: cmp_Al_Ib();
+ 0x5: cmp_rAX_Iz();
+ 0x6: M5InternalError::error(
+ {{"Tried to execute the DS segment override prefix!"}});
+ 0x7: aas();
+ }
+ 0x08: decode OPCODE_OP_BOTTOM3 {
+ 0x0: inc_eAX();
+ 0x1: inc_eCX();
+ 0x2: inc_eDX();
+ 0x3: inc_eBX();
+ 0x4: inc_eSP();
+ 0x5: inc_eBP();
+ 0x6: inc_eSI();
+ 0x7: inc_eDI();
+ }
+ 0x09: decode OPCODE_OP_BOTTOM3 {
+ 0x0: dec_eAX();
+ 0x1: dec_eCX();
+ 0x2: dec_eDX();
+ 0x3: dec_eBX();
+ 0x4: dec_eSP();
+ 0x5: dec_eBP();
+ 0x6: dec_eSI();
+ 0x7: dec_eDI();
+ }
+ 0x0A: decode OPCODE_OP_BOTTOM3 {
+ 0x0: push_rAX();
+ 0x1: push_rCX();
+ 0x2: push_rDX();
+ 0x3: push_rBX();
+ 0x4: push_rSP();
+ 0x5: push_rBP();
+ 0x6: push_rSI();
+ 0x7: push_rDI();
+ }
+ 0x0B: decode OPCODE_OP_BOTTOM3 {
+ 0x0: pop_rAX();
+ 0x1: pop_rCX();
+ 0x2: pop_rDX();
+ 0x3: pop_rBX();
+ 0x4: pop_rSP();
+ 0x5: pop_rBP();
+ 0x6: pop_rSI();
+ 0x7: pop_rDI();
+ }
+ 0x0C: decode OPCODE_OP_BOTTOM3 {
+ 0x0: pusha();
+ 0x1: popa();
+ 0x2: bound_Gv_Ma();
+ 0x3: arpl_Ew_Gw();
+ 0x4: M5InternalError::error(
+ {{"Tried to execute the FS segment override prefix!"}});
+ 0x5: M5InternalError::error(
+ {{"Tried to execute the GS segment override prefix!"}});
+ 0x6: M5InternalError::error(
+ {{"Tried to execute the operand size override prefix!"}});
+ 0x7: M5InternalError::error(
+ {{"Tried to execute the DS address size override prefix!"}});
+ }
+ 0x0D: decode OPCODE_OP_BOTTOM3 {
+ 0x0: push_Iz();
+ 0x1: imul_Gv_Ev_Iz();
+ 0x2: push_Ib();
+ 0x3: imul_Gv_Ev_Ib();
+ 0x4: ins_Yb_Dx();
+ 0x5: ins_Yz_Dx();
+ 0x6: outs_Dx_Xb();
+ 0x7: outs_Dx_Xz();
+ }
+ 0x0E: decode OPCODE_OP_BOTTOM3 {
+ 0x0: jo_Jb();
+ 0x1: jno_Jb();
+ 0x2: jb_Jb();
+ 0x3: jnb_Jb();
+ 0x4: jz_Jb();
+ 0x5: jnz_Jb();
+ 0x6: jbe_Jb();
+ 0x7: jnbe_Jb();
+ }
+ 0x0F: decode OPCODE_OP_BOTTOM3 {
+ 0x0: js_Jb();
+ 0x1: jns_Jb();
+ 0x2: jp_Jb();
+ 0x3: jnp_Jb();
+ 0x4: jl_Jb();
+ 0x5: jnl_Jb();
+ 0x6: jle_Jb();
+ 0x7: jnke_Jb();
+ }
+ 0x10: decode OPCODE_OP_BOTTOM3 {
+ 0x0: group1_Eb_Ib();
+ 0x1: group1_Ev_Iz();
+ 0x2: group1_Eb_Ib();
+ 0x3: group1_Ev_Ib();
+ 0x4: test_Eb_Gb();
+ 0x5: test_Ev_Gv();
+ 0x6: xchg_Eb_Gb();
+ 0x7: xchg_Ev_Gv();
+ }
+ 0x11: decode OPCODE_OP_BOTTOM3 {
+ 0x0: mov_Eb_Gb();
+ 0x1: mov_Ev_Gv();
+ 0x2: mov_Gb_Eb();
+ 0x3: mov_Gv_Ev();
+ 0x4: mov_MwRv_Sw();
+ 0x5: lea_Gv_M();
+ 0x6: mov_Sw_MwRv();
+ 0x7: group10_Ev(); //Make sure this is Ev
+ }
+ 0x12: decode OPCODE_OP_BOTTOM3 {
+ 0x0: nop_or_pause(); //Check for repe prefix
+ 0x1: xchg_rCX_rAX();
+ 0x2: xchg_rDX_rAX();
+ 0x3: xchg_rVX_rAX();
+ 0x4: xchg_rSP_rAX();
+ 0x5: xchg_rBP_rAX();
+ 0x6: xchg_rSI_rAX();
+ 0x7: xchg_rDI_rAX();
+ }
+ 0x13: decode OPCODE_OP_BOTTOM3 {
+ 0x0: cbw_or_cwde_or_cdqe_rAX();
+ 0x1: cwd_or_cdq_or_cqo_rAX_rDX();
+ 0x2: call_Ap();
+ 0x3: fwait(); //aka wait
+ 0x4: pushf_Fv();
+ 0x5: popf_Fv();
+ 0x6: sahf();
+ 0x7: lahf();
+ }
+ 0x14: decode OPCODE_OP_BOTTOM3 {
+ 0x0: mov_Al_Ob();
+ 0x1: mov_rAX_Ov();
+ 0x2: mov_Ob_Al();
+ 0x3: mov_Ov_rAX();
+ 0x4: movs_Yb_Xb();
+ 0x5: movs_Yv_Xv();
+ 0x6: cmps_Yb_Xb();
+ 0x7: cmps_Yv_Xv();
+ }
+ 0x15: decode OPCODE_OP_BOTTOM3 {
+ 0x0: test_Al_Ib();
+ 0x1: test_rAX_Iz();
+ 0x2: stos_Yb_Al();
+ 0x3: stos_Yv_rAX();
+ 0x4: lods_Al_Xb();
+ 0x5: lods_rAX_Xv();
+ 0x6: scas_Yb_Al();
+ 0x7: scas_Yv_rAX();
+ }
+ 0x16: decode OPCODE_OP_BOTTOM3 {
+ 0x0: mov_Al_Ib();
+ 0x1: mov_Cl_Ib();
+ 0x2: mov_Dl_Ib();
+ 0x3: mov_Bl_Ib();
+ 0x4: mov_Ah_Ib();
+ 0x5: mov_Ch_Ib();
+ 0x6: mov_Dh_Ib();
+ 0x7: mov_Bh_Ib();
+ }
+ 0x17: decode OPCODE_OP_BOTTOM3 {
+ 0x0: mov_rAX_Iv();
+ 0x1: mov_rCX_Iv();
+ 0x2: mov_rDX_Iv();
+ 0x3: mov_rBX_Iv();
+ 0x4: mov_rSP_Iv();
+ 0x5: mov_rBP_Iv();
+ 0x6: mov_rSI_Iv();
+ 0x7: mov_rDI_Iv();
+ }
+ 0x18: decode OPCODE_OP_BOTTOM3 {
+ 0x0: group2_Eb_Ib();
+ 0x1: group2_Ev_Ib();
+ 0x2: ret_near_Iw();
+ 0x3: ret_near();
+ 0x4: les_Gz_Mp();
+ 0x5: lds_Gz_Mp();
+ 0x6: group12_Eb_Ib();
+ 0x7: group12_Ev_Iz();
+ }
+ 0x19: decode OPCODE_OP_BOTTOM3 {
+ 0x0: enter_Iw_Ib();
+ 0x1: leave();
+ 0x2: ret_far_Iw();
+ 0x3: ret_far();
+ 0x4: int3();
+ 0x5: int_Ib();
+ 0x6: into();
+ 0x7: iret();
+ }
+ 0x1A: decode OPCODE_OP_BOTTOM3 {
+ 0x0: group2_Eb_1();
+ 0x1: group2_Ev_1();
+ 0x2: group2_Eb_Cl();
+ 0x3: group2_Ev_Cl();
+ 0x4: aam_Ib();
+ 0x5: aad_Ib();
+ 0x6: salc();
+ 0x7: xlat();
+ }
+ 0x1B: decode OPCODE_OP_BOTTOM3 {
+ 0x0: esc0();
+ 0x1: esc1();
+ 0x2: esc2();
+ 0x3: esc3();
+ 0x4: esc4();
+ 0x5: esc5();
+ 0x6: esc6();
+ 0x7: esc7();
+ }
+ 0x1C: decode OPCODE_OP_BOTTOM3 {
+ 0x0: loopne_Jb();
+ 0x1: loope_Jb();
+ 0x2: loop_Jb();
+ 0x3: jcxz_or_jecx_or_jrcx();
+ 0x4: in_Al_Ib();
+ 0x5: in_eAX_Ib();
+ 0x6: out_Ib_Al();
+ 0x7: out_Ib_eAX();
+ }
+ 0x1D: decode OPCODE_OP_BOTTOM3 {
+ 0x0: call_Jz();
+ 0x1: jmp_Jz();
+ 0x2: jmp_Ap();
+ 0x3: jmp_Jb();
+ 0x4: in_Al_Dx();
+ 0x5: in_eAX_Dx();
+ 0x6: out_Dx_Al();
+ 0x7: out_Dx_eAX();
+ }
+ 0x1E: decode OPCODE_OP_BOTTOM3 {
+ 0x0: M5InternalError::error(
+ {{"Tried to execute the lock prefix!"}});
+ 0x1: int1();
+ 0x2: M5InternalError::error(
+ {{"Tried to execute the repne prefix!"}});
+ 0x3: M5InternalError::error(
+ {{"Tried to execute the rep/repe prefix!"}});
+ 0x4: hlt();
+ 0x5: cmc();
+ 0x6: group3_Eb();
+ 0x7: group3_Ev();
+ }
+ 0x1F: decode OPCODE_OP_BOTTOM3 {
+ 0x0: clc();
+ 0x1: stc();
+ 0x2: cli();
+ 0x3: sti();
+ 0x4: cld();
+ 0x5: std();
+ 0x6: group4();
+ 0x7: group5();
+ }
+ }
+ default: FailUnimpl::oneByteOps();
+}
diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
new file mode 100644
index 000000000..f05c33bdb
--- /dev/null
+++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
@@ -0,0 +1,393 @@
+// Copyright (c) 2007 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Decode the two byte opcodes
+//
+0x2: decode OPCODE_PREFIXA {
+ 0xF0: decode OPCODE_OP_TOP5 {
+ format WarnUnimpl {
+ 0x00: decode OPCODE_OP_BOTTOM3 {
+ 0x00: group6();
+ 0x01: group7();
+ 0x02: lar_Gv_Ew();
+ 0x03: lsl_Gv_Ew();
+ //sandpile.org doesn't seem to know what this is... ?
+ 0x04: loadall_or_reset_or_hang();
+ //sandpile.org says (AMD) after syscall, so I might want to check
+ //if that means amd64 or AMD machines
+ 0x05: loadall_or_syscall();
+ 0x06: clts();
+ //sandpile.org says (AMD) after sysret, so I might want to check
+ //if that means amd64 or AMD machines
+ 0x07: loadall_or_sysret();
+ }
+ 0x01: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holderholder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x02: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x03: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x04: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x05: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x06: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x07: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x08: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x09: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x0A: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x0B: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x0C: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x0D: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x0E: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x0F: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x10: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x11: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x12: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x13: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x14: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x15: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x16: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x17: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x18: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x19: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x1A: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x1B: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x1C: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x1D: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x1E: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x1F: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ default: FailUnimpl::twoByteOps();
+ }
+ }
+ default: M5InternalError::error(
+ {{"Unexpected first opcode byte in two byte opcode!"}});
+}
diff --git a/src/arch/x86/isa/formats/basic.isa b/src/arch/x86/isa/formats/basic.isa
new file mode 100644
index 000000000..ea224d638
--- /dev/null
+++ b/src/arch/x86/isa/formats/basic.isa
@@ -0,0 +1,158 @@
+// Copyright (c) 2007 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
+
+// Copyright (c) 2007 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// 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
+
+// Declarations for execute() methods.
+def template BasicExecDeclare {{
+ Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+// Definitions of execute methods that panic.
+def template BasicExecPanic {{
+ Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
+ {
+ panic("Execute method called when it shouldn't!");
+ M5_DUMMY_RETURN
+ }
+}};
+
+// Basic instruction class declaration template.
+def template BasicDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+ // Constructor.
+ %(class_name)s(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ };
+}};
+
+// Basic instruction class constructor template.
+def template BasicConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
+ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+ {
+ %(constructor)s;
+ }
+}};
+
+// Basic instruction class execute method template.
+def template BasicExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
+
+ if(fault == NoFault)
+ {
+ %(op_wb)s;
+ }
+ return fault;
+ }
+}};
+
+// Basic decode template.
+def template BasicDecode {{
+ return new %(class_name)s(machInst);
+}};
+
+// Basic decode template, passing mnemonic in as string arg to constructor.
+def template BasicDecodeWithMnemonic {{
+ return new %(class_name)s("%(mnemonic)s", machInst);
+}};
+
+// The most basic instruction format... used only for a few misc. insts
+def format BasicOperate(code, *flags) {{
+ iop = InstObjParams(name, Name, 'SparcStaticInst', code, flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
diff --git a/src/arch/x86/isa/formats/error.isa b/src/arch/x86/isa/formats/error.isa
new file mode 100644
index 000000000..8ac2ea44d
--- /dev/null
+++ b/src/arch/x86/isa/formats/error.isa
@@ -0,0 +1,77 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// "Format" which really indicates an internal error. This is a more
+// significant problem for x86 than for other ISAs because of it's complex
+// ExtMachInst type.
+//
+
+def template ErrorDecode {{
+ {
+ panic("X86 decoder internal error: '%%s' %%s",
+ %(message)s, machInst);
+ }
+}};
+
+def format M5InternalError(error_message) {{
+ iop = InstObjParams(name, 'M5InternalError')
+ iop.message = error_message
+ decode_block = ErrorDecode.subst(iop)
+}};
+
diff --git a/src/arch/x86/isa/formats/formats.isa b/src/arch/x86/isa/formats/formats.isa
new file mode 100644
index 000000000..d763c05bc
--- /dev/null
+++ b/src/arch/x86/isa/formats/formats.isa
@@ -0,0 +1,100 @@
+// Copyright (c) 2007 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
+
+// Copyright (c) 2007 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// 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 the basic format
+//Templates from this format are used later
+##include "basic.isa"
+
+//Include the "unknown" format
+##include "unknown.isa"
+
+//Include the "unimp" format
+##include "unimp.isa"
+
+//Include a format to signal m5 internal errors. This is used to indicate a
+//malfunction of the decode mechanism.
+##include "error.isa"
+
+//Include a format which implements a batch of instructions which do the same
+//thing on a variety of inputs
+##include "multi.isa"
diff --git a/src/arch/x86/isa/formats/multi.isa b/src/arch/x86/isa/formats/multi.isa
new file mode 100644
index 000000000..3e80f9cfb
--- /dev/null
+++ b/src/arch/x86/isa/formats/multi.isa
@@ -0,0 +1,106 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Instructions that do the same thing to multiple sets of arguments.
+//
+
+output header {{
+}};
+
+output decoder {{
+}};
+
+output exec {{
+}};
+
+let {{
+ multiops = {}
+}};
+
+def format MultiOp(code, switchVal, opTags, *opt_flags) {{
+ # Loads and stores that bring in and write out values from the
+ # instructions. These are determined by the input and output tags,
+ # and the resulting instruction will have the right number of micro ops,
+ # or could be implemented as an atomic macro op.
+ instNames = []
+ for tagSet in opTags:
+ loads = []
+ stores = []
+ postfix = ''
+ for tag in tagSet:
+ postfix += '_' + tag
+ gather_inputs = ''
+ if len(loads) + len(stores) == 0:
+ # If there are no loads or stores, make this a single instruction.
+ iop = InstObjParams(name, Name + postfix, 'X86StaticInst',
+ {"code": code, "gather_inputs": gather_inputs},
+ opt_flags)
+ else:
+ # Build up a macro op. We'll punt on this for now
+ pass
+
+ decodeBlob = 'switch(%s) {\n' % switchVal
+ counter = 0
+ for inst in instNames:
+ decodeBlob += '%d: return (X86StaticInst *)(new %s(machInst));\n' % \
+ (counter, inst)
+ counter += 1
+ decodeBlob += '}\n'
+ # decode_block = BasicDecodeWithMnemonic.subst(iop)
+}};
diff --git a/src/arch/x86/isa/formats/unimp.isa b/src/arch/x86/isa/formats/unimp.isa
new file mode 100644
index 000000000..12fa8387b
--- /dev/null
+++ b/src/arch/x86/isa/formats/unimp.isa
@@ -0,0 +1,174 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Unimplemented instructions
+//
+
+output header {{
+ /**
+ * Static instruction class for unimplemented instructions that
+ * cause simulator termination. Note that these are recognized
+ * (legal) instructions that the simulator does not support; the
+ * 'Unknown' class is used for unrecognized/illegal instructions.
+ * This is a leaf class.
+ */
+ class FailUnimplemented : public X86StaticInst
+ {
+ public:
+ /// Constructor
+ FailUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
+ : X86StaticInst(_mnemonic, _machInst, No_OpClass)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Base class for unimplemented instructions that cause a warning
+ * to be printed (but do not terminate simulation). This
+ * implementation is a little screwy in that it will print a
+ * warning for each instance of a particular unimplemented machine
+ * instruction, not just for each unimplemented opcode. Should
+ * probably make the 'warned' flag a static member of the derived
+ * class.
+ */
+ class WarnUnimplemented : public X86StaticInst
+ {
+ private:
+ /// Have we warned on this instruction yet?
+ mutable bool warned;
+
+ public:
+ /// Constructor
+ WarnUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
+ : X86StaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ std::string
+ FailUnimplemented::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s (unimplemented)", mnemonic);
+ }
+
+ std::string
+ WarnUnimplemented::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+#ifdef SS_COMPATIBLE_DISASSEMBLY
+ return csprintf("%-10s", mnemonic);
+#else
+ return csprintf("%-10s (unimplemented)", mnemonic);
+#endif
+ }
+}};
+
+output exec {{
+ Fault
+ FailUnimplemented::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("attempt to execute unimplemented instruction '%s' %s",
+ mnemonic, machInst);
+ return NoFault;
+ }
+
+ Fault
+ WarnUnimplemented::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ if (!warned) {
+ warn("instruction '%s' unimplemented\n", mnemonic);
+ warned = true;
+ }
+
+ return NoFault;
+ }
+}};
+
+
+def format FailUnimpl() {{
+ iop = InstObjParams(name, 'FailUnimplemented')
+ decode_block = BasicDecodeWithMnemonic.subst(iop)
+}};
+
+def format WarnUnimpl() {{
+ iop = InstObjParams(name, 'WarnUnimplemented')
+ decode_block = BasicDecodeWithMnemonic.subst(iop)
+}};
+
diff --git a/src/arch/x86/isa/formats/unknown.isa b/src/arch/x86/isa/formats/unknown.isa
new file mode 100644
index 000000000..43ddc20c1
--- /dev/null
+++ b/src/arch/x86/isa/formats/unknown.isa
@@ -0,0 +1,130 @@
+// Copyright (c) 2007 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
+
+// Copyright (c) 2007 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Unknown instructions
+//
+
+output header {{
+ /**
+ * Class for Unknown/Illegal instructions
+ */
+ class Unknown : public StaticInst
+ {
+ public:
+
+ // Constructor
+ Unknown(ExtMachInst _machInst) :
+ StaticInst("unknown", _machInst, No_OpClass)
+ {
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
+ };
+}};
+
+output decoder {{
+ std::string Unknown::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return "Unknown instruction";
+ }
+}};
+
+output exec {{
+ Fault Unknown::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ warn("No instructions are implemented for X86!\n");
+ return NoFault;
+ }
+}};
+
+def format Unknown() {{
+ decode_block = 'return new Unknown(machInst);\n'
+}};
diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa
new file mode 100644
index 000000000..65e735b03
--- /dev/null
+++ b/src/arch/x86/isa/includes.isa
@@ -0,0 +1,143 @@
+// Copyright (c) 2007 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
+
+// Copyright (c) 2007 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Output include file directives.
+//
+
+output header {{
+#include <cstring>
+#include <sstream>
+#include <iostream>
+
+#include "arch/x86/faults.hh"
+#include "arch/x86/isa_traits.hh"
+#include "arch/x86/regfile.hh"
+#include "base/misc.hh"
+#include "cpu/static_inst.hh"
+#include "mem/packet.hh"
+#include "mem/request.hh" // some constructors use MemReq flags
+}};
+
+output decoder {{
+#include "base/cprintf.hh"
+#include "base/loader/symtab.hh"
+#include "cpu/thread_context.hh" // for Jump::branchTarget()
+#include "mem/packet.hh"
+
+#if defined(linux) || defined(__APPLE__)
+#include <fenv.h>
+#endif
+#include <algorithm>
+
+using namespace X86ISA;
+}};
+
+output exec {{
+#if defined(linux) || defined(__APPLE__)
+#include <fenv.h>
+#endif
+
+#if defined(__sun) || defined (__OpenBSD__)
+#include <ieeefp.h>
+#endif
+
+#if FULL_SYSTEM
+#include "sim/pseudo_inst.hh"
+#endif
+
+#include <limits>
+
+#include <cmath>
+#include "base/bigint.hh"
+#include "cpu/base.hh"
+#include "cpu/exetrace.hh"
+#include "sim/sim_exit.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+
+using namespace X86ISA;
+using namespace std;
+}};
+
diff --git a/src/arch/x86/isa/main.isa b/src/arch/x86/isa/main.isa
new file mode 100644
index 000000000..146f714a7
--- /dev/null
+++ b/src/arch/x86/isa/main.isa
@@ -0,0 +1,88 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// X86 ISA description file.
+//
+////////////////////////////////////////////////////////////////////
+
+//Include the C++ include directives
+##include "includes.isa"
+
+////////////////////////////////////////////////////////////////////
+//
+// Namespace statement. Everything below this line will be in the
+// SparcISAInst namespace.
+//
+
+namespace X86ISA;
+
+//Include the bitfield definitions
+##include "bitfields.isa"
+
+//Include the operand_types and operand definitions
+##include "operands.isa"
+
+//Include the base class for x86 instructions, and some support code
+##include "base.isa"
+
+//Include the definitions for the instruction formats
+##include "formats/formats.isa"
+
+//Include the decoder definition
+##include "decoder/decoder.isa"
diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa
new file mode 100644
index 000000000..20376f38f
--- /dev/null
+++ b/src/arch/x86/isa/operands.isa
@@ -0,0 +1,102 @@
+// Copyright (c) 2007 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
+
+// Copyright (c) 2007 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// 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
+
+def operand_types {{
+ 'sb' : ('signed int', 8),
+ 'ub' : ('unsigned int', 8),
+ 'sw' : ('signed int', 16),
+ 'uw' : ('unsigned int', 16),
+ 'sdw' : ('signed int', 32),
+ 'udw' : ('unsigned int', 32),
+ 'sqw' : ('signed int', 64),
+ 'uqw' : ('unsigned int', 64),
+ 'sf' : ('float', 32),
+ 'df' : ('float', 64),
+ 'qf' : ('float', 128)
+}};
+
+def operands {{
+ # This is just copied from SPARC, because having no operands confuses
+ # the parser.
+ 'Rd': ('IntReg', 'udw', 'RD', 'IsInteger', 1)
+}};
diff --git a/src/arch/x86/isa_traits.hh b/src/arch/x86/isa_traits.hh
new file mode 100644
index 000000000..5a625f741
--- /dev/null
+++ b/src/arch/x86/isa_traits.hh
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_ISATRAITS_HH__
+#define __ARCH_X86_ISATRAITS_HH__
+
+#include "arch/x86/intregs.hh"
+#include "arch/x86/types.hh"
+#include "arch/x86/x86_traits.hh"
+
+class StaticInstPtr;
+
+namespace LittleEndianGuest {}
+
+namespace X86ISA
+{
+ //This makes sure the little endian version of certain functions
+ //are used.
+ using namespace LittleEndianGuest;
+
+ // X86 does not have a delay slot
+#define ISA_HAS_DELAY_SLOT 0
+
+ // X86 NOP (XCHG rAX, rAX)
+ //XXX This needs to be set to an intermediate instruction struct
+ //which encodes this instruction
+
+ // These enumerate all the registers for dependence tracking.
+ enum DependenceTags {
+ //The number of microcode registers needs to be added to this
+ FP_Base_DepTag = 16,
+ Ctrl_Base_DepTag =
+ FP_Base_DepTag +
+ //mmx/x87 registers
+ 8 +
+ //xmm registers
+ 16
+ };
+
+ // semantically meaningful register indices
+ //There is no such register in X86
+ const int ZeroReg = 0;
+ const int StackPointerReg = INTREG_RSP;
+ //X86 doesn't seem to have a link register
+ const int ReturnAddressReg = 0;
+ const int ReturnValueReg = INTREG_RAX;
+ const int FramePointerReg = INTREG_RBP;
+ const int ArgumentReg0 = INTREG_RDI;
+ const int ArgumentReg1 = INTREG_RSI;
+ const int ArgumentReg2 = INTREG_RDX;
+ const int ArgumentReg3 = INTREG_RCX;
+ const int ArgumentReg4 = INTREG_R8W;
+ const int ArgumentReg5 = INTREG_R9W;
+
+ // Some OS syscalls use a second register (rdx) to return a second
+ // value
+ const int SyscallPseudoReturnReg = INTREG_RDX;
+
+ //XXX These numbers are bogus
+ const int MaxInstSrcRegs = 10;
+ const int MaxInstDestRegs = 10;
+
+ //4k. This value is not constant on x86.
+ const int LogVMPageSize = 12;
+ const int VMPageSize = (1 << LogVMPageSize);
+
+ const int PageShift = 13;
+ const int PageBytes = 1ULL << PageShift;
+
+ const int BranchPredAddrShiftAmt = 0;
+
+ StaticInstPtr decodeInst(ExtMachInst);
+};
+
+#endif // __ARCH_X86_ISATRAITS_HH__
diff --git a/src/arch/x86/kernel_stats.hh b/src/arch/x86/kernel_stats.hh
new file mode 100644
index 000000000..8cd80073e
--- /dev/null
+++ b/src/arch/x86/kernel_stats.hh
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_KERNELSTATS_HH__
+#define __ARCH_X86_KERNELSTATS_HH__
+
+#error X86 is not yet supported!
+
+namespace X86ISA
+{
+};
+
+#endif // __ARCH_X86_KERNELSTATS_HH__
diff --git a/src/arch/x86/linux/linux.cc b/src/arch/x86/linux/linux.cc
new file mode 100644
index 000000000..59754d7b3
--- /dev/null
+++ b/src/arch/x86/linux/linux.cc
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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/x86/linux/linux.hh"
+#include <fcntl.h>
+
+// open(2) flags translation table
+OpenFlagTransTable X86Linux::openFlagTable[] = {
+#ifdef _MSC_VER
+ { TGT_O_RDONLY, _O_RDONLY },
+ { TGT_O_WRONLY, _O_WRONLY },
+ { TGT_O_RDWR, _O_RDWR },
+ { TGT_O_APPEND, _O_APPEND },
+ { TGT_O_CREAT, _O_CREAT },
+ { TGT_O_TRUNC, _O_TRUNC },
+ { TGT_O_EXCL, _O_EXCL },
+#ifdef _O_NONBLOCK
+ { TGT_O_NONBLOCK, _O_NONBLOCK },
+#endif
+#ifdef _O_NOCTTY
+ { TGT_O_NOCTTY, _O_NOCTTY },
+#endif
+#ifdef _O_SYNC
+ { TGT_O_SYNC, _O_SYNC },
+#endif
+#else /* !_MSC_VER */
+ { TGT_O_RDONLY, O_RDONLY },
+ { TGT_O_WRONLY, O_WRONLY },
+ { TGT_O_RDWR, O_RDWR },
+ { TGT_O_APPEND, O_APPEND },
+ { TGT_O_CREAT, O_CREAT },
+ { TGT_O_TRUNC, O_TRUNC },
+ { TGT_O_EXCL, O_EXCL },
+ { TGT_O_NONBLOCK, O_NONBLOCK },
+ { TGT_O_NOCTTY, O_NOCTTY },
+#ifdef O_SYNC
+ { TGT_O_SYNC, O_SYNC },
+#endif
+#endif /* _MSC_VER */
+};
+
+const int X86Linux::NUM_OPEN_FLAGS =
+ (sizeof(X86Linux::openFlagTable)/sizeof(X86Linux::openFlagTable[0]));
+
diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh
new file mode 100644
index 000000000..a276d4c0c
--- /dev/null
+++ b/src/arch/x86/linux/linux.hh
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_LINUX_LINUX_HH__
+#define __ARCH_X86_LINUX_LINUX_HH__
+
+#include "kern/linux/linux.hh"
+
+class X86Linux : public Linux
+{
+ public:
+
+ typedef struct {
+ uint32_t st_dev;
+ char __pad1[4];
+ uint64_t st_ino;
+ uint32_t st_mode;
+ uint16_t st_nlink;
+ uint32_t st_uid;
+ uint32_t st_gid;
+ uint32_t st_rdev;
+ char __pad2[4];
+ int64_t st_size;
+ int64_t st_atimeX;
+ int64_t st_mtimeX;
+ int64_t st_ctimeX;
+ int64_t st_blksize;
+ int64_t st_blocks;
+ uint64_t __unused4[2];
+ } tgt_stat;
+
+ static OpenFlagTransTable openFlagTable[];
+
+ static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY
+ static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY
+ static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR
+ static const int TGT_O_NONBLOCK = 0x00004000; //!< O_NONBLOCK
+ static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND
+ static const int TGT_O_CREAT = 0x00000200; //!< O_CREAT
+ static const int TGT_O_TRUNC = 0x00000400; //!< O_TRUNC
+ static const int TGT_O_EXCL = 0x00000800; //!< O_EXCL
+ static const int TGT_O_NOCTTY = 0x00008000; //!< O_NOCTTY
+ static const int TGT_O_SYNC = 0x00002000; //!< O_SYNC
+// static const int TGT_O_DRD = 0x00010000; //!< O_DRD
+// static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO
+// static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE
+// static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC
+// static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC
+
+ static const int NUM_OPEN_FLAGS;
+
+ static const unsigned TGT_MAP_ANONYMOUS = 0x20;
+};
+
+#endif
diff --git a/src/arch/x86/linux/process.cc b/src/arch/x86/linux/process.cc
new file mode 100644
index 000000000..9ef591a1c
--- /dev/null
+++ b/src/arch/x86/linux/process.cc
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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/x86/isa_traits.hh"
+#include "arch/x86/linux/process.hh"
+#include "arch/x86/regfile.hh"
+
+#include "base/trace.hh"
+#include "cpu/thread_context.hh"
+#include "kern/linux/linux.hh"
+
+#include "sim/process.hh"
+#include "sim/syscall_emul.hh"
+
+using namespace std;
+using namespace X86ISA;
+
+SyscallDesc*
+X86LinuxProcess::getDesc(int callnum)
+{
+ if (callnum < 0 || callnum > Num_Syscall_Descs)
+ return NULL;
+ return &syscallDescs[callnum];
+}
+
+X86LinuxProcess::X86LinuxProcess(const std::string &name,
+ ObjectFile *objFile,
+ System * system,
+ int stdin_fd,
+ int stdout_fd,
+ int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp,
+ const std::string &cwd,
+ uint64_t _uid, uint64_t _euid,
+ uint64_t _gid, uint64_t _egid,
+ uint64_t _pid, uint64_t _ppid)
+ : X86LiveProcess(name, objFile, system,
+ stdin_fd, stdout_fd, stderr_fd, argv, envp, cwd,
+ _uid, _euid, _gid, _egid, _pid, _ppid),
+ Num_Syscall_Descs(273)
+{}
+
+void X86LinuxProcess::handleTrap(int trapNum, ThreadContext *tc)
+{
+ switch(trapNum)
+ {
+ //This implementation is from SPARC
+ case 0x10: //Linux 32 bit syscall trap
+ tc->syscall(tc->readIntReg(1));
+ break;
+ default:
+ X86LiveProcess::handleTrap(trapNum, tc);
+ }
+}
diff --git a/src/arch/x86/linux/process.hh b/src/arch/x86/linux/process.hh
new file mode 100644
index 000000000..7e7236f0d
--- /dev/null
+++ b/src/arch/x86/linux/process.hh
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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 __X86_LINUX_PROCESS_HH__
+#define __X86_LINUX_PROCESS_HH__
+
+#include "sim/process.hh"
+#include "arch/x86/linux/linux.hh"
+#include "arch/x86/syscallreturn.hh"
+#include "arch/x86/process.hh"
+
+namespace X86ISA {
+
+/// A process with emulated x86/Linux syscalls.
+class X86LinuxProcess : public X86LiveProcess
+{
+ public:
+ /// Constructor.
+ X86LinuxProcess(const std::string &name,
+ ObjectFile *objFile,
+ System * system,
+ int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp,
+ const std::string &cwd,
+ uint64_t _uid, uint64_t _euid,
+ uint64_t _gid, uint64_t _egid,
+ uint64_t _pid, uint64_t _ppid);
+
+ /// Array of syscall descriptors, indexed by call number.
+ static SyscallDesc syscallDescs[];
+
+ SyscallDesc* getDesc(int callnum);
+
+ const int Num_Syscall_Descs;
+
+ void handleTrap(int trapNum, ThreadContext *tc);
+};
+
+} // namespace X86ISA
+#endif // __X86_LINUX_PROCESS_HH__
diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc
new file mode 100644
index 000000000..809784635
--- /dev/null
+++ b/src/arch/x86/linux/syscalls.cc
@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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/x86/linux/process.hh"
+#include "kern/linux/linux.hh"
+#include "sim/syscall_emul.hh"
+
+using namespace X86ISA;
+
+/// Target uname() handler.
+static SyscallReturn
+unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+ ThreadContext *tc)
+{
+ TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
+
+ strcpy(name->sysname, "Linux");
+ strcpy(name->nodename, "m5.eecs.umich.edu");
+ strcpy(name->release, "2.6.12");
+ strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
+ strcpy(name->machine, "x86_64");
+
+ name.copyOut(tc->getMemPort());
+
+ return 0;
+}
+
+SyscallDesc X86LinuxProcess::syscallDescs[] = {
+ /* 0 */ SyscallDesc("read", unimplementedFunc),
+ /* 1 */ SyscallDesc("write", unimplementedFunc),
+ /* 2 */ SyscallDesc("open", unimplementedFunc),
+ /* 3 */ SyscallDesc("close", unimplementedFunc),
+ /* 4 */ SyscallDesc("stat", unimplementedFunc),
+ /* 5 */ SyscallDesc("fstat", unimplementedFunc),
+ /* 6 */ SyscallDesc("lstat", unimplementedFunc),
+ /* 7 */ SyscallDesc("poll", unimplementedFunc),
+ /* 8 */ SyscallDesc("lseek", unimplementedFunc),
+ /* 9 */ SyscallDesc("mmap", unimplementedFunc),
+ /* 10 */ SyscallDesc("mprotect", unimplementedFunc),
+ /* 11 */ SyscallDesc("munmap", unimplementedFunc),
+ /* 12 */ SyscallDesc("brk", unimplementedFunc),
+ /* 13 */ SyscallDesc("rt_sigaction", unimplementedFunc),
+ /* 14 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
+ /* 15 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
+ /* 16 */ SyscallDesc("ioctl", unimplementedFunc),
+ /* 17 */ SyscallDesc("pread64", unimplementedFunc),
+ /* 18 */ SyscallDesc("pwrite64", unimplementedFunc),
+ /* 19 */ SyscallDesc("readv", unimplementedFunc),
+ /* 20 */ SyscallDesc("writev", unimplementedFunc),
+ /* 21 */ SyscallDesc("access", unimplementedFunc),
+ /* 22 */ SyscallDesc("pipe", unimplementedFunc),
+ /* 23 */ SyscallDesc("select", unimplementedFunc),
+ /* 24 */ SyscallDesc("sched_yield", unimplementedFunc),
+ /* 25 */ SyscallDesc("mremap", unimplementedFunc),
+ /* 26 */ SyscallDesc("msync", unimplementedFunc),
+ /* 27 */ SyscallDesc("mincore", unimplementedFunc),
+ /* 28 */ SyscallDesc("madvise", unimplementedFunc),
+ /* 29 */ SyscallDesc("shmget", unimplementedFunc),
+ /* 30 */ SyscallDesc("shmat", unimplementedFunc),
+ /* 31 */ SyscallDesc("shmctl", unimplementedFunc),
+ /* 32 */ SyscallDesc("dup", unimplementedFunc),
+ /* 33 */ SyscallDesc("dup2", unimplementedFunc),
+ /* 34 */ SyscallDesc("pause", unimplementedFunc),
+ /* 35 */ SyscallDesc("nanosleep", unimplementedFunc),
+ /* 36 */ SyscallDesc("getitimer", unimplementedFunc),
+ /* 37 */ SyscallDesc("alarm", unimplementedFunc),
+ /* 38 */ SyscallDesc("setitimer", unimplementedFunc),
+ /* 39 */ SyscallDesc("getpid", unimplementedFunc),
+ /* 40 */ SyscallDesc("sendfile", unimplementedFunc),
+ /* 41 */ SyscallDesc("socket", unimplementedFunc),
+ /* 42 */ SyscallDesc("connect", unimplementedFunc),
+ /* 43 */ SyscallDesc("accept", unimplementedFunc),
+ /* 44 */ SyscallDesc("sendto", unimplementedFunc),
+ /* 45 */ SyscallDesc("recvfrom", unimplementedFunc),
+ /* 46 */ SyscallDesc("sendmsg", unimplementedFunc),
+ /* 47 */ SyscallDesc("recvmsg", unimplementedFunc),
+ /* 48 */ SyscallDesc("shutdown", unimplementedFunc),
+ /* 49 */ SyscallDesc("bind", unimplementedFunc),
+ /* 50 */ SyscallDesc("listen", unimplementedFunc),
+ /* 51 */ SyscallDesc("getsockname", unimplementedFunc),
+ /* 52 */ SyscallDesc("getpeername", unimplementedFunc),
+ /* 53 */ SyscallDesc("socketpair", unimplementedFunc),
+ /* 54 */ SyscallDesc("setsockopt", unimplementedFunc),
+ /* 55 */ SyscallDesc("getsockopt", unimplementedFunc),
+ /* 56 */ SyscallDesc("clone", unimplementedFunc),
+ /* 57 */ SyscallDesc("fork", unimplementedFunc),
+ /* 58 */ SyscallDesc("vfork", unimplementedFunc),
+ /* 59 */ SyscallDesc("execve", unimplementedFunc),
+ /* 60 */ SyscallDesc("exit", unimplementedFunc),
+ /* 61 */ SyscallDesc("wait4", unimplementedFunc),
+ /* 62 */ SyscallDesc("kill", unimplementedFunc),
+ /* 63 */ SyscallDesc("uname", unameFunc),
+ /* 64 */ SyscallDesc("semget", unimplementedFunc),
+ /* 65 */ SyscallDesc("semop", unimplementedFunc),
+ /* 66 */ SyscallDesc("semctl", unimplementedFunc),
+ /* 67 */ SyscallDesc("shmdt", unimplementedFunc),
+ /* 68 */ SyscallDesc("msgget", unimplementedFunc),
+ /* 69 */ SyscallDesc("msgsnd", unimplementedFunc),
+ /* 70 */ SyscallDesc("msgrcv", unimplementedFunc),
+ /* 71 */ SyscallDesc("msgctl", unimplementedFunc),
+ /* 72 */ SyscallDesc("fcntl", unimplementedFunc),
+ /* 73 */ SyscallDesc("flock", unimplementedFunc),
+ /* 74 */ SyscallDesc("fsync", unimplementedFunc),
+ /* 75 */ SyscallDesc("fdatasync", unimplementedFunc),
+ /* 76 */ SyscallDesc("truncate", unimplementedFunc),
+ /* 77 */ SyscallDesc("ftruncate", unimplementedFunc),
+ /* 78 */ SyscallDesc("getdents", unimplementedFunc),
+ /* 79 */ SyscallDesc("getcwd", unimplementedFunc),
+ /* 80 */ SyscallDesc("chdir", unimplementedFunc),
+ /* 81 */ SyscallDesc("fchdir", unimplementedFunc),
+ /* 82 */ SyscallDesc("rename", unimplementedFunc),
+ /* 83 */ SyscallDesc("mkdir", unimplementedFunc),
+ /* 84 */ SyscallDesc("rmdir", unimplementedFunc),
+ /* 85 */ SyscallDesc("creat", unimplementedFunc),
+ /* 86 */ SyscallDesc("link", unimplementedFunc),
+ /* 87 */ SyscallDesc("unlink", unimplementedFunc),
+ /* 88 */ SyscallDesc("symlink", unimplementedFunc),
+ /* 89 */ SyscallDesc("readlink", unimplementedFunc),
+ /* 90 */ SyscallDesc("chmod", unimplementedFunc),
+ /* 91 */ SyscallDesc("fchmod", unimplementedFunc),
+ /* 92 */ SyscallDesc("chown", unimplementedFunc),
+ /* 93 */ SyscallDesc("fchown", unimplementedFunc),
+ /* 94 */ SyscallDesc("lchown", unimplementedFunc),
+ /* 95 */ SyscallDesc("umask", unimplementedFunc),
+ /* 96 */ SyscallDesc("gettimeofday", unimplementedFunc),
+ /* 97 */ SyscallDesc("getrlimit", unimplementedFunc),
+ /* 98 */ SyscallDesc("getrusage", unimplementedFunc),
+ /* 99 */ SyscallDesc("sysinfo", unimplementedFunc),
+ /* 100 */ SyscallDesc("times", unimplementedFunc),
+ /* 101 */ SyscallDesc("ptrace", unimplementedFunc),
+ /* 102 */ SyscallDesc("getuid", unimplementedFunc),
+ /* 103 */ SyscallDesc("syslog", unimplementedFunc),
+ /* 104 */ SyscallDesc("getgid", unimplementedFunc),
+ /* 105 */ SyscallDesc("setuid", unimplementedFunc),
+ /* 106 */ SyscallDesc("setgid", unimplementedFunc),
+ /* 107 */ SyscallDesc("geteuid", unimplementedFunc),
+ /* 108 */ SyscallDesc("getegid", unimplementedFunc),
+ /* 109 */ SyscallDesc("setpgid", unimplementedFunc),
+ /* 110 */ SyscallDesc("getppid", unimplementedFunc),
+ /* 111 */ SyscallDesc("getpgrp", unimplementedFunc),
+ /* 112 */ SyscallDesc("setsid", unimplementedFunc),
+ /* 113 */ SyscallDesc("setreuid", unimplementedFunc),
+ /* 114 */ SyscallDesc("setregid", unimplementedFunc),
+ /* 115 */ SyscallDesc("getgroups", unimplementedFunc),
+ /* 116 */ SyscallDesc("setgroups", unimplementedFunc),
+ /* 117 */ SyscallDesc("setresuid", unimplementedFunc),
+ /* 118 */ SyscallDesc("getresuid", unimplementedFunc),
+ /* 119 */ SyscallDesc("setresgid", unimplementedFunc),
+ /* 120 */ SyscallDesc("getresgid", unimplementedFunc),
+ /* 121 */ SyscallDesc("getpgid", unimplementedFunc),
+ /* 122 */ SyscallDesc("setfsuid", unimplementedFunc),
+ /* 123 */ SyscallDesc("setfsgid", unimplementedFunc),
+ /* 124 */ SyscallDesc("getsid", unimplementedFunc),
+ /* 125 */ SyscallDesc("capget", unimplementedFunc),
+ /* 126 */ SyscallDesc("capset", unimplementedFunc),
+ /* 127 */ SyscallDesc("rt_sigpending", unimplementedFunc),
+ /* 128 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
+ /* 129 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc),
+ /* 130 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
+ /* 131 */ SyscallDesc("sigaltstack", unimplementedFunc),
+ /* 132 */ SyscallDesc("utime", unimplementedFunc),
+ /* 133 */ SyscallDesc("mknod", unimplementedFunc),
+ /* 134 */ SyscallDesc("uselib", unimplementedFunc),
+ /* 135 */ SyscallDesc("personality", unimplementedFunc),
+ /* 136 */ SyscallDesc("ustat", unimplementedFunc),
+ /* 137 */ SyscallDesc("statfs", unimplementedFunc),
+ /* 138 */ SyscallDesc("fstatfs", unimplementedFunc),
+ /* 139 */ SyscallDesc("sysfs", unimplementedFunc),
+ /* 140 */ SyscallDesc("getpriority", unimplementedFunc),
+ /* 141 */ SyscallDesc("setpriority", unimplementedFunc),
+ /* 142 */ SyscallDesc("sched_setparam", unimplementedFunc),
+ /* 143 */ SyscallDesc("sched_getparam", unimplementedFunc),
+ /* 144 */ SyscallDesc("sched_setscheduler", unimplementedFunc),
+ /* 145 */ SyscallDesc("sched_getscheduler", unimplementedFunc),
+ /* 146 */ SyscallDesc("sched_get_priority_max", unimplementedFunc),
+ /* 147 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
+ /* 148 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
+ /* 149 */ SyscallDesc("mlock", unimplementedFunc),
+ /* 150 */ SyscallDesc("munlock", unimplementedFunc),
+ /* 151 */ SyscallDesc("mlockall", unimplementedFunc),
+ /* 152 */ SyscallDesc("munlockall", unimplementedFunc),
+ /* 153 */ SyscallDesc("vhangup", unimplementedFunc),
+ /* 154 */ SyscallDesc("modify_ldt", unimplementedFunc),
+ /* 155 */ SyscallDesc("pivot_root", unimplementedFunc),
+ /* 156 */ SyscallDesc("_sysctl", unimplementedFunc),
+ /* 157 */ SyscallDesc("prctl", unimplementedFunc),
+ /* 158 */ SyscallDesc("arch_prctl", unimplementedFunc),
+ /* 159 */ SyscallDesc("adjtimex", unimplementedFunc),
+ /* 160 */ SyscallDesc("setrlimit", unimplementedFunc),
+ /* 161 */ SyscallDesc("chroot", unimplementedFunc),
+ /* 162 */ SyscallDesc("sync", unimplementedFunc),
+ /* 163 */ SyscallDesc("acct", unimplementedFunc),
+ /* 164 */ SyscallDesc("settimeofday", unimplementedFunc),
+ /* 165 */ SyscallDesc("mount", unimplementedFunc),
+ /* 166 */ SyscallDesc("umount2", unimplementedFunc),
+ /* 167 */ SyscallDesc("swapon", unimplementedFunc),
+ /* 168 */ SyscallDesc("swapoff", unimplementedFunc),
+ /* 169 */ SyscallDesc("reboot", unimplementedFunc),
+ /* 170 */ SyscallDesc("sethostname", unimplementedFunc),
+ /* 171 */ SyscallDesc("setdomainname", unimplementedFunc),
+ /* 172 */ SyscallDesc("iopl", unimplementedFunc),
+ /* 173 */ SyscallDesc("ioperm", unimplementedFunc),
+ /* 174 */ SyscallDesc("create_module", unimplementedFunc),
+ /* 175 */ SyscallDesc("init_module", unimplementedFunc),
+ /* 176 */ SyscallDesc("delete_module", unimplementedFunc),
+ /* 177 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
+ /* 178 */ SyscallDesc("query_module", unimplementedFunc),
+ /* 179 */ SyscallDesc("quotactl", unimplementedFunc),
+ /* 180 */ SyscallDesc("nfsservctl", unimplementedFunc),
+ /* 181 */ SyscallDesc("getpmsg", unimplementedFunc),
+ /* 182 */ SyscallDesc("putpmsg", unimplementedFunc),
+ /* 183 */ SyscallDesc("afs_syscall", unimplementedFunc),
+ /* 184 */ SyscallDesc("tuxcall", unimplementedFunc),
+ /* 185 */ SyscallDesc("security", unimplementedFunc),
+ /* 186 */ SyscallDesc("gettid", unimplementedFunc),
+ /* 187 */ SyscallDesc("readahead", unimplementedFunc),
+ /* 188 */ SyscallDesc("setxattr", unimplementedFunc),
+ /* 189 */ SyscallDesc("lsetxattr", unimplementedFunc),
+ /* 190 */ SyscallDesc("fsetxattr", unimplementedFunc),
+ /* 191 */ SyscallDesc("getxattr", unimplementedFunc),
+ /* 192 */ SyscallDesc("lgetxattr", unimplementedFunc),
+ /* 193 */ SyscallDesc("fgetxattr", unimplementedFunc),
+ /* 194 */ SyscallDesc("listxattr", unimplementedFunc),
+ /* 195 */ SyscallDesc("llistxattr", unimplementedFunc),
+ /* 196 */ SyscallDesc("flistxattr", unimplementedFunc),
+ /* 197 */ SyscallDesc("removexattr", unimplementedFunc),
+ /* 198 */ SyscallDesc("lremovexattr", unimplementedFunc),
+ /* 199 */ SyscallDesc("fremovexattr", unimplementedFunc),
+ /* 200 */ SyscallDesc("tkill", unimplementedFunc),
+ /* 201 */ SyscallDesc("time", unimplementedFunc),
+ /* 202 */ SyscallDesc("futex", unimplementedFunc),
+ /* 203 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
+ /* 204 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
+ /* 205 */ SyscallDesc("set_thread_area", unimplementedFunc),
+ /* 206 */ SyscallDesc("io_setup", unimplementedFunc),
+ /* 207 */ SyscallDesc("io_destroy", unimplementedFunc),
+ /* 208 */ SyscallDesc("io_getevents", unimplementedFunc),
+ /* 209 */ SyscallDesc("io_submit", unimplementedFunc),
+ /* 210 */ SyscallDesc("io_cancel", unimplementedFunc),
+ /* 211 */ SyscallDesc("get_thread_area", unimplementedFunc),
+ /* 212 */ SyscallDesc("lookup_dcookie", unimplementedFunc),
+ /* 213 */ SyscallDesc("epoll_create", unimplementedFunc),
+ /* 214 */ SyscallDesc("epoll_ctl_old", unimplementedFunc),
+ /* 215 */ SyscallDesc("epoll_wait_old", unimplementedFunc),
+ /* 216 */ SyscallDesc("remap_file_pages", unimplementedFunc),
+ /* 217 */ SyscallDesc("getdents64", unimplementedFunc),
+ /* 218 */ SyscallDesc("set_tid_address", unimplementedFunc),
+ /* 219 */ SyscallDesc("restart_syscall", unimplementedFunc),
+ /* 220 */ SyscallDesc("semtimedop", unimplementedFunc),
+ /* 221 */ SyscallDesc("fadvise64", unimplementedFunc),
+ /* 222 */ SyscallDesc("timer_create", unimplementedFunc),
+ /* 223 */ SyscallDesc("timer_settime", unimplementedFunc),
+ /* 224 */ SyscallDesc("timer_gettime", unimplementedFunc),
+ /* 225 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
+ /* 226 */ SyscallDesc("timer_delete", unimplementedFunc),
+ /* 227 */ SyscallDesc("clock_settime", unimplementedFunc),
+ /* 228 */ SyscallDesc("clock_gettime", unimplementedFunc),
+ /* 229 */ SyscallDesc("clock_getres", unimplementedFunc),
+ /* 230 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
+ /* 231 */ SyscallDesc("exit_group", unimplementedFunc),
+ /* 232 */ SyscallDesc("epoll_wait", unimplementedFunc),
+ /* 233 */ SyscallDesc("epoll_ctl", unimplementedFunc),
+ /* 234 */ SyscallDesc("tgkill", unimplementedFunc),
+ /* 235 */ SyscallDesc("utimes", unimplementedFunc),
+ /* 236 */ SyscallDesc("vserver", unimplementedFunc),
+ /* 237 */ SyscallDesc("mbind", unimplementedFunc),
+ /* 238 */ SyscallDesc("set_mempolicy", unimplementedFunc),
+ /* 239 */ SyscallDesc("get_mempolicy", unimplementedFunc),
+ /* 240 */ SyscallDesc("mq_open", unimplementedFunc),
+ /* 241 */ SyscallDesc("mq_unlink", unimplementedFunc),
+ /* 242 */ SyscallDesc("mq_timedsend", unimplementedFunc),
+ /* 243 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
+ /* 244 */ SyscallDesc("mq_notify", unimplementedFunc),
+ /* 245 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
+ /* 246 */ SyscallDesc("kexec_load", unimplementedFunc),
+ /* 247 */ SyscallDesc("waitid", unimplementedFunc),
+ /* 248 */ SyscallDesc("add_key", unimplementedFunc),
+ /* 249 */ SyscallDesc("request_key", unimplementedFunc),
+ /* 250 */ SyscallDesc("keyctl", unimplementedFunc),
+ /* 251 */ SyscallDesc("ioprio_set", unimplementedFunc),
+ /* 252 */ SyscallDesc("ioprio_get", unimplementedFunc),
+ /* 253 */ SyscallDesc("inotify_init", unimplementedFunc),
+ /* 254 */ SyscallDesc("inotify_add_watch", unimplementedFunc),
+ /* 255 */ SyscallDesc("inotify_rm_watch", unimplementedFunc),
+ /* 256 */ SyscallDesc("migrate_pages", unimplementedFunc),
+ /* 257 */ SyscallDesc("openat", unimplementedFunc),
+ /* 258 */ SyscallDesc("mkdirat", unimplementedFunc),
+ /* 259 */ SyscallDesc("mknodat", unimplementedFunc),
+ /* 260 */ SyscallDesc("fchownat", unimplementedFunc),
+ /* 261 */ SyscallDesc("futimesat", unimplementedFunc),
+ /* 262 */ SyscallDesc("newfstatat", unimplementedFunc),
+ /* 263 */ SyscallDesc("unlinkat", unimplementedFunc),
+ /* 264 */ SyscallDesc("renameat", unimplementedFunc),
+ /* 265 */ SyscallDesc("linkat", unimplementedFunc),
+ /* 266 */ SyscallDesc("symlinkat", unimplementedFunc),
+ /* 267 */ SyscallDesc("readlinkat", unimplementedFunc),
+ /* 268 */ SyscallDesc("fchmodat", unimplementedFunc),
+ /* 269 */ SyscallDesc("faccessat", unimplementedFunc),
+ /* 270 */ SyscallDesc("pselect6", unimplementedFunc),
+ /* 271 */ SyscallDesc("ppoll", unimplementedFunc),
+ /* 272 */ SyscallDesc("unshare", unimplementedFunc)
+};
diff --git a/src/arch/x86/locked_mem.hh b/src/arch/x86/locked_mem.hh
new file mode 100644
index 000000000..e1d289ee9
--- /dev/null
+++ b/src/arch/x86/locked_mem.hh
@@ -0,0 +1,58 @@
+/*
+ * 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
+ */
+
+#ifndef __ARCH_X86_LOCKEDMEM_HH__
+#define __ARCH_X86_LOCKEDMEM_HH__
+
+/**
+ * @file
+ *
+ * ISA-specific helper functions for locked memory accesses.
+ */
+
+#include "mem/request.hh"
+
+namespace X86ISA
+{
+ template <class XC>
+ inline void
+ handleLockedRead(XC *xc, Request *req)
+ {
+ }
+
+ template <class XC>
+ inline bool
+ handleLockedWrite(XC *xc, Request *req)
+ {
+ return true;
+ }
+};
+
+#endif // __ARCH_X86_LOCKEDMEM_HH__
diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc
new file mode 100644
index 000000000..14ba3c7cc
--- /dev/null
+++ b/src/arch/x86/miscregfile.cc
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2003-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
+ */
+
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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/x86/miscregfile.hh"
+
+using namespace X86ISA;
+using namespace std;
+
+class Checkpoint;
+
+//These functions map register indices to names
+string X86ISA::getMiscRegName(RegIndex index)
+{
+ panic("No misc registers in x86 yet!\n");
+}
+
+void MiscRegFile::clear()
+{
+ //When there are actually misc regs implemented, this will clear them
+}
+
+MiscReg MiscRegFile::readRegNoEffect(int miscReg)
+{
+ panic("No misc registers in x86 yet!\n");
+}
+
+MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc)
+{
+ panic("No misc registers in x86 yet!\n");
+}
+
+void MiscRegFile::setRegNoEffect(int miscReg, const MiscReg &val)
+{
+ panic("No misc registers in x86 yet!\n");
+}
+
+void MiscRegFile::setReg(int miscReg,
+ const MiscReg &val, ThreadContext * tc)
+{
+ panic("No misc registers in x86 yet!\n");
+}
+
+void MiscRegFile::serialize(std::ostream & os)
+{
+ panic("No misc registers in x86 yet!\n");
+}
+
+void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
+{
+ panic("No misc registers in x86 yet!\n");
+}
diff --git a/src/arch/x86/miscregfile.hh b/src/arch/x86/miscregfile.hh
new file mode 100644
index 000000000..10acb97a4
--- /dev/null
+++ b/src/arch/x86/miscregfile.hh
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2003-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
+ */
+
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_MISCREGFILE_HH__
+#define __ARCH_X86_MISCREGFILE_HH__
+
+#include "arch/x86/faults.hh"
+#include "arch/x86/types.hh"
+
+#include <string>
+
+class Checkpoint;
+
+namespace X86ISA
+{
+ std::string getMiscRegName(RegIndex);
+
+ //These will have to be updated in the future.
+ const int NumMiscArchRegs = 0;
+ const int NumMiscRegs = 0;
+
+ class MiscRegFile
+ {
+ public:
+ void clear();
+
+ MiscRegFile()
+ {
+ clear();
+ }
+
+ MiscReg readRegNoEffect(int miscReg);
+
+ MiscReg readReg(int miscReg, ThreadContext *tc);
+
+ void setRegNoEffect(int miscReg, const MiscReg &val);
+
+ void setReg(int miscReg,
+ const MiscReg &val, ThreadContext *tc);
+
+ void serialize(std::ostream & os);
+
+ void unserialize(Checkpoint * cp, const std::string &section);
+
+ void copyMiscRegs(ThreadContext * tc);
+ };
+}
+
+#endif //__ARCH_X86_MISCREGFILE_HH__
diff --git a/src/arch/x86/mmaped_ipr.hh b/src/arch/x86/mmaped_ipr.hh
new file mode 100644
index 000000000..a33a3f4f0
--- /dev/null
+++ b/src/arch/x86/mmaped_ipr.hh
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_MMAPEDIPR_HH__
+#define __ARCH_X86_MMAPEDIPR_HH__
+
+/**
+ * @file
+ *
+ * ISA-specific helper functions for memory mapped IPR accesses.
+ */
+
+#include "config/full_system.hh"
+#include "cpu/thread_context.hh"
+#include "mem/packet.hh"
+
+namespace X86ISA
+{
+ inline Tick
+ handleIprRead(ThreadContext *xc, Packet *pkt)
+ {
+#if !FULL_SYSTEM
+ panic("Shouldn't have a memory mapped register in SE\n");
+#endif
+ }
+
+ inline Tick
+ handleIprWrite(ThreadContext *xc, Packet *pkt)
+ {
+#if !FULL_SYSTEM
+ panic("Shouldn't have a memory mapped register in SE\n");
+#endif
+ }
+};
+
+#endif // __ARCH_X86_MMAPEDIPR_HH__
diff --git a/src/arch/x86/pagetable.hh b/src/arch/x86/pagetable.hh
new file mode 100644
index 000000000..8ca179c86
--- /dev/null
+++ b/src/arch/x86/pagetable.hh
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_PAGETABLE_HH__
+#define __ARCH_X86_PAGETABLE_HH__
+
+#include "sim/host.hh"
+#include "base/misc.hh"
+
+namespace X86ISA
+{
+ struct VAddr
+ {
+ VAddr(Addr a) { panic("not implemented yet."); }
+ };
+
+ class PageTableEntry
+ {
+ };
+}
+
+#endif
diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc
new file mode 100644
index 000000000..fbed4fe41
--- /dev/null
+++ b/src/arch/x86/predecoder.cc
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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/x86/predecoder.hh"
+#include "base/misc.hh"
+#include "base/trace.hh"
+#include "sim/host.hh"
+
+namespace X86ISA
+{
+ void Predecoder::process()
+ {
+ //This function drives the predecoder state machine.
+
+ //Some sanity checks. You shouldn't try to process more bytes if
+ //there aren't any, and you shouldn't overwrite an already
+ //predecoder ExtMachInst.
+ assert(!outOfBytes);
+ assert(!emiIsReady);
+
+ //While there's still something to do...
+ while(!emiIsReady && !outOfBytes)
+ {
+ uint8_t nextByte = getNextByte();
+ switch(state)
+ {
+ case PrefixState:
+ state = doPrefixState(nextByte);
+ break;
+ case OpcodeState:
+ state = doOpcodeState(nextByte);
+ break;
+ case ModRMState:
+ state = doModRMState(nextByte);
+ break;
+ case SIBState:
+ state = doSIBState(nextByte);
+ break;
+ case DisplacementState:
+ state = doDisplacementState();
+ break;
+ case ImmediateState:
+ state = doImmediateState();
+ break;
+ case ErrorState:
+ panic("Went to the error state in the predecoder.\n");
+ default:
+ panic("Unrecognized state! %d\n", state);
+ }
+ }
+ }
+
+ //Either get a prefix and record it in the ExtMachInst, or send the
+ //state machine on to get the opcode(s).
+ Predecoder::State Predecoder::doPrefixState(uint8_t nextByte)
+ {
+ uint8_t prefix = Prefixes[nextByte];
+ State nextState = PrefixState;
+ if(prefix)
+ consumeByte();
+ switch(prefix)
+ {
+ //Operand size override prefixes
+ case OperandSizeOverride:
+ DPRINTF(Predecoder, "Found operand size override prefix.\n");
+ break;
+ case AddressSizeOverride:
+ DPRINTF(Predecoder, "Found address size override prefix.\n");
+ break;
+ //Segment override prefixes
+ case CSOverride:
+ DPRINTF(Predecoder, "Found cs segment override.\n");
+ break;
+ case DSOverride:
+ DPRINTF(Predecoder, "Found ds segment override.\n");
+ break;
+ case ESOverride:
+ DPRINTF(Predecoder, "Found es segment override.\n");
+ break;
+ case FSOverride:
+ DPRINTF(Predecoder, "Found fs segment override.\n");
+ break;
+ case GSOverride:
+ DPRINTF(Predecoder, "Found gs segment override.\n");
+ break;
+ case SSOverride:
+ DPRINTF(Predecoder, "Found ss segment override.\n");
+ break;
+ case Lock:
+ DPRINTF(Predecoder, "Found lock prefix.\n");
+ break;
+ case Rep:
+ DPRINTF(Predecoder, "Found rep prefix.\n");
+ break;
+ case Repne:
+ DPRINTF(Predecoder, "Found repne prefix.\n");
+ break;
+ case RexPrefix:
+ DPRINTF(Predecoder, "Found Rex prefix %#x.\n", nextByte);
+ emi.rex = nextByte;
+ break;
+ case 0:
+ emi.opcode.num = 0;
+ nextState = OpcodeState;
+ break;
+ default:
+ panic("Unrecognized prefix %#x\n", nextByte);
+ }
+ return nextState;
+ }
+
+ //Load all the opcodes (currently up to 2) and then figure out
+ //what immediate and/or ModRM is needed.
+ Predecoder::State Predecoder::doOpcodeState(uint8_t nextByte)
+ {
+ State nextState = ErrorState;
+ emi.opcode.num++;
+ //We can't handle 3+ byte opcodes right now
+ assert(emi.opcode.num < 3);
+ consumeByte();
+ if(emi.opcode.num == 1 && nextByte == 0x0f)
+ {
+ nextState = OpcodeState;
+ DPRINTF(Predecoder, "Found two byte opcode.\n");
+ emi.opcode.prefixA = nextByte;
+ }
+ else if(emi.opcode.num == 2 &&
+ (nextByte == 0x0f ||
+ (nextByte & 0xf8) == 0x38))
+ {
+ panic("Three byte opcodes aren't yet supported!\n");
+ nextState = OpcodeState;
+ DPRINTF(Predecoder, "Found three byte opcode.\n");
+ emi.opcode.prefixB = nextByte;
+ }
+ else
+ {
+ DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte);
+ emi.opcode.op = nextByte;
+
+ //Prepare for any immediate/displacement we might need
+ immediateCollected = 0;
+ emi.immediate = 0;
+ displacementCollected = 0;
+ emi.displacement = 0;
+
+ //Figure out how big of an immediate we'll retreive based
+ //on the opcode.
+ int immType = ImmediateType[
+ emi.opcode.num - 1][nextByte];
+ if(0) //16 bit mode
+ immediateSize = ImmediateTypeToSize[0][immType];
+ else if(!(emi.rex & 0x4)) //32 bit mode
+ immediateSize = ImmediateTypeToSize[1][immType];
+ else //64 bit mode
+ immediateSize = ImmediateTypeToSize[2][immType];
+
+ //Determine what to expect next
+ if (UsesModRM[emi.opcode.num - 1][nextByte]) {
+ nextState = ModRMState;
+ } else if(immediateSize) {
+ nextState = ImmediateState;
+ } else {
+ emiIsReady = true;
+ nextState = PrefixState;
+ }
+ }
+ return nextState;
+ }
+
+ //Get the ModRM byte and determine what displacement, if any, there is.
+ //Also determine whether or not to get the SIB byte, displacement, or
+ //immediate next.
+ Predecoder::State Predecoder::doModRMState(uint8_t nextByte)
+ {
+ State nextState = ErrorState;
+ emi.modRM = nextByte;
+ DPRINTF(Predecoder, "Found modrm byte %#x.\n", nextByte);
+ if (0) {//FIXME in 16 bit mode
+ //figure out 16 bit displacement size
+ if(nextByte & 0xC7 == 0x06 ||
+ nextByte & 0xC0 == 0x80)
+ displacementSize = 2;
+ else if(nextByte & 0xC0 == 0x40)
+ displacementSize = 1;
+ else
+ displacementSize = 0;
+ } else {
+ //figure out 32/64 bit displacement size
+ if(nextByte & 0xC7 == 0x05 ||
+ nextByte & 0xC0 == 0x80)
+ displacementSize = 4;
+ else if(nextByte & 0xC0 == 0x40)
+ displacementSize = 2;
+ else
+ displacementSize = 0;
+ }
+ //If there's an SIB, get that next.
+ //There is no SIB in 16 bit mode.
+ if(nextByte & 0x7 == 4 &&
+ nextByte & 0xC0 != 0xC0) {
+ // && in 32/64 bit mode)
+ nextState = SIBState;
+ } else if(displacementSize) {
+ nextState = DisplacementState;
+ } else if(immediateSize) {
+ nextState = ImmediateState;
+ } else {
+ emiIsReady = true;
+ nextState = PrefixState;
+ }
+ //The ModRM byte is consumed no matter what
+ consumeByte();
+ return nextState;
+ }
+
+ //Get the SIB byte. We don't do anything with it at this point, other
+ //than storing it in the ExtMachInst. Determine if we need to get a
+ //displacement or immediate next.
+ Predecoder::State Predecoder::doSIBState(uint8_t nextByte)
+ {
+ State nextState = ErrorState;
+ emi.sib = nextByte;
+ DPRINTF(Predecoder, "Found SIB byte %#x.\n", nextByte);
+ consumeByte();
+ if(displacementSize) {
+ nextState = DisplacementState;
+ } else if(immediateSize) {
+ nextState = ImmediateState;
+ } else {
+ emiIsReady = true;
+ nextState = PrefixState;
+ }
+ return nextState;
+ }
+
+ //Gather up the displacement, or at least as much of it
+ //as we can get.
+ Predecoder::State Predecoder::doDisplacementState()
+ {
+ State nextState = ErrorState;
+
+ getImmediate(displacementCollected,
+ emi.displacement,
+ displacementSize);
+
+ DPRINTF(Predecoder, "Collecting %d byte displacement, got %d bytes.\n",
+ displacementSize, displacementCollected);
+
+ if(displacementSize == displacementCollected) {
+ //Sign extend the displacement
+ switch(displacementSize)
+ {
+ case 1:
+ emi.displacement = sext<8>(emi.displacement);
+ break;
+ case 2:
+ emi.displacement = sext<16>(emi.displacement);
+ break;
+ case 4:
+ emi.displacement = sext<32>(emi.displacement);
+ break;
+ default:
+ panic("Undefined displacement size!\n");
+ }
+ DPRINTF(Predecoder, "Collected displacement %#x.\n",
+ emi.displacement);
+ if(immediateSize) {
+ nextState = ImmediateState;
+ } else {
+ emiIsReady = true;
+ nextState = PrefixState;
+ }
+ }
+ else
+ nextState = DisplacementState;
+ return nextState;
+ }
+
+ //Gather up the immediate, or at least as much of it
+ //as we can get
+ Predecoder::State Predecoder::doImmediateState()
+ {
+ State nextState = ErrorState;
+
+ getImmediate(immediateCollected,
+ emi.immediate,
+ immediateSize);
+
+ DPRINTF(Predecoder, "Collecting %d byte immediate, got %d bytes.\n",
+ immediateSize, immediateCollected);
+
+ if(immediateSize == immediateCollected)
+ {
+ DPRINTF(Predecoder, "Collected immediate %#x.\n",
+ emi.immediate);
+ emiIsReady = true;
+ nextState = PrefixState;
+ }
+ else
+ nextState = ImmediateState;
+ return nextState;
+ }
+}
diff --git a/src/arch/x86/predecoder.hh b/src/arch/x86/predecoder.hh
new file mode 100644
index 000000000..1df17d6d2
--- /dev/null
+++ b/src/arch/x86/predecoder.hh
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_PREDECODER_HH__
+#define __ARCH_X86_PREDECODER_HH__
+
+#include "arch/x86/types.hh"
+#include "base/bitfield.hh"
+#include "sim/host.hh"
+
+class ThreadContext;
+
+namespace X86ISA
+{
+ class Predecoder
+ {
+ private:
+ //These are defined and documented in predecoder_tables.cc
+ static const uint8_t Prefixes[256];
+ static const uint8_t UsesModRM[2][256];
+ static const uint8_t ImmediateType[2][256];
+ static const uint8_t ImmediateTypeToSize[3][10];
+
+ protected:
+ ThreadContext * tc;
+ //The bytes to be predecoded
+ MachInst fetchChunk;
+ //The pc of the start of fetchChunk
+ Addr basePC;
+ //The offset into fetchChunk of current processing
+ int offset;
+ //The extended machine instruction being generated
+ ExtMachInst emi;
+
+ inline uint8_t getNextByte()
+ {
+ return (fetchChunk >> (offset * 8)) & 0xff;
+ }
+
+ void getImmediate(int &collected, uint64_t &current, int size)
+ {
+ //Figure out how many bytes we still need to get for the
+ //immediate.
+ int toGet = size - collected;
+ //Figure out how many bytes are left in our "buffer"
+ int remaining = sizeof(MachInst) - offset;
+ //Get as much as we need, up to the amount available.
+ toGet = toGet > remaining ? remaining : toGet;
+
+ //Shift the bytes we want to be all the way to the right
+ uint64_t partialDisp = fetchChunk >> (offset * 8);
+ //Mask off what we don't want
+ partialDisp &= mask(toGet * 8);
+ //Shift it over to overlay with our displacement.
+ partialDisp <<= (displacementCollected * 8);
+ //Put it into our displacement
+ current |= partialDisp;
+ //Update how many bytes we've collected.
+ collected += toGet;
+ consumeBytes(toGet);
+ }
+
+ inline void consumeByte()
+ {
+ offset++;
+ assert(offset <= sizeof(MachInst));
+ if(offset == sizeof(MachInst))
+ outOfBytes = true;
+ }
+
+ inline void consumeBytes(int numBytes)
+ {
+ offset += numBytes;
+ assert(offset <= sizeof(MachInst));
+ if(offset == sizeof(MachInst))
+ outOfBytes = true;
+ }
+
+ //State machine state
+ protected:
+ //Whether or not we're out of bytes
+ bool outOfBytes;
+ //Whether we've completed generating an ExtMachInst
+ bool emiIsReady;
+ //The size of the displacement value
+ int displacementSize;
+ int displacementCollected;
+ //The size of the immediate value
+ int immediateSize;
+ int immediateCollected;
+
+ enum State {
+ PrefixState,
+ OpcodeState,
+ ModRMState,
+ SIBState,
+ DisplacementState,
+ ImmediateState,
+ //We should never get to this state. Getting here is an error.
+ ErrorState
+ };
+
+ State state;
+
+ //Functions to handle each of the states
+ State doPrefixState(uint8_t);
+ State doOpcodeState(uint8_t);
+ State doModRMState(uint8_t);
+ State doSIBState(uint8_t);
+ State doDisplacementState();
+ State doImmediateState();
+
+ public:
+ Predecoder(ThreadContext * _tc) :
+ tc(_tc), basePC(0), offset(0),
+ outOfBytes(true), emiIsReady(false),
+ state(PrefixState)
+ {}
+
+ ThreadContext * getTC()
+ {
+ return tc;
+ }
+
+ void setTC(ThreadContext * _tc)
+ {
+ tc = _tc;
+ }
+
+ void process();
+
+ //Use this to give data to the predecoder. This should be used
+ //when there is control flow.
+ void moreBytes(Addr currPC, Addr off, MachInst data)
+ {
+ basePC = currPC;
+ offset = off;
+ fetchChunk = data;
+ assert(off < sizeof(MachInst));
+ outOfBytes = false;
+ process();
+ }
+
+ //Use this to give data to the predecoder. This should be used
+ //when instructions are executed in order.
+ void moreBytes(MachInst machInst)
+ {
+ moreBytes(basePC + sizeof(machInst), 0, machInst);
+ }
+
+ bool needMoreBytes()
+ {
+ return outOfBytes;
+ }
+
+ bool extMachInstReady()
+ {
+ return emiIsReady;
+ }
+
+ //This returns a constant reference to the ExtMachInst to avoid a copy
+ const ExtMachInst & getExtMachInst()
+ {
+ assert(emiIsReady);
+ emiIsReady = false;
+ return emi;
+ }
+ };
+};
+
+#endif // __ARCH_X86_PREDECODER_HH__
diff --git a/src/arch/x86/predecoder_tables.cc b/src/arch/x86/predecoder_tables.cc
new file mode 100644
index 000000000..f233ad234
--- /dev/null
+++ b/src/arch/x86/predecoder_tables.cc
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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/x86/predecoder.hh"
+#include "arch/x86/types.hh"
+
+namespace X86ISA
+{
+ const uint8_t CS = CSOverride;
+ const uint8_t DS = DSOverride;
+ const uint8_t ES = ESOverride;
+ const uint8_t FS = FSOverride;
+ const uint8_t GS = GSOverride;
+ const uint8_t SS = SSOverride;
+
+ const uint8_t OO = OperandSizeOverride;
+ const uint8_t AO = AddressSizeOverride;
+ const uint8_t LO = Lock;
+ const uint8_t RE = Rep;
+ const uint8_t RN = Repne;
+ const uint8_t RX = RexPrefix;
+
+ //This table identifies whether a byte is a prefix, and if it is,
+ //which prefix it is.
+ const uint8_t Predecoder::Prefixes[256] =
+ { //LSB
+// MSB 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
+/* 0*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 1*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 2*/ 0 , 0 , 0 , 0 , 0 , 0 , ES, 0 , 0 , 0 , 0 , 0 , 0 , 0 , CS, 0,
+/* 3*/ 0 , 0 , 0 , 0 , 0 , 0 , SS, 0 , 0 , 0 , 0 , 0 , 0 , 0 , DS, 0,
+/* 4*/ RX, RX, RX, RX, RX, RX, RX, RX, RX, RX, RX, RX, RX, RX, RX, RX,
+/* 5*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 6*/ 0 , 0 , 0 , 0 , FS, GS, OO, AO, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 7*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 8*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 9*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* A*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* B*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* C*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* D*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* E*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* F*/ LO, 0 , RN, RE, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
+ };
+
+ //This table identifies whether a particular opcode uses the ModRM byte
+ const uint8_t Predecoder::UsesModRM[2][256] =
+ {//For one byte instructions
+ { //LSB
+// MSB 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
+/* 0 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0,
+/* 1 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0,
+/* 2 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0,
+/* 3 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0,
+/* 4 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 5 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 6 */ 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0,
+/* 7 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 8 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* 9 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* A */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* B */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* C */ 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* D */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* E */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* F */ 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1
+ },
+ //For two byte instructions
+ { //LSB
+// MSB 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
+/* 0 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1,
+/* 1 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 2 */ 1 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* 3 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 4 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* 5 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* 6 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* 7 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1,
+/* 8 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 9 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* A */ 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1,
+/* B */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1,
+/* C */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* D */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* E */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* F */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0
+ }
+ };
+
+ enum ImmediateTypes {
+ NoImm,
+ NI = NoImm,
+ ByteImm,
+ BY = ByteImm,
+ WordImm,
+ WO = WordImm,
+ DWordImm,
+ DW = DWordImm,
+ QWordImm,
+ QW = QWordImm,
+ OWordImm,
+ OW = OWordImm,
+ VWordImm,
+ VW = VWordImm,
+ ZWordImm,
+ ZW = ZWordImm,
+ Pointer,
+ PO = Pointer,
+ //The enter instruction takes -2- immediates for a total of 3 bytes
+ Enter,
+ EN = Enter
+ };
+
+ const uint8_t Predecoder::ImmediateTypeToSize[3][10] =
+ {
+// noimm byte word dword qword oword vword zword enter
+ {0, 1, 2, 4, 8, 16, 2, 2, 3, 4}, //16 bit
+ {0, 1, 2, 4, 8, 16, 4, 4, 3, 6}, //32 bit
+ {0, 1, 2, 4, 8, 16, 4, 8, 3, 0} //64 bit
+ };
+
+ //This table determines the immediate type. The first index is the
+ //number of bytes in the instruction, and the second is the meaningful
+ //byte of the opcode. I didn't use the NI constant here for the sake
+ //of clarity.
+ const uint8_t Predecoder::ImmediateType[2][256] =
+ {//For one byte instructions
+ { //LSB
+// MSB 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
+/* 0 */ 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 ,
+/* 1 */ 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 ,
+/* 2 */ 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 ,
+/* 3 */ 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 ,
+/* 4 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 5 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 6 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , ZW, ZW, BY, BY, 0 , 0 , 0 , 0 ,
+/* 7 */ BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY,
+/* 8 */ BY, ZW, BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 9 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* A */ BY, VW, BY, VW, 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 ,
+/* B */ BY, BY, BY, BY, BY, BY, BY, BY, VW, VW, VW, VW, VW, VW, VW, VW,
+/* C */ BY, BY, WO, 0 , 0 , 0 , BY, ZW, EN, 0 , WO, 0 , 0 , BY, 0 , 0 ,
+/* D */ 0 , 0 , 0 , 0 , BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* E */ BY, BY, BY, BY, BY, BY, BY, BY, ZW, ZW, PO, BY, 0 , 0 , 0 , 0 ,
+/* F */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
+ },
+ //For two byte instructions
+ { //LSB
+// MSB 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
+/* 0 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 0 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 2 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 3 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 4 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 5 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 6 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 7 */ BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 8 */ ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW,
+/* 9 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* A */ 0 , 0 , 0 , 0 , BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , BY, 0 , 0 , 0 ,
+/* B */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , ZW, 0 , BY, 0 , 0 , 0 , 0 , 0 ,
+/* C */ 0 , 0 , BY, 0 , BY, BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* D */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* E */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* F */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
+ }
+ };
+}
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
new file mode 100644
index 000000000..e6d1e4921
--- /dev/null
+++ b/src/arch/x86/process.cc
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 2003-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
+ * Ali Saidi
+ */
+
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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/x86/isa_traits.hh"
+#include "arch/x86/process.hh"
+#include "arch/x86/types.hh"
+#include "base/loader/object_file.hh"
+#include "base/loader/elf_object.hh"
+#include "base/misc.hh"
+#include "cpu/thread_context.hh"
+#include "mem/page_table.hh"
+#include "mem/translating_port.hh"
+#include "sim/system.hh"
+
+using namespace std;
+using namespace X86ISA;
+
+M5_64_auxv_t::M5_64_auxv_t(int64_t type, int64_t val)
+{
+ a_type = TheISA::htog(type);
+ a_val = TheISA::htog(val);
+}
+
+X86LiveProcess::X86LiveProcess(const std::string &nm, ObjectFile *objFile,
+ System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv, std::vector<std::string> &envp,
+ const std::string &cwd,
+ uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid,
+ uint64_t _pid, uint64_t _ppid)
+ : LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd,
+ argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid)
+{
+ brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
+ brk_point = roundUp(brk_point, VMPageSize);
+
+ // Set pointer for next thread stack. Reserve 8M for main stack.
+ next_thread_stack_base = stack_base - (8 * 1024 * 1024);
+
+ // Set up stack. On SPARC Linux, stack goes from the top of memory
+ // downward, less the hole for the kernel address space.
+ stack_base = (Addr)0x80000000000ULL;
+
+ // Set up region for mmaps. Tru64 seems to start just above 0 and
+ // grow up from there.
+ mmap_start = mmap_end = 0xfffff80000000000ULL;
+}
+
+void X86LiveProcess::handleTrap(int trapNum, ThreadContext *tc)
+{
+ switch(trapNum)
+ {
+ default:
+ panic("Unimplemented trap to operating system: trap number %#x.\n", trapNum);
+ }
+}
+
+void
+X86LiveProcess::startup()
+{
+ argsInit(sizeof(IntReg), VMPageSize);
+
+ //The AMD64 abi says that only rsp and rdx are defined at process
+ //startup. rsp will be set by argsInit, and I don't understand what
+ //rdx should be set to. The other floating point and integer registers
+ //will be zeroed by the register file constructors, but control registers
+ //should be initialized here. Since none of those are implemented, there
+ //isn't anything here.
+}
+
+void
+X86LiveProcess::argsInit(int intSize, int pageSize)
+{
+ typedef M5_64_auxv_t auxv_t;
+ Process::startup();
+
+ string filename;
+ if(argv.size() < 1)
+ filename = "";
+ else
+ filename = argv[0];
+
+ Addr alignmentMask = ~(intSize - 1);
+
+ // load object file into target memory
+ objFile->loadSections(initVirtMem);
+
+ //These are the auxilliary vector types
+ enum auxTypes
+ {
+ X86_AT_NULL = 0,
+ X86_AT_IGNORE = 1,
+ X86_AT_EXECFD = 2,
+ X86_AT_PHDR = 3,
+ X86_AT_PHENT = 4,
+ X86_AT_PHNUM = 5,
+ X86_AT_PAGESZ = 6,
+ X86_AT_BASE = 7,
+ X86_AT_FLAGS = 8,
+ X86_AT_ENTRY = 9,
+ X86_AT_NOTELF = 10,
+ X86_AT_UID = 11,
+ X86_AT_EUID = 12,
+ X86_AT_GID = 13,
+ X86_AT_EGID = 14
+ };
+
+ //Setup the auxilliary vectors. These will already have endian conversion.
+ //Auxilliary vectors are loaded only for elf formatted executables.
+ ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
+ if(elfObject)
+ {
+ /*
+ //Bits which describe the system hardware capabilities
+ auxv.push_back(auxv_t(SPARC_AT_HWCAP, hwcap));
+ //The system page size
+ auxv.push_back(auxv_t(SPARC_AT_PAGESZ, SparcISA::VMPageSize));
+ //Defined to be 100 in the kernel source.
+ //Frequency at which times() increments
+ auxv.push_back(auxv_t(SPARC_AT_CLKTCK, 100));
+ // For statically linked executables, this is the virtual address of the
+ // program header tables if they appear in the executable image
+ auxv.push_back(auxv_t(SPARC_AT_PHDR, elfObject->programHeaderTable()));
+ // This is the size of a program header entry from the elf file.
+ auxv.push_back(auxv_t(SPARC_AT_PHENT, elfObject->programHeaderSize()));
+ // This is the number of program headers from the original elf file.
+ auxv.push_back(auxv_t(SPARC_AT_PHNUM, elfObject->programHeaderCount()));
+ //This is the address of the elf "interpreter", It should be set
+ //to 0 for regular executables. It should be something else
+ //(not sure what) for dynamic libraries.
+ auxv.push_back(auxv_t(SPARC_AT_BASE, 0));
+ //This is hardwired to 0 in the elf loading code in the kernel
+ auxv.push_back(auxv_t(SPARC_AT_FLAGS, 0));
+ //The entry point to the program
+ auxv.push_back(auxv_t(SPARC_AT_ENTRY, objFile->entryPoint()));
+ //Different user and group IDs
+ auxv.push_back(auxv_t(SPARC_AT_UID, uid()));
+ auxv.push_back(auxv_t(SPARC_AT_EUID, euid()));
+ auxv.push_back(auxv_t(SPARC_AT_GID, gid()));
+ auxv.push_back(auxv_t(SPARC_AT_EGID, egid()));
+ //Whether to enable "secure mode" in the executable
+ auxv.push_back(auxv_t(SPARC_AT_SECURE, 0));*/
+ }
+
+ //Figure out how big the initial stack needs to be
+
+ // The unaccounted for 0 at the top of the stack
+ int mysterious_size = intSize;
+
+ //This is the name of the file which is present on the initial stack
+ //It's purpose is to let the user space linker examine the original file.
+ int file_name_size = filename.size() + 1;
+
+ int env_data_size = 0;
+ for (int i = 0; i < envp.size(); ++i) {
+ env_data_size += envp[i].size() + 1;
+ }
+ int arg_data_size = 0;
+ for (int i = 0; i < argv.size(); ++i) {
+ arg_data_size += argv[i].size() + 1;
+ }
+
+ //The info_block needs to be padded so it's size is a multiple of the
+ //alignment mask. Also, it appears that there needs to be at least some
+ //padding, so if the size is already a multiple, we need to increase it
+ //anyway.
+ int info_block_size =
+ (file_name_size +
+ env_data_size +
+ arg_data_size +
+ intSize) & alignmentMask;
+
+ int info_block_padding =
+ info_block_size -
+ file_name_size -
+ env_data_size -
+ arg_data_size;
+
+ //Each auxilliary vector is two 8 byte words
+ int aux_array_size = intSize * 2 * (auxv.size() + 1);
+
+ int envp_array_size = intSize * (envp.size() + 1);
+ int argv_array_size = intSize * (argv.size() + 1);
+
+ int argc_size = intSize;
+ int window_save_size = intSize * 16;
+
+ int space_needed =
+ mysterious_size +
+ info_block_size +
+ aux_array_size +
+ envp_array_size +
+ argv_array_size +
+ argc_size +
+ window_save_size;
+
+ stack_min = stack_base - space_needed;
+ stack_min &= alignmentMask;
+ stack_size = stack_base - stack_min;
+
+ // map memory
+ pTable->allocate(roundDown(stack_min, pageSize),
+ roundUp(stack_size, pageSize));
+
+ // map out initial stack contents
+ Addr mysterious_base = stack_base - mysterious_size;
+ Addr file_name_base = mysterious_base - file_name_size;
+ Addr env_data_base = file_name_base - env_data_size;
+ Addr arg_data_base = env_data_base - arg_data_size;
+ Addr auxv_array_base = arg_data_base - aux_array_size - info_block_padding;
+ Addr envp_array_base = auxv_array_base - envp_array_size;
+ Addr argv_array_base = envp_array_base - argv_array_size;
+ Addr argc_base = argv_array_base - argc_size;
+#ifndef NDEBUG
+ // only used in DPRINTF
+ Addr window_save_base = argc_base - window_save_size;
+#endif
+
+ DPRINTF(X86, "The addresses of items on the initial stack:\n");
+ DPRINTF(X86, "0x%x - file name\n", file_name_base);
+ DPRINTF(X86, "0x%x - env data\n", env_data_base);
+ DPRINTF(X86, "0x%x - arg data\n", arg_data_base);
+ DPRINTF(X86, "0x%x - auxv array\n", auxv_array_base);
+ DPRINTF(X86, "0x%x - envp array\n", envp_array_base);
+ DPRINTF(X86, "0x%x - argv array\n", argv_array_base);
+ DPRINTF(X86, "0x%x - argc \n", argc_base);
+ DPRINTF(X86, "0x%x - window save\n", window_save_base);
+ DPRINTF(X86, "0x%x - stack min\n", stack_min);
+
+ // write contents to stack
+
+ // figure out argc
+ uint64_t argc = argv.size();
+ uint64_t guestArgc = TheISA::htog(argc);
+
+ //Write out the mysterious 0
+ uint64_t mysterious_zero = 0;
+ initVirtMem->writeBlob(mysterious_base,
+ (uint8_t*)&mysterious_zero, mysterious_size);
+
+ //Write the file name
+ initVirtMem->writeString(file_name_base, filename.c_str());
+
+ //Copy the aux stuff
+ for(int x = 0; x < auxv.size(); x++)
+ {
+ initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize,
+ (uint8_t*)&(auxv[x].a_type), intSize);
+ initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
+ (uint8_t*)&(auxv[x].a_val), intSize);
+ }
+ //Write out the terminating zeroed auxilliary vector
+ const uint64_t zero = 0;
+ initVirtMem->writeBlob(auxv_array_base + 2 * intSize * auxv.size(),
+ (uint8_t*)&zero, 2 * intSize);
+
+ copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
+ copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
+
+ initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
+
+ //Set up the thread context to start running the process
+ threadContexts[0]->setIntReg(ArgumentReg0, argc);
+ threadContexts[0]->setIntReg(ArgumentReg1, argv_array_base);
+ threadContexts[0]->setIntReg(StackPointerReg, stack_min);
+
+ Addr prog_entry = objFile->entryPoint();
+ threadContexts[0]->setPC(prog_entry);
+ threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
+
+ //Align the "stack_min" to a page boundary.
+ stack_min = roundDown(stack_min, pageSize);
+
+// num_processes++;
+}
diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh
new file mode 100644
index 000000000..a2fa258c8
--- /dev/null
+++ b/src/arch/x86/process.hh
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_PROCESS_HH__
+#define __ARCH_X86_PROCESS_HH__
+
+#include <string>
+#include <vector>
+#include "sim/process.hh"
+
+namespace X86ISA
+{
+ struct M5_64_auxv_t
+ {
+ int64_t a_type;
+ union {
+ int64_t a_val;
+ int64_t a_ptr;
+ int64_t a_fcn;
+ };
+
+ M5_64_auxv_t()
+ {}
+
+ M5_64_auxv_t(int64_t type, int64_t val);
+ };
+
+ class X86LiveProcess : public LiveProcess
+ {
+ protected:
+ std::vector<M5_64_auxv_t> auxv;
+
+ X86LiveProcess(const std::string &nm, ObjectFile *objFile,
+ System *_system,
+ int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp,
+ const std::string &cwd,
+ uint64_t _uid, uint64_t _euid,
+ uint64_t _gid, uint64_t _egid,
+ uint64_t _pid, uint64_t _ppid);
+
+ void startup();
+
+ public:
+
+ //Handles traps which request services from the operating system
+ virtual void handleTrap(int trapNum, ThreadContext *tc);
+
+ void argsInit(int intSize, int pageSize);
+ };
+}
+
+#endif // __ARCH_X86_PROCESS_HH__
diff --git a/src/arch/x86/regfile.cc b/src/arch/x86/regfile.cc
new file mode 100644
index 000000000..568eb1d94
--- /dev/null
+++ b/src/arch/x86/regfile.cc
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2003-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
+ */
+
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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/x86/regfile.hh"
+#include "sim/serialize.hh"
+#include "cpu/thread_context.hh"
+
+class Checkpoint;
+
+using namespace X86ISA;
+using namespace std;
+
+//RegFile class methods
+Addr RegFile::readPC()
+{
+ return rip;
+}
+
+void RegFile::setPC(Addr val)
+{
+ rip = val;
+}
+
+Addr RegFile::readNextPC()
+{
+ return nextRip;
+}
+
+void RegFile::setNextPC(Addr val)
+{
+ nextRip = val;
+}
+
+Addr RegFile::readNextNPC()
+{
+ return nextRip + sizeof(MachInst);
+}
+
+void RegFile::setNextNPC(Addr val)
+{ }
+
+void RegFile::clear()
+{
+ floatRegFile.clear();
+ intRegFile.clear();
+ miscRegFile.clear();
+}
+
+MiscReg RegFile::readMiscRegNoEffect(int miscReg)
+{
+ return miscRegFile.readRegNoEffect(miscReg);
+}
+
+MiscReg RegFile::readMiscReg(int miscReg, ThreadContext *tc)
+{
+ return miscRegFile.readReg(miscReg, tc);
+}
+
+void RegFile::setMiscRegNoEffect(int miscReg, const MiscReg &val)
+{
+ miscRegFile.setRegNoEffect(miscReg, val);
+}
+
+void RegFile::setMiscReg(int miscReg, const MiscReg &val,
+ ThreadContext * tc)
+{
+ miscRegFile.setReg(miscReg, val, tc);
+}
+
+FloatReg RegFile::readFloatReg(int floatReg, int width)
+{
+ return floatRegFile.readReg(floatReg, width);
+}
+
+FloatReg RegFile::readFloatReg(int floatReg)
+{
+ //Use the "natural" width of a single float
+ return floatRegFile.readReg(floatReg, FloatRegFile::SingleWidth);
+}
+
+FloatRegBits RegFile::readFloatRegBits(int floatReg, int width)
+{
+ return floatRegFile.readRegBits(floatReg, width);
+}
+
+FloatRegBits RegFile::readFloatRegBits(int floatReg)
+{
+ //Use the "natural width of a single float
+ return floatRegFile.readRegBits(floatReg,
+ FloatRegFile::SingleWidth);
+}
+
+void RegFile::setFloatReg(int floatReg, const FloatReg &val, int width)
+{
+ floatRegFile.setReg(floatReg, val, width);
+}
+
+void RegFile::setFloatReg(int floatReg, const FloatReg &val)
+{
+ //Use the "natural" width of a single float
+ setFloatReg(floatReg, val, FloatRegFile::SingleWidth);
+}
+
+void RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
+{
+ floatRegFile.setRegBits(floatReg, val, width);
+}
+
+void RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val)
+{
+ //Use the "natural" width of a single float
+ floatRegFile.setRegBits(floatReg, val, FloatRegFile::SingleWidth);
+}
+
+IntReg RegFile::readIntReg(int intReg)
+{
+ return intRegFile.readReg(intReg);
+}
+
+void RegFile::setIntReg(int intReg, const IntReg &val)
+{
+ intRegFile.setReg(intReg, val);
+}
+
+int X86ISA::flattenIntIndex(ThreadContext * tc, int reg)
+{
+ //For right now, don't do any flattening
+ return reg;
+}
+
+void RegFile::serialize(std::ostream &os)
+{
+ intRegFile.serialize(os);
+ floatRegFile.serialize(os);
+ miscRegFile.serialize(os);
+ SERIALIZE_SCALAR(rip);
+ SERIALIZE_SCALAR(nextRip);
+}
+
+void RegFile::unserialize(Checkpoint *cp, const std::string &section)
+{
+ intRegFile.unserialize(cp, section);
+ floatRegFile.unserialize(cp, section);
+ miscRegFile.unserialize(cp, section);
+ UNSERIALIZE_SCALAR(rip);
+ UNSERIALIZE_SCALAR(nextRip);
+}
+
+void RegFile::changeContext(RegContextParam param, RegContextVal val)
+{
+ panic("changeContext not implemented for x86!\n");
+}
+
+void X86ISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
+{
+ panic("copyMiscRegs not implemented for x86!\n");
+}
+
+void X86ISA::copyRegs(ThreadContext *src, ThreadContext *dest)
+{
+ panic("copyRegs not implemented for x86!\n");
+ //copy int regs
+ //copy float regs
+ copyMiscRegs(src, dest);
+
+ dest->setPC(src->readPC());
+ dest->setNextPC(src->readNextPC());
+}
diff --git a/src/arch/x86/regfile.hh b/src/arch/x86/regfile.hh
new file mode 100644
index 000000000..d4425b04c
--- /dev/null
+++ b/src/arch/x86/regfile.hh
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_REGFILE_HH__
+#define __ARCH_X86_REGFILE_HH__
+
+#include "arch/x86/floatregfile.hh"
+#include "arch/x86/intregfile.hh"
+#include "arch/x86/isa_traits.hh"
+#include "arch/x86/miscregfile.hh"
+#include "arch/x86/types.hh"
+#include "sim/host.hh"
+
+#include <string>
+
+class Checkpoint;
+
+namespace X86ISA
+{
+ class RegFile
+ {
+ protected:
+ Addr rip; //Program Counter
+ Addr nextRip; //Next Program Counter
+
+ public:
+ Addr readPC();
+ void setPC(Addr val);
+
+ Addr readNextPC();
+ void setNextPC(Addr val);
+
+ Addr readNextNPC();
+ void setNextNPC(Addr val);
+
+ protected:
+ IntRegFile intRegFile; // integer register file
+ FloatRegFile floatRegFile; // floating point register file
+ MiscRegFile miscRegFile; // control register file
+
+ public:
+
+ void clear();
+
+ int FlattenIntIndex(int reg);
+
+ MiscReg readMiscRegNoEffect(int miscReg);
+
+ MiscReg readMiscReg(int miscReg, ThreadContext *tc);
+
+ void setMiscRegNoEffect(int miscReg, const MiscReg &val);
+
+ void setMiscReg(int miscReg, const MiscReg &val,
+ ThreadContext * tc);
+
+ int instAsid()
+ {
+ //XXX This doesn't make sense in x86
+ return 0;
+ }
+
+ int dataAsid()
+ {
+ //XXX This doesn't make sense in x86
+ return 0;
+ }
+
+ FloatReg readFloatReg(int floatReg, int width);
+
+ FloatReg readFloatReg(int floatReg);
+
+ FloatRegBits readFloatRegBits(int floatReg, int width);
+
+ FloatRegBits readFloatRegBits(int floatReg);
+
+ void setFloatReg(int floatReg, const FloatReg &val, int width);
+
+ void setFloatReg(int floatReg, const FloatReg &val);
+
+ void setFloatRegBits(int floatReg, const FloatRegBits &val, int width);
+
+ void setFloatRegBits(int floatReg, const FloatRegBits &val);
+
+ IntReg readIntReg(int intReg);
+
+ void setIntReg(int intReg, const IntReg &val);
+
+ void serialize(std::ostream &os);
+ void unserialize(Checkpoint *cp, const std::string &section);
+
+ public:
+
+ void changeContext(RegContextParam param, RegContextVal val);
+ };
+
+ int flattenIntIndex(ThreadContext * tc, int reg);
+
+ void copyRegs(ThreadContext *src, ThreadContext *dest);
+
+ void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
+
+ int InterruptLevel(uint64_t softint);
+
+}; // namespace X86ISA
+
+#endif // __ARCH_X86_REGFILE_HH__
diff --git a/src/arch/x86/remote_gdb.cc b/src/arch/x86/remote_gdb.cc
new file mode 100644
index 000000000..5ab0ec3fb
--- /dev/null
+++ b/src/arch/x86/remote_gdb.cc
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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
+ */
+
+/*
+ * 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/x86/remote_gdb.hh"
+#include "base/remote_gdb.hh"
+#include "base/socket.hh"
+#include "base/trace.hh"
+#include "config/full_system.hh"
+#include "cpu/thread_context.hh"
+
+using namespace std;
+using namespace TheISA;
+
+RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
+ : BaseRemoteGDB(_system, c, NumGDBRegs)
+{}
+
+bool RemoteGDB::acc(Addr va, size_t len)
+{
+ panic("Remote gdb acc not implemented in x86!\n");
+}
+
+void RemoteGDB::getregs()
+{
+ panic("Remote gdb getregs not implemented in x86!\n");
+}
+
+void RemoteGDB::setregs()
+{
+ panic("Remote gdb setregs not implemented in x86!\n");
+}
+
+void RemoteGDB::clearSingleStep()
+{
+ panic("Remote gdb clearSingleStep not implemented in x86!\n");
+}
+
+void RemoteGDB::setSingleStep()
+{
+ panic("Remoge gdb setSingleStep not implemented in x86!\n");
+}
diff --git a/src/arch/x86/remote_gdb.hh b/src/arch/x86/remote_gdb.hh
new file mode 100644
index 000000000..e21250875
--- /dev/null
+++ b/src/arch/x86/remote_gdb.hh
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_REMOTEGDB_HH__
+#define __ARCH_X86_REMOTEGDB_HH__
+
+#include "arch/x86/types.hh"
+#include "base/remote_gdb.hh"
+
+class System;
+class ThreadContext;
+
+namespace X86ISA
+{
+ class RemoteGDB : public BaseRemoteGDB
+ {
+ protected:
+ enum RegisterContants
+ {
+ NumGDBRegs
+ //XXX fill this in
+ };
+
+ public:
+ RemoteGDB(System *system, ThreadContext *context);
+
+ bool acc(Addr addr, size_t len);
+
+ protected:
+ void getregs();
+ void setregs();
+
+ void clearSingleStep();
+ void setSingleStep();
+
+ Addr nextBkpt;
+ };
+}
+
+#endif // __ARCH_X86_REMOTEGDB_HH__
diff --git a/src/arch/x86/stacktrace.hh b/src/arch/x86/stacktrace.hh
new file mode 100644
index 000000000..854fb397c
--- /dev/null
+++ b/src/arch/x86/stacktrace.hh
@@ -0,0 +1,122 @@
+/*
+ * 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: Nathan Binkert
+ */
+
+#ifndef __ARCH_X86_STACKTRACE_HH__
+#define __ARCH_X86_STACKTRACE_HH__
+
+#include "base/trace.hh"
+#include "cpu/static_inst.hh"
+
+class ThreadContext;
+namespace X86ISA
+{
+ class StackTrace;
+
+ class ProcessInfo
+ {
+ private:
+ ThreadContext *tc;
+
+ int thread_info_size;
+ int task_struct_size;
+ int task_off;
+ int pid_off;
+ int name_off;
+
+ public:
+ ProcessInfo(ThreadContext *_tc);
+
+ Addr task(Addr ksp) const;
+ int pid(Addr ksp) const;
+ std::string name(Addr ksp) const;
+ };
+
+ class StackTrace
+ {
+ 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()
+ {
+ 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();
+
+ public:
+ void dprintf() { if (DTRACE(Stack)) dump(); }
+#else
+ public:
+ void dprintf() {}
+#endif
+ };
+
+ inline bool
+ StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
+ {
+ if (!inst->isCall() && !inst->isReturn())
+ return false;
+
+ if (valid())
+ clear();
+
+ trace(tc, !inst->isReturn());
+ return true;
+ }
+}
+
+#endif // __ARCH_X86_STACKTRACE_HH__
diff --git a/src/arch/x86/syscallreturn.hh b/src/arch/x86/syscallreturn.hh
new file mode 100644
index 000000000..9f0d20e2a
--- /dev/null
+++ b/src/arch/x86/syscallreturn.hh
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_SYSCALLRETURN_HH__
+#define __ARCH_X86_SYSCALLRETURN_HH__
+
+#include "base/misc.hh"
+#include "sim/syscallreturn.hh"
+
+class ThreadContext;
+
+namespace X86ISA
+{
+ static inline void setSyscallReturn(SyscallReturn return_value,
+ ThreadContext * tc)
+ {
+ panic("setSyscallReturn not implemented!\n");
+ }
+};
+
+#endif // __ARCH_X86_SYSCALLRETURN_HH__
diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh
new file mode 100644
index 000000000..c19ce0b29
--- /dev/null
+++ b/src/arch/x86/tlb.hh
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_TLB_HH__
+#define __ARCH_X86_TLB_HH__
+
+#error X86 is not yet supported!
+
+namespace X86ISA
+{
+};
+
+#endif // __ARCH_X86_TLB_HH__
diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh
new file mode 100644
index 000000000..ca4a15d24
--- /dev/null
+++ b/src/arch/x86/types.hh
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_TYPES_HH__
+#define __ARCH_X86_TYPES_HH__
+
+#include <inttypes.h>
+#include <iostream>
+
+#include "base/bitfield.hh"
+#include "base/cprintf.hh"
+
+namespace X86ISA
+{
+ //This really determines how many bytes are passed to the predecoder.
+ typedef uint64_t MachInst;
+
+ enum Prefixes {
+ NoOverride = 0,
+ CSOverride = 1,
+ DSOverride = 2,
+ ESOverride = 3,
+ FSOverride = 4,
+ GSOverride = 5,
+ SSOverride = 6,
+ //The Rex prefix obviously doesn't fit in with the above, but putting
+ //it here lets us save double the space the enums take up.
+ RexPrefix = 7,
+ //There can be only one segment override, so they share the
+ //first 3 bits in the legacyPrefixes bitfield.
+ SegmentOverride = 0x7,
+ OperandSizeOverride = 8,
+ AddressSizeOverride = 16,
+ Lock = 32,
+ Rep = 64,
+ Repne = 128
+ };
+
+ BitUnion8(ModRM)
+ Bitfield<7,6> mod;
+ Bitfield<5,3> reg;
+ Bitfield<2,0> rm;
+ EndBitUnion(ModRM)
+
+ BitUnion8(Sib)
+ Bitfield<7,6> scale;
+ Bitfield<5,3> index;
+ Bitfield<2,0> base;
+ EndBitUnion(Sib)
+
+ BitUnion8(Rex)
+ Bitfield<3> w;
+ Bitfield<2> r;
+ Bitfield<1> x;
+ Bitfield<0> b;
+ EndBitUnion(Rex)
+
+ BitUnion8(Opcode)
+ Bitfield<7,3> top5;
+ Bitfield<2,0> bottom3;
+ EndBitUnion(Opcode)
+
+ //The intermediate structure the x86 predecoder returns.
+ struct ExtMachInst
+ {
+ //Prefixes
+ uint8_t legacy;
+ Rex rex;
+ //This holds all of the bytes of the opcode
+ struct
+ {
+ //The number of bytes in this opcode. Right now, we ignore that
+ //this can be 3 in some cases
+ uint8_t num;
+ //The first byte detected in a 2+ byte opcode. Should be 0xF0.
+ uint8_t prefixA;
+ //The second byte detected in a 3+ byte opcode. Could be 0xF0 for
+ //3dnow instructions, or 0x38-0x3F for some SSE instructions.
+ uint8_t prefixB;
+ //The main opcode byte. The highest addressed byte in the opcode.
+ Opcode op;
+ } opcode;
+ //Modifier bytes
+ ModRM modRM;
+ uint8_t sib;
+ //Immediate fields
+ uint64_t immediate;
+ uint64_t displacement;
+ };
+
+ inline static std::ostream &
+ operator << (std::ostream & os, const ExtMachInst & emi)
+ {
+ ccprintf(os, "\n{\n\tleg = %#x,\n\trex = %#x,\n\t"
+ "op = {\n\t\tnum = %d,\n\t\top = %#x,\n\t\t"
+ "prefixA = %#x,\n\t\tprefixB = %#x\n\t},\n\t"
+ "modRM = %#x,\n\tsib = %#x,\n\t"
+ "immediate = %#x,\n\tdisplacement = %#x\n}\n",
+ emi.legacy, (uint8_t)emi.rex,
+ emi.opcode.num, emi.opcode.op,
+ emi.opcode.prefixA, emi.opcode.prefixB,
+ (uint8_t)emi.modRM, (uint8_t)emi.sib,
+ emi.immediate, emi.displacement);
+ return os;
+ }
+
+ inline static bool
+ operator == (const ExtMachInst &emi1, const ExtMachInst &emi2)
+ {
+ //Since this is empty, it's always equal
+ return true;
+ }
+
+ typedef uint64_t IntReg;
+ //XXX Should this be a 128 bit structure for XMM memory ops?
+ typedef uint64_t LargestRead;
+ typedef uint64_t MiscReg;
+
+ //These floating point types are correct for mmx, but not
+ //technically for x87 (80 bits) or at all for xmm (128 bits)
+ typedef double FloatReg;
+ typedef uint64_t FloatRegBits;
+ typedef union
+ {
+ IntReg intReg;
+ FloatReg fpReg;
+ MiscReg ctrlReg;
+ } AnyReg;
+
+ //XXX This is very hypothetical. X87 instructions would need to
+ //change their "context" constantly. It's also not clear how
+ //this would be handled as far as out of order execution.
+ //Maybe x87 instructions are in order?
+ enum RegContextParam
+ {
+ CONTEXT_X87_TOP
+ };
+
+ typedef int RegContextVal;
+
+ typedef uint8_t RegIndex;
+};
+
+#endif // __ARCH_X86_TYPES_HH__
diff --git a/src/arch/x86/utility.hh b/src/arch/x86/utility.hh
new file mode 100644
index 000000000..d89e223de
--- /dev/null
+++ b/src/arch/x86/utility.hh
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_UTILITY_HH__
+#define __ARCH_X86_UTILITY_HH__
+
+#include "arch/x86/types.hh"
+#include "base/hashmap.hh"
+#include "base/misc.hh"
+#include "cpu/thread_context.hh"
+#include "sim/host.hh"
+
+class ThreadContext;
+
+namespace __hash_namespace {
+ template<>
+ struct hash<X86ISA::ExtMachInst> {
+ size_t operator()(const X86ISA::ExtMachInst &emi) const {
+ //Because these are all the same, return 0
+ return 0;
+ };
+ };
+}
+
+namespace X86ISA
+{
+ static inline bool
+ inUserMode(ThreadContext *tc)
+ {
+ return false;
+ }
+
+ inline bool isCallerSaveIntegerRegister(unsigned int reg) {
+ panic("register classification not implemented");
+ return false;
+ }
+
+ inline bool isCalleeSaveIntegerRegister(unsigned int reg) {
+ panic("register classification not implemented");
+ return false;
+ }
+
+ inline bool isCallerSaveFloatRegister(unsigned int reg) {
+ panic("register classification not implemented");
+ return false;
+ }
+
+ inline bool isCalleeSaveFloatRegister(unsigned int reg) {
+ panic("register classification not implemented");
+ return false;
+ }
+
+ // Instruction address compression hooks
+ inline Addr realPCToFetchPC(const Addr &addr)
+ {
+ return addr;
+ }
+
+ inline Addr fetchPCToRealPC(const Addr &addr)
+ {
+ return addr;
+ }
+
+ // the size of "fetched" instructions (not necessarily the size
+ // of real instructions for PISA)
+ inline size_t fetchInstSize()
+ {
+ return sizeof(MachInst);
+ }
+
+ /**
+ * Function to insure ISA semantics about 0 registers.
+ * @param tc The thread context.
+ */
+ template <class TC>
+ void zeroRegisters(TC *tc);
+
+ inline void initCPU(ThreadContext *tc, int cpuId)
+ {
+ panic("initCPU not implemented!\n");
+ }
+
+ inline void startupCPU(ThreadContext *tc, int cpuId)
+ {
+ tc->activate(0);
+ }
+};
+
+#endif // __ARCH_X86_UTILITY_HH__
diff --git a/src/arch/x86/vtophys.hh b/src/arch/x86/vtophys.hh
new file mode 100644
index 000000000..00d0f9499
--- /dev/null
+++ b/src/arch/x86/vtophys.hh
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_VTOPHYS_HH__
+#define __ARCH_X86_VTOPHYS_HH__
+
+#include "arch/x86/isa_traits.hh"
+#include "arch/x86/pagetable.hh"
+#include "sim/host.hh"
+
+class ThreadContext;
+class FunctionalPort;
+
+namespace X86ISA
+{
+
+PageTableEntry
+kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, X86ISA::VAddr vaddr);
+
+Addr vtophys(Addr vaddr);
+Addr vtophys(ThreadContext *tc, Addr vaddr);
+
+};
+
+#endif // __ARCH_X86_VTOPHYS_HH__
diff --git a/src/arch/x86/x86_traits.hh b/src/arch/x86/x86_traits.hh
new file mode 100644
index 000000000..fa54c24e9
--- /dev/null
+++ b/src/arch/x86/x86_traits.hh
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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_X86_X86TRAITS_HH__
+#define __ARCH_X86_X86TRAITS_HH__
+
+namespace X86ISA
+{
+ //XXX This will definitely need to be something larger in the future.
+ const int NumMicroIntRegs = 0;
+
+ const int NumMMXRegs = 8;
+ const int NumXMMRegs = 16;
+}
+
+#endif //__ARCH_X86_X86TRAITS_HH__
diff --git a/src/base/SConscript b/src/base/SConscript
new file mode 100644
index 000000000..788aa3e6f
--- /dev/null
+++ b/src/base/SConscript
@@ -0,0 +1,83 @@
+# -*- 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: Nathan Binkert
+
+Import('*')
+
+# base/traceflags.{cc,hh} are generated from base/traceflags.py.
+# $TARGET.base will expand to "<build-dir>/base/traceflags".
+env.Command(['traceflags.hh', 'traceflags.cc'], 'traceflags.py',
+ 'python $SOURCE $TARGET.base')
+
+Source('annotate.cc')
+Source('bigint.cc')
+Source('circlebuf.cc')
+Source('cprintf.cc')
+Source('crc.cc')
+Source('fast_alloc.cc')
+Source('fifo_buffer.cc')
+Source('hostinfo.cc')
+Source('hybrid_pred.cc')
+Source('inet.cc')
+Source('inifile.cc')
+Source('intmath.cc')
+Source('match.cc')
+Source('misc.cc')
+Source('output.cc')
+Source('pollevent.cc')
+Source('random.cc')
+Source('range.cc')
+Source('remote_gdb.cc')
+Source('sat_counter.cc')
+Source('socket.cc')
+Source('statistics.cc')
+Source('str.cc')
+Source('time.cc')
+Source('trace.cc')
+Source('traceflags.cc')
+Source('userinfo.cc')
+
+Source('compression/lzss_compression.cc')
+
+Source('loader/aout_object.cc')
+Source('loader/ecoff_object.cc')
+Source('loader/elf_object.cc')
+Source('loader/object_file.cc')
+Source('loader/raw_object.cc')
+Source('loader/symtab.cc')
+
+Source('stats/events.cc')
+Source('stats/output.cc')
+Source('stats/statdb.cc')
+Source('stats/text.cc')
+Source('stats/visit.cc')
+
+if env['USE_MYSQL']:
+ Source('mysql.cc')
+ Source('stats/mysql.cc')
diff --git a/src/base/annotate.cc b/src/base/annotate.cc
index ba2fb1788..de7eeed51 100644
--- a/src/base/annotate.cc
+++ b/src/base/annotate.cc
@@ -32,7 +32,7 @@
#include "base/callback.hh"
#include "base/output.hh"
#include "base/trace.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
#include "sim/sim_exit.hh"
#include "sim/system.hh"
diff --git a/src/base/bigint.cc b/src/base/bigint.cc
new file mode 100644
index 000000000..ce9942c9c
--- /dev/null
+++ b/src/base/bigint.cc
@@ -0,0 +1,47 @@
+/*
+ * 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 "base/bigint.hh"
+
+#include <iostream>
+
+using namespace std;
+
+ostream & operator << (ostream & os, const Twin64_t & t)
+{
+ os << t.a << ", " << t.b;
+ return os;
+}
+
+ostream & operator << (ostream & os, const Twin32_t & t)
+{
+ os << t.a << ", " << t.b;
+ return os;
+}
diff --git a/src/base/bigint.hh b/src/base/bigint.hh
new file mode 100644
index 000000000..d60684231
--- /dev/null
+++ b/src/base/bigint.hh
@@ -0,0 +1,97 @@
+/*
+ * 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 "base/misc.hh"
+
+#include <iostream>
+
+#ifndef __BASE_BIGINT_HH__
+#define __BASE_BIGINT_HH__
+// Create a couple of large int types for atomic reads
+struct m5_twin64_t {
+ uint64_t a;
+ uint64_t b;
+ m5_twin64_t()
+ {}
+ m5_twin64_t(const uint64_t x)
+ {
+ a = x;
+ b = x;
+ }
+ inline m5_twin64_t& operator=(const uint64_t x)
+ {
+ a = x;
+ b = x;
+ return *this;
+ }
+
+ operator uint64_t()
+ {
+ panic("Tried to cram a twin64_t into an integer!\n");
+ return a;
+ }
+};
+
+struct m5_twin32_t {
+ uint32_t a;
+ uint32_t b;
+ m5_twin32_t()
+ {}
+ m5_twin32_t(const uint32_t x)
+ {
+ a = x;
+ b = x;
+ }
+ inline m5_twin32_t& operator=(const uint32_t x)
+ {
+ a = x;
+ b = x;
+ return *this;
+ }
+
+ operator uint32_t()
+ {
+ panic("Tried to cram a twin32_t into an integer!\n");
+ return a;
+ }
+};
+
+
+// This is for twin loads (two 64 bit values), not 1 128 bit value (as far as
+// endian conversion is concerned!
+typedef m5_twin64_t Twin64_t;
+typedef m5_twin32_t Twin32_t;
+
+// Output operator overloads
+std::ostream & operator << (std::ostream & os, const Twin64_t & t);
+std::ostream & operator << (std::ostream & os, const Twin32_t & t);
+
+#endif // __BASE_BIGINT_HH__
+
diff --git a/src/base/bitfield.hh b/src/base/bitfield.hh
index 1fc0bad5d..69cce2245 100644
--- a/src/base/bitfield.hh
+++ b/src/base/bitfield.hh
@@ -44,6 +44,7 @@ mask(int nbits)
}
+
/**
* Extract the bitfield from position 'first' to 'last' (inclusive)
* from 'val' and right justify it. MSB is numbered 63, LSB is 0.
@@ -69,6 +70,12 @@ mbits(T val, int first, int last)
return val & (mask(first+1) & ~mask(last));
}
+inline uint64_t
+mask(int first, int last)
+{
+ return mbits((uint64_t)-1LL, first, last);
+}
+
/**
* Sign-extend an N-bit value to 64 bits.
*/
@@ -105,4 +112,291 @@ replaceBits(T& val, int first, int last, B bit_val)
val = insertBits(val, first, last, bit_val);
}
+/**
+ * Returns the bit position of the MSB that is set in the input
+ */
+inline
+int
+findMsbSet(uint64_t val) {
+ int msb = 0;
+ if (!val)
+ return 0;
+ if (bits(val, 63,32)) { msb += 32; val >>= 32; }
+ if (bits(val, 31,16)) { msb += 16; val >>= 16; }
+ if (bits(val, 15,8)) { msb += 8; val >>= 8; }
+ if (bits(val, 7,4)) { msb += 4; val >>= 4; }
+ if (bits(val, 3,2)) { msb += 2; val >>= 2; }
+ if (bits(val, 1,1)) { msb += 1; }
+ return msb;
+}
+
+// The following implements the BitUnion system of defining bitfields
+//on top of an underlying class. This is done through the pervasive use of
+//both named and unnamed unions which all contain the same actual storage.
+//Since they're unioned with each other, all of these storage locations
+//overlap. This allows all of the bitfields to manipulate the same data
+//without having to have access to each other. More details are provided with the
+//individual components.
+
+//This namespace is for classes which implement the backend of the BitUnion
+//stuff. Don't use any of these directly, except for the Bitfield classes in
+//the *BitfieldTypes class(es).
+namespace BitfieldBackend
+{
+ //A base class for all bitfields. It instantiates the actual storage,
+ //and provides getBits and setBits functions for manipulating it. The
+ //Data template parameter is type of the underlying storage.
+ template<class Data>
+ class BitfieldBase
+ {
+ protected:
+ Data __data;
+
+ //This function returns a range of bits from the underlying storage.
+ //It relies on the "bits" function above. It's the user's
+ //responsibility to make sure that there is a properly overloaded
+ //version of this function for whatever type they want to overlay.
+ inline uint64_t
+ getBits(int first, int last) const
+ {
+ return bits(__data, first, last);
+ }
+
+ //Similar to the above, but for settings bits with replaceBits.
+ inline void
+ setBits(int first, int last, uint64_t val)
+ {
+ replaceBits(__data, first, last, val);
+ }
+ };
+
+ //This class contains all the "regular" bitfield classes. It is inherited
+ //by all BitUnions which give them access to those types.
+ template<class Type>
+ class RegularBitfieldTypes
+ {
+ protected:
+ //This class implements ordinary bitfields, that is a span of bits
+ //who's msb is "first", and who's lsb is "last".
+ template<int first, int last=first>
+ class Bitfield : public BitfieldBase<Type>
+ {
+ public:
+ operator uint64_t () const
+ {
+ return this->getBits(first, last);
+ }
+
+ uint64_t
+ operator=(const uint64_t _data)
+ {
+ this->setBits(first, last, _data);
+ return _data;
+ }
+ };
+
+ //A class which specializes the above so that it can only be read
+ //from. This is accomplished explicitly making sure the assignment
+ //operator is blocked. The conversion operator is carried through
+ //inheritance. This will unfortunately need to be copied into each
+ //bitfield type due to limitations with how templates work
+ template<int first, int last=first>
+ class BitfieldRO : public Bitfield<first, last>
+ {
+ private:
+ uint64_t
+ operator=(const uint64_t _data);
+ };
+
+ //Similar to the above, but only allows writing.
+ template<int first, int last=first>
+ class BitfieldWO : public Bitfield<first, last>
+ {
+ private:
+ operator uint64_t () const;
+
+ public:
+ using Bitfield<first, last>::operator=;
+ };
+ };
+
+ //This class contains all the "regular" bitfield classes. It is inherited
+ //by all BitUnions which give them access to those types.
+ template<class Type>
+ class SignedBitfieldTypes
+ {
+ protected:
+ //This class implements ordinary bitfields, that is a span of bits
+ //who's msb is "first", and who's lsb is "last".
+ template<int first, int last=first>
+ class SignedBitfield : public BitfieldBase<Type>
+ {
+ public:
+ operator int64_t () const
+ {
+ return sext<first - last + 1>(this->getBits(first, last));
+ }
+
+ int64_t
+ operator=(const int64_t _data)
+ {
+ this->setBits(first, last, _data);
+ return _data;
+ }
+ };
+
+ //A class which specializes the above so that it can only be read
+ //from. This is accomplished explicitly making sure the assignment
+ //operator is blocked. The conversion operator is carried through
+ //inheritance. This will unfortunately need to be copied into each
+ //bitfield type due to limitations with how templates work
+ template<int first, int last=first>
+ class SignedBitfieldRO : public SignedBitfield<first, last>
+ {
+ private:
+ int64_t
+ operator=(const int64_t _data);
+ };
+
+ //Similar to the above, but only allows writing.
+ template<int first, int last=first>
+ class SignedBitfieldWO : public SignedBitfield<first, last>
+ {
+ private:
+ operator int64_t () const;
+
+ public:
+ int64_t operator=(const int64_t _data)
+ {
+ *((SignedBitfield<first, last> *)this) = _data;
+ return _data;
+ }
+ };
+ };
+
+ template<class Type>
+ class BitfieldTypes : public RegularBitfieldTypes<Type>,
+ public SignedBitfieldTypes<Type>
+ {};
+
+ //When a BitUnion is set up, an underlying class is created which holds
+ //the actual union. This class then inherits from it, and provids the
+ //implementations for various operators. Setting things up this way
+ //prevents having to redefine these functions in every different BitUnion
+ //type. More operators could be implemented in the future, as the need
+ //arises.
+ template <class Type, class Base>
+ class BitUnionOperators : public Base
+ {
+ public:
+ operator Type () const
+ {
+ return Base::__data;
+ }
+
+ Type
+ operator=(const Type & _data)
+ {
+ Base::__data = _data;
+ return _data;
+ }
+
+ bool
+ operator<(const Base & base) const
+ {
+ return Base::__data < base.__data;
+ }
+
+ bool
+ operator==(const Base & base) const
+ {
+ return Base::__data == base.__data;
+ }
+ };
+}
+
+//This macro is a backend for other macros that specialize it slightly.
+//First, it creates/extends a namespace "BitfieldUnderlyingClasses" and
+//sticks the class which has the actual union in it, which
+//BitfieldOperators above inherits from. Putting these classes in a special
+//namespace ensures that there will be no collisions with other names as long
+//as the BitUnion names themselves are all distinct and nothing else uses
+//the BitfieldUnderlyingClasses namespace, which is unlikely. The class itself
+//creates a typedef of the "type" parameter called __DataType. This allows
+//the type to propagate outside of the macro itself in a controlled way.
+//Finally, the base storage is defined which BitfieldOperators will refer to
+//in the operators it defines. This macro is intended to be followed by
+//bitfield definitions which will end up inside it's union. As explained
+//above, these is overlayed the __data member in its entirety by each of the
+//bitfields which are defined in the union, creating shared storage with no
+//overhead.
+#define __BitUnion(type, name) \
+ namespace BitfieldUnderlyingClasses \
+ { \
+ class name; \
+ } \
+ class BitfieldUnderlyingClasses::name : \
+ public BitfieldBackend::BitfieldTypes<type> \
+ { \
+ public: \
+ typedef type __DataType; \
+ union { \
+ type __data;\
+
+//This closes off the class and union started by the above macro. It is
+//followed by a typedef which makes "name" refer to a BitfieldOperator
+//class inheriting from the class and union just defined, which completes
+//building up the type for the user.
+#define EndBitUnion(name) \
+ }; \
+ }; \
+ typedef BitfieldBackend::BitUnionOperators< \
+ BitfieldUnderlyingClasses::name::__DataType, \
+ BitfieldUnderlyingClasses::name> name;
+
+//This sets up a bitfield which has other bitfields nested inside of it. The
+//__data member functions like the "underlying storage" of the top level
+//BitUnion. Like everything else, it overlays with the top level storage, so
+//making it a regular bitfield type makes the entire thing function as a
+//regular bitfield when referred to by itself.
+#define __SubBitUnion(fieldType, first, last, name) \
+ class : public BitfieldBackend::BitfieldTypes<__DataType> \
+ { \
+ public: \
+ union { \
+ fieldType<first, last> __data;
+
+//This closes off the union created above and gives it a name. Unlike the top
+//level BitUnion, we're interested in creating an object instead of a type.
+//The operators are defined in the macro itself instead of a class for
+//technical reasons. If someone determines a way to move them to one, please
+//do so.
+#define EndSubBitUnion(name) \
+ }; \
+ inline operator const __DataType () \
+ { return __data; } \
+ \
+ inline const __DataType operator = (const __DataType & _data) \
+ { __data = _data; } \
+ } name;
+
+//Regular bitfields
+//These define macros for read/write regular bitfield based subbitfields.
+#define SubBitUnion(name, first, last) \
+ __SubBitUnion(Bitfield, first, last, name)
+
+//Regular bitfields
+//These define macros for read/write regular bitfield based subbitfields.
+#define SignedSubBitUnion(name, first, last) \
+ __SubBitUnion(SignedBitfield, first, last, name)
+
+//Use this to define an arbitrary type overlayed with bitfields.
+#define BitUnion(type, name) __BitUnion(type, name)
+
+//Use this to define conveniently sized values overlayed with bitfields.
+#define BitUnion64(name) __BitUnion(uint64_t, name)
+#define BitUnion32(name) __BitUnion(uint32_t, name)
+#define BitUnion16(name) __BitUnion(uint16_t, name)
+#define BitUnion8(name) __BitUnion(uint8_t, name)
+
#endif // __BASE_BITFIELD_HH__
diff --git a/src/base/cprintf.cc b/src/base/cprintf.cc
index dd8ce858b..d4ba9ca21 100644
--- a/src/base/cprintf.cc
+++ b/src/base/cprintf.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2002-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,232 +39,247 @@ using namespace std;
namespace cp {
-ArgList::~ArgList()
+Print::Print(std::ostream &stream, const std::string &format)
+ : stream(stream), format(format.c_str()), ptr(format.c_str())
+{
+ saved_flags = stream.flags();
+ saved_fill = stream.fill();
+ saved_precision = stream.precision();
+}
+
+Print::Print(std::ostream &stream, const char *format)
+ : stream(stream), format(format), ptr(format)
+{
+ saved_flags = stream.flags();
+ saved_fill = stream.fill();
+ saved_precision = stream.precision();
+}
+
+Print::~Print()
{
- while (!objects.empty()) {
- delete objects.front();
- objects.pop_front();
- }
}
void
-ArgList::dump(const string &format)
+Print::process(Format &fmt)
{
- list_t::iterator iter = objects.begin();
- list_t::iterator end = objects.end();
-
- const char *p = format.c_str();
-
- stream->fill(' ');
- stream->flags((ios::fmtflags)0);
-
- while (*p) {
- switch (*p) {
- case '%': {
- if (p[1] == '%') {
- *stream << '%';
- p += 2;
- continue;
- }
-
- Format fmt;
- bool done = false;
- bool end_number = false;
- bool have_precision = false;
- int number = 0;
-
- while (!done) {
- ++p;
- if (*p >= '0' && *p <= '9') {
- if (end_number)
- continue;
- } else if (number > 0)
- end_number = true;
-
- switch (*p) {
- case 's':
- fmt.format = Format::string;
- done = true;
- break;
-
- case 'c':
- fmt.format = Format::character;
- done = true;
- break;
-
- case 'l':
- continue;
-
- case 'p':
- fmt.format = Format::integer;
- fmt.base = Format::hex;
- fmt.alternate_form = true;
- done = true;
- break;
-
- case 'X':
- fmt.uppercase = true;
- case 'x':
- fmt.base = Format::hex;
- fmt.format = Format::integer;
- done = true;
- break;
-
- case 'o':
- fmt.base = Format::oct;
- fmt.format = Format::integer;
- done = true;
- break;
-
- case 'd':
- case 'i':
- case 'u':
- fmt.format = Format::integer;
- done = true;
- break;
-
- case 'G':
- fmt.uppercase = true;
- case 'g':
- fmt.format = Format::floating;
- fmt.float_format = Format::best;
- done = true;
- break;
-
- case 'E':
- fmt.uppercase = true;
- case 'e':
- fmt.format = Format::floating;
- fmt.float_format = Format::scientific;
- done = true;
- break;
-
- case 'f':
- fmt.format = Format::floating;
- fmt.float_format = Format::fixed;
- done = true;
- break;
-
- case 'n':
- *stream << "we don't do %n!!!\n";
- done = true;
- break;
-
- case '#':
- fmt.alternate_form = true;
- break;
-
- case '-':
- fmt.flush_left = true;
- break;
-
- case '+':
- fmt.print_sign = true;
- break;
-
- case ' ':
- fmt.blank_space = true;
- break;
-
- case '.':
- fmt.width = number;
- fmt.precision = 0;
- have_precision = true;
- number = 0;
- end_number = false;
- break;
-
- case '0':
- if (number == 0) {
- fmt.fill_zero = true;
- break;
- }
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- number = number * 10 + (*p - '0');
- break;
-
- case '%':
- assert("we shouldn't get here");
- break;
-
- default:
- done = true;
- break;
- }
-
- if (end_number) {
- if (have_precision)
- fmt.precision = number;
- else
- fmt.width = number;
-
- end_number = false;
- number = 0;
- }
- }
-
- if (iter != end)
- {
- ios::fmtflags saved_flags = stream->flags();
- char old_fill = stream->fill();
- int old_precision = stream->precision();
-
- (*iter)->process(*stream, fmt);
-
- stream->flags(saved_flags);
- stream->fill(old_fill);
- stream->precision(old_precision);
-
- ++iter;
- } else {
- *stream << "<missing arg for format>";
- }
-
- ++p;
- }
+ size_t len;
+
+ while (*ptr) {
+ switch (*ptr) {
+ case '%':
+ if (ptr[1] != '%')
+ goto processing;
+
+ stream.put('%');
+ ptr += 2;
break;
case '\n':
- *stream << endl;
- ++p;
+ stream << endl;
+ ++ptr;
break;
case '\r':
- ++p;
- if (*p != '\n')
- *stream << endl;
+ ++ptr;
+ if (*ptr != '\n')
+ stream << endl;
break;
- default: {
- size_t len = strcspn(p, "%\n\r\0");
- stream->write(p, len);
- p += len;
- }
+ default:
+ len = strcspn(ptr, "%\n\r\0");
+ stream.write(ptr, len);
+ ptr += len;
break;
}
}
- while (iter != end) {
- *stream << "<extra arg>";
- ++iter;
+ return;
+
+ processing:
+ bool done = false;
+ bool end_number = false;
+ bool have_precision = false;
+ int number = 0;
+
+ stream.fill(' ');
+ stream.flags((ios::fmtflags)0);
+
+ while (!done) {
+ ++ptr;
+ if (*ptr >= '0' && *ptr <= '9') {
+ if (end_number)
+ continue;
+ } else if (number > 0)
+ end_number = true;
+
+ switch (*ptr) {
+ case 's':
+ fmt.format = Format::string;
+ done = true;
+ break;
+
+ case 'c':
+ fmt.format = Format::character;
+ done = true;
+ break;
+
+ case 'l':
+ continue;
+
+ case 'p':
+ fmt.format = Format::integer;
+ fmt.base = Format::hex;
+ fmt.alternate_form = true;
+ done = true;
+ break;
+
+ case 'X':
+ fmt.uppercase = true;
+ case 'x':
+ fmt.base = Format::hex;
+ fmt.format = Format::integer;
+ done = true;
+ break;
+
+ case 'o':
+ fmt.base = Format::oct;
+ fmt.format = Format::integer;
+ done = true;
+ break;
+
+ case 'd':
+ case 'i':
+ case 'u':
+ fmt.format = Format::integer;
+ done = true;
+ break;
+
+ case 'G':
+ fmt.uppercase = true;
+ case 'g':
+ fmt.format = Format::floating;
+ fmt.float_format = Format::best;
+ done = true;
+ break;
+
+ case 'E':
+ fmt.uppercase = true;
+ case 'e':
+ fmt.format = Format::floating;
+ fmt.float_format = Format::scientific;
+ done = true;
+ break;
+
+ case 'f':
+ fmt.format = Format::floating;
+ fmt.float_format = Format::fixed;
+ done = true;
+ break;
+
+ case 'n':
+ stream << "we don't do %n!!!\n";
+ done = true;
+ break;
+
+ case '#':
+ fmt.alternate_form = true;
+ break;
+
+ case '-':
+ fmt.flush_left = true;
+ break;
+
+ case '+':
+ fmt.print_sign = true;
+ break;
+
+ case ' ':
+ fmt.blank_space = true;
+ break;
+
+ case '.':
+ fmt.width = number;
+ fmt.precision = 0;
+ have_precision = true;
+ number = 0;
+ end_number = false;
+ break;
+
+ case '0':
+ if (number == 0) {
+ fmt.fill_zero = true;
+ break;
+ }
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ number = number * 10 + (*ptr - '0');
+ break;
+
+ case '%':
+ assert("we shouldn't get here");
+ break;
+
+ default:
+ done = true;
+ break;
+ }
+
+ if (end_number) {
+ if (have_precision)
+ fmt.precision = number;
+ else
+ fmt.width = number;
+
+ end_number = false;
+ number = 0;
+ }
}
+
+ ++ptr;
}
-string
-ArgList::dumpToString(const string &format)
+void
+Print::end_args()
{
- stringstream ss;
+ size_t len;
- dump(ss, format);
+ while (*ptr) {
+ switch (*ptr) {
+ case '%':
+ if (ptr[1] != '%')
+ stream << "<extra arg>";
- return ss.str();
-}
+ stream.put('%');
+ ptr += 2;
+ break;
+ case '\n':
+ stream << endl;
+ ++ptr;
+ break;
+ case '\r':
+ ++ptr;
+ if (*ptr != '\n')
+ stream << endl;
+ break;
+
+ default:
+ len = strcspn(ptr, "%\n\r\0");
+ stream.write(ptr, len);
+ ptr += len;
+ break;
+ }
+ }
+
+ stream.flags(saved_flags);
+ stream.fill(saved_fill);
+ stream.precision(saved_precision);
}
+
+/* end namespace cp */ }
diff --git a/src/base/cprintf.hh b/src/base/cprintf.hh
index dd2256e69..cff73a228 100644
--- a/src/base/cprintf.hh
+++ b/src/base/cprintf.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2002-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,142 +29,135 @@
* Steve Reinhardt
*/
-#ifndef __CPRINTF_HH__
-#define __CPRINTF_HH__
+#ifndef __BASE_CPRINTF_HH__
+#define __BASE_CPRINTF_HH__
+#include <ios>
#include <iostream>
#include <list>
#include <string>
+#include "base/varargs.hh"
#include "base/cprintf_formats.hh"
namespace cp {
-class ArgList
+#define CPRINTF_DECLARATION VARARGS_DECLARATION(cp::Print)
+#define CPRINTF_DEFINITION VARARGS_DEFINITION(cp::Print)
+
+struct Print
{
- private:
- class Base
- {
- public:
- virtual ~Base() {}
- virtual void process(std::ostream &out, Format &fmt) = 0;
- };
+ protected:
+ std::ostream &stream;
+ const char *format;
+ const char *ptr;
+
+ std::ios::fmtflags saved_flags;
+ char saved_fill;
+ int saved_precision;
+
+ void process(Format &fmt);
+
+ public:
+ Print(std::ostream &stream, const std::string &format);
+ Print(std::ostream &stream, const char *format);
+ ~Print();
template <typename T>
- class Node : public Base
+ void
+ add_arg(const T &data)
{
- public:
- const T &data;
-
- public:
- Node(const T &d) : data(d) {}
- virtual void process(std::ostream &out, Format &fmt) {
- switch (fmt.format) {
- case Format::character:
- format_char(out, data, fmt);
- break;
-
- case Format::integer:
- format_integer(out, data, fmt);
- break;
-
- case Format::floating:
- format_float(out, data, fmt);
- break;
-
- case Format::string:
- format_string(out, data, fmt);
- break;
-
- default:
- out << "<bad format>";
- break;
- }
- }
- };
+ Format fmt;
+ process(fmt);
- typedef std::list<Base *> list_t;
+ switch (fmt.format) {
+ case Format::character:
+ format_char(stream, data, fmt);
+ break;
- protected:
- list_t objects;
- std::ostream *stream;
+ case Format::integer:
+ format_integer(stream, data, fmt);
+ break;
- public:
- ArgList() : stream(&std::cout) {}
- ~ArgList();
+ case Format::floating:
+ format_float(stream, data, fmt);
+ break;
- template<class T>
- void append(const T &data) {
- Base *obj = new ArgList::Node<T>(data);
- objects.push_back(obj);
- }
+ case Format::string:
+ format_string(stream, data, fmt);
+ break;
- template<class T>
- void prepend(const T &data) {
- Base *obj = new ArgList::Node<T>(data);
- objects.push_front(obj);
+ default:
+ stream << "<bad format>";
+ break;
+ }
}
- void dump(const std::string &format);
- void dump(std::ostream &strm, const std::string &fmt)
- { stream = &strm; dump(fmt); }
+ void end_args();
+};
- std::string dumpToString(const std::string &format);
+/* end namespace cp */ }
- friend ArgList &operator<<(std::ostream &str, ArgList &list);
-};
+typedef VarArgs::List<cp::Print> CPrintfArgsList;
+
+inline void
+ccprintf(std::ostream &stream, const char *format, const CPrintfArgsList &args)
+{
+ cp::Print print(stream, format);
+ args.add_args(print);
+}
-template<class T>
-inline ArgList &
-operator,(ArgList &alist, const T &data)
+inline void
+ccprintf(std::ostream &stream, const char *format, CPRINTF_DECLARATION)
{
- alist.append(data);
- return alist;
+ cp::Print print(stream, format);
+ VARARGS_ADDARGS(print);
}
-class ArgListNull {
-};
+inline void
+cprintf(const char *format, CPRINTF_DECLARATION)
+{
+ ccprintf(std::cout, format, VARARGS_ALLARGS);
+}
+
+inline std::string
+csprintf(const char *format, CPRINTF_DECLARATION)
+{
+ std::stringstream stream;
+ ccprintf(stream, format, VARARGS_ALLARGS);
+ return stream.str();
+}
-inline ArgList &
-operator,(ArgList &alist, ArgListNull)
-{ return alist; }
+/*
+ * functions again with std::string. We have both so we don't waste
+ * time converting const char * to std::string since we don't take
+ * advantage of it.
+ */
+inline void
+ccprintf(std::ostream &stream, const std::string &format,
+ const CPrintfArgsList &args)
+{
+ ccprintf(stream, format.c_str(), args);
+}
-//
-// cprintf(format, args, ...) prints to cout
-// (analogous to printf())
-//
inline void
-__cprintf(const std::string &format, ArgList &args)
-{ args.dump(format); delete &args; }
-#define __cprintf__(format, ...) \
- cp::__cprintf(format, (*(new cp::ArgList), __VA_ARGS__))
-#define cprintf(...) \
- __cprintf__(__VA_ARGS__, cp::ArgListNull())
-
-//
-// ccprintf(stream, format, args, ...) prints to the specified stream
-// (analogous to fprintf())
-//
+ccprintf(std::ostream &stream, const std::string &format, CPRINTF_DECLARATION)
+{
+ ccprintf(stream, format.c_str(), VARARGS_ALLARGS);
+}
+
inline void
-__ccprintf(std::ostream &stream, const std::string &format, ArgList &args)
-{ args.dump(stream, format); delete &args; }
-#define __ccprintf__(stream, format, ...) \
- cp::__ccprintf(stream, format, (*(new cp::ArgList), __VA_ARGS__))
-#define ccprintf(stream, ...) \
- __ccprintf__(stream, __VA_ARGS__, cp::ArgListNull())
-
-//
-// csprintf(format, args, ...) returns a string
-// (roughly analogous to sprintf())
-//
-inline std::string
-__csprintf(const std::string &format, ArgList &args)
-{ std::string s = args.dumpToString(format); delete &args; return s; }
-#define __csprintf__(format, ...) \
- cp::__csprintf(format, (*(new cp::ArgList), __VA_ARGS__))
-#define csprintf(...) \
- __csprintf__(__VA_ARGS__, cp::ArgListNull())
+cprintf(const std::string &format, CPRINTF_DECLARATION)
+{
+ ccprintf(std::cout, format.c_str(), VARARGS_ALLARGS);
+}
+inline std::string
+csprintf(const std::string &format, CPRINTF_DECLARATION)
+{
+ std::stringstream stream;
+ ccprintf(stream, format.c_str(), VARARGS_ALLARGS);
+ return stream.str();
}
#endif // __CPRINTF_HH__
diff --git a/src/base/cprintf_formats.hh b/src/base/cprintf_formats.hh
index 0af493217..4e8b2b09e 100644
--- a/src/base/cprintf_formats.hh
+++ b/src/base/cprintf_formats.hh
@@ -28,8 +28,8 @@
* Authors: Nathan Binkert
*/
-#ifndef __CPRINTF_FORMATS_HH__
-#define __CPRINTF_FORMATS_HH__
+#ifndef __BASE_CPRINTF_FORMATS_HH__
+#define __BASE_CPRINTF_FORMATS_HH__
#include <sstream>
#include <ostream>
diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc
index d59affe85..8f157da28 100644
--- a/src/base/loader/elf_object.cc
+++ b/src/base/loader/elf_object.cc
@@ -78,12 +78,23 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
//just assume if it wasn't something else and it's 64 bit, that's
//what it must be.
if (ehdr.e_machine == EM_SPARC64 ||
- ehdr.e_machine == EM_SPARC ||
+ (ehdr.e_machine == EM_SPARC &&
+ ehdr.e_ident[EI_CLASS] == ELFCLASS64)||
ehdr.e_machine == EM_SPARCV9) {
- arch = ObjectFile::SPARC;
+ arch = ObjectFile::SPARC64;
+ } else if (ehdr.e_machine == EM_SPARC32PLUS ||
+ (ehdr.e_machine == EM_SPARC &&
+ ehdr.e_ident[EI_CLASS] == ELFCLASS32)) {
+ arch = ObjectFile::SPARC32;
} else if (ehdr.e_machine == EM_MIPS
&& ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
arch = ObjectFile::Mips;
+ } else if (ehdr.e_machine == EM_X86_64 &&
+ ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
+ //In the future, we might want to differentiate between 32 bit
+ //and 64 bit x86 processes in case there are differences in their
+ //initial stack frame.
+ arch = ObjectFile::X86;
} else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
arch = ObjectFile::Alpha;
} else {
diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh
index 18e6482be..4b44a6e22 100644
--- a/src/base/loader/object_file.hh
+++ b/src/base/loader/object_file.hh
@@ -47,8 +47,10 @@ class ObjectFile
enum Arch {
UnknownArch,
Alpha,
- SPARC,
- Mips
+ SPARC64,
+ SPARC32,
+ Mips,
+ X86
};
enum OpSys {
diff --git a/src/base/misc.cc b/src/base/misc.cc
index 991a33736..afb48ca80 100644
--- a/src/base/misc.cc
+++ b/src/base/misc.cc
@@ -36,91 +36,99 @@
#include "base/misc.hh"
#include "base/output.hh"
#include "base/trace.hh"
+#include "base/varargs.hh"
#include "sim/host.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
using namespace std;
void
-__panic(const string &format, cp::ArgList &args, const char *func,
- const char *file, int line)
+__panic(const char *func, const char *file, int line, const char *fmt,
+ CPRINTF_DEFINITION)
{
- string fmt = "panic: " + format;
- switch (fmt[fmt.size() - 1]) {
+ string format = "panic: ";
+ format += fmt;
+ switch (format[format.size() - 1]) {
case '\n':
case '\r':
break;
default:
- fmt += "\n";
+ format += "\n";
}
- fmt += " @ cycle %d\n[%s:%s, line %d]\n";
+ format += " @ cycle %d\n[%s:%s, line %d]\n";
- args.append(curTick);
- args.append(func);
- args.append(file);
- args.append(line);
- args.dump(cerr, fmt);
+ CPrintfArgsList args(VARARGS_ALLARGS);
- delete &args;
+ args.push_back(curTick);
+ args.push_back(func);
+ args.push_back(file);
+ args.push_back(line);
+
+ ccprintf(cerr, format.c_str(), args);
abort();
}
void
-__fatal(const string &format, cp::ArgList &args, const char *func,
- const char *file, int line)
+__fatal(const char *func, const char *file, int line, const char *fmt,
+ CPRINTF_DEFINITION)
{
- string fmt = "fatal: " + format;
+ CPrintfArgsList args(VARARGS_ALLARGS);
+ string format = "fatal: ";
+ format += fmt;
- switch (fmt[fmt.size() - 1]) {
+ switch (format[format.size() - 1]) {
case '\n':
case '\r':
break;
default:
- fmt += "\n";
+ format += "\n";
}
- fmt += " @ cycle %d\n[%s:%s, line %d]\n";
- fmt += "Memory Usage: %ld KBytes\n";
+ format += " @ cycle %d\n[%s:%s, line %d]\n";
+ format += "Memory Usage: %ld KBytes\n";
- args.append(curTick);
- args.append(func);
- args.append(file);
- args.append(line);
- args.append(memUsage());
- args.dump(cerr, fmt);
+ args.push_back(curTick);
+ args.push_back(func);
+ args.push_back(file);
+ args.push_back(line);
+ args.push_back(memUsage());
- delete &args;
+ ccprintf(cerr, format.c_str(), args);
exit(1);
}
void
-__warn(const string &format, cp::ArgList &args, const char *func,
- const char *file, int line)
+__warn(const char *func, const char *file, int line, const char *fmt,
+ CPRINTF_DEFINITION)
{
- string fmt = "warn: " + format;
+ string format = "warn: ";
+ format += fmt;
- switch (fmt[fmt.size() - 1]) {
+ switch (format[format.size() - 1]) {
case '\n':
case '\r':
break;
default:
- fmt += "\n";
+ format += "\n";
}
#ifdef VERBOSE_WARN
- fmt += " @ cycle %d\n[%s:%s, line %d]\n";
- args.append(curTick);
- args.append(func);
- args.append(file);
- args.append(line);
+ format += " @ cycle %d\n[%s:%s, line %d]\n";
#endif
- args.dump(cerr, fmt);
- if (simout.isFile(*outputStream))
- args.dump(*outputStream, fmt);
+ CPrintfArgsList args(VARARGS_ALLARGS);
+
+#ifdef VERBOSE_WARN
+ args.push_back(curTick);
+ args.push_back(func);
+ args.push_back(file);
+ args.push_back(line);
+#endif
- delete &args;
+ ccprintf(cerr, format.c_str(), args);
+ if (simout.isFile(*outputStream))
+ ccprintf(*outputStream, format.c_str(), args);
}
diff --git a/src/base/misc.hh b/src/base/misc.hh
index c12c2fe20..1509ea2d2 100644
--- a/src/base/misc.hh
+++ b/src/base/misc.hh
@@ -32,9 +32,11 @@
#ifndef __MISC_HH__
#define __MISC_HH__
-#include <assert.h>
+#include <cassert>
+
#include "base/compiler.hh"
#include "base/cprintf.hh"
+#include "base/varargs.hh"
#if defined(__SUNPRO_CC)
#define __FUNCTION__ "how to fix me?"
@@ -47,14 +49,20 @@
// calls abort which can dump core or enter the debugger.
//
//
-void __panic(const std::string&, cp::ArgList &, const char*, const char*, int)
- M5_ATTR_NORETURN;
-#define __panic__(format, ...) \
- __panic(format, (*(new cp::ArgList), __VA_ARGS__), \
- __FUNCTION__ , __FILE__, __LINE__)
-#define panic(...) \
- __panic__(__VA_ARGS__, cp::ArgListNull())
+void __panic(const char *func, const char *file, int line, const char *format,
+ CPRINTF_DECLARATION) M5_ATTR_NORETURN;
+void __panic(const char *func, const char *file, int line,
+ const std::string &format, CPRINTF_DECLARATION)
+M5_ATTR_NORETURN;
+
+inline void
+__panic(const char *func, const char *file, int line,
+ const std::string &format, CPRINTF_DEFINITION)
+{
+ __panic(func, file, line, format.c_str(), VARARGS_ALLARGS);
+}
M5_PRAGMA_NORETURN(__panic)
+#define panic(...) __panic(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
//
// This implements a cprintf based fatal() function. fatal() should
@@ -64,34 +72,43 @@ M5_PRAGMA_NORETURN(__panic)
// "normal" exit with an error code, as opposed to abort() like
// panic() does.
//
-void __fatal(const std::string&, cp::ArgList &, const char*, const char*, int)
+void __fatal(const char *func, const char *file, int line, const char *format,
+ CPRINTF_DECLARATION) M5_ATTR_NORETURN;
+void __fatal(const char *func, const char *file, int line,
+ const std::string &format, CPRINTF_DECLARATION)
M5_ATTR_NORETURN;
-#define __fatal__(format, ...) \
- __fatal(format, (*(new cp::ArgList), __VA_ARGS__), \
- __FUNCTION__ , __FILE__, __LINE__)
-#define fatal(...) \
- __fatal__(__VA_ARGS__, cp::ArgListNull())
+
+inline void
+__fatal(const char *func, const char *file, int line,
+ const std::string &format, CPRINTF_DEFINITION)
+{
+ __fatal(func, file, line, format.c_str(), VARARGS_ALLARGS);
+}
M5_PRAGMA_NORETURN(__fatal)
+#define fatal(...) __fatal(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
//
// This implements a cprintf based warn
//
-void __warn(const std::string&, cp::ArgList &, const char*, const char*, int);
-#define __warn__(format, ...) \
- __warn(format, (*(new cp::ArgList), __VA_ARGS__), \
- __FUNCTION__ , __FILE__, __LINE__)
-#define warn(...) \
- __warn__(__VA_ARGS__, cp::ArgListNull())
+void __warn(const char *func, const char *file, int line, const char *format,
+ CPRINTF_DECLARATION);
+inline void
+__warn(const char *func, const char *file, int line, const std::string &format,
+ CPRINTF_DECLARATION)
+{
+ __warn(func, file, line, format, VARARGS_ALLARGS);
+}
+#define warn(...) __warn(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
// Only print the warning message the first time it is seen. This
// doesn't check the warning string itself, it just only lets one
// warning come from the statement. So, even if the arguments change
// and that would have resulted in a different warning message,
// subsequent messages would still be supressed.
-#define warn_once(...) do { \
+#define warn_once(...) do { \
static bool once = false; \
if (!once) { \
- __warn__(__VA_ARGS__, cp::ArgListNull()); \
+ warn(__VA_ARGS__); \
once = true; \
} \
} while (0)
@@ -99,10 +116,10 @@ void __warn(const std::string&, cp::ArgList &, const char*, const char*, int);
//
// assert() that prints out the current cycle
//
-#define m5_assert(TEST) \
- if (!(TEST)) { \
- std::cerr << "Assertion failure, curTick = " << curTick << std::endl; \
- } \
- assert(TEST);
+#define m5_assert(TEST) do { \
+ if (!(TEST)) \
+ ccprintf(std::cerr, "Assertion failure, curTick = %d\n", curTick); \
+ assert(TEST); \
+} while (0)
#endif // __MISC_HH__
diff --git a/src/base/pollevent.cc b/src/base/pollevent.cc
index 32724b74d..331b5eac6 100644
--- a/src/base/pollevent.cc
+++ b/src/base/pollevent.cc
@@ -42,7 +42,7 @@
#include "sim/host.hh"
#include "base/misc.hh"
#include "base/pollevent.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
#include "sim/serialize.hh"
using namespace std;
diff --git a/src/base/pollevent.hh b/src/base/pollevent.hh
index 5b84650cb..ecaeb94ce 100644
--- a/src/base/pollevent.hh
+++ b/src/base/pollevent.hh
@@ -33,7 +33,7 @@
#include <vector>
#include <poll.h>
-#include "sim/root.hh"
+#include "sim/core.hh"
class Checkpoint;
class PollQueue;
diff --git a/src/base/random.cc b/src/base/random.cc
index 0ccedcb00..ceab337d9 100644
--- a/src/base/random.cc
+++ b/src/base/random.cc
@@ -40,38 +40,20 @@
#include <cstdlib>
#include <cmath>
-
-#include "sim/param.hh"
#include "base/random.hh"
-#include "base/trace.hh"
using namespace std;
-class RandomContext : public ParamContext
-{
- public:
- RandomContext(const string &_iniSection)
- : ::ParamContext(_iniSection) {}
- ~RandomContext() {}
-
- void checkParams();
-};
-
-RandomContext paramContext("random");
-
-Param<unsigned>
-seed(&paramContext, "seed", "seed to random number generator", 1);
-
-void
-RandomContext::checkParams()
+uint32_t
+getInt32()
{
- ::srand48(seed);
+ return mrand48() & 0xffffffff;
}
-long
-getLong()
+double
+getDouble()
{
- return mrand48();
+ return drand48();
}
double
@@ -105,21 +87,3 @@ getUniformPos(uint64_t min, uint64_t max)
return (uint64_t)m5round(r);
}
-
-
-// idea for generating a double from erand48
-double
-getDouble()
-{
- union {
- uint32_t _long[2];
- uint16_t _short[4];
- };
-
- _long[0] = mrand48();
- _long[1] = mrand48();
-
- return ldexp((double) _short[0], -48) +
- ldexp((double) _short[1], -32) +
- ldexp((double) _short[2], -16);
-}
diff --git a/src/base/random.hh b/src/base/random.hh
index 40d62da7f..0cd88728d 100644
--- a/src/base/random.hh
+++ b/src/base/random.hh
@@ -34,7 +34,7 @@
#include "sim/host.hh"
-long getLong();
+uint32_t getUInt32();
double getDouble();
double m5random(double r);
uint64_t getUniformPos(uint64_t min, uint64_t max);
@@ -46,7 +46,7 @@ struct Random;
template<> struct Random<int8_t>
{
static int8_t get()
- { return getLong() & (int8_t)-1; }
+ { return getUInt32() & (int8_t)-1; }
static int8_t uniform(int8_t min, int8_t max)
{ return getUniform(min, max); }
@@ -55,7 +55,7 @@ template<> struct Random<int8_t>
template<> struct Random<uint8_t>
{
static uint8_t get()
- { return getLong() & (uint8_t)-1; }
+ { return getUInt32() & (uint8_t)-1; }
static uint8_t uniform(uint8_t min, uint8_t max)
{ return getUniformPos(min, max); }
@@ -64,7 +64,7 @@ template<> struct Random<uint8_t>
template<> struct Random<int16_t>
{
static int16_t get()
- { return getLong() & (int16_t)-1; }
+ { return getUInt32() & (int16_t)-1; }
static int16_t uniform(int16_t min, int16_t max)
{ return getUniform(min, max); }
@@ -73,7 +73,7 @@ template<> struct Random<int16_t>
template<> struct Random<uint16_t>
{
static uint16_t get()
- { return getLong() & (uint16_t)-1; }
+ { return getUInt32() & (uint16_t)-1; }
static uint16_t uniform(uint16_t min, uint16_t max)
{ return getUniformPos(min, max); }
@@ -82,7 +82,7 @@ template<> struct Random<uint16_t>
template<> struct Random<int32_t>
{
static int32_t get()
- { return (int32_t)getLong(); }
+ { return (int32_t)getUInt32(); }
static int32_t uniform(int32_t min, int32_t max)
{ return getUniform(min, max); }
@@ -91,7 +91,7 @@ template<> struct Random<int32_t>
template<> struct Random<uint32_t>
{
static uint32_t get()
- { return (uint32_t)getLong(); }
+ { return (uint32_t)getUInt32(); }
static uint32_t uniform(uint32_t min, uint32_t max)
{ return getUniformPos(min, max); }
@@ -100,7 +100,7 @@ template<> struct Random<uint32_t>
template<> struct Random<int64_t>
{
static int64_t get()
- { return (int64_t)getLong() << 32 || (uint64_t)getLong(); }
+ { return (int64_t)getUInt32() << 32 || (uint64_t)getUInt32(); }
static int64_t uniform(int64_t min, int64_t max)
{ return getUniform(min, max); }
@@ -109,7 +109,7 @@ template<> struct Random<int64_t>
template<> struct Random<uint64_t>
{
static uint64_t get()
- { return (uint64_t)getLong() << 32 || (uint64_t)getLong(); }
+ { return (uint64_t)getUInt32() << 32 || (uint64_t)getUInt32(); }
static uint64_t uniform(uint64_t min, uint64_t max)
{ return getUniformPos(min, max); }
diff --git a/src/base/statistics.hh b/src/base/statistics.hh
index 2b1b327e5..761b30c2b 100644
--- a/src/base/statistics.hh
+++ b/src/base/statistics.hh
@@ -70,7 +70,7 @@
class Callback;
-/** The current simulated cycle. */
+/** The current simulated tick. */
extern Tick curTick;
/* A namespace for all of the Statistics */
@@ -598,9 +598,9 @@ struct StatStor
};
/**
- * Templatized storage and interface to a per-cycle average stat. This keeps
- * a current count and updates a total (count * cycles) when this count
- * changes. This allows the quick calculation of a per cycle count of the item
+ * Templatized storage and interface to a per-tick average stat. This keeps
+ * a current count and updates a total (count * ticks) when this count
+ * changes. This allows the quick calculation of a per tick count of the item
* being watched. This is good for keeping track of residencies in structures
* among other things.
*/
@@ -613,9 +613,9 @@ struct AvgStor
private:
/** The current count. */
Counter current;
- /** The total count for all cycles. */
+ /** The total count for all tick. */
mutable Result total;
- /** The cycle that current last changed. */
+ /** The tick that current last changed. */
mutable Tick last;
public:
@@ -1563,7 +1563,7 @@ struct FancyStor
};
/**
- * Templatized storage for distribution that calculates per cycle mean and
+ * Templatized storage for distribution that calculates per tick mean and
* variance.
*/
struct AvgFancy
@@ -2280,7 +2280,7 @@ class Value : public Wrap<Value, ValueBase, ScalarStatData>
};
/**
- * A stat that calculates the per cycle average of a value.
+ * A stat that calculates the per tick average of a value.
* @sa Stat, ScalarBase, AvgStor
*/
template<int N = 0>
@@ -2417,7 +2417,7 @@ class StandardDeviation
};
/**
- * Calculates the per cycle mean and variance of the samples.
+ * Calculates the per tick mean and variance of the samples.
* @sa Stat, DistBase, AvgFancy
*/
template<int N = 0>
@@ -2839,6 +2839,7 @@ class Temp
*/
void check();
+void dump();
void reset();
void registerResetCallback(Callback *cb);
diff --git a/src/base/stats/events.cc b/src/base/stats/events.cc
index 6ecc5434c..dc56fe75f 100644
--- a/src/base/stats/events.cc
+++ b/src/base/stats/events.cc
@@ -31,20 +31,8 @@
#include <vector>
#include "base/stats/events.hh"
-
-#if USE_MYSQL
-#include "base/cprintf.hh"
-#include "base/misc.hh"
-#include "base/mysql.hh"
-#include "base/stats/mysql.hh"
-#include "base/stats/mysql_run.hh"
-#include "base/str.hh"
-#endif
-
-#include "base/match.hh"
+#include "base/stats/output.hh"
#include "sim/host.hh"
-#include "sim/sim_object.hh"
-#include "sim/root.hh"
using namespace std;
@@ -52,118 +40,21 @@ namespace Stats {
Tick EventStart = ULL(0x7fffffffffffffff);
-ObjectMatch event_ignore;
+extern list<Output *> OutputList;
#if USE_MYSQL
-class InsertEvent
-{
- private:
- char *query;
- int size;
- bool first;
- static const int maxsize = 1024*1024;
-
- typedef map<string, uint32_t> event_map_t;
- event_map_t events;
-
- MySQL::Connection &mysql;
- uint16_t run;
-
- public:
- InsertEvent()
- : mysql(MySqlDB.conn()), run(MySqlDB.run())
- {
- query = new char[maxsize + 1];
- size = 0;
- first = true;
- flush();
- }
- ~InsertEvent()
- {
- flush();
- }
-
- void flush();
- void insert(const string &stat);
-};
-
void
-InsertEvent::insert(const string &stat)
+__event(const string &event)
{
- assert(mysql.connected());
-
- event_map_t::iterator i = events.find(stat);
- uint32_t event;
- if (i == events.end()) {
- mysql.query(
- csprintf("SELECT en_id "
- "from event_names "
- "where en_name=\"%s\"",
- stat));
-
- MySQL::Result result = mysql.store_result();
- if (!result)
- panic("could not get a run\n%s\n", mysql.error);
-
- assert(result.num_fields() == 1);
- MySQL::Row row = result.fetch_row();
- if (row) {
- if (!to_number(row[0], event))
- panic("invalid event id: %s\n", row[0]);
- } else {
- mysql.query(
- csprintf("INSERT INTO "
- "event_names(en_name)"
- "values(\"%s\")",
- stat));
-
- if (mysql.error)
- panic("could not get a run\n%s\n", mysql.error);
-
- event = mysql.insert_id();
- }
- } else {
- event = (*i).second;
+ list<Output *>::iterator i = OutputList.begin();
+ list<Output *>::iterator end = OutputList.end();
+ for (; i != end; ++i) {
+ Output *output = *i;
+ if (!output->valid())
+ continue;
+
+ output->event(event);
}
-
- if (size + 1024 > maxsize)
- flush();
-
- if (!first) {
- query[size++] = ',';
- query[size] = '\0';
- }
-
- first = false;
-
- size += sprintf(query + size, "(%u,%u,%llu)",
- event, run, (unsigned long long)curTick);
-}
-
-void
-InsertEvent::flush()
-{
- static const char query_header[] = "INSERT INTO "
- "events(ev_event, ev_run, ev_tick)"
- "values";
-
- if (size) {
- MySQL::Connection &mysql = MySqlDB.conn();
- assert(mysql.connected());
- mysql.query(query);
- }
-
- query[0] = '\0';
- size = sizeof(query_header);
- first = true;
- memcpy(query, query_header, size);
-}
-
-void
-__event(const string &stat)
-{
- static InsertEvent event;
- event.insert(stat);
}
#endif
diff --git a/src/base/stats/events.hh b/src/base/stats/events.hh
index b09b91c7c..8ba9cece5 100644
--- a/src/base/stats/events.hh
+++ b/src/base/stats/events.hh
@@ -42,11 +42,10 @@ extern Tick EventStart;
#if USE_MYSQL
void __event(const std::string &stat);
-bool MySqlConnected();
+#else
+inline void __event(const std::string &stat) {}
#endif
-bool ignoreEvent(const std::string &name);
-
inline void
recordEvent(const std::string &stat)
{
@@ -55,12 +54,7 @@ recordEvent(const std::string &stat)
DPRINTF(StatEvents, "Statistics Event: %s\n", stat);
-#if USE_MYSQL
- if (!MySqlConnected())
- return;
-
__event(stat);
-#endif
}
/* namespace Stats */ }
diff --git a/src/base/stats/mysql.cc b/src/base/stats/mysql.cc
index 0fb31f4ce..39a687fff 100644
--- a/src/base/stats/mysql.cc
+++ b/src/base/stats/mysql.cc
@@ -43,20 +43,13 @@
#include "base/stats/statdb.hh"
#include "base/stats/types.hh"
#include "base/str.hh"
+#include "base/userinfo.hh"
#include "sim/host.hh"
using namespace std;
namespace Stats {
-MySqlRun MySqlDB;
-
-bool
-MySqlConnected()
-{
- return MySqlDB.connected();
-}
-
void
MySqlRun::connect(const string &host, const string &user, const string &passwd,
const string &db, const string &name, const string &sample,
@@ -196,9 +189,9 @@ SetupStat::init()
}
unsigned
-SetupStat::setup()
+SetupStat::setup(MySqlRun *run)
{
- MySQL::Connection &mysql = MySqlDB.conn();
+ MySQL::Connection &mysql = run->conn();
stringstream insert;
ccprintf(insert,
@@ -301,7 +294,8 @@ SetupStat::setup()
return statid;
}
-InsertData::InsertData()
+InsertData::InsertData(MySqlRun *_run)
+ : run(_run)
{
query = new char[maxsize + 1];
size = 0;
@@ -317,7 +311,7 @@ void
InsertData::flush()
{
if (size) {
- MySQL::Connection &mysql = MySqlDB.conn();
+ MySQL::Connection &mysql = run->conn();
assert(mysql.connected());
mysql.query(query);
if (mysql.error)
@@ -349,10 +343,97 @@ InsertData::insert()
first = false;
size += sprintf(query + size, "(%u,%d,%d,%u,%llu,\"%f\")",
- stat, x, y, MySqlDB.run(), (unsigned long long)tick,
+ stat, x, y, run->run(), (unsigned long long)tick,
data);
}
+InsertEvent::InsertEvent(MySqlRun *_run)
+ : run(_run)
+{
+ query = new char[maxsize + 1];
+ size = 0;
+ first = true;
+ flush();
+}
+
+InsertEvent::~InsertEvent()
+{
+ flush();
+}
+
+void
+InsertEvent::insert(const string &stat)
+{
+ MySQL::Connection &mysql = run->conn();
+ assert(mysql.connected());
+
+ event_map_t::iterator i = events.find(stat);
+ uint32_t event;
+ if (i == events.end()) {
+ mysql.query(
+ csprintf("SELECT en_id "
+ "from event_names "
+ "where en_name=\"%s\"",
+ stat));
+
+ MySQL::Result result = mysql.store_result();
+ if (!result)
+ panic("could not get a run\n%s\n", mysql.error);
+
+ assert(result.num_fields() == 1);
+ MySQL::Row row = result.fetch_row();
+ if (row) {
+ if (!to_number(row[0], event))
+ panic("invalid event id: %s\n", row[0]);
+ } else {
+ mysql.query(
+ csprintf("INSERT INTO "
+ "event_names(en_name)"
+ "values(\"%s\")",
+ stat));
+
+ if (mysql.error)
+ panic("could not get a run\n%s\n", mysql.error);
+
+ event = mysql.insert_id();
+ }
+ } else {
+ event = (*i).second;
+ }
+
+ if (size + 1024 > maxsize)
+ flush();
+
+ if (!first) {
+ query[size++] = ',';
+ query[size] = '\0';
+ }
+
+ first = false;
+
+ size += sprintf(query + size, "(%u,%u,%llu)",
+ event, run->run(), (unsigned long long)curTick);
+}
+
+void
+InsertEvent::flush()
+{
+ static const char query_header[] = "INSERT INTO "
+ "events(ev_event, ev_run, ev_tick)"
+ "values";
+
+ MySQL::Connection &mysql = run->conn();
+ assert(mysql.connected());
+
+ if (size)
+ mysql.query(query);
+
+ query[0] = '\0';
+ size = sizeof(query_header);
+ first = true;
+ memcpy(query, query_header, size);
+}
+
struct InsertSubData
{
uint16_t stat;
@@ -361,13 +442,13 @@ struct InsertSubData
string name;
string descr;
- void setup();
+ void setup(MySqlRun *run);
};
void
-InsertSubData::setup()
+InsertSubData::setup(MySqlRun *run)
{
- MySQL::Connection &mysql = MySqlDB.conn();
+ MySQL::Connection &mysql = run->conn();
assert(mysql.connected());
stringstream insert;
ccprintf(insert,
@@ -383,47 +464,27 @@ InsertSubData::setup()
panic("could not commit transaction\n%s\n", mysql.error);
}
-void
-InsertFormula(uint16_t stat, const string &formula)
-{
- MySQL::Connection &mysql = MySqlDB.conn();
- assert(mysql.connected());
- stringstream insert_formula;
- ccprintf(insert_formula,
- "INSERT INTO formulas(fm_stat,fm_formula) values(%d, \"%s\")",
- stat, formula);
+MySql::MySql()
+ : run(new MySqlRun), newdata(run), newevent(run)
+{}
- mysql.query(insert_formula);
-// if (mysql.error)
-// panic("could not insert formula\n%s\n", mysql.error);
-
- stringstream insert_ref;
- ccprintf(insert_ref,
- "INSERT INTO formula_ref(fr_stat,fr_run) values(%d, %d)",
- stat, MySqlDB.run());
-
- mysql.query(insert_ref);
-// if (mysql.error)
-// panic("could not insert formula reference\n%s\n", mysql.error);
-
- if (mysql.commit())
- panic("could not commit transaction\n%s\n", mysql.error);
+MySql::~MySql()
+{
+ delete run;
}
void
-UpdatePrereq(uint16_t stat, uint16_t prereq)
+MySql::connect(const string &host, const string &user, const string &passwd,
+ const string &db, const string &name, const string &sample,
+ const string &project)
{
- MySQL::Connection &mysql = MySqlDB.conn();
- assert(mysql.connected());
- stringstream update;
- ccprintf(update, "UPDATE stats SET st_prereq=%d WHERE st_id=%d",
- prereq, stat);
- mysql.query(update);
- if (mysql.error)
- panic("could not update prereq\n%s\n", mysql.error);
+ run->connect(host, user, passwd, db, name, sample, project);
+}
- if (mysql.commit())
- panic("could not commit transaction\n%s\n", mysql.error);
+bool
+MySql::connected() const
+{
+ return run->connected();
}
void
@@ -434,7 +495,7 @@ MySql::configure()
*/
using namespace Database;
- MySQL::Connection &mysql = MySqlDB.conn();
+ MySQL::Connection &mysql = run->conn();
stat_list_t::const_iterator i, end = stats().end();
for (i = stats().begin(); i != end; ++i) {
@@ -444,11 +505,20 @@ MySql::configure()
for (i = stats().begin(); i != end; ++i) {
StatData *data = *i;
if (data->prereq) {
+ // update the prerequisite
uint16_t stat_id = find(data->id);
uint16_t prereq_id = find(data->prereq->id);
assert(stat_id && prereq_id);
- UpdatePrereq(stat_id, prereq_id);
+ stringstream update;
+ ccprintf(update, "UPDATE stats SET st_prereq=%d WHERE st_id=%d",
+ prereq_id, stat_id);
+ mysql.query(update);
+ if (mysql.error)
+ panic("could not update prereq\n%s\n", mysql.error);
+
+ if (mysql.commit())
+ panic("could not commit transaction\n%s\n", mysql.error);
}
}
@@ -483,7 +553,7 @@ MySql::configure(const ScalarData &data)
if (!configure(data, "SCALAR"))
return;
- insert(data.id, stat.setup());
+ insert(data.id, stat.setup(run));
}
void
@@ -492,7 +562,7 @@ MySql::configure(const VectorData &data)
if (!configure(data, "VECTOR"))
return;
- uint16_t statid = stat.setup();
+ uint16_t statid = stat.setup(run);
if (!data.subnames.empty()) {
InsertSubData subdata;
@@ -504,7 +574,7 @@ MySql::configure(const VectorData &data)
subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
if (!subdata.name.empty() || !subdata.descr.empty())
- subdata.setup();
+ subdata.setup(run);
}
}
@@ -523,7 +593,7 @@ MySql::configure(const DistData &data)
stat.max = data.data.max;
stat.bktsize = data.data.bucket_size;
}
- insert(data.id, stat.setup());
+ insert(data.id, stat.setup(run));
}
void
@@ -539,7 +609,7 @@ MySql::configure(const VectorDistData &data)
stat.bktsize = data.data[0].bucket_size;
}
- uint16_t statid = stat.setup();
+ uint16_t statid = stat.setup(run);
if (!data.subnames.empty()) {
InsertSubData subdata;
@@ -550,7 +620,7 @@ MySql::configure(const VectorDistData &data)
subdata.name = data.subnames[i];
subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
if (!subdata.name.empty() || !subdata.descr.empty())
- subdata.setup();
+ subdata.setup(run);
}
}
@@ -563,7 +633,7 @@ MySql::configure(const Vector2dData &data)
if (!configure(data, "VECTOR2D"))
return;
- uint16_t statid = stat.setup();
+ uint16_t statid = stat.setup(run);
if (!data.subnames.empty()) {
InsertSubData subdata;
@@ -574,7 +644,7 @@ MySql::configure(const Vector2dData &data)
subdata.name = data.subnames[i];
subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
if (!subdata.name.empty() || !subdata.descr.empty())
- subdata.setup();
+ subdata.setup(run);
}
}
@@ -587,7 +657,7 @@ MySql::configure(const Vector2dData &data)
subdata.y = i;
subdata.name = data.y_subnames[i];
if (!subdata.name.empty())
- subdata.setup();
+ subdata.setup(run);
}
}
@@ -597,15 +667,41 @@ MySql::configure(const Vector2dData &data)
void
MySql::configure(const FormulaData &data)
{
+ MySQL::Connection &mysql = run->conn();
+ assert(mysql.connected());
+
configure(data, "FORMULA");
- insert(data.id, stat.setup());
- InsertFormula(find(data.id), data.str());
+ insert(data.id, stat.setup(run));
+
+ uint16_t stat = find(data.id);
+ string formula = data.str();
+
+ stringstream insert_formula;
+ ccprintf(insert_formula,
+ "INSERT INTO formulas(fm_stat,fm_formula) values(%d, \"%s\")",
+ stat, formula);
+
+ mysql.query(insert_formula);
+// if (mysql.error)
+// panic("could not insert formula\n%s\n", mysql.error);
+
+ stringstream insert_ref;
+ ccprintf(insert_ref,
+ "INSERT INTO formula_ref(fr_stat,fr_run) values(%d, %d)",
+ stat, run->run());
+
+ mysql.query(insert_ref);
+// if (mysql.error)
+// panic("could not insert formula reference\n%s\n", mysql.error);
+
+ if (mysql.commit())
+ panic("could not commit transaction\n%s\n", mysql.error);
}
bool
MySql::valid() const
{
- return MySqlDB.connected();
+ return run->connected();
}
void
@@ -620,7 +716,7 @@ MySql::output()
// store sample #
newdata.tick = curTick;
- MySQL::Connection &mysql = MySqlDB.conn();
+ MySQL::Connection &mysql = run->conn();
Database::stat_list_t::const_iterator i, end = Database::stats().end();
for (i = Database::stats().begin(); i != end; ++i) {
@@ -634,6 +730,13 @@ MySql::output()
}
void
+MySql::event(const std::string &event)
+{
+ newevent.insert(event);
+}
+
+
+void
MySql::output(const ScalarData &data)
{
if (!(data.flags & print))
@@ -825,4 +928,20 @@ MySql::visit(const FormulaData &data)
output(data);
}
-/* namespace Stats */ }
+bool
+initMySQL(string host, string user, string password, string database,
+ string project, string name, string sample)
+{
+ extern list<Output *> OutputList;
+ static MySql mysql;
+
+ if (mysql.connected())
+ return false;
+
+ mysql.connect(host, user, password, database, name, sample, project);
+ OutputList.push_back(&mysql);
+
+ return true;
+}
+
+/* end namespace Stats */ }
diff --git a/src/base/stats/mysql.hh b/src/base/stats/mysql.hh
index 50f7d9e97..0ce381c2f 100644
--- a/src/base/stats/mysql.hh
+++ b/src/base/stats/mysql.hh
@@ -35,14 +35,13 @@
#include <string>
#include "base/stats/output.hh"
+#include "config/use_mysql.hh"
namespace MySQL { class Connection; }
namespace Stats {
class DistDataData;
class MySqlRun;
-bool MySqlConnected();
-extern MySqlRun MySqlDB;
struct SetupStat
{
@@ -63,7 +62,7 @@ struct SetupStat
uint16_t size;
void init();
- unsigned setup();
+ unsigned setup(MySqlRun *run);
};
class InsertData
@@ -85,18 +84,43 @@ class InsertData
int16_t y;
public:
- InsertData();
+ InsertData(MySqlRun *_run);
~InsertData();
void flush();
void insert();
};
+class InsertEvent
+{
+ private:
+ char *query;
+ int size;
+ bool first;
+ static const int maxsize = 1024*1024;
+
+ typedef std::map<std::string, uint32_t> event_map_t;
+ event_map_t events;
+
+ MySqlRun *run;
+
+ public:
+ InsertEvent(MySqlRun *_run);
+ ~InsertEvent();
+
+ void flush();
+ void insert(const std::string &stat);
+};
+
class MySql : public Output
{
protected:
+ MySqlRun *run; /* Hide the implementation so we don't have a
+ #include mess */
+
SetupStat stat;
InsertData newdata;
+ InsertEvent newevent;
std::list<FormulaData *> formulas;
bool configured;
@@ -116,6 +140,17 @@ class MySql : public Output
assert(i != idmap.end());
return (*i).second;
}
+
+ public:
+ MySql();
+ ~MySql();
+
+ void connect(const std::string &host, const std::string &user,
+ const std::string &passwd, const std::string &db,
+ const std::string &name, const std::string &sample,
+ const std::string &project);
+ bool connected() const;
+
public:
// Implement Visit
virtual void visit(const ScalarData &data);
@@ -129,6 +164,9 @@ class MySql : public Output
virtual bool valid() const;
virtual void output();
+ // Implement Event Output
+ virtual void event(const std::string &event);
+
protected:
// Output helper
void output(const DistDataData &data);
@@ -149,6 +187,20 @@ class MySql : public Output
void configure(const FormulaData &data);
};
+bool initMySQL(std::string host, std::string database, std::string user,
+ std::string passwd, std::string project, std::string name,
+ std::string sample);
+
+#if !USE_MYSQL
+inline bool
+initMySQL(std::string host, std::string user, std::string password,
+ std::string database, std::string project, std::string name,
+ std::string sample)
+{
+ return false;
+}
+#endif
+
/* namespace Stats */ }
#endif // __BASE_STATS_MYSQL_HH__
diff --git a/src/base/stats/output.cc b/src/base/stats/output.cc
new file mode 100644
index 000000000..9f2b91c77
--- /dev/null
+++ b/src/base/stats/output.cc
@@ -0,0 +1,70 @@
+/*
+ * 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
+ */
+
+#include <list>
+
+#include "base/stats/output.hh"
+#include "sim/eventq.hh"
+#include "sim/host.hh"
+
+using namespace std;
+
+namespace Stats {
+
+Tick lastDump(0);
+list<Output *> OutputList;
+
+void
+dump()
+{
+ assert(lastDump <= curTick);
+ if (lastDump == curTick)
+ return;
+ lastDump = curTick;
+
+ list<Output *>::iterator i = OutputList.begin();
+ list<Output *>::iterator end = OutputList.end();
+ for (; i != end; ++i) {
+ Output *output = *i;
+ if (!output->valid())
+ continue;
+
+ output->output();
+ }
+}
+
+/* namespace Stats */ }
+
+void
+debugDumpStats()
+{
+ Stats::dump();
+}
+
diff --git a/src/base/stats/output.hh b/src/base/stats/output.hh
index 4fe93791f..c7ffcaade 100644
--- a/src/base/stats/output.hh
+++ b/src/base/stats/output.hh
@@ -42,6 +42,7 @@ struct Output : public Visit
inline void operator()() { output(); }
virtual void output() = 0;
virtual bool valid() const = 0;
+ virtual void event(const std::string &event) = 0;
};
/* namespace Stats */ }
diff --git a/src/base/stats/text.cc b/src/base/stats/text.cc
index ae0d65537..a018c4837 100644
--- a/src/base/stats/text.cc
+++ b/src/base/stats/text.cc
@@ -251,6 +251,7 @@ VectorPrint::operator()(std::ostream &stream) const
ScalarPrint print;
print.name = name;
print.desc = desc;
+ print.compat = compat;
print.precision = precision;
print.descriptions = descriptions;
print.flags = flags;
@@ -725,4 +726,25 @@ Text::visit(const FormulaData &data)
visit((const VectorData &)data);
}
+bool
+initText(const string &filename, bool desc, bool compat)
+{
+ static Text text;
+ static bool connected = false;
+
+ if (connected)
+ return false;
+
+ extern list<Output *> OutputList;
+
+ text.open(*simout.find(filename));
+ text.descriptions = desc;
+ text.compat = compat;
+ OutputList.push_back(&text);
+ connected = true;
+
+ return true;
+}
+
+
/* namespace Stats */ }
diff --git a/src/base/stats/text.hh b/src/base/stats/text.hh
index b3faf5ad5..781d1083d 100644
--- a/src/base/stats/text.hh
+++ b/src/base/stats/text.hh
@@ -34,6 +34,7 @@
#include <iosfwd>
#include <string>
+#include "base/output.hh"
#include "base/stats/output.hh"
namespace Stats {
@@ -71,8 +72,13 @@ class Text : public Output
// Implement Output
virtual bool valid() const;
virtual void output();
+
+ // Implement Event Output
+ virtual void event(const std::string &event) {}
};
+bool initText(const std::string &filename, bool desc=true, bool compat=true);
+
/* namespace Stats */ }
#endif // __BASE_STATS_TEXT_HH__
diff --git a/src/base/trace.cc b/src/base/trace.cc
index 9fa615f4d..0a7e6e833 100644
--- a/src/base/trace.cc
+++ b/src/base/trace.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001-2005 The Regents of The University of Michigan
+ * Copyright (c) 2001-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,14 +37,17 @@
#include <vector>
#include "base/misc.hh"
-#include "base/trace.hh"
+#include "base/output.hh"
#include "base/str.hh"
+#include "base/trace.hh"
+#include "base/varargs.hh"
using namespace std;
namespace Trace {
const string DefaultName("global");
FlagVec flags(NumFlags, false);
+bool enabled = false;
//
// This variable holds the output stream for debug information. Other
@@ -53,151 +56,74 @@ FlagVec flags(NumFlags, false);
// output.
//
ostream *dprintf_stream = &cerr;
-
-ObjectMatch ignore;
-
-Log theLog;
-
-Log::Log()
+ostream &
+output()
{
- size = 0;
- buffer = NULL;
+ return *dprintf_stream;
}
-
void
-Log::init(int _size)
+setOutput(const string &filename)
{
- if (buffer != NULL) {
- fatal("Trace::Log::init called twice!");
- }
-
- size = _size;
-
- buffer = new Record *[size];
-
- for (int i = 0; i < size; ++i) {
- buffer[i] = NULL;
- }
-
- nextRecPtr = &buffer[0];
- wrapRecPtr = &buffer[size];
+ dprintf_stream = simout.find(filename);
}
+ObjectMatch ignore;
-Log::~Log()
+void
+dprintf(Tick when, const std::string &name, const char *format,
+ CPRINTF_DEFINITION)
{
- for (int i = 0; i < size; ++i) {
- delete buffer[i];
- }
-
- delete [] buffer;
-}
+ if (!name.empty() && ignore.match(name))
+ return;
+ std::ostream &os = *dprintf_stream;
-void
-Log::append(Record *rec)
-{
- // dump record to output stream if there's one open
- if (dprintf_stream != NULL) {
- rec->dump(*dprintf_stream);
- } else {
- rec->dump(cout);
- }
+ string fmt = "";
+ CPrintfArgsList args(VARARGS_ALLARGS);
- // no buffering: justget rid of it now
- if (buffer == NULL) {
- delete rec;
- return;
+ if (!name.empty()) {
+ fmt = "%s: " + fmt;
+ args.push_front(name);
}
- Record *oldRec = *nextRecPtr;
-
- if (oldRec != NULL) {
- // log has wrapped: overwrite
- delete oldRec;
+ if (when != (Tick)-1) {
+ fmt = "%7d: " + fmt;
+ args.push_front(when);
}
- *nextRecPtr = rec;
+ fmt += format;
- if (++nextRecPtr == wrapRecPtr) {
- nextRecPtr = &buffer[0];
- }
+ ccprintf(os, fmt.c_str(), args);
+ os.flush();
}
-
void
-Log::dump(ostream &os)
+dump(Tick when, const std::string &name, const void *d, int len)
{
- if (buffer == NULL) {
+ if (!name.empty() && ignore.match(name))
return;
- }
-
- Record **bufPtr = nextRecPtr;
-
- if (*bufPtr == NULL) {
- // next record slot is empty: log must not be full yet.
- // start dumping from beginning of buffer
- bufPtr = buffer;
- }
- do {
- Record *rec = *bufPtr;
-
- rec->dump(os);
-
- if (++bufPtr == wrapRecPtr) {
- bufPtr = &buffer[0];
- }
- } while (bufPtr != nextRecPtr);
-}
-
-PrintfRecord::~PrintfRecord()
-{
- delete &args;
-}
+ std::ostream &os = *dprintf_stream;
-void
-PrintfRecord::dump(ostream &os)
-{
string fmt = "";
+ CPrintfArgsList args;
if (!name.empty()) {
fmt = "%s: " + fmt;
- args.prepend(name);
+ args.push_front(name);
}
- if (cycle != (Tick)-1) {
+ if (when != (Tick)-1) {
fmt = "%7d: " + fmt;
- args.prepend(cycle);
+ args.push_front(when);
}
- fmt += format;
-
- args.dump(os, fmt);
- os.flush();
-}
-
-DataRecord::DataRecord(Tick _cycle, const string &_name,
- const void *_data, int _len)
- : Record(_cycle), name(_name), len(_len)
-{
- data = new uint8_t[len];
- memcpy(data, _data, len);
-}
-
-DataRecord::~DataRecord()
-{
- delete [] data;
-}
-
-void
-DataRecord::dump(ostream &os)
-{
+ const char *data = static_cast<const char *>(d);
int c, i, j;
-
for (i = 0; i < len; i += 16) {
- ccprintf(os, "%d: %s: %08x ", cycle, name, i);
+ ccprintf(os, fmt, args);
+ ccprintf(os, "%08x ", i);
c = len - i;
if (c > 16) c = 16;
@@ -213,8 +139,7 @@ DataRecord::dump(ostream &os)
for (j = 0; j < c; j++) {
int ch = data[i + j] & 0x7f;
- ccprintf(os,
- "%c", (char)(isprint(ch) ? ch : ' '));
+ ccprintf(os, "%c", (char)(isprint(ch) ? ch : ' '));
}
ccprintf(os, "\n");
@@ -223,126 +148,64 @@ DataRecord::dump(ostream &os)
break;
}
}
-} // namespace Trace
-//
-// Returns the current output stream for debug information. As a
-// wrapper around Trace::dprintf_stream, this handles cases where debug
-// information is generated in the process of parsing .ini options,
-// before we process the option that sets up the debug output stream
-// itself.
-//
-std::ostream &
-DebugOut()
-{
- return *Trace::dprintf_stream;
-}
-
-/////////////////////////////////////////////
-//
-// C-linkage functions for invoking from gdb
-//
-/////////////////////////////////////////////
-
-//
-// Dump trace buffer to specified file (cout if NULL)
-//
-void
-dumpTrace(const char *filename)
-{
- if (filename != NULL) {
- ofstream out(filename);
- Trace::theLog.dump(out);
- out.close();
- }
- else {
- Trace::theLog.dump(cout);
- }
-}
-
-
-//
-// Turn on/off trace output to cerr. Typically used when trace output
-// is only going to circular buffer, but you want to see what's being
-// sent there as you step through some code in gdb. This uses the
-// same facility as the "trace to file" feature, and will print error
-// messages rather than clobbering an existing ostream pointer.
-//
-void
-echoTrace(bool on)
-{
- if (on) {
- if (Trace::dprintf_stream != NULL) {
- cerr << "Already echoing trace to a file... go do a 'tail -f'"
- << " on that file instead." << endl;
- } else {
- Trace::dprintf_stream = &cerr;
- }
- } else {
- if (Trace::dprintf_stream != &cerr) {
- cerr << "Not echoing trace to cerr." << endl;
- } else {
- Trace::dprintf_stream = NULL;
- }
- }
-}
-
-void
-printTraceFlags()
-{
- using namespace Trace;
- for (int i = 0; i < numFlagStrings; ++i)
- if (flags[i])
- cprintf("%s\n", flagStrings[i]);
-}
-
-void
-tweakTraceFlag(const char *string, bool value)
+bool
+changeFlag(const char *s, bool value)
{
using namespace Trace;
- std::string str(string);
+ std::string str(s);
for (int i = 0; i < numFlagStrings; ++i) {
if (str != flagStrings[i])
continue;
- int idx = i;
-
- if (idx < NumFlags) {
- flags[idx] = value;
+ if (i < NumFlags) {
+ flags[i] = value;
} else {
- idx -= NumFlags;
- if (idx >= NumCompoundFlags) {
- ccprintf(cerr, "Invalid compound flag");
- return;
- }
-
- const Flags *flagVec = compoundFlags[idx];
+ i -= NumFlags;
+ const Flags *flagVec = compoundFlags[i];
for (int j = 0; flagVec[j] != -1; ++j) {
- if (flagVec[j] >= NumFlags) {
- ccprintf(cerr, "Invalid compound flag");
- return;
- }
- flags[flagVec[j]] = value;
+ if (flagVec[j] < NumFlags)
+ flags[flagVec[j]] = value;
}
}
- cprintf("flag %s was %s\n", string, value ? "set" : "cleared");
- return;
+ return true;
}
- cprintf("could not find flag %s\n", string);
+ // the flag was not found.
+ return false;
+}
+
+void
+dumpStatus()
+{
+ using namespace Trace;
+ for (int i = 0; i < numFlagStrings; ++i) {
+ if (flags[i])
+ cprintf("%s\n", flagStrings[i]);
+ }
}
+/* namespace Trace */ }
+
+
+// add a set of functions that can easily be invoked from gdb
void
setTraceFlag(const char *string)
{
- tweakTraceFlag(string, true);
+ Trace::changeFlag(string, true);
}
void
clearTraceFlag(const char *string)
{
- tweakTraceFlag(string, false);
+ Trace::changeFlag(string, false);
+}
+
+void
+dumpTraceStatus()
+{
+ Trace::dumpStatus();
}
diff --git a/src/base/trace.hh b/src/base/trace.hh
index a46643159..c1b506187 100644
--- a/src/base/trace.hh
+++ b/src/base/trace.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001-2005 The Regents of The University of Michigan
+ * Copyright (c) 2001-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,125 +32,35 @@
#ifndef __BASE_TRACE_HH__
#define __BASE_TRACE_HH__
+#include <string>
#include <vector>
#include "base/cprintf.hh"
#include "base/match.hh"
-#include "sim/host.hh"
-#include "sim/root.hh"
-
#include "base/traceflags.hh"
+#include "sim/host.hh"
+#include "sim/core.hh"
namespace Trace {
- typedef std::vector<bool> FlagVec;
+std::ostream &output();
+void setOutput(const std::string &filename);
- extern FlagVec flags;
+extern bool enabled;
+typedef std::vector<bool> FlagVec;
+extern FlagVec flags;
+inline bool IsOn(int t) { return flags[t]; }
+bool changeFlag(const char *str, bool value);
+void dumpStatus();
-#if TRACING_ON
- const bool On = true;
-#else
- const bool On = false;
-#endif
-
- inline bool
- IsOn(int t)
- {
- return flags[t];
-
- }
-
- void dump(const uint8_t *data, int count);
-
- class Record
- {
- protected:
- Tick cycle;
-
- Record(Tick _cycle)
- : cycle(_cycle)
- {
- }
-
- public:
- virtual ~Record() {}
-
- virtual void dump(std::ostream &) = 0;
- };
-
- class PrintfRecord : public Record
- {
- private:
- const char *format;
- const std::string &name;
- cp::ArgList &args;
-
- public:
- PrintfRecord(const char *_format, cp::ArgList &_args,
- Tick cycle, const std::string &_name)
- : Record(cycle), format(_format), name(_name), args(_args)
- {
- }
-
- virtual ~PrintfRecord();
-
- virtual void dump(std::ostream &);
- };
-
- class DataRecord : public Record
- {
- private:
- const std::string &name;
- uint8_t *data;
- int len;
-
- public:
- DataRecord(Tick cycle, const std::string &name,
- const void *_data, int _len);
- virtual ~DataRecord();
-
- virtual void dump(std::ostream &);
- };
-
- class Log
- {
- private:
- int size; // number of records in log
- Record **buffer; // array of 'size' Record ptrs (circular buf)
- Record **nextRecPtr; // next slot to use in buffer
- Record **wrapRecPtr; // &buffer[size], for quick wrap check
-
- public:
-
- Log();
- ~Log();
-
- void init(int _size);
-
- void append(Record *); // append trace record to log
- void dump(std::ostream &); // dump contents to stream
- };
-
- extern Log theLog;
-
- extern ObjectMatch ignore;
-
- inline void
- dprintf(const char *format, cp::ArgList &args, Tick cycle,
- const std::string &name)
- {
- if (name.empty() || !ignore.match(name))
- theLog.append(new Trace::PrintfRecord(format, args, cycle, name));
- }
-
- inline void
- dataDump(Tick cycle, const std::string &name, const void *data, int len)
- {
- theLog.append(new Trace::DataRecord(cycle, name, data, len));
- }
-
- extern const std::string DefaultName;
-};
+extern ObjectMatch ignore;
+extern const std::string DefaultName;
+
+void dprintf(Tick when, const std::string &name, const char *format,
+ CPRINTF_DECLARATION);
+void dump(Tick when, const std::string &name, const void *data, int len);
+
+/* namespace Trace */ }
// This silly little class allows us to wrap a string in a functor
// object so that we can give a name() that DPRINTF will like
@@ -162,7 +72,6 @@ struct StringWrap
};
inline const std::string &name() { return Trace::DefaultName; }
-std::ostream &DebugOut();
//
// DPRINTF is a debugging trace facility that allows one to
@@ -176,50 +85,44 @@ std::ostream &DebugOut();
#if TRACING_ON
-#define DTRACE(x) (Trace::IsOn(Trace::x))
-
-#define DCOUT(x) if (Trace::IsOn(Trace::x)) DebugOut()
+#define DTRACE(x) (Trace::IsOn(Trace::x) && Trace::enabled)
-#define DDUMP(x, data, count) \
-do { \
- if (Trace::IsOn(Trace::x)) \
- Trace::dataDump(curTick, name(), data, count); \
+#define DDUMP(x, data, count) do { \
+ if (DTRACE(x)) \
+ Trace::dump(curTick, name(), data, count); \
} while (0)
-#define __dprintf(cycle, name, format, ...) \
- Trace::dprintf(format, (*(new cp::ArgList), __VA_ARGS__), cycle, name)
+#define DPRINTF(x, ...) do { \
+ if (DTRACE(x)) \
+ Trace::dprintf(curTick, name(), __VA_ARGS__); \
+} while (0)
-#define DPRINTF(x, ...) \
-do { \
- if (Trace::IsOn(Trace::x)) \
- __dprintf(curTick, name(), __VA_ARGS__, cp::ArgListNull()); \
+#define DPRINTFR(x, ...) do { \
+ if (DTRACE(x)) \
+ Trace::dprintf((Tick)-1, std::string(), __VA_ARGS__); \
} while (0)
-#define DPRINTFR(x, ...) \
-do { \
- if (Trace::IsOn(Trace::x)) \
- __dprintf((Tick)-1, std::string(), __VA_ARGS__, cp::ArgListNull()); \
+#define DDUMPN(data, count) do { \
+ Trace::dump(curTick, name(), data, count); \
} while (0)
-#define DPRINTFN(...) \
-do { \
- __dprintf(curTick, name(), __VA_ARGS__, cp::ArgListNull()); \
+#define DPRINTFN(...) do { \
+ Trace::dprintf(curTick, name(), __VA_ARGS__); \
} while (0)
-#define DPRINTFNR(...) \
-do { \
- __dprintf((Tick)-1, string(), __VA_ARGS__, cp::ArgListNull()); \
+#define DPRINTFNR(...) do { \
+ Trace::dprintf((Tick)-1, string(), __VA_ARGS__); \
} while (0)
#else // !TRACING_ON
#define DTRACE(x) (false)
-#define DCOUT(x) if (0) DebugOut()
+#define DDUMP(x, data, count) do {} while (0)
#define DPRINTF(x, ...) do {} while (0)
#define DPRINTFR(...) do {} while (0)
+#define DDUMPN(data, count) do {} while (0)
#define DPRINTFN(...) do {} while (0)
#define DPRINTFNR(...) do {} while (0)
-#define DDUMP(x, data, count) do {} while (0)
#endif // TRACING_ON
diff --git a/src/base/traceflags.py b/src/base/traceflags.py
index c06399f81..e57bfa350 100644
--- a/src/base/traceflags.py
+++ b/src/base/traceflags.py
@@ -29,19 +29,7 @@
# Authors: Nathan Binkert
# Steve Reinhardt
-#
-# This file generates the header and source files for the flags
-# that control the tracing facility.
-#
-
-import sys
-
-if len(sys.argv) != 2:
- print "%s: Need argument (basename of cc/hh files)" % sys.argv[0]
- sys.exit(1)
-
-hhfilename = sys.argv[1] + '.hh'
-ccfilename = sys.argv[1] + '.cc'
+__all__ = [ 'allFlags', 'baseFlags', 'compoundFlagsMap', 'compoundFlags' ]
#
# The list of trace flags that can be used to condition DPRINTFs etc.
@@ -89,6 +77,20 @@ baseFlags = [
'EthernetPIO',
'EthernetSM',
'Event',
+ 'ExecEnable',
+ 'ExecCPSeq',
+ 'ExecEffAddr',
+ 'ExecFetchSeq',
+ 'ExecIntRegs',
+ 'ExecIntel',
+ 'ExecLegion',
+ 'ExecOpClass',
+ 'ExecRegDelta',
+ 'ExecResult',
+ 'ExecSpeculative',
+ 'ExecSymbol',
+ 'ExecThread',
+ 'ExecTicks',
'FE',
'Fault',
'Fetch',
@@ -114,7 +116,7 @@ baseFlags = [
'ISP',
'IdeCtrl',
'IdeDisk',
- 'InstExec',
+ 'Iob',
'Interrupt',
'LLSC',
'LSQ',
@@ -135,6 +137,7 @@ baseFlags = [
'PciConfigAll',
'Pipeline',
'Printf',
+ 'Predecoder',
'Quiesce',
'ROB',
'Regs',
@@ -167,6 +170,7 @@ baseFlags = [
'VtoPhys',
'WriteBarrier',
'Writeback',
+ 'X86',
]
#
@@ -178,111 +182,119 @@ baseFlags = [
# following the existing examples.
#
compoundFlagMap = {
- 'GDBAll' : [ 'GDBMisc', 'GDBAcc', 'GDBRead', 'GDBWrite', 'GDBSend', 'GDBRecv', 'GDBExtra' ],
- 'ScsiAll' : [ 'ScsiDisk', 'ScsiCtrl', 'ScsiNone' ],
- 'DiskImageAll' : [ 'DiskImage', 'DiskImageRead', 'DiskImageWrite' ],
- 'EthernetAll' : [ 'Ethernet', 'EthernetPIO', 'EthernetDMA', 'EthernetData' , 'EthernetDesc', 'EthernetIntr', 'EthernetSM', 'EthernetCksum' ],
- 'EthernetNoData' : [ 'Ethernet', 'EthernetPIO', 'EthernetDesc', 'EthernetIntr', 'EthernetSM', 'EthernetCksum' ],
- 'IdeAll' : [ 'IdeCtrl', 'IdeDisk' ],
- 'O3CPUAll' : [ 'Fetch', 'Decode', 'Rename', 'IEW', 'Commit', 'IQ', 'ROB', 'FreeList', 'RenameMap', 'LSQ', 'LSQUnit', 'StoreSet', 'MemDepUnit', 'DynInst', 'FullCPU', 'O3CPU', 'Activity','Scoreboard','Writeback'],
- 'OzoneCPUAll' : [ 'BE', 'FE', 'IBE', 'OzoneLSQ', 'OzoneCPU'],
- 'All' : baseFlags
+ 'All' : baseFlags,
+ 'DiskImageAll' : [ 'DiskImage', 'DiskImageRead', 'DiskImageWrite' ],
+ 'EthernetAll' : [ 'Ethernet', 'EthernetPIO', 'EthernetDMA',
+ 'EthernetData' , 'EthernetDesc', 'EthernetIntr',
+ 'EthernetSM', 'EthernetCksum' ],
+ 'EthernetNoData' : [ 'Ethernet', 'EthernetPIO', 'EthernetDesc',
+ 'EthernetIntr', 'EthernetSM', 'EthernetCksum' ],
+ 'Exec' : [ 'ExecEnable', 'ExecTicks', 'ExecOpClass',
+ 'ExecThread', 'ExecEffAddr', 'ExecResult',
+ 'ExecSymbol' ],
+ 'GDBAll' : [ 'GDBMisc', 'GDBAcc', 'GDBRead', 'GDBWrite', 'GDBSend',
+ 'GDBRecv', 'GDBExtra' ],
+ 'IdeAll' : [ 'IdeCtrl', 'IdeDisk' ],
+ 'O3CPUAll' : [ 'Fetch', 'Decode', 'Rename', 'IEW', 'Commit', 'IQ',
+ 'ROB', 'FreeList', 'RenameMap', 'LSQ', 'LSQUnit',
+ 'StoreSet', 'MemDepUnit', 'DynInst', 'FullCPU',
+ 'O3CPU', 'Activity','Scoreboard','Writeback' ],
+ 'OzoneCPUAll' : [ 'BE', 'FE', 'IBE', 'OzoneLSQ', 'OzoneCPU' ],
+ 'ScsiAll' : [ 'ScsiDisk', 'ScsiCtrl', 'ScsiNone' ]
}
-#############################################################
-#
-# Everything below this point generates the appropriate C++
-# declarations and definitions for the trace flags. If you are simply
-# adding or modifying flag definitions, you should not have to change
-# anything below.
-#
-
-import sys
-
# extract just the compound flag names into a list
compoundFlags = []
compoundFlags.extend(compoundFlagMap.keys())
compoundFlags.sort()
-#
-# First generate the header file. This defines the Flag enum
-# and some extern declarations for the .cc file.
-#
-try:
- hhfile = file(hhfilename, 'w')
-except IOError, e:
- sys.exit("can't open %s: %s" % (hhfilename, e))
-
-# file header boilerplate
-print >>hhfile, '''
-/*
- * DO NOT EDIT THIS FILE!
- *
- * Automatically generated from traceflags.py
- */
+allFlags = frozenset(baseFlags + compoundFlags)
-#ifndef __BASE_TRACE_FLAGS_HH__
-#define __BASE_TRACE_FLAGS_HH__
-
-namespace Trace {
-
-enum Flags {
-''',
-
-# Generate the enum. Base flags come first, then compound flags.
-idx = 0
-for flag in baseFlags:
- print >>hhfile, ' %s = %d,' % (flag, idx)
- idx += 1
-
-numBaseFlags = idx
-print >>hhfile, ' NumFlags = %d,' % idx
-
-# put a comment in here to separate base from compound flags
-print >>hhfile, '''
- // The remaining enum values are *not* valid indices for Trace::flags.
- // They are "compound" flags, which correspond to sets of base
- // flags, and are used only by TraceParamContext::setFlags().
-''',
-
-for flag in compoundFlags:
- print >>hhfile, ' %s = %d,' % (flag, idx)
- idx += 1
-
-numCompoundFlags = idx - numBaseFlags
-print >>hhfile, ' NumCompoundFlags = %d' % numCompoundFlags
-
-# trailer boilerplate
-print >>hhfile, '''\
-}; // enum Flags
-
-// Array of strings for SimpleEnumParam
-extern const char *flagStrings[];
-extern const int numFlagStrings;
-
-// Array of arraay pointers: for each compound flag, gives the list of
-// base flags to set. Inidividual flag arrays are terminated by -1.
-extern const Flags *compoundFlags[];
-
-/* namespace Trace */ }
-
-#endif // __BASE_TRACE_FLAGS_HH__
-''',
-
-hhfile.close()
-
-#
-#
-# Print out .cc file with array definitions.
+#############################################################
#
+# Everything below this point generates the appropriate C++
+# declarations and definitions for the trace flags. If you are simply
+# adding or modifying flag definitions, you should not have to change
+# anything below.
#
-try:
- ccfile = file(ccfilename, 'w')
-except OSError, e:
- sys.exit("can't open %s: %s" % (ccfilename, e))
-
-# file header
-print >>ccfile, '''
+def gen_hh(filename):
+ #
+ # First generate the header file. This defines the Flag enum
+ # and some extern declarations for the .cc file.
+ #
+ try:
+ hhfile = file(filename, 'w')
+ except IOError, e:
+ sys.exit("can't open %s: %s" % (hhfilename, e))
+
+ # file header boilerplate
+ print >>hhfile, '''
+ /*
+ * DO NOT EDIT THIS FILE!
+ *
+ * Automatically generated from traceflags.py
+ */
+
+ #ifndef __BASE_TRACE_FLAGS_HH__
+ #define __BASE_TRACE_FLAGS_HH__
+
+ namespace Trace {
+
+ enum Flags {
+ ''',
+
+ # Generate the enum. Base flags come first, then compound flags.
+ idx = 0
+ for flag in baseFlags:
+ print >>hhfile, ' %s = %d,' % (flag, idx)
+ idx += 1
+
+ numBaseFlags = idx
+ print >>hhfile, ' NumFlags = %d,' % idx
+
+ # put a comment in here to separate base from compound flags
+ print >>hhfile, '''
+ // The remaining enum values are *not* valid indices for Trace::flags.
+ // They are "compound" flags, which correspond to sets of base
+ // flags, and are used by changeFlag.
+ ''',
+
+ for flag in compoundFlags:
+ print >>hhfile, ' %s = %d,' % (flag, idx)
+ idx += 1
+
+ numCompoundFlags = idx - numBaseFlags
+ print >>hhfile, ' NumCompoundFlags = %d' % numCompoundFlags
+
+ # trailer boilerplate
+ print >>hhfile, '''\
+ }; // enum Flags
+
+ // Array of strings for SimpleEnumParam
+ extern const char *flagStrings[];
+ extern const int numFlagStrings;
+
+ // Array of arraay pointers: for each compound flag, gives the list of
+ // base flags to set. Inidividual flag arrays are terminated by -1.
+ extern const Flags *compoundFlags[];
+
+ /* namespace Trace */ }
+
+ #endif // __BASE_TRACE_FLAGS_HH__
+ \n''',
+
+ hhfile.close()
+
+def gen_cc(filename):
+ '''Print out .cc file with array definitions.'''
+
+ try:
+ ccfile = file(filename, 'w')
+ except OSError, e:
+ sys.exit("can't open %s: %s" % (ccfilename, e))
+
+ # file header
+ print >>ccfile, '''
/*
* DO NOT EDIT THIS FILE!
*
@@ -297,45 +309,57 @@ const char *Trace::flagStrings[] =
{
''',
-# The string array is used by SimpleEnumParam to map the strings
-# provided by the user to enum values.
-for flag in baseFlags:
- print >>ccfile, ' "%s",' % flag
+ # The string array is used by SimpleEnumParam to map the strings
+ # provided by the user to enum values.
+ for flag in baseFlags:
+ print >>ccfile, ' "%s",' % flag
-for flag in compoundFlags:
- print >>ccfile, ' "%s",' % flag
+ for flag in compoundFlags:
+ print >>ccfile, ' "%s",' % flag
-print >>ccfile, '};\n'
+ print >>ccfile, '};\n'
-numFlagStrings = len(baseFlags) + len(compoundFlags);
+ numFlagStrings = len(baseFlags) + len(compoundFlags);
-print >>ccfile, 'const int Trace::numFlagStrings = %d;' % numFlagStrings
-print >>ccfile
+ print >>ccfile, 'const int Trace::numFlagStrings = %d;' % numFlagStrings
+ print >>ccfile
-#
-# Now define the individual compound flag arrays. There is an array
-# for each compound flag listing the component base flags.
-#
+ #
+ # Now define the individual compound flag arrays. There is an array
+ # for each compound flag listing the component base flags.
+ #
-for flag in compoundFlags:
- flags = compoundFlagMap[flag]
- flags.append('(Flags)-1')
- print >>ccfile, 'static const Flags %sMap[] =' % flag
- print >>ccfile, '{ %s };' % (', '.join(flags))
- print >>ccfile
+ for flag in compoundFlags:
+ flags = compoundFlagMap[flag]
+ flags.append('(Flags)-1')
+ print >>ccfile, 'static const Flags %sMap[] =' % flag
+ print >>ccfile, '{ %s };' % (', '.join(flags))
+ print >>ccfile
-#
-# Finally the compoundFlags[] array maps the compound flags
-# to their individual arrays/
-#
-print >>ccfile, 'const Flags *Trace::compoundFlags[] ='
-print >>ccfile, '{'
+ #
+ # Finally the compoundFlags[] array maps the compound flags
+ # to their individual arrays/
+ #
+ print >>ccfile, 'const Flags *Trace::compoundFlags[] ='
+ print >>ccfile, '{'
+
+ for flag in compoundFlags:
+ print >>ccfile, ' %sMap,' % flag
+
+ # file trailer
+ print >>ccfile, '};'
+
+ ccfile.close()
-for flag in compoundFlags:
- print >>ccfile, ' %sMap,' % flag
+if __name__ == '__main__':
+ # This file generates the header and source files for the flags
+ # that control the tracing facility.
-# file trailer
-print >>ccfile, '};'
+ import sys
-ccfile.close()
+ if len(sys.argv) != 2:
+ print "%s: Need argument (basename of cc/hh files)" % sys.argv[0]
+ sys.exit(1)
+ gen_hh(sys.argv[1] + '.hh')
+ gen_cc(sys.argv[1] + '.cc')
diff --git a/src/base/varargs.hh b/src/base/varargs.hh
new file mode 100644
index 000000000..2ba8c240a
--- /dev/null
+++ b/src/base/varargs.hh
@@ -0,0 +1,292 @@
+/*
+ * 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: Nathan Binkert
+ */
+
+#ifndef __BASE_VARARGS_HH__
+#define __BASE_VARARGS_HH__
+
+#include "base/refcnt.hh"
+
+#define VARARGS_DECLARATION(receiver) \
+ VarArgs::Argument<receiver> a01 = VarArgs::Null(), \
+ VarArgs::Argument<receiver> a02 = VarArgs::Null(), \
+ VarArgs::Argument<receiver> a03 = VarArgs::Null(), \
+ VarArgs::Argument<receiver> a04 = VarArgs::Null(), \
+ VarArgs::Argument<receiver> a05 = VarArgs::Null(), \
+ VarArgs::Argument<receiver> a06 = VarArgs::Null(), \
+ VarArgs::Argument<receiver> a07 = VarArgs::Null(), \
+ VarArgs::Argument<receiver> a08 = VarArgs::Null(), \
+ VarArgs::Argument<receiver> a09 = VarArgs::Null(), \
+ VarArgs::Argument<receiver> a10 = VarArgs::Null(), \
+ VarArgs::Argument<receiver> a11 = VarArgs::Null(), \
+ VarArgs::Argument<receiver> a12 = VarArgs::Null(), \
+ VarArgs::Argument<receiver> a13 = VarArgs::Null(), \
+ VarArgs::Argument<receiver> a14 = VarArgs::Null(), \
+ VarArgs::Argument<receiver> a15 = VarArgs::Null(), \
+ VarArgs::Argument<receiver> a16 = VarArgs::Null()
+
+#define VARARGS_DEFINITION(receiver) \
+ VarArgs::Argument<receiver> a01, \
+ VarArgs::Argument<receiver> a02, \
+ VarArgs::Argument<receiver> a03, \
+ VarArgs::Argument<receiver> a04, \
+ VarArgs::Argument<receiver> a05, \
+ VarArgs::Argument<receiver> a06, \
+ VarArgs::Argument<receiver> a07, \
+ VarArgs::Argument<receiver> a08, \
+ VarArgs::Argument<receiver> a09, \
+ VarArgs::Argument<receiver> a10, \
+ VarArgs::Argument<receiver> a11, \
+ VarArgs::Argument<receiver> a12, \
+ VarArgs::Argument<receiver> a13, \
+ VarArgs::Argument<receiver> a14, \
+ VarArgs::Argument<receiver> a15, \
+ VarArgs::Argument<receiver> a16
+
+#define VARARGS_ALLARGS \
+ a01, a02, a03, a04, a05, a06, a07, a08, \
+ a09, a10, a11, a12, a13, a14, a15, a16
+
+#define VARARGS_ADDARGS(receiver) do { \
+ do { \
+ if (!a01) break; \
+ a01.add_arg(receiver); \
+ if (!a02) break; \
+ a02.add_arg(receiver); \
+ if (!a03) break; \
+ a03.add_arg(receiver); \
+ if (!a04) break; \
+ a04.add_arg(receiver); \
+ if (!a05) break; \
+ a05.add_arg(receiver); \
+ if (!a06) break; \
+ a06.add_arg(receiver); \
+ if (!a07) break; \
+ a07.add_arg(receiver); \
+ if (!a08) break; \
+ a08.add_arg(receiver); \
+ if (!a09) break; \
+ a09.add_arg(receiver); \
+ if (!a10) break; \
+ a10.add_arg(receiver); \
+ if (!a11) break; \
+ a11.add_arg(receiver); \
+ if (!a12) break; \
+ a12.add_arg(receiver); \
+ if (!a13) break; \
+ a13.add_arg(receiver); \
+ if (!a14) break; \
+ a14.add_arg(receiver); \
+ if (!a15) break; \
+ a15.add_arg(receiver); \
+ if (!a16) break; \
+ a16.add_arg(receiver); \
+ } while (0); \
+ receiver.end_args(); \
+} while (0)
+
+namespace VarArgs {
+
+struct Null {};
+
+template <typename T>
+struct Traits
+{
+ enum { enabled = true };
+};
+
+template <>
+struct Traits<Null>
+{
+ enum { enabled = false };
+};
+
+template <class RECV>
+struct Base : public RefCounted
+{
+ virtual void add_arg(RECV &receiver) const = 0;
+};
+
+template <typename T, class RECV>
+struct Any : public Base<RECV>
+{
+ const T &argument;
+
+ Any(const T &arg) : argument(arg) {}
+
+ virtual void
+ add_arg(RECV &receiver) const
+ {
+ receiver.add_arg(argument);
+ }
+};
+
+template <class RECV>
+struct Argument : public RefCountingPtr<Base<RECV> >
+{
+ typedef RefCountingPtr<Base<RECV> > Base;
+
+ Argument() { }
+ Argument(const Null &null) { }
+ template <typename T>
+ Argument(const T& arg) : Base(new Any<T, RECV>(arg)) { }
+
+ void
+ add_arg(RECV &receiver) const
+ {
+ if (this->data)
+ this->data->add_arg(receiver);
+ }
+};
+
+template<class RECV>
+class List
+{
+ public:
+ typedef Argument<RECV> Argument;
+ typedef std::list<Argument> list;
+ typedef typename list::iterator iterator;
+ typedef typename list::const_iterator const_iterator;
+ typedef typename list::size_type size_type;
+
+ protected:
+ list l;
+
+ public:
+ List() {}
+ List(Argument a01, Argument a02, Argument a03, Argument a04,
+ Argument a05, Argument a06, Argument a07, Argument a08,
+ Argument a09, Argument a10, Argument a11, Argument a12,
+ Argument a13, Argument a14, Argument a15, Argument a16)
+ {
+ if (!a01) return;
+ l.push_back(a01);
+ if (!a02) return;
+ l.push_back(a02);
+ if (!a03) return;
+ l.push_back(a03);
+ if (!a04) return;
+ l.push_back(a04);
+ if (!a05) return;
+ l.push_back(a05);
+ if (!a06) return;
+ l.push_back(a06);
+ if (!a07) return;
+ l.push_back(a07);
+ if (!a08) return;
+ l.push_back(a08);
+ if (!a09) return;
+ l.push_back(a09);
+ if (!a10) return;
+ l.push_back(a10);
+ if (!a11) return;
+ l.push_back(a11);
+ if (!a12) return;
+ l.push_back(a12);
+ if (!a13) return;
+ l.push_back(a13);
+ if (!a14) return;
+ l.push_back(a14);
+ if (!a15) return;
+ l.push_back(a15);
+ if (!a16) return;
+ l.push_back(a16);
+ }
+
+ size_type size() const { return l.size(); }
+ bool empty() const { return l.empty(); }
+
+ iterator begin() { return l.begin(); }
+ const_iterator begin() const { return l.begin(); }
+
+ iterator end() { return l.end(); }
+ const_iterator end() const { return l.end(); }
+
+ void
+ push_back(const Argument &arg)
+ {
+ if (arg)
+ l.push_back(arg);
+ }
+
+ void
+ push_front(const Argument &arg)
+ {
+ if (arg)
+ l.push_front(arg);
+ }
+
+ template <typename T>
+ void
+ push_back(const T &arg)
+ {
+ if (Traits<T>::enabled)
+ l.push_back(arg);
+ }
+
+ template <typename T>
+ void
+ push_front(const T &arg)
+ {
+ if (Traits<T>::enabled)
+ l.push_front(arg);
+ }
+
+ Argument& front() { return l.front(); }
+ const Argument& front() const { return l.front(); }
+ Argument& back() { return l.back(); }
+ const Argument& back() const { return l.back(); }
+
+ void erase(iterator position) { return l.erase(position); }
+ void erase(iterator first, iterator last) { return l.erase(first, last); }
+ void clear() { return l.clear(); }
+ void pop_front() { return l.pop_front(); }
+ void pop_back() { return l.pop_back(); }
+ void reverse() { l.reverse(); }
+
+ /*
+ * Functions specific to variable arguments
+ */
+ void
+ add_args(RECV &recv) const
+ {
+ const_iterator i = l.begin();
+ const_iterator end = l.end();
+ while (i != end) {
+ i->add_arg(recv);
+ ++i;
+ }
+
+ recv.end_args();
+ }
+};
+
+/* end namespace VarArgs */ }
+
+#endif /* __BASE_VARARGS_HH__ */
diff --git a/src/cpu/SConscript b/src/cpu/SConscript
index 4d4b7574c..1c2278f6f 100644
--- a/src/cpu/SConscript
+++ b/src/cpu/SConscript
@@ -28,11 +28,7 @@
#
# Authors: Steve Reinhardt
-import os
-import os.path
-
-# Import build environment variable from SConstruct.
-Import('env')
+Import('*')
#################################################################
#
@@ -107,89 +103,24 @@ env.Depends('static_inst_exec_sigs.hh', Value(env['CPU_MODELS']))
# and one of these are not being used.
CheckerSupportedCPUList = ['O3CPU', 'OzoneCPU']
-#################################################################
-#
-# Include CPU-model-specific files based on set of models
-# specified in CPU_MODELS build option.
-#
-#################################################################
-
-# Keep a list of CPU models that support SMT
-env['SMT_CPU_MODELS'] = []
-
-sources = []
-
-need_simple_base = False
-if 'AtomicSimpleCPU' in env['CPU_MODELS']:
- need_simple_base = True
- sources += Split('simple/atomic.cc')
-
-if 'TimingSimpleCPU' in env['CPU_MODELS']:
- need_simple_base = True
- sources += Split('simple/timing.cc')
-
-if need_simple_base:
- sources += Split('simple/base.cc')
-
-if 'FastCPU' in env['CPU_MODELS']:
- sources += Split('fast/cpu.cc')
-
-need_bp_unit = False
-if 'O3CPU' in env['CPU_MODELS']:
- need_bp_unit = True
- sources += SConscript('o3/SConscript', exports = 'env')
- sources += Split('''
- o3/base_dyn_inst.cc
- o3/bpred_unit.cc
- o3/commit.cc
- o3/decode.cc
- o3/fetch.cc
- o3/free_list.cc
- o3/fu_pool.cc
- o3/cpu.cc
- o3/iew.cc
- o3/inst_queue.cc
- o3/lsq_unit.cc
- o3/lsq.cc
- o3/mem_dep_unit.cc
- o3/rename.cc
- o3/rename_map.cc
- o3/rob.cc
- o3/scoreboard.cc
- o3/store_set.cc
- ''')
- sources += Split('memtest/memtest.cc')
- if env['USE_CHECKER']:
- sources += Split('o3/checker_builder.cc')
- else:
- env['SMT_CPU_MODELS'].append('O3CPU') # Checker doesn't support SMT right now
-
-if 'OzoneCPU' in env['CPU_MODELS']:
- need_bp_unit = True
- sources += Split('''
- ozone/base_dyn_inst.cc
- ozone/bpred_unit.cc
- ozone/cpu.cc
- ozone/cpu_builder.cc
- ozone/dyn_inst.cc
- ozone/front_end.cc
- ozone/lw_back_end.cc
- ozone/lw_lsq.cc
- ozone/rename_table.cc
- ''')
- if env['USE_CHECKER']:
- sources += Split('ozone/checker_builder.cc')
-
-if need_bp_unit:
- sources += Split('''
- o3/2bit_local_pred.cc
- o3/btb.cc
- o3/ras.cc
- o3/tournament_pred.cc
- ''')
+Source('activity.cc')
+Source('base.cc')
+Source('cpuevent.cc')
+Source('exetrace.cc')
+Source('func_unit.cc')
+Source('op_class.cc')
+Source('pc_event.cc')
+Source('quiesce_event.cc')
+Source('static_inst.cc')
+Source('simple_thread.cc')
+Source('thread_state.cc')
+
+if env['FULL_SYSTEM']:
+ Source('intr_control.cc')
+ Source('profile.cc')
if env['USE_CHECKER']:
- sources += Split('checker/cpu.cc')
+ Source('checker/cpu.cc')
checker_supports = False
for i in CheckerSupportedCPUList:
if i in env['CPU_MODELS']:
@@ -198,16 +129,5 @@ if env['USE_CHECKER']:
print "Checker only supports CPU models",
for i in CheckerSupportedCPUList:
print i,
- print ", please set USE_CHECKER=False or use one of those CPU models"
+ print ", please set USE_CHECKER=False or use one of those CPU models"
Exit(1)
-
-
-# FullCPU sources are included from src/SConscript since they're not
-# below this point in the file hierarchy.
-
-# 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/cpu/base.cc b/src/cpu/base.cc
index 03110630c..4dccee0d3 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -63,7 +63,7 @@ int maxThreadsPerCPU = 1;
CPUProgressEvent::CPUProgressEvent(EventQueue *q, Tick ival,
BaseCPU *_cpu)
- : Event(q, Event::Stat_Event_Pri), interval(ival),
+ : Event(q, Event::Progress_Event_Pri), interval(ival),
lastNumInst(0), cpu(_cpu)
{
if (interval)
@@ -320,7 +320,7 @@ BaseCPU::switchOut()
}
void
-BaseCPU::takeOverFrom(BaseCPU *oldCPU)
+BaseCPU::takeOverFrom(BaseCPU *oldCPU, Port *ic, Port *dc)
{
assert(threadContexts.size() == oldCPU->threadContexts.size());
@@ -353,6 +353,26 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
// if (profileEvent)
// profileEvent->schedule(curTick);
#endif
+
+ // Connect new CPU to old CPU's memory only if new CPU isn't
+ // connected to anything. Also connect old CPU's memory to new
+ // CPU.
+ Port *peer;
+ if (ic->getPeer() == NULL) {
+ peer = oldCPU->getPort("icache_port")->getPeer();
+ ic->setPeer(peer);
+ } else {
+ peer = ic->getPeer();
+ }
+ peer->setPeer(ic);
+
+ if (dc->getPeer() == NULL) {
+ peer = oldCPU->getPort("dcache_port")->getPeer();
+ dc->setPeer(peer);
+ } else {
+ peer = dc->getPeer();
+ }
+ peer->setPeer(dc);
}
@@ -373,12 +393,6 @@ BaseCPU::ProfileEvent::process()
}
void
-BaseCPU::post_interrupt(int int_type)
-{
- interrupts.post(int_type);
-}
-
-void
BaseCPU::post_interrupt(int int_num, int index)
{
interrupts.post(int_num, index);
@@ -396,6 +410,11 @@ BaseCPU::clear_interrupts()
interrupts.clear_all();
}
+uint64_t
+BaseCPU::get_interrupts(int int_num)
+{
+ return interrupts.get_vec(int_num);
+}
void
BaseCPU::serialize(std::ostream &os)
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index a1265b748..4d8300186 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -34,11 +34,11 @@
#include <vector>
+#include "arch/isa_traits.hh"
#include "base/statistics.hh"
#include "config/full_system.hh"
#include "sim/eventq.hh"
#include "mem/mem_object.hh"
-#include "arch/isa_traits.hh"
#if FULL_SYSTEM
#include "arch/interrupts.hh"
@@ -50,6 +50,11 @@ class ThreadContext;
class System;
class Port;
+namespace TheISA
+{
+ class Predecoder;
+}
+
class CPUProgressEvent : public Event
{
protected:
@@ -102,10 +107,10 @@ class BaseCPU : public MemObject
TheISA::Interrupts interrupts;
public:
- virtual void post_interrupt(int int_type);
virtual void post_interrupt(int int_num, int index);
virtual void clear_interrupt(int int_num, int index);
virtual void clear_interrupts();
+ virtual uint64_t get_interrupts(int int_num);
bool check_interrupts(ThreadContext * tc) const
{ return interrupts.check_interrupts(tc); }
@@ -125,6 +130,7 @@ class BaseCPU : public MemObject
protected:
std::vector<ThreadContext *> threadContexts;
+ std::vector<TheISA::Predecoder *> predecoders;
public:
@@ -196,7 +202,7 @@ class BaseCPU : public MemObject
/// Take over execution from the given CPU. Used for warm-up and
/// sampling.
- virtual void takeOverFrom(BaseCPU *);
+ virtual void takeOverFrom(BaseCPU *, Port *ic, Port *dc);
/**
* Number of threads we're actually simulating (<= SMT_MAX_THREADS).
diff --git a/src/cpu/checker/cpu.cc b/src/cpu/checker/cpu.cc
index d6cd9409b..a6af98d66 100644
--- a/src/cpu/checker/cpu.cc
+++ b/src/cpu/checker/cpu.cc
@@ -244,7 +244,7 @@ CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
!(unverifiedReq->isUncacheable()) &&
(!(unverifiedReq->isLocked()) ||
((unverifiedReq->isLocked()) &&
- unverifiedReq->getScResult() == 1))) {
+ unverifiedReq->getExtraData() == 1))) {
T inst_data;
/*
// This code would work if the LSQ allowed for snooping.
@@ -269,7 +269,7 @@ CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
// doesn't check if the SC should succeed or fail, it just checks the
// value.
if (res && unverifiedReq->scResultValid())
- *res = unverifiedReq->getScResult();
+ *res = unverifiedReq->getExtraData();
return NoFault;
}
diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh
index 3e08193ee..7b3628986 100644
--- a/src/cpu/checker/cpu.hh
+++ b/src/cpu/checker/cpu.hh
@@ -298,27 +298,27 @@ class CheckerCPU : public BaseCPU
thread->setNextPC(val);
}
- MiscReg readMiscReg(int misc_reg)
+ MiscReg readMiscRegNoEffect(int misc_reg)
{
- return thread->readMiscReg(misc_reg);
+ return thread->readMiscRegNoEffect(misc_reg);
}
- MiscReg readMiscRegWithEffect(int misc_reg)
+ MiscReg readMiscReg(int misc_reg)
{
- return thread->readMiscRegWithEffect(misc_reg);
+ return thread->readMiscReg(misc_reg);
}
- void setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
result.integer = val;
miscRegIdxs.push(misc_reg);
- return thread->setMiscReg(misc_reg, val);
+ return thread->setMiscRegNoEffect(misc_reg, val);
}
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{
miscRegIdxs.push(misc_reg);
- return thread->setMiscRegWithEffect(misc_reg, val);
+ return thread->setMiscReg(misc_reg, val);
}
void recordPCChange(uint64_t val) { changedPC = true; newPC = val; }
diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh
index 56e13dd1e..f3f8a0bb3 100644
--- a/src/cpu/checker/cpu_impl.hh
+++ b/src/cpu/checker/cpu_impl.hh
@@ -386,13 +386,13 @@ Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
int misc_reg_idx = miscRegIdxs.front();
miscRegIdxs.pop();
- if (inst->tcBase()->readMiscReg(misc_reg_idx) !=
- thread->readMiscReg(misc_reg_idx)) {
+ if (inst->tcBase()->readMiscRegNoEffect(misc_reg_idx) !=
+ thread->readMiscRegNoEffect(misc_reg_idx)) {
warn("%lli: Misc reg idx %i (side effect) does not match! "
"Inst: %#x, checker: %#x",
curTick, misc_reg_idx,
- inst->tcBase()->readMiscReg(misc_reg_idx),
- thread->readMiscReg(misc_reg_idx));
+ inst->tcBase()->readMiscRegNoEffect(misc_reg_idx),
+ thread->readMiscRegNoEffect(misc_reg_idx));
handleError(inst);
}
}
@@ -432,7 +432,7 @@ Checker<DynInstPtr>::copyResult(DynInstPtr &inst)
} else if (idx < TheISA::Fpcr_DepTag) {
thread->setFloatRegBits(idx, inst->readIntResult());
} else {
- thread->setMiscReg(idx, inst->readIntResult());
+ thread->setMiscRegNoEffect(idx, inst->readIntResult());
}
}
diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh
index cf36d8392..3b4d21e13 100644
--- a/src/cpu/checker/thread_context.hh
+++ b/src/cpu/checker/thread_context.hh
@@ -248,11 +248,17 @@ class CheckerThreadContext : public ThreadContext
checkerCPU->recordNextPCChange(val);
}
+ MiscReg readMiscRegNoEffect(int misc_reg)
+ { return actualTC->readMiscRegNoEffect(misc_reg); }
+
MiscReg readMiscReg(int misc_reg)
{ return actualTC->readMiscReg(misc_reg); }
- MiscReg readMiscRegWithEffect(int misc_reg)
- { return actualTC->readMiscRegWithEffect(misc_reg); }
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
+ {
+ checkerTC->setMiscRegNoEffect(misc_reg, val);
+ actualTC->setMiscRegNoEffect(misc_reg, val);
+ }
void setMiscReg(int misc_reg, const MiscReg &val)
{
@@ -260,12 +266,6 @@ class CheckerThreadContext : public ThreadContext
actualTC->setMiscReg(misc_reg, val);
}
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
- {
- checkerTC->setMiscRegWithEffect(misc_reg, val);
- actualTC->setMiscRegWithEffect(misc_reg, val);
- }
-
unsigned readStCondFailures()
{ return actualTC->readStCondFailures(); }
diff --git a/src/cpu/exec_context.hh b/src/cpu/exec_context.hh
index edccd747f..2b9fe4bcf 100644
--- a/src/cpu/exec_context.hh
+++ b/src/cpu/exec_context.hh
@@ -100,18 +100,18 @@ class ExecContext {
void setNextNPC(uint64_t val);
/** Reads a miscellaneous register. */
- MiscReg readMiscReg(int misc_reg);
+ MiscReg readMiscRegNoEffect(int misc_reg);
/** Reads a miscellaneous register, handling any architectural
* side effects due to reading that register. */
- MiscReg readMiscRegWithEffect(int misc_reg);
+ MiscReg readMiscReg(int misc_reg);
/** Sets a miscellaneous register. */
- void setMiscReg(int misc_reg, const MiscReg &val);
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
/** Sets a miscellaneous register, handling any architectural
* side effects due to writing that register. */
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val);
+ void setMiscReg(int misc_reg, const MiscReg &val);
/** Records the effective address of the instruction. Only valid
* for memory ops. */
diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc
index 5108d7338..c568b1439 100644
--- a/src/cpu/exetrace.cc
+++ b/src/cpu/exetrace.cc
@@ -31,14 +31,17 @@
* Steve Raasch
*/
+#include <errno.h>
#include <fstream>
#include <iomanip>
#include <sys/ipc.h>
#include <sys/shm.h>
+#include "arch/predecoder.hh"
#include "arch/regfile.hh"
#include "arch/utility.hh"
#include "base/loader/symtab.hh"
+#include "base/socket.hh"
#include "config/full_system.hh"
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
@@ -64,6 +67,28 @@ static bool wasMicro = false;
namespace Trace {
SharedData *shared_data = NULL;
+ListenSocket *cosim_listener = NULL;
+
+void
+setupSharedData()
+{
+ int shmfd = shmget('M' << 24 | 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);
+
+ // step legion forward one cycle so we can get register values
+ shared_data->flags = OWN_LEGION;
}
////////////////////////////////////////////////////////////////////////
@@ -123,12 +148,101 @@ inline void printLevelHeader(ostream & os, int level)
#endif
void
-Trace::InstRecord::dump(ostream &outs)
+Trace::InstRecord::dump()
{
+ ostream &outs = Trace::output();
+
DPRINTF(Sparc, "Instruction: %#X\n", staticInst->machInst);
- if (flags[PRINT_REG_DELTA])
+ bool diff = true;
+ if (IsOn(ExecRegDelta))
{
+ diff = false;
+#ifndef NDEBUG
#if THE_ISA == SPARC_ISA
+ static int fd = 0;
+ //Don't print what happens for each micro-op, just print out
+ //once at the last op, and for regular instructions.
+ if(!staticInst->isMicroOp() || staticInst->isLastMicroOp())
+ {
+ if(!cosim_listener)
+ {
+ int port = 8000;
+ cosim_listener = new ListenSocket();
+ while(!cosim_listener->listen(port, true))
+ {
+ DPRINTF(GDBMisc, "Can't bind port %d\n", port);
+ port++;
+ }
+ ccprintf(cerr, "Listening for cosimulator on port %d\n", port);
+ fd = cosim_listener->accept();
+ }
+ char prefix[] = "goli";
+ for(int p = 0; p < 4; p++)
+ {
+ for(int i = 0; i < 8; i++)
+ {
+ uint64_t regVal;
+ int res = read(fd, &regVal, sizeof(regVal));
+ if(res < 0)
+ panic("First read call failed! %s\n", strerror(errno));
+ regVal = TheISA::gtoh(regVal);
+ uint64_t realRegVal = thread->readIntReg(p * 8 + i);
+ if((regVal & 0xffffffffULL) != (realRegVal & 0xffffffffULL))
+ {
+ DPRINTF(ExecRegDelta, "Register %s%d should be %#x but is %#x.\n", prefix[p], i, regVal, realRegVal);
+ diff = true;
+ }
+ //ccprintf(outs, "%s%d m5 = %#x statetrace = %#x\n", prefix[p], i, realRegVal, regVal);
+ }
+ }
+ /*for(int f = 0; f <= 62; f+=2)
+ {
+ uint64_t regVal;
+ int res = read(fd, &regVal, sizeof(regVal));
+ if(res < 0)
+ panic("First read call failed! %s\n", strerror(errno));
+ regVal = TheISA::gtoh(regVal);
+ uint64_t realRegVal = thread->readFloatRegBits(f, 64);
+ if(regVal != realRegVal)
+ {
+ DPRINTF(ExecRegDelta, "Register f%d should be %#x but is %#x.\n", f, regVal, realRegVal);
+ }
+ }*/
+ uint64_t regVal;
+ int res = read(fd, &regVal, sizeof(regVal));
+ if(res < 0)
+ panic("First read call failed! %s\n", strerror(errno));
+ regVal = TheISA::gtoh(regVal);
+ uint64_t realRegVal = thread->readNextPC();
+ if(regVal != realRegVal)
+ {
+ DPRINTF(ExecRegDelta, "Register pc should be %#x but is %#x.\n", regVal, realRegVal);
+ diff = true;
+ }
+ res = read(fd, &regVal, sizeof(regVal));
+ if(res < 0)
+ panic("First read call failed! %s\n", strerror(errno));
+ regVal = TheISA::gtoh(regVal);
+ realRegVal = thread->readNextNPC();
+ if(regVal != realRegVal)
+ {
+ DPRINTF(ExecRegDelta, "Register npc should be %#x but is %#x.\n", regVal, realRegVal);
+ diff = true;
+ }
+ res = read(fd, &regVal, sizeof(regVal));
+ if(res < 0)
+ panic("First read call failed! %s\n", strerror(errno));
+ regVal = TheISA::gtoh(regVal);
+ realRegVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
+ if((regVal & 0xF) != (realRegVal & 0xF))
+ {
+ DPRINTF(ExecRegDelta, "Register ccr should be %#x but is %#x.\n", regVal, realRegVal);
+ diff = true;
+ }
+ }
+#endif
+#endif
+#if 0 //THE_ISA == SPARC_ISA
//Don't print what happens for each micro-op, just print out
//once at the last op, and for regular instructions.
if(!staticInst->isMicroOp() || staticInst->isLastMicroOp())
@@ -148,14 +262,14 @@ Trace::InstRecord::dump(ostream &outs)
outs << "PC = " << thread->readNextPC();
outs << " NPC = " << thread->readNextNPC();
newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
- //newVal = thread->readMiscReg(SparcISA::MISCREG_CCR);
+ //newVal = thread->readMiscRegNoEffect(SparcISA::MISCREG_CCR);
if(newVal != ccr)
{
outs << " CCR = " << newVal;
ccr = newVal;
}
newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 1);
- //newVal = thread->readMiscReg(SparcISA::MISCREG_Y);
+ //newVal = thread->readMiscRegNoEffect(SparcISA::MISCREG_Y);
if(newVal != y)
{
outs << " Y = " << newVal;
@@ -187,34 +301,26 @@ Trace::InstRecord::dump(ostream &outs)
}
#endif
}
- else if (flags[INTEL_FORMAT]) {
-#if FULL_SYSTEM
- bool is_trace_system = (thread->getCpuPtr()->system->name() == trace_system);
-#else
- bool is_trace_system = true;
-#endif
- if (is_trace_system) {
- ccprintf(outs, "%7d ) ", cycle);
- outs << "0x" << hex << PC << ":\t";
- if (staticInst->isLoad()) {
- outs << "<RD 0x" << hex << addr;
- outs << ">";
- } else if (staticInst->isStore()) {
- outs << "<WR 0x" << hex << addr;
- outs << ">";
- }
- outs << endl;
+ if(!diff) {
+ } else if (IsOn(ExecIntel)) {
+ ccprintf(outs, "%7d ) ", when);
+ outs << "0x" << hex << PC << ":\t";
+ if (staticInst->isLoad()) {
+ ccprintf(outs, "<RD %#x>", addr);
+ } else if (staticInst->isStore()) {
+ ccprintf(outs, "<WR %#x>", addr);
}
+ outs << endl;
} else {
- if (flags[PRINT_CYCLE])
- ccprintf(outs, "%7d: ", cycle);
+ if (IsOn(ExecTicks))
+ ccprintf(outs, "%7d: ", when);
outs << thread->getCpuPtr()->name() << " ";
- if (flags[TRACE_MISSPEC])
+ if (IsOn(ExecSpeculative))
outs << (misspeculating ? "-" : "+") << " ";
- if (flags[PRINT_THREAD_NUM])
+ if (IsOn(ExecThread))
outs << "T" << thread->getThreadNum() << " : ";
@@ -222,7 +328,7 @@ Trace::InstRecord::dump(ostream &outs)
Addr sym_addr;
if (debugSymbolTable
&& debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr)
- && flags[PC_SYMBOL]) {
+ && IsOn(ExecSymbol)) {
if (PC != sym_addr)
sym_str += csprintf("+%d", PC - sym_addr);
outs << "@" << sym_str << " : ";
@@ -248,11 +354,11 @@ Trace::InstRecord::dump(ostream &outs)
outs << " : ";
- if (flags[PRINT_OP_CLASS]) {
+ if (IsOn(ExecOpClass)) {
outs << opClassStrings[staticInst->opClass()] << " : ";
}
- if (flags[PRINT_RESULT_DATA] && data_status != DataInvalid) {
+ if (IsOn(ExecResult) && data_status != DataInvalid) {
outs << " D=";
#if 0
if (data_status == DataDouble)
@@ -264,10 +370,10 @@ Trace::InstRecord::dump(ostream &outs)
#endif
}
- if (flags[PRINT_EFF_ADDR] && addr_valid)
+ if (IsOn(ExecEffAddr) && addr_valid)
outs << " A=0x" << hex << addr;
- if (flags[PRINT_INT_REGS] && regs_valid) {
+ if (IsOn(ExecIntRegs) && regs_valid) {
for (int i = 0; i < TheISA::NumIntRegs;)
for (int j = i + 1; i <= j; i++)
ccprintf(outs, "r%02d = %#018x%s", i,
@@ -276,10 +382,10 @@ Trace::InstRecord::dump(ostream &outs)
outs << "\n";
}
- if (flags[PRINT_FETCH_SEQ] && fetch_seq_valid)
+ if (IsOn(ExecFetchSeq) && fetch_seq_valid)
outs << " FetchSeq=" << dec << fetch_seq;
- if (flags[PRINT_CP_SEQ] && cp_seq_valid)
+ if (IsOn(ExecCPSeq) && cp_seq_valid)
outs << " CPSeq=" << dec << cp_seq;
//
@@ -288,8 +394,9 @@ Trace::InstRecord::dump(ostream &outs)
outs << endl;
}
#if THE_ISA == SPARC_ISA && FULL_SYSTEM
+ static TheISA::Predecoder predecoder(NULL);
// Compare
- if (flags[LEGION_LOCKSTEP])
+ if (IsOn(ExecLegion))
{
bool compared = false;
bool diffPC = false;
@@ -321,10 +428,13 @@ Trace::InstRecord::dump(ostream &outs)
bool diffTlb = false;
Addr m5Pc, lgnPc;
+ if (!shared_data)
+ setupSharedData();
+
// We took a trap on a micro-op...
if (wasMicro && !staticInst->isMicroOp())
{
- // let's skip comparing this cycle
+ // let's skip comparing this tick
while (!compared)
if (shared_data->flags == OWN_M5) {
shared_data->flags = OWN_LEGION;
@@ -370,30 +480,30 @@ Trace::InstRecord::dump(ostream &outs)
diffFpRegs = true;
}
}
- uint64_t oldTl = thread->readMiscReg(MISCREG_TL);
+ uint64_t oldTl = thread->readMiscRegNoEffect(MISCREG_TL);
if (oldTl != shared_data->tl)
diffTl = true;
for (int i = 1; i <= MaxTL; i++) {
- thread->setMiscReg(MISCREG_TL, i);
- if (thread->readMiscReg(MISCREG_TPC) !=
+ thread->setMiscRegNoEffect(MISCREG_TL, i);
+ if (thread->readMiscRegNoEffect(MISCREG_TPC) !=
shared_data->tpc[i-1])
diffTpc = true;
- if (thread->readMiscReg(MISCREG_TNPC) !=
+ if (thread->readMiscRegNoEffect(MISCREG_TNPC) !=
shared_data->tnpc[i-1])
diffTnpc = true;
- if (thread->readMiscReg(MISCREG_TSTATE) !=
+ if (thread->readMiscRegNoEffect(MISCREG_TSTATE) !=
shared_data->tstate[i-1])
diffTstate = true;
- if (thread->readMiscReg(MISCREG_TT) !=
+ if (thread->readMiscRegNoEffect(MISCREG_TT) !=
shared_data->tt[i-1])
diffTt = true;
- if (thread->readMiscReg(MISCREG_HTSTATE) !=
+ if (thread->readMiscRegNoEffect(MISCREG_HTSTATE) !=
shared_data->htstate[i-1])
diffHtstate = true;
}
- thread->setMiscReg(MISCREG_TL, oldTl);
+ thread->setMiscRegNoEffect(MISCREG_TL, oldTl);
- if(shared_data->tba != thread->readMiscReg(MISCREG_TBA))
+ if(shared_data->tba != thread->readMiscRegNoEffect(MISCREG_TBA))
diffTba = true;
//When the hpstate register is read by an instruction,
//legion has bit 11 set. When it's in storage, it doesn't.
@@ -401,50 +511,50 @@ Trace::InstRecord::dump(ostream &outs)
//of the registers like that, the bit is always set to 1 and
//we just don't compare it. It's not supposed to matter
//anyway.
- if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE))
+ if((shared_data->hpstate | (1 << 11)) != thread->readMiscRegNoEffect(MISCREG_HPSTATE))
diffHpstate = true;
- if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA))
+ if(shared_data->htba != thread->readMiscRegNoEffect(MISCREG_HTBA))
diffHtba = true;
- if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE))
+ if(shared_data->pstate != thread->readMiscRegNoEffect(MISCREG_PSTATE))
diffPstate = true;
- //if(shared_data->y != thread->readMiscReg(MISCREG_Y))
+ //if(shared_data->y != thread->readMiscRegNoEffect(MISCREG_Y))
if(shared_data->y !=
thread->readIntReg(NumIntArchRegs + 1))
diffY = true;
- if(shared_data->fsr != thread->readMiscReg(MISCREG_FSR)) {
+ if(shared_data->fsr != thread->readMiscRegNoEffect(MISCREG_FSR)) {
diffFsr = true;
if (mbits(shared_data->fsr, 63,10) ==
- mbits(thread->readMiscReg(MISCREG_FSR), 63,10)) {
- thread->setMiscReg(MISCREG_FSR, shared_data->fsr);
+ mbits(thread->readMiscRegNoEffect(MISCREG_FSR), 63,10)) {
+ thread->setMiscRegNoEffect(MISCREG_FSR, shared_data->fsr);
diffFsr = false;
}
}
- //if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR))
+ //if(shared_data->ccr != thread->readMiscRegNoEffect(MISCREG_CCR))
if(shared_data->ccr !=
thread->readIntReg(NumIntArchRegs + 2))
diffCcr = true;
- if(shared_data->gl != thread->readMiscReg(MISCREG_GL))
+ if(shared_data->gl != thread->readMiscRegNoEffect(MISCREG_GL))
diffGl = true;
- if(shared_data->asi != thread->readMiscReg(MISCREG_ASI))
+ if(shared_data->asi != thread->readMiscRegNoEffect(MISCREG_ASI))
diffAsi = true;
- if(shared_data->pil != thread->readMiscReg(MISCREG_PIL))
+ if(shared_data->pil != thread->readMiscRegNoEffect(MISCREG_PIL))
diffPil = true;
- if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP))
+ if(shared_data->cwp != thread->readMiscRegNoEffect(MISCREG_CWP))
diffCwp = true;
- //if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE))
+ //if(shared_data->cansave != thread->readMiscRegNoEffect(MISCREG_CANSAVE))
if(shared_data->cansave !=
thread->readIntReg(NumIntArchRegs + 3))
diffCansave = true;
//if(shared_data->canrestore !=
- // thread->readMiscReg(MISCREG_CANRESTORE))
+ // thread->readMiscRegNoEffect(MISCREG_CANRESTORE))
if(shared_data->canrestore !=
thread->readIntReg(NumIntArchRegs + 4))
diffCanrestore = true;
- //if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN))
+ //if(shared_data->otherwin != thread->readMiscRegNoEffect(MISCREG_OTHERWIN))
if(shared_data->otherwin !=
thread->readIntReg(NumIntArchRegs + 6))
diffOtherwin = true;
- //if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN))
+ //if(shared_data->cleanwin != thread->readMiscRegNoEffect(MISCREG_CLEANWIN))
if(shared_data->cleanwin !=
thread->readIntReg(NumIntArchRegs + 5))
diffCleanwin = true;
@@ -539,9 +649,13 @@ Trace::InstRecord::dump(ostream &outs)
<< staticInst->disassemble(m5Pc, debugSymbolTable)
<< endl;
+ predecoder.setTC(thread);
+ predecoder.moreBytes(m5Pc, 0, shared_data->instruction);
+
+ assert(predecoder.extMachInstRead());
+
StaticInstPtr legionInst =
- StaticInst::decode(makeExtMI(shared_data->instruction,
- thread));
+ StaticInst::decode(predecoder.getExtMachInst());
outs << setfill(' ') << setw(15)
<< " Legion Inst: "
<< "0x" << setw(8) << setfill('0') << hex
@@ -552,78 +666,78 @@ Trace::InstRecord::dump(ostream &outs)
printSectionHeader(outs, "General State");
printColumnLabels(outs);
printRegPair(outs, "HPstate",
- thread->readMiscReg(MISCREG_HPSTATE),
+ thread->readMiscRegNoEffect(MISCREG_HPSTATE),
shared_data->hpstate | (1 << 11));
printRegPair(outs, "Htba",
- thread->readMiscReg(MISCREG_HTBA),
+ thread->readMiscRegNoEffect(MISCREG_HTBA),
shared_data->htba);
printRegPair(outs, "Pstate",
- thread->readMiscReg(MISCREG_PSTATE),
+ thread->readMiscRegNoEffect(MISCREG_PSTATE),
shared_data->pstate);
printRegPair(outs, "Y",
- //thread->readMiscReg(MISCREG_Y),
+ //thread->readMiscRegNoEffect(MISCREG_Y),
thread->readIntReg(NumIntArchRegs + 1),
shared_data->y);
printRegPair(outs, "FSR",
- thread->readMiscReg(MISCREG_FSR),
+ thread->readMiscRegNoEffect(MISCREG_FSR),
shared_data->fsr);
printRegPair(outs, "Ccr",
- //thread->readMiscReg(MISCREG_CCR),
+ //thread->readMiscRegNoEffect(MISCREG_CCR),
thread->readIntReg(NumIntArchRegs + 2),
shared_data->ccr);
printRegPair(outs, "Tl",
- thread->readMiscReg(MISCREG_TL),
+ thread->readMiscRegNoEffect(MISCREG_TL),
shared_data->tl);
printRegPair(outs, "Gl",
- thread->readMiscReg(MISCREG_GL),
+ thread->readMiscRegNoEffect(MISCREG_GL),
shared_data->gl);
printRegPair(outs, "Asi",
- thread->readMiscReg(MISCREG_ASI),
+ thread->readMiscRegNoEffect(MISCREG_ASI),
shared_data->asi);
printRegPair(outs, "Pil",
- thread->readMiscReg(MISCREG_PIL),
+ thread->readMiscRegNoEffect(MISCREG_PIL),
shared_data->pil);
printRegPair(outs, "Cwp",
- thread->readMiscReg(MISCREG_CWP),
+ thread->readMiscRegNoEffect(MISCREG_CWP),
shared_data->cwp);
printRegPair(outs, "Cansave",
- //thread->readMiscReg(MISCREG_CANSAVE),
+ //thread->readMiscRegNoEffect(MISCREG_CANSAVE),
thread->readIntReg(NumIntArchRegs + 3),
shared_data->cansave);
printRegPair(outs, "Canrestore",
- //thread->readMiscReg(MISCREG_CANRESTORE),
+ //thread->readMiscRegNoEffect(MISCREG_CANRESTORE),
thread->readIntReg(NumIntArchRegs + 4),
shared_data->canrestore);
printRegPair(outs, "Otherwin",
- //thread->readMiscReg(MISCREG_OTHERWIN),
+ //thread->readMiscRegNoEffect(MISCREG_OTHERWIN),
thread->readIntReg(NumIntArchRegs + 6),
shared_data->otherwin);
printRegPair(outs, "Cleanwin",
- //thread->readMiscReg(MISCREG_CLEANWIN),
+ //thread->readMiscRegNoEffect(MISCREG_CLEANWIN),
thread->readIntReg(NumIntArchRegs + 5),
shared_data->cleanwin);
outs << endl;
for (int i = 1; i <= MaxTL; i++) {
printLevelHeader(outs, i);
printColumnLabels(outs);
- thread->setMiscReg(MISCREG_TL, i);
+ thread->setMiscRegNoEffect(MISCREG_TL, i);
printRegPair(outs, "Tpc",
- thread->readMiscReg(MISCREG_TPC),
+ thread->readMiscRegNoEffect(MISCREG_TPC),
shared_data->tpc[i-1]);
printRegPair(outs, "Tnpc",
- thread->readMiscReg(MISCREG_TNPC),
+ thread->readMiscRegNoEffect(MISCREG_TNPC),
shared_data->tnpc[i-1]);
printRegPair(outs, "Tstate",
- thread->readMiscReg(MISCREG_TSTATE),
+ thread->readMiscRegNoEffect(MISCREG_TSTATE),
shared_data->tstate[i-1]);
printRegPair(outs, "Tt",
- thread->readMiscReg(MISCREG_TT),
+ thread->readMiscRegNoEffect(MISCREG_TT),
shared_data->tt[i-1]);
printRegPair(outs, "Htstate",
- thread->readMiscReg(MISCREG_HTSTATE),
+ thread->readMiscRegNoEffect(MISCREG_HTSTATE),
shared_data->htstate[i-1]);
}
- thread->setMiscReg(MISCREG_TL, oldTl);
+ thread->setMiscRegNoEffect(MISCREG_TL, oldTl);
outs << endl;
printSectionHeader(outs, "General Purpose Registers");
@@ -684,110 +798,4 @@ Trace::InstRecord::dump(ostream &outs)
#endif
}
-
-vector<bool> Trace::InstRecord::flags(NUM_BITS);
-string Trace::InstRecord::trace_system;
-
-////////////////////////////////////////////////////////////////////////
-//
-// Parameter space for per-cycle execution address tracing options.
-// Derive from ParamContext so we can override checkParams() function.
-//
-class ExecutionTraceParamContext : public ParamContext
-{
- public:
- ExecutionTraceParamContext(const string &_iniSection)
- : ParamContext(_iniSection)
- {
- }
-
- void checkParams(); // defined at bottom of file
-};
-
-ExecutionTraceParamContext exeTraceParams("exetrace");
-
-Param<bool> exe_trace_spec(&exeTraceParams, "speculative",
- "capture speculative instructions", true);
-
-Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle",
- "print cycle number", true);
-Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass",
- "print op class", true);
-Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread",
- "print thread number", true);
-Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr",
- "print effective address", true);
-Param<bool> exe_trace_print_data(&exeTraceParams, "print_data",
- "print result data", true);
-Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs",
- "print all integer regs", false);
-Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq",
- "print fetch sequence number", false);
-Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq",
- "print correct-path sequence number", false);
-Param<bool> exe_trace_print_reg_delta(&exeTraceParams, "print_reg_delta",
- "print which registers changed to what", false);
-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");
-
-
-//
-// Helper function for ExecutionTraceParamContext::checkParams() just
-// to get us into the InstRecord namespace
-//
-void
-Trace::InstRecord::setParams()
-{
- flags[TRACE_MISSPEC] = exe_trace_spec;
-
- flags[PRINT_CYCLE] = exe_trace_print_cycle;
- flags[PRINT_OP_CLASS] = exe_trace_print_opclass;
- flags[PRINT_THREAD_NUM] = exe_trace_print_thread;
- flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr;
- flags[PRINT_EFF_ADDR] = exe_trace_print_data;
- flags[PRINT_INT_REGS] = exe_trace_print_iregs;
- flags[PRINT_FETCH_SEQ] = exe_trace_print_fetchseq;
- flags[PRINT_CP_SEQ] = exe_trace_print_cp_seq;
- 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('M' << 24 | 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);
-
- // step legion forward one cycle so we can get register values
- shared_data->flags = OWN_LEGION;
- }
-}
-
-void
-ExecutionTraceParamContext::checkParams()
-{
- Trace::InstRecord::setParams();
-}
-
+/* namespace Trace */ }
diff --git a/src/cpu/exetrace.hh b/src/cpu/exetrace.hh
index a825f6a82..8c0fa22cb 100644
--- a/src/cpu/exetrace.hh
+++ b/src/cpu/exetrace.hh
@@ -36,22 +36,24 @@
#include <fstream>
#include <vector>
-#include "sim/host.hh"
-#include "cpu/inst_seq.hh" // for InstSeqNum
#include "base/trace.hh"
-#include "cpu/thread_context.hh"
+#include "cpu/inst_seq.hh" // for InstSeqNum
#include "cpu/static_inst.hh"
+#include "cpu/thread_context.hh"
+#include "sim/host.hh"
class ThreadContext;
namespace Trace {
-class InstRecord : public Record
+class InstRecord
{
protected:
typedef TheISA::IntRegFile IntRegFile;
+ Tick when;
+
// The following fields are initialized by the constructor and
// thus guaranteed to be valid.
ThreadContext *thread;
@@ -95,10 +97,10 @@ class InstRecord : public Record
bool regs_valid;
public:
- InstRecord(Tick _cycle, ThreadContext *_thread,
+ InstRecord(Tick _when, ThreadContext *_thread,
const StaticInstPtr &_staticInst,
Addr _pc, bool spec)
- : Record(_cycle), thread(_thread),
+ : when(_when), thread(_thread),
staticInst(_staticInst), PC(_pc),
misspeculating(spec)
{
@@ -110,12 +112,12 @@ class InstRecord : public Record
cp_seq_valid = false;
}
- virtual ~InstRecord() { }
-
- virtual void dump(std::ostream &outs);
+ ~InstRecord() { }
void setAddr(Addr a) { addr = a; addr_valid = true; }
+ void setData(Twin64_t d) { data.as_int = d.a; data_status = DataInt64; }
+ void setData(Twin32_t d) { data.as_int = d.a; data_status = DataInt32; }
void setData(uint64_t d) { data.as_int = d; data_status = DataInt64; }
void setData(uint32_t d) { data.as_int = d; data_status = DataInt32; }
void setData(uint16_t d) { data.as_int = d; data_status = DataInt16; }
@@ -136,31 +138,7 @@ class InstRecord : public Record
void setRegs(const IntRegFile &regs);
- void finalize() { theLog.append(this); }
-
- enum InstExecFlagBits {
- TRACE_MISSPEC = 0,
- PRINT_CYCLE,
- PRINT_OP_CLASS,
- PRINT_THREAD_NUM,
- PRINT_RESULT_DATA,
- PRINT_EFF_ADDR,
- PRINT_INT_REGS,
- PRINT_FETCH_SEQ,
- PRINT_CP_SEQ,
- PRINT_REG_DELTA,
- PC_SYMBOL,
- INTEL_FORMAT,
- LEGION_LOCKSTEP,
- NUM_BITS
- };
-
- static std::vector<bool> flags;
- static std::string trace_system;
-
- static void setParams();
-
- static bool traceMisspec() { return flags[TRACE_MISSPEC]; }
+ void dump();
};
@@ -174,22 +152,22 @@ InstRecord::setRegs(const IntRegFile &regs)
regs_valid = true;
}
-inline
-InstRecord *
-getInstRecord(Tick cycle, ThreadContext *tc,
- const StaticInstPtr staticInst,
+inline InstRecord *
+getInstRecord(Tick when, ThreadContext *tc, const StaticInstPtr staticInst,
Addr pc)
{
- if (DTRACE(InstExec) &&
- (InstRecord::traceMisspec() || !tc->misspeculating())) {
- return new InstRecord(cycle, tc, staticInst, pc,
- tc->misspeculating());
- }
+ if (!IsOn(ExecEnable))
+ return NULL;
- return NULL;
-}
+ if (!Trace::enabled)
+ return NULL;
+ if (!IsOn(ExecSpeculative) && tc->misspeculating())
+ return NULL;
+ return new InstRecord(when, tc, staticInst, pc, tc->misspeculating());
}
+/* namespace Trace */ }
+
#endif // __EXETRACE_HH__
diff --git a/src/cpu/intr_control.cc b/src/cpu/intr_control.cc
index 4cbc86891..be0f6599b 100644
--- a/src/cpu/intr_control.cc
+++ b/src/cpu/intr_control.cc
@@ -40,18 +40,14 @@
using namespace std;
-IntrControl::IntrControl(const string &name, BaseCPU *c)
- : SimObject(name), cpu(c)
+IntrControl::IntrControl(const string &name, System *s)
+ : SimObject(name), sys(s)
{}
-/* @todo
- *Fix the cpu sim object parameter to be a system pointer
- *instead, to avoid some extra dereferencing
- */
void
IntrControl::post(int int_num, int index)
{
- std::vector<ThreadContext *> &tcvec = cpu->system->threadContexts;
+ std::vector<ThreadContext *> &tcvec = sys->threadContexts;
BaseCPU *temp = tcvec[0]->getCpuPtr();
temp->post_interrupt(int_num, index);
}
@@ -59,7 +55,7 @@ IntrControl::post(int int_num, int index)
void
IntrControl::post(int cpu_id, int int_num, int index)
{
- std::vector<ThreadContext *> &tcvec = cpu->system->threadContexts;
+ std::vector<ThreadContext *> &tcvec = sys->threadContexts;
BaseCPU *temp = tcvec[cpu_id]->getCpuPtr();
temp->post_interrupt(int_num, index);
}
@@ -67,7 +63,7 @@ IntrControl::post(int cpu_id, int int_num, int index)
void
IntrControl::clear(int int_num, int index)
{
- std::vector<ThreadContext *> &tcvec = cpu->system->threadContexts;
+ std::vector<ThreadContext *> &tcvec = sys->threadContexts;
BaseCPU *temp = tcvec[0]->getCpuPtr();
temp->clear_interrupt(int_num, index);
}
@@ -75,26 +71,26 @@ IntrControl::clear(int int_num, int index)
void
IntrControl::clear(int cpu_id, int int_num, int index)
{
- std::vector<ThreadContext *> &tcvec = cpu->system->threadContexts;
+ std::vector<ThreadContext *> &tcvec = sys->threadContexts;
BaseCPU *temp = tcvec[cpu_id]->getCpuPtr();
temp->clear_interrupt(int_num, index);
}
BEGIN_DECLARE_SIM_OBJECT_PARAMS(IntrControl)
- SimObjectParam<BaseCPU *> cpu;
+ SimObjectParam<System *> sys;
END_DECLARE_SIM_OBJECT_PARAMS(IntrControl)
BEGIN_INIT_SIM_OBJECT_PARAMS(IntrControl)
- INIT_PARAM(cpu, "the cpu")
+ INIT_PARAM(sys, "the system we are part of")
END_INIT_SIM_OBJECT_PARAMS(IntrControl)
CREATE_SIM_OBJECT(IntrControl)
{
- return new IntrControl(getInstanceName(), cpu);
+ return new IntrControl(getInstanceName(), sys);
}
REGISTER_SIM_OBJECT("IntrControl", IntrControl)
diff --git a/src/cpu/intr_control.hh b/src/cpu/intr_control.hh
index 2e3f9e038..c6f75abf0 100644
--- a/src/cpu/intr_control.hh
+++ b/src/cpu/intr_control.hh
@@ -42,8 +42,8 @@
class IntrControl : public SimObject
{
public:
- BaseCPU *cpu;
- IntrControl(const std::string &name, BaseCPU *c);
+ System *sys;
+ IntrControl(const std::string &name, System *s);
void clear(int int_num, int index = 0);
void post(int int_num, int index = 0);
diff --git a/src/cpu/memtest/SConscript b/src/cpu/memtest/SConscript
new file mode 100644
index 000000000..7b4d6d2c5
--- /dev/null
+++ b/src/cpu/memtest/SConscript
@@ -0,0 +1,34 @@
+# -*- 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: Nathan Binkert
+
+Import('*')
+
+if 'O3CPU' in env['CPU_MODELS']:
+ Source('memtest.cc')
diff --git a/src/cpu/memtest/memtest.cc b/src/cpu/memtest/memtest.cc
index 180f41541..607cf1066 100644
--- a/src/cpu/memtest/memtest.cc
+++ b/src/cpu/memtest/memtest.cc
@@ -226,8 +226,8 @@ MemTest::completeRequest(PacketPtr pkt)
assert(removeAddr != outstandingAddrs.end());
outstandingAddrs.erase(removeAddr);
- switch (pkt->cmd) {
- case Packet::ReadResp:
+ switch (pkt->cmd.toInt()) {
+ case MemCmd::ReadResp:
if (memcmp(pkt_data, data, pkt->getSize()) != 0) {
cerr << name() << ": on read of 0x" << hex << req->getPaddr()
@@ -254,7 +254,7 @@ MemTest::completeRequest(PacketPtr pkt)
exitSimLoop("Maximum number of loads reached!");
break;
- case Packet::WriteResp:
+ case MemCmd::WriteResp:
numWritesStat++;
break;
/*
@@ -369,7 +369,7 @@ MemTest::tick()
//This means we assume CPU does write forwarding to reads that alias something
//in the cpu store buffer.
if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) {
- delete result;
+ delete [] result;
delete req;
return;
}
@@ -389,7 +389,7 @@ MemTest::tick()
<< dec << curTick << endl;
}
- PacketPtr pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
+ PacketPtr pkt = new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
pkt->dataDynamicArray(new uint8_t[req->getSize()]);
MemTestSenderState *state = new MemTestSenderState(result);
pkt->senderState = state;
@@ -429,7 +429,7 @@ MemTest::tick()
<< dec << curTick << endl;
}
*/
- PacketPtr pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
+ PacketPtr pkt = new Packet(req, MemCmd::WriteReq, Packet::Broadcast);
uint8_t *pkt_data = new uint8_t[req->getSize()];
pkt->dataDynamicArray(pkt_data);
memcpy(pkt_data, &data, req->getSize());
diff --git a/src/cpu/o3/SConscript b/src/cpu/o3/SConscript
index afbd4c533..bb1dfb613 100755
--- a/src/cpu/o3/SConscript
+++ b/src/cpu/o3/SConscript
@@ -26,52 +26,56 @@
# (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: Korey Sewell
+# Authors: Nathan Binkert
-import os
-import os.path
import sys
-# Import build environment variable from SConstruct.
-Import('env')
+Import('*')
+if 'O3CPU' in env['CPU_MODELS']:
+ Source('base_dyn_inst.cc')
+ Source('bpred_unit.cc')
+ Source('commit.cc')
+ Source('cpu.cc')
+ Source('decode.cc')
+ Source('fetch.cc')
+ Source('free_list.cc')
+ Source('fu_pool.cc')
+ Source('iew.cc')
+ Source('inst_queue.cc')
+ Source('lsq.cc')
+ Source('lsq_unit.cc')
+ Source('mem_dep_unit.cc')
+ Source('rename.cc')
+ Source('rename_map.cc')
+ Source('rob.cc')
+ Source('scoreboard.cc')
+ Source('store_set.cc')
-#################################################################
-#
-# Include ISA-specific files for the O3 CPU-model
-#
-#################################################################
-
-sources = []
-
-if env['TARGET_ISA'] == 'alpha':
- sources += Split('''
- alpha/dyn_inst.cc
- alpha/cpu.cc
- alpha/thread_context.cc
- alpha/cpu_builder.cc
- ''')
-elif env['TARGET_ISA'] == 'mips':
- sources += Split('''
- mips/dyn_inst.cc
- mips/cpu.cc
- mips/thread_context.cc
- mips/cpu_builder.cc
- ''')
-elif env['TARGET_ISA'] == 'sparc':
- sources += Split('''
- sparc/dyn_inst.cc
- sparc/cpu.cc
- sparc/thread_context.cc
- sparc/cpu_builder.cc
- ''')
-else:
- sys.exit('O3 CPU does not support the \'%s\' ISA' % env['TARGET_ISA'])
-
+ if env['TARGET_ISA'] == 'alpha':
+ Source('alpha/cpu.cc')
+ Source('alpha/cpu_builder.cc')
+ Source('alpha/dyn_inst.cc')
+ Source('alpha/thread_context.cc')
+ elif env['TARGET_ISA'] == 'mips':
+ Source('mips/cpu.cc')
+ Source('mips/cpu_builder.cc')
+ Source('mips/dyn_inst.cc')
+ Source('mips/thread_context.cc')
+ elif env['TARGET_ISA'] == 'sparc':
+ Source('sparc/cpu.cc')
+ Source('sparc/cpu_builder.cc')
+ Source('sparc/dyn_inst.cc')
+ Source('sparc/thread_context.cc')
+ else:
+ sys.exit('O3 CPU does not support the \'%s\' ISA' % env['TARGET_ISA'])
-# 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]
+ if env['USE_CHECKER']:
+ Source('checker_builder.cc')
-Return('sources')
+if 'O3CPU' in env['CPU_MODELS'] or 'OzoneCPU' in env['CPU_MODELS']:
+ Source('2bit_local_pred.cc')
+ Source('btb.cc')
+ Source('ras.cc')
+ Source('tournament_pred.cc')
diff --git a/src/cpu/o3/SConsopts b/src/cpu/o3/SConsopts
new file mode 100644
index 000000000..040352e6a
--- /dev/null
+++ b/src/cpu/o3/SConsopts
@@ -0,0 +1,34 @@
+# -*- 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: Nathan Binkert
+
+Import('*')
+
+all_cpu_list.append('O3CPU')
+default_cpus.append('O3CPU')
diff --git a/src/cpu/o3/alpha/cpu.hh b/src/cpu/o3/alpha/cpu.hh
index 4a2086296..676893098 100644
--- a/src/cpu/o3/alpha/cpu.hh
+++ b/src/cpu/o3/alpha/cpu.hh
@@ -106,21 +106,21 @@ class AlphaO3CPU : public FullO3CPU<Impl>
#endif
/** Reads a miscellaneous register. */
- TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid);
/** Reads a misc. register, including any side effects the read
* might have as defined by the architecture.
*/
- TheISA::MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
/** Sets a miscellaneous register. */
- void setMiscReg(int misc_reg, const TheISA::MiscReg &val,
+ void setMiscRegNoEffect(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.
*/
- void setMiscRegWithEffect(int misc_reg, const TheISA::MiscReg &val,
+ void setMiscReg(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/alpha/cpu_impl.hh b/src/cpu/o3/alpha/cpu_impl.hh
index 7799d8f05..304ee6c38 100644
--- a/src/cpu/o3/alpha/cpu_impl.hh
+++ b/src/cpu/o3/alpha/cpu_impl.hh
@@ -155,32 +155,32 @@ AlphaO3CPU<Impl>::regStats()
template <class Impl>
TheISA::MiscReg
-AlphaO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
+AlphaO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, unsigned tid)
{
- return this->regFile.readMiscReg(misc_reg, tid);
+ return this->regFile.readMiscRegNoEffect(misc_reg, tid);
}
template <class Impl>
TheISA::MiscReg
-AlphaO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, unsigned tid)
+AlphaO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
{
- return this->regFile.readMiscRegWithEffect(misc_reg, tid);
+ return this->regFile.readMiscReg(misc_reg, tid);
}
template <class Impl>
void
-AlphaO3CPU<Impl>::setMiscReg(int misc_reg, const TheISA::MiscReg &val,
+AlphaO3CPU<Impl>::setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val,
unsigned tid)
{
- this->regFile.setMiscReg(misc_reg, val, tid);
+ this->regFile.setMiscRegNoEffect(misc_reg, val, tid);
}
template <class Impl>
void
-AlphaO3CPU<Impl>::setMiscRegWithEffect(int misc_reg,
+AlphaO3CPU<Impl>::setMiscReg(int misc_reg,
const TheISA::MiscReg &val, unsigned tid)
{
- this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
+ this->regFile.setMiscReg(misc_reg, val, tid);
}
template <class Impl>
@@ -210,7 +210,7 @@ Fault
AlphaO3CPU<Impl>::hwrei(unsigned tid)
{
// Need to clear the lock flag upon returning from an interrupt.
- this->setMiscReg(AlphaISA::MISCREG_LOCKFLAG, false, tid);
+ this->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG, false, tid);
this->thread[tid]->kernelStats->hwrei();
diff --git a/src/cpu/o3/alpha/dyn_inst.hh b/src/cpu/o3/alpha/dyn_inst.hh
index 603a1b52d..20759d849 100644
--- a/src/cpu/o3/alpha/dyn_inst.hh
+++ b/src/cpu/o3/alpha/dyn_inst.hh
@@ -95,39 +95,39 @@ class AlphaDynInst : public BaseDynInst<Impl>
public:
/** Reads a miscellaneous register. */
- MiscReg readMiscReg(int misc_reg)
+ MiscReg readMiscRegNoEffect(int misc_reg)
{
- return this->cpu->readMiscReg(misc_reg, this->threadNumber);
+ return this->cpu->readMiscRegNoEffect(misc_reg, this->threadNumber);
}
/** Reads a misc. register, including any side-effects the read
* might have as defined by the architecture.
*/
- MiscReg readMiscRegWithEffect(int misc_reg)
+ MiscReg readMiscReg(int misc_reg)
{
- return this->cpu->readMiscRegWithEffect(misc_reg, this->threadNumber);
+ return this->cpu->readMiscReg(misc_reg, this->threadNumber);
}
/** Sets a misc. register. */
- void setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
this->instResult.integer = val;
- return this->cpu->setMiscReg(misc_reg, val, this->threadNumber);
+ return this->cpu->setMiscRegNoEffect(misc_reg, val, this->threadNumber);
}
/** Sets a misc. register, including any side-effects the write
* might have as defined by the architecture.
*/
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{
- return this->cpu->setMiscRegWithEffect(misc_reg, val,
+ return this->cpu->setMiscReg(misc_reg, val,
this->threadNumber);
}
/** Reads a miscellaneous register. */
- TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
+ TheISA::MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx)
{
- return this->cpu->readMiscReg(
+ return this->cpu->readMiscRegNoEffect(
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
this->threadNumber);
}
@@ -135,18 +135,18 @@ class AlphaDynInst : public BaseDynInst<Impl>
/** Reads a misc. register, including any side-effects the read
* might have as defined by the architecture.
*/
- TheISA::MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx)
+ TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
{
- return this->cpu->readMiscRegWithEffect(
+ return this->cpu->readMiscReg(
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
this->threadNumber);
}
/** Sets a misc. register. */
- void setMiscRegOperand(const StaticInst * si, int idx, const MiscReg &val)
+ void setMiscRegOperandNoEffect(const StaticInst * si, int idx, const MiscReg &val)
{
this->instResult.integer = val;
- return this->cpu->setMiscReg(
+ return this->cpu->setMiscRegNoEffect(
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
val, this->threadNumber);
}
@@ -154,10 +154,10 @@ class AlphaDynInst : public BaseDynInst<Impl>
/** Sets a misc. register, including any side-effects the write
* might have as defined by the architecture.
*/
- void setMiscRegOperandWithEffect(const StaticInst *si, int idx,
+ void setMiscRegOperand(const StaticInst *si, int idx,
const MiscReg &val)
{
- return this->cpu->setMiscRegWithEffect(
+ return this->cpu->setMiscReg(
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
val, this->threadNumber);
}
diff --git a/src/cpu/o3/alpha/dyn_inst_impl.hh b/src/cpu/o3/alpha/dyn_inst_impl.hh
index 50cdec408..fdce1ade5 100644
--- a/src/cpu/o3/alpha/dyn_inst_impl.hh
+++ b/src/cpu/o3/alpha/dyn_inst_impl.hh
@@ -118,7 +118,7 @@ AlphaDynInst<Impl>::hwrei()
return new AlphaISA::UnimplementedOpcodeFault;
// Set the next PC based on the value of the EXC_ADDR IPR.
- this->setNextPC(this->cpu->readMiscReg(AlphaISA::IPR_EXC_ADDR,
+ this->setNextPC(this->cpu->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR,
this->threadNumber));
// Tell CPU to clear any state it needs to if a hwrei is taken.
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index b42a6f523..c17c8836d 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -1148,7 +1148,8 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
if (head_inst->traceData) {
head_inst->traceData->setFetchSeq(head_inst->seqNum);
head_inst->traceData->setCPSeq(thread[tid]->numInst);
- head_inst->traceData->finalize();
+ head_inst->traceData->dump();
+ delete head_inst->traceData;
head_inst->traceData = NULL;
}
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index f9e094d75..354e3c490 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -45,7 +45,7 @@
#include "cpu/o3/isa_specific.hh"
#include "cpu/o3/cpu.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
#include "sim/stat_control.hh"
#if USE_CHECKER
@@ -557,12 +557,6 @@ template <class Impl>
void
FullO3CPU<Impl>::activateContext(int tid, int delay)
{
-#if FULL_SYSTEM
- // Connect the ThreadContext's memory ports (Functional/Virtual
- // Ports)
- threadContexts[tid]->connectMemPorts();
-#endif
-
// Needs to set each stage to running as well.
if (delay){
DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to activate "
@@ -781,6 +775,18 @@ FullO3CPU<Impl>::activateWhenReady(int tid)
}
}
+#if FULL_SYSTEM
+template <class Impl>
+void
+FullO3CPU<Impl>::updateMemPorts()
+{
+ // Update all ThreadContext's memory ports (Functional/Virtual
+ // Ports)
+ for (int i = 0; i < thread.size(); ++i)
+ thread[i]->connectMemPorts();
+}
+#endif
+
template <class Impl>
void
FullO3CPU<Impl>::serialize(std::ostream &os)
@@ -941,7 +947,7 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
activityRec.reset();
- BaseCPU::takeOverFrom(oldCPU);
+ BaseCPU::takeOverFrom(oldCPU, fetch.getIcachePort(), iew.getDcachePort());
fetch.takeOverFrom();
decode.takeOverFrom();
@@ -978,25 +984,6 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
}
if (!tickEvent.scheduled())
tickEvent.schedule(nextCycle());
-
- Port *peer;
- Port *icachePort = fetch.getIcachePort();
- if (icachePort->getPeer() == NULL) {
- peer = oldCPU->getPort("icache_port")->getPeer();
- icachePort->setPeer(peer);
- } else {
- peer = icachePort->getPeer();
- }
- peer->setPeer(icachePort);
-
- Port *dcachePort = iew.getDcachePort();
- if (dcachePort->getPeer() == NULL) {
- peer = oldCPU->getPort("dcache_port")->getPeer();
- dcachePort->setPeer(peer);
- } else {
- peer = dcachePort->getPeer();
- }
- peer->setPeer(dcachePort);
}
template <class Impl>
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index b47c2a494..0ab20ba2a 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -361,6 +361,10 @@ class FullO3CPU : public BaseO3CPU
{ return globalSeqNum++; }
#if FULL_SYSTEM
+ /** Update the Virt and Phys ports of all ThreadContexts to
+ * reflect change in memory connections. */
+ void updateMemPorts();
+
/** Check if this address is a valid instruction address. */
bool validInstAddr(Addr addr) { return true; }
diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh
index 279513493..c37f8007e 100644
--- a/src/cpu/o3/dyn_inst.hh
+++ b/src/cpu/o3/dyn_inst.hh
@@ -45,6 +45,10 @@
template <class Impl> class SparcDynInst;
struct SparcSimpleImpl;
typedef SparcDynInst<SparcSimpleImpl> O3DynInst;
+#elif THE_ISA == X86_ISA
+ template <class Impl> class X86DynInst;
+ struct X86SimpleImpl;
+ typedef X86DynInst<X86SimpleImpl> O3DynInst;
#else
#error "O3DynInst not defined for this ISA"
#endif
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index 8347ed775..da7ce00f5 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -33,6 +33,7 @@
#define __CPU_O3_FETCH_HH__
#include "arch/utility.hh"
+#include "arch/predecoder.hh"
#include "base/statistics.hh"
#include "base/timebuf.hh"
#include "cpu/pc_event.hh"
@@ -338,6 +339,9 @@ class DefaultFetch
/** BPredUnit. */
BPredUnit branchPred;
+ /** Predecoder. */
+ TheISA::Predecoder predecoder;
+
/** Per-thread fetch PC. */
Addr PC[Impl::MaxThreads];
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index a8727a425..663cd3142 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -40,7 +40,7 @@
#include "mem/request.hh"
#include "sim/byteswap.hh"
#include "sim/host.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
#if FULL_SYSTEM
#include "arch/tlb.hh"
@@ -103,6 +103,7 @@ DefaultFetch<Impl>::IcachePort::recvRetry()
template<class Impl>
DefaultFetch<Impl>::DefaultFetch(Params *params)
: branchPred(params),
+ predecoder(NULL),
decodeToFetchDelay(params->decodeToFetchDelay),
renameToFetchDelay(params->renameToFetchDelay),
iewToFetchDelay(params->iewToFetchDelay),
@@ -602,7 +603,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
// Build packet here.
PacketPtr data_pkt = new Packet(mem_req,
- Packet::ReadReq, Packet::Broadcast);
+ MemCmd::ReadReq, Packet::Broadcast);
data_pkt->dataDynamicArray(new uint8_t[cacheBlkSize]);
cacheDataPC[tid] = block_PC;
@@ -1119,13 +1120,10 @@ DefaultFetch<Impl>::fetch(bool &status_change)
inst = TheISA::gtoh(*reinterpret_cast<TheISA::MachInst *>
(&cacheData[tid][offset]));
-#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());
-#elif THE_ISA == MIPS_ISA
- ext_inst = TheISA::makeExtMI(inst, cpu->thread[tid]->getTC());
-#endif
+ predecoder.setTC(cpu->thread[tid]->getTC());
+ predecoder.moreBytes(fetch_PC, 0, inst);
+
+ ext_inst = predecoder.getExtMachInst();
// Create a new DynInst from the instruction fetched.
DynInstPtr instruction = new DynInst(ext_inst,
diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh
index 87bf60dfa..79e03d4bf 100644
--- a/src/cpu/o3/inst_queue_impl.hh
+++ b/src/cpu/o3/inst_queue_impl.hh
@@ -32,7 +32,7 @@
#include <limits>
#include <vector>
-#include "sim/root.hh"
+#include "sim/core.hh"
#include "cpu/o3/fu_pool.hh"
#include "cpu/o3/inst_queue.hh"
diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh
index e68085cfd..80f53a726 100644
--- a/src/cpu/o3/lsq.hh
+++ b/src/cpu/o3/lsq.hh
@@ -300,6 +300,8 @@ class LSQ {
bool snoopRangeSent;
+ virtual void setPeer(Port *port);
+
protected:
/** Atomic version of receive. Panics. */
virtual Tick recvAtomic(PacketPtr pkt);
@@ -327,6 +329,11 @@ class LSQ {
/** D-cache port. */
DcachePort dcachePort;
+#if FULL_SYSTEM
+ /** Tell the CPU to update the Phys and Virt ports. */
+ void updateMemPorts() { cpu->updateMemPorts(); }
+#endif
+
protected:
/** The LSQ policy for SMT mode. */
LSQPolicy lsqPolicy;
diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh
index fb738f7c9..d4994fcb7 100644
--- a/src/cpu/o3/lsq_impl.hh
+++ b/src/cpu/o3/lsq_impl.hh
@@ -34,6 +34,19 @@
#include "cpu/o3/lsq.hh"
+template<class Impl>
+void
+LSQ<Impl>::DcachePort::setPeer(Port *port)
+{
+ Port::setPeer(port);
+
+#if FULL_SYSTEM
+ // Update the ThreadContext's memory ports (Functional/Virtual
+ // Ports)
+ lsq->updateMemPorts();
+#endif
+}
+
template <class Impl>
Tick
LSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh
index 704d2183d..1b10843f5 100644
--- a/src/cpu/o3/lsq_unit.hh
+++ b/src/cpu/o3/lsq_unit.hh
@@ -583,7 +583,8 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
"addr %#x, data %#x\n",
store_idx, req->getVaddr(), data);
- PacketPtr data_pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
+ PacketPtr data_pkt = new Packet(req, MemCmd::ReadReq,
+ Packet::Broadcast);
data_pkt->dataStatic(load_inst->memData);
WritebackEvent *wb = new WritebackEvent(load_inst, data_pkt, this);
@@ -653,7 +654,7 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
// if we the cache is not blocked, do cache access
if (!lsq->cacheBlocked()) {
PacketPtr data_pkt =
- new Packet(req, Packet::ReadReq, Packet::Broadcast);
+ new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
data_pkt->dataStatic(load_inst->memData);
LSQSenderState *state = new LSQSenderState;
diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh
index ed331386b..e70c960b3 100644
--- a/src/cpu/o3/lsq_unit_impl.hh
+++ b/src/cpu/o3/lsq_unit_impl.hh
@@ -656,7 +656,8 @@ LSQUnit<Impl>::writebackStores()
(sizeof(TheISA::IntReg) - req->getSize()) : 0),
req->getSize());
- PacketPtr data_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
+ PacketPtr data_pkt = new Packet(req, MemCmd::WriteReq,
+ Packet::Broadcast);
data_pkt->dataStatic(inst->memData);
LSQSenderState *state = new LSQSenderState;
diff --git a/src/cpu/o3/mips/cpu.hh b/src/cpu/o3/mips/cpu.hh
index 7e6268cdf..0361c1814 100755
--- a/src/cpu/o3/mips/cpu.hh
+++ b/src/cpu/o3/mips/cpu.hh
@@ -87,20 +87,20 @@ class MipsO3CPU : public FullO3CPU<Impl>
}
/** Reads a miscellaneous register. */
- TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid);
/** Reads a misc. register, including any side effects the read
* might have as defined by the architecture.
*/
- TheISA::MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
/** Sets a miscellaneous register. */
- void setMiscReg(int misc_reg, const TheISA::MiscReg &val, unsigned tid);
+ void setMiscRegNoEffect(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.
*/
- void setMiscRegWithEffect(int misc_reg,
+ void setMiscReg(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_impl.hh b/src/cpu/o3/mips/cpu_impl.hh
index e7dbd3aba..317fd748e 100644
--- a/src/cpu/o3/mips/cpu_impl.hh
+++ b/src/cpu/o3/mips/cpu_impl.hh
@@ -135,31 +135,31 @@ MipsO3CPU<Impl>::regStats()
template <class Impl>
MiscReg
-MipsO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
+MipsO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, unsigned tid)
{
- return this->regFile.readMiscReg(misc_reg, tid);
+ return this->regFile.readMiscRegNoEffect(misc_reg, tid);
}
template <class Impl>
MiscReg
-MipsO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, unsigned tid)
+MipsO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
{
- return this->regFile.readMiscRegWithEffect(misc_reg, tid);
+ return this->regFile.readMiscReg(misc_reg, tid);
}
template <class Impl>
void
-MipsO3CPU<Impl>::setMiscReg(int misc_reg, const MiscReg &val, unsigned tid)
+MipsO3CPU<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid)
{
- this->regFile.setMiscReg(misc_reg, val, tid);
+ this->regFile.setMiscRegNoEffect(misc_reg, val, tid);
}
template <class Impl>
void
-MipsO3CPU<Impl>::setMiscRegWithEffect(int misc_reg, const MiscReg &val,
+MipsO3CPU<Impl>::setMiscReg(int misc_reg, const MiscReg &val,
unsigned tid)
{
- this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
+ this->regFile.setMiscReg(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 f53530908..366b4bb23 100755
--- a/src/cpu/o3/mips/dyn_inst.hh
+++ b/src/cpu/o3/mips/dyn_inst.hh
@@ -93,32 +93,32 @@ class MipsDynInst : public BaseDynInst<Impl>
public:
/** Reads a miscellaneous register. */
- MiscReg readMiscReg(int misc_reg)
+ MiscReg readMiscRegNoEffect(int misc_reg)
{
- return this->cpu->readMiscReg(misc_reg, this->threadNumber);
+ return this->cpu->readMiscRegNoEffect(misc_reg, this->threadNumber);
}
/** Reads a misc. register, including any side-effects the read
* might have as defined by the architecture.
*/
- MiscReg readMiscRegWithEffect(int misc_reg)
+ MiscReg readMiscReg(int misc_reg)
{
- return this->cpu->readMiscRegWithEffect(misc_reg, this->threadNumber);
+ return this->cpu->readMiscReg(misc_reg, this->threadNumber);
}
/** Sets a misc. register. */
- void setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
this->instResult.integer = val;
- this->cpu->setMiscReg(misc_reg, val, this->threadNumber);
+ this->cpu->setMiscRegNoEffect(misc_reg, val, this->threadNumber);
}
/** Sets a misc. register, including any side-effects the write
* might have as defined by the architecture.
*/
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{
- return this->cpu->setMiscRegWithEffect(misc_reg, val,
+ return this->cpu->setMiscReg(misc_reg, val,
this->threadNumber);
}
diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh
index 598af123e..c4f8f3a9f 100644
--- a/src/cpu/o3/regfile.hh
+++ b/src/cpu/o3/regfile.hh
@@ -225,26 +225,26 @@ class PhysRegFile
floatRegFile[reg_idx].q = val;
}
- MiscReg readMiscReg(int misc_reg, unsigned thread_id)
+ MiscReg readMiscRegNoEffect(int misc_reg, unsigned thread_id)
{
- return miscRegs[thread_id].readReg(misc_reg);
+ return miscRegs[thread_id].readRegNoEffect(misc_reg);
}
- MiscReg readMiscRegWithEffect(int misc_reg, unsigned thread_id)
+ MiscReg readMiscReg(int misc_reg, unsigned thread_id)
{
- return miscRegs[thread_id].readRegWithEffect(misc_reg,
+ return miscRegs[thread_id].readReg(misc_reg,
cpu->tcBase(thread_id));
}
- void setMiscReg(int misc_reg, const MiscReg &val, unsigned thread_id)
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val, unsigned thread_id)
{
- miscRegs[thread_id].setReg(misc_reg, val);
+ miscRegs[thread_id].setRegNoEffect(misc_reg, val);
}
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val,
+ void setMiscReg(int misc_reg, const MiscReg &val,
unsigned thread_id)
{
- miscRegs[thread_id].setRegWithEffect(misc_reg, val,
+ miscRegs[thread_id].setReg(misc_reg, val,
cpu->tcBase(thread_id));
}
diff --git a/src/cpu/o3/sparc/cpu.hh b/src/cpu/o3/sparc/cpu.hh
index 08ebd2710..7b932e429 100644
--- a/src/cpu/o3/sparc/cpu.hh
+++ b/src/cpu/o3/sparc/cpu.hh
@@ -106,20 +106,20 @@ class SparcO3CPU : public FullO3CPU<Impl>
#endif
/** Reads a miscellaneous register. */
- TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid);
/** Reads a misc. register, including any side effects the read
* might have as defined by the architecture.
*/
- TheISA::MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
/** Sets a miscellaneous register. */
- void setMiscReg(int misc_reg, const TheISA::MiscReg &val, unsigned tid);
+ void setMiscRegNoEffect(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.
*/
- void setMiscRegWithEffect(int misc_reg, const TheISA::MiscReg &val,
+ void setMiscReg(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/sparc/cpu_impl.hh b/src/cpu/o3/sparc/cpu_impl.hh
index c039a8fec..a425a8a56 100644
--- a/src/cpu/o3/sparc/cpu_impl.hh
+++ b/src/cpu/o3/sparc/cpu_impl.hh
@@ -153,32 +153,32 @@ SparcO3CPU<Impl>::regStats()
template <class Impl>
TheISA::MiscReg
-SparcO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
+SparcO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, unsigned tid)
{
- return this->regFile.readMiscReg(misc_reg, tid);
+ return this->regFile.readMiscRegNoEffect(misc_reg, tid);
}
template <class Impl>
TheISA::MiscReg
-SparcO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, unsigned tid)
+SparcO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
{
- return this->regFile.readMiscRegWithEffect(misc_reg, tid);
+ return this->regFile.readMiscReg(misc_reg, tid);
}
template <class Impl>
void
-SparcO3CPU<Impl>::setMiscReg(int misc_reg,
+SparcO3CPU<Impl>::setMiscRegNoEffect(int misc_reg,
const SparcISA::MiscReg &val, unsigned tid)
{
- this->regFile.setMiscReg(misc_reg, val, tid);
+ this->regFile.setMiscRegNoEffect(misc_reg, val, tid);
}
template <class Impl>
void
-SparcO3CPU<Impl>::setMiscRegWithEffect(int misc_reg,
+SparcO3CPU<Impl>::setMiscReg(int misc_reg,
const SparcISA::MiscReg &val, unsigned tid)
{
- this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
+ this->regFile.setMiscReg(misc_reg, val, tid);
}
template <class Impl>
diff --git a/src/cpu/o3/sparc/dyn_inst.hh b/src/cpu/o3/sparc/dyn_inst.hh
index 4314488b5..72242b161 100644
--- a/src/cpu/o3/sparc/dyn_inst.hh
+++ b/src/cpu/o3/sparc/dyn_inst.hh
@@ -77,39 +77,39 @@ class SparcDynInst : public BaseDynInst<Impl>
public:
/** Reads a miscellaneous register. */
- TheISA::MiscReg readMiscReg(int misc_reg)
+ TheISA::MiscReg readMiscRegNoEffect(int misc_reg)
{
- return this->cpu->readMiscReg(misc_reg, this->threadNumber);
+ return this->cpu->readMiscRegNoEffect(misc_reg, this->threadNumber);
}
/** Reads a misc. register, including any side-effects the read
* might have as defined by the architecture.
*/
- TheISA::MiscReg readMiscRegWithEffect(int misc_reg)
+ TheISA::MiscReg readMiscReg(int misc_reg)
{
- return this->cpu->readMiscRegWithEffect(misc_reg, this->threadNumber);
+ return this->cpu->readMiscReg(misc_reg, this->threadNumber);
}
/** Sets a misc. register. */
- void setMiscReg(int misc_reg, const TheISA::MiscReg &val)
+ void setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val)
{
this->instResult.integer = val;
- return this->cpu->setMiscReg(misc_reg, val, this->threadNumber);
+ return this->cpu->setMiscRegNoEffect(misc_reg, val, this->threadNumber);
}
/** Sets a misc. register, including any side-effects the write
* might have as defined by the architecture.
*/
- void setMiscRegWithEffect(int misc_reg, const TheISA::MiscReg &val)
+ void setMiscReg(int misc_reg, const TheISA::MiscReg &val)
{
- return this->cpu->setMiscRegWithEffect(misc_reg, val,
+ return this->cpu->setMiscReg(misc_reg, val,
this->threadNumber);
}
/** Reads a miscellaneous register. */
- TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
+ TheISA::MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx)
{
- return this->cpu->readMiscReg(
+ return this->cpu->readMiscRegNoEffect(
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
this->threadNumber);
}
@@ -117,19 +117,19 @@ class SparcDynInst : public BaseDynInst<Impl>
/** Reads a misc. register, including any side-effects the read
* might have as defined by the architecture.
*/
- TheISA::MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx)
+ TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
{
- return this->cpu->readMiscRegWithEffect(
+ return this->cpu->readMiscReg(
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
this->threadNumber);
}
/** Sets a misc. register. */
- void setMiscRegOperand(const StaticInst * si,
+ void setMiscRegOperandNoEffect(const StaticInst * si,
int idx, const TheISA::MiscReg &val)
{
this->instResult.integer = val;
- return this->cpu->setMiscReg(
+ return this->cpu->setMiscRegNoEffect(
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
val, this->threadNumber);
}
@@ -137,10 +137,10 @@ class SparcDynInst : public BaseDynInst<Impl>
/** Sets a misc. register, including any side-effects the write
* might have as defined by the architecture.
*/
- void setMiscRegOperandWithEffect(
+ void setMiscRegOperand(
const StaticInst *si, int idx, const TheISA::MiscReg &val)
{
- return this->cpu->setMiscRegWithEffect(
+ return this->cpu->setMiscReg(
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
val, this->threadNumber);
}
diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh
index 4987d6eb4..93638673b 100755
--- a/src/cpu/o3/thread_context.hh
+++ b/src/cpu/o3/thread_context.hh
@@ -206,20 +206,20 @@ class O3ThreadContext : public ThreadContext
virtual void setNextPC(uint64_t val);
/** Reads a miscellaneous register. */
- virtual MiscReg readMiscReg(int misc_reg)
- { return cpu->readMiscReg(misc_reg, thread->readTid()); }
+ virtual MiscReg readMiscRegNoEffect(int misc_reg)
+ { return cpu->readMiscRegNoEffect(misc_reg, thread->readTid()); }
/** Reads a misc. register, including any side-effects the
* read might have as defined by the architecture. */
- virtual MiscReg readMiscRegWithEffect(int misc_reg)
- { return cpu->readMiscRegWithEffect(misc_reg, thread->readTid()); }
+ virtual MiscReg readMiscReg(int misc_reg)
+ { return cpu->readMiscReg(misc_reg, thread->readTid()); }
/** Sets a misc. register. */
- virtual void setMiscReg(int misc_reg, const MiscReg &val);
+ virtual void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
/** Sets a misc. register, including any side-effects the
* write might have as defined by the architecture. */
- virtual void setMiscRegWithEffect(int misc_reg, const MiscReg &val);
+ virtual void setMiscReg(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 af98fa1f5..a145e046e 100755
--- a/src/cpu/o3/thread_context_impl.hh
+++ b/src/cpu/o3/thread_context_impl.hh
@@ -103,7 +103,7 @@ void
O3ThreadContext<Impl>::delVirtPort(VirtualPort *vp)
{
if (vp != thread->getVirtPort()) {
- delete vp->getPeer();
+ vp->removeConn();
delete vp;
}
}
@@ -442,9 +442,9 @@ O3ThreadContext<Impl>::setNextPC(uint64_t val)
template <class Impl>
void
-O3ThreadContext<Impl>::setMiscReg(int misc_reg, const MiscReg &val)
+O3ThreadContext<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
- cpu->setMiscReg(misc_reg, val, thread->readTid());
+ cpu->setMiscRegNoEffect(misc_reg, val, thread->readTid());
// Squash if we're not already in a state update mode.
if (!thread->trapPending && !thread->inSyscall) {
@@ -454,10 +454,10 @@ O3ThreadContext<Impl>::setMiscReg(int misc_reg, const MiscReg &val)
template <class Impl>
void
-O3ThreadContext<Impl>::setMiscRegWithEffect(int misc_reg,
+O3ThreadContext<Impl>::setMiscReg(int misc_reg,
const MiscReg &val)
{
- cpu->setMiscRegWithEffect(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) {
diff --git a/src/cpu/ozone/SConscript b/src/cpu/ozone/SConscript
new file mode 100644
index 000000000..4a040684a
--- /dev/null
+++ b/src/cpu/ozone/SConscript
@@ -0,0 +1,45 @@
+# -*- 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: Nathan Binkert
+
+Import('*')
+
+if 'OzoneCPU' in env['CPU_MODELS']:
+ need_bp_unit = True
+ Source('base_dyn_inst.cc')
+ Source('bpred_unit.cc')
+ Source('cpu.cc')
+ Source('cpu_builder.cc')
+ Source('dyn_inst.cc')
+ Source('front_end.cc')
+ Source('lw_back_end.cc')
+ Source('lw_lsq.cc')
+ Source('rename_table.cc')
+ if env['USE_CHECKER']:
+ Source('checker_builder.cc')
diff --git a/src/cpu/ozone/SConsopts b/src/cpu/ozone/SConsopts
new file mode 100644
index 000000000..341644dcd
--- /dev/null
+++ b/src/cpu/ozone/SConsopts
@@ -0,0 +1,33 @@
+# -*- 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: Nathan Binkert
+
+Import('*')
+
+all_cpu_list.append('OzoneCPU')
diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh
index baea7a546..2432df55e 100644
--- a/src/cpu/ozone/cpu.hh
+++ b/src/cpu/ozone/cpu.hh
@@ -235,14 +235,14 @@ class OzoneCPU : public BaseCPU
public:
// ISA stuff:
+ MiscReg readMiscRegNoEffect(int misc_reg);
+
MiscReg readMiscReg(int misc_reg);
- MiscReg readMiscRegWithEffect(int misc_reg);
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
void setMiscReg(int misc_reg, const MiscReg &val);
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val);
-
unsigned readStCondFailures()
{ return thread->storeCondFailures; }
diff --git a/src/cpu/ozone/cpu_impl.hh b/src/cpu/ozone/cpu_impl.hh
index a854de8de..d78162243 100644
--- a/src/cpu/ozone/cpu_impl.hh
+++ b/src/cpu/ozone/cpu_impl.hh
@@ -748,7 +748,7 @@ template <class Impl>
void
OzoneCPU<Impl>::OzoneTC::delVirtPort(VirtualPort *vp)
{
- delete vp->getPeer();
+ vp->removeConn();
delete vp;
}
#endif
@@ -1089,24 +1089,24 @@ OzoneCPU<Impl>::OzoneTC::setNextPC(Addr val)
template <class Impl>
TheISA::MiscReg
-OzoneCPU<Impl>::OzoneTC::readMiscReg(int misc_reg)
+OzoneCPU<Impl>::OzoneTC::readMiscRegNoEffect(int misc_reg)
{
- return thread->miscRegFile.readReg(misc_reg);
+ return thread->miscRegFile.readRegNoEffect(misc_reg);
}
template <class Impl>
TheISA::MiscReg
-OzoneCPU<Impl>::OzoneTC::readMiscRegWithEffect(int misc_reg)
+OzoneCPU<Impl>::OzoneTC::readMiscReg(int misc_reg)
{
- return thread->miscRegFile.readRegWithEffect(misc_reg, this);
+ return thread->miscRegFile.readReg(misc_reg, this);
}
template <class Impl>
void
-OzoneCPU<Impl>::OzoneTC::setMiscReg(int misc_reg, const MiscReg &val)
+OzoneCPU<Impl>::OzoneTC::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
// Needs to setup a squash event unless we're in syscall mode
- thread->miscRegFile.setReg(misc_reg, val);
+ thread->miscRegFile.setRegNoEffect(misc_reg, val);
if (!thread->inSyscall) {
cpu->squashFromTC();
@@ -1115,10 +1115,10 @@ OzoneCPU<Impl>::OzoneTC::setMiscReg(int misc_reg, const MiscReg &val)
template <class Impl>
void
-OzoneCPU<Impl>::OzoneTC::setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+OzoneCPU<Impl>::OzoneTC::setMiscReg(int misc_reg, const MiscReg &val)
{
// Needs to setup a squash event unless we're in syscall mode
- thread->miscRegFile.setRegWithEffect(misc_reg, val, this);
+ thread->miscRegFile.setReg(misc_reg, val, this);
if (!thread->inSyscall) {
cpu->squashFromTC();
diff --git a/src/cpu/ozone/dyn_inst.hh b/src/cpu/ozone/dyn_inst.hh
index 88f96b14b..e138cbe13 100644
--- a/src/cpu/ozone/dyn_inst.hh
+++ b/src/cpu/ozone/dyn_inst.hh
@@ -231,14 +231,14 @@ class OzoneDynInst : public BaseDynInst<Impl>
public:
// ISA stuff
+ MiscReg readMiscRegNoEffect(int misc_reg);
+
MiscReg readMiscReg(int misc_reg);
- MiscReg readMiscRegWithEffect(int misc_reg);
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
void setMiscReg(int misc_reg, const MiscReg &val);
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val);
-
#if FULL_SYSTEM
Fault hwrei();
void trap(Fault fault);
diff --git a/src/cpu/ozone/dyn_inst_impl.hh b/src/cpu/ozone/dyn_inst_impl.hh
index 05a66d77a..8519917f5 100644
--- a/src/cpu/ozone/dyn_inst_impl.hh
+++ b/src/cpu/ozone/dyn_inst_impl.hh
@@ -219,31 +219,31 @@ OzoneDynInst<Impl>::clearMemDependents()
template <class Impl>
TheISA::MiscReg
-OzoneDynInst<Impl>::readMiscReg(int misc_reg)
+OzoneDynInst<Impl>::readMiscRegNoEffect(int misc_reg)
{
- return this->thread->readMiscReg(misc_reg);
+ return this->thread->readMiscRegNoEffect(misc_reg);
}
template <class Impl>
TheISA::MiscReg
-OzoneDynInst<Impl>::readMiscRegWithEffect(int misc_reg)
+OzoneDynInst<Impl>::readMiscReg(int misc_reg)
{
- return this->thread->readMiscRegWithEffect(misc_reg);
+ return this->thread->readMiscReg(misc_reg);
}
template <class Impl>
void
-OzoneDynInst<Impl>::setMiscReg(int misc_reg, const MiscReg &val)
+OzoneDynInst<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
this->setIntResult(val);
- this->thread->setMiscReg(misc_reg, val);
+ this->thread->setMiscRegNoEffect(misc_reg, val);
}
template <class Impl>
void
-OzoneDynInst<Impl>::setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+OzoneDynInst<Impl>::setMiscReg(int misc_reg, const MiscReg &val)
{
- this->thread->setMiscRegWithEffect(misc_reg, val);
+ this->thread->setMiscReg(misc_reg, val);
}
#if FULL_SYSTEM
@@ -255,7 +255,7 @@ OzoneDynInst<Impl>::hwrei()
if (!(this->readPC() & 0x3))
return new AlphaISA::UnimplementedOpcodeFault;
- this->setNextPC(this->thread->readMiscReg(AlphaISA::IPR_EXC_ADDR));
+ this->setNextPC(this->thread->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR));
this->cpu->hwrei();
diff --git a/src/cpu/ozone/inorder_back_end_impl.hh b/src/cpu/ozone/inorder_back_end_impl.hh
index 84f935a72..8d7ebb60e 100644
--- a/src/cpu/ozone/inorder_back_end_impl.hh
+++ b/src/cpu/ozone/inorder_back_end_impl.hh
@@ -89,13 +89,13 @@ InorderBackEnd<Impl>::checkInterrupts()
int summary = 0;
- if (thread->readMiscReg(IPR_ASTRR))
+ if (thread->readMiscRegNoEffect(IPR_ASTRR))
panic("asynchronous traps not implemented\n");
- if (thread->readMiscReg(IPR_SIRR)) {
+ if (thread->readMiscRegNoEffect(IPR_SIRR)) {
for (int i = INTLEVEL_SOFTWARE_MIN;
i < INTLEVEL_SOFTWARE_MAX; i++) {
- if (thread->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
+ if (thread->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) {
// See table 4-19 of the 21164 hardware reference
ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
summary |= (ULL(1) << i);
@@ -116,14 +116,14 @@ InorderBackEnd<Impl>::checkInterrupts()
}
}
- if (ipl && ipl > thread->readMiscReg(IPR_IPLR)) {
+ if (ipl && ipl > thread->readMiscRegNoEffect(IPR_IPLR)) {
thread->inSyscall = true;
- thread->setMiscReg(IPR_ISR, summary);
- thread->setMiscReg(IPR_INTID, ipl);
+ thread->setMiscRegNoEffect(IPR_ISR, summary);
+ thread->setMiscRegNoEffect(IPR_INTID, ipl);
Fault(new InterruptFault)->invoke(xc);
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
- thread->readMiscReg(IPR_IPLR), ipl, summary);
+ thread->readMiscRegNoEffect(IPR_IPLR), ipl, summary);
// May need to go 1 inst prior
squashPending = true;
diff --git a/src/cpu/ozone/inst_queue_impl.hh b/src/cpu/ozone/inst_queue_impl.hh
index 84f2b2a19..ea9d03c0d 100644
--- a/src/cpu/ozone/inst_queue_impl.hh
+++ b/src/cpu/ozone/inst_queue_impl.hh
@@ -38,7 +38,7 @@
#include <vector>
-#include "sim/root.hh"
+#include "sim/core.hh"
#include "cpu/ozone/inst_queue.hh"
#if 0
diff --git a/src/cpu/ozone/lw_back_end_impl.hh b/src/cpu/ozone/lw_back_end_impl.hh
index a181c93f4..c0a9cad24 100644
--- a/src/cpu/ozone/lw_back_end_impl.hh
+++ b/src/cpu/ozone/lw_back_end_impl.hh
@@ -1193,7 +1193,7 @@ LWBackEnd<Impl>::commitInst(int inst_num)
#if FULL_SYSTEM
if (thread->profile) {
// bool usermode =
-// (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
+// (xc->readMiscRegNoEffect(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
// thread->profilePC = usermode ? 1 : inst->readPC();
thread->profilePC = inst->readPC();
ProfileNode *node = thread->profile->consume(thread->getTC(),
diff --git a/src/cpu/ozone/lw_lsq_impl.hh b/src/cpu/ozone/lw_lsq_impl.hh
index ee1968626..f26b06453 100644
--- a/src/cpu/ozone/lw_lsq_impl.hh
+++ b/src/cpu/ozone/lw_lsq_impl.hh
@@ -605,12 +605,12 @@ OzoneLWLSQ<Impl>::writebackStores()
// @todo: Remove this SC hack once the memory system handles it.
if (req->isLocked()) {
if (req->isUncacheable()) {
- req->setScResult(2);
+ req->setExtraData(2);
} else {
if (cpu->lockFlag) {
- req->setScResult(1);
+ req->setExtraData(1);
} else {
- req->setScResult(0);
+ req->setExtraData(0);
// Hack: Instantly complete this store.
completeDataAccess(data_pkt);
--sq_it;
diff --git a/src/cpu/ozone/thread_state.hh b/src/cpu/ozone/thread_state.hh
index a71795851..53776e7d9 100644
--- a/src/cpu/ozone/thread_state.hh
+++ b/src/cpu/ozone/thread_state.hh
@@ -115,24 +115,24 @@ struct OzoneThreadState : public ThreadState {
ThreadContext *getTC() { return tc; }
- MiscReg readMiscReg(int misc_reg)
+ MiscReg readMiscRegNoEffect(int misc_reg)
{
- return miscRegFile.readReg(misc_reg);
+ return miscRegFile.readRegNoEffect(misc_reg);
}
- MiscReg readMiscRegWithEffect(int misc_reg)
+ MiscReg readMiscReg(int misc_reg)
{
- return miscRegFile.readRegWithEffect(misc_reg, tc);
+ return miscRegFile.readReg(misc_reg, tc);
}
- void setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
- miscRegFile.setReg(misc_reg, val);
+ miscRegFile.setRegNoEffect(misc_reg, val);
}
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{
- miscRegFile.setRegWithEffect(misc_reg, val, tc);
+ miscRegFile.setReg(misc_reg, val, tc);
}
uint64_t readPC()
diff --git a/src/cpu/pc_event.cc b/src/cpu/pc_event.cc
index fca357fe3..438218df2 100644
--- a/src/cpu/pc_event.cc
+++ b/src/cpu/pc_event.cc
@@ -40,7 +40,7 @@
#include "cpu/thread_context.hh"
#include "cpu/pc_event.hh"
#include "sim/debug.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
#include "sim/system.hh"
using namespace std;
@@ -138,14 +138,12 @@ BreakPCEvent::process(ThreadContext *tc)
}
#if FULL_SYSTEM
-extern "C"
void
sched_break_pc_sys(System *sys, Addr addr)
{
new BreakPCEvent(&sys->pcEventQueue, "debug break", addr, true);
}
-extern "C"
void
sched_break_pc(Addr addr)
{
diff --git a/src/cpu/simple/SConscript b/src/cpu/simple/SConscript
new file mode 100644
index 000000000..9a6a80473
--- /dev/null
+++ b/src/cpu/simple/SConscript
@@ -0,0 +1,43 @@
+# -*- 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: Nathan Binkert
+
+Import('*')
+
+need_simple_base = False
+if 'AtomicSimpleCPU' in env['CPU_MODELS']:
+ need_simple_base = True
+ Source('atomic.cc')
+
+if 'TimingSimpleCPU' in env['CPU_MODELS']:
+ need_simple_base = True
+ Source('timing.cc')
+
+if need_simple_base:
+ Source('base.cc')
diff --git a/src/cpu/simple/SConsopts b/src/cpu/simple/SConsopts
new file mode 100644
index 000000000..32dbda1a5
--- /dev/null
+++ b/src/cpu/simple/SConsopts
@@ -0,0 +1,34 @@
+# -*- 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: Nathan Binkert
+
+Import('*')
+
+all_cpu_list.extend(('AtomicSimpleCPU', 'TimingSimpleCPU'))
+default_cpus.extend(('AtomicSimpleCPU', 'TimingSimpleCPU'))
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index 3b3536e44..6f69b5ac4 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -31,6 +31,7 @@
#include "arch/locked_mem.hh"
#include "arch/mmaped_ipr.hh"
#include "arch/utility.hh"
+#include "base/bigint.hh"
#include "cpu/exetrace.hh"
#include "cpu/simple/atomic.hh"
#include "mem/packet.hh"
@@ -125,6 +126,17 @@ AtomicSimpleCPU::CpuPort::recvRetry()
panic("AtomicSimpleCPU doesn't expect recvRetry callback!");
}
+void
+AtomicSimpleCPU::DcachePort::setPeer(Port *port)
+{
+ Port::setPeer(port);
+
+#if FULL_SYSTEM
+ // Update the ThreadContext's memory ports (Functional/Virtual
+ // Ports)
+ cpu->tcBase()->connectMemPorts();
+#endif
+}
AtomicSimpleCPU::AtomicSimpleCPU(Params *p)
: BaseSimpleCPU(p), tickEvent(this),
@@ -138,18 +150,20 @@ AtomicSimpleCPU::AtomicSimpleCPU(Params *p)
ifetch_req = new Request();
ifetch_req->setThreadContext(p->cpu_id, 0); // Add thread ID if we add MT
- ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
+ ifetch_pkt = new Packet(ifetch_req, MemCmd::ReadReq, Packet::Broadcast);
ifetch_pkt->dataStatic(&inst);
data_read_req = new Request();
data_read_req->setThreadContext(p->cpu_id, 0); // Add thread ID here too
- data_read_pkt = new Packet(data_read_req, Packet::ReadReq,
+ data_read_pkt = new Packet(data_read_req, MemCmd::ReadReq,
Packet::Broadcast);
data_read_pkt->dataStatic(&dataReg);
data_write_req = new Request();
data_write_req->setThreadContext(p->cpu_id, 0); // Add thread ID here too
- data_write_pkt = new Packet(data_write_req, Packet::WriteReq,
+ data_write_pkt = new Packet(data_write_req, MemCmd::WriteReq,
+ Packet::Broadcast);
+ data_swap_pkt = new Packet(data_write_req, MemCmd::SwapReq,
Packet::Broadcast);
}
@@ -208,7 +222,7 @@ AtomicSimpleCPU::switchOut()
void
AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
{
- BaseCPU::takeOverFrom(oldCPU);
+ BaseCPU::takeOverFrom(oldCPU, &icachePort, &dcachePort);
assert(!tickEvent.scheduled());
@@ -239,12 +253,6 @@ AtomicSimpleCPU::activateContext(int thread_num, int delay)
notIdleFraction++;
-#if FULL_SYSTEM
- // Connect the ThreadContext's memory ports (Functional/Virtual
- // Ports)
- tc->connectMemPorts();
-#endif
-
//Make sure ticks are still on multiples of cycles
tickEvent.schedule(nextCycle(curTick + cycles(delay)));
_status = Running;
@@ -318,6 +326,14 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
template
Fault
+AtomicSimpleCPU::read(Addr addr, Twin32_t &data, unsigned flags);
+
+template
+Fault
+AtomicSimpleCPU::read(Addr addr, Twin64_t &data, unsigned flags);
+
+template
+Fault
AtomicSimpleCPU::read(Addr addr, uint64_t &data, unsigned flags);
template
@@ -363,10 +379,15 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
{
// use the CPU's statically allocated write request and packet objects
Request *req = data_write_req;
- PacketPtr pkt = data_write_pkt;
+ PacketPtr pkt;
req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
+ if (req->isSwap())
+ pkt = data_swap_pkt;
+ else
+ pkt = data_write_pkt;
+
if (traceData) {
traceData->setAddr(addr);
}
@@ -381,6 +402,11 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
if (req->isLocked()) {
do_access = TheISA::handleLockedWrite(thread, req);
}
+ if (req->isCondSwap()) {
+ assert(res);
+ req->setExtraData(*res);
+ }
+
if (do_access) {
pkt->reinitFromRequest();
@@ -401,15 +427,11 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
#endif
}
- if (req->isLocked()) {
- uint64_t scResult = req->getScResult();
- if (scResult != 0) {
- // clear failure counter
- thread->setStCondFailures(0);
- }
- if (res) {
- *res = req->getScResult();
- }
+ if (req->isSwap()) {
+ assert(res);
+ *res = pkt->get<T>();
+ } else if (res) {
+ *res = req->getExtraData();
}
}
@@ -424,6 +446,17 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+template
+Fault
+AtomicSimpleCPU::write(Twin32_t data, Addr addr,
+ unsigned flags, uint64_t *res);
+
+template
+Fault
+AtomicSimpleCPU::write(Twin64_t data, Addr addr,
+ unsigned flags, uint64_t *res);
+
template
Fault
AtomicSimpleCPU::write(uint64_t data, Addr addr,
@@ -483,17 +516,28 @@ AtomicSimpleCPU::tick()
Fault fault = setupFetchRequest(ifetch_req);
if (fault == NoFault) {
- ifetch_pkt->reinitFromRequest();
+ Tick icache_latency = 0;
+ bool icache_access = false;
+ dcache_access = false; // assume no dcache access
- Tick icache_latency = icachePort.sendAtomic(ifetch_pkt);
- // ifetch_req is initialized to read the instruction directly
- // into the CPU object's inst field.
+ //Fetch more instruction memory if necessary
+ if(predecoder.needMoreBytes())
+ {
+ icache_access = true;
+ ifetch_pkt->reinitFromRequest();
+
+ icache_latency = icachePort.sendAtomic(ifetch_pkt);
+ // ifetch_req is initialized to read the instruction directly
+ // into the CPU object's inst field.
+ }
- dcache_access = false; // assume no dcache access
preExecute();
- fault = curStaticInst->execute(this, traceData);
- postExecute();
+ if(curStaticInst)
+ {
+ fault = curStaticInst->execute(this, traceData);
+ postExecute();
+ }
// @todo remove me after debugging with legion done
if (curStaticInst && (!curStaticInst->isMicroOp() ||
@@ -501,7 +545,8 @@ AtomicSimpleCPU::tick()
instCnt++;
if (simulate_stalls) {
- Tick icache_stall = icache_latency - cycles(1);
+ Tick icache_stall =
+ icache_access ? icache_latency - cycles(1) : 0;
Tick dcache_stall =
dcache_access ? dcache_latency - cycles(1) : 0;
Tick stall_cycles = (icache_stall + dcache_stall) / cycles(1);
@@ -512,8 +557,8 @@ AtomicSimpleCPU::tick()
}
}
-
- advancePC(fault);
+ if(predecoder.needMoreBytes())
+ advancePC(fault);
}
if (_status != Idle)
diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh
index 42c7bf23a..ad4aa4708 100644
--- a/src/cpu/simple/atomic.hh
+++ b/src/cpu/simple/atomic.hh
@@ -81,9 +81,6 @@ class AtomicSimpleCPU : public BaseSimpleCPU
class CpuPort : public Port
{
-
- AtomicSimpleCPU *cpu;
-
public:
CpuPort(const std::string &_name, AtomicSimpleCPU *_cpu)
@@ -94,6 +91,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU
protected:
+ AtomicSimpleCPU *cpu;
+
virtual bool recvTiming(PacketPtr pkt);
virtual Tick recvAtomic(PacketPtr pkt);
@@ -110,7 +109,17 @@ class AtomicSimpleCPU : public BaseSimpleCPU
};
CpuPort icachePort;
- CpuPort dcachePort;
+
+ class DcachePort : public CpuPort
+ {
+ public:
+ DcachePort(const std::string &_name, AtomicSimpleCPU *_cpu)
+ : CpuPort(_name, _cpu)
+ { }
+
+ virtual void setPeer(Port *port);
+ };
+ DcachePort dcachePort;
Request *ifetch_req;
PacketPtr ifetch_pkt;
@@ -118,6 +127,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU
PacketPtr data_read_pkt;
Request *data_write_req;
PacketPtr data_write_pkt;
+ PacketPtr data_swap_pkt;
bool dcache_access;
Tick dcache_latency;
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index b8d1f3bed..877dc5bd4 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -70,7 +70,7 @@ using namespace std;
using namespace TheISA;
BaseSimpleCPU::BaseSimpleCPU(Params *p)
- : BaseCPU(p), thread(NULL)
+ : BaseCPU(p), thread(NULL), predecoder(NULL)
{
#if FULL_SYSTEM
thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
@@ -301,7 +301,7 @@ BaseSimpleCPU::post_interrupt(int int_num, int index)
BaseCPU::post_interrupt(int_num, index);
if (thread->status() == ThreadContext::Suspended) {
- DPRINTF(IPI,"Suspended Processor awoke\n");
+ DPRINTF(Quiesce,"Suspended Processor awoke\n");
thread->activate();
}
}
@@ -367,16 +367,23 @@ 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()) {
+ StaticInstPtr instPtr = NULL;
+
+ //Predecode, ie bundle up an ExtMachInst
+ //This should go away once the constructor can be set up properly
+ predecoder.setTC(thread->getTC());
+ //If more fetch data is needed, pass it in.
+ if(predecoder.needMoreBytes())
+ predecoder.moreBytes(thread->readPC(), 0, inst);
+ else
+ predecoder.process();
+ //If an instruction is ready, decode it
+ if (predecoder.extMachInstReady())
+ instPtr = StaticInst::decode(predecoder.getExtMachInst());
+
+ //If we decoded an instruction and it's microcoded, start pulling
+ //out micro ops
+ if (instPtr && instPtr->isMacroOp()) {
curMacroStaticInst = instPtr;
curStaticInst = curMacroStaticInst->
fetchMicroOp(thread->readMicroPC());
@@ -389,17 +396,19 @@ BaseSimpleCPU::preExecute()
fetchMicroOp(thread->readMicroPC());
}
+ //If we decoded an instruction this "tick", record information about it.
+ if(curStaticInst)
+ {
+ traceData = Trace::getInstRecord(curTick, tc, curStaticInst,
+ thread->readPC());
- traceData = Trace::getInstRecord(curTick, tc, curStaticInst,
- thread->readPC());
-
- DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n",
- curStaticInst->getName(), curStaticInst->getOpcode(),
- curStaticInst->machInst);
+ DPRINTF(Decode,"Decode: Decoded %s instruction: 0x%x\n",
+ curStaticInst->getName(), curStaticInst->machInst);
#if FULL_SYSTEM
- thread->setInst(inst);
+ thread->setInst(inst);
#endif // FULL_SYSTEM
+ }
}
void
@@ -409,7 +418,8 @@ BaseSimpleCPU::postExecute()
if (thread->profile) {
bool usermode = TheISA::inUserMode(tc);
thread->profilePC = usermode ? 1 : thread->readPC();
- ProfileNode *node = thread->profile->consume(tc, inst);
+ StaticInstPtr si(inst);
+ ProfileNode *node = thread->profile->consume(tc, si);
if (node)
thread->profileNode = node;
}
@@ -427,7 +437,9 @@ BaseSimpleCPU::postExecute()
traceFunctions(thread->readPC());
if (traceData) {
- traceData->finalize();
+ traceData->dump();
+ delete traceData;
+ traceData = NULL;
}
}
@@ -440,9 +452,9 @@ BaseSimpleCPU::advancePC(Fault fault)
fault->invoke(tc);
thread->setMicroPC(0);
thread->setNextMicroPC(1);
- } else {
+ } else if (predecoder.needMoreBytes()) {
//If we're at the last micro op for this instruction
- if (curStaticInst->isLastMicroOp()) {
+ if (curStaticInst && curStaticInst->isLastMicroOp()) {
//We should be working with a macro op
assert(curMacroStaticInst);
//Close out this macro op, and clean up the
@@ -461,13 +473,9 @@ BaseSimpleCPU::advancePC(Fault fault)
} else {
// go to the next instruction
thread->setPC(thread->readNextPC());
-#if ISA_HAS_DELAY_SLOT
thread->setNextPC(thread->readNextNPC());
thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
assert(thread->readNextPC() != thread->readNextNPC());
-#else
- thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
-#endif
}
}
diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh
index c4853b916..787259c96 100644
--- a/src/cpu/simple/base.hh
+++ b/src/cpu/simple/base.hh
@@ -33,6 +33,7 @@
#ifndef __CPU_SIMPLE_BASE_HH__
#define __CPU_SIMPLE_BASE_HH__
+#include "arch/predecoder.hh"
#include "base/statistics.hh"
#include "config/full_system.hh"
#include "cpu/base.hh"
@@ -63,6 +64,10 @@ class Process;
class RemoteGDB;
class GDBListener;
+namespace TheISA
+{
+ class Predecoder;
+}
class ThreadContext;
class Checkpoint;
@@ -74,7 +79,6 @@ namespace Trace {
class BaseSimpleCPU : public BaseCPU
{
protected:
- typedef TheISA::MachInst MachInst;
typedef TheISA::MiscReg MiscReg;
typedef TheISA::FloatReg FloatReg;
typedef TheISA::FloatRegBits FloatRegBits;
@@ -122,10 +126,13 @@ class BaseSimpleCPU : public BaseCPU
#endif
// current instruction
- MachInst inst;
+ TheISA::MachInst inst;
+
+ // The predecoder
+ TheISA::Predecoder predecoder;
// Static data storage
- TheISA::IntReg dataReg;
+ TheISA::LargestRead dataReg;
StaticInstPtr curStaticInst;
StaticInstPtr curMacroStaticInst;
@@ -284,14 +291,19 @@ class BaseSimpleCPU : public BaseCPU
void setNextPC(uint64_t val) { thread->setNextPC(val); }
void setNextNPC(uint64_t val) { thread->setNextNPC(val); }
+ MiscReg readMiscRegNoEffect(int misc_reg)
+ {
+ return thread->readMiscRegNoEffect(misc_reg);
+ }
+
MiscReg readMiscReg(int misc_reg)
{
return thread->readMiscReg(misc_reg);
}
- MiscReg readMiscRegWithEffect(int misc_reg)
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
- return thread->readMiscRegWithEffect(misc_reg);
+ return thread->setMiscRegNoEffect(misc_reg, val);
}
void setMiscReg(int misc_reg, const MiscReg &val)
@@ -299,9 +311,10 @@ class BaseSimpleCPU : public BaseCPU
return thread->setMiscReg(misc_reg, val);
}
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx)
{
- return thread->setMiscRegWithEffect(misc_reg, val);
+ int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
+ return thread->readMiscRegNoEffect(reg_idx);
}
MiscReg readMiscRegOperand(const StaticInst *si, int idx)
@@ -310,23 +323,25 @@ class BaseSimpleCPU : public BaseCPU
return thread->readMiscReg(reg_idx);
}
- MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx)
+ void setMiscRegOperandNoEffect(const StaticInst *si, int idx, const MiscReg &val)
{
- int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
- return thread->readMiscRegWithEffect(reg_idx);
+ int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
+ return thread->setMiscRegNoEffect(reg_idx, val);
}
- void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val)
+ void setMiscRegOperand(
+ const StaticInst *si, int idx, const MiscReg &val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
return thread->setMiscReg(reg_idx, val);
}
- void setMiscRegOperandWithEffect(
- const StaticInst *si, int idx, const MiscReg &val)
- {
- int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
- return thread->setMiscRegWithEffect(reg_idx, val);
+ unsigned readStCondFailures() {
+ return thread->readStCondFailures();
+ }
+
+ void setStCondFailures(unsigned sc_failures) {
+ thread->setStCondFailures(sc_failures);
}
#if FULL_SYSTEM
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index dfffb0b1f..45da7c3eb 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -30,6 +30,7 @@
#include "arch/locked_mem.hh"
#include "arch/utility.hh"
+#include "base/bigint.hh"
#include "cpu/exetrace.hh"
#include "cpu/simple/timing.hh"
#include "mem/packet.hh"
@@ -193,7 +194,7 @@ TimingSimpleCPU::switchOut()
void
TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
{
- BaseCPU::takeOverFrom(oldCPU);
+ BaseCPU::takeOverFrom(oldCPU, &icachePort, &dcachePort);
// if any of this CPU's ThreadContexts are active, mark the CPU as
// running and schedule its tick event.
@@ -208,23 +209,6 @@ TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
if (_status != Running) {
_status = Idle;
}
-
- Port *peer;
- if (icachePort.getPeer() == NULL) {
- peer = oldCPU->getPort("icache_port")->getPeer();
- icachePort.setPeer(peer);
- } else {
- peer = icachePort.getPeer();
- }
- peer->setPeer(&icachePort);
-
- if (dcachePort.getPeer() == NULL) {
- peer = oldCPU->getPort("dcache_port")->getPeer();
- dcachePort.setPeer(peer);
- } else {
- peer = dcachePort.getPeer();
- }
- peer->setPeer(&dcachePort);
}
@@ -239,12 +223,6 @@ TimingSimpleCPU::activateContext(int thread_num, int delay)
notIdleFraction++;
_status = Running;
-#if FULL_SYSTEM
- // Connect the ThreadContext's memory ports (Functional/Virtual
- // Ports)
- tc->connectMemPorts();
-#endif
-
// kick things off by initiating the fetch of the next instruction
fetchEvent =
new EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch>(this, false);
@@ -286,7 +264,7 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
// Now do the access.
if (fault == NoFault) {
PacketPtr pkt =
- new Packet(req, Packet::ReadReq, Packet::Broadcast);
+ new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
pkt->dataDynamic<T>(new T);
if (!dcachePort.sendTiming(pkt)) {
@@ -297,14 +275,14 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
// memory system takes ownership of packet
dcache_pkt = NULL;
}
+
+ // This will need a new way to tell if it has a dcache attached.
+ if (req->isUncacheable())
+ recordEvent("Uncached Read");
} else {
delete req;
}
- // This will need a new way to tell if it has a dcache attached.
- if (req->isUncacheable())
- recordEvent("Uncached Read");
-
return fault;
}
@@ -312,6 +290,14 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
template
Fault
+TimingSimpleCPU::read(Addr addr, Twin64_t &data, unsigned flags);
+
+template
+Fault
+TimingSimpleCPU::read(Addr addr, Twin32_t &data, unsigned flags);
+
+template
+Fault
TimingSimpleCPU::read(Addr addr, uint64_t &data, unsigned flags);
template
@@ -359,13 +345,20 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
new Request(/* asid */ 0, addr, sizeof(T), flags, thread->readPC(),
cpu_id, /* thread ID */ 0);
+ if (traceData) {
+ traceData->setAddr(req->getVaddr());
+ }
+
// translate to physical address
Fault fault = thread->translateDataWriteReq(req);
// Now do the access.
if (fault == NoFault) {
assert(dcache_pkt == NULL);
- dcache_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
+ if (req->isSwap())
+ dcache_pkt = new Packet(req, MemCmd::SwapReq, Packet::Broadcast);
+ else
+ dcache_pkt = new Packet(req, MemCmd::WriteReq, Packet::Broadcast);
dcache_pkt->allocate();
dcache_pkt->set(data);
@@ -374,6 +367,10 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
if (req->isLocked()) {
do_access = TheISA::handleLockedWrite(thread, req);
}
+ if (req->isCondSwap()) {
+ assert(res);
+ req->setExtraData(*res);
+ }
if (do_access) {
if (!dcachePort.sendTiming(dcache_pkt)) {
@@ -384,13 +381,13 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
dcache_pkt = NULL;
}
}
+ // This will need a new way to tell if it's hooked up to a cache or not.
+ if (req->isUncacheable())
+ recordEvent("Uncached Write");
} else {
delete req;
}
- // This will need a new way to tell if it's hooked up to a cache or not.
- if (req->isUncacheable())
- recordEvent("Uncached Write");
// If the write needs to have a fault on the access, consider calling
// changeStatus() and changing it to "bad addr write" or something.
@@ -401,6 +398,16 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template
Fault
+TimingSimpleCPU::write(Twin32_t data, Addr addr,
+ unsigned flags, uint64_t *res);
+
+template
+Fault
+TimingSimpleCPU::write(Twin64_t data, Addr addr,
+ unsigned flags, uint64_t *res);
+
+template
+Fault
TimingSimpleCPU::write(uint64_t data, Addr addr,
unsigned flags, uint64_t *res);
@@ -454,7 +461,7 @@ TimingSimpleCPU::fetch()
ifetch_req->setThreadContext(cpu_id, /* thread ID */ 0);
Fault fault = setupFetchRequest(ifetch_req);
- ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
+ ifetch_pkt = new Packet(ifetch_req, MemCmd::ReadReq, Packet::Broadcast);
ifetch_pkt->dataStatic(&inst);
if (fault == NoFault) {
@@ -629,6 +636,18 @@ TimingSimpleCPU::completeDrain()
drainEvent->process();
}
+void
+TimingSimpleCPU::DcachePort::setPeer(Port *port)
+{
+ Port::setPeer(port);
+
+#if FULL_SYSTEM
+ // Update the ThreadContext's memory ports (Functional/Virtual
+ // Ports)
+ cpu->tcBase()->connectMemPorts();
+#endif
+}
+
bool
TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
{
diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh
index abcb224bf..ef062d24a 100644
--- a/src/cpu/simple/timing.hh
+++ b/src/cpu/simple/timing.hh
@@ -144,6 +144,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
: CpuPort(_cpu->name() + "-dport", _cpu, _lat), tickEvent(_cpu)
{ }
+ virtual void setPeer(Port *port);
+
protected:
virtual bool recvTiming(PacketPtr pkt);
diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc
index 13d0e2e29..39f31782b 100644
--- a/src/cpu/simple_thread.cc
+++ b/src/cpu/simple_thread.cc
@@ -305,7 +305,7 @@ void
SimpleThread::delVirtPort(VirtualPort *vp)
{
if (vp != virtPort) {
- delete vp->getPeer();
+ vp->removeConn();
delete vp;
}
}
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index f2f79c070..824914ad0 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.hh
@@ -350,24 +350,24 @@ class SimpleThread : public ThreadState
regs.setNextNPC(val);
}
- MiscReg readMiscReg(int misc_reg)
+ MiscReg readMiscRegNoEffect(int misc_reg)
{
- return regs.readMiscReg(misc_reg);
+ return regs.readMiscRegNoEffect(misc_reg);
}
- MiscReg readMiscRegWithEffect(int misc_reg)
+ MiscReg readMiscReg(int misc_reg)
{
- return regs.readMiscRegWithEffect(misc_reg, tc);
+ return regs.readMiscReg(misc_reg, tc);
}
- void setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
- return regs.setMiscReg(misc_reg, val);
+ return regs.setMiscRegNoEffect(misc_reg, val);
}
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{
- return regs.setMiscRegWithEffect(misc_reg, val, tc);
+ return regs.setMiscReg(misc_reg, val, tc);
}
unsigned readStCondFailures() { return storeCondFailures; }
diff --git a/src/cpu/static_inst.cc b/src/cpu/static_inst.cc
index cb4a7cdf7..64fcc0580 100644
--- a/src/cpu/static_inst.cc
+++ b/src/cpu/static_inst.cc
@@ -31,7 +31,7 @@
#include <iostream>
#include "cpu/static_inst.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
StaticInstPtr StaticInst::nullStaticInstPtr;
diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh
index 416c8ab56..a58ac85d6 100644
--- a/src/cpu/static_inst.hh
+++ b/src/cpu/static_inst.hh
@@ -35,6 +35,7 @@
#include <string>
#include "arch/isa_traits.hh"
+#include "arch/utility.hh"
#include "sim/faults.hh"
#include "base/bitfield.hh"
#include "base/hashmap.hh"
@@ -439,9 +440,6 @@ class StaticInst : public StaticInstBase
//This is defined as inline below.
static StaticInstPtr decode(ExtMachInst mach_inst);
- /// Return opcode of machine instruction
- uint32_t getOpcode() { return bits(machInst, 31, 26);}
-
/// Return name of machine instruction
std::string getName() { return mnemonic; }
};
@@ -474,7 +472,7 @@ class StaticInstPtr : public RefCountingPtr<StaticInst>
/// Construct directly from machine instruction.
/// Calls StaticInst::decode().
- StaticInstPtr(TheISA::ExtMachInst mach_inst)
+ explicit StaticInstPtr(TheISA::ExtMachInst mach_inst)
: RefCountingPtr<StaticInst>(StaticInst::decode(mach_inst))
{
}
diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh
index 16e491fd3..05c409c95 100644
--- a/src/cpu/thread_context.hh
+++ b/src/cpu/thread_context.hh
@@ -226,14 +226,14 @@ class ThreadContext
virtual void setNextNPC(uint64_t val) = 0;
+ virtual MiscReg readMiscRegNoEffect(int misc_reg) = 0;
+
virtual MiscReg readMiscReg(int misc_reg) = 0;
- virtual MiscReg readMiscRegWithEffect(int misc_reg) = 0;
+ virtual void setMiscRegNoEffect(int misc_reg, const MiscReg &val) = 0;
virtual void setMiscReg(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.
virtual unsigned readStCondFailures() = 0;
@@ -254,6 +254,8 @@ class ThreadContext
// Same with st cond failures.
virtual Counter readFuncExeInst() = 0;
+ virtual void syscall(int64_t callnum) = 0;
+
// This function exits the thread context in the CPU and returns
// 1 if the CPU has no more active threads (meaning it's OK to exit);
// Used in syscall-emulation mode when a thread calls the exit syscall.
@@ -410,18 +412,18 @@ class ProxyThreadContext : public ThreadContext
void setNextNPC(uint64_t val) { actualTC->setNextNPC(val); }
+ MiscReg readMiscRegNoEffect(int misc_reg)
+ { return actualTC->readMiscRegNoEffect(misc_reg); }
+
MiscReg readMiscReg(int misc_reg)
{ return actualTC->readMiscReg(misc_reg); }
- MiscReg readMiscRegWithEffect(int misc_reg)
- { return actualTC->readMiscRegWithEffect(misc_reg); }
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
+ { return actualTC->setMiscRegNoEffect(misc_reg, val); }
void setMiscReg(int misc_reg, const MiscReg &val)
{ return actualTC->setMiscReg(misc_reg, val); }
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
- { return actualTC->setMiscRegWithEffect(misc_reg, val); }
-
unsigned readStCondFailures()
{ return actualTC->readStCondFailures(); }
@@ -441,6 +443,9 @@ class ProxyThreadContext : public ThreadContext
void setSyscallReturn(SyscallReturn return_value)
{ actualTC->setSyscallReturn(return_value); }
+ void syscall(int64_t callnum)
+ { actualTC->syscall(callnum); }
+
Counter readFuncExeInst() { return actualTC->readFuncExeInst(); }
#endif
diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc
index 93dd1e2eb..4b65ca4b8 100644
--- a/src/cpu/thread_state.cc
+++ b/src/cpu/thread_state.cc
@@ -125,7 +125,10 @@ ThreadState::connectPhysPort()
// @todo: For now this disregards any older port that may have
// already existed. Fix this memory leak once the bus port IDs
// for functional ports is resolved.
- physPort = new FunctionalPort(csprintf("%s-%d-funcport",
+ if (physPort)
+ physPort->removeConn();
+ else
+ physPort = new FunctionalPort(csprintf("%s-%d-funcport",
baseCpu->name(), tid));
connectToMemFunc(physPort);
}
@@ -136,7 +139,10 @@ ThreadState::connectVirtPort()
// @todo: For now this disregards any older port that may have
// already existed. Fix this memory leak once the bus port IDs
// for functional ports is resolved.
- virtPort = new VirtualPort(csprintf("%s-%d-vport",
+ if (virtPort)
+ virtPort->removeConn();
+ else
+ virtPort = new VirtualPort(csprintf("%s-%d-vport",
baseCpu->name(), tid));
connectToMemFunc(virtPort);
}
diff --git a/src/cpu/trace/SConscript b/src/cpu/trace/SConscript
new file mode 100644
index 000000000..f166b2f23
--- /dev/null
+++ b/src/cpu/trace/SConscript
@@ -0,0 +1,40 @@
+# -*- 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: Nathan Binkert
+
+Import('*')
+
+if False:
+ Source('opt_cpu.cc')
+ Source('trace_cpu.cc')
+
+ Source('reader/mem_trace_reader.cc')
+ Source('reader/ibm_reader.cc')
+ Source('reader/itx_reader.cc')
+ Source('reader/m5_reader.cc')
diff --git a/src/dev/SConscript b/src/dev/SConscript
index 951bc29d1..ea529b536 100644
--- a/src/dev/SConscript
+++ b/src/dev/SConscript
@@ -29,51 +29,29 @@
# 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')
+Import('*')
+
+if env['FULL_SYSTEM']:
+ Source('baddev.cc')
+ Source('disk_image.cc')
+ Source('etherbus.cc')
+ Source('etherdump.cc')
+ Source('etherint.cc')
+ Source('etherlink.cc')
+ Source('etherpkt.cc')
+ Source('ethertap.cc')
+ Source('i8254xGBe.cc')
+ Source('ide_ctrl.cc')
+ Source('ide_disk.cc')
+ Source('io_device.cc')
+ Source('isa_fake.cc')
+ Source('ns_gige.cc')
+ Source('pciconfigall.cc')
+ Source('pcidev.cc')
+ Source('pktfifo.cc')
+ Source('platform.cc')
+ Source('simconsole.cc')
+ Source('simple_disk.cc')
+ #Source('sinic.cc')
+ Source('uart.cc')
+ Source('uart8250.cc')
diff --git a/src/dev/alpha/SConscript b/src/dev/alpha/SConscript
index fb0e626d3..c985fdd9f 100644
--- a/src/dev/alpha/SConscript
+++ b/src/dev/alpha/SConscript
@@ -29,40 +29,11 @@
# Authors: Steve Reinhardt
# Gabe Black
-import os.path, sys
+Import('*')
-# 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')
+if env['FULL_SYSTEM'] and env['TARGET_ISA'] == 'alpha':
+ Source('console.cc')
+ Source('tsunami.cc')
+ Source('tsunami_cchip.cc')
+ Source('tsunami_io.cc')
+ Source('tsunami_pchip.cc')
diff --git a/src/dev/alpha/tsunami_cchip.cc b/src/dev/alpha/tsunami_cchip.cc
index 15c47984b..118160adf 100644
--- a/src/dev/alpha/tsunami_cchip.cc
+++ b/src/dev/alpha/tsunami_cchip.cc
@@ -372,7 +372,7 @@ TsunamiCChip::write(PacketPtr pkt)
void
TsunamiCChip::clearIPI(uint64_t ipintr)
{
- int numcpus = tsunami->intrctrl->cpu->system->threadContexts.size();
+ int numcpus = sys->threadContexts.size();
assert(numcpus <= Tsunami::Max_CPUs);
if (ipintr) {
@@ -398,7 +398,7 @@ TsunamiCChip::clearIPI(uint64_t ipintr)
void
TsunamiCChip::clearITI(uint64_t itintr)
{
- int numcpus = tsunami->intrctrl->cpu->system->threadContexts.size();
+ int numcpus = sys->threadContexts.size();
assert(numcpus <= Tsunami::Max_CPUs);
if (itintr) {
@@ -418,7 +418,7 @@ TsunamiCChip::clearITI(uint64_t itintr)
void
TsunamiCChip::reqIPI(uint64_t ipreq)
{
- int numcpus = tsunami->intrctrl->cpu->system->threadContexts.size();
+ int numcpus = sys->threadContexts.size();
assert(numcpus <= Tsunami::Max_CPUs);
if (ipreq) {
@@ -445,7 +445,7 @@ TsunamiCChip::reqIPI(uint64_t ipreq)
void
TsunamiCChip::postRTC()
{
- int size = tsunami->intrctrl->cpu->system->threadContexts.size();
+ int size = sys->threadContexts.size();
assert(size <= Tsunami::Max_CPUs);
for (int i = 0; i < size; i++) {
@@ -463,7 +463,7 @@ void
TsunamiCChip::postDRIR(uint32_t interrupt)
{
uint64_t bitvector = ULL(1) << interrupt;
- uint64_t size = tsunami->intrctrl->cpu->system->threadContexts.size();
+ uint64_t size = sys->threadContexts.size();
assert(size <= Tsunami::Max_CPUs);
drir |= bitvector;
@@ -481,7 +481,7 @@ void
TsunamiCChip::clearDRIR(uint32_t interrupt)
{
uint64_t bitvector = ULL(1) << interrupt;
- uint64_t size = tsunami->intrctrl->cpu->system->threadContexts.size();
+ uint64_t size = sys->threadContexts.size();
assert(size <= Tsunami::Max_CPUs);
if (drir & bitvector)
diff --git a/src/dev/alpha/tsunamireg.h b/src/dev/alpha/tsunamireg.h
index d603972be..a2742e36d 100644
--- a/src/dev/alpha/tsunamireg.h
+++ b/src/dev/alpha/tsunamireg.h
@@ -136,15 +136,6 @@
/* Added for keyboard accesses */
#define TSDEV_KBD 0x64
-/* Added for ATA PCI DMA */
-#define ATA_PCI_DMA 0x00
-#define ATA_PCI_DMA2 0x02
-#define ATA_PCI_DMA3 0x16
-#define ATA_PCI_DMA4 0x17
-#define ATA_PCI_DMA5 0x1a
-#define ATA_PCI_DMA6 0x11
-#define ATA_PCI_DMA7 0x14
-
#define TSDEV_RTC_ADDR 0x70
#define TSDEV_RTC_DATA 0x71
@@ -155,18 +146,6 @@
#define TSUNAMI_PCI0_IO TSUNAMI_UNCACHABLE_BIT + PCHIP_PCI0_IO
-// UART Defines
-#define UART_IER_RDI 0x01
-#define UART_IER_THRI 0x02
-#define UART_IER_RLSI 0x04
-
-
-#define UART_LSR_TEMT 0x40
-#define UART_LSR_THRE 0x20
-#define UART_LSR_DR 0x01
-
-#define UART_MCR_LOOP 0x10
-
// System Control PortB Status Bits
#define PORTB_SPKR_HIGH 0x20
diff --git a/src/dev/etherbus.cc b/src/dev/etherbus.cc
index 348bb818a..cedb3cd4d 100644
--- a/src/dev/etherbus.cc
+++ b/src/dev/etherbus.cc
@@ -43,7 +43,7 @@
#include "dev/etherint.hh"
#include "dev/etherpkt.hh"
#include "sim/builder.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
using namespace std;
diff --git a/src/dev/etherdump.cc b/src/dev/etherdump.cc
index 0c986cc21..04463f3ee 100644
--- a/src/dev/etherdump.cc
+++ b/src/dev/etherdump.cc
@@ -41,7 +41,7 @@
#include "base/output.hh"
#include "dev/etherdump.hh"
#include "sim/builder.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
using std::string;
diff --git a/src/dev/etherlink.cc b/src/dev/etherlink.cc
index cd3812270..5d30e1744 100644
--- a/src/dev/etherlink.cc
+++ b/src/dev/etherlink.cc
@@ -47,7 +47,7 @@
#include "sim/builder.hh"
#include "sim/serialize.hh"
#include "sim/system.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
using namespace std;
diff --git a/src/dev/i8254xGBe.cc b/src/dev/i8254xGBe.cc
index 7fc68f4e7..d6449f6c5 100644
--- a/src/dev/i8254xGBe.cc
+++ b/src/dev/i8254xGBe.cc
@@ -35,7 +35,13 @@
* other MACs with slight modifications.
*/
+
+/*
+ * @todo really there are multiple dma engines.. we should implement them.
+ */
+
#include "base/inet.hh"
+#include "base/trace.hh"
#include "dev/i8254xGBe.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
@@ -43,32 +49,37 @@
#include "sim/stats.hh"
#include "sim/system.hh"
+#include <algorithm>
+
using namespace iGbReg;
+using namespace Net;
IGbE::IGbE(Params *p)
- : PciDev(p), etherInt(NULL)
+ : PciDev(p), etherInt(NULL), useFlowControl(p->use_flow_control),
+ rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size), rxTick(false),
+ txTick(false), rdtrEvent(this), radvEvent(this), tadvEvent(this),
+ tidvEvent(this), tickEvent(this), interEvent(this),
+ rxDescCache(this, name()+".TxDesc", p->rx_desc_cache_size),
+ txDescCache(this, name()+".RxDesc", p->tx_desc_cache_size), clock(p->clock)
{
// Initialized internal registers per Intel documentation
- regs.tctl.reg = 0;
- regs.rctl.reg = 0;
- regs.ctrl.reg = 0;
- regs.ctrl.fd = 1;
- regs.ctrl.lrst = 1;
- regs.ctrl.speed = 2;
- regs.ctrl.frcspd = 1;
- regs.sts.reg = 0;
- regs.eecd.reg = 0;
- regs.eecd.fwe = 1;
- regs.eecd.ee_type = 1;
- regs.eerd.reg = 0;
- regs.icd.reg = 0;
- regs.imc.reg = 0;
- regs.rctl.reg = 0;
- regs.tctl.reg = 0;
- regs.manc.reg = 0;
-
- regs.pba.rxa = 0x30;
- regs.pba.txa = 0x10;
+ // All registers intialized to 0 by per register constructor
+ regs.ctrl.fd(1);
+ regs.ctrl.lrst(1);
+ regs.ctrl.speed(2);
+ regs.ctrl.frcspd(1);
+ regs.sts.speed(3); // Say we're 1000Mbps
+ regs.sts.fd(1); // full duplex
+ regs.eecd.fwe(1);
+ regs.eecd.ee_type(1);
+ regs.imr = 0;
+ regs.iam = 0;
+ regs.rxdctl.gran(1);
+ regs.rxdctl.wthresh(1);
+ regs.fcrth(1);
+
+ regs.pba.rxa(0x30);
+ regs.pba.txa(0x10);
eeOpBits = 0;
eeAddrBits = 0;
@@ -78,8 +89,20 @@ IGbE::IGbE(Params *p)
// clear all 64 16 bit words of the eeprom
memset(&flash, 0, EEPROM_SIZE*2);
+ //We'll need to instert the MAC address into the flash
+ flash[0] = 0xA4A4;
+ flash[1] = 0xB6B6;
+ flash[2] = 0xC8C8;
+
+ uint16_t csum = 0;
+ for (int x = 0; x < EEPROM_SIZE; x++)
+ csum += flash[x];
+
// Magic happy checksum value
- flash[0] = 0xBABA;
+ flash[EEPROM_SIZE-1] = htobe((uint16_t)(EEPROM_CSUM - csum));
+
+ rxFifo.clear();
+ txFifo.clear();
}
@@ -124,47 +147,129 @@ IGbE::read(PacketPtr pkt)
switch (daddr) {
- case CTRL:
- pkt->set<uint32_t>(regs.ctrl.reg);
- break;
- case STATUS:
- pkt->set<uint32_t>(regs.sts.reg);
- break;
- case EECD:
- pkt->set<uint32_t>(regs.eecd.reg);
- break;
- case EERD:
- pkt->set<uint32_t>(regs.eerd.reg);
- break;
- case ICR:
- pkt->set<uint32_t>(regs.icd.reg);
- break;
- case IMC:
- pkt->set<uint32_t>(regs.imc.reg);
- break;
- case RCTL:
- pkt->set<uint32_t>(regs.rctl.reg);
- break;
- case TCTL:
- pkt->set<uint32_t>(regs.tctl.reg);
- break;
- case PBA:
- pkt->set<uint32_t>(regs.pba.reg);
- break;
- case WUC:
- case LEDCTL:
- pkt->set<uint32_t>(0); // We don't care, so just return 0
- break;
- case MANC:
- pkt->set<uint32_t>(regs.manc.reg);
- break;
+ case REG_CTRL:
+ pkt->set<uint32_t>(regs.ctrl());
+ break;
+ case REG_STATUS:
+ pkt->set<uint32_t>(regs.sts());
+ break;
+ case REG_EECD:
+ pkt->set<uint32_t>(regs.eecd());
+ break;
+ case REG_EERD:
+ pkt->set<uint32_t>(regs.eerd());
+ break;
+ case REG_CTRL_EXT:
+ pkt->set<uint32_t>(regs.ctrl_ext());
+ break;
+ case REG_MDIC:
+ pkt->set<uint32_t>(regs.mdic());
+ break;
+ case REG_ICR:
+ pkt->set<uint32_t>(regs.icr());
+ if (regs.icr.int_assert())
+ regs.imr &= regs.iam;
+ if (regs.imr == 0 || (regs.icr.int_assert() && regs.ctrl_ext.iame())) {
+ regs.icr(0);
+ cpuClearInt();
+ }
+ break;
+ case REG_ITR:
+ pkt->set<uint32_t>(regs.itr());
+ break;
+ case REG_RCTL:
+ pkt->set<uint32_t>(regs.rctl());
+ break;
+ case REG_FCTTV:
+ pkt->set<uint32_t>(regs.fcttv());
+ break;
+ case REG_TCTL:
+ pkt->set<uint32_t>(regs.tctl());
+ break;
+ case REG_PBA:
+ pkt->set<uint32_t>(regs.pba());
+ break;
+ case REG_WUC:
+ case REG_LEDCTL:
+ pkt->set<uint32_t>(0); // We don't care, so just return 0
+ break;
+ case REG_FCRTL:
+ pkt->set<uint32_t>(regs.fcrtl());
+ break;
+ case REG_FCRTH:
+ pkt->set<uint32_t>(regs.fcrth());
+ break;
+ case REG_RDBAL:
+ pkt->set<uint32_t>(regs.rdba.rdbal());
+ break;
+ case REG_RDBAH:
+ pkt->set<uint32_t>(regs.rdba.rdbah());
+ break;
+ case REG_RDLEN:
+ pkt->set<uint32_t>(regs.rdlen());
+ break;
+ case REG_RDH:
+ pkt->set<uint32_t>(regs.rdh());
+ break;
+ case REG_RDT:
+ pkt->set<uint32_t>(regs.rdt());
+ break;
+ case REG_RDTR:
+ pkt->set<uint32_t>(regs.rdtr());
+ if (regs.rdtr.fpd()) {
+ rxDescCache.writeback(0);
+ postInterrupt(IT_RXT);
+ regs.rdtr.fpd(0);
+ }
+ if (regs.rdtr.delay()) {
+ Tick t = regs.rdtr.delay() * Clock::Int::ns * 1024;
+ if (rdtrEvent.scheduled())
+ rdtrEvent.reschedule(curTick + t);
+ else
+ rdtrEvent.schedule(curTick + t);
+ }
+ break;
+ case REG_RADV:
+ pkt->set<uint32_t>(regs.radv());
+ break;
+ case REG_TDBAL:
+ pkt->set<uint32_t>(regs.tdba.tdbal());
+ break;
+ case REG_TDBAH:
+ pkt->set<uint32_t>(regs.tdba.tdbah());
+ break;
+ case REG_TDLEN:
+ pkt->set<uint32_t>(regs.tdlen());
+ break;
+ case REG_TDH:
+ pkt->set<uint32_t>(regs.tdh());
+ break;
+ case REG_TDT:
+ pkt->set<uint32_t>(regs.tdt());
+ break;
+ case REG_TIDV:
+ pkt->set<uint32_t>(regs.tidv());
+ break;
+ case REG_TXDCTL:
+ pkt->set<uint32_t>(regs.txdctl());
+ break;
+ case REG_TADV:
+ pkt->set<uint32_t>(regs.tadv());
+ break;
+ case REG_RXCSUM:
+ pkt->set<uint32_t>(regs.rxcsum());
+ break;
+ case REG_MANC:
+ pkt->set<uint32_t>(regs.manc());
+ break;
default:
- if (!(daddr >= VFTA && daddr < (VFTA + VLAN_FILTER_TABLE_SIZE)*4) &&
- !(daddr >= RAL && daddr < (RAL + RCV_ADDRESS_TABLE_SIZE)*4) &&
- !(daddr >= MTA && daddr < (MTA + MULTICAST_TABLE_SIZE)*4))
- pkt->set<uint32_t>(0);
- else
- panic("Read request to unknown register number: %#x\n", daddr);
+ if (!(daddr >= REG_VFTA && daddr < (REG_VFTA + VLAN_FILTER_TABLE_SIZE*4)) &&
+ !(daddr >= REG_RAL && daddr < (REG_RAL + RCV_ADDRESS_TABLE_SIZE*8)) &&
+ !(daddr >= REG_MTA && daddr < (REG_MTA + MULTICAST_TABLE_SIZE*4)) &&
+ !(daddr >= REG_CRCERRS && daddr < (REG_CRCERRS + STATS_REGS_SIZE)))
+ panic("Read request to unknown register number: %#x\n", daddr);
+ else
+ pkt->set<uint32_t>(0);
};
pkt->result = Packet::Success;
@@ -194,93 +299,253 @@ IGbE::write(PacketPtr pkt)
///
uint32_t val = pkt->get<uint32_t>();
+ Regs::RCTL oldrctl;
+ Regs::TCTL oldtctl;
+
switch (daddr) {
- case CTRL:
- regs.ctrl.reg = val;
- break;
- case STATUS:
- regs.sts.reg = val;
- break;
- case EECD:
- int oldClk;
- oldClk = regs.eecd.sk;
- regs.eecd.reg = val;
- // See if this is a eeprom access and emulate accordingly
- if (!oldClk && regs.eecd.sk) {
- if (eeOpBits < 8) {
- eeOpcode = eeOpcode << 1 | regs.eecd.din;
- eeOpBits++;
- } else if (eeAddrBits < 8 && eeOpcode == EEPROM_READ_OPCODE_SPI) {
- eeAddr = eeAddr << 1 | regs.eecd.din;
- eeAddrBits++;
- } else if (eeDataBits < 16 && eeOpcode == EEPROM_READ_OPCODE_SPI) {
- assert(eeAddr>>1 < EEPROM_SIZE);
- DPRINTF(EthernetEEPROM, "EEPROM bit read: %d word: %#X\n",
- flash[eeAddr>>1] >> eeDataBits & 0x1, flash[eeAddr>>1]);
- regs.eecd.dout = (flash[eeAddr>>1] >> (15-eeDataBits)) & 0x1;
- eeDataBits++;
- } else if (eeDataBits < 8 && eeOpcode == EEPROM_RDSR_OPCODE_SPI) {
- regs.eecd.dout = 0;
- eeDataBits++;
- } else
- panic("What's going on with eeprom interface? opcode:"
- " %#x:%d addr: %#x:%d, data: %d\n", (uint32_t)eeOpcode,
- (uint32_t)eeOpBits, (uint32_t)eeAddr,
- (uint32_t)eeAddrBits, (uint32_t)eeDataBits);
-
- // Reset everything for the next command
- if ((eeDataBits == 16 && eeOpcode == EEPROM_READ_OPCODE_SPI) ||
+ case REG_CTRL:
+ regs.ctrl = val;
+ if (regs.ctrl.tfce())
+ warn("TX Flow control enabled, should implement\n");
+ if (regs.ctrl.rfce())
+ warn("RX Flow control enabled, should implement\n");
+ break;
+ case REG_CTRL_EXT:
+ regs.ctrl_ext = val;
+ break;
+ case REG_STATUS:
+ regs.sts = val;
+ break;
+ case REG_EECD:
+ int oldClk;
+ oldClk = regs.eecd.sk();
+ regs.eecd = val;
+ // See if this is a eeprom access and emulate accordingly
+ if (!oldClk && regs.eecd.sk()) {
+ if (eeOpBits < 8) {
+ eeOpcode = eeOpcode << 1 | regs.eecd.din();
+ eeOpBits++;
+ } else if (eeAddrBits < 8 && eeOpcode == EEPROM_READ_OPCODE_SPI) {
+ eeAddr = eeAddr << 1 | regs.eecd.din();
+ eeAddrBits++;
+ } else if (eeDataBits < 16 && eeOpcode == EEPROM_READ_OPCODE_SPI) {
+ assert(eeAddr>>1 < EEPROM_SIZE);
+ DPRINTF(EthernetEEPROM, "EEPROM bit read: %d word: %#X\n",
+ flash[eeAddr>>1] >> eeDataBits & 0x1, flash[eeAddr>>1]);
+ regs.eecd.dout((flash[eeAddr>>1] >> (15-eeDataBits)) & 0x1);
+ eeDataBits++;
+ } else if (eeDataBits < 8 && eeOpcode == EEPROM_RDSR_OPCODE_SPI) {
+ regs.eecd.dout(0);
+ eeDataBits++;
+ } else
+ panic("What's going on with eeprom interface? opcode:"
+ " %#x:%d addr: %#x:%d, data: %d\n", (uint32_t)eeOpcode,
+ (uint32_t)eeOpBits, (uint32_t)eeAddr,
+ (uint32_t)eeAddrBits, (uint32_t)eeDataBits);
+
+ // Reset everything for the next command
+ if ((eeDataBits == 16 && eeOpcode == EEPROM_READ_OPCODE_SPI) ||
(eeDataBits == 8 && eeOpcode == EEPROM_RDSR_OPCODE_SPI)) {
- eeOpBits = 0;
- eeAddrBits = 0;
- eeDataBits = 0;
+ eeOpBits = 0;
+ eeAddrBits = 0;
+ eeDataBits = 0;
eeOpcode = 0;
- eeAddr = 0;
- }
+ eeAddr = 0;
+ }
DPRINTF(EthernetEEPROM, "EEPROM: opcode: %#X:%d addr: %#X:%d\n",
- (uint32_t)eeOpcode, (uint32_t) eeOpBits,
- (uint32_t)eeAddr>>1, (uint32_t)eeAddrBits);
+ (uint32_t)eeOpcode, (uint32_t) eeOpBits,
+ (uint32_t)eeAddr>>1, (uint32_t)eeAddrBits);
if (eeOpBits == 8 && !(eeOpcode == EEPROM_READ_OPCODE_SPI ||
- eeOpcode == EEPROM_RDSR_OPCODE_SPI ))
- panic("Unknown eeprom opcode: %#X:%d\n", (uint32_t)eeOpcode,
- (uint32_t)eeOpBits);
-
-
- }
- // If driver requests eeprom access, immediately give it to it
- regs.eecd.ee_gnt = regs.eecd.ee_req;
- break;
- case EERD:
- regs.eerd.reg = val;
- break;
- case ICR:
- regs.icd.reg = val;
- break;
- case IMC:
- regs.imc.reg = val;
- break;
- case RCTL:
- regs.rctl.reg = val;
- break;
- case TCTL:
- regs.tctl.reg = val;
- break;
- case PBA:
- regs.pba.rxa = val;
- regs.pba.txa = 64 - regs.pba.rxa;
- break;
- case WUC:
- case LEDCTL:
- ; // We don't care, so don't store anything
- break;
- case MANC:
- regs.manc.reg = val;
- break;
+ eeOpcode == EEPROM_RDSR_OPCODE_SPI ))
+ panic("Unknown eeprom opcode: %#X:%d\n", (uint32_t)eeOpcode,
+ (uint32_t)eeOpBits);
+
+
+ }
+ // If driver requests eeprom access, immediately give it to it
+ regs.eecd.ee_gnt(regs.eecd.ee_req());
+ break;
+ case REG_EERD:
+ regs.eerd = val;
+ break;
+ case REG_MDIC:
+ regs.mdic = val;
+ if (regs.mdic.i())
+ panic("No support for interrupt on mdic complete\n");
+ if (regs.mdic.phyadd() != 1)
+ panic("No support for reading anything but phy\n");
+ DPRINTF(Ethernet, "%s phy address %x\n", regs.mdic.op() == 1 ? "Writing"
+ : "Reading", regs.mdic.regadd());
+ switch (regs.mdic.regadd()) {
+ case PHY_PSTATUS:
+ regs.mdic.data(0x796D); // link up
+ break;
+ case PHY_PID:
+ regs.mdic.data(0x02A8);
+ break;
+ case PHY_EPID:
+ regs.mdic.data(0x0380);
+ break;
+ case PHY_GSTATUS:
+ regs.mdic.data(0x7C00);
+ break;
+ case PHY_EPSTATUS:
+ regs.mdic.data(0x3000);
+ break;
+ case PHY_AGC:
+ regs.mdic.data(0x180); // some random length
+ break;
+ default:
+ regs.mdic.data(0);
+ warn("Accessing unknown phy register %d\n", regs.mdic.regadd());
+ }
+ regs.mdic.r(1);
+ break;
+ case REG_ICR:
+ if (regs.icr.int_assert())
+ regs.imr &= regs.iam;
+
+ regs.icr = ~bits(val,30,0) & regs.icr();
+ // if no more bits are set clear the int_asserted bit
+ if (!bits(regs.icr(),31,31))
+ cpuClearInt();
+
+ break;
+ case REG_ITR:
+ regs.itr = val;
+ break;
+ case REG_ICS:
+ postInterrupt((IntTypes)val);
+ break;
+ case REG_IMS:
+ regs.imr |= val;
+ chkInterrupt();
+ break;
+ case REG_IMC:
+ regs.imr &= ~val;
+ chkInterrupt();
+ break;
+ case REG_IAM:
+ regs.iam = val;
+ break;
+ case REG_RCTL:
+ oldrctl = regs.rctl;
+ regs.rctl = val;
+ if (regs.rctl.rst()) {
+ rxDescCache.reset();
+ rxFifo.clear();
+ regs.rctl.rst(0);
+ }
+ if (regs.rctl.en())
+ rxTick = true;
+ if ((rxTick || txTick) && !tickEvent.scheduled())
+ tickEvent.schedule(curTick + cycles(1));
+ break;
+ case REG_FCTTV:
+ regs.fcttv = val;
+ break;
+ case REG_TCTL:
+ regs.tctl = val;
+ oldtctl = regs.tctl;
+ regs.tctl = val;
+ if (regs.tctl.en())
+ txTick = true;
+ if ((rxTick || txTick) && !tickEvent.scheduled())
+ tickEvent.schedule(curTick + cycles(1));
+ if (regs.tctl.en() && !oldtctl.en()) {
+ txDescCache.reset();
+ }
+ break;
+ case REG_PBA:
+ regs.pba.rxa(val);
+ regs.pba.txa(64 - regs.pba.rxa());
+ break;
+ case REG_WUC:
+ case REG_LEDCTL:
+ case REG_FCAL:
+ case REG_FCAH:
+ case REG_FCT:
+ case REG_VET:
+ case REG_AIFS:
+ case REG_TIPG:
+ ; // We don't care, so don't store anything
+ break;
+ case REG_FCRTL:
+ regs.fcrtl = val;
+ break;
+ case REG_FCRTH:
+ regs.fcrth = val;
+ break;
+ case REG_RDBAL:
+ regs.rdba.rdbal( val & ~mask(4));
+ rxDescCache.areaChanged();
+ break;
+ case REG_RDBAH:
+ regs.rdba.rdbah(val);
+ rxDescCache.areaChanged();
+ break;
+ case REG_RDLEN:
+ regs.rdlen = val & ~mask(7);
+ rxDescCache.areaChanged();
+ break;
+ case REG_RDH:
+ regs.rdh = val;
+ rxDescCache.areaChanged();
+ break;
+ case REG_RDT:
+ regs.rdt = val;
+ rxTick = true;
+ if ((rxTick || txTick) && !tickEvent.scheduled())
+ tickEvent.schedule(curTick + cycles(1));
+ break;
+ case REG_RDTR:
+ regs.rdtr = val;
+ break;
+ case REG_RADV:
+ regs.radv = val;
+ break;
+ case REG_TDBAL:
+ regs.tdba.tdbal( val & ~mask(4));
+ txDescCache.areaChanged();
+ break;
+ case REG_TDBAH:
+ regs.tdba.tdbah(val);
+ txDescCache.areaChanged();
+ break;
+ case REG_TDLEN:
+ regs.tdlen = val & ~mask(7);
+ txDescCache.areaChanged();
+ break;
+ case REG_TDH:
+ regs.tdh = val;
+ txDescCache.areaChanged();
+ break;
+ case REG_TDT:
+ regs.tdt = val;
+ txTick = true;
+ if ((rxTick || txTick) && !tickEvent.scheduled())
+ tickEvent.schedule(curTick + cycles(1));
+ break;
+ case REG_TIDV:
+ regs.tidv = val;
+ break;
+ case REG_TXDCTL:
+ regs.txdctl = val;
+ break;
+ case REG_TADV:
+ regs.tadv = val;
+ break;
+ case REG_RXCSUM:
+ regs.rxcsum = val;
+ break;
+ case REG_MANC:
+ regs.manc = val;
+ break;
default:
- if (!(daddr >= VFTA && daddr < (VFTA + VLAN_FILTER_TABLE_SIZE)*4) &&
- !(daddr >= RAL && daddr < (RAL + RCV_ADDRESS_TABLE_SIZE)*4) &&
- !(daddr >= MTA && daddr < (MTA + MULTICAST_TABLE_SIZE)*4))
+ if (!(daddr >= REG_VFTA && daddr < (REG_VFTA + VLAN_FILTER_TABLE_SIZE*4)) &&
+ !(daddr >= REG_RAL && daddr < (REG_RAL + RCV_ADDRESS_TABLE_SIZE*8)) &&
+ !(daddr >= REG_MTA && daddr < (REG_MTA + MULTICAST_TABLE_SIZE*4)))
panic("Write request to unknown register number: %#x\n", daddr);
};
@@ -288,18 +553,585 @@ IGbE::write(PacketPtr pkt)
return pioDelay;
}
+void
+IGbE::postInterrupt(IntTypes t, bool now)
+{
+ // Interrupt is already pending
+ if (t & regs.icr())
+ return;
+
+ if (regs.icr() & regs.imr)
+ {
+ // already in an interrupt state, set new int and done
+ regs.icr = regs.icr() | t;
+ } else {
+ regs.icr = regs.icr() | t;
+ if (regs.itr.interval() == 0 || now) {
+ if (now) {
+ if (interEvent.scheduled())
+ interEvent.deschedule();
+ }
+ cpuPostInt();
+ } else {
+ DPRINTF(EthernetIntr, "EINT: Scheduling timer interrupt for %d ticks\n",
+ Clock::Int::ns * 256 * regs.itr.interval());
+ assert(!interEvent.scheduled());
+ interEvent.schedule(curTick + Clock::Int::ns * 256 * regs.itr.interval());
+ }
+ }
+}
+
+void
+IGbE::cpuPostInt()
+{
+ if (rdtrEvent.scheduled()) {
+ regs.icr.rxt0(1);
+ rdtrEvent.deschedule();
+ }
+ if (radvEvent.scheduled()) {
+ regs.icr.rxt0(1);
+ radvEvent.deschedule();
+ }
+ if (tadvEvent.scheduled()) {
+ regs.icr.txdw(1);
+ tadvEvent.deschedule();
+ }
+ if (tidvEvent.scheduled()) {
+ regs.icr.txdw(1);
+ tidvEvent.deschedule();
+ }
+
+ regs.icr.int_assert(1);
+ DPRINTF(EthernetIntr, "EINT: Posting interrupt to CPU now. Vector %#x\n",
+ regs.icr());
+ intrPost();
+}
+
+void
+IGbE::cpuClearInt()
+{
+ regs.icr.int_assert(0);
+ DPRINTF(EthernetIntr, "EINT: Clearing interrupt to CPU now. Vector %#x\n",
+ regs.icr());
+ intrClear();
+}
+
+void
+IGbE::chkInterrupt()
+{
+ // Check if we need to clear the cpu interrupt
+ if (!(regs.icr() & regs.imr))
+ cpuClearInt();
+
+ // Check if we need to set the cpu interupt
+ postInterrupt(IT_NONE);
+}
+
+
+IGbE::RxDescCache::RxDescCache(IGbE *i, const std::string n, int s)
+ : DescCache<RxDesc>(i, n, s), pktDone(false), pktEvent(this)
+
+{
+}
bool
-IGbE::ethRxPkt(EthPacketPtr packet)
+IGbE::RxDescCache::writePacket(EthPacketPtr packet)
{
- panic("Need to implemenet\n");
+ // We shouldn't have to deal with any of these yet
+ assert(packet->length < igbe->regs.rctl.descSize());
+
+ if (!unusedCache.size())
+ return false;
+
+ pktPtr = packet;
+
+ igbe->dmaWrite(unusedCache.front()->buf, packet->length, &pktEvent, packet->data);
+ return true;
+}
+
+void
+IGbE::RxDescCache::pktComplete()
+{
+ assert(unusedCache.size());
+ RxDesc *desc;
+ desc = unusedCache.front();
+
+ desc->len = pktPtr->length;
+ // no support for anything but starting at 0
+ assert(igbe->regs.rxcsum.pcss() == 0);
+
+ DPRINTF(EthernetDesc, "RxDesc: Packet written to memory updating Descriptor\n");
+
+ uint8_t status = RXDS_DD | RXDS_EOP;
+ uint8_t err = 0;
+ IpPtr ip(pktPtr);
+ if (ip) {
+ if (igbe->regs.rxcsum.ipofld()) {
+ DPRINTF(EthernetDesc, "RxDesc: Checking IP checksum\n");
+ status |= RXDS_IPCS;
+ desc->csum = cksum(ip);
+ if (cksum(ip) != 0) {
+ err |= RXDE_IPE;
+ DPRINTF(EthernetDesc, "RxDesc: Checksum is bad!!\n");
+ }
+ }
+ TcpPtr tcp(ip);
+ if (tcp && igbe->regs.rxcsum.tuofld()) {
+ DPRINTF(EthernetDesc, "RxDesc: Checking TCP checksum\n");
+ status |= RXDS_TCPCS;
+ desc->csum = cksum(tcp);
+ if (cksum(tcp) != 0) {
+ DPRINTF(EthernetDesc, "RxDesc: Checksum is bad!!\n");
+ err |= RXDE_TCPE;
+ }
+ }
+
+ UdpPtr udp(ip);
+ if (udp && igbe->regs.rxcsum.tuofld()) {
+ DPRINTF(EthernetDesc, "RxDesc: Checking UDP checksum\n");
+ status |= RXDS_UDPCS;
+ desc->csum = cksum(udp);
+ if (cksum(tcp) != 0) {
+ DPRINTF(EthernetDesc, "RxDesc: Checksum is bad!!\n");
+ err |= RXDE_TCPE;
+ }
+ }
+ } // if ip
+
+ desc->status = status;
+ desc->errors = err;
+
+ // No vlan support at this point... just set it to 0
+ desc->vlan = 0;
+
+ // Deal with the rx timer interrupts
+ if (igbe->regs.rdtr.delay()) {
+ DPRINTF(EthernetSM, "RXS: Scheduling DTR for %d\n",
+ igbe->regs.rdtr.delay() * igbe->intClock());
+ if (igbe->rdtrEvent.scheduled())
+ igbe->rdtrEvent.reschedule(curTick + igbe->regs.rdtr.delay() *
+ igbe->intClock());
+ else
+ igbe->rdtrEvent.schedule(curTick + igbe->regs.rdtr.delay() *
+ igbe->intClock());
+ }
+
+ if (igbe->regs.radv.idv() && igbe->regs.rdtr.delay()) {
+ DPRINTF(EthernetSM, "RXS: Scheduling ADV for %d\n",
+ igbe->regs.radv.idv() * igbe->intClock());
+ if (!igbe->radvEvent.scheduled())
+ igbe->radvEvent.schedule(curTick + igbe->regs.radv.idv() *
+ igbe->intClock());
+ }
+
+ // If the packet is small enough, interrupt appropriately
+ if (pktPtr->length <= igbe->regs.rsrpd.idv())
+ igbe->postInterrupt(IT_SRPD);
+
+ DPRINTF(EthernetDesc, "RxDesc: Processing of this descriptor complete\n");
+ unusedCache.pop_front();
+ usedCache.push_back(desc);
+ pktPtr = NULL;
+ enableSm();
+ pktDone = true;
+}
+
+void
+IGbE::RxDescCache::enableSm()
+{
+ igbe->rxTick = true;
+ if ((igbe->rxTick || igbe->txTick) && !igbe->tickEvent.scheduled())
+ igbe->tickEvent.schedule((curTick/igbe->cycles(1)) * igbe->cycles(1) +
+ igbe->cycles(1));
+}
+
+bool
+IGbE::RxDescCache::packetDone()
+{
+ if (pktDone) {
+ pktDone = false;
+ return true;
+ }
+ return false;
+}
+
+///////////////////////////////////// IGbE::TxDesc /////////////////////////////////
+
+IGbE::TxDescCache::TxDescCache(IGbE *i, const std::string n, int s)
+ : DescCache<TxDesc>(i,n, s), pktDone(false), isTcp(false), pktWaiting(false),
+ pktEvent(this)
+
+{
+}
+
+int
+IGbE::TxDescCache::getPacketSize()
+{
+ assert(unusedCache.size());
+
+ TxDesc *desc;
+
+ DPRINTF(EthernetDesc, "TxDesc: Starting processing of descriptor\n");
+
+ while (unusedCache.size() && TxdOp::isContext(unusedCache.front())) {
+ DPRINTF(EthernetDesc, "TxDesc: Got context descriptor type... skipping\n");
+
+ // I think we can just ignore these for now?
+ desc = unusedCache.front();
+ // is this going to be a tcp or udp packet?
+ isTcp = TxdOp::tcp(desc) ? true : false;
+
+ // make sure it's ipv4
+ assert(TxdOp::ip(desc));
+
+ TxdOp::setDd(desc);
+ unusedCache.pop_front();
+ usedCache.push_back(desc);
+ }
+
+ if (!unusedCache.size())
+ return -1;
+
+ DPRINTF(EthernetDesc, "TxDesc: Next TX packet is %d bytes\n",
+ TxdOp::getLen(unusedCache.front()));
+
+ return TxdOp::getLen(unusedCache.front());
+}
+
+void
+IGbE::TxDescCache::getPacketData(EthPacketPtr p)
+{
+ assert(unusedCache.size());
+
+ TxDesc *desc;
+ desc = unusedCache.front();
+
+ assert((TxdOp::isLegacy(desc) || TxdOp::isData(desc)) && TxdOp::getLen(desc));
+
+ pktPtr = p;
+
+ pktWaiting = true;
+
+ DPRINTF(EthernetDesc, "TxDesc: Starting DMA of packet\n");
+ igbe->dmaRead(TxdOp::getBuf(desc), TxdOp::getLen(desc), &pktEvent, p->data);
+
+
+}
+
+void
+IGbE::TxDescCache::pktComplete()
+{
+
+ TxDesc *desc;
+ assert(unusedCache.size());
+ assert(pktPtr);
+
+ DPRINTF(EthernetDesc, "TxDesc: DMA of packet complete\n");
+
+ desc = unusedCache.front();
+ assert((TxdOp::isLegacy(desc) || TxdOp::isData(desc)) && TxdOp::getLen(desc));
+
+ // no support for vlans
+ assert(!TxdOp::vle(desc));
+
+ // we alway report status
+ assert(TxdOp::rs(desc));
+
+ // we only support single packet descriptors at this point
+ assert(TxdOp::eop(desc));
+
+ // set that this packet is done
+ TxdOp::setDd(desc);
+
+ // Checksums are only ofloaded for new descriptor types
+ if (TxdOp::isData(desc) && ( TxdOp::ixsm(desc) || TxdOp::txsm(desc)) ) {
+ DPRINTF(EthernetDesc, "TxDesc: Calculating checksums for packet\n");
+ IpPtr ip(pktPtr);
+ if (TxdOp::ixsm(desc)) {
+ ip->sum(0);
+ ip->sum(cksum(ip));
+ DPRINTF(EthernetDesc, "TxDesc: Calculated IP checksum\n");
+ }
+ if (TxdOp::txsm(desc)) {
+ if (isTcp) {
+ TcpPtr tcp(ip);
+ tcp->sum(0);
+ tcp->sum(cksum(tcp));
+ DPRINTF(EthernetDesc, "TxDesc: Calculated TCP checksum\n");
+ } else {
+ UdpPtr udp(ip);
+ udp->sum(0);
+ udp->sum(cksum(udp));
+ DPRINTF(EthernetDesc, "TxDesc: Calculated UDP checksum\n");
+ }
+ }
+ }
+
+ if (TxdOp::ide(desc)) {
+ // Deal with the rx timer interrupts
+ DPRINTF(EthernetDesc, "TxDesc: Descriptor had IDE set\n");
+ if (igbe->regs.tidv.idv()) {
+ DPRINTF(EthernetDesc, "TxDesc: setting tidv\n");
+ if (igbe->tidvEvent.scheduled())
+ igbe->tidvEvent.reschedule(curTick + igbe->regs.tidv.idv() *
+ igbe->intClock());
+ else
+ igbe->tidvEvent.schedule(curTick + igbe->regs.tidv.idv() *
+ igbe->intClock());
+ }
+
+ if (igbe->regs.tadv.idv() && igbe->regs.tidv.idv()) {
+ DPRINTF(EthernetDesc, "TxDesc: setting tadv\n");
+ if (!igbe->tadvEvent.scheduled())
+ igbe->tadvEvent.schedule(curTick + igbe->regs.tadv.idv() *
+ igbe->intClock());
+ }
+ }
+
+ unusedCache.pop_front();
+ usedCache.push_back(desc);
+ pktDone = true;
+ pktWaiting = false;
+ pktPtr = NULL;
+
+ DPRINTF(EthernetDesc, "TxDesc: Descriptor Done\n");
+}
+
+bool
+IGbE::TxDescCache::packetAvailable()
+{
+ if (pktDone) {
+ pktDone = false;
+ return true;
+ }
+ return false;
+}
+
+void
+IGbE::TxDescCache::enableSm()
+{
+ igbe->txTick = true;
+ if ((igbe->rxTick || igbe->txTick) && !igbe->tickEvent.scheduled())
+ igbe->tickEvent.schedule((curTick/igbe->cycles(1)) * igbe->cycles(1) +
+ igbe->cycles(1));
+}
+
+
+
+
+///////////////////////////////////// IGbE /////////////////////////////////
+
+void
+IGbE::txStateMachine()
+{
+ if (!regs.tctl.en()) {
+ txTick = false;
+ DPRINTF(EthernetSM, "TXS: RX disabled, stopping ticking\n");
+ return;
+ }
+
+ if (txPacket && txDescCache.packetAvailable()) {
+ bool success;
+ DPRINTF(EthernetSM, "TXS: packet placed in TX FIFO\n");
+ success = txFifo.push(txPacket);
+ assert(success);
+ txPacket = NULL;
+ return;
+ }
+
+ // Only support descriptor granularity
+ assert(regs.txdctl.gran());
+ if (regs.txdctl.lwthresh() && txDescCache.descLeft() < (regs.txdctl.lwthresh() * 8)) {
+ DPRINTF(EthernetSM, "TXS: LWTHRESH caused posting of TXDLOW\n");
+ postInterrupt(IT_TXDLOW);
+ }
+
+ if (!txPacket) {
+ txPacket = new EthPacketData(16384);
+ }
+
+ if (!txDescCache.packetWaiting()) {
+ if (txDescCache.descLeft() == 0) {
+ DPRINTF(EthernetSM, "TXS: No descriptors left in ring, forcing writeback\n");
+ txDescCache.writeback(0);
+ DPRINTF(EthernetSM, "TXS: No descriptors left, stopping ticking\n");
+ txTick = false;
+ }
+
+ if (!(txDescCache.descUnused())) {
+ DPRINTF(EthernetSM, "TXS: No descriptors available in cache, stopping ticking\n");
+ txTick = false;
+ DPRINTF(EthernetSM, "TXS: No descriptors left, fetching\n");
+ txDescCache.fetchDescriptors();
+ return;
+ }
+
+ int size;
+ size = txDescCache.getPacketSize();
+ if (size > 0 && rxFifo.avail() > size) {
+ DPRINTF(EthernetSM, "TXS: Reserving %d bytes in FIFO and begining DMA of next packet\n");
+ rxFifo.reserve(size);
+ txDescCache.getPacketData(txPacket);
+ } else {
+ DPRINTF(EthernetSM, "TXS: No packets to get, writing back used descriptors\n");
+ txDescCache.writeback(0);
+ }
+
+ return;
+ }
+}
+
+bool
+IGbE::ethRxPkt(EthPacketPtr pkt)
+{
+ DPRINTF(Ethernet, "RxFIFO: Receiving pcakte from wire\n");
+ if (!regs.rctl.en()) {
+ DPRINTF(Ethernet, "RxFIFO: RX not enabled, dropping\n");
+ return true;
+ }
+
+ // restart the state machines if they are stopped
+ rxTick = true;
+ if ((rxTick || txTick) && !tickEvent.scheduled()) {
+ DPRINTF(EthernetSM, "RXS: received packet into fifo, starting ticking\n");
+ tickEvent.schedule(curTick/cycles(1) + cycles(1));
+ }
+
+ if (!rxFifo.push(pkt)) {
+ DPRINTF(Ethernet, "RxFIFO: Packet won't fit in fifo... dropped\n");
+ postInterrupt(IT_RXO, true);
+ return false;
+ }
+ return true;
+}
+
+
+void
+IGbE::rxStateMachine()
+{
+ if (!regs.rctl.en()) {
+ rxTick = false;
+ DPRINTF(EthernetSM, "RXS: RX disabled, stopping ticking\n");
+ return;
+ }
+
+ // If the packet is done check for interrupts/descriptors/etc
+ if (rxDescCache.packetDone()) {
+ DPRINTF(EthernetSM, "RXS: Packet completed DMA to memory\n");
+ int descLeft = rxDescCache.descLeft();
+ switch (regs.rctl.rdmts()) {
+ case 2: if (descLeft > .125 * regs.rdlen()) break;
+ case 1: if (descLeft > .250 * regs.rdlen()) break;
+ case 0: if (descLeft > .500 * regs.rdlen()) break;
+ DPRINTF(Ethernet, "RXS: Interrupting (RXDMT) because of descriptors left\n");
+ postInterrupt(IT_RXDMT);
+ break;
+ }
+
+ if (descLeft == 0) {
+ DPRINTF(EthernetSM, "RXS: No descriptors left in ring, forcing writeback\n");
+ rxDescCache.writeback(0);
+ DPRINTF(EthernetSM, "RXS: No descriptors left, stopping ticking\n");
+ rxTick = false;
+ }
+
+ // only support descriptor granulaties
+ assert(regs.rxdctl.gran());
+
+ if (regs.rxdctl.wthresh() >= rxDescCache.descUsed()) {
+ DPRINTF(EthernetSM, "RXS: Writing back because WTHRESH >= descUsed\n");
+ rxDescCache.writeback(cacheBlockSize()-1);
+ }
+
+ if ((rxDescCache.descUnused() < regs.rxdctl.pthresh()) &&
+ ((rxDescCache.descLeft() - rxDescCache.descUnused()) > regs.rxdctl.hthresh())) {
+ DPRINTF(EthernetSM, "RXS: Fetching descriptors because descUnused < PTHRESH\n");
+ rxDescCache.fetchDescriptors();
+ }
+
+ if (rxDescCache.descUnused() == 0) {
+ DPRINTF(EthernetSM, "RXS: No descriptors available in cache, stopping ticking\n");
+ rxTick = false;
+ DPRINTF(EthernetSM, "RXS: Fetching descriptors because none available\n");
+ rxDescCache.fetchDescriptors();
+ }
+ return;
+ }
+
+ if (!rxDescCache.descUnused()) {
+ DPRINTF(EthernetSM, "RXS: No descriptors available in cache, stopping ticking\n");
+ rxTick = false;
+ DPRINTF(EthernetSM, "RXS: No descriptors available, fetching\n");
+ rxDescCache.fetchDescriptors();
+ return;
+ }
+
+ if (rxFifo.empty()) {
+ DPRINTF(EthernetSM, "RXS: RxFIFO empty, stopping ticking\n");
+ rxTick = false;
+ return;
+ }
+
+ EthPacketPtr pkt;
+ pkt = rxFifo.front();
+
+ DPRINTF(EthernetSM, "RXS: Writing packet into memory\n");
+ if (!rxDescCache.writePacket(pkt)) {
+ return;
+ }
+
+ DPRINTF(EthernetSM, "RXS: Removing packet from FIFO\n");
+ rxFifo.pop();
+ DPRINTF(EthernetSM, "RXS: stopping ticking until packet DMA completes\n");
+ rxTick = false;
}
+void
+IGbE::txWire()
+{
+ if (txFifo.empty()) {
+ return;
+ }
+
+ txTick = true;
+
+ if (etherInt->sendPacket(txFifo.front())) {
+ DPRINTF(Ethernet, "TxFIFO: Successful transmit, bytes in fifo: %d\n",
+ txFifo.avail());
+ txFifo.pop();
+ }
+
+ if (txFifo.empty()) {
+ postInterrupt(IT_TXQE);
+ DPRINTF(Ethernet, "TxFIFO: Empty, posting interruppt\n");
+ }
+}
+
+void
+IGbE::tick()
+{
+ DPRINTF(EthernetSM, "IGbE: -------------- Cycle -------------- ");
+
+ if (rxTick)
+ rxStateMachine();
+
+ if (txTick) {
+ txStateMachine();
+ txWire();
+ }
+
+ if (rxTick || txTick)
+ tickEvent.schedule(curTick + cycles(1));
+}
void
IGbE::ethTxDone()
{
- panic("Need to implemenet\n");
+ // restart the state machines if they are stopped
+ txTick = true;
+ if ((rxTick || txTick) && !tickEvent.scheduled())
+ tickEvent.schedule(curTick/cycles(1) + cycles(1));
+ DPRINTF(Ethernet, "TxFIFO: Transmission complete\n");
}
void
diff --git a/src/dev/i8254xGBe.hh b/src/dev/i8254xGBe.hh
index ce4007263..d7d20ae50 100644
--- a/src/dev/i8254xGBe.hh
+++ b/src/dev/i8254xGBe.hh
@@ -35,6 +35,9 @@
#ifndef __DEV_I8254XGBE_HH__
#define __DEV_I8254XGBE_HH__
+#include <deque>
+#include <string>
+
#include "base/inet.hh"
#include "base/statistics.hh"
#include "dev/etherint.hh"
@@ -50,22 +53,434 @@ class IGbE : public PciDev
{
private:
IGbEInt *etherInt;
+
+ // device registers
iGbReg::Regs regs;
+
+ // eeprom data, status and control bits
int eeOpBits, eeAddrBits, eeDataBits;
uint8_t eeOpcode, eeAddr;
-
uint16_t flash[iGbReg::EEPROM_SIZE];
+ // cached parameters from params struct
+ Tick tickRate;
+ bool useFlowControl;
+
+ // packet fifos
+ PacketFifo rxFifo;
+ PacketFifo txFifo;
+
+ // Packet that we are currently putting into the txFifo
+ EthPacketPtr txPacket;
+
+ // Should to Rx/Tx State machine tick?
+ bool rxTick;
+ bool txTick;
+
+ // Event and function to deal with RDTR timer expiring
+ void rdtrProcess() { postInterrupt(iGbReg::IT_RXDMT, true); }
+ //friend class EventWrapper<IGbE, &IGbE::rdtrProcess>;
+ EventWrapper<IGbE, &IGbE::rdtrProcess> rdtrEvent;
+
+ // Event and function to deal with RADV timer expiring
+ void radvProcess() { postInterrupt(iGbReg::IT_RXDMT, true); }
+ //friend class EventWrapper<IGbE, &IGbE::radvProcess>;
+ EventWrapper<IGbE, &IGbE::radvProcess> radvEvent;
+
+ // Event and function to deal with TADV timer expiring
+ void tadvProcess() { postInterrupt(iGbReg::IT_TXDW, true); }
+ //friend class EventWrapper<IGbE, &IGbE::tadvProcess>;
+ EventWrapper<IGbE, &IGbE::tadvProcess> tadvEvent;
+
+ // Event and function to deal with TIDV timer expiring
+ void tidvProcess() { postInterrupt(iGbReg::IT_TXDW, true); };
+ //friend class EventWrapper<IGbE, &IGbE::tidvProcess>;
+ EventWrapper<IGbE, &IGbE::tidvProcess> tidvEvent;
+
+ // Main event to tick the device
+ void tick();
+ //friend class EventWrapper<IGbE, &IGbE::tick>;
+ EventWrapper<IGbE, &IGbE::tick> tickEvent;
+
+
+ void rxStateMachine();
+ void txStateMachine();
+ void txWire();
+
+ /** Write an interrupt into the interrupt pending register and check mask
+ * and interrupt limit timer before sending interrupt to CPU
+ * @param t the type of interrupt we are posting
+ * @param now should we ignore the interrupt limiting timer
+ */
+ void postInterrupt(iGbReg::IntTypes t, bool now = false);
+
+ /** Check and see if changes to the mask register have caused an interrupt
+ * to need to be sent or perhaps removed an interrupt cause.
+ */
+ void chkInterrupt();
+
+ /** Send an interrupt to the cpu
+ */
+ void cpuPostInt();
+ // Event to moderate interrupts
+ EventWrapper<IGbE, &IGbE::cpuPostInt> interEvent;
+
+ /** Clear the interupt line to the cpu
+ */
+ void cpuClearInt();
+
+ Tick intClock() { return Clock::Int::ns * 1024; }
+
+ template<class T>
+ class DescCache
+ {
+ protected:
+ virtual Addr descBase() const = 0;
+ virtual long descHead() const = 0;
+ virtual long descTail() const = 0;
+ virtual long descLen() const = 0;
+ virtual void updateHead(long h) = 0;
+ virtual void enableSm() = 0;
+
+ std::deque<T*> usedCache;
+ std::deque<T*> unusedCache;
+
+ T *fetchBuf;
+ T *wbBuf;
+
+ // Pointer to the device we cache for
+ IGbE *igbe;
+
+ // Name of this descriptor cache
+ std::string _name;
+
+ // How far we've cached
+ int cachePnt;
+
+ // The size of the descriptor cache
+ int size;
+
+ // How many descriptors we are currently fetching
+ int curFetching;
+
+ // How many descriptors we are currently writing back
+ int wbOut;
+
+ // if the we wrote back to the end of the descriptor ring and are going
+ // to have to wrap and write more
+ bool moreToWb;
+
+ // What the alignment is of the next descriptor writeback
+ Addr wbAlignment;
+
+ /** The packet that is currently being dmad to memory if any
+ */
+ EthPacketPtr pktPtr;
+
+ public:
+ DescCache(IGbE *i, const std::string n, int s)
+ : igbe(i), _name(n), cachePnt(0), size(s), curFetching(0), wbOut(0),
+ pktPtr(NULL), fetchEvent(this), wbEvent(this)
+ {
+ fetchBuf = new T[size];
+ wbBuf = new T[size];
+ }
+
+ virtual ~DescCache()
+ {
+ reset();
+ }
+
+ std::string name() { return _name; }
+
+ /** If the address/len/head change when we've got descriptors that are
+ * dirty that is very bad. This function checks that we don't and if we
+ * do panics.
+ */
+ void areaChanged()
+ {
+ if (usedCache.size() > 0 || unusedCache.size() > 0)
+ panic("Descriptor Address, Length or Head changed. Bad\n");
+ }
+
+ void writeback(Addr aMask)
+ {
+ int curHead = descHead();
+ int max_to_wb = usedCache.size() + curHead;
+
+ DPRINTF(EthernetDesc, "Writing back descriptors head: %d tail: "
+ "%d len: %d cachePnt: %d max_to_wb: %d descleft: %d\n",
+ curHead, descTail(), descLen(), cachePnt, max_to_wb,
+ descLeft());
+
+ // Check if this writeback is less restrictive that the previous
+ // and if so setup another one immediately following it
+ if (wbOut && (aMask < wbAlignment)) {
+ moreToWb = true;
+ wbAlignment = aMask;
+ DPRINTF(EthernetDesc, "Writing back already in process, returning\n");
+ return;
+ }
+
+
+ moreToWb = false;
+ wbAlignment = aMask;
+
+ if (max_to_wb > descLen()) {
+ max_to_wb = descLen() - curHead;
+ moreToWb = true;
+ // this is by definition aligned correctly
+ } else if (aMask != 0) {
+ // align the wb point to the mask
+ max_to_wb = max_to_wb & ~(aMask>>4);
+ }
+
+ DPRINTF(EthernetDesc, "Writing back %d descriptors\n", max_to_wb);
+
+ if (max_to_wb <= 0 || wbOut)
+ return;
+
+ wbOut = max_to_wb - curHead;
+
+ for (int x = 0; x < wbOut; x++)
+ memcpy(&wbBuf[x], usedCache[x], sizeof(T));
+
+ for (int x = 0; x < wbOut; x++) {
+ assert(usedCache.size());
+ delete usedCache[0];
+ usedCache.pop_front();
+ };
+
+ igbe->dmaWrite(descBase() + curHead * sizeof(T), wbOut * sizeof(T),
+ &wbEvent, (uint8_t*)wbBuf);
+ }
+
+ /** Fetch a chunk of descriptors into the descriptor cache.
+ * Calls fetchComplete when the memory system returns the data
+ */
+ void fetchDescriptors()
+ {
+ size_t max_to_fetch = cachePnt - descTail();
+ if (max_to_fetch < 0)
+ max_to_fetch = descLen() - cachePnt;
+
+ max_to_fetch = std::min(max_to_fetch, (size - usedCache.size() -
+ unusedCache.size()));
+
+ DPRINTF(EthernetDesc, "Fetching descriptors head: %d tail: "
+ "%d len: %d cachePnt: %d max_to_wb: %d descleft: %d\n",
+ descHead(), descTail(), descLen(), cachePnt,
+ max_to_fetch, descLeft());
+
+ // Nothing to do
+ if (max_to_fetch == 0 || curFetching)
+ return;
+
+ // So we don't have two descriptor fetches going on at once
+ curFetching = max_to_fetch;
+
+ igbe->dmaRead(descBase() + cachePnt * sizeof(T),
+ curFetching * sizeof(T), &fetchEvent, (uint8_t*)fetchBuf);
+ }
+
+
+ /** Called by event when dma to read descriptors is completed
+ */
+ void fetchComplete()
+ {
+ T *newDesc;
+ for (int x = 0; x < curFetching; x++) {
+ newDesc = new T;
+ memcpy(newDesc, &fetchBuf[x], sizeof(T));
+ unusedCache.push_back(newDesc);
+ }
+
+#ifndef NDEBUG
+ int oldCp = cachePnt;
+#endif
+
+ cachePnt += curFetching;
+ if (cachePnt > descLen())
+ cachePnt -= descLen();
+
+ DPRINTF(EthernetDesc, "Fetching complete cachePnt %d -> %d\n",
+ oldCp, cachePnt);
+
+ enableSm();
+
+ }
+
+ EventWrapper<DescCache, &DescCache::fetchComplete> fetchEvent;
+
+ /** Called by event when dma to writeback descriptors is completed
+ */
+ void wbComplete()
+ {
+ long curHead = descHead();
+#ifndef NDEBUG
+ long oldHead = curHead;
+#endif
+
+ curHead += wbOut;
+ wbOut = 0;
+
+ if (curHead > descLen())
+ curHead = 0;
+
+ // Update the head
+ updateHead(curHead);
+
+ DPRINTF(EthernetDesc, "Writeback complete cachePnt %d -> %d\n",
+ oldHead, curHead);
+
+ // If we still have more to wb, call wb now
+ if (moreToWb) {
+ DPRINTF(EthernetDesc, "Writeback has more todo\n");
+ writeback(wbAlignment);
+ }
+ }
+
+
+ EventWrapper<DescCache, &DescCache::wbComplete> wbEvent;
+
+ /* Return the number of descriptors left in the ring, so the device has
+ * a way to figure out if it needs to interrupt.
+ */
+ int descLeft() const
+ {
+ int left = unusedCache.size();
+ if (cachePnt - descTail() >= 0)
+ left += (cachePnt - descTail());
+ else
+ left += (descLen() - cachePnt);
+
+ return left;
+ }
+
+ /* Return the number of descriptors used and not written back.
+ */
+ int descUsed() const { return usedCache.size(); }
+
+ /* Return the number of cache unused descriptors we have. */
+ int descUnused() const {return unusedCache.size(); }
+
+ /* Get into a state where the descriptor address/head/etc colud be
+ * changed */
+ void reset()
+ {
+ DPRINTF(EthernetDesc, "Reseting descriptor cache\n");
+ for (int x = 0; x < usedCache.size(); x++)
+ delete usedCache[x];
+ for (int x = 0; x < unusedCache.size(); x++)
+ delete unusedCache[x];
+
+ usedCache.clear();
+ unusedCache.clear();
+ }
+
+ };
+
+
+ class RxDescCache : public DescCache<iGbReg::RxDesc>
+ {
+ protected:
+ virtual Addr descBase() const { return igbe->regs.rdba(); }
+ virtual long descHead() const { return igbe->regs.rdh(); }
+ virtual long descLen() const { return igbe->regs.rdlen() >> 4; }
+ virtual long descTail() const { return igbe->regs.rdt(); }
+ virtual void updateHead(long h) { igbe->regs.rdh(h); }
+ virtual void enableSm();
+
+ bool pktDone;
+
+ public:
+ RxDescCache(IGbE *i, std::string n, int s);
+
+ /** Write the given packet into the buffer(s) pointed to by the
+ * descriptor and update the book keeping. Should only be called when
+ * there are no dma's pending.
+ * @param packet ethernet packet to write
+ * @return if the packet could be written (there was a free descriptor)
+ */
+ bool writePacket(EthPacketPtr packet);
+ /** Called by event when dma to write packet is completed
+ */
+ void pktComplete();
+
+ /** Check if the dma on the packet has completed.
+ */
+
+ bool packetDone();
+
+ EventWrapper<RxDescCache, &RxDescCache::pktComplete> pktEvent;
+
+ };
+ friend class RxDescCache;
+
+ RxDescCache rxDescCache;
+
+ class TxDescCache : public DescCache<iGbReg::TxDesc>
+ {
+ protected:
+ virtual Addr descBase() const { return igbe->regs.tdba(); }
+ virtual long descHead() const { return igbe->regs.tdh(); }
+ virtual long descTail() const { return igbe->regs.tdt(); }
+ virtual long descLen() const { return igbe->regs.tdlen() >> 4; }
+ virtual void updateHead(long h) { igbe->regs.tdh(h); }
+ virtual void enableSm();
+
+ bool pktDone;
+ bool isTcp;
+ bool pktWaiting;
+
+ public:
+ TxDescCache(IGbE *i, std::string n, int s);
+
+ /** Tell the cache to DMA a packet from main memory into its buffer and
+ * return the size the of the packet to reserve space in tx fifo.
+ * @return size of the packet
+ */
+ int getPacketSize();
+ void getPacketData(EthPacketPtr p);
+
+ /** Ask if the packet has been transfered so the state machine can give
+ * it to the fifo.
+ * @return packet available in descriptor cache
+ */
+ bool packetAvailable();
+
+ /** Ask if we are still waiting for the packet to be transfered.
+ * @return packet still in transit.
+ */
+ bool packetWaiting() { return pktWaiting; }
+
+ /** Called by event when dma to write packet is completed
+ */
+ void pktComplete();
+ EventWrapper<TxDescCache, &TxDescCache::pktComplete> pktEvent;
+
+ };
+ friend class TxDescCache;
+
+ TxDescCache txDescCache;
public:
struct Params : public PciDev::Params
{
- ;
+ bool use_flow_control;
+ int rx_fifo_size;
+ int tx_fifo_size;
+ int rx_desc_cache_size;
+ int tx_desc_cache_size;
+ Tick clock;
};
IGbE(Params *params);
~IGbE() {;}
+ Tick clock;
+ inline Tick cycles(int numCycles) const { return numCycles * clock; }
+
virtual Tick read(PacketPtr pkt);
virtual Tick write(PacketPtr pkt);
@@ -76,6 +491,7 @@ class IGbE : public PciDev
void setEthInt(IGbEInt *i) { assert(!etherInt); etherInt = i; }
+
const Params *params() const {return (const Params *)_params; }
virtual void serialize(std::ostream &os);
diff --git a/src/dev/i8254xGBe_defs.hh b/src/dev/i8254xGBe_defs.hh
index ae0925356..d9648a7c2 100644
--- a/src/dev/i8254xGBe_defs.hh
+++ b/src/dev/i8254xGBe_defs.hh
@@ -31,433 +31,570 @@
/* @file
* Register and structure descriptions for Intel's 8254x line of gigabit ethernet controllers.
*/
+#include "base/bitfield.hh"
namespace iGbReg {
-const uint32_t CTRL = 0x00000; //*
-const uint32_t STATUS = 0x00008; //*
-const uint32_t EECD = 0x00010; //*
-const uint32_t EERD = 0x00014; //*
-const uint32_t CTRL_EXT = 0x00018;
-const uint32_t PBA = 0x01000;
-const uint32_t ICR = 0x000C0; //*
-const uint32_t ITR = 0x000C4;
-const uint32_t ICS = 0x000C8;
-const uint32_t IMS = 0x000D0;
-const uint32_t IMC = 0x000D8; //*
-const uint32_t RCTL = 0x00100; //*
-const uint32_t RDBAL = 0x02800;
-const uint32_t RDBAH = 0x02804;
-const uint32_t RDLEN = 0x02808;
-const uint32_t RDH = 0x02810;
-const uint32_t RDT = 0x02818;
-const uint32_t RDTR = 0x02820;
-const uint32_t RADV = 0x0282C;
-const uint32_t RSRPD = 0x02C00;
-const uint32_t TCTL = 0x00400; //*
-const uint32_t TDBAL = 0x03800;
-const uint32_t TDBAH = 0x03804;
-const uint32_t TDLEN = 0x03808;
-const uint32_t TDH = 0x03810;
-const uint32_t THT = 0x03818;
-const uint32_t TIDV = 0x03820;
-const uint32_t TXDMAC = 0x03000;
-const uint32_t TXDCTL = 0x03828;
-const uint32_t TADV = 0x0282C;
-const uint32_t TSPMT = 0x03830;
-const uint32_t RXDCTL = 0x02828;
-const uint32_t RXCSUM = 0x05000;
-const uint32_t MANC = 0x05820;//*
+
+// Registers used by the Intel GbE NIC
+const uint32_t REG_CTRL = 0x00000;
+const uint32_t REG_STATUS = 0x00008;
+const uint32_t REG_EECD = 0x00010;
+const uint32_t REG_EERD = 0x00014;
+const uint32_t REG_CTRL_EXT = 0x00018;
+const uint32_t REG_MDIC = 0x00020;
+const uint32_t REG_FCAL = 0x00028;
+const uint32_t REG_FCAH = 0x0002C;
+const uint32_t REG_FCT = 0x00030;
+const uint32_t REG_VET = 0x00038;
+const uint32_t REG_PBA = 0x01000;
+const uint32_t REG_ICR = 0x000C0;
+const uint32_t REG_ITR = 0x000C4;
+const uint32_t REG_ICS = 0x000C8;
+const uint32_t REG_IMS = 0x000D0;
+const uint32_t REG_IMC = 0x000D8;
+const uint32_t REG_IAM = 0x000E0;
+const uint32_t REG_RCTL = 0x00100;
+const uint32_t REG_FCTTV = 0x00170;
+const uint32_t REG_TIPG = 0x00410;
+const uint32_t REG_AIFS = 0x00458;
+const uint32_t REG_LEDCTL = 0x00e00;
+const uint32_t REG_FCRTL = 0x02160;
+const uint32_t REG_FCRTH = 0x02168;
+const uint32_t REG_RDBAL = 0x02800;
+const uint32_t REG_RDBAH = 0x02804;
+const uint32_t REG_RDLEN = 0x02808;
+const uint32_t REG_RDH = 0x02810;
+const uint32_t REG_RDT = 0x02818;
+const uint32_t REG_RDTR = 0x02820;
+const uint32_t REG_RXDCTL = 0x02828;
+const uint32_t REG_RADV = 0x0282C;
+const uint32_t REG_TCTL = 0x00400;
+const uint32_t REG_TDBAL = 0x03800;
+const uint32_t REG_TDBAH = 0x03804;
+const uint32_t REG_TDLEN = 0x03808;
+const uint32_t REG_TDH = 0x03810;
+const uint32_t REG_TDT = 0x03818;
+const uint32_t REG_TIDV = 0x03820;
+const uint32_t REG_TXDCTL = 0x03828;
+const uint32_t REG_TADV = 0x0382C;
+const uint32_t REG_CRCERRS = 0x04000;
+const uint32_t REG_RXCSUM = 0x05000;
+const uint32_t REG_MTA = 0x05200;
+const uint32_t REG_RAL = 0x05400;
+const uint32_t REG_RAH = 0x05404;
+const uint32_t REG_VFTA = 0x05600;
+
+const uint32_t REG_WUC = 0x05800;
+const uint32_t REG_MANC = 0x05820;
const uint8_t EEPROM_READ_OPCODE_SPI = 0x03;
const uint8_t EEPROM_RDSR_OPCODE_SPI = 0x05;
const uint8_t EEPROM_SIZE = 64;
+const uint16_t EEPROM_CSUM = 0xBABA;
+
+const uint8_t VLAN_FILTER_TABLE_SIZE = 128;
+const uint8_t RCV_ADDRESS_TABLE_SIZE = 16;
+const uint8_t MULTICAST_TABLE_SIZE = 128;
+const uint32_t STATS_REGS_SIZE = 0x124;
+
+
+// Registers in that are accessed in the PHY
+const uint8_t PHY_PSTATUS = 0x1;
+const uint8_t PHY_PID = 0x2;
+const uint8_t PHY_EPID = 0x3;
+const uint8_t PHY_GSTATUS = 10;
+const uint8_t PHY_EPSTATUS = 15;
+const uint8_t PHY_AGC = 18;
+
+// Receive Descriptor Status Flags
+const uint8_t RXDS_PIF = 0x80;
+const uint8_t RXDS_IPCS = 0x40;
+const uint8_t RXDS_TCPCS = 0x20;
+const uint8_t RXDS_UDPCS = 0x10;
+const uint8_t RXDS_VP = 0x08;
+const uint8_t RXDS_IXSM = 0x04;
+const uint8_t RXDS_EOP = 0x02;
+const uint8_t RXDS_DD = 0x01;
+// Receive Descriptor Error Flags
+const uint8_t RXDE_RXE = 0x80;
+const uint8_t RXDE_IPE = 0x40;
+const uint8_t RXDE_TCPE = 0x20;
+const uint8_t RXDE_SEQ = 0x04;
+const uint8_t RXDE_SE = 0x02;
+const uint8_t RXDE_CE = 0x01;
+
+// Interrupt types
+enum IntTypes
+{
+ IT_NONE = 0x00000, //dummy value
+ IT_TXDW = 0x00001,
+ IT_TXQE = 0x00002,
+ IT_LSC = 0x00004,
+ IT_RXSEQ = 0x00008,
+ IT_RXDMT = 0x00010,
+ IT_RXO = 0x00040,
+ IT_RXT = 0x00080,
+ IT_MADC = 0x00200,
+ IT_RXCFG = 0x00400,
+ IT_GPI0 = 0x02000,
+ IT_GPI1 = 0x04000,
+ IT_TXDLOW = 0x08000,
+ IT_SRPD = 0x10000,
+ IT_ACK = 0x20000
+};
+
+// Receive Descriptor struct
struct RxDesc {
Addr buf;
uint16_t len;
uint16_t csum;
- union {
- uint8_t status;
- struct { // these may be in the worng order
- uint8_t dd:1; // descriptor done (hw is done when 1)
- uint8_t eop:1; // end of packet
- uint8_t xism:1; // ignore checksum
- uint8_t vp:1; // packet is vlan packet
- uint8_t rsv:1; // reserved
- uint8_t tcpcs:1; // TCP checksum done
- uint8_t ipcs:1; // IP checksum done
- uint8_t pif:1; // passed in-exact filter
- } st;
- };
- union {
- uint8_t errors;
- struct {
- uint8_t ce:1; // crc error or alignment error
- uint8_t se:1; // symbol error
- uint8_t seq:1; // sequence error
- uint8_t rsv:1; // reserved
- uint8_t cxe:1; // carrier extension error
- uint8_t tcpe:1; // tcp checksum error
- uint8_t ipe:1; // ip checksum error
- uint8_t rxe:1; // PX data error
- } er;
- };
- union {
- uint16_t special;
- struct {
- uint16_t vlan:12; //vlan id
- uint16_t cfi:1; // canocial form id
- uint16_t pri:3; // user priority
- } sp;
- };
+ uint8_t status;
+ uint8_t errors;
+ uint16_t vlan;
};
-union TxDesc {
- uint8_t data[16];
- struct {
- Addr buf;
- uint16_t len;
- uint8_t cso;
- union {
- uint8_t command;
- struct {
- uint8_t eop:1; // end of packet
- uint8_t ifcs:1; // insert crc
- uint8_t ic:1; // insert checksum
- uint8_t rs:1; // report status
- uint8_t rps:1; // report packet sent
- uint8_t dext:1; // extension
- uint8_t vle:1; // vlan enable
- uint8_t ide:1; // interrupt delay enable
- } cmd;
- };
- union {
- uint8_t status:4;
- struct {
- uint8_t dd:1; // descriptor done
- uint8_t ec:1; // excess collisions
- uint8_t lc:1; // late collision
- uint8_t tu:1; // transmit underrun
- } st;
- };
- uint8_t reserved:4;
- uint8_t css;
- union {
- uint16_t special;
- struct {
- uint16_t vlan:12; //vlan id
- uint16_t cfi:1; // canocial form id
- uint16_t pri:3; // user priority
- } sp;
- };
- } legacy;
-
- // Type 0000 descriptor
- struct {
- uint8_t ipcss;
- uint8_t ipcso;
- uint16_t ipcse;
- uint8_t tucss;
- uint8_t tucso;
- uint16_t tucse;
- uint32_t paylen:20;
- uint8_t dtype:4;
- union {
- uint8_t tucommand;
- struct {
- uint8_t tcp:1; // tcp/udp
- uint8_t ip:1; // ip ipv4/ipv6
- uint8_t tse:1; // tcp segment enbale
- uint8_t rs:1; // report status
- uint8_t rsv0:1; // reserved
- uint8_t dext:1; // descriptor extension
- uint8_t rsv1:1; // reserved
- uint8_t ide:1; // interrupt delay enable
- } tucmd;
- };
- union {
- uint8_t status:4;
- struct {
- uint8_t dd:1;
- uint8_t rsvd:3;
- } sta;
- };
- uint8_t reserved:4;
- uint8_t hdrlen;
- uint16_t mss;
- } t0;
-
- // Type 0001 descriptor
- struct {
- Addr buf;
- uint32_t dtalen:20;
- uint8_t dtype:4;
- union {
- uint8_t dcommand;
- struct {
- uint8_t eop:1; // end of packet
- uint8_t ifcs:1; // insert crc
- uint8_t tse:1; // segmentation enable
- uint8_t rs:1; // report status
- uint8_t rps:1; // report packet sent
- uint8_t dext:1; // extension
- uint8_t vle:1; // vlan enable
- uint8_t ide:1; // interrupt delay enable
- } dcmd;
- };
- union {
- uint8_t status:4;
- struct {
- uint8_t dd:1; // descriptor done
- uint8_t ec:1; // excess collisions
- uint8_t lc:1; // late collision
- uint8_t tu:1; // transmit underrun
- } sta;
- };
- union {
- uint8_t pktopts;
- struct {
- uint8_t ixsm:1; // insert ip checksum
- uint8_t txsm:1; // insert tcp checksum
- };
- };
- union {
- uint16_t special;
- struct {
- uint16_t vlan:12; //vlan id
- uint16_t cfi:1; // canocial form id
- uint16_t pri:3; // user priority
- } sp;
- };
- } t1;
-
- // Junk to test descriptor type!
- struct {
- uint64_t junk;
- uint32_t junk1:20;
- uint8_t dtype;
- uint8_t junk2:5;
- uint8_t dext:1;
- uint8_t junk3:2;
- uint8_t junk4:4;
- uint32_t junk5;
- } type;
+struct TxDesc {
+ uint64_t d1;
+ uint64_t d2;
};
+namespace TxdOp {
+const uint8_t TXD_CNXT = 0x0;
+const uint8_t TXD_DATA = 0x0;
+
+bool isLegacy(TxDesc *d) { return !bits(d->d2,29,29); }
+uint8_t getType(TxDesc *d) { return bits(d->d2, 23,20); }
+bool isContext(TxDesc *d) { return !isLegacy(d) && getType(d) == TXD_CNXT; }
+bool isData(TxDesc *d) { return !isLegacy(d) && getType(d) == TXD_DATA; }
+
+Addr getBuf(TxDesc *d) { assert(isLegacy(d) || isData(d)); return d->d1; }
+Addr getLen(TxDesc *d) { if (isLegacy(d)) return bits(d->d2,15,0); else return bits(d->d2, 19,0); }
+void setDd(TxDesc *d)
+{
+ replaceBits(d->d1, 35, 32, 1);
+}
+
+bool ide(TxDesc *d) { return bits(d->d2, 31,31); }
+bool vle(TxDesc *d) { assert(isLegacy(d) || isData(d)); return bits(d->d2, 30,30); }
+bool rs(TxDesc *d) { return bits(d->d2, 28,28); }
+bool ic(TxDesc *d) { assert(isLegacy(d) || isData(d)); return isLegacy(d) && bits(d->d2, 27,27); }
+bool tse(TxDesc *d) { return (isData(d) || isContext(d)) && bits(d->d2, 27,27); }
+bool ifcs(TxDesc *d) { assert(isLegacy(d) || isData(d)); return bits(d->d2, 26,26); }
+bool eop(TxDesc *d) { assert(isLegacy(d) || isData(d)); return bits(d->d2, 25,25); }
+bool ip(TxDesc *d) { assert(isContext(d)); return bits(d->d2, 26,26); }
+bool tcp(TxDesc *d) { assert(isContext(d)); return bits(d->d2, 25,25); }
+
+uint8_t getCso(TxDesc *d) { assert(isLegacy(d)); return bits(d->d2, 23,16); }
+uint8_t getCss(TxDesc *d) { assert(isLegacy(d)); return bits(d->d2, 47,40); }
+
+bool ixsm(TxDesc *d) { return isData(d) && bits(d->d2, 40,40); }
+bool txsm(TxDesc *d) { return isData(d) && bits(d->d2, 41,41); }
+
+int tucse(TxDesc *d) { assert(isContext(d)); return bits(d->d1,63,48); }
+int tucso(TxDesc *d) { assert(isContext(d)); return bits(d->d1,47,40); }
+int tucss(TxDesc *d) { assert(isContext(d)); return bits(d->d1,39,32); }
+int ipcse(TxDesc *d) { assert(isContext(d)); return bits(d->d1,31,16); }
+int ipcso(TxDesc *d) { assert(isContext(d)); return bits(d->d1,15,8); }
+int ipcss(TxDesc *d) { assert(isContext(d)); return bits(d->d1,7,0); }
+int mss(TxDesc *d) { assert(isContext(d)); return bits(d->d2,63,48); }
+int hdrlen(TxDesc *d) { assert(isContext(d)); return bits(d->d2,47,40); }
+} // namespace TxdOp
+
+
+#define ADD_FIELD32(NAME, OFFSET, BITS) \
+ inline uint32_t NAME() { return bits(_data, OFFSET+BITS-1, OFFSET); } \
+ inline void NAME(uint32_t d) { replaceBits(_data, OFFSET+BITS-1, OFFSET,d); }
+
+#define ADD_FIELD64(NAME, OFFSET, BITS) \
+ inline uint64_t NAME() { return bits(_data, OFFSET+BITS-1, OFFSET); } \
+ inline void NAME(uint64_t d) { replaceBits(_data, OFFSET+BITS-1, OFFSET,d); }
+
struct Regs {
- union { // 0x0000 CTRL Register
- uint32_t reg;
- struct {
- uint8_t fd:1; // full duplex
- uint8_t bem:1; // big endian mode
- uint8_t pcipr:1; // PCI priority
- uint8_t lrst:1; // link reset
- uint8_t tme:1; // test mode enable
- uint8_t asde:1; // Auto-speed detection
- uint8_t slu:1; // Set link up
- uint8_t ilos:1; // invert los-of-signal
- uint8_t speed:2; // speed selection bits
- uint8_t be32:1; // big endian mode 32
- uint8_t frcspd:1; // force speed
- uint8_t frcdpx:1; // force duplex
- uint8_t duden:1; // dock/undock enable
- uint8_t dudpol:1; // dock/undock polarity
- uint8_t fphyrst:1; // force phy reset
- uint8_t extlen:1; // external link status enable
- uint8_t rsvd:1; // reserved
- uint8_t sdp0d:1; // software controlled pin data
- uint8_t sdp1d:1; // software controlled pin data
- uint8_t sdp2d:1; // software controlled pin data
- uint8_t sdp3d:1; // software controlled pin data
- uint8_t sdp0i:1; // software controlled pin dir
- uint8_t sdp1i:1; // software controlled pin dir
- uint8_t sdp2i:1; // software controlled pin dir
- uint8_t sdp3i:1; // software controlled pin dir
- uint8_t rst:1; // reset
- uint8_t rfce:1; // receive flow control enable
- uint8_t tfce:1; // transmit flow control enable
- uint8_t rte:1; // routing tag enable
- uint8_t vme:1; // vlan enable
- uint8_t phyrst:1; // phy reset
- } ;
- } ctrl;
-
- union { // 0x0008 STATUS
- uint32_t reg;
- struct {
- uint8_t fd:1; // full duplex
- uint8_t lu:1; // link up
- uint8_t func:2; // function id
- uint8_t txoff:1; // transmission paused
- uint8_t tbimode:1; // tbi mode
- uint8_t speed:2; // link speed
- uint8_t asdv:2; // auto speed detection value
- uint8_t mtxckok:1; // mtx clock running ok
- uint8_t pci66:1; // In 66Mhz pci slot
- uint8_t bus64:1; // in 64 bit slot
- uint8_t pcix:1; // Pci mode
- uint8_t pcixspd:1; // pci x speed
- uint8_t reserved; // reserved
- } ;
- } sts;
-
- union { // 0x0010 EECD
- uint32_t reg;
- struct {
- uint8_t sk:1; // clack input to the eeprom
- uint8_t cs:1; // chip select to eeprom
- uint8_t din:1; // data input to eeprom
- uint8_t dout:1; // data output bit
- uint8_t fwe:2; // flash write enable
- uint8_t ee_req:1; // request eeprom access
- uint8_t ee_gnt:1; // grant eeprom access
- uint8_t ee_pres:1; // eeprom present
- uint8_t ee_size:1; // eeprom size
- uint8_t ee_sz1:1; // eeprom size
- uint8_t rsvd:2; // reserved
- uint8_t ee_type:1; // type of eeprom
- } ;
- } eecd;
-
- union { // 0x0014 EERD
- uint32_t reg;
- struct {
- uint8_t start:1; // start read
- uint8_t done:1; // done read
- uint16_t addr:14; // address
- uint16_t data; // data
- };
- } eerd;
-
- union { // 0x00C0 ICR
- uint32_t reg;
- struct {
- uint8_t txdw:1; // tx descr witten back
- uint8_t txqe:1; // tx queue empty
- uint8_t lsc:1; // link status change
- uint8_t rxseq:1; // rcv sequence error
- uint8_t rxdmt0:1; // rcv descriptor min thresh
- uint8_t rsvd1:1; // reserved
- uint8_t rxo:1; // receive overrunn
- uint8_t rxt0:1; // receiver timer interrupt
- uint8_t rsvd2:1; // reserved
- uint8_t mdac:1; // mdi/o access complete
- uint8_t rxcfg:1; // recv /c/ ordered sets
- uint8_t rsvd3:1; // reserved
- uint8_t phyint:1; // phy interrupt
- uint8_t gpi1:1; // gpi int 1
- uint8_t gpi2:1; // gpi int 2
- uint8_t txdlow:1; // transmit desc low thresh
- uint8_t srpd:1; // small receive packet detected
- uint16_t rsvd4:15; // reserved
- } ;
- } icd;
-
- union { // 0x00C0 IMC
- uint32_t reg;
- struct {
- uint8_t txdw:1; // tx descr witten back
- uint8_t txqe:1; // tx queue empty
- uint8_t lsc:1; // link status change
- uint8_t rxseq:1; // rcv sequence error
- uint8_t rxdmt0:1; // rcv descriptor min thresh
- uint8_t rsvd1:1; // reserved
- uint8_t rxo:1; // receive overrunn
- uint8_t rxt0:1; // receiver timer interrupt
- uint8_t rsvd2:1; // reserved
- uint8_t mdac:1; // mdi/o access complete
- uint8_t rxcfg:1; // recv /c/ ordered sets
- uint8_t rsvd3:1; // reserved
- uint8_t phyint:1; // phy interrupt
- uint8_t gpi1:1; // gpi int 1
- uint8_t gpi2:1; // gpi int 2
- uint8_t txdlow:1; // transmit desc low thresh
- uint8_t srpd:1; // small receive packet detected
- uint16_t rsvd4:15; // reserved
- } ;
- } imc;
-
- union { // 0x0100 RCTL
- uint32_t reg;
- struct {
- uint8_t rst:1; // Reset
- uint8_t en:1; // Enable
- uint8_t sbp:1; // Store bad packets
- uint8_t upe:1; // Unicast Promiscuous enabled
- uint8_t mpe:1; // Multicast promiscuous enabled
- uint8_t lpe:1; // long packet reception enabled
- uint8_t lbm:2; //
- uint8_t rdmts:2; //
- uint8_t rsvd:2; //
- uint8_t mo:2; //
- uint8_t mdr:1; //
- uint8_t bam:1; //
- uint8_t bsize:2; //
- uint8_t vpe:1; //
- uint8_t cfien:1; //
- uint8_t cfi:1; //
- uint8_t rsvd2:1; //
- uint8_t dpf:1; // discard pause frames
- uint8_t pmcf:1; // pass mac control frames
- uint8_t rsvd3:1; // reserved
- uint8_t bsex:1; // buffer size extension
- uint8_t secrc:1; // strip ethernet crc from incoming packet
- uint8_t rsvd1:5; // reserved
- } ;
- } rctl;
-
- union { // 0x0400 TCTL
- uint32_t reg;
- struct {
- uint8_t rst:1; // Reset
- uint8_t en:1; // Enable
- uint8_t bce:1; // busy check enable
- uint8_t psp:1; // pad short packets
- uint8_t ct:8; // collision threshold
- uint16_t cold:10; // collision distance
- uint8_t swxoff:1; // software xoff transmission
- uint8_t pbe:1; // packet burst enable
- uint8_t rtlc:1; // retransmit late collisions
- uint8_t nrtu:1; // on underrun no TX
- uint8_t mulr:1; // multiple request
- uint8_t rsvd:5; // reserved
- } ;
- } tctl;
-
- union { // 0x5820 MANC
- uint32_t reg;
- struct {
- uint8_t smbus:1; // SMBus enabled #####
- uint8_t asf:1; // ASF enabled #####
- uint8_t ronforce:1; // reset of force
- uint8_t rsvd:5; // reserved
- uint8_t rmcp1:1; // rcmp1 filtering
- uint8_t rmcp2:1; // rcmp2 filtering
- uint8_t ipv4:1; // enable ipv4
- uint8_t ipv6:1; // enable ipv6
- uint8_t snap:1; // accept snap
- uint8_t arp:1; // filter arp #####
- uint8_t neighbor:1; // neighbor discovery
- uint8_t arp_resp:1; // arp response
- uint8_t tcorst:1; // tco reset happened
- uint8_t rcvtco:1; // receive tco enabled ######
- uint8_t blkphyrst:1;// block phy resets ########
- uint8_t rcvall:1; // receive all
- uint8_t macaddrfltr:1; // mac address filtering ######
- uint8_t mng2host:1; // mng2 host packets #######
- uint8_t ipaddrfltr:1; // ip address filtering
- uint8_t xsumfilter:1; // checksum filtering
- uint8_t brfilter:1; // broadcast filtering
- uint8_t smbreq:1; // smb request
- uint8_t smbgnt:1; // smb grant
- uint8_t smbclkin:1; // smbclkin
- uint8_t smbdatain:1; // smbdatain
- uint8_t smbdataout:1; // smb data out
- uint8_t smbclkout:1; // smb clock out
- uint8_t rsvd2:2;
- };
- } manc;
+ template<class T>
+ struct Reg {
+ T _data;
+ T operator()() { return _data; }
+ const Reg<T> &operator=(T d) { _data = d; return *this;}
+ bool operator==(T d) { return d == _data; }
+ void operator()(T d) { _data = d; }
+ Reg() { _data = 0; }
+ };
+
+ struct CTRL : public Reg<uint32_t> { // 0x0000 CTRL Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(fd,0,1); // full duplex
+ ADD_FIELD32(bem,1,1); // big endian mode
+ ADD_FIELD32(pcipr,2,1); // PCI priority
+ ADD_FIELD32(lrst,3,1); // link reset
+ ADD_FIELD32(tme,4,1); // test mode enable
+ ADD_FIELD32(asde,5,1); // Auto-speed detection
+ ADD_FIELD32(slu,6,1); // Set link up
+ ADD_FIELD32(ilos,7,1); // invert los-of-signal
+ ADD_FIELD32(speed,8,2); // speed selection bits
+ ADD_FIELD32(be32,10,1); // big endian mode 32
+ ADD_FIELD32(frcspd,11,1); // force speed
+ ADD_FIELD32(frcdpx,12,1); // force duplex
+ ADD_FIELD32(duden,13,1); // dock/undock enable
+ ADD_FIELD32(dudpol,14,1); // dock/undock polarity
+ ADD_FIELD32(fphyrst,15,1); // force phy reset
+ ADD_FIELD32(extlen,16,1); // external link status enable
+ ADD_FIELD32(rsvd,17,1); // reserved
+ ADD_FIELD32(sdp0d,18,1); // software controlled pin data
+ ADD_FIELD32(sdp1d,19,1); // software controlled pin data
+ ADD_FIELD32(sdp2d,20,1); // software controlled pin data
+ ADD_FIELD32(sdp3d,21,1); // software controlled pin data
+ ADD_FIELD32(sdp0i,22,1); // software controlled pin dir
+ ADD_FIELD32(sdp1i,23,1); // software controlled pin dir
+ ADD_FIELD32(sdp2i,24,1); // software controlled pin dir
+ ADD_FIELD32(sdp3i,25,1); // software controlled pin dir
+ ADD_FIELD32(rst,26,1); // reset
+ ADD_FIELD32(rfce,27,1); // receive flow control enable
+ ADD_FIELD32(tfce,28,1); // transmit flow control enable
+ ADD_FIELD32(rte,29,1); // routing tag enable
+ ADD_FIELD32(vme,30,1); // vlan enable
+ ADD_FIELD32(phyrst,31,1); // phy reset
+ };
+ CTRL ctrl;
+
+ struct STATUS : public Reg<uint32_t> { // 0x0008 STATUS Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(fd,0,1); // full duplex
+ ADD_FIELD32(lu,1,1); // link up
+ ADD_FIELD32(func,2,2); // function id
+ ADD_FIELD32(txoff,4,1); // transmission paused
+ ADD_FIELD32(tbimode,5,1); // tbi mode
+ ADD_FIELD32(speed,6,2); // link speed
+ ADD_FIELD32(asdv,8,2); // auto speed detection value
+ ADD_FIELD32(mtxckok,10,1); // mtx clock running ok
+ ADD_FIELD32(pci66,11,1); // In 66Mhz pci slot
+ ADD_FIELD32(bus64,12,1); // in 64 bit slot
+ ADD_FIELD32(pcix,13,1); // Pci mode
+ ADD_FIELD32(pcixspd,14,2); // pci x speed
+ };
+ STATUS sts;
+
+ struct EECD : public Reg<uint32_t> { // 0x0010 EECD Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(sk,0,1); // clack input to the eeprom
+ ADD_FIELD32(cs,1,1); // chip select to eeprom
+ ADD_FIELD32(din,2,1); // data input to eeprom
+ ADD_FIELD32(dout,3,1); // data output bit
+ ADD_FIELD32(fwe,4,2); // flash write enable
+ ADD_FIELD32(ee_req,6,1); // request eeprom access
+ ADD_FIELD32(ee_gnt,7,1); // grant eeprom access
+ ADD_FIELD32(ee_pres,8,1); // eeprom present
+ ADD_FIELD32(ee_size,9,1); // eeprom size
+ ADD_FIELD32(ee_sz1,10,1); // eeprom size
+ ADD_FIELD32(rsvd,11,2); // reserved
+ ADD_FIELD32(ee_type,13,1); // type of eeprom
+ } ;
+ EECD eecd;
+
+ struct EERD : public Reg<uint32_t> { // 0x0014 EERD Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(start,0,1); // start read
+ ADD_FIELD32(done,4,1); // done read
+ ADD_FIELD32(addr,8,8); // address
+ ADD_FIELD32(data,16,16); // data
+ };
+ EERD eerd;
+
+ struct CTRL_EXT : public Reg<uint32_t> { // 0x0018 CTRL_EXT Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(gpi_en,0,4); // enable interrupts from gpio
+ ADD_FIELD32(phyint,5,1); // reads the phy internal int status
+ ADD_FIELD32(sdp2_data,6,1); // data from gpio sdp
+ ADD_FIELD32(spd3_data,7,1); // data frmo gpio sdp
+ ADD_FIELD32(spd2_iodir,10,1); // direction of sdp2
+ ADD_FIELD32(spd3_iodir,11,1); // direction of sdp2
+ ADD_FIELD32(asdchk,12,1); // initiate auto-speed-detection
+ ADD_FIELD32(eerst,13,1); // reset the eeprom
+ ADD_FIELD32(spd_byps,15,1); // bypass speed select
+ ADD_FIELD32(ro_dis,17,1); // disable relaxed memory ordering
+ ADD_FIELD32(vreg,21,1); // power down the voltage regulator
+ ADD_FIELD32(link_mode,22,2); // interface to talk to the link
+ ADD_FIELD32(iame, 27,1); // interrupt acknowledge auto-mask ??
+ ADD_FIELD32(drv_loaded, 28,1);// driver is loaded and incharge of device
+ ADD_FIELD32(timer_clr, 29,1); // clear interrupt timers after IMS clear ??
+ };
+ CTRL_EXT ctrl_ext;
+
+ struct MDIC : public Reg<uint32_t> { // 0x0020 MDIC Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(data,0,16); // data
+ ADD_FIELD32(regadd,16,5); // register address
+ ADD_FIELD32(phyadd,21,5); // phy addresses
+ ADD_FIELD32(op,26,2); // opcode
+ ADD_FIELD32(r,28,1); // ready
+ ADD_FIELD32(i,29,1); // interrupt
+ ADD_FIELD32(e,30,1); // error
+ };
+ MDIC mdic;
+
+ struct ICR : public Reg<uint32_t> { // 0x00C0 ICR Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(txdw,0,1) // tx descr witten back
+ ADD_FIELD32(txqe,1,1) // tx queue empty
+ ADD_FIELD32(lsc,2,1) // link status change
+ ADD_FIELD32(rxseq,3,1) // rcv sequence error
+ ADD_FIELD32(rxdmt0,4,1) // rcv descriptor min thresh
+ ADD_FIELD32(rsvd1,5,1) // reserved
+ ADD_FIELD32(rxo,6,1) // receive overrunn
+ ADD_FIELD32(rxt0,7,1) // receiver timer interrupt
+ ADD_FIELD32(mdac,9,1) // mdi/o access complete
+ ADD_FIELD32(rxcfg,10,1) // recv /c/ ordered sets
+ ADD_FIELD32(phyint,12,1) // phy interrupt
+ ADD_FIELD32(gpi1,13,1) // gpi int 1
+ ADD_FIELD32(gpi2,14,1) // gpi int 2
+ ADD_FIELD32(txdlow,15,1) // transmit desc low thresh
+ ADD_FIELD32(srpd,16,1) // small receive packet detected
+ ADD_FIELD32(ack,17,1); // receive ack frame
+ ADD_FIELD32(int_assert, 31,0); // interrupt caused a system interrupt
+ };
+ ICR icr;
+
+ uint32_t imr; // register that contains the current interrupt mask
+
+ struct ITR : public Reg<uint32_t> { // 0x00C4 ITR Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(interval, 0,16); // minimum inter-interrutp inteval
+ // specified in 256ns interrupts
+ };
+ ITR itr;
+
+ // When CTRL_EXT.IAME and the ICR.INT_ASSERT is 1 an ICR read or write
+ // causes the IAM register contents to be written into the IMC
+ // automatically clearing all interrupts that have a bit in the IAM set
+ uint32_t iam;
+
+ struct RCTL : public Reg<uint32_t> { // 0x0100 RCTL Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(rst,0,1); // Reset
+ ADD_FIELD32(en,1,1); // Enable
+ ADD_FIELD32(sbp,2,1); // Store bad packets
+ ADD_FIELD32(upe,3,1); // Unicast Promiscuous enabled
+ ADD_FIELD32(mpe,4,1); // Multicast promiscuous enabled
+ ADD_FIELD32(lpe,5,1); // long packet reception enabled
+ ADD_FIELD32(lbm,6,2); //
+ ADD_FIELD32(rdmts,8,2); //
+ ADD_FIELD32(mo,12,2); //
+ ADD_FIELD32(mdr,14,1); //
+ ADD_FIELD32(bam,15,1); //
+ ADD_FIELD32(bsize,16,2); //
+ ADD_FIELD32(vfe,18,1); //
+ ADD_FIELD32(cfien,19,1); //
+ ADD_FIELD32(cfi,20,1); //
+ ADD_FIELD32(dpf,22,1); // discard pause frames
+ ADD_FIELD32(pmcf,23,1); // pass mac control frames
+ ADD_FIELD32(bsex,25,1); // buffer size extension
+ ADD_FIELD32(secrc,26,1); // strip ethernet crc from incoming packet
+ int descSize()
+ {
+ switch(bsize()) {
+ case 0: return bsex() ? 2048 : -1;
+ case 1: return bsex() ? 1024 : 16384;
+ case 2: return bsex() ? 512 : 8192;
+ case 3: return bsex() ? 256 : 4096;
+ default:
+ return -1;
+ }
+ }
+ };
+ RCTL rctl;
+
+ struct FCTTV : public Reg<uint32_t> { // 0x0170 FCTTV
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(ttv,0,16); // Transmit Timer Value
+ };
+ FCTTV fcttv;
+
+ struct TCTL : public Reg<uint32_t> { // 0x0400 TCTL Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(rst,0,1); // Reset
+ ADD_FIELD32(en,1,1); // Enable
+ ADD_FIELD32(bce,2,1); // busy check enable
+ ADD_FIELD32(psp,3,1); // pad short packets
+ ADD_FIELD32(ct,4,8); // collision threshold
+ ADD_FIELD32(cold,12,10); // collision distance
+ ADD_FIELD32(swxoff,22,1); // software xoff transmission
+ ADD_FIELD32(pbe,23,1); // packet burst enable
+ ADD_FIELD32(rtlc,24,1); // retransmit late collisions
+ ADD_FIELD32(nrtu,25,1); // on underrun no TX
+ ADD_FIELD32(mulr,26,1); // multiple request
+ };
+ TCTL tctl;
+
+ struct PBA : public Reg<uint32_t> { // 0x1000 PBA Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(rxa,0,16);
+ ADD_FIELD32(txa,16,16);
+ };
+ PBA pba;
+
+ struct FCRTL : public Reg<uint32_t> { // 0x2160 FCRTL Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(rtl,3,28); // make this bigger than the spec so we can have
+ // a larger buffer
+ ADD_FIELD32(xone, 31,1);
+ };
+ FCRTL fcrtl;
+
+ struct FCRTH : public Reg<uint32_t> { // 0x2168 FCRTL Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(rth,3,13); // make this bigger than the spec so we can have
+ //a larger buffer
+ ADD_FIELD32(xfce, 31,1);
+ };
+ FCRTH fcrth;
+
+ struct RDBA : public Reg<uint64_t> { // 0x2800 RDBA Register
+ using Reg<uint64_t>::operator=;
+ ADD_FIELD64(rdbal,4,28); // base address of rx descriptor ring
+ ADD_FIELD64(rdbah,32,32); // base address of rx descriptor ring
+ };
+ RDBA rdba;
+
+ struct RDLEN : public Reg<uint32_t> { // 0x2808 RDLEN Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(len,7,13); // number of bytes in the descriptor buffer
+ };
+ RDLEN rdlen;
+
+ struct RDH : public Reg<uint32_t> { // 0x2810 RDH Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(rdh,0,16); // head of the descriptor ring
+ };
+ RDH rdh;
+
+ struct RDT : public Reg<uint32_t> { // 0x2818 RDT Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(rdt,0,16); // tail of the descriptor ring
+ };
+ RDT rdt;
+
+ struct RDTR : public Reg<uint32_t> { // 0x2820 RDTR Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(delay,0,16); // receive delay timer
+ ADD_FIELD32(fpd, 31,1); // flush partial descriptor block ??
+ };
+ RDTR rdtr;
+
+ struct RXDCTL : public Reg<uint32_t> { // 0x2828 RXDCTL Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(pthresh,0,6); // prefetch threshold, less that this
+ // consider prefetch
+ ADD_FIELD32(hthresh,8,6); // number of descriptors in host mem to
+ // consider prefetch
+ ADD_FIELD32(wthresh,16,6); // writeback threshold
+ ADD_FIELD32(gran,24,1); // granularity 0 = desc, 1 = cacheline
+ };
+ RXDCTL rxdctl;
+
+ struct RADV : public Reg<uint32_t> { // 0x282C RADV Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(idv,0,16); // absolute interrupt delay
+ };
+ RADV radv;
+
+ struct RSRPD : public Reg<uint32_t> { // 0x2C00 RSRPD Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(idv,0,12); // size to interrutp on small packets
+ };
+ RSRPD rsrpd;
+
+ struct TDBA : public Reg<uint64_t> { // 0x3800 TDBAL Register
+ using Reg<uint64_t>::operator=;
+ ADD_FIELD64(tdbal,4,28); // base address of transmit descriptor ring
+ ADD_FIELD64(tdbah,32,32); // base address of transmit descriptor ring
+ };
+ TDBA tdba;
+
+ struct TDLEN : public Reg<uint32_t> { // 0x3808 TDLEN Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(len,7,13); // number of bytes in the descriptor buffer
+ };
+ TDLEN tdlen;
+
+ struct TDH : public Reg<uint32_t> { // 0x3810 TDH Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(tdh,0,16); // head of the descriptor ring
+ };
+ TDH tdh;
+
+ struct TDT : public Reg<uint32_t> { // 0x3818 TDT Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(tdt,0,16); // tail of the descriptor ring
+ };
+ TDT tdt;
+
+ struct TIDV : public Reg<uint32_t> { // 0x3820 TIDV Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(idv,0,16); // interrupt delay
+ };
+ TIDV tidv;
+
+ struct TXDCTL : public Reg<uint32_t> { // 0x3828 TXDCTL Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(pthresh, 0,6); // if number of descriptors control has is
+ // below this number, a prefetch is considered
+ ADD_FIELD32(hthresh,8,8); // number of valid descriptors is host memory
+ // before a prefetch is considered
+ ADD_FIELD32(wthresh,16,6); // number of descriptors to keep until
+ // writeback is considered
+ ADD_FIELD32(gran, 24,1); // granulatiry of above values (0 = cacheline,
+ // 1 == desscriptor)
+ ADD_FIELD32(lwthresh,25,7); // xmit descriptor low thresh, interrupt
+ // below this level
+ };
+ TXDCTL txdctl;
+
+ struct TADV : public Reg<uint32_t> { // 0x382C TADV Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(idv,0,16); // absolute interrupt delay
+ };
+ TADV tadv;
+
+ struct RXCSUM : public Reg<uint32_t> { // 0x5000 RXCSUM Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(pcss,0,8);
+ ADD_FIELD32(ipofld,8,1);
+ ADD_FIELD32(tuofld,9,1);
+ };
+ RXCSUM rxcsum;
+
+ struct MANC : public Reg<uint32_t> { // 0x5820 MANC Register
+ using Reg<uint32_t>::operator=;
+ ADD_FIELD32(smbus,0,1); // SMBus enabled #####
+ ADD_FIELD32(asf,1,1); // ASF enabled #####
+ ADD_FIELD32(ronforce,2,1); // reset of force
+ ADD_FIELD32(rsvd,3,5); // reserved
+ ADD_FIELD32(rmcp1,8,1); // rcmp1 filtering
+ ADD_FIELD32(rmcp2,9,1); // rcmp2 filtering
+ ADD_FIELD32(ipv4,10,1); // enable ipv4
+ ADD_FIELD32(ipv6,11,1); // enable ipv6
+ ADD_FIELD32(snap,12,1); // accept snap
+ ADD_FIELD32(arp,13,1); // filter arp #####
+ ADD_FIELD32(neighbor,14,1); // neighbor discovery
+ ADD_FIELD32(arp_resp,15,1); // arp response
+ ADD_FIELD32(tcorst,16,1); // tco reset happened
+ ADD_FIELD32(rcvtco,17,1); // receive tco enabled ######
+ ADD_FIELD32(blkphyrst,18,1);// block phy resets ########
+ ADD_FIELD32(rcvall,19,1); // receive all
+ ADD_FIELD32(macaddrfltr,20,1); // mac address filtering ######
+ ADD_FIELD32(mng2host,21,1); // mng2 host packets #######
+ ADD_FIELD32(ipaddrfltr,22,1); // ip address filtering
+ ADD_FIELD32(xsumfilter,23,1); // checksum filtering
+ ADD_FIELD32(brfilter,24,1); // broadcast filtering
+ ADD_FIELD32(smbreq,25,1); // smb request
+ ADD_FIELD32(smbgnt,26,1); // smb grant
+ ADD_FIELD32(smbclkin,27,1); // smbclkin
+ ADD_FIELD32(smbdatain,28,1); // smbdatain
+ ADD_FIELD32(smbdataout,29,1); // smb data out
+ ADD_FIELD32(smbclkout,30,1); // smb clock out
+ };
+ MANC manc;
};
}; // iGbReg namespace
diff --git a/src/dev/ide_disk.cc b/src/dev/ide_disk.cc
index 5083c9c8d..9fa0cedde 100644
--- a/src/dev/ide_disk.cc
+++ b/src/dev/ide_disk.cc
@@ -48,7 +48,7 @@
#include "dev/alpha/tsunami_pchip.hh"
#include "sim/builder.hh"
#include "sim/sim_object.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
#include "arch/isa_traits.hh"
using namespace std;
diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh
index c56eba267..cd7a5296a 100644
--- a/src/dev/io_device.hh
+++ b/src/dev/io_device.hh
@@ -132,6 +132,7 @@ class DmaPort : public Port
bool dmaPending() { return pendingCount > 0; }
+ int cacheBlockSize() { return peerBlockSize(); }
unsigned int drain(Event *de);
};
@@ -256,15 +257,22 @@ class DmaDevice : public PioDevice
virtual ~DmaDevice();
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data)
- { dmaPort->dmaAction(Packet::WriteInvalidateReq, addr, size, event, data) ; }
+ {
+ dmaPort->dmaAction(MemCmd::WriteInvalidateReq,
+ addr, size, event, data);
+ }
- void dmaRead(Addr addr, int size, Event *event, uint8_t *data = NULL)
- { dmaPort->dmaAction(Packet::ReadReq, addr, size, event, data); }
+ void dmaRead(Addr addr, int size, Event *event, uint8_t *data)
+ {
+ dmaPort->dmaAction(MemCmd::ReadReq, addr, size, event, data);
+ }
bool dmaPending() { return dmaPort->dmaPending(); }
virtual unsigned int drain(Event *de);
+ int cacheBlockSize() { return dmaPort->cacheBlockSize(); }
+
virtual Port *getPort(const std::string &if_name, int idx = -1)
{
if (if_name == "pio") {
diff --git a/src/dev/ns_gige.cc b/src/dev/ns_gige.cc
index 74f9d88d1..86f56b62e 100644
--- a/src/dev/ns_gige.cc
+++ b/src/dev/ns_gige.cc
@@ -92,28 +92,30 @@ NSGigE::NSGigE(Params *p)
: PciDev(p), ioEnable(false),
txFifo(p->tx_fifo_size), rxFifo(p->rx_fifo_size),
txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL),
- txXferLen(0), rxXferLen(0), clock(p->clock),
- txState(txIdle), txEnable(false), CTDD(false),
+ txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false),
+ clock(p->clock),
+ txState(txIdle), txEnable(false), CTDD(false), txHalt(false),
txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle),
- rxEnable(false), CRDD(false), rxPktBytes(0),
+ rxEnable(false), CRDD(false), rxPktBytes(0), rxHalt(false),
rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false),
- eepromState(eepromStart), rxDmaReadEvent(this), rxDmaWriteEvent(this),
+ eepromState(eepromStart), eepromClk(false), eepromBitsToRx(0),
+ eepromOpcode(0), eepromAddress(0), eepromData(0),
+ dmaReadDelay(p->dma_read_delay), dmaWriteDelay(p->dma_write_delay),
+ dmaReadFactor(p->dma_read_factor), dmaWriteFactor(p->dma_write_factor),
+ rxDmaData(NULL), rxDmaAddr(0), rxDmaLen(0),
+ txDmaData(NULL), txDmaAddr(0), txDmaLen(0),
+ rxDmaReadEvent(this), rxDmaWriteEvent(this),
txDmaReadEvent(this), txDmaWriteEvent(this),
dmaDescFree(p->dma_desc_free), dmaDataFree(p->dma_data_free),
txDelay(p->tx_delay), rxDelay(p->rx_delay),
rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this),
- txEvent(this), rxFilterEnable(p->rx_filter), acceptBroadcast(false),
- acceptMulticast(false), acceptUnicast(false),
+ txEvent(this), rxFilterEnable(p->rx_filter),
+ acceptBroadcast(false), acceptMulticast(false), acceptUnicast(false),
acceptPerfect(false), acceptArp(false), multicastHashEnable(false),
- intrTick(0), cpuPendingIntr(false),
+ intrDelay(p->intr_delay), intrTick(0), cpuPendingIntr(false),
intrEvent(0), interface(0)
{
- intrDelay = p->intr_delay;
- dmaReadDelay = p->dma_read_delay;
- dmaWriteDelay = p->dma_write_delay;
- dmaReadFactor = p->dma_read_factor;
- dmaWriteFactor = p->dma_write_factor;
regsReset();
memcpy(&rom.perfectMatch, p->eaddr.bytes(), ETH_ADDR_LEN);
diff --git a/src/dev/pcidev.cc b/src/dev/pcidev.cc
index 1c2465dd1..f906e69cf 100644
--- a/src/dev/pcidev.cc
+++ b/src/dev/pcidev.cc
@@ -51,7 +51,7 @@
#include "sim/builder.hh"
#include "sim/byteswap.hh"
#include "sim/param.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
using namespace std;
diff --git a/src/dev/platform.hh b/src/dev/platform.hh
index 1940dcad6..aceec0970 100644
--- a/src/dev/platform.hh
+++ b/src/dev/platform.hh
@@ -55,9 +55,6 @@ class Platform : public SimObject
/** Pointer to the interrupt controller */
IntrControl *intrctrl;
- /** Pointer to the UART, set by the uart */
- Uart *uart;
-
/** Pointer to the system for info about the memory system. */
System *system;
diff --git a/src/dev/simconsole.cc b/src/dev/simconsole.cc
index 77aafd9fa..c6ff9c1c6 100644
--- a/src/dev/simconsole.cc
+++ b/src/dev/simconsole.cc
@@ -56,17 +56,31 @@
using namespace std;
-////////////////////////////////////////////////////////////////////////
-//
-//
-SimConsole::Event::Event(SimConsole *c, int fd, int e)
+/*
+ * Poll event for the listen socket
+ */
+SimConsole::ListenEvent::ListenEvent(SimConsole *c, int fd, int e)
: PollEvent(fd, e), cons(c)
{
}
void
-SimConsole::Event::process(int revent)
+SimConsole::ListenEvent::process(int revent)
+{
+ cons->accept();
+}
+
+/*
+ * Poll event for the data socket
+ */
+SimConsole::DataEvent::DataEvent(SimConsole *c, int fd, int e)
+ : PollEvent(fd, e), cons(c)
+{
+}
+
+void
+SimConsole::DataEvent::process(int revent)
{
if (revent & POLLIN)
cons->data();
@@ -74,41 +88,76 @@ SimConsole::Event::process(int revent)
cons->detach();
}
-SimConsole::SimConsole(const string &name, ostream *os, int num)
- : SimObject(name), event(NULL), number(num), in_fd(-1), out_fd(-1),
- listener(NULL), txbuf(16384), rxbuf(16384), outfile(os)
+/*
+ * SimConsole code
+ */
+SimConsole::SimConsole(const string &name, ostream *os, int num, int port)
+ : SimObject(name), listenEvent(NULL), dataEvent(NULL), number(num),
+ data_fd(-1), txbuf(16384), rxbuf(16384), outfile(os)
#if TRACING_ON == 1
, linebuf(16384)
#endif
{
if (outfile)
outfile->setf(ios::unitbuf);
+
+ if (port)
+ listen(port);
}
SimConsole::~SimConsole()
{
- close();
+ if (data_fd != -1)
+ ::close(data_fd);
+
+ if (listenEvent)
+ delete listenEvent;
+
+ if (dataEvent)
+ delete dataEvent;
}
+///////////////////////////////////////////////////////////////////////
+// socket creation and console attach
+//
+
void
-SimConsole::close()
+SimConsole::listen(int port)
{
- if (in_fd != -1)
- ::close(in_fd);
+ while (!listener.listen(port, true)) {
+ DPRINTF(Console,
+ ": can't bind address console port %d inuse PID %d\n",
+ port, getpid());
+ port++;
+ }
- if (out_fd != in_fd && out_fd != -1)
- ::close(out_fd);
+ int p1, p2;
+ p2 = name().rfind('.') - 1;
+ p1 = name().rfind('.', p2);
+ ccprintf(cerr, "Listening for %s connection on port %d\n",
+ name().substr(p1+1,p2-p1), port);
+
+ listenEvent = new ListenEvent(this, listener.getfd(), POLLIN);
+ pollQueue.schedule(listenEvent);
}
void
-SimConsole::attach(int in, int out, ConsoleListener *l)
+SimConsole::accept()
{
- in_fd = in;
- out_fd = out;
- listener = l;
+ if (!listener.islistening())
+ panic("%s: cannot accept a connection if not listening!", name());
- event = new Event(this, in, POLLIN);
- pollQueue.schedule(event);
+ int fd = listener.accept(true);
+ if (data_fd != -1) {
+ char message[] = "console already attached!\n";
+ ::write(fd, message, sizeof(message));
+ ::close(fd);
+ return;
+ }
+
+ data_fd = fd;
+ dataEvent = new DataEvent(this, data_fd, POLLIN);
+ pollQueue.schedule(dataEvent);
stringstream stream;
ccprintf(stream, "==== m5 slave console: Console %d ====", number);
@@ -119,26 +168,23 @@ SimConsole::attach(int in, int out, ConsoleListener *l)
write((const uint8_t *)stream.str().c_str(), stream.str().size());
-
DPRINTFN("attach console %d\n", number);
- txbuf.readall(out);
+ txbuf.readall(data_fd);
}
void
SimConsole::detach()
{
- close();
- in_fd = -1;
- out_fd = -1;
-
- pollQueue.remove(event);
-
- if (listener) {
- listener->add(this);
- listener = NULL;
+ if (data_fd != -1) {
+ ::close(data_fd);
+ data_fd = -1;
}
+ pollQueue.remove(dataEvent);
+ delete dataEvent;
+ dataEvent = NULL;
+
DPRINTFN("detach console %d\n", number);
}
@@ -159,12 +205,12 @@ SimConsole::data()
size_t
SimConsole::read(uint8_t *buf, size_t len)
{
- if (in_fd < 0)
+ if (data_fd < 0)
panic("Console not properly attached.\n");
size_t ret;
do {
- ret = ::read(in_fd, buf, len);
+ ret = ::read(data_fd, buf, len);
} while (ret == -1 && errno == EINTR);
@@ -183,12 +229,12 @@ SimConsole::read(uint8_t *buf, size_t len)
size_t
SimConsole::write(const uint8_t *buf, size_t len)
{
- if (out_fd < 0)
+ if (data_fd < 0)
panic("Console not properly attached.\n");
size_t ret;
for (;;) {
- ret = ::write(out_fd, buf, len);
+ ret = ::write(data_fd, buf, len);
if (ret >= 0)
break;
@@ -268,7 +314,7 @@ SimConsole::out(char c)
txbuf.write(c);
- if (out_fd >= 0)
+ if (data_fd >= 0)
write(c);
if (outfile)
@@ -279,23 +325,11 @@ SimConsole::out(char c)
}
-
-void
-SimConsole::serialize(ostream &os)
-{
-}
-
-void
-SimConsole::unserialize(Checkpoint *cp, const std::string &section)
-{
-}
-
-
BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimConsole)
- SimObjectParam<ConsoleListener *> listener;
SimObjectParam<IntrControl *> intr_control;
Param<string> output;
+ Param<int> port;
Param<bool> append_name;
Param<int> number;
@@ -303,9 +337,9 @@ END_DECLARE_SIM_OBJECT_PARAMS(SimConsole)
BEGIN_INIT_SIM_OBJECT_PARAMS(SimConsole)
- INIT_PARAM(listener, "console listener"),
INIT_PARAM(intr_control, "interrupt controller"),
INIT_PARAM(output, "file to dump output to"),
+ INIT_PARAM(port, ""),
INIT_PARAM_DFLT(append_name, "append name() to filename", true),
INIT_PARAM_DFLT(number, "console number", 0)
@@ -322,95 +356,7 @@ CREATE_SIM_OBJECT(SimConsole)
stream = simout.find(filename);
}
- SimConsole *console = new SimConsole(getInstanceName(), stream, number);
- ((ConsoleListener *)listener)->add(console);
-
- return console;
+ return new SimConsole(getInstanceName(), stream, number, port);
}
REGISTER_SIM_OBJECT("SimConsole", SimConsole)
-
-////////////////////////////////////////////////////////////////////////
-//
-//
-
-ConsoleListener::ConsoleListener(const string &name)
- : SimObject(name), event(NULL)
-{}
-
-ConsoleListener::~ConsoleListener()
-{
- if (event)
- delete event;
-}
-
-void
-ConsoleListener::Event::process(int revent)
-{
- listener->accept();
-}
-
-///////////////////////////////////////////////////////////////////////
-// socket creation and console attach
-//
-
-void
-ConsoleListener::listen(int port)
-{
- while (!listener.listen(port, true)) {
- DPRINTF(Console,
- ": can't bind address console port %d inuse PID %d\n",
- port, getpid());
- port++;
- }
-
- ccprintf(cerr, "Listening for console connection on port %d\n", port);
-
- event = new Event(this, listener.getfd(), POLLIN);
- pollQueue.schedule(event);
-}
-
-void
-ConsoleListener::add(SimConsole *cons)
-{ ConsoleList.push_back(cons);}
-
-void
-ConsoleListener::accept()
-{
- if (!listener.islistening())
- panic("%s: cannot accept a connection if not listening!", name());
-
- int sfd = listener.accept(true);
- if (sfd != -1) {
- iter_t i = ConsoleList.begin();
- iter_t end = ConsoleList.end();
- if (i == end) {
- close(sfd);
- } else {
- (*i)->attach(sfd, this);
- i = ConsoleList.erase(i);
- }
- }
-}
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(ConsoleListener)
-
- Param<int> port;
-
-END_DECLARE_SIM_OBJECT_PARAMS(ConsoleListener)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(ConsoleListener)
-
- INIT_PARAM_DFLT(port, "listen port", 3456)
-
-END_INIT_SIM_OBJECT_PARAMS(ConsoleListener)
-
-CREATE_SIM_OBJECT(ConsoleListener)
-{
- ConsoleListener *listener = new ConsoleListener(getInstanceName());
- listener->listen(port);
-
- return listener;
-}
-
-REGISTER_SIM_OBJECT("ConsoleListener", ConsoleListener)
diff --git a/src/dev/simconsole.hh b/src/dev/simconsole.hh
index ec99c6028..18a193493 100644
--- a/src/dev/simconsole.hh
+++ b/src/dev/simconsole.hh
@@ -53,30 +53,47 @@ class SimConsole : public SimObject
Uart *uart;
protected:
- class Event : public PollEvent
+ class ListenEvent : public PollEvent
{
protected:
SimConsole *cons;
public:
- Event(SimConsole *c, int fd, int e);
+ ListenEvent(SimConsole *c, int fd, int e);
void process(int revent);
};
- friend class Event;
- Event *event;
+ friend class ListenEvent;
+ ListenEvent *listenEvent;
+
+ class DataEvent : public PollEvent
+ {
+ protected:
+ SimConsole *cons;
+
+ public:
+ DataEvent(SimConsole *c, int fd, int e);
+ void process(int revent);
+ };
+
+ friend class DataEvent;
+ DataEvent *dataEvent;
protected:
int number;
- int in_fd;
- int out_fd;
- ConsoleListener *listener;
+ int data_fd;
public:
- SimConsole(const std::string &name, std::ostream *os, int num);
+ SimConsole(const std::string &name, std::ostream *os, int num, int port);
~SimConsole();
protected:
+ ListenSocket listener;
+
+ void listen(int port);
+ void accept();
+
+ protected:
CircleBuf txbuf;
CircleBuf rxbuf;
std::ostream *outfile;
@@ -88,17 +105,13 @@ class SimConsole : public SimObject
///////////////////////
// Terminal Interface
- void attach(int fd, ConsoleListener *l = NULL) { attach(fd, fd, l); }
- void attach(int in, int out, ConsoleListener *l = NULL);
- void detach();
-
void data();
- void close();
void read(uint8_t &c) { read(&c, 1); }
size_t read(uint8_t *buf, size_t len);
void write(uint8_t c) { write(&c, 1); }
size_t write(const uint8_t *buf, size_t len);
+ void detach();
public:
/////////////////
@@ -126,43 +139,6 @@ class SimConsole : public SimObject
//Ask the console if data is available
bool dataAvailable() { return !rxbuf.empty(); }
-
- virtual void serialize(std::ostream &os);
- virtual void unserialize(Checkpoint *cp, const std::string &section);
-};
-
-class ConsoleListener : public SimObject
-{
- protected:
- class Event : public PollEvent
- {
- protected:
- ConsoleListener *listener;
-
- public:
- Event(ConsoleListener *l, int fd, int e)
- : PollEvent(fd, e), listener(l) {}
- void process(int revent);
- };
-
- friend class Event;
- Event *event;
-
- typedef std::list<SimConsole *> list_t;
- typedef list_t::iterator iter_t;
- list_t ConsoleList;
-
- protected:
- ListenSocket listener;
-
- public:
- ConsoleListener(const std::string &name);
- ~ConsoleListener();
-
- void add(SimConsole *cons);
-
- void accept();
- void listen(int port);
};
#endif // __CONSOLE_HH__
diff --git a/src/dev/sparc/SConscript b/src/dev/sparc/SConscript
index 44b082b68..8511b16fb 100644
--- a/src/dev/sparc/SConscript
+++ b/src/dev/sparc/SConscript
@@ -29,21 +29,10 @@
# Authors: Steve Reinhardt
# Gabe Black
-import os.path, sys
+Import('*')
-# Import build environment variable from SConstruct.
-Import('env')
-
-sources = []
-
-sources += Split('''
- dtod.cc
- t1000.cc
- mm_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')
+if env['FULL_SYSTEM'] and env['TARGET_ISA'] == 'sparc':
+ Source('dtod.cc')
+ Source('iob.cc')
+ Source('t1000.cc')
+ Source('mm_disk.cc')
diff --git a/src/dev/sparc/iob.cc b/src/dev/sparc/iob.cc
new file mode 100644
index 000000000..e686e51f7
--- /dev/null
+++ b/src/dev/sparc/iob.cc
@@ -0,0 +1,402 @@
+/*
+ * 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
+ */
+
+/** @file
+ * This device implemetns the niagara I/O bridge chip. It manages incomming
+ * interrupts and posts them to the CPU when needed. It holds mask registers and
+ * various status registers for CPUs to check what interrupts are pending as
+ * well as facilities to send IPIs to other cpus.
+ */
+
+#include <cstring>
+
+#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/faults.hh"
+#include "base/trace.hh"
+#include "cpu/intr_control.hh"
+#include "dev/sparc/iob.hh"
+#include "dev/platform.hh"
+#include "mem/port.hh"
+#include "mem/packet_access.hh"
+#include "sim/builder.hh"
+#include "sim/faults.hh"
+#include "sim/system.hh"
+
+Iob::Iob(Params *p)
+ : PioDevice(p), ic(p->platform->intrctrl)
+{
+ iobManAddr = ULL(0x9800000000);
+ iobManSize = ULL(0x0100000000);
+ iobJBusAddr = ULL(0x9F00000000);
+ iobJBusSize = ULL(0x0100000000);
+ assert (params()->system->threadContexts.size() <= MaxNiagaraProcs);
+ // Get the interrupt controller from the platform
+ ic = platform->intrctrl;
+
+ for (int x = 0; x < NumDeviceIds; ++x) {
+ intMan[x].cpu = 0;
+ intMan[x].vector = 0;
+ intCtl[x].mask = true;
+ intCtl[x].pend = false;
+ }
+
+}
+
+Tick
+Iob::read(PacketPtr pkt)
+{
+ assert(pkt->result == Packet::Unknown);
+
+ if (pkt->getAddr() >= iobManAddr && pkt->getAddr() < iobManAddr + iobManSize)
+ readIob(pkt);
+ else if (pkt->getAddr() >= iobJBusAddr && pkt->getAddr() < iobJBusAddr+iobJBusSize)
+ readJBus(pkt);
+ else
+ panic("Invalid address reached Iob\n");
+
+ pkt->result = Packet::Success;
+ return pioDelay;
+}
+
+void
+Iob::readIob(PacketPtr pkt)
+{
+ Addr accessAddr = pkt->getAddr() - iobManAddr;
+ int index;
+ uint64_t data;
+
+ if (accessAddr >= IntManAddr && accessAddr < IntManAddr + IntManSize) {
+ index = (accessAddr - IntManAddr) >> 3;
+ data = intMan[index].cpu << 8 | intMan[index].vector << 0;
+ pkt->set(data);
+ return;
+ }
+
+ if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) {
+ index = (accessAddr - IntManAddr) >> 3;
+ data = intCtl[index].mask ? 1 << 2 : 0 |
+ intCtl[index].pend ? 1 << 0 : 0;
+ pkt->set(data);
+ return;
+ }
+
+ if (accessAddr == JIntVecAddr) {
+ pkt->set(jIntVec);
+ return;
+ }
+
+ panic("Read to unknown IOB offset 0x%x\n", accessAddr);
+}
+
+void
+Iob::readJBus(PacketPtr pkt)
+{
+ Addr accessAddr = pkt->getAddr() - iobJBusAddr;
+ int cpuid = pkt->req->getCpuNum();
+ int index;
+ uint64_t data;
+
+
+
+
+ if (accessAddr >= JIntData0Addr && accessAddr < JIntData1Addr) {
+ index = (accessAddr - JIntData0Addr) >> 3;
+ pkt->set(jBusData0[index]);
+ return;
+ }
+
+ if (accessAddr >= JIntData1Addr && accessAddr < JIntDataA0Addr) {
+ index = (accessAddr - JIntData1Addr) >> 3;
+ pkt->set(jBusData1[index]);
+ return;
+ }
+
+ if (accessAddr == JIntDataA0Addr) {
+ pkt->set(jBusData0[cpuid]);
+ return;
+ }
+
+ if (accessAddr == JIntDataA1Addr) {
+ pkt->set(jBusData1[cpuid]);
+ return;
+ }
+
+ if (accessAddr >= JIntBusyAddr && accessAddr < JIntBusyAddr + JIntBusySize) {
+ index = (accessAddr - JIntBusyAddr) >> 3;
+ data = jIntBusy[index].busy ? 1 << 5 : 0 |
+ jIntBusy[index].source;
+ pkt->set(data);
+ return;
+ }
+ if (accessAddr == JIntABusyAddr) {
+ data = jIntBusy[cpuid].busy ? 1 << 5 : 0 |
+ jIntBusy[cpuid].source;
+ pkt->set(data);
+ return;
+ };
+
+ panic("Read to unknown JBus offset 0x%x\n", accessAddr);
+}
+
+Tick
+Iob::write(PacketPtr pkt)
+{
+ if (pkt->getAddr() >= iobManAddr && pkt->getAddr() < iobManAddr + iobManSize)
+ writeIob(pkt);
+ else if (pkt->getAddr() >= iobJBusAddr && pkt->getAddr() < iobJBusAddr+iobJBusSize)
+ writeJBus(pkt);
+ else
+ panic("Invalid address reached Iob\n");
+
+
+ pkt->result = Packet::Success;
+ return pioDelay;
+}
+
+void
+Iob::writeIob(PacketPtr pkt)
+{
+ Addr accessAddr = pkt->getAddr() - iobManAddr;
+ int index;
+ uint64_t data;
+
+ if (accessAddr >= IntManAddr && accessAddr < IntManAddr + IntManSize) {
+ index = (accessAddr - IntManAddr) >> 3;
+ data = pkt->get<uint64_t>();
+ intMan[index].cpu = bits(data,12,8);
+ intMan[index].vector = bits(data,5,0);
+ DPRINTF(Iob, "Wrote IntMan %d cpu %d, vec %d\n", index,
+ intMan[index].cpu, intMan[index].vector);
+ return;
+ }
+
+ if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) {
+ index = (accessAddr - IntManAddr) >> 3;
+ data = pkt->get<uint64_t>();
+ intCtl[index].mask = bits(data,2,2);
+ if (bits(data,1,1))
+ intCtl[index].pend = false;
+ DPRINTF(Iob, "Wrote IntCtl %d pend %d cleared %d\n", index,
+ intCtl[index].pend, bits(data,2,2));
+ return;
+ }
+
+ if (accessAddr == JIntVecAddr) {
+ jIntVec = bits(pkt->get<uint64_t>(), 5,0);
+ DPRINTF(Iob, "Wrote jIntVec %d\n", jIntVec);
+ return;
+ }
+
+ if (accessAddr >= IntVecDisAddr && accessAddr < IntVecDisAddr + IntVecDisSize) {
+ Type type;
+ int cpu_id;
+ int vector;
+ index = (accessAddr - IntManAddr) >> 3;
+ data = pkt->get<uint64_t>();
+ type = (Type)bits(data,17,16);
+ cpu_id = bits(data, 12,8);
+ vector = bits(data,5,0);
+ generateIpi(type,cpu_id, vector);
+ return;
+ }
+
+ panic("Write to unknown IOB offset 0x%x\n", accessAddr);
+}
+
+void
+Iob::writeJBus(PacketPtr pkt)
+{
+ Addr accessAddr = pkt->getAddr() - iobJBusAddr;
+ int cpuid = pkt->req->getCpuNum();
+ int index;
+ uint64_t data;
+
+ if (accessAddr >= JIntBusyAddr && accessAddr < JIntBusyAddr + JIntBusySize) {
+ index = (accessAddr - JIntBusyAddr) >> 3;
+ data = pkt->get<uint64_t>();
+ jIntBusy[index].busy = bits(data,5,5);
+ DPRINTF(Iob, "Wrote jIntBusy index %d busy: %d\n", index,
+ jIntBusy[index].busy);
+ return;
+ }
+ if (accessAddr == JIntABusyAddr) {
+ data = pkt->get<uint64_t>();
+ jIntBusy[cpuid].busy = bits(data,5,5);
+ DPRINTF(Iob, "Wrote jIntBusy index %d busy: %d\n", cpuid,
+ jIntBusy[cpuid].busy);
+ return;
+ };
+
+ panic("Write to unknown JBus offset 0x%x\n", accessAddr);
+}
+
+void
+Iob::receiveDeviceInterrupt(DeviceId devid)
+{
+ assert(devid < NumDeviceIds);
+ if (intCtl[devid].mask)
+ return;
+ intCtl[devid].mask = true;
+ intCtl[devid].pend = true;
+ DPRINTF(Iob, "Receiving Device interrupt: %d for cpu %d vec %d\n",
+ devid, intMan[devid].cpu, intMan[devid].vector);
+ ic->post(intMan[devid].cpu, SparcISA::IT_INT_VEC, intMan[devid].vector);
+}
+
+
+void
+Iob::generateIpi(Type type, int cpu_id, int vector)
+{
+ SparcISA::SparcFault<SparcISA::PowerOnReset> *por = new SparcISA::PowerOnReset();
+ if (cpu_id >= sys->getNumCPUs())
+ return;
+
+ switch (type) {
+ case 0: // interrupt
+ DPRINTF(Iob, "Generating interrupt because of I/O write to cpu: %d vec %d\n",
+ cpu_id, vector);
+ ic->post(cpu_id, SparcISA::IT_INT_VEC, vector);
+ break;
+ case 1: // reset
+ warn("Sending reset to CPU: %d\n", cpu_id);
+ if (vector != por->trapType())
+ panic("Don't know how to set non-POR reset to cpu\n");
+ por->invoke(sys->threadContexts[cpu_id]);
+ sys->threadContexts[cpu_id]->activate();
+ break;
+ case 2: // idle -- this means stop executing and don't wake on interrupts
+ DPRINTF(Iob, "Idling CPU because of I/O write cpu: %d\n", cpu_id);
+ sys->threadContexts[cpu_id]->halt();
+ break;
+ case 3: // resume
+ DPRINTF(Iob, "Resuming CPU because of I/O write cpu: %d\n", cpu_id);
+ sys->threadContexts[cpu_id]->activate();
+ break;
+ default:
+ panic("Invalid type to generate ipi\n");
+ }
+}
+
+bool
+Iob::receiveJBusInterrupt(int cpu_id, int source, uint64_t d0, uint64_t d1)
+{
+ // If we are already dealing with an interrupt for that cpu we can't deal
+ // with another one right now... come back later
+ if (jIntBusy[cpu_id].busy)
+ return false;
+
+ DPRINTF(Iob, "Receiving jBus interrupt: %d for cpu %d vec %d\n",
+ source, cpu_id, jIntVec);
+
+ jIntBusy[cpu_id].busy = true;
+ jIntBusy[cpu_id].source = source;
+ jBusData0[cpu_id] = d0;
+ jBusData1[cpu_id] = d1;
+
+ ic->post(cpu_id, SparcISA::IT_INT_VEC, jIntVec);
+ return true;
+}
+
+void
+Iob::addressRanges(AddrRangeList &range_list)
+{
+ range_list.clear();
+ range_list.push_back(RangeSize(iobManAddr, iobManSize));
+ range_list.push_back(RangeSize(iobJBusAddr, iobJBusSize));
+}
+
+
+void
+Iob::serialize(std::ostream &os)
+{
+
+ SERIALIZE_SCALAR(jIntVec);
+ SERIALIZE_ARRAY(jBusData0, MaxNiagaraProcs);
+ SERIALIZE_ARRAY(jBusData1, MaxNiagaraProcs);
+ for (int x = 0; x < NumDeviceIds; x++) {
+ nameOut(os, csprintf("%s.Int%d", name(), x));
+ paramOut(os, "cpu", intMan[x].cpu);
+ paramOut(os, "vector", intMan[x].vector);
+ paramOut(os, "mask", intCtl[x].mask);
+ paramOut(os, "pend", intCtl[x].pend);
+ };
+ for (int x = 0; x < MaxNiagaraProcs; x++) {
+ nameOut(os, csprintf("%s.jIntBusy%d", name(), x));
+ paramOut(os, "busy", jIntBusy[x].busy);
+ paramOut(os, "source", jIntBusy[x].source);
+ };
+}
+
+void
+Iob::unserialize(Checkpoint *cp, const std::string &section)
+{
+ UNSERIALIZE_SCALAR(jIntVec);
+ UNSERIALIZE_ARRAY(jBusData0, MaxNiagaraProcs);
+ UNSERIALIZE_ARRAY(jBusData1, MaxNiagaraProcs);
+ for (int x = 0; x < NumDeviceIds; x++) {
+ paramIn(cp, csprintf("%s.Int%d", name(), x), "cpu", intMan[x].cpu);
+ paramIn(cp, csprintf("%s.Int%d", name(), x), "vector", intMan[x].vector);
+ paramIn(cp, csprintf("%s.Int%d", name(), x), "mask", intCtl[x].mask);
+ paramIn(cp, csprintf("%s.Int%d", name(), x), "pend", intCtl[x].pend);
+ };
+ for (int x = 0; x < MaxNiagaraProcs; x++) {
+ paramIn(cp, csprintf("%s.jIntBusy%d", name(), x), "busy", jIntBusy[x].busy);
+ paramIn(cp, csprintf("%s.jIntBusy%d", name(), x), "source", jIntBusy[x].source);
+ };
+}
+
+
+
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(Iob)
+ Param<Tick> pio_latency;
+ SimObjectParam<Platform *> platform;
+ SimObjectParam<System *> system;
+END_DECLARE_SIM_OBJECT_PARAMS(Iob)
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(Iob)
+
+ INIT_PARAM(pio_latency, "Programmed IO latency"),
+ INIT_PARAM(platform, "platform"),
+ INIT_PARAM(system, "system object")
+
+END_INIT_SIM_OBJECT_PARAMS(Iob)
+
+CREATE_SIM_OBJECT(Iob)
+{
+ Iob::Params *p = new Iob::Params;
+ p->name = getInstanceName();
+ p->pio_delay = pio_latency;
+ p->platform = platform;
+ p->system = system;
+ return new Iob(p);
+}
+
+REGISTER_SIM_OBJECT("Iob", Iob)
diff --git a/src/dev/sparc/iob.hh b/src/dev/sparc/iob.hh
new file mode 100644
index 000000000..c05c4f2ef
--- /dev/null
+++ b/src/dev/sparc/iob.hh
@@ -0,0 +1,153 @@
+/*
+ * 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
+ */
+
+/** @file
+ * This device implements the niagara I/O Bridge chip. The device manages
+ * internal (ipi) and external (serial, pci via jbus).
+ */
+
+#ifndef __DEV_SPARC_IOB_HH__
+#define __DEV_SPARC_IOB_HH__
+
+#include "base/range.hh"
+#include "dev/io_device.hh"
+#include "dev/disk_image.hh"
+
+class IntrControl;
+
+const int MaxNiagaraProcs = 32;
+// IOB Managment Addresses
+const Addr IntManAddr = 0x0000;
+const Addr IntManSize = 0x0020;
+const Addr IntCtlAddr = 0x0400;
+const Addr IntCtlSize = 0x0020;
+const Addr JIntVecAddr = 0x0A00;
+const Addr IntVecDisAddr = 0x0800;
+const Addr IntVecDisSize = 0x0100;
+
+
+// IOB Control Addresses
+const Addr JIntData0Addr = 0x0400;
+const Addr JIntData1Addr = 0x0500;
+const Addr JIntDataA0Addr = 0x0600;
+const Addr JIntDataA1Addr = 0x0700;
+const Addr JIntBusyAddr = 0x0900;
+const Addr JIntBusySize = 0x0100;
+const Addr JIntABusyAddr = 0x0B00;
+
+
+// IOB Masks
+const uint64_t IntManMask = 0x01F3F;
+const uint64_t IntCtlMask = 0x00006;
+const uint64_t JIntVecMask = 0x0003F;
+const uint64_t IntVecDis = 0x31F3F;
+const uint64_t JIntBusyMask = 0x0003F;
+
+
+class Iob : public PioDevice
+{
+ private:
+ IntrControl *ic;
+ Addr iobManAddr;
+ Addr iobManSize;
+ Addr iobJBusAddr;
+ Addr iobJBusSize;
+ Tick pioDelay;
+
+ enum DeviceId {
+ Interal = 0,
+ Error = 1,
+ SSI = 2,
+ Reserved = 3,
+ NumDeviceIds
+ };
+
+ struct IntMan {
+ int cpu;
+ int vector;
+ };
+
+ struct IntCtl {
+ bool mask;
+ bool pend;
+ };
+
+ struct IntBusy {
+ bool busy;
+ int source;
+ };
+
+ enum Type {
+ Interrupt,
+ Reset,
+ Idle,
+ Resume
+ };
+
+ IntMan intMan[NumDeviceIds];
+ IntCtl intCtl[NumDeviceIds];
+ uint64_t jIntVec;
+ uint64_t jBusData0[MaxNiagaraProcs];
+ uint64_t jBusData1[MaxNiagaraProcs];
+ IntBusy jIntBusy[MaxNiagaraProcs];
+
+ void writeIob(PacketPtr pkt);
+ void writeJBus(PacketPtr pkt);
+ void readIob(PacketPtr pkt);
+ void readJBus(PacketPtr pkt);
+
+
+ public:
+ struct Params : public PioDevice::Params
+ {
+ Tick pio_delay;
+ };
+ protected:
+ const Params *params() const { return (const Params*)_params; }
+
+ public:
+ Iob(Params *p);
+
+ virtual Tick read(PacketPtr pkt);
+ virtual Tick write(PacketPtr pkt);
+ void generateIpi(Type type, int cpu_id, int vector);
+ void receiveDeviceInterrupt(DeviceId devid);
+ bool receiveJBusInterrupt(int cpu_id, int source, uint64_t d0, uint64_t d1);
+
+
+ void addressRanges(AddrRangeList &range_list);
+
+ virtual void serialize(std::ostream &os);
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
+
+};
+
+#endif //__DEV_SPARC_IOB_HH__
+
diff --git a/src/dev/sparc/mm_disk.cc b/src/dev/sparc/mm_disk.cc
index b8cabd0cf..81c5c589a 100644
--- a/src/dev/sparc/mm_disk.cc
+++ b/src/dev/sparc/mm_disk.cc
@@ -45,7 +45,7 @@
#include "sim/system.hh"
MmDisk::MmDisk(Params *p)
- : BasicPioDevice(p), image(p->image), curSector((uint64_t)-1), dirty(false)
+ : BasicPioDevice(p), image(p->image), curSector((off_t)-1), dirty(false)
{
std::memset(&diskData, 0, SectorSize);
pioSize = image->size() * SectorSize;
diff --git a/src/dev/uart.cc b/src/dev/uart.cc
index f769b720b..1c781f76d 100644
--- a/src/dev/uart.cc
+++ b/src/dev/uart.cc
@@ -47,7 +47,6 @@ Uart::Uart(Params *p)
// set back pointers
cons->uart = this;
- platform->uart = this;
}
DEFINE_SIM_OBJECT_CLASS_NAME("Uart", Uart)
diff --git a/src/dev/uart8250.hh b/src/dev/uart8250.hh
index a0620c7e0..c28200592 100644
--- a/src/dev/uart8250.hh
+++ b/src/dev/uart8250.hh
@@ -35,7 +35,6 @@
#ifndef __DEV_UART8250_HH__
#define __DEV_UART8250_HH__
-#include "dev/alpha/tsunamireg.h"
#include "base/range.hh"
#include "dev/io_device.hh"
#include "dev/uart.hh"
@@ -54,6 +53,18 @@ const uint8_t IIR_TXID = 0x02; /* Tx Data */
const uint8_t IIR_RXID = 0x04; /* Rx Data */
const uint8_t IIR_LINE = 0x06; /* Rx Line Status (highest priority)*/
+const uint8_t UART_IER_RDI = 0x01;
+const uint8_t UART_IER_THRI = 0x02;
+const uint8_t UART_IER_RLSI = 0x04;
+
+
+const uint8_t UART_LSR_TEMT = 0x40;
+const uint8_t UART_LSR_THRE = 0x20;
+const uint8_t UART_LSR_DR = 0x01;
+
+const uint8_t UART_MCR_LOOP = 0x10;
+
+
class SimConsole;
class Platform;
diff --git a/src/kern/SConscript b/src/kern/SConscript
index 12df28836..eec8012a7 100644
--- a/src/kern/SConscript
+++ b/src/kern/SConscript
@@ -28,21 +28,18 @@
#
# Authors: Steve Reinhardt
-import os.path, sys
+Import('*')
-# Import build environment variable from SConstruct.
-Import('env')
+if env['FULL_SYSTEM']:
+ Source('kernel_stats.cc')
+ Source('system_events.cc')
-sources = Split('''
- kernel_stats.cc
- system_events.cc
- linux/events.cc
- linux/linux_syscalls.cc
- linux/printk.cc
- ''')
+ Source('linux/events.cc')
+ Source('linux/linux_syscalls.cc')
+ Source('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')
+ if env['TARGET_ISA'] == 'alpha':
+ Source('tru64/dump_mbuf.cc')
+ Source('tru64/printf.cc')
+ Source('tru64/tru64_events.cc')
+ Source('tru64/tru64_syscalls.cc')
diff --git a/src/kern/linux/printk.cc b/src/kern/linux/printk.cc
index ea3d59f19..0e9fd6620 100644
--- a/src/kern/linux/printk.cc
+++ b/src/kern/linux/printk.cc
@@ -41,11 +41,12 @@ using namespace std;
void
Printk(TheISA::Arguments args)
{
+ std::ostream &out = Trace::output();
char *p = (char *)args++;
- ios::fmtflags saved_flags = DebugOut().flags();
- char old_fill = DebugOut().fill();
- int old_precision = DebugOut().precision();
+ ios::fmtflags saved_flags = out.flags();
+ char old_fill = out.fill();
+ int old_precision = out.precision();
while (*p) {
switch (*p) {
@@ -118,53 +119,53 @@ Printk(TheISA::Arguments args)
case 'P':
case 'p': {
if (hexnum)
- DebugOut() << hex;
+ out << hex;
if (octal)
- DebugOut() << oct;
+ out << oct;
if (format) {
if (!zero)
- DebugOut().setf(ios::showbase);
+ out.setf(ios::showbase);
else {
if (hexnum) {
- DebugOut() << "0x";
+ out << "0x";
width -= 2;
} else if (octal) {
- DebugOut() << "0";
+ out << "0";
width -= 1;
}
}
}
if (zero)
- DebugOut().fill('0');
+ out.fill('0');
if (width > 0)
- DebugOut().width(width);
+ out.width(width);
if (leftjustify && !zero)
- DebugOut().setf(ios::left);
+ out.setf(ios::left);
if (sign) {
if (islong)
- DebugOut() << (int64_t)args;
+ out << (int64_t)args;
else
- DebugOut() << (int32_t)args;
+ out << (int32_t)args;
} else {
if (islong)
- DebugOut() << (uint64_t)args;
+ out << (uint64_t)args;
else
- DebugOut() << (uint32_t)args;
+ out << (uint32_t)args;
}
if (zero)
- DebugOut().fill(' ');
+ out.fill(' ');
if (width > 0)
- DebugOut().width(0);
+ out.width(0);
- DebugOut() << dec;
+ out << dec;
++args;
}
@@ -176,11 +177,11 @@ Printk(TheISA::Arguments args)
s = "<NULL>";
if (width > 0)
- DebugOut().width(width);
+ out.width(width);
if (leftjustify)
- DebugOut().setf(ios::left);
+ out.setf(ios::left);
- DebugOut() << s;
+ out << s;
++args;
}
break;
@@ -201,7 +202,7 @@ Printk(TheISA::Arguments args)
while (width-- > 0) {
char c = (char)(num & mask);
if (c)
- DebugOut() << c;
+ out << c;
num >>= 8;
}
@@ -211,7 +212,7 @@ Printk(TheISA::Arguments args)
case 'b': {
uint64_t n = (uint64_t)args++;
char *s = (char *)args++;
- DebugOut() << s << ": " << n;
+ out << s << ": " << n;
}
break;
case 'n':
@@ -233,32 +234,32 @@ Printk(TheISA::Arguments args)
}
break;
case '%':
- DebugOut() << '%';
+ out << '%';
break;
}
++p;
}
break;
case '\n':
- DebugOut() << endl;
+ out << endl;
++p;
break;
case '\r':
++p;
if (*p != '\n')
- DebugOut() << endl;
+ out << endl;
break;
default: {
size_t len = strcspn(p, "%\n\r\0");
- DebugOut().write(p, len);
+ out.write(p, len);
p += len;
}
}
}
- DebugOut().flags(saved_flags);
- DebugOut().fill(old_fill);
- DebugOut().precision(old_precision);
+ out.flags(saved_flags);
+ out.fill(old_fill);
+ out.precision(old_precision);
}
diff --git a/src/kern/tru64/dump_mbuf.cc b/src/kern/tru64/dump_mbuf.cc
index 22d2228f0..5ccfbca5d 100644
--- a/src/kern/tru64/dump_mbuf.cc
+++ b/src/kern/tru64/dump_mbuf.cc
@@ -50,6 +50,7 @@ void
DumpMbuf(Arguments args)
{
ThreadContext *tc = args.getThreadContext();
+ StringWrap name(tc->getSystemPtr()->name());
Addr addr = (Addr)args;
struct mbuf m;
@@ -57,16 +58,14 @@ DumpMbuf(Arguments args)
int count = m.m_pkthdr.len;
- ccprintf(DebugOut(), "m=%#lx, m->m_pkthdr.len=%#d\n", addr,
- m.m_pkthdr.len);
+ DPRINTFN("m=%#lx, m->m_pkthdr.len=%#d\n", addr, m.m_pkthdr.len);
while (count > 0) {
- ccprintf(DebugOut(), "m=%#lx, m->m_data=%#lx, m->m_len=%d\n",
+ DPRINTFN("m=%#lx, m->m_data=%#lx, m->m_len=%d\n",
addr, m.m_data, m.m_len);
char *buffer = new char[m.m_len];
CopyOut(tc, buffer, m.m_data, m.m_len);
- Trace::dataDump(curTick, tc->getSystemPtr()->name(), (uint8_t *)buffer,
- m.m_len);
+ DDUMPN((uint8_t *)buffer, m.m_len);
delete [] buffer;
count -= m.m_len;
diff --git a/src/kern/tru64/printf.cc b/src/kern/tru64/printf.cc
index 2c767c4d2..4245ac6d0 100644
--- a/src/kern/tru64/printf.cc
+++ b/src/kern/tru64/printf.cc
@@ -44,11 +44,13 @@ namespace tru64 {
void
Printf(TheISA::Arguments args)
{
+ std::ostream &out = Trace::output();
+
char *p = (char *)args++;
- ios::fmtflags saved_flags = DebugOut().flags();
- char old_fill = DebugOut().fill();
- int old_precision = DebugOut().precision();
+ ios::fmtflags saved_flags = out.flags();
+ char old_fill = out.fill();
+ int old_precision = out.precision();
while (*p) {
switch (*p) {
@@ -121,53 +123,53 @@ Printf(TheISA::Arguments args)
case 'P':
case 'p': {
if (hexnum)
- DebugOut() << hex;
+ out << hex;
if (octal)
- DebugOut() << oct;
+ out << oct;
if (format) {
if (!zero)
- DebugOut().setf(ios::showbase);
+ out.setf(ios::showbase);
else {
if (hexnum) {
- DebugOut() << "0x";
+ out << "0x";
width -= 2;
} else if (octal) {
- DebugOut() << "0";
+ out << "0";
width -= 1;
}
}
}
if (zero)
- DebugOut().fill('0');
+ out.fill('0');
if (width > 0)
- DebugOut().width(width);
+ out.width(width);
if (leftjustify && !zero)
- DebugOut().setf(ios::left);
+ out.setf(ios::left);
if (sign) {
if (islong)
- DebugOut() << (int64_t)args;
+ out << (int64_t)args;
else
- DebugOut() << (int32_t)args;
+ out << (int32_t)args;
} else {
if (islong)
- DebugOut() << (uint64_t)args;
+ out << (uint64_t)args;
else
- DebugOut() << (uint32_t)args;
+ out << (uint32_t)args;
}
if (zero)
- DebugOut().fill(' ');
+ out.fill(' ');
if (width > 0)
- DebugOut().width(0);
+ out.width(0);
- DebugOut() << dec;
+ out << dec;
++args;
}
@@ -179,11 +181,11 @@ Printf(TheISA::Arguments args)
s = "<NULL>";
if (width > 0)
- DebugOut().width(width);
+ out.width(width);
if (leftjustify)
- DebugOut().setf(ios::left);
+ out.setf(ios::left);
- DebugOut() << s;
+ out << s;
++args;
}
break;
@@ -204,7 +206,7 @@ Printf(TheISA::Arguments args)
while (width-- > 0) {
char c = (char)(num & mask);
if (c)
- DebugOut() << c;
+ out << c;
num >>= 8;
}
@@ -214,7 +216,7 @@ Printf(TheISA::Arguments args)
case 'b': {
uint64_t n = (uint64_t)args++;
char *s = (char *)args++;
- DebugOut() << s << ": " << n;
+ out << s << ": " << n;
}
break;
case 'n':
@@ -236,33 +238,33 @@ Printf(TheISA::Arguments args)
}
break;
case '%':
- DebugOut() << '%';
+ out << '%';
break;
}
++p;
}
break;
case '\n':
- DebugOut() << endl;
+ out << endl;
++p;
break;
case '\r':
++p;
if (*p != '\n')
- DebugOut() << endl;
+ out << endl;
break;
default: {
size_t len = strcspn(p, "%\n\r\0");
- DebugOut().write(p, len);
+ out.write(p, len);
p += len;
}
}
}
- DebugOut().flags(saved_flags);
- DebugOut().fill(old_fill);
- DebugOut().precision(old_precision);
+ out.flags(saved_flags);
+ out.fill(old_fill);
+ out.precision(old_precision);
}
} // namespace Tru64
diff --git a/src/kern/tru64/tru64.hh b/src/kern/tru64/tru64.hh
index 82db34bf6..b94276035 100644
--- a/src/kern/tru64/tru64.hh
+++ b/src/kern/tru64/tru64.hh
@@ -56,7 +56,7 @@ class Tru64 {};
#include <unistd.h>
#include "cpu/base.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
#include "sim/syscall_emul.hh"
typedef struct stat global_stat;
@@ -511,7 +511,7 @@ class Tru64 : public OperatingSystem
tc->setFloatRegBits(i, htog(sc->sc_fpregs[i]));
}
- tc->setMiscReg(AlphaISA::MISCREG_FPCR, htog(sc->sc_fpcr));
+ tc->setMiscRegNoEffect(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(AlphaISA::MISCREG_UNIQ);
+ uint64_t uniq = tc->readMiscRegNoEffect(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(AlphaISA::MISCREG_UNIQ, uniq_val);
+ tc->setMiscRegNoEffect(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 851b3a526..0ad89f8bd 100644
--- a/src/kern/tru64/tru64_events.cc
+++ b/src/kern/tru64/tru64_events.cc
@@ -79,7 +79,8 @@ void
PrintfEvent::process(ThreadContext *tc)
{
if (DTRACE(Printf)) {
- DebugOut() << curTick << ": " << tc->getCpuPtr()->name() << ": ";
+ StringWrap name(tc->getSystemPtr()->name());
+ DPRINTFN("");
Arguments args(tc);
tru64::Printf(args);
@@ -90,8 +91,10 @@ void
DebugPrintfEvent::process(ThreadContext *tc)
{
if (DTRACE(DebugPrintf)) {
- if (!raw)
- DebugOut() << curTick << ": " << tc->getCpuPtr()->name() << ": ";
+ if (!raw) {
+ StringWrap name(tc->getSystemPtr()->name());
+ DPRINTFN("");
+ }
Arguments args(tc);
tru64::Printf(args);
diff --git a/src/mem/SConscript b/src/mem/SConscript
new file mode 100644
index 000000000..61fb766d6
--- /dev/null
+++ b/src/mem/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: Nathan Binkert
+
+Import('*')
+
+Source('bridge.cc')
+Source('bus.cc')
+Source('dram.cc')
+Source('mem_object.cc')
+Source('packet.cc')
+Source('physical.cc')
+Source('port.cc')
+Source('tport.cc')
+
+if env['FULL_SYSTEM']:
+ Source('vport.cc')
+else:
+ Source('page_table.cc')
+ Source('translating_port.cc')
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index 401dc0186..6e6ba2380 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -34,6 +34,8 @@
*/
+#include <limits>
+
#include "base/misc.hh"
#include "base/trace.hh"
#include "mem/bus.hh"
@@ -52,20 +54,30 @@ Bus::getPort(const std::string &if_name, int idx)
}
// if_name ignored? forced to be empty?
- int id = interfaces.size();
+ int id = maxId++;
+ assert(maxId < std::numeric_limits<typeof(maxId)>::max());
BusPort *bp = new BusPort(csprintf("%s-p%d", name(), id), this, id);
- interfaces.push_back(bp);
+ interfaces[id] = bp;
return bp;
}
+void
+Bus::deletePortRefs(Port *p)
+{
+ BusPort *bp = dynamic_cast<BusPort*>(p);
+ if (bp == NULL)
+ panic("Couldn't convert Port* to BusPort*\n");
+ interfaces.erase(bp->getId());
+}
+
/** Get the ranges of anyone other buses that we are connected to. */
void
Bus::init()
{
- std::vector<BusPort*>::iterator intIter;
+ m5::hash_map<short,BusPort*>::iterator intIter;
for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
- (*intIter)->sendStatusChange(Port::RangeChange);
+ intIter->second->sendStatusChange(Port::RangeChange);
}
Bus::BusFreeEvent::BusFreeEvent(Bus *_bus) : Event(&mainEventQueue), bus(_bus)
@@ -184,12 +196,13 @@ Bus::recvTiming(PacketPtr pkt)
}
} else {
//Snoop didn't succeed
- DPRINTF(Bus, "Adding a retry to RETRY list %i\n", pktPort);
+ DPRINTF(Bus, "Adding a retry to RETRY list %d\n",
+ pktPort->getId());
addToRetryList(pktPort);
return false;
}
} else {
- assert(dest >= 0 && dest < interfaces.size());
+ assert(dest >= 0 && dest < maxId);
assert(dest != pkt->getSrc()); // catch infinite loops
port = interfaces[dest];
}
@@ -201,7 +214,8 @@ Bus::recvTiming(PacketPtr pkt)
// Packet was successfully sent. Return true.
// Also take care of retries
if (inRetry) {
- DPRINTF(Bus, "Remove retry from list %i\n", retryList.front());
+ DPRINTF(Bus, "Remove retry from list %d\n",
+ retryList.front()->getId());
retryList.front()->onRetryList(false);
retryList.pop_front();
inRetry = false;
@@ -210,7 +224,8 @@ Bus::recvTiming(PacketPtr pkt)
}
// Packet not successfully sent. Leave or put it on the retry list.
- DPRINTF(Bus, "Adding a retry to RETRY list %i\n", pktPort);
+ DPRINTF(Bus, "Adding a retry to RETRY list %d\n",
+ pktPort->getId());
addToRetryList(pktPort);
return false;
}
@@ -436,7 +451,6 @@ Bus::recvStatusChange(Port::Status status, int id)
{
AddrRangeList ranges;
AddrRangeList snoops;
- int x;
AddrRangeIter iter;
assert(status == Port::RangeChange &&
@@ -458,7 +472,7 @@ Bus::recvStatusChange(Port::Status status, int id)
}
} else {
- assert((id < interfaces.size() && id >= 0) || id == defaultId);
+ assert((id < maxId && id >= 0) || id == defaultId);
Port *port = interfaces[id];
range_map<Addr,int>::iterator portIter;
std::vector<DevMap>::iterator snoopIter;
@@ -503,9 +517,11 @@ Bus::recvStatusChange(Port::Status status, int id)
// tell all our peers that our address range has changed.
// Don't tell the device that caused this change, it already knows
- for (x = 0; x < interfaces.size(); x++)
- if (x != id)
- interfaces[x]->sendStatusChange(Port::RangeChange);
+ m5::hash_map<short,BusPort*>::iterator intIter;
+
+ for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
+ if (intIter->first != id)
+ intIter->second->sendStatusChange(Port::RangeChange);
if (id != defaultId && defaultPort)
defaultPort->sendStatusChange(Port::RangeChange);
diff --git a/src/mem/bus.hh b/src/mem/bus.hh
index 0ad4aad60..6706b6c77 100644
--- a/src/mem/bus.hh
+++ b/src/mem/bus.hh
@@ -42,6 +42,7 @@
#include <inttypes.h>
#include "base/range.hh"
+#include "base/hashmap.hh"
#include "base/range_map.hh"
#include "mem/mem_object.hh"
#include "mem/packet.hh"
@@ -156,6 +157,8 @@ class Bus : public MemObject
void onRetryList(bool newVal)
{ _onRetryList = newVal; }
+ int getId() { return id; }
+
protected:
/** When reciving a timing request from the peer port (at id),
@@ -210,9 +213,12 @@ class Bus : public MemObject
bool inRetry;
+ /** max number of bus ids we've handed out so far */
+ short maxId;
+
/** An array of pointers to the peer port interfaces
connected to this bus.*/
- std::vector<BusPort*> interfaces;
+ m5::hash_map<short,BusPort*> interfaces;
/** An array of pointers to ports that retry should be called on because the
* original send failed for whatever reason.*/
@@ -250,6 +256,7 @@ class Bus : public MemObject
/** A function used to return the port associated with this bus object. */
virtual Port *getPort(const std::string &if_name, int idx = -1);
+ virtual void deletePortRefs(Port *p);
virtual void init();
@@ -259,7 +266,7 @@ class Bus : public MemObject
bool responder_set)
: MemObject(n), busId(bus_id), clock(_clock), width(_width),
tickNextIdle(0), drainEvent(NULL), busIdle(this), inRetry(false),
- defaultPort(NULL), responderSet(responder_set)
+ maxId(0), defaultPort(NULL), responderSet(responder_set)
{
//Both the width and clock period must be positive
if (width <= 0)
diff --git a/src/mem/cache/SConscript b/src/mem/cache/SConscript
new file mode 100644
index 000000000..7150719ad
--- /dev/null
+++ b/src/mem/cache/SConscript
@@ -0,0 +1,35 @@
+# -*- 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: Nathan Binkert
+
+Import('*')
+
+Source('base_cache.cc')
+Source('cache.cc')
+Source('cache_builder.cc')
diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc
index d9e6c5e1f..ed665dafb 100644
--- a/src/mem/cache/base_cache.cc
+++ b/src/mem/cache/base_cache.cc
@@ -356,7 +356,7 @@ BaseCache::CacheEvent::process()
const char *
BaseCache::CacheEvent::description()
{
- return "timing event\n";
+ return "BaseCache timing event";
}
void
@@ -370,17 +370,12 @@ BaseCache::init()
void
BaseCache::regStats()
{
- Request temp_req((Addr) NULL, 4, 0);
- Packet::Command temp_cmd = Packet::ReadReq;
- Packet temp_pkt(&temp_req, temp_cmd, 0); //@todo FIx command strings so this isn't neccessary
- temp_pkt.allocate(); //Temp allocate, all need data
-
using namespace Stats;
// Hit statistics
- for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::Command)access_idx;
- const string &cstr = temp_pkt.cmdIdxToString(cmd);
+ for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
+ MemCmd cmd(access_idx);
+ const string &cstr = cmd.toString();
hits[access_idx]
.init(maxThreadsPerCPU)
@@ -395,20 +390,20 @@ BaseCache::regStats()
.desc("number of demand (read+write) hits")
.flags(total)
;
- demandHits = hits[Packet::ReadReq] + hits[Packet::WriteReq];
+ demandHits = hits[MemCmd::ReadReq] + hits[MemCmd::WriteReq];
overallHits
.name(name() + ".overall_hits")
.desc("number of overall hits")
.flags(total)
;
- overallHits = demandHits + hits[Packet::SoftPFReq] + hits[Packet::HardPFReq]
- + hits[Packet::Writeback];
+ overallHits = demandHits + hits[MemCmd::SoftPFReq] + hits[MemCmd::HardPFReq]
+ + hits[MemCmd::Writeback];
// Miss statistics
- for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::Command)access_idx;
- const string &cstr = temp_pkt.cmdIdxToString(cmd);
+ for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
+ MemCmd cmd(access_idx);
+ const string &cstr = cmd.toString();
misses[access_idx]
.init(maxThreadsPerCPU)
@@ -423,20 +418,20 @@ BaseCache::regStats()
.desc("number of demand (read+write) misses")
.flags(total)
;
- demandMisses = misses[Packet::ReadReq] + misses[Packet::WriteReq];
+ demandMisses = misses[MemCmd::ReadReq] + misses[MemCmd::WriteReq];
overallMisses
.name(name() + ".overall_misses")
.desc("number of overall misses")
.flags(total)
;
- overallMisses = demandMisses + misses[Packet::SoftPFReq] +
- misses[Packet::HardPFReq] + misses[Packet::Writeback];
+ overallMisses = demandMisses + misses[MemCmd::SoftPFReq] +
+ misses[MemCmd::HardPFReq] + misses[MemCmd::Writeback];
// Miss latency statistics
- for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::Command)access_idx;
- const string &cstr = temp_pkt.cmdIdxToString(cmd);
+ for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
+ MemCmd cmd(access_idx);
+ const string &cstr = cmd.toString();
missLatency[access_idx]
.init(maxThreadsPerCPU)
@@ -451,20 +446,20 @@ BaseCache::regStats()
.desc("number of demand (read+write) miss cycles")
.flags(total)
;
- demandMissLatency = missLatency[Packet::ReadReq] + missLatency[Packet::WriteReq];
+ demandMissLatency = missLatency[MemCmd::ReadReq] + missLatency[MemCmd::WriteReq];
overallMissLatency
.name(name() + ".overall_miss_latency")
.desc("number of overall miss cycles")
.flags(total)
;
- overallMissLatency = demandMissLatency + missLatency[Packet::SoftPFReq] +
- missLatency[Packet::HardPFReq];
+ overallMissLatency = demandMissLatency + missLatency[MemCmd::SoftPFReq] +
+ missLatency[MemCmd::HardPFReq];
// access formulas
- for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::Command)access_idx;
- const string &cstr = temp_pkt.cmdIdxToString(cmd);
+ for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
+ MemCmd cmd(access_idx);
+ const string &cstr = cmd.toString();
accesses[access_idx]
.name(name() + "." + cstr + "_accesses")
@@ -490,9 +485,9 @@ BaseCache::regStats()
overallAccesses = overallHits + overallMisses;
// miss rate formulas
- for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::Command)access_idx;
- const string &cstr = temp_pkt.cmdIdxToString(cmd);
+ for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
+ MemCmd cmd(access_idx);
+ const string &cstr = cmd.toString();
missRate[access_idx]
.name(name() + "." + cstr + "_miss_rate")
@@ -518,9 +513,9 @@ BaseCache::regStats()
overallMissRate = overallMisses / overallAccesses;
// miss latency formulas
- for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::Command)access_idx;
- const string &cstr = temp_pkt.cmdIdxToString(cmd);
+ for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
+ MemCmd cmd(access_idx);
+ const string &cstr = cmd.toString();
avgMissLatency[access_idx]
.name(name() + "." + cstr + "_avg_miss_latency")
diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh
index c10d98e8e..ee871c1c4 100644
--- a/src/mem/cache/base_cache.hh
+++ b/src/mem/cache/base_cache.hh
@@ -200,14 +200,14 @@ class BaseCache : public MemObject
*/
/** Number of hits per thread for each type of command. @sa Packet::Command */
- Stats::Vector<> hits[NUM_MEM_CMDS];
+ Stats::Vector<> hits[MemCmd::NUM_MEM_CMDS];
/** Number of hits for demand accesses. */
Stats::Formula demandHits;
/** Number of hit for all accesses. */
Stats::Formula overallHits;
/** Number of misses per thread for each type of command. @sa Packet::Command */
- Stats::Vector<> misses[NUM_MEM_CMDS];
+ Stats::Vector<> misses[MemCmd::NUM_MEM_CMDS];
/** Number of misses for demand accesses. */
Stats::Formula demandMisses;
/** Number of misses for all accesses. */
@@ -217,28 +217,28 @@ class BaseCache : public MemObject
* Total number of cycles per thread/command spent waiting for a miss.
* Used to calculate the average miss latency.
*/
- Stats::Vector<> missLatency[NUM_MEM_CMDS];
+ Stats::Vector<> missLatency[MemCmd::NUM_MEM_CMDS];
/** Total number of cycles spent waiting for demand misses. */
Stats::Formula demandMissLatency;
/** Total number of cycles spent waiting for all misses. */
Stats::Formula overallMissLatency;
/** The number of accesses per command and thread. */
- Stats::Formula accesses[NUM_MEM_CMDS];
+ Stats::Formula accesses[MemCmd::NUM_MEM_CMDS];
/** The number of demand accesses. */
Stats::Formula demandAccesses;
/** The number of overall accesses. */
Stats::Formula overallAccesses;
/** The miss rate per command and thread. */
- Stats::Formula missRate[NUM_MEM_CMDS];
+ Stats::Formula missRate[MemCmd::NUM_MEM_CMDS];
/** The miss rate of all demand accesses. */
Stats::Formula demandMissRate;
/** The miss rate for all accesses. */
Stats::Formula overallMissRate;
/** The average miss latency per command and thread. */
- Stats::Formula avgMissLatency[NUM_MEM_CMDS];
+ Stats::Formula avgMissLatency[MemCmd::NUM_MEM_CMDS];
/** The average miss latency for demand misses. */
Stats::Formula demandAvgMissLatency;
/** The average miss latency for all misses. */
@@ -535,7 +535,7 @@ class BaseCache : public MemObject
}
}
else {
- if (pkt->cmd != Packet::UpgradeReq)
+ if (pkt->cmd != MemCmd::UpgradeReq)
{
delete pkt->req;
delete pkt;
@@ -594,7 +594,7 @@ class BaseCache : public MemObject
}
}
else {
- if (pkt->cmd != Packet::UpgradeReq)
+ if (pkt->cmd != MemCmd::UpgradeReq)
{
delete pkt->req;
delete pkt;
diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh
index 26dab2179..722ce216b 100644
--- a/src/mem/cache/cache.hh
+++ b/src/mem/cache/cache.hh
@@ -331,6 +331,7 @@ class Cache : public BaseCache
Cache(const std::string &_name, Params &params);
virtual Port *getPort(const std::string &if_name, int idx = -1);
+ virtual void deletePortRefs(Port *p);
virtual void recvStatusChange(Port::Status status, bool isCpuSide);
diff --git a/src/mem/cache/cache_blk.hh b/src/mem/cache/cache_blk.hh
index 7b999e4b1..fa00a0f5a 100644
--- a/src/mem/cache/cache_blk.hh
+++ b/src/mem/cache/cache_blk.hh
@@ -37,7 +37,7 @@
#include <list>
-#include "sim/root.hh" // for Tick
+#include "sim/core.hh" // for Tick
#include "arch/isa_traits.hh" // for Addr
#include "mem/request.hh"
@@ -249,7 +249,7 @@ class CacheBlk
}
}
- req->setScResult(success ? 1 : 0);
+ req->setExtraData(success ? 1 : 0);
clearLoadLocks();
return success;
} else {
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 08e226343..fc4660269 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -90,7 +90,7 @@ Cache(const std::string &_name,
coherence->setCache(this);
prefetcher->setCache(this);
invalidateReq = new Request((Addr) NULL, blkSize, 0);
- invalidatePkt = new Packet(invalidateReq, Packet::InvalidateReq, 0);
+ invalidatePkt = new Packet(invalidateReq, MemCmd::InvalidateReq, 0);
}
template<class TagStore, class Coherence>
@@ -206,7 +206,7 @@ Cache<TagStore,Coherence>::handleAccess(PacketPtr &pkt, int & lat,
// complete miss (no matching block)
if (pkt->req->isLocked() && pkt->isWrite()) {
// miss on store conditional... just give up now
- pkt->req->setScResult(0);
+ pkt->req->setExtraData(0);
pkt->flags |= SATISFIED;
}
}
@@ -239,7 +239,7 @@ Cache<TagStore,Coherence>::handleFill(BlkType *blk, PacketPtr &pkt,
target->flags |= SATISFIED;
- if (target->cmd == Packet::InvalidateReq) {
+ if (target->cmd == MemCmd::InvalidateReq) {
tags->invalidateBlk(blk);
blk = NULL;
}
@@ -316,7 +316,7 @@ Cache<TagStore,Coherence>::handleFill(BlkType *blk, MSHR * mshr,
Tick completion_time = tags->getHitLatency() +
transfer_offset ? pkt->finishTime : pkt->firstWordTime;
- if (target->cmd == Packet::InvalidateReq) {
+ if (target->cmd == MemCmd::InvalidateReq) {
//Mark the blk as invalid now, if it hasn't been already
if (blk) {
tags->invalidateBlk(blk);
@@ -430,7 +430,7 @@ Cache<TagStore,Coherence>::writebackBlk(BlkType *blk)
Request *writebackReq =
new Request(tags->regenerateBlkAddr(blk->tag, blk->set), blkSize, 0);
- PacketPtr writeback = new Packet(writebackReq, Packet::Writeback, -1);
+ PacketPtr writeback = new Packet(writebackReq, MemCmd::Writeback, -1);
writeback->allocate();
std::memcpy(writeback->getPtr<uint8_t>(),blk->data,blkSize);
@@ -560,11 +560,11 @@ Cache<TagStore,Coherence>::access(PacketPtr &pkt)
/** @todo make the fast write alloc (wh64) work with coherence. */
/** @todo Do we want to do fast writes for writebacks as well? */
if (!blk && pkt->getSize() >= blkSize && coherence->allowFastWrites() &&
- (pkt->cmd == Packet::WriteReq
- || pkt->cmd == Packet::WriteInvalidateReq) ) {
+ (pkt->cmd == MemCmd::WriteReq
+ || pkt->cmd == MemCmd::WriteInvalidateReq) ) {
// not outstanding misses, can do this
MSHR* outstanding_miss = missQueue->findMSHR(pkt->getAddr());
- if (pkt->cmd == Packet::WriteInvalidateReq || !outstanding_miss) {
+ if (pkt->cmd == MemCmd::WriteInvalidateReq || !outstanding_miss) {
if (outstanding_miss) {
warn("WriteInv doing a fastallocate"
"with an outstanding miss to the same address\n");
@@ -575,8 +575,10 @@ Cache<TagStore,Coherence>::access(PacketPtr &pkt)
}
}
while (!writebacks.empty()) {
- missQueue->doWriteback(writebacks.front());
+ PacketPtr wbPkt = writebacks.front();
+ missQueue->doWriteback(wbPkt);
writebacks.pop_front();
+ delete wbPkt;
}
DPRINTF(Cache, "%s %x %s\n", pkt->cmdString(), pkt->getAddr(),
@@ -586,12 +588,7 @@ Cache<TagStore,Coherence>::access(PacketPtr &pkt)
// Hit
hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++;
// clear dirty bit if write through
- if (pkt->needsResponse())
- respond(pkt, curTick+lat);
- if (pkt->cmd == Packet::Writeback) {
- //Signal that you can kill the pkt/req
- pkt->flags |= SATISFIED;
- }
+ respond(pkt, curTick+lat);
return true;
}
@@ -609,14 +606,14 @@ Cache<TagStore,Coherence>::access(PacketPtr &pkt)
if (pkt->flags & SATISFIED) {
// happens when a store conditional fails because it missed
// the cache completely
- if (pkt->needsResponse())
- respond(pkt, curTick+lat);
+ respond(pkt, curTick+lat);
} else {
missQueue->handleMiss(pkt, size, curTick + hitLatency);
}
- if (pkt->cmd == Packet::Writeback) {
+ if (!pkt->needsResponse()) {
//Need to clean up the packet on a writeback miss, but leave the request
+ //for the next level.
delete pkt;
}
@@ -632,11 +629,11 @@ Cache<TagStore,Coherence>::getPacket()
PacketPtr pkt = missQueue->getPacket();
if (pkt) {
if (!pkt->req->isUncacheable()) {
- if (pkt->cmd == Packet::HardPFReq)
- misses[Packet::HardPFReq][0/*pkt->req->getThreadNum()*/]++;
+ if (pkt->cmd == MemCmd::HardPFReq)
+ misses[MemCmd::HardPFReq][0/*pkt->req->getThreadNum()*/]++;
BlkType *blk = tags->findBlock(pkt->getAddr());
- Packet::Command cmd = coherence->getBusCmd(pkt->cmd,
- (blk)? blk->status : 0);
+ MemCmd cmd =
+ coherence->getBusCmd(pkt->cmd, (blk) ? blk->status : 0);
missQueue->setBusCmd(pkt, cmd);
}
}
@@ -655,7 +652,7 @@ Cache<TagStore,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr,
if (success && !(SIGNAL_NACK_HACK)) {
//Remember if it was an upgrade because writeback MSHR's are removed
//in Mark in Service
- bool upgrade = (mshr->pkt && mshr->pkt->cmd == Packet::UpgradeReq);
+ bool upgrade = (mshr->pkt && mshr->pkt->cmd == MemCmd::UpgradeReq);
missQueue->markInService(mshr->pkt, mshr);
@@ -726,8 +723,10 @@ Cache<TagStore,Coherence>::handleResponse(PacketPtr &pkt)
blk = handleFill(blk, (MSHR*)pkt->senderState,
new_state, writebacks, pkt);
while (!writebacks.empty()) {
- missQueue->doWriteback(writebacks.front());
- writebacks.pop_front();
+ PacketPtr wbPkt = writebacks.front();
+ missQueue->doWriteback(wbPkt);
+ writebacks.pop_front();
+ delete wbPkt;
}
}
missQueue->handleResponse(pkt, curTick + hitLatency);
@@ -780,8 +779,8 @@ Cache<TagStore,Coherence>::snoop(PacketPtr &pkt)
if (mshr) {
if (mshr->inService) {
if ((mshr->pkt->isInvalidate() || !mshr->pkt->isCacheFill())
- && (pkt->cmd != Packet::InvalidateReq
- && pkt->cmd != Packet::WriteInvalidateReq)) {
+ && (pkt->cmd != MemCmd::InvalidateReq
+ && pkt->cmd != MemCmd::WriteInvalidateReq)) {
//If the outstanding request was an invalidate
//(upgrade,readex,..) Then we need to ACK the request
//until we get the data Also NACK if the outstanding
@@ -987,11 +986,11 @@ Cache<TagStore,Coherence>::probe(PacketPtr &pkt, bool update,
panic("Atomic access ran into outstanding MSHR's or WB's!");
}
if (!pkt->req->isUncacheable() /*Uncacheables just go through*/
- && (pkt->cmd != Packet::Writeback)/*Writebacks on miss fall through*/) {
+ && (pkt->cmd != MemCmd::Writeback)/*Writebacks on miss fall through*/) {
// Fetch the cache block to fill
BlkType *blk = tags->findBlock(pkt->getAddr());
- Packet::Command temp_cmd = coherence->getBusCmd(pkt->cmd,
- (blk)? blk->status : 0);
+ MemCmd temp_cmd =
+ coherence->getBusCmd(pkt->cmd, (blk) ? blk->status : 0);
PacketPtr busPkt = new Packet(pkt->req,temp_cmd, -1, blkSize);
@@ -1045,8 +1044,10 @@ return 0;
// There was a cache hit.
// Handle writebacks if needed
while (!writebacks.empty()){
- memSidePort->sendAtomic(writebacks.front());
+ PacketPtr wbPkt = writebacks.front();
+ memSidePort->sendAtomic(wbPkt);
writebacks.pop_front();
+ delete wbPkt;
}
hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++;
@@ -1105,7 +1106,7 @@ Cache<TagStore,Coherence>::getPort(const std::string &if_name, int idx)
}
else if (if_name == "functional")
{
- return new CpuSidePort(name() + "-cpu_side_port", this);
+ return new CpuSidePort(name() + "-cpu_side_funcport", this);
}
else if (if_name == "cpu_side")
{
@@ -1126,6 +1127,15 @@ Cache<TagStore,Coherence>::getPort(const std::string &if_name, int idx)
else panic("Port name %s unrecognized\n", if_name);
}
+template<class TagStore, class Coherence>
+void
+Cache<TagStore,Coherence>::deletePortRefs(Port *p)
+{
+ if (cpuSidePort == p || memSidePort == p)
+ panic("Can only delete functional ports\n");
+ // nothing else to do
+}
+
template<class TagStore, class Coherence>
bool
@@ -1152,7 +1162,7 @@ Cache<TagStore,Coherence>::CpuSidePort::recvTiming(PacketPtr pkt)
}
if (pkt->isWrite() && (pkt->req->isLocked())) {
- pkt->req->setScResult(1);
+ pkt->req->setExtraData(1);
}
myCache()->access(pkt);
return true;
diff --git a/src/mem/cache/coherence/SConscript b/src/mem/cache/coherence/SConscript
new file mode 100644
index 000000000..03a2d85d7
--- /dev/null
+++ b/src/mem/cache/coherence/SConscript
@@ -0,0 +1,35 @@
+# -*- 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: Nathan Binkert
+
+Import('*')
+
+Source('coherence_protocol.cc')
+Source('uni_coherence.cc')
+
diff --git a/src/mem/cache/coherence/coherence_protocol.cc b/src/mem/cache/coherence/coherence_protocol.cc
index 3d7721805..e8520401d 100644
--- a/src/mem/cache/coherence/coherence_protocol.cc
+++ b/src/mem/cache/coherence/coherence_protocol.cc
@@ -47,7 +47,7 @@ using namespace std;
CoherenceProtocol::StateTransition::StateTransition()
- : busCmd(Packet::InvalidCmd), newState(-1), snoopFunc(invalidTransition)
+ : busCmd(MemCmd::InvalidCmd), newState(-1), snoopFunc(invalidTransition)
{
}
@@ -59,132 +59,132 @@ CoherenceProtocol::regStats()
// requestCount and snoopCount arrays, most of these are invalid,
// so we just select the interesting ones to print here.
- requestCount[Invalid][Packet::ReadReq]
+ requestCount[Invalid][MemCmd::ReadReq]
.name(name() + ".read_invalid")
.desc("read misses to invalid blocks")
;
- requestCount[Invalid][Packet::WriteReq]
+ requestCount[Invalid][MemCmd::WriteReq]
.name(name() +".write_invalid")
.desc("write misses to invalid blocks")
;
- requestCount[Invalid][Packet::SoftPFReq]
+ requestCount[Invalid][MemCmd::SoftPFReq]
.name(name() +".swpf_invalid")
.desc("soft prefetch misses to invalid blocks")
;
- requestCount[Invalid][Packet::HardPFReq]
+ requestCount[Invalid][MemCmd::HardPFReq]
.name(name() +".hwpf_invalid")
.desc("hard prefetch misses to invalid blocks")
;
- requestCount[Shared][Packet::WriteReq]
+ requestCount[Shared][MemCmd::WriteReq]
.name(name() + ".write_shared")
.desc("write misses to shared blocks")
;
- requestCount[Owned][Packet::WriteReq]
+ requestCount[Owned][MemCmd::WriteReq]
.name(name() + ".write_owned")
.desc("write misses to owned blocks")
;
- snoopCount[Shared][Packet::ReadReq]
+ snoopCount[Shared][MemCmd::ReadReq]
.name(name() + ".snoop_read_shared")
.desc("read snoops on shared blocks")
;
- snoopCount[Shared][Packet::ReadExReq]
+ snoopCount[Shared][MemCmd::ReadExReq]
.name(name() + ".snoop_readex_shared")
.desc("readEx snoops on shared blocks")
;
- snoopCount[Shared][Packet::UpgradeReq]
+ snoopCount[Shared][MemCmd::UpgradeReq]
.name(name() + ".snoop_upgrade_shared")
.desc("upgradee snoops on shared blocks")
;
- snoopCount[Modified][Packet::ReadReq]
+ snoopCount[Modified][MemCmd::ReadReq]
.name(name() + ".snoop_read_modified")
.desc("read snoops on modified blocks")
;
- snoopCount[Modified][Packet::ReadExReq]
+ snoopCount[Modified][MemCmd::ReadExReq]
.name(name() + ".snoop_readex_modified")
.desc("readEx snoops on modified blocks")
;
- snoopCount[Owned][Packet::ReadReq]
+ snoopCount[Owned][MemCmd::ReadReq]
.name(name() + ".snoop_read_owned")
.desc("read snoops on owned blocks")
;
- snoopCount[Owned][Packet::ReadExReq]
+ snoopCount[Owned][MemCmd::ReadExReq]
.name(name() + ".snoop_readex_owned")
.desc("readEx snoops on owned blocks")
;
- snoopCount[Owned][Packet::UpgradeReq]
+ snoopCount[Owned][MemCmd::UpgradeReq]
.name(name() + ".snoop_upgrade_owned")
.desc("upgrade snoops on owned blocks")
;
- snoopCount[Exclusive][Packet::ReadReq]
+ snoopCount[Exclusive][MemCmd::ReadReq]
.name(name() + ".snoop_read_exclusive")
.desc("read snoops on exclusive blocks")
;
- snoopCount[Exclusive][Packet::ReadExReq]
+ snoopCount[Exclusive][MemCmd::ReadExReq]
.name(name() + ".snoop_readex_exclusive")
.desc("readEx snoops on exclusive blocks")
;
- snoopCount[Shared][Packet::InvalidateReq]
+ snoopCount[Shared][MemCmd::InvalidateReq]
.name(name() + ".snoop_inv_shared")
.desc("Invalidate snoops on shared blocks")
;
- snoopCount[Owned][Packet::InvalidateReq]
+ snoopCount[Owned][MemCmd::InvalidateReq]
.name(name() + ".snoop_inv_owned")
.desc("Invalidate snoops on owned blocks")
;
- snoopCount[Exclusive][Packet::InvalidateReq]
+ snoopCount[Exclusive][MemCmd::InvalidateReq]
.name(name() + ".snoop_inv_exclusive")
.desc("Invalidate snoops on exclusive blocks")
;
- snoopCount[Modified][Packet::InvalidateReq]
+ snoopCount[Modified][MemCmd::InvalidateReq]
.name(name() + ".snoop_inv_modified")
.desc("Invalidate snoops on modified blocks")
;
- snoopCount[Invalid][Packet::InvalidateReq]
+ snoopCount[Invalid][MemCmd::InvalidateReq]
.name(name() + ".snoop_inv_invalid")
.desc("Invalidate snoops on invalid blocks")
;
- snoopCount[Shared][Packet::WriteInvalidateReq]
+ snoopCount[Shared][MemCmd::WriteInvalidateReq]
.name(name() + ".snoop_writeinv_shared")
.desc("WriteInvalidate snoops on shared blocks")
;
- snoopCount[Owned][Packet::WriteInvalidateReq]
+ snoopCount[Owned][MemCmd::WriteInvalidateReq]
.name(name() + ".snoop_writeinv_owned")
.desc("WriteInvalidate snoops on owned blocks")
;
- snoopCount[Exclusive][Packet::WriteInvalidateReq]
+ snoopCount[Exclusive][MemCmd::WriteInvalidateReq]
.name(name() + ".snoop_writeinv_exclusive")
.desc("WriteInvalidate snoops on exclusive blocks")
;
- snoopCount[Modified][Packet::WriteInvalidateReq]
+ snoopCount[Modified][MemCmd::WriteInvalidateReq]
.name(name() + ".snoop_writeinv_modified")
.desc("WriteInvalidate snoops on modified blocks")
;
- snoopCount[Invalid][Packet::WriteInvalidateReq]
+ snoopCount[Invalid][MemCmd::WriteInvalidateReq]
.name(name() + ".snoop_writeinv_invalid")
.desc("WriteInvalidate snoops on invalid blocks")
;
@@ -278,11 +278,13 @@ CoherenceProtocol::CoherenceProtocol(const string &name,
}
// set up a few shortcuts to save typing & visual clutter
- typedef Packet P;
- StateTransition (&tt)[stateMax+1][NUM_MEM_CMDS] = transitionTable;
+ typedef MemCmd MC;
+ StateTransition (&tt)[stateMax+1][MC::NUM_MEM_CMDS] = transitionTable;
- P::Command writeToSharedCmd = doUpgrades ? P::UpgradeReq : P::ReadExReq;
- P::Command writeToSharedResp = doUpgrades ? P::UpgradeReq : P::ReadExResp;
+ MC::Command writeToSharedCmd =
+ doUpgrades ? MC::UpgradeReq : MC::ReadExReq;
+ MC::Command writeToSharedResp =
+ doUpgrades ? MC::UpgradeReq : MC::ReadExResp;
// Note that all transitions by default cause a panic.
// Override the valid transitions with the appropriate actions here.
@@ -290,34 +292,34 @@ CoherenceProtocol::CoherenceProtocol(const string &name,
//
// ----- incoming requests: specify outgoing bus request -----
//
- tt[Invalid][P::ReadReq].onRequest(P::ReadReq);
+ tt[Invalid][MC::ReadReq].onRequest(MC::ReadReq);
// we only support write allocate right now
- tt[Invalid][P::WriteReq].onRequest(P::ReadExReq);
- tt[Shared][P::WriteReq].onRequest(writeToSharedCmd);
+ tt[Invalid][MC::WriteReq].onRequest(MC::ReadExReq);
+ tt[Shared][MC::WriteReq].onRequest(writeToSharedCmd);
if (hasOwned) {
- tt[Owned][P::WriteReq].onRequest(writeToSharedCmd);
+ tt[Owned][MC::WriteReq].onRequest(writeToSharedCmd);
}
// Prefetching causes a read
- tt[Invalid][P::SoftPFReq].onRequest(P::ReadReq);
- tt[Invalid][P::HardPFReq].onRequest(P::ReadReq);
+ tt[Invalid][MC::SoftPFReq].onRequest(MC::ReadReq);
+ tt[Invalid][MC::HardPFReq].onRequest(MC::ReadReq);
//
// ----- on response to given request: specify new state -----
//
- tt[Invalid][P::ReadExResp].onResponse(Modified);
+ tt[Invalid][MC::ReadExResp].onResponse(Modified);
tt[Shared][writeToSharedResp].onResponse(Modified);
// Go to Exclusive state on read response if we have one (will
// move into shared if the shared line is asserted in the
// getNewState function)
//
// originally had this as:
- // tt[Invalid][P::ReadResp].onResponse(hasExclusive ? Exclusive: Shared);
+ // tt[Invalid][MC::ReadResp].onResponse(hasExclusive ? Exclusive: Shared);
// ...but for some reason that caused a link error...
if (hasExclusive) {
- tt[Invalid][P::ReadResp].onResponse(Exclusive);
+ tt[Invalid][MC::ReadResp].onResponse(Exclusive);
} else {
- tt[Invalid][P::ReadResp].onResponse(Shared);
+ tt[Invalid][MC::ReadResp].onResponse(Shared);
}
if (hasOwned) {
tt[Owned][writeToSharedResp].onResponse(Modified);
@@ -326,58 +328,58 @@ CoherenceProtocol::CoherenceProtocol(const string &name,
//
// ----- bus snoop transition functions -----
//
- tt[Invalid][P::ReadReq].onSnoop(nullTransition);
- tt[Invalid][P::ReadExReq].onSnoop(nullTransition);
- tt[Invalid][P::InvalidateReq].onSnoop(invalidateTrans);
- tt[Invalid][P::WriteInvalidateReq].onSnoop(invalidateTrans);
- tt[Shared][P::ReadReq].onSnoop(hasExclusive
+ tt[Invalid][MC::ReadReq].onSnoop(nullTransition);
+ tt[Invalid][MC::ReadExReq].onSnoop(nullTransition);
+ tt[Invalid][MC::InvalidateReq].onSnoop(invalidateTrans);
+ tt[Invalid][MC::WriteInvalidateReq].onSnoop(invalidateTrans);
+ tt[Shared][MC::ReadReq].onSnoop(hasExclusive
? assertShared : nullTransition);
- tt[Shared][P::ReadExReq].onSnoop(invalidateTrans);
- tt[Shared][P::InvalidateReq].onSnoop(invalidateTrans);
- tt[Shared][P::WriteInvalidateReq].onSnoop(invalidateTrans);
+ tt[Shared][MC::ReadExReq].onSnoop(invalidateTrans);
+ tt[Shared][MC::InvalidateReq].onSnoop(invalidateTrans);
+ tt[Shared][MC::WriteInvalidateReq].onSnoop(invalidateTrans);
if (doUpgrades) {
- tt[Invalid][P::UpgradeReq].onSnoop(nullTransition);
- tt[Shared][P::UpgradeReq].onSnoop(invalidateTrans);
+ tt[Invalid][MC::UpgradeReq].onSnoop(nullTransition);
+ tt[Shared][MC::UpgradeReq].onSnoop(invalidateTrans);
}
- tt[Modified][P::ReadExReq].onSnoop(supplyAndInvalidateTrans);
- tt[Modified][P::ReadReq].onSnoop(hasOwned
+ tt[Modified][MC::ReadExReq].onSnoop(supplyAndInvalidateTrans);
+ tt[Modified][MC::ReadReq].onSnoop(hasOwned
? supplyAndGotoOwnedTrans
: supplyAndGotoSharedTrans);
- tt[Modified][P::InvalidateReq].onSnoop(invalidateTrans);
- tt[Modified][P::WriteInvalidateReq].onSnoop(invalidateTrans);
+ tt[Modified][MC::InvalidateReq].onSnoop(invalidateTrans);
+ tt[Modified][MC::WriteInvalidateReq].onSnoop(invalidateTrans);
if (hasExclusive) {
- tt[Exclusive][P::ReadReq].onSnoop(assertShared);
- tt[Exclusive][P::ReadExReq].onSnoop(invalidateTrans);
- tt[Exclusive][P::InvalidateReq].onSnoop(invalidateTrans);
- tt[Exclusive][P::WriteInvalidateReq].onSnoop(invalidateTrans);
+ tt[Exclusive][MC::ReadReq].onSnoop(assertShared);
+ tt[Exclusive][MC::ReadExReq].onSnoop(invalidateTrans);
+ tt[Exclusive][MC::InvalidateReq].onSnoop(invalidateTrans);
+ tt[Exclusive][MC::WriteInvalidateReq].onSnoop(invalidateTrans);
}
if (hasOwned) {
- tt[Owned][P::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
- tt[Owned][P::ReadExReq].onSnoop(supplyAndInvalidateTrans);
- tt[Owned][P::UpgradeReq].onSnoop(invalidateTrans);
- tt[Owned][P::InvalidateReq].onSnoop(invalidateTrans);
- tt[Owned][P::WriteInvalidateReq].onSnoop(invalidateTrans);
+ tt[Owned][MC::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
+ tt[Owned][MC::ReadExReq].onSnoop(supplyAndInvalidateTrans);
+ tt[Owned][MC::UpgradeReq].onSnoop(invalidateTrans);
+ tt[Owned][MC::InvalidateReq].onSnoop(invalidateTrans);
+ tt[Owned][MC::WriteInvalidateReq].onSnoop(invalidateTrans);
}
// @todo add in hardware prefetch to this list
}
-Packet::Command
-CoherenceProtocol::getBusCmd(Packet::Command cmdIn, CacheBlk::State state,
+MemCmd
+CoherenceProtocol::getBusCmd(MemCmd cmdIn, CacheBlk::State state,
MSHR *mshr)
{
state &= stateMask;
- int cmd_idx = (int) cmdIn;
+ int cmd_idx = cmdIn.toInt();
assert(0 <= state && state <= stateMax);
- assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS);
+ assert(0 <= cmd_idx && cmd_idx < MemCmd::NUM_MEM_CMDS);
- Packet::Command cmdOut = transitionTable[state][cmd_idx].busCmd;
+ MemCmd::Command cmdOut = transitionTable[state][cmd_idx].busCmd;
- assert(cmdOut != Packet::InvalidCmd);
+ assert(cmdOut != MemCmd::InvalidCmd);
++requestCount[state][cmd_idx];
@@ -392,7 +394,7 @@ CoherenceProtocol::getNewState(PacketPtr &pkt, CacheBlk::State oldState)
int cmd_idx = pkt->cmdToIndex();
assert(0 <= state && state <= stateMax);
- assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS);
+ assert(0 <= cmd_idx && cmd_idx < MemCmd::NUM_MEM_CMDS);
CacheBlk::State newState = transitionTable[state][cmd_idx].newState;
@@ -425,7 +427,7 @@ CoherenceProtocol::handleBusRequest(BaseCache *cache, PacketPtr &pkt,
int cmd_idx = pkt->cmdToIndex();
assert(0 <= state && state <= stateMax);
- assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS);
+ assert(0 <= cmd_idx && cmd_idx < MemCmd::NUM_MEM_CMDS);
// assert(mshr == NULL); // can't currently handle outstanding requests
//Check first if MSHR, and also insure, if there is one, that it is not in service
diff --git a/src/mem/cache/coherence/coherence_protocol.hh b/src/mem/cache/coherence/coherence_protocol.hh
index 481277523..775bc807a 100644
--- a/src/mem/cache/coherence/coherence_protocol.hh
+++ b/src/mem/cache/coherence/coherence_protocol.hh
@@ -80,8 +80,8 @@ class CoherenceProtocol : public SimObject
* @param mshr The MSHR matching the request.
* @return The proper bus command, as determined by the protocol.
*/
- Packet::Command getBusCmd(Packet::Command cmd, CacheBlk::State status,
- MSHR *mshr = NULL);
+ MemCmd getBusCmd(MemCmd cmd, CacheBlk::State status,
+ MSHR *mshr = NULL);
/**
* Return the proper state given the current state and the bus response.
@@ -235,7 +235,7 @@ class CoherenceProtocol : public SimObject
* The table of all possible transitions, organized by starting state and
* request command.
*/
- StateTransition transitionTable[stateMax+1][NUM_MEM_CMDS];
+ StateTransition transitionTable[stateMax+1][MemCmd::NUM_MEM_CMDS];
/**
* @addtogroup CoherenceStatistics
@@ -244,11 +244,11 @@ class CoherenceProtocol : public SimObject
/**
* State accesses from parent cache.
*/
- Stats::Scalar<> requestCount[stateMax+1][NUM_MEM_CMDS];
+ Stats::Scalar<> requestCount[stateMax+1][MemCmd::NUM_MEM_CMDS];
/**
* State accesses from snooped requests.
*/
- Stats::Scalar<> snoopCount[stateMax+1][NUM_MEM_CMDS];
+ Stats::Scalar<> snoopCount[stateMax+1][MemCmd::NUM_MEM_CMDS];
/**
* @}
*/
diff --git a/src/mem/cache/coherence/simple_coherence.hh b/src/mem/cache/coherence/simple_coherence.hh
index a1fd33080..1c89c703a 100644
--- a/src/mem/cache/coherence/simple_coherence.hh
+++ b/src/mem/cache/coherence/simple_coherence.hh
@@ -131,7 +131,7 @@ class SimpleCoherence
//Got rid of, there could be an MSHR, but it can't be in service
if (blk != NULL)
{
- if (pkt->cmd != Packet::Writeback) {
+ if (pkt->cmd != MemCmd::Writeback) {
return protocol->handleBusRequest(cache, pkt, blk, mshr,
new_state);
}
@@ -148,9 +148,10 @@ class SimpleCoherence
* @param state The current state of the cache block.
* @return The proper bus command, as determined by the protocol.
*/
- Packet::Command getBusCmd(Packet::Command &cmd, CacheBlk::State state)
+ MemCmd getBusCmd(MemCmd cmd,
+ CacheBlk::State state)
{
- if (cmd == Packet::Writeback) return Packet::Writeback;
+ if (cmd == MemCmd::Writeback) return MemCmd::Writeback;
return protocol->getBusCmd(cmd, state);
}
diff --git a/src/mem/cache/coherence/uni_coherence.cc b/src/mem/cache/coherence/uni_coherence.cc
index ea615d70a..6061c89c3 100644
--- a/src/mem/cache/coherence/uni_coherence.cc
+++ b/src/mem/cache/coherence/uni_coherence.cc
@@ -99,19 +99,19 @@ UniCoherence::propogateInvalidate(PacketPtr pkt, bool isTiming)
if (isTiming) {
// Forward to other caches
Request* req = new Request(pkt->req->getPaddr(), pkt->getSize(), 0);
- PacketPtr tmp = new Packet(req, Packet::InvalidateReq, -1);
+ PacketPtr tmp = new Packet(req, MemCmd::InvalidateReq, -1);
cshrs.allocate(tmp);
cache->setSlaveRequest(Request_Coherence, curTick);
if (cshrs.isFull())
cache->setBlockedForSnoop(Blocked_Coherence);
}
else {
- PacketPtr tmp = new Packet(pkt->req, Packet::InvalidateReq, -1);
+ PacketPtr tmp = new Packet(pkt->req, MemCmd::InvalidateReq, -1);
cache->cpuSidePort->sendAtomic(tmp);
delete tmp;
}
/**/
-/* PacketPtr tmp = new Packet(pkt->req, Packet::InvalidateReq, -1);
+/* PacketPtr tmp = new Packet(pkt->req, MemCmd::InvalidateReq, -1);
cache->cpuSidePort->sendFunctional(tmp);
delete tmp;
*/
@@ -119,7 +119,7 @@ UniCoherence::propogateInvalidate(PacketPtr pkt, bool isTiming)
if (pkt->isRead()) {
/*For now we will see if someone above us has the data by
doing a functional access on reads. Fix this later */
- PacketPtr tmp = new Packet(pkt->req, Packet::ReadReq, -1);
+ PacketPtr tmp = new Packet(pkt->req, MemCmd::ReadReq, -1);
tmp->allocate();
cache->cpuSidePort->sendFunctional(tmp);
bool hit = (tmp->result == Packet::Success);
diff --git a/src/mem/cache/coherence/uni_coherence.hh b/src/mem/cache/coherence/uni_coherence.hh
index 9a4aacdec..9efb4e192 100644
--- a/src/mem/cache/coherence/uni_coherence.hh
+++ b/src/mem/cache/coherence/uni_coherence.hh
@@ -77,13 +77,13 @@ class UniCoherence
* @return The proper bus command, as determined by the protocol.
* @todo Make changes so writebacks don't get here.
*/
- Packet::Command getBusCmd(Packet::Command &cmd, CacheBlk::State state)
+ MemCmd getBusCmd(MemCmd cmd, CacheBlk::State state)
{
- if (cmd == Packet::HardPFReq && state)
+ if (cmd == MemCmd::HardPFReq && state)
warn("Trying to issue a prefetch to a block we already have\n");
- if (cmd == Packet::Writeback)
- return Packet::Writeback;
- return Packet::ReadReq;
+ if (cmd == MemCmd::Writeback)
+ return MemCmd::Writeback;
+ return MemCmd::ReadReq;
}
/**
@@ -96,7 +96,7 @@ class UniCoherence
{
if (pkt->senderState) //Blocking Buffers don't get mshrs
{
- if (((MSHR *)(pkt->senderState))->originalCmd == Packet::HardPFReq) {
+ if (((MSHR *)(pkt->senderState))->originalCmd == MemCmd::HardPFReq) {
DPRINTF(HWPrefetch, "Marking a hardware prefetch as such in the state\n");
return BlkHWPrefetched | BlkValid | BlkWritable;
}
diff --git a/src/mem/cache/miss/SConscript b/src/mem/cache/miss/SConscript
new file mode 100644
index 000000000..0f81a2570
--- /dev/null
+++ b/src/mem/cache/miss/SConscript
@@ -0,0 +1,37 @@
+# -*- 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: Nathan Binkert
+
+Import('*')
+
+Source('blocking_buffer.cc')
+Source('miss_buffer.cc')
+Source('miss_queue.cc')
+Source('mshr.cc')
+Source('mshr_queue.cc')
diff --git a/src/mem/cache/miss/blocking_buffer.cc b/src/mem/cache/miss/blocking_buffer.cc
index a1af88341..e8ff26880 100644
--- a/src/mem/cache/miss/blocking_buffer.cc
+++ b/src/mem/cache/miss/blocking_buffer.cc
@@ -90,7 +90,7 @@ BlockingBuffer::getPacket()
}
void
-BlockingBuffer::setBusCmd(PacketPtr &pkt, Packet::Command cmd)
+BlockingBuffer::setBusCmd(PacketPtr &pkt, MemCmd cmd)
{
MSHR *mshr = (MSHR*) pkt->senderState;
mshr->originalCmd = pkt->cmd;
@@ -189,7 +189,7 @@ BlockingBuffer::doWriteback(Addr addr,
{
// Generate request
Request * req = new Request(addr, size, 0);
- PacketPtr pkt = new Packet(req, Packet::Writeback, -1);
+ PacketPtr pkt = new Packet(req, MemCmd::Writeback, -1);
pkt->allocate();
if (data) {
std::memcpy(pkt->getPtr<uint8_t>(), data, size);
diff --git a/src/mem/cache/miss/blocking_buffer.hh b/src/mem/cache/miss/blocking_buffer.hh
index 24386a249..86b24d539 100644
--- a/src/mem/cache/miss/blocking_buffer.hh
+++ b/src/mem/cache/miss/blocking_buffer.hh
@@ -104,7 +104,7 @@ public:
* @param pkt The request to update.
* @param cmd The bus command to use.
*/
- void setBusCmd(PacketPtr &pkt, Packet::Command cmd);
+ void setBusCmd(PacketPtr &pkt, MemCmd cmd);
/**
* Restore the original command in case of a bus transmission error.
diff --git a/src/mem/cache/miss/miss_buffer.hh b/src/mem/cache/miss/miss_buffer.hh
index 3e3080578..9a86db304 100644
--- a/src/mem/cache/miss/miss_buffer.hh
+++ b/src/mem/cache/miss/miss_buffer.hh
@@ -123,7 +123,7 @@ class MissBuffer
* @param pkt The request to update.
* @param cmd The bus command to use.
*/
- virtual void setBusCmd(PacketPtr &pkt, Packet::Command cmd) = 0;
+ virtual void setBusCmd(PacketPtr &pkt, MemCmd cmd) = 0;
/**
* Restore the original command in case of a bus transmission error.
diff --git a/src/mem/cache/miss/miss_queue.cc b/src/mem/cache/miss/miss_queue.cc
index 38c5ffa71..24ca9cfa2 100644
--- a/src/mem/cache/miss/miss_queue.cc
+++ b/src/mem/cache/miss/miss_queue.cc
@@ -67,17 +67,12 @@ MissQueue::regStats(const string &name)
{
MissBuffer::regStats(name);
- Request temp_req((Addr) NULL, 4, 0);
- Packet::Command temp_cmd = Packet::ReadReq;
- Packet temp_pkt(&temp_req, temp_cmd, 0); //@todo FIx command strings so this isn't neccessary
- temp_pkt.allocate();
-
using namespace Stats;
// MSHR hit statistics
- for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::Command)access_idx;
- const string &cstr = temp_pkt.cmdIdxToString(cmd);
+ for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
+ MemCmd cmd(access_idx);
+ const string &cstr = cmd.toString();
mshr_hits[access_idx]
.init(maxThreadsPerCPU)
@@ -92,20 +87,20 @@ MissQueue::regStats(const string &name)
.desc("number of demand (read+write) MSHR hits")
.flags(total)
;
- demandMshrHits = mshr_hits[Packet::ReadReq] + mshr_hits[Packet::WriteReq];
+ demandMshrHits = mshr_hits[MemCmd::ReadReq] + mshr_hits[MemCmd::WriteReq];
overallMshrHits
.name(name + ".overall_mshr_hits")
.desc("number of overall MSHR hits")
.flags(total)
;
- overallMshrHits = demandMshrHits + mshr_hits[Packet::SoftPFReq] +
- mshr_hits[Packet::HardPFReq];
+ overallMshrHits = demandMshrHits + mshr_hits[MemCmd::SoftPFReq] +
+ mshr_hits[MemCmd::HardPFReq];
// MSHR miss statistics
- for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::Command)access_idx;
- const string &cstr = temp_pkt.cmdIdxToString(cmd);
+ for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
+ MemCmd cmd(access_idx);
+ const string &cstr = cmd.toString();
mshr_misses[access_idx]
.init(maxThreadsPerCPU)
@@ -120,20 +115,20 @@ MissQueue::regStats(const string &name)
.desc("number of demand (read+write) MSHR misses")
.flags(total)
;
- demandMshrMisses = mshr_misses[Packet::ReadReq] + mshr_misses[Packet::WriteReq];
+ demandMshrMisses = mshr_misses[MemCmd::ReadReq] + mshr_misses[MemCmd::WriteReq];
overallMshrMisses
.name(name + ".overall_mshr_misses")
.desc("number of overall MSHR misses")
.flags(total)
;
- overallMshrMisses = demandMshrMisses + mshr_misses[Packet::SoftPFReq] +
- mshr_misses[Packet::HardPFReq];
+ overallMshrMisses = demandMshrMisses + mshr_misses[MemCmd::SoftPFReq] +
+ mshr_misses[MemCmd::HardPFReq];
// MSHR miss latency statistics
- for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::Command)access_idx;
- const string &cstr = temp_pkt.cmdIdxToString(cmd);
+ for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
+ MemCmd cmd(access_idx);
+ const string &cstr = cmd.toString();
mshr_miss_latency[access_idx]
.init(maxThreadsPerCPU)
@@ -148,8 +143,8 @@ MissQueue::regStats(const string &name)
.desc("number of demand (read+write) MSHR miss cycles")
.flags(total)
;
- demandMshrMissLatency = mshr_miss_latency[Packet::ReadReq]
- + mshr_miss_latency[Packet::WriteReq];
+ demandMshrMissLatency = mshr_miss_latency[MemCmd::ReadReq]
+ + mshr_miss_latency[MemCmd::WriteReq];
overallMshrMissLatency
.name(name + ".overall_mshr_miss_latency")
@@ -157,12 +152,12 @@ MissQueue::regStats(const string &name)
.flags(total)
;
overallMshrMissLatency = demandMshrMissLatency +
- mshr_miss_latency[Packet::SoftPFReq] + mshr_miss_latency[Packet::HardPFReq];
+ mshr_miss_latency[MemCmd::SoftPFReq] + mshr_miss_latency[MemCmd::HardPFReq];
// MSHR uncacheable statistics
- for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::Command)access_idx;
- const string &cstr = temp_pkt.cmdIdxToString(cmd);
+ for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
+ MemCmd cmd(access_idx);
+ const string &cstr = cmd.toString();
mshr_uncacheable[access_idx]
.init(maxThreadsPerCPU)
@@ -177,14 +172,14 @@ MissQueue::regStats(const string &name)
.desc("number of overall MSHR uncacheable misses")
.flags(total)
;
- overallMshrUncacheable = mshr_uncacheable[Packet::ReadReq]
- + mshr_uncacheable[Packet::WriteReq] + mshr_uncacheable[Packet::SoftPFReq]
- + mshr_uncacheable[Packet::HardPFReq];
+ overallMshrUncacheable = mshr_uncacheable[MemCmd::ReadReq]
+ + mshr_uncacheable[MemCmd::WriteReq] + mshr_uncacheable[MemCmd::SoftPFReq]
+ + mshr_uncacheable[MemCmd::HardPFReq];
// MSHR miss latency statistics
- for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::Command)access_idx;
- const string &cstr = temp_pkt.cmdIdxToString(cmd);
+ for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
+ MemCmd cmd(access_idx);
+ const string &cstr = cmd.toString();
mshr_uncacheable_lat[access_idx]
.init(maxThreadsPerCPU)
@@ -199,16 +194,16 @@ MissQueue::regStats(const string &name)
.desc("number of overall MSHR uncacheable cycles")
.flags(total)
;
- overallMshrUncacheableLatency = mshr_uncacheable_lat[Packet::ReadReq]
- + mshr_uncacheable_lat[Packet::WriteReq]
- + mshr_uncacheable_lat[Packet::SoftPFReq]
- + mshr_uncacheable_lat[Packet::HardPFReq];
+ overallMshrUncacheableLatency = mshr_uncacheable_lat[MemCmd::ReadReq]
+ + mshr_uncacheable_lat[MemCmd::WriteReq]
+ + mshr_uncacheable_lat[MemCmd::SoftPFReq]
+ + mshr_uncacheable_lat[MemCmd::HardPFReq];
#if 0
// MSHR access formulas
- for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::Command)access_idx;
- const string &cstr = temp_pkt.cmdIdxToString(cmd);
+ for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
+ MemCmd cmd(access_idx);
+ const string &cstr = cmd.toString();
mshrAccesses[access_idx]
.name(name + "." + cstr + "_mshr_accesses")
@@ -237,9 +232,9 @@ MissQueue::regStats(const string &name)
#endif
// MSHR miss rate formulas
- for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::Command)access_idx;
- const string &cstr = temp_pkt.cmdIdxToString(cmd);
+ for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
+ MemCmd cmd(access_idx);
+ const string &cstr = cmd.toString();
mshrMissRate[access_idx]
.name(name + "." + cstr + "_mshr_miss_rate")
@@ -266,9 +261,9 @@ MissQueue::regStats(const string &name)
overallMshrMissRate = overallMshrMisses / cache->overallAccesses;
// mshrMiss latency formulas
- for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::Command)access_idx;
- const string &cstr = temp_pkt.cmdIdxToString(cmd);
+ for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
+ MemCmd cmd(access_idx);
+ const string &cstr = cmd.toString();
avgMshrMissLatency[access_idx]
.name(name + "." + cstr + "_avg_mshr_miss_latency")
@@ -295,9 +290,9 @@ MissQueue::regStats(const string &name)
overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
// mshrUncacheable latency formulas
- for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::Command)access_idx;
- const string &cstr = temp_pkt.cmdIdxToString(cmd);
+ for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
+ MemCmd cmd(access_idx);
+ const string &cstr = cmd.toString();
avgMshrUncacheableLatency[access_idx]
.name(name + "." + cstr + "_avg_mshr_uncacheable_latency")
@@ -351,7 +346,7 @@ MissQueue::allocateMiss(PacketPtr &pkt, int size, Tick time)
if (mq.isFull()) {
cache->setBlocked(Blocked_NoMSHRs);
}
- if (pkt->cmd != Packet::HardPFReq) {
+ if (pkt->cmd != MemCmd::HardPFReq) {
//If we need to request the bus (not on HW prefetch), do so
cache->setMasterRequest(Request_MSHR, time);
}
@@ -500,17 +495,17 @@ MissQueue::getPacket()
}
void
-MissQueue::setBusCmd(PacketPtr &pkt, Packet::Command cmd)
+MissQueue::setBusCmd(PacketPtr &pkt, MemCmd cmd)
{
assert(pkt->senderState != 0);
MSHR * mshr = (MSHR*)pkt->senderState;
mshr->originalCmd = pkt->cmd;
- if (cmd == Packet::UpgradeReq || cmd == Packet::InvalidateReq) {
+ if (cmd == MemCmd::UpgradeReq || cmd == MemCmd::InvalidateReq) {
pkt->flags |= NO_ALLOCATE;
pkt->flags &= ~CACHE_LINE_FILL;
}
else if (!pkt->req->isUncacheable() && !pkt->isNoAllocate() &&
- (cmd & (1 << 6)/*NeedsResponse*/)) {
+ cmd.needsResponse()) {
pkt->flags |= CACHE_LINE_FILL;
}
if (pkt->isCacheFill() || pkt->isNoAllocate())
@@ -552,7 +547,7 @@ MissQueue::markInService(PacketPtr &pkt, MSHR* mshr)
if (!mq.havePending()){
cache->clearMasterRequest(Request_MSHR);
}
- if (mshr->originalCmd == Packet::HardPFReq) {
+ if (mshr->originalCmd == MemCmd::HardPFReq) {
DPRINTF(HWPrefetch, "%s:Marking a HW_PF in service\n",
cache->name());
//Also clear pending if need be
@@ -576,7 +571,7 @@ void
MissQueue::handleResponse(PacketPtr &pkt, Tick time)
{
MSHR* mshr = (MSHR*)pkt->senderState;
- if (((MSHR*)(pkt->senderState))->originalCmd == Packet::HardPFReq) {
+ if (((MSHR*)(pkt->senderState))->originalCmd == MemCmd::HardPFReq) {
DPRINTF(HWPrefetch, "%s:Handling the response to a HW_PF\n",
cache->name());
}
@@ -589,7 +584,7 @@ MissQueue::handleResponse(PacketPtr &pkt, Tick time)
BlockedCause cause = NUM_BLOCKED_CAUSES;
if (pkt->isCacheFill() && !pkt->isNoAllocate()) {
- mshr_miss_latency[mshr->originalCmd][0/*pkt->req->getThreadNum()*/] +=
+ mshr_miss_latency[mshr->originalCmd.toInt()][0/*pkt->req->getThreadNum()*/] +=
curTick - pkt->time;
// targets were handled in the cache tags
if (mshr == noTargetMSHR) {
@@ -601,7 +596,7 @@ MissQueue::handleResponse(PacketPtr &pkt, Tick time)
if (mshr->hasTargets()) {
// Didn't satisfy all the targets, need to resend
- Packet::Command cmd = mshr->getTarget()->cmd;
+ MemCmd cmd = mshr->getTarget()->cmd;
mshr->pkt->setDest(Packet::Broadcast);
mshr->pkt->result = Packet::Unknown;
mshr->pkt->req = mshr->getTarget()->req;
@@ -619,7 +614,7 @@ MissQueue::handleResponse(PacketPtr &pkt, Tick time)
}
} else {
if (pkt->req->isUncacheable()) {
- mshr_uncacheable_lat[pkt->cmd][0/*pkt->req->getThreadNum()*/] +=
+ mshr_uncacheable_lat[pkt->cmd.toInt()][0/*pkt->req->getThreadNum()*/] +=
curTick - pkt->time;
}
if (mshr->hasTargets() && pkt->req->isUncacheable()) {
@@ -714,7 +709,7 @@ MissQueue::doWriteback(Addr addr,
{
// Generate request
Request * req = new Request(addr, size, 0);
- PacketPtr pkt = new Packet(req, Packet::Writeback, -1);
+ PacketPtr pkt = new Packet(req, MemCmd::Writeback, -1);
pkt->allocate();
if (data) {
memcpy(pkt->getPtr<uint8_t>(), data, size);
diff --git a/src/mem/cache/miss/miss_queue.hh b/src/mem/cache/miss/miss_queue.hh
index 1f9bb1e0c..d3560ff36 100644
--- a/src/mem/cache/miss/miss_queue.hh
+++ b/src/mem/cache/miss/miss_queue.hh
@@ -77,59 +77,59 @@ class MissQueue : public MissBuffer
* @{
*/
/** Number of misses that hit in the MSHRs per command and thread. */
- Stats::Vector<> mshr_hits[NUM_MEM_CMDS];
+ Stats::Vector<> mshr_hits[MemCmd::NUM_MEM_CMDS];
/** Demand misses that hit in the MSHRs. */
Stats::Formula demandMshrHits;
/** Total number of misses that hit in the MSHRs. */
Stats::Formula overallMshrHits;
/** Number of misses that miss in the MSHRs, per command and thread. */
- Stats::Vector<> mshr_misses[NUM_MEM_CMDS];
+ Stats::Vector<> mshr_misses[MemCmd::NUM_MEM_CMDS];
/** Demand misses that miss in the MSHRs. */
Stats::Formula demandMshrMisses;
/** Total number of misses that miss in the MSHRs. */
Stats::Formula overallMshrMisses;
/** Number of misses that miss in the MSHRs, per command and thread. */
- Stats::Vector<> mshr_uncacheable[NUM_MEM_CMDS];
+ Stats::Vector<> mshr_uncacheable[MemCmd::NUM_MEM_CMDS];
/** Total number of misses that miss in the MSHRs. */
Stats::Formula overallMshrUncacheable;
/** Total cycle latency of each MSHR miss, per command and thread. */
- Stats::Vector<> mshr_miss_latency[NUM_MEM_CMDS];
+ Stats::Vector<> mshr_miss_latency[MemCmd::NUM_MEM_CMDS];
/** Total cycle latency of demand MSHR misses. */
Stats::Formula demandMshrMissLatency;
/** Total cycle latency of overall MSHR misses. */
Stats::Formula overallMshrMissLatency;
/** Total cycle latency of each MSHR miss, per command and thread. */
- Stats::Vector<> mshr_uncacheable_lat[NUM_MEM_CMDS];
+ Stats::Vector<> mshr_uncacheable_lat[MemCmd::NUM_MEM_CMDS];
/** Total cycle latency of overall MSHR misses. */
Stats::Formula overallMshrUncacheableLatency;
/** The total number of MSHR accesses per command and thread. */
- Stats::Formula mshrAccesses[NUM_MEM_CMDS];
+ Stats::Formula mshrAccesses[MemCmd::NUM_MEM_CMDS];
/** The total number of demand MSHR accesses. */
Stats::Formula demandMshrAccesses;
/** The total number of MSHR accesses. */
Stats::Formula overallMshrAccesses;
/** The miss rate in the MSHRs pre command and thread. */
- Stats::Formula mshrMissRate[NUM_MEM_CMDS];
+ Stats::Formula mshrMissRate[MemCmd::NUM_MEM_CMDS];
/** The demand miss rate in the MSHRs. */
Stats::Formula demandMshrMissRate;
/** The overall miss rate in the MSHRs. */
Stats::Formula overallMshrMissRate;
/** The average latency of an MSHR miss, per command and thread. */
- Stats::Formula avgMshrMissLatency[NUM_MEM_CMDS];
+ Stats::Formula avgMshrMissLatency[MemCmd::NUM_MEM_CMDS];
/** The average latency of a demand MSHR miss. */
Stats::Formula demandAvgMshrMissLatency;
/** The average overall latency of an MSHR miss. */
Stats::Formula overallAvgMshrMissLatency;
/** The average latency of an MSHR miss, per command and thread. */
- Stats::Formula avgMshrUncacheableLatency[NUM_MEM_CMDS];
+ Stats::Formula avgMshrUncacheableLatency[MemCmd::NUM_MEM_CMDS];
/** The average overall latency of an MSHR miss. */
Stats::Formula overallAvgMshrUncacheableLatency;
@@ -220,7 +220,7 @@ class MissQueue : public MissBuffer
* @param pkt The request to update.
* @param cmd The bus command to use.
*/
- void setBusCmd(PacketPtr &pkt, Packet::Command cmd);
+ void setBusCmd(PacketPtr &pkt, MemCmd cmd);
/**
* Restore the original command in case of a bus transmission error.
diff --git a/src/mem/cache/miss/mshr.cc b/src/mem/cache/miss/mshr.cc
index fc520b4b4..74dad658b 100644
--- a/src/mem/cache/miss/mshr.cc
+++ b/src/mem/cache/miss/mshr.cc
@@ -39,7 +39,7 @@
#include <vector>
#include "mem/cache/miss/mshr.hh"
-#include "sim/root.hh" // for curTick
+#include "sim/core.hh" // for curTick
#include "sim/host.hh"
#include "base/misc.hh"
#include "mem/cache/cache.hh"
@@ -54,7 +54,7 @@ MSHR::MSHR()
}
void
-MSHR::allocate(Packet::Command cmd, Addr _addr, int size,
+MSHR::allocate(MemCmd cmd, Addr _addr, int size,
PacketPtr &target)
{
addr = _addr;
@@ -148,7 +148,7 @@ MSHR::allocateTarget(PacketPtr &target)
*/
if (!inService && target->isWrite()) {
- pkt->cmd = Packet::WriteReq;
+ pkt->cmd = MemCmd::WriteReq;
}
}
diff --git a/src/mem/cache/miss/mshr.hh b/src/mem/cache/miss/mshr.hh
index 281ea9d49..d0410acda 100644
--- a/src/mem/cache/miss/mshr.hh
+++ b/src/mem/cache/miss/mshr.hh
@@ -72,7 +72,7 @@ class MSHR {
/** The number of currently allocated targets. */
short ntargets;
/** The original requesting command. */
- Packet::Command originalCmd;
+ MemCmd originalCmd;
/** Order number of assigned by the miss queue. */
uint64_t order;
@@ -100,7 +100,7 @@ public:
* @param size The number of bytes to request.
* @param pkt The original miss.
*/
- void allocate(Packet::Command cmd, Addr addr, int size,
+ void allocate(MemCmd cmd, Addr addr, int size,
PacketPtr &pkt);
/**
diff --git a/src/mem/cache/miss/mshr_queue.cc b/src/mem/cache/miss/mshr_queue.cc
index 6cb62429d..add11dfe7 100644
--- a/src/mem/cache/miss/mshr_queue.cc
+++ b/src/mem/cache/miss/mshr_queue.cc
@@ -136,7 +136,7 @@ MSHRQueue::allocateFetch(Addr addr, int size, PacketPtr &target)
MSHR *mshr = freeList.front();
assert(mshr->getNumTargets() == 0);
freeList.pop_front();
- mshr->allocate(Packet::ReadReq, addr, size, target);
+ mshr->allocate(MemCmd::ReadReq, addr, size, target);
mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
mshr->readyIter = pendingList.insert(pendingList.end(), mshr);
@@ -151,7 +151,7 @@ MSHRQueue::allocateTargetList(Addr addr, int size)
assert(mshr->getNumTargets() == 0);
freeList.pop_front();
PacketPtr dummy;
- mshr->allocate(Packet::ReadReq, addr, size, dummy);
+ mshr->allocate(MemCmd::ReadReq, addr, size, dummy);
mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
mshr->inService = true;
++inServiceMSHRs;
@@ -196,7 +196,7 @@ void
MSHRQueue::markInService(MSHR* mshr)
{
//assert(mshr == pendingList.front());
- if (!mshr->pkt->needsResponse() && !(mshr->pkt->cmd == Packet::UpgradeReq)) {
+ if (!mshr->pkt->needsResponse() && !(mshr->pkt->cmd == MemCmd::UpgradeReq)) {
assert(mshr->getNumTargets() == 0);
deallocate(mshr);
return;
@@ -209,7 +209,7 @@ MSHRQueue::markInService(MSHR* mshr)
}
void
-MSHRQueue::markPending(MSHR* mshr, Packet::Command cmd)
+MSHRQueue::markPending(MSHR* mshr, MemCmd cmd)
{
//assert(mshr->readyIter == NULL);
mshr->pkt->cmd = cmd;
diff --git a/src/mem/cache/miss/mshr_queue.hh b/src/mem/cache/miss/mshr_queue.hh
index ec2ddae8a..5069db661 100644
--- a/src/mem/cache/miss/mshr_queue.hh
+++ b/src/mem/cache/miss/mshr_queue.hh
@@ -185,7 +185,7 @@ class MSHRQueue {
* @param mshr The MSHR to resend.
* @param cmd The command to resend.
*/
- void markPending(MSHR* mshr, Packet::Command cmd);
+ void markPending(MSHR* mshr, MemCmd cmd);
/**
* Squash outstanding requests with the given thread number. If a request
diff --git a/src/mem/cache/prefetch/SConscript b/src/mem/cache/prefetch/SConscript
new file mode 100644
index 000000000..8a7f1232c
--- /dev/null
+++ b/src/mem/cache/prefetch/SConscript
@@ -0,0 +1,37 @@
+# -*- 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: Nathan Binkert
+
+Import('*')
+
+Source('base_prefetcher.cc')
+Source('ghb_prefetcher.cc')
+Source('stride_prefetcher.cc')
+Source('tagged_prefetcher.cc')
+
diff --git a/src/mem/cache/prefetch/base_prefetcher.cc b/src/mem/cache/prefetch/base_prefetcher.cc
index 4254800b1..44daf75e1 100644
--- a/src/mem/cache/prefetch/base_prefetcher.cc
+++ b/src/mem/cache/prefetch/base_prefetcher.cc
@@ -200,7 +200,7 @@ BasePrefetcher::handleMiss(PacketPtr &pkt, Tick time)
//create a prefetch memreq
Request * prefetchReq = new Request(*addr, blkSize, 0);
PacketPtr prefetch;
- prefetch = new Packet(prefetchReq, Packet::HardPFReq, -1);
+ prefetch = new Packet(prefetchReq, MemCmd::HardPFReq, -1);
prefetch->allocate();
prefetch->req->setThreadContext(pkt->req->getCpuNum(),
pkt->req->getThreadNum());
diff --git a/src/mem/cache/tags/SConscript b/src/mem/cache/tags/SConscript
new file mode 100644
index 000000000..baf71f687
--- /dev/null
+++ b/src/mem/cache/tags/SConscript
@@ -0,0 +1,42 @@
+# -*- 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: Nathan Binkert
+
+Import('*')
+
+Source('base_tags.cc')
+Source('fa_lru.cc')
+Source('iic.cc')
+Source('lru.cc')
+Source('split.cc')
+Source('split_lifo.cc')
+Source('split_lru.cc')
+
+Source('repl/gen.cc')
+Source('repl/repl.cc')
diff --git a/src/mem/cache/tags/iic.cc b/src/mem/cache/tags/iic.cc
index e547e112e..9c802d0dc 100644
--- a/src/mem/cache/tags/iic.cc
+++ b/src/mem/cache/tags/iic.cc
@@ -42,7 +42,7 @@
#include "mem/cache/base_cache.hh"
#include "mem/cache/tags/iic.hh"
#include "base/intmath.hh"
-#include "sim/root.hh" // for curTick
+#include "sim/core.hh" // for curTick
#include "base/trace.hh" // for DPRINTF
@@ -372,7 +372,8 @@ IIC::freeReplacementBlock(PacketList & writebacks)
*/
Request *writebackReq = new Request(regenerateBlkAddr(tag_ptr->tag, 0),
blkSize, 0);
- PacketPtr writeback = new Packet(writebackReq, Packet::Writeback, -1);
+ PacketPtr writeback = new Packet(writebackReq, MemCmd::Writeback,
+ -1);
writeback->allocate();
memcpy(writeback->getPtr<uint8_t>(), tag_ptr->data, blkSize);
diff --git a/src/mem/cache/tags/lru.cc b/src/mem/cache/tags/lru.cc
index 102bb3506..8e8779774 100644
--- a/src/mem/cache/tags/lru.cc
+++ b/src/mem/cache/tags/lru.cc
@@ -38,7 +38,7 @@
#include "mem/cache/base_cache.hh"
#include "base/intmath.hh"
#include "mem/cache/tags/lru.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
using namespace std;
diff --git a/src/mem/cache/tags/split_lifo.cc b/src/mem/cache/tags/split_lifo.cc
index 792ff8fa7..d71d1a3ef 100644
--- a/src/mem/cache/tags/split_lifo.cc
+++ b/src/mem/cache/tags/split_lifo.cc
@@ -38,7 +38,7 @@
#include "mem/cache/base_cache.hh"
#include "base/intmath.hh"
#include "mem/cache/tags/split_lifo.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
#include "base/trace.hh"
using namespace std;
diff --git a/src/mem/cache/tags/split_lru.cc b/src/mem/cache/tags/split_lru.cc
index c37d72cb7..7227fb5c1 100644
--- a/src/mem/cache/tags/split_lru.cc
+++ b/src/mem/cache/tags/split_lru.cc
@@ -38,7 +38,7 @@
#include "mem/cache/base_cache.hh"
#include "base/intmath.hh"
#include "mem/cache/tags/split_lru.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
using namespace std;
diff --git a/src/mem/mem_object.cc b/src/mem/mem_object.cc
index d4d3fd283..ef31cf999 100644
--- a/src/mem/mem_object.cc
+++ b/src/mem/mem_object.cc
@@ -35,5 +35,10 @@ MemObject::MemObject(const std::string &name)
: SimObject(name)
{
}
+void
+MemObject::deletePortRefs(Port *p)
+{
+ panic("This object does not support port deletion\n");
+}
DEFINE_SIM_OBJECT_CLASS_NAME("MemObject", MemObject)
diff --git a/src/mem/mem_object.hh b/src/mem/mem_object.hh
index d12eeffe0..ec6fa2b2a 100644
--- a/src/mem/mem_object.hh
+++ b/src/mem/mem_object.hh
@@ -51,6 +51,10 @@ class MemObject : public SimObject
public:
/** Additional function to return the Port of a memory object. */
virtual Port *getPort(const std::string &if_name, int idx = -1) = 0;
+
+ /** Tell object that this port is about to disappear, so it should remove it
+ * from any structures that it's keeping it in. */
+ virtual void deletePortRefs(Port *p) ;
};
#endif //__MEM_MEM_OBJECT_HH__
diff --git a/src/mem/packet.cc b/src/mem/packet.cc
index 44805236c..14d08db1b 100644
--- a/src/mem/packet.cc
+++ b/src/mem/packet.cc
@@ -41,68 +41,68 @@
#include "base/trace.hh"
#include "mem/packet.hh"
-static const std::string ReadReqString("ReadReq");
-static const std::string WriteReqString("WriteReq");
-static const std::string WriteReqNoAckString("WriteReqNoAck|Writeback");
-static const std::string ReadRespString("ReadResp");
-static const std::string WriteRespString("WriteResp");
-static const std::string SoftPFReqString("SoftPFReq");
-static const std::string SoftPFRespString("SoftPFResp");
-static const std::string HardPFReqString("HardPFReq");
-static const std::string HardPFRespString("HardPFResp");
-static const std::string InvalidateReqString("InvalidateReq");
-static const std::string WriteInvalidateReqString("WriteInvalidateReq");
-static const std::string WriteInvalidateRespString("WriteInvalidateResp");
-static const std::string UpgradeReqString("UpgradeReq");
-static const std::string ReadExReqString("ReadExReq");
-static const std::string ReadExRespString("ReadExResp");
-static const std::string OtherCmdString("<other>");
+// The one downside to bitsets is that static initializers can get ugly.
+#define SET1(a1) (1 << (a1))
+#define SET2(a1, a2) (SET1(a1) | SET1(a2))
+#define SET3(a1, a2, a3) (SET2(a1, a2) | SET1(a3))
+#define SET4(a1, a2, a3, a4) (SET3(a1, a2, a3) | SET1(a4))
+#define SET5(a1, a2, a3, a4, a5) (SET4(a1, a2, a3, a4) | SET1(a5))
+#define SET6(a1, a2, a3, a4, a5, a6) (SET5(a1, a2, a3, a4, a5) | SET1(a6))
-const std::string &
-Packet::cmdString() const
+const MemCmd::CommandInfo
+MemCmd::commandInfo[] =
{
- switch (cmd) {
- case ReadReq: return ReadReqString;
- case WriteReq: return WriteReqString;
- case WriteReqNoAck: return WriteReqNoAckString;
- case ReadResp: return ReadRespString;
- case WriteResp: return WriteRespString;
- case SoftPFReq: return SoftPFReqString;
- case SoftPFResp: return SoftPFRespString;
- case HardPFReq: return HardPFReqString;
- case HardPFResp: return HardPFRespString;
- case InvalidateReq: return InvalidateReqString;
- case WriteInvalidateReq:return WriteInvalidateReqString;
- case WriteInvalidateResp:return WriteInvalidateRespString;
- case UpgradeReq: return UpgradeReqString;
- case ReadExReq: return ReadExReqString;
- case ReadExResp: return ReadExRespString;
- default: return OtherCmdString;
- }
-}
+ /* InvalidCmd */
+ { 0, InvalidCmd, "InvalidCmd" },
+ /* ReadReq */
+ { SET3(IsRead, IsRequest, NeedsResponse), ReadResp, "ReadReq" },
+ /* WriteReq */
+ { SET4(IsWrite, IsRequest, NeedsResponse, HasData),
+ WriteResp, "WriteReq" },
+ /* WriteReqNoAck */
+ { SET3(IsWrite, IsRequest, HasData), InvalidCmd, "WriteReqNoAck" },
+ /* ReadResp */
+ { SET3(IsRead, IsResponse, HasData), InvalidCmd, "ReadResp" },
+ /* WriteResp */
+ { SET2(IsWrite, IsResponse), InvalidCmd, "WriteResp" },
+ /* Writeback */
+ { SET3(IsWrite, IsRequest, HasData), InvalidCmd, "Writeback" },
+ /* SoftPFReq */
+ { SET4(IsRead, IsRequest, IsSWPrefetch, NeedsResponse),
+ SoftPFResp, "SoftPFReq" },
+ /* HardPFReq */
+ { SET4(IsRead, IsRequest, IsHWPrefetch, NeedsResponse),
+ HardPFResp, "HardPFReq" },
+ /* SoftPFResp */
+ { SET4(IsRead, IsResponse, IsSWPrefetch, HasData),
+ InvalidCmd, "SoftPFResp" },
+ /* HardPFResp */
+ { SET4(IsRead, IsResponse, IsHWPrefetch, HasData),
+ InvalidCmd, "HardPFResp" },
+ /* InvalidateReq */
+ { SET2(IsInvalidate, IsRequest), InvalidCmd, "InvalidateReq" },
+ /* WriteInvalidateReq */
+ { SET5(IsWrite, IsInvalidate, IsRequest, HasData, NeedsResponse),
+ WriteInvalidateResp, "WriteInvalidateReq" },
+ /* WriteInvalidateResp */
+ { SET5(IsWrite, IsInvalidate, IsRequest, NeedsResponse, IsResponse),
+ InvalidCmd, "WriteInvalidateResp" },
+ /* UpgradeReq */
+ { SET3(IsInvalidate, IsRequest, IsUpgrade), InvalidCmd, "UpgradeReq" },
+ /* ReadExReq */
+ { SET4(IsRead, IsInvalidate, IsRequest, NeedsResponse),
+ ReadExResp, "ReadExReq" },
+ /* ReadExResp */
+ { SET4(IsRead, IsInvalidate, IsResponse, HasData),
+ InvalidCmd, "ReadExResp" },
+ /* SwapReq -- for Swap ldstub type operations */
+ { SET4(IsReadWrite, IsRequest, HasData, NeedsResponse),
+ SwapResp, "SwapReq" },
+ /* SwapResp -- for Swap ldstub type operations */
+ { SET3(IsReadWrite, IsResponse, HasData),
+ InvalidCmd, "SwapResp" }
+};
-const std::string &
-Packet::cmdIdxToString(Packet::Command idx)
-{
- switch (idx) {
- case ReadReq: return ReadReqString;
- case WriteReq: return WriteReqString;
- case WriteReqNoAck: return WriteReqNoAckString;
- case ReadResp: return ReadRespString;
- case WriteResp: return WriteRespString;
- case SoftPFReq: return SoftPFReqString;
- case SoftPFResp: return SoftPFRespString;
- case HardPFReq: return HardPFReqString;
- case HardPFResp: return HardPFRespString;
- case InvalidateReq: return InvalidateReqString;
- case WriteInvalidateReq:return WriteInvalidateReqString;
- case WriteInvalidateResp:return WriteInvalidateRespString;
- case UpgradeReq: return UpgradeReqString;
- case ReadExReq: return ReadExReqString;
- case ReadExResp: return ReadExRespString;
- default: return OtherCmdString;
- }
-}
/** delete the data pointed to in the data pointer. Ok to call to matter how
* data was allocted. */
@@ -149,9 +149,17 @@ fixDelayedResponsePacket(PacketPtr func, PacketPtr timing)
bool result;
if (timing->isRead() || timing->isWrite()) {
- timing->toggleData();
+ // Ugly hack to deal with the fact that we queue the requests
+ // and don't convert them to responses until we issue them on
+ // the bus. I tried to avoid this by converting packets to
+ // responses right away, but this breaks during snoops where a
+ // responder may do the conversion before other caches have
+ // done the snoop. Would work if we copied the packet instead
+ // of just hanging on to a pointer.
+ MemCmd oldCmd = timing->cmd;
+ timing->cmd = timing->cmd.responseCommand();
result = fixPacket(func, timing);
- timing->toggleData();
+ timing->cmd = oldCmd;
}
else {
//Don't toggle if it isn't a read/write response
@@ -171,11 +179,6 @@ fixPacket(PacketPtr func, PacketPtr timing)
assert(!(funcStart > timingEnd || timingStart > funcEnd));
- if (DTRACE(FunctionalAccess)) {
- DebugOut() << func;
- DebugOut() << timing;
- }
-
// this packet can't solve our problem, continue on
if (!timing->hasData())
return true;
@@ -241,9 +244,11 @@ operator<<(std::ostream &o, const Packet &p)
if (p.isRead())
o << "Read ";
if (p.isWrite())
- o << "Read ";
+ o << "Write ";
+ if (p.isReadWrite())
+ o << "Read/Write ";
if (p.isInvalidate())
- o << "Read ";
+ o << "Invalidate ";
if (p.isRequest())
o << "Request ";
if (p.isResponse())
diff --git a/src/mem/packet.hh b/src/mem/packet.hh
index a4c003e8b..dc23e9f6d 100644
--- a/src/mem/packet.hh
+++ b/src/mem/packet.hh
@@ -40,12 +40,13 @@
#include <cassert>
#include <list>
+#include <bitset>
#include "base/compiler.hh"
#include "base/misc.hh"
#include "mem/request.hh"
#include "sim/host.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
struct Packet;
@@ -62,8 +63,118 @@ typedef std::list<PacketPtr> PacketList;
#define NO_ALLOCATE (1 << 5)
#define SNOOP_COMMIT (1 << 6)
-//for now. @todo fix later
-#define NUM_MEM_CMDS (1 << 11)
+
+class MemCmd
+{
+ public:
+
+ /** List of all commands associated with a packet. */
+ enum Command
+ {
+ InvalidCmd,
+ ReadReq,
+ WriteReq,
+ WriteReqNoAck,
+ ReadResp,
+ WriteResp,
+ Writeback,
+ SoftPFReq,
+ HardPFReq,
+ SoftPFResp,
+ HardPFResp,
+ InvalidateReq,
+ WriteInvalidateReq,
+ WriteInvalidateResp,
+ UpgradeReq,
+ ReadExReq,
+ ReadExResp,
+ SwapReq,
+ SwapResp,
+ NUM_MEM_CMDS
+ };
+
+ private:
+ /** List of command attributes. */
+ enum Attribute
+ {
+ IsRead,
+ IsWrite,
+ IsPrefetch,
+ IsInvalidate,
+ IsRequest,
+ IsResponse,
+ NeedsResponse,
+ IsSWPrefetch,
+ IsHWPrefetch,
+ IsUpgrade,
+ HasData,
+ IsReadWrite,
+ NUM_COMMAND_ATTRIBUTES
+ };
+
+ /** Structure that defines attributes and other data associated
+ * with a Command. */
+ struct CommandInfo {
+ /** Set of attribute flags. */
+ const std::bitset<NUM_COMMAND_ATTRIBUTES> attributes;
+ /** Corresponding response for requests; InvalidCmd if no
+ * response is applicable. */
+ const Command response;
+ /** String representation (for printing) */
+ const std::string str;
+ };
+
+ /** Array to map Command enum to associated info. */
+ static const CommandInfo commandInfo[];
+
+ private:
+
+ Command cmd;
+
+ bool testCmdAttrib(MemCmd::Attribute attrib) const {
+ return commandInfo[cmd].attributes[attrib] != 0;
+ }
+
+ public:
+
+ bool isRead() const { return testCmdAttrib(IsRead); }
+ bool isWrite() const { return testCmdAttrib(IsWrite); }
+ bool isRequest() const { return testCmdAttrib(IsRequest); }
+ bool isResponse() const { return testCmdAttrib(IsResponse); }
+ bool needsResponse() const { return testCmdAttrib(NeedsResponse); }
+ bool isInvalidate() const { return testCmdAttrib(IsInvalidate); }
+ bool hasData() const { return testCmdAttrib(HasData); }
+ bool isReadWrite() const { return testCmdAttrib(IsReadWrite); }
+
+ const Command responseCommand() const {
+ return commandInfo[cmd].response;
+ }
+
+ /** Return the string to a cmd given by idx. */
+ const std::string &toString() const {
+ return commandInfo[cmd].str;
+ }
+
+ int toInt() const { return (int)cmd; }
+
+ MemCmd(Command _cmd)
+ : cmd(_cmd)
+ { }
+
+ MemCmd(int _cmd)
+ : cmd((Command)_cmd)
+ { }
+
+ MemCmd()
+ : cmd(InvalidCmd)
+ { }
+
+ bool operator==(MemCmd c2) { return (cmd == c2.cmd); }
+ bool operator!=(MemCmd c2) { return (cmd != c2.cmd); }
+
+ friend class Packet;
+};
+
/**
* A Packet is used to encapsulate a transfer between two objects in
* the memory system (e.g., the L1 and L2 cache). (In contrast, a
@@ -74,6 +185,9 @@ typedef std::list<PacketPtr> PacketList;
class Packet
{
public:
+
+ typedef MemCmd::Command Command;
+
/** Temporary FLAGS field until cache gets working, this should be in coherence/sender state. */
uint64_t flags;
@@ -169,73 +283,28 @@ class Packet
* to cast to the state appropriate to the sender. */
SenderState *senderState;
- private:
- /** List of command attributes. */
- // If you add a new CommandAttribute, make sure to increase NUM_MEM_CMDS
- // as well.
- enum CommandAttribute
- {
- IsRead = 1 << 0,
- IsWrite = 1 << 1,
- IsPrefetch = 1 << 2,
- IsInvalidate = 1 << 3,
- IsRequest = 1 << 4,
- IsResponse = 1 << 5,
- NeedsResponse = 1 << 6,
- IsSWPrefetch = 1 << 7,
- IsHWPrefetch = 1 << 8,
- IsUpgrade = 1 << 9,
- HasData = 1 << 10
- };
-
public:
- /** List of all commands associated with a packet. */
- enum Command
- {
- InvalidCmd = 0,
- ReadReq = IsRead | IsRequest | NeedsResponse,
- WriteReq = IsWrite | IsRequest | NeedsResponse | HasData,
- WriteReqNoAck = IsWrite | IsRequest | HasData,
- ReadResp = IsRead | IsResponse | NeedsResponse | HasData,
- WriteResp = IsWrite | IsResponse | NeedsResponse,
- Writeback = IsWrite | IsRequest | HasData,
- SoftPFReq = IsRead | IsRequest | IsSWPrefetch | NeedsResponse,
- HardPFReq = IsRead | IsRequest | IsHWPrefetch | NeedsResponse,
- SoftPFResp = IsRead | IsResponse | IsSWPrefetch
- | NeedsResponse | HasData,
- HardPFResp = IsRead | IsResponse | IsHWPrefetch
- | NeedsResponse | HasData,
- InvalidateReq = IsInvalidate | IsRequest,
- WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest
- | HasData | NeedsResponse,
- WriteInvalidateResp = IsWrite | IsInvalidate | IsRequest
- | NeedsResponse | IsResponse,
- UpgradeReq = IsInvalidate | IsRequest | IsUpgrade,
- ReadExReq = IsRead | IsInvalidate | IsRequest | NeedsResponse,
- ReadExResp = IsRead | IsInvalidate | IsResponse
- | NeedsResponse | HasData
- };
+
+ /** The command field of the packet. */
+ MemCmd cmd;
/** Return the string name of the cmd field (for debugging and
* tracing). */
- const std::string &cmdString() const;
-
- /** Reutrn the string to a cmd given by idx. */
- const std::string &cmdIdxToString(Command idx);
+ const std::string &cmdString() const { return cmd.toString(); }
/** Return the index of this command. */
- inline int cmdToIndex() const { return (int) cmd; }
+ inline int cmdToIndex() const { return cmd.toInt(); }
- /** The command field of the packet. */
- Command cmd;
+ public:
- bool isRead() const { return (cmd & IsRead) != 0; }
- bool isWrite() const { return (cmd & IsWrite) != 0; }
- bool isRequest() const { return (cmd & IsRequest) != 0; }
- bool isResponse() const { return (cmd & IsResponse) != 0; }
- bool needsResponse() const { return (cmd & NeedsResponse) != 0; }
- bool isInvalidate() const { return (cmd & IsInvalidate) != 0; }
- bool hasData() const { return (cmd & HasData) != 0; }
+ bool isRead() const { return cmd.isRead(); }
+ bool isWrite() const { return cmd.isWrite(); }
+ bool isRequest() const { return cmd.isRequest(); }
+ bool isResponse() const { return cmd.isResponse(); }
+ bool needsResponse() const { return cmd.needsResponse(); }
+ bool isInvalidate() const { return cmd.isInvalidate(); }
+ bool hasData() const { return cmd.hasData(); }
+ bool isReadWrite() const { return cmd.isReadWrite(); }
bool isCacheFill() const { return (flags & CACHE_LINE_FILL) != 0; }
bool isNoAllocate() const { return (flags & NO_ALLOCATE) != 0; }
@@ -269,13 +338,13 @@ class Packet
Addr getOffset(int blkSize) const { return addr & (Addr)(blkSize - 1); }
void addrOverride(Addr newAddr) { assert(addrSizeValid); addr = newAddr; }
- void cmdOverride(Command newCmd) { cmd = newCmd; }
+ void cmdOverride(MemCmd newCmd) { cmd = newCmd; }
/** Constructor. Note that a Request object must be constructed
* first, but the Requests's physical address and size fields
* need not be valid. The command and destination addresses
* must be supplied. */
- Packet(Request *_req, Command _cmd, short _dest)
+ Packet(Request *_req, MemCmd _cmd, short _dest)
: data(NULL), staticData(false), dynamicData(false), arrayData(false),
addr(_req->paddr), size(_req->size), dest(_dest),
addrSizeValid(_req->validPaddr),
@@ -290,7 +359,7 @@ class Packet
/** Alternate constructor if you are trying to create a packet with
* a request that is for a whole block, not the address from the req.
* this allows for overriding the size/addr of the req.*/
- Packet(Request *_req, Command _cmd, short _dest, int _blkSize)
+ Packet(Request *_req, MemCmd _cmd, short _dest, int _blkSize)
: data(NULL), staticData(false), dynamicData(false), arrayData(false),
addr(_req->paddr & ~(_blkSize - 1)), size(_blkSize),
dest(_dest),
@@ -335,25 +404,11 @@ class Packet
void makeTimingResponse() {
assert(needsResponse());
assert(isRequest());
- int icmd = (int)cmd;
- icmd &= ~(IsRequest);
- icmd |= IsResponse;
- if (isRead())
- icmd |= HasData;
- if (isWrite())
- icmd &= ~HasData;
- cmd = (Command)icmd;
+ cmd = cmd.responseCommand();
dest = src;
srcValid = false;
}
-
- void toggleData() {
- int icmd = (int)cmd;
- icmd ^= HasData;
- cmd = (Command)icmd;
- }
-
/**
* Take a request packet and modify it in place to be suitable for
* returning as a response to that request.
@@ -362,14 +417,7 @@ class Packet
{
assert(needsResponse());
assert(isRequest());
- int icmd = (int)cmd;
- icmd &= ~(IsRequest);
- icmd |= IsResponse;
- if (isRead())
- icmd |= HasData;
- if (isWrite())
- icmd &= ~HasData;
- cmd = (Command)icmd;
+ cmd = cmd.responseCommand();
}
/**
diff --git a/src/mem/packet_access.hh b/src/mem/packet_access.hh
index aac0c3ae5..d1edd00aa 100644
--- a/src/mem/packet_access.hh
+++ b/src/mem/packet_access.hh
@@ -30,6 +30,7 @@
*/
#include "arch/isa_traits.hh"
+#include "base/bigint.hh"
#include "mem/packet.hh"
#include "sim/byteswap.hh"
diff --git a/src/mem/page_table.cc b/src/mem/page_table.cc
index fe8094b88..96bc23793 100644
--- a/src/mem/page_table.cc
+++ b/src/mem/page_table.cc
@@ -157,7 +157,7 @@ PageTable::translate(RequestPtr &req)
assert(pageAlign(req->getVaddr() + req->getSize() - 1)
== pageAlign(req->getVaddr()));
if (!translate(req->getVaddr(), paddr)) {
- return genPageTableFault(req->getVaddr());
+ return Fault(new PageTableFault(req->getVaddr()));
}
req->setPaddr(paddr);
return page_check(req->getPaddr(), req->getSize());
diff --git a/src/mem/physical.cc b/src/mem/physical.cc
index eccd42bec..5d7d7382a 100644
--- a/src/mem/physical.cc
+++ b/src/mem/physical.cc
@@ -92,7 +92,7 @@ Addr
PhysicalMemory::new_page()
{
Addr return_addr = pagePtr << LogVMPageSize;
- return_addr += params()->addrRange.start;
+ return_addr += start();
++pagePtr;
return return_addr;
@@ -187,7 +187,7 @@ PhysicalMemory::checkLockedAddrList(Request *req)
}
if (isLocked) {
- req->setScResult(success ? 1 : 0);
+ req->setExtraData(success ? 1 : 0);
}
return success;
@@ -196,16 +196,14 @@ PhysicalMemory::checkLockedAddrList(Request *req)
void
PhysicalMemory::doFunctionalAccess(PacketPtr pkt)
{
- assert(pkt->getAddr() >= params()->addrRange.start &&
- pkt->getAddr() + pkt->getSize() <= params()->addrRange.start +
- params()->addrRange.size());
+ assert(pkt->getAddr() >= start() &&
+ pkt->getAddr() + pkt->getSize() <= start() + size());
if (pkt->isRead()) {
if (pkt->req->isLocked()) {
trackLoadLocked(pkt->req);
}
- memcpy(pkt->getPtr<uint8_t>(),
- pmemAddr + pkt->getAddr() - params()->addrRange.start,
+ memcpy(pkt->getPtr<uint8_t>(), pmemAddr + pkt->getAddr() - start(),
pkt->getSize());
#if TRACING_ON
switch (pkt->getSize()) {
@@ -233,8 +231,8 @@ PhysicalMemory::doFunctionalAccess(PacketPtr pkt)
}
else if (pkt->isWrite()) {
if (writeOK(pkt->req)) {
- memcpy(pmemAddr + pkt->getAddr() - params()->addrRange.start,
- pkt->getPtr<uint8_t>(), pkt->getSize());
+ memcpy(pmemAddr + pkt->getAddr() - start(), pkt->getPtr<uint8_t>(),
+ pkt->getSize());
#if TRACING_ON
switch (pkt->getSize()) {
case sizeof(uint64_t):
@@ -259,12 +257,75 @@ PhysicalMemory::doFunctionalAccess(PacketPtr pkt)
}
#endif
}
- }
- else if (pkt->isInvalidate()) {
+ } else if (pkt->isInvalidate()) {
//upgrade or invalidate
pkt->flags |= SATISFIED;
- }
- else {
+ } else if (pkt->isReadWrite()) {
+ IntReg overwrite_val;
+ bool overwrite_mem;
+ uint64_t condition_val64;
+ uint32_t condition_val32;
+
+ assert(sizeof(IntReg) >= pkt->getSize());
+
+ overwrite_mem = true;
+ // keep a copy of our possible write value, and copy what is at the
+ // memory address into the packet
+ std::memcpy(&overwrite_val, pkt->getPtr<uint8_t>(), pkt->getSize());
+ std::memcpy(pkt->getPtr<uint8_t>(), pmemAddr + pkt->getAddr() - start(),
+ pkt->getSize());
+
+ if (pkt->req->isCondSwap()) {
+ if (pkt->getSize() == sizeof(uint64_t)) {
+ condition_val64 = pkt->req->getExtraData();
+ overwrite_mem = !std::memcmp(&condition_val64, pmemAddr +
+ pkt->getAddr() - start(), sizeof(uint64_t));
+ } else if (pkt->getSize() == sizeof(uint32_t)) {
+ condition_val32 = (uint32_t)pkt->req->getExtraData();
+ overwrite_mem = !std::memcmp(&condition_val32, pmemAddr +
+ pkt->getAddr() - start(), sizeof(uint32_t));
+ } else
+ panic("Invalid size for conditional read/write\n");
+ }
+
+ if (overwrite_mem)
+ std::memcpy(pmemAddr + pkt->getAddr() - start(),
+ &overwrite_val, pkt->getSize());
+
+#if TRACING_ON
+ switch (pkt->getSize()) {
+ case sizeof(uint64_t):
+ DPRINTF(MemoryAccess, "Read/Write of size %i on address 0x%x old data 0x%x\n",
+ pkt->getSize(), pkt->getAddr(),pkt->get<uint64_t>());
+ DPRINTF(MemoryAccess, "New Data 0x%x %s conditional (0x%x) and %s \n",
+ overwrite_mem, pkt->req->isCondSwap() ? "was" : "wasn't",
+ condition_val64, overwrite_mem ? "happened" : "didn't happen");
+ break;
+ case sizeof(uint32_t):
+ DPRINTF(MemoryAccess, "Read/Write of size %i on address 0x%x old data 0x%x\n",
+ pkt->getSize(), pkt->getAddr(),pkt->get<uint32_t>());
+ DPRINTF(MemoryAccess, "New Data 0x%x %s conditional (0x%x) and %s \n",
+ overwrite_mem, pkt->req->isCondSwap() ? "was" : "wasn't",
+ condition_val32, overwrite_mem ? "happened" : "didn't happen");
+ break;
+ case sizeof(uint16_t):
+ DPRINTF(MemoryAccess, "Read/Write of size %i on address 0x%x old data 0x%x\n",
+ pkt->getSize(), pkt->getAddr(),pkt->get<uint16_t>());
+ DPRINTF(MemoryAccess, "New Data 0x%x wasn't conditional and happned\n",
+ overwrite_mem);
+ break;
+ case sizeof(uint8_t):
+ DPRINTF(MemoryAccess, "Read/Write of size %i on address 0x%x old data 0x%x\n",
+ pkt->getSize(), pkt->getAddr(),pkt->get<uint8_t>());
+ DPRINTF(MemoryAccess, "New Data 0x%x wasn't conditional and happned\n",
+ overwrite_mem);
+ break;
+ default:
+ DPRINTF(MemoryAccess, "Read/Write of size %i on address 0x%x\n",
+ pkt->getSize(), pkt->getAddr());
+ }
+#endif
+ } else {
panic("unimplemented");
}
@@ -315,7 +376,7 @@ PhysicalMemory::getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
{
snoop.clear();
resp.clear();
- resp.push_back(RangeSize(params()->addrRange.start,
+ resp.push_back(RangeSize(start(),
params()->addrRange.size()));
}
diff --git a/src/mem/physical.hh b/src/mem/physical.hh
index af88bcaa0..f7200b502 100644
--- a/src/mem/physical.hh
+++ b/src/mem/physical.hh
@@ -131,7 +131,7 @@ class PhysicalMemory : public MemObject
// no locked addrs: nothing to check, store_conditional fails
bool isLocked = req->isLocked();
if (isLocked) {
- req->setScResult(0);
+ req->setExtraData(0);
}
return !isLocked; // only do write if not an sc
} else {
@@ -148,6 +148,7 @@ class PhysicalMemory : public MemObject
public:
Addr new_page();
uint64_t size() { return params()->addrRange.size(); }
+ uint64_t start() { return params()->addrRange.start; }
struct Params
{
diff --git a/src/mem/port.cc b/src/mem/port.cc
index da719bbd9..e75e50e4d 100644
--- a/src/mem/port.cc
+++ b/src/mem/port.cc
@@ -36,6 +36,7 @@
#include "base/chunk_generator.hh"
#include "base/trace.hh"
+#include "mem/mem_object.hh"
#include "mem/port.hh"
void
@@ -46,7 +47,16 @@ Port::setPeer(Port *port)
}
void
-Port::blobHelper(Addr addr, uint8_t *p, int size, Packet::Command cmd)
+Port::removeConn()
+{
+ if (peer->getOwner())
+ peer->getOwner()->deletePortRefs(peer);
+ delete peer;
+ peer = NULL;
+}
+
+void
+Port::blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd)
{
Request req;
Packet pkt(&req, cmd, Packet::Broadcast);
@@ -64,13 +74,13 @@ Port::blobHelper(Addr addr, uint8_t *p, int size, Packet::Command cmd)
void
Port::writeBlob(Addr addr, uint8_t *p, int size)
{
- blobHelper(addr, p, size, Packet::WriteReq);
+ blobHelper(addr, p, size, MemCmd::WriteReq);
}
void
Port::readBlob(Addr addr, uint8_t *p, int size)
{
- blobHelper(addr, p, size, Packet::ReadReq);
+ blobHelper(addr, p, size, MemCmd::ReadReq);
}
void
@@ -80,7 +90,7 @@ Port::memsetBlob(Addr addr, uint8_t val, int size)
uint8_t *buf = new uint8_t[size];
std::memset(buf, val, size);
- blobHelper(addr, buf, size, Packet::WriteReq);
+ blobHelper(addr, buf, size, MemCmd::WriteReq);
delete [] buf;
}
diff --git a/src/mem/port.hh b/src/mem/port.hh
index 5e55225bf..6296b42ca 100644
--- a/src/mem/port.hh
+++ b/src/mem/port.hh
@@ -120,7 +120,7 @@ class Port
{ portName = name; }
/** Function to set the pointer for the peer port. */
- void setPeer(Port *port);
+ virtual void setPeer(Port *port);
/** Function to get the pointer to the peer port. */
Port *getPeer() { return peer; }
@@ -131,6 +131,11 @@ class Port
/** Function to return the owner of this port. */
MemObject *getOwner() { return owner; }
+ /** Inform the peer port to delete itself and notify it's owner about it's
+ * demise. */
+ void removeConn();
+
+
protected:
/** These functions are protected because they should only be
@@ -245,7 +250,7 @@ class Port
/** Internal helper function for read/writeBlob().
*/
- void blobHelper(Addr addr, uint8_t *p, int size, Packet::Command cmd);
+ void blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd);
};
/** A simple functional port that is only meant for one way communication to
diff --git a/src/mem/request.hh b/src/mem/request.hh
index de0512e1c..d2ebc91d3 100644
--- a/src/mem/request.hh
+++ b/src/mem/request.hh
@@ -40,7 +40,7 @@
#define __MEM_REQUEST_HH__
#include "sim/host.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
#include <cassert>
@@ -71,6 +71,10 @@ const uint32_t EVICT_NEXT = 0x20000;
const uint32_t NO_ALIGN_FAULT = 0x40000;
/** The request was an instruction read. */
const uint32_t INST_READ = 0x80000;
+/** This request is for a memory swap. */
+const uint32_t MEM_SWAP = 0x100000;
+const uint32_t MEM_SWAP_COND = 0x200000;
+
class Request
{
@@ -104,8 +108,9 @@ class Request
/** The virtual address of the request. */
Addr vaddr;
- /** The return value of store conditional. */
- uint64_t scResult;
+ /** Extra data for the request, such as the return value of
+ * store conditional or the compare value for a CAS. */
+ uint64_t extraData;
/** The cpu number (for statistics, typically). */
int cpuNum;
@@ -120,7 +125,7 @@ class Request
/** Whether or not the asid & vaddr are valid. */
bool validAsidVaddr;
/** Whether or not the sc result is valid. */
- bool validScResult;
+ bool validExData;
/** Whether or not the cpu number & thread ID are valid. */
bool validCpuAndThreadNums;
/** Whether or not the pc is valid. */
@@ -130,7 +135,7 @@ class Request
/** Minimal constructor. No fields are initialized. */
Request()
: validPaddr(false), validAsidVaddr(false),
- validScResult(false), validCpuAndThreadNums(false), validPC(false)
+ validExData(false), validCpuAndThreadNums(false), validPC(false)
{}
/**
@@ -169,7 +174,7 @@ class Request
validPaddr = true;
validAsidVaddr = false;
validPC = false;
- validScResult = false;
+ validExData = false;
mmapedIpr = false;
}
@@ -187,7 +192,7 @@ class Request
validPaddr = false;
validAsidVaddr = true;
validPC = true;
- validScResult = false;
+ validExData = false;
mmapedIpr = false;
}
@@ -237,12 +242,12 @@ class Request
void setMmapedIpr(bool r) { assert(validAsidVaddr); mmapedIpr = r; }
/** Accessor function to check if sc result is valid. */
- bool scResultValid() { return validScResult; }
+ bool extraDataValid() { return validExData; }
/** Accessor function for store conditional return value.*/
- uint64_t getScResult() { assert(validScResult); return scResult; }
+ uint64_t getExtraData() { assert(validExData); return extraData; }
/** Accessor function for store conditional return value.*/
- void setScResult(uint64_t _scResult)
- { scResult = _scResult; validScResult = true; }
+ void setExtraData(uint64_t _extraData)
+ { extraData = _extraData; validExData = true; }
/** Accessor function for cpu number.*/
int getCpuNum() { assert(validCpuAndThreadNums); return cpuNum; }
@@ -259,6 +264,12 @@ class Request
bool isLocked() { return (getFlags() & LOCKED) != 0; }
+ bool isSwap() { return (getFlags() & MEM_SWAP ||
+ getFlags() & MEM_SWAP_COND); }
+
+ bool isCondSwap() { return (getFlags() & MEM_SWAP_COND) != 0; }
+
+
friend class Packet;
};
diff --git a/src/mem/tport.cc b/src/mem/tport.cc
index c43c9aac0..b384a0444 100644
--- a/src/mem/tport.cc
+++ b/src/mem/tport.cc
@@ -68,7 +68,7 @@ SimpleTimingPort::recvTiming(PacketPtr pkt)
sendTiming(pkt, latency);
}
else {
- if (pkt->cmd != Packet::UpgradeReq)
+ if (pkt->cmd != MemCmd::UpgradeReq)
{
delete pkt->req;
delete pkt;
diff --git a/src/mem/vport.cc b/src/mem/vport.cc
index 8030c5a15..6cc4d9ca9 100644
--- a/src/mem/vport.cc
+++ b/src/mem/vport.cc
@@ -34,6 +34,7 @@
*/
#include "base/chunk_generator.hh"
+#include "cpu/thread_context.hh"
#include "mem/vport.hh"
void
@@ -70,3 +71,53 @@ VirtualPort::writeBlob(Addr addr, uint8_t *p, int size)
}
}
+void
+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
+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
+CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
+{
+ int len = 0;
+ char *start = dst;
+ VirtualPort *vp = tc->getVirtPort(tc);
+
+ do {
+ vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
+ } while (len < maxlen && start[len++] != 0 );
+
+ tc->delVirtPort(vp);
+ dst[len] = 0;
+}
+
+void
+CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
+{
+ VirtualPort *vp = tc->getVirtPort(tc);
+ for (ChunkGenerator gen(vaddr, strlen(src), TheISA::PageBytes); !gen.done();
+ gen.next())
+ {
+ vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size());
+ src += gen.size();
+ }
+ tc->delVirtPort(vp);
+}
diff --git a/src/mem/vport.hh b/src/mem/vport.hh
index c83836258..a8ceaa9fc 100644
--- a/src/mem/vport.hh
+++ b/src/mem/vport.hh
@@ -49,6 +49,7 @@
* simple address masking operation (such as alpha super page accesses).
*/
+
class VirtualPort : public FunctionalPort
{
private:
@@ -75,5 +76,11 @@ class VirtualPort : public FunctionalPort
virtual void writeBlob(Addr addr, uint8_t *p, int size);
};
+
+void CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen);
+void CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen);
+void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen);
+void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr);
+
#endif //__MEM_VPORT_HH__
diff --git a/src/python/SConscript b/src/python/SConscript
index df1464809..6662c8a45 100644
--- a/src/python/SConscript
+++ b/src/python/SConscript
@@ -29,14 +29,14 @@
# Authors: Steve Reinhardt
# Nathan Binkert
-import os, os.path, re, sys
-from zipfile import PyZipFile
+import os
+import zipfile
# handy function for path joins
def join(*args):
return os.path.normpath(os.path.join(*args))
-Import('env')
+Import('*')
# This SConscript is in charge of collecting .py files and generating
# a zip archive that is appended to the m5 binary.
@@ -97,22 +97,59 @@ addPkg('m5')
pyzip_files.append('m5/defines.py')
pyzip_files.append('m5/info.py')
pyzip_files.append(join(env['ROOT'], 'util/pbs/jobfile.py'))
+pyzip_files.append(join(env['ROOT'], 'src/base/traceflags.py'))
-def swig_it(basename):
- env.Command(['swig/%s_wrap.cc' % basename, 'm5/internal/%s.py' % basename],
- 'swig/%s.i' % basename,
+swig_modules = []
+def swig_it(module):
+ env.Command(['swig/%s_wrap.cc' % module, 'm5/internal/%s.py' % module],
+ 'swig/%s.i' % module,
'$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} '
'-o ${TARGETS[0]} $SOURCES')
- pyzip_dep_files.append('m5/internal/%s.py' % basename)
+ swig_modules.append(module)
+ Source('swig/%s_wrap.cc' % module)
-swig_it('main')
+Source('swig/init.cc')
+Source('swig/pyevent.cc')
+Source('swig/pyobject.cc')
+
+swig_it('core')
swig_it('debug')
swig_it('event')
+swig_it('random')
+swig_it('sim_object')
+swig_it('stats')
+swig_it('trace')
+
+# Automatically generate m5/internals/__init__.py
+def MakeInternalsInit(target, source, env):
+ f = file(str(target[0]), 'w')
+ for m in swig_modules:
+ print >>f, 'import %s' % m
+ f.close()
+
+swig_py_files = [ 'm5/internal/%s.py' % m for m in swig_modules ]
+env.Command('m5/internal/__init__.py', swig_py_files, MakeInternalsInit)
+pyzip_dep_files.append('m5/internal/__init__.py')
+
+def MakeSwigInit(target, source, env):
+ f = file(str(target[0]), 'w')
+ print >>f, 'extern "C" {'
+ for m in swig_modules:
+ print >>f, ' void init_%s();' % m
+ print >>f, '}'
+ print >>f, 'void init_swig() {'
+ for m in swig_modules:
+ print >>f, ' init_%s();' % m
+ print >>f, '}'
+ f.close()
+
+swig_cc_files = [ 'swig/%s_wrap.cc' % m for m in swig_modules ]
+env.Command('swig/init.cc', swig_cc_files, MakeSwigInit)
# Action function to build the zip archive. Uses the PyZipFile module
# included in the standard Python library.
def buildPyZip(target, source, env):
- pzf = PyZipFile(str(target[0]), 'w')
+ pzf = zipfile.PyZipFile(str(target[0]), 'w')
for s in source:
pzf.writepy(str(s))
diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py
index 934358298..42266a80e 100644
--- a/src/python/m5/SimObject.py
+++ b/src/python/m5/SimObject.py
@@ -653,15 +653,13 @@ class SimObject(object):
instanceDict[self.path()] = self
- if hasattr(self, 'type') and not isinstance(self, ParamContext):
+ if hasattr(self, 'type'):
print 'type=%s' % self.type
child_names = self._children.keys()
child_names.sort()
- np_child_names = [c for c in child_names \
- if not isinstance(self._children[c], ParamContext)]
- if len(np_child_names):
- print 'children=%s' % ' '.join(np_child_names)
+ if len(child_names):
+ print 'children=%s' % ' '.join(child_names)
param_names = self._params.keys()
param_names.sort()
@@ -695,7 +693,7 @@ class SimObject(object):
def getCCObject(self):
if not self._ccObject:
self._ccObject = -1 # flag to catch cycles in recursion
- self._ccObject = internal.main.createSimObject(self.path())
+ self._ccObject = internal.sim_object.createSimObject(self.path())
elif self._ccObject == -1:
raise RuntimeError, "%s: recursive call to getCCObject()" \
% self.path()
@@ -711,8 +709,7 @@ class SimObject(object):
def startDrain(self, drain_event, recursive):
count = 0
- # ParamContexts don't serialize
- if isinstance(self, SimObject) and not isinstance(self, ParamContext):
+ if isinstance(self, SimObject):
count += self._ccObject.drain(drain_event)
if recursive:
for child in self._children.itervalues():
@@ -720,7 +717,7 @@ class SimObject(object):
return count
def resume(self):
- if isinstance(self, SimObject) and not isinstance(self, ParamContext):
+ if isinstance(self, SimObject):
self._ccObject.resume()
for child in self._children.itervalues():
child.resume()
@@ -730,13 +727,13 @@ class SimObject(object):
# i don't know if there's a better way to do this - calling
# setMemoryMode directly from self._ccObject results in calling
# SimObject::setMemoryMode, not the System::setMemoryMode
- system_ptr = internal.main.convertToSystemPtr(self._ccObject)
+ system_ptr = internal.sim_object.convertToSystemPtr(self._ccObject)
system_ptr.setMemoryMode(mode)
for child in self._children.itervalues():
child.changeTiming(mode)
def takeOverFrom(self, old_cpu):
- cpu_ptr = internal.main.convertToBaseCPUPtr(old_cpu._ccObject)
+ cpu_ptr = internal.sim_object.convertToBaseCPUPtr(old_cpu._ccObject)
self._ccObject.takeOverFrom(cpu_ptr)
# generate output file for 'dot' to display as a pretty graph.
@@ -782,9 +779,6 @@ class SimObject(object):
for c in self.children:
c.outputDot(dot)
-class ParamContext(SimObject):
- pass
-
# Function to provide to C++ so it can look up instances based on paths
def resolveSimObject(name):
obj = instanceDict[name]
@@ -793,7 +787,7 @@ def resolveSimObject(name):
# __all__ defines the list of symbols that get exported when
# 'from config import *' is invoked. Try to keep this reasonably
# short to avoid polluting other namespaces.
-__all__ = ['SimObject', 'ParamContext']
+__all__ = ['SimObject']
# see comment on imports at end of __init__.py.
import proxy
diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py
index f39cc670a..06dc92bc6 100644
--- a/src/python/m5/__init__.py
+++ b/src/python/m5/__init__.py
@@ -27,14 +27,16 @@
# Authors: Nathan Binkert
# Steve Reinhardt
-import atexit, os, sys
+import atexit
+import os
+import sys
# import the SWIG-wrapped main C++ functions
import internal
# import a few SWIG-wrapped items (those that are likely to be used
# directly by user scripts) completely into this module for
# convenience
-from internal.main import simulate, SimLoopExitEvent
+import event
# import the m5 compile options
import defines
@@ -78,34 +80,72 @@ env.update(os.environ)
# The final hook to generate .ini files. Called from the user script
# once the config is built.
def instantiate(root):
- params.ticks_per_sec = float(root.clock.frequency)
+ # we need to fix the global frequency
+ ticks.fixGlobalFrequency()
+
root.unproxy_all()
# ugly temporary hack to get output to config.ini
sys.stdout = file(os.path.join(options.outdir, 'config.ini'), 'w')
root.print_ini()
sys.stdout.close() # close config.ini
sys.stdout = sys.__stdout__ # restore to original
- internal.main.loadIniFile(resolveSimObject) # load config.ini into C++
+
+ # load config.ini into C++
+ internal.core.loadIniFile(resolveSimObject)
+
+ # Initialize the global statistics
+ internal.stats.initSimStats()
+
+ # Create the C++ sim objects and connect ports
root.createCCObject()
root.connectPorts()
- internal.main.finalInit()
- noDot = True # temporary until we fix dot
- if not noDot:
- dot = pydot.Dot()
- instance.outputDot(dot)
- dot.orientation = "portrait"
- dot.size = "8.5,11"
- dot.ranksep="equally"
- dot.rank="samerank"
- dot.write("config.dot")
- dot.write_ps("config.ps")
+
+ # Do a second pass to finish initializing the sim objects
+ internal.sim_object.initAll()
+
+ # Do a third pass to initialize statistics
+ internal.sim_object.regAllStats()
+
+ # Check to make sure that the stats package is properly initialized
+ internal.stats.check()
+
+ # Reset to put the stats in a consistent state.
+ internal.stats.reset()
+
+def doDot(root):
+ dot = pydot.Dot()
+ instance.outputDot(dot)
+ dot.orientation = "portrait"
+ dot.size = "8.5,11"
+ dot.ranksep="equally"
+ dot.rank="samerank"
+ dot.write("config.dot")
+ dot.write_ps("config.ps")
+
+need_resume = []
+need_startup = True
+def simulate(*args, **kwargs):
+ global need_resume, need_startup
+
+ if need_startup:
+ internal.core.SimStartup()
+ need_startup = False
+
+ for root in need_resume:
+ resume(root)
+ need_resume = []
+
+ return internal.event.simulate(*args, **kwargs)
# Export curTick to user script.
def curTick():
- return internal.main.cvar.curTick
+ return internal.core.cvar.curTick
+
+# Python exit handlers happen in reverse order. We want to dump stats last.
+atexit.register(internal.stats.dump)
# register our C++ exit callback function with Python
-atexit.register(internal.main.doExitCleanup)
+atexit.register(internal.core.doExitCleanup)
# This loops until all objects have been fully drained.
def doDrain(root):
@@ -119,7 +159,7 @@ def doDrain(root):
# be drained.
def drain(root):
all_drained = False
- drain_event = internal.main.createCountedDrain()
+ drain_event = internal.event.createCountedDrain()
unready_objects = root.startDrain(drain_event, True)
# If we've got some objects that can't drain immediately, then simulate
if unready_objects > 0:
@@ -127,7 +167,7 @@ def drain(root):
simulate()
else:
all_drained = True
- internal.main.cleanupCountedDrain(drain_event)
+ internal.event.cleanupCountedDrain(drain_event)
return all_drained
def resume(root):
@@ -135,32 +175,32 @@ def resume(root):
def checkpoint(root, dir):
if not isinstance(root, objects.Root):
- raise TypeError, "Object is not a root object. Checkpoint must be called on a root object."
+ raise TypeError, "Checkpoint must be called on a root object."
doDrain(root)
print "Writing checkpoint"
- internal.main.serializeAll(dir)
+ internal.sim_object.serializeAll(dir)
resume(root)
def restoreCheckpoint(root, dir):
print "Restoring from checkpoint"
- internal.main.unserializeAll(dir)
- resume(root)
+ internal.sim_object.unserializeAll(dir)
+ need_resume.append(root)
def changeToAtomic(system):
- if not isinstance(system, objects.Root) and not isinstance(system, objects.System):
- raise TypeError, "Object is not a root or system object. Checkpoint must be "
- "called on a root object."
+ if not isinstance(system, (objects.Root, objects.System)):
+ raise TypeError, "Parameter of type '%s'. Must be type %s or %s." % \
+ (type(system), objects.Root, objects.System)
doDrain(system)
print "Changing memory mode to atomic"
- system.changeTiming(internal.main.SimObject.Atomic)
+ system.changeTiming(internal.sim_object.SimObject.Atomic)
def changeToTiming(system):
- if not isinstance(system, objects.Root) and not isinstance(system, objects.System):
- raise TypeError, "Object is not a root or system object. Checkpoint must be "
- "called on a root object."
+ if not isinstance(system, (objects.Root, objects.System)):
+ raise TypeError, "Parameter of type '%s'. Must be type %s or %s." % \
+ (type(system), objects.Root, objects.System)
doDrain(system)
print "Changing memory mode to timing"
- system.changeTiming(internal.main.SimObject.Timing)
+ system.changeTiming(internal.sim_object.SimObject.Timing)
def switchCpus(cpuList):
print "switching cpus"
@@ -180,7 +220,7 @@ def switchCpus(cpuList):
raise TypeError, "%s is not of type BaseCPU" % cpu
# Drain all of the individual CPUs
- drain_event = internal.main.createCountedDrain()
+ drain_event = internal.event.createCountedDrain()
unready_cpus = 0
for old_cpu in old_cpus:
unready_cpus += old_cpu.startDrain(drain_event, False)
@@ -188,7 +228,7 @@ def switchCpus(cpuList):
if unready_cpus > 0:
drain_event.setCount(unready_cpus)
simulate()
- internal.main.cleanupCountedDrain(drain_event)
+ internal.event.cleanupCountedDrain(drain_event)
# Now all of the CPUs are ready to be switched out
for old_cpu in old_cpus:
old_cpu._ccObject.switchOut()
diff --git a/src/python/m5/convert.py b/src/python/m5/convert.py
index 580a579bc..bb9e3e1f1 100644
--- a/src/python/m5/convert.py
+++ b/src/python/m5/convert.py
@@ -148,7 +148,7 @@ def toLatency(value):
raise ValueError, "cannot convert '%s' to latency" % value
-def toClockPeriod(value):
+def anyToLatency(value):
"""result is a clock period"""
if not isinstance(value, str):
@@ -170,6 +170,27 @@ def toClockPeriod(value):
raise ValueError, "cannot convert '%s' to clock period" % value
+def anyToFrequency(value):
+ """result is a clock period"""
+
+ if not isinstance(value, str):
+ raise TypeError, "wrong type '%s' should be str" % type(value)
+
+ try:
+ val = toFrequency(value)
+ return val
+ except ValueError:
+ pass
+
+ try:
+ val = toLatency(value)
+ if val != 0:
+ val = 1 / val
+ return val
+ except ValueError:
+ pass
+
+ raise ValueError, "cannot convert '%s' to clock period" % value
def toNetworkBandwidth(value):
if not isinstance(value, str):
diff --git a/src/python/m5/event.py b/src/python/m5/event.py
new file mode 100644
index 000000000..2d6497464
--- /dev/null
+++ b/src/python/m5/event.py
@@ -0,0 +1,42 @@
+# 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: Nathan Binkert
+
+from internal.event import create
+from internal.event import SimLoopExitEvent as SimExit
+
+class ProgressEvent(object):
+ def __init__(self, period):
+ self.period = int(period)
+ self.schedule()
+
+ def schedule(self):
+ create(self, m5.curTick() + self.period)
+
+ def __call__(self):
+ print "Progress! Time now %fs" % (m5.curTick()/1e12)
+ self.schedule()
diff --git a/src/python/m5/main.py b/src/python/m5/main.py
index 5df6d03cf..1695ed75f 100644
--- a/src/python/m5/main.py
+++ b/src/python/m5/main.py
@@ -29,11 +29,7 @@
import code, optparse, os, socket, sys
from datetime import datetime
from attrdict import attrdict
-
-try:
- import info
-except ImportError:
- info = None
+import traceflags
__all__ = [ 'options', 'arguments', 'main' ]
@@ -45,6 +41,19 @@ The Regents of The University of Michigan
All Rights Reserved
'''
+def print_list(items, indent=4):
+ line = ' ' * indent
+ for i,item in enumerate(items):
+ if len(line) + len(item) > 76:
+ print line
+ line = ' ' * indent
+
+ if i < len(items) - 1:
+ line += '%s, ' % item
+ else:
+ line += item
+ print line
+
# there's only one option parsing done, so make it global and add some
# helper functions to make it work well.
parser = optparse.OptionParser(usage=usage, version=version,
@@ -140,50 +149,17 @@ add_option("--debug-break", metavar="TIME[,TIME]", action='append', split=',',
# Tracing options
set_group("Trace Options")
+add_option("--trace-help", action='store_true',
+ help="Print help on trace flags")
add_option("--trace-flags", metavar="FLAG[,FLAG]", action='append', split=',',
- help="Sets the flags for tracing")
-add_option("--trace-start", metavar="TIME", default='0s',
- help="Start tracing at TIME (must have units)")
-add_option("--trace-cycle", metavar="CYCLE", default='0',
- help="Start tracing at CYCLE")
+ help="Sets the flags for tracing (-FLAG disables a flag)")
+add_option("--trace-start", metavar="TIME", type='int',
+ help="Start tracing at TIME (must be in ticks)")
add_option("--trace-file", metavar="FILE", default="cout",
help="Sets the output file for tracing [Default: %default]")
-add_option("--trace-circlebuf", metavar="SIZE", type="int", default=0,
- help="If SIZE is non-zero, turn on the circular buffer with SIZE lines")
-add_option("--no-trace-circlebuf", action="store_const", const=0,
- dest='trace_circlebuf', help=optparse.SUPPRESS_HELP)
-bool_option("trace-dumponexit", default=False,
- help="Dump trace buffer on exit")
add_option("--trace-ignore", metavar="EXPR", action='append', split=':',
help="Ignore EXPR sim objects")
-# Execution Trace options
-set_group("Execution Trace Options")
-bool_option("speculative", default=True,
- help="Don't capture speculative instructions")
-bool_option("print-cycle", default=True,
- help="Don't print cycle numbers in trace output")
-bool_option("print-symbol", default=True,
- help="Disable PC symbols in trace output")
-bool_option("print-opclass", default=True,
- help="Don't print op class type in trace output")
-bool_option("print-thread", default=True,
- help="Don't print thread number in trace output")
-bool_option("print-effaddr", default=True,
- help="Don't print effective address in trace output")
-bool_option("print-data", default=True,
- help="Don't print result data in trace output")
-bool_option("print-iregs", default=False,
- help="Print fetch sequence numbers in trace output")
-bool_option("print-fetch-seq", default=False,
- help="Print fetch sequence numbers in trace output")
-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 = []
@@ -211,6 +187,9 @@ def parse_args():
return opts,args
def main():
+ import defines
+ import event
+ import info
import internal
parse_args()
@@ -242,6 +221,19 @@ def main():
print info.RELEASE_NOTES
print
+ if options.trace_help:
+ done = True
+ print "Base Flags:"
+ print_list(traceflags.baseFlags, indent=4)
+ print
+ print "Compound Flags:"
+ for flag in traceflags.compoundFlags:
+ if flag == 'All':
+ continue
+ print " %s:" % flag
+ print_list(traceflags.compoundFlagMap[flag], indent=8)
+ print
+
if done:
sys.exit(0)
@@ -249,7 +241,7 @@ def main():
print "M5 Simulator System"
print brief_copyright
print
- print "M5 compiled %s" % internal.main.cvar.compileDate;
+ print "M5 compiled %s" % internal.core.cvar.compileDate;
print "M5 started %s" % datetime.now().ctime()
print "M5 executing on %s" % socket.gethostname()
print "command line:",
@@ -261,10 +253,11 @@ def main():
if not arguments or not os.path.isfile(arguments[0]):
if arguments and not os.path.isfile(arguments[0]):
print "Script %s not found" % arguments[0]
+
usage(2)
# tell C++ about output directory
- internal.main.setOutputDir(options.outdir)
+ internal.core.setOutputDir(options.outdir)
# update the system path with elements from the -p option
sys.path[0:0] = options.path
@@ -272,34 +265,45 @@ def main():
import objects
# set stats options
- objects.Statistics.text_file = options.stats_file
+ internal.stats.initText(options.stats_file)
# set debugging options
for when in options.debug_break:
internal.debug.schedBreakCycle(int(when))
- # set tracing options
- objects.Trace.flags = options.trace_flags
- objects.Trace.start = options.trace_start
- objects.Trace.cycle = options.trace_cycle
- objects.Trace.file = options.trace_file
- objects.Trace.bufsize = options.trace_circlebuf
- objects.Trace.dump_on_exit = options.trace_dumponexit
- objects.Trace.ignore = options.trace_ignore
-
- # set execution trace options
- objects.ExecutionTrace.speculative = options.speculative
- objects.ExecutionTrace.print_cycle = options.print_cycle
- objects.ExecutionTrace.pc_symbol = options.print_symbol
- objects.ExecutionTrace.print_opclass = options.print_opclass
- objects.ExecutionTrace.print_thread = options.print_thread
- objects.ExecutionTrace.print_effaddr = options.print_effaddr
- objects.ExecutionTrace.print_data = options.print_data
- objects.ExecutionTrace.print_iregs = options.print_iregs
- 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
+ on_flags = []
+ off_flags = []
+ for flag in options.trace_flags:
+ off = False
+ if flag.startswith('-'):
+ flag = flag[1:]
+ off = True
+ if flag not in traceflags.allFlags:
+ print >>sys.stderr, "invalid trace flag '%s'" % flag
+ sys.exit(1)
+
+ if off:
+ off_flags.append(flag)
+ else:
+ on_flags.append(flag)
+
+ for flag in on_flags:
+ internal.trace.set(flag)
+
+ for flag in off_flags:
+ internal.trace.clear(flag)
+
+ if options.trace_start:
+ def enable_trace():
+ internal.trace.cvar.enabled = True
+ event.create(enable_trace, int(options.trace_start))
+ else:
+ internal.trace.cvar.enabled = True
+
+ internal.trace.output(options.trace_file)
+
+ for ignore in options.trace_ignore:
+ internal.trace.ignore(ignore)
sys.argv = arguments
sys.path = [ os.path.dirname(sys.argv[0]) ] + sys.path
@@ -309,7 +313,7 @@ def main():
# we want readline if we're doing anything interactive
if options.interactive or options.pdb:
- exec("import readline", scope)
+ exec "import readline" in scope
# if pdb was requested, execfile the thing under pdb, otherwise,
# just do the execfile normally
diff --git a/src/python/m5/objects/BaseCPU.py b/src/python/m5/objects/BaseCPU.py
index 67a28a61e..986220c3f 100644
--- a/src/python/m5/objects/BaseCPU.py
+++ b/src/python/m5/objects/BaseCPU.py
@@ -47,8 +47,8 @@ class BaseCPU(SimObject):
defer_registration = Param.Bool(False,
"defer registration with system (for sampling)")
- clock = Param.Clock(Parent.clock, "clock speed")
- phase = Param.Latency("0ns", "clock phase")
+ clock = Param.Clock('1t', "clock speed")
+ phase = Param.Latency('0ns', "clock phase")
_mem_ports = []
diff --git a/src/python/m5/objects/IntrControl.py b/src/python/m5/objects/IntrControl.py
index a7cf5cc84..398ba47f9 100644
--- a/src/python/m5/objects/IntrControl.py
+++ b/src/python/m5/objects/IntrControl.py
@@ -3,4 +3,4 @@ from m5.params import *
from m5.proxy import *
class IntrControl(SimObject):
type = 'IntrControl'
- cpu = Param.BaseCPU(Parent.cpu[0], "the cpu")
+ sys = Param.System(Parent.any, "the system we are part of")
diff --git a/src/python/m5/objects/PhysicalMemory.py b/src/python/m5/objects/PhysicalMemory.py
index b8df6229e..c389e4a7f 100644
--- a/src/python/m5/objects/PhysicalMemory.py
+++ b/src/python/m5/objects/PhysicalMemory.py
@@ -8,7 +8,7 @@ class PhysicalMemory(MemObject):
functional = Port("Functional Access Port")
range = Param.AddrRange(AddrRange('128MB'), "Device Address")
file = Param.String('', "memory mapped file")
- latency = Param.Latency(Parent.clock, "latency of an access")
+ latency = Param.Latency('1t', "latency of an access")
zero = Param.Bool(False, "zero initialize memory")
class DRAMMemory(PhysicalMemory):
diff --git a/src/python/m5/objects/Root.py b/src/python/m5/objects/Root.py
index b6123f192..2b0e736e7 100644
--- a/src/python/m5/objects/Root.py
+++ b/src/python/m5/objects/Root.py
@@ -1,23 +1,6 @@
from m5.SimObject import SimObject
from m5.params import *
-from Serialize import Serialize
-from Serialize import Statreset
-from Statistics import Statistics
-from Trace import Trace
-from ExeTrace import ExecutionTrace
class Root(SimObject):
type = 'Root'
- clock = Param.RootClock('1THz', "tick frequency")
- max_tick = Param.Tick('0', "maximum simulation ticks (0 = infinite)")
- progress_interval = Param.Tick('0',
- "print a progress message every n ticks (0 = never)")
- output_file = Param.String('cout', "file to dump simulator output to")
- checkpoint = Param.String('', "checkpoint file to load")
-# stats = Param.Statistics(Statistics(), "statistics object")
-# trace = Param.Trace(Trace(), "trace object")
-# serialize = Param.Serialize(Serialize(), "checkpoint generation options")
- stats = Statistics()
- trace = Trace()
- exetrace = ExecutionTrace()
- serialize = Serialize()
+ dummy = Param.Int(0, "We don't support objects without params")
diff --git a/src/python/m5/objects/SimConsole.py b/src/python/m5/objects/SimConsole.py
index bdd7f246d..dfad18eb6 100644
--- a/src/python/m5/objects/SimConsole.py
+++ b/src/python/m5/objects/SimConsole.py
@@ -1,14 +1,11 @@
from m5.SimObject import SimObject
from m5.params import *
from m5.proxy import *
-class ConsoleListener(SimObject):
- type = 'ConsoleListener'
- port = Param.TcpPort(3456, "listen port")
class SimConsole(SimObject):
type = 'SimConsole'
append_name = Param.Bool(True, "append name() to filename")
intr_control = Param.IntrControl(Parent.any, "interrupt controller")
- listener = Param.ConsoleListener("console listener")
+ port = Param.TcpPort(3456, "listen port")
number = Param.Int(0, "console number")
output = Param.String('console', "file to dump output to")
diff --git a/src/python/m5/objects/T1000.py b/src/python/m5/objects/T1000.py
index 85c4db6df..0acfa0920 100644
--- a/src/python/m5/objects/T1000.py
+++ b/src/python/m5/objects/T1000.py
@@ -1,9 +1,9 @@
from m5.params import *
from m5.proxy import *
-from Device import BasicPioDevice, IsaFake, BadAddr
+from Device import BasicPioDevice, PioDevice, IsaFake, BadAddr
from Uart import Uart8250
from Platform import Platform
-from SimConsole import SimConsole, ConsoleListener
+from SimConsole import SimConsole
class MmDisk(BasicPioDevice):
@@ -16,6 +16,10 @@ class DumbTOD(BasicPioDevice):
time = Param.Time('01/01/2009', "System time to use ('Now' for real time)")
pio_addr = 0xfff0c1fff8
+class Iob(PioDevice):
+ type = 'Iob'
+ pio_latency = Param.Latency('1ns', "Programed IO latency in simticks")
+
class T1000(Platform):
type = 'T1000'
@@ -28,9 +32,6 @@ class T1000(Platform):
ret_data64=0x0000000000000000, update_data=False)
#warn_access="Accessing Memory Banks -- Unimplemented!")
- fake_iob = IsaFake(pio_addr=0x9800000000, pio_size=0x100000000)
- #warn_access="Accessing IOB -- Unimplemented!")
-
fake_jbi = IsaFake(pio_addr=0x8000000000, pio_size=0x100000000)
#warn_access="Accessing JBI -- Unimplemented!")
@@ -69,20 +70,28 @@ class T1000(Platform):
fake_ssi = IsaFake(pio_addr=0xff00000000, pio_size=0x10000000)
#warn_access="Accessing SSI -- Unimplemented!")
+ hconsole = SimConsole()
hvuart = Uart8250(pio_addr=0xfff0c2c000)
htod = DumbTOD()
+ pconsole = SimConsole()
puart0 = Uart8250(pio_addr=0x1f10000000)
- console = SimConsole(listener = ConsoleListener())
+
+ iob = Iob()
+ # Attach I/O devices that are on chip
+ def attachOnChipIO(self, bus):
+ self.iob.pio = bus.port
+ self.htod.pio = bus.port
+
# Attach I/O devices to specified bus object. Can't do this
# earlier, since the bus object itself is typically defined at the
# System level.
def attachIO(self, bus):
+ self.hvuart.sim_console = self.hconsole
+ self.puart0.sim_console = self.pconsole
self.fake_clk.pio = bus.port
self.fake_membnks.pio = bus.port
- self.fake_iob.pio = bus.port
- self.fake_jbi.pio = bus.port
self.fake_l2_1.pio = bus.port
self.fake_l2_2.pio = bus.port
self.fake_l2_3.pio = bus.port
@@ -92,6 +101,6 @@ class T1000(Platform):
self.fake_l2esr_3.pio = bus.port
self.fake_l2esr_4.pio = bus.port
self.fake_ssi.pio = bus.port
+ self.fake_jbi.pio = bus.port
self.puart0.pio = bus.port
self.hvuart.pio = bus.port
- self.htod.pio = bus.port
diff --git a/src/python/m5/params.py b/src/python/m5/params.py
index f8a9f9ddd..9892df97c 100644
--- a/src/python/m5/params.py
+++ b/src/python/m5/params.py
@@ -51,6 +51,7 @@ import sys
import time
import convert
+import ticks
from util import *
# Dummy base class to identify types that are legitimate for SimObject
@@ -360,6 +361,7 @@ class MemorySize(CheckedInt):
self._check()
class MemorySize32(CheckedInt):
+ cxx_type = 'uint32_t'
size = 32
unsigned = True
def __init__(self, value):
@@ -632,47 +634,29 @@ class Enum(ParamValue):
def __str__(self):
return self.value
-ticks_per_sec = None
-
# how big does a rounding error need to be before we warn about it?
frequency_tolerance = 0.001 # 0.1%
-# convert a floting-point # of ticks to integer, and warn if rounding
-# discards too much precision
-def tick_check(float_ticks):
- if float_ticks == 0:
- return 0
- int_ticks = int(round(float_ticks))
- err = (float_ticks - int_ticks) / float_ticks
- if err > frequency_tolerance:
- print >> sys.stderr, "Warning: rounding error > tolerance"
- print >> sys.stderr, " %f rounded to %d" % (float_ticks, int_ticks)
- #raise ValueError
- return int_ticks
-
-def getLatency(value):
- if isinstance(value, Latency) or isinstance(value, Clock):
- return value.value
- elif isinstance(value, Frequency) or isinstance(value, RootClock):
- return 1 / value.value
- elif isinstance(value, str):
- try:
- return convert.toLatency(value)
- except ValueError:
- try:
- return 1 / convert.toFrequency(value)
- except ValueError:
- pass # fall through
- raise ValueError, "Invalid Frequency/Latency value '%s'" % value
-
-
-class Latency(NumericParamValue):
+class TickParamValue(NumericParamValue):
cxx_type = 'Tick'
cxx_predecls = ['#include "sim/host.hh"']
swig_predecls = ['%import "python/m5/swig/stdint.i"\n' +
'%import "sim/host.hh"']
+
+class Latency(TickParamValue):
def __init__(self, value):
- self.value = getLatency(value)
+ if isinstance(value, (Latency, Clock)):
+ self.ticks = value.ticks
+ self.value = value.value
+ elif isinstance(value, Frequency):
+ self.ticks = value.ticks
+ self.value = 1.0 / value.value
+ elif value.endswith('t'):
+ self.ticks = True
+ self.value = int(value[:-1])
+ else:
+ self.ticks = False
+ self.value = convert.toLatency(value)
def __getattr__(self, attr):
if attr in ('latency', 'period'):
@@ -683,15 +667,25 @@ class Latency(NumericParamValue):
# convert latency to ticks
def ini_str(self):
- return str(tick_check(self.value * ticks_per_sec))
+ if self.ticks or self.value == 0:
+ return '%d' % self.value
+ else:
+ return '%d' % (ticks.fromSeconds(self.value))
-class Frequency(NumericParamValue):
- cxx_type = 'Tick'
- cxx_predecls = ['#include "sim/host.hh"']
- swig_predecls = ['%import "python/m5/swig/stdint.i"\n' +
- '%import "sim/host.hh"']
+class Frequency(TickParamValue):
def __init__(self, value):
- self.value = 1 / getLatency(value)
+ if isinstance(value, (Latency, Clock)):
+ if value.value == 0:
+ self.value = 0
+ else:
+ self.value = 1.0 / value.value
+ self.ticks = value.ticks
+ elif isinstance(value, Frequency):
+ self.value = value.value
+ self.ticks = value.ticks
+ else:
+ self.ticks = False
+ self.value = convert.toFrequency(value)
def __getattr__(self, attr):
if attr == 'frequency':
@@ -700,30 +694,12 @@ class Frequency(NumericParamValue):
return Latency(self)
raise AttributeError, "Frequency object has no attribute '%s'" % attr
- # convert frequency to ticks per period
- def ini_str(self):
- return self.period.ini_str()
-
-# Just like Frequency, except ini_str() is absolute # of ticks per sec (Hz).
-# We can't inherit from Frequency because we don't want it to be directly
-# assignable to a regular Frequency parameter.
-class RootClock(ParamValue):
- cxx_type = 'Tick'
- cxx_predecls = ['#include "sim/host.hh"']
- swig_predecls = ['%import "python/m5/swig/stdint.i"\n' +
- '%import "sim/host.hh"']
- def __init__(self, value):
- self.value = 1 / getLatency(value)
-
- def __getattr__(self, attr):
- if attr == 'frequency':
- return Frequency(self)
- if attr in ('latency', 'period'):
- return Latency(self)
- raise AttributeError, "Frequency object has no attribute '%s'" % attr
-
+ # convert latency to ticks
def ini_str(self):
- return str(tick_check(self.value))
+ if self.ticks or self.value == 0:
+ return '%d' % self.value
+ else:
+ return '%d' % (ticks.fromSeconds(1.0 / self.value))
# A generic frequency and/or Latency value. Value is stored as a latency,
# but to avoid ambiguity this object does not support numeric ops (* or /).
@@ -734,7 +710,18 @@ class Clock(ParamValue):
swig_predecls = ['%import "python/m5/swig/stdint.i"\n' +
'%import "sim/host.hh"']
def __init__(self, value):
- self.value = getLatency(value)
+ if isinstance(value, (Latency, Clock)):
+ self.ticks = value.ticks
+ self.value = value.value
+ elif isinstance(value, Frequency):
+ self.ticks = value.ticks
+ self.value = 1.0 / value.value
+ elif value.endswith('t'):
+ self.ticks = True
+ self.value = int(value[:-1])
+ else:
+ self.ticks = False
+ self.value = convert.anyToLatency(value)
def __getattr__(self, attr):
if attr == 'frequency':
@@ -749,18 +736,23 @@ class Clock(ParamValue):
class NetworkBandwidth(float,ParamValue):
cxx_type = 'float'
def __new__(cls, value):
- val = convert.toNetworkBandwidth(value) / 8.0
+ # convert to bits per second
+ val = convert.toNetworkBandwidth(value)
return super(cls, NetworkBandwidth).__new__(cls, val)
def __str__(self):
return str(self.val)
def ini_str(self):
- return '%f' % (ticks_per_sec / float(self))
+ # convert to seconds per byte
+ value = 8.0 / float(self)
+ # convert to ticks per byte
+ return '%f' % (ticks.fromSeconds(value))
class MemoryBandwidth(float,ParamValue):
cxx_type = 'float'
def __new__(self, value):
+ # we want the number of ticks per byte of data
val = convert.toMemoryBandwidth(value)
return super(cls, MemoryBandwidth).__new__(cls, val)
@@ -768,7 +760,10 @@ class MemoryBandwidth(float,ParamValue):
return str(self.val)
def ini_str(self):
- return '%f' % (ticks_per_sec / float(self))
+ # convert to seconds per byte
+ value = 1.0 / float(self)
+ # convert to ticks per byte
+ return '%f' % (ticks.fromSeconds(value))
#
# "Constants"... handy aliases for various values.
@@ -894,9 +889,8 @@ class PortRef(object):
if self.ccConnected: # already done this
return
peer = self.peer
- internal.main.connectPorts(self.simobj.getCCObject(), self.name,
- self.index, peer.simobj.getCCObject(),
- peer.name, peer.index)
+ internal.sim_object.connectPorts(self.simobj.getCCObject(), self.name,
+ self.index, peer.simobj.getCCObject(), peer.name, peer.index)
self.ccConnected = True
peer.ccConnected = True
@@ -1024,7 +1018,7 @@ __all__ = ['Param', 'VectorParam',
'Counter', 'Addr', 'Tick', 'Percent',
'TcpPort', 'UdpPort', 'EthernetAddr',
'MemorySize', 'MemorySize32',
- 'Latency', 'Frequency', 'RootClock', 'Clock',
+ 'Latency', 'Frequency', 'Clock',
'NetworkBandwidth', 'MemoryBandwidth',
'Range', 'AddrRange', 'TickRange',
'MaxAddr', 'MaxTick', 'AllMemory',
diff --git a/src/python/m5/stats.py b/src/python/m5/stats.py
new file mode 100644
index 000000000..041a3f58d
--- /dev/null
+++ b/src/python/m5/stats.py
@@ -0,0 +1,46 @@
+# Copyright (c) 2007 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
+
+import internal
+
+from internal.stats import dump
+from internal.stats import initSimStats
+from internal.stats import reset
+from internal.stats import StatEvent as event
+
+def initText(filename, desc=True, compat=True):
+ internal.stats.initText(filename, desc, compat)
+
+def initMySQL(host, database, user='', passwd='', project='test', name='test',
+ sample='0'):
+ if not user:
+ import getpass
+ user = getpass.getuser()
+
+ internal.stats.initMySQL(host, database, user, passwd, project, name,
+ sample)
diff --git a/src/python/m5/ticks.py b/src/python/m5/ticks.py
new file mode 100644
index 000000000..e91b470ff
--- /dev/null
+++ b/src/python/m5/ticks.py
@@ -0,0 +1,89 @@
+# Copyright (c) 2007 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
+
+import sys
+
+import convert
+import internal
+
+tps = 1.0e12 # default to 1 THz (1 Tick == 1 ps)
+tps_fixed = False # once set to true, can't be changed
+
+# fix the global frequency and tell C++ about it
+def fixGlobalFrequency():
+ global tps, tps_fixed
+ if not tps_fixed:
+ tps_fixed = True
+ internal.core.setClockFrequency(int(tps))
+ print "Global frequency set at %d ticks per second" % int(tps)
+
+def setGlobalFrequency(ticksPerSecond):
+ global tps, tps_fixed
+
+ if tps_fixed:
+ raise AttributeError, \
+ "Global frequency already fixed at %f ticks/s." % tps
+
+ if isinstance(ticksPerSecond, (int, long)):
+ tps = ticksPerSecond
+ elif isinstance(ticksPerSecond, float):
+ tps = ticksPerSecond
+ elif isinstance(ticksPerSecond, str):
+ tps = round(convert.anyToFrequency(ticksPerSecond))
+ else:
+ raise TypeError, \
+ "wrong type '%s' for ticksPerSecond" % type(ticksPerSecond)
+
+# how big does a rounding error need to be before we warn about it?
+frequency_tolerance = 0.001 # 0.1%
+
+def fromSeconds(value):
+ if not isinstance(value, float):
+ raise TypeError, "can't convert '%s' to type tick" % type(value)
+
+ # once someone needs to convert to seconds, the global frequency
+ # had better be fixed
+ if not tps_fixed:
+ raise AttributeError, \
+ "In order to do conversions, the global frequency must be fixed"
+
+ if value == 0:
+ return 0
+
+ # convert the value from time to ticks
+ value *= tps
+
+ int_value = int(round(value))
+ err = (value - int_value) / value
+ if err > frequency_tolerance:
+ print >>sys.stderr, "Warning: rounding error > tolerance"
+ print >>sys.stderr, " %f rounded to %d" % (value, int_value)
+ return int_value
+
+__all__ = [ 'setGlobalFrequency', 'fixGlobalFrequency', 'fromSeconds',
+ 'frequency_tolerance' ]
diff --git a/src/python/swig/core.i b/src/python/swig/core.i
new file mode 100644
index 000000000..3edfa4c7e
--- /dev/null
+++ b/src/python/swig/core.i
@@ -0,0 +1,65 @@
+/*
+ * 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: Nathan Binkert
+ * Steve Reinhardt
+ */
+
+%module core
+
+%{
+#include "python/swig/pyobject.hh"
+
+#include "sim/core.hh"
+#include "sim/host.hh"
+#include "sim/startup.hh"
+
+extern const char *compileDate;
+%}
+
+%include "stdint.i"
+%include "std_string.i"
+%include "sim/host.hh"
+
+void setOutputDir(const std::string &dir);
+void setOutputFile(const std::string &file);
+void loadIniFile(PyObject *);
+void SimStartup();
+void doExitCleanup();
+
+char *compileDate;
+
+void setClockFrequency(Tick ticksPerSecond);
+
+%immutable curTick;
+Tick curTick;
+
+%wrapper %{
+// fix up module name to reflect the fact that it's inside the m5 package
+#undef SWIG_name
+#define SWIG_name "m5.internal._core"
+%}
diff --git a/src/python/swig/event.i b/src/python/swig/event.i
index 554c9fa0e..9a2093c99 100644
--- a/src/python/swig/event.i
+++ b/src/python/swig/event.i
@@ -33,19 +33,43 @@
%{
#include "python/swig/pyevent.hh"
-inline void
-create(PyObject *object, Tick when)
-{
- new PythonEvent(object, when);
-}
+#include "sim/sim_events.hh"
+#include "sim/sim_exit.hh"
+#include "sim/simulate.hh"
%}
%include "stdint.i"
+%include "std_string.i"
%include "sim/host.hh"
-%inline %{
-extern void create(PyObject *object, Tick when);
-%}
+void create(PyObject *object, Tick when);
+
+class Event;
+class CountedDrainEvent : public Event {
+ public:
+ void setCount(int _count);
+};
+
+CountedDrainEvent *createCountedDrain();
+void cleanupCountedDrain(Event *drain_event);
+
+// minimal definition of SimExitEvent interface to wrap
+class SimLoopExitEvent {
+ public:
+ std::string getCause();
+ int getCode();
+ SimLoopExitEvent(EventQueue *q, Tick _when, Tick _repeat,
+ const std::string &_cause, int c = 0);
+};
+
+%exception simulate {
+ $action
+ if (!result) {
+ return NULL;
+ }
+}
+SimLoopExitEvent *simulate(Tick num_cycles = MaxTick);
+void exitSimLoop(const std::string &message, int exit_code);
%wrapper %{
// fix up module name to reflect the fact that it's inside the m5 package
diff --git a/src/python/swig/pyevent.cc b/src/python/swig/pyevent.cc
index 6fb7d3f17..7f23b8874 100644
--- a/src/python/swig/pyevent.cc
+++ b/src/python/swig/pyevent.cc
@@ -31,6 +31,7 @@
#include <Python.h>
#include "python/swig/pyevent.hh"
+#include "sim/async.hh"
PythonEvent::PythonEvent(PyObject *obj, Tick when, Priority priority)
: Event(&mainEventQueue, priority), object(obj)
@@ -52,9 +53,9 @@ PythonEvent::~PythonEvent()
void
PythonEvent::process()
{
- PyObject *result;
-
- result = PyObject_CallMethod(object, "process", "");
+ PyObject *args = PyTuple_New(0);
+ PyObject *result = PyObject_Call(object, args, NULL);
+ Py_DECREF(args);
if (result) {
// Nothing to do just decrement the reference count
@@ -62,5 +63,7 @@ PythonEvent::process()
} else {
// Somethign should be done to signal back to the main interpreter
// that there's been an exception.
+ async_event = true;
+ async_exception = true;
}
}
diff --git a/src/python/swig/pyevent.hh b/src/python/swig/pyevent.hh
index 16af85a84..65e80e9e4 100644
--- a/src/python/swig/pyevent.hh
+++ b/src/python/swig/pyevent.hh
@@ -32,6 +32,7 @@
#define __PYTHON_SWIG_PYEVENT_HH__
#include "sim/eventq.hh"
+#include "sim/sim_events.hh"
class PythonEvent : public Event
{
@@ -45,4 +46,29 @@ class PythonEvent : public Event
virtual void process();
};
+inline void
+create(PyObject *object, Tick when)
+{
+ new PythonEvent(object, when);
+}
+
+inline Event *
+createCountedDrain()
+{
+ return new CountedDrainEvent();
+}
+
+inline void
+cleanupCountedDrain(Event *counted_drain)
+{
+ CountedDrainEvent *event =
+ dynamic_cast<CountedDrainEvent *>(counted_drain);
+ if (event == NULL) {
+ fatal("Called cleanupCountedDrain() on an event that was not "
+ "a CountedDrainEvent.");
+ }
+ assert(event->getCount() == 0);
+ delete event;
+}
+
#endif // __PYTHON_SWIG_PYEVENT_HH__
diff --git a/src/python/swig/pyobject.cc b/src/python/swig/pyobject.cc
new file mode 100644
index 000000000..11141fa84
--- /dev/null
+++ b/src/python/swig/pyobject.cc
@@ -0,0 +1,137 @@
+/*
+ * 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: Nathan Binkert
+ */
+
+#include <Python.h>
+
+#include <string>
+
+#include "base/inifile.hh"
+#include "base/output.hh"
+#include "mem/mem_object.hh"
+#include "mem/port.hh"
+#include "sim/builder.hh"
+#include "sim/sim_object.hh"
+
+using namespace std;
+
+/**
+ * Look up a MemObject port. Helper function for connectPorts().
+ */
+Port *
+lookupPort(SimObject *so, const std::string &name, int i)
+{
+ MemObject *mo = dynamic_cast<MemObject *>(so);
+ if (mo == NULL) {
+ warn("error casting SimObject %s to MemObject", so->name());
+ return NULL;
+ }
+
+ Port *p = mo->getPort(name, i);
+ if (p == NULL)
+ warn("error looking up port %s on object %s", name, so->name());
+ return p;
+}
+
+
+/**
+ * Connect the described MemObject ports. Called from Python via SWIG.
+ */
+int
+connectPorts(SimObject *o1, const std::string &name1, int i1,
+ SimObject *o2, const std::string &name2, int i2)
+{
+ Port *p1 = lookupPort(o1, name1, i1);
+ Port *p2 = lookupPort(o2, name2, i2);
+
+ if (p1 == NULL || p2 == NULL) {
+ warn("connectPorts: port lookup error");
+ return 0;
+ }
+
+ p1->setPeer(p2);
+ p2->setPeer(p1);
+
+ return 1;
+}
+
+inline IniFile &
+inifile()
+{
+ static IniFile inifile;
+ return inifile;
+}
+
+SimObject *
+createSimObject(const string &name)
+{
+ return SimObjectClass::createObject(inifile(), name);
+}
+
+/**
+ * Pointer to the Python function that maps names to SimObjects.
+ */
+PyObject *resolveFunc = NULL;
+
+/**
+ * Convert a pointer to the Python object that SWIG wraps around a C++
+ * SimObject pointer back to the actual C++ pointer. See main.i.
+ */
+extern "C" SimObject *convertSwigSimObjectPtr(PyObject *);
+
+SimObject *
+resolveSimObject(const string &name)
+{
+ PyObject *pyPtr = PyEval_CallFunction(resolveFunc, "(s)", name.c_str());
+ if (pyPtr == NULL) {
+ PyErr_Print();
+ panic("resolveSimObject: failure on call to Python for %s", name);
+ }
+
+ SimObject *simObj = convertSwigSimObjectPtr(pyPtr);
+ if (simObj == NULL)
+ panic("resolveSimObject: failure on pointer conversion for %s", name);
+
+ return simObj;
+}
+
+/**
+ * Load config.ini into C++ database. Exported to Python via SWIG;
+ * invoked from m5.instantiate().
+ */
+void
+loadIniFile(PyObject *_resolveFunc)
+{
+ resolveFunc = _resolveFunc;
+ configStream = simout.find("config.out");
+
+ // The configuration database is now complete; start processing it.
+ inifile().load(simout.resolve("config.ini"));
+}
+
diff --git a/src/python/swig/pyobject.hh b/src/python/swig/pyobject.hh
new file mode 100644
index 000000000..d8efc9149
--- /dev/null
+++ b/src/python/swig/pyobject.hh
@@ -0,0 +1,94 @@
+/*
+ * 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: Nathan Binkert
+ */
+
+#include <Python.h>
+
+#include "cpu/base.hh"
+#include "sim/host.hh"
+#include "sim/serialize.hh"
+#include "sim/sim_object.hh"
+#include "sim/system.hh"
+
+SimObject *createSimObject(const std::string &name);
+extern "C" SimObject *convertSwigSimObjectPtr(PyObject *);
+SimObject *resolveSimObject(const std::string &name);
+void loadIniFile(PyObject *_resolveFunc);
+
+
+/**
+ * Connect the described MemObject ports. Called from Python via SWIG.
+ */
+int connectPorts(SimObject *o1, const std::string &name1, int i1,
+ SimObject *o2, const std::string &name2, int i2);
+
+inline BaseCPU *
+convertToBaseCPUPtr(SimObject *obj)
+{
+ BaseCPU *ptr = dynamic_cast<BaseCPU *>(obj);
+
+ if (ptr == NULL)
+ warn("Casting to BaseCPU pointer failed");
+ return ptr;
+}
+
+inline System *
+convertToSystemPtr(SimObject *obj)
+{
+ System *ptr = dynamic_cast<System *>(obj);
+
+ if (ptr == NULL)
+ warn("Casting to System pointer failed");
+ return ptr;
+}
+
+inline void
+initAll()
+{
+ SimObject::initAll();
+}
+
+inline void
+regAllStats()
+{
+ SimObject::regAllStats();
+}
+
+inline void
+serializeAll(const std::string &cpt_dir)
+{
+ Serializable::serializeAll(cpt_dir);
+}
+
+inline void
+unserializeAll(const std::string &cpt_dir)
+{
+ Serializable::unserializeAll(cpt_dir);
+}
+
diff --git a/src/python/swig/random.i b/src/python/swig/random.i
new file mode 100644
index 000000000..657a59780
--- /dev/null
+++ b/src/python/swig/random.i
@@ -0,0 +1,55 @@
+/*
+ * 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: Nathan Binkert
+ */
+
+%module random
+
+%include "stdint.i"
+
+%{
+#include <cstdlib>
+
+#include "sim/host.hh"
+
+inline void
+seed(uint64_t seed)
+{
+ ::srand48(seed & ULL(0xffffffffffff));
+}
+%}
+
+%inline %{
+extern void seed(uint64_t seed);
+%}
+
+%wrapper %{
+// fix up module name to reflect the fact that it's inside the m5 package
+#undef SWIG_name
+#define SWIG_name "m5.internal._random"
+%}
diff --git a/src/python/swig/sim_object.i b/src/python/swig/sim_object.i
new file mode 100644
index 000000000..b2af72c61
--- /dev/null
+++ b/src/python/swig/sim_object.i
@@ -0,0 +1,101 @@
+/*
+ * 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: Nathan Binkert
+ */
+
+%module sim_object
+
+%{
+#include "python/swig/pyobject.hh"
+%}
+
+// import these files for SWIG to wrap
+%include "stdint.i"
+%include "std_string.i"
+%include "sim/host.hh"
+
+class BaseCPU;
+
+class SimObject {
+ public:
+ enum State {
+ Running,
+ Draining,
+ Drained
+ };
+
+ enum MemoryMode {
+ Invalid,
+ Atomic,
+ Timing
+ };
+
+ unsigned int drain(Event *drain_event);
+ void resume();
+ void switchOut();
+ void takeOverFrom(BaseCPU *cpu);
+ SimObject(const std::string &_name);
+};
+
+class System {
+ private:
+ System();
+ public:
+ void setMemoryMode(SimObject::MemoryMode mode);
+};
+
+SimObject *createSimObject(const std::string &name);
+
+int connectPorts(SimObject *o1, const std::string &name1, int i1,
+ SimObject *o2, const std::string &name2, int i2);
+
+BaseCPU *convertToBaseCPUPtr(SimObject *obj);
+System *convertToSystemPtr(SimObject *obj);
+
+void serializeAll(const std::string &cpt_dir);
+void unserializeAll(const std::string &cpt_dir);
+
+void initAll();
+void regAllStats();
+
+%wrapper %{
+// fix up module name to reflect the fact that it's inside the m5 package
+#undef SWIG_name
+#define SWIG_name "m5.internal._sim_object"
+
+// Convert a pointer to the Python object that SWIG wraps around a
+// C++ SimObject pointer back to the actual C++ pointer.
+SimObject *
+convertSwigSimObjectPtr(PyObject *pyObj)
+{
+ SimObject *so;
+ if (SWIG_ConvertPtr(pyObj, (void **) &so, SWIGTYPE_p_SimObject, 0) == -1)
+ return NULL;
+ return so;
+}
+%}
diff --git a/src/python/swig/stats.i b/src/python/swig/stats.i
new file mode 100644
index 000000000..d36f82dbc
--- /dev/null
+++ b/src/python/swig/stats.i
@@ -0,0 +1,61 @@
+/*
+ * 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: Nathan Binkert
+ */
+
+%module stats
+
+%include "std_string.i"
+
+%{
+#include "base/statistics.hh"
+#include "base/stats/mysql.hh"
+#include "base/stats/text.hh"
+#include "sim/stat_control.hh"
+%}
+
+namespace Stats {
+void initSimStats();
+void initText(const std::string &filename, bool desc=true, bool compat=true);
+void initMySQL(std::string host, std::string database, std::string user,
+ std::string passwd, std::string project, std::string name,
+ std::string sample);
+
+void StatEvent(bool dump, bool reset, Tick when = curTick, Tick repeat = 0);
+
+void check();
+void dump();
+void reset();
+
+/* namespace Stat */ }
+
+%wrapper %{
+// fix up module name to reflect the fact that it's inside the m5 package
+#undef SWIG_name
+#define SWIG_name "m5.internal._stats"
+%}
diff --git a/src/python/swig/trace.i b/src/python/swig/trace.i
new file mode 100644
index 000000000..69b44c025
--- /dev/null
+++ b/src/python/swig/trace.i
@@ -0,0 +1,76 @@
+/*
+ * 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: Nathan Binkert
+ */
+
+%module trace
+
+%{
+#include "base/trace.hh"
+#include "sim/host.hh"
+
+inline void
+output(const char *filename)
+{
+ Trace::setOutput(filename);
+}
+
+inline void
+set(const char *flag)
+{
+ Trace::changeFlag(flag, true);
+}
+
+inline void
+clear(const char *flag)
+{
+ Trace::changeFlag(flag, false);
+}
+
+inline void
+ignore(const char *expr)
+{
+ Trace::ignore.setExpression(expr);
+}
+
+using Trace::enabled;
+%}
+
+%inline %{
+extern void output(const char *string);
+extern void set(const char *string);
+extern void clear(const char *string);
+extern void ignore(const char *expr);
+extern bool enabled;
+%}
+
+%wrapper %{
+// fix up module name to reflect the fact that it's inside the m5 package
+#undef SWIG_name
+#define SWIG_name "m5.internal._trace"
+%}
diff --git a/src/sim/SConscript b/src/sim/SConscript
new file mode 100644
index 000000000..46dc2c8dd
--- /dev/null
+++ b/src/sim/SConscript
@@ -0,0 +1,54 @@
+# -*- 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: Nathan Binkert
+
+Import('*')
+
+Source('async.cc')
+Source('builder.cc')
+Source('core.cc')
+Source('debug.cc')
+Source('eventq.cc')
+Source('faults.cc')
+Source('main.cc')
+Source('param.cc')
+Source('root.cc')
+Source('serialize.cc')
+Source('sim_events.cc')
+Source('sim_object.cc')
+Source('simulate.cc')
+Source('startup.cc')
+Source('stat_control.cc')
+Source('system.cc')
+
+if env['FULL_SYSTEM']:
+ Source('pseudo_inst.cc')
+else:
+ Source('process.cc')
+ Source('syscall_emul.cc')
diff --git a/src/sim/async.cc b/src/sim/async.cc
new file mode 100644
index 000000000..1a8e499f7
--- /dev/null
+++ b/src/sim/async.cc
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2000-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
+ */
+
+volatile bool async_event = false;
+volatile bool async_statdump = false;
+volatile bool async_statreset = false;
+volatile bool async_exit = false;
+volatile bool async_io = false;
+volatile bool async_alarm = false;
+volatile bool async_exception = false;
+
diff --git a/src/sim/async.hh b/src/sim/async.hh
index 50ae73040..932f975d2 100644
--- a/src/sim/async.hh
+++ b/src/sim/async.hh
@@ -43,10 +43,12 @@
/// @note See the PollQueue object (in pollevent.hh) for the use of async_io and async_alarm.
//@{
extern volatile bool async_event; ///< Some asynchronous event has happened.
-extern volatile bool async_dump; ///< Async request to dump stats.
+extern volatile bool async_statdump; ///< Async request to dump stats.
+extern volatile bool async_statreset; ///< Async request to reset stats.
extern volatile bool async_exit; ///< Async request to exit simulator.
extern volatile bool async_io; ///< Async I/O request (SIGIO).
extern volatile bool async_alarm; ///< Async alarm event (SIGALRM).
+extern volatile bool async_exception; ///< Python exception.
//@}
#endif // __ASYNC_HH__
diff --git a/src/sim/builder.cc b/src/sim/builder.cc
index 9074cc899..532df36b1 100644
--- a/src/sim/builder.cc
+++ b/src/sim/builder.cc
@@ -35,12 +35,12 @@
#include "sim/builder.hh"
#include "sim/host.hh"
#include "sim/sim_object.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
using namespace std;
SimObjectBuilder::SimObjectBuilder(const std::string &_iniSection)
- : ParamContext(_iniSection, NoAutoInit)
+ : ParamContext(_iniSection)
{
}
diff --git a/src/sim/byteswap.hh b/src/sim/byteswap.hh
index cbc0b5088..062fc4513 100644
--- a/src/sim/byteswap.hh
+++ b/src/sim/byteswap.hh
@@ -37,6 +37,7 @@
#ifndef __SIM_BYTE_SWAP_HH__
#define __SIM_BYTE_SWAP_HH__
+#include "base/bigint.hh"
#include "base/misc.hh"
#include "sim/host.hh"
@@ -109,7 +110,7 @@ swap_byte16(uint16_t x)
// This function lets the compiler figure out how to call the
// swap_byte functions above for different data types. Since the
-// sizeof() values are known at compiel time, it should inline to a
+// sizeof() values are known at compile time, it should inline to a
// direct call to the right swap_byteNN() function.
template <typename T>
static inline T swap_byte(T x) {
@@ -125,6 +126,22 @@ static inline T swap_byte(T x) {
panic("Can't byte-swap values larger than 64 bits");
}
+template<>
+static inline Twin64_t swap_byte<Twin64_t>(Twin64_t x)
+{
+ x.a = swap_byte(x.a);
+ x.b = swap_byte(x.b);
+ return x;
+}
+
+template<>
+static inline Twin32_t swap_byte<Twin32_t>(Twin32_t x)
+{
+ x.a = swap_byte(x.a);
+ x.b = swap_byte(x.b);
+ return x;
+}
+
//The conversion functions with fixed endianness on both ends don't need to
//be in a namespace
template <typename T> static inline T betole(T value) {return swap_byte(value);}
diff --git a/src/sim/core.cc b/src/sim/core.cc
new file mode 100644
index 000000000..c961e9eb8
--- /dev/null
+++ b/src/sim/core.cc
@@ -0,0 +1,140 @@
+/*
+ * 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: Nathan Binkert
+ * Steve Reinhardt
+ */
+
+#include <iostream>
+#include <string>
+
+#include "base/callback.hh"
+#include "base/output.hh"
+#include "sim/core.hh"
+
+using namespace std;
+
+Tick curTick = 0;
+
+namespace Clock {
+/// The simulated frequency of curTick. (In ticks per second)
+Tick Frequency;
+
+namespace Float {
+double s;
+double ms;
+double us;
+double ns;
+double ps;
+
+double Hz;
+double kHz;
+double MHz;
+double GHZ;
+/* namespace Float */ }
+
+namespace Int {
+Tick s;
+Tick ms;
+Tick us;
+Tick ns;
+Tick ps;
+/* namespace Float */ }
+
+/* namespace Clock */ }
+
+void
+setClockFrequency(Tick ticksPerSecond)
+{
+ using namespace Clock;
+ Frequency = ticksPerSecond;
+ Float::s = static_cast<double>(Frequency);
+ Float::ms = Float::s / 1.0e3;
+ Float::us = Float::s / 1.0e6;
+ Float::ns = Float::s / 1.0e9;
+ Float::ps = Float::s / 1.0e12;
+
+ Float::Hz = 1.0 / Float::s;
+ Float::kHz = 1.0 / Float::ms;
+ Float::MHz = 1.0 / Float::us;
+ Float::GHZ = 1.0 / Float::ns;
+
+ Int::s = Frequency;
+ Int::ms = Int::s / 1000;
+ Int::us = Int::ms / 1000;
+ Int::ns = Int::us / 1000;
+ Int::ps = Int::ns / 1000;
+
+}
+
+void
+setOutputDir(const string &dir)
+{
+ simout.setDirectory(dir);
+}
+
+ostream *outputStream;
+ostream *configStream;
+
+void
+setOutputFile(const string &file)
+{
+ outputStream = simout.find(file);
+}
+
+/**
+ * Queue of C++ callbacks to invoke on simulator exit.
+ */
+inline CallbackQueue &
+exitCallbacks()
+{
+ static CallbackQueue theQueue;
+ return theQueue;
+}
+
+/**
+ * Register an exit callback.
+ */
+void
+registerExitCallback(Callback *callback)
+{
+ exitCallbacks().add(callback);
+}
+
+/**
+ * Do C++ simulator exit processing. Exported to SWIG to be invoked
+ * when simulator terminates via Python's atexit mechanism.
+ */
+void
+doExitCleanup()
+{
+ exitCallbacks().process();
+ exitCallbacks().clear();
+
+ cout.flush();
+}
+
diff --git a/src/sim/core.hh b/src/sim/core.hh
new file mode 100644
index 000000000..7360032c2
--- /dev/null
+++ b/src/sim/core.hh
@@ -0,0 +1,85 @@
+/*
+ * 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: Nathan Binkert
+ * Steve Reinhardt
+ */
+
+#ifndef __SIM_CORE_HH__
+#define __SIM_CORE_HH__
+
+#include <string>
+
+#include "sim/host.hh"
+
+/// The universal simulation clock.
+extern Tick curTick;
+const Tick retryTime = 1000;
+
+namespace Clock {
+/// The simulated frequency of curTick.
+extern Tick Frequency;
+
+namespace Float {
+extern double s;
+extern double ms;
+extern double us;
+extern double ns;
+extern double ps;
+
+extern double Hz;
+extern double kHz;
+extern double MHz;
+extern double GHZ;
+/* namespace Float */ }
+
+namespace Int {
+extern Tick s;
+extern Tick ms;
+extern Tick us;
+extern Tick ns;
+extern Tick ps;
+/* namespace Int */ }
+/* namespace Clock */ }
+
+void setClockFrequency(Tick ticksPerSecond);
+
+/// Output stream for simulator messages (e.g., cprintf()). Also used
+/// as default stream for tracing and DPRINTF() messages (unless
+/// overridden with trace:file option).
+extern std::ostream *outputStream;
+void setOutputFile(const std::string &file);
+void setOutputDir(const std::string &dir);
+
+/// Output stream for configuration dump.
+extern std::ostream *configStream;
+
+struct Callback;
+void registerExitCallback(Callback *callback);
+void doExitCleanup();
+
+#endif /* __SIM_CORE_HH__ */
diff --git a/src/sim/eventq.cc b/src/sim/eventq.cc
index 6ae838897..65e115256 100644
--- a/src/sim/eventq.cc
+++ b/src/sim/eventq.cc
@@ -41,7 +41,7 @@
#include "sim/eventq.hh"
#include "base/trace.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
using namespace std;
@@ -53,6 +53,10 @@ using namespace std;
//
EventQueue mainEventQueue("MainEventQueue");
+#ifndef NDEBUG
+Counter Event::instanceCounter = 0;
+#endif
+
void
EventQueue::insert(Event *event)
{
@@ -218,7 +222,6 @@ EventQueue::dump()
cprintf("============================================================\n");
}
-extern "C"
void
dumpMainQueue()
{
diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh
index fa65b08af..a57e9077e 100644
--- a/src/sim/eventq.hh
+++ b/src/sim/eventq.hh
@@ -75,6 +75,18 @@ class Event : public Serializable, public FastAlloc
friend class EventQueue;
private:
+
+#ifndef NDEBUG
+ /// Global counter to generate unique IDs for Event instances
+ static Counter instanceCounter;
+
+ /// This event's unique ID. We can also use pointer values for
+ /// this but they're not consistent across runs making debugging
+ /// more difficult. Thus we use a global counter value when
+ /// debugging.
+ Counter instanceId;
+#endif // NDEBUG
+
/// queue to which this event belongs (though it may or may not be
/// scheduled on this queue yet)
EventQueue *queue;
@@ -157,6 +169,9 @@ class Event : public Serializable, public FastAlloc
/// everything else, but before exit.
Stat_Event_Pri = 90,
+ /// Progress events come at the end.
+ Progress_Event_Pri = 95,
+
/// If we want to exit on this cycle, it's the very last thing
/// we do.
Sim_Exit_Pri = 100
@@ -173,12 +188,19 @@ class Event : public Serializable, public FastAlloc
#endif
annotated_value(0)
{
+#ifndef NDEBUG
+ instanceId = ++instanceCounter;
+#endif
}
~Event() {}
virtual const std::string name() const {
+#ifndef NDEBUG
+ return csprintf("Event_%d", instanceId);
+#else
return csprintf("Event_%x", (uintptr_t)this);
+#endif
}
/// Determine if the current event is scheduled
diff --git a/src/sim/faults.cc b/src/sim/faults.cc
index cea35482a..b09bbc177 100644
--- a/src/sim/faults.cc
+++ b/src/sim/faults.cc
@@ -29,10 +29,13 @@
* Gabe Black
*/
+#include "arch/isa_traits.hh"
#include "base/misc.hh"
-#include "sim/faults.hh"
#include "cpu/thread_context.hh"
#include "cpu/base.hh"
+#include "sim/faults.hh"
+#include "sim/process.hh"
+#include "mem/page_table.hh"
#if !FULL_SYSTEM
void FaultBase::invoke(ThreadContext * tc)
@@ -53,3 +56,26 @@ void UnimpFault::invoke(ThreadContext * tc)
{
panic("Unimpfault: %s\n", panicStr.c_str());
}
+#if !FULL_SYSTEM
+void PageTableFault::invoke(ThreadContext *tc)
+{
+ Process *p = tc->getProcessPtr();
+
+ // We've accessed the next page of the stack, so extend the stack
+ // to cover it.
+ if(vaddr < p->stack_min && vaddr >= p->stack_min - TheISA::PageBytes)
+ {
+ p->stack_min -= TheISA::PageBytes;
+ if(p->stack_base - p->stack_min > 8*1024*1024)
+ fatal("Over max stack size for one thread\n");
+ p->pTable->allocate(p->stack_min, TheISA::PageBytes);
+ warn("Increasing stack size by one page.");
+ }
+ // Otherwise, we have an unexpected page fault. Report that fact,
+ // and what address was accessed to cause the fault.
+ else
+ {
+ panic("Page table fault when accessing virtual address %#x\n", vaddr);
+ }
+}
+#endif
diff --git a/src/sim/faults.hh b/src/sim/faults.hh
index 00264d8fc..2f0b5af62 100644
--- a/src/sim/faults.hh
+++ b/src/sim/faults.hh
@@ -76,4 +76,16 @@ class UnimpFault : public FaultBase
void invoke(ThreadContext * tc);
};
+#if !FULL_SYSTEM
+class PageTableFault : public FaultBase
+{
+ private:
+ Addr vaddr;
+ public:
+ FaultName name() {return "M5 page table fault";}
+ PageTableFault(Addr va) : vaddr(va) {}
+ void invoke(ThreadContext * tc);
+};
+#endif
+
#endif // __FAULTS_HH__
diff --git a/src/sim/main.cc b/src/sim/main.cc
index 04dbe1ef4..5bf4add4b 100644
--- a/src/sim/main.cc
+++ b/src/sim/main.cc
@@ -25,77 +25,39 @@
* (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 Raasch
- * Nathan Binkert
- * Steve Reinhardt
+ * Authors: Nathan Binkert
*/
-///
-/// @file sim/main.cc
-///
-#include <Python.h> // must be before system headers... see Python docs
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <libgen.h>
-#include <stdlib.h>
+#include <Python.h>
#include <signal.h>
-#include <getopt.h>
-#include <list>
+#include <iostream>
#include <string>
-#include <vector>
-#include "base/callback.hh"
-#include "base/inifile.hh"
+#include "base/cprintf.hh"
#include "base/misc.hh"
-#include "base/output.hh"
-#include "base/pollevent.hh"
-#include "base/statistics.hh"
-#include "base/str.hh"
-#include "base/time.hh"
#include "config/pythonhome.hh"
-#include "cpu/base.hh"
-#include "cpu/smt.hh"
-#include "mem/mem_object.hh"
-#include "mem/port.hh"
#include "python/swig/init.hh"
#include "sim/async.hh"
-#include "sim/builder.hh"
#include "sim/host.hh"
-#include "sim/serialize.hh"
-#include "sim/sim_events.hh"
-#include "sim/sim_exit.hh"
-#include "sim/sim_object.hh"
-#include "sim/system.hh"
-#include "sim/stat_control.hh"
-#include "sim/stats.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
using namespace std;
-// See async.h.
-volatile bool async_event = false;
-volatile bool async_dump = false;
-volatile bool async_dumpreset = false;
-volatile bool async_exit = false;
-volatile bool async_io = false;
-volatile bool async_alarm = false;
-
/// Stats signal handler.
void
dumpStatsHandler(int sigtype)
{
async_event = true;
- async_dump = true;
+ async_statdump = true;
}
void
dumprstStatsHandler(int sigtype)
{
async_event = true;
- async_dumpreset = true;
+ async_statdump = true;
+ async_statreset = true;
}
/// Exit signal handler.
@@ -110,12 +72,7 @@ exitNowHandler(int sigtype)
void
abortHandler(int sigtype)
{
- cerr << "Program aborted at cycle " << curTick << endl;
-
-#if TRACING_ON
- // dump trace buffer, if there is one
- Trace::theLog.dump(cerr);
-#endif
+ ccprintf(cerr, "Program aborted at cycle %d\n", curTick);
}
int
@@ -163,310 +120,3 @@ main(int argc, char **argv)
// clean up Python intepreter.
Py_Finalize();
}
-
-
-void
-setOutputDir(const string &dir)
-{
- simout.setDirectory(dir);
-}
-
-
-IniFile inifile;
-
-SimObject *
-createSimObject(const string &name)
-{
- return SimObjectClass::createObject(inifile, name);
-}
-
-
-/**
- * Pointer to the Python function that maps names to SimObjects.
- */
-PyObject *resolveFunc = NULL;
-
-/**
- * Convert a pointer to the Python object that SWIG wraps around a C++
- * SimObject pointer back to the actual C++ pointer. See main.i.
- */
-extern "C" SimObject *convertSwigSimObjectPtr(PyObject *);
-
-
-SimObject *
-resolveSimObject(const string &name)
-{
- PyObject *pyPtr = PyEval_CallFunction(resolveFunc, "(s)", name.c_str());
- if (pyPtr == NULL) {
- PyErr_Print();
- panic("resolveSimObject: failure on call to Python for %s", name);
- }
-
- SimObject *simObj = convertSwigSimObjectPtr(pyPtr);
- if (simObj == NULL)
- panic("resolveSimObject: failure on pointer conversion for %s", name);
-
- return simObj;
-}
-
-
-/**
- * Load config.ini into C++ database. Exported to Python via SWIG;
- * invoked from m5.instantiate().
- */
-void
-loadIniFile(PyObject *_resolveFunc)
-{
- resolveFunc = _resolveFunc;
- configStream = simout.find("config.out");
-
- // The configuration database is now complete; start processing it.
- inifile.load(simout.resolve("config.ini"));
-
- // Initialize statistics database
- Stats::InitSimStats();
-}
-
-
-/**
- * Look up a MemObject port. Helper function for connectPorts().
- */
-Port *
-lookupPort(SimObject *so, const std::string &name, int i)
-{
- MemObject *mo = dynamic_cast<MemObject *>(so);
- if (mo == NULL) {
- warn("error casting SimObject %s to MemObject", so->name());
- return NULL;
- }
-
- Port *p = mo->getPort(name, i);
- if (p == NULL)
- warn("error looking up port %s on object %s", name, so->name());
- return p;
-}
-
-
-/**
- * Connect the described MemObject ports. Called from Python via SWIG.
- */
-int
-connectPorts(SimObject *o1, const std::string &name1, int i1,
- SimObject *o2, const std::string &name2, int i2)
-{
- Port *p1 = lookupPort(o1, name1, i1);
- Port *p2 = lookupPort(o2, name2, i2);
-
- if (p1 == NULL || p2 == NULL) {
- warn("connectPorts: port lookup error");
- return 0;
- }
-
- p1->setPeer(p2);
- p2->setPeer(p1);
-
- return 1;
-}
-
-/**
- * Do final initialization steps after object construction but before
- * start of simulation.
- */
-void
-finalInit()
-{
- // Parse and check all non-config-hierarchy parameters.
- ParamContext::parseAllContexts(inifile);
- ParamContext::checkAllContexts();
-
- // Echo all parameter settings to stats file as well.
- ParamContext::showAllContexts(*configStream);
-
- // Do a second pass to finish initializing the sim objects
- SimObject::initAll();
-
- // Restore checkpointed state, if any.
-#if 0
- configHierarchy.unserializeSimObjects();
-#endif
-
- SimObject::regAllStats();
-
- // Check to make sure that the stats package is properly initialized
- Stats::check();
-
- // Reset to put the stats in a consistent state.
- Stats::reset();
-
- SimStartup();
-}
-
-
-/** Simulate for num_cycles additional cycles. If num_cycles is -1
- * (the default), do not limit simulation; some other event must
- * terminate the loop. Exported to Python via SWIG.
- * @return The SimLoopExitEvent that caused the loop to exit.
- */
-SimLoopExitEvent *
-simulate(Tick num_cycles = MaxTick)
-{
- warn("Entering event queue @ %d. Starting simulation...\n", curTick);
-
- 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;
-
- Event *limit_event = schedExitSimLoop("simulate() limit reached",
- num_cycles);
-
- while (1) {
- // there should always be at least one event (the SimLoopExitEvent
- // we just scheduled) in the queue
- assert(!mainEventQueue.empty());
- assert(curTick <= mainEventQueue.nextTick() &&
- "event scheduled in the past");
-
- // forward current cycle to the time of the first event on the
- // queue
- curTick = mainEventQueue.nextTick();
- Event *exit_event = mainEventQueue.serviceOne();
- if (exit_event != NULL) {
- // hit some kind of exit event; return to Python
- // event must be subclass of SimLoopExitEvent...
- SimLoopExitEvent *se_event = dynamic_cast<SimLoopExitEvent *>(exit_event);
- if (se_event == NULL)
- panic("Bogus exit event class!");
-
- // if we didn't hit limit_event, delete it
- if (se_event != limit_event) {
- assert(limit_event->scheduled());
- limit_event->deschedule();
- delete limit_event;
- }
-
- return se_event;
- }
-
- if (async_event) {
- async_event = false;
- if (async_dump) {
- async_dump = false;
-
- using namespace Stats;
- SetupEvent(Dump, curTick);
- }
-
- if (async_dumpreset) {
- async_dumpreset = false;
-
- using namespace Stats;
- SetupEvent(Dump | Reset, curTick);
- }
-
- if (async_exit) {
- async_exit = false;
- exitSimLoop("user interrupt received");
- }
-
- if (async_io || async_alarm) {
- async_io = false;
- async_alarm = false;
- pollQueue.service();
- }
- }
- }
-
- // not reached... only exit is return on SimLoopExitEvent
-}
-
-Event *
-createCountedDrain()
-{
- return new CountedDrainEvent();
-}
-
-void
-cleanupCountedDrain(Event *counted_drain)
-{
- CountedDrainEvent *event =
- dynamic_cast<CountedDrainEvent *>(counted_drain);
- if (event == NULL) {
- fatal("Called cleanupCountedDrain() on an event that was not "
- "a CountedDrainEvent.");
- }
- assert(event->getCount() == 0);
- delete event;
-}
-
-void
-serializeAll(const std::string &cpt_dir)
-{
- Serializable::serializeAll(cpt_dir);
-}
-
-void
-unserializeAll(const std::string &cpt_dir)
-{
- Serializable::unserializeAll(cpt_dir);
-}
-
-/**
- * Queue of C++ callbacks to invoke on simulator exit.
- */
-CallbackQueue&
-exitCallbacks()
-{
- static CallbackQueue theQueue;
- return theQueue;
-}
-
-/**
- * Register an exit callback.
- */
-void
-registerExitCallback(Callback *callback)
-{
- exitCallbacks().add(callback);
-}
-
-BaseCPU *
-convertToBaseCPUPtr(SimObject *obj)
-{
- BaseCPU *ptr = dynamic_cast<BaseCPU *>(obj);
-
- if (ptr == NULL)
- warn("Casting to BaseCPU pointer failed");
- return ptr;
-}
-
-System *
-convertToSystemPtr(SimObject *obj)
-{
- System *ptr = dynamic_cast<System *>(obj);
-
- if (ptr == NULL)
- warn("Casting to System pointer failed");
- return ptr;
-}
-
-
-/**
- * Do C++ simulator exit processing. Exported to SWIG to be invoked
- * when simulator terminates via Python's atexit mechanism.
- */
-void
-doExitCleanup()
-{
- exitCallbacks().process();
- exitCallbacks().clear();
-
- cout.flush();
-
- ParamContext::cleanupAllContexts();
-
- // print simulation stats
- Stats::DumpNow();
-}
diff --git a/src/sim/param.cc b/src/sim/param.cc
index 5cc69b161..51d389f5a 100644
--- a/src/sim/param.cc
+++ b/src/sim/param.cc
@@ -583,30 +583,10 @@ SimObjectBaseParam::parse(const string &s, vector<SimObject *>&value)
//
////////////////////////////////////////////////////////////////////////
-list<ParamContext *> *ParamContext::ctxList = NULL;
-
-ParamContext::ParamContext(const string &_iniSection, InitPhase _initPhase)
+ParamContext::ParamContext(const string &_iniSection)
: iniFilePtr(NULL), // initialized on call to parseParams()
- iniSection(_iniSection), paramList(NULL),
- initPhase(_initPhase)
-{
- // Put this context on global list for initialization
- if (initPhase != NoAutoInit) {
- if (ctxList == NULL)
- ctxList = new list<ParamContext *>();
-
- // keep list sorted by ascending initPhase values
- list<ParamContext *>::iterator i = ctxList->begin();
- list<ParamContext *>::iterator end = ctxList->end();
- for (; i != end; ++i) {
- if (initPhase <= (*i)->initPhase) {
- // found where we want to insert
- break;
- }
- }
- // (fall through case: insert at end)
- ctxList->insert(i, this);
- }
+ iniSection(_iniSection), paramList(NULL)
+{
}
@@ -695,89 +675,6 @@ ParamContext::printErrorProlog(ostream &os)
os << "Parameter error in section [" << iniSection << "]: " << endl;
}
-//
-// static method: call parseParams() on all registered contexts
-//
-void
-ParamContext::parseAllContexts(IniFile &iniFile)
-{
- list<ParamContext *>::iterator iter;
-
- for (iter = ctxList->begin(); iter != ctxList->end(); ++iter) {
- ParamContext *pc = *iter;
-
- pc->parseParams(iniFile);
- }
-}
-
-
-//
-// static method: call checkParams() on all registered contexts
-//
-void
-ParamContext::checkAllContexts()
-{
- list<ParamContext *>::iterator iter;
-
- for (iter = ctxList->begin(); iter != ctxList->end(); ++iter) {
- ParamContext *pc = *iter;
-
- pc->checkParams();
- }
-}
-
-
-//
-// static method: call showParams() on all registered contexts
-//
-void
-ParamContext::showAllContexts(ostream &os)
-{
- list<ParamContext *>::iterator iter;
-
- for (iter = ctxList->begin(); iter != ctxList->end(); ++iter) {
- ParamContext *pc = *iter;
-
- os << "[" << pc->iniSection << "]" << endl;
- pc->showParams(os);
- os << endl;
- }
-}
-
-
-//
-// static method: call cleanup() on all registered contexts
-//
-void
-ParamContext::cleanupAllContexts()
-{
- list<ParamContext *>::iterator iter;
-
- for (iter = ctxList->begin(); iter != ctxList->end(); ++iter) {
- ParamContext *pc = *iter;
-
- pc->cleanup();
- }
-}
-
-
-//
-// static method: call describeParams() on all registered contexts
-//
-void
-ParamContext::describeAllContexts(ostream &os)
-{
- list<ParamContext *>::iterator iter;
-
- for (iter = ctxList->begin(); iter != ctxList->end(); ++iter) {
- ParamContext *pc = *iter;
-
- os << "[" << pc->iniSection << "]\n";
- pc->describeParams(os);
- os << endl;
- }
-}
-
void
parseTime(const std::vector<int> &time, struct tm *tm)
{
diff --git a/src/sim/param.hh b/src/sim/param.hh
index 8a4670e27..dff0fa72d 100644
--- a/src/sim/param.hh
+++ b/src/sim/param.hh
@@ -50,12 +50,6 @@ class SimObject;
//
class ParamContext : protected StartupCallback
{
- private:
-
- // static list of all ParamContext objects, built as a side effect
- // of the ParamContext constructor
- static std::list<ParamContext *> *ctxList;
-
protected:
// .ini file (database) for parameter lookup... initialized on call
@@ -78,31 +72,10 @@ class ParamContext : protected StartupCallback
public:
- /// Initialization phases for ParamContext objects.
- enum InitPhase {
- NoAutoInit = -1, ///< Don't initialize at all... params
- /// will be parsed later (used by
- /// SimObjectBuilder, which parses
- /// params in SimObject::create().
- OutputInitPhase = 0, ///< Output stream initialization
- TraceInitPhase = 1, ///< Trace context initialization:
- /// depends on output streams, but
- /// needs to come before others so we
- /// can use tracing in other
- /// ParamContext init code
- StatsInitPhase = 2, ///< Stats output initialization
- DefaultInitPhase = 3 ///< Everything else
- };
-
- /// Records the initialization phase for this ParamContext.
- InitPhase initPhase;
-
/// Constructor.
/// @param _iniSection Name of .ini section corresponding to this context.
/// @param _initPhase Initialization phase (see InitPhase).
- ParamContext(const std::string &_iniSection,
- InitPhase _initPhase = DefaultInitPhase);
-
+ ParamContext(const std::string &_iniSection);
virtual ~ParamContext() {}
// add a parameter to the context... called from the parameter
@@ -135,24 +108,6 @@ class ParamContext : protected StartupCallback
// generate the name for this instance of this context (used as a
// prefix to create unique names in resolveSimObject()
virtual const std::string &getInstanceName() { return iniSection; }
-
- // Parse all parameters registered with all ParamContext objects.
- static void parseAllContexts(IniFile &iniFile);
-
- // Check all parameters registered with all ParamContext objects.
- // (calls checkParams() on each)
- static void checkAllContexts();
-
- // Print all parameter values on indicated ostream.
- static void showAllContexts(std::ostream &os);
-
- // Clean up all registered ParamContext objects. (calls cleanup()
- // on each)
- static void cleanupAllContexts();
-
- // print descriptions of all parameters registered with all
- // ParamContext objects
- static void describeAllContexts(std::ostream &os);
};
diff --git a/src/sim/process.cc b/src/sim/process.cc
index e5d868115..2b283c9d1 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -60,6 +60,8 @@
#include "arch/sparc/solaris/process.hh"
#elif THE_ISA == MIPS_ISA
#include "arch/mips/linux/process.hh"
+#elif THE_ISA == X86_ISA
+#include "arch/x86/linux/process.hh"
#else
#error "THE_ISA not set"
#endif
@@ -300,24 +302,6 @@ DEFINE_SIM_OBJECT_CLASS_NAME("Process", Process)
////////////////////////////////////////////////////////////////////////
-void
-copyStringArray(vector<string> &strings, Addr array_ptr, Addr data_ptr,
- TranslatingPort* memPort)
-{
- Addr data_ptr_swap;
- for (int i = 0; i < strings.size(); ++i) {
- data_ptr_swap = htog(data_ptr);
- memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr_swap, sizeof(Addr));
- memPort->writeString(data_ptr, strings[i].c_str());
- array_ptr += sizeof(Addr);
- data_ptr += strings[i].size() + 1;
- }
- // add NULL terminator
- data_ptr = 0;
-
- memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(Addr));
-}
-
LiveProcess::LiveProcess(const string &nm, ObjectFile *_objFile,
System *_system,
int stdin_fd, int stdout_fd, int stderr_fd,
@@ -475,14 +459,23 @@ LiveProcess::create(const std::string &nm, System *system, int stdin_fd,
fatal("Unknown/unsupported operating system.");
}
#elif THE_ISA == SPARC_ISA
- if (objFile->getArch() != ObjectFile::SPARC)
+ if (objFile->getArch() != ObjectFile::SPARC64 && objFile->getArch() != ObjectFile::SPARC32)
fatal("Object file architecture does not match compiled ISA (SPARC).");
switch (objFile->getOpSys()) {
case ObjectFile::Linux:
- process = new SparcLinuxProcess(nm, objFile, system,
- stdin_fd, stdout_fd, stderr_fd,
- argv, envp, cwd,
- _uid, _euid, _gid, _egid, _pid, _ppid);
+ if (objFile->getArch() == ObjectFile::SPARC64) {
+ process = new Sparc64LinuxProcess(nm, objFile, system,
+ stdin_fd, stdout_fd, stderr_fd,
+ argv, envp, cwd,
+ _uid, _euid, _gid,
+ _egid, _pid, _ppid);
+ } else {
+ process = new Sparc32LinuxProcess(nm, objFile, system,
+ stdin_fd, stdout_fd, stderr_fd,
+ argv, envp, cwd,
+ _uid, _euid, _gid,
+ _egid, _pid, _ppid);
+ }
break;
@@ -495,6 +488,20 @@ LiveProcess::create(const std::string &nm, System *system, int stdin_fd,
default:
fatal("Unknown/unsupported operating system.");
}
+#elif THE_ISA == X86_ISA
+ if (objFile->getArch() != ObjectFile::X86)
+ fatal("Object file architecture does not match compiled ISA (x86).");
+ switch (objFile->getOpSys()) {
+ case ObjectFile::Linux:
+ process = new X86LinuxProcess(nm, objFile, system,
+ stdin_fd, stdout_fd, stderr_fd,
+ argv, envp, cwd,
+ _uid, _euid, _gid,
+ _egid, _pid, _ppid);
+ break;
+ default:
+ fatal("Unknown/unsupported operating system.");
+ }
#elif THE_ISA == MIPS_ISA
if (objFile->getArch() != ObjectFile::Mips)
fatal("Object file architecture does not match compiled ISA (MIPS).");
diff --git a/src/sim/process.hh b/src/sim/process.hh
index bf65c6e06..dd64fa607 100644
--- a/src/sim/process.hh
+++ b/src/sim/process.hh
@@ -41,9 +41,12 @@
#if !FULL_SYSTEM
+#include <string>
#include <vector>
#include "base/statistics.hh"
+#include "mem/translating_port.hh"
+#include "sim/host.hh"
#include "sim/sim_object.hh"
class ThreadContext;
@@ -57,9 +60,27 @@ namespace TheISA
class RemoteGDB;
}
+//This needs to be templated for cases where 32 bit pointers are needed.
+template<class AddrType>
void
-copyStringArray(std::vector<std::string> &strings, Addr array_ptr,
- Addr data_ptr, TranslatingPort* memPort);
+copyStringArray(std::vector<std::string> &strings,
+ AddrType array_ptr, AddrType data_ptr,
+ TranslatingPort* memPort)
+{
+ AddrType data_ptr_swap;
+ for (int i = 0; i < strings.size(); ++i) {
+ data_ptr_swap = htog(data_ptr);
+ memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr_swap,
+ sizeof(AddrType));
+ memPort->writeString(data_ptr, strings[i].c_str());
+ array_ptr += sizeof(AddrType);
+ data_ptr += strings[i].size() + 1;
+ }
+ // add NULL terminator
+ data_ptr = 0;
+
+ memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(AddrType));
+}
class Process : public SimObject
{
diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc
index 4a8c0eb66..56a779674 100644
--- a/src/sim/pseudo_inst.cc
+++ b/src/sim/pseudo_inst.cc
@@ -32,6 +32,7 @@
#include <fcntl.h>
#include <unistd.h>
+#include <fstream>
#include <string>
#include "arch/vtophys.hh"
@@ -54,7 +55,7 @@ using namespace std;
using namespace Stats;
using namespace TheISA;
-namespace AlphaPseudo
+namespace PseudoInst
{
void
arm(ThreadContext *tc)
@@ -199,8 +200,7 @@ namespace AlphaPseudo
Tick when = curTick + delay * Clock::Int::ns;
Tick repeat = period * Clock::Int::ns;
- using namespace Stats;
- SetupEvent(Reset, when, repeat);
+ Stats::StatEvent(false, true, when, repeat);
}
void
@@ -213,8 +213,7 @@ namespace AlphaPseudo
Tick when = curTick + delay * Clock::Int::ns;
Tick repeat = period * Clock::Int::ns;
- using namespace Stats;
- SetupEvent(Dump, when, repeat);
+ Stats::StatEvent(true, false, when, repeat);
}
void
@@ -254,8 +253,7 @@ namespace AlphaPseudo
Tick when = curTick + delay * Clock::Int::ns;
Tick repeat = period * Clock::Int::ns;
- using namespace Stats;
- SetupEvent(Dump|Reset, when, repeat);
+ Stats::StatEvent(true, true, when, repeat);
}
void
diff --git a/src/sim/pseudo_inst.hh b/src/sim/pseudo_inst.hh
index bc71a7e64..93021abad 100644
--- a/src/sim/pseudo_inst.hh
+++ b/src/sim/pseudo_inst.hh
@@ -33,7 +33,7 @@ class ThreadContext;
//We need the "Tick" and "Addr" data types from here
#include "sim/host.hh"
-namespace AlphaPseudo
+namespace PseudoInst
{
/**
* @todo these externs are only here for a hack in fullCPU::takeOver...
diff --git a/src/sim/root.cc b/src/sim/root.cc
index 565b57269..f4743af0a 100644
--- a/src/sim/root.cc
+++ b/src/sim/root.cc
@@ -36,91 +36,24 @@
#include <vector>
#include "base/misc.hh"
-#include "base/output.hh"
#include "sim/builder.hh"
-#include "sim/host.hh"
-#include "sim/sim_events.hh"
-#include "sim/sim_exit.hh"
#include "sim/sim_object.hh"
-#include "sim/root.hh"
-
-using namespace std;
-
-Tick curTick = 0;
-ostream *outputStream;
-ostream *configStream;
-
-/// The simulated frequency of curTick. (This is only here for a short time)
-Tick ticksPerSecond;
-
-namespace Clock {
-/// The simulated frequency of curTick. (In ticks per second)
-Tick Frequency;
-
-namespace Float {
-double s;
-double ms;
-double us;
-double ns;
-double ps;
-
-double Hz;
-double kHz;
-double MHz;
-double GHZ;
-/* namespace Float */ }
-
-namespace Int {
-Tick s;
-Tick ms;
-Tick us;
-Tick ns;
-Tick ps;
-/* namespace Float */ }
-
-/* namespace Clock */ }
-
// Dummy Object
-class Root : public SimObject
+struct Root : public SimObject
{
- private:
- Tick max_tick;
- Tick progress_interval;
-
- public:
- Root(const std::string &name, Tick maxtick, Tick pi)
- : SimObject(name), max_tick(maxtick), progress_interval(pi)
- {}
-
- virtual void startup();
+ Root(const std::string &name) : SimObject(name) {}
};
-void
-Root::startup()
-{
- if (max_tick != 0)
- schedExitSimLoop("reached maximum cycle count", curTick + max_tick);
-
- if (progress_interval != 0)
- new ProgressEvent(&mainEventQueue, progress_interval);
-}
-
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Root)
- Param<Tick> clock;
- Param<Tick> max_tick;
- Param<Tick> progress_interval;
- Param<string> output_file;
+ Param<int> dummy; // needed below
END_DECLARE_SIM_OBJECT_PARAMS(Root)
BEGIN_INIT_SIM_OBJECT_PARAMS(Root)
- INIT_PARAM(clock, "tick frequency"),
- INIT_PARAM(max_tick, "maximum simulation time"),
- INIT_PARAM(progress_interval, "print a progress message"),
- INIT_PARAM(output_file, "file to dump simulator output to")
+ INIT_PARAM(dummy, "") // All SimObjects must have params
END_INIT_SIM_OBJECT_PARAMS(Root)
@@ -132,29 +65,7 @@ CREATE_SIM_OBJECT(Root)
created = true;
- outputStream = simout.find(output_file);
- Root *root = new Root(getInstanceName(), max_tick, progress_interval);
-
- using namespace Clock;
- Frequency = clock;
- Float::s = static_cast<double>(Frequency);
- Float::ms = Float::s / 1.0e3;
- Float::us = Float::s / 1.0e6;
- Float::ns = Float::s / 1.0e9;
- Float::ps = Float::s / 1.0e12;
-
- Float::Hz = 1.0 / Float::s;
- Float::kHz = 1.0 / Float::ms;
- Float::MHz = 1.0 / Float::us;
- Float::GHZ = 1.0 / Float::ns;
-
- Int::s = Frequency;
- Int::ms = Int::s / 1000;
- Int::us = Int::ms / 1000;
- Int::ns = Int::us / 1000;
- Int::ps = Int::ns / 1000;
-
- return root;
+ return new Root(getInstanceName());
}
REGISTER_SIM_OBJECT("Root", Root)
diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc
index 1ff16976d..d32bb1142 100644
--- a/src/sim/serialize.cc
+++ b/src/sim/serialize.cc
@@ -407,36 +407,3 @@ Checkpoint::sectionExists(const std::string &section)
{
return db->sectionExists(section);
}
-
-/** Hacked stat reset event */
-
-class StatresetParamContext : public ParamContext
-{
- public:
- StatresetParamContext(const string &section);
- ~StatresetParamContext();
- void startup();
-};
-
-StatresetParamContext statParams("statsreset");
-
-Param<Tick> reset_cycle(&statParams, "reset_cycle",
- "Cycle to reset stats on", 0);
-
-StatresetParamContext::StatresetParamContext(const string &section)
- : ParamContext(section)
-{ }
-
-StatresetParamContext::~StatresetParamContext()
-{
-}
-
-void
-StatresetParamContext::startup()
-{
- if (reset_cycle > 0) {
- Stats::SetupEvent(Stats::Reset, curTick + reset_cycle, 0);
- cprintf("Stats reset event scheduled for %lli\n",
- curTick + reset_cycle);
- }
-}
diff --git a/src/sim/sim_events.cc b/src/sim/sim_events.cc
index 2ccc9dad2..a4457a11c 100644
--- a/src/sim/sim_events.cc
+++ b/src/sim/sim_events.cc
@@ -158,21 +158,3 @@ CheckSwapEvent::description()
{
return "check swap";
}
-
-//
-// handle progress event: print message and reschedule
-//
-void
-ProgressEvent::process()
-{
- DPRINTFN("ProgressEvent\n");
- // reschedule for next interval
- schedule(curTick + interval);
-}
-
-
-const char *
-ProgressEvent::description()
-{
- return "progress message";
-}
diff --git a/src/sim/sim_events.hh b/src/sim/sim_events.hh
index e1576b38c..94e2540b1 100644
--- a/src/sim/sim_events.hh
+++ b/src/sim/sim_events.hh
@@ -125,23 +125,4 @@ class CheckSwapEvent : public Event
virtual const char *description();
};
-//
-// Progress event: print out cycle every so often so we know we're
-// making forward progress.
-//
-class ProgressEvent : public Event
-{
- protected:
- Tick interval;
-
- public:
- ProgressEvent(EventQueue *q, Tick ival)
- : Event(q), interval(ival)
- { schedule(curTick + interval); }
-
- void process(); // process event
-
- virtual const char *description();
-};
-
#endif // __SIM_SIM_EVENTS_HH__
diff --git a/src/sim/sim_object.cc b/src/sim/sim_object.cc
index 8fc8fe58f..434fcffe6 100644
--- a/src/sim/sim_object.cc
+++ b/src/sim/sim_object.cc
@@ -56,10 +56,6 @@ using namespace std;
//
SimObject::SimObjectList SimObject::simObjectList;
-namespace Stats {
- extern ObjectMatch event_ignore;
-}
-
//
// SimObject constructor: used to maintain static simObjectList
//
@@ -70,7 +66,6 @@ SimObject::SimObject(Params *p)
doDebugBreak = false;
#endif
- doRecordEvent = !Stats::event_ignore.match(name());
simObjectList.push_back(this);
state = Running;
}
@@ -86,7 +81,6 @@ SimObject::SimObject(const string &_name)
doDebugBreak = false;
#endif
- doRecordEvent = !Stats::event_ignore.match(name());
simObjectList.push_back(this);
state = Running;
}
@@ -245,8 +239,7 @@ debugObjectBreak(const char *objs)
void
SimObject::recordEvent(const std::string &stat)
{
- if (doRecordEvent)
- Stats::recordEvent(stat);
+ Stats::recordEvent(stat);
}
unsigned int
diff --git a/src/sim/sim_object.hh b/src/sim/sim_object.hh
index 93802e247..536e761e5 100644
--- a/src/sim/sim_object.hh
+++ b/src/sim/sim_object.hh
@@ -136,7 +136,6 @@ class SimObject : public Serializable, protected StartupCallback
#endif
public:
- bool doRecordEvent;
void recordEvent(const std::string &stat);
};
diff --git a/src/sim/simulate.cc b/src/sim/simulate.cc
new file mode 100644
index 000000000..55cbb50a9
--- /dev/null
+++ b/src/sim/simulate.cc
@@ -0,0 +1,121 @@
+/*
+ * 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: Nathan Binkert
+ * Steve Reinhardt
+ */
+
+#include "base/misc.hh"
+#include "base/pollevent.hh"
+#include "sim/stat_control.hh"
+#include "sim/async.hh"
+#include "sim/eventq.hh"
+#include "sim/host.hh"
+#include "sim/sim_events.hh"
+#include "sim/sim_exit.hh"
+#include "sim/simulate.hh"
+
+/** Simulate for num_cycles additional cycles. If num_cycles is -1
+ * (the default), do not limit simulation; some other event must
+ * terminate the loop. Exported to Python via SWIG.
+ * @return The SimLoopExitEvent that caused the loop to exit.
+ */
+SimLoopExitEvent *
+simulate(Tick num_cycles)
+{
+ warn("Entering event queue @ %d. Starting simulation...\n", curTick);
+
+ 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;
+
+ Event *limit_event;
+ limit_event = schedExitSimLoop("simulate() limit reached", num_cycles);
+
+ while (1) {
+ // there should always be at least one event (the SimLoopExitEvent
+ // we just scheduled) in the queue
+ assert(!mainEventQueue.empty());
+ assert(curTick <= mainEventQueue.nextTick() &&
+ "event scheduled in the past");
+
+ // forward current cycle to the time of the first event on the
+ // queue
+ curTick = mainEventQueue.nextTick();
+ Event *exit_event = mainEventQueue.serviceOne();
+ if (exit_event != NULL) {
+ // hit some kind of exit event; return to Python
+ // event must be subclass of SimLoopExitEvent...
+ SimLoopExitEvent *se_event;
+ se_event = dynamic_cast<SimLoopExitEvent *>(exit_event);
+
+ if (se_event == NULL)
+ panic("Bogus exit event class!");
+
+ // if we didn't hit limit_event, delete it
+ if (se_event != limit_event) {
+ assert(limit_event->scheduled());
+ limit_event->deschedule();
+ delete limit_event;
+ }
+
+ return se_event;
+ }
+
+ if (async_event) {
+ async_event = false;
+ if (async_statdump || async_statreset) {
+ async_statdump = false;
+ async_statreset = false;
+
+ Stats::StatEvent(async_statdump, async_statreset);
+ }
+
+ if (async_exit) {
+ async_exit = false;
+ exitSimLoop("user interrupt received");
+ }
+
+ if (async_io || async_alarm) {
+ async_io = false;
+ async_alarm = false;
+ pollQueue.service();
+ }
+
+ if (async_exception) {
+ async_exception = false;
+ return NULL;
+ }
+ }
+ }
+
+ // not reached... only exit is return on SimLoopExitEvent
+}
+
diff --git a/src/sim/simulate.hh b/src/sim/simulate.hh
new file mode 100644
index 000000000..139bddb82
--- /dev/null
+++ b/src/sim/simulate.hh
@@ -0,0 +1,35 @@
+/*
+ * 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: Nathan Binkert
+ * Steve Reinhardt
+ */
+
+#include "sim/host.hh"
+#include "sim/sim_events.hh"
+
+SimLoopExitEvent *simulate(Tick num_cycles = MaxTick);
diff --git a/src/sim/stat_control.cc b/src/sim/stat_control.cc
index 3fad8beb5..228c83898 100644
--- a/src/sim/stat_control.cc
+++ b/src/sim/stat_control.cc
@@ -38,14 +38,9 @@
#include "base/callback.hh"
#include "base/hostinfo.hh"
#include "base/statistics.hh"
-#include "base/str.hh"
#include "base/time.hh"
-#include "base/stats/output.hh"
#include "cpu/base.hh"
#include "sim/eventq.hh"
-#include "sim/sim_object.hh"
-#include "sim/stat_control.hh"
-#include "sim/root.hh"
using namespace std;
@@ -63,11 +58,9 @@ namespace Stats {
Time statTime(true);
Tick startTick;
-Tick lastDump(0);
-class SimTicksReset : public Callback
+struct SimTicksReset : public Callback
{
- public:
void process()
{
statTime.set();
@@ -92,7 +85,7 @@ statElapsedTicks()
SimTicksReset simTicksReset;
void
-InitSimStats()
+initSimStats()
{
simInsts
.functor(BaseCPU::numSimulatedInstructions)
@@ -153,81 +146,40 @@ InitSimStats()
registerResetCallback(&simTicksReset);
}
-class StatEvent : public Event
+class _StatEvent : public Event
{
- protected:
- int flags;
+ private:
+ bool dump;
+ bool reset;
Tick repeat;
public:
- StatEvent(EventQueue *queue, int _flags, Tick _when, Tick _repeat);
- virtual void process();
- virtual const char *description();
-};
-
-StatEvent::StatEvent(EventQueue *queue, int _flags, Tick _when, Tick _repeat)
- : Event(queue, Stat_Event_Pri),
- flags(_flags), repeat(_repeat)
-{
- setFlags(AutoDelete);
- schedule(_when);
-}
-
-const char *
-StatEvent::description()
-{
- return "Statistics dump and/or reset";
-}
-
-void
-StatEvent::process()
-{
- if (flags & Stats::Dump)
- DumpNow();
-
- if (flags & Stats::Reset) {
- cprintf("Resetting stats at cycle %d!\n", curTick);
- reset();
+ _StatEvent(bool _dump, bool _reset, Tick _when, Tick _repeat)
+ : Event(&mainEventQueue, Stat_Event_Pri), dump(_dump), reset(_reset),
+ repeat(_repeat)
+ {
+ setFlags(AutoDelete);
+ schedule(_when);
}
- if (repeat)
- schedule(curTick + repeat);
-}
+ virtual void
+ process()
+ {
+ if (dump)
+ Stats::dump();
-list<Output *> OutputList;
+ if (reset)
+ Stats::reset();
-void
-DumpNow()
-{
- assert(lastDump <= curTick);
- if (lastDump == curTick)
- return;
- lastDump = curTick;
-
- list<Output *>::iterator i = OutputList.begin();
- list<Output *>::iterator end = OutputList.end();
- for (; i != end; ++i) {
- Output *output = *i;
- if (!output->valid())
- continue;
-
- output->output();
+ if (repeat)
+ new _StatEvent(dump, reset, curTick + repeat, repeat);
}
-}
+};
void
-SetupEvent(int flags, Tick when, Tick repeat, EventQueue *queue)
+StatEvent(bool dump, bool reset, Tick when, Tick repeat)
{
- if (queue == NULL)
- queue = &mainEventQueue;
-
- new StatEvent(queue, flags, when, repeat);
+ new _StatEvent(dump, reset, when, repeat);
}
/* namespace Stats */ }
-
-void debugDumpStats()
-{
- Stats::DumpNow();
-}
-
diff --git a/src/sim/stat_control.hh b/src/sim/stat_control.hh
index 67f7cc491..1efa2554e 100644
--- a/src/sim/stat_control.hh
+++ b/src/sim/stat_control.hh
@@ -31,25 +31,10 @@
#ifndef __SIM_STAT_CONTROL_HH__
#define __SIM_STAT_CONTROL_HH__
-#include <fstream>
-#include <list>
-
-class EventQueue;
-
namespace Stats {
-enum {
- Reset = 0x1,
- Dump = 0x2
-};
-
-class Output;
-extern std::list<Output *> OutputList;
-
-void DumpNow();
-void SetupEvent(int flags, Tick when, Tick repeat = 0, EventQueue *queue = NULL);
-
-void InitSimStats();
+void initSimStats();
+void StatEvent(bool dump, bool reset, Tick when = curTick, Tick repeat = 0);
/* namespace Stats */ }
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index ab44c0a35..876f39e99 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -184,6 +184,39 @@ lseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
SyscallReturn
+_llseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
+{
+ int fd = p->sim_fd(tc->getSyscallArg(0));
+ uint64_t offset_high = tc->getSyscallArg(1);
+ uint32_t offset_low = tc->getSyscallArg(2);
+ Addr result_ptr = tc->getSyscallArg(3);
+ int whence = tc->getSyscallArg(4);
+
+ uint64_t offset = (offset_high << 32) | offset_low;
+
+ uint64_t result = lseek(fd, offset, whence);
+ result = TheISA::htog(result);
+
+ if (result == (off_t)-1) {
+ //The seek failed.
+ return -errno;
+ } else {
+ //The seek succeeded.
+ //Copy "result" to "result_ptr"
+ //XXX We'll assume that the size of loff_t is 64 bits on the
+ //target platform
+ BufferArg result_buf(result_ptr, sizeof(result));
+ memcpy(result_buf.bufferPtr(), &result, sizeof(result));
+ result_buf.copyOut(tc->getMemPort());
+ return 0;
+ }
+
+
+ return (result == (off_t)-1) ? -errno : result;
+}
+
+
+SyscallReturn
munmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
// given that we don't really implement mmap, munmap is really easy
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index 27356c9f1..a3d95b8ec 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -211,6 +211,10 @@ SyscallReturn writeFunc(SyscallDesc *desc, int num,
SyscallReturn lseekFunc(SyscallDesc *desc, int num,
LiveProcess *p, ThreadContext *tc);
+/// Target _llseek() handler.
+SyscallReturn _llseekFunc(SyscallDesc *desc, int num,
+ LiveProcess *p, ThreadContext *tc);
+
/// Target munmap() handler.
SyscallReturn munmapFunc(SyscallDesc *desc, int num,
LiveProcess *p, ThreadContext *tc);
@@ -349,6 +353,8 @@ template <typename target_stat, typename host_stat>
static void
convertStatBuf(target_stat &tgt, host_stat *host, bool fakeTTY = false)
{
+ using namespace TheISA;
+
if (fakeTTY)
tgt->st_dev = 0xA;
else
@@ -377,7 +383,9 @@ convertStatBuf(target_stat &tgt, host_stat *host, bool fakeTTY = false)
tgt->st_mtimeX = htog(tgt->st_mtimeX);
tgt->st_ctimeX = host->st_ctime;
tgt->st_ctimeX = htog(tgt->st_ctimeX);
- tgt->st_blksize = host->st_blksize;
+ // Force the block size to be 8k. This helps to ensure buffered io works
+ // consistently across different hosts.
+ tgt->st_blksize = 0x2000;
tgt->st_blksize = htog(tgt->st_blksize);
tgt->st_blocks = host->st_blocks;
tgt->st_blocks = htog(tgt->st_blocks);
@@ -389,6 +397,8 @@ template <typename target_stat, typename host_stat64>
static void
convertStat64Buf(target_stat &tgt, host_stat64 *host, bool fakeTTY = false)
{
+ using namespace TheISA;
+
convertStatBuf<target_stat, host_stat64>(tgt, host, fakeTTY);
#if defined(STAT_HAVE_NSEC)
tgt->st_atime_nsec = host->st_atime_nsec;
@@ -446,14 +456,14 @@ ioctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
}
switch (req) {
- case OS::TIOCISATTY:
- case OS::TIOCGETP:
- case OS::TIOCSETP:
- case OS::TIOCSETN:
- case OS::TIOCSETC:
- case OS::TIOCGETC:
- case OS::TIOCGETS:
- case OS::TIOCGETA:
+ case OS::TIOCISATTY_:
+ case OS::TIOCGETP_:
+ case OS::TIOCSETP_:
+ case OS::TIOCSETN_:
+ case OS::TIOCSETC_:
+ case OS::TIOCGETC_:
+ case OS::TIOCGETS_:
+ case OS::TIOCGETA_:
return -ENOTTY;
default:
diff --git a/src/sim/system.cc b/src/sim/system.cc
index f6febe4b1..2d0eaaf5b 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -33,6 +33,7 @@
#include "arch/isa_traits.hh"
#include "arch/remote_gdb.hh"
+#include "arch/utility.hh"
#include "base/loader/object_file.hh"
#include "base/loader/symtab.hh"
#include "base/trace.hh"
@@ -142,6 +143,7 @@ System::~System()
}
int rgdb_wait = -1;
+int rgdb_enable = true;
void
System::setMemoryMode(MemoryMode mode)
@@ -152,7 +154,9 @@ System::setMemoryMode(MemoryMode mode)
bool System::breakpoint()
{
- return remoteGDB[0]->breakpoint();
+ if (remoteGDB.size())
+ return remoteGDB[0]->breakpoint();
+ return false;
}
int
@@ -174,22 +178,24 @@ System::registerThreadContext(ThreadContext *tc, int id)
threadContexts[id] = tc;
numcpus++;
- RemoteGDB *rgdb = new RemoteGDB(this, tc);
- GDBListener *gdbl = new GDBListener(rgdb, 7000 + id);
- gdbl->listen();
- /**
- * Uncommenting this line waits for a remote debugger to connect
- * to the simulator before continuing.
- */
- if (rgdb_wait != -1 && rgdb_wait == id)
- gdbl->accept();
+ if (rgdb_enable) {
+ RemoteGDB *rgdb = new RemoteGDB(this, tc);
+ GDBListener *gdbl = new GDBListener(rgdb, 7000 + id);
+ gdbl->listen();
+ /**
+ * Uncommenting this line waits for a remote debugger to
+ * connect to the simulator before continuing.
+ */
+ if (rgdb_wait != -1 && rgdb_wait == id)
+ gdbl->accept();
+
+ if (remoteGDB.size() <= id) {
+ remoteGDB.resize(id + 1);
+ }
- if (remoteGDB.size() <= id) {
- remoteGDB.resize(id + 1);
+ remoteGDB[id] = rgdb;
}
- remoteGDB[id] = rgdb;
-
return id;
}
@@ -198,7 +204,7 @@ System::startup()
{
int i;
for (i = 0; i < threadContexts.size(); i++)
- threadContexts[i]->activate(0);
+ TheISA::startupCPU(threadContexts[i], i);
}
void
@@ -210,7 +216,8 @@ System::replaceThreadContext(ThreadContext *tc, int id)
}
threadContexts[id] = tc;
- remoteGDB[id]->replaceThreadContext(tc);
+ if (id < remoteGDB.size())
+ remoteGDB[id]->replaceThreadContext(tc);
}
#if !FULL_SYSTEM
diff --git a/src/unittest/Makefile b/src/unittest/Makefile
index e22b80b48..e6a621a9e 100644
--- a/src/unittest/Makefile
+++ b/src/unittest/Makefile
@@ -56,6 +56,9 @@ circletest: unittest/circletest.cc base/circlebuf.cc
cprintftest: unittest/cprintftest.cc base/cprintf.cc
$(CXX) $(CCFLAGS) -o $@ $^
+cprintftime: unittest/cprintftime.cc base/cprintf.cc
+ $(CXX) $(CCFLAGS) -o $@ $^
+
initest: unittest/initest.cc base/str.cc base/inifile.cc base/cprintf.cc
$(CXX) $(CCFLAGS) -o $@ $^
diff --git a/src/unittest/cprintftime.cc b/src/unittest/cprintftime.cc
new file mode 100644
index 000000000..f35e0aa25
--- /dev/null
+++ b/src/unittest/cprintftime.cc
@@ -0,0 +1,90 @@
+/*
+ * 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
+ */
+
+#include <iostream>
+#include <list>
+#include <string>
+#include <sstream>
+
+#include "base/cprintf.hh"
+
+using namespace std;
+
+volatile int stop = false;
+
+void
+handle_alarm(int signal)
+{
+ stop = true;
+}
+
+void
+do_test(int seconds)
+{
+ stop = false;
+ alarm(seconds);
+}
+
+int
+main()
+{
+ stringstream result;
+ int iterations = 0;
+
+ signal(SIGALRM, handle_alarm);
+
+ do_test(10);
+ while (!stop) {
+ stringstream result;
+ ccprintf(result,
+ "this is a %s of %d iterations %3.2f %#x\n",
+ "test", iterations, 51.934, &result);
+
+ iterations += 1;
+ }
+
+ cprintf("completed %d iterations of ccprintf in 10s, %f iterations/s\n",
+ iterations, iterations / 10.0);
+
+ do_test(10);
+ while (!stop) {
+ char result[1024];
+ sprintf(result,
+ "this is a %s of %d iterations %3.2f %#x\n",
+ "test", iterations, 51.934, &result);
+
+ iterations += 1;
+ }
+
+ cprintf("completed %d iterations of sprintf in 10s, %f iterations/s\n",
+ iterations, iterations / 10.0);
+
+ return 0;
+}