New directory structure:
- simulator source now in 'src' subdirectory
- imported files from 'ext' repository
- support building in arbitrary places, including
outside of the source tree. See comment at top
of SConstruct file for more details.
Regression tests are temporarily disabled; that
syetem needs more extensive revisions.
SConstruct:
Update for new directory structure.
Modify to support build trees that are not subdirectories
of the source tree. See comment at top of file for
more details.
Regression tests are temporarily disabled.
src/arch/SConscript:
src/arch/isa_parser.py:
src/python/SConscript:
Update for new directory structure.
--HG--
rename : build/SConstruct => SConstruct
rename : build/default_options/ALPHA_FS => build_opts/ALPHA_FS
rename : build/default_options/ALPHA_FS_TL => build_opts/ALPHA_FS_TL
rename : build/default_options/ALPHA_SE => build_opts/ALPHA_SE
rename : build/default_options/MIPS_SE => build_opts/MIPS_SE
rename : build/default_options/SPARC_SE => build_opts/SPARC_SE
rename : Doxyfile => src/Doxyfile
rename : SConscript => src/SConscript
rename : arch/SConscript => src/arch/SConscript
rename : arch/alpha/SConscript => src/arch/alpha/SConscript
rename : arch/alpha/aout_machdep.h => src/arch/alpha/aout_machdep.h
rename : arch/alpha/arguments.cc => src/arch/alpha/arguments.cc
rename : arch/alpha/arguments.hh => src/arch/alpha/arguments.hh
rename : arch/alpha/ecoff_machdep.h => src/arch/alpha/ecoff_machdep.h
rename : arch/alpha/ev5.cc => src/arch/alpha/ev5.cc
rename : arch/alpha/ev5.hh => src/arch/alpha/ev5.hh
rename : arch/alpha/faults.cc => src/arch/alpha/faults.cc
rename : arch/alpha/faults.hh => src/arch/alpha/faults.hh
rename : arch/alpha/freebsd/system.cc => src/arch/alpha/freebsd/system.cc
rename : arch/alpha/freebsd/system.hh => src/arch/alpha/freebsd/system.hh
rename : arch/alpha/isa/branch.isa => src/arch/alpha/isa/branch.isa
rename : arch/alpha/isa/decoder.isa => src/arch/alpha/isa/decoder.isa
rename : arch/alpha/isa/fp.isa => src/arch/alpha/isa/fp.isa
rename : arch/alpha/isa/int.isa => src/arch/alpha/isa/int.isa
rename : arch/alpha/isa/main.isa => src/arch/alpha/isa/main.isa
rename : arch/alpha/isa/mem.isa => src/arch/alpha/isa/mem.isa
rename : arch/alpha/isa/opcdec.isa => src/arch/alpha/isa/opcdec.isa
rename : arch/alpha/isa/pal.isa => src/arch/alpha/isa/pal.isa
rename : arch/alpha/isa/unimp.isa => src/arch/alpha/isa/unimp.isa
rename : arch/alpha/isa/unknown.isa => src/arch/alpha/isa/unknown.isa
rename : arch/alpha/isa/util.isa => src/arch/alpha/isa/util.isa
rename : arch/alpha/isa_traits.hh => src/arch/alpha/isa_traits.hh
rename : arch/alpha/linux/aligned.hh => src/arch/alpha/linux/aligned.hh
rename : arch/alpha/linux/hwrpb.hh => src/arch/alpha/linux/hwrpb.hh
rename : arch/alpha/linux/linux.cc => src/arch/alpha/linux/linux.cc
rename : arch/alpha/linux/linux.hh => src/arch/alpha/linux/linux.hh
rename : arch/alpha/linux/process.cc => src/arch/alpha/linux/process.cc
rename : arch/alpha/linux/process.hh => src/arch/alpha/linux/process.hh
rename : arch/alpha/linux/system.cc => src/arch/alpha/linux/system.cc
rename : arch/alpha/linux/system.hh => src/arch/alpha/linux/system.hh
rename : arch/alpha/linux/thread_info.hh => src/arch/alpha/linux/thread_info.hh
rename : arch/alpha/linux/threadinfo.hh => src/arch/alpha/linux/threadinfo.hh
rename : arch/alpha/osfpal.cc => src/arch/alpha/osfpal.cc
rename : arch/alpha/osfpal.hh => src/arch/alpha/osfpal.hh
rename : arch/alpha/process.cc => src/arch/alpha/process.cc
rename : arch/alpha/process.hh => src/arch/alpha/process.hh
rename : arch/alpha/regfile.hh => src/arch/alpha/regfile.hh
rename : arch/alpha/stacktrace.cc => src/arch/alpha/stacktrace.cc
rename : arch/alpha/stacktrace.hh => src/arch/alpha/stacktrace.hh
rename : arch/alpha/system.cc => src/arch/alpha/system.cc
rename : arch/alpha/system.hh => src/arch/alpha/system.hh
rename : arch/alpha/tlb.cc => src/arch/alpha/tlb.cc
rename : arch/alpha/tlb.hh => src/arch/alpha/tlb.hh
rename : arch/alpha/tru64/process.cc => src/arch/alpha/tru64/process.cc
rename : arch/alpha/tru64/process.hh => src/arch/alpha/tru64/process.hh
rename : arch/alpha/tru64/system.cc => src/arch/alpha/tru64/system.cc
rename : arch/alpha/tru64/system.hh => src/arch/alpha/tru64/system.hh
rename : arch/alpha/tru64/tru64.cc => src/arch/alpha/tru64/tru64.cc
rename : arch/alpha/tru64/tru64.hh => src/arch/alpha/tru64/tru64.hh
rename : arch/alpha/types.hh => src/arch/alpha/types.hh
rename : arch/alpha/utility.hh => src/arch/alpha/utility.hh
rename : arch/alpha/vtophys.cc => src/arch/alpha/vtophys.cc
rename : arch/alpha/vtophys.hh => src/arch/alpha/vtophys.hh
rename : arch/isa_parser.py => src/arch/isa_parser.py
rename : arch/isa_specific.hh => src/arch/isa_specific.hh
rename : arch/mips/SConscript => src/arch/mips/SConscript
rename : arch/mips/faults.cc => src/arch/mips/faults.cc
rename : arch/mips/faults.hh => src/arch/mips/faults.hh
rename : arch/mips/isa/base.isa => src/arch/mips/isa/base.isa
rename : arch/mips/isa/bitfields.isa => src/arch/mips/isa/bitfields.isa
rename : arch/mips/isa/decoder.isa => src/arch/mips/isa/decoder.isa
rename : arch/mips/isa/formats/basic.isa => src/arch/mips/isa/formats/basic.isa
rename : arch/mips/isa/formats/branch.isa => src/arch/mips/isa/formats/branch.isa
rename : arch/mips/isa/formats/formats.isa => src/arch/mips/isa/formats/formats.isa
rename : arch/mips/isa/formats/fp.isa => src/arch/mips/isa/formats/fp.isa
rename : arch/mips/isa/formats/int.isa => src/arch/mips/isa/formats/int.isa
rename : arch/mips/isa/formats/mem.isa => src/arch/mips/isa/formats/mem.isa
rename : arch/mips/isa/formats/noop.isa => src/arch/mips/isa/formats/noop.isa
rename : arch/mips/isa/formats/tlbop.isa => src/arch/mips/isa/formats/tlbop.isa
rename : arch/mips/isa/formats/trap.isa => src/arch/mips/isa/formats/trap.isa
rename : arch/mips/isa/formats/unimp.isa => src/arch/mips/isa/formats/unimp.isa
rename : arch/mips/isa/formats/unknown.isa => src/arch/mips/isa/formats/unknown.isa
rename : arch/mips/isa/formats/util.isa => src/arch/mips/isa/formats/util.isa
rename : arch/mips/isa/includes.isa => src/arch/mips/isa/includes.isa
rename : arch/mips/isa/main.isa => src/arch/mips/isa/main.isa
rename : arch/mips/isa/operands.isa => src/arch/mips/isa/operands.isa
rename : arch/mips/isa_traits.cc => src/arch/mips/isa_traits.cc
rename : arch/mips/isa_traits.hh => src/arch/mips/isa_traits.hh
rename : arch/mips/linux/linux.cc => src/arch/mips/linux/linux.cc
rename : arch/mips/linux/linux.hh => src/arch/mips/linux/linux.hh
rename : arch/mips/linux/process.cc => src/arch/mips/linux/process.cc
rename : arch/mips/linux/process.hh => src/arch/mips/linux/process.hh
rename : arch/mips/process.cc => src/arch/mips/process.cc
rename : arch/mips/process.hh => src/arch/mips/process.hh
rename : arch/mips/regfile/float_regfile.hh => src/arch/mips/regfile/float_regfile.hh
rename : arch/mips/regfile/int_regfile.hh => src/arch/mips/regfile/int_regfile.hh
rename : arch/mips/regfile/misc_regfile.hh => src/arch/mips/regfile/misc_regfile.hh
rename : arch/mips/regfile/regfile.hh => src/arch/mips/regfile/regfile.hh
rename : arch/mips/stacktrace.hh => src/arch/mips/stacktrace.hh
rename : arch/mips/types.hh => src/arch/mips/types.hh
rename : arch/mips/utility.hh => src/arch/mips/utility.hh
rename : arch/sparc/SConscript => src/arch/sparc/SConscript
rename : arch/sparc/faults.cc => src/arch/sparc/faults.cc
rename : arch/sparc/faults.hh => src/arch/sparc/faults.hh
rename : arch/sparc/isa/base.isa => src/arch/sparc/isa/base.isa
rename : arch/sparc/isa/bitfields.isa => src/arch/sparc/isa/bitfields.isa
rename : arch/sparc/isa/decoder.isa => src/arch/sparc/isa/decoder.isa
rename : arch/sparc/isa/formats.isa => src/arch/sparc/isa/formats.isa
rename : arch/sparc/isa/formats/basic.isa => src/arch/sparc/isa/formats/basic.isa
rename : arch/sparc/isa/formats/branch.isa => src/arch/sparc/isa/formats/branch.isa
rename : arch/sparc/isa/formats/integerop.isa => src/arch/sparc/isa/formats/integerop.isa
rename : arch/sparc/isa/formats/mem.isa => src/arch/sparc/isa/formats/mem.isa
rename : arch/sparc/isa/formats/nop.isa => src/arch/sparc/isa/formats/nop.isa
rename : arch/sparc/isa/formats/priv.isa => src/arch/sparc/isa/formats/priv.isa
rename : arch/sparc/isa/formats/trap.isa => src/arch/sparc/isa/formats/trap.isa
rename : arch/sparc/isa/formats/unknown.isa => src/arch/sparc/isa/formats/unknown.isa
rename : arch/sparc/isa/includes.isa => src/arch/sparc/isa/includes.isa
rename : arch/sparc/isa/main.isa => src/arch/sparc/isa/main.isa
rename : arch/sparc/isa/operands.isa => src/arch/sparc/isa/operands.isa
rename : arch/sparc/isa_traits.hh => src/arch/sparc/isa_traits.hh
rename : arch/sparc/linux/linux.cc => src/arch/sparc/linux/linux.cc
rename : arch/sparc/linux/linux.hh => src/arch/sparc/linux/linux.hh
rename : arch/sparc/linux/process.cc => src/arch/sparc/linux/process.cc
rename : arch/sparc/linux/process.hh => src/arch/sparc/linux/process.hh
rename : arch/sparc/process.cc => src/arch/sparc/process.cc
rename : arch/sparc/process.hh => src/arch/sparc/process.hh
rename : arch/sparc/regfile.hh => src/arch/sparc/regfile.hh
rename : arch/sparc/solaris/process.cc => src/arch/sparc/solaris/process.cc
rename : arch/sparc/solaris/process.hh => src/arch/sparc/solaris/process.hh
rename : arch/sparc/solaris/solaris.cc => src/arch/sparc/solaris/solaris.cc
rename : arch/sparc/solaris/solaris.hh => src/arch/sparc/solaris/solaris.hh
rename : arch/sparc/stacktrace.hh => src/arch/sparc/stacktrace.hh
rename : arch/sparc/system.cc => src/arch/sparc/system.cc
rename : arch/sparc/system.hh => src/arch/sparc/system.hh
rename : arch/sparc/utility.hh => src/arch/sparc/utility.hh
rename : base/bitfield.hh => src/base/bitfield.hh
rename : base/callback.hh => src/base/callback.hh
rename : base/chunk_generator.hh => src/base/chunk_generator.hh
rename : base/circlebuf.cc => src/base/circlebuf.cc
rename : base/circlebuf.hh => src/base/circlebuf.hh
rename : base/compression/lzss_compression.cc => src/base/compression/lzss_compression.cc
rename : base/compression/lzss_compression.hh => src/base/compression/lzss_compression.hh
rename : base/compression/null_compression.hh => src/base/compression/null_compression.hh
rename : base/cprintf.cc => src/base/cprintf.cc
rename : base/cprintf.hh => src/base/cprintf.hh
rename : base/cprintf_formats.hh => src/base/cprintf_formats.hh
rename : base/crc.cc => src/base/crc.cc
rename : base/crc.hh => src/base/crc.hh
rename : base/date.cc => src/base/date.cc
rename : base/dbl_list.hh => src/base/dbl_list.hh
rename : base/endian.hh => src/base/endian.hh
rename : base/fast_alloc.cc => src/base/fast_alloc.cc
rename : base/fast_alloc.hh => src/base/fast_alloc.hh
rename : base/fenv.hh => src/base/fenv.hh
rename : base/fifo_buffer.cc => src/base/fifo_buffer.cc
rename : base/fifo_buffer.hh => src/base/fifo_buffer.hh
rename : base/hashmap.hh => src/base/hashmap.hh
rename : base/hostinfo.cc => src/base/hostinfo.cc
rename : base/hostinfo.hh => src/base/hostinfo.hh
rename : base/hybrid_pred.cc => src/base/hybrid_pred.cc
rename : base/hybrid_pred.hh => src/base/hybrid_pred.hh
rename : base/inet.cc => src/base/inet.cc
rename : base/inet.hh => src/base/inet.hh
rename : base/inifile.cc => src/base/inifile.cc
rename : base/inifile.hh => src/base/inifile.hh
rename : base/intmath.cc => src/base/intmath.cc
rename : base/intmath.hh => src/base/intmath.hh
rename : base/kgdb.h => src/base/kgdb.h
rename : base/loader/aout_object.cc => src/base/loader/aout_object.cc
rename : base/loader/aout_object.hh => src/base/loader/aout_object.hh
rename : base/loader/coff_sym.h => src/base/loader/coff_sym.h
rename : base/loader/coff_symconst.h => src/base/loader/coff_symconst.h
rename : base/loader/ecoff_object.cc => src/base/loader/ecoff_object.cc
rename : base/loader/ecoff_object.hh => src/base/loader/ecoff_object.hh
rename : base/loader/elf_object.cc => src/base/loader/elf_object.cc
rename : base/loader/elf_object.hh => src/base/loader/elf_object.hh
rename : base/loader/exec_aout.h => src/base/loader/exec_aout.h
rename : base/loader/exec_ecoff.h => src/base/loader/exec_ecoff.h
rename : base/loader/object_file.cc => src/base/loader/object_file.cc
rename : base/loader/object_file.hh => src/base/loader/object_file.hh
rename : base/loader/symtab.cc => src/base/loader/symtab.cc
rename : base/loader/symtab.hh => src/base/loader/symtab.hh
rename : base/match.cc => src/base/match.cc
rename : base/match.hh => src/base/match.hh
rename : base/misc.cc => src/base/misc.cc
rename : base/misc.hh => src/base/misc.hh
rename : base/mod_num.hh => src/base/mod_num.hh
rename : base/mysql.cc => src/base/mysql.cc
rename : base/mysql.hh => src/base/mysql.hh
rename : base/output.cc => src/base/output.cc
rename : base/output.hh => src/base/output.hh
rename : base/pollevent.cc => src/base/pollevent.cc
rename : base/pollevent.hh => src/base/pollevent.hh
rename : base/predictor.hh => src/base/predictor.hh
rename : base/random.cc => src/base/random.cc
rename : base/random.hh => src/base/random.hh
rename : base/range.cc => src/base/range.cc
rename : base/range.hh => src/base/range.hh
rename : base/refcnt.hh => src/base/refcnt.hh
rename : base/remote_gdb.cc => src/base/remote_gdb.cc
rename : base/remote_gdb.hh => src/base/remote_gdb.hh
rename : base/res_list.hh => src/base/res_list.hh
rename : base/sat_counter.cc => src/base/sat_counter.cc
rename : base/sat_counter.hh => src/base/sat_counter.hh
rename : base/sched_list.hh => src/base/sched_list.hh
rename : base/socket.cc => src/base/socket.cc
rename : base/socket.hh => src/base/socket.hh
rename : base/statistics.cc => src/base/statistics.cc
rename : base/statistics.hh => src/base/statistics.hh
rename : base/stats/events.cc => src/base/stats/events.cc
rename : base/stats/events.hh => src/base/stats/events.hh
rename : base/stats/flags.hh => src/base/stats/flags.hh
rename : base/stats/mysql.cc => src/base/stats/mysql.cc
rename : base/stats/mysql.hh => src/base/stats/mysql.hh
rename : base/stats/mysql_run.hh => src/base/stats/mysql_run.hh
rename : base/stats/output.hh => src/base/stats/output.hh
rename : base/stats/statdb.cc => src/base/stats/statdb.cc
rename : base/stats/statdb.hh => src/base/stats/statdb.hh
rename : base/stats/text.cc => src/base/stats/text.cc
rename : base/stats/text.hh => src/base/stats/text.hh
rename : base/stats/types.hh => src/base/stats/types.hh
rename : base/stats/visit.cc => src/base/stats/visit.cc
rename : base/stats/visit.hh => src/base/stats/visit.hh
rename : base/str.cc => src/base/str.cc
rename : base/str.hh => src/base/str.hh
rename : base/time.cc => src/base/time.cc
rename : base/time.hh => src/base/time.hh
rename : base/timebuf.hh => src/base/timebuf.hh
rename : base/trace.cc => src/base/trace.cc
rename : base/trace.hh => src/base/trace.hh
rename : base/traceflags.py => src/base/traceflags.py
rename : base/userinfo.cc => src/base/userinfo.cc
rename : base/userinfo.hh => src/base/userinfo.hh
rename : cpu/SConscript => src/cpu/SConscript
rename : cpu/base.cc => src/cpu/base.cc
rename : cpu/base.hh => src/cpu/base.hh
rename : cpu/base_dyn_inst.cc => src/cpu/base_dyn_inst.cc
rename : cpu/base_dyn_inst.hh => src/cpu/base_dyn_inst.hh
rename : cpu/cpu_exec_context.cc => src/cpu/cpu_exec_context.cc
rename : cpu/cpu_exec_context.hh => src/cpu/cpu_exec_context.hh
rename : cpu/cpu_models.py => src/cpu/cpu_models.py
rename : cpu/exec_context.hh => src/cpu/exec_context.hh
rename : cpu/exetrace.cc => src/cpu/exetrace.cc
rename : cpu/exetrace.hh => src/cpu/exetrace.hh
rename : cpu/inst_seq.hh => src/cpu/inst_seq.hh
rename : cpu/intr_control.cc => src/cpu/intr_control.cc
rename : cpu/intr_control.hh => src/cpu/intr_control.hh
rename : cpu/memtest/memtest.cc => src/cpu/memtest/memtest.cc
rename : cpu/memtest/memtest.hh => src/cpu/memtest/memtest.hh
rename : cpu/o3/2bit_local_pred.cc => src/cpu/o3/2bit_local_pred.cc
rename : cpu/o3/2bit_local_pred.hh => src/cpu/o3/2bit_local_pred.hh
rename : cpu/o3/alpha_cpu.cc => src/cpu/o3/alpha_cpu.cc
rename : cpu/o3/alpha_cpu.hh => src/cpu/o3/alpha_cpu.hh
rename : cpu/o3/alpha_cpu_builder.cc => src/cpu/o3/alpha_cpu_builder.cc
rename : cpu/o3/alpha_cpu_impl.hh => src/cpu/o3/alpha_cpu_impl.hh
rename : cpu/o3/alpha_dyn_inst.cc => src/cpu/o3/alpha_dyn_inst.cc
rename : cpu/o3/alpha_dyn_inst.hh => src/cpu/o3/alpha_dyn_inst.hh
rename : cpu/o3/alpha_dyn_inst_impl.hh => src/cpu/o3/alpha_dyn_inst_impl.hh
rename : cpu/o3/alpha_impl.hh => src/cpu/o3/alpha_impl.hh
rename : cpu/o3/alpha_params.hh => src/cpu/o3/alpha_params.hh
rename : cpu/o3/bpred_unit.cc => src/cpu/o3/bpred_unit.cc
rename : cpu/o3/bpred_unit.hh => src/cpu/o3/bpred_unit.hh
rename : cpu/o3/bpred_unit_impl.hh => src/cpu/o3/bpred_unit_impl.hh
rename : cpu/o3/btb.cc => src/cpu/o3/btb.cc
rename : cpu/o3/btb.hh => src/cpu/o3/btb.hh
rename : cpu/o3/comm.hh => src/cpu/o3/comm.hh
rename : cpu/o3/commit.cc => src/cpu/o3/commit.cc
rename : cpu/o3/commit.hh => src/cpu/o3/commit.hh
rename : cpu/o3/commit_impl.hh => src/cpu/o3/commit_impl.hh
rename : cpu/o3/cpu.cc => src/cpu/o3/cpu.cc
rename : cpu/o3/cpu.hh => src/cpu/o3/cpu.hh
rename : cpu/o3/cpu_policy.hh => src/cpu/o3/cpu_policy.hh
rename : cpu/o3/decode.cc => src/cpu/o3/decode.cc
rename : cpu/o3/decode.hh => src/cpu/o3/decode.hh
rename : cpu/o3/decode_impl.hh => src/cpu/o3/decode_impl.hh
rename : cpu/o3/fetch.cc => src/cpu/o3/fetch.cc
rename : cpu/o3/fetch.hh => src/cpu/o3/fetch.hh
rename : cpu/o3/fetch_impl.hh => src/cpu/o3/fetch_impl.hh
rename : cpu/o3/free_list.cc => src/cpu/o3/free_list.cc
rename : cpu/o3/free_list.hh => src/cpu/o3/free_list.hh
rename : cpu/o3/iew.cc => src/cpu/o3/iew.cc
rename : cpu/o3/iew.hh => src/cpu/o3/iew.hh
rename : cpu/o3/iew_impl.hh => src/cpu/o3/iew_impl.hh
rename : cpu/o3/inst_queue.cc => src/cpu/o3/inst_queue.cc
rename : cpu/o3/inst_queue.hh => src/cpu/o3/inst_queue.hh
rename : cpu/o3/inst_queue_impl.hh => src/cpu/o3/inst_queue_impl.hh
rename : cpu/o3/mem_dep_unit.cc => src/cpu/o3/mem_dep_unit.cc
rename : cpu/o3/mem_dep_unit.hh => src/cpu/o3/mem_dep_unit.hh
rename : cpu/o3/mem_dep_unit_impl.hh => src/cpu/o3/mem_dep_unit_impl.hh
rename : cpu/o3/ras.cc => src/cpu/o3/ras.cc
rename : cpu/o3/ras.hh => src/cpu/o3/ras.hh
rename : cpu/o3/regfile.hh => src/cpu/o3/regfile.hh
rename : cpu/o3/rename.cc => src/cpu/o3/rename.cc
rename : cpu/o3/rename.hh => src/cpu/o3/rename.hh
rename : cpu/o3/rename_impl.hh => src/cpu/o3/rename_impl.hh
rename : cpu/o3/rename_map.cc => src/cpu/o3/rename_map.cc
rename : cpu/o3/rename_map.hh => src/cpu/o3/rename_map.hh
rename : cpu/o3/rob.cc => src/cpu/o3/rob.cc
rename : cpu/o3/rob.hh => src/cpu/o3/rob.hh
rename : cpu/o3/rob_impl.hh => src/cpu/o3/rob_impl.hh
rename : cpu/o3/sat_counter.cc => src/cpu/o3/sat_counter.cc
rename : cpu/o3/sat_counter.hh => src/cpu/o3/sat_counter.hh
rename : cpu/o3/store_set.cc => src/cpu/o3/store_set.cc
rename : cpu/o3/store_set.hh => src/cpu/o3/store_set.hh
rename : cpu/o3/tournament_pred.cc => src/cpu/o3/tournament_pred.cc
rename : cpu/o3/tournament_pred.hh => src/cpu/o3/tournament_pred.hh
rename : cpu/op_class.cc => src/cpu/op_class.cc
rename : cpu/op_class.hh => src/cpu/op_class.hh
rename : cpu/ozone/cpu.cc => src/cpu/ozone/cpu.cc
rename : cpu/ozone/cpu.hh => src/cpu/ozone/cpu.hh
rename : cpu/ozone/cpu_impl.hh => src/cpu/ozone/cpu_impl.hh
rename : cpu/ozone/ea_list.cc => src/cpu/ozone/ea_list.cc
rename : cpu/ozone/ea_list.hh => src/cpu/ozone/ea_list.hh
rename : cpu/pc_event.cc => src/cpu/pc_event.cc
rename : cpu/pc_event.hh => src/cpu/pc_event.hh
rename : cpu/profile.cc => src/cpu/profile.cc
rename : cpu/profile.hh => src/cpu/profile.hh
rename : cpu/simple/atomic.cc => src/cpu/simple/atomic.cc
rename : cpu/simple/atomic.hh => src/cpu/simple/atomic.hh
rename : cpu/simple/base.cc => src/cpu/simple/base.cc
rename : cpu/simple/base.hh => src/cpu/simple/base.hh
rename : cpu/simple/timing.cc => src/cpu/simple/timing.cc
rename : cpu/simple/timing.hh => src/cpu/simple/timing.hh
rename : cpu/smt.hh => src/cpu/smt.hh
rename : cpu/static_inst.cc => src/cpu/static_inst.cc
rename : cpu/static_inst.hh => src/cpu/static_inst.hh
rename : cpu/trace/opt_cpu.cc => src/cpu/trace/opt_cpu.cc
rename : cpu/trace/opt_cpu.hh => src/cpu/trace/opt_cpu.hh
rename : cpu/trace/reader/ibm_reader.cc => src/cpu/trace/reader/ibm_reader.cc
rename : cpu/trace/reader/ibm_reader.hh => src/cpu/trace/reader/ibm_reader.hh
rename : cpu/trace/reader/itx_reader.cc => src/cpu/trace/reader/itx_reader.cc
rename : cpu/trace/reader/itx_reader.hh => src/cpu/trace/reader/itx_reader.hh
rename : cpu/trace/reader/m5_reader.cc => src/cpu/trace/reader/m5_reader.cc
rename : cpu/trace/reader/m5_reader.hh => src/cpu/trace/reader/m5_reader.hh
rename : cpu/trace/reader/mem_trace_reader.cc => src/cpu/trace/reader/mem_trace_reader.cc
rename : cpu/trace/reader/mem_trace_reader.hh => src/cpu/trace/reader/mem_trace_reader.hh
rename : cpu/trace/trace_cpu.cc => src/cpu/trace/trace_cpu.cc
rename : cpu/trace/trace_cpu.hh => src/cpu/trace/trace_cpu.hh
rename : dev/alpha_access.h => src/dev/alpha_access.h
rename : dev/alpha_console.cc => src/dev/alpha_console.cc
rename : dev/alpha_console.hh => src/dev/alpha_console.hh
rename : dev/baddev.cc => src/dev/baddev.cc
rename : dev/baddev.hh => src/dev/baddev.hh
rename : dev/disk_image.cc => src/dev/disk_image.cc
rename : dev/disk_image.hh => src/dev/disk_image.hh
rename : dev/etherbus.cc => src/dev/etherbus.cc
rename : dev/etherbus.hh => src/dev/etherbus.hh
rename : dev/etherdump.cc => src/dev/etherdump.cc
rename : dev/etherdump.hh => src/dev/etherdump.hh
rename : dev/etherint.cc => src/dev/etherint.cc
rename : dev/etherint.hh => src/dev/etherint.hh
rename : dev/etherlink.cc => src/dev/etherlink.cc
rename : dev/etherlink.hh => src/dev/etherlink.hh
rename : dev/etherpkt.cc => src/dev/etherpkt.cc
rename : dev/etherpkt.hh => src/dev/etherpkt.hh
rename : dev/ethertap.cc => src/dev/ethertap.cc
rename : dev/ethertap.hh => src/dev/ethertap.hh
rename : dev/ide_atareg.h => src/dev/ide_atareg.h
rename : dev/ide_ctrl.cc => src/dev/ide_ctrl.cc
rename : dev/ide_ctrl.hh => src/dev/ide_ctrl.hh
rename : dev/ide_disk.cc => src/dev/ide_disk.cc
rename : dev/ide_disk.hh => src/dev/ide_disk.hh
rename : dev/ide_wdcreg.h => src/dev/ide_wdcreg.h
rename : dev/io_device.cc => src/dev/io_device.cc
rename : dev/io_device.hh => src/dev/io_device.hh
rename : dev/isa_fake.cc => src/dev/isa_fake.cc
rename : dev/isa_fake.hh => src/dev/isa_fake.hh
rename : dev/ns_gige.cc => src/dev/ns_gige.cc
rename : dev/ns_gige.hh => src/dev/ns_gige.hh
rename : dev/ns_gige_reg.h => src/dev/ns_gige_reg.h
rename : dev/pciconfigall.cc => src/dev/pciconfigall.cc
rename : dev/pciconfigall.hh => src/dev/pciconfigall.hh
rename : dev/pcidev.cc => src/dev/pcidev.cc
rename : dev/pcidev.hh => src/dev/pcidev.hh
rename : dev/pcireg.h => src/dev/pcireg.h
rename : dev/pitreg.h => src/dev/pitreg.h
rename : dev/pktfifo.cc => src/dev/pktfifo.cc
rename : dev/pktfifo.hh => src/dev/pktfifo.hh
rename : dev/platform.cc => src/dev/platform.cc
rename : dev/platform.hh => src/dev/platform.hh
rename : dev/rtcreg.h => src/dev/rtcreg.h
rename : dev/simconsole.cc => src/dev/simconsole.cc
rename : dev/simconsole.hh => src/dev/simconsole.hh
rename : dev/simple_disk.cc => src/dev/simple_disk.cc
rename : dev/simple_disk.hh => src/dev/simple_disk.hh
rename : dev/sinic.cc => src/dev/sinic.cc
rename : dev/sinic.hh => src/dev/sinic.hh
rename : dev/sinicreg.hh => src/dev/sinicreg.hh
rename : dev/tsunami.cc => src/dev/tsunami.cc
rename : dev/tsunami.hh => src/dev/tsunami.hh
rename : dev/tsunami_cchip.cc => src/dev/tsunami_cchip.cc
rename : dev/tsunami_cchip.hh => src/dev/tsunami_cchip.hh
rename : dev/tsunami_io.cc => src/dev/tsunami_io.cc
rename : dev/tsunami_io.hh => src/dev/tsunami_io.hh
rename : dev/tsunami_pchip.cc => src/dev/tsunami_pchip.cc
rename : dev/tsunami_pchip.hh => src/dev/tsunami_pchip.hh
rename : dev/tsunamireg.h => src/dev/tsunamireg.h
rename : dev/uart.cc => src/dev/uart.cc
rename : dev/uart.hh => src/dev/uart.hh
rename : dev/uart8250.cc => src/dev/uart8250.cc
rename : dev/uart8250.hh => src/dev/uart8250.hh
rename : kern/kernel_stats.cc => src/kern/kernel_stats.cc
rename : kern/kernel_stats.hh => src/kern/kernel_stats.hh
rename : kern/linux/events.cc => src/kern/linux/events.cc
rename : kern/linux/events.hh => src/kern/linux/events.hh
rename : kern/linux/linux.hh => src/kern/linux/linux.hh
rename : kern/linux/linux_syscalls.cc => src/kern/linux/linux_syscalls.cc
rename : kern/linux/linux_syscalls.hh => src/kern/linux/linux_syscalls.hh
rename : kern/linux/printk.cc => src/kern/linux/printk.cc
rename : kern/linux/printk.hh => src/kern/linux/printk.hh
rename : kern/linux/sched.hh => src/kern/linux/sched.hh
rename : kern/solaris/solaris.hh => src/kern/solaris/solaris.hh
rename : kern/system_events.cc => src/kern/system_events.cc
rename : kern/system_events.hh => src/kern/system_events.hh
rename : kern/tru64/dump_mbuf.cc => src/kern/tru64/dump_mbuf.cc
rename : kern/tru64/dump_mbuf.hh => src/kern/tru64/dump_mbuf.hh
rename : kern/tru64/mbuf.hh => src/kern/tru64/mbuf.hh
rename : kern/tru64/printf.cc => src/kern/tru64/printf.cc
rename : kern/tru64/printf.hh => src/kern/tru64/printf.hh
rename : kern/tru64/tru64.hh => src/kern/tru64/tru64.hh
rename : kern/tru64/tru64_events.cc => src/kern/tru64/tru64_events.cc
rename : kern/tru64/tru64_events.hh => src/kern/tru64/tru64_events.hh
rename : kern/tru64/tru64_syscalls.cc => src/kern/tru64/tru64_syscalls.cc
rename : kern/tru64/tru64_syscalls.hh => src/kern/tru64/tru64_syscalls.hh
rename : mem/bridge.cc => src/mem/bridge.cc
rename : mem/bridge.hh => src/mem/bridge.hh
rename : mem/bus.cc => src/mem/bus.cc
rename : mem/bus.hh => src/mem/bus.hh
rename : mem/cache/prefetch/tagged_prefetcher_impl.hh => src/mem/cache/prefetch/tagged_prefetcher_impl.hh
rename : mem/config/prefetch.hh => src/mem/config/prefetch.hh
rename : mem/mem_object.cc => src/mem/mem_object.cc
rename : mem/mem_object.hh => src/mem/mem_object.hh
rename : mem/packet.cc => src/mem/packet.cc
rename : mem/packet.hh => src/mem/packet.hh
rename : mem/page_table.cc => src/mem/page_table.cc
rename : mem/page_table.hh => src/mem/page_table.hh
rename : mem/physical.cc => src/mem/physical.cc
rename : mem/physical.hh => src/mem/physical.hh
rename : mem/port.cc => src/mem/port.cc
rename : mem/port.hh => src/mem/port.hh
rename : mem/request.hh => src/mem/request.hh
rename : mem/translating_port.cc => src/mem/translating_port.cc
rename : mem/translating_port.hh => src/mem/translating_port.hh
rename : mem/vport.cc => src/mem/vport.cc
rename : mem/vport.hh => src/mem/vport.hh
rename : python/SConscript => src/python/SConscript
rename : python/m5/__init__.py => src/python/m5/__init__.py
rename : python/m5/config.py => src/python/m5/config.py
rename : python/m5/convert.py => src/python/m5/convert.py
rename : python/m5/multidict.py => src/python/m5/multidict.py
rename : python/m5/objects/AlphaConsole.py => src/python/m5/objects/AlphaConsole.py
rename : python/m5/objects/AlphaFullCPU.py => src/python/m5/objects/AlphaFullCPU.py
rename : python/m5/objects/AlphaTLB.py => src/python/m5/objects/AlphaTLB.py
rename : python/m5/objects/BadDevice.py => src/python/m5/objects/BadDevice.py
rename : python/m5/objects/BaseCPU.py => src/python/m5/objects/BaseCPU.py
rename : python/m5/objects/BaseCache.py => src/python/m5/objects/BaseCache.py
rename : python/m5/objects/Bridge.py => src/python/m5/objects/Bridge.py
rename : python/m5/objects/Bus.py => src/python/m5/objects/Bus.py
rename : python/m5/objects/CoherenceProtocol.py => src/python/m5/objects/CoherenceProtocol.py
rename : python/m5/objects/Device.py => src/python/m5/objects/Device.py
rename : python/m5/objects/DiskImage.py => src/python/m5/objects/DiskImage.py
rename : python/m5/objects/Ethernet.py => src/python/m5/objects/Ethernet.py
rename : python/m5/objects/Ide.py => src/python/m5/objects/Ide.py
rename : python/m5/objects/IntrControl.py => src/python/m5/objects/IntrControl.py
rename : python/m5/objects/MemObject.py => src/python/m5/objects/MemObject.py
rename : python/m5/objects/MemTest.py => src/python/m5/objects/MemTest.py
rename : python/m5/objects/Pci.py => src/python/m5/objects/Pci.py
rename : python/m5/objects/PhysicalMemory.py => src/python/m5/objects/PhysicalMemory.py
rename : python/m5/objects/Platform.py => src/python/m5/objects/Platform.py
rename : python/m5/objects/Process.py => src/python/m5/objects/Process.py
rename : python/m5/objects/Repl.py => src/python/m5/objects/Repl.py
rename : python/m5/objects/Root.py => src/python/m5/objects/Root.py
rename : python/m5/objects/SimConsole.py => src/python/m5/objects/SimConsole.py
rename : python/m5/objects/SimpleDisk.py => src/python/m5/objects/SimpleDisk.py
rename : python/m5/objects/System.py => src/python/m5/objects/System.py
rename : python/m5/objects/Tsunami.py => src/python/m5/objects/Tsunami.py
rename : python/m5/objects/Uart.py => src/python/m5/objects/Uart.py
rename : python/m5/smartdict.py => src/python/m5/smartdict.py
rename : sim/async.hh => src/sim/async.hh
rename : sim/builder.cc => src/sim/builder.cc
rename : sim/builder.hh => src/sim/builder.hh
rename : sim/byteswap.hh => src/sim/byteswap.hh
rename : sim/debug.cc => src/sim/debug.cc
rename : sim/debug.hh => src/sim/debug.hh
rename : sim/eventq.cc => src/sim/eventq.cc
rename : sim/eventq.hh => src/sim/eventq.hh
rename : sim/faults.cc => src/sim/faults.cc
rename : sim/faults.hh => src/sim/faults.hh
rename : sim/host.hh => src/sim/host.hh
rename : sim/main.cc => src/sim/main.cc
rename : sim/param.cc => src/sim/param.cc
rename : sim/param.hh => src/sim/param.hh
rename : sim/process.cc => src/sim/process.cc
rename : sim/process.hh => src/sim/process.hh
rename : sim/pseudo_inst.cc => src/sim/pseudo_inst.cc
rename : sim/pseudo_inst.hh => src/sim/pseudo_inst.hh
rename : sim/root.cc => src/sim/root.cc
rename : sim/serialize.cc => src/sim/serialize.cc
rename : sim/serialize.hh => src/sim/serialize.hh
rename : sim/sim_events.cc => src/sim/sim_events.cc
rename : sim/sim_events.hh => src/sim/sim_events.hh
rename : sim/sim_exit.hh => src/sim/sim_exit.hh
rename : sim/sim_object.cc => src/sim/sim_object.cc
rename : sim/sim_object.hh => src/sim/sim_object.hh
rename : sim/startup.cc => src/sim/startup.cc
rename : sim/startup.hh => src/sim/startup.hh
rename : sim/stat_control.cc => src/sim/stat_control.cc
rename : sim/stat_control.hh => src/sim/stat_control.hh
rename : sim/stats.hh => src/sim/stats.hh
rename : sim/syscall_emul.cc => src/sim/syscall_emul.cc
rename : sim/syscall_emul.hh => src/sim/syscall_emul.hh
rename : sim/system.cc => src/sim/system.cc
rename : sim/system.hh => src/sim/system.hh
rename : sim/vptr.hh => src/sim/vptr.hh
rename : test/Makefile => src/unittest/Makefile
rename : test/bitvectest.cc => src/unittest/bitvectest.cc
rename : test/circletest.cc => src/unittest/circletest.cc
rename : test/cprintftest.cc => src/unittest/cprintftest.cc
rename : test/foo.ini => src/unittest/foo.ini
rename : test/genini.py => src/unittest/genini.py
rename : test/initest.cc => src/unittest/initest.cc
rename : test/initest.ini => src/unittest/initest.ini
rename : test/lru_test.cc => src/unittest/lru_test.cc
rename : test/nmtest.cc => src/unittest/nmtest.cc
rename : test/offtest.cc => src/unittest/offtest.cc
rename : test/paramtest.cc => src/unittest/paramtest.cc
rename : test/rangetest.cc => src/unittest/rangetest.cc
rename : test/sized_test.cc => src/unittest/sized_test.cc
rename : test/stattest.cc => src/unittest/stattest.cc
rename : test/strnumtest.cc => src/unittest/strnumtest.cc
rename : test/symtest.cc => src/unittest/symtest.cc
rename : test/tokentest.cc => src/unittest/tokentest.cc
rename : test/tracetest.cc => src/unittest/tracetest.cc
extra : convert_revision : cab6a5271ca1b368193cd948e5d3dcc47ab1bd48
This commit is contained in:
1127
src/Doxyfile
Normal file
1127
src/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
402
src/SConscript
Normal file
402
src/SConscript
Normal file
@@ -0,0 +1,402 @@
|
||||
# -*- 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.
|
||||
|
||||
import os
|
||||
import sys
|
||||
from os.path import isdir
|
||||
|
||||
# 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/circlebuf.cc
|
||||
base/copyright.cc
|
||||
base/cprintf.cc
|
||||
base/embedfile.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/sat_counter.cc
|
||||
base/serializer.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/object_file.cc
|
||||
base/loader/symtab.cc
|
||||
base/stats/events.cc
|
||||
base/stats/statdb.cc
|
||||
base/stats/visit.cc
|
||||
base/stats/text.cc
|
||||
|
||||
cpu/base.cc
|
||||
cpu/cpu_exec_context.cc
|
||||
cpu/exetrace.cc
|
||||
cpu/op_class.cc
|
||||
cpu/pc_event.cc
|
||||
cpu/static_inst.cc
|
||||
cpu/sampler/sampler.cc
|
||||
|
||||
mem/bridge.cc
|
||||
mem/bus.cc
|
||||
mem/connector.cc
|
||||
mem/mem_object.cc
|
||||
mem/packet.cc
|
||||
mem/physical.cc
|
||||
mem/port.cc
|
||||
mem/request.cc
|
||||
|
||||
python/pyconfig.cc
|
||||
python/embedded_py.cc
|
||||
|
||||
sim/builder.cc
|
||||
sim/configfile.cc
|
||||
sim/debug.cc
|
||||
sim/eventq.cc
|
||||
sim/faults.cc
|
||||
sim/main.cc
|
||||
sim/param.cc
|
||||
sim/profile.cc
|
||||
sim/root.cc
|
||||
sim/serialize.cc
|
||||
sim/sim_events.cc
|
||||
sim/sim_exit.cc
|
||||
sim/sim_object.cc
|
||||
sim/startup.cc
|
||||
sim/stat_context.cc
|
||||
sim/stat_control.cc
|
||||
sim/system.cc
|
||||
sim/trace_context.cc
|
||||
''')
|
||||
|
||||
# Old FullCPU sources
|
||||
full_cpu_sources = Split('''
|
||||
encumbered/cpu/full/bpred.cc
|
||||
encumbered/cpu/full/commit.cc
|
||||
encumbered/cpu/full/cpu.cc
|
||||
encumbered/cpu/full/create_vector.cc
|
||||
encumbered/cpu/full/cv_spec_state.cc
|
||||
encumbered/cpu/full/dd_queue.cc
|
||||
encumbered/cpu/full/dep_link.cc
|
||||
encumbered/cpu/full/dispatch.cc
|
||||
encumbered/cpu/full/dyn_inst.cc
|
||||
encumbered/cpu/full/execute.cc
|
||||
encumbered/cpu/full/fetch.cc
|
||||
encumbered/cpu/full/floss_reasons.cc
|
||||
encumbered/cpu/full/fu_pool.cc
|
||||
encumbered/cpu/full/inst_fifo.cc
|
||||
encumbered/cpu/full/instpipe.cc
|
||||
encumbered/cpu/full/issue.cc
|
||||
encumbered/cpu/full/ls_queue.cc
|
||||
encumbered/cpu/full/machine_queue.cc
|
||||
encumbered/cpu/full/pipetrace.cc
|
||||
encumbered/cpu/full/readyq.cc
|
||||
encumbered/cpu/full/reg_info.cc
|
||||
encumbered/cpu/full/rob_station.cc
|
||||
encumbered/cpu/full/spec_memory.cc
|
||||
encumbered/cpu/full/spec_state.cc
|
||||
encumbered/cpu/full/storebuffer.cc
|
||||
encumbered/cpu/full/writeback.cc
|
||||
encumbered/cpu/full/iq/iq_station.cc
|
||||
encumbered/cpu/full/iq/iqueue.cc
|
||||
encumbered/cpu/full/iq/segmented/chain_info.cc
|
||||
encumbered/cpu/full/iq/segmented/chain_wire.cc
|
||||
encumbered/cpu/full/iq/segmented/iq_seg.cc
|
||||
encumbered/cpu/full/iq/segmented/iq_segmented.cc
|
||||
encumbered/cpu/full/iq/segmented/seg_chain.cc
|
||||
encumbered/cpu/full/iq/seznec/iq_seznec.cc
|
||||
encumbered/cpu/full/iq/standard/iq_standard.cc
|
||||
''')
|
||||
|
||||
trace_reader_sources = Split('''
|
||||
cpu/trace/reader/mem_trace_reader.cc
|
||||
cpu/trace/reader/ibm_reader.cc
|
||||
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
|
||||
base/remote_gdb.cc
|
||||
|
||||
cpu/intr_control.cc
|
||||
cpu/profile.cc
|
||||
|
||||
dev/alpha_console.cc
|
||||
dev/baddev.cc
|
||||
dev/disk_image.cc
|
||||
dev/etherbus.cc
|
||||
dev/etherdump.cc
|
||||
dev/etherint.cc
|
||||
dev/etherlink.cc
|
||||
dev/etherpkt.cc
|
||||
dev/ethertap.cc
|
||||
dev/ide_ctrl.cc
|
||||
dev/ide_disk.cc
|
||||
dev/io_device.cc
|
||||
dev/isa_fake.cc
|
||||
dev/ns_gige.cc
|
||||
dev/pciconfigall.cc
|
||||
dev/pcidev.cc
|
||||
dev/pcifake.cc
|
||||
dev/pktfifo.cc
|
||||
dev/platform.cc
|
||||
dev/simconsole.cc
|
||||
dev/simple_disk.cc
|
||||
dev/sinic.cc
|
||||
dev/tsunami.cc
|
||||
dev/tsunami_cchip.cc
|
||||
dev/tsunami_io.cc
|
||||
dev/tsunami_fake.cc
|
||||
dev/tsunami_pchip.cc
|
||||
|
||||
dev/uart.cc
|
||||
dev/uart8250.cc
|
||||
|
||||
kern/kernel_binning.cc
|
||||
kern/kernel_stats.cc
|
||||
kern/system_events.cc
|
||||
kern/linux/events.cc
|
||||
kern/linux/linux_syscalls.cc
|
||||
kern/linux/printk.cc
|
||||
|
||||
mem/vport.cc
|
||||
|
||||
sim/pseudo_inst.cc
|
||||
''')
|
||||
|
||||
|
||||
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
|
||||
''')
|
||||
|
||||
# turbolaser encumbered sources
|
||||
turbolaser_sources = Split('''
|
||||
encumbered/dev/dma.cc
|
||||
encumbered/dev/etherdev.cc
|
||||
encumbered/dev/scsi.cc
|
||||
encumbered/dev/scsi_ctrl.cc
|
||||
encumbered/dev/scsi_disk.cc
|
||||
encumbered/dev/scsi_none.cc
|
||||
encumbered/dev/tlaser_clock.cc
|
||||
encumbered/dev/tlaser_ipi.cc
|
||||
encumbered/dev/tlaser_mbox.cc
|
||||
encumbered/dev/tlaser_mc146818.cc
|
||||
encumbered/dev/tlaser_node.cc
|
||||
encumbered/dev/tlaser_pcia.cc
|
||||
encumbered/dev/tlaser_pcidev.cc
|
||||
encumbered/dev/tlaser_serial.cc
|
||||
encumbered/dev/turbolaser.cc
|
||||
encumbered/dev/uart8530.cc
|
||||
''')
|
||||
|
||||
# Syscall emulation (non-full-system) sources
|
||||
syscall_emulation_sources = Split('''
|
||||
mem/translating_port.cc
|
||||
mem/page_table.cc
|
||||
sim/process.cc
|
||||
sim/syscall_emul.cc
|
||||
''')
|
||||
|
||||
#if env['TARGET_ISA'] == 'alpha':
|
||||
# syscall_emulation_sources += Split('''
|
||||
# kern/tru64/tru64.cc
|
||||
# ''')
|
||||
|
||||
alpha_eio_sources = Split('''
|
||||
encumbered/eio/exolex.cc
|
||||
encumbered/eio/libexo.cc
|
||||
encumbered/eio/eio.cc
|
||||
''')
|
||||
|
||||
if env['TARGET_ISA'] == 'ALPHA_ISA':
|
||||
syscall_emulation_sources += alpha_eio_sources
|
||||
|
||||
memtest_sources = Split('''
|
||||
cpu/memtest/memtest.cc
|
||||
''')
|
||||
|
||||
# Add a flag defining what THE_ISA should be for all compilation
|
||||
env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())])
|
||||
|
||||
arch_sources = SConscript('arch/SConscript',
|
||||
exports = 'env', duplicate = False)
|
||||
|
||||
cpu_sources = SConscript('cpu/SConscript',
|
||||
exports = 'env', duplicate = False)
|
||||
|
||||
# This is outside of cpu/SConscript since the source directory isn't
|
||||
# underneath 'cpu'.
|
||||
if 'FullCPU' in env['CPU_MODELS']:
|
||||
cpu_sources += full_cpu_sources
|
||||
|
||||
# Set up complete list of sources based on configuration.
|
||||
sources = base_sources + arch_sources + cpu_sources
|
||||
|
||||
if env['FULL_SYSTEM']:
|
||||
sources += full_system_sources
|
||||
if env['ALPHA_TLASER']:
|
||||
sources += turbolaser_sources
|
||||
else:
|
||||
sources += syscall_emulation_sources
|
||||
|
||||
if env['USE_MYSQL']:
|
||||
sources += mysql_sources
|
||||
|
||||
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')
|
||||
|
||||
# libelf build is described in its own SConscript file.
|
||||
# SConscript-local is the per-config build, which just copies some
|
||||
# header files into a place where they can be found.
|
||||
SConscript('libelf/SConscript-local', exports = 'env', duplicate=0)
|
||||
SConscript('python/SConscript', exports = ['env'], duplicate=0)
|
||||
|
||||
# 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
|
||||
# add the Object nodes so we can set up special dependencies for
|
||||
# date.cc.
|
||||
def make_objs(sources, env):
|
||||
objs = [env.Object(s) for s in sources]
|
||||
# make date.cc depend on all other objects so it always gets
|
||||
# recompiled whenever anything else does
|
||||
date_obj = env.Object('base/date.cc')
|
||||
env.Depends(date_obj, objs)
|
||||
objs.append(date_obj)
|
||||
return objs
|
||||
|
||||
###################################################
|
||||
#
|
||||
# Define binaries. Each different build type (debug, opt, etc.) gets
|
||||
# a slightly different build environment.
|
||||
#
|
||||
###################################################
|
||||
|
||||
# Include file paths are rooted in this directory. SCons will
|
||||
# automatically expand '.' to refer to both the source directory and
|
||||
# the corresponding build directory to pick up generated include
|
||||
# files.
|
||||
env.Append(CPPPATH='.')
|
||||
env.Append(CPPPATH='./libelf')
|
||||
|
||||
# Debug binary
|
||||
debugEnv = env.Copy(OBJSUFFIX='.do')
|
||||
debugEnv.Label = 'debug'
|
||||
debugEnv.Append(CCFLAGS=Split('-g3 -gdwarf-2 -O0'))
|
||||
debugEnv.Append(CPPDEFINES='DEBUG')
|
||||
tlist = debugEnv.Program(target = 'm5.debug',
|
||||
source = make_objs(sources, debugEnv))
|
||||
debugEnv.M5Binary = tlist[0]
|
||||
|
||||
# Optimized binary
|
||||
optEnv = env.Copy()
|
||||
optEnv.Label = 'opt'
|
||||
optEnv.Append(CCFLAGS=Split('-g -O3'))
|
||||
tlist = optEnv.Program(target = 'm5.opt',
|
||||
source = make_objs(sources, optEnv))
|
||||
optEnv.M5Binary = tlist[0]
|
||||
|
||||
# "Fast" binary
|
||||
fastEnv = env.Copy(OBJSUFFIX='.fo')
|
||||
fastEnv.Label = 'fast'
|
||||
fastEnv.Append(CCFLAGS=Split('-O3'))
|
||||
fastEnv.Append(CPPDEFINES='NDEBUG')
|
||||
fastEnv.Program(target = 'm5.fast.unstripped',
|
||||
source = make_objs(sources, fastEnv))
|
||||
tlist = fastEnv.Command(target = 'm5.fast',
|
||||
source = 'm5.fast.unstripped',
|
||||
action = 'strip $SOURCE -o $TARGET')
|
||||
fastEnv.M5Binary = tlist[0]
|
||||
|
||||
# Profiled binary
|
||||
profEnv = env.Copy(OBJSUFFIX='.po')
|
||||
profEnv.Label = 'prof'
|
||||
profEnv.Append(CCFLAGS=Split('-O3 -g -pg'), LINKFLAGS='-pg')
|
||||
tlist = profEnv.Program(target = 'm5.prof',
|
||||
source = make_objs(sources, profEnv))
|
||||
profEnv.M5Binary = tlist[0]
|
||||
|
||||
envList = [debugEnv, optEnv, fastEnv, profEnv]
|
||||
|
||||
Return('envList')
|
||||
150
src/arch/SConscript
Normal file
150
src/arch/SConscript
Normal file
@@ -0,0 +1,150 @@
|
||||
# -*- 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.
|
||||
|
||||
import os.path
|
||||
|
||||
# Import build environment variable from SConstruct.
|
||||
Import('env')
|
||||
|
||||
# Right now there are no source files immediately in this directory
|
||||
sources = []
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# ISA "switch header" generation.
|
||||
#
|
||||
# Auto-generate arch headers that include the right ISA-specific
|
||||
# header based on the setting of THE_ISA preprocessor variable.
|
||||
#
|
||||
#################################################################
|
||||
|
||||
# List of headers to generate
|
||||
isa_switch_hdrs = Split('''
|
||||
arguments.hh
|
||||
constants.hh
|
||||
faults.hh
|
||||
isa_traits.hh
|
||||
process.hh
|
||||
regfile.hh
|
||||
stacktrace.hh
|
||||
tlb.hh
|
||||
types.hh
|
||||
utility.hh
|
||||
vtophys.hh
|
||||
''')
|
||||
|
||||
# Generate the header. target[0] is the full path of the output
|
||||
# header to generate. 'source' is a dummy variable, since we get the
|
||||
# list of ISAs from env['ALL_ISA_LIST'].
|
||||
def gen_switch_hdr(target, source, env):
|
||||
fname = str(target[0])
|
||||
basename = os.path.basename(fname)
|
||||
f = open(fname, 'w')
|
||||
f.write('#include "arch/isa_specific.hh"\n')
|
||||
cond = '#if'
|
||||
for isa in env['ALL_ISA_LIST']:
|
||||
f.write('%s THE_ISA == %s_ISA\n#include "arch/%s/%s"\n'
|
||||
% (cond, isa.upper(), isa, basename))
|
||||
cond = '#elif'
|
||||
f.write('#else\n#error "THE_ISA not set"\n#endif\n')
|
||||
f.close()
|
||||
return 0
|
||||
|
||||
# String to print when generating header
|
||||
def gen_switch_hdr_string(target, source, env):
|
||||
return "Generating ISA switch header " + str(target[0])
|
||||
|
||||
# Build SCons Action object. 'varlist' specifies env vars that this
|
||||
# action depends on; when env['ALL_ISA_LIST'] changes these actions
|
||||
# should get re-executed.
|
||||
switch_hdr_action = Action(gen_switch_hdr, gen_switch_hdr_string,
|
||||
varlist=['ALL_ISA_LIST'])
|
||||
|
||||
# Instantiate actions for each header
|
||||
for hdr in isa_switch_hdrs:
|
||||
env.Command(hdr, [], switch_hdr_action)
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Include architecture-specific files.
|
||||
#
|
||||
#################################################################
|
||||
|
||||
#
|
||||
# Build a SCons scanner for ISA files
|
||||
#
|
||||
import SCons.Scanner
|
||||
|
||||
isa_scanner = SCons.Scanner.Classic("ISAScan",
|
||||
[".isa", ".ISA"],
|
||||
"SRCDIR",
|
||||
r'^\s*##include\s+"([\w/.-]*)"')
|
||||
|
||||
env.Append(SCANNERS = isa_scanner)
|
||||
|
||||
#
|
||||
# Now create a Builder object that uses isa_parser.py to generate C++
|
||||
# output from the ISA description (*.isa) files.
|
||||
#
|
||||
|
||||
# Convert to File node to fix path
|
||||
isa_parser = File('isa_parser.py')
|
||||
cpu_models_file = File('../cpu/cpu_models.py')
|
||||
|
||||
# This sucks in the defintions of the CpuModel objects.
|
||||
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')
|
||||
# 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']]
|
||||
|
||||
# The emitter patches up the sources & targets to include the
|
||||
# autogenerated files as targets and isa parser itself as a source.
|
||||
def isa_desc_emitter(target, source, env):
|
||||
return (isa_desc_gen_files, [isa_parser, cpu_models_file] + source)
|
||||
|
||||
# Pieces are in place, so create the builder.
|
||||
isa_desc_builder = Builder(action='python $SOURCES $TARGET.dir $CPU_MODELS',
|
||||
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', duplicate = False)
|
||||
|
||||
Return('sources')
|
||||
93
src/arch/alpha/SConscript
Normal file
93
src/arch/alpha/SConscript
Normal file
@@ -0,0 +1,93 @@
|
||||
# -*- 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.
|
||||
|
||||
import os
|
||||
import sys
|
||||
from os.path import isdir
|
||||
|
||||
# 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('''
|
||||
faults.cc
|
||||
isa_traits.cc
|
||||
''')
|
||||
|
||||
# Full-system sources
|
||||
full_system_sources = Split('''
|
||||
tlb.cc
|
||||
arguments.cc
|
||||
ev5.cc
|
||||
osfpal.cc
|
||||
stacktrace.cc
|
||||
vtophys.cc
|
||||
system.cc
|
||||
freebsd/system.cc
|
||||
linux/system.cc
|
||||
tru64/system.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
|
||||
|
||||
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')
|
||||
67
src/arch/alpha/aout_machdep.h
Normal file
67
src/arch/alpha/aout_machdep.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __AOUT_MACHDEP_H__
|
||||
#define __AOUT_MACHDEP_H__
|
||||
|
||||
///
|
||||
/// Funky Alpha 64-bit a.out header used for PAL code.
|
||||
///
|
||||
struct aout_exechdr {
|
||||
uint16_t magic; ///< magic number
|
||||
uint16_t vstamp; ///< version stamp?
|
||||
uint16_t bldrev; ///< ???
|
||||
uint16_t padcell; ///< padding
|
||||
uint64_t tsize; ///< text segment size
|
||||
uint64_t dsize; ///< data segment size
|
||||
uint64_t bsize; ///< bss segment size
|
||||
uint64_t entry; ///< entry point
|
||||
uint64_t text_start; ///< text base address
|
||||
uint64_t data_start; ///< data base address
|
||||
uint64_t bss_start; ///< bss base address
|
||||
uint32_t gprmask; ///< GPR mask (unused, AFAIK)
|
||||
uint32_t fprmask; ///< FPR mask (unused, AFAIK)
|
||||
uint64_t gp_value; ///< global pointer reg value
|
||||
};
|
||||
|
||||
#define AOUT_LDPGSZ 8192
|
||||
|
||||
#define N_GETMAGIC(ex) ((ex).magic)
|
||||
|
||||
#define N_BADMAX
|
||||
|
||||
#define N_TXTADDR(ex) ((ex).text_start)
|
||||
#define N_DATADDR(ex) ((ex).data_start)
|
||||
#define N_BSSADDR(ex) ((ex).bss_start)
|
||||
|
||||
#define N_TXTOFF(ex) \
|
||||
(N_GETMAGIC(ex) == ZMAGIC ? 0 : sizeof(struct aout_exechdr))
|
||||
|
||||
#define N_DATOFF(ex) N_ALIGN(ex, N_TXTOFF(ex) + (ex).tsize)
|
||||
|
||||
#endif /* !__AOUT_MACHDEP_H__*/
|
||||
68
src/arch/alpha/arguments.cc
Normal file
68
src/arch/alpha/arguments.cc
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "arch/alpha/arguments.hh"
|
||||
#include "arch/alpha/vtophys.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "mem/vport.hh"
|
||||
|
||||
using namespace AlphaISA;
|
||||
|
||||
AlphaArguments::Data::~Data()
|
||||
{
|
||||
while (!data.empty()) {
|
||||
delete [] data.front();
|
||||
data.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
AlphaArguments::Data::alloc(size_t size)
|
||||
{
|
||||
char *buf = new char[size];
|
||||
data.push_back(buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
AlphaArguments::getArg(bool fp)
|
||||
{
|
||||
if (number < 6) {
|
||||
if (fp)
|
||||
return xc->readFloatRegBits(16 + number);
|
||||
else
|
||||
return xc->readIntReg(16 + number);
|
||||
} else {
|
||||
Addr sp = xc->readIntReg(30);
|
||||
VirtualPort *vp = xc->getVirtPort(xc);
|
||||
uint64_t arg = vp->read<uint64_t>(sp + (number-6) * sizeof(uint64_t));
|
||||
xc->delVirtPort(vp);
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
|
||||
147
src/arch/alpha/arguments.hh
Normal file
147
src/arch/alpha/arguments.hh
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ALPHA_ARGUMENTS_HH__
|
||||
#define __ARCH_ALPHA_ARGUMENTS_HH__
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "arch/alpha/vtophys.hh"
|
||||
#include "base/refcnt.hh"
|
||||
#include "sim/host.hh"
|
||||
|
||||
class ExecContext;
|
||||
|
||||
namespace AlphaISA {
|
||||
|
||||
class AlphaArguments
|
||||
{
|
||||
protected:
|
||||
ExecContext *xc;
|
||||
int number;
|
||||
uint64_t getArg(bool fp = false);
|
||||
|
||||
protected:
|
||||
class Data : public RefCounted
|
||||
{
|
||||
public:
|
||||
Data(){}
|
||||
~Data();
|
||||
|
||||
private:
|
||||
std::list<char *> data;
|
||||
|
||||
public:
|
||||
char *alloc(size_t size);
|
||||
};
|
||||
|
||||
RefCountingPtr<Data> data;
|
||||
|
||||
public:
|
||||
AlphaArguments(ExecContext *ctx, int n = 0)
|
||||
: xc(ctx), number(n), data(NULL)
|
||||
{ assert(number >= 0); data = new Data;}
|
||||
AlphaArguments(const AlphaArguments &args)
|
||||
: xc(args.xc), number(args.number), data(args.data) {}
|
||||
~AlphaArguments() {}
|
||||
|
||||
ExecContext *getExecContext() const { return xc; }
|
||||
|
||||
const AlphaArguments &operator=(const AlphaArguments &args) {
|
||||
xc = args.xc;
|
||||
number = args.number;
|
||||
data = args.data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AlphaArguments &operator++() {
|
||||
++number;
|
||||
assert(number >= 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AlphaArguments operator++(int) {
|
||||
AlphaArguments args = *this;
|
||||
++number;
|
||||
assert(number >= 0);
|
||||
return args;
|
||||
}
|
||||
|
||||
AlphaArguments &operator--() {
|
||||
--number;
|
||||
assert(number >= 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AlphaArguments operator--(int) {
|
||||
AlphaArguments args = *this;
|
||||
--number;
|
||||
assert(number >= 0);
|
||||
return args;
|
||||
}
|
||||
|
||||
const AlphaArguments &operator+=(int index) {
|
||||
number += index;
|
||||
assert(number >= 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const AlphaArguments &operator-=(int index) {
|
||||
number -= index;
|
||||
assert(number >= 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AlphaArguments operator[](int index) {
|
||||
return AlphaArguments(xc, index);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
operator T() {
|
||||
assert(sizeof(T) <= sizeof(uint64_t));
|
||||
T data = static_cast<T>(getArg());
|
||||
return data;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
operator T *() {
|
||||
T *buf = (T *)data->alloc(sizeof(T));
|
||||
CopyData(xc, buf, getArg(), sizeof(T));
|
||||
return buf;
|
||||
}
|
||||
|
||||
operator char *() {
|
||||
char *buf = data->alloc(2048);
|
||||
CopyStringOut(xc, buf, getArg(), 2048);
|
||||
return buf;
|
||||
}
|
||||
};
|
||||
|
||||
}; // namespace AlphaISA
|
||||
|
||||
#endif // __ARCH_ALPHA_ARGUMENTS_HH__
|
||||
73
src/arch/alpha/ecoff_machdep.h
Normal file
73
src/arch/alpha/ecoff_machdep.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Taken from NetBSD arch/alpha/ecoff_machdep.h
|
||||
*/
|
||||
|
||||
/* $NetBSD: ecoff_machdep.h,v 1.5 1999/04/27 02:32:33 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Adam Glass
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Adam Glass.
|
||||
* 4. The name of the Author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Adam Glass ``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 Adam Glass 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.
|
||||
*/
|
||||
|
||||
//
|
||||
// Define COFF/ECOFF integer type sizes
|
||||
//
|
||||
typedef int16_t coff_short;
|
||||
typedef uint16_t coff_ushort;
|
||||
typedef int32_t coff_int;
|
||||
typedef uint32_t coff_uint;
|
||||
typedef int64_t coff_long;
|
||||
typedef uint64_t coff_ulong;
|
||||
typedef uint64_t coff_addr;
|
||||
|
||||
#define ECOFF_LDPGSZ 4096
|
||||
|
||||
#define ECOFF_PAD \
|
||||
coff_ushort bldrev; /* XXX */
|
||||
|
||||
#define ECOFF_MACHDEP \
|
||||
coff_uint gprmask; \
|
||||
coff_uint fprmask; \
|
||||
coff_ulong gp_value
|
||||
|
||||
#define ECOFF_MAGIC_ALPHA 0603
|
||||
#define ECOFF_MAGIC_NETBSD_ALPHA 0605
|
||||
#define ECOFF_BADMAG(ep) \
|
||||
((ep)->f.f_magic != ECOFF_MAGIC_ALPHA && \
|
||||
(ep)->f.f_magic != ECOFF_MAGIC_NETBSD_ALPHA)
|
||||
|
||||
#define ECOFF_FLAG_EXEC 0002
|
||||
#define ECOFF_SEGMENT_ALIGNMENT(ep) \
|
||||
(((ep)->f.f_flags & ECOFF_FLAG_EXEC) == 0 ? 8 : 16)
|
||||
|
||||
#define ECOFF_FLAG_OBJECT_TYPE_MASK 0x3000
|
||||
#define ECOFF_OBJECT_TYPE_NO_SHARED 0x1000
|
||||
#define ECOFF_OBJECT_TYPE_SHARABLE 0x2000
|
||||
#define ECOFF_OBJECT_TYPE_CALL_SHARED 0x3000
|
||||
|
||||
577
src/arch/alpha/ev5.cc
Normal file
577
src/arch/alpha/ev5.cc
Normal file
@@ -0,0 +1,577 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arch/alpha/tlb.hh"
|
||||
#include "arch/alpha/isa_traits.hh"
|
||||
#include "arch/alpha/osfpal.hh"
|
||||
#include "base/kgdb.h"
|
||||
#include "base/remote_gdb.hh"
|
||||
#include "base/stats/events.hh"
|
||||
#include "config/full_system.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/cpu_exec_context.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "kern/kernel_stats.hh"
|
||||
#include "sim/debug.hh"
|
||||
#include "sim/sim_events.hh"
|
||||
|
||||
#if FULL_SYSTEM
|
||||
|
||||
using namespace EV5;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Machine dependent functions
|
||||
//
|
||||
void
|
||||
AlphaISA::initCPU(ExecContext *xc, int cpuId)
|
||||
{
|
||||
initIPRs(xc, cpuId);
|
||||
|
||||
xc->setIntReg(16, cpuId);
|
||||
xc->setIntReg(0, cpuId);
|
||||
|
||||
xc->setPC(xc->readMiscReg(IPR_PAL_BASE) + (new ResetFault)->vect());
|
||||
xc->setNextPC(xc->readPC() + sizeof(MachInst));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
void
|
||||
AlphaISA::initIPRs(ExecContext *xc, int cpuId)
|
||||
{
|
||||
for (int i = 0; i < NumInternalProcRegs; ++i) {
|
||||
xc->setMiscReg(i, 0);
|
||||
}
|
||||
|
||||
xc->setMiscReg(IPR_PAL_BASE, PalBase);
|
||||
xc->setMiscReg(IPR_MCSR, 0x6);
|
||||
xc->setMiscReg(IPR_PALtemp16, cpuId);
|
||||
}
|
||||
|
||||
|
||||
template <class CPU>
|
||||
void
|
||||
AlphaISA::processInterrupts(CPU *cpu)
|
||||
{
|
||||
//Check if there are any outstanding interrupts
|
||||
//Handle the interrupts
|
||||
int ipl = 0;
|
||||
int summary = 0;
|
||||
|
||||
cpu->checkInterrupts = false;
|
||||
|
||||
if (cpu->readMiscReg(IPR_ASTRR))
|
||||
panic("asynchronous traps not implemented\n");
|
||||
|
||||
if (cpu->readMiscReg(IPR_SIRR)) {
|
||||
for (int i = INTLEVEL_SOFTWARE_MIN;
|
||||
i < INTLEVEL_SOFTWARE_MAX; i++) {
|
||||
if (cpu->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
|
||||
// See table 4-19 of the 21164 hardware reference
|
||||
ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
|
||||
summary |= (ULL(1) << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t interrupts = cpu->intr_status();
|
||||
|
||||
if (interrupts) {
|
||||
for (int i = INTLEVEL_EXTERNAL_MIN;
|
||||
i < INTLEVEL_EXTERNAL_MAX; i++) {
|
||||
if (interrupts & (ULL(1) << i)) {
|
||||
// See table 4-19 of the 21164 hardware reference
|
||||
ipl = i;
|
||||
summary |= (ULL(1) << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ipl && ipl > cpu->readMiscReg(IPR_IPLR)) {
|
||||
cpu->setMiscReg(IPR_ISR, summary);
|
||||
cpu->setMiscReg(IPR_INTID, ipl);
|
||||
cpu->trap(new InterruptFault);
|
||||
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
|
||||
cpu->readMiscReg(IPR_IPLR), ipl, summary);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <class CPU>
|
||||
void
|
||||
AlphaISA::zeroRegisters(CPU *cpu)
|
||||
{
|
||||
// Insure ISA semantics
|
||||
// (no longer very clean due to the change in setIntReg() in the
|
||||
// cpu model. Consider changing later.)
|
||||
cpu->cpuXC->setIntReg(ZeroReg, 0);
|
||||
cpu->cpuXC->setFloatReg(ZeroReg, 0.0);
|
||||
}
|
||||
|
||||
Fault
|
||||
CPUExecContext::hwrei()
|
||||
{
|
||||
if (!inPalMode())
|
||||
return new UnimplementedOpcodeFault;
|
||||
|
||||
setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR));
|
||||
|
||||
if (!misspeculating()) {
|
||||
cpu->kernelStats->hwrei();
|
||||
|
||||
cpu->checkInterrupts = true;
|
||||
}
|
||||
|
||||
// FIXME: XXX check for interrupts? XXX
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
int
|
||||
AlphaISA::MiscRegFile::getInstAsid()
|
||||
{
|
||||
return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]);
|
||||
}
|
||||
|
||||
int
|
||||
AlphaISA::MiscRegFile::getDataAsid()
|
||||
{
|
||||
return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]);
|
||||
}
|
||||
|
||||
AlphaISA::MiscReg
|
||||
AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc)
|
||||
{
|
||||
uint64_t retval = 0; // return value, default 0
|
||||
|
||||
switch (idx) {
|
||||
case AlphaISA::IPR_PALtemp0:
|
||||
case AlphaISA::IPR_PALtemp1:
|
||||
case AlphaISA::IPR_PALtemp2:
|
||||
case AlphaISA::IPR_PALtemp3:
|
||||
case AlphaISA::IPR_PALtemp4:
|
||||
case AlphaISA::IPR_PALtemp5:
|
||||
case AlphaISA::IPR_PALtemp6:
|
||||
case AlphaISA::IPR_PALtemp7:
|
||||
case AlphaISA::IPR_PALtemp8:
|
||||
case AlphaISA::IPR_PALtemp9:
|
||||
case AlphaISA::IPR_PALtemp10:
|
||||
case AlphaISA::IPR_PALtemp11:
|
||||
case AlphaISA::IPR_PALtemp12:
|
||||
case AlphaISA::IPR_PALtemp13:
|
||||
case AlphaISA::IPR_PALtemp14:
|
||||
case AlphaISA::IPR_PALtemp15:
|
||||
case AlphaISA::IPR_PALtemp16:
|
||||
case AlphaISA::IPR_PALtemp17:
|
||||
case AlphaISA::IPR_PALtemp18:
|
||||
case AlphaISA::IPR_PALtemp19:
|
||||
case AlphaISA::IPR_PALtemp20:
|
||||
case AlphaISA::IPR_PALtemp21:
|
||||
case AlphaISA::IPR_PALtemp22:
|
||||
case AlphaISA::IPR_PALtemp23:
|
||||
case AlphaISA::IPR_PAL_BASE:
|
||||
|
||||
case AlphaISA::IPR_IVPTBR:
|
||||
case AlphaISA::IPR_DC_MODE:
|
||||
case AlphaISA::IPR_MAF_MODE:
|
||||
case AlphaISA::IPR_ISR:
|
||||
case AlphaISA::IPR_EXC_ADDR:
|
||||
case AlphaISA::IPR_IC_PERR_STAT:
|
||||
case AlphaISA::IPR_DC_PERR_STAT:
|
||||
case AlphaISA::IPR_MCSR:
|
||||
case AlphaISA::IPR_ASTRR:
|
||||
case AlphaISA::IPR_ASTER:
|
||||
case AlphaISA::IPR_SIRR:
|
||||
case AlphaISA::IPR_ICSR:
|
||||
case AlphaISA::IPR_ICM:
|
||||
case AlphaISA::IPR_DTB_CM:
|
||||
case AlphaISA::IPR_IPLR:
|
||||
case AlphaISA::IPR_INTID:
|
||||
case AlphaISA::IPR_PMCTR:
|
||||
// no side-effect
|
||||
retval = ipr[idx];
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_CC:
|
||||
retval |= ipr[idx] & ULL(0xffffffff00000000);
|
||||
retval |= xc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff);
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_VA:
|
||||
retval = ipr[idx];
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_VA_FORM:
|
||||
case AlphaISA::IPR_MM_STAT:
|
||||
case AlphaISA::IPR_IFAULT_VA_FORM:
|
||||
case AlphaISA::IPR_EXC_MASK:
|
||||
case AlphaISA::IPR_EXC_SUM:
|
||||
retval = ipr[idx];
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_DTB_PTE:
|
||||
{
|
||||
AlphaISA::PTE &pte = xc->getDTBPtr()->index(!xc->misspeculating());
|
||||
|
||||
retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32;
|
||||
retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8;
|
||||
retval |= ((u_int64_t)pte.xwe & ULL(0xf)) << 12;
|
||||
retval |= ((u_int64_t)pte.fonr & ULL(0x1)) << 1;
|
||||
retval |= ((u_int64_t)pte.fonw & ULL(0x1))<< 2;
|
||||
retval |= ((u_int64_t)pte.asma & ULL(0x1)) << 4;
|
||||
retval |= ((u_int64_t)pte.asn & ULL(0x7f)) << 57;
|
||||
}
|
||||
break;
|
||||
|
||||
// write only registers
|
||||
case AlphaISA::IPR_HWINT_CLR:
|
||||
case AlphaISA::IPR_SL_XMIT:
|
||||
case AlphaISA::IPR_DC_FLUSH:
|
||||
case AlphaISA::IPR_IC_FLUSH:
|
||||
case AlphaISA::IPR_ALT_MODE:
|
||||
case AlphaISA::IPR_DTB_IA:
|
||||
case AlphaISA::IPR_DTB_IAP:
|
||||
case AlphaISA::IPR_ITB_IA:
|
||||
case AlphaISA::IPR_ITB_IAP:
|
||||
fault = new UnimplementedOpcodeFault;
|
||||
break;
|
||||
|
||||
default:
|
||||
// invalid IPR
|
||||
fault = new UnimplementedOpcodeFault;
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Cause the simulator to break when changing to the following IPL
|
||||
int break_ipl = -1;
|
||||
#endif
|
||||
|
||||
Fault
|
||||
AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
|
||||
{
|
||||
uint64_t old;
|
||||
|
||||
if (xc->misspeculating())
|
||||
return NoFault;
|
||||
|
||||
switch (idx) {
|
||||
case AlphaISA::IPR_PALtemp0:
|
||||
case AlphaISA::IPR_PALtemp1:
|
||||
case AlphaISA::IPR_PALtemp2:
|
||||
case AlphaISA::IPR_PALtemp3:
|
||||
case AlphaISA::IPR_PALtemp4:
|
||||
case AlphaISA::IPR_PALtemp5:
|
||||
case AlphaISA::IPR_PALtemp6:
|
||||
case AlphaISA::IPR_PALtemp7:
|
||||
case AlphaISA::IPR_PALtemp8:
|
||||
case AlphaISA::IPR_PALtemp9:
|
||||
case AlphaISA::IPR_PALtemp10:
|
||||
case AlphaISA::IPR_PALtemp11:
|
||||
case AlphaISA::IPR_PALtemp12:
|
||||
case AlphaISA::IPR_PALtemp13:
|
||||
case AlphaISA::IPR_PALtemp14:
|
||||
case AlphaISA::IPR_PALtemp15:
|
||||
case AlphaISA::IPR_PALtemp16:
|
||||
case AlphaISA::IPR_PALtemp17:
|
||||
case AlphaISA::IPR_PALtemp18:
|
||||
case AlphaISA::IPR_PALtemp19:
|
||||
case AlphaISA::IPR_PALtemp20:
|
||||
case AlphaISA::IPR_PALtemp21:
|
||||
case AlphaISA::IPR_PALtemp22:
|
||||
case AlphaISA::IPR_PAL_BASE:
|
||||
case AlphaISA::IPR_IC_PERR_STAT:
|
||||
case AlphaISA::IPR_DC_PERR_STAT:
|
||||
case AlphaISA::IPR_PMCTR:
|
||||
// write entire quad w/ no side-effect
|
||||
ipr[idx] = val;
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_CC_CTL:
|
||||
// This IPR resets the cycle counter. We assume this only
|
||||
// happens once... let's verify that.
|
||||
assert(ipr[idx] == 0);
|
||||
ipr[idx] = 1;
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_CC:
|
||||
// This IPR only writes the upper 64 bits. It's ok to write
|
||||
// all 64 here since we mask out the lower 32 in rpcc (see
|
||||
// isa_desc).
|
||||
ipr[idx] = val;
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_PALtemp23:
|
||||
// write entire quad w/ no side-effect
|
||||
old = ipr[idx];
|
||||
ipr[idx] = val;
|
||||
xc->getCpuPtr()->kernelStats->context(old, val, xc);
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_DTB_PTE:
|
||||
// write entire quad w/ no side-effect, tag is forthcoming
|
||||
ipr[idx] = val;
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_EXC_ADDR:
|
||||
// second least significant bit in PC is always zero
|
||||
ipr[idx] = val & ~2;
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_ASTRR:
|
||||
case AlphaISA::IPR_ASTER:
|
||||
// only write least significant four bits - privilege mask
|
||||
ipr[idx] = val & 0xf;
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_IPLR:
|
||||
#ifdef DEBUG
|
||||
if (break_ipl != -1 && break_ipl == (val & 0x1f))
|
||||
debug_break();
|
||||
#endif
|
||||
|
||||
// only write least significant five bits - interrupt level
|
||||
ipr[idx] = val & 0x1f;
|
||||
xc->getCpuPtr()->kernelStats->swpipl(ipr[idx]);
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_DTB_CM:
|
||||
if (val & 0x18)
|
||||
xc->getCpuPtr()->kernelStats->mode(Kernel::user, xc);
|
||||
else
|
||||
xc->getCpuPtr()->kernelStats->mode(Kernel::kernel, xc);
|
||||
|
||||
case AlphaISA::IPR_ICM:
|
||||
// only write two mode bits - processor mode
|
||||
ipr[idx] = val & 0x18;
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_ALT_MODE:
|
||||
// only write two mode bits - processor mode
|
||||
ipr[idx] = val & 0x18;
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_MCSR:
|
||||
// more here after optimization...
|
||||
ipr[idx] = val;
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_SIRR:
|
||||
// only write software interrupt mask
|
||||
ipr[idx] = val & 0x7fff0;
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_ICSR:
|
||||
ipr[idx] = val & ULL(0xffffff0300);
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_IVPTBR:
|
||||
case AlphaISA::IPR_MVPTBR:
|
||||
ipr[idx] = val & ULL(0xffffffffc0000000);
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_DC_TEST_CTL:
|
||||
ipr[idx] = val & 0x1ffb;
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_DC_MODE:
|
||||
case AlphaISA::IPR_MAF_MODE:
|
||||
ipr[idx] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_ITB_ASN:
|
||||
ipr[idx] = val & 0x7f0;
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_DTB_ASN:
|
||||
ipr[idx] = val & ULL(0xfe00000000000000);
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_EXC_SUM:
|
||||
case AlphaISA::IPR_EXC_MASK:
|
||||
// any write to this register clears it
|
||||
ipr[idx] = 0;
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_INTID:
|
||||
case AlphaISA::IPR_SL_RCV:
|
||||
case AlphaISA::IPR_MM_STAT:
|
||||
case AlphaISA::IPR_ITB_PTE_TEMP:
|
||||
case AlphaISA::IPR_DTB_PTE_TEMP:
|
||||
// read-only registers
|
||||
return new UnimplementedOpcodeFault;
|
||||
|
||||
case AlphaISA::IPR_HWINT_CLR:
|
||||
case AlphaISA::IPR_SL_XMIT:
|
||||
case AlphaISA::IPR_DC_FLUSH:
|
||||
case AlphaISA::IPR_IC_FLUSH:
|
||||
// the following are write only
|
||||
ipr[idx] = val;
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_DTB_IA:
|
||||
// really a control write
|
||||
ipr[idx] = 0;
|
||||
|
||||
xc->getDTBPtr()->flushAll();
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_DTB_IAP:
|
||||
// really a control write
|
||||
ipr[idx] = 0;
|
||||
|
||||
xc->getDTBPtr()->flushProcesses();
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_DTB_IS:
|
||||
// really a control write
|
||||
ipr[idx] = val;
|
||||
|
||||
xc->getDTBPtr()->flushAddr(val,
|
||||
DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_DTB_TAG: {
|
||||
struct AlphaISA::PTE pte;
|
||||
|
||||
// FIXME: granularity hints NYI...
|
||||
if (DTB_PTE_GH(ipr[AlphaISA::IPR_DTB_PTE]) != 0)
|
||||
panic("PTE GH field != 0");
|
||||
|
||||
// write entire quad
|
||||
ipr[idx] = val;
|
||||
|
||||
// construct PTE for new entry
|
||||
pte.ppn = DTB_PTE_PPN(ipr[AlphaISA::IPR_DTB_PTE]);
|
||||
pte.xre = DTB_PTE_XRE(ipr[AlphaISA::IPR_DTB_PTE]);
|
||||
pte.xwe = DTB_PTE_XWE(ipr[AlphaISA::IPR_DTB_PTE]);
|
||||
pte.fonr = DTB_PTE_FONR(ipr[AlphaISA::IPR_DTB_PTE]);
|
||||
pte.fonw = DTB_PTE_FONW(ipr[AlphaISA::IPR_DTB_PTE]);
|
||||
pte.asma = DTB_PTE_ASMA(ipr[AlphaISA::IPR_DTB_PTE]);
|
||||
pte.asn = DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]);
|
||||
|
||||
// insert new TAG/PTE value into data TLB
|
||||
xc->getDTBPtr()->insert(val, pte);
|
||||
}
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_ITB_PTE: {
|
||||
struct AlphaISA::PTE pte;
|
||||
|
||||
// FIXME: granularity hints NYI...
|
||||
if (ITB_PTE_GH(val) != 0)
|
||||
panic("PTE GH field != 0");
|
||||
|
||||
// write entire quad
|
||||
ipr[idx] = val;
|
||||
|
||||
// construct PTE for new entry
|
||||
pte.ppn = ITB_PTE_PPN(val);
|
||||
pte.xre = ITB_PTE_XRE(val);
|
||||
pte.xwe = 0;
|
||||
pte.fonr = ITB_PTE_FONR(val);
|
||||
pte.fonw = ITB_PTE_FONW(val);
|
||||
pte.asma = ITB_PTE_ASMA(val);
|
||||
pte.asn = ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]);
|
||||
|
||||
// insert new TAG/PTE value into data TLB
|
||||
xc->getITBPtr()->insert(ipr[AlphaISA::IPR_ITB_TAG], pte);
|
||||
}
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_ITB_IA:
|
||||
// really a control write
|
||||
ipr[idx] = 0;
|
||||
|
||||
xc->getITBPtr()->flushAll();
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_ITB_IAP:
|
||||
// really a control write
|
||||
ipr[idx] = 0;
|
||||
|
||||
xc->getITBPtr()->flushProcesses();
|
||||
break;
|
||||
|
||||
case AlphaISA::IPR_ITB_IS:
|
||||
// really a control write
|
||||
ipr[idx] = val;
|
||||
|
||||
xc->getITBPtr()->flushAddr(val,
|
||||
ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]));
|
||||
break;
|
||||
|
||||
default:
|
||||
// invalid IPR
|
||||
return new UnimplementedOpcodeFault;
|
||||
}
|
||||
|
||||
// no error...
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
void
|
||||
AlphaISA::copyIprs(ExecContext *src, ExecContext *dest)
|
||||
{
|
||||
for (int i = IPR_Base_DepTag; i < NumInternalProcRegs; ++i) {
|
||||
dest->setMiscReg(i, src->readMiscReg(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for special simulator handling of specific PAL calls.
|
||||
* If return value is false, actual PAL call will be suppressed.
|
||||
*/
|
||||
bool
|
||||
CPUExecContext::simPalCheck(int palFunc)
|
||||
{
|
||||
cpu->kernelStats->callpal(palFunc, proxy);
|
||||
|
||||
switch (palFunc) {
|
||||
case PAL::halt:
|
||||
halt();
|
||||
if (--System::numSystemsRunning == 0)
|
||||
new SimExitEvent("all cpus halted");
|
||||
break;
|
||||
|
||||
case PAL::bpt:
|
||||
case PAL::bugchk:
|
||||
if (system->breakpoint())
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // FULL_SYSTEM
|
||||
121
src/arch/alpha/ev5.hh
Normal file
121
src/arch/alpha/ev5.hh
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ALPHA_EV5_HH__
|
||||
#define __ARCH_ALPHA_EV5_HH__
|
||||
|
||||
#include "config/alpha_tlaser.hh"
|
||||
#include "arch/alpha/isa_traits.hh"
|
||||
|
||||
namespace EV5 {
|
||||
|
||||
//It seems like a safe assumption EV5 only applies to alpha
|
||||
using namespace AlphaISA;
|
||||
|
||||
#if ALPHA_TLASER
|
||||
const uint64_t AsnMask = ULL(0x7f);
|
||||
#else
|
||||
const uint64_t AsnMask = ULL(0xff);
|
||||
#endif
|
||||
|
||||
const int VAddrImplBits = 43;
|
||||
const Addr VAddrImplMask = (ULL(1) << VAddrImplBits) - 1;
|
||||
const Addr VAddrUnImplMask = ~VAddrImplMask;
|
||||
inline Addr VAddrImpl(Addr a) { return a & VAddrImplMask; }
|
||||
inline Addr VAddrVPN(Addr a) { return a >> AlphaISA::PageShift; }
|
||||
inline Addr VAddrOffset(Addr a) { return a & AlphaISA::PageOffset; }
|
||||
inline Addr VAddrSpaceEV5(Addr a) { return a >> 41 & 0x3; }
|
||||
inline Addr VAddrSpaceEV6(Addr a) { return a >> 41 & 0x7f; }
|
||||
|
||||
#if ALPHA_TLASER
|
||||
inline bool PAddrIprSpace(Addr a) { return a >= ULL(0xFFFFF00000); }
|
||||
const int PAddrImplBits = 40;
|
||||
#else
|
||||
inline bool PAddrIprSpace(Addr a) { return a >= ULL(0xFFFFFF00000); }
|
||||
const int PAddrImplBits = 44; // for Tsunami
|
||||
#endif
|
||||
const Addr PAddrImplMask = (ULL(1) << PAddrImplBits) - 1;
|
||||
const Addr PAddrUncachedBit39 = ULL(0x8000000000);
|
||||
const Addr PAddrUncachedBit40 = ULL(0x10000000000);
|
||||
const Addr PAddrUncachedBit43 = ULL(0x80000000000);
|
||||
const Addr PAddrUncachedMask = ULL(0x807ffffffff); // Clear PA<42:35>
|
||||
inline Addr Phys2K0Seg(Addr addr)
|
||||
{
|
||||
#if !ALPHA_TLASER
|
||||
if (addr & PAddrUncachedBit43) {
|
||||
addr &= PAddrUncachedMask;
|
||||
addr |= PAddrUncachedBit40;
|
||||
}
|
||||
#endif
|
||||
return addr | AlphaISA::K0SegBase;
|
||||
}
|
||||
|
||||
inline int DTB_ASN_ASN(uint64_t reg) { return reg >> 57 & AsnMask; }
|
||||
inline Addr DTB_PTE_PPN(uint64_t reg)
|
||||
{ return reg >> 32 & (ULL(1) << PAddrImplBits - AlphaISA::PageShift) - 1; }
|
||||
inline int DTB_PTE_XRE(uint64_t reg) { return reg >> 8 & 0xf; }
|
||||
inline int DTB_PTE_XWE(uint64_t reg) { return reg >> 12 & 0xf; }
|
||||
inline int DTB_PTE_FONR(uint64_t reg) { return reg >> 1 & 0x1; }
|
||||
inline int DTB_PTE_FONW(uint64_t reg) { return reg >> 2 & 0x1; }
|
||||
inline int DTB_PTE_GH(uint64_t reg) { return reg >> 5 & 0x3; }
|
||||
inline int DTB_PTE_ASMA(uint64_t reg) { return reg >> 4 & 0x1; }
|
||||
|
||||
inline int ITB_ASN_ASN(uint64_t reg) { return reg >> 4 & AsnMask; }
|
||||
inline Addr ITB_PTE_PPN(uint64_t reg)
|
||||
{ return reg >> 32 & (ULL(1) << PAddrImplBits - AlphaISA::PageShift) - 1; }
|
||||
inline int ITB_PTE_XRE(uint64_t reg) { return reg >> 8 & 0xf; }
|
||||
inline bool ITB_PTE_FONR(uint64_t reg) { return reg >> 1 & 0x1; }
|
||||
inline bool ITB_PTE_FONW(uint64_t reg) { return reg >> 2 & 0x1; }
|
||||
inline int ITB_PTE_GH(uint64_t reg) { return reg >> 5 & 0x3; }
|
||||
inline bool ITB_PTE_ASMA(uint64_t reg) { return reg >> 4 & 0x1; }
|
||||
|
||||
inline uint64_t MCSR_SP(uint64_t reg) { return reg >> 1 & 0x3; }
|
||||
|
||||
inline bool ICSR_SDE(uint64_t reg) { return reg >> 30 & 0x1; }
|
||||
inline int ICSR_SPE(uint64_t reg) { return reg >> 28 & 0x3; }
|
||||
inline bool ICSR_FPE(uint64_t reg) { return reg >> 26 & 0x1; }
|
||||
|
||||
inline uint64_t ALT_MODE_AM(uint64_t reg) { return reg >> 3 & 0x3; }
|
||||
inline uint64_t DTB_CM_CM(uint64_t reg) { return reg >> 3 & 0x3; }
|
||||
inline uint64_t ICM_CM(uint64_t reg) { return reg >> 3 & 0x3; }
|
||||
|
||||
const uint64_t MM_STAT_BAD_VA_MASK = ULL(0x0020);
|
||||
const uint64_t MM_STAT_DTB_MISS_MASK = ULL(0x0010);
|
||||
const uint64_t MM_STAT_FONW_MASK = ULL(0x0008);
|
||||
const uint64_t MM_STAT_FONR_MASK = ULL(0x0004);
|
||||
const uint64_t MM_STAT_ACV_MASK = ULL(0x0002);
|
||||
const uint64_t MM_STAT_WR_MASK = ULL(0x0001);
|
||||
inline int Opcode(AlphaISA::MachInst inst) { return inst >> 26 & 0x3f; }
|
||||
inline int Ra(AlphaISA::MachInst inst) { return inst >> 21 & 0x1f; }
|
||||
|
||||
const Addr PalBase = 0x4000;
|
||||
const Addr PalMax = 0x10000;
|
||||
|
||||
/* namespace EV5 */ }
|
||||
|
||||
#endif // __ARCH_ALPHA_EV5_HH__
|
||||
176
src/arch/alpha/faults.cc
Normal file
176
src/arch/alpha/faults.cc
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arch/alpha/faults.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "base/trace.hh"
|
||||
#if FULL_SYSTEM
|
||||
#include "arch/alpha/ev5.hh"
|
||||
#endif
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
|
||||
FaultName MachineCheckFault::_name = "mchk";
|
||||
FaultVect MachineCheckFault::_vect = 0x0401;
|
||||
FaultStat MachineCheckFault::_count;
|
||||
|
||||
FaultName AlignmentFault::_name = "unalign";
|
||||
FaultVect AlignmentFault::_vect = 0x0301;
|
||||
FaultStat AlignmentFault::_count;
|
||||
|
||||
FaultName ResetFault::_name = "reset";
|
||||
FaultVect ResetFault::_vect = 0x0001;
|
||||
FaultStat ResetFault::_count;
|
||||
|
||||
FaultName ArithmeticFault::_name = "arith";
|
||||
FaultVect ArithmeticFault::_vect = 0x0501;
|
||||
FaultStat ArithmeticFault::_count;
|
||||
|
||||
FaultName InterruptFault::_name = "interrupt";
|
||||
FaultVect InterruptFault::_vect = 0x0101;
|
||||
FaultStat InterruptFault::_count;
|
||||
|
||||
FaultName NDtbMissFault::_name = "dtb_miss_single";
|
||||
FaultVect NDtbMissFault::_vect = 0x0201;
|
||||
FaultStat NDtbMissFault::_count;
|
||||
|
||||
FaultName PDtbMissFault::_name = "dtb_miss_double";
|
||||
FaultVect PDtbMissFault::_vect = 0x0281;
|
||||
FaultStat PDtbMissFault::_count;
|
||||
|
||||
FaultName DtbPageFault::_name = "dfault";
|
||||
FaultVect DtbPageFault::_vect = 0x0381;
|
||||
FaultStat DtbPageFault::_count;
|
||||
|
||||
FaultName DtbAcvFault::_name = "dfault";
|
||||
FaultVect DtbAcvFault::_vect = 0x0381;
|
||||
FaultStat DtbAcvFault::_count;
|
||||
|
||||
FaultName DtbAlignmentFault::_name = "unalign";
|
||||
FaultVect DtbAlignmentFault::_vect = 0x0301;
|
||||
FaultStat DtbAlignmentFault::_count;
|
||||
|
||||
FaultName ItbMissFault::_name = "itbmiss";
|
||||
FaultVect ItbMissFault::_vect = 0x0181;
|
||||
FaultStat ItbMissFault::_count;
|
||||
|
||||
FaultName ItbPageFault::_name = "itbmiss";
|
||||
FaultVect ItbPageFault::_vect = 0x0181;
|
||||
FaultStat ItbPageFault::_count;
|
||||
|
||||
FaultName ItbAcvFault::_name = "iaccvio";
|
||||
FaultVect ItbAcvFault::_vect = 0x0081;
|
||||
FaultStat ItbAcvFault::_count;
|
||||
|
||||
FaultName UnimplementedOpcodeFault::_name = "opdec";
|
||||
FaultVect UnimplementedOpcodeFault::_vect = 0x0481;
|
||||
FaultStat UnimplementedOpcodeFault::_count;
|
||||
|
||||
FaultName FloatEnableFault::_name = "fen";
|
||||
FaultVect FloatEnableFault::_vect = 0x0581;
|
||||
FaultStat FloatEnableFault::_count;
|
||||
|
||||
FaultName PalFault::_name = "pal";
|
||||
FaultVect PalFault::_vect = 0x2001;
|
||||
FaultStat PalFault::_count;
|
||||
|
||||
FaultName IntegerOverflowFault::_name = "intover";
|
||||
FaultVect IntegerOverflowFault::_vect = 0x0501;
|
||||
FaultStat IntegerOverflowFault::_count;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
|
||||
void AlphaFault::invoke(ExecContext * xc)
|
||||
{
|
||||
FaultBase::invoke(xc);
|
||||
countStat()++;
|
||||
|
||||
// exception restart address
|
||||
if (setRestartAddress() || !xc->inPalMode())
|
||||
xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->readPC());
|
||||
|
||||
if (skipFaultingInstruction()) {
|
||||
// traps... skip faulting instruction.
|
||||
xc->setMiscReg(AlphaISA::IPR_EXC_ADDR,
|
||||
xc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4);
|
||||
}
|
||||
|
||||
xc->setPC(xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect());
|
||||
xc->setNextPC(xc->readPC() + sizeof(MachInst));
|
||||
}
|
||||
|
||||
void ArithmeticFault::invoke(ExecContext * xc)
|
||||
{
|
||||
FaultBase::invoke(xc);
|
||||
panic("Arithmetic traps are unimplemented!");
|
||||
}
|
||||
|
||||
void DtbFault::invoke(ExecContext * xc)
|
||||
{
|
||||
// Set fault address and flags. Even though we're modeling an
|
||||
// EV5, we use the EV6 technique of not latching fault registers
|
||||
// on VPTE loads (instead of locking the registers until IPR_VA is
|
||||
// read, like the EV5). The EV6 approach is cleaner and seems to
|
||||
// work with EV5 PAL code, but not the other way around.
|
||||
if (!xc->misspeculating()
|
||||
&& !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) {
|
||||
// set VA register with faulting address
|
||||
xc->setMiscReg(AlphaISA::IPR_VA, vaddr);
|
||||
|
||||
// set MM_STAT register flags
|
||||
xc->setMiscReg(AlphaISA::IPR_MM_STAT,
|
||||
(((EV5::Opcode(xc->getInst()) & 0x3f) << 11)
|
||||
| ((EV5::Ra(xc->getInst()) & 0x1f) << 6)
|
||||
| (flags & 0x3f)));
|
||||
|
||||
// set VA_FORM register with faulting formatted address
|
||||
xc->setMiscReg(AlphaISA::IPR_VA_FORM,
|
||||
xc->readMiscReg(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3));
|
||||
}
|
||||
|
||||
AlphaFault::invoke(xc);
|
||||
}
|
||||
|
||||
void ItbFault::invoke(ExecContext * xc)
|
||||
{
|
||||
if (!xc->misspeculating()) {
|
||||
xc->setMiscReg(AlphaISA::IPR_ITB_TAG, pc);
|
||||
xc->setMiscReg(AlphaISA::IPR_IFAULT_VA_FORM,
|
||||
xc->readMiscReg(AlphaISA::IPR_IVPTBR) |
|
||||
(AlphaISA::VAddr(pc).vpn() << 3));
|
||||
}
|
||||
|
||||
AlphaFault::invoke(xc);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
352
src/arch/alpha/faults.hh
Normal file
352
src/arch/alpha/faults.hh
Normal file
@@ -0,0 +1,352 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ALPHA_FAULTS_HH__
|
||||
#define __ALPHA_FAULTS_HH__
|
||||
|
||||
#include "arch/alpha/isa_traits.hh"
|
||||
#include "sim/faults.hh"
|
||||
|
||||
// The design of the "name" and "vect" functions is in sim/faults.hh
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
|
||||
typedef const Addr FaultVect;
|
||||
|
||||
class AlphaFault : public FaultBase
|
||||
{
|
||||
protected:
|
||||
virtual bool skipFaultingInstruction() {return false;}
|
||||
virtual bool setRestartAddress() {return true;}
|
||||
public:
|
||||
#if FULL_SYSTEM
|
||||
void invoke(ExecContext * xc);
|
||||
#endif
|
||||
virtual FaultVect vect() = 0;
|
||||
virtual FaultStat & countStat() = 0;
|
||||
};
|
||||
|
||||
class MachineCheckFault : public AlphaFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
bool isMachineCheckFault() {return true;}
|
||||
};
|
||||
|
||||
class AlignmentFault : public AlphaFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
bool isAlignmentFault() {return true;}
|
||||
};
|
||||
|
||||
static inline Fault genMachineCheckFault()
|
||||
{
|
||||
return new MachineCheckFault;
|
||||
}
|
||||
|
||||
static inline Fault genAlignmentFault()
|
||||
{
|
||||
return new AlignmentFault;
|
||||
}
|
||||
|
||||
class ResetFault : public AlphaFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class ArithmeticFault : public AlphaFault
|
||||
{
|
||||
protected:
|
||||
bool skipFaultingInstruction() {return true;}
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
#if FULL_SYSTEM
|
||||
void invoke(ExecContext * xc);
|
||||
#endif
|
||||
};
|
||||
|
||||
class InterruptFault : public AlphaFault
|
||||
{
|
||||
protected:
|
||||
bool setRestartAddress() {return false;}
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class DtbFault : public AlphaFault
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
private:
|
||||
AlphaISA::VAddr vaddr;
|
||||
uint32_t reqFlags;
|
||||
uint64_t flags;
|
||||
public:
|
||||
DtbFault(AlphaISA::VAddr _vaddr, uint32_t _reqFlags, uint64_t _flags)
|
||||
: vaddr(_vaddr), reqFlags(_reqFlags), flags(_flags)
|
||||
{ }
|
||||
#endif
|
||||
FaultName name() = 0;
|
||||
FaultVect vect() = 0;
|
||||
FaultStat & countStat() = 0;
|
||||
#if FULL_SYSTEM
|
||||
void invoke(ExecContext * xc);
|
||||
#endif
|
||||
};
|
||||
|
||||
class NDtbMissFault : public DtbFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
#if FULL_SYSTEM
|
||||
NDtbMissFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
||||
: DtbFault(vaddr, reqFlags, flags)
|
||||
{ }
|
||||
#endif
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class PDtbMissFault : public DtbFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
#if FULL_SYSTEM
|
||||
PDtbMissFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
||||
: DtbFault(vaddr, reqFlags, flags)
|
||||
{ }
|
||||
#endif
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class DtbPageFault : public DtbFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
#if FULL_SYSTEM
|
||||
DtbPageFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
||||
: DtbFault(vaddr, reqFlags, flags)
|
||||
{ }
|
||||
#endif
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class DtbAcvFault : public DtbFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
#if FULL_SYSTEM
|
||||
DtbAcvFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
||||
: DtbFault(vaddr, reqFlags, flags)
|
||||
{ }
|
||||
#endif
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class DtbAlignmentFault : public DtbFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
#if FULL_SYSTEM
|
||||
DtbAlignmentFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
||||
: DtbFault(vaddr, reqFlags, flags)
|
||||
{ }
|
||||
#endif
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class ItbFault : public AlphaFault
|
||||
{
|
||||
private:
|
||||
Addr pc;
|
||||
public:
|
||||
ItbFault(Addr _pc)
|
||||
: pc(_pc)
|
||||
{ }
|
||||
FaultName name() = 0;
|
||||
FaultVect vect() = 0;
|
||||
FaultStat & countStat() = 0;
|
||||
#if FULL_SYSTEM
|
||||
void invoke(ExecContext * xc);
|
||||
#endif
|
||||
};
|
||||
|
||||
class ItbMissFault : public ItbFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
ItbMissFault(Addr pc)
|
||||
: ItbFault(pc)
|
||||
{ }
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class ItbPageFault : public ItbFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
ItbPageFault(Addr pc)
|
||||
: ItbFault(pc)
|
||||
{ }
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class ItbAcvFault : public ItbFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
ItbAcvFault(Addr pc)
|
||||
: ItbFault(pc)
|
||||
{ }
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class UnimplementedOpcodeFault : public AlphaFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class FloatEnableFault : public AlphaFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class PalFault : public AlphaFault
|
||||
{
|
||||
protected:
|
||||
bool skipFaultingInstruction() {return true;}
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class IntegerOverflowFault : public AlphaFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
} // AlphaISA namespace
|
||||
|
||||
#endif // __FAULTS_HH__
|
||||
156
src/arch/alpha/freebsd/system.cc
Normal file
156
src/arch/alpha/freebsd/system.cc
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Modifications for the FreeBSD kernel.
|
||||
* Based on kern/linux/linux_system.cc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "arch/alpha/system.hh"
|
||||
#include "arch/alpha/freebsd/system.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "mem/physical.hh"
|
||||
#include "mem/port.hh"
|
||||
#include "arch/isa_traits.hh"
|
||||
#include "sim/builder.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
#include "arch/vtophys.hh"
|
||||
|
||||
#define TIMER_FREQUENCY 1193180
|
||||
|
||||
using namespace std;
|
||||
using namespace AlphaISA;
|
||||
|
||||
FreebsdAlphaSystem::FreebsdAlphaSystem(Params *p)
|
||||
: AlphaSystem(p)
|
||||
{
|
||||
/**
|
||||
* Any time DELAY is called just skip the function.
|
||||
* Shouldn't we actually emulate the delay?
|
||||
*/
|
||||
skipDelayEvent = addKernelFuncEvent<SkipFuncEvent>("DELAY");
|
||||
skipCalibrateClocks =
|
||||
addKernelFuncEvent<SkipCalibrateClocksEvent>("calibrate_clocks");
|
||||
}
|
||||
|
||||
|
||||
FreebsdAlphaSystem::~FreebsdAlphaSystem()
|
||||
{
|
||||
delete skipDelayEvent;
|
||||
delete skipCalibrateClocks;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FreebsdAlphaSystem::doCalibrateClocks(ExecContext *xc)
|
||||
{
|
||||
Addr ppc_vaddr = 0;
|
||||
Addr timer_vaddr = 0;
|
||||
|
||||
ppc_vaddr = (Addr)xc->readIntReg(ArgumentReg1);
|
||||
timer_vaddr = (Addr)xc->readIntReg(ArgumentReg2);
|
||||
|
||||
virtPort.write(ppc_vaddr, (uint32_t)Clock::Frequency);
|
||||
virtPort.write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ExecContext *xc)
|
||||
{
|
||||
SkipFuncEvent::process(xc);
|
||||
((FreebsdAlphaSystem *)xc->getSystemPtr())->doCalibrateClocks(xc);
|
||||
}
|
||||
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
|
||||
|
||||
Param<Tick> boot_cpu_frequency;
|
||||
SimObjectParam<PhysicalMemory *> physmem;
|
||||
|
||||
Param<string> kernel;
|
||||
Param<string> console;
|
||||
Param<string> pal;
|
||||
|
||||
Param<string> boot_osflags;
|
||||
Param<string> readfile;
|
||||
Param<unsigned int> init_param;
|
||||
|
||||
Param<uint64_t> system_type;
|
||||
Param<uint64_t> system_rev;
|
||||
|
||||
Param<bool> bin;
|
||||
VectorParam<string> binned_fns;
|
||||
Param<bool> bin_int;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
|
||||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
|
||||
|
||||
INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
|
||||
INIT_PARAM(physmem, "phsyical memory"),
|
||||
INIT_PARAM(kernel, "file that contains the kernel code"),
|
||||
INIT_PARAM(console, "file that contains the console code"),
|
||||
INIT_PARAM(pal, "file that contains palcode"),
|
||||
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
|
||||
"a"),
|
||||
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
|
||||
INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
|
||||
INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
|
||||
INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10),
|
||||
INIT_PARAM_DFLT(bin, "is this system to be binned", false),
|
||||
INIT_PARAM(binned_fns, "functions to be broken down and binned"),
|
||||
INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true)
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
|
||||
|
||||
CREATE_SIM_OBJECT(FreebsdAlphaSystem)
|
||||
{
|
||||
AlphaSystem::Params *p = new AlphaSystem::Params;
|
||||
p->name = getInstanceName();
|
||||
p->boot_cpu_frequency = boot_cpu_frequency;
|
||||
p->physmem = physmem;
|
||||
p->kernel_path = kernel;
|
||||
p->console_path = console;
|
||||
p->palcode = pal;
|
||||
p->boot_osflags = boot_osflags;
|
||||
p->init_param = init_param;
|
||||
p->readfile = readfile;
|
||||
p->system_type = system_type;
|
||||
p->system_rev = system_rev;
|
||||
p->bin = bin;
|
||||
p->binned_fns = binned_fns;
|
||||
p->bin_int = bin_int;
|
||||
return new FreebsdAlphaSystem(p);
|
||||
}
|
||||
|
||||
REGISTER_SIM_OBJECT("FreebsdAlphaSystem", FreebsdAlphaSystem)
|
||||
|
||||
56
src/arch/alpha/freebsd/system.hh
Normal file
56
src/arch/alpha/freebsd/system.hh
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __KERN_FREEBSD_FREEBSD_SYSTEM_HH__
|
||||
#define __KERN_FREEBSD_FREEBSD_SYSTEM_HH__
|
||||
|
||||
#include "kern/system_events.hh"
|
||||
|
||||
class FreebsdAlphaSystem : public AlphaSystem
|
||||
{
|
||||
private:
|
||||
class SkipCalibrateClocksEvent : public SkipFuncEvent
|
||||
{
|
||||
public:
|
||||
SkipCalibrateClocksEvent(PCEventQueue *q, const std::string &desc,
|
||||
Addr addr)
|
||||
: SkipFuncEvent(q, desc, addr) {}
|
||||
virtual void process(ExecContext *xc);
|
||||
};
|
||||
|
||||
SkipFuncEvent *skipDelayEvent;
|
||||
SkipCalibrateClocksEvent *skipCalibrateClocks;
|
||||
|
||||
public:
|
||||
FreebsdAlphaSystem(Params *p);
|
||||
~FreebsdAlphaSystem();
|
||||
void doCalibrateClocks(ExecContext *xc);
|
||||
|
||||
};
|
||||
|
||||
#endif // __KERN_FREEBSD_FREEBSD_SYSTEM_HH__
|
||||
259
src/arch/alpha/isa/branch.isa
Normal file
259
src/arch/alpha/isa/branch.isa
Normal file
@@ -0,0 +1,259 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
output header {{
|
||||
|
||||
/**
|
||||
* Base class for instructions whose disassembly is not purely a
|
||||
* function of the machine instruction (i.e., it depends on the
|
||||
* PC). This class overrides the disassemble() method to check
|
||||
* the PC and symbol table values before re-using a cached
|
||||
* disassembly string. This is necessary for branches and jumps,
|
||||
* where the disassembly string includes the target address (which
|
||||
* may depend on the PC and/or symbol table).
|
||||
*/
|
||||
class PCDependentDisassembly : public AlphaStaticInst
|
||||
{
|
||||
protected:
|
||||
/// Cached program counter from last disassembly
|
||||
mutable Addr cachedPC;
|
||||
/// Cached symbol table pointer from last disassembly
|
||||
mutable const SymbolTable *cachedSymtab;
|
||||
|
||||
/// Constructor
|
||||
PCDependentDisassembly(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass)
|
||||
: AlphaStaticInst(mnem, _machInst, __opClass),
|
||||
cachedPC(0), cachedSymtab(0)
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &
|
||||
disassemble(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for branches (PC-relative control transfers),
|
||||
* conditional or unconditional.
|
||||
*/
|
||||
class Branch : public PCDependentDisassembly
|
||||
{
|
||||
protected:
|
||||
/// Displacement to target address (signed).
|
||||
int32_t disp;
|
||||
|
||||
/// Constructor.
|
||||
Branch(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
|
||||
: PCDependentDisassembly(mnem, _machInst, __opClass),
|
||||
disp(BRDISP << 2)
|
||||
{
|
||||
}
|
||||
|
||||
Addr branchTarget(Addr branchPC) const;
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for jumps (register-indirect control transfers). In
|
||||
* the Alpha ISA, these are always unconditional.
|
||||
*/
|
||||
class Jump : public PCDependentDisassembly
|
||||
{
|
||||
protected:
|
||||
|
||||
/// Displacement to target address (signed).
|
||||
int32_t disp;
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
Jump(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
|
||||
: PCDependentDisassembly(mnem, _machInst, __opClass),
|
||||
disp(BRDISP)
|
||||
{
|
||||
}
|
||||
|
||||
Addr branchTarget(ExecContext *xc) const;
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
Addr
|
||||
Branch::branchTarget(Addr branchPC) const
|
||||
{
|
||||
return branchPC + 4 + disp;
|
||||
}
|
||||
|
||||
Addr
|
||||
Jump::branchTarget(ExecContext *xc) const
|
||||
{
|
||||
Addr NPC = xc->readPC() + 4;
|
||||
uint64_t Rb = xc->readIntReg(_srcRegIdx[0]);
|
||||
return (Rb & ~3) | (NPC & 1);
|
||||
}
|
||||
|
||||
const std::string &
|
||||
PCDependentDisassembly::disassemble(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
if (!cachedDisassembly ||
|
||||
pc != cachedPC || symtab != cachedSymtab)
|
||||
{
|
||||
if (cachedDisassembly)
|
||||
delete cachedDisassembly;
|
||||
|
||||
cachedDisassembly =
|
||||
new std::string(generateDisassembly(pc, symtab));
|
||||
cachedPC = pc;
|
||||
cachedSymtab = symtab;
|
||||
}
|
||||
|
||||
return *cachedDisassembly;
|
||||
}
|
||||
|
||||
std::string
|
||||
Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ccprintf(ss, "%-10s ", mnemonic);
|
||||
|
||||
// There's only one register arg (RA), but it could be
|
||||
// either a source (the condition for conditional
|
||||
// branches) or a destination (the link reg for
|
||||
// unconditional branches)
|
||||
if (_numSrcRegs > 0) {
|
||||
printReg(ss, _srcRegIdx[0]);
|
||||
ss << ",";
|
||||
}
|
||||
else if (_numDestRegs > 0) {
|
||||
printReg(ss, _destRegIdx[0]);
|
||||
ss << ",";
|
||||
}
|
||||
|
||||
#ifdef SS_COMPATIBLE_DISASSEMBLY
|
||||
if (_numSrcRegs == 0 && _numDestRegs == 0) {
|
||||
printReg(ss, 31);
|
||||
ss << ",";
|
||||
}
|
||||
#endif
|
||||
|
||||
Addr target = pc + 4 + disp;
|
||||
|
||||
std::string str;
|
||||
if (symtab && symtab->findSymbol(target, str))
|
||||
ss << str;
|
||||
else
|
||||
ccprintf(ss, "0x%x", target);
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ccprintf(ss, "%-10s ", mnemonic);
|
||||
|
||||
#ifdef SS_COMPATIBLE_DISASSEMBLY
|
||||
if (_numDestRegs == 0) {
|
||||
printReg(ss, 31);
|
||||
ss << ",";
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_numDestRegs > 0) {
|
||||
printReg(ss, _destRegIdx[0]);
|
||||
ss << ",";
|
||||
}
|
||||
|
||||
ccprintf(ss, "(r%d)", RB);
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
}};
|
||||
|
||||
def template JumpOrBranchDecode {{
|
||||
return (RA == 31)
|
||||
? (StaticInst *)new %(class_name)s(machInst)
|
||||
: (StaticInst *)new %(class_name)sAndLink(machInst);
|
||||
}};
|
||||
|
||||
def format CondBranch(code) {{
|
||||
code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n';
|
||||
iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
|
||||
('IsDirectControl', 'IsCondControl'))
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
let {{
|
||||
def UncondCtrlBase(name, Name, base_class, npc_expr, flags):
|
||||
# Declare basic control transfer w/o link (i.e. link reg is R31)
|
||||
nolink_code = 'NPC = %s;\n' % npc_expr
|
||||
nolink_iop = InstObjParams(name, Name, base_class,
|
||||
CodeBlock(nolink_code), flags)
|
||||
header_output = BasicDeclare.subst(nolink_iop)
|
||||
decoder_output = BasicConstructor.subst(nolink_iop)
|
||||
exec_output = BasicExecute.subst(nolink_iop)
|
||||
|
||||
# Generate declaration of '*AndLink' version, append to decls
|
||||
link_code = 'Ra = NPC & ~3;\n' + nolink_code
|
||||
link_iop = InstObjParams(name, Name + 'AndLink', base_class,
|
||||
CodeBlock(link_code), flags)
|
||||
header_output += BasicDeclare.subst(link_iop)
|
||||
decoder_output += BasicConstructor.subst(link_iop)
|
||||
exec_output += BasicExecute.subst(link_iop)
|
||||
|
||||
# need to use link_iop for the decode template since it is expecting
|
||||
# the shorter version of class_name (w/o "AndLink")
|
||||
|
||||
return (header_output, decoder_output,
|
||||
JumpOrBranchDecode.subst(nolink_iop), exec_output)
|
||||
}};
|
||||
|
||||
def format UncondBranch(*flags) {{
|
||||
flags += ('IsUncondControl', 'IsDirectControl')
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
UncondCtrlBase(name, Name, 'Branch', 'NPC + disp', flags)
|
||||
}};
|
||||
|
||||
def format Jump(*flags) {{
|
||||
flags += ('IsUncondControl', 'IsIndirectControl')
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
UncondCtrlBase(name, Name, 'Jump', '(Rb & ~3) | (NPC & 1)', flags)
|
||||
}};
|
||||
|
||||
|
||||
819
src/arch/alpha/isa/decoder.isa
Normal file
819
src/arch/alpha/isa/decoder.isa
Normal file
@@ -0,0 +1,819 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
decode OPCODE default Unknown::unknown() {
|
||||
|
||||
format LoadAddress {
|
||||
0x08: lda({{ Ra = Rb + disp; }});
|
||||
0x09: ldah({{ Ra = Rb + (disp << 16); }});
|
||||
}
|
||||
|
||||
format LoadOrNop {
|
||||
0x0a: ldbu({{ Ra.uq = Mem.ub; }});
|
||||
0x0c: ldwu({{ Ra.uq = Mem.uw; }});
|
||||
0x0b: ldq_u({{ Ra = Mem.uq; }}, ea_code = {{ EA = (Rb + disp) & ~7; }});
|
||||
0x23: ldt({{ Fa = Mem.df; }});
|
||||
0x2a: ldl_l({{ Ra.sl = Mem.sl; }}, mem_flags = LOCKED);
|
||||
0x2b: ldq_l({{ Ra.uq = Mem.uq; }}, mem_flags = LOCKED);
|
||||
0x20: MiscPrefetch::copy_load({{ EA = Ra; }},
|
||||
{{ fault = xc->copySrcTranslate(EA); }},
|
||||
inst_flags = [IsMemRef, IsLoad, IsCopy]);
|
||||
}
|
||||
|
||||
format LoadOrPrefetch {
|
||||
0x28: ldl({{ Ra.sl = Mem.sl; }});
|
||||
0x29: ldq({{ Ra.uq = Mem.uq; }}, pf_flags = EVICT_NEXT);
|
||||
// IsFloating flag on lds gets the prefetch to disassemble
|
||||
// using f31 instead of r31... funcitonally it's unnecessary
|
||||
0x22: lds({{ Fa.uq = s_to_t(Mem.ul); }},
|
||||
pf_flags = PF_EXCLUSIVE, inst_flags = IsFloating);
|
||||
}
|
||||
|
||||
format Store {
|
||||
0x0e: stb({{ Mem.ub = Ra<7:0>; }});
|
||||
0x0d: stw({{ Mem.uw = Ra<15:0>; }});
|
||||
0x2c: stl({{ Mem.ul = Ra<31:0>; }});
|
||||
0x2d: stq({{ Mem.uq = Ra.uq; }});
|
||||
0x0f: stq_u({{ Mem.uq = Ra.uq; }}, {{ EA = (Rb + disp) & ~7; }});
|
||||
0x26: sts({{ Mem.ul = t_to_s(Fa.uq); }});
|
||||
0x27: stt({{ Mem.df = Fa; }});
|
||||
0x24: MiscPrefetch::copy_store({{ EA = Rb; }},
|
||||
{{ fault = xc->copy(EA); }},
|
||||
inst_flags = [IsMemRef, IsStore, IsCopy]);
|
||||
}
|
||||
|
||||
format StoreCond {
|
||||
0x2e: stl_c({{ Mem.ul = Ra<31:0>; }},
|
||||
{{
|
||||
uint64_t tmp = write_result;
|
||||
// see stq_c
|
||||
Ra = (tmp == 0 || tmp == 1) ? tmp : Ra;
|
||||
}}, mem_flags = LOCKED);
|
||||
0x2f: stq_c({{ Mem.uq = Ra; }},
|
||||
{{
|
||||
uint64_t tmp = write_result;
|
||||
// If the write operation returns 0 or 1, then
|
||||
// this was a conventional store conditional,
|
||||
// and the value indicates the success/failure
|
||||
// of the operation. If another value is
|
||||
// returned, then this was a Turbolaser
|
||||
// mailbox access, and we don't update the
|
||||
// result register at all.
|
||||
Ra = (tmp == 0 || tmp == 1) ? tmp : Ra;
|
||||
}}, mem_flags = LOCKED);
|
||||
}
|
||||
|
||||
format IntegerOperate {
|
||||
|
||||
0x10: decode INTFUNC { // integer arithmetic operations
|
||||
|
||||
0x00: addl({{ Rc.sl = Ra.sl + Rb_or_imm.sl; }});
|
||||
0x40: addlv({{
|
||||
uint32_t tmp = Ra.sl + Rb_or_imm.sl;
|
||||
// signed overflow occurs when operands have same sign
|
||||
// and sign of result does not match.
|
||||
if (Ra.sl<31:> == Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>)
|
||||
fault = new IntegerOverflowFault;
|
||||
Rc.sl = tmp;
|
||||
}});
|
||||
0x02: s4addl({{ Rc.sl = (Ra.sl << 2) + Rb_or_imm.sl; }});
|
||||
0x12: s8addl({{ Rc.sl = (Ra.sl << 3) + Rb_or_imm.sl; }});
|
||||
|
||||
0x20: addq({{ Rc = Ra + Rb_or_imm; }});
|
||||
0x60: addqv({{
|
||||
uint64_t tmp = Ra + Rb_or_imm;
|
||||
// signed overflow occurs when operands have same sign
|
||||
// and sign of result does not match.
|
||||
if (Ra<63:> == Rb_or_imm<63:> && tmp<63:> != Ra<63:>)
|
||||
fault = new IntegerOverflowFault;
|
||||
Rc = tmp;
|
||||
}});
|
||||
0x22: s4addq({{ Rc = (Ra << 2) + Rb_or_imm; }});
|
||||
0x32: s8addq({{ Rc = (Ra << 3) + Rb_or_imm; }});
|
||||
|
||||
0x09: subl({{ Rc.sl = Ra.sl - Rb_or_imm.sl; }});
|
||||
0x49: sublv({{
|
||||
uint32_t tmp = Ra.sl - Rb_or_imm.sl;
|
||||
// signed overflow detection is same as for add,
|
||||
// except we need to look at the *complemented*
|
||||
// sign bit of the subtrahend (Rb), i.e., if the initial
|
||||
// signs are the *same* then no overflow can occur
|
||||
if (Ra.sl<31:> != Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>)
|
||||
fault = new IntegerOverflowFault;
|
||||
Rc.sl = tmp;
|
||||
}});
|
||||
0x0b: s4subl({{ Rc.sl = (Ra.sl << 2) - Rb_or_imm.sl; }});
|
||||
0x1b: s8subl({{ Rc.sl = (Ra.sl << 3) - Rb_or_imm.sl; }});
|
||||
|
||||
0x29: subq({{ Rc = Ra - Rb_or_imm; }});
|
||||
0x69: subqv({{
|
||||
uint64_t tmp = Ra - Rb_or_imm;
|
||||
// signed overflow detection is same as for add,
|
||||
// except we need to look at the *complemented*
|
||||
// sign bit of the subtrahend (Rb), i.e., if the initial
|
||||
// signs are the *same* then no overflow can occur
|
||||
if (Ra<63:> != Rb_or_imm<63:> && tmp<63:> != Ra<63:>)
|
||||
fault = new IntegerOverflowFault;
|
||||
Rc = tmp;
|
||||
}});
|
||||
0x2b: s4subq({{ Rc = (Ra << 2) - Rb_or_imm; }});
|
||||
0x3b: s8subq({{ Rc = (Ra << 3) - Rb_or_imm; }});
|
||||
|
||||
0x2d: cmpeq({{ Rc = (Ra == Rb_or_imm); }});
|
||||
0x6d: cmple({{ Rc = (Ra.sq <= Rb_or_imm.sq); }});
|
||||
0x4d: cmplt({{ Rc = (Ra.sq < Rb_or_imm.sq); }});
|
||||
0x3d: cmpule({{ Rc = (Ra.uq <= Rb_or_imm.uq); }});
|
||||
0x1d: cmpult({{ Rc = (Ra.uq < Rb_or_imm.uq); }});
|
||||
|
||||
0x0f: cmpbge({{
|
||||
int hi = 7;
|
||||
int lo = 0;
|
||||
uint64_t tmp = 0;
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
tmp |= (Ra.uq<hi:lo> >= Rb_or_imm.uq<hi:lo>) << i;
|
||||
hi += 8;
|
||||
lo += 8;
|
||||
}
|
||||
Rc = tmp;
|
||||
}});
|
||||
}
|
||||
|
||||
0x11: decode INTFUNC { // integer logical operations
|
||||
|
||||
0x00: and({{ Rc = Ra & Rb_or_imm; }});
|
||||
0x08: bic({{ Rc = Ra & ~Rb_or_imm; }});
|
||||
0x20: bis({{ Rc = Ra | Rb_or_imm; }});
|
||||
0x28: ornot({{ Rc = Ra | ~Rb_or_imm; }});
|
||||
0x40: xor({{ Rc = Ra ^ Rb_or_imm; }});
|
||||
0x48: eqv({{ Rc = Ra ^ ~Rb_or_imm; }});
|
||||
|
||||
// conditional moves
|
||||
0x14: cmovlbs({{ Rc = ((Ra & 1) == 1) ? Rb_or_imm : Rc; }});
|
||||
0x16: cmovlbc({{ Rc = ((Ra & 1) == 0) ? Rb_or_imm : Rc; }});
|
||||
0x24: cmoveq({{ Rc = (Ra == 0) ? Rb_or_imm : Rc; }});
|
||||
0x26: cmovne({{ Rc = (Ra != 0) ? Rb_or_imm : Rc; }});
|
||||
0x44: cmovlt({{ Rc = (Ra.sq < 0) ? Rb_or_imm : Rc; }});
|
||||
0x46: cmovge({{ Rc = (Ra.sq >= 0) ? Rb_or_imm : Rc; }});
|
||||
0x64: cmovle({{ Rc = (Ra.sq <= 0) ? Rb_or_imm : Rc; }});
|
||||
0x66: cmovgt({{ Rc = (Ra.sq > 0) ? Rb_or_imm : Rc; }});
|
||||
|
||||
// For AMASK, RA must be R31.
|
||||
0x61: decode RA {
|
||||
31: amask({{ Rc = Rb_or_imm & ~ULL(0x17); }});
|
||||
}
|
||||
|
||||
// For IMPLVER, RA must be R31 and the B operand
|
||||
// must be the immediate value 1.
|
||||
0x6c: decode RA {
|
||||
31: decode IMM {
|
||||
1: decode INTIMM {
|
||||
// return EV5 for FULL_SYSTEM and EV6 otherwise
|
||||
1: implver({{
|
||||
#if FULL_SYSTEM
|
||||
Rc = 1;
|
||||
#else
|
||||
Rc = 2;
|
||||
#endif
|
||||
}});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
// The mysterious 11.25...
|
||||
0x25: WarnUnimpl::eleven25();
|
||||
#endif
|
||||
}
|
||||
|
||||
0x12: decode INTFUNC {
|
||||
0x39: sll({{ Rc = Ra << Rb_or_imm<5:0>; }});
|
||||
0x34: srl({{ Rc = Ra.uq >> Rb_or_imm<5:0>; }});
|
||||
0x3c: sra({{ Rc = Ra.sq >> Rb_or_imm<5:0>; }});
|
||||
|
||||
0x02: mskbl({{ Rc = Ra & ~(mask( 8) << (Rb_or_imm<2:0> * 8)); }});
|
||||
0x12: mskwl({{ Rc = Ra & ~(mask(16) << (Rb_or_imm<2:0> * 8)); }});
|
||||
0x22: mskll({{ Rc = Ra & ~(mask(32) << (Rb_or_imm<2:0> * 8)); }});
|
||||
0x32: mskql({{ Rc = Ra & ~(mask(64) << (Rb_or_imm<2:0> * 8)); }});
|
||||
|
||||
0x52: mskwh({{
|
||||
int bv = Rb_or_imm<2:0>;
|
||||
Rc = bv ? (Ra & ~(mask(16) >> (64 - 8 * bv))) : Ra;
|
||||
}});
|
||||
0x62: msklh({{
|
||||
int bv = Rb_or_imm<2:0>;
|
||||
Rc = bv ? (Ra & ~(mask(32) >> (64 - 8 * bv))) : Ra;
|
||||
}});
|
||||
0x72: mskqh({{
|
||||
int bv = Rb_or_imm<2:0>;
|
||||
Rc = bv ? (Ra & ~(mask(64) >> (64 - 8 * bv))) : Ra;
|
||||
}});
|
||||
|
||||
0x06: extbl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))< 7:0>; }});
|
||||
0x16: extwl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<15:0>; }});
|
||||
0x26: extll({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<31:0>; }});
|
||||
0x36: extql({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8)); }});
|
||||
|
||||
0x5a: extwh({{
|
||||
Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<15:0>; }});
|
||||
0x6a: extlh({{
|
||||
Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<31:0>; }});
|
||||
0x7a: extqh({{
|
||||
Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>); }});
|
||||
|
||||
0x0b: insbl({{ Rc = Ra< 7:0> << (Rb_or_imm<2:0> * 8); }});
|
||||
0x1b: inswl({{ Rc = Ra<15:0> << (Rb_or_imm<2:0> * 8); }});
|
||||
0x2b: insll({{ Rc = Ra<31:0> << (Rb_or_imm<2:0> * 8); }});
|
||||
0x3b: insql({{ Rc = Ra << (Rb_or_imm<2:0> * 8); }});
|
||||
|
||||
0x57: inswh({{
|
||||
int bv = Rb_or_imm<2:0>;
|
||||
Rc = bv ? (Ra.uq<15:0> >> (64 - 8 * bv)) : 0;
|
||||
}});
|
||||
0x67: inslh({{
|
||||
int bv = Rb_or_imm<2:0>;
|
||||
Rc = bv ? (Ra.uq<31:0> >> (64 - 8 * bv)) : 0;
|
||||
}});
|
||||
0x77: insqh({{
|
||||
int bv = Rb_or_imm<2:0>;
|
||||
Rc = bv ? (Ra.uq >> (64 - 8 * bv)) : 0;
|
||||
}});
|
||||
|
||||
0x30: zap({{
|
||||
uint64_t zapmask = 0;
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (Rb_or_imm<i:>)
|
||||
zapmask |= (mask(8) << (i * 8));
|
||||
}
|
||||
Rc = Ra & ~zapmask;
|
||||
}});
|
||||
0x31: zapnot({{
|
||||
uint64_t zapmask = 0;
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (!Rb_or_imm<i:>)
|
||||
zapmask |= (mask(8) << (i * 8));
|
||||
}
|
||||
Rc = Ra & ~zapmask;
|
||||
}});
|
||||
}
|
||||
|
||||
0x13: decode INTFUNC { // integer multiplies
|
||||
0x00: mull({{ Rc.sl = Ra.sl * Rb_or_imm.sl; }}, IntMultOp);
|
||||
0x20: mulq({{ Rc = Ra * Rb_or_imm; }}, IntMultOp);
|
||||
0x30: umulh({{
|
||||
uint64_t hi, lo;
|
||||
mul128(Ra, Rb_or_imm, hi, lo);
|
||||
Rc = hi;
|
||||
}}, IntMultOp);
|
||||
0x40: mullv({{
|
||||
// 32-bit multiply with trap on overflow
|
||||
int64_t Rax = Ra.sl; // sign extended version of Ra.sl
|
||||
int64_t Rbx = Rb_or_imm.sl;
|
||||
int64_t tmp = Rax * Rbx;
|
||||
// To avoid overflow, all the upper 32 bits must match
|
||||
// the sign bit of the lower 32. We code this as
|
||||
// checking the upper 33 bits for all 0s or all 1s.
|
||||
uint64_t sign_bits = tmp<63:31>;
|
||||
if (sign_bits != 0 && sign_bits != mask(33))
|
||||
fault = new IntegerOverflowFault;
|
||||
Rc.sl = tmp<31:0>;
|
||||
}}, IntMultOp);
|
||||
0x60: mulqv({{
|
||||
// 64-bit multiply with trap on overflow
|
||||
uint64_t hi, lo;
|
||||
mul128(Ra, Rb_or_imm, hi, lo);
|
||||
// all the upper 64 bits must match the sign bit of
|
||||
// the lower 64
|
||||
if (!((hi == 0 && lo<63:> == 0) ||
|
||||
(hi == mask(64) && lo<63:> == 1)))
|
||||
fault = new IntegerOverflowFault;
|
||||
Rc = lo;
|
||||
}}, IntMultOp);
|
||||
}
|
||||
|
||||
0x1c: decode INTFUNC {
|
||||
0x00: decode RA { 31: sextb({{ Rc.sb = Rb_or_imm< 7:0>; }}); }
|
||||
0x01: decode RA { 31: sextw({{ Rc.sw = Rb_or_imm<15:0>; }}); }
|
||||
0x32: ctlz({{
|
||||
uint64_t count = 0;
|
||||
uint64_t temp = Rb;
|
||||
if (temp<63:32>) temp >>= 32; else count += 32;
|
||||
if (temp<31:16>) temp >>= 16; else count += 16;
|
||||
if (temp<15:8>) temp >>= 8; else count += 8;
|
||||
if (temp<7:4>) temp >>= 4; else count += 4;
|
||||
if (temp<3:2>) temp >>= 2; else count += 2;
|
||||
if (temp<1:1>) temp >>= 1; else count += 1;
|
||||
if ((temp<0:0>) != 0x1) count += 1;
|
||||
Rc = count;
|
||||
}}, IntAluOp);
|
||||
|
||||
0x33: cttz({{
|
||||
uint64_t count = 0;
|
||||
uint64_t temp = Rb;
|
||||
if (!(temp<31:0>)) { temp >>= 32; count += 32; }
|
||||
if (!(temp<15:0>)) { temp >>= 16; count += 16; }
|
||||
if (!(temp<7:0>)) { temp >>= 8; count += 8; }
|
||||
if (!(temp<3:0>)) { temp >>= 4; count += 4; }
|
||||
if (!(temp<1:0>)) { temp >>= 2; count += 2; }
|
||||
if (!(temp<0:0> & ULL(0x1))) count += 1;
|
||||
Rc = count;
|
||||
}}, IntAluOp);
|
||||
|
||||
format FailUnimpl {
|
||||
0x30: ctpop();
|
||||
0x31: perr();
|
||||
0x34: unpkbw();
|
||||
0x35: unpkbl();
|
||||
0x36: pkwb();
|
||||
0x37: pklb();
|
||||
0x38: minsb8();
|
||||
0x39: minsw4();
|
||||
0x3a: minub8();
|
||||
0x3b: minuw4();
|
||||
0x3c: maxub8();
|
||||
0x3d: maxuw4();
|
||||
0x3e: maxsb8();
|
||||
0x3f: maxsw4();
|
||||
}
|
||||
|
||||
format BasicOperateWithNopCheck {
|
||||
0x70: decode RB {
|
||||
31: ftoit({{ Rc = Fa.uq; }}, FloatCvtOp);
|
||||
}
|
||||
0x78: decode RB {
|
||||
31: ftois({{ Rc.sl = t_to_s(Fa.uq); }},
|
||||
FloatCvtOp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Conditional branches.
|
||||
format CondBranch {
|
||||
0x39: beq({{ cond = (Ra == 0); }});
|
||||
0x3d: bne({{ cond = (Ra != 0); }});
|
||||
0x3e: bge({{ cond = (Ra.sq >= 0); }});
|
||||
0x3f: bgt({{ cond = (Ra.sq > 0); }});
|
||||
0x3b: ble({{ cond = (Ra.sq <= 0); }});
|
||||
0x3a: blt({{ cond = (Ra.sq < 0); }});
|
||||
0x38: blbc({{ cond = ((Ra & 1) == 0); }});
|
||||
0x3c: blbs({{ cond = ((Ra & 1) == 1); }});
|
||||
|
||||
0x31: fbeq({{ cond = (Fa == 0); }});
|
||||
0x35: fbne({{ cond = (Fa != 0); }});
|
||||
0x36: fbge({{ cond = (Fa >= 0); }});
|
||||
0x37: fbgt({{ cond = (Fa > 0); }});
|
||||
0x33: fble({{ cond = (Fa <= 0); }});
|
||||
0x32: fblt({{ cond = (Fa < 0); }});
|
||||
}
|
||||
|
||||
// unconditional branches
|
||||
format UncondBranch {
|
||||
0x30: br();
|
||||
0x34: bsr(IsCall);
|
||||
}
|
||||
|
||||
// indirect branches
|
||||
0x1a: decode JMPFUNC {
|
||||
format Jump {
|
||||
0: jmp();
|
||||
1: jsr(IsCall);
|
||||
2: ret(IsReturn);
|
||||
3: jsr_coroutine(IsCall, IsReturn);
|
||||
}
|
||||
}
|
||||
|
||||
// Square root and integer-to-FP moves
|
||||
0x14: decode FP_SHORTFUNC {
|
||||
// Integer to FP register moves must have RB == 31
|
||||
0x4: decode RB {
|
||||
31: decode FP_FULLFUNC {
|
||||
format BasicOperateWithNopCheck {
|
||||
0x004: itofs({{ Fc.uq = s_to_t(Ra.ul); }}, FloatCvtOp);
|
||||
0x024: itoft({{ Fc.uq = Ra.uq; }}, FloatCvtOp);
|
||||
0x014: FailUnimpl::itoff(); // VAX-format conversion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Square root instructions must have FA == 31
|
||||
0xb: decode FA {
|
||||
31: decode FP_TYPEFUNC {
|
||||
format FloatingPointOperate {
|
||||
#if SS_COMPATIBLE_FP
|
||||
0x0b: sqrts({{
|
||||
if (Fb < 0.0)
|
||||
fault = new ArithmeticFault;
|
||||
Fc = sqrt(Fb);
|
||||
}}, FloatSqrtOp);
|
||||
#else
|
||||
0x0b: sqrts({{
|
||||
if (Fb.sf < 0.0)
|
||||
fault = new ArithmeticFault;
|
||||
Fc.sf = sqrt(Fb.sf);
|
||||
}}, FloatSqrtOp);
|
||||
#endif
|
||||
0x2b: sqrtt({{
|
||||
if (Fb < 0.0)
|
||||
fault = new ArithmeticFault;
|
||||
Fc = sqrt(Fb);
|
||||
}}, FloatSqrtOp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// VAX-format sqrtf and sqrtg are not implemented
|
||||
0xa: FailUnimpl::sqrtfg();
|
||||
}
|
||||
|
||||
// IEEE floating point
|
||||
0x16: decode FP_SHORTFUNC_TOP2 {
|
||||
// The top two bits of the short function code break this
|
||||
// space into four groups: binary ops, compares, reserved, and
|
||||
// conversions. See Table 4-12 of AHB. There are different
|
||||
// special cases in these different groups, so we decode on
|
||||
// these top two bits first just to select a decode strategy.
|
||||
// Most of these instructions may have various trapping and
|
||||
// rounding mode flags set; these are decoded in the
|
||||
// FloatingPointDecode template used by the
|
||||
// FloatingPointOperate format.
|
||||
|
||||
// add/sub/mul/div: just decode on the short function code
|
||||
// and source type. All valid trapping and rounding modes apply.
|
||||
0: decode FP_TRAPMODE {
|
||||
// check for valid trapping modes here
|
||||
0,1,5,7: decode FP_TYPEFUNC {
|
||||
format FloatingPointOperate {
|
||||
#if SS_COMPATIBLE_FP
|
||||
0x00: adds({{ Fc = Fa + Fb; }});
|
||||
0x01: subs({{ Fc = Fa - Fb; }});
|
||||
0x02: muls({{ Fc = Fa * Fb; }}, FloatMultOp);
|
||||
0x03: divs({{ Fc = Fa / Fb; }}, FloatDivOp);
|
||||
#else
|
||||
0x00: adds({{ Fc.sf = Fa.sf + Fb.sf; }});
|
||||
0x01: subs({{ Fc.sf = Fa.sf - Fb.sf; }});
|
||||
0x02: muls({{ Fc.sf = Fa.sf * Fb.sf; }}, FloatMultOp);
|
||||
0x03: divs({{ Fc.sf = Fa.sf / Fb.sf; }}, FloatDivOp);
|
||||
#endif
|
||||
|
||||
0x20: addt({{ Fc = Fa + Fb; }});
|
||||
0x21: subt({{ Fc = Fa - Fb; }});
|
||||
0x22: mult({{ Fc = Fa * Fb; }}, FloatMultOp);
|
||||
0x23: divt({{ Fc = Fa / Fb; }}, FloatDivOp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Floating-point compare instructions must have the default
|
||||
// rounding mode, and may use the default trapping mode or
|
||||
// /SU. Both trapping modes are treated the same by M5; the
|
||||
// only difference on the real hardware (as far a I can tell)
|
||||
// is that without /SU you'd get an imprecise trap if you
|
||||
// tried to compare a NaN with something else (instead of an
|
||||
// "unordered" result).
|
||||
1: decode FP_FULLFUNC {
|
||||
format BasicOperateWithNopCheck {
|
||||
0x0a5, 0x5a5: cmpteq({{ Fc = (Fa == Fb) ? 2.0 : 0.0; }},
|
||||
FloatCmpOp);
|
||||
0x0a7, 0x5a7: cmptle({{ Fc = (Fa <= Fb) ? 2.0 : 0.0; }},
|
||||
FloatCmpOp);
|
||||
0x0a6, 0x5a6: cmptlt({{ Fc = (Fa < Fb) ? 2.0 : 0.0; }},
|
||||
FloatCmpOp);
|
||||
0x0a4, 0x5a4: cmptun({{ // unordered
|
||||
Fc = (!(Fa < Fb) && !(Fa == Fb) && !(Fa > Fb)) ? 2.0 : 0.0;
|
||||
}}, FloatCmpOp);
|
||||
}
|
||||
}
|
||||
|
||||
// The FP-to-integer and integer-to-FP conversion insts
|
||||
// require that FA be 31.
|
||||
3: decode FA {
|
||||
31: decode FP_TYPEFUNC {
|
||||
format FloatingPointOperate {
|
||||
0x2f: decode FP_ROUNDMODE {
|
||||
format FPFixedRounding {
|
||||
// "chopped" i.e. round toward zero
|
||||
0: cvttq({{ Fc.sq = (int64_t)trunc(Fb); }},
|
||||
Chopped);
|
||||
// round to minus infinity
|
||||
1: cvttq({{ Fc.sq = (int64_t)floor(Fb); }},
|
||||
MinusInfinity);
|
||||
}
|
||||
default: cvttq({{ Fc.sq = (int64_t)nearbyint(Fb); }});
|
||||
}
|
||||
|
||||
// The cvtts opcode is overloaded to be cvtst if the trap
|
||||
// mode is 2 or 6 (which are not valid otherwise)
|
||||
0x2c: decode FP_FULLFUNC {
|
||||
format BasicOperateWithNopCheck {
|
||||
// trap on denorm version "cvtst/s" is
|
||||
// simulated same as cvtst
|
||||
0x2ac, 0x6ac: cvtst({{ Fc = Fb.sf; }});
|
||||
}
|
||||
default: cvtts({{ Fc.sf = Fb; }});
|
||||
}
|
||||
|
||||
// The trapping mode for integer-to-FP conversions
|
||||
// must be /SUI or nothing; /U and /SU are not
|
||||
// allowed. The full set of rounding modes are
|
||||
// supported though.
|
||||
0x3c: decode FP_TRAPMODE {
|
||||
0,7: cvtqs({{ Fc.sf = Fb.sq; }});
|
||||
}
|
||||
0x3e: decode FP_TRAPMODE {
|
||||
0,7: cvtqt({{ Fc = Fb.sq; }});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// misc FP operate
|
||||
0x17: decode FP_FULLFUNC {
|
||||
format BasicOperateWithNopCheck {
|
||||
0x010: cvtlq({{
|
||||
Fc.sl = (Fb.uq<63:62> << 30) | Fb.uq<58:29>;
|
||||
}});
|
||||
0x030: cvtql({{
|
||||
Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29);
|
||||
}});
|
||||
|
||||
// We treat the precise & imprecise trapping versions of
|
||||
// cvtql identically.
|
||||
0x130, 0x530: cvtqlv({{
|
||||
// To avoid overflow, all the upper 32 bits must match
|
||||
// the sign bit of the lower 32. We code this as
|
||||
// checking the upper 33 bits for all 0s or all 1s.
|
||||
uint64_t sign_bits = Fb.uq<63:31>;
|
||||
if (sign_bits != 0 && sign_bits != mask(33))
|
||||
fault = new IntegerOverflowFault;
|
||||
Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29);
|
||||
}});
|
||||
|
||||
0x020: cpys({{ // copy sign
|
||||
Fc.uq = (Fa.uq<63:> << 63) | Fb.uq<62:0>;
|
||||
}});
|
||||
0x021: cpysn({{ // copy sign negated
|
||||
Fc.uq = (~Fa.uq<63:> << 63) | Fb.uq<62:0>;
|
||||
}});
|
||||
0x022: cpyse({{ // copy sign and exponent
|
||||
Fc.uq = (Fa.uq<63:52> << 52) | Fb.uq<51:0>;
|
||||
}});
|
||||
|
||||
0x02a: fcmoveq({{ Fc = (Fa == 0) ? Fb : Fc; }});
|
||||
0x02b: fcmovne({{ Fc = (Fa != 0) ? Fb : Fc; }});
|
||||
0x02c: fcmovlt({{ Fc = (Fa < 0) ? Fb : Fc; }});
|
||||
0x02d: fcmovge({{ Fc = (Fa >= 0) ? Fb : Fc; }});
|
||||
0x02e: fcmovle({{ Fc = (Fa <= 0) ? Fb : Fc; }});
|
||||
0x02f: fcmovgt({{ Fc = (Fa > 0) ? Fb : Fc; }});
|
||||
|
||||
0x024: mt_fpcr({{ FPCR = Fa.uq; }});
|
||||
0x025: mf_fpcr({{ Fa.uq = FPCR; }});
|
||||
}
|
||||
}
|
||||
|
||||
// miscellaneous mem-format ops
|
||||
0x18: decode MEMFUNC {
|
||||
format WarnUnimpl {
|
||||
0x8000: fetch();
|
||||
0xa000: fetch_m();
|
||||
0xe800: ecb();
|
||||
}
|
||||
|
||||
format MiscPrefetch {
|
||||
0xf800: wh64({{ EA = Rb & ~ULL(63); }},
|
||||
{{ xc->writeHint(EA, 64, memAccessFlags); }},
|
||||
mem_flags = NO_FAULT,
|
||||
inst_flags = [IsMemRef, IsDataPrefetch,
|
||||
IsStore, MemWriteOp]);
|
||||
}
|
||||
|
||||
format BasicOperate {
|
||||
0xc000: rpcc({{
|
||||
#if FULL_SYSTEM
|
||||
/* Rb is a fake dependency so here is a fun way to get
|
||||
* the parser to understand that.
|
||||
*/
|
||||
Ra = xc->readMiscRegWithEffect(AlphaISA::IPR_CC, fault) + (Rb & 0);
|
||||
|
||||
#else
|
||||
Ra = curTick;
|
||||
#endif
|
||||
}});
|
||||
|
||||
// All of the barrier instructions below do nothing in
|
||||
// their execute() methods (hence the empty code blocks).
|
||||
// All of their functionality is hard-coded in the
|
||||
// pipeline based on the flags IsSerializing,
|
||||
// IsMemBarrier, and IsWriteBarrier. In the current
|
||||
// detailed CPU model, the execute() function only gets
|
||||
// called at fetch, so there's no way to generate pipeline
|
||||
// behavior at any other stage. Once we go to an
|
||||
// exec-in-exec CPU model we should be able to get rid of
|
||||
// these flags and implement this behavior via the
|
||||
// execute() methods.
|
||||
|
||||
// trapb is just a barrier on integer traps, where excb is
|
||||
// a barrier on integer and FP traps. "EXCB is thus a
|
||||
// superset of TRAPB." (Alpha ARM, Sec 4.11.4) We treat
|
||||
// them the same though.
|
||||
0x0000: trapb({{ }}, IsSerializing, No_OpClass);
|
||||
0x0400: excb({{ }}, IsSerializing, No_OpClass);
|
||||
0x4000: mb({{ }}, IsMemBarrier, MemReadOp);
|
||||
0x4400: wmb({{ }}, IsWriteBarrier, MemWriteOp);
|
||||
}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
format BasicOperate {
|
||||
0xe000: rc({{
|
||||
Ra = xc->readIntrFlag();
|
||||
xc->setIntrFlag(0);
|
||||
}}, IsNonSpeculative);
|
||||
0xf000: rs({{
|
||||
Ra = xc->readIntrFlag();
|
||||
xc->setIntrFlag(1);
|
||||
}}, IsNonSpeculative);
|
||||
}
|
||||
#else
|
||||
format FailUnimpl {
|
||||
0xe000: rc();
|
||||
0xf000: rs();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
0x00: CallPal::call_pal({{
|
||||
if (!palValid ||
|
||||
(palPriv
|
||||
&& xc->readMiscRegWithEffect(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) {
|
||||
// invalid pal function code, or attempt to do privileged
|
||||
// PAL call in non-kernel mode
|
||||
fault = new UnimplementedOpcodeFault;
|
||||
}
|
||||
else {
|
||||
// check to see if simulator wants to do something special
|
||||
// on this PAL call (including maybe suppress it)
|
||||
bool dopal = xc->simPalCheck(palFunc);
|
||||
|
||||
if (dopal) {
|
||||
xc->setMiscRegWithEffect(AlphaISA::IPR_EXC_ADDR, NPC);
|
||||
NPC = xc->readMiscRegWithEffect(AlphaISA::IPR_PAL_BASE, fault) + palOffset;
|
||||
}
|
||||
}
|
||||
}}, IsNonSpeculative);
|
||||
#else
|
||||
0x00: decode PALFUNC {
|
||||
format EmulatedCallPal {
|
||||
0x00: halt ({{
|
||||
SimExit(curTick, "halt instruction encountered");
|
||||
}}, IsNonSpeculative);
|
||||
0x83: callsys({{
|
||||
xc->syscall(R0);
|
||||
}}, IsNonSpeculative);
|
||||
// Read uniq reg into ABI return value register (r0)
|
||||
0x9e: rduniq({{ R0 = Runiq; }});
|
||||
// Write uniq reg with value from ABI arg register (r16)
|
||||
0x9f: wruniq({{ Runiq = R16; }});
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if FULL_SYSTEM
|
||||
0x1b: decode PALMODE {
|
||||
0: OpcdecFault::hw_st_quad();
|
||||
1: decode HW_LDST_QUAD {
|
||||
format HwLoad {
|
||||
0: hw_ld({{ EA = (Rb + disp) & ~3; }}, {{ Ra = Mem.ul; }}, L);
|
||||
1: hw_ld({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}, Q);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
0x1f: decode PALMODE {
|
||||
0: OpcdecFault::hw_st_cond();
|
||||
format HwStore {
|
||||
1: decode HW_LDST_COND {
|
||||
0: decode HW_LDST_QUAD {
|
||||
0: hw_st({{ EA = (Rb + disp) & ~3; }},
|
||||
{{ Mem.ul = Ra<31:0>; }}, L);
|
||||
1: hw_st({{ EA = (Rb + disp) & ~7; }},
|
||||
{{ Mem.uq = Ra.uq; }}, Q);
|
||||
}
|
||||
|
||||
1: FailUnimpl::hw_st_cond();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
0x19: decode PALMODE {
|
||||
0: OpcdecFault::hw_mfpr();
|
||||
format HwMoveIPR {
|
||||
1: hw_mfpr({{
|
||||
Ra = xc->readMiscRegWithEffect(ipr_index, fault);
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
0x1d: decode PALMODE {
|
||||
0: OpcdecFault::hw_mtpr();
|
||||
format HwMoveIPR {
|
||||
1: hw_mtpr({{
|
||||
xc->setMiscRegWithEffect(ipr_index, Ra);
|
||||
if (traceData) { traceData->setData(Ra); }
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
format BasicOperate {
|
||||
0x1e: decode PALMODE {
|
||||
0: OpcdecFault::hw_rei();
|
||||
1:hw_rei({{ xc->hwrei(); }}, IsSerializing);
|
||||
}
|
||||
|
||||
// M5 special opcodes use the reserved 0x01 opcode space
|
||||
0x01: decode M5FUNC {
|
||||
0x00: arm({{
|
||||
AlphaPseudo::arm(xc->xcBase());
|
||||
}}, IsNonSpeculative);
|
||||
0x01: quiesce({{
|
||||
AlphaPseudo::quiesce(xc->xcBase());
|
||||
}}, IsNonSpeculative);
|
||||
0x02: quiesceNs({{
|
||||
AlphaPseudo::quiesceNs(xc->xcBase(), R16);
|
||||
}}, IsNonSpeculative);
|
||||
0x03: quiesceCycles({{
|
||||
AlphaPseudo::quiesceCycles(xc->xcBase(), R16);
|
||||
}}, IsNonSpeculative);
|
||||
0x04: quiesceTime({{
|
||||
R0 = AlphaPseudo::quiesceTime(xc->xcBase());
|
||||
}}, IsNonSpeculative);
|
||||
0x10: ivlb({{
|
||||
AlphaPseudo::ivlb(xc->xcBase());
|
||||
}}, No_OpClass, IsNonSpeculative);
|
||||
0x11: ivle({{
|
||||
AlphaPseudo::ivle(xc->xcBase());
|
||||
}}, No_OpClass, IsNonSpeculative);
|
||||
0x20: m5exit_old({{
|
||||
AlphaPseudo::m5exit_old(xc->xcBase());
|
||||
}}, No_OpClass, IsNonSpeculative);
|
||||
0x21: m5exit({{
|
||||
AlphaPseudo::m5exit(xc->xcBase(), R16);
|
||||
}}, No_OpClass, IsNonSpeculative);
|
||||
0x30: initparam({{ Ra = xc->xcBase()->getCpuPtr()->system->init_param; }});
|
||||
0x40: resetstats({{
|
||||
AlphaPseudo::resetstats(xc->xcBase(), R16, R17);
|
||||
}}, IsNonSpeculative);
|
||||
0x41: dumpstats({{
|
||||
AlphaPseudo::dumpstats(xc->xcBase(), R16, R17);
|
||||
}}, IsNonSpeculative);
|
||||
0x42: dumpresetstats({{
|
||||
AlphaPseudo::dumpresetstats(xc->xcBase(), R16, R17);
|
||||
}}, IsNonSpeculative);
|
||||
0x43: m5checkpoint({{
|
||||
AlphaPseudo::m5checkpoint(xc->xcBase(), R16, R17);
|
||||
}}, IsNonSpeculative);
|
||||
0x50: m5readfile({{
|
||||
R0 = AlphaPseudo::readfile(xc->xcBase(), R16, R17, R18);
|
||||
}}, IsNonSpeculative);
|
||||
0x51: m5break({{
|
||||
AlphaPseudo::debugbreak(xc->xcBase());
|
||||
}}, IsNonSpeculative);
|
||||
0x52: m5switchcpu({{
|
||||
AlphaPseudo::switchcpu(xc->xcBase());
|
||||
}}, IsNonSpeculative);
|
||||
0x53: m5addsymbol({{
|
||||
AlphaPseudo::addsymbol(xc->xcBase(), R16, R17);
|
||||
}}, IsNonSpeculative);
|
||||
0x54: m5panic({{
|
||||
panic("M5 panic instruction called at pc=%#x.", xc->readPC());
|
||||
}}, IsNonSpeculative);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
301
src/arch/alpha/isa/fp.isa
Normal file
301
src/arch/alpha/isa/fp.isa
Normal file
@@ -0,0 +1,301 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
output exec {{
|
||||
/// Check "FP enabled" machine status bit. Called when executing any FP
|
||||
/// instruction in full-system mode.
|
||||
/// @retval Full-system mode: NoFault if FP is enabled, FenFault
|
||||
/// if not. Non-full-system mode: always returns NoFault.
|
||||
#if FULL_SYSTEM
|
||||
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
|
||||
{
|
||||
Fault fault = NoFault; // dummy... this ipr access should not fault
|
||||
if (!EV5::ICSR_FPE(xc->readMiscRegWithEffect(AlphaISA::IPR_ICSR, fault))) {
|
||||
fault = new FloatEnableFault;
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
#else
|
||||
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
|
||||
{
|
||||
return NoFault;
|
||||
}
|
||||
#endif
|
||||
}};
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Base class for general floating-point instructions. Includes
|
||||
* support for various Alpha rounding and trapping modes. Only FP
|
||||
* instructions that require this support are derived from this
|
||||
* class; the rest derive directly from AlphaStaticInst.
|
||||
*/
|
||||
class AlphaFP : public AlphaStaticInst
|
||||
{
|
||||
public:
|
||||
/// Alpha FP rounding modes.
|
||||
enum RoundingMode {
|
||||
Chopped = 0, ///< round toward zero
|
||||
Minus_Infinity = 1, ///< round toward minus infinity
|
||||
Normal = 2, ///< round to nearest (default)
|
||||
Dynamic = 3, ///< use FPCR setting (in instruction)
|
||||
Plus_Infinity = 3 ///< round to plus inifinity (in FPCR)
|
||||
};
|
||||
|
||||
/// Alpha FP trapping modes.
|
||||
/// For instructions that produce integer results, the
|
||||
/// "Underflow Enable" modes really mean "Overflow Enable", and
|
||||
/// the assembly modifier is V rather than U.
|
||||
enum TrappingMode {
|
||||
/// default: nothing enabled
|
||||
Imprecise = 0, ///< no modifier
|
||||
/// underflow/overflow traps enabled, inexact disabled
|
||||
Underflow_Imprecise = 1, ///< /U or /V
|
||||
Underflow_Precise = 5, ///< /SU or /SV
|
||||
/// underflow/overflow and inexact traps enabled
|
||||
Underflow_Inexact_Precise = 7 ///< /SUI or /SVI
|
||||
};
|
||||
|
||||
protected:
|
||||
/// Map Alpha rounding mode to C99 constants from <fenv.h>.
|
||||
static const int alphaToC99RoundingMode[];
|
||||
|
||||
/// Map enum RoundingMode values to disassembly suffixes.
|
||||
static const char *roundingModeSuffix[];
|
||||
/// Map enum TrappingMode values to FP disassembly suffixes.
|
||||
static const char *fpTrappingModeSuffix[];
|
||||
/// Map enum TrappingMode values to integer disassembly suffixes.
|
||||
static const char *intTrappingModeSuffix[];
|
||||
|
||||
/// This instruction's rounding mode.
|
||||
RoundingMode roundingMode;
|
||||
/// This instruction's trapping mode.
|
||||
TrappingMode trappingMode;
|
||||
|
||||
/// Have we warned about this instruction's unsupported
|
||||
/// rounding mode (if applicable)?
|
||||
mutable bool warnedOnRounding;
|
||||
|
||||
/// Have we warned about this instruction's unsupported
|
||||
/// trapping mode (if applicable)?
|
||||
mutable bool warnedOnTrapping;
|
||||
|
||||
/// Constructor
|
||||
AlphaFP(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
|
||||
: AlphaStaticInst(mnem, _machInst, __opClass),
|
||||
roundingMode((enum RoundingMode)FP_ROUNDMODE),
|
||||
trappingMode((enum TrappingMode)FP_TRAPMODE),
|
||||
warnedOnRounding(false),
|
||||
warnedOnTrapping(false)
|
||||
{
|
||||
}
|
||||
|
||||
int getC99RoundingMode(uint64_t fpcr_val) const;
|
||||
|
||||
// This differs from the AlphaStaticInst version only in
|
||||
// printing suffixes for non-default rounding & trapping modes.
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
|
||||
}};
|
||||
|
||||
|
||||
output decoder {{
|
||||
int
|
||||
AlphaFP::getC99RoundingMode(uint64_t fpcr_val) const
|
||||
{
|
||||
if (roundingMode == Dynamic) {
|
||||
return alphaToC99RoundingMode[bits(fpcr_val, 59, 58)];
|
||||
}
|
||||
else {
|
||||
return alphaToC99RoundingMode[roundingMode];
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
AlphaFP::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::string mnem_str(mnemonic);
|
||||
|
||||
#ifndef SS_COMPATIBLE_DISASSEMBLY
|
||||
std::string suffix("");
|
||||
suffix += ((_destRegIdx[0] >= FP_Base_DepTag)
|
||||
? fpTrappingModeSuffix[trappingMode]
|
||||
: intTrappingModeSuffix[trappingMode]);
|
||||
suffix += roundingModeSuffix[roundingMode];
|
||||
|
||||
if (suffix != "") {
|
||||
mnem_str = csprintf("%s/%s", mnemonic, suffix);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::stringstream ss;
|
||||
ccprintf(ss, "%-10s ", mnem_str.c_str());
|
||||
|
||||
// just print the first two source regs... if there's
|
||||
// a third one, it's a read-modify-write dest (Rc),
|
||||
// e.g. for CMOVxx
|
||||
if (_numSrcRegs > 0) {
|
||||
printReg(ss, _srcRegIdx[0]);
|
||||
}
|
||||
if (_numSrcRegs > 1) {
|
||||
ss << ",";
|
||||
printReg(ss, _srcRegIdx[1]);
|
||||
}
|
||||
|
||||
// just print the first dest... if there's a second one,
|
||||
// it's generally implicit
|
||||
if (_numDestRegs > 0) {
|
||||
if (_numSrcRegs > 0)
|
||||
ss << ",";
|
||||
printReg(ss, _destRegIdx[0]);
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
const int AlphaFP::alphaToC99RoundingMode[] = {
|
||||
FE_TOWARDZERO, // Chopped
|
||||
FE_DOWNWARD, // Minus_Infinity
|
||||
FE_TONEAREST, // Normal
|
||||
FE_UPWARD // Dynamic in inst, Plus_Infinity in FPCR
|
||||
};
|
||||
|
||||
const char *AlphaFP::roundingModeSuffix[] = { "c", "m", "", "d" };
|
||||
// mark invalid trapping modes, but don't fail on them, because
|
||||
// you could decode anything on a misspeculated path
|
||||
const char *AlphaFP::fpTrappingModeSuffix[] =
|
||||
{ "", "u", "INVTM2", "INVTM3", "INVTM4", "su", "INVTM6", "sui" };
|
||||
const char *AlphaFP::intTrappingModeSuffix[] =
|
||||
{ "", "v", "INVTM2", "INVTM3", "INVTM4", "sv", "INVTM6", "svi" };
|
||||
}};
|
||||
|
||||
// FP instruction class execute method template. Handles non-standard
|
||||
// rounding modes.
|
||||
def template FloatingPointExecute {{
|
||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
if (trappingMode != Imprecise && !warnedOnTrapping) {
|
||||
warn("%s: non-standard trapping mode not supported",
|
||||
generateDisassembly(0, NULL));
|
||||
warnedOnTrapping = true;
|
||||
}
|
||||
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
#if USE_FENV
|
||||
if (roundingMode == Normal) {
|
||||
%(code)s;
|
||||
} else {
|
||||
fesetround(getC99RoundingMode(
|
||||
xc->readMiscReg(AlphaISA::Fpcr_DepTag)));
|
||||
%(code)s;
|
||||
fesetround(FE_TONEAREST);
|
||||
}
|
||||
#else
|
||||
if (roundingMode != Normal && !warnedOnRounding) {
|
||||
warn("%s: non-standard rounding mode not supported",
|
||||
generateDisassembly(0, NULL));
|
||||
warnedOnRounding = true;
|
||||
}
|
||||
%(code)s;
|
||||
#endif
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
// FP instruction class execute method template where no dynamic
|
||||
// rounding mode control is needed. Like BasicExecute, but includes
|
||||
// check & warning for non-standard trapping mode.
|
||||
def template FPFixedRoundingExecute {{
|
||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
if (trappingMode != Imprecise && !warnedOnTrapping) {
|
||||
warn("%s: non-standard trapping mode not supported",
|
||||
generateDisassembly(0, NULL));
|
||||
warnedOnTrapping = true;
|
||||
}
|
||||
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
%(code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
def template FloatingPointDecode {{
|
||||
{
|
||||
AlphaStaticInst *i = new %(class_name)s(machInst);
|
||||
if (FC == 31) {
|
||||
i = makeNop(i);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}};
|
||||
|
||||
// General format for floating-point operate instructions:
|
||||
// - Checks trapping and rounding mode flags. Trapping modes
|
||||
// currently unimplemented (will fail).
|
||||
// - Generates NOP if FC == 31.
|
||||
def format FloatingPointOperate(code, *opt_args) {{
|
||||
iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args)
|
||||
decode_block = FloatingPointDecode.subst(iop)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
exec_output = FloatingPointExecute.subst(iop)
|
||||
}};
|
||||
|
||||
// Special format for cvttq where rounding mode is pre-decoded
|
||||
def format FPFixedRounding(code, class_suffix, *opt_args) {{
|
||||
Name += class_suffix
|
||||
iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args)
|
||||
decode_block = FloatingPointDecode.subst(iop)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
exec_output = FPFixedRoundingExecute.subst(iop)
|
||||
}};
|
||||
|
||||
128
src/arch/alpha/isa/int.isa
Normal file
128
src/arch/alpha/isa/int.isa
Normal file
@@ -0,0 +1,128 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Base class for integer immediate instructions.
|
||||
*/
|
||||
class IntegerImm : public AlphaStaticInst
|
||||
{
|
||||
protected:
|
||||
/// Immediate operand value (unsigned 8-bit int).
|
||||
uint8_t imm;
|
||||
|
||||
/// Constructor
|
||||
IntegerImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
|
||||
: AlphaStaticInst(mnem, _machInst, __opClass), imm(INTIMM)
|
||||
{
|
||||
}
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
std::string
|
||||
IntegerImm::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ccprintf(ss, "%-10s ", mnemonic);
|
||||
|
||||
// just print the first source reg... if there's
|
||||
// a second one, it's a read-modify-write dest (Rc),
|
||||
// e.g. for CMOVxx
|
||||
if (_numSrcRegs > 0) {
|
||||
printReg(ss, _srcRegIdx[0]);
|
||||
ss << ",";
|
||||
}
|
||||
|
||||
ss << (int)imm;
|
||||
|
||||
if (_numDestRegs > 0) {
|
||||
ss << ",";
|
||||
printReg(ss, _destRegIdx[0]);
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template RegOrImmDecode {{
|
||||
{
|
||||
AlphaStaticInst *i =
|
||||
(IMM) ? (AlphaStaticInst *)new %(class_name)sImm(machInst)
|
||||
: (AlphaStaticInst *)new %(class_name)s(machInst);
|
||||
if (RC == 31) {
|
||||
i = makeNop(i);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}};
|
||||
|
||||
// Primary format for integer operate instructions:
|
||||
// - Generates both reg-reg and reg-imm versions if Rb_or_imm is used.
|
||||
// - Generates NOP if RC == 31.
|
||||
def format IntegerOperate(code, *opt_flags) {{
|
||||
# If the code block contains 'Rb_or_imm', we define two instructions,
|
||||
# one using 'Rb' and one using 'imm', and have the decoder select
|
||||
# the right one.
|
||||
uses_imm = (code.find('Rb_or_imm') != -1)
|
||||
if uses_imm:
|
||||
orig_code = code
|
||||
# base code is reg version:
|
||||
# rewrite by substituting 'Rb' for 'Rb_or_imm'
|
||||
code = re.sub(r'Rb_or_imm', 'Rb', orig_code)
|
||||
# generate immediate version by substituting 'imm'
|
||||
# note that imm takes no extenstion, so we extend
|
||||
# the regexp to replace any extension as well
|
||||
imm_code = re.sub(r'Rb_or_imm(\.\w+)?', 'imm', orig_code)
|
||||
|
||||
# generate declaration for register version
|
||||
cblk = CodeBlock(code)
|
||||
iop = InstObjParams(name, Name, 'AlphaStaticInst', cblk, opt_flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
|
||||
if uses_imm:
|
||||
# append declaration for imm version
|
||||
imm_cblk = CodeBlock(imm_code)
|
||||
imm_iop = InstObjParams(name, Name + 'Imm', 'IntegerImm', imm_cblk,
|
||||
opt_flags)
|
||||
header_output += BasicDeclare.subst(imm_iop)
|
||||
decoder_output += BasicConstructor.subst(imm_iop)
|
||||
exec_output += BasicExecute.subst(imm_iop)
|
||||
# decode checks IMM bit to pick correct version
|
||||
decode_block = RegOrImmDecode.subst(iop)
|
||||
else:
|
||||
# no imm version: just check for nop
|
||||
decode_block = OperateNopCheckDecode.subst(iop)
|
||||
}};
|
||||
449
src/arch/alpha/isa/main.isa
Normal file
449
src/arch/alpha/isa/main.isa
Normal file
@@ -0,0 +1,449 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
output header {{
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "config/ss_compatible_fp.hh"
|
||||
#include "cpu/static_inst.hh"
|
||||
#include "arch/alpha/faults.hh"
|
||||
#include "mem/request.hh" // some constructors use MemReq flags
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
#include "base/cprintf.hh"
|
||||
#include "base/fenv.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "config/ss_compatible_fp.hh"
|
||||
#include "cpu/exec_context.hh" // for Jump::branchTarget()
|
||||
|
||||
#include <math.h>
|
||||
|
||||
using namespace AlphaISA;
|
||||
}};
|
||||
|
||||
output exec {{
|
||||
#include <math.h>
|
||||
|
||||
#if FULL_SYSTEM
|
||||
#include "sim/pseudo_inst.hh"
|
||||
#endif
|
||||
#include "base/fenv.hh"
|
||||
#include "config/ss_compatible_fp.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/exetrace.hh"
|
||||
#include "sim/sim_exit.hh"
|
||||
#include "mem/packet_impl.hh"
|
||||
|
||||
using namespace AlphaISA;
|
||||
}};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Namespace statement. Everything below this line will be in the
|
||||
// AlphaISAInst namespace.
|
||||
//
|
||||
|
||||
|
||||
namespace AlphaISA;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bitfield definitions.
|
||||
//
|
||||
|
||||
// Universal (format-independent) fields
|
||||
def bitfield PALMODE <32:32>;
|
||||
def bitfield OPCODE <31:26>;
|
||||
def bitfield RA <25:21>;
|
||||
def bitfield RB <20:16>;
|
||||
|
||||
// Memory format
|
||||
def signed bitfield MEMDISP <15: 0>; // displacement
|
||||
def bitfield MEMFUNC <15: 0>; // function code (same field, unsigned)
|
||||
|
||||
// Memory-format jumps
|
||||
def bitfield JMPFUNC <15:14>; // function code (disp<15:14>)
|
||||
def bitfield JMPHINT <13: 0>; // tgt Icache idx hint (disp<13:0>)
|
||||
|
||||
// Branch format
|
||||
def signed bitfield BRDISP <20: 0>; // displacement
|
||||
|
||||
// Integer operate format(s>;
|
||||
def bitfield INTIMM <20:13>; // integer immediate (literal)
|
||||
def bitfield IMM <12:12>; // immediate flag
|
||||
def bitfield INTFUNC <11: 5>; // function code
|
||||
def bitfield RC < 4: 0>; // dest reg
|
||||
|
||||
// Floating-point operate format
|
||||
def bitfield FA <25:21>;
|
||||
def bitfield FB <20:16>;
|
||||
def bitfield FP_FULLFUNC <15: 5>; // complete function code
|
||||
def bitfield FP_TRAPMODE <15:13>; // trapping mode
|
||||
def bitfield FP_ROUNDMODE <12:11>; // rounding mode
|
||||
def bitfield FP_TYPEFUNC <10: 5>; // type+func: handiest for decoding
|
||||
def bitfield FP_SRCTYPE <10: 9>; // source reg type
|
||||
def bitfield FP_SHORTFUNC < 8: 5>; // short function code
|
||||
def bitfield FP_SHORTFUNC_TOP2 <8:7>; // top 2 bits of short func code
|
||||
def bitfield FC < 4: 0>; // dest reg
|
||||
|
||||
// PALcode format
|
||||
def bitfield PALFUNC <25: 0>; // function code
|
||||
|
||||
// EV5 PAL instructions:
|
||||
// HW_LD/HW_ST
|
||||
def bitfield HW_LDST_PHYS <15>; // address is physical
|
||||
def bitfield HW_LDST_ALT <14>; // use ALT_MODE IPR
|
||||
def bitfield HW_LDST_WRTCK <13>; // HW_LD only: fault if no write acc
|
||||
def bitfield HW_LDST_QUAD <12>; // size: 0=32b, 1=64b
|
||||
def bitfield HW_LDST_VPTE <11>; // HW_LD only: is PTE fetch
|
||||
def bitfield HW_LDST_LOCK <10>; // HW_LD only: is load locked
|
||||
def bitfield HW_LDST_COND <10>; // HW_ST only: is store conditional
|
||||
def signed bitfield HW_LDST_DISP <9:0>; // signed displacement
|
||||
|
||||
// HW_REI
|
||||
def bitfield HW_REI_TYP <15:14>; // type: stalling vs. non-stallingk
|
||||
def bitfield HW_REI_MBZ <13: 0>; // must be zero
|
||||
|
||||
// HW_MTPR/MW_MFPR
|
||||
def bitfield HW_IPR_IDX <15:0>; // IPR index
|
||||
|
||||
// M5 instructions
|
||||
def bitfield M5FUNC <7:0>;
|
||||
|
||||
def operand_types {{
|
||||
'sb' : ('signed int', 8),
|
||||
'ub' : ('unsigned int', 8),
|
||||
'sw' : ('signed int', 16),
|
||||
'uw' : ('unsigned int', 16),
|
||||
'sl' : ('signed int', 32),
|
||||
'ul' : ('unsigned int', 32),
|
||||
'sq' : ('signed int', 64),
|
||||
'uq' : ('unsigned int', 64),
|
||||
'sf' : ('float', 32),
|
||||
'df' : ('float', 64)
|
||||
}};
|
||||
|
||||
def operands {{
|
||||
# Int regs default to unsigned, but code should not count on this.
|
||||
# For clarity, descriptions that depend on unsigned behavior should
|
||||
# explicitly specify '.uq'.
|
||||
'Ra': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RA] : RA',
|
||||
'IsInteger', 1),
|
||||
'Rb': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RB] : RB',
|
||||
'IsInteger', 2),
|
||||
'Rc': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RC] : RC',
|
||||
'IsInteger', 3),
|
||||
'Fa': ('FloatReg', 'df', 'FA', 'IsFloating', 1),
|
||||
'Fb': ('FloatReg', 'df', 'FB', 'IsFloating', 2),
|
||||
'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3),
|
||||
'Mem': ('Mem', 'uq', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
|
||||
'NPC': ('NPC', 'uq', None, ( None, None, 'IsControl' ), 4),
|
||||
'Runiq': ('ControlReg', 'uq', 'TheISA::Uniq_DepTag', None, 1),
|
||||
'FPCR': (' ControlReg', 'uq', 'TheISA::Fpcr_DepTag', None, 1),
|
||||
# The next two are hacks for non-full-system call-pal emulation
|
||||
'R0': ('IntReg', 'uq', '0', None, 1),
|
||||
'R16': ('IntReg', 'uq', '16', None, 1),
|
||||
'R17': ('IntReg', 'uq', '17', None, 1),
|
||||
'R18': ('IntReg', 'uq', '18', None, 1)
|
||||
}};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Basic instruction classes/templates/formats etc.
|
||||
//
|
||||
|
||||
output header {{
|
||||
// uncomment the following to get SimpleScalar-compatible disassembly
|
||||
// (useful for diffing output traces).
|
||||
// #define SS_COMPATIBLE_DISASSEMBLY
|
||||
|
||||
/**
|
||||
* Base class for all Alpha static instructions.
|
||||
*/
|
||||
class AlphaStaticInst : public StaticInst
|
||||
{
|
||||
protected:
|
||||
|
||||
/// Make AlphaISA register dependence tags directly visible in
|
||||
/// this class and derived classes. Maybe these should really
|
||||
/// live here and not in the AlphaISA namespace.
|
||||
enum DependenceTags {
|
||||
FP_Base_DepTag = AlphaISA::FP_Base_DepTag,
|
||||
Fpcr_DepTag = AlphaISA::Fpcr_DepTag,
|
||||
Uniq_DepTag = AlphaISA::Uniq_DepTag,
|
||||
Lock_Flag_DepTag = AlphaISA::Lock_Flag_DepTag,
|
||||
Lock_Addr_DepTag = AlphaISA::Lock_Addr_DepTag,
|
||||
IPR_Base_DepTag = AlphaISA::IPR_Base_DepTag
|
||||
};
|
||||
|
||||
/// Constructor.
|
||||
AlphaStaticInst(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass)
|
||||
: StaticInst(mnem, _machInst, __opClass)
|
||||
{
|
||||
}
|
||||
|
||||
/// Print a register name for disassembly given the unique
|
||||
/// dependence tag number (FP or int).
|
||||
void printReg(std::ostream &os, int reg) const;
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
void
|
||||
AlphaStaticInst::printReg(std::ostream &os, int reg) const
|
||||
{
|
||||
if (reg < FP_Base_DepTag) {
|
||||
ccprintf(os, "r%d", reg);
|
||||
}
|
||||
else {
|
||||
ccprintf(os, "f%d", reg - FP_Base_DepTag);
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
AlphaStaticInst::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ccprintf(ss, "%-10s ", mnemonic);
|
||||
|
||||
// just print the first two source regs... if there's
|
||||
// a third one, it's a read-modify-write dest (Rc),
|
||||
// e.g. for CMOVxx
|
||||
if (_numSrcRegs > 0) {
|
||||
printReg(ss, _srcRegIdx[0]);
|
||||
}
|
||||
if (_numSrcRegs > 1) {
|
||||
ss << ",";
|
||||
printReg(ss, _srcRegIdx[1]);
|
||||
}
|
||||
|
||||
// just print the first dest... if there's a second one,
|
||||
// it's generally implicit
|
||||
if (_numDestRegs > 0) {
|
||||
if (_numSrcRegs > 0)
|
||||
ss << ",";
|
||||
printReg(ss, _destRegIdx[0]);
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
}};
|
||||
|
||||
// Declarations for execute() methods.
|
||||
def template BasicExecDeclare {{
|
||||
Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
|
||||
}};
|
||||
|
||||
// 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, 'AlphaStaticInst', CodeBlock(code), flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Nop
|
||||
//
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Static instruction class for no-ops. This is a leaf class.
|
||||
*/
|
||||
class Nop : public AlphaStaticInst
|
||||
{
|
||||
/// Disassembly of original instruction.
|
||||
const std::string originalDisassembly;
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
Nop(const std::string _originalDisassembly, ExtMachInst _machInst)
|
||||
: AlphaStaticInst("nop", _machInst, No_OpClass),
|
||||
originalDisassembly(_originalDisassembly)
|
||||
{
|
||||
flags[IsNop] = true;
|
||||
}
|
||||
|
||||
~Nop() { }
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
|
||||
%(BasicExecDeclare)s
|
||||
};
|
||||
|
||||
/// Helper function for decoding nops. Substitute Nop object
|
||||
/// for original inst passed in as arg (and delete latter).
|
||||
static inline
|
||||
AlphaStaticInst *
|
||||
makeNop(AlphaStaticInst *inst)
|
||||
{
|
||||
AlphaStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst);
|
||||
delete inst;
|
||||
return nop;
|
||||
}
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
std::string Nop::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
#ifdef SS_COMPATIBLE_DISASSEMBLY
|
||||
return originalDisassembly;
|
||||
#else
|
||||
return csprintf("%-10s (%s)", "nop", originalDisassembly);
|
||||
#endif
|
||||
}
|
||||
}};
|
||||
|
||||
output exec {{
|
||||
Fault
|
||||
Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
|
||||
{
|
||||
return NoFault;
|
||||
}
|
||||
}};
|
||||
|
||||
// integer & FP operate instructions use Rc as dest, so check for
|
||||
// Rc == 31 to detect nops
|
||||
def template OperateNopCheckDecode {{
|
||||
{
|
||||
AlphaStaticInst *i = new %(class_name)s(machInst);
|
||||
if (RC == 31) {
|
||||
i = makeNop(i);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}};
|
||||
|
||||
// Like BasicOperate format, but generates NOP if RC/FC == 31
|
||||
def format BasicOperateWithNopCheck(code, *opt_args) {{
|
||||
iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code),
|
||||
opt_args)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = OperateNopCheckDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
// Integer instruction templates, formats, etc.
|
||||
##include "int.isa"
|
||||
|
||||
// Floating-point instruction templates, formats, etc.
|
||||
##include "fp.isa"
|
||||
|
||||
// Memory instruction templates, formats, etc.
|
||||
##include "mem.isa"
|
||||
|
||||
// Branch/jump instruction templates, formats, etc.
|
||||
##include "branch.isa"
|
||||
|
||||
// PAL instruction templates, formats, etc.
|
||||
##include "pal.isa"
|
||||
|
||||
// Opcdec fault instruction templates, formats, etc.
|
||||
##include "opcdec.isa"
|
||||
|
||||
// Unimplemented instruction templates, formats, etc.
|
||||
##include "unimp.isa"
|
||||
|
||||
// Unknown instruction templates, formats, etc.
|
||||
##include "unknown.isa"
|
||||
|
||||
// Execution utility functions
|
||||
##include "util.isa"
|
||||
|
||||
// The actual decoder
|
||||
##include "decoder.isa"
|
||||
729
src/arch/alpha/isa/mem.isa
Normal file
729
src/arch/alpha/isa/mem.isa
Normal file
@@ -0,0 +1,729 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Base class for general Alpha memory-format instructions.
|
||||
*/
|
||||
class Memory : public AlphaStaticInst
|
||||
{
|
||||
protected:
|
||||
|
||||
/// Memory request flags. See mem_req_base.hh.
|
||||
unsigned memAccessFlags;
|
||||
/// Pointer to EAComp object.
|
||||
const StaticInstPtr eaCompPtr;
|
||||
/// Pointer to MemAcc object.
|
||||
const StaticInstPtr memAccPtr;
|
||||
|
||||
/// Constructor
|
||||
Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
|
||||
StaticInstPtr _eaCompPtr = nullStaticInstPtr,
|
||||
StaticInstPtr _memAccPtr = nullStaticInstPtr)
|
||||
: AlphaStaticInst(mnem, _machInst, __opClass),
|
||||
memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr)
|
||||
{
|
||||
}
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
|
||||
public:
|
||||
|
||||
const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
|
||||
const StaticInstPtr &memAccInst() const { return memAccPtr; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for memory-format instructions using a 32-bit
|
||||
* displacement (i.e. most of them).
|
||||
*/
|
||||
class MemoryDisp32 : public Memory
|
||||
{
|
||||
protected:
|
||||
/// Displacement for EA calculation (signed).
|
||||
int32_t disp;
|
||||
|
||||
/// Constructor.
|
||||
MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
|
||||
StaticInstPtr _eaCompPtr = nullStaticInstPtr,
|
||||
StaticInstPtr _memAccPtr = nullStaticInstPtr)
|
||||
: Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
|
||||
disp(MEMDISP)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Base class for a few miscellaneous memory-format insts
|
||||
* that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
|
||||
* None of these instructions has a destination register either.
|
||||
*/
|
||||
class MemoryNoDisp : public Memory
|
||||
{
|
||||
protected:
|
||||
/// Constructor
|
||||
MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
|
||||
StaticInstPtr _eaCompPtr = nullStaticInstPtr,
|
||||
StaticInstPtr _memAccPtr = nullStaticInstPtr)
|
||||
: Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
|
||||
{
|
||||
}
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
|
||||
output decoder {{
|
||||
std::string
|
||||
Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
|
||||
flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
|
||||
}
|
||||
|
||||
std::string
|
||||
MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
return csprintf("%-10s (r%d)", mnemonic, RB);
|
||||
}
|
||||
}};
|
||||
|
||||
def format LoadAddress(code) {{
|
||||
iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
|
||||
def template LoadStoreDeclare {{
|
||||
/**
|
||||
* Static instruction class for "%(mnemonic)s".
|
||||
*/
|
||||
class %(class_name)s : public %(base_class)s
|
||||
{
|
||||
protected:
|
||||
|
||||
/**
|
||||
* "Fake" effective address computation class for "%(mnemonic)s".
|
||||
*/
|
||||
class EAComp : public %(base_class)s
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
EAComp(ExtMachInst machInst);
|
||||
|
||||
%(BasicExecDeclare)s
|
||||
};
|
||||
|
||||
/**
|
||||
* "Fake" memory access instruction class for "%(mnemonic)s".
|
||||
*/
|
||||
class MemAcc : public %(base_class)s
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
MemAcc(ExtMachInst machInst);
|
||||
|
||||
%(BasicExecDeclare)s
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor.
|
||||
%(class_name)s(ExtMachInst machInst);
|
||||
|
||||
%(BasicExecDeclare)s
|
||||
|
||||
%(InitiateAccDeclare)s
|
||||
|
||||
%(CompleteAccDeclare)s
|
||||
};
|
||||
}};
|
||||
|
||||
|
||||
def template InitiateAccDeclare {{
|
||||
Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
|
||||
}};
|
||||
|
||||
|
||||
def template CompleteAccDeclare {{
|
||||
Fault completeAcc(Packet *, %(CPU_exec_context)s *,
|
||||
Trace::InstRecord *) const;
|
||||
}};
|
||||
|
||||
|
||||
def template LoadStoreConstructor {{
|
||||
/** TODO: change op_class to AddrGenOp or something (requires
|
||||
* creating new member of OpClass enum in op_class.hh, updating
|
||||
* config files, etc.). */
|
||||
inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
|
||||
: %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
|
||||
{
|
||||
%(ea_constructor)s;
|
||||
}
|
||||
|
||||
inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
|
||||
: %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
|
||||
{
|
||||
%(memacc_constructor)s;
|
||||
}
|
||||
|
||||
inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
||||
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
|
||||
new EAComp(machInst), new MemAcc(machInst))
|
||||
{
|
||||
%(constructor)s;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template EACompExecute {{
|
||||
Fault
|
||||
%(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Addr EA;
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
%(code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
xc->setEA(EA);
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
def template LoadMemAccExecute {{
|
||||
Fault
|
||||
%(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Addr EA;
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
EA = xc->getEA();
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
|
||||
%(code)s;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template LoadExecute {{
|
||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Addr EA;
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
%(ea_code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
|
||||
%(memacc_code)s;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template LoadInitiateAcc {{
|
||||
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Addr EA;
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_src_decl)s;
|
||||
%(op_rd)s;
|
||||
%(ea_code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template LoadCompleteAcc {{
|
||||
Fault %(class_name)s::completeAcc(Packet *pkt,
|
||||
%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
|
||||
Mem = pkt->get<typeof(Mem)>();
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(memacc_code)s;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template StoreMemAccExecute {{
|
||||
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;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
EA = xc->getEA();
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(code)s;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, &write_result);
|
||||
if (traceData) { traceData->setData(Mem); }
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(postacc_code)s;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template StoreExecute {{
|
||||
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;
|
||||
%(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, &write_result);
|
||||
if (traceData) { traceData->setData(Mem); }
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(postacc_code)s;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
def template StoreInitiateAcc {{
|
||||
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
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); }
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template StoreCompleteAcc {{
|
||||
Fault %(class_name)s::completeAcc(Packet *pkt,
|
||||
%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_dest_decl)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(postacc_code)s;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template StoreCondCompleteAcc {{
|
||||
Fault %(class_name)s::completeAcc(Packet *pkt,
|
||||
%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_dest_decl)s;
|
||||
|
||||
uint64_t write_result = pkt->req->getScResult();
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(postacc_code)s;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template MiscMemAccExecute {{
|
||||
Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Addr EA;
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
EA = xc->getEA();
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(code)s;
|
||||
}
|
||||
|
||||
return NoFault;
|
||||
}
|
||||
}};
|
||||
|
||||
def template MiscExecute {{
|
||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Addr EA;
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
%(ea_code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(memacc_code)s;
|
||||
}
|
||||
|
||||
return NoFault;
|
||||
}
|
||||
}};
|
||||
|
||||
def template MiscInitiateAcc {{
|
||||
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
panic("Misc instruction does not support split access method!");
|
||||
return NoFault;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template MiscCompleteAcc {{
|
||||
Fault %(class_name)s::completeAcc(Packet *pkt,
|
||||
%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
panic("Misc instruction does not support split access method!");
|
||||
|
||||
return NoFault;
|
||||
}
|
||||
}};
|
||||
|
||||
// load instructions use Ra as dest, so check for
|
||||
// Ra == 31 to detect nops
|
||||
def template LoadNopCheckDecode {{
|
||||
{
|
||||
AlphaStaticInst *i = new %(class_name)s(machInst);
|
||||
if (RA == 31) {
|
||||
i = makeNop(i);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
|
||||
def template LoadPrefetchCheckDecode {{
|
||||
{
|
||||
if (RA != 31) {
|
||||
return new %(class_name)s(machInst);
|
||||
}
|
||||
else {
|
||||
return new %(class_name)sPrefetch(machInst);
|
||||
}
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
let {{
|
||||
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
postacc_code = '', base_class = 'MemoryDisp32',
|
||||
decode_template = BasicDecode, exec_template_base = ''):
|
||||
# Make sure flags are in lists (convert to lists if not).
|
||||
mem_flags = makeList(mem_flags)
|
||||
inst_flags = makeList(inst_flags)
|
||||
|
||||
# add hook to get effective addresses into execution trace output.
|
||||
ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
|
||||
|
||||
# generate code block objects
|
||||
ea_cblk = CodeBlock(ea_code)
|
||||
memacc_cblk = CodeBlock(memacc_code)
|
||||
postacc_cblk = CodeBlock(postacc_code)
|
||||
|
||||
# Some CPU models execute the memory operation as an atomic unit,
|
||||
# while others want to separate them into an effective address
|
||||
# computation and a memory access operation. As a result, we need
|
||||
# to generate three StaticInst objects. Note that the latter two
|
||||
# are nested inside the larger "atomic" one.
|
||||
|
||||
# generate InstObjParams for EAComp object
|
||||
ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)
|
||||
|
||||
# generate InstObjParams for MemAcc object
|
||||
memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)
|
||||
# in the split execution model, the MemAcc portion is responsible
|
||||
# for the post-access code.
|
||||
memacc_iop.postacc_code = postacc_cblk.code
|
||||
|
||||
# generate InstObjParams for InitiateAcc, CompleteAcc object
|
||||
# The code used depends on the template being used
|
||||
if (exec_template_base == 'Load'):
|
||||
initiateacc_cblk = CodeBlock(ea_code + memacc_code)
|
||||
completeacc_cblk = CodeBlock(memacc_code + postacc_code)
|
||||
elif (exec_template_base.startswith('Store')):
|
||||
initiateacc_cblk = CodeBlock(ea_code + memacc_code)
|
||||
completeacc_cblk = CodeBlock(postacc_code)
|
||||
else:
|
||||
initiateacc_cblk = ''
|
||||
completeacc_cblk = ''
|
||||
|
||||
initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk,
|
||||
inst_flags)
|
||||
|
||||
completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk,
|
||||
inst_flags)
|
||||
|
||||
if (exec_template_base == 'Load'):
|
||||
initiateacc_iop.ea_code = ea_cblk.code
|
||||
initiateacc_iop.memacc_code = memacc_cblk.code
|
||||
completeacc_iop.memacc_code = memacc_cblk.code
|
||||
completeacc_iop.postacc_code = postacc_cblk.code
|
||||
elif (exec_template_base.startswith('Store')):
|
||||
initiateacc_iop.ea_code = ea_cblk.code
|
||||
initiateacc_iop.memacc_code = memacc_cblk.code
|
||||
completeacc_iop.postacc_code = postacc_cblk.code
|
||||
|
||||
# generate InstObjParams for unified execution
|
||||
cblk = CodeBlock(ea_code + memacc_code + postacc_code)
|
||||
iop = InstObjParams(name, Name, base_class, cblk, inst_flags)
|
||||
|
||||
iop.ea_constructor = ea_cblk.constructor
|
||||
iop.ea_code = ea_cblk.code
|
||||
iop.memacc_constructor = memacc_cblk.constructor
|
||||
iop.memacc_code = memacc_cblk.code
|
||||
iop.postacc_code = postacc_cblk.code
|
||||
|
||||
if mem_flags:
|
||||
s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
|
||||
iop.constructor += s
|
||||
memacc_iop.constructor += s
|
||||
|
||||
# select templates
|
||||
|
||||
# define aliases... most StoreCond templates are the same as the
|
||||
# corresponding Store templates (only CompleteAcc is different).
|
||||
StoreCondMemAccExecute = StoreMemAccExecute
|
||||
StoreCondExecute = StoreExecute
|
||||
StoreCondInitiateAcc = StoreInitiateAcc
|
||||
|
||||
memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
|
||||
fullExecTemplate = eval(exec_template_base + 'Execute')
|
||||
initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
|
||||
completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
|
||||
|
||||
# (header_output, decoder_output, decode_block, exec_output)
|
||||
return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
|
||||
decode_template.subst(iop),
|
||||
EACompExecute.subst(ea_iop)
|
||||
+ memAccExecTemplate.subst(memacc_iop)
|
||||
+ fullExecTemplate.subst(iop)
|
||||
+ initiateAccTemplate.subst(initiateacc_iop)
|
||||
+ completeAccTemplate.subst(completeacc_iop))
|
||||
}};
|
||||
|
||||
|
||||
def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
|
||||
mem_flags = [], inst_flags = []) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
decode_template = LoadNopCheckDecode,
|
||||
exec_template_base = 'Load')
|
||||
}};
|
||||
|
||||
|
||||
// Note that the flags passed in apply only to the prefetch version
|
||||
def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
|
||||
mem_flags = [], pf_flags = [], inst_flags = []) {{
|
||||
# declare the load instruction object and generate the decode block
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
decode_template = LoadPrefetchCheckDecode,
|
||||
exec_template_base = 'Load')
|
||||
|
||||
# Declare the prefetch instruction object.
|
||||
|
||||
# Make sure flag args are lists so we can mess with them.
|
||||
mem_flags = makeList(mem_flags)
|
||||
pf_flags = makeList(pf_flags)
|
||||
inst_flags = makeList(inst_flags)
|
||||
|
||||
pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
|
||||
pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
|
||||
'IsDataPrefetch', 'MemReadOp']
|
||||
|
||||
(pf_header_output, pf_decoder_output, _, pf_exec_output) = \
|
||||
LoadStoreBase(name, Name + 'Prefetch', ea_code,
|
||||
'xc->prefetch(EA, memAccessFlags);',
|
||||
pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
|
||||
|
||||
header_output += pf_header_output
|
||||
decoder_output += pf_decoder_output
|
||||
exec_output += pf_exec_output
|
||||
}};
|
||||
|
||||
|
||||
def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
|
||||
mem_flags = [], inst_flags = []) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
exec_template_base = 'Store')
|
||||
}};
|
||||
|
||||
|
||||
def format StoreCond(memacc_code, postacc_code,
|
||||
ea_code = {{ EA = Rb + disp; }},
|
||||
mem_flags = [], inst_flags = []) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
postacc_code, exec_template_base = 'StoreCond')
|
||||
}};
|
||||
|
||||
|
||||
// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
|
||||
def format MiscPrefetch(ea_code, memacc_code,
|
||||
mem_flags = [], inst_flags = []) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
|
||||
}};
|
||||
|
||||
|
||||
72
src/arch/alpha/isa/opcdec.isa
Normal file
72
src/arch/alpha/isa/opcdec.isa
Normal file
@@ -0,0 +1,72 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Static instruction class for instructions that cause an OPCDEC fault
|
||||
* when executed. This is currently only for PAL mode instructions
|
||||
* executed in non-PAL mode.
|
||||
*/
|
||||
class OpcdecFault : public AlphaStaticInst
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
OpcdecFault(ExtMachInst _machInst)
|
||||
: AlphaStaticInst("opcdec fault", _machInst, No_OpClass)
|
||||
{
|
||||
}
|
||||
|
||||
%(BasicExecDeclare)s
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
std::string
|
||||
OpcdecFault::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
return csprintf("%-10s (inst 0x%x, opcode 0x%x)",
|
||||
" OPCDEC fault", machInst, OPCODE);
|
||||
}
|
||||
}};
|
||||
|
||||
output exec {{
|
||||
Fault
|
||||
OpcdecFault::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
return new UnimplementedOpcodeFault;
|
||||
}
|
||||
}};
|
||||
|
||||
def format OpcdecFault() {{
|
||||
decode_block = 'return new OpcdecFault(machInst);\n'
|
||||
}};
|
||||
|
||||
271
src/arch/alpha/isa/pal.isa
Normal file
271
src/arch/alpha/isa/pal.isa
Normal file
@@ -0,0 +1,271 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Base class for emulated call_pal calls (used only in
|
||||
* non-full-system mode).
|
||||
*/
|
||||
class EmulatedCallPal : public AlphaStaticInst
|
||||
{
|
||||
protected:
|
||||
|
||||
/// Constructor.
|
||||
EmulatedCallPal(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass)
|
||||
: AlphaStaticInst(mnem, _machInst, __opClass)
|
||||
{
|
||||
}
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
std::string
|
||||
EmulatedCallPal::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
#ifdef SS_COMPATIBLE_DISASSEMBLY
|
||||
return csprintf("%s %s", "call_pal", mnemonic);
|
||||
#else
|
||||
return csprintf("%-10s %s", "call_pal", mnemonic);
|
||||
#endif
|
||||
}
|
||||
}};
|
||||
|
||||
def format EmulatedCallPal(code, *flags) {{
|
||||
iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code), flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Base class for full-system-mode call_pal instructions.
|
||||
* Probably could turn this into a leaf class and get rid of the
|
||||
* parser template.
|
||||
*/
|
||||
class CallPalBase : public AlphaStaticInst
|
||||
{
|
||||
protected:
|
||||
int palFunc; ///< Function code part of instruction
|
||||
int palOffset; ///< Target PC, offset from IPR_PAL_BASE
|
||||
bool palValid; ///< is the function code valid?
|
||||
bool palPriv; ///< is this call privileged?
|
||||
|
||||
/// Constructor.
|
||||
CallPalBase(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass);
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
inline
|
||||
CallPalBase::CallPalBase(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass)
|
||||
: AlphaStaticInst(mnem, _machInst, __opClass),
|
||||
palFunc(PALFUNC)
|
||||
{
|
||||
// From the 21164 HRM (paraphrased):
|
||||
// Bit 7 of the function code (mask 0x80) indicates
|
||||
// whether the call is privileged (bit 7 == 0) or
|
||||
// unprivileged (bit 7 == 1). The privileged call table
|
||||
// starts at 0x2000, the unprivielged call table starts at
|
||||
// 0x3000. Bits 5-0 (mask 0x3f) are used to calculate the
|
||||
// offset.
|
||||
const int palPrivMask = 0x80;
|
||||
const int palOffsetMask = 0x3f;
|
||||
|
||||
// Pal call is invalid unless all other bits are 0
|
||||
palValid = ((machInst & ~(palPrivMask | palOffsetMask)) == 0);
|
||||
palPriv = ((machInst & palPrivMask) == 0);
|
||||
int shortPalFunc = (machInst & palOffsetMask);
|
||||
// Add 1 to base to set pal-mode bit
|
||||
palOffset = (palPriv ? 0x2001 : 0x3001) + (shortPalFunc << 6);
|
||||
}
|
||||
|
||||
std::string
|
||||
CallPalBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
return csprintf("%-10s %#x", "call_pal", palFunc);
|
||||
}
|
||||
}};
|
||||
|
||||
def format CallPal(code, *flags) {{
|
||||
iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code), flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// hw_ld, hw_st
|
||||
//
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Base class for hw_ld and hw_st.
|
||||
*/
|
||||
class HwLoadStore : public Memory
|
||||
{
|
||||
protected:
|
||||
|
||||
/// Displacement for EA calculation (signed).
|
||||
int16_t disp;
|
||||
|
||||
/// Constructor
|
||||
HwLoadStore(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
|
||||
StaticInstPtr _eaCompPtr = nullStaticInstPtr,
|
||||
StaticInstPtr _memAccPtr = nullStaticInstPtr);
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
|
||||
output decoder {{
|
||||
inline
|
||||
HwLoadStore::HwLoadStore(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass,
|
||||
StaticInstPtr _eaCompPtr,
|
||||
StaticInstPtr _memAccPtr)
|
||||
: Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
|
||||
disp(HW_LDST_DISP)
|
||||
{
|
||||
memAccessFlags = 0;
|
||||
if (HW_LDST_PHYS) memAccessFlags |= PHYSICAL;
|
||||
if (HW_LDST_ALT) memAccessFlags |= ALTMODE;
|
||||
if (HW_LDST_VPTE) memAccessFlags |= VPTE;
|
||||
if (HW_LDST_LOCK) memAccessFlags |= LOCKED;
|
||||
}
|
||||
|
||||
std::string
|
||||
HwLoadStore::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
#ifdef SS_COMPATIBLE_DISASSEMBLY
|
||||
return csprintf("%-10s r%d,%d(r%d)", mnemonic, RA, disp, RB);
|
||||
#else
|
||||
// HW_LDST_LOCK and HW_LDST_COND are the same bit.
|
||||
const char *lock_str =
|
||||
(HW_LDST_LOCK) ? (flags[IsLoad] ? ",LOCK" : ",COND") : "";
|
||||
|
||||
return csprintf("%-10s r%d,%d(r%d)%s%s%s%s%s",
|
||||
mnemonic, RA, disp, RB,
|
||||
HW_LDST_PHYS ? ",PHYS" : "",
|
||||
HW_LDST_ALT ? ",ALT" : "",
|
||||
HW_LDST_QUAD ? ",QUAD" : "",
|
||||
HW_LDST_VPTE ? ",VPTE" : "",
|
||||
lock_str);
|
||||
#endif
|
||||
}
|
||||
}};
|
||||
|
||||
def format HwLoad(ea_code, memacc_code, class_ext, *flags) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
|
||||
mem_flags = [], inst_flags = flags,
|
||||
base_class = 'HwLoadStore', exec_template_base = 'Load')
|
||||
}};
|
||||
|
||||
|
||||
def format HwStore(ea_code, memacc_code, class_ext, *flags) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
|
||||
mem_flags = [], inst_flags = flags,
|
||||
base_class = 'HwLoadStore', exec_template_base = 'Store')
|
||||
}};
|
||||
|
||||
|
||||
def format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext,
|
||||
*flags) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
|
||||
postacc_code, mem_flags = [], inst_flags = flags,
|
||||
base_class = 'HwLoadStore')
|
||||
}};
|
||||
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Base class for hw_mfpr and hw_mtpr.
|
||||
*/
|
||||
class HwMoveIPR : public AlphaStaticInst
|
||||
{
|
||||
protected:
|
||||
/// Index of internal processor register.
|
||||
int ipr_index;
|
||||
|
||||
/// Constructor
|
||||
HwMoveIPR(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
|
||||
: AlphaStaticInst(mnem, _machInst, __opClass),
|
||||
ipr_index(HW_IPR_IDX)
|
||||
{
|
||||
}
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
std::string
|
||||
HwMoveIPR::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
if (_numSrcRegs > 0) {
|
||||
// must be mtpr
|
||||
return csprintf("%-10s r%d,IPR(%#x)",
|
||||
mnemonic, RA, ipr_index);
|
||||
}
|
||||
else {
|
||||
// must be mfpr
|
||||
return csprintf("%-10s IPR(%#x),r%d",
|
||||
mnemonic, ipr_index, RA);
|
||||
}
|
||||
}
|
||||
}};
|
||||
|
||||
def format HwMoveIPR(code) {{
|
||||
iop = InstObjParams(name, Name, 'HwMoveIPR', CodeBlock(code),
|
||||
['IprAccessOp'])
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
|
||||
165
src/arch/alpha/isa/unimp.isa
Normal file
165
src/arch/alpha/isa/unimp.isa
Normal file
@@ -0,0 +1,165 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
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 AlphaStaticInst
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
FailUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
|
||||
: AlphaStaticInst(_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 AlphaStaticInst
|
||||
{
|
||||
private:
|
||||
/// Have we warned on this instruction yet?
|
||||
mutable bool warned;
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
WarnUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
|
||||
: AlphaStaticInst(_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' "
|
||||
"(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE);
|
||||
return new UnimplementedOpcodeFault;
|
||||
}
|
||||
|
||||
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)
|
||||
}};
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Static instruction class for unknown (illegal) instructions.
|
||||
* These cause simulator termination if they are executed in a
|
||||
* non-speculative mode. This is a leaf class.
|
||||
*/
|
||||
class Unknown : public AlphaStaticInst
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
Unknown(ExtMachInst _machInst)
|
||||
: AlphaStaticInst("unknown", _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;
|
||||
};
|
||||
}};
|
||||
|
||||
52
src/arch/alpha/isa/unknown.isa
Normal file
52
src/arch/alpha/isa/unknown.isa
Normal file
@@ -0,0 +1,52 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
output decoder {{
|
||||
std::string
|
||||
Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
return csprintf("%-10s (inst 0x%x, opcode 0x%x)",
|
||||
"unknown", machInst, OPCODE);
|
||||
}
|
||||
}};
|
||||
|
||||
output exec {{
|
||||
Fault
|
||||
Unknown::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
panic("attempt to execute unknown instruction "
|
||||
"(inst 0x%08x, opcode 0x%x)", machInst, OPCODE);
|
||||
return new UnimplementedOpcodeFault;
|
||||
}
|
||||
}};
|
||||
|
||||
def format Unknown() {{
|
||||
decode_block = 'return new Unknown(machInst);\n'
|
||||
}};
|
||||
|
||||
112
src/arch/alpha/isa/util.isa
Normal file
112
src/arch/alpha/isa/util.isa
Normal file
@@ -0,0 +1,112 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
output exec {{
|
||||
|
||||
/// Return opa + opb, summing carry into third arg.
|
||||
inline uint64_t
|
||||
addc(uint64_t opa, uint64_t opb, int &carry)
|
||||
{
|
||||
uint64_t res = opa + opb;
|
||||
if (res < opa || res < opb)
|
||||
++carry;
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Multiply two 64-bit values (opa * opb), returning the 128-bit
|
||||
/// product in res_hi and res_lo.
|
||||
inline void
|
||||
mul128(uint64_t opa, uint64_t opb, uint64_t &res_hi, uint64_t &res_lo)
|
||||
{
|
||||
// do a 64x64 --> 128 multiply using four 32x32 --> 64 multiplies
|
||||
uint64_t opa_hi = opa<63:32>;
|
||||
uint64_t opa_lo = opa<31:0>;
|
||||
uint64_t opb_hi = opb<63:32>;
|
||||
uint64_t opb_lo = opb<31:0>;
|
||||
|
||||
res_lo = opa_lo * opb_lo;
|
||||
|
||||
// The middle partial products logically belong in bit
|
||||
// positions 95 to 32. Thus the lower 32 bits of each product
|
||||
// sum into the upper 32 bits of the low result, while the
|
||||
// upper 32 sum into the low 32 bits of the upper result.
|
||||
uint64_t partial1 = opa_hi * opb_lo;
|
||||
uint64_t partial2 = opa_lo * opb_hi;
|
||||
|
||||
uint64_t partial1_lo = partial1<31:0> << 32;
|
||||
uint64_t partial1_hi = partial1<63:32>;
|
||||
uint64_t partial2_lo = partial2<31:0> << 32;
|
||||
uint64_t partial2_hi = partial2<63:32>;
|
||||
|
||||
// Add partial1_lo and partial2_lo to res_lo, keeping track
|
||||
// of any carries out
|
||||
int carry_out = 0;
|
||||
res_lo = addc(partial1_lo, res_lo, carry_out);
|
||||
res_lo = addc(partial2_lo, res_lo, carry_out);
|
||||
|
||||
// Now calculate the high 64 bits...
|
||||
res_hi = (opa_hi * opb_hi) + partial1_hi + partial2_hi + carry_out;
|
||||
}
|
||||
|
||||
/// Map 8-bit S-floating exponent to 11-bit T-floating exponent.
|
||||
/// See Table 2-2 of Alpha AHB.
|
||||
inline int
|
||||
map_s(int old_exp)
|
||||
{
|
||||
int hibit = old_exp<7:>;
|
||||
int lobits = old_exp<6:0>;
|
||||
|
||||
if (hibit == 1) {
|
||||
return (lobits == 0x7f) ? 0x7ff : (0x400 | lobits);
|
||||
}
|
||||
else {
|
||||
return (lobits == 0) ? 0 : (0x380 | lobits);
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a 32-bit S-floating value to the equivalent 64-bit
|
||||
/// representation to be stored in an FP reg.
|
||||
inline uint64_t
|
||||
s_to_t(uint32_t s_val)
|
||||
{
|
||||
uint64_t tmp = s_val;
|
||||
return (tmp<31:> << 63 // sign bit
|
||||
| (uint64_t)map_s(tmp<30:23>) << 52 // exponent
|
||||
| tmp<22:0> << 29); // fraction
|
||||
}
|
||||
|
||||
/// Convert a 64-bit T-floating value to the equivalent 32-bit
|
||||
/// S-floating representation to be stored in memory.
|
||||
inline int32_t
|
||||
t_to_s(uint64_t t_val)
|
||||
{
|
||||
return (t_val<63:62> << 30 // sign bit & hi exp bit
|
||||
| t_val<58:29>); // rest of exp & fraction
|
||||
}
|
||||
}};
|
||||
|
||||
112
src/arch/alpha/isa_traits.hh
Normal file
112
src/arch/alpha/isa_traits.hh
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ALPHA_ISA_TRAITS_HH__
|
||||
#define __ARCH_ALPHA_ISA_TRAITS_HH__
|
||||
|
||||
namespace LittleEndianGuest {}
|
||||
|
||||
#include "arch/alpha/types.hh"
|
||||
#include "arch/alpha/constants.hh"
|
||||
#include "arch/alpha/regfile.hh"
|
||||
#include "config/full_system.hh"
|
||||
#include "sim/host.hh"
|
||||
|
||||
class StaticInstPtr;
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
class SyscallReturn {
|
||||
public:
|
||||
template <class T>
|
||||
SyscallReturn(T v, bool s)
|
||||
{
|
||||
retval = (uint64_t)v;
|
||||
success = s;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
SyscallReturn(T v)
|
||||
{
|
||||
success = (v >= 0);
|
||||
retval = (uint64_t)v;
|
||||
}
|
||||
|
||||
~SyscallReturn() {}
|
||||
|
||||
SyscallReturn& operator=(const SyscallReturn& s) {
|
||||
retval = s.retval;
|
||||
success = s.success;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool successful() { return success; }
|
||||
uint64_t value() { return retval; }
|
||||
|
||||
|
||||
private:
|
||||
uint64_t retval;
|
||||
bool success;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if FULL_SYSTEM
|
||||
#include "arch/alpha/isa_fullsys_traits.hh"
|
||||
#endif
|
||||
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
|
||||
using namespace LittleEndianGuest;
|
||||
|
||||
// redirected register map, really only used for the full system case.
|
||||
extern const int reg_redir[NumIntRegs];
|
||||
|
||||
StaticInstPtr decodeInst(ExtMachInst);
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
|
||||
{
|
||||
// check for error condition. Alpha syscall convention is to
|
||||
// indicate success/failure in reg a3 (r19) and put the
|
||||
// return value itself in the standard return value reg (v0).
|
||||
if (return_value.successful()) {
|
||||
// no error
|
||||
regs->setIntReg(SyscallSuccessReg, 0);
|
||||
regs->setIntReg(ReturnValueReg, return_value.value());
|
||||
} else {
|
||||
// got an error, return details
|
||||
regs->setIntReg(SyscallSuccessReg, (IntReg)-1);
|
||||
regs->setIntReg(ReturnValueReg, -return_value.value());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // __ARCH_ALPHA_ISA_TRAITS_HH__
|
||||
47
src/arch/alpha/linux/aligned.hh
Normal file
47
src/arch/alpha/linux/aligned.hh
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ALPHA_LINUX_ALIGNED_HH__
|
||||
#define __ARCH_ALPHA_LINUX_ALIGNED_HH__
|
||||
|
||||
|
||||
/* GCC 3.3.X has a bug in which attributes+typedefs don't work. 3.2.X is fine
|
||||
* as in 3.4.X, but the bug is marked will not fix in 3.3.X so here is
|
||||
* the work around.
|
||||
*/
|
||||
#if (__GNUC__ == 3 && __GNUC_MINOR__ != 3) || __GNUC__ > 3
|
||||
typedef uint64_t uint64_ta __attribute__ ((aligned (8))) ;
|
||||
typedef int64_t int64_ta __attribute__ ((aligned (8))) ;
|
||||
typedef Addr Addr_a __attribute__ ((aligned (8))) ;
|
||||
#else
|
||||
#define uint64_ta uint64_t __attribute__ ((aligned (8)))
|
||||
#define int64_ta int64_t __attribute__ ((aligned (8)))
|
||||
#define Addr_a Addr __attribute__ ((aligned (8)))
|
||||
#endif /* __GNUC__ __GNUC_MINOR__ */
|
||||
|
||||
#endif /* __ARCH_ALPHA_LINUX_ALIGNED_HH__ */
|
||||
42
src/arch/alpha/linux/hwrpb.hh
Normal file
42
src/arch/alpha/linux/hwrpb.hh
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 1990 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ALPHA_LINUX_HWRPB_HH__
|
||||
#define __ARCH_ALPHA_LINUX_HWRPB_HH__
|
||||
|
||||
#include "arch/alpha/linux/aligned.hh"
|
||||
|
||||
namespace Linux {
|
||||
struct pcb_struct {
|
||||
uint64_ta rpb_ksp;
|
||||
uint64_ta rpb_usp;
|
||||
uint64_ta rpb_ptbr;
|
||||
uint32_t rpb_cc;
|
||||
uint32_t rpb_psn;
|
||||
uint64_ta rpb_unique;
|
||||
uint64_ta rpb_fen;
|
||||
uint64_ta res1, res2;
|
||||
};
|
||||
}
|
||||
#endif // __ARCH_ALPHA_LINUX_HWRPB_HH__
|
||||
70
src/arch/alpha/linux/linux.cc
Normal file
70
src/arch/alpha/linux/linux.cc
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arch/alpha/linux/linux.hh"
|
||||
|
||||
// open(2) flags translation table
|
||||
OpenFlagTransTable AlphaLinux::openFlagTable[] = {
|
||||
#ifdef _MSC_VER
|
||||
{ AlphaLinux::TGT_O_RDONLY, _O_RDONLY },
|
||||
{ AlphaLinux::TGT_O_WRONLY, _O_WRONLY },
|
||||
{ AlphaLinux::TGT_O_RDWR, _O_RDWR },
|
||||
{ AlphaLinux::TGT_O_APPEND, _O_APPEND },
|
||||
{ AlphaLinux::TGT_O_CREAT, _O_CREAT },
|
||||
{ AlphaLinux::TGT_O_TRUNC, _O_TRUNC },
|
||||
{ AlphaLinux::TGT_O_EXCL, _O_EXCL },
|
||||
#ifdef _O_NONBLOCK
|
||||
{ AlphaLinux::TGT_O_NONBLOCK, _O_NONBLOCK },
|
||||
#endif
|
||||
#ifdef _O_NOCTTY
|
||||
{ AlphaLinux::TGT_O_NOCTTY, _O_NOCTTY },
|
||||
#endif
|
||||
#ifdef _O_SYNC
|
||||
{ AlphaLinux::TGT_O_SYNC, _O_SYNC },
|
||||
#endif
|
||||
#else /* !_MSC_VER */
|
||||
{ AlphaLinux::TGT_O_RDONLY, O_RDONLY },
|
||||
{ AlphaLinux::TGT_O_WRONLY, O_WRONLY },
|
||||
{ AlphaLinux::TGT_O_RDWR, O_RDWR },
|
||||
{ AlphaLinux::TGT_O_APPEND, O_APPEND },
|
||||
{ AlphaLinux::TGT_O_CREAT, O_CREAT },
|
||||
{ AlphaLinux::TGT_O_TRUNC, O_TRUNC },
|
||||
{ AlphaLinux::TGT_O_EXCL, O_EXCL },
|
||||
{ AlphaLinux::TGT_O_NONBLOCK, O_NONBLOCK },
|
||||
{ AlphaLinux::TGT_O_NOCTTY, O_NOCTTY },
|
||||
#ifdef O_SYNC
|
||||
{ AlphaLinux::TGT_O_SYNC, O_SYNC },
|
||||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
};
|
||||
|
||||
const int AlphaLinux::NUM_OPEN_FLAGS =
|
||||
(sizeof(AlphaLinux::openFlagTable)/sizeof(AlphaLinux::openFlagTable[0]));
|
||||
|
||||
|
||||
|
||||
128
src/arch/alpha/linux/linux.hh
Normal file
128
src/arch/alpha/linux/linux.hh
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ALPHA_ALPHA_LINUX_HH
|
||||
#define __ALPHA_ALPHA_LINUX_HH
|
||||
|
||||
#include "kern/linux/linux.hh"
|
||||
|
||||
/* AlphaLinux class contains static constants/definitions/misc.
|
||||
* structures which are specific to the Linux OS AND the Alpha
|
||||
* architecture
|
||||
*/
|
||||
class AlphaLinux : public Linux
|
||||
{
|
||||
public:
|
||||
|
||||
/// This table maps the target open() flags to the corresponding
|
||||
/// host open() flags.
|
||||
static OpenFlagTransTable openFlagTable[];
|
||||
|
||||
/// Number of entries in openFlagTable[].
|
||||
static const int NUM_OPEN_FLAGS;
|
||||
|
||||
//@{
|
||||
/// open(2) flag values.
|
||||
static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY
|
||||
static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY
|
||||
static const int TGT_O_RDWR = 00000002; //!< O_RDWR
|
||||
static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK
|
||||
static const int TGT_O_APPEND = 00000010; //!< O_APPEND
|
||||
static const int TGT_O_CREAT = 00001000; //!< O_CREAT
|
||||
static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC
|
||||
static const int TGT_O_EXCL = 00004000; //!< O_EXCL
|
||||
static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY
|
||||
static const int TGT_O_SYNC = 00040000; //!< O_SYNC
|
||||
static const int TGT_O_DRD = 00100000; //!< O_DRD
|
||||
static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO
|
||||
static const int TGT_O_CACHE = 00400000; //!< O_CACHE
|
||||
static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC
|
||||
static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC
|
||||
//@}
|
||||
|
||||
/// For mmap().
|
||||
static const unsigned TGT_MAP_ANONYMOUS = 0x10;
|
||||
|
||||
//@{
|
||||
/// For getsysinfo().
|
||||
static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
|
||||
static const unsigned GSI_CPU_INFO = 59; //!< CPU information
|
||||
static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
|
||||
static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine
|
||||
static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
|
||||
static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB
|
||||
static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
|
||||
static const unsigned GSI_IEEE_FP_CONTROL = 45;
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/// For getrusage().
|
||||
static const int TGT_RUSAGE_SELF = 0;
|
||||
static const int TGT_RUSAGE_CHILDREN = -1;
|
||||
static const int TGT_RUSAGE_BOTH = -2;
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/// For setsysinfo().
|
||||
static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control()
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/// 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;
|
||||
//@}
|
||||
|
||||
/// For table().
|
||||
static const int TBL_SYSINFO = 12;
|
||||
|
||||
/// Resource enumeration for getrlimit().
|
||||
enum rlimit_resources {
|
||||
TGT_RLIMIT_CPU = 0,
|
||||
TGT_RLIMIT_FSIZE = 1,
|
||||
TGT_RLIMIT_DATA = 2,
|
||||
TGT_RLIMIT_STACK = 3,
|
||||
TGT_RLIMIT_CORE = 4,
|
||||
TGT_RLIMIT_RSS = 5,
|
||||
TGT_RLIMIT_NOFILE = 6,
|
||||
TGT_RLIMIT_AS = 7,
|
||||
TGT_RLIMIT_VMEM = 7,
|
||||
TGT_RLIMIT_NPROC = 8,
|
||||
TGT_RLIMIT_MEMLOCK = 9,
|
||||
TGT_RLIMIT_LOCKS = 10
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
591
src/arch/alpha/linux/process.cc
Normal file
591
src/arch/alpha/linux/process.cc
Normal file
@@ -0,0 +1,591 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arch/alpha/linux/linux.hh"
|
||||
#include "arch/alpha/linux/process.hh"
|
||||
#include "arch/alpha/isa_traits.hh"
|
||||
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "kern/linux/linux.hh"
|
||||
|
||||
#include "sim/process.hh"
|
||||
#include "sim/syscall_emul.hh"
|
||||
|
||||
using namespace std;
|
||||
using namespace AlphaISA;
|
||||
|
||||
|
||||
|
||||
/// Target uname() handler.
|
||||
static SyscallReturn
|
||||
unameFunc(SyscallDesc *desc, int callnum, Process *process,
|
||||
ExecContext *xc)
|
||||
{
|
||||
TypedBufferArg<Linux::utsname> name(xc->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, "alpha");
|
||||
|
||||
name.copyOut(xc->getMemPort());
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Target osf_getsysyinfo() handler. Even though this call is
|
||||
/// borrowed from Tru64, the subcases that get used appear to be
|
||||
/// different in practice from those used by Tru64 processes.
|
||||
static SyscallReturn
|
||||
osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
|
||||
ExecContext *xc)
|
||||
{
|
||||
unsigned op = xc->getSyscallArg(0);
|
||||
// unsigned nbytes = xc->getSyscallArg(2);
|
||||
|
||||
switch (op) {
|
||||
|
||||
case 45: { // GSI_IEEE_FP_CONTROL
|
||||
TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
|
||||
// I don't think this exactly matches the HW FPCR
|
||||
*fpcr = 0;
|
||||
fpcr.copyOut(xc->getMemPort());
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
cerr << "osf_getsysinfo: unknown op " << op << endl;
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// Target osf_setsysinfo() handler.
|
||||
static SyscallReturn
|
||||
osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
|
||||
ExecContext *xc)
|
||||
{
|
||||
unsigned op = xc->getSyscallArg(0);
|
||||
// unsigned nbytes = xc->getSyscallArg(2);
|
||||
|
||||
switch (op) {
|
||||
|
||||
case 14: { // SSI_IEEE_FP_CONTROL
|
||||
TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
|
||||
// I don't think this exactly matches the HW FPCR
|
||||
fpcr.copyIn(xc->getMemPort());
|
||||
DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
|
||||
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
cerr << "osf_setsysinfo: unknown op " << op << endl;
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
|
||||
/* 0 */ SyscallDesc("osf_syscall", unimplementedFunc),
|
||||
/* 1 */ SyscallDesc("exit", exitFunc),
|
||||
/* 2 */ SyscallDesc("fork", unimplementedFunc),
|
||||
/* 3 */ SyscallDesc("read", readFunc),
|
||||
/* 4 */ SyscallDesc("write", writeFunc),
|
||||
/* 5 */ SyscallDesc("osf_old_open", unimplementedFunc),
|
||||
/* 6 */ SyscallDesc("close", closeFunc),
|
||||
/* 7 */ SyscallDesc("osf_wait4", unimplementedFunc),
|
||||
/* 8 */ SyscallDesc("osf_old_creat", unimplementedFunc),
|
||||
/* 9 */ SyscallDesc("link", unimplementedFunc),
|
||||
/* 10 */ SyscallDesc("unlink", unlinkFunc),
|
||||
/* 11 */ SyscallDesc("osf_execve", unimplementedFunc),
|
||||
/* 12 */ SyscallDesc("chdir", unimplementedFunc),
|
||||
/* 13 */ SyscallDesc("fchdir", unimplementedFunc),
|
||||
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
|
||||
/* 15 */ SyscallDesc("chmod", chmodFunc<AlphaLinux>),
|
||||
/* 16 */ SyscallDesc("chown", chownFunc),
|
||||
/* 17 */ SyscallDesc("brk", obreakFunc),
|
||||
/* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc),
|
||||
/* 19 */ SyscallDesc("lseek", lseekFunc),
|
||||
/* 20 */ SyscallDesc("getxpid", getpidPseudoFunc),
|
||||
/* 21 */ SyscallDesc("osf_mount", unimplementedFunc),
|
||||
/* 22 */ SyscallDesc("umount", unimplementedFunc),
|
||||
/* 23 */ SyscallDesc("setuid", setuidFunc),
|
||||
/* 24 */ SyscallDesc("getxuid", getuidPseudoFunc),
|
||||
/* 25 */ SyscallDesc("exec_with_loader", unimplementedFunc),
|
||||
/* 26 */ SyscallDesc("osf_ptrace", unimplementedFunc),
|
||||
/* 27 */ SyscallDesc("osf_nrecvmsg", unimplementedFunc),
|
||||
/* 28 */ SyscallDesc("osf_nsendmsg", unimplementedFunc),
|
||||
/* 29 */ SyscallDesc("osf_nrecvfrom", unimplementedFunc),
|
||||
/* 30 */ SyscallDesc("osf_naccept", unimplementedFunc),
|
||||
/* 31 */ SyscallDesc("osf_ngetpeername", unimplementedFunc),
|
||||
/* 32 */ SyscallDesc("osf_ngetsockname", unimplementedFunc),
|
||||
/* 33 */ SyscallDesc("access", unimplementedFunc),
|
||||
/* 34 */ SyscallDesc("osf_chflags", unimplementedFunc),
|
||||
/* 35 */ SyscallDesc("osf_fchflags", unimplementedFunc),
|
||||
/* 36 */ SyscallDesc("sync", unimplementedFunc),
|
||||
/* 37 */ SyscallDesc("kill", unimplementedFunc),
|
||||
/* 38 */ SyscallDesc("osf_old_stat", unimplementedFunc),
|
||||
/* 39 */ SyscallDesc("setpgid", unimplementedFunc),
|
||||
/* 40 */ SyscallDesc("osf_old_lstat", unimplementedFunc),
|
||||
/* 41 */ SyscallDesc("dup", unimplementedFunc),
|
||||
/* 42 */ SyscallDesc("pipe", pipePseudoFunc),
|
||||
/* 43 */ SyscallDesc("osf_set_program_attributes", unimplementedFunc),
|
||||
/* 44 */ SyscallDesc("osf_profil", unimplementedFunc),
|
||||
/* 45 */ SyscallDesc("open", openFunc<AlphaLinux>),
|
||||
/* 46 */ SyscallDesc("osf_old_sigaction", unimplementedFunc),
|
||||
/* 47 */ SyscallDesc("getxgid", getgidPseudoFunc),
|
||||
/* 48 */ SyscallDesc("osf_sigprocmask", ignoreFunc),
|
||||
/* 49 */ SyscallDesc("osf_getlogin", unimplementedFunc),
|
||||
/* 50 */ SyscallDesc("osf_setlogin", unimplementedFunc),
|
||||
/* 51 */ SyscallDesc("acct", unimplementedFunc),
|
||||
/* 52 */ SyscallDesc("sigpending", unimplementedFunc),
|
||||
/* 53 */ SyscallDesc("osf_classcntl", unimplementedFunc),
|
||||
/* 54 */ SyscallDesc("ioctl", ioctlFunc<AlphaLinux>),
|
||||
/* 55 */ SyscallDesc("osf_reboot", unimplementedFunc),
|
||||
/* 56 */ SyscallDesc("osf_revoke", unimplementedFunc),
|
||||
/* 57 */ SyscallDesc("symlink", unimplementedFunc),
|
||||
/* 58 */ SyscallDesc("readlink", unimplementedFunc),
|
||||
/* 59 */ SyscallDesc("execve", unimplementedFunc),
|
||||
/* 60 */ SyscallDesc("umask", unimplementedFunc),
|
||||
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
|
||||
/* 62 */ SyscallDesc("osf_old_fstat", unimplementedFunc),
|
||||
/* 63 */ SyscallDesc("getpgrp", unimplementedFunc),
|
||||
/* 64 */ SyscallDesc("getpagesize", getpagesizeFunc),
|
||||
/* 65 */ SyscallDesc("osf_mremap", unimplementedFunc),
|
||||
/* 66 */ SyscallDesc("vfork", unimplementedFunc),
|
||||
/* 67 */ SyscallDesc("stat", statFunc<AlphaLinux>),
|
||||
/* 68 */ SyscallDesc("lstat", lstatFunc<AlphaLinux>),
|
||||
/* 69 */ SyscallDesc("osf_sbrk", unimplementedFunc),
|
||||
/* 70 */ SyscallDesc("osf_sstk", unimplementedFunc),
|
||||
/* 71 */ SyscallDesc("mmap", mmapFunc<AlphaLinux>),
|
||||
/* 72 */ SyscallDesc("osf_old_vadvise", unimplementedFunc),
|
||||
/* 73 */ SyscallDesc("munmap", munmapFunc),
|
||||
/* 74 */ SyscallDesc("mprotect", ignoreFunc),
|
||||
/* 75 */ SyscallDesc("madvise", unimplementedFunc),
|
||||
/* 76 */ SyscallDesc("vhangup", unimplementedFunc),
|
||||
/* 77 */ SyscallDesc("osf_kmodcall", unimplementedFunc),
|
||||
/* 78 */ SyscallDesc("osf_mincore", unimplementedFunc),
|
||||
/* 79 */ SyscallDesc("getgroups", unimplementedFunc),
|
||||
/* 80 */ SyscallDesc("setgroups", unimplementedFunc),
|
||||
/* 81 */ SyscallDesc("osf_old_getpgrp", unimplementedFunc),
|
||||
/* 82 */ SyscallDesc("setpgrp", unimplementedFunc),
|
||||
/* 83 */ SyscallDesc("osf_setitimer", unimplementedFunc),
|
||||
/* 84 */ SyscallDesc("osf_old_wait", unimplementedFunc),
|
||||
/* 85 */ SyscallDesc("osf_table", unimplementedFunc),
|
||||
/* 86 */ SyscallDesc("osf_getitimer", unimplementedFunc),
|
||||
/* 87 */ SyscallDesc("gethostname", gethostnameFunc),
|
||||
/* 88 */ SyscallDesc("sethostname", unimplementedFunc),
|
||||
/* 89 */ SyscallDesc("getdtablesize", unimplementedFunc),
|
||||
/* 90 */ SyscallDesc("dup2", unimplementedFunc),
|
||||
/* 91 */ SyscallDesc("fstat", fstatFunc<AlphaLinux>),
|
||||
/* 92 */ SyscallDesc("fcntl", fcntlFunc),
|
||||
/* 93 */ SyscallDesc("osf_select", unimplementedFunc),
|
||||
/* 94 */ SyscallDesc("poll", 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("send", unimplementedFunc),
|
||||
/* 102 */ SyscallDesc("recv", unimplementedFunc),
|
||||
/* 103 */ SyscallDesc("sigreturn", unimplementedFunc),
|
||||
/* 104 */ SyscallDesc("bind", unimplementedFunc),
|
||||
/* 105 */ SyscallDesc("setsockopt", unimplementedFunc),
|
||||
/* 106 */ SyscallDesc("listen", unimplementedFunc),
|
||||
/* 107 */ SyscallDesc("osf_plock", unimplementedFunc),
|
||||
/* 108 */ SyscallDesc("osf_old_sigvec", unimplementedFunc),
|
||||
/* 109 */ SyscallDesc("osf_old_sigblock", unimplementedFunc),
|
||||
/* 110 */ SyscallDesc("osf_old_sigsetmask", unimplementedFunc),
|
||||
/* 111 */ SyscallDesc("sigsuspend", unimplementedFunc),
|
||||
/* 112 */ SyscallDesc("osf_sigstack", ignoreFunc),
|
||||
/* 113 */ SyscallDesc("recvmsg", unimplementedFunc),
|
||||
/* 114 */ SyscallDesc("sendmsg", unimplementedFunc),
|
||||
/* 115 */ SyscallDesc("osf_old_vtrace", unimplementedFunc),
|
||||
/* 116 */ SyscallDesc("osf_gettimeofday", unimplementedFunc),
|
||||
/* 117 */ SyscallDesc("osf_getrusage", unimplementedFunc),
|
||||
/* 118 */ SyscallDesc("getsockopt", unimplementedFunc),
|
||||
/* 119 */ SyscallDesc("numa_syscalls", unimplementedFunc),
|
||||
/* 120 */ SyscallDesc("readv", unimplementedFunc),
|
||||
/* 121 */ SyscallDesc("writev", writevFunc<AlphaLinux>),
|
||||
/* 122 */ SyscallDesc("osf_settimeofday", unimplementedFunc),
|
||||
/* 123 */ SyscallDesc("fchown", fchownFunc),
|
||||
/* 124 */ SyscallDesc("fchmod", fchmodFunc<AlphaLinux>),
|
||||
/* 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("setgid", unimplementedFunc),
|
||||
/* 133 */ SyscallDesc("sendto", unimplementedFunc),
|
||||
/* 134 */ SyscallDesc("shutdown", unimplementedFunc),
|
||||
/* 135 */ SyscallDesc("socketpair", unimplementedFunc),
|
||||
/* 136 */ SyscallDesc("mkdir", unimplementedFunc),
|
||||
/* 137 */ SyscallDesc("rmdir", unimplementedFunc),
|
||||
/* 138 */ SyscallDesc("osf_utimes", unimplementedFunc),
|
||||
/* 139 */ SyscallDesc("osf_old_sigreturn", unimplementedFunc),
|
||||
/* 140 */ SyscallDesc("osf_adjtime", unimplementedFunc),
|
||||
/* 141 */ SyscallDesc("getpeername", unimplementedFunc),
|
||||
/* 142 */ SyscallDesc("osf_gethostid", unimplementedFunc),
|
||||
/* 143 */ SyscallDesc("osf_sethostid", unimplementedFunc),
|
||||
/* 144 */ SyscallDesc("getrlimit", getrlimitFunc<AlphaLinux>),
|
||||
/* 145 */ SyscallDesc("setrlimit", ignoreFunc),
|
||||
/* 146 */ SyscallDesc("osf_old_killpg", unimplementedFunc),
|
||||
/* 147 */ SyscallDesc("setsid", unimplementedFunc),
|
||||
/* 148 */ SyscallDesc("quotactl", unimplementedFunc),
|
||||
/* 149 */ SyscallDesc("osf_oldquota", unimplementedFunc),
|
||||
/* 150 */ SyscallDesc("getsockname", unimplementedFunc),
|
||||
/* 151 */ SyscallDesc("osf_pread", unimplementedFunc),
|
||||
/* 152 */ SyscallDesc("osf_pwrite", unimplementedFunc),
|
||||
/* 153 */ SyscallDesc("osf_pid_block", unimplementedFunc),
|
||||
/* 154 */ SyscallDesc("osf_pid_unblock", unimplementedFunc),
|
||||
/* 155 */ SyscallDesc("osf_signal_urti", unimplementedFunc),
|
||||
/* 156 */ SyscallDesc("sigaction", ignoreFunc),
|
||||
/* 157 */ SyscallDesc("osf_sigwaitprim", unimplementedFunc),
|
||||
/* 158 */ SyscallDesc("osf_nfssvc", unimplementedFunc),
|
||||
/* 159 */ SyscallDesc("osf_getdirentries", unimplementedFunc),
|
||||
/* 160 */ SyscallDesc("osf_statfs", unimplementedFunc),
|
||||
/* 161 */ SyscallDesc("osf_fstatfs", unimplementedFunc),
|
||||
/* 162 */ SyscallDesc("unknown #162", unimplementedFunc),
|
||||
/* 163 */ SyscallDesc("osf_async_daemon", unimplementedFunc),
|
||||
/* 164 */ SyscallDesc("osf_getfh", unimplementedFunc),
|
||||
/* 165 */ SyscallDesc("osf_getdomainname", unimplementedFunc),
|
||||
/* 166 */ SyscallDesc("setdomainname", unimplementedFunc),
|
||||
/* 167 */ SyscallDesc("unknown #167", unimplementedFunc),
|
||||
/* 168 */ SyscallDesc("unknown #168", unimplementedFunc),
|
||||
/* 169 */ SyscallDesc("osf_exportfs", unimplementedFunc),
|
||||
/* 170 */ SyscallDesc("unknown #170", unimplementedFunc),
|
||||
/* 171 */ SyscallDesc("unknown #171", unimplementedFunc),
|
||||
/* 172 */ SyscallDesc("unknown #172", unimplementedFunc),
|
||||
/* 173 */ SyscallDesc("unknown #173", unimplementedFunc),
|
||||
/* 174 */ SyscallDesc("unknown #174", unimplementedFunc),
|
||||
/* 175 */ SyscallDesc("unknown #175", unimplementedFunc),
|
||||
/* 176 */ SyscallDesc("unknown #176", unimplementedFunc),
|
||||
/* 177 */ SyscallDesc("unknown #177", unimplementedFunc),
|
||||
/* 178 */ SyscallDesc("unknown #178", unimplementedFunc),
|
||||
/* 179 */ SyscallDesc("unknown #179", unimplementedFunc),
|
||||
/* 180 */ SyscallDesc("unknown #180", unimplementedFunc),
|
||||
/* 181 */ SyscallDesc("osf_alt_plock", unimplementedFunc),
|
||||
/* 182 */ SyscallDesc("unknown #182", unimplementedFunc),
|
||||
/* 183 */ SyscallDesc("unknown #183", unimplementedFunc),
|
||||
/* 184 */ SyscallDesc("osf_getmnt", unimplementedFunc),
|
||||
/* 185 */ SyscallDesc("unknown #185", unimplementedFunc),
|
||||
/* 186 */ SyscallDesc("unknown #186", unimplementedFunc),
|
||||
/* 187 */ SyscallDesc("osf_alt_sigpending", unimplementedFunc),
|
||||
/* 188 */ SyscallDesc("osf_alt_setsid", unimplementedFunc),
|
||||
/* 189 */ SyscallDesc("unknown #189", unimplementedFunc),
|
||||
/* 190 */ SyscallDesc("unknown #190", unimplementedFunc),
|
||||
/* 191 */ SyscallDesc("unknown #191", unimplementedFunc),
|
||||
/* 192 */ SyscallDesc("unknown #192", unimplementedFunc),
|
||||
/* 193 */ SyscallDesc("unknown #193", unimplementedFunc),
|
||||
/* 194 */ SyscallDesc("unknown #194", unimplementedFunc),
|
||||
/* 195 */ SyscallDesc("unknown #195", unimplementedFunc),
|
||||
/* 196 */ SyscallDesc("unknown #196", unimplementedFunc),
|
||||
/* 197 */ SyscallDesc("unknown #197", unimplementedFunc),
|
||||
/* 198 */ SyscallDesc("unknown #198", unimplementedFunc),
|
||||
/* 199 */ SyscallDesc("osf_swapon", unimplementedFunc),
|
||||
/* 200 */ SyscallDesc("msgctl", unimplementedFunc),
|
||||
/* 201 */ SyscallDesc("msgget", unimplementedFunc),
|
||||
/* 202 */ SyscallDesc("msgrcv", unimplementedFunc),
|
||||
/* 203 */ SyscallDesc("msgsnd", unimplementedFunc),
|
||||
/* 204 */ SyscallDesc("semctl", unimplementedFunc),
|
||||
/* 205 */ SyscallDesc("semget", unimplementedFunc),
|
||||
/* 206 */ SyscallDesc("semop", unimplementedFunc),
|
||||
/* 207 */ SyscallDesc("osf_utsname", unimplementedFunc),
|
||||
/* 208 */ SyscallDesc("lchown", unimplementedFunc),
|
||||
/* 209 */ SyscallDesc("osf_shmat", unimplementedFunc),
|
||||
/* 210 */ SyscallDesc("shmctl", unimplementedFunc),
|
||||
/* 211 */ SyscallDesc("shmdt", unimplementedFunc),
|
||||
/* 212 */ SyscallDesc("shmget", unimplementedFunc),
|
||||
/* 213 */ SyscallDesc("osf_mvalid", unimplementedFunc),
|
||||
/* 214 */ SyscallDesc("osf_getaddressconf", unimplementedFunc),
|
||||
/* 215 */ SyscallDesc("osf_msleep", unimplementedFunc),
|
||||
/* 216 */ SyscallDesc("osf_mwakeup", unimplementedFunc),
|
||||
/* 217 */ SyscallDesc("msync", unimplementedFunc),
|
||||
/* 218 */ SyscallDesc("osf_signal", unimplementedFunc),
|
||||
/* 219 */ SyscallDesc("osf_utc_gettime", unimplementedFunc),
|
||||
/* 220 */ SyscallDesc("osf_utc_adjtime", unimplementedFunc),
|
||||
/* 221 */ SyscallDesc("unknown #221", unimplementedFunc),
|
||||
/* 222 */ SyscallDesc("osf_security", unimplementedFunc),
|
||||
/* 223 */ SyscallDesc("osf_kloadcall", unimplementedFunc),
|
||||
/* 224 */ SyscallDesc("unknown #224", unimplementedFunc),
|
||||
/* 225 */ SyscallDesc("unknown #225", unimplementedFunc),
|
||||
/* 226 */ SyscallDesc("unknown #226", unimplementedFunc),
|
||||
/* 227 */ SyscallDesc("unknown #227", unimplementedFunc),
|
||||
/* 228 */ SyscallDesc("unknown #228", unimplementedFunc),
|
||||
/* 229 */ SyscallDesc("unknown #229", unimplementedFunc),
|
||||
/* 230 */ SyscallDesc("unknown #230", unimplementedFunc),
|
||||
/* 231 */ SyscallDesc("unknown #231", unimplementedFunc),
|
||||
/* 232 */ SyscallDesc("unknown #232", unimplementedFunc),
|
||||
/* 233 */ SyscallDesc("getpgid", unimplementedFunc),
|
||||
/* 234 */ SyscallDesc("getsid", unimplementedFunc),
|
||||
/* 235 */ SyscallDesc("sigaltstack", ignoreFunc),
|
||||
/* 236 */ SyscallDesc("osf_waitid", unimplementedFunc),
|
||||
/* 237 */ SyscallDesc("osf_priocntlset", unimplementedFunc),
|
||||
/* 238 */ SyscallDesc("osf_sigsendset", unimplementedFunc),
|
||||
/* 239 */ SyscallDesc("osf_set_speculative", unimplementedFunc),
|
||||
/* 240 */ SyscallDesc("osf_msfs_syscall", unimplementedFunc),
|
||||
/* 241 */ SyscallDesc("osf_sysinfo", unimplementedFunc),
|
||||
/* 242 */ SyscallDesc("osf_uadmin", unimplementedFunc),
|
||||
/* 243 */ SyscallDesc("osf_fuser", unimplementedFunc),
|
||||
/* 244 */ SyscallDesc("osf_proplist_syscall", unimplementedFunc),
|
||||
/* 245 */ SyscallDesc("osf_ntp_adjtime", unimplementedFunc),
|
||||
/* 246 */ SyscallDesc("osf_ntp_gettime", unimplementedFunc),
|
||||
/* 247 */ SyscallDesc("osf_pathconf", unimplementedFunc),
|
||||
/* 248 */ SyscallDesc("osf_fpathconf", unimplementedFunc),
|
||||
/* 249 */ SyscallDesc("unknown #249", unimplementedFunc),
|
||||
/* 250 */ SyscallDesc("osf_uswitch", unimplementedFunc),
|
||||
/* 251 */ SyscallDesc("osf_usleep_thread", unimplementedFunc),
|
||||
/* 252 */ SyscallDesc("osf_audcntl", unimplementedFunc),
|
||||
/* 253 */ SyscallDesc("osf_audgen", unimplementedFunc),
|
||||
/* 254 */ SyscallDesc("sysfs", unimplementedFunc),
|
||||
/* 255 */ SyscallDesc("osf_subsys_info", unimplementedFunc),
|
||||
/* 256 */ SyscallDesc("osf_getsysinfo", osf_getsysinfoFunc),
|
||||
/* 257 */ SyscallDesc("osf_setsysinfo", osf_setsysinfoFunc),
|
||||
/* 258 */ SyscallDesc("osf_afs_syscall", unimplementedFunc),
|
||||
/* 259 */ SyscallDesc("osf_swapctl", unimplementedFunc),
|
||||
/* 260 */ SyscallDesc("osf_memcntl", unimplementedFunc),
|
||||
/* 261 */ SyscallDesc("osf_fdatasync", unimplementedFunc),
|
||||
/* 262 */ SyscallDesc("unknown #262", unimplementedFunc),
|
||||
/* 263 */ SyscallDesc("unknown #263", unimplementedFunc),
|
||||
/* 264 */ SyscallDesc("unknown #264", unimplementedFunc),
|
||||
/* 265 */ SyscallDesc("unknown #265", unimplementedFunc),
|
||||
/* 266 */ SyscallDesc("unknown #266", unimplementedFunc),
|
||||
/* 267 */ SyscallDesc("unknown #267", unimplementedFunc),
|
||||
/* 268 */ SyscallDesc("unknown #268", unimplementedFunc),
|
||||
/* 269 */ SyscallDesc("unknown #269", unimplementedFunc),
|
||||
/* 270 */ SyscallDesc("unknown #270", unimplementedFunc),
|
||||
/* 271 */ SyscallDesc("unknown #271", unimplementedFunc),
|
||||
/* 272 */ SyscallDesc("unknown #272", unimplementedFunc),
|
||||
/* 273 */ SyscallDesc("unknown #273", unimplementedFunc),
|
||||
/* 274 */ SyscallDesc("unknown #274", unimplementedFunc),
|
||||
/* 275 */ SyscallDesc("unknown #275", unimplementedFunc),
|
||||
/* 276 */ SyscallDesc("unknown #276", unimplementedFunc),
|
||||
/* 277 */ SyscallDesc("unknown #277", unimplementedFunc),
|
||||
/* 278 */ SyscallDesc("unknown #278", unimplementedFunc),
|
||||
/* 279 */ SyscallDesc("unknown #279", unimplementedFunc),
|
||||
/* 280 */ SyscallDesc("unknown #280", unimplementedFunc),
|
||||
/* 281 */ SyscallDesc("unknown #281", unimplementedFunc),
|
||||
/* 282 */ SyscallDesc("unknown #282", unimplementedFunc),
|
||||
/* 283 */ SyscallDesc("unknown #283", unimplementedFunc),
|
||||
/* 284 */ SyscallDesc("unknown #284", unimplementedFunc),
|
||||
/* 285 */ SyscallDesc("unknown #285", unimplementedFunc),
|
||||
/* 286 */ SyscallDesc("unknown #286", unimplementedFunc),
|
||||
/* 287 */ SyscallDesc("unknown #287", unimplementedFunc),
|
||||
/* 288 */ SyscallDesc("unknown #288", unimplementedFunc),
|
||||
/* 289 */ SyscallDesc("unknown #289", unimplementedFunc),
|
||||
/* 290 */ SyscallDesc("unknown #290", unimplementedFunc),
|
||||
/* 291 */ SyscallDesc("unknown #291", unimplementedFunc),
|
||||
/* 292 */ SyscallDesc("unknown #292", unimplementedFunc),
|
||||
/* 293 */ SyscallDesc("unknown #293", unimplementedFunc),
|
||||
/* 294 */ SyscallDesc("unknown #294", unimplementedFunc),
|
||||
/* 295 */ SyscallDesc("unknown #295", unimplementedFunc),
|
||||
/* 296 */ SyscallDesc("unknown #296", unimplementedFunc),
|
||||
/* 297 */ SyscallDesc("unknown #297", unimplementedFunc),
|
||||
/* 298 */ SyscallDesc("unknown #298", unimplementedFunc),
|
||||
/* 299 */ SyscallDesc("unknown #299", unimplementedFunc),
|
||||
/*
|
||||
* Linux-specific system calls begin at 300
|
||||
*/
|
||||
/* 300 */ SyscallDesc("bdflush", unimplementedFunc),
|
||||
/* 301 */ SyscallDesc("sethae", unimplementedFunc),
|
||||
/* 302 */ SyscallDesc("mount", unimplementedFunc),
|
||||
/* 303 */ SyscallDesc("old_adjtimex", unimplementedFunc),
|
||||
/* 304 */ SyscallDesc("swapoff", unimplementedFunc),
|
||||
/* 305 */ SyscallDesc("getdents", unimplementedFunc),
|
||||
/* 306 */ SyscallDesc("create_module", unimplementedFunc),
|
||||
/* 307 */ SyscallDesc("init_module", unimplementedFunc),
|
||||
/* 308 */ SyscallDesc("delete_module", unimplementedFunc),
|
||||
/* 309 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
|
||||
/* 310 */ SyscallDesc("syslog", unimplementedFunc),
|
||||
/* 311 */ SyscallDesc("reboot", unimplementedFunc),
|
||||
/* 312 */ SyscallDesc("clone", unimplementedFunc),
|
||||
/* 313 */ SyscallDesc("uselib", unimplementedFunc),
|
||||
/* 314 */ SyscallDesc("mlock", unimplementedFunc),
|
||||
/* 315 */ SyscallDesc("munlock", unimplementedFunc),
|
||||
/* 316 */ SyscallDesc("mlockall", unimplementedFunc),
|
||||
/* 317 */ SyscallDesc("munlockall", unimplementedFunc),
|
||||
/* 318 */ SyscallDesc("sysinfo", unimplementedFunc),
|
||||
/* 319 */ SyscallDesc("_sysctl", unimplementedFunc),
|
||||
/* 320 */ SyscallDesc("was sys_idle", unimplementedFunc),
|
||||
/* 321 */ SyscallDesc("oldumount", unimplementedFunc),
|
||||
/* 322 */ SyscallDesc("swapon", unimplementedFunc),
|
||||
/* 323 */ SyscallDesc("times", ignoreFunc),
|
||||
/* 324 */ SyscallDesc("personality", unimplementedFunc),
|
||||
/* 325 */ SyscallDesc("setfsuid", unimplementedFunc),
|
||||
/* 326 */ SyscallDesc("setfsgid", unimplementedFunc),
|
||||
/* 327 */ SyscallDesc("ustat", unimplementedFunc),
|
||||
/* 328 */ SyscallDesc("statfs", unimplementedFunc),
|
||||
/* 329 */ SyscallDesc("fstatfs", unimplementedFunc),
|
||||
/* 330 */ SyscallDesc("sched_setparam", unimplementedFunc),
|
||||
/* 331 */ SyscallDesc("sched_getparam", unimplementedFunc),
|
||||
/* 332 */ SyscallDesc("sched_setscheduler", unimplementedFunc),
|
||||
/* 333 */ SyscallDesc("sched_getscheduler", unimplementedFunc),
|
||||
/* 334 */ SyscallDesc("sched_yield", unimplementedFunc),
|
||||
/* 335 */ SyscallDesc("sched_get_priority_max", unimplementedFunc),
|
||||
/* 336 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
|
||||
/* 337 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
|
||||
/* 338 */ SyscallDesc("afs_syscall", unimplementedFunc),
|
||||
/* 339 */ SyscallDesc("uname", unameFunc),
|
||||
/* 340 */ SyscallDesc("nanosleep", unimplementedFunc),
|
||||
/* 341 */ SyscallDesc("mremap", unimplementedFunc),
|
||||
/* 342 */ SyscallDesc("nfsservctl", unimplementedFunc),
|
||||
/* 343 */ SyscallDesc("setresuid", unimplementedFunc),
|
||||
/* 344 */ SyscallDesc("getresuid", unimplementedFunc),
|
||||
/* 345 */ SyscallDesc("pciconfig_read", unimplementedFunc),
|
||||
/* 346 */ SyscallDesc("pciconfig_write", unimplementedFunc),
|
||||
/* 347 */ SyscallDesc("query_module", unimplementedFunc),
|
||||
/* 348 */ SyscallDesc("prctl", unimplementedFunc),
|
||||
/* 349 */ SyscallDesc("pread", unimplementedFunc),
|
||||
/* 350 */ SyscallDesc("pwrite", unimplementedFunc),
|
||||
/* 351 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
|
||||
/* 352 */ SyscallDesc("rt_sigaction", ignoreFunc),
|
||||
/* 353 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
|
||||
/* 354 */ SyscallDesc("rt_sigpending", unimplementedFunc),
|
||||
/* 355 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
|
||||
/* 356 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc),
|
||||
/* 357 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
|
||||
/* 358 */ SyscallDesc("select", unimplementedFunc),
|
||||
/* 359 */ SyscallDesc("gettimeofday", gettimeofdayFunc<AlphaLinux>),
|
||||
/* 360 */ SyscallDesc("settimeofday", unimplementedFunc),
|
||||
/* 361 */ SyscallDesc("getitimer", unimplementedFunc),
|
||||
/* 362 */ SyscallDesc("setitimer", unimplementedFunc),
|
||||
/* 363 */ SyscallDesc("utimes", utimesFunc<AlphaLinux>),
|
||||
/* 364 */ SyscallDesc("getrusage", getrusageFunc<AlphaLinux>),
|
||||
/* 365 */ SyscallDesc("wait4", unimplementedFunc),
|
||||
/* 366 */ SyscallDesc("adjtimex", unimplementedFunc),
|
||||
/* 367 */ SyscallDesc("getcwd", unimplementedFunc),
|
||||
/* 368 */ SyscallDesc("capget", unimplementedFunc),
|
||||
/* 369 */ SyscallDesc("capset", unimplementedFunc),
|
||||
/* 370 */ SyscallDesc("sendfile", unimplementedFunc),
|
||||
/* 371 */ SyscallDesc("setresgid", unimplementedFunc),
|
||||
/* 372 */ SyscallDesc("getresgid", unimplementedFunc),
|
||||
/* 373 */ SyscallDesc("dipc", unimplementedFunc),
|
||||
/* 374 */ SyscallDesc("pivot_root", unimplementedFunc),
|
||||
/* 375 */ SyscallDesc("mincore", unimplementedFunc),
|
||||
/* 376 */ SyscallDesc("pciconfig_iobase", unimplementedFunc),
|
||||
/* 377 */ SyscallDesc("getdents64", unimplementedFunc),
|
||||
/* 378 */ SyscallDesc("gettid", unimplementedFunc),
|
||||
/* 379 */ SyscallDesc("readahead", unimplementedFunc),
|
||||
/* 380 */ SyscallDesc("security", unimplementedFunc),
|
||||
/* 381 */ SyscallDesc("tkill", unimplementedFunc),
|
||||
/* 382 */ SyscallDesc("setxattr", unimplementedFunc),
|
||||
/* 383 */ SyscallDesc("lsetxattr", unimplementedFunc),
|
||||
/* 384 */ SyscallDesc("fsetxattr", unimplementedFunc),
|
||||
/* 385 */ SyscallDesc("getxattr", unimplementedFunc),
|
||||
/* 386 */ SyscallDesc("lgetxattr", unimplementedFunc),
|
||||
/* 387 */ SyscallDesc("fgetxattr", unimplementedFunc),
|
||||
/* 388 */ SyscallDesc("listxattr", unimplementedFunc),
|
||||
/* 389 */ SyscallDesc("llistxattr", unimplementedFunc),
|
||||
/* 390 */ SyscallDesc("flistxattr", unimplementedFunc),
|
||||
/* 391 */ SyscallDesc("removexattr", unimplementedFunc),
|
||||
/* 392 */ SyscallDesc("lremovexattr", unimplementedFunc),
|
||||
/* 393 */ SyscallDesc("fremovexattr", unimplementedFunc),
|
||||
/* 394 */ SyscallDesc("futex", unimplementedFunc),
|
||||
/* 395 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
|
||||
/* 396 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
|
||||
/* 397 */ SyscallDesc("tuxcall", unimplementedFunc),
|
||||
/* 398 */ SyscallDesc("io_setup", unimplementedFunc),
|
||||
/* 399 */ SyscallDesc("io_destroy", unimplementedFunc),
|
||||
/* 400 */ SyscallDesc("io_getevents", unimplementedFunc),
|
||||
/* 401 */ SyscallDesc("io_submit", unimplementedFunc),
|
||||
/* 402 */ SyscallDesc("io_cancel", unimplementedFunc),
|
||||
/* 403 */ SyscallDesc("unknown #403", unimplementedFunc),
|
||||
/* 404 */ SyscallDesc("unknown #404", unimplementedFunc),
|
||||
/* 405 */ SyscallDesc("exit_group", exitFunc), // exit all threads...
|
||||
/* 406 */ SyscallDesc("lookup_dcookie", unimplementedFunc),
|
||||
/* 407 */ SyscallDesc("sys_epoll_create", unimplementedFunc),
|
||||
/* 408 */ SyscallDesc("sys_epoll_ctl", unimplementedFunc),
|
||||
/* 409 */ SyscallDesc("sys_epoll_wait", unimplementedFunc),
|
||||
/* 410 */ SyscallDesc("remap_file_pages", unimplementedFunc),
|
||||
/* 411 */ SyscallDesc("set_tid_address", unimplementedFunc),
|
||||
/* 412 */ SyscallDesc("restart_syscall", unimplementedFunc),
|
||||
/* 413 */ SyscallDesc("fadvise64", unimplementedFunc),
|
||||
/* 414 */ SyscallDesc("timer_create", unimplementedFunc),
|
||||
/* 415 */ SyscallDesc("timer_settime", unimplementedFunc),
|
||||
/* 416 */ SyscallDesc("timer_gettime", unimplementedFunc),
|
||||
/* 417 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
|
||||
/* 418 */ SyscallDesc("timer_delete", unimplementedFunc),
|
||||
/* 419 */ SyscallDesc("clock_settime", unimplementedFunc),
|
||||
/* 420 */ SyscallDesc("clock_gettime", unimplementedFunc),
|
||||
/* 421 */ SyscallDesc("clock_getres", unimplementedFunc),
|
||||
/* 422 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
|
||||
/* 423 */ SyscallDesc("semtimedop", unimplementedFunc),
|
||||
/* 424 */ SyscallDesc("tgkill", unimplementedFunc),
|
||||
/* 425 */ SyscallDesc("stat64", unimplementedFunc),
|
||||
/* 426 */ SyscallDesc("lstat64", lstat64Func<AlphaLinux>),
|
||||
/* 427 */ SyscallDesc("fstat64", fstat64Func<AlphaLinux>),
|
||||
/* 428 */ SyscallDesc("vserver", unimplementedFunc),
|
||||
/* 429 */ SyscallDesc("mbind", unimplementedFunc),
|
||||
/* 430 */ SyscallDesc("get_mempolicy", unimplementedFunc),
|
||||
/* 431 */ SyscallDesc("set_mempolicy", unimplementedFunc),
|
||||
/* 432 */ SyscallDesc("mq_open", unimplementedFunc),
|
||||
/* 433 */ SyscallDesc("mq_unlink", unimplementedFunc),
|
||||
/* 434 */ SyscallDesc("mq_timedsend", unimplementedFunc),
|
||||
/* 435 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
|
||||
/* 436 */ SyscallDesc("mq_notify", unimplementedFunc),
|
||||
/* 437 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
|
||||
/* 438 */ SyscallDesc("waitid", unimplementedFunc),
|
||||
/* 439 */ SyscallDesc("add_key", unimplementedFunc),
|
||||
/* 440 */ SyscallDesc("request_key", unimplementedFunc),
|
||||
/* 441 */ SyscallDesc("keyctl", unimplementedFunc)
|
||||
};
|
||||
|
||||
AlphaLinuxProcess::AlphaLinuxProcess(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)
|
||||
: AlphaLiveProcess(name, objFile, system, stdin_fd, stdout_fd,
|
||||
stderr_fd, argv, envp),
|
||||
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
|
||||
{
|
||||
//init_regs->intRegFile[0] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SyscallDesc*
|
||||
AlphaLinuxProcess::getDesc(int callnum)
|
||||
{
|
||||
if (callnum < 0 || callnum > Num_Syscall_Descs)
|
||||
return NULL;
|
||||
return &syscallDescs[callnum];
|
||||
}
|
||||
60
src/arch/alpha/linux/process.hh
Normal file
60
src/arch/alpha/linux/process.hh
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ALPHA_LINUX_PROCESS_HH__
|
||||
#define __ALPHA_LINUX_PROCESS_HH__
|
||||
|
||||
#include "arch/alpha/process.hh"
|
||||
|
||||
namespace AlphaISA {
|
||||
|
||||
/// A process with emulated Alpha/Linux syscalls.
|
||||
class AlphaLinuxProcess : public AlphaLiveProcess
|
||||
{
|
||||
public:
|
||||
/// Constructor.
|
||||
AlphaLinuxProcess(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);
|
||||
|
||||
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[];
|
||||
|
||||
const int Num_Syscall_Descs;
|
||||
};
|
||||
|
||||
} // namespace AlphaISA
|
||||
#endif // __ALPHA_LINUX_PROCESS_HH__
|
||||
265
src/arch/alpha/linux/system.cc
Normal file
265
src/arch/alpha/linux/system.cc
Normal file
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This code loads the linux kernel, console, pal and patches certain
|
||||
* functions. The symbol tables are loaded so that traces can show
|
||||
* the executing function and we can skip functions. Various delay
|
||||
* loops are skipped and their final values manually computed to speed
|
||||
* up boot time.
|
||||
*/
|
||||
|
||||
#include "arch/arguments.hh"
|
||||
#include "arch/vtophys.hh"
|
||||
#include "arch/alpha/linux/system.hh"
|
||||
#include "arch/alpha/linux/threadinfo.hh"
|
||||
#include "arch/alpha/system.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "dev/platform.hh"
|
||||
#include "kern/linux/printk.hh"
|
||||
#include "kern/linux/events.hh"
|
||||
#include "mem/physical.hh"
|
||||
#include "mem/port.hh"
|
||||
#include "sim/builder.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
|
||||
using namespace std;
|
||||
using namespace AlphaISA;
|
||||
using namespace Linux;
|
||||
|
||||
LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
|
||||
: AlphaSystem(p)
|
||||
{
|
||||
Addr addr = 0;
|
||||
|
||||
/**
|
||||
* The symbol swapper_pg_dir marks the beginning of the kernel and
|
||||
* the location of bootloader passed arguments
|
||||
*/
|
||||
if (!kernelSymtab->findAddress("swapper_pg_dir", KernelStart)) {
|
||||
panic("Could not determine start location of kernel");
|
||||
}
|
||||
|
||||
/**
|
||||
* Since we aren't using a bootloader, we have to copy the
|
||||
* kernel arguments directly into the kernel's memory.
|
||||
*/
|
||||
virtPort.writeBlob(CommandLine(), (uint8_t*)params()->boot_osflags.c_str(),
|
||||
params()->boot_osflags.length()+1);
|
||||
|
||||
/**
|
||||
* find the address of the est_cycle_freq variable and insert it
|
||||
* so we don't through the lengthly process of trying to
|
||||
* calculated it by using the PIT, RTC, etc.
|
||||
*/
|
||||
if (kernelSymtab->findAddress("est_cycle_freq", addr))
|
||||
virtPort.write(addr, (uint64_t)(Clock::Frequency /
|
||||
p->boot_cpu_frequency));
|
||||
|
||||
|
||||
/**
|
||||
* EV5 only supports 127 ASNs so we are going to tell the kernel that the
|
||||
* paritiuclar EV6 we have only supports 127 asns.
|
||||
* @todo At some point we should change ev5.hh and the palcode to support
|
||||
* 255 ASNs.
|
||||
*/
|
||||
if (kernelSymtab->findAddress("dp264_mv", addr))
|
||||
virtPort.write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127));
|
||||
else
|
||||
panic("could not find dp264_mv\n");
|
||||
|
||||
#ifndef NDEBUG
|
||||
kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
|
||||
if (!kernelPanicEvent)
|
||||
panic("could not find kernel symbol \'panic\'");
|
||||
|
||||
#if 0
|
||||
kernelDieEvent = addKernelFuncEvent<BreakPCEvent>("die_if_kernel");
|
||||
if (!kernelDieEvent)
|
||||
panic("could not find kernel symbol \'die_if_kernel\'");
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Any time ide_delay_50ms, calibarte_delay or
|
||||
* determine_cpu_caches is called just skip the
|
||||
* function. Currently determine_cpu_caches only is used put
|
||||
* information in proc, however if that changes in the future we
|
||||
* will have to fill in the cache size variables appropriately.
|
||||
*/
|
||||
|
||||
skipIdeDelay50msEvent =
|
||||
addKernelFuncEvent<SkipFuncEvent>("ide_delay_50ms");
|
||||
skipDelayLoopEvent =
|
||||
addKernelFuncEvent<SkipDelayLoopEvent>("calibrate_delay");
|
||||
skipCacheProbeEvent =
|
||||
addKernelFuncEvent<SkipFuncEvent>("determine_cpu_caches");
|
||||
debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
|
||||
idleStartEvent = addKernelFuncEvent<IdleStartEvent>("cpu_idle");
|
||||
|
||||
if (kernelSymtab->findAddress("alpha_switch_to", addr) && DTRACE(Thread)) {
|
||||
printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo",
|
||||
addr + sizeof(MachInst) * 6);
|
||||
} else {
|
||||
printThreadEvent = NULL;
|
||||
}
|
||||
|
||||
if (params()->bin_int) {
|
||||
intStartEvent = addPalFuncEvent<InterruptStartEvent>("sys_int_21");
|
||||
if (!intStartEvent)
|
||||
panic("could not find symbol: sys_int_21\n");
|
||||
|
||||
intEndEvent = addPalFuncEvent<InterruptEndEvent>("rti_to_kern");
|
||||
if (!intEndEvent)
|
||||
panic("could not find symbol: rti_to_kern\n");
|
||||
|
||||
intEndEvent2 = addPalFuncEvent<InterruptEndEvent>("rti_to_user");
|
||||
if (!intEndEvent2)
|
||||
panic("could not find symbol: rti_to_user\n");
|
||||
|
||||
intEndEvent3 = addKernelFuncEvent<InterruptEndEvent>("do_softirq");
|
||||
if (!intEndEvent3)
|
||||
panic("could not find symbol: do_softirq\n");
|
||||
}
|
||||
}
|
||||
|
||||
LinuxAlphaSystem::~LinuxAlphaSystem()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
delete kernelPanicEvent;
|
||||
#endif
|
||||
delete skipIdeDelay50msEvent;
|
||||
delete skipDelayLoopEvent;
|
||||
delete skipCacheProbeEvent;
|
||||
delete debugPrintkEvent;
|
||||
delete idleStartEvent;
|
||||
delete printThreadEvent;
|
||||
delete intStartEvent;
|
||||
delete intEndEvent;
|
||||
delete intEndEvent2;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LinuxAlphaSystem::setDelayLoop(ExecContext *xc)
|
||||
{
|
||||
Addr addr = 0;
|
||||
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
|
||||
Tick cpuFreq = xc->getCpuPtr()->frequency();
|
||||
Tick intrFreq = platform->intrFrequency();
|
||||
xc->getVirtPort(xc)->write(addr,
|
||||
(uint32_t)((cpuFreq / intrFreq) * 0.9988));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LinuxAlphaSystem::SkipDelayLoopEvent::process(ExecContext *xc)
|
||||
{
|
||||
SkipFuncEvent::process(xc);
|
||||
// calculate and set loops_per_jiffy
|
||||
((LinuxAlphaSystem *)xc->getSystemPtr())->setDelayLoop(xc);
|
||||
}
|
||||
|
||||
void
|
||||
LinuxAlphaSystem::PrintThreadInfo::process(ExecContext *xc)
|
||||
{
|
||||
Linux::ThreadInfo ti(xc);
|
||||
|
||||
DPRINTF(Thread, "Currently Executing Thread %s, pid %d, started at: %d\n",
|
||||
ti.curTaskName(), ti.curTaskPID(), ti.curTaskStart());
|
||||
}
|
||||
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
|
||||
|
||||
Param<Tick> boot_cpu_frequency;
|
||||
SimObjectParam<PhysicalMemory *> physmem;
|
||||
|
||||
Param<string> kernel;
|
||||
Param<string> console;
|
||||
Param<string> pal;
|
||||
|
||||
Param<string> boot_osflags;
|
||||
Param<string> readfile;
|
||||
Param<unsigned int> init_param;
|
||||
|
||||
Param<uint64_t> system_type;
|
||||
Param<uint64_t> system_rev;
|
||||
|
||||
Param<bool> bin;
|
||||
VectorParam<string> binned_fns;
|
||||
Param<bool> bin_int;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
|
||||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
|
||||
|
||||
INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
|
||||
INIT_PARAM(physmem, "phsyical memory"),
|
||||
INIT_PARAM(kernel, "file that contains the kernel code"),
|
||||
INIT_PARAM(console, "file that contains the console code"),
|
||||
INIT_PARAM(pal, "file that contains palcode"),
|
||||
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
|
||||
"a"),
|
||||
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
|
||||
INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
|
||||
INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
|
||||
INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10),
|
||||
INIT_PARAM_DFLT(bin, "is this system to be binned", false),
|
||||
INIT_PARAM(binned_fns, "functions to be broken down and binned"),
|
||||
INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true)
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
|
||||
|
||||
CREATE_SIM_OBJECT(LinuxAlphaSystem)
|
||||
{
|
||||
AlphaSystem::Params *p = new AlphaSystem::Params;
|
||||
p->name = getInstanceName();
|
||||
p->boot_cpu_frequency = boot_cpu_frequency;
|
||||
p->physmem = physmem;
|
||||
p->kernel_path = kernel;
|
||||
p->console_path = console;
|
||||
p->palcode = pal;
|
||||
p->boot_osflags = boot_osflags;
|
||||
p->init_param = init_param;
|
||||
p->readfile = readfile;
|
||||
p->system_type = system_type;
|
||||
p->system_rev = system_rev;
|
||||
p->bin = bin;
|
||||
p->binned_fns = binned_fns;
|
||||
p->bin_int = bin_int;
|
||||
return new LinuxAlphaSystem(p);
|
||||
}
|
||||
|
||||
REGISTER_SIM_OBJECT("LinuxAlphaSystem", LinuxAlphaSystem)
|
||||
|
||||
145
src/arch/alpha/linux/system.hh
Normal file
145
src/arch/alpha/linux/system.hh
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2004-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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ALPHA_LINUX_SYSTEM_HH__
|
||||
#define __ARCH_ALPHA_LINUX_SYSTEM_HH__
|
||||
|
||||
class ExecContext;
|
||||
|
||||
class BreakPCEvent;
|
||||
class IdleStartEvent;
|
||||
|
||||
#include "arch/alpha/system.hh"
|
||||
#include "kern/linux/events.hh"
|
||||
|
||||
using namespace AlphaISA;
|
||||
using namespace Linux;
|
||||
|
||||
/**
|
||||
* This class contains linux specific system code (Loading, Events, Binning).
|
||||
* It points to objects that are the system binaries to load and patches them
|
||||
* appropriately to work in simulator.
|
||||
*/
|
||||
class LinuxAlphaSystem : public AlphaSystem
|
||||
{
|
||||
private:
|
||||
class SkipDelayLoopEvent : public SkipFuncEvent
|
||||
{
|
||||
public:
|
||||
SkipDelayLoopEvent(PCEventQueue *q, const std::string &desc, Addr addr)
|
||||
: SkipFuncEvent(q, desc, addr) {}
|
||||
virtual void process(ExecContext *xc);
|
||||
};
|
||||
|
||||
class PrintThreadInfo : public PCEvent
|
||||
{
|
||||
public:
|
||||
PrintThreadInfo(PCEventQueue *q, const std::string &desc, Addr addr)
|
||||
: PCEvent(q, desc, addr) {}
|
||||
virtual void process(ExecContext *xc);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Addresses defining where the kernel bootloader places various
|
||||
* elements. Details found in include/asm-alpha/system.h
|
||||
*/
|
||||
Addr KernelStart; // Lookup the symbol swapper_pg_dir
|
||||
|
||||
public:
|
||||
Addr InitStack() const { return KernelStart + 0x02000; }
|
||||
Addr EmptyPGT() const { return KernelStart + 0x04000; }
|
||||
Addr EmptyPGE() const { return KernelStart + 0x08000; }
|
||||
Addr ZeroPGE() const { return KernelStart + 0x0A000; }
|
||||
Addr StartAddr() const { return KernelStart + 0x10000; }
|
||||
|
||||
Addr Param() const { return ZeroPGE() + 0x0; }
|
||||
Addr CommandLine() const { return Param() + 0x0; }
|
||||
Addr InitrdStart() const { return Param() + 0x100; }
|
||||
Addr InitrdSize() const { return Param() + 0x108; }
|
||||
static const int CommandLineSize = 256;
|
||||
|
||||
private:
|
||||
#ifndef NDEBUG
|
||||
/** Event to halt the simulator if the kernel calls panic() */
|
||||
BreakPCEvent *kernelPanicEvent;
|
||||
|
||||
/** Event to halt the simulator if the kernel calls die_if_kernel */
|
||||
BreakPCEvent *kernelDieEvent;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Event to skip determine_cpu_caches() because we don't support
|
||||
* the IPRs that the code can access to figure out cache sizes
|
||||
*/
|
||||
SkipFuncEvent *skipCacheProbeEvent;
|
||||
|
||||
/** PC based event to skip the ide_delay_50ms() call */
|
||||
SkipFuncEvent *skipIdeDelay50msEvent;
|
||||
|
||||
/**
|
||||
* PC based event to skip the dprink() call and emulate its
|
||||
* functionality
|
||||
*/
|
||||
DebugPrintkEvent *debugPrintkEvent;
|
||||
|
||||
/**
|
||||
* Skip calculate_delay_loop() rather than waiting for this to be
|
||||
* calculated
|
||||
*/
|
||||
SkipDelayLoopEvent *skipDelayLoopEvent;
|
||||
|
||||
/**
|
||||
* Event to print information about thread switches if the trace flag
|
||||
* Thread is set
|
||||
*/
|
||||
PrintThreadInfo *printThreadEvent;
|
||||
|
||||
/**
|
||||
* Event to bin Interrupts seperately from kernel code
|
||||
*/
|
||||
InterruptStartEvent *intStartEvent;
|
||||
|
||||
/**
|
||||
* Event to bin Interrupts seperately from kernel code
|
||||
*/
|
||||
InterruptEndEvent *intEndEvent;
|
||||
InterruptEndEvent *intEndEvent2;
|
||||
InterruptEndEvent *intEndEvent3;
|
||||
|
||||
/** Grab the PCBB of the idle process when it starts */
|
||||
IdleStartEvent *idleStartEvent;
|
||||
|
||||
public:
|
||||
LinuxAlphaSystem(Params *p);
|
||||
~LinuxAlphaSystem();
|
||||
|
||||
void setDelayLoop(ExecContext *xc);
|
||||
};
|
||||
|
||||
#endif // __ARCH_ALPHA_LINUX_SYSTEM_HH__
|
||||
41
src/arch/alpha/linux/thread_info.hh
Normal file
41
src/arch/alpha/linux/thread_info.hh
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ALPHA_LINUX_THREAD_INFO_H__
|
||||
#define __ARCH_ALPHA_LINUX_THREAD_INFO_H__
|
||||
|
||||
#include "arch/alpha/linux/hwrpb.hh"
|
||||
|
||||
namespace Linux {
|
||||
struct thread_info {
|
||||
struct pcb_struct pcb;
|
||||
Addr_a task;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // __ARCH_ALPHA_LINUX_THREAD_INFO_H__
|
||||
89
src/arch/alpha/linux/threadinfo.hh
Normal file
89
src/arch/alpha/linux/threadinfo.hh
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ALPHA_LINUX_LINUX_TREADNIFO_HH__
|
||||
#define __ARCH_ALPHA_LINUX_LINUX_TREADNIFO_HH__
|
||||
|
||||
#include "arch/alpha/linux/thread_info.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "kern/linux/sched.hh"
|
||||
#include "sim/vptr.hh"
|
||||
|
||||
namespace Linux {
|
||||
|
||||
class ThreadInfo
|
||||
{
|
||||
private:
|
||||
ExecContext *xc;
|
||||
|
||||
public:
|
||||
ThreadInfo(ExecContext *exec) : xc(exec) {}
|
||||
~ThreadInfo() {}
|
||||
|
||||
inline VPtr<thread_info>
|
||||
curThreadInfo()
|
||||
{
|
||||
Addr current;
|
||||
|
||||
/* Each kernel stack is only 2 pages, the start of which is the
|
||||
* thread_info struct. So we can get the address by masking off
|
||||
* the lower 14 bits.
|
||||
*/
|
||||
current = xc->readIntReg(TheISA::StackPointerReg) & ~0x3fff;
|
||||
return VPtr<thread_info>(xc, current);
|
||||
}
|
||||
|
||||
inline VPtr<task_struct>
|
||||
curTaskInfo()
|
||||
{
|
||||
Addr task = curThreadInfo()->task;
|
||||
return VPtr<task_struct>(xc, task);
|
||||
}
|
||||
|
||||
std::string
|
||||
curTaskName()
|
||||
{
|
||||
return curTaskInfo()->name;
|
||||
}
|
||||
|
||||
int32_t
|
||||
curTaskPID()
|
||||
{
|
||||
return curTaskInfo()->pid;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
curTaskStart()
|
||||
{
|
||||
return curTaskInfo()->start;
|
||||
}
|
||||
};
|
||||
|
||||
/* namespace Linux */ }
|
||||
|
||||
#endif // __ARCH_ALPHA_LINUX_LINUX_THREADINFO_HH__
|
||||
304
src/arch/alpha/osfpal.cc
Normal file
304
src/arch/alpha/osfpal.cc
Normal file
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arch/alpha/osfpal.hh"
|
||||
|
||||
namespace {
|
||||
const char *strings[PAL::NumCodes] = {
|
||||
// Priviledged PAL instructions
|
||||
"halt", // 0x00
|
||||
"cflush", // 0x01
|
||||
"draina", // 0x02
|
||||
0, // 0x03
|
||||
0, // 0x04
|
||||
0, // 0x05
|
||||
0, // 0x06
|
||||
0, // 0x07
|
||||
0, // 0x08
|
||||
"cserve", // 0x09
|
||||
"swppal", // 0x0a
|
||||
0, // 0x0b
|
||||
0, // 0x0c
|
||||
"wripir", // 0x0d
|
||||
0, // 0x0e
|
||||
0, // 0x0f
|
||||
"rdmces", // 0x10
|
||||
"wrmces", // 0x11
|
||||
0, // 0x12
|
||||
0, // 0x13
|
||||
0, // 0x14
|
||||
0, // 0x15
|
||||
0, // 0x16
|
||||
0, // 0x17
|
||||
0, // 0x18
|
||||
0, // 0x19
|
||||
0, // 0x1a
|
||||
0, // 0x1b
|
||||
0, // 0x1c
|
||||
0, // 0x1d
|
||||
0, // 0x1e
|
||||
0, // 0x1f
|
||||
0, // 0x20
|
||||
0, // 0x21
|
||||
0, // 0x22
|
||||
0, // 0x23
|
||||
0, // 0x24
|
||||
0, // 0x25
|
||||
0, // 0x26
|
||||
0, // 0x27
|
||||
0, // 0x28
|
||||
0, // 0x29
|
||||
0, // 0x2a
|
||||
"wrfen", // 0x2b
|
||||
0, // 0x2c
|
||||
"wrvptptr", // 0x2d
|
||||
0, // 0x2e
|
||||
0, // 0x2f
|
||||
"swpctx", // 0x30
|
||||
"wrval", // 0x31
|
||||
"rdval", // 0x32
|
||||
"tbi", // 0x33
|
||||
"wrent", // 0x34
|
||||
"swpipl", // 0x35
|
||||
"rdps", // 0x36
|
||||
"wrkgp", // 0x37
|
||||
"wrusp", // 0x38
|
||||
"wrperfmon", // 0x39
|
||||
"rdusp", // 0x3a
|
||||
0, // 0x3b
|
||||
"whami", // 0x3c
|
||||
"retsys", // 0x3d
|
||||
"wtint", // 0x3e
|
||||
"rti", // 0x3f
|
||||
0, // 0x40
|
||||
0, // 0x41
|
||||
0, // 0x42
|
||||
0, // 0x43
|
||||
0, // 0x44
|
||||
0, // 0x45
|
||||
0, // 0x46
|
||||
0, // 0x47
|
||||
0, // 0x48
|
||||
0, // 0x49
|
||||
0, // 0x4a
|
||||
0, // 0x4b
|
||||
0, // 0x4c
|
||||
0, // 0x4d
|
||||
0, // 0x4e
|
||||
0, // 0x4f
|
||||
0, // 0x50
|
||||
0, // 0x51
|
||||
0, // 0x52
|
||||
0, // 0x53
|
||||
0, // 0x54
|
||||
0, // 0x55
|
||||
0, // 0x56
|
||||
0, // 0x57
|
||||
0, // 0x58
|
||||
0, // 0x59
|
||||
0, // 0x5a
|
||||
0, // 0x5b
|
||||
0, // 0x5c
|
||||
0, // 0x5d
|
||||
0, // 0x5e
|
||||
0, // 0x5f
|
||||
0, // 0x60
|
||||
0, // 0x61
|
||||
0, // 0x62
|
||||
0, // 0x63
|
||||
0, // 0x64
|
||||
0, // 0x65
|
||||
0, // 0x66
|
||||
0, // 0x67
|
||||
0, // 0x68
|
||||
0, // 0x69
|
||||
0, // 0x6a
|
||||
0, // 0x6b
|
||||
0, // 0x6c
|
||||
0, // 0x6d
|
||||
0, // 0x6e
|
||||
0, // 0x6f
|
||||
0, // 0x70
|
||||
0, // 0x71
|
||||
0, // 0x72
|
||||
0, // 0x73
|
||||
0, // 0x74
|
||||
0, // 0x75
|
||||
0, // 0x76
|
||||
0, // 0x77
|
||||
0, // 0x78
|
||||
0, // 0x79
|
||||
0, // 0x7a
|
||||
0, // 0x7b
|
||||
0, // 0x7c
|
||||
0, // 0x7d
|
||||
0, // 0x7e
|
||||
0, // 0x7f
|
||||
|
||||
// Unpriviledged PAL instructions
|
||||
"bpt", // 0x80
|
||||
"bugchk", // 0x81
|
||||
0, // 0x82
|
||||
"callsys", // 0x83
|
||||
0, // 0x84
|
||||
0, // 0x85
|
||||
"imb", // 0x86
|
||||
0, // 0x87
|
||||
0, // 0x88
|
||||
0, // 0x89
|
||||
0, // 0x8a
|
||||
0, // 0x8b
|
||||
0, // 0x8c
|
||||
0, // 0x8d
|
||||
0, // 0x8e
|
||||
0, // 0x8f
|
||||
0, // 0x90
|
||||
0, // 0x91
|
||||
"urti", // 0x92
|
||||
0, // 0x93
|
||||
0, // 0x94
|
||||
0, // 0x95
|
||||
0, // 0x96
|
||||
0, // 0x97
|
||||
0, // 0x98
|
||||
0, // 0x99
|
||||
0, // 0x9a
|
||||
0, // 0x9b
|
||||
0, // 0x9c
|
||||
0, // 0x9d
|
||||
"rdunique", // 0x9e
|
||||
"wrunique", // 0x9f
|
||||
0, // 0xa0
|
||||
0, // 0xa1
|
||||
0, // 0xa2
|
||||
0, // 0xa3
|
||||
0, // 0xa4
|
||||
0, // 0xa5
|
||||
0, // 0xa6
|
||||
0, // 0xa7
|
||||
0, // 0xa8
|
||||
0, // 0xa9
|
||||
"gentrap", // 0xaa
|
||||
0, // 0xab
|
||||
0, // 0xac
|
||||
0, // 0xad
|
||||
"clrfen", // 0xae
|
||||
0, // 0xaf
|
||||
0, // 0xb0
|
||||
0, // 0xb1
|
||||
0, // 0xb2
|
||||
0, // 0xb3
|
||||
0, // 0xb4
|
||||
0, // 0xb5
|
||||
0, // 0xb6
|
||||
0, // 0xb7
|
||||
0, // 0xb8
|
||||
0, // 0xb9
|
||||
0, // 0xba
|
||||
0, // 0xbb
|
||||
0, // 0xbc
|
||||
0, // 0xbd
|
||||
"nphalt", // 0xbe
|
||||
"copypal", // 0xbf
|
||||
#if 0
|
||||
0, // 0xc0
|
||||
0, // 0xc1
|
||||
0, // 0xc2
|
||||
0, // 0xc3
|
||||
0, // 0xc4
|
||||
0, // 0xc5
|
||||
0, // 0xc6
|
||||
0, // 0xc7
|
||||
0, // 0xc8
|
||||
0, // 0xc9
|
||||
0, // 0xca
|
||||
0, // 0xcb
|
||||
0, // 0xcc
|
||||
0, // 0xcd
|
||||
0, // 0xce
|
||||
0, // 0xcf
|
||||
0, // 0xd0
|
||||
0, // 0xd1
|
||||
0, // 0xd2
|
||||
0, // 0xd3
|
||||
0, // 0xd4
|
||||
0, // 0xd5
|
||||
0, // 0xd6
|
||||
0, // 0xd7
|
||||
0, // 0xd8
|
||||
0, // 0xd9
|
||||
0, // 0xda
|
||||
0, // 0xdb
|
||||
0, // 0xdc
|
||||
0, // 0xdd
|
||||
0, // 0xde
|
||||
0, // 0xdf
|
||||
0, // 0xe0
|
||||
0, // 0xe1
|
||||
0, // 0xe2
|
||||
0, // 0xe3
|
||||
0, // 0xe4
|
||||
0, // 0xe5
|
||||
0, // 0xe6
|
||||
0, // 0xe7
|
||||
0, // 0xe8
|
||||
0, // 0xe9
|
||||
0, // 0xea
|
||||
0, // 0xeb
|
||||
0, // 0xec
|
||||
0, // 0xed
|
||||
0, // 0xee
|
||||
0, // 0xef
|
||||
0, // 0xf0
|
||||
0, // 0xf1
|
||||
0, // 0xf2
|
||||
0, // 0xf3
|
||||
0, // 0xf4
|
||||
0, // 0xf5
|
||||
0, // 0xf6
|
||||
0, // 0xf7
|
||||
0, // 0xf8
|
||||
0, // 0xf9
|
||||
0, // 0xfa
|
||||
0, // 0xfb
|
||||
0, // 0xfc
|
||||
0, // 0xfd
|
||||
0, // 0xfe
|
||||
0 // 0xff
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
const char *
|
||||
PAL::name(int index)
|
||||
{
|
||||
if (index > NumCodes || index < 0)
|
||||
return 0;
|
||||
|
||||
return strings[index];
|
||||
}
|
||||
80
src/arch/alpha/osfpal.hh
Normal file
80
src/arch/alpha/osfpal.hh
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __OSFPAL_HH__
|
||||
#define __OSFPAL_HH__
|
||||
|
||||
struct PAL
|
||||
{
|
||||
enum {
|
||||
// Privileged PAL functions
|
||||
halt = 0x00,
|
||||
cflush = 0x01,
|
||||
draina = 0x02,
|
||||
cserve = 0x09,
|
||||
swppal = 0x0a,
|
||||
wripir = 0x0d,
|
||||
rdmces = 0x10,
|
||||
wrmces = 0x11,
|
||||
wrfen = 0x2b,
|
||||
wrvptptr = 0x2d,
|
||||
swpctx = 0x30,
|
||||
wrval = 0x31,
|
||||
rdval = 0x32,
|
||||
tbi = 0x33,
|
||||
wrent = 0x34,
|
||||
swpipl = 0x35,
|
||||
rdps = 0x36,
|
||||
wrkgp = 0x37,
|
||||
wrusp = 0x38,
|
||||
wrperfmon = 0x39,
|
||||
rdusp = 0x3a,
|
||||
whami = 0x3c,
|
||||
retsys = 0x3d,
|
||||
wtint = 0x3e,
|
||||
rti = 0x3f,
|
||||
|
||||
// unprivileged pal functions
|
||||
bpt = 0x80,
|
||||
bugchk = 0x81,
|
||||
callsys = 0x83,
|
||||
imb = 0x86,
|
||||
urti = 0x92,
|
||||
rdunique = 0x9e,
|
||||
wrunique = 0x9f,
|
||||
gentrap = 0xaa,
|
||||
clrfen = 0xae,
|
||||
nphalt = 0xbe,
|
||||
copypal = 0xbf,
|
||||
NumCodes
|
||||
};
|
||||
|
||||
static const char *name(int index);
|
||||
};
|
||||
|
||||
#endif // __OSFPAL_HH__
|
||||
167
src/arch/alpha/process.cc
Normal file
167
src/arch/alpha/process.cc
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arch/alpha/constants.hh"
|
||||
#include "arch/alpha/process.hh"
|
||||
#include "arch/alpha/linux/process.hh"
|
||||
#include "arch/alpha/tru64/process.hh"
|
||||
#include "base/loader/object_file.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "sim/builder.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
|
||||
using namespace AlphaISA;
|
||||
using namespace std;
|
||||
|
||||
AlphaLiveProcess *
|
||||
AlphaLiveProcess::create(const std::string &nm, System *system, int stdin_fd,
|
||||
int stdout_fd, int stderr_fd, std::string executable,
|
||||
std::vector<std::string> &argv, std::vector<std::string> &envp)
|
||||
{
|
||||
AlphaLiveProcess *process = NULL;
|
||||
|
||||
ObjectFile *objFile = createObjectFile(executable);
|
||||
if (objFile == NULL) {
|
||||
fatal("Can't load object file %s", executable);
|
||||
}
|
||||
|
||||
|
||||
if (objFile->getArch() != ObjectFile::Alpha)
|
||||
fatal("Object file does not match architecture.");
|
||||
switch (objFile->getOpSys()) {
|
||||
case ObjectFile::Tru64:
|
||||
process = new AlphaTru64Process(nm, objFile, system,
|
||||
stdin_fd, stdout_fd, stderr_fd,
|
||||
argv, envp);
|
||||
break;
|
||||
|
||||
case ObjectFile::Linux:
|
||||
process = new AlphaLinuxProcess(nm, objFile, system,
|
||||
stdin_fd, stdout_fd, stderr_fd,
|
||||
argv, envp);
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("Unknown/unsupported operating system.");
|
||||
}
|
||||
|
||||
if (process == NULL)
|
||||
fatal("Unknown error creating process object.");
|
||||
return process;
|
||||
}
|
||||
|
||||
AlphaLiveProcess::AlphaLiveProcess(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)
|
||||
: LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd,
|
||||
argv, envp)
|
||||
{
|
||||
brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
|
||||
brk_point = roundUp(brk_point, VMPageSize);
|
||||
|
||||
// Set up stack. On Alpha, stack goes below text section. This
|
||||
// code should get moved to some architecture-specific spot.
|
||||
stack_base = objFile->textBase() - (409600+4096);
|
||||
|
||||
// Set up region for mmaps. Tru64 seems to start just above 0 and
|
||||
// grow up from there.
|
||||
mmap_start = mmap_end = 0x10000;
|
||||
|
||||
// Set pointer for next thread stack. Reserve 8M for main stack.
|
||||
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
AlphaLiveProcess::startup()
|
||||
{
|
||||
argsInit(MachineBytes, VMPageSize);
|
||||
|
||||
execContexts[0]->setIntReg(GlobalPointerReg, objFile->globalPointer());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaLiveProcess)
|
||||
|
||||
VectorParam<string> cmd;
|
||||
Param<string> executable;
|
||||
Param<string> input;
|
||||
Param<string> output;
|
||||
VectorParam<string> env;
|
||||
SimObjectParam<System *> system;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(AlphaLiveProcess)
|
||||
|
||||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaLiveProcess)
|
||||
|
||||
INIT_PARAM(cmd, "command line (executable plus arguments)"),
|
||||
INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
|
||||
INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
|
||||
INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
|
||||
INIT_PARAM(env, "environment settings"),
|
||||
INIT_PARAM(system, "system")
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(AlphaLiveProcess)
|
||||
|
||||
|
||||
CREATE_SIM_OBJECT(AlphaLiveProcess)
|
||||
{
|
||||
string in = input;
|
||||
string out = output;
|
||||
|
||||
// initialize file descriptors to default: same as simulator
|
||||
int stdin_fd, stdout_fd, stderr_fd;
|
||||
|
||||
if (in == "stdin" || in == "cin")
|
||||
stdin_fd = STDIN_FILENO;
|
||||
else
|
||||
stdin_fd = Process::openInputFile(input);
|
||||
|
||||
if (out == "stdout" || out == "cout")
|
||||
stdout_fd = STDOUT_FILENO;
|
||||
else if (out == "stderr" || out == "cerr")
|
||||
stdout_fd = STDERR_FILENO;
|
||||
else
|
||||
stdout_fd = Process::openOutputFile(out);
|
||||
|
||||
stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
|
||||
|
||||
return AlphaLiveProcess::create(getInstanceName(), system,
|
||||
stdin_fd, stdout_fd, stderr_fd,
|
||||
(string)executable == "" ? cmd[0] : executable,
|
||||
cmd, env);
|
||||
}
|
||||
|
||||
|
||||
REGISTER_SIM_OBJECT("AlphaLiveProcess", AlphaLiveProcess)
|
||||
|
||||
64
src/arch/alpha/process.hh
Normal file
64
src/arch/alpha/process.hh
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ALPHA_PROCESS_HH__
|
||||
#define __ALPHA_PROCESS_HH__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "sim/process.hh"
|
||||
|
||||
class ObjectFile;
|
||||
class System;
|
||||
|
||||
|
||||
class AlphaLiveProcess : public LiveProcess
|
||||
{
|
||||
protected:
|
||||
AlphaLiveProcess(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);
|
||||
|
||||
void startup();
|
||||
|
||||
public:
|
||||
// this function is used to create the LiveProcess object, since
|
||||
// we can't tell which subclass of LiveProcess to use until we
|
||||
// open and look at the object file.
|
||||
static AlphaLiveProcess *create(const std::string &nm,
|
||||
System *_system,
|
||||
int stdin_fd, int stdout_fd, int stderr_fd,
|
||||
std::string executable,
|
||||
std::vector<std::string> &argv,
|
||||
std::vector<std::string> &envp);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // __ALPHA_PROCESS_HH__
|
||||
278
src/arch/alpha/regfile.hh
Normal file
278
src/arch/alpha/regfile.hh
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ALPHA_REGFILE_HH__
|
||||
#define __ARCH_ALPHA_REGFILE_HH__
|
||||
|
||||
#include "arch/alpha/types.hh"
|
||||
#include "arch/alpha/constants.hh"
|
||||
#include "sim/faults.hh"
|
||||
|
||||
class Checkpoint;
|
||||
class ExecContext;
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
class IntRegFile
|
||||
{
|
||||
protected:
|
||||
IntReg regs[NumIntRegs];
|
||||
|
||||
public:
|
||||
|
||||
IntReg readReg(int intReg)
|
||||
{
|
||||
return regs[intReg];
|
||||
}
|
||||
|
||||
Fault setReg(int intReg, const IntReg &val)
|
||||
{
|
||||
regs[intReg] = val;
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
};
|
||||
|
||||
class FloatRegFile
|
||||
{
|
||||
public:
|
||||
|
||||
union {
|
||||
uint64_t q[NumFloatRegs]; // integer qword view
|
||||
double d[NumFloatRegs]; // double-precision floating point view
|
||||
};
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
};
|
||||
|
||||
class MiscRegFile {
|
||||
protected:
|
||||
uint64_t fpcr; // floating point condition codes
|
||||
uint64_t uniq; // process-unique register
|
||||
bool lock_flag; // lock flag for LL/SC
|
||||
Addr lock_addr; // lock address for LL/SC
|
||||
|
||||
public:
|
||||
MiscReg readReg(int misc_reg);
|
||||
|
||||
MiscReg readRegWithEffect(int misc_reg, Fault &fault,
|
||||
ExecContext *xc);
|
||||
|
||||
//These functions should be removed once the simplescalar cpu model
|
||||
//has been replaced.
|
||||
int getInstAsid();
|
||||
int getDataAsid();
|
||||
|
||||
Fault setReg(int misc_reg, const MiscReg &val);
|
||||
|
||||
Fault setRegWithEffect(int misc_reg, const MiscReg &val,
|
||||
ExecContext *xc);
|
||||
|
||||
#if FULL_SYSTEM
|
||||
protected:
|
||||
typedef uint64_t InternalProcReg;
|
||||
|
||||
InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
|
||||
|
||||
private:
|
||||
InternalProcReg readIpr(int idx, Fault &fault, ExecContext *xc);
|
||||
|
||||
Fault setIpr(int idx, InternalProcReg val, ExecContext *xc);
|
||||
#endif
|
||||
friend class RegFile;
|
||||
};
|
||||
|
||||
class RegFile {
|
||||
|
||||
protected:
|
||||
Addr pc; // program counter
|
||||
Addr npc; // next-cycle program counter
|
||||
Addr nnpc;
|
||||
|
||||
public:
|
||||
Addr readPC()
|
||||
{
|
||||
return pc;
|
||||
}
|
||||
|
||||
void setPC(Addr val)
|
||||
{
|
||||
pc = val;
|
||||
}
|
||||
|
||||
Addr readNextPC()
|
||||
{
|
||||
return npc;
|
||||
}
|
||||
|
||||
void setNextPC(Addr val)
|
||||
{
|
||||
npc = val;
|
||||
}
|
||||
|
||||
Addr readNextNPC()
|
||||
{
|
||||
return nnpc;
|
||||
}
|
||||
|
||||
void setNextNPC(Addr val)
|
||||
{
|
||||
nnpc = val;
|
||||
}
|
||||
|
||||
protected:
|
||||
IntRegFile intRegFile; // (signed) integer register file
|
||||
FloatRegFile floatRegFile; // floating point register file
|
||||
MiscRegFile miscRegFile; // control register file
|
||||
|
||||
public:
|
||||
|
||||
#if FULL_SYSTEM
|
||||
int intrflag; // interrupt flag
|
||||
inline int instAsid()
|
||||
{ return miscRegFile.getInstAsid(); }
|
||||
inline int dataAsid()
|
||||
{ return miscRegFile.getDataAsid(); }
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
void clear()
|
||||
{
|
||||
bzero(&intRegFile, sizeof(intRegFile));
|
||||
bzero(&floatRegFile, sizeof(floatRegFile));
|
||||
bzero(&miscRegFile, sizeof(miscRegFile));
|
||||
}
|
||||
|
||||
MiscReg readMiscReg(int miscReg)
|
||||
{
|
||||
return miscRegFile.readReg(miscReg);
|
||||
}
|
||||
|
||||
MiscReg readMiscRegWithEffect(int miscReg,
|
||||
Fault &fault, ExecContext *xc)
|
||||
{
|
||||
fault = NoFault;
|
||||
return miscRegFile.readRegWithEffect(miscReg, fault, xc);
|
||||
}
|
||||
|
||||
Fault setMiscReg(int miscReg, const MiscReg &val)
|
||||
{
|
||||
return miscRegFile.setReg(miscReg, val);
|
||||
}
|
||||
|
||||
Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
|
||||
ExecContext * xc)
|
||||
{
|
||||
return miscRegFile.setRegWithEffect(miscReg, val, xc);
|
||||
}
|
||||
|
||||
FloatReg readFloatReg(int floatReg)
|
||||
{
|
||||
return floatRegFile.d[floatReg];
|
||||
}
|
||||
|
||||
FloatReg readFloatReg(int floatReg, int width)
|
||||
{
|
||||
return readFloatReg(floatReg);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegBits(int floatReg)
|
||||
{
|
||||
return floatRegFile.q[floatReg];
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegBits(int floatReg, int width)
|
||||
{
|
||||
return readFloatRegBits(floatReg);
|
||||
}
|
||||
|
||||
Fault setFloatReg(int floatReg, const FloatReg &val)
|
||||
{
|
||||
floatRegFile.d[floatReg] = val;
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
Fault setFloatReg(int floatReg, const FloatReg &val, int width)
|
||||
{
|
||||
return setFloatReg(floatReg, val);
|
||||
}
|
||||
|
||||
Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
|
||||
{
|
||||
floatRegFile.q[floatReg] = val;
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
|
||||
{
|
||||
return setFloatRegBits(floatReg, val);
|
||||
}
|
||||
|
||||
IntReg readIntReg(int intReg)
|
||||
{
|
||||
return intRegFile.readReg(intReg);
|
||||
}
|
||||
|
||||
Fault setIntReg(int intReg, const IntReg &val)
|
||||
{
|
||||
return intRegFile.setReg(intReg, val);
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
enum ContextParam
|
||||
{
|
||||
CONTEXT_PALMODE
|
||||
};
|
||||
|
||||
typedef bool ContextVal;
|
||||
|
||||
void changeContext(ContextParam param, ContextVal val)
|
||||
{
|
||||
//This would be an alternative place to call/implement
|
||||
//the swapPALShadow function
|
||||
}
|
||||
};
|
||||
|
||||
void copyRegs(ExecContext *src, ExecContext *dest);
|
||||
|
||||
void copyMiscRegs(ExecContext *src, ExecContext *dest);
|
||||
|
||||
#if FULL_SYSTEM
|
||||
void copyIprs(ExecContext *src, ExecContext *dest);
|
||||
#endif
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif
|
||||
344
src/arch/alpha/stacktrace.cc
Normal file
344
src/arch/alpha/stacktrace.cc
Normal file
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* Copyright (c) 2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "arch/alpha/isa_traits.hh"
|
||||
#include "arch/alpha/stacktrace.hh"
|
||||
#include "arch/alpha/vtophys.hh"
|
||||
#include "base/bitfield.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
using namespace std;
|
||||
using namespace AlphaISA;
|
||||
|
||||
ProcessInfo::ProcessInfo(ExecContext *_xc)
|
||||
: xc(_xc)
|
||||
{
|
||||
Addr addr = 0;
|
||||
|
||||
if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
thread_info_size = gtoh(xc->getVirtPort()->read<int32_t>(addr));
|
||||
|
||||
if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
task_struct_size = gtoh(xc->getVirtPort()->read<int32_t>(addr));
|
||||
|
||||
if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
task_off = gtoh(xc->getVirtPort()->read<int32_t>(addr));
|
||||
|
||||
if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
pid_off = gtoh(xc->getVirtPort()->read<int32_t>(addr));
|
||||
|
||||
if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
name_off = gtoh(xc->getVirtPort()->read<int32_t>(addr));
|
||||
}
|
||||
|
||||
Addr
|
||||
ProcessInfo::task(Addr ksp) const
|
||||
{
|
||||
Addr base = ksp & ~0x3fff;
|
||||
if (base == ULL(0xfffffc0000000000))
|
||||
return 0;
|
||||
|
||||
return gtoh(xc->getVirtPort()->read<Addr>(base + task_off));
|
||||
}
|
||||
|
||||
int
|
||||
ProcessInfo::pid(Addr ksp) const
|
||||
{
|
||||
Addr task = this->task(ksp);
|
||||
if (!task)
|
||||
return -1;
|
||||
|
||||
return gtoh(xc->getVirtPort()->read<uint16_t>(task + pid_off));
|
||||
}
|
||||
|
||||
string
|
||||
ProcessInfo::name(Addr ksp) const
|
||||
{
|
||||
Addr task = this->task(ksp);
|
||||
if (!task)
|
||||
return "console";
|
||||
|
||||
char comm[256];
|
||||
CopyStringOut(xc, comm, task + name_off, sizeof(comm));
|
||||
if (!comm[0])
|
||||
return "startup";
|
||||
|
||||
return comm;
|
||||
}
|
||||
|
||||
StackTrace::StackTrace()
|
||||
: xc(0), stack(64)
|
||||
{
|
||||
}
|
||||
|
||||
StackTrace::StackTrace(ExecContext *_xc, StaticInstPtr inst)
|
||||
: xc(0), stack(64)
|
||||
{
|
||||
trace(_xc, inst);
|
||||
}
|
||||
|
||||
StackTrace::~StackTrace()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
StackTrace::trace(ExecContext *_xc, bool is_call)
|
||||
{
|
||||
xc = _xc;
|
||||
|
||||
bool usermode = (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
|
||||
|
||||
Addr pc = xc->readNextPC();
|
||||
bool kernel = xc->getSystemPtr()->kernelStart <= pc &&
|
||||
pc <= xc->getSystemPtr()->kernelEnd;
|
||||
|
||||
if (usermode) {
|
||||
stack.push_back(user);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!kernel) {
|
||||
stack.push_back(console);
|
||||
return;
|
||||
}
|
||||
|
||||
SymbolTable *symtab = xc->getSystemPtr()->kernelSymtab;
|
||||
Addr ksp = xc->readIntReg(TheISA::StackPointerReg);
|
||||
Addr bottom = ksp & ~0x3fff;
|
||||
Addr addr;
|
||||
|
||||
if (is_call) {
|
||||
if (!symtab->findNearestAddr(pc, addr))
|
||||
panic("could not find address %#x", pc);
|
||||
|
||||
stack.push_back(addr);
|
||||
pc = xc->readPC();
|
||||
}
|
||||
|
||||
Addr ra;
|
||||
int size;
|
||||
|
||||
while (ksp > bottom) {
|
||||
if (!symtab->findNearestAddr(pc, addr))
|
||||
panic("could not find symbol for pc=%#x", pc);
|
||||
assert(pc >= addr && "symbol botch: callpc < func");
|
||||
|
||||
stack.push_back(addr);
|
||||
|
||||
if (isEntry(addr))
|
||||
return;
|
||||
|
||||
if (decodePrologue(ksp, pc, addr, size, ra)) {
|
||||
if (!ra)
|
||||
return;
|
||||
|
||||
if (size <= 0) {
|
||||
stack.push_back(unknown);
|
||||
return;
|
||||
}
|
||||
|
||||
pc = ra;
|
||||
ksp += size;
|
||||
} else {
|
||||
stack.push_back(unknown);
|
||||
return;
|
||||
}
|
||||
|
||||
bool kernel = xc->getSystemPtr()->kernelStart <= pc &&
|
||||
pc <= xc->getSystemPtr()->kernelEnd;
|
||||
if (!kernel)
|
||||
return;
|
||||
|
||||
if (stack.size() >= 1000)
|
||||
panic("unwinding too far");
|
||||
}
|
||||
|
||||
panic("unwinding too far");
|
||||
}
|
||||
|
||||
bool
|
||||
StackTrace::isEntry(Addr addr)
|
||||
{
|
||||
if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp12))
|
||||
return true;
|
||||
|
||||
if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp7))
|
||||
return true;
|
||||
|
||||
if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp11))
|
||||
return true;
|
||||
|
||||
if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp21))
|
||||
return true;
|
||||
|
||||
if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp9))
|
||||
return true;
|
||||
|
||||
if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp2))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
StackTrace::decodeStack(MachInst inst, int &disp)
|
||||
{
|
||||
// lda $sp, -disp($sp)
|
||||
//
|
||||
// Opcode<31:26> == 0x08
|
||||
// RA<25:21> == 30
|
||||
// RB<20:16> == 30
|
||||
// Disp<15:0>
|
||||
const MachInst mem_mask = 0xffff0000;
|
||||
const MachInst lda_pattern = 0x23de0000;
|
||||
const MachInst lda_disp_mask = 0x0000ffff;
|
||||
|
||||
// subq $sp, disp, $sp
|
||||
// addq $sp, disp, $sp
|
||||
//
|
||||
// Opcode<31:26> == 0x10
|
||||
// RA<25:21> == 30
|
||||
// Lit<20:13>
|
||||
// One<12> = 1
|
||||
// Func<11:5> == 0x20 (addq)
|
||||
// Func<11:5> == 0x29 (subq)
|
||||
// RC<4:0> == 30
|
||||
const MachInst intop_mask = 0xffe01fff;
|
||||
const MachInst addq_pattern = 0x43c0141e;
|
||||
const MachInst subq_pattern = 0x43c0153e;
|
||||
const MachInst intop_disp_mask = 0x001fe000;
|
||||
const int intop_disp_shift = 13;
|
||||
|
||||
if ((inst & mem_mask) == lda_pattern)
|
||||
disp = -sext<16>(inst & lda_disp_mask);
|
||||
else if ((inst & intop_mask) == addq_pattern)
|
||||
disp = -int((inst & intop_disp_mask) >> intop_disp_shift);
|
||||
else if ((inst & intop_mask) == subq_pattern)
|
||||
disp = int((inst & intop_disp_mask) >> intop_disp_shift);
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
StackTrace::decodeSave(MachInst inst, int ®, int &disp)
|
||||
{
|
||||
// lda $stq, disp($sp)
|
||||
//
|
||||
// Opcode<31:26> == 0x08
|
||||
// RA<25:21> == ?
|
||||
// RB<20:16> == 30
|
||||
// Disp<15:0>
|
||||
const MachInst stq_mask = 0xfc1f0000;
|
||||
const MachInst stq_pattern = 0xb41e0000;
|
||||
const MachInst stq_disp_mask = 0x0000ffff;
|
||||
const MachInst reg_mask = 0x03e00000;
|
||||
const int reg_shift = 21;
|
||||
|
||||
if ((inst & stq_mask) == stq_pattern) {
|
||||
reg = (inst & reg_mask) >> reg_shift;
|
||||
disp = sext<16>(inst & stq_disp_mask);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode the function prologue for the function we're in, and note
|
||||
* which registers are stored where, and how large the stack frame is.
|
||||
*/
|
||||
bool
|
||||
StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
|
||||
int &size, Addr &ra)
|
||||
{
|
||||
size = 0;
|
||||
ra = 0;
|
||||
|
||||
for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
|
||||
MachInst inst;
|
||||
CopyOut(xc, (uint8_t *)&inst, pc, sizeof(MachInst));
|
||||
|
||||
int reg, disp;
|
||||
if (decodeStack(inst, disp)) {
|
||||
if (size) {
|
||||
// panic("decoding frame size again");
|
||||
return true;
|
||||
}
|
||||
size += disp;
|
||||
} else if (decodeSave(inst, reg, disp)) {
|
||||
if (!ra && reg == ReturnAddressReg) {
|
||||
CopyOut(xc, (uint8_t *)&ra, sp + disp, sizeof(Addr));
|
||||
if (!ra) {
|
||||
// panic("no return address value pc=%#x\n", pc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if TRACING_ON
|
||||
void
|
||||
StackTrace::dump()
|
||||
{
|
||||
StringWrap name(xc->getCpuPtr()->name());
|
||||
SymbolTable *symtab = xc->getSystemPtr()->kernelSymtab;
|
||||
|
||||
DPRINTFN("------ Stack ------\n");
|
||||
|
||||
string symbol;
|
||||
for (int i = 0, size = stack.size(); i < size; ++i) {
|
||||
Addr addr = stack[size - i - 1];
|
||||
if (addr == user)
|
||||
symbol = "user";
|
||||
else if (addr == console)
|
||||
symbol = "console";
|
||||
else if (addr == unknown)
|
||||
symbol = "unknown";
|
||||
else
|
||||
symtab->findSymbol(addr, symbol);
|
||||
|
||||
DPRINTFN("%#x: %s\n", addr, symbol);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
119
src/arch/alpha/stacktrace.hh
Normal file
119
src/arch/alpha/stacktrace.hh
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ALPHA_STACKTRACE_HH__
|
||||
#define __ARCH_ALPHA_STACKTRACE_HH__
|
||||
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/static_inst.hh"
|
||||
|
||||
class ExecContext;
|
||||
class StackTrace;
|
||||
|
||||
class ProcessInfo
|
||||
{
|
||||
private:
|
||||
ExecContext *xc;
|
||||
|
||||
int thread_info_size;
|
||||
int task_struct_size;
|
||||
int task_off;
|
||||
int pid_off;
|
||||
int name_off;
|
||||
|
||||
public:
|
||||
ProcessInfo(ExecContext *_xc);
|
||||
|
||||
Addr task(Addr ksp) const;
|
||||
int pid(Addr ksp) const;
|
||||
std::string name(Addr ksp) const;
|
||||
};
|
||||
|
||||
class StackTrace
|
||||
{
|
||||
protected:
|
||||
typedef TheISA::MachInst MachInst;
|
||||
private:
|
||||
ExecContext *xc;
|
||||
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 ®, int &disp);
|
||||
bool decodeStack(MachInst inst, int &disp);
|
||||
|
||||
void trace(ExecContext *xc, bool is_call);
|
||||
|
||||
public:
|
||||
StackTrace();
|
||||
StackTrace(ExecContext *xc, StaticInstPtr inst);
|
||||
~StackTrace();
|
||||
|
||||
void clear()
|
||||
{
|
||||
xc = 0;
|
||||
stack.clear();
|
||||
}
|
||||
|
||||
bool valid() const { return xc != NULL; }
|
||||
bool trace(ExecContext *xc, 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(ExecContext *xc, StaticInstPtr inst)
|
||||
{
|
||||
if (!inst->isCall() && !inst->isReturn())
|
||||
return false;
|
||||
|
||||
if (valid())
|
||||
clear();
|
||||
|
||||
trace(xc, !inst->isReturn());
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // __ARCH_ALPHA_STACKTRACE_HH__
|
||||
280
src/arch/alpha/system.cc
Normal file
280
src/arch/alpha/system.cc
Normal file
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arch/alpha/ev5.hh"
|
||||
#include "arch/alpha/system.hh"
|
||||
#include "arch/vtophys.hh"
|
||||
#include "base/remote_gdb.hh"
|
||||
#include "base/loader/object_file.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "mem/physical.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
#include "sim/builder.hh"
|
||||
|
||||
|
||||
using namespace LittleEndianGuest;
|
||||
|
||||
AlphaSystem::AlphaSystem(Params *p)
|
||||
: System(p)
|
||||
{
|
||||
consoleSymtab = new SymbolTable;
|
||||
palSymtab = new SymbolTable;
|
||||
|
||||
|
||||
/**
|
||||
* Load the pal, and console code into memory
|
||||
*/
|
||||
// Load Console Code
|
||||
console = createObjectFile(params()->console_path);
|
||||
if (console == NULL)
|
||||
fatal("Could not load console file %s", params()->console_path);
|
||||
|
||||
// Load pal file
|
||||
pal = createObjectFile(params()->palcode);
|
||||
if (pal == NULL)
|
||||
fatal("Could not load PALcode file %s", params()->palcode);
|
||||
|
||||
|
||||
// Load program sections into memory
|
||||
pal->loadSections(&functionalPort, AlphaISA::LoadAddrMask);
|
||||
console->loadSections(&functionalPort, AlphaISA::LoadAddrMask);
|
||||
|
||||
// load symbols
|
||||
if (!console->loadGlobalSymbols(consoleSymtab))
|
||||
panic("could not load console symbols\n");
|
||||
|
||||
if (!pal->loadGlobalSymbols(palSymtab))
|
||||
panic("could not load pal symbols\n");
|
||||
|
||||
if (!pal->loadLocalSymbols(palSymtab))
|
||||
panic("could not load pal symbols\n");
|
||||
|
||||
if (!console->loadGlobalSymbols(debugSymbolTable))
|
||||
panic("could not load console symbols\n");
|
||||
|
||||
if (!pal->loadGlobalSymbols(debugSymbolTable))
|
||||
panic("could not load pal symbols\n");
|
||||
|
||||
if (!pal->loadLocalSymbols(debugSymbolTable))
|
||||
panic("could not load pal symbols\n");
|
||||
|
||||
Addr addr = 0;
|
||||
#ifndef NDEBUG
|
||||
consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic");
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Copy the osflags (kernel arguments) into the consoles
|
||||
* memory. (Presently Linux does not use the console service
|
||||
* routine to get these command line arguments, but Tru64 and
|
||||
* others do.)
|
||||
*/
|
||||
if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
|
||||
virtPort.writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
|
||||
strlen(params()->boot_osflags.c_str()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the hardware reset parameter block system type and revision
|
||||
* information to Tsunami.
|
||||
*/
|
||||
if (consoleSymtab->findAddress("m5_rpb", addr)) {
|
||||
uint64_t data;
|
||||
data = htog(params()->system_type);
|
||||
virtPort.write(addr+0x50, data);
|
||||
data = htog(params()->system_rev);
|
||||
virtPort.write(addr+0x58, data);
|
||||
} else
|
||||
panic("could not find hwrpb\n");
|
||||
|
||||
}
|
||||
|
||||
AlphaSystem::~AlphaSystem()
|
||||
{
|
||||
delete consoleSymtab;
|
||||
delete console;
|
||||
delete pal;
|
||||
#ifdef DEBUG
|
||||
delete consolePanicEvent;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* This function fixes up addresses that are used to match PCs for
|
||||
* hooking simulator events on to target function executions.
|
||||
*
|
||||
* Alpha binaries may have multiple global offset table (GOT)
|
||||
* sections. A function that uses the GOT starts with a
|
||||
* two-instruction prolog which sets the global pointer (gp == r29) to
|
||||
* the appropriate GOT section. The proper gp value is calculated
|
||||
* based on the function address, which must be passed by the caller
|
||||
* in the procedure value register (pv aka t12 == r27). This sequence
|
||||
* looks like the following:
|
||||
*
|
||||
* opcode Ra Rb offset
|
||||
* ldah gp,X(pv) 09 29 27 X
|
||||
* lda gp,Y(gp) 08 29 29 Y
|
||||
*
|
||||
* for some constant offsets X and Y. The catch is that the linker
|
||||
* (or maybe even the compiler, I'm not sure) may recognize that the
|
||||
* caller and callee are using the same GOT section, making this
|
||||
* prolog redundant, and modify the call target to skip these
|
||||
* instructions. If we check for execution of the first instruction
|
||||
* of a function (the one the symbol points to) to detect when to skip
|
||||
* it, we'll miss all these modified calls. It might work to
|
||||
* unconditionally check for the third instruction, but not all
|
||||
* functions have this prolog, and there's some chance that those
|
||||
* first two instructions could have undesired consequences. So we do
|
||||
* the Right Thing and pattern-match the first two instructions of the
|
||||
* function to decide where to patch.
|
||||
*
|
||||
* Eventually this code should be moved into an ISA-specific file.
|
||||
*/
|
||||
Addr
|
||||
AlphaSystem::fixFuncEventAddr(Addr addr)
|
||||
{
|
||||
// mask for just the opcode, Ra, and Rb fields (not the offset)
|
||||
const uint32_t inst_mask = 0xffff0000;
|
||||
// ldah gp,X(pv): opcode 9, Ra = 29, Rb = 27
|
||||
const uint32_t gp_ldah_pattern = (9 << 26) | (29 << 21) | (27 << 16);
|
||||
// lda gp,Y(gp): opcode 8, Ra = 29, rb = 29
|
||||
const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16);
|
||||
|
||||
uint32_t i1 = virtPort.read<uint32_t>(addr);
|
||||
uint32_t i2 = virtPort.read<uint32_t>(addr + sizeof(AlphaISA::MachInst));
|
||||
|
||||
if ((i1 & inst_mask) == gp_ldah_pattern &&
|
||||
(i2 & inst_mask) == gp_lda_pattern) {
|
||||
Addr new_addr = addr + 2* sizeof(AlphaISA::MachInst);
|
||||
DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr);
|
||||
return new_addr;
|
||||
} else {
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlphaSystem::setAlphaAccess(Addr access)
|
||||
{
|
||||
Addr addr = 0;
|
||||
if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
|
||||
virtPort.write(addr, htog(EV5::Phys2K0Seg(access)));
|
||||
} else
|
||||
panic("could not find m5AlphaAccess\n");
|
||||
}
|
||||
|
||||
bool
|
||||
AlphaSystem::breakpoint()
|
||||
{
|
||||
return remoteGDB[0]->trap(ALPHA_KENTRY_INT);
|
||||
}
|
||||
|
||||
void
|
||||
AlphaSystem::serialize(std::ostream &os)
|
||||
{
|
||||
System::serialize(os);
|
||||
consoleSymtab->serialize("console_symtab", os);
|
||||
palSymtab->serialize("pal_symtab", os);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlphaSystem::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
System::unserialize(cp,section);
|
||||
consoleSymtab->unserialize("console_symtab", cp, section);
|
||||
palSymtab->unserialize("pal_symtab", cp, section);
|
||||
}
|
||||
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem)
|
||||
|
||||
Param<Tick> boot_cpu_frequency;
|
||||
SimObjectParam<PhysicalMemory *> physmem;
|
||||
|
||||
Param<std::string> kernel;
|
||||
Param<std::string> console;
|
||||
Param<std::string> pal;
|
||||
|
||||
Param<std::string> boot_osflags;
|
||||
Param<std::string> readfile;
|
||||
Param<unsigned int> init_param;
|
||||
|
||||
Param<uint64_t> system_type;
|
||||
Param<uint64_t> system_rev;
|
||||
|
||||
Param<bool> bin;
|
||||
VectorParam<std::string> binned_fns;
|
||||
Param<bool> bin_int;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem)
|
||||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaSystem)
|
||||
|
||||
INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
|
||||
INIT_PARAM(physmem, "phsyical memory"),
|
||||
INIT_PARAM(kernel, "file that contains the kernel code"),
|
||||
INIT_PARAM(console, "file that contains the console code"),
|
||||
INIT_PARAM(pal, "file that contains palcode"),
|
||||
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
|
||||
"a"),
|
||||
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
|
||||
INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
|
||||
INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
|
||||
INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10),
|
||||
INIT_PARAM_DFLT(bin, "is this system to be binned", false),
|
||||
INIT_PARAM(binned_fns, "functions to be broken down and binned"),
|
||||
INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true)
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(AlphaSystem)
|
||||
|
||||
CREATE_SIM_OBJECT(AlphaSystem)
|
||||
{
|
||||
AlphaSystem::Params *p = new AlphaSystem::Params;
|
||||
p->name = getInstanceName();
|
||||
p->boot_cpu_frequency = boot_cpu_frequency;
|
||||
p->physmem = physmem;
|
||||
p->kernel_path = kernel;
|
||||
p->console_path = console;
|
||||
p->palcode = pal;
|
||||
p->boot_osflags = boot_osflags;
|
||||
p->init_param = init_param;
|
||||
p->readfile = readfile;
|
||||
p->system_type = system_type;
|
||||
p->system_rev = system_rev;
|
||||
p->bin = bin;
|
||||
p->binned_fns = binned_fns;
|
||||
p->bin_int = bin_int;
|
||||
return new AlphaSystem(p);
|
||||
}
|
||||
|
||||
REGISTER_SIM_OBJECT("AlphaSystem", AlphaSystem)
|
||||
|
||||
|
||||
108
src/arch/alpha/system.hh
Normal file
108
src/arch/alpha/system.hh
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ALPHA_SYSTEM_HH__
|
||||
#define __ARCH_ALPHA_SYSTEM_HH__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "sim/system.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "cpu/pc_event.hh"
|
||||
#include "kern/system_events.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
|
||||
class AlphaSystem : public System
|
||||
{
|
||||
public:
|
||||
struct Params : public System::Params
|
||||
{
|
||||
std::string console_path;
|
||||
std::string palcode;
|
||||
uint64_t system_type;
|
||||
uint64_t system_rev;
|
||||
};
|
||||
|
||||
AlphaSystem(Params *p);
|
||||
|
||||
~AlphaSystem();
|
||||
|
||||
virtual bool breakpoint();
|
||||
|
||||
/**
|
||||
* Serialization stuff
|
||||
*/
|
||||
public:
|
||||
virtual void serialize(std::ostream &os);
|
||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
/**
|
||||
* Set the m5AlphaAccess pointer in the console
|
||||
*/
|
||||
void setAlphaAccess(Addr access);
|
||||
|
||||
/** console symbol table */
|
||||
SymbolTable *consoleSymtab;
|
||||
|
||||
/** pal symbol table */
|
||||
SymbolTable *palSymtab;
|
||||
|
||||
/** Object pointer for the console code */
|
||||
ObjectFile *console;
|
||||
|
||||
/** Object pointer for the PAL code */
|
||||
ObjectFile *pal;
|
||||
|
||||
#ifndef NDEBUG
|
||||
/** Event to halt the simulator if the console calls panic() */
|
||||
BreakPCEvent *consolePanicEvent;
|
||||
#endif
|
||||
protected:
|
||||
const Params *params() const { return (const Params *)_params; }
|
||||
|
||||
/** Add a function-based event to PALcode. */
|
||||
template <class T>
|
||||
T *AlphaSystem::addPalFuncEvent(const char *lbl)
|
||||
{
|
||||
return addFuncEvent<T>(palSymtab, lbl);
|
||||
}
|
||||
|
||||
/** Add a function-based event to the console code. */
|
||||
template <class T>
|
||||
T *AlphaSystem::addConsoleFuncEvent(const char *lbl)
|
||||
{
|
||||
return addFuncEvent<T>(consoleSymtab, lbl);
|
||||
}
|
||||
|
||||
virtual Addr fixFuncEventAddr(Addr addr);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
628
src/arch/alpha/tlb.cc
Normal file
628
src/arch/alpha/tlb.cc
Normal file
@@ -0,0 +1,628 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "arch/alpha/tlb.hh"
|
||||
#include "base/inifile.hh"
|
||||
#include "base/str.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "config/alpha_tlaser.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "sim/builder.hh"
|
||||
|
||||
using namespace std;
|
||||
using namespace EV5;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Alpha TLB
|
||||
//
|
||||
#ifdef DEBUG
|
||||
bool uncacheBit39 = false;
|
||||
bool uncacheBit40 = false;
|
||||
#endif
|
||||
|
||||
#define MODE2MASK(X) (1 << (X))
|
||||
|
||||
AlphaTLB::AlphaTLB(const string &name, int s)
|
||||
: SimObject(name), size(s), nlu(0)
|
||||
{
|
||||
table = new AlphaISA::PTE[size];
|
||||
memset(table, 0, sizeof(AlphaISA::PTE[size]));
|
||||
}
|
||||
|
||||
AlphaTLB::~AlphaTLB()
|
||||
{
|
||||
if (table)
|
||||
delete [] table;
|
||||
}
|
||||
|
||||
// look up an entry in the TLB
|
||||
AlphaISA::PTE *
|
||||
AlphaTLB::lookup(Addr vpn, uint8_t asn) const
|
||||
{
|
||||
// assume not found...
|
||||
AlphaISA::PTE *retval = NULL;
|
||||
|
||||
PageTable::const_iterator i = lookupTable.find(vpn);
|
||||
if (i != lookupTable.end()) {
|
||||
while (i->first == vpn) {
|
||||
int index = i->second;
|
||||
AlphaISA::PTE *pte = &table[index];
|
||||
assert(pte->valid);
|
||||
if (vpn == pte->tag && (pte->asma || pte->asn == asn)) {
|
||||
retval = pte;
|
||||
break;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
|
||||
retval ? "hit" : "miss", retval ? retval->ppn : 0);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
Fault
|
||||
AlphaTLB::checkCacheability(RequestPtr &req)
|
||||
{
|
||||
// in Alpha, cacheability is controlled by upper-level bits of the
|
||||
// physical address
|
||||
|
||||
/*
|
||||
* We support having the uncacheable bit in either bit 39 or bit 40.
|
||||
* The Turbolaser platform (and EV5) support having the bit in 39, but
|
||||
* Tsunami (which Linux assumes uses an EV6) generates accesses with
|
||||
* the bit in 40. So we must check for both, but we have debug flags
|
||||
* to catch a weird case where both are used, which shouldn't happen.
|
||||
*/
|
||||
|
||||
|
||||
#if ALPHA_TLASER
|
||||
if (req->getPaddr() & PAddrUncachedBit39) {
|
||||
#else
|
||||
if (req->getPaddr() & PAddrUncachedBit43) {
|
||||
#endif
|
||||
// IPR memory space not implemented
|
||||
if (PAddrIprSpace(req->getPaddr())) {
|
||||
return new UnimpFault("IPR memory space not implemented!");
|
||||
} else {
|
||||
// mark request as uncacheable
|
||||
req->setFlags(req->getFlags() | UNCACHEABLE);
|
||||
|
||||
#if !ALPHA_TLASER
|
||||
// Clear bits 42:35 of the physical address (10-2 in Tsunami manual)
|
||||
req->setPaddr(req->getPaddr() & PAddrUncachedMask);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
|
||||
// insert a new TLB entry
|
||||
void
|
||||
AlphaTLB::insert(Addr addr, AlphaISA::PTE &pte)
|
||||
{
|
||||
AlphaISA::VAddr vaddr = addr;
|
||||
if (table[nlu].valid) {
|
||||
Addr oldvpn = table[nlu].tag;
|
||||
PageTable::iterator i = lookupTable.find(oldvpn);
|
||||
|
||||
if (i == lookupTable.end())
|
||||
panic("TLB entry not found in lookupTable");
|
||||
|
||||
int index;
|
||||
while ((index = i->second) != nlu) {
|
||||
if (table[index].tag != oldvpn)
|
||||
panic("TLB entry not found in lookupTable");
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn);
|
||||
|
||||
lookupTable.erase(i);
|
||||
}
|
||||
|
||||
DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn);
|
||||
|
||||
table[nlu] = pte;
|
||||
table[nlu].tag = vaddr.vpn();
|
||||
table[nlu].valid = true;
|
||||
|
||||
lookupTable.insert(make_pair(vaddr.vpn(), nlu));
|
||||
nextnlu();
|
||||
}
|
||||
|
||||
void
|
||||
AlphaTLB::flushAll()
|
||||
{
|
||||
DPRINTF(TLB, "flushAll\n");
|
||||
memset(table, 0, sizeof(AlphaISA::PTE[size]));
|
||||
lookupTable.clear();
|
||||
nlu = 0;
|
||||
}
|
||||
|
||||
void
|
||||
AlphaTLB::flushProcesses()
|
||||
{
|
||||
PageTable::iterator i = lookupTable.begin();
|
||||
PageTable::iterator end = lookupTable.end();
|
||||
while (i != end) {
|
||||
int index = i->second;
|
||||
AlphaISA::PTE *pte = &table[index];
|
||||
assert(pte->valid);
|
||||
|
||||
// we can't increment i after we erase it, so save a copy and
|
||||
// increment it to get the next entry now
|
||||
PageTable::iterator cur = i;
|
||||
++i;
|
||||
|
||||
if (!pte->asma) {
|
||||
DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn);
|
||||
pte->valid = false;
|
||||
lookupTable.erase(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AlphaTLB::flushAddr(Addr addr, uint8_t asn)
|
||||
{
|
||||
AlphaISA::VAddr vaddr = addr;
|
||||
|
||||
PageTable::iterator i = lookupTable.find(vaddr.vpn());
|
||||
if (i == lookupTable.end())
|
||||
return;
|
||||
|
||||
while (i->first == vaddr.vpn()) {
|
||||
int index = i->second;
|
||||
AlphaISA::PTE *pte = &table[index];
|
||||
assert(pte->valid);
|
||||
|
||||
if (vaddr.vpn() == pte->tag && (pte->asma || pte->asn == asn)) {
|
||||
DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(),
|
||||
pte->ppn);
|
||||
|
||||
// invalidate this entry
|
||||
pte->valid = false;
|
||||
|
||||
lookupTable.erase(i);
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlphaTLB::serialize(ostream &os)
|
||||
{
|
||||
SERIALIZE_SCALAR(size);
|
||||
SERIALIZE_SCALAR(nlu);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
nameOut(os, csprintf("%s.PTE%d", name(), i));
|
||||
table[i].serialize(os);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AlphaTLB::unserialize(Checkpoint *cp, const string §ion)
|
||||
{
|
||||
UNSERIALIZE_SCALAR(size);
|
||||
UNSERIALIZE_SCALAR(nlu);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
table[i].unserialize(cp, csprintf("%s.PTE%d", section, i));
|
||||
if (table[i].valid) {
|
||||
lookupTable.insert(make_pair(table[i].tag, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Alpha ITB
|
||||
//
|
||||
AlphaITB::AlphaITB(const std::string &name, int size)
|
||||
: AlphaTLB(name, size)
|
||||
{}
|
||||
|
||||
|
||||
void
|
||||
AlphaITB::regStats()
|
||||
{
|
||||
hits
|
||||
.name(name() + ".hits")
|
||||
.desc("ITB hits");
|
||||
misses
|
||||
.name(name() + ".misses")
|
||||
.desc("ITB misses");
|
||||
acv
|
||||
.name(name() + ".acv")
|
||||
.desc("ITB acv");
|
||||
accesses
|
||||
.name(name() + ".accesses")
|
||||
.desc("ITB accesses");
|
||||
|
||||
accesses = hits + misses;
|
||||
}
|
||||
|
||||
|
||||
Fault
|
||||
AlphaITB::translate(RequestPtr &req, ExecContext *xc) const
|
||||
{
|
||||
if (AlphaISA::PcPAL(req->getVaddr())) {
|
||||
// strip off PAL PC marker (lsb is 1)
|
||||
req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask);
|
||||
hits++;
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
if (req->getFlags() & PHYSICAL) {
|
||||
req->setPaddr(req->getVaddr());
|
||||
} else {
|
||||
// verify that this is a good virtual address
|
||||
if (!validVirtualAddress(req->getVaddr())) {
|
||||
acv++;
|
||||
return new ItbAcvFault(req->getVaddr());
|
||||
}
|
||||
|
||||
|
||||
// VA<42:41> == 2, VA<39:13> maps directly to PA<39:13> for EV5
|
||||
// VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6
|
||||
#if ALPHA_TLASER
|
||||
if ((MCSR_SP(xc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) &&
|
||||
VAddrSpaceEV5(req->getVaddr()) == 2) {
|
||||
#else
|
||||
if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
|
||||
#endif
|
||||
// only valid in kernel mode
|
||||
if (ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM)) !=
|
||||
AlphaISA::mode_kernel) {
|
||||
acv++;
|
||||
return new ItbAcvFault(req->getVaddr());
|
||||
}
|
||||
|
||||
req->setPaddr(req->getVaddr() & PAddrImplMask);
|
||||
|
||||
#if !ALPHA_TLASER
|
||||
// sign extend the physical address properly
|
||||
if (req->getPaddr() & PAddrUncachedBit40)
|
||||
req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
|
||||
else
|
||||
req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
|
||||
#endif
|
||||
|
||||
} else {
|
||||
// not a physical address: need to look up pte
|
||||
int asn = DTB_ASN_ASN(xc->readMiscReg(AlphaISA::IPR_DTB_ASN));
|
||||
AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(),
|
||||
asn);
|
||||
|
||||
if (!pte) {
|
||||
misses++;
|
||||
return new ItbPageFault(req->getVaddr());
|
||||
}
|
||||
|
||||
req->setPaddr((pte->ppn << AlphaISA::PageShift) +
|
||||
(AlphaISA::VAddr(req->getVaddr()).offset()
|
||||
& ~3));
|
||||
|
||||
// check permissions for this access
|
||||
if (!(pte->xre &
|
||||
(1 << ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM))))) {
|
||||
// instruction access fault
|
||||
acv++;
|
||||
return new ItbAcvFault(req->getVaddr());
|
||||
}
|
||||
|
||||
hits++;
|
||||
}
|
||||
}
|
||||
|
||||
// check that the physical address is ok (catch bad physical addresses)
|
||||
if (req->getPaddr() & ~PAddrImplMask)
|
||||
return genMachineCheckFault();
|
||||
|
||||
return checkCacheability(req);
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Alpha DTB
|
||||
//
|
||||
AlphaDTB::AlphaDTB(const std::string &name, int size)
|
||||
: AlphaTLB(name, size)
|
||||
{}
|
||||
|
||||
void
|
||||
AlphaDTB::regStats()
|
||||
{
|
||||
read_hits
|
||||
.name(name() + ".read_hits")
|
||||
.desc("DTB read hits")
|
||||
;
|
||||
|
||||
read_misses
|
||||
.name(name() + ".read_misses")
|
||||
.desc("DTB read misses")
|
||||
;
|
||||
|
||||
read_acv
|
||||
.name(name() + ".read_acv")
|
||||
.desc("DTB read access violations")
|
||||
;
|
||||
|
||||
read_accesses
|
||||
.name(name() + ".read_accesses")
|
||||
.desc("DTB read accesses")
|
||||
;
|
||||
|
||||
write_hits
|
||||
.name(name() + ".write_hits")
|
||||
.desc("DTB write hits")
|
||||
;
|
||||
|
||||
write_misses
|
||||
.name(name() + ".write_misses")
|
||||
.desc("DTB write misses")
|
||||
;
|
||||
|
||||
write_acv
|
||||
.name(name() + ".write_acv")
|
||||
.desc("DTB write access violations")
|
||||
;
|
||||
|
||||
write_accesses
|
||||
.name(name() + ".write_accesses")
|
||||
.desc("DTB write accesses")
|
||||
;
|
||||
|
||||
hits
|
||||
.name(name() + ".hits")
|
||||
.desc("DTB hits")
|
||||
;
|
||||
|
||||
misses
|
||||
.name(name() + ".misses")
|
||||
.desc("DTB misses")
|
||||
;
|
||||
|
||||
acv
|
||||
.name(name() + ".acv")
|
||||
.desc("DTB access violations")
|
||||
;
|
||||
|
||||
accesses
|
||||
.name(name() + ".accesses")
|
||||
.desc("DTB accesses")
|
||||
;
|
||||
|
||||
hits = read_hits + write_hits;
|
||||
misses = read_misses + write_misses;
|
||||
acv = read_acv + write_acv;
|
||||
accesses = read_accesses + write_accesses;
|
||||
}
|
||||
|
||||
Fault
|
||||
AlphaDTB::translate(RequestPtr &req, ExecContext *xc, bool write) const
|
||||
{
|
||||
Addr pc = xc->readPC();
|
||||
|
||||
AlphaISA::mode_type mode =
|
||||
(AlphaISA::mode_type)DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM));
|
||||
|
||||
|
||||
/**
|
||||
* Check for alignment faults
|
||||
*/
|
||||
if (req->getVaddr() & (req->getSize() - 1)) {
|
||||
DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(),
|
||||
req->getSize());
|
||||
uint64_t flags = write ? MM_STAT_WR_MASK : 0;
|
||||
return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags);
|
||||
}
|
||||
|
||||
if (pc & 0x1) {
|
||||
mode = (req->getFlags() & ALTMODE) ?
|
||||
(AlphaISA::mode_type)ALT_MODE_AM(
|
||||
xc->readMiscReg(AlphaISA::IPR_ALT_MODE))
|
||||
: AlphaISA::mode_kernel;
|
||||
}
|
||||
|
||||
if (req->getFlags() & PHYSICAL) {
|
||||
req->setPaddr(req->getVaddr());
|
||||
} else {
|
||||
// verify that this is a good virtual address
|
||||
if (!validVirtualAddress(req->getVaddr())) {
|
||||
if (write) { write_acv++; } else { read_acv++; }
|
||||
uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
|
||||
MM_STAT_BAD_VA_MASK |
|
||||
MM_STAT_ACV_MASK;
|
||||
return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
|
||||
}
|
||||
|
||||
// Check for "superpage" mapping
|
||||
#if ALPHA_TLASER
|
||||
if ((MCSR_SP(xc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) &&
|
||||
VAddrSpaceEV5(req->getVaddr()) == 2) {
|
||||
#else
|
||||
if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
|
||||
#endif
|
||||
|
||||
// only valid in kernel mode
|
||||
if (DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM)) !=
|
||||
AlphaISA::mode_kernel) {
|
||||
if (write) { write_acv++; } else { read_acv++; }
|
||||
uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) |
|
||||
MM_STAT_ACV_MASK);
|
||||
return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
|
||||
}
|
||||
|
||||
req->setPaddr(req->getVaddr() & PAddrImplMask);
|
||||
|
||||
#if !ALPHA_TLASER
|
||||
// sign extend the physical address properly
|
||||
if (req->getPaddr() & PAddrUncachedBit40)
|
||||
req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
|
||||
else
|
||||
req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
|
||||
#endif
|
||||
|
||||
} else {
|
||||
if (write)
|
||||
write_accesses++;
|
||||
else
|
||||
read_accesses++;
|
||||
|
||||
int asn = DTB_ASN_ASN(xc->readMiscReg(AlphaISA::IPR_DTB_ASN));
|
||||
|
||||
// not a physical address: need to look up pte
|
||||
AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(),
|
||||
asn);
|
||||
|
||||
if (!pte) {
|
||||
// page fault
|
||||
if (write) { write_misses++; } else { read_misses++; }
|
||||
uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
|
||||
MM_STAT_DTB_MISS_MASK;
|
||||
return (req->getFlags() & VPTE) ?
|
||||
(Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(),
|
||||
flags)) :
|
||||
(Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(),
|
||||
flags));
|
||||
}
|
||||
|
||||
req->setPaddr((pte->ppn << AlphaISA::PageShift) +
|
||||
AlphaISA::VAddr(req->getVaddr()).offset());
|
||||
|
||||
if (write) {
|
||||
if (!(pte->xwe & MODE2MASK(mode))) {
|
||||
// declare the instruction access fault
|
||||
write_acv++;
|
||||
uint64_t flags = MM_STAT_WR_MASK |
|
||||
MM_STAT_ACV_MASK |
|
||||
(pte->fonw ? MM_STAT_FONW_MASK : 0);
|
||||
return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
|
||||
}
|
||||
if (pte->fonw) {
|
||||
write_acv++;
|
||||
uint64_t flags = MM_STAT_WR_MASK |
|
||||
MM_STAT_FONW_MASK;
|
||||
return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
|
||||
}
|
||||
} else {
|
||||
if (!(pte->xre & MODE2MASK(mode))) {
|
||||
read_acv++;
|
||||
uint64_t flags = MM_STAT_ACV_MASK |
|
||||
(pte->fonr ? MM_STAT_FONR_MASK : 0);
|
||||
return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
|
||||
}
|
||||
if (pte->fonr) {
|
||||
read_acv++;
|
||||
uint64_t flags = MM_STAT_FONR_MASK;
|
||||
return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (write)
|
||||
write_hits++;
|
||||
else
|
||||
read_hits++;
|
||||
}
|
||||
|
||||
// check that the physical address is ok (catch bad physical addresses)
|
||||
if (req->getPaddr() & ~PAddrImplMask)
|
||||
return genMachineCheckFault();
|
||||
|
||||
return checkCacheability(req);
|
||||
}
|
||||
|
||||
AlphaISA::PTE &
|
||||
AlphaTLB::index(bool advance)
|
||||
{
|
||||
AlphaISA::PTE *pte = &table[nlu];
|
||||
|
||||
if (advance)
|
||||
nextnlu();
|
||||
|
||||
return *pte;
|
||||
}
|
||||
|
||||
DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", AlphaTLB)
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaITB)
|
||||
|
||||
Param<int> size;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(AlphaITB)
|
||||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaITB)
|
||||
|
||||
INIT_PARAM_DFLT(size, "TLB size", 48)
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(AlphaITB)
|
||||
|
||||
|
||||
CREATE_SIM_OBJECT(AlphaITB)
|
||||
{
|
||||
return new AlphaITB(getInstanceName(), size);
|
||||
}
|
||||
|
||||
REGISTER_SIM_OBJECT("AlphaITB", AlphaITB)
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB)
|
||||
|
||||
Param<int> size;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB)
|
||||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDTB)
|
||||
|
||||
INIT_PARAM_DFLT(size, "TLB size", 64)
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(AlphaDTB)
|
||||
|
||||
|
||||
CREATE_SIM_OBJECT(AlphaDTB)
|
||||
{
|
||||
return new AlphaDTB(getInstanceName(), size);
|
||||
}
|
||||
|
||||
REGISTER_SIM_OBJECT("AlphaDTB", AlphaDTB)
|
||||
|
||||
121
src/arch/alpha/tlb.hh
Normal file
121
src/arch/alpha/tlb.hh
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __ALPHA_MEMORY_HH__
|
||||
#define __ALPHA_MEMORY_HH__
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "arch/alpha/ev5.hh"
|
||||
#include "arch/alpha/isa_traits.hh"
|
||||
#include "arch/alpha/faults.hh"
|
||||
#include "base/statistics.hh"
|
||||
#include "mem/request.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
|
||||
class ExecContext;
|
||||
|
||||
class AlphaTLB : public SimObject
|
||||
{
|
||||
protected:
|
||||
typedef std::multimap<Addr, int> PageTable;
|
||||
PageTable lookupTable; // Quick lookup into page table
|
||||
|
||||
AlphaISA::PTE *table; // the Page Table
|
||||
int size; // TLB Size
|
||||
int nlu; // not last used entry (for replacement)
|
||||
|
||||
void nextnlu() { if (++nlu >= size) nlu = 0; }
|
||||
AlphaISA::PTE *lookup(Addr vpn, uint8_t asn) const;
|
||||
|
||||
public:
|
||||
AlphaTLB(const std::string &name, int size);
|
||||
virtual ~AlphaTLB();
|
||||
|
||||
int getsize() const { return size; }
|
||||
|
||||
AlphaISA::PTE &index(bool advance = true);
|
||||
void insert(Addr vaddr, AlphaISA::PTE &pte);
|
||||
|
||||
void flushAll();
|
||||
void flushProcesses();
|
||||
void flushAddr(Addr addr, uint8_t asn);
|
||||
|
||||
// static helper functions... really EV5 VM traits
|
||||
static bool validVirtualAddress(Addr vaddr) {
|
||||
// unimplemented bits must be all 0 or all 1
|
||||
Addr unimplBits = vaddr & EV5::VAddrUnImplMask;
|
||||
return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask);
|
||||
}
|
||||
|
||||
static Fault checkCacheability(RequestPtr &req);
|
||||
|
||||
// Checkpointing
|
||||
virtual void serialize(std::ostream &os);
|
||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
class AlphaITB : public AlphaTLB
|
||||
{
|
||||
protected:
|
||||
mutable Stats::Scalar<> hits;
|
||||
mutable Stats::Scalar<> misses;
|
||||
mutable Stats::Scalar<> acv;
|
||||
mutable Stats::Formula accesses;
|
||||
|
||||
public:
|
||||
AlphaITB(const std::string &name, int size);
|
||||
virtual void regStats();
|
||||
|
||||
Fault translate(RequestPtr &req, ExecContext *xc) const;
|
||||
};
|
||||
|
||||
class AlphaDTB : public AlphaTLB
|
||||
{
|
||||
protected:
|
||||
mutable Stats::Scalar<> read_hits;
|
||||
mutable Stats::Scalar<> read_misses;
|
||||
mutable Stats::Scalar<> read_acv;
|
||||
mutable Stats::Scalar<> read_accesses;
|
||||
mutable Stats::Scalar<> write_hits;
|
||||
mutable Stats::Scalar<> write_misses;
|
||||
mutable Stats::Scalar<> write_acv;
|
||||
mutable Stats::Scalar<> write_accesses;
|
||||
Stats::Formula hits;
|
||||
Stats::Formula misses;
|
||||
Stats::Formula acv;
|
||||
Stats::Formula accesses;
|
||||
|
||||
public:
|
||||
AlphaDTB(const std::string &name, int size);
|
||||
virtual void regStats();
|
||||
|
||||
Fault translate(RequestPtr &req, ExecContext *xc, bool write) const;
|
||||
};
|
||||
|
||||
#endif // __ALPHA_MEMORY_HH__
|
||||
586
src/arch/alpha/tru64/process.cc
Normal file
586
src/arch/alpha/tru64/process.cc
Normal file
@@ -0,0 +1,586 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "arch/alpha/tru64/tru64.hh"
|
||||
#include "arch/alpha/isa_traits.hh"
|
||||
#include "arch/alpha/tru64/process.hh"
|
||||
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "kern/tru64/tru64.hh"
|
||||
|
||||
#include "sim/process.hh"
|
||||
#include "sim/syscall_emul.hh"
|
||||
|
||||
using namespace std;
|
||||
using namespace AlphaISA;
|
||||
|
||||
/// Target uname() handler.
|
||||
static SyscallReturn
|
||||
unameFunc(SyscallDesc *desc, int callnum, Process *process,
|
||||
ExecContext *xc)
|
||||
{
|
||||
TypedBufferArg<AlphaTru64::utsname> name(xc->getSyscallArg(0));
|
||||
|
||||
strcpy(name->sysname, "OSF1");
|
||||
strcpy(name->nodename, "m5.eecs.umich.edu");
|
||||
strcpy(name->release, "V5.1");
|
||||
strcpy(name->version, "732");
|
||||
strcpy(name->machine, "alpha");
|
||||
|
||||
name.copyOut(xc->getMemPort());
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Target getsysyinfo() handler.
|
||||
static SyscallReturn
|
||||
getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
|
||||
ExecContext *xc)
|
||||
{
|
||||
unsigned op = xc->getSyscallArg(0);
|
||||
unsigned nbytes = xc->getSyscallArg(2);
|
||||
|
||||
switch (op) {
|
||||
|
||||
case AlphaTru64::GSI_MAX_CPU: {
|
||||
TypedBufferArg<uint32_t> max_cpu(xc->getSyscallArg(1));
|
||||
*max_cpu = htog((uint32_t)process->numCpus());
|
||||
max_cpu.copyOut(xc->getMemPort());
|
||||
return 1;
|
||||
}
|
||||
|
||||
case AlphaTru64::GSI_CPUS_IN_BOX: {
|
||||
TypedBufferArg<uint32_t> cpus_in_box(xc->getSyscallArg(1));
|
||||
*cpus_in_box = htog((uint32_t)process->numCpus());
|
||||
cpus_in_box.copyOut(xc->getMemPort());
|
||||
return 1;
|
||||
}
|
||||
|
||||
case AlphaTru64::GSI_PHYSMEM: {
|
||||
TypedBufferArg<uint64_t> physmem(xc->getSyscallArg(1));
|
||||
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
|
||||
physmem.copyOut(xc->getMemPort());
|
||||
return 1;
|
||||
}
|
||||
|
||||
case AlphaTru64::GSI_CPU_INFO: {
|
||||
TypedBufferArg<AlphaTru64::cpu_info> infop(xc->getSyscallArg(1));
|
||||
|
||||
infop->current_cpu = htog(0);
|
||||
infop->cpus_in_box = htog(process->numCpus());
|
||||
infop->cpu_type = htog(57);
|
||||
infop->ncpus = htog(process->numCpus());
|
||||
uint64_t cpumask = (1 << process->numCpus()) - 1;
|
||||
infop->cpus_present = infop->cpus_running = htog(cpumask);
|
||||
infop->cpu_binding = htog(0);
|
||||
infop->cpu_ex_binding = htog(0);
|
||||
infop->mhz = htog(667);
|
||||
|
||||
infop.copyOut(xc->getMemPort());
|
||||
return 1;
|
||||
}
|
||||
|
||||
case AlphaTru64::GSI_PROC_TYPE: {
|
||||
TypedBufferArg<uint64_t> proc_type(xc->getSyscallArg(1));
|
||||
*proc_type = htog((uint64_t)11);
|
||||
proc_type.copyOut(xc->getMemPort());
|
||||
return 1;
|
||||
}
|
||||
|
||||
case AlphaTru64::GSI_PLATFORM_NAME: {
|
||||
BufferArg bufArg(xc->getSyscallArg(1), nbytes);
|
||||
strncpy((char *)bufArg.bufferPtr(),
|
||||
"COMPAQ Professional Workstation XP1000",
|
||||
nbytes);
|
||||
bufArg.copyOut(xc->getMemPort());
|
||||
return 1;
|
||||
}
|
||||
|
||||
case AlphaTru64::GSI_CLK_TCK: {
|
||||
TypedBufferArg<uint64_t> clk_hz(xc->getSyscallArg(1));
|
||||
*clk_hz = htog((uint64_t)1024);
|
||||
clk_hz.copyOut(xc->getMemPort());
|
||||
return 1;
|
||||
}
|
||||
|
||||
default:
|
||||
warn("getsysinfo: unknown op %d\n", op);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Target setsysyinfo() handler.
|
||||
static SyscallReturn
|
||||
setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
|
||||
ExecContext *xc)
|
||||
{
|
||||
unsigned op = xc->getSyscallArg(0);
|
||||
|
||||
switch (op) {
|
||||
case AlphaTru64::SSI_IEEE_FP_CONTROL:
|
||||
warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n",
|
||||
xc->getSyscallArg(1));
|
||||
break;
|
||||
|
||||
default:
|
||||
warn("setsysinfo: unknown op %d\n", op);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/// Target table() handler.
|
||||
static
|
||||
SyscallReturn tableFunc(SyscallDesc *desc, int callnum,Process *process,
|
||||
ExecContext *xc)
|
||||
{
|
||||
using namespace std;
|
||||
using namespace TheISA;
|
||||
|
||||
int id = xc->getSyscallArg(0); // table ID
|
||||
int index = xc->getSyscallArg(1); // index into table
|
||||
// arg 2 is buffer pointer; type depends on table ID
|
||||
int nel = xc->getSyscallArg(3); // number of elements
|
||||
int lel = xc->getSyscallArg(4); // expected element size
|
||||
|
||||
switch (id) {
|
||||
case AlphaTru64::TBL_SYSINFO: {
|
||||
if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo))
|
||||
return -EINVAL;
|
||||
TypedBufferArg<Tru64::tbl_sysinfo> elp(xc->getSyscallArg(2));
|
||||
|
||||
const int clk_hz = one_million;
|
||||
elp->si_user = htog(curTick / (Clock::Frequency / clk_hz));
|
||||
elp->si_nice = htog(0);
|
||||
elp->si_sys = htog(0);
|
||||
elp->si_idle = htog(0);
|
||||
elp->wait = htog(0);
|
||||
elp->si_hz = htog(clk_hz);
|
||||
elp->si_phz = htog(clk_hz);
|
||||
elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch?
|
||||
elp->si_max_procs = htog(process->numCpus());
|
||||
elp.copyOut(xc->getMemPort());
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
cerr << "table(): id " << id << " unknown." << endl;
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
SyscallDesc AlphaTru64Process::syscallDescs[] = {
|
||||
/* 0 */ SyscallDesc("syscall (#0)", AlphaTru64::indirectSyscallFunc,
|
||||
SyscallDesc::SuppressReturnValue),
|
||||
/* 1 */ SyscallDesc("exit", exitFunc),
|
||||
/* 2 */ SyscallDesc("fork", unimplementedFunc),
|
||||
/* 3 */ SyscallDesc("read", readFunc),
|
||||
/* 4 */ SyscallDesc("write", writeFunc),
|
||||
/* 5 */ SyscallDesc("old_open", unimplementedFunc),
|
||||
/* 6 */ SyscallDesc("close", closeFunc),
|
||||
/* 7 */ SyscallDesc("wait4", unimplementedFunc),
|
||||
/* 8 */ SyscallDesc("old_creat", unimplementedFunc),
|
||||
/* 9 */ SyscallDesc("link", unimplementedFunc),
|
||||
/* 10 */ SyscallDesc("unlink", unlinkFunc),
|
||||
/* 11 */ SyscallDesc("execv", unimplementedFunc),
|
||||
/* 12 */ SyscallDesc("chdir", unimplementedFunc),
|
||||
/* 13 */ SyscallDesc("fchdir", unimplementedFunc),
|
||||
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
|
||||
/* 15 */ SyscallDesc("chmod", unimplementedFunc),
|
||||
/* 16 */ SyscallDesc("chown", unimplementedFunc),
|
||||
/* 17 */ SyscallDesc("obreak", obreakFunc),
|
||||
/* 18 */ SyscallDesc("pre_F64_getfsstat", unimplementedFunc),
|
||||
/* 19 */ SyscallDesc("lseek", lseekFunc),
|
||||
/* 20 */ SyscallDesc("getpid", getpidPseudoFunc),
|
||||
/* 21 */ SyscallDesc("mount", unimplementedFunc),
|
||||
/* 22 */ SyscallDesc("unmount", unimplementedFunc),
|
||||
/* 23 */ SyscallDesc("setuid", setuidFunc),
|
||||
/* 24 */ SyscallDesc("getuid", getuidPseudoFunc),
|
||||
/* 25 */ SyscallDesc("exec_with_loader", unimplementedFunc),
|
||||
/* 26 */ SyscallDesc("ptrace", unimplementedFunc),
|
||||
/* 27 */ SyscallDesc("recvmsg", unimplementedFunc),
|
||||
/* 28 */ SyscallDesc("sendmsg", unimplementedFunc),
|
||||
/* 29 */ SyscallDesc("recvfrom", unimplementedFunc),
|
||||
/* 30 */ SyscallDesc("accept", unimplementedFunc),
|
||||
/* 31 */ SyscallDesc("getpeername", unimplementedFunc),
|
||||
/* 32 */ SyscallDesc("getsockname", unimplementedFunc),
|
||||
/* 33 */ SyscallDesc("access", unimplementedFunc),
|
||||
/* 34 */ SyscallDesc("chflags", unimplementedFunc),
|
||||
/* 35 */ SyscallDesc("fchflags", unimplementedFunc),
|
||||
/* 36 */ SyscallDesc("sync", unimplementedFunc),
|
||||
/* 37 */ SyscallDesc("kill", unimplementedFunc),
|
||||
/* 38 */ SyscallDesc("old_stat", unimplementedFunc),
|
||||
/* 39 */ SyscallDesc("setpgid", unimplementedFunc),
|
||||
/* 40 */ SyscallDesc("old_lstat", unimplementedFunc),
|
||||
/* 41 */ SyscallDesc("dup", unimplementedFunc),
|
||||
/* 42 */ SyscallDesc("pipe", unimplementedFunc),
|
||||
/* 43 */ SyscallDesc("set_program_attributes", unimplementedFunc),
|
||||
/* 44 */ SyscallDesc("profil", unimplementedFunc),
|
||||
/* 45 */ SyscallDesc("open", openFunc<AlphaTru64>),
|
||||
/* 46 */ SyscallDesc("obsolete osigaction", unimplementedFunc),
|
||||
/* 47 */ SyscallDesc("getgid", getgidPseudoFunc),
|
||||
/* 48 */ SyscallDesc("sigprocmask", ignoreFunc),
|
||||
/* 49 */ SyscallDesc("getlogin", unimplementedFunc),
|
||||
/* 50 */ SyscallDesc("setlogin", unimplementedFunc),
|
||||
/* 51 */ SyscallDesc("acct", unimplementedFunc),
|
||||
/* 52 */ SyscallDesc("sigpending", unimplementedFunc),
|
||||
/* 53 */ SyscallDesc("classcntl", unimplementedFunc),
|
||||
/* 54 */ SyscallDesc("ioctl", ioctlFunc<AlphaTru64>),
|
||||
/* 55 */ SyscallDesc("reboot", unimplementedFunc),
|
||||
/* 56 */ SyscallDesc("revoke", unimplementedFunc),
|
||||
/* 57 */ SyscallDesc("symlink", unimplementedFunc),
|
||||
/* 58 */ SyscallDesc("readlink", unimplementedFunc),
|
||||
/* 59 */ SyscallDesc("execve", unimplementedFunc),
|
||||
/* 60 */ SyscallDesc("umask", unimplementedFunc),
|
||||
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
|
||||
/* 62 */ SyscallDesc("old_fstat", unimplementedFunc),
|
||||
/* 63 */ SyscallDesc("getpgrp", unimplementedFunc),
|
||||
/* 64 */ SyscallDesc("getpagesize", getpagesizeFunc),
|
||||
/* 65 */ SyscallDesc("mremap", unimplementedFunc),
|
||||
/* 66 */ SyscallDesc("vfork", unimplementedFunc),
|
||||
/* 67 */ SyscallDesc("pre_F64_stat", statFunc<AlphaTru64::PreF64>),
|
||||
/* 68 */ SyscallDesc("pre_F64_lstat", lstatFunc<AlphaTru64::PreF64>),
|
||||
/* 69 */ SyscallDesc("sbrk", unimplementedFunc),
|
||||
/* 70 */ SyscallDesc("sstk", unimplementedFunc),
|
||||
/* 71 */ SyscallDesc("mmap", mmapFunc<AlphaTru64>),
|
||||
/* 72 */ SyscallDesc("ovadvise", unimplementedFunc),
|
||||
/* 73 */ SyscallDesc("munmap", munmapFunc),
|
||||
/* 74 */ SyscallDesc("mprotect", ignoreFunc),
|
||||
/* 75 */ SyscallDesc("madvise", unimplementedFunc),
|
||||
/* 76 */ SyscallDesc("old_vhangup", unimplementedFunc),
|
||||
/* 77 */ SyscallDesc("kmodcall", unimplementedFunc),
|
||||
/* 78 */ SyscallDesc("mincore", unimplementedFunc),
|
||||
/* 79 */ SyscallDesc("getgroups", unimplementedFunc),
|
||||
/* 80 */ SyscallDesc("setgroups", unimplementedFunc),
|
||||
/* 81 */ SyscallDesc("old_getpgrp", unimplementedFunc),
|
||||
/* 82 */ SyscallDesc("setpgrp", unimplementedFunc),
|
||||
/* 83 */ SyscallDesc("setitimer", unimplementedFunc),
|
||||
/* 84 */ SyscallDesc("old_wait", unimplementedFunc),
|
||||
/* 85 */ SyscallDesc("table", tableFunc),
|
||||
/* 86 */ SyscallDesc("getitimer", unimplementedFunc),
|
||||
/* 87 */ SyscallDesc("gethostname", gethostnameFunc),
|
||||
/* 88 */ SyscallDesc("sethostname", unimplementedFunc),
|
||||
/* 89 */ SyscallDesc("getdtablesize", unimplementedFunc),
|
||||
/* 90 */ SyscallDesc("dup2", unimplementedFunc),
|
||||
/* 91 */ SyscallDesc("pre_F64_fstat", fstatFunc<AlphaTru64::PreF64>),
|
||||
/* 92 */ SyscallDesc("fcntl", fcntlFunc),
|
||||
/* 93 */ SyscallDesc("select", unimplementedFunc),
|
||||
/* 94 */ SyscallDesc("poll", unimplementedFunc),
|
||||
/* 95 */ SyscallDesc("fsync", unimplementedFunc),
|
||||
/* 96 */ SyscallDesc("setpriority", unimplementedFunc),
|
||||
/* 97 */ SyscallDesc("socket", unimplementedFunc),
|
||||
/* 98 */ SyscallDesc("connect", unimplementedFunc),
|
||||
/* 99 */ SyscallDesc("old_accept", unimplementedFunc),
|
||||
/* 100 */ SyscallDesc("getpriority", unimplementedFunc),
|
||||
/* 101 */ SyscallDesc("old_send", unimplementedFunc),
|
||||
/* 102 */ SyscallDesc("old_recv", unimplementedFunc),
|
||||
/* 103 */ SyscallDesc("sigreturn", AlphaTru64::sigreturnFunc,
|
||||
SyscallDesc::SuppressReturnValue),
|
||||
/* 104 */ SyscallDesc("bind", unimplementedFunc),
|
||||
/* 105 */ SyscallDesc("setsockopt", unimplementedFunc),
|
||||
/* 106 */ SyscallDesc("listen", unimplementedFunc),
|
||||
/* 107 */ SyscallDesc("plock", unimplementedFunc),
|
||||
/* 108 */ SyscallDesc("old_sigvec", unimplementedFunc),
|
||||
/* 109 */ SyscallDesc("old_sigblock", unimplementedFunc),
|
||||
/* 110 */ SyscallDesc("old_sigsetmask", unimplementedFunc),
|
||||
/* 111 */ SyscallDesc("sigsuspend", unimplementedFunc),
|
||||
/* 112 */ SyscallDesc("sigstack", ignoreFunc),
|
||||
/* 113 */ SyscallDesc("old_recvmsg", unimplementedFunc),
|
||||
/* 114 */ SyscallDesc("old_sendmsg", unimplementedFunc),
|
||||
/* 115 */ SyscallDesc("obsolete vtrace", unimplementedFunc),
|
||||
/* 116 */ SyscallDesc("gettimeofday", gettimeofdayFunc<AlphaTru64>),
|
||||
/* 117 */ SyscallDesc("getrusage", getrusageFunc<AlphaTru64>),
|
||||
/* 118 */ SyscallDesc("getsockopt", unimplementedFunc),
|
||||
/* 119 */ SyscallDesc("numa_syscalls", unimplementedFunc),
|
||||
/* 120 */ SyscallDesc("readv", unimplementedFunc),
|
||||
/* 121 */ SyscallDesc("writev", unimplementedFunc),
|
||||
/* 122 */ SyscallDesc("settimeofday", unimplementedFunc),
|
||||
/* 123 */ SyscallDesc("fchown", unimplementedFunc),
|
||||
/* 124 */ SyscallDesc("fchmod", unimplementedFunc),
|
||||
/* 125 */ SyscallDesc("old_recvfrom", unimplementedFunc),
|
||||
/* 126 */ SyscallDesc("setreuid", unimplementedFunc),
|
||||
/* 127 */ SyscallDesc("setregid", unimplementedFunc),
|
||||
/* 128 */ SyscallDesc("rename", renameFunc),
|
||||
/* 129 */ SyscallDesc("truncate", truncateFunc),
|
||||
/* 130 */ SyscallDesc("ftruncate", ftruncateFunc),
|
||||
/* 131 */ SyscallDesc("flock", unimplementedFunc),
|
||||
/* 132 */ SyscallDesc("setgid", 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("obsolete 4.2 sigreturn", unimplementedFunc),
|
||||
/* 140 */ SyscallDesc("adjtime", unimplementedFunc),
|
||||
/* 141 */ SyscallDesc("old_getpeername", unimplementedFunc),
|
||||
/* 142 */ SyscallDesc("gethostid", unimplementedFunc),
|
||||
/* 143 */ SyscallDesc("sethostid", unimplementedFunc),
|
||||
/* 144 */ SyscallDesc("getrlimit", getrlimitFunc<AlphaTru64>),
|
||||
/* 145 */ SyscallDesc("setrlimit", ignoreFunc),
|
||||
/* 146 */ SyscallDesc("old_killpg", unimplementedFunc),
|
||||
/* 147 */ SyscallDesc("setsid", unimplementedFunc),
|
||||
/* 148 */ SyscallDesc("quotactl", unimplementedFunc),
|
||||
/* 149 */ SyscallDesc("oldquota", unimplementedFunc),
|
||||
/* 150 */ SyscallDesc("old_getsockname", unimplementedFunc),
|
||||
/* 151 */ SyscallDesc("pread", unimplementedFunc),
|
||||
/* 152 */ SyscallDesc("pwrite", unimplementedFunc),
|
||||
/* 153 */ SyscallDesc("pid_block", unimplementedFunc),
|
||||
/* 154 */ SyscallDesc("pid_unblock", unimplementedFunc),
|
||||
/* 155 */ SyscallDesc("signal_urti", unimplementedFunc),
|
||||
/* 156 */ SyscallDesc("sigaction", ignoreFunc),
|
||||
/* 157 */ SyscallDesc("sigwaitprim", unimplementedFunc),
|
||||
/* 158 */ SyscallDesc("nfssvc", unimplementedFunc),
|
||||
/* 159 */ SyscallDesc("getdirentries", AlphaTru64::getdirentriesFunc),
|
||||
/* 160 */ SyscallDesc("pre_F64_statfs", statfsFunc<AlphaTru64::PreF64>),
|
||||
/* 161 */ SyscallDesc("pre_F64_fstatfs", fstatfsFunc<AlphaTru64::PreF64>),
|
||||
/* 162 */ SyscallDesc("unknown #162", unimplementedFunc),
|
||||
/* 163 */ SyscallDesc("async_daemon", unimplementedFunc),
|
||||
/* 164 */ SyscallDesc("getfh", unimplementedFunc),
|
||||
/* 165 */ SyscallDesc("getdomainname", unimplementedFunc),
|
||||
/* 166 */ SyscallDesc("setdomainname", unimplementedFunc),
|
||||
/* 167 */ SyscallDesc("unknown #167", unimplementedFunc),
|
||||
/* 168 */ SyscallDesc("unknown #168", unimplementedFunc),
|
||||
/* 169 */ SyscallDesc("exportfs", unimplementedFunc),
|
||||
/* 170 */ SyscallDesc("unknown #170", unimplementedFunc),
|
||||
/* 171 */ SyscallDesc("unknown #171", unimplementedFunc),
|
||||
/* 172 */ SyscallDesc("unknown #172", unimplementedFunc),
|
||||
/* 173 */ SyscallDesc("unknown #173", unimplementedFunc),
|
||||
/* 174 */ SyscallDesc("unknown #174", unimplementedFunc),
|
||||
/* 175 */ SyscallDesc("unknown #175", unimplementedFunc),
|
||||
/* 176 */ SyscallDesc("unknown #176", unimplementedFunc),
|
||||
/* 177 */ SyscallDesc("unknown #177", unimplementedFunc),
|
||||
/* 178 */ SyscallDesc("unknown #178", unimplementedFunc),
|
||||
/* 179 */ SyscallDesc("unknown #179", unimplementedFunc),
|
||||
/* 180 */ SyscallDesc("unknown #180", unimplementedFunc),
|
||||
/* 181 */ SyscallDesc("alt_plock", unimplementedFunc),
|
||||
/* 182 */ SyscallDesc("unknown #182", unimplementedFunc),
|
||||
/* 183 */ SyscallDesc("unknown #183", unimplementedFunc),
|
||||
/* 184 */ SyscallDesc("getmnt", unimplementedFunc),
|
||||
/* 185 */ SyscallDesc("unknown #185", unimplementedFunc),
|
||||
/* 186 */ SyscallDesc("unknown #186", unimplementedFunc),
|
||||
/* 187 */ SyscallDesc("alt_sigpending", unimplementedFunc),
|
||||
/* 188 */ SyscallDesc("alt_setsid", unimplementedFunc),
|
||||
/* 189 */ SyscallDesc("unknown #189", unimplementedFunc),
|
||||
/* 190 */ SyscallDesc("unknown #190", unimplementedFunc),
|
||||
/* 191 */ SyscallDesc("unknown #191", unimplementedFunc),
|
||||
/* 192 */ SyscallDesc("unknown #192", unimplementedFunc),
|
||||
/* 193 */ SyscallDesc("unknown #193", unimplementedFunc),
|
||||
/* 194 */ SyscallDesc("unknown #194", unimplementedFunc),
|
||||
/* 195 */ SyscallDesc("unknown #195", unimplementedFunc),
|
||||
/* 196 */ SyscallDesc("unknown #196", unimplementedFunc),
|
||||
/* 197 */ SyscallDesc("unknown #197", unimplementedFunc),
|
||||
/* 198 */ SyscallDesc("unknown #198", unimplementedFunc),
|
||||
/* 199 */ SyscallDesc("swapon", unimplementedFunc),
|
||||
/* 200 */ SyscallDesc("msgctl", unimplementedFunc),
|
||||
/* 201 */ SyscallDesc("msgget", unimplementedFunc),
|
||||
/* 202 */ SyscallDesc("msgrcv", unimplementedFunc),
|
||||
/* 203 */ SyscallDesc("msgsnd", unimplementedFunc),
|
||||
/* 204 */ SyscallDesc("semctl", unimplementedFunc),
|
||||
/* 205 */ SyscallDesc("semget", unimplementedFunc),
|
||||
/* 206 */ SyscallDesc("semop", unimplementedFunc),
|
||||
/* 207 */ SyscallDesc("uname", unameFunc),
|
||||
/* 208 */ SyscallDesc("lchown", unimplementedFunc),
|
||||
/* 209 */ SyscallDesc("shmat", unimplementedFunc),
|
||||
/* 210 */ SyscallDesc("shmctl", unimplementedFunc),
|
||||
/* 211 */ SyscallDesc("shmdt", unimplementedFunc),
|
||||
/* 212 */ SyscallDesc("shmget", unimplementedFunc),
|
||||
/* 213 */ SyscallDesc("mvalid", unimplementedFunc),
|
||||
/* 214 */ SyscallDesc("getaddressconf", unimplementedFunc),
|
||||
/* 215 */ SyscallDesc("msleep", unimplementedFunc),
|
||||
/* 216 */ SyscallDesc("mwakeup", unimplementedFunc),
|
||||
/* 217 */ SyscallDesc("msync", unimplementedFunc),
|
||||
/* 218 */ SyscallDesc("signal", unimplementedFunc),
|
||||
/* 219 */ SyscallDesc("utc_gettime", unimplementedFunc),
|
||||
/* 220 */ SyscallDesc("utc_adjtime", unimplementedFunc),
|
||||
/* 221 */ SyscallDesc("unknown #221", unimplementedFunc),
|
||||
/* 222 */ SyscallDesc("security", unimplementedFunc),
|
||||
/* 223 */ SyscallDesc("kloadcall", unimplementedFunc),
|
||||
/* 224 */ SyscallDesc("stat", statFunc<AlphaTru64::F64>),
|
||||
/* 225 */ SyscallDesc("lstat", lstatFunc<AlphaTru64::F64>),
|
||||
/* 226 */ SyscallDesc("fstat", fstatFunc<AlphaTru64::F64>),
|
||||
/* 227 */ SyscallDesc("statfs", statfsFunc<AlphaTru64::F64>),
|
||||
/* 228 */ SyscallDesc("fstatfs", fstatfsFunc<AlphaTru64::F64>),
|
||||
/* 229 */ SyscallDesc("getfsstat", unimplementedFunc),
|
||||
/* 230 */ SyscallDesc("gettimeofday64", unimplementedFunc),
|
||||
/* 231 */ SyscallDesc("settimeofday64", unimplementedFunc),
|
||||
/* 232 */ SyscallDesc("unknown #232", unimplementedFunc),
|
||||
/* 233 */ SyscallDesc("getpgid", unimplementedFunc),
|
||||
/* 234 */ SyscallDesc("getsid", unimplementedFunc),
|
||||
/* 235 */ SyscallDesc("sigaltstack", ignoreFunc),
|
||||
/* 236 */ SyscallDesc("waitid", unimplementedFunc),
|
||||
/* 237 */ SyscallDesc("priocntlset", unimplementedFunc),
|
||||
/* 238 */ SyscallDesc("sigsendset", unimplementedFunc),
|
||||
/* 239 */ SyscallDesc("set_speculative", unimplementedFunc),
|
||||
/* 240 */ SyscallDesc("msfs_syscall", unimplementedFunc),
|
||||
/* 241 */ SyscallDesc("sysinfo", unimplementedFunc),
|
||||
/* 242 */ SyscallDesc("uadmin", unimplementedFunc),
|
||||
/* 243 */ SyscallDesc("fuser", unimplementedFunc),
|
||||
/* 244 */ SyscallDesc("proplist_syscall", unimplementedFunc),
|
||||
/* 245 */ SyscallDesc("ntp_adjtime", unimplementedFunc),
|
||||
/* 246 */ SyscallDesc("ntp_gettime", unimplementedFunc),
|
||||
/* 247 */ SyscallDesc("pathconf", unimplementedFunc),
|
||||
/* 248 */ SyscallDesc("fpathconf", unimplementedFunc),
|
||||
/* 249 */ SyscallDesc("sync2", unimplementedFunc),
|
||||
/* 250 */ SyscallDesc("uswitch", unimplementedFunc),
|
||||
/* 251 */ SyscallDesc("usleep_thread", unimplementedFunc),
|
||||
/* 252 */ SyscallDesc("audcntl", unimplementedFunc),
|
||||
/* 253 */ SyscallDesc("audgen", unimplementedFunc),
|
||||
/* 254 */ SyscallDesc("sysfs", unimplementedFunc),
|
||||
/* 255 */ SyscallDesc("subsys_info", unimplementedFunc),
|
||||
/* 256 */ SyscallDesc("getsysinfo", getsysinfoFunc),
|
||||
/* 257 */ SyscallDesc("setsysinfo", setsysinfoFunc),
|
||||
/* 258 */ SyscallDesc("afs_syscall", unimplementedFunc),
|
||||
/* 259 */ SyscallDesc("swapctl", unimplementedFunc),
|
||||
/* 260 */ SyscallDesc("memcntl", unimplementedFunc),
|
||||
/* 261 */ SyscallDesc("fdatasync", unimplementedFunc),
|
||||
/* 262 */ SyscallDesc("oflock", unimplementedFunc),
|
||||
/* 263 */ SyscallDesc("F64_readv", unimplementedFunc),
|
||||
/* 264 */ SyscallDesc("F64_writev", unimplementedFunc),
|
||||
/* 265 */ SyscallDesc("cdslxlate", unimplementedFunc),
|
||||
/* 266 */ SyscallDesc("sendfile", unimplementedFunc),
|
||||
};
|
||||
|
||||
|
||||
|
||||
SyscallDesc AlphaTru64Process::machSyscallDescs[] = {
|
||||
/* 0 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 1 */ SyscallDesc("m5_mutex_lock", AlphaTru64::m5_mutex_lockFunc),
|
||||
/* 2 */ SyscallDesc("m5_mutex_trylock", AlphaTru64::m5_mutex_trylockFunc),
|
||||
/* 3 */ SyscallDesc("m5_mutex_unlock", AlphaTru64::m5_mutex_unlockFunc),
|
||||
/* 4 */ SyscallDesc("m5_cond_signal", AlphaTru64::m5_cond_signalFunc),
|
||||
/* 5 */ SyscallDesc("m5_cond_broadcast", AlphaTru64::m5_cond_broadcastFunc),
|
||||
/* 6 */ SyscallDesc("m5_cond_wait", AlphaTru64::m5_cond_waitFunc),
|
||||
/* 7 */ SyscallDesc("m5_thread_exit", AlphaTru64::m5_thread_exitFunc),
|
||||
/* 8 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 9 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 10 */ SyscallDesc("task_self", unimplementedFunc),
|
||||
/* 11 */ SyscallDesc("thread_reply", unimplementedFunc),
|
||||
/* 12 */ SyscallDesc("task_notify", unimplementedFunc),
|
||||
/* 13 */ SyscallDesc("thread_self", unimplementedFunc),
|
||||
/* 14 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 15 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 16 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 17 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 18 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 19 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 20 */ SyscallDesc("msg_send_trap", unimplementedFunc),
|
||||
/* 21 */ SyscallDesc("msg_receive_trap", unimplementedFunc),
|
||||
/* 22 */ SyscallDesc("msg_rpc_trap", unimplementedFunc),
|
||||
/* 23 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 24 */ SyscallDesc("nxm_block", AlphaTru64::nxm_blockFunc),
|
||||
/* 25 */ SyscallDesc("nxm_unblock", AlphaTru64::nxm_unblockFunc),
|
||||
/* 26 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 27 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 28 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 29 */ SyscallDesc("nxm_thread_destroy", unimplementedFunc),
|
||||
/* 30 */ SyscallDesc("lw_wire", unimplementedFunc),
|
||||
/* 31 */ SyscallDesc("lw_unwire", unimplementedFunc),
|
||||
/* 32 */ SyscallDesc("nxm_thread_create", AlphaTru64::nxm_thread_createFunc),
|
||||
/* 33 */ SyscallDesc("nxm_task_init", AlphaTru64::nxm_task_initFunc),
|
||||
/* 34 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 35 */ SyscallDesc("nxm_idle", AlphaTru64::nxm_idleFunc),
|
||||
/* 36 */ SyscallDesc("nxm_wakeup_idle", unimplementedFunc),
|
||||
/* 37 */ SyscallDesc("nxm_set_pthid", unimplementedFunc),
|
||||
/* 38 */ SyscallDesc("nxm_thread_kill", unimplementedFunc),
|
||||
/* 39 */ SyscallDesc("nxm_thread_block", AlphaTru64::nxm_thread_blockFunc),
|
||||
/* 40 */ SyscallDesc("nxm_thread_wakeup", unimplementedFunc),
|
||||
/* 41 */ SyscallDesc("init_process", unimplementedFunc),
|
||||
/* 42 */ SyscallDesc("nxm_get_binding", unimplementedFunc),
|
||||
/* 43 */ SyscallDesc("map_fd", unimplementedFunc),
|
||||
/* 44 */ SyscallDesc("nxm_resched", unimplementedFunc),
|
||||
/* 45 */ SyscallDesc("nxm_set_cancel", unimplementedFunc),
|
||||
/* 46 */ SyscallDesc("nxm_set_binding", unimplementedFunc),
|
||||
/* 47 */ SyscallDesc("stack_create", AlphaTru64::stack_createFunc),
|
||||
/* 48 */ SyscallDesc("nxm_get_state", unimplementedFunc),
|
||||
/* 49 */ SyscallDesc("nxm_thread_suspend", unimplementedFunc),
|
||||
/* 50 */ SyscallDesc("nxm_thread_resume", unimplementedFunc),
|
||||
/* 51 */ SyscallDesc("nxm_signal_check", unimplementedFunc),
|
||||
/* 52 */ SyscallDesc("htg_unix_syscall", unimplementedFunc),
|
||||
/* 53 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 54 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 55 */ SyscallDesc("host_self", unimplementedFunc),
|
||||
/* 56 */ SyscallDesc("host_priv_self", unimplementedFunc),
|
||||
/* 57 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 58 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 59 */ SyscallDesc("swtch_pri", AlphaTru64::swtch_priFunc),
|
||||
/* 60 */ SyscallDesc("swtch", unimplementedFunc),
|
||||
/* 61 */ SyscallDesc("thread_switch", unimplementedFunc),
|
||||
/* 62 */ SyscallDesc("semop_fast", unimplementedFunc),
|
||||
/* 63 */ SyscallDesc("nxm_pshared_init", unimplementedFunc),
|
||||
/* 64 */ SyscallDesc("nxm_pshared_block", unimplementedFunc),
|
||||
/* 65 */ SyscallDesc("nxm_pshared_unblock", unimplementedFunc),
|
||||
/* 66 */ SyscallDesc("nxm_pshared_destroy", unimplementedFunc),
|
||||
/* 67 */ SyscallDesc("nxm_swtch_pri", AlphaTru64::swtch_priFunc),
|
||||
/* 68 */ SyscallDesc("lw_syscall", unimplementedFunc),
|
||||
/* 69 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 70 */ SyscallDesc("mach_sctimes_0", unimplementedFunc),
|
||||
/* 71 */ SyscallDesc("mach_sctimes_1", unimplementedFunc),
|
||||
/* 72 */ SyscallDesc("mach_sctimes_2", unimplementedFunc),
|
||||
/* 73 */ SyscallDesc("mach_sctimes_3", unimplementedFunc),
|
||||
/* 74 */ SyscallDesc("mach_sctimes_4", unimplementedFunc),
|
||||
/* 75 */ SyscallDesc("mach_sctimes_5", unimplementedFunc),
|
||||
/* 76 */ SyscallDesc("mach_sctimes_6", unimplementedFunc),
|
||||
/* 77 */ SyscallDesc("mach_sctimes_7", unimplementedFunc),
|
||||
/* 78 */ SyscallDesc("mach_sctimes_8", unimplementedFunc),
|
||||
/* 79 */ SyscallDesc("mach_sctimes_9", unimplementedFunc),
|
||||
/* 80 */ SyscallDesc("mach_sctimes_10", unimplementedFunc),
|
||||
/* 81 */ SyscallDesc("mach_sctimes_11", unimplementedFunc),
|
||||
/* 82 */ SyscallDesc("mach_sctimes_port_alloc_dealloc", unimplementedFunc)
|
||||
};
|
||||
|
||||
SyscallDesc*
|
||||
AlphaTru64Process::getDesc(int callnum)
|
||||
{
|
||||
if (callnum < -Num_Mach_Syscall_Descs || callnum > Num_Syscall_Descs)
|
||||
return NULL;
|
||||
|
||||
if (callnum < 0)
|
||||
return &machSyscallDescs[-callnum];
|
||||
else
|
||||
return &syscallDescs[callnum];
|
||||
}
|
||||
|
||||
|
||||
AlphaTru64Process::AlphaTru64Process(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)
|
||||
: AlphaLiveProcess(name, objFile, system, stdin_fd, stdout_fd,
|
||||
stderr_fd, argv, envp),
|
||||
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)),
|
||||
Num_Mach_Syscall_Descs(sizeof(machSyscallDescs) / sizeof(SyscallDesc))
|
||||
{
|
||||
}
|
||||
61
src/arch/alpha/tru64/process.hh
Normal file
61
src/arch/alpha/tru64/process.hh
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ALPHA_TRU64_PROCESS_HH__
|
||||
#define __ALPHA_TRU64_PROCESS_HH__
|
||||
|
||||
#include "arch/alpha/process.hh"
|
||||
|
||||
namespace AlphaISA {
|
||||
/// A process with emulated Alpha Tru64 syscalls.
|
||||
class AlphaTru64Process : public AlphaLiveProcess
|
||||
{
|
||||
public:
|
||||
/// Constructor.
|
||||
AlphaTru64Process(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);
|
||||
|
||||
/// Array of syscall descriptors, indexed by call number.
|
||||
static SyscallDesc syscallDescs[];
|
||||
|
||||
/// Array of mach syscall descriptors, indexed by call number.
|
||||
static SyscallDesc machSyscallDescs[];
|
||||
|
||||
const int Num_Syscall_Descs;
|
||||
const int Num_Mach_Syscall_Descs;
|
||||
|
||||
virtual SyscallDesc* getDesc(int callnum);
|
||||
};
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ALPHA_TRU64_PROCESS_HH__
|
||||
151
src/arch/alpha/tru64/system.cc
Normal file
151
src/arch/alpha/tru64/system.cc
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arch/alpha/tru64/system.hh"
|
||||
#include "arch/isa_traits.hh"
|
||||
#include "arch/vtophys.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "kern/tru64/tru64_events.hh"
|
||||
#include "kern/system_events.hh"
|
||||
#include "mem/physical.hh"
|
||||
#include "mem/port.hh"
|
||||
#include "sim/builder.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Tru64AlphaSystem::Tru64AlphaSystem(Tru64AlphaSystem::Params *p)
|
||||
: AlphaSystem(p)
|
||||
{
|
||||
Addr addr = 0;
|
||||
if (kernelSymtab->findAddress("enable_async_printf", addr)) {
|
||||
virtPort.write(addr, (uint32_t)0);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
|
||||
if (!kernelPanicEvent)
|
||||
panic("could not find kernel symbol \'panic\'");
|
||||
#endif
|
||||
|
||||
badaddrEvent = addKernelFuncEvent<BadAddrEvent>("badaddr");
|
||||
if (!badaddrEvent)
|
||||
panic("could not find kernel symbol \'badaddr\'");
|
||||
|
||||
skipPowerStateEvent =
|
||||
addKernelFuncEvent<SkipFuncEvent>("tl_v48_capture_power_state");
|
||||
skipScavengeBootEvent =
|
||||
addKernelFuncEvent<SkipFuncEvent>("pmap_scavenge_boot");
|
||||
|
||||
#if TRACING_ON
|
||||
printfEvent = addKernelFuncEvent<PrintfEvent>("printf");
|
||||
debugPrintfEvent = addKernelFuncEvent<DebugPrintfEvent>("m5printf");
|
||||
debugPrintfrEvent = addKernelFuncEvent<DebugPrintfrEvent>("m5printfr");
|
||||
dumpMbufEvent = addKernelFuncEvent<DumpMbufEvent>("m5_dump_mbuf");
|
||||
#endif
|
||||
}
|
||||
|
||||
Tru64AlphaSystem::~Tru64AlphaSystem()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
delete kernelPanicEvent;
|
||||
#endif
|
||||
delete badaddrEvent;
|
||||
delete skipPowerStateEvent;
|
||||
delete skipScavengeBootEvent;
|
||||
#if TRACING_ON
|
||||
delete printfEvent;
|
||||
delete debugPrintfEvent;
|
||||
delete debugPrintfrEvent;
|
||||
delete dumpMbufEvent;
|
||||
#endif
|
||||
}
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
|
||||
|
||||
Param<Tick> boot_cpu_frequency;
|
||||
SimObjectParam<PhysicalMemory *> physmem;
|
||||
|
||||
Param<string> kernel;
|
||||
Param<string> console;
|
||||
Param<string> pal;
|
||||
|
||||
Param<string> boot_osflags;
|
||||
Param<string> readfile;
|
||||
Param<unsigned int> init_param;
|
||||
|
||||
Param<uint64_t> system_type;
|
||||
Param<uint64_t> system_rev;
|
||||
|
||||
Param<bool> bin;
|
||||
VectorParam<string> binned_fns;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
|
||||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
|
||||
|
||||
INIT_PARAM(boot_cpu_frequency, "frequency of the boot cpu"),
|
||||
INIT_PARAM(physmem, "phsyical memory"),
|
||||
INIT_PARAM(kernel, "file that contains the kernel code"),
|
||||
INIT_PARAM(console, "file that contains the console code"),
|
||||
INIT_PARAM(pal, "file that contains palcode"),
|
||||
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
|
||||
"a"),
|
||||
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
|
||||
INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
|
||||
INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 12),
|
||||
INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 2<<1),
|
||||
INIT_PARAM_DFLT(bin, "is this system to be binned", false),
|
||||
INIT_PARAM(binned_fns, "functions to be broken down and binned")
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
|
||||
|
||||
CREATE_SIM_OBJECT(Tru64AlphaSystem)
|
||||
{
|
||||
AlphaSystem::Params *p = new AlphaSystem::Params;
|
||||
p->name = getInstanceName();
|
||||
p->boot_cpu_frequency = boot_cpu_frequency;
|
||||
p->physmem = physmem;
|
||||
p->kernel_path = kernel;
|
||||
p->console_path = console;
|
||||
p->palcode = pal;
|
||||
p->boot_osflags = boot_osflags;
|
||||
p->init_param = init_param;
|
||||
p->readfile = readfile;
|
||||
p->system_type = system_type;
|
||||
p->system_rev = system_rev;
|
||||
p->bin = bin;
|
||||
p->binned_fns = binned_fns;
|
||||
p->bin_int = false;
|
||||
|
||||
return new Tru64AlphaSystem(p);
|
||||
}
|
||||
|
||||
REGISTER_SIM_OBJECT("Tru64AlphaSystem", Tru64AlphaSystem)
|
||||
71
src/arch/alpha/tru64/system.hh
Normal file
71
src/arch/alpha/tru64/system.hh
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ALPHA_TRU64_SYSTEM_HH__
|
||||
#define __ARCH_ALPHA_TRU64_SYSTEM_HH__
|
||||
|
||||
#include "arch/alpha/system.hh"
|
||||
#include "arch/isa_traits.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
class ExecContext;
|
||||
|
||||
class BreakPCEvent;
|
||||
class BadAddrEvent;
|
||||
class SkipFuncEvent;
|
||||
class PrintfEvent;
|
||||
class DebugPrintfEvent;
|
||||
class DebugPrintfrEvent;
|
||||
class DumpMbufEvent;
|
||||
class AlphaArguments;
|
||||
|
||||
class Tru64AlphaSystem : public AlphaSystem
|
||||
{
|
||||
private:
|
||||
#ifdef DEBUG
|
||||
/** Event to halt the simulator if the kernel calls panic() */
|
||||
BreakPCEvent *kernelPanicEvent;
|
||||
#endif
|
||||
|
||||
BadAddrEvent *badaddrEvent;
|
||||
SkipFuncEvent *skipPowerStateEvent;
|
||||
SkipFuncEvent *skipScavengeBootEvent;
|
||||
PrintfEvent *printfEvent;
|
||||
DebugPrintfEvent *debugPrintfEvent;
|
||||
DebugPrintfrEvent *debugPrintfrEvent;
|
||||
DumpMbufEvent *dumpMbufEvent;
|
||||
|
||||
public:
|
||||
Tru64AlphaSystem(Params *p);
|
||||
~Tru64AlphaSystem();
|
||||
|
||||
static void Printf(AlphaArguments args);
|
||||
static void DumpMbuf(AlphaArguments args);
|
||||
};
|
||||
|
||||
#endif // __ARCH_ALPHA_TRU64_SYSTEM_HH__
|
||||
70
src/arch/alpha/tru64/tru64.cc
Normal file
70
src/arch/alpha/tru64/tru64.cc
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arch/alpha/tru64/tru64.hh"
|
||||
|
||||
// open(2) flags translation table
|
||||
OpenFlagTransTable AlphaTru64::openFlagTable[] = {
|
||||
#ifdef _MSC_VER
|
||||
{ AlphaTru64::TGT_O_RDONLY, _O_RDONLY },
|
||||
{ AlphaTru64::TGT_O_WRONLY, _O_WRONLY },
|
||||
{ AlphaTru64::TGT_O_RDWR, _O_RDWR },
|
||||
{ AlphaTru64::TGT_O_APPEND, _O_APPEND },
|
||||
{ AlphaTru64::TGT_O_CREAT, _O_CREAT },
|
||||
{ AlphaTru64::TGT_O_TRUNC, _O_TRUNC },
|
||||
{ AlphaTru64::TGT_O_EXCL, _O_EXCL },
|
||||
#ifdef _O_NONBLOCK
|
||||
{ AlphaTru64::TGT_O_NONBLOCK, _O_NONBLOCK },
|
||||
#endif
|
||||
#ifdef _O_NOCTTY
|
||||
{ AlphaTru64::TGT_O_NOCTTY, _O_NOCTTY },
|
||||
#endif
|
||||
#ifdef _O_SYNC
|
||||
{ AlphaTru64::TGT_O_SYNC, _O_SYNC },
|
||||
#endif
|
||||
#else /* !_MSC_VER */
|
||||
{ AlphaTru64::TGT_O_RDONLY, O_RDONLY },
|
||||
{ AlphaTru64::TGT_O_WRONLY, O_WRONLY },
|
||||
{ AlphaTru64::TGT_O_RDWR, O_RDWR },
|
||||
{ AlphaTru64::TGT_O_APPEND, O_APPEND },
|
||||
{ AlphaTru64::TGT_O_CREAT, O_CREAT },
|
||||
{ AlphaTru64::TGT_O_TRUNC, O_TRUNC },
|
||||
{ AlphaTru64::TGT_O_EXCL, O_EXCL },
|
||||
{ AlphaTru64::TGT_O_NONBLOCK, O_NONBLOCK },
|
||||
{ AlphaTru64::TGT_O_NOCTTY, O_NOCTTY },
|
||||
#ifdef O_SYNC
|
||||
{ AlphaTru64::TGT_O_SYNC, O_SYNC },
|
||||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
};
|
||||
|
||||
const int AlphaTru64::NUM_OPEN_FLAGS =
|
||||
(sizeof(AlphaTru64::openFlagTable)/sizeof(AlphaTru64::openFlagTable[0]));
|
||||
|
||||
|
||||
|
||||
127
src/arch/alpha/tru64/tru64.hh
Normal file
127
src/arch/alpha/tru64/tru64.hh
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ALPHA_ALPHA_TRU64_HH
|
||||
#define __ALPHA_ALPHA_TRU64_HH
|
||||
|
||||
#include "kern/tru64/tru64.hh"
|
||||
|
||||
class AlphaTru64 : public Tru64
|
||||
{
|
||||
|
||||
public:
|
||||
/// This table maps the target open() flags to the corresponding
|
||||
/// host open() flags.
|
||||
static OpenFlagTransTable openFlagTable[];
|
||||
|
||||
/// Number of entries in openFlagTable[].
|
||||
static const int NUM_OPEN_FLAGS;
|
||||
|
||||
//@{
|
||||
/// open(2) flag values.
|
||||
static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY
|
||||
static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY
|
||||
static const int TGT_O_RDWR = 00000002; //!< O_RDWR
|
||||
static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK
|
||||
static const int TGT_O_APPEND = 00000010; //!< O_APPEND
|
||||
static const int TGT_O_CREAT = 00001000; //!< O_CREAT
|
||||
static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC
|
||||
static const int TGT_O_EXCL = 00004000; //!< O_EXCL
|
||||
static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY
|
||||
static const int TGT_O_SYNC = 00040000; //!< O_SYNC
|
||||
static const int TGT_O_DRD = 00100000; //!< O_DRD
|
||||
static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO
|
||||
static const int TGT_O_CACHE = 00400000; //!< O_CACHE
|
||||
static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC
|
||||
static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC
|
||||
//@}
|
||||
|
||||
/// For mmap().
|
||||
static const unsigned TGT_MAP_ANONYMOUS = 0x10;
|
||||
|
||||
//@{
|
||||
/// For getsysinfo().
|
||||
static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
|
||||
static const unsigned GSI_CPU_INFO = 59; //!< CPU information
|
||||
static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
|
||||
static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine
|
||||
static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
|
||||
static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB
|
||||
static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/// For getrusage().
|
||||
static const int TGT_RUSAGE_THREAD = 1;
|
||||
static const int TGT_RUSAGE_SELF = 0;
|
||||
static const int TGT_RUSAGE_CHILDREN = -1;
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/// For setsysinfo().
|
||||
static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control()
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/// 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;
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/// For table().
|
||||
static const int TBL_SYSINFO = 12;
|
||||
//@}
|
||||
|
||||
/// Resource enumeration for getrlimit().
|
||||
enum rlimit_resources {
|
||||
TGT_RLIMIT_CPU = 0,
|
||||
TGT_RLIMIT_FSIZE = 1,
|
||||
TGT_RLIMIT_DATA = 2,
|
||||
TGT_RLIMIT_STACK = 3,
|
||||
TGT_RLIMIT_CORE = 4,
|
||||
TGT_RLIMIT_RSS = 5,
|
||||
TGT_RLIMIT_NOFILE = 6,
|
||||
TGT_RLIMIT_AS = 7,
|
||||
TGT_RLIMIT_VMEM = 7,
|
||||
TGT_RLIMIT_NPROC = 8,
|
||||
TGT_RLIMIT_MEMLOCK = 9,
|
||||
TGT_RLIMIT_LOCKS = 10
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
64
src/arch/alpha/types.hh
Normal file
64
src/arch/alpha/types.hh
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ALPHA_TYPES_HH__
|
||||
#define __ARCH_ALPHA_TYPES_HH__
|
||||
|
||||
#include "sim/host.hh"
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
|
||||
typedef uint32_t MachInst;
|
||||
typedef uint64_t ExtMachInst;
|
||||
typedef uint8_t RegIndex;
|
||||
|
||||
typedef uint64_t IntReg;
|
||||
|
||||
// floating point register file entry type
|
||||
typedef double FloatReg;
|
||||
typedef uint64_t FloatRegBits;
|
||||
|
||||
// control register file contents
|
||||
typedef uint64_t MiscReg;
|
||||
|
||||
typedef union {
|
||||
IntReg intreg;
|
||||
FloatReg fpreg;
|
||||
MiscReg ctrlreg;
|
||||
} AnyReg;
|
||||
|
||||
enum annotes {
|
||||
ANNOTE_NONE = 0,
|
||||
// An impossible number for instruction annotations
|
||||
ITOUCH_ANNOTE = 0xffffffff,
|
||||
};
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif
|
||||
156
src/arch/alpha/utility.hh
Normal file
156
src/arch/alpha/utility.hh
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ALPHA_UTILITY_HH__
|
||||
#define __ARCH_ALPHA_UTILITY_HH__
|
||||
|
||||
#include "config/full_system.hh"
|
||||
#include "arch/alpha/types.hh"
|
||||
#include "arch/alpha/constants.hh"
|
||||
#include "arch/alpha/regfile.hh"
|
||||
#include "base/misc.hh"
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
|
||||
static inline ExtMachInst
|
||||
makeExtMI(MachInst inst, const uint64_t &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
|
||||
}
|
||||
|
||||
inline bool isCallerSaveIntegerRegister(unsigned int reg) {
|
||||
panic("register classification not implemented");
|
||||
return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27);
|
||||
}
|
||||
|
||||
inline bool isCalleeSaveIntegerRegister(unsigned int reg) {
|
||||
panic("register classification not implemented");
|
||||
return (reg >= 9 && reg <= 15);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
inline Addr alignAddress(const Addr &addr,
|
||||
unsigned int nbytes) {
|
||||
return (addr & ~(nbytes - 1));
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
inline MachInst makeRegisterCopy(int dest, int src) {
|
||||
panic("makeRegisterCopy not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Machine operations
|
||||
|
||||
void saveMachineReg(AnyReg &savereg, const RegFile ®_file,
|
||||
int regnum);
|
||||
|
||||
void restoreMachineReg(RegFile ®s, const AnyReg ®,
|
||||
int regnum);
|
||||
|
||||
/**
|
||||
* Function to insure ISA semantics about 0 registers.
|
||||
* @param xc The execution context.
|
||||
*/
|
||||
template <class XC>
|
||||
void zeroRegisters(XC *xc);
|
||||
|
||||
#if FULL_SYSTEM
|
||||
// Alpha IPR register accessors
|
||||
inline bool PcPAL(Addr addr) { return addr & 0x1; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Translation stuff
|
||||
//
|
||||
|
||||
inline Addr PteAddr(Addr a) { return (a & PteMask) << PteShift; }
|
||||
|
||||
// User Virtual
|
||||
inline bool IsUSeg(Addr a) { return USegBase <= a && a <= USegEnd; }
|
||||
|
||||
// Kernel Direct Mapped
|
||||
inline bool IsK0Seg(Addr a) { return K0SegBase <= a && a <= K0SegEnd; }
|
||||
inline Addr K0Seg2Phys(Addr addr) { return addr & ~K0SegBase; }
|
||||
|
||||
// Kernel Virtual
|
||||
inline bool IsK1Seg(Addr a) { return K1SegBase <= a && a <= K1SegEnd; }
|
||||
|
||||
inline Addr
|
||||
TruncPage(Addr addr)
|
||||
{ return addr & ~(PageBytes - 1); }
|
||||
|
||||
inline Addr
|
||||
RoundPage(Addr addr)
|
||||
{ return (addr + PageBytes - 1) & ~(PageBytes - 1); }
|
||||
|
||||
void initCPU(ExecContext *xc, int cpuId);
|
||||
void initIPRs(ExecContext *xc, int cpuId);
|
||||
|
||||
/**
|
||||
* Function to check for and process any interrupts.
|
||||
* @param xc The execution context.
|
||||
*/
|
||||
template <class XC>
|
||||
void processInterrupts(XC *xc);
|
||||
#endif
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif
|
||||
162
src/arch/alpha/vtophys.cc
Normal file
162
src/arch/alpha/vtophys.cc
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "arch/alpha/ev5.hh"
|
||||
#include "arch/alpha/vtophys.hh"
|
||||
#include "base/chunk_generator.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "mem/vport.hh"
|
||||
|
||||
using namespace std;
|
||||
using namespace AlphaISA;
|
||||
|
||||
AlphaISA::PageTableEntry
|
||||
AlphaISA::kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr)
|
||||
{
|
||||
Addr level1_pte = ptbr + vaddr.level1();
|
||||
AlphaISA::PageTableEntry level1 = mem->read<uint64_t>(level1_pte);
|
||||
if (!level1.valid()) {
|
||||
DPRINTF(VtoPhys, "level 1 PTE not valid, va = %#\n", vaddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Addr level2_pte = level1.paddr() + vaddr.level2();
|
||||
AlphaISA::PageTableEntry level2 = mem->read<uint64_t>(level2_pte);
|
||||
if (!level2.valid()) {
|
||||
DPRINTF(VtoPhys, "level 2 PTE not valid, va = %#x\n", vaddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Addr level3_pte = level2.paddr() + vaddr.level3();
|
||||
AlphaISA::PageTableEntry level3 = mem->read<uint64_t>(level3_pte);
|
||||
if (!level3.valid()) {
|
||||
DPRINTF(VtoPhys, "level 3 PTE not valid, va = %#x\n", vaddr);
|
||||
return 0;
|
||||
}
|
||||
return level3;
|
||||
}
|
||||
|
||||
Addr
|
||||
AlphaISA::vtophys(Addr vaddr)
|
||||
{
|
||||
Addr paddr = 0;
|
||||
if (AlphaISA::IsUSeg(vaddr))
|
||||
DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr);
|
||||
else if (AlphaISA::IsK0Seg(vaddr))
|
||||
paddr = AlphaISA::K0Seg2Phys(vaddr);
|
||||
else
|
||||
panic("vtophys: ptbr is not set on virtual lookup");
|
||||
|
||||
DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr);
|
||||
|
||||
return paddr;
|
||||
}
|
||||
|
||||
Addr
|
||||
AlphaISA::vtophys(ExecContext *xc, Addr addr)
|
||||
{
|
||||
AlphaISA::VAddr vaddr = addr;
|
||||
Addr ptbr = xc->readMiscReg(AlphaISA::IPR_PALtemp20);
|
||||
Addr paddr = 0;
|
||||
//@todo Andrew couldn't remember why he commented some of this code
|
||||
//so I put it back in. Perhaps something to do with gdb debugging?
|
||||
if (AlphaISA::PcPAL(vaddr) && (vaddr < EV5::PalMax)) {
|
||||
paddr = vaddr & ~ULL(1);
|
||||
} else {
|
||||
if (AlphaISA::IsK0Seg(vaddr)) {
|
||||
paddr = AlphaISA::K0Seg2Phys(vaddr);
|
||||
} else if (!ptbr) {
|
||||
paddr = vaddr;
|
||||
} else {
|
||||
AlphaISA::PageTableEntry pte =
|
||||
kernel_pte_lookup(xc->getPhysPort(), ptbr, vaddr);
|
||||
if (pte.valid())
|
||||
paddr = pte.paddr() | vaddr.offset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr);
|
||||
|
||||
return paddr;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlphaISA::CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen)
|
||||
{
|
||||
uint8_t *dst = (uint8_t *)dest;
|
||||
VirtualPort *vp = xc->getVirtPort(xc);
|
||||
|
||||
vp->readBlob(src, dst, cplen);
|
||||
|
||||
xc->delVirtPort(vp);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
AlphaISA::CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen)
|
||||
{
|
||||
uint8_t *src = (uint8_t *)source;
|
||||
VirtualPort *vp = xc->getVirtPort(xc);
|
||||
|
||||
vp->writeBlob(dest, src, cplen);
|
||||
|
||||
xc->delVirtPort(vp);
|
||||
}
|
||||
|
||||
void
|
||||
AlphaISA::CopyStringOut(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen)
|
||||
{
|
||||
int len = 0;
|
||||
VirtualPort *vp = xc->getVirtPort(xc);
|
||||
|
||||
do {
|
||||
vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
|
||||
len++;
|
||||
} while (len < maxlen && dst[len] != 0 );
|
||||
|
||||
xc->delVirtPort(vp);
|
||||
dst[len] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
AlphaISA::CopyStringIn(ExecContext *xc, char *src, Addr vaddr)
|
||||
{
|
||||
VirtualPort *vp = xc->getVirtPort(xc);
|
||||
for (ChunkGenerator gen(vaddr, strlen(src), AlphaISA::PageBytes); !gen.done();
|
||||
gen.next())
|
||||
{
|
||||
vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size());
|
||||
src += gen.size();
|
||||
}
|
||||
xc->delVirtPort(vp);
|
||||
}
|
||||
52
src/arch/alpha/vtophys.hh
Normal file
52
src/arch/alpha/vtophys.hh
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ALPHA_VTOPHYS_H__
|
||||
#define __ARCH_ALPHA_VTOPHYS_H__
|
||||
|
||||
#include "arch/alpha/isa_traits.hh"
|
||||
|
||||
class ExecContext;
|
||||
class FunctionalPort;
|
||||
|
||||
namespace AlphaISA {
|
||||
|
||||
PageTableEntry
|
||||
kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr);
|
||||
|
||||
Addr vtophys(Addr vaddr);
|
||||
Addr vtophys(ExecContext *xc, Addr vaddr);
|
||||
|
||||
void CopyOut(ExecContext *xc, void *dst, Addr src, size_t len);
|
||||
void CopyIn(ExecContext *xc, Addr dst, void *src, size_t len);
|
||||
void CopyStringOut(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen);
|
||||
void CopyStringIn(ExecContext *xc, char *src, Addr vaddr);
|
||||
|
||||
};
|
||||
#endif // __ARCH_ALPHA_VTOPHYS_H__
|
||||
|
||||
1810
src/arch/isa_parser.py
Executable file
1810
src/arch/isa_parser.py
Executable file
File diff suppressed because it is too large
Load Diff
62
src/arch/isa_specific.hh
Normal file
62
src/arch/isa_specific.hh
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ISA_SPECIFIC_HH__
|
||||
#define __ARCH_ISA_SPECIFIC_HH__
|
||||
|
||||
//This file provides a mechanism for other source code to bring in
|
||||
//files from the ISA being compiled with
|
||||
|
||||
//These are constants so you can selective 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"
|
||||
|
||||
//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
|
||||
|
||||
//These tell the preprocessor where to find the files of a particular
|
||||
//ISA, and set the "TheISA" macro for use elsewhere.
|
||||
#if THE_ISA == ALPHA_ISA
|
||||
#define TheISA AlphaISA
|
||||
#elif THE_ISA == SPARC_ISA
|
||||
#define TheISA SparcISA
|
||||
#elif THE_ISA == MIPS_ISA
|
||||
#define TheISA MipsISA
|
||||
#else
|
||||
#error "THE_ISA not set"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
83
src/arch/mips/SConscript
Normal file
83
src/arch/mips/SConscript
Normal file
@@ -0,0 +1,83 @@
|
||||
# -*- 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.
|
||||
|
||||
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
|
||||
''')
|
||||
|
||||
# Full-system sources
|
||||
full_system_sources = Split('''
|
||||
memory.cc
|
||||
arguments.cc
|
||||
mips34k.cc
|
||||
osfpal.cc
|
||||
stacktrace.cc
|
||||
vtophys.cc
|
||||
''')
|
||||
|
||||
# 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')
|
||||
131
src/arch/mips/faults.cc
Normal file
131
src/arch/mips/faults.cc
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arch/mips/faults.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "base/trace.hh"
|
||||
|
||||
namespace MipsISA
|
||||
{
|
||||
|
||||
FaultName MachineCheckFault::_name = "Machine Check";
|
||||
FaultVect MachineCheckFault::_vect = 0x0401;
|
||||
FaultStat MachineCheckFault::_count;
|
||||
|
||||
FaultName AlignmentFault::_name = "Alignment";
|
||||
FaultVect AlignmentFault::_vect = 0x0301;
|
||||
FaultStat AlignmentFault::_count;
|
||||
|
||||
FaultName ResetFault::_name = "reset";
|
||||
FaultVect ResetFault::_vect = 0x0001;
|
||||
FaultStat ResetFault::_count;
|
||||
|
||||
FaultName ArithmeticFault::_name = "arith";
|
||||
FaultVect ArithmeticFault::_vect = 0x0501;
|
||||
FaultStat ArithmeticFault::_count;
|
||||
|
||||
FaultName InterruptFault::_name = "interrupt";
|
||||
FaultVect InterruptFault::_vect = 0x0101;
|
||||
FaultStat InterruptFault::_count;
|
||||
|
||||
FaultName NDtbMissFault::_name = "dtb_miss_single";
|
||||
FaultVect NDtbMissFault::_vect = 0x0201;
|
||||
FaultStat NDtbMissFault::_count;
|
||||
|
||||
FaultName PDtbMissFault::_name = "dtb_miss_double";
|
||||
FaultVect PDtbMissFault::_vect = 0x0281;
|
||||
FaultStat PDtbMissFault::_count;
|
||||
|
||||
FaultName DtbPageFault::_name = "dfault";
|
||||
FaultVect DtbPageFault::_vect = 0x0381;
|
||||
FaultStat DtbPageFault::_count;
|
||||
|
||||
FaultName DtbAcvFault::_name = "dfault";
|
||||
FaultVect DtbAcvFault::_vect = 0x0381;
|
||||
FaultStat DtbAcvFault::_count;
|
||||
|
||||
FaultName ItbMissFault::_name = "itbmiss";
|
||||
FaultVect ItbMissFault::_vect = 0x0181;
|
||||
FaultStat ItbMissFault::_count;
|
||||
|
||||
FaultName ItbPageFault::_name = "itbmiss";
|
||||
FaultVect ItbPageFault::_vect = 0x0181;
|
||||
FaultStat ItbPageFault::_count;
|
||||
|
||||
FaultName ItbAcvFault::_name = "iaccvio";
|
||||
FaultVect ItbAcvFault::_vect = 0x0081;
|
||||
FaultStat ItbAcvFault::_count;
|
||||
|
||||
FaultName UnimplementedOpcodeFault::_name = "opdec";
|
||||
FaultVect UnimplementedOpcodeFault::_vect = 0x0481;
|
||||
FaultStat UnimplementedOpcodeFault::_count;
|
||||
|
||||
FaultName FloatEnableFault::_name = "fen";
|
||||
FaultVect FloatEnableFault::_vect = 0x0581;
|
||||
FaultStat FloatEnableFault::_count;
|
||||
|
||||
FaultName PalFault::_name = "pal";
|
||||
FaultVect PalFault::_vect = 0x2001;
|
||||
FaultStat PalFault::_count;
|
||||
|
||||
FaultName IntegerOverflowFault::_name = "intover";
|
||||
FaultVect IntegerOverflowFault::_vect = 0x0501;
|
||||
FaultStat IntegerOverflowFault::_count;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
|
||||
void MipsFault::invoke(ExecContext * xc)
|
||||
{
|
||||
FaultBase::invoke(xc);
|
||||
countStat()++;
|
||||
|
||||
// exception restart address
|
||||
if (setRestartAddress() || !xc->inPalMode())
|
||||
xc->setMiscReg(MipsISA::IPR_EXC_ADDR, xc->readPC());
|
||||
|
||||
if (skipFaultingInstruction()) {
|
||||
// traps... skip faulting instruction.
|
||||
xc->setMiscReg(MipsISA::IPR_EXC_ADDR,
|
||||
xc->readMiscReg(MipsISA::IPR_EXC_ADDR) + 4);
|
||||
}
|
||||
|
||||
xc->setPC(xc->readMiscReg(MipsISA::IPR_PAL_BASE) + vect());
|
||||
xc->setNextPC(xc->readPC() + sizeof(MachInst));
|
||||
}
|
||||
|
||||
void ArithmeticFault::invoke(ExecContext * xc)
|
||||
{
|
||||
FaultBase::invoke(xc);
|
||||
panic("Arithmetic traps are unimplemented!");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace MipsISA
|
||||
|
||||
269
src/arch/mips/faults.hh
Normal file
269
src/arch/mips/faults.hh
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __MIPS_FAULTS_HH__
|
||||
#define __MIPS_FAULTS_HH__
|
||||
|
||||
#include "sim/faults.hh"
|
||||
|
||||
// The design of the "name" and "vect" functions is in sim/faults.hh
|
||||
|
||||
namespace MipsISA
|
||||
{
|
||||
|
||||
typedef const Addr FaultVect;
|
||||
|
||||
class MipsFault : public FaultBase
|
||||
{
|
||||
protected:
|
||||
virtual bool skipFaultingInstruction() {return false;}
|
||||
virtual bool setRestartAddress() {return true;}
|
||||
public:
|
||||
#if FULL_SYSTEM
|
||||
void invoke(ExecContext * xc);
|
||||
#endif
|
||||
virtual FaultVect vect() = 0;
|
||||
virtual FaultStat & countStat() = 0;
|
||||
};
|
||||
|
||||
class MachineCheckFault : public MipsFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
bool isMachineCheckFault() {return true;}
|
||||
};
|
||||
|
||||
class AlignmentFault : public MipsFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
bool isAlignmentFault() {return true;}
|
||||
};
|
||||
|
||||
static inline Fault genMachineCheckFault()
|
||||
{
|
||||
return new MachineCheckFault;
|
||||
}
|
||||
|
||||
static inline Fault genAlignmentFault()
|
||||
{
|
||||
return new AlignmentFault;
|
||||
}
|
||||
|
||||
class ResetFault : public MipsFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class ArithmeticFault : public MipsFault
|
||||
{
|
||||
protected:
|
||||
bool skipFaultingInstruction() {return true;}
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
#if FULL_SYSTEM
|
||||
void invoke(ExecContext * xc);
|
||||
#endif
|
||||
};
|
||||
|
||||
class InterruptFault : public MipsFault
|
||||
{
|
||||
protected:
|
||||
bool setRestartAddress() {return false;}
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class NDtbMissFault : public MipsFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class PDtbMissFault : public MipsFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class DtbPageFault : public MipsFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class DtbAcvFault : public MipsFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class ItbMissFault : public MipsFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class ItbPageFault : public MipsFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class ItbAcvFault : public MipsFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class UnimplementedOpcodeFault : public MipsFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class FloatEnableFault : public MipsFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class PalFault : public MipsFault
|
||||
{
|
||||
protected:
|
||||
bool skipFaultingInstruction() {return true;}
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class IntegerOverflowFault : public MipsFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
} // MipsISA namespace
|
||||
|
||||
#endif // __FAULTS_HH__
|
||||
88
src/arch/mips/isa/base.isa
Normal file
88
src/arch/mips/isa/base.isa
Normal file
@@ -0,0 +1,88 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Base class for MIPS instructions, and some support functions
|
||||
//
|
||||
|
||||
//Outputs to decoder.hh
|
||||
output header {{
|
||||
|
||||
using namespace MipsISA;
|
||||
|
||||
|
||||
/**
|
||||
* Base class for all MIPS static instructions.
|
||||
*/
|
||||
class MipsStaticInst : public StaticInst
|
||||
{
|
||||
protected:
|
||||
|
||||
/// Make MipsISA register dependence tags directly visible in
|
||||
/// this class and derived classes. Maybe these should really
|
||||
/// live here and not in the MipsISA namespace.
|
||||
/*enum DependenceTags {
|
||||
FP_Base_DepTag = MipsISA::FP_Base_DepTag,
|
||||
Fpcr_DepTag = MipsISA::Fpcr_DepTag,
|
||||
Uniq_DepTag = MipsISA::Uniq_DepTag,
|
||||
IPR_Base_DepTag = MipsISA::IPR_Base_DepTag
|
||||
};*/
|
||||
|
||||
// Constructor
|
||||
MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||
: StaticInst(mnem, _machInst, __opClass)
|
||||
{
|
||||
}
|
||||
|
||||
/// Print a register name for disassembly given the unique
|
||||
/// dependence tag number (FP or int).
|
||||
void printReg(std::ostream &os, int reg) const;
|
||||
|
||||
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
|
||||
}};
|
||||
|
||||
//Ouputs to decoder.cc
|
||||
output decoder {{
|
||||
|
||||
void MipsStaticInst::printReg(std::ostream &os, int reg) const
|
||||
{
|
||||
if (reg < FP_Base_DepTag) {
|
||||
ccprintf(os, "r%d", reg);
|
||||
}
|
||||
else {
|
||||
ccprintf(os, "f%d", reg - FP_Base_DepTag);
|
||||
}
|
||||
}
|
||||
|
||||
std::string MipsStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ccprintf(ss, "%-10s ", mnemonic);
|
||||
|
||||
if(_numDestRegs > 0){
|
||||
printReg(ss, _destRegIdx[0]);
|
||||
}
|
||||
|
||||
if(_numSrcRegs > 0) {
|
||||
ss << ",";
|
||||
printReg(ss, _srcRegIdx[0]);
|
||||
}
|
||||
|
||||
if(_numSrcRegs > 1) {
|
||||
ss << ",";
|
||||
printReg(ss, _srcRegIdx[1]);
|
||||
}
|
||||
|
||||
|
||||
if(mnemonic == "sll" || mnemonic == "sra"){
|
||||
ccprintf(ss,", %d",SA);
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
}};
|
||||
|
||||
71
src/arch/mips/isa/bitfields.isa
Normal file
71
src/arch/mips/isa/bitfields.isa
Normal file
@@ -0,0 +1,71 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bitfield definitions.
|
||||
//
|
||||
|
||||
def bitfield OPCODE <31:26>;
|
||||
def bitfield OPCODE_HI <31:29>;
|
||||
def bitfield OPCODE_LO <28:26>;
|
||||
|
||||
def bitfield REGIMM <20:16>;
|
||||
def bitfield REGIMM_HI <20:19>;
|
||||
def bitfield REGIMM_LO <18:16>;
|
||||
|
||||
def bitfield FUNCTION < 5: 0>;
|
||||
def bitfield FUNCTION_HI < 5: 3>;
|
||||
def bitfield FUNCTION_LO < 2: 0>;
|
||||
|
||||
// Integer operate format
|
||||
def bitfield RT <20:16>;
|
||||
def bitfield RT_HI <20:19>;
|
||||
def bitfield RT_LO <18:16>;
|
||||
|
||||
def bitfield RS <25:21>;
|
||||
def bitfield RS_MSB <25:25>;
|
||||
def bitfield RS_HI <25:24>;
|
||||
def bitfield RS_LO <23:21>;
|
||||
def bitfield RS_SRL <25:22>;
|
||||
|
||||
def bitfield RD <15:11>;
|
||||
|
||||
def bitfield INTIMM <15: 0>; // integer immediate (literal)
|
||||
|
||||
// Floating-point operate format
|
||||
def bitfield FMT <25:21>;
|
||||
def bitfield FR <25:21>;
|
||||
def bitfield FT <20:16>;
|
||||
def bitfield FS <15:11>;
|
||||
def bitfield FD <10:6>;
|
||||
|
||||
def bitfield ND <17:17>;
|
||||
def bitfield TF <16:16>;
|
||||
def bitfield MOVCI <16:16>;
|
||||
def bitfield MOVCF <16:16>;
|
||||
def bitfield SRL <21:21>;
|
||||
def bitfield SRLV < 6: 6>;
|
||||
def bitfield SA <10: 6>;
|
||||
|
||||
// Floating Point Condition Codes
|
||||
def bitfield CC <10:8>;
|
||||
def bitfield BRANCH_CC <20:18>;
|
||||
|
||||
// CP0 Register Select
|
||||
def bitfield SEL < 2: 0>;
|
||||
|
||||
// Interrupts
|
||||
def bitfield SC < 5: 5>;
|
||||
|
||||
// Branch format
|
||||
def bitfield OFFSET <15: 0>; // displacement
|
||||
|
||||
// Jmp format
|
||||
def bitfield JMPTARG <25: 0>;
|
||||
def bitfield HINT <10: 6>;
|
||||
|
||||
def bitfield SYSCALLCODE <25: 6>;
|
||||
def bitfield TRAPCODE <15:13>;
|
||||
|
||||
// M5 instructions
|
||||
def bitfield M5FUNC <7:0>;
|
||||
1688
src/arch/mips/isa/decoder.isa
Normal file
1688
src/arch/mips/isa/decoder.isa
Normal file
File diff suppressed because it is too large
Load Diff
66
src/arch/mips/isa/formats/basic.isa
Normal file
66
src/arch/mips/isa/formats/basic.isa
Normal file
@@ -0,0 +1,66 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// Declarations for execute() methods.
|
||||
def template BasicExecDeclare {{
|
||||
Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
|
||||
}};
|
||||
|
||||
// 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(MachInst machInst);
|
||||
%(BasicExecDeclare)s
|
||||
};
|
||||
}};
|
||||
|
||||
// Basic instruction class constructor template.
|
||||
def template BasicConstructor {{
|
||||
inline %(class_name)s::%(class_name)s(MachInst 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 BasicOp(code, *flags) {{
|
||||
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
324
src/arch/mips/isa/formats/branch.isa
Normal file
324
src/arch/mips/isa/formats/branch.isa
Normal file
@@ -0,0 +1,324 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Control transfer instructions
|
||||
//
|
||||
|
||||
output header {{
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* Base class for instructions whose disassembly is not purely a
|
||||
* function of the machine instruction (i.e., it depends on the
|
||||
* PC). This class overrides the disassemble() method to check
|
||||
* the PC and symbol table values before re-using a cached
|
||||
* disassembly string. This is necessary for branches and jumps,
|
||||
* where the disassembly string includes the target address (which
|
||||
* may depend on the PC and/or symbol table).
|
||||
*/
|
||||
class PCDependentDisassembly : public MipsStaticInst
|
||||
{
|
||||
protected:
|
||||
/// Cached program counter from last disassembly
|
||||
mutable Addr cachedPC;
|
||||
|
||||
/// Cached symbol table pointer from last disassembly
|
||||
mutable const SymbolTable *cachedSymtab;
|
||||
|
||||
/// Constructor
|
||||
PCDependentDisassembly(const char *mnem, MachInst _machInst,
|
||||
OpClass __opClass)
|
||||
: MipsStaticInst(mnem, _machInst, __opClass),
|
||||
cachedPC(0), cachedSymtab(0)
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &
|
||||
disassemble(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for branches (PC-relative control transfers),
|
||||
* conditional or unconditional.
|
||||
*/
|
||||
class Branch : public PCDependentDisassembly
|
||||
{
|
||||
protected:
|
||||
/// target address (signed) Displacement .
|
||||
int32_t disp;
|
||||
|
||||
/// Constructor.
|
||||
Branch(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||
: PCDependentDisassembly(mnem, _machInst, __opClass),
|
||||
disp(OFFSET << 2)
|
||||
{
|
||||
//If Bit 17 is 1 then Sign Extend
|
||||
if ( (disp & 0x00020000) > 0 ) {
|
||||
disp |= 0xFFFE0000;
|
||||
}
|
||||
}
|
||||
|
||||
Addr branchTarget(Addr branchPC) const;
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for branch likely branches (PC-relative control transfers),
|
||||
*/
|
||||
class BranchLikely : public PCDependentDisassembly
|
||||
{
|
||||
protected:
|
||||
/// target address (signed) Displacement .
|
||||
int32_t disp;
|
||||
|
||||
/// Constructor.
|
||||
BranchLikely(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||
: PCDependentDisassembly(mnem, _machInst, __opClass),
|
||||
disp(OFFSET << 2)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Addr branchTarget(Addr branchPC) const;
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for jumps (register-indirect control transfers). In
|
||||
* the Mips ISA, these are always unconditional.
|
||||
*/
|
||||
class Jump : public PCDependentDisassembly
|
||||
{
|
||||
protected:
|
||||
|
||||
/// Displacement to target address (signed).
|
||||
int32_t disp;
|
||||
|
||||
uint32_t target;
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
Jump(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||
: PCDependentDisassembly(mnem, _machInst, __opClass),
|
||||
disp(JMPTARG << 2)
|
||||
{
|
||||
}
|
||||
|
||||
Addr branchTarget(ExecContext *xc) const;
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
Addr
|
||||
Branch::branchTarget(Addr branchPC) const
|
||||
{
|
||||
return branchPC + 4 + disp;
|
||||
}
|
||||
|
||||
Addr
|
||||
BranchLikely::branchTarget(Addr branchPC) const
|
||||
{
|
||||
return branchPC + 4 + disp;
|
||||
}
|
||||
|
||||
Addr
|
||||
Jump::branchTarget(ExecContext *xc) const
|
||||
{
|
||||
Addr NPC = xc->readPC() + 4;
|
||||
uint64_t Rb = xc->readIntReg(_srcRegIdx[0]);
|
||||
return (Rb & ~3) | (NPC & 1);
|
||||
}
|
||||
|
||||
const std::string &
|
||||
PCDependentDisassembly::disassemble(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
if (!cachedDisassembly ||
|
||||
pc != cachedPC || symtab != cachedSymtab)
|
||||
{
|
||||
if (cachedDisassembly)
|
||||
delete cachedDisassembly;
|
||||
|
||||
cachedDisassembly =
|
||||
new std::string(generateDisassembly(pc, symtab));
|
||||
cachedPC = pc;
|
||||
cachedSymtab = symtab;
|
||||
}
|
||||
|
||||
return *cachedDisassembly;
|
||||
}
|
||||
|
||||
std::string
|
||||
Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ccprintf(ss, "%-10s ", mnemonic);
|
||||
|
||||
// There's only one register arg (RA), but it could be
|
||||
// either a source (the condition for conditional
|
||||
// branches) or a destination (the link reg for
|
||||
// unconditional branches)
|
||||
if (_numSrcRegs == 1) {
|
||||
printReg(ss, _srcRegIdx[0]);
|
||||
ss << ",";
|
||||
} else if(_numSrcRegs == 2) {
|
||||
printReg(ss, _srcRegIdx[0]);
|
||||
ss << ",";
|
||||
printReg(ss, _srcRegIdx[1]);
|
||||
ss << ",";
|
||||
}
|
||||
|
||||
Addr target = pc + 4 + disp;
|
||||
|
||||
std::string str;
|
||||
if (symtab && symtab->findSymbol(target, str))
|
||||
ss << str;
|
||||
else
|
||||
ccprintf(ss, "0x%x", target);
|
||||
|
||||
string inst_name = mnemonic;
|
||||
|
||||
if (inst_name.substr(inst_name.length()-2,inst_name.length()) == "al"){
|
||||
ccprintf(ss, " (r31=0x%x)",pc+8);
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
BranchLikely::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ccprintf(ss, "%-10s ", mnemonic);
|
||||
|
||||
// There's only one register arg (RA), but it could be
|
||||
// either a source (the condition for conditional
|
||||
// branches) or a destination (the link reg for
|
||||
// unconditional branches)
|
||||
if (_numSrcRegs > 0) {
|
||||
printReg(ss, _srcRegIdx[0]);
|
||||
ss << ",";
|
||||
}
|
||||
else if (_numDestRegs > 0) {
|
||||
printReg(ss, _destRegIdx[0]);
|
||||
ss << ",";
|
||||
}
|
||||
|
||||
Addr target = pc + 4 + disp;
|
||||
|
||||
std::string str;
|
||||
if (symtab && symtab->findSymbol(target, str))
|
||||
ss << str;
|
||||
else
|
||||
ccprintf(ss, "0x%x", target);
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ccprintf(ss, "%-10s ", mnemonic);
|
||||
|
||||
if ( mnemonic == "jal" ) {
|
||||
Addr npc = pc + 4;
|
||||
ccprintf(ss,"0x%x",(npc & 0xF0000000) | disp);
|
||||
} else if (_numSrcRegs == 0) {
|
||||
std::string str;
|
||||
if (symtab && symtab->findSymbol(disp, str))
|
||||
ss << str;
|
||||
else
|
||||
ccprintf(ss, "0x%x", disp);
|
||||
} else if (_numSrcRegs == 1) {
|
||||
printReg(ss, _srcRegIdx[0]);
|
||||
} else if(_numSrcRegs == 2) {
|
||||
printReg(ss, _srcRegIdx[0]);
|
||||
ss << ",";
|
||||
printReg(ss, _srcRegIdx[1]);
|
||||
} else {
|
||||
panic(">= 3 Source Registers!!!");
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
}};
|
||||
|
||||
def format Branch(code,*flags) {{
|
||||
#Add Link Code if Link instruction
|
||||
strlen = len(name)
|
||||
if name[strlen-2:] == 'al':
|
||||
code += 'R31 = NNPC;\n'
|
||||
|
||||
#Condition code
|
||||
code = 'bool cond;\n' + code
|
||||
code += 'if (cond) {\n'
|
||||
code += ' NNPC = NPC + disp;\n'
|
||||
code += '} else {\n'
|
||||
code += ' NNPC = NNPC;\n'
|
||||
code += '} \n'
|
||||
|
||||
iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
|
||||
('IsDirectControl', 'IsCondControl'))
|
||||
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
|
||||
def format BranchLikely(code,*flags) {{
|
||||
#Add Link Code if Link instruction
|
||||
strlen = len(name)
|
||||
if name[strlen-3:] == 'all':
|
||||
code += 'R31 = NNPC;\n'
|
||||
|
||||
#Condition code
|
||||
code = 'bool cond;\n' + code
|
||||
code += 'if (cond) {'
|
||||
code += 'NNPC = NPC + disp;\n'
|
||||
code += '} \n'
|
||||
|
||||
|
||||
iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
|
||||
('IsDirectControl', 'IsCondControl','IsCondDelaySlot'))
|
||||
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
def format Jump(code,*flags) {{
|
||||
#Add Link Code if Link instruction
|
||||
strlen = len(name)
|
||||
if strlen > 1 and name[1:] == 'al':
|
||||
code = 'R31 = NNPC;\n' + code
|
||||
|
||||
|
||||
iop = InstObjParams(name, Name, 'Jump', CodeBlock(code),\
|
||||
('IsIndirectControl', 'IsUncondControl'))
|
||||
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
|
||||
|
||||
|
||||
35
src/arch/mips/isa/formats/formats.isa
Normal file
35
src/arch/mips/isa/formats/formats.isa
Normal file
@@ -0,0 +1,35 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
//Templates from this format are used later
|
||||
//Include the basic format
|
||||
##include "basic.isa"
|
||||
|
||||
//Include the basic format
|
||||
##include "noop.isa"
|
||||
|
||||
//Include utility functions
|
||||
##include "util.isa"
|
||||
|
||||
//Include the cop0 formats
|
||||
##include "cop0.isa"
|
||||
|
||||
//Include the integer formats
|
||||
##include "int.isa"
|
||||
|
||||
//Include the floatOp format
|
||||
##include "fp.isa"
|
||||
|
||||
//Include the mem format
|
||||
##include "mem.isa"
|
||||
|
||||
//Include the trap format
|
||||
##include "trap.isa"
|
||||
|
||||
//Include the branch format
|
||||
##include "branch.isa"
|
||||
|
||||
//Include the noop format
|
||||
##include "unimp.isa"
|
||||
|
||||
//Include the noop format
|
||||
##include "unknown.isa"
|
||||
109
src/arch/mips/isa/formats/fp.isa
Normal file
109
src/arch/mips/isa/formats/fp.isa
Normal file
@@ -0,0 +1,109 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Floating Point operate instructions
|
||||
//
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Base class for FP operations.
|
||||
*/
|
||||
class FPOp : public MipsStaticInst
|
||||
{
|
||||
protected:
|
||||
|
||||
/// Constructor
|
||||
FPOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass)
|
||||
{
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
std::string FPOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
return "Disassembly of integer instruction\n";
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
// Primary format for float operate instructions:
|
||||
def format FloatOp(code, *flags) {{
|
||||
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
def format FloatCompareOp(code, *flags) {{
|
||||
code = 'bool cond;\n' + code
|
||||
code += 'FCSR = makeCCVector(FCSR, CC,cond);\n'
|
||||
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
def format FloatCompareWithXcptOp(code, *flags) {{
|
||||
code = 'bool cond;\n' + code
|
||||
code += 'FCSR = makeCCVector(FCSR, CC,cond);\n'
|
||||
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
def format FloatConvertOp(code, *flags) {{
|
||||
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
// Primary format for float64 operate instructions:
|
||||
def format Float64Op(code, *flags) {{
|
||||
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
def format Float64ConvertOp(code, *flags) {{
|
||||
code = 'bool cond;\n' + code
|
||||
code += 'FCSR = makeCCVector(FCSR, CC,cond);\n'
|
||||
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
def format FloatPSCompareOp(code, *flags) {{
|
||||
code = 'bool cond1;\nbool cond2;\n' + code
|
||||
code += 'FCSR = makeCCVector(FCSR, CC+1, cond1);\n'
|
||||
code += 'FCSR = makeCCVector(FCSR, CC, cond2);\n'
|
||||
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
def format FloatPSCompareWithXcptOp(code, *flags) {{
|
||||
code = 'bool cond1;\nbool cond2;\n' + code
|
||||
code += 'FCSR = makeCCVector(FCSR, CC+1, cond1);\n'
|
||||
code += 'FCSR = makeCCVector(FCSR, CC, cond2);\n'
|
||||
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
131
src/arch/mips/isa/formats/int.isa
Normal file
131
src/arch/mips/isa/formats/int.isa
Normal file
@@ -0,0 +1,131 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Integer operate instructions
|
||||
//
|
||||
|
||||
//Outputs to decoder.hh
|
||||
output header {{
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
/**
|
||||
* Base class for integer operations.
|
||||
*/
|
||||
class IntOp : public MipsStaticInst
|
||||
{
|
||||
protected:
|
||||
|
||||
/// Constructor
|
||||
IntOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
|
||||
MipsStaticInst(mnem, _machInst, __opClass)
|
||||
{
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
|
||||
class IntImmOp : public MipsStaticInst
|
||||
{
|
||||
protected:
|
||||
|
||||
int16_t imm;
|
||||
int32_t sextImm;
|
||||
uint32_t zextImm;
|
||||
|
||||
/// Constructor
|
||||
IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
|
||||
MipsStaticInst(mnem, _machInst, __opClass),imm(INTIMM),
|
||||
sextImm(INTIMM),zextImm(0x0000FFFF & INTIMM)
|
||||
{
|
||||
//If Bit 15 is 1 then Sign Extend
|
||||
int32_t temp = sextImm & 0x00008000;
|
||||
if (temp > 0 && mnemonic != "lui") {
|
||||
sextImm |= 0xFFFF0000;
|
||||
}
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
|
||||
|
||||
};
|
||||
|
||||
}};
|
||||
|
||||
//Outputs to decoder.cc
|
||||
output decoder {{
|
||||
std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ccprintf(ss, "%-10s ", mnemonic);
|
||||
|
||||
// just print the first dest... if there's a second one,
|
||||
// it's generally implicit
|
||||
if (_numDestRegs > 0) {
|
||||
printReg(ss, _destRegIdx[0]);
|
||||
ss << ",";
|
||||
}
|
||||
|
||||
// just print the first two source regs... if there's
|
||||
// a third one, it's a read-modify-write dest (Rc),
|
||||
// e.g. for CMOVxx
|
||||
if (_numSrcRegs > 0) {
|
||||
printReg(ss, _srcRegIdx[0]);
|
||||
}
|
||||
|
||||
if (_numSrcRegs > 1) {
|
||||
ss << ",";
|
||||
printReg(ss, _srcRegIdx[1]);
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ccprintf(ss, "%-10s ", mnemonic);
|
||||
|
||||
if (_numDestRegs > 0) {
|
||||
printReg(ss, _destRegIdx[0]);
|
||||
}
|
||||
|
||||
ss << ",";
|
||||
|
||||
if (_numSrcRegs > 0) {
|
||||
printReg(ss, _srcRegIdx[0]);
|
||||
ss << ",";
|
||||
}
|
||||
|
||||
if( mnemonic == "lui")
|
||||
ccprintf(ss, "%08p ", sextImm);
|
||||
else
|
||||
ss << (int) sextImm;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
}};
|
||||
|
||||
//Used by decoder.isa
|
||||
def format IntOp(code, *opt_flags) {{
|
||||
orig_code = code
|
||||
cblk = CodeBlock(code)
|
||||
|
||||
# Figure out if we are creating a IntImmOp or a IntOp
|
||||
# by looking at the instruction name
|
||||
iop = InstObjParams(name, Name, 'IntOp', cblk, opt_flags)
|
||||
strlen = len(name)
|
||||
if name[strlen-1] == 'i' or name[strlen-2:] == 'iu':
|
||||
iop = InstObjParams(name, Name, 'IntImmOp', cblk, opt_flags)
|
||||
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = OperateNopCheckDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
|
||||
|
||||
473
src/arch/mips/isa/formats/mem.isa
Normal file
473
src/arch/mips/isa/formats/mem.isa
Normal file
@@ -0,0 +1,473 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Base class for general Mips memory-format instructions.
|
||||
*/
|
||||
class Memory : public MipsStaticInst
|
||||
{
|
||||
protected:
|
||||
|
||||
/// Memory request flags. See mem_req_base.hh.
|
||||
unsigned memAccessFlags;
|
||||
/// Pointer to EAComp object.
|
||||
const StaticInstPtr eaCompPtr;
|
||||
/// Pointer to MemAcc object.
|
||||
const StaticInstPtr memAccPtr;
|
||||
|
||||
/// Displacement for EA calculation (signed).
|
||||
int32_t disp;
|
||||
|
||||
/// Constructor
|
||||
Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
|
||||
StaticInstPtr _eaCompPtr = nullStaticInstPtr,
|
||||
StaticInstPtr _memAccPtr = nullStaticInstPtr)
|
||||
: MipsStaticInst(mnem, _machInst, __opClass),
|
||||
memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
|
||||
disp(OFFSET)
|
||||
{
|
||||
//If Bit 15 is 1 then Sign Extend
|
||||
int32_t temp = disp & 0x00008000;
|
||||
|
||||
if (temp > 0) {
|
||||
disp |= 0xFFFF0000;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
|
||||
public:
|
||||
|
||||
const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
|
||||
const StaticInstPtr &memAccInst() const { return memAccPtr; }
|
||||
};
|
||||
|
||||
}};
|
||||
|
||||
|
||||
output decoder {{
|
||||
std::string
|
||||
Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
|
||||
flags[IsFloating] ? 'f' : 'r', RT, disp, RS);
|
||||
}
|
||||
|
||||
}};
|
||||
|
||||
def format LoadAddress(code) {{
|
||||
iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
|
||||
def template LoadStoreDeclare {{
|
||||
/**
|
||||
* Static instruction class for "%(mnemonic)s".
|
||||
*/
|
||||
class %(class_name)s : public %(base_class)s
|
||||
{
|
||||
protected:
|
||||
|
||||
/**
|
||||
* "Fake" effective address computation class for "%(mnemonic)s".
|
||||
*/
|
||||
class EAComp : public %(base_class)s
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
EAComp(MachInst machInst);
|
||||
|
||||
%(BasicExecDeclare)s
|
||||
};
|
||||
|
||||
/**
|
||||
* "Fake" memory access instruction class for "%(mnemonic)s".
|
||||
*/
|
||||
class MemAcc : public %(base_class)s
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
MemAcc(MachInst machInst);
|
||||
|
||||
%(BasicExecDeclare)s
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor.
|
||||
%(class_name)s(MachInst machInst);
|
||||
|
||||
%(BasicExecDeclare)s
|
||||
|
||||
%(InitiateAccDeclare)s
|
||||
|
||||
%(CompleteAccDeclare)s
|
||||
};
|
||||
}};
|
||||
|
||||
|
||||
def template InitiateAccDeclare {{
|
||||
Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
|
||||
}};
|
||||
|
||||
|
||||
def template CompleteAccDeclare {{
|
||||
Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
|
||||
}};
|
||||
|
||||
|
||||
def template LoadStoreConstructor {{
|
||||
/** TODO: change op_class to AddrGenOp or something (requires
|
||||
* creating new member of OpClass enum in op_class.hh, updating
|
||||
* config files, etc.). */
|
||||
inline %(class_name)s::EAComp::EAComp(MachInst machInst)
|
||||
: %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
|
||||
{
|
||||
%(ea_constructor)s;
|
||||
}
|
||||
|
||||
inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
|
||||
: %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
|
||||
{
|
||||
%(memacc_constructor)s;
|
||||
}
|
||||
|
||||
inline %(class_name)s::%(class_name)s(MachInst machInst)
|
||||
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
|
||||
new EAComp(machInst), new MemAcc(machInst))
|
||||
{
|
||||
%(constructor)s;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template EACompExecute {{
|
||||
Fault
|
||||
%(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Addr EA;
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
%(code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
xc->setEA(EA);
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
def template LoadMemAccExecute {{
|
||||
Fault
|
||||
%(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Addr EA;
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
EA = xc->getEA();
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
|
||||
%(code)s;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template LoadExecute {{
|
||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Addr EA;
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
%(ea_code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
|
||||
%(memacc_code)s;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template LoadInitiateAcc {{
|
||||
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Addr EA;
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_src_decl)s;
|
||||
%(op_rd)s;
|
||||
%(ea_code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template LoadCompleteAcc {{
|
||||
Fault %(class_name)s::completeAcc(uint8_t *data,
|
||||
%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
|
||||
memcpy(&Mem, data, sizeof(Mem));
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(memacc_code)s;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template StoreMemAccExecute {{
|
||||
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;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
EA = xc->getEA();
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(code)s;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, &write_result);
|
||||
if (traceData) { traceData->setData(Mem); }
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(postacc_code)s;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template StoreExecute {{
|
||||
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;
|
||||
%(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, &write_result);
|
||||
if (traceData) { traceData->setData(Mem); }
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(postacc_code)s;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
def template StoreInitiateAcc {{
|
||||
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Addr EA;
|
||||
Fault fault = NoFault;
|
||||
uint64_t write_result = 0;
|
||||
|
||||
%(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, &write_result);
|
||||
if (traceData) { traceData->setData(Mem); }
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
def template StoreCompleteAcc {{
|
||||
Fault %(class_name)s::completeAcc(uint8_t *data,
|
||||
%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
uint64_t write_result = 0;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_dest_decl)s;
|
||||
|
||||
memcpy(&write_result, data, sizeof(write_result));
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(postacc_code)s;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
// load instructions use Rt as dest, so check for
|
||||
// Rt == 31 to detect nops
|
||||
def template LoadNopCheckDecode {{
|
||||
{
|
||||
MipsStaticInst *i = new %(class_name)s(machInst);
|
||||
if (RT == 0) {
|
||||
i = makeNop(i);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}};
|
||||
|
||||
def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
|
||||
mem_flags = [], inst_flags = []) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
decode_template = LoadNopCheckDecode,
|
||||
exec_template_base = 'Load')
|
||||
}};
|
||||
|
||||
|
||||
def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
|
||||
mem_flags = [], inst_flags = []) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
exec_template_base = 'Store')
|
||||
}};
|
||||
|
||||
//FP loads are offloaded to these formats for now ...
|
||||
def format LoadFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
|
||||
mem_flags = [], inst_flags = []) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
decode_template = BasicDecode,
|
||||
exec_template_base = 'Load')
|
||||
}};
|
||||
|
||||
|
||||
def format StoreFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
|
||||
mem_flags = [], inst_flags = []) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
exec_template_base = 'Store')
|
||||
}};
|
||||
|
||||
|
||||
def format UnalignedStore(memacc_code, postacc_code,
|
||||
ea_code = {{ EA = Rb + disp; }},
|
||||
mem_flags = [], inst_flags = []) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
postacc_code, exec_template_base = 'Store')
|
||||
}};
|
||||
94
src/arch/mips/isa/formats/noop.isa
Normal file
94
src/arch/mips/isa/formats/noop.isa
Normal file
@@ -0,0 +1,94 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Nop
|
||||
//
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Static instruction class for no-ops. This is a leaf class.
|
||||
*/
|
||||
class Nop : public MipsStaticInst
|
||||
{
|
||||
/// Disassembly of original instruction.
|
||||
const std::string originalDisassembly;
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
Nop(const std::string _originalDisassembly, MachInst _machInst)
|
||||
: MipsStaticInst("nop", _machInst, No_OpClass),
|
||||
originalDisassembly(_originalDisassembly)
|
||||
{
|
||||
flags[IsNop] = true;
|
||||
}
|
||||
|
||||
~Nop() { }
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
|
||||
%(BasicExecDeclare)s
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
std::string Nop::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
#ifdef SS_COMPATIBLE_DISASSEMBLY
|
||||
return originalDisassembly;
|
||||
#else
|
||||
return csprintf("%-10s (%s)", "nop", originalDisassembly);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Helper function for decoding nops. Substitute Nop object
|
||||
/// for original inst passed in as arg (and delete latter).
|
||||
inline
|
||||
MipsStaticInst *
|
||||
makeNop(MipsStaticInst *inst)
|
||||
{
|
||||
MipsStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst);
|
||||
delete inst;
|
||||
return nop;
|
||||
}
|
||||
}};
|
||||
|
||||
output exec {{
|
||||
Fault
|
||||
Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
|
||||
{
|
||||
return NoFault;
|
||||
}
|
||||
}};
|
||||
|
||||
// integer & FP operate instructions use RT as dest, so check for
|
||||
// RT == 0 to detect nops
|
||||
def template OperateNopCheckDecode {{
|
||||
{
|
||||
MipsStaticInst *i = new %(class_name)s(machInst);
|
||||
|
||||
//if (RD == 0) {
|
||||
// i = makeNop(i);
|
||||
//}
|
||||
|
||||
return i;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
// Like BasicOperate format, but generates NOP if RC/FC == 31
|
||||
def format BasicOperateWithNopCheck(code, *opt_args) {{
|
||||
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code),
|
||||
opt_args)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = OperateNopCheckDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
def format Nop() {{
|
||||
decode_block = 'return new Nop(\"sll r0,r0,0\",machInst);\n'
|
||||
}};
|
||||
|
||||
53
src/arch/mips/isa/formats/tlbop.isa
Normal file
53
src/arch/mips/isa/formats/tlbop.isa
Normal file
@@ -0,0 +1,53 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TlbOp instructions
|
||||
//
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Base class for integer operations.
|
||||
*/
|
||||
class TlbOp : public MipsStaticInst
|
||||
{
|
||||
protected:
|
||||
|
||||
/// Constructor
|
||||
TlbOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass)
|
||||
{
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
std::string TlbOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
return "Disassembly of integer instruction\n";
|
||||
}
|
||||
}};
|
||||
|
||||
def template TlbOpExecute {{
|
||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
|
||||
{
|
||||
//Call into the trap handler with the appropriate fault
|
||||
return No_Fault;
|
||||
}
|
||||
|
||||
//Write the resulting state to the execution context
|
||||
%(op_wb)s;
|
||||
|
||||
return No_Fault;
|
||||
}
|
||||
}};
|
||||
|
||||
// Primary format for integer operate instructions:
|
||||
def format TlbOp(code, *opt_flags) {{
|
||||
orig_code = code
|
||||
cblk = CodeBlock(code)
|
||||
iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecodeWithMnemonic.subst(iop)
|
||||
exec_output = TlbOpExecute.subst(iop)
|
||||
}};
|
||||
52
src/arch/mips/isa/formats/trap.isa
Normal file
52
src/arch/mips/isa/formats/trap.isa
Normal file
@@ -0,0 +1,52 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Trap instructions
|
||||
//
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Base class for integer operations.
|
||||
*/
|
||||
class Trap : public MipsStaticInst
|
||||
{
|
||||
protected:
|
||||
|
||||
/// Constructor
|
||||
Trap(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass)
|
||||
{
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
std::string Trap::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
return "Disassembly of integer instruction\n";
|
||||
}
|
||||
}};
|
||||
|
||||
def template TrapExecute {{
|
||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
|
||||
{
|
||||
//Call into the trap handler with the appropriate fault
|
||||
return No_Fault;
|
||||
}
|
||||
|
||||
//Write the resulting state to the execution context
|
||||
%(op_wb)s;
|
||||
|
||||
return No_Fault;
|
||||
}
|
||||
}};
|
||||
|
||||
// Primary format for integer operate instructions:
|
||||
def format Trap(code, *flags) {{
|
||||
code = 'bool cond;\n' + code;
|
||||
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
166
src/arch/mips/isa/formats/unimp.isa
Normal file
166
src/arch/mips/isa/formats/unimp.isa
Normal file
@@ -0,0 +1,166 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
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 MipsStaticInst
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
FailUnimplemented(const char *_mnemonic, MachInst _machInst)
|
||||
: MipsStaticInst(_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 MipsStaticInst
|
||||
{
|
||||
private:
|
||||
/// Have we warned on this instruction yet?
|
||||
mutable bool warned;
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
WarnUnimplemented(const char *_mnemonic, MachInst _machInst)
|
||||
: MipsStaticInst(_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' "
|
||||
"(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
|
||||
inst2string(machInst));
|
||||
return new UnimplementedOpcodeFault;
|
||||
}
|
||||
|
||||
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)
|
||||
}};
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Static instruction class for unknown (illegal) instructions.
|
||||
* These cause simulator termination if they are executed in a
|
||||
* non-speculative mode. This is a leaf class.
|
||||
*/
|
||||
class Unknown : public MipsStaticInst
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
Unknown(MachInst _machInst)
|
||||
: MipsStaticInst("unknown", _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;
|
||||
};
|
||||
}};
|
||||
|
||||
74
src/arch/mips/isa/formats/unknown.isa
Normal file
74
src/arch/mips/isa/formats/unknown.isa
Normal file
@@ -0,0 +1,74 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
output header {{
|
||||
std::string inst2string(MachInst machInst);
|
||||
}};
|
||||
output decoder {{
|
||||
|
||||
std::string inst2string(MachInst machInst)
|
||||
{
|
||||
string str = "";
|
||||
uint32_t mask = 0x80000000;
|
||||
|
||||
for(int i=0; i < 32; i++) {
|
||||
if ((machInst & mask) == 0) {
|
||||
str += "0";
|
||||
} else {
|
||||
str += "1";
|
||||
}
|
||||
|
||||
mask = mask >> 1;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string
|
||||
Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
return csprintf("%-10s (inst 0x%x, opcode 0x%x, binary:%s)",
|
||||
"unknown", machInst, OPCODE, inst2string(machInst));
|
||||
}
|
||||
}};
|
||||
|
||||
output exec {{
|
||||
Fault
|
||||
Unknown::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
panic("attempt to execute unknown instruction "
|
||||
"(inst 0x%08x, opcode 0x%x, binary: %s)", machInst, OPCODE, inst2string(machInst));
|
||||
return new UnimplementedOpcodeFault;
|
||||
}
|
||||
}};
|
||||
|
||||
def format Unknown() {{
|
||||
decode_block = 'return new Unknown(machInst);\n'
|
||||
}};
|
||||
|
||||
129
src/arch/mips/isa/formats/util.isa
Normal file
129
src/arch/mips/isa/formats/util.isa
Normal file
@@ -0,0 +1,129 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
let {{
|
||||
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
postacc_code = '', base_class = 'Memory',
|
||||
decode_template = BasicDecode, exec_template_base = ''):
|
||||
# Make sure flags are in lists (convert to lists if not).
|
||||
mem_flags = makeList(mem_flags)
|
||||
inst_flags = makeList(inst_flags)
|
||||
|
||||
# add hook to get effective addresses into execution trace output.
|
||||
ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
|
||||
|
||||
# generate code block objects
|
||||
ea_cblk = CodeBlock(ea_code)
|
||||
memacc_cblk = CodeBlock(memacc_code)
|
||||
postacc_cblk = CodeBlock(postacc_code)
|
||||
|
||||
# Some CPU models execute the memory operation as an atomic unit,
|
||||
# while others want to separate them into an effective address
|
||||
# computation and a memory access operation. As a result, we need
|
||||
# to generate three StaticInst objects. Note that the latter two
|
||||
# are nested inside the larger "atomic" one.
|
||||
|
||||
# generate InstObjParams for EAComp object
|
||||
ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)
|
||||
|
||||
# generate InstObjParams for MemAcc object
|
||||
memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)
|
||||
# in the split execution model, the MemAcc portion is responsible
|
||||
# for the post-access code.
|
||||
memacc_iop.postacc_code = postacc_cblk.code
|
||||
|
||||
# generate InstObjParams for InitiateAcc, CompleteAcc object
|
||||
# The code used depends on the template being used
|
||||
if (exec_template_base == 'Load'):
|
||||
initiateacc_cblk = CodeBlock(ea_code + memacc_code)
|
||||
completeacc_cblk = CodeBlock(memacc_code + postacc_code)
|
||||
elif (exec_template_base == 'Store'):
|
||||
initiateacc_cblk = CodeBlock(ea_code + memacc_code)
|
||||
completeacc_cblk = CodeBlock(postacc_code)
|
||||
else:
|
||||
initiateacc_cblk = ''
|
||||
completeacc_cblk = ''
|
||||
|
||||
initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk,
|
||||
inst_flags)
|
||||
|
||||
completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk,
|
||||
inst_flags)
|
||||
|
||||
if (exec_template_base == 'Load'):
|
||||
initiateacc_iop.ea_code = ea_cblk.code
|
||||
initiateacc_iop.memacc_code = memacc_cblk.code
|
||||
completeacc_iop.memacc_code = memacc_cblk.code
|
||||
completeacc_iop.postacc_code = postacc_cblk.code
|
||||
elif (exec_template_base == 'Store'):
|
||||
initiateacc_iop.ea_code = ea_cblk.code
|
||||
initiateacc_iop.memacc_code = memacc_cblk.code
|
||||
completeacc_iop.postacc_code = postacc_cblk.code
|
||||
|
||||
# generate InstObjParams for unified execution
|
||||
cblk = CodeBlock(ea_code + memacc_code + postacc_code)
|
||||
iop = InstObjParams(name, Name, base_class, cblk, inst_flags)
|
||||
|
||||
iop.ea_constructor = ea_cblk.constructor
|
||||
iop.ea_code = ea_cblk.code
|
||||
iop.memacc_constructor = memacc_cblk.constructor
|
||||
iop.memacc_code = memacc_cblk.code
|
||||
iop.postacc_code = postacc_cblk.code
|
||||
|
||||
if mem_flags:
|
||||
s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
|
||||
iop.constructor += s
|
||||
memacc_iop.constructor += s
|
||||
|
||||
# select templates
|
||||
memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
|
||||
fullExecTemplate = eval(exec_template_base + 'Execute')
|
||||
initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
|
||||
completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
|
||||
|
||||
# (header_output, decoder_output, decode_block, exec_output)
|
||||
return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
|
||||
decode_template.subst(iop),
|
||||
EACompExecute.subst(ea_iop)
|
||||
+ memAccExecTemplate.subst(memacc_iop)
|
||||
+ fullExecTemplate.subst(iop)
|
||||
+ initiateAccTemplate.subst(initiateacc_iop)
|
||||
+ completeAccTemplate.subst(completeacc_iop))
|
||||
}};
|
||||
|
||||
|
||||
output exec {{
|
||||
|
||||
using namespace MipsISA;
|
||||
|
||||
/// CLEAR ALL CPU INST/EXE HAZARDS
|
||||
inline void
|
||||
clear_exe_inst_hazards()
|
||||
{
|
||||
//CODE HERE
|
||||
}
|
||||
|
||||
|
||||
/// Check "FP enabled" machine status bit. Called when executing any FP
|
||||
/// instruction in full-system mode.
|
||||
/// @retval Full-system mode: NoFault if FP is enabled, FenFault
|
||||
/// if not. Non-full-system mode: always returns NoFault.
|
||||
#if FULL_SYSTEM
|
||||
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
|
||||
{
|
||||
Fault fault = NoFault; // dummy... this ipr access should not fault
|
||||
if (!Mips34k::ICSR_FPE(xc->readIpr(MipsISA::IPR_ICSR, fault))) {
|
||||
fault = FloatEnableFault;
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
#else
|
||||
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
|
||||
{
|
||||
return NoFault;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}};
|
||||
|
||||
|
||||
48
src/arch/mips/isa/includes.isa
Normal file
48
src/arch/mips/isa/includes.isa
Normal file
@@ -0,0 +1,48 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Output include file directives.
|
||||
//
|
||||
|
||||
output header {{
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "cpu/static_inst.hh"
|
||||
#include "arch/mips/isa_traits.hh"
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
#include "arch/mips/isa_traits.hh"
|
||||
#include "base/cprintf.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "cpu/exec_context.hh" // for Jump::branchTarget()
|
||||
#include "arch/mips/faults.hh"
|
||||
#include "arch/mips/isa_traits.hh"
|
||||
|
||||
#include <math.h>
|
||||
#if defined(linux)
|
||||
#include <fenv.h>
|
||||
#endif
|
||||
|
||||
using namespace MipsISA;
|
||||
}};
|
||||
|
||||
output exec {{
|
||||
#include "arch/mips/faults.hh"
|
||||
#include "arch/mips/isa_traits.hh"
|
||||
#include <math.h>
|
||||
#if defined(linux)
|
||||
#include <fenv.h>
|
||||
#endif
|
||||
|
||||
#ifdef FULL_SYSTEM
|
||||
//#include "arch/alpha/pseudo_inst.hh"
|
||||
#endif
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/exetrace.hh"
|
||||
#include "sim/sim_exit.hh"
|
||||
|
||||
using namespace MipsISA;
|
||||
}};
|
||||
|
||||
52
src/arch/mips/isa/main.isa
Normal file
52
src/arch/mips/isa/main.isa
Normal file
@@ -0,0 +1,52 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
##include "includes.isa"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Namespace statement. Everything below this line will be in the
|
||||
// MipsISAInst namespace.
|
||||
//
|
||||
|
||||
namespace MipsISA;
|
||||
|
||||
//Include the bitfield definitions
|
||||
##include "bitfields.isa"
|
||||
|
||||
//Include the operand_types and operand definitions
|
||||
##include "operands.isa"
|
||||
|
||||
//Include the base class for mips 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.isa"
|
||||
61
src/arch/mips/isa/operands.isa
Normal file
61
src/arch/mips/isa/operands.isa
Normal file
@@ -0,0 +1,61 @@
|
||||
def operand_types {{
|
||||
'sb' : ('signed int', 8),
|
||||
'ub' : ('unsigned int', 8),
|
||||
'sh' : ('signed int', 16),
|
||||
'uh' : ('unsigned int', 16),
|
||||
'sw' : ('signed int', 32),
|
||||
'uw' : ('unsigned int', 32),
|
||||
'sd' : ('signed int', 64),
|
||||
'ud' : ('unsigned int', 64),
|
||||
'sf' : ('float', 32),
|
||||
'df' : ('float', 64),
|
||||
'qf' : ('float', 128)
|
||||
}};
|
||||
|
||||
def operands {{
|
||||
#General Purpose Integer Reg Operands
|
||||
'Rd': ('IntReg', 'uw', 'RD', 'IsInteger', 1),
|
||||
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 2),
|
||||
'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 3),
|
||||
|
||||
#Operands used for Link or Syscall Insts
|
||||
'R31': ('IntReg', 'uw','31','IsInteger', 4),
|
||||
'R2': ('IntReg', 'uw','2', 'IsInteger', 5),
|
||||
|
||||
#Special Integer Reg operands
|
||||
'HI': ('IntReg', 'uw','32', 'IsInteger', 6),
|
||||
'LO': ('IntReg', 'uw','33', 'IsInteger', 7),
|
||||
|
||||
#Immediate Value operand
|
||||
'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3),
|
||||
|
||||
#Floating Point Reg Operands
|
||||
'Fd': ('FloatReg', 'sf', 'FD', 'IsFloating', 1),
|
||||
'Fs': ('FloatReg', 'sf', 'FS', 'IsFloating', 2),
|
||||
'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3),
|
||||
'Fr': ('FloatReg', 'sf', 'FR', 'IsFloating', 3),
|
||||
|
||||
#Special Floating Point Control Reg Operands
|
||||
'FIR': ('FloatReg', 'uw', '32', 'IsFloating', 1),
|
||||
'FCCR': ('FloatReg', 'uw', '33', 'IsFloating', 2),
|
||||
'FEXR': ('FloatReg', 'uw', '34', 'IsFloating', 3),
|
||||
'FENR': ('FloatReg', 'uw', '35', 'IsFloating', 3),
|
||||
'FCSR': ('FloatReg', 'uw', '36', 'IsFloating', 3),
|
||||
|
||||
#Operands For Paired Singles FP Operations
|
||||
'Fd1': ('FloatReg', 'sf', 'FD', 'IsFloating', 4),
|
||||
'Fd2': ('FloatReg', 'sf', 'FD+1', 'IsFloating', 4),
|
||||
'Fs1': ('FloatReg', 'sf', 'FS', 'IsFloating', 5),
|
||||
'Fs2': ('FloatReg', 'sf', 'FS+1', 'IsFloating', 5),
|
||||
'Ft1': ('FloatReg', 'sf', 'FT', 'IsFloating', 6),
|
||||
'Ft2': ('FloatReg', 'sf', 'FT+1', 'IsFloating', 6),
|
||||
'Fr1': ('FloatReg', 'sf', 'FR', 'IsFloating', 7),
|
||||
'Fr2': ('FloatReg', 'sf', 'FR+1', 'IsFloating', 7),
|
||||
|
||||
#Memory Operand
|
||||
'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
|
||||
|
||||
#Program Counter Operands
|
||||
'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4),
|
||||
'NNPC':('NNPC', 'uw', None, ( None, None, 'IsControl' ), 4)
|
||||
}};
|
||||
229
src/arch/mips/isa_traits.cc
Normal file
229
src/arch/mips/isa_traits.cc
Normal file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arch/mips/isa_traits.hh"
|
||||
#include "config/full_system.hh"
|
||||
#include "cpu/static_inst.hh"
|
||||
#include "sim/serialize.hh"
|
||||
#include "base/bitfield.hh"
|
||||
|
||||
using namespace MipsISA;
|
||||
using namespace std;
|
||||
|
||||
|
||||
void
|
||||
MipsISA::copyRegs(ExecContext *src, ExecContext *dest)
|
||||
{
|
||||
/*fpcr = xc->readMiscReg(MipsISA::Fpcr_DepTag);
|
||||
uniq = xc->readMiscReg(MipsISA::Uniq_DepTag);
|
||||
lock_flag = xc->readMiscReg(MipsISA::Lock_Flag_DepTag);
|
||||
lock_addr = xc->readMiscReg(MipsISA::Lock_Addr_DepTag);
|
||||
|
||||
#if FULL_SYSTEM
|
||||
copyIprs(xc);
|
||||
#endif*/
|
||||
}
|
||||
|
||||
void
|
||||
MipsISA::MiscRegFile::copyMiscRegs(ExecContext *xc)
|
||||
{
|
||||
/*fpcr = xc->readMiscReg(MipsISA::Fpcr_DepTag);
|
||||
uniq = xc->readMiscReg(MipsISA::Uniq_DepTag);
|
||||
lock_flag = xc->readMiscReg(MipsISA::Lock_Flag_DepTag);
|
||||
lock_addr = xc->readMiscReg(MipsISA::Lock_Addr_DepTag);
|
||||
|
||||
#endif*/
|
||||
}
|
||||
|
||||
uint64_t
|
||||
MipsISA::fpConvert(double fp_val, ConvertType cvt_type)
|
||||
{
|
||||
|
||||
switch (cvt_type)
|
||||
{
|
||||
case SINGLE_TO_DOUBLE:
|
||||
double sdouble_val = fp_val;
|
||||
void *sdouble_ptr = &sdouble_val;
|
||||
uint64_t sdp_bits = *(uint64_t *) sdouble_ptr;
|
||||
return sdp_bits;
|
||||
|
||||
case SINGLE_TO_WORD:
|
||||
int32_t sword_val = (int32_t) fp_val;
|
||||
void *sword_ptr = &sword_val;
|
||||
uint64_t sword_bits= *(uint32_t *) sword_ptr;
|
||||
return sword_bits;
|
||||
|
||||
case WORD_TO_SINGLE:
|
||||
float wfloat_val = fp_val;
|
||||
void *wfloat_ptr = &wfloat_val;
|
||||
uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr;
|
||||
return wfloat_bits;
|
||||
|
||||
case WORD_TO_DOUBLE:
|
||||
double wdouble_val = fp_val;
|
||||
void *wdouble_ptr = &wdouble_val;
|
||||
uint64_t wdp_bits = *(uint64_t *) wdouble_ptr;
|
||||
return wdp_bits;
|
||||
|
||||
default:
|
||||
panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
MipsISA::roundFP(double val, int digits)
|
||||
{
|
||||
double digit_offset = pow(10.0,digits);
|
||||
val = val * digit_offset;
|
||||
val = val + 0.5;
|
||||
val = floor(val);
|
||||
val = val / digit_offset;
|
||||
return val;
|
||||
}
|
||||
|
||||
double
|
||||
MipsISA::truncFP(double val)
|
||||
{
|
||||
int trunc_val = (int) val;
|
||||
return (double) trunc_val;
|
||||
}
|
||||
|
||||
bool
|
||||
MipsISA::getFPConditionCode(uint32_t fcsr_reg, int cc)
|
||||
{
|
||||
//uint32_t cc_bits = xc->readFloatReg(35);
|
||||
return false;//regFile.floatRegfile.getConditionCode(cc);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
MipsISA::makeCCVector(uint32_t fcsr, int num, bool val)
|
||||
{
|
||||
int shift = (num == 0) ? 22 : num + 23;
|
||||
|
||||
fcsr = fcsr | (val << shift);
|
||||
|
||||
return fcsr;
|
||||
}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
|
||||
static inline Addr
|
||||
TruncPage(Addr addr)
|
||||
{ return addr & ~(MipsISA::PageBytes - 1); }
|
||||
|
||||
static inline Addr
|
||||
RoundPage(Addr addr)
|
||||
{ return (addr + MipsISA::PageBytes - 1) & ~(MipsISA::PageBytes - 1); }
|
||||
#endif
|
||||
|
||||
void
|
||||
IntRegFile::serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_ARRAY(regs, NumIntRegs);
|
||||
}
|
||||
|
||||
void
|
||||
IntRegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_ARRAY(regs, NumIntRegs);
|
||||
}
|
||||
|
||||
void
|
||||
RegFile::serialize(std::ostream &os)
|
||||
{
|
||||
intRegFile.serialize(os);
|
||||
//SERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
|
||||
//SERIALIZE_SCALAR(miscRegs.fpcr);
|
||||
//SERIALIZE_SCALAR(miscRegs.uniq);
|
||||
//SERIALIZE_SCALAR(miscRegs.lock_flag);
|
||||
//SERIALIZE_SCALAR(miscRegs.lock_addr);
|
||||
SERIALIZE_SCALAR(pc);
|
||||
SERIALIZE_SCALAR(npc);
|
||||
SERIALIZE_SCALAR(nnpc);
|
||||
#if FULL_SYSTEM
|
||||
SERIALIZE_ARRAY(palregs, NumIntRegs);
|
||||
SERIALIZE_ARRAY(ipr, NumInternalProcRegs);
|
||||
SERIALIZE_SCALAR(intrflag);
|
||||
SERIALIZE_SCALAR(pal_shadow);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
intRegFile.unserialize(cp, section);
|
||||
//UNSERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
|
||||
//UNSERIALIZE_SCALAR(miscRegs.fpcr);
|
||||
//UNSERIALIZE_SCALAR(miscRegs.uniq);
|
||||
//UNSERIALIZE_SCALAR(miscRegs.lock_flag);
|
||||
//UNSERIALIZE_SCALAR(miscRegs.lock_addr);
|
||||
UNSERIALIZE_SCALAR(pc);
|
||||
UNSERIALIZE_SCALAR(npc);
|
||||
UNSERIALIZE_SCALAR(nnpc);
|
||||
#if FULL_SYSTEM
|
||||
UNSERIALIZE_ARRAY(palregs, NumIntRegs);
|
||||
UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs);
|
||||
UNSERIALIZE_SCALAR(intrflag);
|
||||
UNSERIALIZE_SCALAR(pal_shadow);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if FULL_SYSTEM
|
||||
void
|
||||
PTE::serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_SCALAR(tag);
|
||||
SERIALIZE_SCALAR(ppn);
|
||||
SERIALIZE_SCALAR(xre);
|
||||
SERIALIZE_SCALAR(xwe);
|
||||
SERIALIZE_SCALAR(asn);
|
||||
SERIALIZE_SCALAR(asma);
|
||||
SERIALIZE_SCALAR(fonr);
|
||||
SERIALIZE_SCALAR(fonw);
|
||||
SERIALIZE_SCALAR(valid);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PTE::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_SCALAR(tag);
|
||||
UNSERIALIZE_SCALAR(ppn);
|
||||
UNSERIALIZE_SCALAR(xre);
|
||||
UNSERIALIZE_SCALAR(xwe);
|
||||
UNSERIALIZE_SCALAR(asn);
|
||||
UNSERIALIZE_SCALAR(asma);
|
||||
UNSERIALIZE_SCALAR(fonr);
|
||||
UNSERIALIZE_SCALAR(fonw);
|
||||
UNSERIALIZE_SCALAR(valid);
|
||||
}
|
||||
|
||||
#endif //FULL_SYSTEM
|
||||
199
src/arch/mips/isa_traits.hh
Normal file
199
src/arch/mips/isa_traits.hh
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_MIPS_ISA_TRAITS_HH__
|
||||
#define __ARCH_MIPS_ISA_TRAITS_HH__
|
||||
|
||||
#include "arch/mips/constants.hh"
|
||||
#include "arch/mips/types.hh"
|
||||
#include "arch/mips/regfile/regfile.hh"
|
||||
#include "arch/mips/faults.hh"
|
||||
#include "arch/mips/utility.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "config/full_system.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
#include "sim/host.hh"
|
||||
#include "sim/faults.hh"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class FastCPU;
|
||||
class FullCPU;
|
||||
class Checkpoint;
|
||||
class ExecContext;
|
||||
|
||||
namespace LittleEndianGuest {};
|
||||
|
||||
#define TARGET_MIPS
|
||||
|
||||
class StaticInst;
|
||||
class StaticInstPtr;
|
||||
|
||||
namespace MIPS34K {
|
||||
int DTB_ASN_ASN(uint64_t reg);
|
||||
int ITB_ASN_ASN(uint64_t reg);
|
||||
};
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
class SyscallReturn {
|
||||
public:
|
||||
template <class T>
|
||||
SyscallReturn(T v, bool s)
|
||||
{
|
||||
retval = (uint32_t)v;
|
||||
success = s;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
SyscallReturn(T v)
|
||||
{
|
||||
success = (v >= 0);
|
||||
retval = (uint32_t)v;
|
||||
}
|
||||
|
||||
~SyscallReturn() {}
|
||||
|
||||
SyscallReturn& operator=(const SyscallReturn& s) {
|
||||
retval = s.retval;
|
||||
success = s.success;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool successful() { return success; }
|
||||
uint64_t value() { return retval; }
|
||||
|
||||
|
||||
private:
|
||||
uint64_t retval;
|
||||
bool success;
|
||||
};
|
||||
#endif
|
||||
|
||||
namespace MipsISA
|
||||
{
|
||||
using namespace LittleEndianGuest;
|
||||
|
||||
static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
|
||||
{
|
||||
if (return_value.successful()) {
|
||||
// no error
|
||||
regs->setIntReg(SyscallSuccessReg, 0);
|
||||
regs->setIntReg(ReturnValueReg1, return_value.value());
|
||||
} else {
|
||||
// got an error, return details
|
||||
regs->setIntReg(SyscallSuccessReg, (IntReg) -1);
|
||||
regs->setIntReg(ReturnValueReg1, -return_value.value());
|
||||
}
|
||||
}
|
||||
|
||||
StaticInstPtr decodeInst(ExtMachInst);
|
||||
|
||||
static inline ExtMachInst
|
||||
makeExtMI(MachInst inst, const uint64_t &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
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to insure ISA semantics about 0 registers.
|
||||
* @param xc The execution context.
|
||||
*/
|
||||
template <class XC>
|
||||
void zeroRegisters(XC *xc);
|
||||
|
||||
const Addr MaxAddr = (Addr)-1;
|
||||
|
||||
void copyRegs(ExecContext *src, ExecContext *dest);
|
||||
|
||||
uint64_t fpConvert(double fp_val, ConvertType cvt_type);
|
||||
double roundFP(double val, int digits);
|
||||
double truncFP(double val);
|
||||
bool getFPConditionCode(uint32_t fcsr_reg, int cc);
|
||||
uint32_t makeCCVector(uint32_t fcsr, int num, bool val);
|
||||
|
||||
// Machine operations
|
||||
|
||||
void saveMachineReg(AnyReg &savereg, const RegFile ®_file,
|
||||
int regnum);
|
||||
|
||||
void restoreMachineReg(RegFile ®s, const AnyReg ®,
|
||||
int regnum);
|
||||
|
||||
#if 0
|
||||
static void serializeSpecialRegs(const Serializable::Proxy &proxy,
|
||||
const RegFile ®s);
|
||||
|
||||
static void unserializeSpecialRegs(const IniFile *db,
|
||||
const std::string &category,
|
||||
ConfigNode *node,
|
||||
RegFile ®s);
|
||||
#endif
|
||||
|
||||
static inline Addr alignAddress(const Addr &addr,
|
||||
unsigned int nbytes) {
|
||||
return (addr & ~(nbytes - 1));
|
||||
}
|
||||
|
||||
// Instruction address compression hooks
|
||||
static inline Addr realPCToFetchPC(const Addr &addr) {
|
||||
return addr;
|
||||
}
|
||||
|
||||
static inline Addr fetchPCToRealPC(const Addr &addr) {
|
||||
return addr;
|
||||
}
|
||||
|
||||
// the size of "fetched" instructions (not necessarily the size
|
||||
// of real instructions for PISA)
|
||||
static inline size_t fetchInstSize() {
|
||||
return sizeof(MachInst);
|
||||
}
|
||||
|
||||
static inline MachInst makeRegisterCopy(int dest, int src) {
|
||||
panic("makeRegisterCopy not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#if FULL_SYSTEM
|
||||
|
||||
#include "arch/mips/mips34k.hh"
|
||||
|
||||
#endif
|
||||
|
||||
using namespace MipsISA;
|
||||
|
||||
#endif // __ARCH_MIPS_ISA_TRAITS_HH__
|
||||
72
src/arch/mips/linux/linux.cc
Normal file
72
src/arch/mips/linux/linux.cc
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2006 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Korey Sewell
|
||||
*/
|
||||
|
||||
#include "arch/mips/linux/linux.hh"
|
||||
|
||||
// open(2) flags translation table
|
||||
OpenFlagTransTable MipsLinux::openFlagTable[] = {
|
||||
#ifdef _MSC_VER
|
||||
{ MipsLinux::TGT_O_RDONLY, _O_RDONLY },
|
||||
{ MipsLinux::TGT_O_WRONLY, _O_WRONLY },
|
||||
{ MipsLinux::TGT_O_RDWR, _O_RDWR },
|
||||
{ MipsLinux::TGT_O_APPEND, _O_APPEND },
|
||||
{ MipsLinux::TGT_O_CREAT, _O_CREAT },
|
||||
{ MipsLinux::TGT_O_TRUNC, _O_TRUNC },
|
||||
{ MipsLinux::TGT_O_EXCL, _O_EXCL },
|
||||
#ifdef _O_NONBLOCK
|
||||
{ MipsLinux::TGT_O_NONBLOCK, _O_NONBLOCK },
|
||||
#endif
|
||||
#ifdef _O_NOCTTY
|
||||
{ MipsLinux::TGT_O_NOCTTY, _O_NOCTTY },
|
||||
#endif
|
||||
#ifdef _O_SYNC
|
||||
{ MipsLinux::TGT_O_SYNC, _O_SYNC },
|
||||
#endif
|
||||
#else /* !_MSC_VER */
|
||||
{ MipsLinux::TGT_O_RDONLY, O_RDONLY },
|
||||
{ MipsLinux::TGT_O_WRONLY, O_WRONLY },
|
||||
{ MipsLinux::TGT_O_RDWR, O_RDWR },
|
||||
{ MipsLinux::TGT_O_APPEND, O_APPEND },
|
||||
{ MipsLinux::TGT_O_CREAT, O_CREAT },
|
||||
{ MipsLinux::TGT_O_TRUNC, O_TRUNC },
|
||||
{ MipsLinux::TGT_O_EXCL, O_EXCL },
|
||||
{ MipsLinux::TGT_O_NONBLOCK, O_NONBLOCK },
|
||||
{ MipsLinux::TGT_O_NOCTTY, O_NOCTTY },
|
||||
#ifdef O_SYNC
|
||||
{ MipsLinux::TGT_O_SYNC, O_SYNC },
|
||||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
};
|
||||
|
||||
const int MipsLinux::NUM_OPEN_FLAGS =
|
||||
(sizeof(MipsLinux::openFlagTable)/sizeof(MipsLinux::openFlagTable[0]));
|
||||
|
||||
|
||||
|
||||
126
src/arch/mips/linux/linux.hh
Normal file
126
src/arch/mips/linux/linux.hh
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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: Korey Sewell
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_MIPS_LINUX_LINUX_HH__
|
||||
#define __ARCH_MIPS_LINUX_LINUX_HH__
|
||||
|
||||
#include "kern/linux/linux.hh"
|
||||
|
||||
class MipsLinux : public Linux
|
||||
{
|
||||
public:
|
||||
|
||||
/// This table maps the target open() flags to the corresponding
|
||||
/// host open() flags.
|
||||
static OpenFlagTransTable openFlagTable[];
|
||||
|
||||
/// Number of entries in openFlagTable[].
|
||||
static const int NUM_OPEN_FLAGS;
|
||||
|
||||
//@{
|
||||
/// open(2) flag values.
|
||||
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 = 0x00000080; //!< O_NONBLOCK
|
||||
static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND
|
||||
static const int TGT_O_CREAT = 0x00000100; //!< O_CREAT
|
||||
static const int TGT_O_TRUNC = 0x00000200; //!< O_TRUNC
|
||||
static const int TGT_O_EXCL = 0x00000400; //!< O_EXCL
|
||||
static const int TGT_O_NOCTTY = 0x00000800; //!< O_NOCTTY
|
||||
static const int TGT_O_SYNC = 0x00000010; //!< 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
|
||||
//@}
|
||||
|
||||
/// For mmap().
|
||||
static const unsigned TGT_MAP_ANONYMOUS = 0x800;
|
||||
|
||||
//@{
|
||||
/// For getsysinfo().
|
||||
static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
|
||||
static const unsigned GSI_CPU_INFO = 59; //!< CPU information
|
||||
static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
|
||||
static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine
|
||||
static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
|
||||
static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB
|
||||
static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/// For getrusage().
|
||||
static const int TGT_RUSAGE_SELF = 0;
|
||||
static const int TGT_RUSAGE_CHILDREN = -1;
|
||||
static const int TGT_RUSAGE_BOTH = -2;
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/// For setsysinfo().
|
||||
static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control()
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/// 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;
|
||||
//@}
|
||||
|
||||
/// For table().
|
||||
static const int TBL_SYSINFO = 12;
|
||||
|
||||
/// Resource enumeration for getrlimit().
|
||||
enum rlimit_resources {
|
||||
TGT_RLIMIT_CPU = 0,
|
||||
TGT_RLIMIT_FSIZE = 1,
|
||||
TGT_RLIMIT_DATA = 2,
|
||||
TGT_RLIMIT_STACK = 3,
|
||||
TGT_RLIMIT_CORE = 4,
|
||||
TGT_RLIMIT_NOFILE = 5,
|
||||
TGT_RLIMIT_AS = 6,
|
||||
TGT_RLIMIT_RSS = 7,
|
||||
TGT_RLIMIT_VMEM = 7,
|
||||
TGT_RLIMIT_NPROC = 8,
|
||||
TGT_RLIMIT_MEMLOCK = 9,
|
||||
TGT_RLIMIT_LOCKS = 10
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
429
src/arch/mips/linux/process.cc
Normal file
429
src/arch/mips/linux/process.cc
Normal file
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arch/mips/linux/linux.hh"
|
||||
#include "arch/mips/linux/process.hh"
|
||||
#include "arch/mips/isa_traits.hh"
|
||||
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "kern/linux/linux.hh"
|
||||
|
||||
#include "sim/process.hh"
|
||||
#include "sim/syscall_emul.hh"
|
||||
|
||||
using namespace std;
|
||||
using namespace MipsISA;
|
||||
|
||||
/// Target uname() handler.
|
||||
static SyscallReturn
|
||||
unameFunc(SyscallDesc *desc, int callnum, Process *process,
|
||||
ExecContext *xc)
|
||||
{
|
||||
TypedBufferArg<Linux::utsname> name(xc->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, "mips");
|
||||
|
||||
name.copyOut(xc->getMemPort());
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Target sys_getsysyinfo() handler. Even though this call is
|
||||
/// borrowed from Tru64, the subcases that get used appear to be
|
||||
/// different in practice from those used by Tru64 processes.
|
||||
static SyscallReturn
|
||||
sys_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
|
||||
ExecContext *xc)
|
||||
{
|
||||
unsigned op = xc->getSyscallArg(0);
|
||||
// unsigned nbytes = xc->getSyscallArg(2);
|
||||
|
||||
switch (op) {
|
||||
|
||||
case 45: { // GSI_IEEE_FP_CONTROL
|
||||
TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
|
||||
// I don't think this exactly matches the HW FPCR
|
||||
*fpcr = 0;
|
||||
fpcr.copyOut(xc->getMemPort());
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
cerr << "sys_getsysinfo: unknown op " << op << endl;
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// Target sys_setsysinfo() handler.
|
||||
static SyscallReturn
|
||||
sys_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
|
||||
ExecContext *xc)
|
||||
{
|
||||
unsigned op = xc->getSyscallArg(0);
|
||||
// unsigned nbytes = xc->getSyscallArg(2);
|
||||
|
||||
switch (op) {
|
||||
|
||||
case 14: { // SSI_IEEE_FP_CONTROL
|
||||
TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
|
||||
// I don't think this exactly matches the HW FPCR
|
||||
fpcr.copyIn(xc->getMemPort());
|
||||
DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): "
|
||||
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
cerr << "sys_setsysinfo: unknown op " << op << endl;
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
SyscallDesc MipsLinuxProcess::syscallDescs[] = {
|
||||
/* 0 */ SyscallDesc("syscall", unimplementedFunc),
|
||||
/* 1 */ SyscallDesc("exit", exitFunc),
|
||||
/* 2 */ SyscallDesc("fork", unimplementedFunc),
|
||||
/* 3 */ SyscallDesc("read", readFunc),
|
||||
/* 4 */ SyscallDesc("write", writeFunc),
|
||||
/* 5 */ SyscallDesc("open", openFunc<MipsLinux>),
|
||||
/* 6 */ SyscallDesc("close", closeFunc),
|
||||
/* 7 */ SyscallDesc("waitpid", unimplementedFunc),
|
||||
/* 8 */ SyscallDesc("creat", unimplementedFunc),
|
||||
/* 9 */ SyscallDesc("link", unimplementedFunc),
|
||||
/* 10 */ SyscallDesc("unlink", unlinkFunc),
|
||||
/* 11 */ SyscallDesc("execve", unimplementedFunc),
|
||||
/* 12 */ SyscallDesc("chdir", unimplementedFunc),
|
||||
/* 13 */ SyscallDesc("time", unimplementedFunc),
|
||||
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
|
||||
/* 15 */ SyscallDesc("chmod", chmodFunc<MipsLinux>),
|
||||
/* 16 */ SyscallDesc("lchown", chownFunc),
|
||||
/* 17 */ SyscallDesc("break", obreakFunc), /*obreak*/
|
||||
/* 18 */ SyscallDesc("unused#18", unimplementedFunc),
|
||||
/* 19 */ SyscallDesc("lseek", lseekFunc),
|
||||
/* 20 */ SyscallDesc("getpid", getpidFunc),
|
||||
/* 21 */ SyscallDesc("mount", unimplementedFunc),
|
||||
/* 22 */ SyscallDesc("umount", unimplementedFunc),
|
||||
/* 23 */ SyscallDesc("setuid", setuidFunc),
|
||||
/* 24 */ SyscallDesc("getuid", getuidFunc),
|
||||
/* 25 */ SyscallDesc("stime", unimplementedFunc),
|
||||
/* 26 */ SyscallDesc("ptrace", unimplementedFunc),
|
||||
/* 27 */ SyscallDesc("alarm", unimplementedFunc),
|
||||
/* 28 */ SyscallDesc("unused#28", unimplementedFunc),
|
||||
/* 29 */ SyscallDesc("pause", unimplementedFunc),
|
||||
/* 30 */ SyscallDesc("utime", unimplementedFunc),
|
||||
/* 31 */ SyscallDesc("stty", unimplementedFunc),
|
||||
/* 32 */ SyscallDesc("gtty", unimplementedFunc),
|
||||
/* 33 */ SyscallDesc("access", unimplementedFunc),
|
||||
/* 34 */ SyscallDesc("nice", unimplementedFunc),
|
||||
/* 35 */ SyscallDesc("ftime", unimplementedFunc),
|
||||
/* 36 */ SyscallDesc("sync", unimplementedFunc),
|
||||
/* 37 */ SyscallDesc("kill", ignoreFunc),
|
||||
/* 38 */ SyscallDesc("rename", unimplementedFunc),
|
||||
/* 39 */ SyscallDesc("mkdir", unimplementedFunc),
|
||||
/* 40 */ SyscallDesc("rmdir", unimplementedFunc),
|
||||
/* 41 */ SyscallDesc("dup", unimplementedFunc),
|
||||
/* 42 */ SyscallDesc("pipe", unimplementedFunc),
|
||||
/* 43 */ SyscallDesc("times", unimplementedFunc),
|
||||
/* 44 */ SyscallDesc("prof", unimplementedFunc),
|
||||
/* 45 */ SyscallDesc("brk", obreakFunc),/*openFunc<MipsLinux>*/
|
||||
/* 46 */ SyscallDesc("setgid", unimplementedFunc),
|
||||
/* 47 */ SyscallDesc("getgid", getgidFunc),
|
||||
/* 48 */ SyscallDesc("signal", ignoreFunc),
|
||||
/* 49 */ SyscallDesc("geteuid", geteuidFunc),
|
||||
/* 50 */ SyscallDesc("getegid", getegidFunc),
|
||||
/* 51 */ SyscallDesc("acct", unimplementedFunc),
|
||||
/* 52 */ SyscallDesc("umount2", unimplementedFunc),
|
||||
/* 53 */ SyscallDesc("lock", unimplementedFunc),
|
||||
/* 54 */ SyscallDesc("ioctl", ioctlFunc<MipsLinux>),
|
||||
/* 55 */ SyscallDesc("fcntl", unimplementedFunc),
|
||||
/* 56 */ SyscallDesc("mpx", unimplementedFunc),
|
||||
/* 57 */ SyscallDesc("setpgid", unimplementedFunc),
|
||||
/* 58 */ SyscallDesc("ulimit", unimplementedFunc),
|
||||
/* 59 */ SyscallDesc("unused#59", unimplementedFunc),
|
||||
/* 60 */ SyscallDesc("umask", unimplementedFunc),
|
||||
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
|
||||
/* 62 */ SyscallDesc("ustat", unimplementedFunc),
|
||||
/* 63 */ SyscallDesc("dup2", unimplementedFunc),
|
||||
/* 64 */ SyscallDesc("getppid", getpagesizeFunc),
|
||||
/* 65 */ SyscallDesc("getpgrp", unimplementedFunc),
|
||||
/* 66 */ SyscallDesc("setsid", unimplementedFunc),
|
||||
/* 67 */ SyscallDesc("sigaction",unimplementedFunc),
|
||||
/* 68 */ SyscallDesc("sgetmask", unimplementedFunc),
|
||||
/* 69 */ SyscallDesc("ssetmask", unimplementedFunc),
|
||||
/* 70 */ SyscallDesc("setreuid", unimplementedFunc),
|
||||
/* 71 */ SyscallDesc("setregid", unimplementedFunc),
|
||||
/* 72 */ SyscallDesc("sigsuspend", unimplementedFunc),
|
||||
/* 73 */ SyscallDesc("sigpending", unimplementedFunc),
|
||||
/* 74 */ SyscallDesc("sethostname", ignoreFunc),
|
||||
/* 75 */ SyscallDesc("setrlimit", unimplementedFunc),
|
||||
/* 76 */ SyscallDesc("getrlimit", unimplementedFunc),
|
||||
/* 77 */ SyscallDesc("getrusage", unimplementedFunc),
|
||||
/* 78 */ SyscallDesc("gettimeofday", unimplementedFunc),
|
||||
/* 79 */ SyscallDesc("settimeofday", unimplementedFunc),
|
||||
/* 80 */ SyscallDesc("getgroups", unimplementedFunc),
|
||||
/* 81 */ SyscallDesc("setgroups", unimplementedFunc),
|
||||
/* 82 */ SyscallDesc("reserved#82", unimplementedFunc),
|
||||
/* 83 */ SyscallDesc("symlink", unimplementedFunc),
|
||||
/* 84 */ SyscallDesc("unused#84", unimplementedFunc),
|
||||
/* 85 */ SyscallDesc("readlink", unimplementedFunc),
|
||||
/* 86 */ SyscallDesc("uselib", unimplementedFunc),
|
||||
/* 87 */ SyscallDesc("swapon", gethostnameFunc),
|
||||
/* 88 */ SyscallDesc("reboot", unimplementedFunc),
|
||||
/* 89 */ SyscallDesc("readdir", unimplementedFunc),
|
||||
/* 90 */ SyscallDesc("mmap", mmapFunc<MipsLinux>),
|
||||
/* 91 */ SyscallDesc("munmap",munmapFunc),
|
||||
/* 92 */ SyscallDesc("truncate", fcntlFunc),
|
||||
/* 93 */ SyscallDesc("ftruncate", unimplementedFunc),
|
||||
/* 94 */ SyscallDesc("fchmod", unimplementedFunc),
|
||||
/* 95 */ SyscallDesc("fchown", unimplementedFunc),
|
||||
/* 96 */ SyscallDesc("getpriority", unimplementedFunc),
|
||||
/* 97 */ SyscallDesc("setpriority", unimplementedFunc),
|
||||
/* 98 */ SyscallDesc("profil", unimplementedFunc),
|
||||
/* 99 */ SyscallDesc("statfs", unimplementedFunc),
|
||||
/* 100 */ SyscallDesc("fstatfs", unimplementedFunc),
|
||||
/* 101 */ SyscallDesc("ioperm", unimplementedFunc),
|
||||
/* 102 */ SyscallDesc("socketcall", unimplementedFunc),
|
||||
/* 103 */ SyscallDesc("syslog", unimplementedFunc),
|
||||
/* 104 */ SyscallDesc("setitimer", unimplementedFunc),
|
||||
/* 105 */ SyscallDesc("getitimer", unimplementedFunc),
|
||||
/* 106 */ SyscallDesc("stat", statFunc<MipsLinux>),
|
||||
/* 107 */ SyscallDesc("lstat", unimplementedFunc),
|
||||
/* 108 */ SyscallDesc("fstat", fstatFunc<MipsLinux>),
|
||||
/* 109 */ SyscallDesc("unused#109", unimplementedFunc),
|
||||
/* 110 */ SyscallDesc("iopl", unimplementedFunc),
|
||||
/* 111 */ SyscallDesc("vhangup", unimplementedFunc),
|
||||
/* 112 */ SyscallDesc("idle", ignoreFunc),
|
||||
/* 113 */ SyscallDesc("vm86", unimplementedFunc),
|
||||
/* 114 */ SyscallDesc("wait4", unimplementedFunc),
|
||||
/* 115 */ SyscallDesc("swapoff", unimplementedFunc),
|
||||
/* 116 */ SyscallDesc("sysinfo", unimplementedFunc),
|
||||
/* 117 */ SyscallDesc("ipc", unimplementedFunc),
|
||||
/* 118 */ SyscallDesc("fsync", unimplementedFunc),
|
||||
/* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
|
||||
/* 120 */ SyscallDesc("clone", unimplementedFunc),
|
||||
/* 121 */ SyscallDesc("setdomainname", unimplementedFunc),
|
||||
/* 122 */ SyscallDesc("uname", unameFunc),
|
||||
/* 123 */ SyscallDesc("modify_ldt", unimplementedFunc),
|
||||
/* 124 */ SyscallDesc("adjtimex", unimplementedFunc),
|
||||
/* 125 */ SyscallDesc("mprotect", ignoreFunc),
|
||||
/* 126 */ SyscallDesc("sigprocmask", unimplementedFunc),
|
||||
/* 127 */ SyscallDesc("create_module", unimplementedFunc),
|
||||
/* 128 */ SyscallDesc("init_module", unimplementedFunc),
|
||||
/* 129 */ SyscallDesc("delete_module", unimplementedFunc),
|
||||
/* 130 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
|
||||
/* 131 */ SyscallDesc("quotactl", unimplementedFunc),
|
||||
/* 132 */ SyscallDesc("getpgid", unimplementedFunc),
|
||||
/* 133 */ SyscallDesc("fchdir", unimplementedFunc),
|
||||
/* 134 */ SyscallDesc("bdflush", unimplementedFunc),
|
||||
/* 135 */ SyscallDesc("sysfs", unimplementedFunc),
|
||||
/* 136 */ SyscallDesc("personality", unimplementedFunc),
|
||||
/* 137 */ SyscallDesc("afs_syscall", unimplementedFunc),
|
||||
/* 138 */ SyscallDesc("setfsuid", unimplementedFunc),
|
||||
/* 139 */ SyscallDesc("setfsgid", unimplementedFunc),
|
||||
/* 140 */ SyscallDesc("llseek", unimplementedFunc),
|
||||
/* 141 */ SyscallDesc("getdents", unimplementedFunc),
|
||||
/* 142 */ SyscallDesc("newselect", unimplementedFunc),
|
||||
/* 143 */ SyscallDesc("flock", unimplementedFunc),
|
||||
/* 144 */ SyscallDesc("msync", unimplementedFunc),/*getrlimitFunc<MipsLinux>*/
|
||||
/* 145 */ SyscallDesc("readv", unimplementedFunc),
|
||||
/* 146 */ SyscallDesc("writev", writevFunc<MipsLinux>),
|
||||
/* 147 */ SyscallDesc("cacheflush", unimplementedFunc),
|
||||
/* 148 */ SyscallDesc("cachectl", unimplementedFunc),
|
||||
/* 149 */ SyscallDesc("sysmips", unimplementedFunc),
|
||||
/* 150 */ SyscallDesc("unused#150", unimplementedFunc),
|
||||
/* 151 */ SyscallDesc("getsid", unimplementedFunc),
|
||||
/* 152 */ SyscallDesc("fdatasync", unimplementedFunc),
|
||||
/* 153 */ SyscallDesc("sysctl", unimplementedFunc),
|
||||
/* 154 */ SyscallDesc("mlock", unimplementedFunc),
|
||||
/* 155 */ SyscallDesc("munlock", unimplementedFunc),
|
||||
/* 156 */ SyscallDesc("mlockall", unimplementedFunc),
|
||||
/* 157 */ SyscallDesc("munlockall", unimplementedFunc),
|
||||
/* 158 */ SyscallDesc("sched_setparam", unimplementedFunc),
|
||||
/* 159 */ SyscallDesc("sched_getparam", unimplementedFunc),
|
||||
/* 160 */ SyscallDesc("sched_setscheduler", unimplementedFunc),
|
||||
/* 161 */ SyscallDesc("sched_getscheduler", unimplementedFunc),
|
||||
/* 162 */ SyscallDesc("sched_yield", unimplementedFunc),
|
||||
/* 163 */ SyscallDesc("sched_get_prioritymax", unimplementedFunc),
|
||||
/* 164 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
|
||||
/* 165 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
|
||||
/* 166 */ SyscallDesc("nanosleep", unimplementedFunc),
|
||||
/* 167 */ SyscallDesc("mremap", unimplementedFunc),
|
||||
/* 168 */ SyscallDesc("accept", unimplementedFunc),
|
||||
/* 169 */ SyscallDesc("bind", unimplementedFunc),
|
||||
/* 170 */ SyscallDesc("connect", unimplementedFunc),
|
||||
/* 171 */ SyscallDesc("getpeername", unimplementedFunc),
|
||||
/* 172 */ SyscallDesc("getsockname", unimplementedFunc),
|
||||
/* 173 */ SyscallDesc("getsockopt", unimplementedFunc),
|
||||
/* 174 */ SyscallDesc("listen", unimplementedFunc),
|
||||
/* 175 */ SyscallDesc("recv", unimplementedFunc),
|
||||
/* 176 */ SyscallDesc("recvmsg", unimplementedFunc),
|
||||
/* 177 */ SyscallDesc("send", unimplementedFunc),
|
||||
/* 178 */ SyscallDesc("sendmsg", ignoreFunc),
|
||||
/* 179 */ SyscallDesc("sendto", unimplementedFunc),
|
||||
/* 180 */ SyscallDesc("setsockopt", unimplementedFunc),
|
||||
/* 181 */ SyscallDesc("shutdown", unimplementedFunc),
|
||||
/* 182 */ SyscallDesc("unknown #182", unimplementedFunc),
|
||||
/* 183 */ SyscallDesc("socket", ignoreFunc),
|
||||
/* 184 */ SyscallDesc("socketpair", unimplementedFunc),
|
||||
/* 185 */ SyscallDesc("setresuid", unimplementedFunc),
|
||||
/* 186 */ SyscallDesc("getresuid", unimplementedFunc),
|
||||
/* 187 */ SyscallDesc("query_module", unimplementedFunc),
|
||||
/* 188 */ SyscallDesc("poll", unimplementedFunc),
|
||||
/* 189 */ SyscallDesc("nfsservctl", unimplementedFunc),
|
||||
/* 190 */ SyscallDesc("setresgid", unimplementedFunc),
|
||||
/* 191 */ SyscallDesc("getresgid", unimplementedFunc),
|
||||
/* 192 */ SyscallDesc("prctl", unimplementedFunc),
|
||||
/* 193 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
|
||||
/* 194 */ SyscallDesc("rt_sigaction", ignoreFunc),
|
||||
/* 195 */ SyscallDesc("rt_sigprocmask", ignoreFunc),
|
||||
/* 196 */ SyscallDesc("rt_sigpending", unimplementedFunc),
|
||||
/* 197 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
|
||||
/* 198 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc),
|
||||
/* 199 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
|
||||
/* 200 */ SyscallDesc("pread64", unimplementedFunc),
|
||||
/* 201 */ SyscallDesc("pwrite64", unimplementedFunc),
|
||||
/* 202 */ SyscallDesc("chown", unimplementedFunc),
|
||||
/* 203 */ SyscallDesc("getcwd", unimplementedFunc),
|
||||
/* 204 */ SyscallDesc("capget", unimplementedFunc),
|
||||
/* 205 */ SyscallDesc("capset", unimplementedFunc),
|
||||
/* 206 */ SyscallDesc("sigalstack", unimplementedFunc),
|
||||
/* 207 */ SyscallDesc("sendfile", unimplementedFunc),
|
||||
/* 208 */ SyscallDesc("getpmsg", unimplementedFunc),
|
||||
/* 209 */ SyscallDesc("putpmsg", unimplementedFunc),
|
||||
/* 210 */ SyscallDesc("mmap2", unimplementedFunc),
|
||||
/* 211 */ SyscallDesc("truncate64", unimplementedFunc),
|
||||
/* 212 */ SyscallDesc("ftruncate64", unimplementedFunc),
|
||||
/* 213 */ SyscallDesc("stat64", unimplementedFunc),
|
||||
/* 214 */ SyscallDesc("lstat64", lstat64Func<MipsLinux>),
|
||||
/* 215 */ SyscallDesc("fstat64", fstat64Func<MipsLinux>),
|
||||
/* 216 */ SyscallDesc("pivot_root", unimplementedFunc),
|
||||
/* 217 */ SyscallDesc("mincore", unimplementedFunc),
|
||||
/* 218 */ SyscallDesc("madvise", unimplementedFunc),
|
||||
/* 219 */ SyscallDesc("getdents64", unimplementedFunc),
|
||||
/* 220 */ SyscallDesc("fcntl64", fcntlFunc),
|
||||
/* 221 */ SyscallDesc("reserved#221", unimplementedFunc),
|
||||
/* 222 */ SyscallDesc("gettid", unimplementedFunc),
|
||||
/* 223 */ SyscallDesc("readahead", unimplementedFunc),
|
||||
/* 224 */ SyscallDesc("setxattr", unimplementedFunc),
|
||||
/* 225 */ SyscallDesc("lsetxattr", unimplementedFunc),
|
||||
/* 226 */ SyscallDesc("fsetxattr", unimplementedFunc),
|
||||
/* 227 */ SyscallDesc("getxattr", unimplementedFunc),
|
||||
/* 228 */ SyscallDesc("lgetxattr", unimplementedFunc),
|
||||
/* 229 */ SyscallDesc("fgetxattr", unimplementedFunc),
|
||||
/* 230 */ SyscallDesc("listxattr", unimplementedFunc),
|
||||
/* 231 */ SyscallDesc("llistxattr", unimplementedFunc),
|
||||
/* 232 */ SyscallDesc("flistxattr", unimplementedFunc),
|
||||
/* 233 */ SyscallDesc("removexattr", unimplementedFunc),
|
||||
/* 234 */ SyscallDesc("lremovexattr", unimplementedFunc),
|
||||
/* 235 */ SyscallDesc("fremovexattr", ignoreFunc),
|
||||
/* 236 */ SyscallDesc("tkill", unimplementedFunc),
|
||||
/* 237 */ SyscallDesc("sendfile64", unimplementedFunc),
|
||||
/* 238 */ SyscallDesc("futex", unimplementedFunc),
|
||||
/* 239 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
|
||||
/* 240 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
|
||||
/* 241 */ SyscallDesc("io_setup", unimplementedFunc),
|
||||
/* 242 */ SyscallDesc("io_destroy", unimplementedFunc),
|
||||
/* 243 */ SyscallDesc("io_getevents", unimplementedFunc),
|
||||
/* 244 */ SyscallDesc("io_submit", unimplementedFunc),
|
||||
/* 245 */ SyscallDesc("io_cancel", unimplementedFunc),
|
||||
/* 246 */ SyscallDesc("exit_group", exitFunc),
|
||||
/* 247 */ SyscallDesc("lookup_dcookie", unimplementedFunc),
|
||||
/* 248 */ SyscallDesc("epoll_create", unimplementedFunc),
|
||||
/* 249 */ SyscallDesc("epoll_ctl", unimplementedFunc),
|
||||
/* 250 */ SyscallDesc("epoll_wait", unimplementedFunc),
|
||||
/* 251 */ SyscallDesc("remap_file_pages", unimplementedFunc),
|
||||
/* 252 */ SyscallDesc("set_tid_address", unimplementedFunc),
|
||||
/* 253 */ SyscallDesc("restart_syscall", unimplementedFunc),
|
||||
/* 254 */ SyscallDesc("fadvise64", unimplementedFunc),
|
||||
/* 255 */ SyscallDesc("statfs64", unimplementedFunc),
|
||||
/* 256 */ SyscallDesc("fstafs64", unimplementedFunc),
|
||||
/* 257 */ SyscallDesc("timer_create", sys_getsysinfoFunc),
|
||||
/* 258 */ SyscallDesc("timer_settime", sys_setsysinfoFunc),
|
||||
/* 259 */ SyscallDesc("timer_gettime", unimplementedFunc),
|
||||
/* 260 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
|
||||
/* 261 */ SyscallDesc("timer_delete", unimplementedFunc),
|
||||
/* 262 */ SyscallDesc("clock_settime", unimplementedFunc),
|
||||
/* 263 */ SyscallDesc("clock_gettime", unimplementedFunc),
|
||||
/* 264 */ SyscallDesc("clock_getres", unimplementedFunc),
|
||||
/* 265 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
|
||||
/* 266 */ SyscallDesc("tgkill", unimplementedFunc),
|
||||
/* 267 */ SyscallDesc("utimes", unimplementedFunc),
|
||||
/* 268 */ SyscallDesc("mbind", unimplementedFunc),
|
||||
/* 269 */ SyscallDesc("get_mempolicy", unimplementedFunc),
|
||||
/* 270 */ SyscallDesc("set_mempolicy", unimplementedFunc),
|
||||
/* 271 */ SyscallDesc("mq_open", unimplementedFunc),
|
||||
/* 272 */ SyscallDesc("mq_unlink", unimplementedFunc),
|
||||
/* 273 */ SyscallDesc("mq_timedsend", unimplementedFunc),
|
||||
/* 274 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
|
||||
/* 275 */ SyscallDesc("mq_notify", unimplementedFunc),
|
||||
/* 276 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
|
||||
/* 277 */ SyscallDesc("vserver", unimplementedFunc),
|
||||
/* 278 */ SyscallDesc("waitid", unimplementedFunc),
|
||||
/* 279 */ SyscallDesc("unknown #279", unimplementedFunc),
|
||||
/* 280 */ SyscallDesc("add_key", unimplementedFunc),
|
||||
/* 281 */ SyscallDesc("request_key", unimplementedFunc),
|
||||
/* 282 */ SyscallDesc("keyctl", unimplementedFunc),
|
||||
};
|
||||
|
||||
MipsLinuxProcess::MipsLinuxProcess(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)
|
||||
: MipsLiveProcess(name, objFile, system, stdin_fd, stdout_fd, stderr_fd,
|
||||
argv, envp),
|
||||
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
|
||||
{
|
||||
//init_regs->intRegFile[0] = 0;
|
||||
}
|
||||
|
||||
SyscallDesc*
|
||||
MipsLinuxProcess::getDesc(int callnum)
|
||||
{
|
||||
//MIPS32 syscalls are in the range of 4000 - 4999
|
||||
int m5_sys_idx = callnum - 4000;
|
||||
|
||||
if (m5_sys_idx < 0 || m5_sys_idx > Num_Syscall_Descs)
|
||||
return NULL;
|
||||
|
||||
return &syscallDescs[m5_sys_idx];
|
||||
}
|
||||
59
src/arch/mips/linux/process.hh
Normal file
59
src/arch/mips/linux/process.hh
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __MIPS_LINUX_PROCESS_HH__
|
||||
#define __MIPS_LINUX_PROCESS_HH__
|
||||
|
||||
#include "arch/mips/process.hh"
|
||||
|
||||
|
||||
/// A process with emulated Mips/Linux syscalls.
|
||||
class MipsLinuxProcess : public MipsLiveProcess
|
||||
{
|
||||
public:
|
||||
/// Constructor.
|
||||
MipsLinuxProcess(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);
|
||||
|
||||
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[];
|
||||
|
||||
const int Num_Syscall_Descs;
|
||||
};
|
||||
|
||||
|
||||
#endif // __MIPS_LINUX_PROCESS_HH__
|
||||
161
src/arch/mips/process.cc
Normal file
161
src/arch/mips/process.cc
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arch/mips/isa_traits.hh"
|
||||
#include "arch/mips/process.hh"
|
||||
#include "arch/mips/linux/process.hh"
|
||||
#include "base/loader/object_file.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "sim/builder.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
using namespace std;
|
||||
using namespace MipsISA;
|
||||
|
||||
|
||||
MipsLiveProcess *
|
||||
MipsLiveProcess::create(const std::string &nm, System *system, int stdin_fd,
|
||||
int stdout_fd, int stderr_fd, std::string executable,
|
||||
std::vector<std::string> &argv, std::vector<std::string> &envp)
|
||||
{
|
||||
MipsLiveProcess *process = NULL;
|
||||
|
||||
ObjectFile *objFile = createObjectFile(executable);
|
||||
if (objFile == NULL) {
|
||||
fatal("Can't load object file %s", executable);
|
||||
}
|
||||
|
||||
|
||||
if (objFile->getArch() != ObjectFile::Mips)
|
||||
fatal("Object file does not match architecture.");
|
||||
switch (objFile->getOpSys()) {
|
||||
case ObjectFile::Linux:
|
||||
process = new MipsLinuxProcess(nm, objFile, system,
|
||||
stdin_fd, stdout_fd, stderr_fd,
|
||||
argv, envp);
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("Unknown/unsupported operating system.");
|
||||
}
|
||||
|
||||
if (process == NULL)
|
||||
fatal("Unknown error creating process object.");
|
||||
return process;
|
||||
}
|
||||
|
||||
MipsLiveProcess::MipsLiveProcess(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)
|
||||
: LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd,
|
||||
argv, envp)
|
||||
{
|
||||
|
||||
// XXX all the below need to be updated for SPARC - Ali
|
||||
brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
|
||||
brk_point = roundUp(brk_point, VMPageSize);
|
||||
|
||||
// Set up stack. On Alpha, stack goes below text section. This
|
||||
// code should get moved to some architecture-specific spot.
|
||||
stack_base = objFile->textBase() - (409600+4096);
|
||||
|
||||
// Set up region for mmaps. Tru64 seems to start just above 0 and
|
||||
// grow up from there.
|
||||
mmap_start = mmap_end = 0x10000;
|
||||
|
||||
// Set pointer for next thread stack. Reserve 8M for main stack.
|
||||
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
MipsLiveProcess::startup()
|
||||
{
|
||||
argsInit(MachineBytes, VMPageSize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(MipsLiveProcess)
|
||||
|
||||
VectorParam<string> cmd;
|
||||
Param<string> executable;
|
||||
Param<string> input;
|
||||
Param<string> output;
|
||||
VectorParam<string> env;
|
||||
SimObjectParam<System *> system;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(MipsLiveProcess)
|
||||
|
||||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(MipsLiveProcess)
|
||||
|
||||
INIT_PARAM(cmd, "command line (executable plus arguments)"),
|
||||
INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
|
||||
INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
|
||||
INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
|
||||
INIT_PARAM(env, "environment settings"),
|
||||
INIT_PARAM(system, "system")
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(MipsLiveProcess)
|
||||
|
||||
|
||||
CREATE_SIM_OBJECT(MipsLiveProcess)
|
||||
{
|
||||
string in = input;
|
||||
string out = output;
|
||||
|
||||
// initialize file descriptors to default: same as simulator
|
||||
int stdin_fd, stdout_fd, stderr_fd;
|
||||
|
||||
if (in == "stdin" || in == "cin")
|
||||
stdin_fd = STDIN_FILENO;
|
||||
else
|
||||
stdin_fd = Process::openInputFile(input);
|
||||
|
||||
if (out == "stdout" || out == "cout")
|
||||
stdout_fd = STDOUT_FILENO;
|
||||
else if (out == "stderr" || out == "cerr")
|
||||
stdout_fd = STDERR_FILENO;
|
||||
else
|
||||
stdout_fd = Process::openOutputFile(out);
|
||||
|
||||
stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
|
||||
|
||||
return MipsLiveProcess::create(getInstanceName(), system,
|
||||
stdin_fd, stdout_fd, stderr_fd,
|
||||
(string)executable == "" ? cmd[0] : executable,
|
||||
cmd, env);
|
||||
}
|
||||
|
||||
|
||||
REGISTER_SIM_OBJECT("MipsLiveProcess", MipsLiveProcess)
|
||||
|
||||
|
||||
64
src/arch/mips/process.hh
Normal file
64
src/arch/mips/process.hh
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __MIPS_PROCESS_HH__
|
||||
#define __MIPS_PROCESS_HH__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "sim/process.hh"
|
||||
|
||||
class LiveProcess;
|
||||
class ObjectFile;
|
||||
class System;
|
||||
|
||||
class MipsLiveProcess : public LiveProcess
|
||||
{
|
||||
protected:
|
||||
MipsLiveProcess(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);
|
||||
|
||||
void startup();
|
||||
|
||||
public:
|
||||
// this function is used to create the LiveProcess object, since
|
||||
// we can't tell which subclass of LiveProcess to use until we
|
||||
// open and look at the object file.
|
||||
static MipsLiveProcess *create(const std::string &nm,
|
||||
System *_system,
|
||||
int stdin_fd, int stdout_fd, int stderr_fd,
|
||||
std::string executable,
|
||||
std::vector<std::string> &argv,
|
||||
std::vector<std::string> &envp);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // __MIPS_PROCESS_HH__
|
||||
159
src/arch/mips/regfile/float_regfile.hh
Normal file
159
src/arch/mips/regfile/float_regfile.hh
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_MIPS_FLOAT_REGFILE_HH__
|
||||
#define __ARCH_MIPS_FLOAT_REGFILE_HH__
|
||||
|
||||
#include "arch/mips/types.hh"
|
||||
#include "arch/mips/constants.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "config/full_system.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
#include "sim/faults.hh"
|
||||
#include "sim/host.hh"
|
||||
|
||||
class Checkpoint;
|
||||
class ExecContext;
|
||||
class Regfile;
|
||||
|
||||
namespace MipsISA
|
||||
{
|
||||
class FloatRegFile
|
||||
{
|
||||
protected:
|
||||
FloatReg32 regs[NumFloatRegs];
|
||||
|
||||
public:
|
||||
|
||||
void clear()
|
||||
{
|
||||
bzero(regs, sizeof(regs));
|
||||
}
|
||||
|
||||
double readReg(int floatReg, int width)
|
||||
{
|
||||
switch(width)
|
||||
{
|
||||
case SingleWidth:
|
||||
void *float_ptr = ®s[floatReg];
|
||||
return *(float *) float_ptr;
|
||||
|
||||
case DoubleWidth:
|
||||
uint64_t double_val = (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg];
|
||||
void *double_ptr = &double_val;
|
||||
return *(double *) double_ptr;
|
||||
|
||||
default:
|
||||
panic("Attempted to read a %d bit floating point register!", width);
|
||||
}
|
||||
}
|
||||
|
||||
FloatRegBits readRegBits(int floatReg, int width)
|
||||
{
|
||||
if (floatReg < NumFloatArchRegs - 1) {
|
||||
switch(width)
|
||||
{
|
||||
case SingleWidth:
|
||||
return regs[floatReg];
|
||||
|
||||
case DoubleWidth:
|
||||
return (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg];
|
||||
|
||||
default:
|
||||
panic("Attempted to read a %d bit floating point register!", width);
|
||||
}
|
||||
} else {
|
||||
if (width > SingleWidth)
|
||||
assert("Control Regs are only 32 bits wide");
|
||||
|
||||
return regs[floatReg];
|
||||
}
|
||||
}
|
||||
|
||||
Fault setReg(int floatReg, const FloatReg &val, int width)
|
||||
{
|
||||
|
||||
switch(width)
|
||||
{
|
||||
case SingleWidth:
|
||||
float temp = val;
|
||||
void *float_ptr = &temp;
|
||||
regs[floatReg] = *(FloatReg32 *) float_ptr;
|
||||
break;
|
||||
|
||||
case DoubleWidth:
|
||||
const void *double_ptr = &val;
|
||||
FloatReg64 temp_double = *(FloatReg64 *) double_ptr;
|
||||
regs[floatReg + 1] = temp_double >> 32;
|
||||
regs[floatReg] = temp_double;
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("Attempted to read a %d bit floating point register!", width);
|
||||
}
|
||||
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
switch(width)
|
||||
{
|
||||
case SingleWidth:
|
||||
regs[floatReg] = val;
|
||||
break;
|
||||
|
||||
case DoubleWidth:
|
||||
regs[floatReg + 1] = val >> 32;
|
||||
regs[floatReg] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("Attempted to read a %d bit floating point register!", width);
|
||||
}
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
enum MiscFloatRegNums {
|
||||
FIR = NumFloatArchRegs,
|
||||
FCCR,
|
||||
FEXR,
|
||||
FENR,
|
||||
FCSR
|
||||
};
|
||||
|
||||
} // namespace MipsISA
|
||||
|
||||
#endif
|
||||
73
src/arch/mips/regfile/int_regfile.hh
Normal file
73
src/arch/mips/regfile/int_regfile.hh
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_MIPS_INT_REGFILE_HH__
|
||||
#define __ARCH_MIPS_INT_REGFILE_HH__
|
||||
|
||||
#include "arch/mips/types.hh"
|
||||
#include "arch/mips/constants.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "sim/faults.hh"
|
||||
|
||||
class Checkpoint;
|
||||
class ExecContext;
|
||||
class Regfile;
|
||||
|
||||
namespace MipsISA
|
||||
{
|
||||
class IntRegFile
|
||||
{
|
||||
protected:
|
||||
IntReg regs[NumIntRegs];
|
||||
|
||||
public:
|
||||
IntReg readReg(int intReg)
|
||||
{
|
||||
return regs[intReg];
|
||||
}
|
||||
|
||||
Fault setReg(int intReg, const IntReg &val)
|
||||
{
|
||||
regs[intReg] = val;
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
};
|
||||
|
||||
enum MiscIntRegNums {
|
||||
HI = NumIntArchRegs,
|
||||
LO
|
||||
};
|
||||
|
||||
} // namespace MipsISA
|
||||
|
||||
#endif
|
||||
96
src/arch/mips/regfile/misc_regfile.hh
Normal file
96
src/arch/mips/regfile/misc_regfile.hh
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_MIPS_MISC_REGFILE_HH__
|
||||
#define __ARCH_MIPS_MISC_REGFILE_HH__
|
||||
|
||||
#include "arch/mips/types.hh"
|
||||
#include "arch/mips/constants.hh"
|
||||
#include "sim/faults.hh"
|
||||
|
||||
class Checkpoint;
|
||||
class ExecContext;
|
||||
class Regfile;
|
||||
|
||||
namespace MipsISA
|
||||
{
|
||||
class MiscRegFile {
|
||||
|
||||
protected:
|
||||
uint64_t fpcr; // floating point condition codes
|
||||
uint64_t uniq; // process-unique register
|
||||
bool lock_flag; // lock flag for LL/SC
|
||||
Addr lock_addr; // lock address for LL/SC
|
||||
|
||||
MiscReg miscRegFile[NumMiscRegs];
|
||||
|
||||
public:
|
||||
//These functions should be removed once the simplescalar cpu model
|
||||
//has been replaced.
|
||||
int getInstAsid();
|
||||
int getDataAsid();
|
||||
|
||||
void copyMiscRegs(ExecContext *xc);
|
||||
|
||||
MiscReg readReg(int misc_reg)
|
||||
{
|
||||
return miscRegFile[misc_reg];
|
||||
}
|
||||
|
||||
MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc)
|
||||
{
|
||||
return miscRegFile[misc_reg];
|
||||
}
|
||||
|
||||
Fault setReg(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
miscRegFile[misc_reg] = val; return NoFault;
|
||||
}
|
||||
|
||||
Fault setRegWithEffect(int misc_reg, const MiscReg &val,
|
||||
ExecContext *xc)
|
||||
{
|
||||
miscRegFile[misc_reg] = val; return NoFault;
|
||||
}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
void clearIprs() { }
|
||||
|
||||
protected:
|
||||
InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
|
||||
|
||||
private:
|
||||
MiscReg readIpr(int idx, Fault &fault, ExecContext *xc) { }
|
||||
|
||||
Fault setIpr(int idx, uint64_t val, ExecContext *xc) { }
|
||||
#endif
|
||||
friend class RegFile;
|
||||
};
|
||||
} // namespace MipsISA
|
||||
|
||||
#endif
|
||||
199
src/arch/mips/regfile/regfile.hh
Normal file
199
src/arch/mips/regfile/regfile.hh
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_MIPS_REGFILE_HH__
|
||||
#define __ARCH_MIPS_REGFILE_HH__
|
||||
|
||||
#include "arch/mips/types.hh"
|
||||
#include "arch/mips/constants.hh"
|
||||
#include "arch/mips/regfile/int_regfile.hh"
|
||||
#include "arch/mips/regfile/float_regfile.hh"
|
||||
#include "arch/mips/regfile/misc_regfile.hh"
|
||||
#include "sim/faults.hh"
|
||||
|
||||
class Checkpoint;
|
||||
class ExecContext;
|
||||
|
||||
namespace MipsISA
|
||||
{
|
||||
class RegFile {
|
||||
protected:
|
||||
IntRegFile intRegFile; // (signed) integer register file
|
||||
FloatRegFile floatRegFile; // floating point register file
|
||||
MiscRegFile miscRegFile; // control register file
|
||||
|
||||
public:
|
||||
|
||||
void clear()
|
||||
{
|
||||
bzero(&intRegFile, sizeof(intRegFile));
|
||||
bzero(&floatRegFile, sizeof(floatRegFile));
|
||||
bzero(&miscRegFile, sizeof(miscRegFile));
|
||||
}
|
||||
|
||||
MiscReg readMiscReg(int miscReg)
|
||||
{
|
||||
return miscRegFile.readReg(miscReg);
|
||||
}
|
||||
|
||||
MiscReg readMiscRegWithEffect(int miscReg,
|
||||
Fault &fault, ExecContext *xc)
|
||||
{
|
||||
fault = NoFault;
|
||||
return miscRegFile.readRegWithEffect(miscReg, fault, xc);
|
||||
}
|
||||
|
||||
Fault setMiscReg(int miscReg, const MiscReg &val)
|
||||
{
|
||||
return miscRegFile.setReg(miscReg, val);
|
||||
}
|
||||
|
||||
Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
|
||||
ExecContext * xc)
|
||||
{
|
||||
return miscRegFile.setRegWithEffect(miscReg, val, xc);
|
||||
}
|
||||
|
||||
FloatReg readFloatReg(int floatReg)
|
||||
{
|
||||
return floatRegFile.readReg(floatReg,SingleWidth);
|
||||
}
|
||||
|
||||
FloatReg readFloatReg(int floatReg, int width)
|
||||
{
|
||||
return floatRegFile.readReg(floatReg,width);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegBits(int floatReg)
|
||||
{
|
||||
return floatRegFile.readRegBits(floatReg,SingleWidth);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegBits(int floatReg, int width)
|
||||
{
|
||||
return floatRegFile.readRegBits(floatReg,width);
|
||||
}
|
||||
|
||||
Fault setFloatReg(int floatReg, const FloatReg &val)
|
||||
{
|
||||
return floatRegFile.setReg(floatReg, val, SingleWidth);
|
||||
}
|
||||
|
||||
Fault setFloatReg(int floatReg, const FloatReg &val, int width)
|
||||
{
|
||||
return floatRegFile.setReg(floatReg, val, width);
|
||||
}
|
||||
|
||||
Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
|
||||
{
|
||||
return floatRegFile.setRegBits(floatReg, val, SingleWidth);
|
||||
}
|
||||
|
||||
Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
|
||||
{
|
||||
return floatRegFile.setRegBits(floatReg, val, width);
|
||||
}
|
||||
|
||||
IntReg readIntReg(int intReg)
|
||||
{
|
||||
return intRegFile.readReg(intReg);
|
||||
}
|
||||
|
||||
Fault setIntReg(int intReg, const IntReg &val)
|
||||
{
|
||||
return intRegFile.setReg(intReg, val);
|
||||
}
|
||||
protected:
|
||||
|
||||
Addr pc; // program counter
|
||||
Addr npc; // next-cycle program counter
|
||||
Addr nnpc; // next-next-cycle program counter
|
||||
// used to implement branch delay slot
|
||||
// not real register
|
||||
public:
|
||||
Addr readPC()
|
||||
{
|
||||
return pc;
|
||||
}
|
||||
|
||||
void setPC(Addr val)
|
||||
{
|
||||
pc = val;
|
||||
}
|
||||
|
||||
Addr readNextPC()
|
||||
{
|
||||
return npc;
|
||||
}
|
||||
|
||||
void setNextPC(Addr val)
|
||||
{
|
||||
npc = val;
|
||||
}
|
||||
|
||||
Addr readNextNPC()
|
||||
{
|
||||
return nnpc;
|
||||
}
|
||||
|
||||
void setNextNPC(Addr val)
|
||||
{
|
||||
nnpc = val;
|
||||
}
|
||||
|
||||
|
||||
#if FULL_SYSTEM
|
||||
IntReg palregs[NumIntRegs]; // PAL shadow registers
|
||||
InternalProcReg ipr[NumInternalProcRegs]; // internal processor regs
|
||||
int intrflag; // interrupt flag
|
||||
bool pal_shadow; // using pal_shadow registers
|
||||
inline int instAsid() { return MIPS34K::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); }
|
||||
inline int dataAsid() { return MIPS34K::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); }
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
typedef int ContextParam;
|
||||
typedef int ContextVal;
|
||||
|
||||
void changeContext(ContextParam param, ContextVal val)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
void copyRegs(ExecContext *src, ExecContext *dest);
|
||||
|
||||
void copyMiscRegs(ExecContext *src, ExecContext *dest);
|
||||
|
||||
#if FULL_SYSTEM
|
||||
void copyIprs(ExecContext *src, ExecContext *dest);
|
||||
#endif
|
||||
} // namespace MipsISA
|
||||
|
||||
#endif
|
||||
119
src/arch/mips/stacktrace.hh
Normal file
119
src/arch/mips/stacktrace.hh
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ALPHA_STACKTRACE_HH__
|
||||
#define __ARCH_ALPHA_STACKTRACE_HH__
|
||||
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/static_inst.hh"
|
||||
|
||||
class ExecContext;
|
||||
class StackTrace;
|
||||
|
||||
class ProcessInfo
|
||||
{
|
||||
private:
|
||||
ExecContext *xc;
|
||||
|
||||
int thread_info_size;
|
||||
int task_struct_size;
|
||||
int task_off;
|
||||
int pid_off;
|
||||
int name_off;
|
||||
|
||||
public:
|
||||
ProcessInfo(ExecContext *_xc);
|
||||
|
||||
Addr task(Addr ksp) const;
|
||||
int pid(Addr ksp) const;
|
||||
std::string name(Addr ksp) const;
|
||||
};
|
||||
|
||||
class StackTrace
|
||||
{
|
||||
protected:
|
||||
typedef TheISA::MachInst MachInst;
|
||||
private:
|
||||
ExecContext *xc;
|
||||
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 ®, int &disp);
|
||||
bool decodeStack(MachInst inst, int &disp);
|
||||
|
||||
void trace(ExecContext *xc, bool is_call);
|
||||
|
||||
public:
|
||||
StackTrace();
|
||||
StackTrace(ExecContext *xc, StaticInstPtr inst);
|
||||
~StackTrace();
|
||||
|
||||
void clear()
|
||||
{
|
||||
xc = 0;
|
||||
stack.clear();
|
||||
}
|
||||
|
||||
bool valid() const { return xc != NULL; }
|
||||
bool trace(ExecContext *xc, 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(ExecContext *xc, StaticInstPtr inst)
|
||||
{
|
||||
if (!inst->isCall() && !inst->isReturn())
|
||||
return false;
|
||||
|
||||
if (valid())
|
||||
clear();
|
||||
|
||||
trace(xc, !inst->isReturn());
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // __ARCH_ALPHA_STACKTRACE_HH__
|
||||
92
src/arch/mips/types.hh
Normal file
92
src/arch/mips/types.hh
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_MIPS_TYPES_HH__
|
||||
#define __ARCH_MIPS_TYPES_HH__
|
||||
|
||||
#include "sim/host.hh"
|
||||
|
||||
namespace MipsISA
|
||||
{
|
||||
typedef uint32_t MachInst;
|
||||
typedef uint64_t ExtMachInst;
|
||||
typedef uint8_t RegIndex;
|
||||
|
||||
typedef uint32_t IntReg;
|
||||
|
||||
// floating point register file entry type
|
||||
typedef double FloatReg;
|
||||
typedef uint32_t FloatReg32;
|
||||
typedef uint64_t FloatReg64;
|
||||
typedef uint64_t FloatRegBits;
|
||||
|
||||
// cop-0/cop-1 system control register
|
||||
typedef uint64_t MiscReg;
|
||||
typedef uint64_t InternalProcReg;
|
||||
|
||||
typedef union {
|
||||
IntReg intreg;
|
||||
FloatReg fpreg;
|
||||
MiscReg ctrlreg;
|
||||
} AnyReg;
|
||||
|
||||
//used in FP convert & round function
|
||||
enum ConvertType{
|
||||
SINGLE_TO_DOUBLE,
|
||||
SINGLE_TO_WORD,
|
||||
SINGLE_TO_LONG,
|
||||
|
||||
DOUBLE_TO_SINGLE,
|
||||
DOUBLE_TO_WORD,
|
||||
DOUBLE_TO_LONG,
|
||||
|
||||
LONG_TO_SINGLE,
|
||||
LONG_TO_DOUBLE,
|
||||
LONG_TO_WORD,
|
||||
LONG_TO_PS,
|
||||
|
||||
WORD_TO_SINGLE,
|
||||
WORD_TO_DOUBLE,
|
||||
WORD_TO_LONG,
|
||||
WORD_TO_PS,
|
||||
|
||||
PL_TO_SINGLE,
|
||||
PU_TO_SINGLE
|
||||
};
|
||||
|
||||
//used in FP convert & round function
|
||||
enum RoundMode{
|
||||
RND_ZERO,
|
||||
RND_DOWN,
|
||||
RND_UP,
|
||||
RND_NEAREST
|
||||
};
|
||||
|
||||
} // namespace MipsISA
|
||||
|
||||
#endif
|
||||
44
src/arch/mips/utility.hh
Normal file
44
src/arch/mips/utility.hh
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Steve Reinhardt
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_MIPS_UTILITY_HH__
|
||||
#define __ARCH_MIPS_UTILITY_HH__
|
||||
|
||||
#include "arch/mips/types.hh"
|
||||
#include "arch/mips/constants.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "sim/host.hh"
|
||||
|
||||
namespace MipsISA {
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
84
src/arch/sparc/SConscript
Normal file
84
src/arch/sparc/SConscript
Normal file
@@ -0,0 +1,84 @@
|
||||
# -*- 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.
|
||||
|
||||
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
|
||||
''')
|
||||
|
||||
# Full-system sources
|
||||
full_system_sources = Split('''
|
||||
tlb.cc
|
||||
arguments.cc
|
||||
ev5.cc
|
||||
osfpal.cc
|
||||
stacktrace.cc
|
||||
vtophys.cc
|
||||
''')
|
||||
|
||||
# Syscall emulation (non-full-system) sources
|
||||
syscall_emulation_sources = Split('''
|
||||
linux/linux.cc
|
||||
linux/process.cc
|
||||
solaris/solaris.cc
|
||||
solaris/process.cc
|
||||
process.cc
|
||||
''')
|
||||
|
||||
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')
|
||||
255
src/arch/sparc/faults.cc
Normal file
255
src/arch/sparc/faults.cc
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arch/sparc/faults.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "base/trace.hh"
|
||||
|
||||
namespace SparcISA
|
||||
{
|
||||
|
||||
FaultName InternalProcessorError::_name = "intprocerr";
|
||||
TrapType InternalProcessorError::_trapType = 0x029;
|
||||
FaultPriority InternalProcessorError::_priority = 4;
|
||||
FaultStat InternalProcessorError::_count;
|
||||
|
||||
FaultName MemAddressNotAligned::_name = "unalign";
|
||||
TrapType MemAddressNotAligned::_trapType = 0x034;
|
||||
FaultPriority MemAddressNotAligned::_priority = 10;
|
||||
FaultStat MemAddressNotAligned::_count;
|
||||
|
||||
FaultName PowerOnReset::_name = "pow_reset";
|
||||
TrapType PowerOnReset::_trapType = 0x001;
|
||||
FaultPriority PowerOnReset::_priority = 0;
|
||||
FaultStat PowerOnReset::_count;
|
||||
|
||||
FaultName WatchDogReset::_name = "watch_dog_reset";
|
||||
TrapType WatchDogReset::_trapType = 0x002;
|
||||
FaultPriority WatchDogReset::_priority = 1;
|
||||
FaultStat WatchDogReset::_count;
|
||||
|
||||
FaultName ExternallyInitiatedReset::_name = "extern_reset";
|
||||
TrapType ExternallyInitiatedReset::_trapType = 0x003;
|
||||
FaultPriority ExternallyInitiatedReset::_priority = 1;
|
||||
FaultStat ExternallyInitiatedReset::_count;
|
||||
|
||||
FaultName SoftwareInitiatedReset::_name = "software_reset";
|
||||
TrapType SoftwareInitiatedReset::_trapType = 0x004;
|
||||
FaultPriority SoftwareInitiatedReset::_priority = 1;
|
||||
FaultStat SoftwareInitiatedReset::_count;
|
||||
|
||||
FaultName REDStateException::_name = "red_counte";
|
||||
TrapType REDStateException::_trapType = 0x005;
|
||||
FaultPriority REDStateException::_priority = 1;
|
||||
FaultStat REDStateException::_count;
|
||||
|
||||
FaultName InstructionAccessException::_name = "inst_access";
|
||||
TrapType InstructionAccessException::_trapType = 0x008;
|
||||
FaultPriority InstructionAccessException::_priority = 5;
|
||||
FaultStat InstructionAccessException::_count;
|
||||
|
||||
FaultName InstructionAccessMMUMiss::_name = "inst_mmu";
|
||||
TrapType InstructionAccessMMUMiss::_trapType = 0x009;
|
||||
FaultPriority InstructionAccessMMUMiss::_priority = 2;
|
||||
FaultStat InstructionAccessMMUMiss::_count;
|
||||
|
||||
FaultName InstructionAccessError::_name = "inst_error";
|
||||
TrapType InstructionAccessError::_trapType = 0x00A;
|
||||
FaultPriority InstructionAccessError::_priority = 3;
|
||||
FaultStat InstructionAccessError::_count;
|
||||
|
||||
FaultName IllegalInstruction::_name = "illegal_inst";
|
||||
TrapType IllegalInstruction::_trapType = 0x010;
|
||||
FaultPriority IllegalInstruction::_priority = 7;
|
||||
FaultStat IllegalInstruction::_count;
|
||||
|
||||
FaultName PrivilegedOpcode::_name = "priv_opcode";
|
||||
TrapType PrivilegedOpcode::_trapType = 0x011;
|
||||
FaultPriority PrivilegedOpcode::_priority = 6;
|
||||
FaultStat PrivilegedOpcode::_count;
|
||||
|
||||
FaultName UnimplementedLDD::_name = "unimp_ldd";
|
||||
TrapType UnimplementedLDD::_trapType = 0x012;
|
||||
FaultPriority UnimplementedLDD::_priority = 6;
|
||||
FaultStat UnimplementedLDD::_count;
|
||||
|
||||
FaultName UnimplementedSTD::_name = "unimp_std";
|
||||
TrapType UnimplementedSTD::_trapType = 0x013;
|
||||
FaultPriority UnimplementedSTD::_priority = 6;
|
||||
FaultStat UnimplementedSTD::_count;
|
||||
|
||||
FaultName FpDisabled::_name = "fp_disabled";
|
||||
TrapType FpDisabled::_trapType = 0x020;
|
||||
FaultPriority FpDisabled::_priority = 8;
|
||||
FaultStat FpDisabled::_count;
|
||||
|
||||
FaultName FpExceptionIEEE754::_name = "fp_754";
|
||||
TrapType FpExceptionIEEE754::_trapType = 0x021;
|
||||
FaultPriority FpExceptionIEEE754::_priority = 11;
|
||||
FaultStat FpExceptionIEEE754::_count;
|
||||
|
||||
FaultName FpExceptionOther::_name = "fp_other";
|
||||
TrapType FpExceptionOther::_trapType = 0x022;
|
||||
FaultPriority FpExceptionOther::_priority = 11;
|
||||
FaultStat FpExceptionOther::_count;
|
||||
|
||||
FaultName TagOverflow::_name = "tag_overflow";
|
||||
TrapType TagOverflow::_trapType = 0x023;
|
||||
FaultPriority TagOverflow::_priority = 14;
|
||||
FaultStat TagOverflow::_count;
|
||||
|
||||
FaultName DivisionByZero::_name = "div_by_zero";
|
||||
TrapType DivisionByZero::_trapType = 0x028;
|
||||
FaultPriority DivisionByZero::_priority = 15;
|
||||
FaultStat DivisionByZero::_count;
|
||||
|
||||
FaultName DataAccessException::_name = "data_access";
|
||||
TrapType DataAccessException::_trapType = 0x030;
|
||||
FaultPriority DataAccessException::_priority = 12;
|
||||
FaultStat DataAccessException::_count;
|
||||
|
||||
FaultName DataAccessMMUMiss::_name = "data_mmu";
|
||||
TrapType DataAccessMMUMiss::_trapType = 0x031;
|
||||
FaultPriority DataAccessMMUMiss::_priority = 12;
|
||||
FaultStat DataAccessMMUMiss::_count;
|
||||
|
||||
FaultName DataAccessError::_name = "data_error";
|
||||
TrapType DataAccessError::_trapType = 0x032;
|
||||
FaultPriority DataAccessError::_priority = 12;
|
||||
FaultStat DataAccessError::_count;
|
||||
|
||||
FaultName DataAccessProtection::_name = "data_protection";
|
||||
TrapType DataAccessProtection::_trapType = 0x033;
|
||||
FaultPriority DataAccessProtection::_priority = 12;
|
||||
FaultStat DataAccessProtection::_count;
|
||||
|
||||
FaultName LDDFMemAddressNotAligned::_name = "unalign_lddf";
|
||||
TrapType LDDFMemAddressNotAligned::_trapType = 0x035;
|
||||
FaultPriority LDDFMemAddressNotAligned::_priority = 10;
|
||||
FaultStat LDDFMemAddressNotAligned::_count;
|
||||
|
||||
FaultName STDFMemAddressNotAligned::_name = "unalign_stdf";
|
||||
TrapType STDFMemAddressNotAligned::_trapType = 0x036;
|
||||
FaultPriority STDFMemAddressNotAligned::_priority = 10;
|
||||
FaultStat STDFMemAddressNotAligned::_count;
|
||||
|
||||
FaultName PrivilegedAction::_name = "priv_action";
|
||||
TrapType PrivilegedAction::_trapType = 0x037;
|
||||
FaultPriority PrivilegedAction::_priority = 11;
|
||||
FaultStat PrivilegedAction::_count;
|
||||
|
||||
FaultName LDQFMemAddressNotAligned::_name = "unalign_ldqf";
|
||||
TrapType LDQFMemAddressNotAligned::_trapType = 0x038;
|
||||
FaultPriority LDQFMemAddressNotAligned::_priority = 10;
|
||||
FaultStat LDQFMemAddressNotAligned::_count;
|
||||
|
||||
FaultName STQFMemAddressNotAligned::_name = "unalign_stqf";
|
||||
TrapType STQFMemAddressNotAligned::_trapType = 0x039;
|
||||
FaultPriority STQFMemAddressNotAligned::_priority = 10;
|
||||
FaultStat STQFMemAddressNotAligned::_count;
|
||||
|
||||
FaultName AsyncDataError::_name = "async_data";
|
||||
TrapType AsyncDataError::_trapType = 0x040;
|
||||
FaultPriority AsyncDataError::_priority = 2;
|
||||
FaultStat AsyncDataError::_count;
|
||||
|
||||
FaultName CleanWindow::_name = "clean_win";
|
||||
TrapType CleanWindow::_trapType = 0x024;
|
||||
FaultPriority CleanWindow::_priority = 10;
|
||||
FaultStat CleanWindow::_count;
|
||||
|
||||
//The enumerated faults
|
||||
|
||||
FaultName InterruptLevelN::_name = "interrupt_n";
|
||||
TrapType InterruptLevelN::_baseTrapType = 0x041;
|
||||
FaultStat InterruptLevelN::_count;
|
||||
|
||||
FaultName SpillNNormal::_name = "spill_n_normal";
|
||||
TrapType SpillNNormal::_baseTrapType = 0x080;
|
||||
FaultPriority SpillNNormal::_priority = 9;
|
||||
FaultStat SpillNNormal::_count;
|
||||
|
||||
FaultName SpillNOther::_name = "spill_n_other";
|
||||
TrapType SpillNOther::_baseTrapType = 0x0A0;
|
||||
FaultPriority SpillNOther::_priority = 9;
|
||||
FaultStat SpillNOther::_count;
|
||||
|
||||
FaultName FillNNormal::_name = "fill_n_normal";
|
||||
TrapType FillNNormal::_baseTrapType = 0x0C0;
|
||||
FaultPriority FillNNormal::_priority = 9;
|
||||
FaultStat FillNNormal::_count;
|
||||
|
||||
FaultName FillNOther::_name = "fill_n_other";
|
||||
TrapType FillNOther::_baseTrapType = 0x0E0;
|
||||
FaultPriority FillNOther::_priority = 9;
|
||||
FaultStat FillNOther::_count;
|
||||
|
||||
FaultName TrapInstruction::_name = "trap_inst_n";
|
||||
TrapType TrapInstruction::_baseTrapType = 0x100;
|
||||
FaultPriority TrapInstruction::_priority = 16;
|
||||
FaultStat TrapInstruction::_count;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
|
||||
void SparcFault::invoke(ExecContext * xc)
|
||||
{
|
||||
FaultBase::invoke(xc);
|
||||
countStat()++;
|
||||
|
||||
//Use the SPARC trap state machine
|
||||
/*// exception restart address
|
||||
if (setRestartAddress() || !xc->inPalMode())
|
||||
xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->regs.pc);
|
||||
|
||||
if (skipFaultingInstruction()) {
|
||||
// traps... skip faulting instruction.
|
||||
xc->setMiscReg(AlphaISA::IPR_EXC_ADDR,
|
||||
xc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4);
|
||||
}
|
||||
|
||||
if (!xc->inPalMode())
|
||||
AlphaISA::swap_palshadow(&(xc->regs), true);
|
||||
|
||||
xc->regs.pc = xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect();
|
||||
xc->regs.npc = xc->regs.pc + sizeof(MachInst);*/
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
|
||||
void TrapInstruction::invoke(ExecContext * xc)
|
||||
{
|
||||
xc->syscall(syscall_num);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace SparcISA
|
||||
|
||||
591
src/arch/sparc/faults.hh
Normal file
591
src/arch/sparc/faults.hh
Normal file
@@ -0,0 +1,591 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ALPHA_FAULTS_HH__
|
||||
#define __ALPHA_FAULTS_HH__
|
||||
|
||||
#include "sim/faults.hh"
|
||||
|
||||
// The design of the "name" and "vect" functions is in sim/faults.hh
|
||||
|
||||
namespace SparcISA
|
||||
{
|
||||
|
||||
typedef const uint32_t TrapType;
|
||||
typedef const uint32_t FaultPriority;
|
||||
|
||||
class SparcFault : public FaultBase
|
||||
{
|
||||
public:
|
||||
#if FULL_SYSTEM
|
||||
void invoke(ExecContext * xc);
|
||||
#endif
|
||||
virtual TrapType trapType() = 0;
|
||||
virtual FaultPriority priority() = 0;
|
||||
virtual FaultStat & countStat() = 0;
|
||||
};
|
||||
|
||||
class InternalProcessorError : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
bool isMachineCheckFault() {return true;}
|
||||
};
|
||||
|
||||
class MemAddressNotAligned : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
bool isAlignmentFault() {return true;}
|
||||
};
|
||||
|
||||
static inline Fault genMachineCheckFault()
|
||||
{
|
||||
return new InternalProcessorError;
|
||||
}
|
||||
|
||||
static inline Fault genAlignmentFault()
|
||||
{
|
||||
return new MemAddressNotAligned;
|
||||
}
|
||||
|
||||
class PowerOnReset : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class WatchDogReset : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class ExternallyInitiatedReset : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class SoftwareInitiatedReset : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class REDStateException : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class InstructionAccessException : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class InstructionAccessMMUMiss : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class InstructionAccessError : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class IllegalInstruction : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class PrivilegedOpcode : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class UnimplementedLDD : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class UnimplementedSTD : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class FpDisabled : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class FpExceptionIEEE754 : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class FpExceptionOther : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class TagOverflow : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class DivisionByZero : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class DataAccessException : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class DataAccessMMUMiss : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class DataAccessError : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class DataAccessProtection : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class LDDFMemAddressNotAligned : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class STDFMemAddressNotAligned : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class PrivilegedAction : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class LDQFMemAddressNotAligned : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class STQFMemAddressNotAligned : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class AsyncDataError : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class CleanWindow : public SparcFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _trapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
TrapType trapType() {return _trapType;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class EnumeratedFault : public SparcFault
|
||||
{
|
||||
protected:
|
||||
uint32_t _n;
|
||||
virtual TrapType baseTrapType() = 0;
|
||||
public:
|
||||
EnumeratedFault(uint32_t n) : SparcFault() {_n = n;}
|
||||
TrapType trapType() {return baseTrapType() + _n;}
|
||||
};
|
||||
|
||||
class InterruptLevelN : public EnumeratedFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _baseTrapType;
|
||||
static FaultStat _count;
|
||||
TrapType baseTrapType() {return _baseTrapType;}
|
||||
public:
|
||||
InterruptLevelN(uint32_t n) : EnumeratedFault(n) {;}
|
||||
FaultName name() {return _name;}
|
||||
FaultPriority priority() {return 32 - _n;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class SpillNNormal : public EnumeratedFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _baseTrapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
TrapType baseTrapType() {return _baseTrapType;}
|
||||
public:
|
||||
SpillNNormal(uint32_t n) : EnumeratedFault(n) {;}
|
||||
FaultName name() {return _name;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class SpillNOther : public EnumeratedFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _baseTrapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
TrapType baseTrapType() {return _baseTrapType;}
|
||||
public:
|
||||
SpillNOther(uint32_t n) : EnumeratedFault(n) {;}
|
||||
FaultName name() {return _name;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class FillNNormal : public EnumeratedFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _baseTrapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
TrapType baseTrapType() {return _baseTrapType;}
|
||||
public:
|
||||
FillNNormal(uint32_t n) : EnumeratedFault(n) {;}
|
||||
FaultName name() {return _name;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class FillNOther : public EnumeratedFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _baseTrapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
TrapType baseTrapType() {return _baseTrapType;}
|
||||
public:
|
||||
FillNOther(uint32_t n) : EnumeratedFault(n) {;}
|
||||
FaultName name() {return _name;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class TrapInstruction : public EnumeratedFault
|
||||
{
|
||||
private:
|
||||
static FaultName _name;
|
||||
static TrapType _baseTrapType;
|
||||
static FaultPriority _priority;
|
||||
static FaultStat _count;
|
||||
uint64_t syscall_num;
|
||||
TrapType baseTrapType() {return _baseTrapType;}
|
||||
public:
|
||||
TrapInstruction(uint32_t n, uint64_t syscall) :
|
||||
EnumeratedFault(n), syscall_num(syscall) {;}
|
||||
FaultName name() {return _name;}
|
||||
FaultPriority priority() {return _priority;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
#if !FULL_SYSTEM
|
||||
void invoke(ExecContext * xc);
|
||||
#endif
|
||||
};
|
||||
|
||||
} // SparcISA namespace
|
||||
|
||||
#endif // __FAULTS_HH__
|
||||
252
src/arch/sparc/isa/base.isa
Normal file
252
src/arch/sparc/isa/base.isa
Normal file
@@ -0,0 +1,252 @@
|
||||
// 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
|
||||
// Gabe Black
|
||||
// Steve Reinhardt
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Base class for sparc instructions, and some support functions
|
||||
//
|
||||
|
||||
output header {{
|
||||
|
||||
union CondCodes
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t c:1;
|
||||
uint8_t v:1;
|
||||
uint8_t z:1;
|
||||
uint8_t n:1;
|
||||
};
|
||||
uint32_t bits;
|
||||
};
|
||||
|
||||
enum CondTest
|
||||
{
|
||||
Always=0x8,
|
||||
Never=0x0,
|
||||
NotEqual=0x9,
|
||||
Equal=0x1,
|
||||
Greater=0xA,
|
||||
LessOrEqual=0x2,
|
||||
GreaterOrEqual=0xB,
|
||||
Less=0x3,
|
||||
GreaterUnsigned=0xC,
|
||||
LessOrEqualUnsigned=0x4,
|
||||
CarryClear=0xD,
|
||||
CarrySet=0x5,
|
||||
Positive=0xE,
|
||||
Negative=0x6,
|
||||
OverflowClear=0xF,
|
||||
OverflowSet=0x7
|
||||
};
|
||||
|
||||
extern char * CondTestAbbrev[];
|
||||
|
||||
/**
|
||||
* Base class for all SPARC static instructions.
|
||||
*/
|
||||
class SparcStaticInst : public StaticInst
|
||||
{
|
||||
protected:
|
||||
// Constructor.
|
||||
SparcStaticInst(const char *mnem,
|
||||
MachInst _machInst, OpClass __opClass)
|
||||
: StaticInst(mnem, _machInst, __opClass)
|
||||
{
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const;
|
||||
|
||||
void printReg(std::ostream &os, int reg) const;
|
||||
};
|
||||
|
||||
bool passesCondition(uint32_t codes, uint32_t condition);
|
||||
|
||||
inline int64_t sign_ext(uint64_t data, int origWidth)
|
||||
{
|
||||
int shiftAmount = 64 - origWidth;
|
||||
return (((int64_t)data) << shiftAmount) >> shiftAmount;
|
||||
}
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
|
||||
char * CondTestAbbrev[] =
|
||||
{
|
||||
"nev", //Never
|
||||
"e", //Equal
|
||||
"le", //Less or Equal
|
||||
"l", //Less
|
||||
"leu", //Less or Equal Unsigned
|
||||
"c", //Carry set
|
||||
"n", //Negative
|
||||
"o", //Overflow set
|
||||
"a", //Always
|
||||
"ne", //Not Equal
|
||||
"g", //Greater
|
||||
"ge", //Greater or Equal
|
||||
"gu", //Greater Unsigned
|
||||
"cc", //Carry clear
|
||||
"p", //Positive
|
||||
"oc" //Overflow Clear
|
||||
};
|
||||
}};
|
||||
|
||||
def template ROrImmDecode {{
|
||||
{
|
||||
return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
|
||||
: (SparcStaticInst *)(new %(class_name)s(machInst)));
|
||||
}
|
||||
}};
|
||||
|
||||
let {{
|
||||
def splitOutImm(code):
|
||||
matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?')
|
||||
rOrImmMatch = matcher.search(code)
|
||||
if (rOrImmMatch == None):
|
||||
return (False, code, '', '', '')
|
||||
rString = rOrImmMatch.group("rNum")
|
||||
if (rOrImmMatch.group("typeQual") != None):
|
||||
rString += rOrImmMatch.group("typeQual")
|
||||
iString = rOrImmMatch.group("iNum")
|
||||
orig_code = code
|
||||
code = matcher.sub('Rs' + rString, orig_code)
|
||||
imm_code = matcher.sub('imm', orig_code)
|
||||
return (True, code, imm_code, rString, iString)
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
|
||||
inline void printMnemonic(std::ostream &os, const char * mnemonic)
|
||||
{
|
||||
ccprintf(os, "\t%s ", mnemonic);
|
||||
}
|
||||
|
||||
void
|
||||
SparcStaticInst::printReg(std::ostream &os, int reg) const
|
||||
{
|
||||
const int MaxGlobal = 8;
|
||||
const int MaxOutput = 16;
|
||||
const int MaxLocal = 24;
|
||||
const int MaxInput = 32;
|
||||
if (reg == FramePointerReg)
|
||||
ccprintf(os, "%%fp");
|
||||
else if (reg == StackPointerReg)
|
||||
ccprintf(os, "%%sp");
|
||||
else if(reg < MaxGlobal)
|
||||
ccprintf(os, "%%g%d", reg);
|
||||
else if(reg < MaxOutput)
|
||||
ccprintf(os, "%%o%d", reg - MaxGlobal);
|
||||
else if(reg < MaxLocal)
|
||||
ccprintf(os, "%%l%d", reg - MaxOutput);
|
||||
else if(reg < MaxInput)
|
||||
ccprintf(os, "%%i%d", reg - MaxLocal);
|
||||
else {
|
||||
ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
|
||||
}
|
||||
}
|
||||
|
||||
std::string SparcStaticInst::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
printMnemonic(ss, mnemonic);
|
||||
|
||||
// just print the first two source regs... if there's
|
||||
// a third one, it's a read-modify-write dest (Rc),
|
||||
// e.g. for CMOVxx
|
||||
if(_numSrcRegs > 0)
|
||||
{
|
||||
printReg(ss, _srcRegIdx[0]);
|
||||
}
|
||||
if(_numSrcRegs > 1)
|
||||
{
|
||||
ss << ",";
|
||||
printReg(ss, _srcRegIdx[1]);
|
||||
}
|
||||
|
||||
// just print the first dest... if there's a second one,
|
||||
// it's generally implicit
|
||||
if(_numDestRegs > 0)
|
||||
{
|
||||
if(_numSrcRegs > 0)
|
||||
ss << ",";
|
||||
printReg(ss, _destRegIdx[0]);
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
bool passesCondition(uint32_t codes, uint32_t condition)
|
||||
{
|
||||
CondCodes condCodes;
|
||||
condCodes.bits = codes;
|
||||
switch(condition)
|
||||
{
|
||||
case Always:
|
||||
return true;
|
||||
case Never:
|
||||
return false;
|
||||
case NotEqual:
|
||||
return !condCodes.z;
|
||||
case Equal:
|
||||
return condCodes.z;
|
||||
case Greater:
|
||||
return !(condCodes.z | (condCodes.n ^ condCodes.v));
|
||||
case LessOrEqual:
|
||||
return condCodes.z | (condCodes.n ^ condCodes.v);
|
||||
case GreaterOrEqual:
|
||||
return !(condCodes.n ^ condCodes.v);
|
||||
case Less:
|
||||
return (condCodes.n ^ condCodes.v);
|
||||
case GreaterUnsigned:
|
||||
return !(condCodes.c | condCodes.z);
|
||||
case LessOrEqualUnsigned:
|
||||
return (condCodes.c | condCodes.z);
|
||||
case CarryClear:
|
||||
return !condCodes.c;
|
||||
case CarrySet:
|
||||
return condCodes.c;
|
||||
case Positive:
|
||||
return !condCodes.n;
|
||||
case Negative:
|
||||
return condCodes.n;
|
||||
case OverflowClear:
|
||||
return !condCodes.v;
|
||||
case OverflowSet:
|
||||
return condCodes.v;
|
||||
}
|
||||
panic("Tried testing condition nonexistant "
|
||||
"condition code %d", condition);
|
||||
}
|
||||
}};
|
||||
|
||||
78
src/arch/sparc/isa/bitfields.isa
Normal file
78
src/arch/sparc/isa/bitfields.isa
Normal file
@@ -0,0 +1,78 @@
|
||||
// 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
|
||||
// Gabe Black
|
||||
// Steve Reinhardt
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bitfield definitions.
|
||||
//
|
||||
|
||||
// Bitfields are shared liberally between instruction formats, so they are
|
||||
// simply defined alphabetically
|
||||
|
||||
def bitfield A <29>;
|
||||
def bitfield BPCC <21:20>; // for BPcc & FBPcc
|
||||
def bitfield FCMPCC <26:56>; // for FCMP & FCMPEa
|
||||
def bitfield FMOVCC <13:11>; // for FMOVcc
|
||||
def bitfield CC <12:11>; // for MOVcc & Tcc
|
||||
def bitfield MOVCC3 <18>; // also for MOVcc
|
||||
def bitfield CMASK <6:4>;
|
||||
def bitfield COND2 <28:25>;
|
||||
def bitfield COND4 <17:14>;
|
||||
def bitfield D16HI <21:20>;
|
||||
def bitfield D16LO <13:0>;
|
||||
def bitfield DISP19 <18:0>;
|
||||
def bitfield DISP22 <21:0>;
|
||||
def bitfield DISP30 <29:0>;
|
||||
def bitfield FCN <29:26>;
|
||||
def bitfield I <13>;
|
||||
def bitfield IMM_ASI <12:5>;
|
||||
def bitfield IMM22 <21:0>;
|
||||
def bitfield MMASK <3:0>;
|
||||
def bitfield OP <31:30>;
|
||||
def bitfield OP2 <24:22>;
|
||||
def bitfield OP3 <24:19>;
|
||||
def bitfield OPF <13:5>;
|
||||
def bitfield OPF_CC <13:11>;
|
||||
def bitfield OPF_LOW5 <9:5>;
|
||||
def bitfield OPF_LOW6 <10:5>;
|
||||
def bitfield P <19>;
|
||||
def bitfield RCOND2 <27:25>;
|
||||
def bitfield RCOND3 <12:10>;
|
||||
def bitfield RCOND4 <12:10>;
|
||||
def bitfield RD <29:25>;
|
||||
def bitfield RS1 <18:14>;
|
||||
def bitfield RS2 <4:0>;
|
||||
def bitfield SHCNT32 <4:0>;
|
||||
def bitfield SHCNT64 <5:0>;
|
||||
def bitfield SIMM10 <9:0>;
|
||||
def bitfield SIMM11 <10:0>;
|
||||
def bitfield SIMM13 <12:0>;
|
||||
def bitfield SW_TRAP <7:0>;
|
||||
def bitfield X <12>;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user