summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-04-06 10:19:36 -0700
committerGabe Black <gblack@eecs.umich.edu>2009-04-06 10:19:36 -0700
commitd080581db1f9ee4e1e6d07d2b01c13c67908a391 (patch)
treecc484b289fa5a30c4631f9faa1d8b456bffeebfc /src/arch
parent7a7c4c5fca83a8d47c7e71c9c080a882ebe204a9 (diff)
parent639cb0a42d953ee32bc7e96b0cdfa96cd40e9fc1 (diff)
downloadgem5-d080581db1f9ee4e1e6d07d2b01c13c67908a391.tar.xz
Merge ARM into the head. ARM will compile but may not actually work.
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/SConscript7
-rw-r--r--src/arch/alpha/AlphaInterrupts.py33
-rw-r--r--src/arch/alpha/AlphaTLB.py13
-rw-r--r--src/arch/alpha/SConscript2
-rw-r--r--src/arch/alpha/SConsopts2
-rw-r--r--src/arch/alpha/aout_machdep.h42
-rw-r--r--src/arch/alpha/ev5.cc383
-rw-r--r--src/arch/alpha/ev5.hh25
-rw-r--r--src/arch/alpha/faults.cc60
-rw-r--r--src/arch/alpha/faults.hh75
-rw-r--r--src/arch/alpha/floatregfile.cc30
-rw-r--r--src/arch/alpha/floatregfile.hh41
-rw-r--r--src/arch/alpha/freebsd/system.cc8
-rw-r--r--src/arch/alpha/freebsd/system.hh1
-rw-r--r--src/arch/alpha/idle_event.cc9
-rw-r--r--src/arch/alpha/interrupts.cc37
-rw-r--r--src/arch/alpha/interrupts.hh239
-rw-r--r--src/arch/alpha/intregfile.cc53
-rw-r--r--src/arch/alpha/intregfile.hh57
-rw-r--r--src/arch/alpha/ipr.cc210
-rw-r--r--src/arch/alpha/ipr.hh402
-rw-r--r--src/arch/alpha/isa/decoder.isa122
-rw-r--r--src/arch/alpha/isa/fp.isa4
-rw-r--r--src/arch/alpha/isa/main.isa9
-rw-r--r--src/arch/alpha/isa/mem.isa5
-rw-r--r--src/arch/alpha/isa/pal.isa10
-rw-r--r--src/arch/alpha/isa_traits.hh254
-rw-r--r--src/arch/alpha/kernel_stats.cc6
-rw-r--r--src/arch/alpha/kernel_stats.hh16
-rw-r--r--src/arch/alpha/linux/linux.cc49
-rw-r--r--src/arch/alpha/linux/linux.hh50
-rw-r--r--src/arch/alpha/linux/process.cc36
-rw-r--r--src/arch/alpha/linux/process.hh1
-rw-r--r--src/arch/alpha/linux/system.cc3
-rw-r--r--src/arch/alpha/linux/system.hh12
-rw-r--r--src/arch/alpha/linux/threadinfo.hh6
-rw-r--r--src/arch/alpha/locked_mem.hh10
-rw-r--r--src/arch/alpha/microcode_rom.hh (renamed from src/arch/alpha/syscallreturn.hh)31
-rw-r--r--src/arch/alpha/miscregfile.cc208
-rw-r--r--src/arch/alpha/miscregfile.hh116
-rw-r--r--src/arch/alpha/mmaped_ipr.hh5
-rw-r--r--src/arch/alpha/osfpal.cc522
-rw-r--r--src/arch/alpha/osfpal.hh6
-rw-r--r--src/arch/alpha/pagetable.cc55
-rw-r--r--src/arch/alpha/pagetable.hh186
-rw-r--r--src/arch/alpha/predecoder.hh114
-rw-r--r--src/arch/alpha/process.cc165
-rw-r--r--src/arch/alpha/process.hh22
-rw-r--r--src/arch/alpha/regfile.cc103
-rw-r--r--src/arch/alpha/regfile.hh270
-rw-r--r--src/arch/alpha/remote_gdb.cc101
-rw-r--r--src/arch/alpha/remote_gdb.hh40
-rw-r--r--src/arch/alpha/stacktrace.cc516
-rw-r--r--src/arch/alpha/stacktrace.hh128
-rw-r--r--src/arch/alpha/system.cc25
-rw-r--r--src/arch/alpha/system.hh16
-rw-r--r--src/arch/alpha/tlb.cc102
-rw-r--r--src/arch/alpha/tlb.hh212
-rw-r--r--src/arch/alpha/tru64/process.cc68
-rw-r--r--src/arch/alpha/tru64/process.hh9
-rw-r--r--src/arch/alpha/tru64/tru64.cc40
-rw-r--r--src/arch/alpha/tru64/tru64.hh53
-rw-r--r--src/arch/alpha/types.hh62
-rw-r--r--src/arch/alpha/utility.cc16
-rw-r--r--src/arch/alpha/utility.hh232
-rw-r--r--src/arch/alpha/vtophys.cc36
-rw-r--r--src/arch/alpha/vtophys.hh11
-rw-r--r--src/arch/arm/ArmTLB.py12
-rw-r--r--src/arch/arm/isa_traits.hh3
-rw-r--r--src/arch/arm/linux/process.cc6
-rw-r--r--src/arch/arm/process.cc36
-rw-r--r--src/arch/arm/process.hh3
-rw-r--r--src/arch/arm/regfile/regfile.cc4
-rw-r--r--src/arch/arm/regfile/regfile.hh9
-rw-r--r--src/arch/arm/tlb.cc24
-rw-r--r--src/arch/arm/tlb.hh39
-rwxr-xr-xsrc/arch/isa_parser.py10
-rw-r--r--src/arch/isa_specific.hh2
-rw-r--r--src/arch/micro_asm.py7
-rw-r--r--src/arch/mips/MipsInterrupts.py33
-rw-r--r--src/arch/mips/MipsTLB.py17
-rw-r--r--src/arch/mips/SConscript1
-rwxr-xr-xsrc/arch/mips/bare_iron/system.hh2
-rwxr-xr-xsrc/arch/mips/dsp.cc989
-rwxr-xr-xsrc/arch/mips/dsp.hh285
-rw-r--r--src/arch/mips/idle_event.cc2
-rwxr-xr-xsrc/arch/mips/interrupts.cc18
-rwxr-xr-xsrc/arch/mips/interrupts.hh32
-rw-r--r--src/arch/mips/isa/decoder.isa32
-rw-r--r--src/arch/mips/isa/formats/mem.isa6
-rw-r--r--src/arch/mips/isa/formats/mt.isa4
-rw-r--r--src/arch/mips/isa/formats/util.isa1
-rw-r--r--src/arch/mips/isa_traits.hh28
-rw-r--r--src/arch/mips/linux/linux.cc40
-rw-r--r--src/arch/mips/linux/linux.hh61
-rw-r--r--src/arch/mips/linux/process.cc32
-rw-r--r--src/arch/mips/linux/system.cc1
-rw-r--r--src/arch/mips/linux/system.hh5
-rw-r--r--src/arch/mips/linux/threadinfo.hh4
-rw-r--r--src/arch/mips/locked_mem.hh23
-rw-r--r--src/arch/mips/microcode_rom.hh (renamed from src/arch/mips/syscallreturn.hh)26
-rwxr-xr-xsrc/arch/mips/mips_core_specific.cc4
-rwxr-xr-xsrc/arch/mips/mt.hh13
-rwxr-xr-xsrc/arch/mips/pagetable.hh4
-rw-r--r--src/arch/mips/process.cc34
-rw-r--r--src/arch/mips/process.hh4
-rw-r--r--src/arch/mips/regfile.cc12
-rw-r--r--src/arch/mips/regfile/float_regfile.hh5
-rw-r--r--src/arch/mips/regfile/int_regfile.cc51
-rw-r--r--src/arch/mips/regfile/int_regfile.hh8
-rw-r--r--[-rwxr-xr-x]src/arch/mips/regfile/misc_regfile.cc261
-rw-r--r--src/arch/mips/regfile/misc_regfile.hh8
-rw-r--r--src/arch/mips/regfile/regfile.cc5
-rw-r--r--src/arch/mips/regfile/regfile.hh24
-rw-r--r--src/arch/mips/stacktrace.cc6
-rw-r--r--src/arch/mips/stacktrace.hh2
-rwxr-xr-xsrc/arch/mips/system.cc8
-rw-r--r--src/arch/mips/tlb.cc54
-rw-r--r--src/arch/mips/tlb.hh36
-rw-r--r--src/arch/mips/types.hh3
-rw-r--r--src/arch/mips/utility.cc7
-rw-r--r--src/arch/sparc/SConscript5
-rw-r--r--src/arch/sparc/SparcInterrupts.py33
-rw-r--r--src/arch/sparc/SparcTLB.py13
-rw-r--r--src/arch/sparc/faults.cc2
-rw-r--r--src/arch/sparc/floatregfile.cc38
-rw-r--r--src/arch/sparc/floatregfile.hh2
-rw-r--r--src/arch/sparc/interrupts.cc37
-rw-r--r--src/arch/sparc/interrupts.hh59
-rw-r--r--src/arch/sparc/intregfile.cc102
-rw-r--r--src/arch/sparc/intregfile.hh44
-rw-r--r--src/arch/sparc/isa/decoder.isa18
-rw-r--r--src/arch/sparc/isa/formats/mem/basicmem.isa10
-rw-r--r--src/arch/sparc/isa/formats/mem/swap.isa3
-rw-r--r--src/arch/sparc/isa/formats/mem/util.isa23
-rw-r--r--src/arch/sparc/isa_traits.hh10
-rw-r--r--src/arch/sparc/linux/linux.cc40
-rw-r--r--src/arch/sparc/linux/linux.hh30
-rw-r--r--src/arch/sparc/linux/process.cc4
-rw-r--r--src/arch/sparc/linux/process.hh1
-rw-r--r--src/arch/sparc/linux/syscalls.cc27
-rw-r--r--src/arch/sparc/microcode_rom.hh (renamed from src/arch/sparc/syscallreturn.hh)37
-rw-r--r--src/arch/sparc/miscregfile.cc57
-rw-r--r--src/arch/sparc/miscregfile.hh64
-rw-r--r--src/arch/sparc/pagetable.hh127
-rw-r--r--src/arch/sparc/process.cc145
-rw-r--r--src/arch/sparc/process.hh27
-rw-r--r--src/arch/sparc/regfile.cc33
-rw-r--r--src/arch/sparc/regfile.hh19
-rw-r--r--src/arch/sparc/remote_gdb.cc28
-rw-r--r--src/arch/sparc/solaris/process.cc10
-rw-r--r--src/arch/sparc/solaris/solaris.cc52
-rw-r--r--src/arch/sparc/solaris/solaris.hh20
-rw-r--r--src/arch/sparc/sparc_traits.hh4
-rw-r--r--src/arch/sparc/stacktrace.cc6
-rw-r--r--src/arch/sparc/stacktrace.hh2
-rw-r--r--src/arch/sparc/tlb.cc165
-rw-r--r--src/arch/sparc/tlb.hh15
-rw-r--r--src/arch/sparc/tlb_map.hh3
-rw-r--r--src/arch/sparc/types.hh8
-rw-r--r--src/arch/sparc/ua2005.cc115
-rw-r--r--src/arch/sparc/utility.cc6
-rw-r--r--src/arch/sparc/vtophys.cc162
-rw-r--r--src/arch/x86/SConscript16
-rw-r--r--src/arch/x86/SConsopts45
-rw-r--r--src/arch/x86/X86LocalApic.py36
-rw-r--r--src/arch/x86/X86System.py19
-rw-r--r--src/arch/x86/X86TLB.py17
-rw-r--r--src/arch/x86/apicregs.hh91
-rw-r--r--src/arch/x86/bios/ACPI.py99
-rw-r--r--src/arch/x86/bios/E820.py71
-rw-r--r--src/arch/x86/bios/IntelMP.py242
-rw-r--r--src/arch/x86/bios/SConscript77
-rw-r--r--src/arch/x86/bios/SMBios.py140
-rw-r--r--src/arch/x86/bios/acpi.cc109
-rw-r--r--src/arch/x86/bios/acpi.hh147
-rw-r--r--src/arch/x86/bios/e820.cc103
-rw-r--r--src/arch/x86/bios/e820.hh (renamed from src/arch/x86/syscallreturn.hh)48
-rw-r--r--src/arch/x86/bios/intelmp.cc476
-rw-r--r--src/arch/x86/bios/intelmp.hh330
-rw-r--r--src/arch/x86/bios/smbios.cc (renamed from src/arch/x86/smbios.cc)154
-rw-r--r--src/arch/x86/bios/smbios.hh (renamed from src/arch/x86/smbios.hh)118
-rw-r--r--src/arch/x86/cpuid.cc160
-rw-r--r--src/arch/x86/cpuid.hh (renamed from src/arch/arm/syscallreturn.hh)48
-rw-r--r--src/arch/x86/emulenv.cc12
-rw-r--r--src/arch/x86/emulenv.hh1
-rw-r--r--src/arch/x86/faults.cc112
-rw-r--r--src/arch/x86/faults.hh168
-rw-r--r--src/arch/x86/floatregfile.cc17
-rw-r--r--src/arch/x86/floatregfile.hh2
-rw-r--r--src/arch/x86/insts/macroop.hh121
-rw-r--r--src/arch/x86/insts/microldstop.cc29
-rw-r--r--src/arch/x86/insts/microldstop.hh33
-rw-r--r--src/arch/x86/insts/microop.cc4
-rw-r--r--src/arch/x86/insts/microregop.cc3
-rw-r--r--src/arch/x86/insts/static_inst.cc42
-rw-r--r--src/arch/x86/insts/static_inst.hh3
-rw-r--r--src/arch/x86/interrupts.cc569
-rw-r--r--src/arch/x86/interrupts.hh253
-rw-r--r--src/arch/x86/intmessage.hh110
-rw-r--r--src/arch/x86/intregfile.cc17
-rw-r--r--src/arch/x86/intregfile.hh3
-rw-r--r--src/arch/x86/isa/decoder/one_byte_opcodes.isa23
-rw-r--r--src/arch/x86/isa/decoder/two_byte_opcodes.isa187
-rw-r--r--src/arch/x86/isa/formats/basic.isa8
-rw-r--r--src/arch/x86/isa/formats/cpuid.isa110
-rw-r--r--src/arch/x86/isa/formats/formats.isa3
-rw-r--r--src/arch/x86/isa/includes.isa9
-rw-r--r--src/arch/x86/isa/insts/__init__.py3
-rw-r--r--src/arch/x86/isa/insts/general_purpose/__init__.py1
-rw-r--r--src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py24
-rw-r--r--src/arch/x86/isa/insts/general_purpose/cache_and_memory_management.py40
-rw-r--r--src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py153
-rw-r--r--src/arch/x86/isa/insts/general_purpose/control_transfer/call.py2
-rw-r--r--src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py198
-rw-r--r--src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py23
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_conversion/ascii_adjust.py8
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_conversion/bcd_adjust.py4
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py22
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_conversion/extract_sign_mask.py4
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_conversion/translate.py2
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_transfer/move.py148
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py106
-rw-r--r--src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py14
-rw-r--r--src/arch/x86/isa/insts/general_purpose/flags/set_and_clear.py22
-rw-r--r--src/arch/x86/isa/insts/general_purpose/input_output/general_io.py18
-rw-r--r--src/arch/x86/isa/insts/general_purpose/input_output/string_io.py32
-rw-r--r--src/arch/x86/isa/insts/general_purpose/load_segment_registers.py14
-rw-r--r--src/arch/x86/isa/insts/general_purpose/processor_information.py405
-rw-r--r--src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py89
-rw-r--r--src/arch/x86/isa/insts/general_purpose/semaphores.py26
-rw-r--r--src/arch/x86/isa/insts/general_purpose/string/compare_strings.py16
-rw-r--r--src/arch/x86/isa/insts/general_purpose/string/load_string.py15
-rw-r--r--src/arch/x86/isa/insts/general_purpose/string/move_string.py7
-rw-r--r--src/arch/x86/isa/insts/general_purpose/string/scan_string.py16
-rw-r--r--src/arch/x86/isa/insts/general_purpose/string/store_string.py7
-rw-r--r--src/arch/x86/isa/insts/general_purpose/system_calls.py183
-rw-r--r--src/arch/x86/isa/insts/romutil.py212
-rw-r--r--src/arch/x86/isa/insts/system/__init__.py3
-rw-r--r--src/arch/x86/isa/insts/system/control_registers.py35
-rw-r--r--src/arch/x86/isa/insts/system/msrs.py16
-rw-r--r--src/arch/x86/isa/insts/system/segmentation.py131
-rw-r--r--src/arch/x86/isa/macroop.isa122
-rw-r--r--src/arch/x86/isa/microasm.isa49
-rw-r--r--src/arch/x86/isa/microops/base.isa31
-rw-r--r--src/arch/x86/isa/microops/debug.isa229
-rw-r--r--src/arch/x86/isa/microops/fpop.isa2
-rw-r--r--src/arch/x86/isa/microops/ldstop.isa145
-rw-r--r--src/arch/x86/isa/microops/limmop.isa2
-rw-r--r--src/arch/x86/isa/microops/microops.isa8
-rw-r--r--src/arch/x86/isa/microops/regop.isa323
-rw-r--r--src/arch/x86/isa/microops/seqop.isa251
-rw-r--r--src/arch/x86/isa/microops/specop.isa19
-rw-r--r--src/arch/x86/isa/operands.isa54
-rw-r--r--src/arch/x86/isa/rom.isa90
-rw-r--r--src/arch/x86/isa/specialize.isa46
-rw-r--r--src/arch/x86/isa_traits.hh12
-rw-r--r--src/arch/x86/linux/linux.cc39
-rw-r--r--src/arch/x86/linux/linux.hh81
-rw-r--r--src/arch/x86/linux/process.cc30
-rw-r--r--src/arch/x86/linux/process.hh22
-rw-r--r--src/arch/x86/linux/syscalls.cc444
-rw-r--r--src/arch/x86/linux/system.cc61
-rw-r--r--src/arch/x86/linux/system.hh4
-rw-r--r--src/arch/x86/microcode_rom.hh74
-rw-r--r--src/arch/x86/miscregfile.cc289
-rw-r--r--src/arch/x86/miscregfile.hh13
-rw-r--r--src/arch/x86/miscregs.hh117
-rw-r--r--src/arch/x86/mmaped_ipr.hh30
-rw-r--r--src/arch/x86/pagetable.hh6
-rw-r--r--src/arch/x86/pagetable_walker.cc249
-rw-r--r--src/arch/x86/pagetable_walker.hh31
-rw-r--r--src/arch/x86/predecoder.cc45
-rw-r--r--src/arch/x86/predecoder.hh2
-rw-r--r--src/arch/x86/predecoder_tables.cc6
-rw-r--r--src/arch/x86/process.cc324
-rw-r--r--src/arch/x86/process.hh72
-rw-r--r--src/arch/x86/regfile.cc21
-rw-r--r--src/arch/x86/regfile.hh10
-rw-r--r--src/arch/x86/remote_gdb.cc18
-rw-r--r--src/arch/x86/stacktrace.cc4
-rw-r--r--src/arch/x86/system.cc78
-rw-r--r--src/arch/x86/system.hh14
-rw-r--r--src/arch/x86/tlb.cc355
-rw-r--r--src/arch/x86/tlb.hh21
-rw-r--r--src/arch/x86/types.hh11
-rw-r--r--src/arch/x86/utility.cc16
-rw-r--r--src/arch/x86/utility.hh7
-rw-r--r--src/arch/x86/x86_traits.hh37
289 files changed, 13257 insertions, 6785 deletions
diff --git a/src/arch/SConscript b/src/arch/SConscript
index 66f93870e..b85ffbd89 100644
--- a/src/arch/SConscript
+++ b/src/arch/SConscript
@@ -49,13 +49,13 @@ isa_switch_hdrs = Split('''
isa_traits.hh
kernel_stats.hh
locked_mem.hh
+ microcode_rom.hh
mmaped_ipr.hh
process.hh
predecoder.hh
regfile.hh
remote_gdb.hh
stacktrace.hh
- syscallreturn.hh
tlb.hh
types.hh
utility.hh
@@ -125,3 +125,8 @@ else:
emitter = isa_desc_emitter)
env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder })
+
+TraceFlag('IntRegs')
+TraceFlag('FloatRegs')
+TraceFlag('MiscRegs')
+CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'MiscRegs' ])
diff --git a/src/arch/alpha/AlphaInterrupts.py b/src/arch/alpha/AlphaInterrupts.py
new file mode 100644
index 000000000..ecfcf5c21
--- /dev/null
+++ b/src/arch/alpha/AlphaInterrupts.py
@@ -0,0 +1,33 @@
+# Copyright (c) 2008 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+from m5.SimObject import SimObject
+
+class AlphaInterrupts(SimObject):
+ type = 'AlphaInterrupts'
+ cxx_class = 'AlphaISA::Interrupts'
diff --git a/src/arch/alpha/AlphaTLB.py b/src/arch/alpha/AlphaTLB.py
index fec245b75..099327470 100644
--- a/src/arch/alpha/AlphaTLB.py
+++ b/src/arch/alpha/AlphaTLB.py
@@ -28,21 +28,20 @@
from m5.SimObject import SimObject
from m5.params import *
-class AlphaTLB(SimObject):
+
+from BaseTLB import BaseTLB
+
+class AlphaTLB(BaseTLB):
type = 'AlphaTLB'
abstract = True
size = Param.Int("TLB size")
class AlphaDTB(AlphaTLB):
type = 'AlphaDTB'
- cxx_namespace = 'AlphaISA'
- cxx_class = 'DTB'
-
+ cxx_class = 'AlphaISA::DTB'
size = 64
class AlphaITB(AlphaTLB):
type = 'AlphaITB'
- cxx_namespace = 'AlphaISA'
- cxx_class = 'ITB'
-
+ cxx_class = 'AlphaISA::ITB'
size = 48
diff --git a/src/arch/alpha/SConscript b/src/arch/alpha/SConscript
index 04bac3996..069db2551 100644
--- a/src/arch/alpha/SConscript
+++ b/src/arch/alpha/SConscript
@@ -47,9 +47,11 @@ if env['TARGET_ISA'] == 'alpha':
SimObject('AlphaTLB.py')
if env['FULL_SYSTEM']:
+ SimObject('AlphaInterrupts.py')
SimObject('AlphaSystem.py')
Source('idle_event.cc')
+ Source('interrupts.cc')
Source('kernel_stats.cc')
Source('osfpal.cc')
Source('stacktrace.cc')
diff --git a/src/arch/alpha/SConsopts b/src/arch/alpha/SConsopts
index 633eeb06f..b418e27c8 100644
--- a/src/arch/alpha/SConsopts
+++ b/src/arch/alpha/SConsopts
@@ -33,5 +33,5 @@ Import('*')
all_isa_list.append('alpha')
# Alpha can be compiled with Turbolaser support instead of Tsunami
-sticky_opts.Add(BoolOption('ALPHA_TLASER',
+sticky_vars.Add(BoolVariable('ALPHA_TLASER',
'Model Alpha TurboLaser platform (vs. Tsunami)', False))
diff --git a/src/arch/alpha/aout_machdep.h b/src/arch/alpha/aout_machdep.h
index 58991256a..bcf004d05 100644
--- a/src/arch/alpha/aout_machdep.h
+++ b/src/arch/alpha/aout_machdep.h
@@ -36,35 +36,35 @@
/// 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
+ 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 AOUT_LDPGSZ 8192
-#define N_GETMAGIC(ex) ((ex).magic)
+#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_TXTADDR(ex) ((ex).text_start)
+#define N_DATADDR(ex) ((ex).data_start)
+#define N_BSSADDR(ex) ((ex).bss_start)
-#define N_TXTOFF(ex) \
+#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)
+#define N_DATOFF(ex) N_ALIGN(ex, N_TXTOFF(ex) + (ex).tsize)
#endif /* !__AOUT_MACHDEP_H__*/
diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc
index 5dc49623e..02497e282 100644
--- a/src/arch/alpha/ev5.cc
+++ b/src/arch/alpha/ev5.cc
@@ -35,32 +35,33 @@
#include "arch/alpha/osfpal.hh"
#include "arch/alpha/tlb.hh"
#include "arch/alpha/kgdb.h"
+#include "base/cp_annotate.hh"
+#include "base/debug.hh"
#include "base/remote_gdb.hh"
#include "base/stats/events.hh"
#include "config/full_system.hh"
#include "cpu/base.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
-#include "sim/debug.hh"
#include "sim/sim_exit.hh"
-#if FULL_SYSTEM
+namespace AlphaISA {
-using namespace EV5;
+#if FULL_SYSTEM
////////////////////////////////////////////////////////////////////////
//
// Machine dependent functions
//
void
-AlphaISA::initCPU(ThreadContext *tc, int cpuId)
+initCPU(ThreadContext *tc, int cpuId)
{
initIPRs(tc, cpuId);
tc->setIntReg(16, cpuId);
tc->setIntReg(0, cpuId);
- AlphaISA::AlphaFault *reset = new AlphaISA::ResetFault;
+ AlphaFault *reset = new ResetFault;
tc->setPC(tc->readMiscRegNoEffect(IPR_PAL_BASE) + reset->vect());
tc->setNextPC(tc->readPC() + sizeof(MachInst));
@@ -71,7 +72,7 @@ AlphaISA::initCPU(ThreadContext *tc, int cpuId)
template <class CPU>
void
-AlphaISA::processInterrupts(CPU *cpu)
+processInterrupts(CPU *cpu)
{
//Check if there are any outstanding interrupts
//Handle the interrupts
@@ -117,7 +118,7 @@ AlphaISA::processInterrupts(CPU *cpu)
template <class CPU>
void
-AlphaISA::zeroRegisters(CPU *cpu)
+zeroRegisters(CPU *cpu)
{
// Insure ISA semantics
// (no longer very clean due to the change in setIntReg() in the
@@ -126,33 +127,16 @@ AlphaISA::zeroRegisters(CPU *cpu)
cpu->thread->setFloatReg(ZeroReg, 0.0);
}
-Fault
-SimpleThread::hwrei()
-{
- if (!(readPC() & 0x3))
- return new UnimplementedOpcodeFault;
-
- setNextPC(readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR));
-
- if (!misspeculating()) {
- if (kernelStats)
- kernelStats->hwrei();
- }
-
- // FIXME: XXX check for interrupts? XXX
- return NoFault;
-}
-
int
-AlphaISA::MiscRegFile::getInstAsid()
+MiscRegFile::getInstAsid()
{
- return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]);
+ return ITB_ASN_ASN(ipr[IPR_ITB_ASN]);
}
int
-AlphaISA::MiscRegFile::getDataAsid()
+MiscRegFile::getDataAsid()
{
- return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]);
+ return DTB_ASN_ASN(ipr[IPR_DTB_ASN]);
}
#endif
@@ -162,90 +146,90 @@ AlphaISA::MiscRegFile::getDataAsid()
//
//
void
-AlphaISA::initIPRs(ThreadContext *tc, int cpuId)
+initIPRs(ThreadContext *tc, int cpuId)
{
for (int i = 0; i < NumInternalProcRegs; ++i) {
tc->setMiscRegNoEffect(i, 0);
}
- tc->setMiscRegNoEffect(IPR_PAL_BASE, EV5::PalBase);
+ tc->setMiscRegNoEffect(IPR_PAL_BASE, PalBase);
tc->setMiscRegNoEffect(IPR_MCSR, 0x6);
tc->setMiscRegNoEffect(IPR_PALtemp16, cpuId);
}
-AlphaISA::MiscReg
-AlphaISA::MiscRegFile::readIpr(int idx, ThreadContext *tc)
+MiscReg
+MiscRegFile::readIpr(int idx, ThreadContext *tc)
{
- uint64_t retval = 0; // return value, default 0
+ 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:
+ case IPR_PALtemp0:
+ case IPR_PALtemp1:
+ case IPR_PALtemp2:
+ case IPR_PALtemp3:
+ case IPR_PALtemp4:
+ case IPR_PALtemp5:
+ case IPR_PALtemp6:
+ case IPR_PALtemp7:
+ case IPR_PALtemp8:
+ case IPR_PALtemp9:
+ case IPR_PALtemp10:
+ case IPR_PALtemp11:
+ case IPR_PALtemp12:
+ case IPR_PALtemp13:
+ case IPR_PALtemp14:
+ case IPR_PALtemp15:
+ case IPR_PALtemp16:
+ case IPR_PALtemp17:
+ case IPR_PALtemp18:
+ case IPR_PALtemp19:
+ case IPR_PALtemp20:
+ case IPR_PALtemp21:
+ case IPR_PALtemp22:
+ case IPR_PALtemp23:
+ case IPR_PAL_BASE:
+
+ case IPR_IVPTBR:
+ case IPR_DC_MODE:
+ case IPR_MAF_MODE:
+ case IPR_ISR:
+ case IPR_EXC_ADDR:
+ case IPR_IC_PERR_STAT:
+ case IPR_DC_PERR_STAT:
+ case IPR_MCSR:
+ case IPR_ASTRR:
+ case IPR_ASTER:
+ case IPR_SIRR:
+ case IPR_ICSR:
+ case IPR_ICM:
+ case IPR_DTB_CM:
+ case IPR_IPLR:
+ case IPR_INTID:
+ case IPR_PMCTR:
// no side-effect
retval = ipr[idx];
break;
- case AlphaISA::IPR_CC:
+ case IPR_CC:
retval |= ipr[idx] & ULL(0xffffffff00000000);
retval |= tc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff);
break;
- case AlphaISA::IPR_VA:
+ case 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:
+ case IPR_VA_FORM:
+ case IPR_MM_STAT:
+ case IPR_IFAULT_VA_FORM:
+ case IPR_EXC_MASK:
+ case IPR_EXC_SUM:
retval = ipr[idx];
break;
- case AlphaISA::IPR_DTB_PTE:
+ case IPR_DTB_PTE:
{
- AlphaISA::TlbEntry &entry
+ TlbEntry &entry
= tc->getDTBPtr()->index(!tc->misspeculating());
retval |= ((uint64_t)entry.ppn & ULL(0x7ffffff)) << 32;
@@ -259,15 +243,15 @@ AlphaISA::MiscRegFile::readIpr(int idx, ThreadContext *tc)
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:
+ case IPR_HWINT_CLR:
+ case IPR_SL_XMIT:
+ case IPR_DC_FLUSH:
+ case IPR_IC_FLUSH:
+ case IPR_ALT_MODE:
+ case IPR_DTB_IA:
+ case IPR_DTB_IAP:
+ case IPR_ITB_IA:
+ case IPR_ITB_IAP:
panic("Tried to read write only register %d\n", idx);
break;
@@ -286,7 +270,7 @@ int break_ipl = -1;
#endif
void
-AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
+MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
{
uint64_t old;
@@ -294,52 +278,52 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
return;
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:
+ case IPR_PALtemp0:
+ case IPR_PALtemp1:
+ case IPR_PALtemp2:
+ case IPR_PALtemp3:
+ case IPR_PALtemp4:
+ case IPR_PALtemp5:
+ case IPR_PALtemp6:
+ case IPR_PALtemp7:
+ case IPR_PALtemp8:
+ case IPR_PALtemp9:
+ case IPR_PALtemp10:
+ case IPR_PALtemp11:
+ case IPR_PALtemp12:
+ case IPR_PALtemp13:
+ case IPR_PALtemp14:
+ case IPR_PALtemp15:
+ case IPR_PALtemp16:
+ case IPR_PALtemp17:
+ case IPR_PALtemp18:
+ case IPR_PALtemp19:
+ case IPR_PALtemp20:
+ case IPR_PALtemp21:
+ case IPR_PALtemp22:
+ case IPR_PAL_BASE:
+ case IPR_IC_PERR_STAT:
+ case IPR_DC_PERR_STAT:
+ case IPR_PMCTR:
// write entire quad w/ no side-effect
ipr[idx] = val;
break;
- case AlphaISA::IPR_CC_CTL:
+ case 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:
+ case 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:
+ case IPR_PALtemp23:
// write entire quad w/ no side-effect
old = ipr[idx];
ipr[idx] = val;
@@ -349,23 +333,23 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
#endif
break;
- case AlphaISA::IPR_DTB_PTE:
+ case IPR_DTB_PTE:
// write entire quad w/ no side-effect, tag is forthcoming
ipr[idx] = val;
break;
- case AlphaISA::IPR_EXC_ADDR:
+ case 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:
+ case IPR_ASTRR:
+ case IPR_ASTER:
// only write least significant four bits - privilege mask
ipr[idx] = val & 0xf;
break;
- case AlphaISA::IPR_IPLR:
+ case IPR_IPLR:
#ifdef DEBUG
if (break_ipl != -1 && break_ipl == (val & 0x1f))
debug_break();
@@ -379,175 +363,173 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
#endif
break;
- case AlphaISA::IPR_DTB_CM:
+ case IPR_DTB_CM:
#if FULL_SYSTEM
if (val & 0x18) {
if (tc->getKernelStats())
- tc->getKernelStats()->mode(TheISA::Kernel::user, tc);
+ tc->getKernelStats()->mode(Kernel::user, tc);
} else {
if (tc->getKernelStats())
- tc->getKernelStats()->mode(TheISA::Kernel::kernel, tc);
+ tc->getKernelStats()->mode(Kernel::kernel, tc);
}
#endif
- case AlphaISA::IPR_ICM:
+ case IPR_ICM:
// only write two mode bits - processor mode
ipr[idx] = val & 0x18;
break;
- case AlphaISA::IPR_ALT_MODE:
+ case IPR_ALT_MODE:
// only write two mode bits - processor mode
ipr[idx] = val & 0x18;
break;
- case AlphaISA::IPR_MCSR:
+ case IPR_MCSR:
// more here after optimization...
ipr[idx] = val;
break;
- case AlphaISA::IPR_SIRR:
+ case IPR_SIRR:
// only write software interrupt mask
ipr[idx] = val & 0x7fff0;
break;
- case AlphaISA::IPR_ICSR:
+ case IPR_ICSR:
ipr[idx] = val & ULL(0xffffff0300);
break;
- case AlphaISA::IPR_IVPTBR:
- case AlphaISA::IPR_MVPTBR:
+ case IPR_IVPTBR:
+ case IPR_MVPTBR:
ipr[idx] = val & ULL(0xffffffffc0000000);
break;
- case AlphaISA::IPR_DC_TEST_CTL:
+ case IPR_DC_TEST_CTL:
ipr[idx] = val & 0x1ffb;
break;
- case AlphaISA::IPR_DC_MODE:
- case AlphaISA::IPR_MAF_MODE:
+ case IPR_DC_MODE:
+ case IPR_MAF_MODE:
ipr[idx] = val & 0x3f;
break;
- case AlphaISA::IPR_ITB_ASN:
+ case IPR_ITB_ASN:
ipr[idx] = val & 0x7f0;
break;
- case AlphaISA::IPR_DTB_ASN:
+ case IPR_DTB_ASN:
ipr[idx] = val & ULL(0xfe00000000000000);
break;
- case AlphaISA::IPR_EXC_SUM:
- case AlphaISA::IPR_EXC_MASK:
+ case IPR_EXC_SUM:
+ case 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:
+ case IPR_INTID:
+ case IPR_SL_RCV:
+ case IPR_MM_STAT:
+ case IPR_ITB_PTE_TEMP:
+ case IPR_DTB_PTE_TEMP:
// read-only registers
panic("Tried to write read only ipr %d\n", idx);
- case AlphaISA::IPR_HWINT_CLR:
- case AlphaISA::IPR_SL_XMIT:
- case AlphaISA::IPR_DC_FLUSH:
- case AlphaISA::IPR_IC_FLUSH:
+ case IPR_HWINT_CLR:
+ case IPR_SL_XMIT:
+ case IPR_DC_FLUSH:
+ case IPR_IC_FLUSH:
// the following are write only
ipr[idx] = val;
break;
- case AlphaISA::IPR_DTB_IA:
+ case IPR_DTB_IA:
// really a control write
ipr[idx] = 0;
tc->getDTBPtr()->flushAll();
break;
- case AlphaISA::IPR_DTB_IAP:
+ case IPR_DTB_IAP:
// really a control write
ipr[idx] = 0;
tc->getDTBPtr()->flushProcesses();
break;
- case AlphaISA::IPR_DTB_IS:
+ case IPR_DTB_IS:
// really a control write
ipr[idx] = val;
- tc->getDTBPtr()->flushAddr(val,
- EV5::DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
+ tc->getDTBPtr()->flushAddr(val, DTB_ASN_ASN(ipr[IPR_DTB_ASN]));
break;
- case AlphaISA::IPR_DTB_TAG: {
- struct AlphaISA::TlbEntry entry;
+ case IPR_DTB_TAG: {
+ struct TlbEntry entry;
// FIXME: granularity hints NYI...
- if (EV5::DTB_PTE_GH(ipr[AlphaISA::IPR_DTB_PTE]) != 0)
+ if (DTB_PTE_GH(ipr[IPR_DTB_PTE]) != 0)
panic("PTE GH field != 0");
// write entire quad
ipr[idx] = val;
// construct PTE for new entry
- entry.ppn = EV5::DTB_PTE_PPN(ipr[AlphaISA::IPR_DTB_PTE]);
- entry.xre = EV5::DTB_PTE_XRE(ipr[AlphaISA::IPR_DTB_PTE]);
- entry.xwe = EV5::DTB_PTE_XWE(ipr[AlphaISA::IPR_DTB_PTE]);
- entry.fonr = EV5::DTB_PTE_FONR(ipr[AlphaISA::IPR_DTB_PTE]);
- entry.fonw = EV5::DTB_PTE_FONW(ipr[AlphaISA::IPR_DTB_PTE]);
- entry.asma = EV5::DTB_PTE_ASMA(ipr[AlphaISA::IPR_DTB_PTE]);
- entry.asn = EV5::DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]);
+ entry.ppn = DTB_PTE_PPN(ipr[IPR_DTB_PTE]);
+ entry.xre = DTB_PTE_XRE(ipr[IPR_DTB_PTE]);
+ entry.xwe = DTB_PTE_XWE(ipr[IPR_DTB_PTE]);
+ entry.fonr = DTB_PTE_FONR(ipr[IPR_DTB_PTE]);
+ entry.fonw = DTB_PTE_FONW(ipr[IPR_DTB_PTE]);
+ entry.asma = DTB_PTE_ASMA(ipr[IPR_DTB_PTE]);
+ entry.asn = DTB_ASN_ASN(ipr[IPR_DTB_ASN]);
// insert new TAG/PTE value into data TLB
tc->getDTBPtr()->insert(val, entry);
}
break;
- case AlphaISA::IPR_ITB_PTE: {
- struct AlphaISA::TlbEntry entry;
+ case IPR_ITB_PTE: {
+ struct TlbEntry entry;
// FIXME: granularity hints NYI...
- if (EV5::ITB_PTE_GH(val) != 0)
+ if (ITB_PTE_GH(val) != 0)
panic("PTE GH field != 0");
// write entire quad
ipr[idx] = val;
// construct PTE for new entry
- entry.ppn = EV5::ITB_PTE_PPN(val);
- entry.xre = EV5::ITB_PTE_XRE(val);
+ entry.ppn = ITB_PTE_PPN(val);
+ entry.xre = ITB_PTE_XRE(val);
entry.xwe = 0;
- entry.fonr = EV5::ITB_PTE_FONR(val);
- entry.fonw = EV5::ITB_PTE_FONW(val);
- entry.asma = EV5::ITB_PTE_ASMA(val);
- entry.asn = EV5::ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]);
+ entry.fonr = ITB_PTE_FONR(val);
+ entry.fonw = ITB_PTE_FONW(val);
+ entry.asma = ITB_PTE_ASMA(val);
+ entry.asn = ITB_ASN_ASN(ipr[IPR_ITB_ASN]);
// insert new TAG/PTE value into data TLB
- tc->getITBPtr()->insert(ipr[AlphaISA::IPR_ITB_TAG], entry);
+ tc->getITBPtr()->insert(ipr[IPR_ITB_TAG], entry);
}
break;
- case AlphaISA::IPR_ITB_IA:
+ case IPR_ITB_IA:
// really a control write
ipr[idx] = 0;
tc->getITBPtr()->flushAll();
break;
- case AlphaISA::IPR_ITB_IAP:
+ case IPR_ITB_IAP:
// really a control write
ipr[idx] = 0;
tc->getITBPtr()->flushProcesses();
break;
- case AlphaISA::IPR_ITB_IS:
+ case IPR_ITB_IS:
// really a control write
ipr[idx] = val;
- tc->getITBPtr()->flushAddr(val,
- EV5::ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]));
+ tc->getITBPtr()->flushAddr(val, ITB_ASN_ASN(ipr[IPR_ITB_ASN]));
break;
default:
@@ -558,17 +540,38 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
// no error...
}
-
void
-AlphaISA::copyIprs(ThreadContext *src, ThreadContext *dest)
+copyIprs(ThreadContext *src, ThreadContext *dest)
{
- for (int i = 0; i < NumInternalProcRegs; ++i) {
+ for (int i = 0; i < NumInternalProcRegs; ++i)
dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
- }
}
+} // namespace AlphaISA
+
#if FULL_SYSTEM
+using namespace AlphaISA;
+
+Fault
+SimpleThread::hwrei()
+{
+ if (!(readPC() & 0x3))
+ return new UnimplementedOpcodeFault;
+
+ setNextPC(readMiscRegNoEffect(IPR_EXC_ADDR));
+
+ CPA::cpa()->swAutoBegin(tc, readNextPC());
+
+ if (!misspeculating()) {
+ if (kernelStats)
+ kernelStats->hwrei();
+ }
+
+ // FIXME: XXX check for interrupts? XXX
+ return NoFault;
+}
+
/**
* Check for special simulator handling of specific PAL calls.
* If return value is false, actual PAL call will be suppressed.
diff --git a/src/arch/alpha/ev5.hh b/src/arch/alpha/ev5.hh
index 4dd225786..1915d822b 100644
--- a/src/arch/alpha/ev5.hh
+++ b/src/arch/alpha/ev5.hh
@@ -36,10 +36,7 @@
#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;
+namespace AlphaISA {
#if ALPHA_TLASER
const uint64_t AsnMask = ULL(0x7f);
@@ -51,8 +48,8 @@ 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 VAddrVPN(Addr a) { return a >> PageShift; }
+inline Addr VAddrOffset(Addr a) { return a & PageOffset; }
inline Addr VAddrSpaceEV5(Addr a) { return a >> 41 & 0x3; }
inline Addr VAddrSpaceEV6(Addr a) { return a >> 41 & 0x7f; }
@@ -68,7 +65,9 @@ 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)
+
+inline Addr
+Phys2K0Seg(Addr addr)
{
#if !ALPHA_TLASER
if (addr & PAddrUncachedBit43) {
@@ -76,12 +75,12 @@ inline Addr Phys2K0Seg(Addr addr)
addr |= PAddrUncachedBit40;
}
#endif
- return addr | AlphaISA::K0SegBase;
+ return addr | 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; }
+{ return reg >> 32 & ((ULL(1) << (PAddrImplBits - 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; }
@@ -91,7 +90,7 @@ 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; }
+{ return reg >> 32 & ((ULL(1) << (PAddrImplBits - 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; }
@@ -114,12 +113,12 @@ 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; }
+inline int Opcode(MachInst inst) { return inst >> 26 & 0x3f; }
+inline int Ra(MachInst inst) { return inst >> 21 & 0x1f; }
const Addr PalBase = 0x4000;
const Addr PalMax = 0x10000;
-/* namespace EV5 */ }
+} // namespace AlphaISA
#endif // __ARCH_ALPHA_EV5_HH__
diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc
index 20591b357..e93e16711 100644
--- a/src/arch/alpha/faults.cc
+++ b/src/arch/alpha/faults.cc
@@ -40,8 +40,7 @@
#include "mem/page_table.hh"
#endif
-namespace AlphaISA
-{
+namespace AlphaISA {
FaultName MachineCheckFault::_name = "mchk";
FaultVect MachineCheckFault::_vect = 0x0401;
@@ -109,64 +108,67 @@ FaultStat IntegerOverflowFault::_count;
#if FULL_SYSTEM
-void AlphaFault::invoke(ThreadContext * tc)
+void
+AlphaFault::invoke(ThreadContext *tc)
{
FaultBase::invoke(tc);
countStat()++;
// exception restart address
if (setRestartAddress() || !(tc->readPC() & 0x3))
- tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR, tc->readPC());
+ tc->setMiscRegNoEffect(IPR_EXC_ADDR, tc->readPC());
if (skipFaultingInstruction()) {
// traps... skip faulting instruction.
- tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR,
- tc->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR) + 4);
+ tc->setMiscRegNoEffect(IPR_EXC_ADDR,
+ tc->readMiscRegNoEffect(IPR_EXC_ADDR) + 4);
}
- tc->setPC(tc->readMiscRegNoEffect(AlphaISA::IPR_PAL_BASE) + vect());
+ tc->setPC(tc->readMiscRegNoEffect(IPR_PAL_BASE) + vect());
tc->setNextPC(tc->readPC() + sizeof(MachInst));
}
-void ArithmeticFault::invoke(ThreadContext * tc)
+void
+ArithmeticFault::invoke(ThreadContext *tc)
{
FaultBase::invoke(tc);
panic("Arithmetic traps are unimplemented!");
}
-void DtbFault::invoke(ThreadContext * tc)
+void
+DtbFault::invoke(ThreadContext *tc)
{
// 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 (!tc->misspeculating()
- && !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) {
+ if (!tc->misspeculating() &&
+ reqFlags.noneSet(Request::VPTE|Request::NO_FAULT)) {
// set VA register with faulting address
- tc->setMiscRegNoEffect(AlphaISA::IPR_VA, vaddr);
+ tc->setMiscRegNoEffect(IPR_VA, vaddr);
// set MM_STAT register flags
- tc->setMiscRegNoEffect(AlphaISA::IPR_MM_STAT,
- (((EV5::Opcode(tc->getInst()) & 0x3f) << 11)
- | ((EV5::Ra(tc->getInst()) & 0x1f) << 6)
- | (flags & 0x3f)));
+ tc->setMiscRegNoEffect(IPR_MM_STAT,
+ (((Opcode(tc->getInst()) & 0x3f) << 11) |
+ ((Ra(tc->getInst()) & 0x1f) << 6) |
+ (flags & 0x3f)));
// set VA_FORM register with faulting formatted address
- tc->setMiscRegNoEffect(AlphaISA::IPR_VA_FORM,
- tc->readMiscRegNoEffect(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3));
+ tc->setMiscRegNoEffect(IPR_VA_FORM,
+ tc->readMiscRegNoEffect(IPR_MVPTBR) | (vaddr.vpn() << 3));
}
AlphaFault::invoke(tc);
}
-void ItbFault::invoke(ThreadContext * tc)
+void
+ItbFault::invoke(ThreadContext *tc)
{
if (!tc->misspeculating()) {
- tc->setMiscRegNoEffect(AlphaISA::IPR_ITB_TAG, pc);
- tc->setMiscRegNoEffect(AlphaISA::IPR_IFAULT_VA_FORM,
- tc->readMiscRegNoEffect(AlphaISA::IPR_IVPTBR) |
- (AlphaISA::VAddr(pc).vpn() << 3));
+ tc->setMiscRegNoEffect(IPR_ITB_TAG, pc);
+ tc->setMiscRegNoEffect(IPR_IFAULT_VA_FORM,
+ tc->readMiscRegNoEffect(IPR_IVPTBR) | (VAddr(pc).vpn() << 3));
}
AlphaFault::invoke(tc);
@@ -174,12 +176,13 @@ void ItbFault::invoke(ThreadContext * tc)
#else
-void ItbPageFault::invoke(ThreadContext * tc)
+void
+ItbPageFault::invoke(ThreadContext *tc)
{
Process *p = tc->getProcessPtr();
TlbEntry entry;
bool success = p->pTable->lookup(pc, entry);
- if(!success) {
+ if (!success) {
panic("Tried to execute unmapped address %#x.\n", pc);
} else {
VAddr vaddr(pc);
@@ -187,16 +190,17 @@ void ItbPageFault::invoke(ThreadContext * tc)
}
}
-void NDtbMissFault::invoke(ThreadContext * tc)
+void
+NDtbMissFault::invoke(ThreadContext *tc)
{
Process *p = tc->getProcessPtr();
TlbEntry entry;
bool success = p->pTable->lookup(vaddr, entry);
- if(!success) {
+ if (!success) {
p->checkAndAllocNextPage(vaddr);
success = p->pTable->lookup(vaddr, entry);
}
- if(!success) {
+ if (!success) {
panic("Tried to access unmapped address %#x.\n", (Addr)vaddr);
} else {
tc->getDTBPtr()->insert(vaddr.page(), entry);
diff --git a/src/arch/alpha/faults.hh b/src/arch/alpha/faults.hh
index 74699b2b5..9d90c7719 100644
--- a/src/arch/alpha/faults.hh
+++ b/src/arch/alpha/faults.hh
@@ -29,18 +29,16 @@
* Kevin Lim
*/
-#ifndef __ALPHA_FAULTS_HH__
-#define __ALPHA_FAULTS_HH__
+#ifndef __ARCH_ALPHA_FAULTS_HH__
+#define __ARCH_ALPHA_FAULTS_HH__
+#include "arch/alpha/pagetable.hh"
#include "config/full_system.hh"
#include "sim/faults.hh"
-#include "arch/alpha/pagetable.hh"
-
// The design of the "name" and "vect" functions is in sim/faults.hh
-namespace AlphaISA
-{
+namespace AlphaISA {
typedef const Addr FaultVect;
@@ -63,6 +61,7 @@ class MachineCheckFault : public AlphaFault
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
+
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
@@ -76,6 +75,7 @@ class AlignmentFault : public AlphaFault
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
+
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
@@ -94,6 +94,7 @@ class ResetFault : public AlphaFault
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
+
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
@@ -102,12 +103,14 @@ class ResetFault : public AlphaFault
class ArithmeticFault : public AlphaFault
{
- protected:
- bool skipFaultingInstruction() {return true;}
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
+
+ protected:
+ bool skipFaultingInstruction() {return true;}
+
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
@@ -119,12 +122,14 @@ class ArithmeticFault : public AlphaFault
class InterruptFault : public AlphaFault
{
- protected:
- bool setRestartAddress() {return false;}
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
+
+ protected:
+ bool setRestartAddress() {return false;}
+
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
@@ -134,11 +139,12 @@ class InterruptFault : public AlphaFault
class DtbFault : public AlphaFault
{
protected:
- AlphaISA::VAddr vaddr;
- uint32_t reqFlags;
+ VAddr vaddr;
+ Request::Flags reqFlags;
uint64_t flags;
+
public:
- DtbFault(AlphaISA::VAddr _vaddr, uint32_t _reqFlags, uint64_t _flags)
+ DtbFault(VAddr _vaddr, Request::Flags _reqFlags, uint64_t _flags)
: vaddr(_vaddr), reqFlags(_reqFlags), flags(_flags)
{ }
FaultName name() const = 0;
@@ -155,8 +161,9 @@ class NDtbMissFault : public DtbFault
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
+
public:
- NDtbMissFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
+ NDtbMissFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags)
: DtbFault(vaddr, reqFlags, flags)
{ }
FaultName name() const {return _name;}
@@ -173,8 +180,9 @@ class PDtbMissFault : public DtbFault
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
+
public:
- PDtbMissFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
+ PDtbMissFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags)
: DtbFault(vaddr, reqFlags, flags)
{ }
FaultName name() const {return _name;}
@@ -188,8 +196,9 @@ class DtbPageFault : public DtbFault
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
+
public:
- DtbPageFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
+ DtbPageFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags)
: DtbFault(vaddr, reqFlags, flags)
{ }
FaultName name() const {return _name;}
@@ -203,8 +212,9 @@ class DtbAcvFault : public DtbFault
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
+
public:
- DtbAcvFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
+ DtbAcvFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags)
: DtbFault(vaddr, reqFlags, flags)
{ }
FaultName name() const {return _name;}
@@ -218,8 +228,9 @@ class DtbAlignmentFault : public DtbFault
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
+
public:
- DtbAlignmentFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
+ DtbAlignmentFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags)
: DtbFault(vaddr, reqFlags, flags)
{ }
FaultName name() const {return _name;}
@@ -231,10 +242,9 @@ class ItbFault : public AlphaFault
{
protected:
Addr pc;
+
public:
- ItbFault(Addr _pc)
- : pc(_pc)
- { }
+ ItbFault(Addr _pc) : pc(_pc) { }
FaultName name() const = 0;
FaultVect vect() = 0;
FaultStat & countStat() = 0;
@@ -249,10 +259,9 @@ class ItbPageFault : public ItbFault
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
+
public:
- ItbPageFault(Addr pc)
- : ItbFault(pc)
- { }
+ ItbPageFault(Addr pc) : ItbFault(pc) { }
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
@@ -267,10 +276,9 @@ class ItbAcvFault : public ItbFault
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
+
public:
- ItbAcvFault(Addr pc)
- : ItbFault(pc)
- { }
+ ItbAcvFault(Addr pc) : ItbFault(pc) { }
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
@@ -282,6 +290,7 @@ class UnimplementedOpcodeFault : public AlphaFault
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
+
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
@@ -294,6 +303,7 @@ class FloatEnableFault : public AlphaFault
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
+
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
@@ -302,12 +312,14 @@ class FloatEnableFault : public AlphaFault
class PalFault : public AlphaFault
{
- protected:
- bool skipFaultingInstruction() {return true;}
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
+
+ protected:
+ bool skipFaultingInstruction() {return true;}
+
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
@@ -320,12 +332,13 @@ class IntegerOverflowFault : public AlphaFault
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
+
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
};
-} // AlphaISA namespace
+} // namespace AlphaISA
-#endif // __FAULTS_HH__
+#endif // __ARCH_ALPHA_FAULTS_HH__
diff --git a/src/arch/alpha/floatregfile.cc b/src/arch/alpha/floatregfile.cc
index 512b0df95..192b0f1d4 100644
--- a/src/arch/alpha/floatregfile.cc
+++ b/src/arch/alpha/floatregfile.cc
@@ -30,20 +30,28 @@
* Kevin Lim
*/
+#include <cstring>
+
#include "arch/alpha/floatregfile.hh"
#include "sim/serialize.hh"
-namespace AlphaISA
+namespace AlphaISA {
+void
+FloatRegFile::clear()
{
- void
- FloatRegFile::serialize(std::ostream &os)
- {
- SERIALIZE_ARRAY(q, NumFloatRegs);
- }
+ std::memset(d, 0, sizeof(d));
+}
- void
- FloatRegFile::unserialize(Checkpoint *cp, const std::string &section)
- {
- UNSERIALIZE_ARRAY(q, NumFloatRegs);
- }
+void
+FloatRegFile::serialize(std::ostream &os)
+{
+ SERIALIZE_ARRAY(q, NumFloatRegs);
}
+
+void
+FloatRegFile::unserialize(Checkpoint *cp, const std::string &section)
+{
+ UNSERIALIZE_ARRAY(q, NumFloatRegs);
+}
+
+} // namespace AlphaISA
diff --git a/src/arch/alpha/floatregfile.hh b/src/arch/alpha/floatregfile.hh
index 0c5fe17a7..d5f9eec0f 100644
--- a/src/arch/alpha/floatregfile.hh
+++ b/src/arch/alpha/floatregfile.hh
@@ -32,37 +32,30 @@
#ifndef __ARCH_ALPHA_FLOATREGFILE_HH__
#define __ARCH_ALPHA_FLOATREGFILE_HH__
+#include <iosfwd>
+#include <string>
+
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/types.hh"
-#include <cstring>
-#include <iostream>
-
class Checkpoint;
-namespace AlphaISA
-{
- static inline std::string getFloatRegName(RegIndex)
- {
- return "";
- }
-
- class FloatRegFile
- {
- public:
+namespace AlphaISA {
- union {
- uint64_t q[NumFloatRegs]; // integer qword view
- double d[NumFloatRegs]; // double-precision floating point view
- };
+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 clear();
- void unserialize(Checkpoint *cp, const std::string &section);
+ void serialize(std::ostream &os);
+ void unserialize(Checkpoint *cp, const std::string &section);
+};
- void clear()
- { std::memset(d, 0, sizeof(d)); }
- };
-}
+} // namespace AlphaISA
-#endif
+#endif // __ARCH_ALPHA_FLOATREGFILE_HH__
diff --git a/src/arch/alpha/freebsd/system.cc b/src/arch/alpha/freebsd/system.cc
index f666de604..e541b260c 100644
--- a/src/arch/alpha/freebsd/system.cc
+++ b/src/arch/alpha/freebsd/system.cc
@@ -62,29 +62,25 @@ FreebsdAlphaSystem::FreebsdAlphaSystem(Params *p)
addKernelFuncEvent<SkipCalibrateClocksEvent>("calibrate_clocks");
}
-
FreebsdAlphaSystem::~FreebsdAlphaSystem()
{
delete skipDelayEvent;
delete skipCalibrateClocks;
}
-
void
FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc)
{
Addr ppc_vaddr = 0;
Addr timer_vaddr = 0;
- assert(NumArgumentRegs >= 3);
- ppc_vaddr = (Addr)tc->readIntReg(ArgumentReg[1]);
- timer_vaddr = (Addr)tc->readIntReg(ArgumentReg[2]);
+ ppc_vaddr = (Addr)tc->readIntReg(17);
+ timer_vaddr = (Addr)tc->readIntReg(18);
virtPort.write(ppc_vaddr, (uint32_t)Clock::Frequency);
virtPort.write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
}
-
void
FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ThreadContext *tc)
{
diff --git a/src/arch/alpha/freebsd/system.hh b/src/arch/alpha/freebsd/system.hh
index 8e8493f97..48f6238c0 100644
--- a/src/arch/alpha/freebsd/system.hh
+++ b/src/arch/alpha/freebsd/system.hh
@@ -57,7 +57,6 @@ class FreebsdAlphaSystem : public AlphaSystem
~FreebsdAlphaSystem();
void doCalibrateClocks(ThreadContext *tc);
-
};
#endif // __ARCH_ALPHA_FREEBSD_SYSTEM_HH__
diff --git a/src/arch/alpha/idle_event.cc b/src/arch/alpha/idle_event.cc
index f0f1eab7a..bb68782e7 100644
--- a/src/arch/alpha/idle_event.cc
+++ b/src/arch/alpha/idle_event.cc
@@ -33,13 +33,14 @@
#include "arch/alpha/kernel_stats.hh"
#include "cpu/thread_context.hh"
-using namespace TheISA;
+using namespace AlphaISA;
void
IdleStartEvent::process(ThreadContext *tc)
{
- if (tc->getKernelStats())
- tc->getKernelStats()->setIdleProcess(
- tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23), tc);
+ if (tc->getKernelStats()) {
+ MiscReg val = tc->readMiscRegNoEffect(IPR_PALtemp23);
+ tc->getKernelStats()->setIdleProcess(val, tc);
+ }
remove();
}
diff --git a/src/arch/alpha/interrupts.cc b/src/arch/alpha/interrupts.cc
new file mode 100644
index 000000000..4b5dc5661
--- /dev/null
+++ b/src/arch/alpha/interrupts.cc
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2008 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "arch/alpha/interrupts.hh"
+
+AlphaISA::Interrupts *
+AlphaInterruptsParams::create()
+{
+ return new AlphaISA::Interrupts(this);
+}
diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh
index 6453edf97..f8e0ad4ef 100644
--- a/src/arch/alpha/interrupts.hh
+++ b/src/arch/alpha/interrupts.hh
@@ -35,142 +35,163 @@
#include "arch/alpha/faults.hh"
#include "arch/alpha/isa_traits.hh"
#include "base/compiler.hh"
+#include "base/trace.hh"
#include "cpu/thread_context.hh"
+#include "params/AlphaInterrupts.hh"
+#include "sim/sim_object.hh"
-namespace AlphaISA
+namespace AlphaISA {
+
+class Interrupts : public SimObject
{
- class Interrupts
+ private:
+ bool newInfoSet;
+ int newIpl;
+ int newSummary;
+ BaseCPU * cpu;
+
+ protected:
+ uint64_t interrupts[NumInterruptLevels];
+ uint64_t intstatus;
+
+ public:
+ typedef AlphaInterruptsParams Params;
+
+ const Params *
+ params() const
{
- protected:
- uint64_t interrupts[NumInterruptLevels];
- uint64_t intstatus;
-
- public:
- Interrupts()
- {
- memset(interrupts, 0, sizeof(interrupts));
- intstatus = 0;
- newInfoSet = false;
- }
+ return dynamic_cast<const Params *>(_params);
+ }
- void post(int int_num, int index)
- {
- DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
+ Interrupts(Params * p) : SimObject(p), cpu(NULL)
+ {
+ memset(interrupts, 0, sizeof(interrupts));
+ intstatus = 0;
+ newInfoSet = false;
+ }
- if (int_num < 0 || int_num >= NumInterruptLevels)
- panic("int_num out of bounds\n");
+ void
+ setCPU(BaseCPU * _cpu)
+ {
+ cpu = _cpu;
+ }
- if (index < 0 || index >= sizeof(uint64_t) * 8)
- panic("int_num out of bounds\n");
+ void
+ post(int int_num, int index)
+ {
+ DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
- interrupts[int_num] |= 1 << index;
- intstatus |= (ULL(1) << int_num);
- }
+ if (int_num < 0 || int_num >= NumInterruptLevels)
+ panic("int_num out of bounds\n");
- void clear(int int_num, int index)
- {
- DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
+ if (index < 0 || index >= (int)sizeof(uint64_t) * 8)
+ panic("int_num out of bounds\n");
- if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
- panic("int_num out of bounds\n");
+ interrupts[int_num] |= 1 << index;
+ intstatus |= (ULL(1) << int_num);
+ }
- if (index < 0 || index >= sizeof(uint64_t) * 8)
- panic("int_num out of bounds\n");
+ void
+ clear(int int_num, int index)
+ {
+ DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
- interrupts[int_num] &= ~(1 << index);
- if (interrupts[int_num] == 0)
- intstatus &= ~(ULL(1) << int_num);
- }
+ if (int_num < 0 || int_num >= NumInterruptLevels)
+ panic("int_num out of bounds\n");
- void clear_all()
- {
- DPRINTF(Interrupt, "Interrupts all cleared\n");
+ if (index < 0 || index >= (int)sizeof(uint64_t) * 8)
+ panic("int_num out of bounds\n");
- memset(interrupts, 0, sizeof(interrupts));
- intstatus = 0;
- }
+ interrupts[int_num] &= ~(1 << index);
+ if (interrupts[int_num] == 0)
+ intstatus &= ~(ULL(1) << int_num);
+ }
- void serialize(std::ostream &os)
- {
- SERIALIZE_ARRAY(interrupts, NumInterruptLevels);
- SERIALIZE_SCALAR(intstatus);
- }
+ void
+ clearAll()
+ {
+ DPRINTF(Interrupt, "Interrupts all cleared\n");
- void unserialize(Checkpoint *cp, const std::string &section)
- {
- UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels);
- UNSERIALIZE_SCALAR(intstatus);
- }
+ memset(interrupts, 0, sizeof(interrupts));
+ intstatus = 0;
+ }
- bool check_interrupts(ThreadContext * tc) const
- {
- return (intstatus != 0) && !(tc->readPC() & 0x3);
- }
+ void
+ serialize(std::ostream &os)
+ {
+ SERIALIZE_ARRAY(interrupts, NumInterruptLevels);
+ SERIALIZE_SCALAR(intstatus);
+ }
- Fault getInterrupt(ThreadContext * tc)
- {
- int ipl = 0;
- int summary = 0;
-
- if (tc->readMiscRegNoEffect(IPR_ASTRR))
- panic("asynchronous traps not implemented\n");
-
- if (tc->readMiscRegNoEffect(IPR_SIRR)) {
- for (int i = INTLEVEL_SOFTWARE_MIN;
- i < INTLEVEL_SOFTWARE_MAX; i++) {
- if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) {
- // See table 4-19 of 21164 hardware reference
- ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
- summary |= (ULL(1) << i);
- }
- }
- }
+ void
+ unserialize(Checkpoint *cp, const std::string &section)
+ {
+ UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels);
+ UNSERIALIZE_SCALAR(intstatus);
+ }
+
+ bool
+ checkInterrupts(ThreadContext *tc) const
+ {
+ return (intstatus != 0) && !(tc->readPC() & 0x3);
+ }
- uint64_t interrupts = intstatus;
- if (interrupts) {
- for (int i = INTLEVEL_EXTERNAL_MIN;
- i < INTLEVEL_EXTERNAL_MAX; i++) {
- if (interrupts & (ULL(1) << i)) {
- // See table 4-19 of 21164 hardware reference
- ipl = i;
- summary |= (ULL(1) << i);
- }
+ Fault
+ getInterrupt(ThreadContext *tc)
+ {
+ int ipl = 0;
+ int summary = 0;
+
+ if (tc->readMiscRegNoEffect(IPR_ASTRR))
+ panic("asynchronous traps not implemented\n");
+
+ if (tc->readMiscRegNoEffect(IPR_SIRR)) {
+ for (int i = INTLEVEL_SOFTWARE_MIN;
+ i < INTLEVEL_SOFTWARE_MAX; i++) {
+ if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) {
+ // See table 4-19 of 21164 hardware reference
+ ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
+ summary |= (ULL(1) << i);
}
}
+ }
- if (ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR)) {
- newIpl = ipl;
- newSummary = summary;
- newInfoSet = true;
- DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
- tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary);
-
- return new InterruptFault;
- } else {
- return NoFault;
+ uint64_t interrupts = intstatus;
+ if (interrupts) {
+ for (int i = INTLEVEL_EXTERNAL_MIN;
+ i < INTLEVEL_EXTERNAL_MAX; i++) {
+ if (interrupts & (ULL(1) << i)) {
+ // See table 4-19 of 21164 hardware reference
+ ipl = i;
+ summary |= (ULL(1) << i);
+ }
}
}
- void updateIntrInfo(ThreadContext *tc)
- {
- assert(newInfoSet);
- tc->setMiscRegNoEffect(IPR_ISR, newSummary);
- tc->setMiscRegNoEffect(IPR_INTID, newIpl);
- newInfoSet = false;
- }
+ if (ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR)) {
+ newIpl = ipl;
+ newSummary = summary;
+ newInfoSet = true;
+ DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
+ tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary);
- uint64_t get_vec(int int_num)
- {
- panic("Shouldn't be called for Alpha\n");
- M5_DUMMY_RETURN
+ return new InterruptFault;
+ } else {
+ return NoFault;
}
+ }
+
+ void
+ updateIntrInfo(ThreadContext *tc)
+ {
+ assert(newInfoSet);
+ tc->setMiscRegNoEffect(IPR_ISR, newSummary);
+ tc->setMiscRegNoEffect(IPR_INTID, newIpl);
+ newInfoSet = false;
+ }
+};
- private:
- bool newInfoSet;
- int newIpl;
- int newSummary;
- };
-}
+} // namespace AlphaISA
-#endif
+#endif // __ARCH_ALPHA_INTERRUPT_HH__
diff --git a/src/arch/alpha/intregfile.cc b/src/arch/alpha/intregfile.cc
index 0188cb2cd..8f692f856 100644
--- a/src/arch/alpha/intregfile.cc
+++ b/src/arch/alpha/intregfile.cc
@@ -30,36 +30,45 @@
* Kevin Lim
*/
+#include <cstring>
+
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/intregfile.hh"
#include "sim/serialize.hh"
-namespace AlphaISA
-{
+namespace AlphaISA {
+
#if FULL_SYSTEM
- const int reg_redir[AlphaISA::NumIntRegs] = {
- /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7,
- /* 8 */ 32, 33, 34, 35, 36, 37, 38, 15,
- /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23,
- /* 24 */ 24, 39, 26, 27, 28, 29, 30, 31 };
+const int reg_redir[NumIntRegs] = {
+ /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7,
+ /* 8 */ 32, 33, 34, 35, 36, 37, 38, 15,
+ /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23,
+ /* 24 */ 24, 39, 26, 27, 28, 29, 30, 31 };
#else
- const int reg_redir[AlphaISA::NumIntRegs] = {
- /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7,
- /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15,
- /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23,
- /* 24 */ 24, 25, 26, 27, 28, 29, 30, 31 };
+const int reg_redir[NumIntRegs] = {
+ /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7,
+ /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15,
+ /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23,
+ /* 24 */ 24, 25, 26, 27, 28, 29, 30, 31 };
#endif
- void
- IntRegFile::serialize(std::ostream &os)
- {
- SERIALIZE_ARRAY(regs, NumIntRegs);
- }
+void
+IntRegFile::clear()
+{
+ std::memset(regs, 0, sizeof(regs));
+}
+
+void
+IntRegFile::serialize(std::ostream &os)
+{
+ SERIALIZE_ARRAY(regs, NumIntRegs);
+}
- void
- IntRegFile::unserialize(Checkpoint *cp, const std::string &section)
- {
- UNSERIALIZE_ARRAY(regs, NumIntRegs);
- }
+void
+IntRegFile::unserialize(Checkpoint *cp, const std::string &section)
+{
+ UNSERIALIZE_ARRAY(regs, NumIntRegs);
}
+} // namespace AlphaISA
+
diff --git a/src/arch/alpha/intregfile.hh b/src/arch/alpha/intregfile.hh
index dea160992..3aa7d92c4 100644
--- a/src/arch/alpha/intregfile.hh
+++ b/src/arch/alpha/intregfile.hh
@@ -32,47 +32,42 @@
#ifndef __ARCH_ALPHA_INTREGFILE_HH__
#define __ARCH_ALPHA_INTREGFILE_HH__
-#include "arch/alpha/types.hh"
+#include <iosfwd>
+#include <string>
-#include <iostream>
-#include <cstring>
+#include "arch/alpha/types.hh"
class Checkpoint;
-namespace AlphaISA
+namespace AlphaISA {
+
+// redirected register map, really only used for the full system case.
+extern const int reg_redir[NumIntRegs];
+
+class IntRegFile
{
- static inline std::string getIntRegName(RegIndex)
+ protected:
+ IntReg regs[NumIntRegs];
+
+ public:
+ IntReg
+ readReg(int intReg)
{
- return "";
+ return regs[intReg];
}
- // redirected register map, really only used for the full system case.
- extern const int reg_redir[NumIntRegs];
-
- class IntRegFile
+ void
+ setReg(int intReg, const IntReg &val)
{
- protected:
- IntReg regs[NumIntRegs];
-
- public:
-
- IntReg readReg(int intReg)
- {
- return regs[intReg];
- }
-
- void setReg(int intReg, const IntReg &val)
- {
- regs[intReg] = val;
- }
+ regs[intReg] = val;
+ }
- void serialize(std::ostream &os);
+ void clear();
- void unserialize(Checkpoint *cp, const std::string &section);
+ void serialize(std::ostream &os);
+ void unserialize(Checkpoint *cp, const std::string &section);
+};
- void clear()
- { std::memset(regs, 0, sizeof(regs)); }
- };
-}
+} // namespace AlphaISA
-#endif
+#endif // __ARCH_ALPHA_INTREGFILE_HH__
diff --git a/src/arch/alpha/ipr.cc b/src/arch/alpha/ipr.cc
index 8e83102eb..502ada5eb 100644
--- a/src/arch/alpha/ipr.cc
+++ b/src/arch/alpha/ipr.cc
@@ -28,113 +28,115 @@
* Authors: Gabe Black
*/
-#include <assert.h>
-#include <string.h>
+#include <cassert>
+#include <cstring>
#include "arch/alpha/ipr.hh"
-namespace AlphaISA
+namespace AlphaISA {
+
+md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs] = {
+
+ //Write only
+ RAW_IPR_HWINT_CLR, // H/W interrupt clear register
+ RAW_IPR_SL_XMIT, // serial line transmit register
+ RAW_IPR_DC_FLUSH,
+ RAW_IPR_IC_FLUSH, // instruction cache flush control
+ RAW_IPR_ALT_MODE, // alternate mode register
+ RAW_IPR_DTB_IA, // DTLB invalidate all register
+ RAW_IPR_DTB_IAP, // DTLB invalidate all process register
+ RAW_IPR_ITB_IA, // ITLB invalidate all register
+ RAW_IPR_ITB_IAP, // ITLB invalidate all process register
+
+ //Read only
+ RAW_IPR_INTID, // interrupt ID register
+ RAW_IPR_SL_RCV, // serial line receive register
+ RAW_IPR_MM_STAT, // data MMU fault status register
+ RAW_IPR_ITB_PTE_TEMP, // ITLB page table entry temp register
+ RAW_IPR_DTB_PTE_TEMP, // DTLB page table entry temporary register
+
+ RAW_IPR_ISR, // interrupt summary register
+ RAW_IPR_ITB_TAG, // ITLB tag register
+ RAW_IPR_ITB_PTE, // ITLB page table entry register
+ RAW_IPR_ITB_ASN, // ITLB address space register
+ RAW_IPR_ITB_IS, // ITLB invalidate select register
+ RAW_IPR_SIRR, // software interrupt request register
+ RAW_IPR_ASTRR, // asynchronous system trap request register
+ RAW_IPR_ASTER, // asynchronous system trap enable register
+ RAW_IPR_EXC_ADDR, // exception address register
+ RAW_IPR_EXC_SUM, // exception summary register
+ RAW_IPR_EXC_MASK, // exception mask register
+ RAW_IPR_PAL_BASE, // PAL base address register
+ RAW_IPR_ICM, // instruction current mode
+ RAW_IPR_IPLR, // interrupt priority level register
+ RAW_IPR_IFAULT_VA_FORM, // formatted faulting virtual addr register
+ RAW_IPR_IVPTBR, // virtual page table base register
+ RAW_IPR_ICSR, // instruction control and status register
+ RAW_IPR_IC_PERR_STAT, // inst cache parity error status register
+ RAW_IPR_PMCTR, // performance counter register
+
+ // PAL temporary registers...
+ // register meanings gleaned from osfpal.s source code
+ RAW_IPR_PALtemp0, // local scratch
+ RAW_IPR_PALtemp1, // local scratch
+ RAW_IPR_PALtemp2, // entUna
+ RAW_IPR_PALtemp3, // CPU specific impure area pointer
+ RAW_IPR_PALtemp4, // memory management temp
+ RAW_IPR_PALtemp5, // memory management temp
+ RAW_IPR_PALtemp6, // memory management temp
+ RAW_IPR_PALtemp7, // entIF
+ RAW_IPR_PALtemp8, // intmask
+ RAW_IPR_PALtemp9, // entSys
+ RAW_IPR_PALtemp10, // ??
+ RAW_IPR_PALtemp11, // entInt
+ RAW_IPR_PALtemp12, // entArith
+ RAW_IPR_PALtemp13, // reserved for platform specific PAL
+ RAW_IPR_PALtemp14, // reserved for platform specific PAL
+ RAW_IPR_PALtemp15, // reserved for platform specific PAL
+ RAW_IPR_PALtemp16, // scratch / whami<7:0> / mces<4:0>
+ RAW_IPR_PALtemp17, // sysval
+ RAW_IPR_PALtemp18, // usp
+ RAW_IPR_PALtemp19, // ksp
+ RAW_IPR_PALtemp20, // PTBR
+ RAW_IPR_PALtemp21, // entMM
+ RAW_IPR_PALtemp22, // kgp
+ RAW_IPR_PALtemp23, // PCBB
+
+ RAW_IPR_DTB_ASN, // DTLB address space number register
+ RAW_IPR_DTB_CM, // DTLB current mode register
+ RAW_IPR_DTB_TAG, // DTLB tag register
+ RAW_IPR_DTB_PTE, // DTLB page table entry register
+
+ RAW_IPR_VA, // fault virtual address register
+ RAW_IPR_VA_FORM, // formatted virtual address register
+ RAW_IPR_MVPTBR, // MTU virtual page table base register
+ RAW_IPR_DTB_IS, // DTLB invalidate single register
+ RAW_IPR_CC, // cycle counter register
+ RAW_IPR_CC_CTL, // cycle counter control register
+ RAW_IPR_MCSR, // MTU control register
+
+ RAW_IPR_DC_PERR_STAT, // Dcache parity error status register
+ RAW_IPR_DC_TEST_CTL, // Dcache test tag control register
+ RAW_IPR_DC_TEST_TAG, // Dcache test tag register
+ RAW_IPR_DC_TEST_TAG_TEMP, // Dcache test tag temporary register
+ RAW_IPR_DC_MODE, // Dcache mode register
+ RAW_IPR_MAF_MODE // miss address file mode register
+};
+
+int IprToMiscRegIndex[MaxInternalProcRegs];
+
+void
+initializeIprTable()
{
- md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs] =
- {
- //Write only
- RAW_IPR_HWINT_CLR, // H/W interrupt clear register
- RAW_IPR_SL_XMIT, // serial line transmit register
- RAW_IPR_DC_FLUSH,
- RAW_IPR_IC_FLUSH, // instruction cache flush control
- RAW_IPR_ALT_MODE, // alternate mode register
- RAW_IPR_DTB_IA, // DTLB invalidate all register
- RAW_IPR_DTB_IAP, // DTLB invalidate all process register
- RAW_IPR_ITB_IA, // ITLB invalidate all register
- RAW_IPR_ITB_IAP, // ITLB invalidate all process register
-
- //Read only
- RAW_IPR_INTID, // interrupt ID register
- RAW_IPR_SL_RCV, // serial line receive register
- RAW_IPR_MM_STAT, // data MMU fault status register
- RAW_IPR_ITB_PTE_TEMP, // ITLB page table entry temp register
- RAW_IPR_DTB_PTE_TEMP, // DTLB page table entry temporary register
-
- RAW_IPR_ISR, // interrupt summary register
- RAW_IPR_ITB_TAG, // ITLB tag register
- RAW_IPR_ITB_PTE, // ITLB page table entry register
- RAW_IPR_ITB_ASN, // ITLB address space register
- RAW_IPR_ITB_IS, // ITLB invalidate select register
- RAW_IPR_SIRR, // software interrupt request register
- RAW_IPR_ASTRR, // asynchronous system trap request register
- RAW_IPR_ASTER, // asynchronous system trap enable register
- RAW_IPR_EXC_ADDR, // exception address register
- RAW_IPR_EXC_SUM, // exception summary register
- RAW_IPR_EXC_MASK, // exception mask register
- RAW_IPR_PAL_BASE, // PAL base address register
- RAW_IPR_ICM, // instruction current mode
- RAW_IPR_IPLR, // interrupt priority level register
- RAW_IPR_IFAULT_VA_FORM, // formatted faulting virtual addr register
- RAW_IPR_IVPTBR, // virtual page table base register
- RAW_IPR_ICSR, // instruction control and status register
- RAW_IPR_IC_PERR_STAT, // inst cache parity error status register
- RAW_IPR_PMCTR, // performance counter register
-
- // PAL temporary registers...
- // register meanings gleaned from osfpal.s source code
- RAW_IPR_PALtemp0, // local scratch
- RAW_IPR_PALtemp1, // local scratch
- RAW_IPR_PALtemp2, // entUna
- RAW_IPR_PALtemp3, // CPU specific impure area pointer
- RAW_IPR_PALtemp4, // memory management temp
- RAW_IPR_PALtemp5, // memory management temp
- RAW_IPR_PALtemp6, // memory management temp
- RAW_IPR_PALtemp7, // entIF
- RAW_IPR_PALtemp8, // intmask
- RAW_IPR_PALtemp9, // entSys
- RAW_IPR_PALtemp10, // ??
- RAW_IPR_PALtemp11, // entInt
- RAW_IPR_PALtemp12, // entArith
- RAW_IPR_PALtemp13, // reserved for platform specific PAL
- RAW_IPR_PALtemp14, // reserved for platform specific PAL
- RAW_IPR_PALtemp15, // reserved for platform specific PAL
- RAW_IPR_PALtemp16, // scratch / whami<7:0> / mces<4:0>
- RAW_IPR_PALtemp17, // sysval
- RAW_IPR_PALtemp18, // usp
- RAW_IPR_PALtemp19, // ksp
- RAW_IPR_PALtemp20, // PTBR
- RAW_IPR_PALtemp21, // entMM
- RAW_IPR_PALtemp22, // kgp
- RAW_IPR_PALtemp23, // PCBB
-
- RAW_IPR_DTB_ASN, // DTLB address space number register
- RAW_IPR_DTB_CM, // DTLB current mode register
- RAW_IPR_DTB_TAG, // DTLB tag register
- RAW_IPR_DTB_PTE, // DTLB page table entry register
-
- RAW_IPR_VA, // fault virtual address register
- RAW_IPR_VA_FORM, // formatted virtual address register
- RAW_IPR_MVPTBR, // MTU virtual page table base register
- RAW_IPR_DTB_IS, // DTLB invalidate single register
- RAW_IPR_CC, // cycle counter register
- RAW_IPR_CC_CTL, // cycle counter control register
- RAW_IPR_MCSR, // MTU control register
-
- RAW_IPR_DC_PERR_STAT, // Dcache parity error status register
- RAW_IPR_DC_TEST_CTL, // Dcache test tag control register
- RAW_IPR_DC_TEST_TAG, // Dcache test tag register
- RAW_IPR_DC_TEST_TAG_TEMP, // Dcache test tag temporary register
- RAW_IPR_DC_MODE, // Dcache mode register
- RAW_IPR_MAF_MODE // miss address file mode register
- };
-
- int IprToMiscRegIndex[MaxInternalProcRegs];
-
- void initializeIprTable()
- {
- static bool initialized = false;
- if(initialized)
- return;
-
- memset(IprToMiscRegIndex, -1, MaxInternalProcRegs * sizeof(int));
-
- for(int x = 0; x < NumInternalProcRegs; x++)
- IprToMiscRegIndex[MiscRegIndexToIpr[x]] = x;
- }
+ static bool initialized = false;
+ if (initialized)
+ return;
+
+ memset(IprToMiscRegIndex, -1, MaxInternalProcRegs * sizeof(int));
+
+ for (int x = 0; x < NumInternalProcRegs; x++)
+ IprToMiscRegIndex[MiscRegIndexToIpr[x]] = x;
}
+} // namespace AlphaISA
+
diff --git a/src/arch/alpha/ipr.hh b/src/arch/alpha/ipr.hh
index b55154764..4e7bf1fa4 100644
--- a/src/arch/alpha/ipr.hh
+++ b/src/arch/alpha/ipr.hh
@@ -32,206 +32,208 @@
#ifndef __ARCH_ALPHA_IPR_HH__
#define __ARCH_ALPHA_IPR_HH__
-namespace AlphaISA
+namespace AlphaISA {
+
+////////////////////////////////////////////////////////////////////////
+//
+// Internal Processor Reigsters
+//
+enum md_ipr_names {
+ RAW_IPR_ISR = 0x100, // interrupt summary
+ RAW_IPR_ITB_TAG = 0x101, // ITLB tag
+ RAW_IPR_ITB_PTE = 0x102, // ITLB page table entry
+ RAW_IPR_ITB_ASN = 0x103, // ITLB address space
+ RAW_IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp
+ RAW_IPR_ITB_IA = 0x105, // ITLB invalidate all
+ RAW_IPR_ITB_IAP = 0x106, // ITLB invalidate all process
+ RAW_IPR_ITB_IS = 0x107, // ITLB invalidate select
+ RAW_IPR_SIRR = 0x108, // software interrupt request
+ RAW_IPR_ASTRR = 0x109, // asynchronous system trap request
+ RAW_IPR_ASTER = 0x10a, // asynchronous system trap enable
+ RAW_IPR_EXC_ADDR = 0x10b, // exception address
+ RAW_IPR_EXC_SUM = 0x10c, // exception summary
+ RAW_IPR_EXC_MASK = 0x10d, // exception mask
+ RAW_IPR_PAL_BASE = 0x10e, // PAL base address
+ RAW_IPR_ICM = 0x10f, // instruction current mode
+ RAW_IPR_IPLR = 0x110, // interrupt priority level
+ RAW_IPR_INTID = 0x111, // interrupt ID
+ RAW_IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr
+ RAW_IPR_IVPTBR = 0x113, // virtual page table base
+ RAW_IPR_HWINT_CLR = 0x115, // H/W interrupt clear
+ RAW_IPR_SL_XMIT = 0x116, // serial line transmit
+ RAW_IPR_SL_RCV = 0x117, // serial line receive
+ RAW_IPR_ICSR = 0x118, // instruction control and status
+ RAW_IPR_IC_FLUSH = 0x119, // instruction cache flush control
+ RAW_IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status
+ RAW_IPR_PMCTR = 0x11c, // performance counter
+
+ // PAL temporary registers...
+ // register meanings gleaned from osfpal.s source code
+ RAW_IPR_PALtemp0 = 0x140, // local scratch
+ RAW_IPR_PALtemp1 = 0x141, // local scratch
+ RAW_IPR_PALtemp2 = 0x142, // entUna
+ RAW_IPR_PALtemp3 = 0x143, // CPU specific impure area pointer
+ RAW_IPR_PALtemp4 = 0x144, // memory management temp
+ RAW_IPR_PALtemp5 = 0x145, // memory management temp
+ RAW_IPR_PALtemp6 = 0x146, // memory management temp
+ RAW_IPR_PALtemp7 = 0x147, // entIF
+ RAW_IPR_PALtemp8 = 0x148, // intmask
+ RAW_IPR_PALtemp9 = 0x149, // entSys
+ RAW_IPR_PALtemp10 = 0x14a, // ??
+ RAW_IPR_PALtemp11 = 0x14b, // entInt
+ RAW_IPR_PALtemp12 = 0x14c, // entArith
+ RAW_IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL
+ RAW_IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL
+ RAW_IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL
+ RAW_IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0>
+ RAW_IPR_PALtemp17 = 0x151, // sysval
+ RAW_IPR_PALtemp18 = 0x152, // usp
+ RAW_IPR_PALtemp19 = 0x153, // ksp
+ RAW_IPR_PALtemp20 = 0x154, // PTBR
+ RAW_IPR_PALtemp21 = 0x155, // entMM
+ RAW_IPR_PALtemp22 = 0x156, // kgp
+ RAW_IPR_PALtemp23 = 0x157, // PCBB
+
+ RAW_IPR_DTB_ASN = 0x200, // DTLB address space number
+ RAW_IPR_DTB_CM = 0x201, // DTLB current mode
+ RAW_IPR_DTB_TAG = 0x202, // DTLB tag
+ RAW_IPR_DTB_PTE = 0x203, // DTLB page table entry
+ RAW_IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary
+
+ RAW_IPR_MM_STAT = 0x205, // data MMU fault status
+ RAW_IPR_VA = 0x206, // fault virtual address
+ RAW_IPR_VA_FORM = 0x207, // formatted virtual address
+ RAW_IPR_MVPTBR = 0x208, // MTU virtual page table base
+ RAW_IPR_DTB_IAP = 0x209, // DTLB invalidate all process
+ RAW_IPR_DTB_IA = 0x20a, // DTLB invalidate all
+ RAW_IPR_DTB_IS = 0x20b, // DTLB invalidate single
+ RAW_IPR_ALT_MODE = 0x20c, // alternate mode
+ RAW_IPR_CC = 0x20d, // cycle counter
+ RAW_IPR_CC_CTL = 0x20e, // cycle counter control
+ RAW_IPR_MCSR = 0x20f, // MTU control
+
+ RAW_IPR_DC_FLUSH = 0x210,
+ RAW_IPR_DC_PERR_STAT = 0x212, // Dcache parity error status
+ RAW_IPR_DC_TEST_CTL = 0x213, // Dcache test tag control
+ RAW_IPR_DC_TEST_TAG = 0x214, // Dcache test tag
+ RAW_IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary
+ RAW_IPR_DC_MODE = 0x216, // Dcache mode
+ RAW_IPR_MAF_MODE = 0x217, // miss address file mode
+
+ MaxInternalProcRegs // number of IPRs
+};
+
+enum MiscRegIpr
{
- ////////////////////////////////////////////////////////////////////////
- //
- // Internal Processor Reigsters
- //
- enum md_ipr_names
- {
- RAW_IPR_ISR = 0x100, // interrupt summary register
- RAW_IPR_ITB_TAG = 0x101, // ITLB tag register
- RAW_IPR_ITB_PTE = 0x102, // ITLB page table entry register
- RAW_IPR_ITB_ASN = 0x103, // ITLB address space register
- RAW_IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp register
- RAW_IPR_ITB_IA = 0x105, // ITLB invalidate all register
- RAW_IPR_ITB_IAP = 0x106, // ITLB invalidate all process register
- RAW_IPR_ITB_IS = 0x107, // ITLB invalidate select register
- RAW_IPR_SIRR = 0x108, // software interrupt request register
- RAW_IPR_ASTRR = 0x109, // asynchronous system trap request register
- RAW_IPR_ASTER = 0x10a, // asynchronous system trap enable register
- RAW_IPR_EXC_ADDR = 0x10b, // exception address register
- RAW_IPR_EXC_SUM = 0x10c, // exception summary register
- RAW_IPR_EXC_MASK = 0x10d, // exception mask register
- RAW_IPR_PAL_BASE = 0x10e, // PAL base address register
- RAW_IPR_ICM = 0x10f, // instruction current mode
- RAW_IPR_IPLR = 0x110, // interrupt priority level register
- RAW_IPR_INTID = 0x111, // interrupt ID register
- RAW_IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr register
- RAW_IPR_IVPTBR = 0x113, // virtual page table base register
- RAW_IPR_HWINT_CLR = 0x115, // H/W interrupt clear register
- RAW_IPR_SL_XMIT = 0x116, // serial line transmit register
- RAW_IPR_SL_RCV = 0x117, // serial line receive register
- RAW_IPR_ICSR = 0x118, // instruction control and status register
- RAW_IPR_IC_FLUSH = 0x119, // instruction cache flush control
- RAW_IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status register
- RAW_IPR_PMCTR = 0x11c, // performance counter register
-
- // PAL temporary registers...
- // register meanings gleaned from osfpal.s source code
- RAW_IPR_PALtemp0 = 0x140, // local scratch
- RAW_IPR_PALtemp1 = 0x141, // local scratch
- RAW_IPR_PALtemp2 = 0x142, // entUna
- RAW_IPR_PALtemp3 = 0x143, // CPU specific impure area pointer
- RAW_IPR_PALtemp4 = 0x144, // memory management temp
- RAW_IPR_PALtemp5 = 0x145, // memory management temp
- RAW_IPR_PALtemp6 = 0x146, // memory management temp
- RAW_IPR_PALtemp7 = 0x147, // entIF
- RAW_IPR_PALtemp8 = 0x148, // intmask
- RAW_IPR_PALtemp9 = 0x149, // entSys
- RAW_IPR_PALtemp10 = 0x14a, // ??
- RAW_IPR_PALtemp11 = 0x14b, // entInt
- RAW_IPR_PALtemp12 = 0x14c, // entArith
- RAW_IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL
- RAW_IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL
- RAW_IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL
- RAW_IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0>
- RAW_IPR_PALtemp17 = 0x151, // sysval
- RAW_IPR_PALtemp18 = 0x152, // usp
- RAW_IPR_PALtemp19 = 0x153, // ksp
- RAW_IPR_PALtemp20 = 0x154, // PTBR
- RAW_IPR_PALtemp21 = 0x155, // entMM
- RAW_IPR_PALtemp22 = 0x156, // kgp
- RAW_IPR_PALtemp23 = 0x157, // PCBB
-
- RAW_IPR_DTB_ASN = 0x200, // DTLB address space number register
- RAW_IPR_DTB_CM = 0x201, // DTLB current mode register
- RAW_IPR_DTB_TAG = 0x202, // DTLB tag register
- RAW_IPR_DTB_PTE = 0x203, // DTLB page table entry register
- RAW_IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary register
-
- RAW_IPR_MM_STAT = 0x205, // data MMU fault status register
- RAW_IPR_VA = 0x206, // fault virtual address register
- RAW_IPR_VA_FORM = 0x207, // formatted virtual address register
- RAW_IPR_MVPTBR = 0x208, // MTU virtual page table base register
- RAW_IPR_DTB_IAP = 0x209, // DTLB invalidate all process register
- RAW_IPR_DTB_IA = 0x20a, // DTLB invalidate all register
- RAW_IPR_DTB_IS = 0x20b, // DTLB invalidate single register
- RAW_IPR_ALT_MODE = 0x20c, // alternate mode register
- RAW_IPR_CC = 0x20d, // cycle counter register
- RAW_IPR_CC_CTL = 0x20e, // cycle counter control register
- RAW_IPR_MCSR = 0x20f, // MTU control register
-
- RAW_IPR_DC_FLUSH = 0x210,
- RAW_IPR_DC_PERR_STAT = 0x212, // Dcache parity error status register
- RAW_IPR_DC_TEST_CTL = 0x213, // Dcache test tag control register
- RAW_IPR_DC_TEST_TAG = 0x214, // Dcache test tag register
- RAW_IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary register
- RAW_IPR_DC_MODE = 0x216, // Dcache mode register
- RAW_IPR_MAF_MODE = 0x217, // miss address file mode register
-
- MaxInternalProcRegs // number of IPR registers
- };
-
- enum MiscRegIpr
- {
- //Write only
- MinWriteOnlyIpr,
- IPR_HWINT_CLR = MinWriteOnlyIpr,
- IPR_SL_XMIT,
- IPR_DC_FLUSH,
- IPR_IC_FLUSH,
- IPR_ALT_MODE,
- IPR_DTB_IA,
- IPR_DTB_IAP,
- IPR_ITB_IA,
- MaxWriteOnlyIpr,
- IPR_ITB_IAP = MaxWriteOnlyIpr,
-
- //Read only
- MinReadOnlyIpr,
- IPR_INTID = MinReadOnlyIpr,
- IPR_SL_RCV,
- IPR_MM_STAT,
- IPR_ITB_PTE_TEMP,
- MaxReadOnlyIpr,
- IPR_DTB_PTE_TEMP = MaxReadOnlyIpr,
-
- IPR_ISR,
- IPR_ITB_TAG,
- IPR_ITB_PTE,
- IPR_ITB_ASN,
- IPR_ITB_IS,
- IPR_SIRR,
- IPR_ASTRR,
- IPR_ASTER,
- IPR_EXC_ADDR,
- IPR_EXC_SUM,
- IPR_EXC_MASK,
- IPR_PAL_BASE,
- IPR_ICM,
- IPR_IPLR,
- IPR_IFAULT_VA_FORM,
- IPR_IVPTBR,
- IPR_ICSR,
- IPR_IC_PERR_STAT,
- IPR_PMCTR,
-
- // PAL temporary registers...
- // register meanings gleaned from osfpal.s source code
- IPR_PALtemp0,
- IPR_PALtemp1,
- IPR_PALtemp2,
- IPR_PALtemp3,
- IPR_PALtemp4,
- IPR_PALtemp5,
- IPR_PALtemp6,
- IPR_PALtemp7,
- IPR_PALtemp8,
- IPR_PALtemp9,
- IPR_PALtemp10,
- IPR_PALtemp11,
- IPR_PALtemp12,
- IPR_PALtemp13,
- IPR_PALtemp14,
- IPR_PALtemp15,
- IPR_PALtemp16,
- IPR_PALtemp17,
- IPR_PALtemp18,
- IPR_PALtemp19,
- IPR_PALtemp20,
- IPR_PALtemp21,
- IPR_PALtemp22,
- IPR_PALtemp23,
-
- IPR_DTB_ASN,
- IPR_DTB_CM,
- IPR_DTB_TAG,
- IPR_DTB_PTE,
-
- IPR_VA,
- IPR_VA_FORM,
- IPR_MVPTBR,
- IPR_DTB_IS,
- IPR_CC,
- IPR_CC_CTL,
- IPR_MCSR,
-
- IPR_DC_PERR_STAT,
- IPR_DC_TEST_CTL,
- IPR_DC_TEST_TAG,
- IPR_DC_TEST_TAG_TEMP,
- IPR_DC_MODE,
- IPR_MAF_MODE,
-
- NumInternalProcRegs // number of IPR registers
- };
-
- inline bool IprIsWritable(int index)
- {
- return index < MinReadOnlyIpr || index > MaxReadOnlyIpr;
- }
-
- inline bool IprIsReadable(int index)
- {
- return index < MinWriteOnlyIpr || index > MaxWriteOnlyIpr;
- }
-
- extern md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs];
- extern int IprToMiscRegIndex[MaxInternalProcRegs];
-
- void initializeIprTable();
+ //Write only
+ MinWriteOnlyIpr,
+ IPR_HWINT_CLR = MinWriteOnlyIpr,
+ IPR_SL_XMIT,
+ IPR_DC_FLUSH,
+ IPR_IC_FLUSH,
+ IPR_ALT_MODE,
+ IPR_DTB_IA,
+ IPR_DTB_IAP,
+ IPR_ITB_IA,
+ MaxWriteOnlyIpr,
+ IPR_ITB_IAP = MaxWriteOnlyIpr,
+
+ //Read only
+ MinReadOnlyIpr,
+ IPR_INTID = MinReadOnlyIpr,
+ IPR_SL_RCV,
+ IPR_MM_STAT,
+ IPR_ITB_PTE_TEMP,
+ MaxReadOnlyIpr,
+ IPR_DTB_PTE_TEMP = MaxReadOnlyIpr,
+
+ IPR_ISR,
+ IPR_ITB_TAG,
+ IPR_ITB_PTE,
+ IPR_ITB_ASN,
+ IPR_ITB_IS,
+ IPR_SIRR,
+ IPR_ASTRR,
+ IPR_ASTER,
+ IPR_EXC_ADDR,
+ IPR_EXC_SUM,
+ IPR_EXC_MASK,
+ IPR_PAL_BASE,
+ IPR_ICM,
+ IPR_IPLR,
+ IPR_IFAULT_VA_FORM,
+ IPR_IVPTBR,
+ IPR_ICSR,
+ IPR_IC_PERR_STAT,
+ IPR_PMCTR,
+
+ // PAL temporary registers...
+ // register meanings gleaned from osfpal.s source code
+ IPR_PALtemp0,
+ IPR_PALtemp1,
+ IPR_PALtemp2,
+ IPR_PALtemp3,
+ IPR_PALtemp4,
+ IPR_PALtemp5,
+ IPR_PALtemp6,
+ IPR_PALtemp7,
+ IPR_PALtemp8,
+ IPR_PALtemp9,
+ IPR_PALtemp10,
+ IPR_PALtemp11,
+ IPR_PALtemp12,
+ IPR_PALtemp13,
+ IPR_PALtemp14,
+ IPR_PALtemp15,
+ IPR_PALtemp16,
+ IPR_PALtemp17,
+ IPR_PALtemp18,
+ IPR_PALtemp19,
+ IPR_PALtemp20,
+ IPR_PALtemp21,
+ IPR_PALtemp22,
+ IPR_PALtemp23,
+
+ IPR_DTB_ASN,
+ IPR_DTB_CM,
+ IPR_DTB_TAG,
+ IPR_DTB_PTE,
+
+ IPR_VA,
+ IPR_VA_FORM,
+ IPR_MVPTBR,
+ IPR_DTB_IS,
+ IPR_CC,
+ IPR_CC_CTL,
+ IPR_MCSR,
+
+ IPR_DC_PERR_STAT,
+ IPR_DC_TEST_CTL,
+ IPR_DC_TEST_TAG,
+ IPR_DC_TEST_TAG_TEMP,
+ IPR_DC_MODE,
+ IPR_MAF_MODE,
+
+ NumInternalProcRegs // number of IPR registers
+};
+
+inline bool
+IprIsWritable(int index)
+{
+ return index < MinReadOnlyIpr || index > MaxReadOnlyIpr;
+}
+
+inline bool
+IprIsReadable(int index)
+{
+ return index < MinWriteOnlyIpr || index > MaxWriteOnlyIpr;
}
-#endif
+extern md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs];
+extern int IprToMiscRegIndex[MaxInternalProcRegs];
+
+void initializeIprTable();
+
+} // namespace AlphaISA
+
+#endif // __ARCH_ALPHA_IPR_HH__
diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa
index 2177e8c4f..0b2a31410 100644
--- a/src/arch/alpha/isa/decoder.isa
+++ b/src/arch/alpha/isa/decoder.isa
@@ -638,7 +638,7 @@ decode OPCODE default Unknown::unknown() {
/* Rb is a fake dependency so here is a fun way to get
* the parser to understand that.
*/
- Ra = xc->readMiscReg(AlphaISA::IPR_CC) + (Rb & 0);
+ Ra = xc->readMiscReg(IPR_CC) + (Rb & 0);
#else
Ra = curTick;
@@ -690,7 +690,7 @@ decode OPCODE default Unknown::unknown() {
0x00: CallPal::call_pal({{
if (!palValid ||
(palPriv
- && xc->readMiscReg(AlphaISA::IPR_ICM) != AlphaISA::mode_kernel)) {
+ && xc->readMiscReg(IPR_ICM) != mode_kernel)) {
// invalid pal function code, or attempt to do privileged
// PAL call in non-kernel mode
fault = new UnimplementedOpcodeFault;
@@ -701,8 +701,8 @@ decode OPCODE default Unknown::unknown() {
bool dopal = xc->simPalCheck(palFunc);
if (dopal) {
- xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, NPC);
- NPC = xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + palOffset;
+ xc->setMiscReg(IPR_EXC_ADDR, NPC);
+ NPC = xc->readMiscReg(IPR_PAL_BASE) + palOffset;
}
}
}}, IsNonSpeculative);
@@ -783,14 +783,19 @@ decode OPCODE default Unknown::unknown() {
}
}
- format BasicOperate {
- 0x1e: decode PALMODE {
- 0: OpcdecFault::hw_rei();
- 1:hw_rei({{ xc->hwrei(); }}, IsSerializing, IsSerializeBefore);
+ 0x1e: decode PALMODE {
+ 0: OpcdecFault::hw_rei();
+ format BasicOperate {
+ 1: hw_rei({{ xc->hwrei(); }}, IsSerializing, IsSerializeBefore);
}
+ }
+
+#endif
+ format BasicOperate {
// M5 special opcodes use the reserved 0x01 opcode space
0x01: decode M5FUNC {
+#if FULL_SYSTEM
0x00: arm({{
PseudoInst::arm(xc->tcBase());
}}, IsNonSpeculative);
@@ -806,22 +811,34 @@ decode OPCODE default Unknown::unknown() {
0x04: quiesceTime({{
R0 = PseudoInst::quiesceTime(xc->tcBase());
}}, IsNonSpeculative, IsUnverifiable);
- 0x10: ivlb({{
- warn_once("Obsolete M5 instruction ivlb encountered.\n");
+#endif
+ 0x07: rpns({{
+ R0 = PseudoInst::rpns(xc->tcBase());
+ }}, IsNonSpeculative, IsUnverifiable);
+ 0x09: wakeCPU({{
+ PseudoInst::wakeCPU(xc->tcBase(), R16);
+ }}, IsNonSpeculative, IsUnverifiable);
+ 0x10: deprecated_ivlb({{
+ warn_once("Obsolete M5 ivlb instruction encountered.\n");
}});
- 0x11: ivle({{
- warn_once("Obsolete M5 instruction ivlb encountered.\n");
+ 0x11: deprecated_ivle({{
+ warn_once("Obsolete M5 ivlb instruction encountered.\n");
}});
- 0x20: m5exit_old({{
- PseudoInst::m5exit_old(xc->tcBase());
+ 0x20: deprecated_exit ({{
+ warn_once("deprecated M5 exit instruction encountered.\n");
+ PseudoInst::m5exit(xc->tcBase(), 0);
}}, No_OpClass, IsNonSpeculative);
0x21: m5exit({{
PseudoInst::m5exit(xc->tcBase(), R16);
}}, No_OpClass, IsNonSpeculative);
+#if FULL_SYSTEM
0x31: loadsymbol({{
PseudoInst::loadsymbol(xc->tcBase());
}}, No_OpClass, IsNonSpeculative);
- 0x30: initparam({{ Ra = xc->tcBase()->getCpuPtr()->system->init_param; }});
+ 0x30: initparam({{
+ Ra = xc->tcBase()->getCpuPtr()->system->init_param;
+ }});
+#endif
0x40: resetstats({{
PseudoInst::resetstats(xc->tcBase(), R16, R17);
}}, IsNonSpeculative);
@@ -834,28 +851,93 @@ decode OPCODE default Unknown::unknown() {
0x43: m5checkpoint({{
PseudoInst::m5checkpoint(xc->tcBase(), R16, R17);
}}, IsNonSpeculative);
+#if FULL_SYSTEM
0x50: m5readfile({{
R0 = PseudoInst::readfile(xc->tcBase(), R16, R17, R18);
}}, IsNonSpeculative);
+#endif
0x51: m5break({{
PseudoInst::debugbreak(xc->tcBase());
}}, IsNonSpeculative);
0x52: m5switchcpu({{
PseudoInst::switchcpu(xc->tcBase());
}}, IsNonSpeculative);
+#if FULL_SYSTEM
0x53: m5addsymbol({{
PseudoInst::addsymbol(xc->tcBase(), R16, R17);
}}, IsNonSpeculative);
+#endif
0x54: m5panic({{
panic("M5 panic instruction called at pc=%#x.", xc->readPC());
}}, IsNonSpeculative);
- 0x55: m5anBegin({{
- PseudoInst::anBegin(xc->tcBase(), R16);
+#define CPANN(lbl) CPA::cpa()->lbl(xc->tcBase())
+ 0x55: decode RA {
+ 0x00: m5a_old({{
+ panic("Deprecated M5 annotate instruction executed at pc=%#x\n",
+ xc->readPC());
+ }}, IsNonSpeculative);
+ 0x01: m5a_bsm({{
+ CPANN(swSmBegin);
+ }}, IsNonSpeculative);
+ 0x02: m5a_esm({{
+ CPANN(swSmEnd);
+ }}, IsNonSpeculative);
+ 0x03: m5a_begin({{
+ CPANN(swExplictBegin);
+ }}, IsNonSpeculative);
+ 0x04: m5a_end({{
+ CPANN(swEnd);
+ }}, IsNonSpeculative);
+ 0x06: m5a_q({{
+ CPANN(swQ);
+ }}, IsNonSpeculative);
+ 0x07: m5a_dq({{
+ CPANN(swDq);
+ }}, IsNonSpeculative);
+ 0x08: m5a_wf({{
+ CPANN(swWf);
+ }}, IsNonSpeculative);
+ 0x09: m5a_we({{
+ CPANN(swWe);
+ }}, IsNonSpeculative);
+ 0x0C: m5a_sq({{
+ CPANN(swSq);
+ }}, IsNonSpeculative);
+ 0x0D: m5a_aq({{
+ CPANN(swAq);
+ }}, IsNonSpeculative);
+ 0x0E: m5a_pq({{
+ CPANN(swPq);
+ }}, IsNonSpeculative);
+ 0x0F: m5a_l({{
+ CPANN(swLink);
+ }}, IsNonSpeculative);
+ 0x10: m5a_identify({{
+ CPANN(swIdentify);
+ }}, IsNonSpeculative);
+ 0x11: m5a_getid({{
+ R0 = CPANN(swGetId);
+ }}, IsNonSpeculative);
+ 0x13: m5a_scl({{
+ CPANN(swSyscallLink);
+ }}, IsNonSpeculative);
+ 0x14: m5a_rq({{
+ CPANN(swRq);
+ }}, IsNonSpeculative);
+ } // M5 Annotate Operations
+#undef CPANN
+ 0x56: m5reserved2({{
+ warn("M5 reserved opcode ignored");
+ }}, IsNonSpeculative);
+ 0x57: m5reserved3({{
+ warn("M5 reserved opcode ignored");
}}, IsNonSpeculative);
- 0x56: m5anWait({{
- PseudoInst::anWait(xc->tcBase(), R16, R17);
+ 0x58: m5reserved4({{
+ warn("M5 reserved opcode ignored");
+ }}, IsNonSpeculative);
+ 0x59: m5reserved5({{
+ warn("M5 reserved opcode ignored");
}}, IsNonSpeculative);
}
}
-#endif
}
diff --git a/src/arch/alpha/isa/fp.isa b/src/arch/alpha/isa/fp.isa
index 773e7d10c..ed04d2a50 100644
--- a/src/arch/alpha/isa/fp.isa
+++ b/src/arch/alpha/isa/fp.isa
@@ -46,7 +46,7 @@ output exec {{
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
{
Fault fault = NoFault; // dummy... this ipr access should not fault
- if (!EV5::ICSR_FPE(xc->readMiscReg(AlphaISA::IPR_ICSR))) {
+ if (!ICSR_FPE(xc->readMiscReg(IPR_ICSR))) {
fault = new FloatEnableFault;
}
return fault;
@@ -229,7 +229,7 @@ def template FloatingPointExecute {{
%(code)s;
} else {
m5_fesetround(getC99RoundingMode(
- xc->readMiscRegNoEffect(AlphaISA::MISCREG_FPCR)));
+ xc->readMiscRegNoEffect(MISCREG_FPCR)));
%(code)s;
m5_fesetround(M5_FE_TONEAREST);
}
diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa
index d72dfe34a..aea44976c 100644
--- a/src/arch/alpha/isa/main.isa
+++ b/src/arch/alpha/isa/main.isa
@@ -68,9 +68,8 @@ using namespace AlphaISA;
output exec {{
#include <math.h>
-#if FULL_SYSTEM
+#include "base/cp_annotate.hh"
#include "sim/pseudo_inst.hh"
-#endif
#include "arch/alpha/ipr.hh"
#include "base/fenv.hh"
#include "config/ss_compatible_fp.hh"
@@ -173,11 +172,11 @@ 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',
+ 'Ra': ('IntReg', 'uq', 'PALMODE ? reg_redir[RA] : RA',
'IsInteger', 1),
- 'Rb': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RB] : RB',
+ 'Rb': ('IntReg', 'uq', 'PALMODE ? reg_redir[RB] : RB',
'IsInteger', 2),
- 'Rc': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RC] : RC',
+ 'Rc': ('IntReg', 'uq', 'PALMODE ? reg_redir[RC] : RC',
'IsInteger', 3),
'Fa': ('FloatReg', 'df', 'FA', 'IsFloating', 1),
'Fb': ('FloatReg', 'df', 'FB', 'IsFloating', 2),
diff --git a/src/arch/alpha/isa/mem.isa b/src/arch/alpha/isa/mem.isa
index fe0daf772..cd5e117ec 100644
--- a/src/arch/alpha/isa/mem.isa
+++ b/src/arch/alpha/isa/mem.isa
@@ -43,7 +43,7 @@ output header {{
protected:
/// Memory request flags. See mem_req_base.hh.
- unsigned memAccessFlags;
+ Request::Flags memAccessFlags;
/// Pointer to EAComp object.
const StaticInstPtr eaCompPtr;
/// Pointer to MemAcc object.
@@ -54,7 +54,7 @@ output header {{
StaticInstPtr _eaCompPtr = nullStaticInstPtr,
StaticInstPtr _memAccPtr = nullStaticInstPtr)
: AlphaStaticInst(mnem, _machInst, __opClass),
- memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr)
+ eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr)
{
}
@@ -677,6 +677,7 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
inst_flags)
if mem_flags:
+ mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
iop.constructor += s
memacc_iop.constructor += s
diff --git a/src/arch/alpha/isa/pal.isa b/src/arch/alpha/isa/pal.isa
index 294b92e2f..3d3b81600 100644
--- a/src/arch/alpha/isa/pal.isa
+++ b/src/arch/alpha/isa/pal.isa
@@ -174,11 +174,11 @@ output decoder {{
: 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;
+ memAccessFlags.clear();
+ if (HW_LDST_PHYS) memAccessFlags.set(Request::PHYSICAL);
+ if (HW_LDST_ALT) memAccessFlags.set(Request::ALTMODE);
+ if (HW_LDST_VPTE) memAccessFlags.set(Request::VPTE);
+ if (HW_LDST_LOCK) memAccessFlags.set(Request::LOCKED);
}
std::string
diff --git a/src/arch/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh
index be1d1b8bb..d37a769ea 100644
--- a/src/arch/alpha/isa_traits.hh
+++ b/src/arch/alpha/isa_traits.hh
@@ -42,142 +42,134 @@ namespace LittleEndianGuest {}
class StaticInstPtr;
-namespace AlphaISA
+namespace AlphaISA {
+
+using namespace LittleEndianGuest;
+using AlphaISAInst::MaxInstSrcRegs;
+using AlphaISAInst::MaxInstDestRegs;
+
+// These enumerate all the registers for dependence tracking.
+enum DependenceTags {
+ // 0..31 are the integer regs 0..31
+ // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
+ FP_Base_DepTag = 40,
+ Ctrl_Base_DepTag = 72
+};
+
+StaticInstPtr decodeInst(ExtMachInst);
+
+// Alpha Does NOT have a delay slot
+#define ISA_HAS_DELAY_SLOT 0
+
+const Addr PageShift = 13;
+const Addr PageBytes = ULL(1) << PageShift;
+const Addr PageMask = ~(PageBytes - 1);
+const Addr PageOffset = PageBytes - 1;
+
+////////////////////////////////////////////////////////////////////////
+//
+// Translation stuff
+//
+
+const Addr PteShift = 3;
+const Addr NPtePageShift = PageShift - PteShift;
+const Addr NPtePage = ULL(1) << NPtePageShift;
+const Addr PteMask = NPtePage - 1;
+
+// User Virtual
+const Addr USegBase = ULL(0x0);
+const Addr USegEnd = ULL(0x000003ffffffffff);
+
+// Kernel Direct Mapped
+const Addr K0SegBase = ULL(0xfffffc0000000000);
+const Addr K0SegEnd = ULL(0xfffffdffffffffff);
+
+// Kernel Virtual
+const Addr K1SegBase = ULL(0xfffffe0000000000);
+const Addr K1SegEnd = ULL(0xffffffffffffffff);
+
+// For loading... XXX This maybe could be USegEnd?? --ali
+const Addr LoadAddrMask = ULL(0xffffffffff);
+
+////////////////////////////////////////////////////////////////////////
+//
+// Interrupt levels
+//
+enum InterruptLevels
{
- using namespace LittleEndianGuest;
- using AlphaISAInst::MaxInstSrcRegs;
- using AlphaISAInst::MaxInstDestRegs;
-
- // These enumerate all the registers for dependence tracking.
- enum DependenceTags {
- // 0..31 are the integer regs 0..31
- // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
- FP_Base_DepTag = 40,
- Ctrl_Base_DepTag = 72
- };
-
- StaticInstPtr decodeInst(ExtMachInst);
-
- // Alpha Does NOT have a delay slot
- #define ISA_HAS_DELAY_SLOT 0
-
- const Addr PageShift = 13;
- const Addr PageBytes = ULL(1) << PageShift;
- const Addr PageMask = ~(PageBytes - 1);
- const Addr PageOffset = PageBytes - 1;
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Translation stuff
- //
-
- const Addr PteShift = 3;
- const Addr NPtePageShift = PageShift - PteShift;
- const Addr NPtePage = ULL(1) << NPtePageShift;
- const Addr PteMask = NPtePage - 1;
-
- // User Virtual
- const Addr USegBase = ULL(0x0);
- const Addr USegEnd = ULL(0x000003ffffffffff);
-
- // Kernel Direct Mapped
- const Addr K0SegBase = ULL(0xfffffc0000000000);
- const Addr K0SegEnd = ULL(0xfffffdffffffffff);
-
- // Kernel Virtual
- const Addr K1SegBase = ULL(0xfffffe0000000000);
- const Addr K1SegEnd = ULL(0xffffffffffffffff);
-
- // For loading... XXX This maybe could be USegEnd?? --ali
- const Addr LoadAddrMask = ULL(0xffffffffff);
-
-#if FULL_SYSTEM
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Interrupt levels
- //
- enum InterruptLevels
- {
- INTLEVEL_SOFTWARE_MIN = 4,
- INTLEVEL_SOFTWARE_MAX = 19,
-
- INTLEVEL_EXTERNAL_MIN = 20,
- INTLEVEL_EXTERNAL_MAX = 34,
-
- INTLEVEL_IRQ0 = 20,
- INTLEVEL_IRQ1 = 21,
- INTINDEX_ETHERNET = 0,
- INTINDEX_SCSI = 1,
- INTLEVEL_IRQ2 = 22,
- INTLEVEL_IRQ3 = 23,
-
- INTLEVEL_SERIAL = 33,
-
- NumInterruptLevels = INTLEVEL_EXTERNAL_MAX
- };
-
-#endif
-
- // EV5 modes
- enum mode_type
- {
- mode_kernel = 0, // kernel
- mode_executive = 1, // executive (unused by unix)
- mode_supervisor = 2, // supervisor (unused by unix)
- mode_user = 3, // user mode
- mode_number // number of modes
- };
-
- // Constants Related to the number of registers
-
- const int NumIntArchRegs = 32;
- const int NumPALShadowRegs = 8;
- const int NumFloatArchRegs = 32;
- // @todo: Figure out what this number really should be.
- const int NumMiscArchRegs = 77;
-
- const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
- const int NumFloatRegs = NumFloatArchRegs;
- const int NumMiscRegs = NumMiscArchRegs;
-
- const int TotalNumRegs = NumIntRegs + NumFloatRegs +
- NumMiscRegs + NumInternalProcRegs;
-
- const int TotalDataRegs = NumIntRegs + NumFloatRegs;
-
- // semantically meaningful register indices
- const int ZeroReg = 31; // architecturally meaningful
- // the rest of these depend on the ABI
- const int StackPointerReg = 30;
- const int GlobalPointerReg = 29;
- const int ProcedureValueReg = 27;
- const int ReturnAddressReg = 26;
- const int ReturnValueReg = 0;
- const int FramePointerReg = 15;
+ INTLEVEL_SOFTWARE_MIN = 4,
+ INTLEVEL_SOFTWARE_MAX = 19,
+
+ INTLEVEL_EXTERNAL_MIN = 20,
+ INTLEVEL_EXTERNAL_MAX = 34,
- const int ArgumentReg[] = {16, 17, 18, 19, 20, 21};
- const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int);
+ INTLEVEL_IRQ0 = 20,
+ INTLEVEL_IRQ1 = 21,
+ INTINDEX_ETHERNET = 0,
+ INTINDEX_SCSI = 1,
+ INTLEVEL_IRQ2 = 22,
+ INTLEVEL_IRQ3 = 23,
- const int SyscallNumReg = ReturnValueReg;
- const int SyscallPseudoReturnReg = ArgumentReg[4];
- const int SyscallSuccessReg = 19;
+ INTLEVEL_SERIAL = 33,
- const int LogVMPageSize = 13; // 8K bytes
- const int VMPageSize = (1 << LogVMPageSize);
-
- const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
-
- const int MachineBytes = 8;
- const int WordBytes = 4;
- const int HalfwordBytes = 2;
- const int ByteBytes = 1;
-
- // return a no-op instruction... used for instruction fetch faults
- // Alpha UNOP (ldq_u r31,0(r0))
- const ExtMachInst NoopMachInst = 0x2ffe0000;
+ NumInterruptLevels = INTLEVEL_EXTERNAL_MAX
+};
+// EV5 modes
+enum mode_type
+{
+ mode_kernel = 0, // kernel
+ mode_executive = 1, // executive (unused by unix)
+ mode_supervisor = 2, // supervisor (unused by unix)
+ mode_user = 3, // user mode
+ mode_number // number of modes
};
+// Constants Related to the number of registers
+
+const int NumIntArchRegs = 32;
+const int NumPALShadowRegs = 8;
+const int NumFloatArchRegs = 32;
+// @todo: Figure out what this number really should be.
+const int NumMiscArchRegs = 77;
+
+const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
+const int NumFloatRegs = NumFloatArchRegs;
+const int NumMiscRegs = NumMiscArchRegs;
+
+const int TotalNumRegs =
+ NumIntRegs + NumFloatRegs + NumMiscRegs + NumInternalProcRegs;
+
+const int TotalDataRegs = NumIntRegs + NumFloatRegs;
+
+// semantically meaningful register indices
+const int ZeroReg = 31; // architecturally meaningful
+// the rest of these depend on the ABI
+const int StackPointerReg = 30;
+const int GlobalPointerReg = 29;
+const int ProcedureValueReg = 27;
+const int ReturnAddressReg = 26;
+const int ReturnValueReg = 0;
+const int FramePointerReg = 15;
+
+const int SyscallNumReg = 0;
+const int FirstArgumentReg = 16;
+const int SyscallPseudoReturnReg = 20;
+
+const int LogVMPageSize = 13; // 8K bytes
+const int VMPageSize = (1 << LogVMPageSize);
+
+const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
+
+const int MachineBytes = 8;
+const int WordBytes = 4;
+const int HalfwordBytes = 2;
+const int ByteBytes = 1;
+
+// return a no-op instruction... used for instruction fetch faults
+// Alpha UNOP (ldq_u r31,0(r0))
+const ExtMachInst NoopMachInst = 0x2ffe0000;
+
+} // namespace AlphaISA
+
#endif // __ARCH_ALPHA_ISA_TRAITS_HH__
diff --git a/src/arch/alpha/kernel_stats.cc b/src/arch/alpha/kernel_stats.cc
index a004d5f25..6e9dc1611 100644
--- a/src/arch/alpha/kernel_stats.cc
+++ b/src/arch/alpha/kernel_stats.cc
@@ -152,7 +152,7 @@ Statistics::changeMode(cpu_mode newmode, ThreadContext *tc)
void
Statistics::mode(cpu_mode newmode, ThreadContext *tc)
{
- Addr pcbb = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23);
+ Addr pcbb = tc->readMiscRegNoEffect(IPR_PALtemp23);
if (newmode == kernel && pcbb == idleProcess)
newmode = idle;
@@ -213,5 +213,5 @@ Statistics::unserialize(Checkpoint *cp, const string &section)
themode = (cpu_mode)exemode;
}
-} /* end namespace AlphaISA::Kernel */
-} /* end namespace AlphaISA */
+} // namespace Kernel
+} // namespace AlphaISA
diff --git a/src/arch/alpha/kernel_stats.hh b/src/arch/alpha/kernel_stats.hh
index 7b8640ad7..837269309 100644
--- a/src/arch/alpha/kernel_stats.hh
+++ b/src/arch/alpha/kernel_stats.hh
@@ -62,15 +62,15 @@ class Statistics : public ::Kernel::Statistics
void changeMode(cpu_mode newmode, ThreadContext *tc);
private:
- Stats::Vector<> _callpal;
-// Stats::Vector<> _faults;
+ Stats::Vector _callpal;
+// Stats::Vector _faults;
- Stats::Vector<> _mode;
- Stats::Vector<> _modeGood;
+ Stats::Vector _mode;
+ Stats::Vector _modeGood;
Stats::Formula _modeFraction;
- Stats::Vector<> _modeTicks;
+ Stats::Vector _modeTicks;
- Stats::Scalar<> _swap_context;
+ Stats::Scalar _swap_context;
public:
Statistics(System *system);
@@ -90,7 +90,7 @@ class Statistics : public ::Kernel::Statistics
void unserialize(Checkpoint *cp, const std::string &section);
};
-} /* end namespace AlphaISA::Kernel */
-} /* end namespace AlphaISA */
+} // namespace Kernel
+} // namespace AlphaISA
#endif // __ARCH_ALPHA_KERNEL_STATS_HH__
diff --git a/src/arch/alpha/linux/linux.cc b/src/arch/alpha/linux/linux.cc
index e6908a572..ad8388096 100644
--- a/src/arch/alpha/linux/linux.cc
+++ b/src/arch/alpha/linux/linux.cc
@@ -28,47 +28,44 @@
* Authors: Korey Sewell
*/
-#include "arch/alpha/linux/linux.hh"
-
#include <fcntl.h>
+#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 },
+ { 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 },
+ { AlphaLinux::TGT_O_NONBLOCK, _O_NONBLOCK },
#endif
#ifdef _O_NOCTTY
- { AlphaLinux::TGT_O_NOCTTY, _O_NOCTTY },
+ { AlphaLinux::TGT_O_NOCTTY, _O_NOCTTY },
#endif
#ifdef _O_SYNC
- { AlphaLinux::TGT_O_SYNC, _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 },
+ { 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 },
+ { AlphaLinux::TGT_O_SYNC, O_SYNC },
#endif
#endif /* _MSC_VER */
};
const int AlphaLinux::NUM_OPEN_FLAGS =
- (sizeof(AlphaLinux::openFlagTable)/sizeof(AlphaLinux::openFlagTable[0]));
-
-
-
+ (sizeof(AlphaLinux::openFlagTable)/sizeof(AlphaLinux::openFlagTable[0]));
diff --git a/src/arch/alpha/linux/linux.hh b/src/arch/alpha/linux/linux.hh
index 84c04ebc3..c622c5ef1 100644
--- a/src/arch/alpha/linux/linux.hh
+++ b/src/arch/alpha/linux/linux.hh
@@ -28,8 +28,8 @@
* Authors: Korey Sewell
*/
-#ifndef __ALPHA_ALPHA_LINUX_HH
-#define __ALPHA_ALPHA_LINUX_HH
+#ifndef __ALPHA_ALPHA_LINUX_LINUX_HH__
+#define __ALPHA_ALPHA_LINUX_LINUX_HH__
#include "kern/linux/linux.hh"
@@ -50,21 +50,21 @@ class AlphaLinux : public Linux
//@{
/// 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
+ 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().
@@ -72,13 +72,13 @@ class AlphaLinux : public Linux
//@{
/// 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_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 # CPUs on 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;
//@}
@@ -127,4 +127,4 @@ class AlphaLinux : public Linux
};
};
-#endif
+#endif // __ALPHA_ALPHA_LINUX_LINUX_HH__
diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc
index ec47992bd..aeff9fbed 100644
--- a/src/arch/alpha/linux/process.cc
+++ b/src/arch/alpha/linux/process.cc
@@ -43,18 +43,16 @@
using namespace std;
using namespace AlphaISA;
-
-
/// Target uname() handler.
static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
+ TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
- strcpy(name->release, "2.4.20");
+ strcpy(name->release, "2.6.26");
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "alpha");
@@ -69,13 +67,13 @@ static SyscallReturn
osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- unsigned op = tc->getSyscallArg(0);
- // unsigned nbytes = tc->getSyscallArg(2);
+ unsigned op = process->getSyscallArg(tc, 0);
+ // unsigned nbytes = process->getSyscallArg(tc, 2);
switch (op) {
case 45: { // GSI_IEEE_FP_CONTROL
- TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1));
+ TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
// I don't think this exactly matches the HW FPCR
*fpcr = 0;
fpcr.copyOut(tc->getMemPort());
@@ -96,13 +94,13 @@ static SyscallReturn
osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- unsigned op = tc->getSyscallArg(0);
- // unsigned nbytes = tc->getSyscallArg(2);
+ unsigned op = process->getSyscallArg(tc, 0);
+ // unsigned nbytes = process->getSyscallArg(tc, 2);
switch (op) {
case 14: { // SSI_IEEE_FP_CONTROL
- TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1));
+ TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
// I don't think this exactly matches the HW FPCR
fpcr.copyIn(tc->getMemPort());
DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
@@ -138,7 +136,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", chmodFunc<AlphaLinux>),
/* 16 */ SyscallDesc("chown", chownFunc),
- /* 17 */ SyscallDesc("brk", obreakFunc),
+ /* 17 */ SyscallDesc("brk", brkFunc),
/* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getxpid", getpidPseudoFunc),
@@ -179,9 +177,9 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
/* 55 */ SyscallDesc("osf_reboot", unimplementedFunc),
/* 56 */ SyscallDesc("osf_revoke", unimplementedFunc),
/* 57 */ SyscallDesc("symlink", unimplementedFunc),
- /* 58 */ SyscallDesc("readlink", unimplementedFunc),
+ /* 58 */ SyscallDesc("readlink", readlinkFunc),
/* 59 */ SyscallDesc("execve", unimplementedFunc),
- /* 60 */ SyscallDesc("umask", unimplementedFunc),
+ /* 60 */ SyscallDesc("umask", umaskFunc),
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
/* 62 */ SyscallDesc("osf_old_fstat", unimplementedFunc),
/* 63 */ SyscallDesc("getpgrp", unimplementedFunc),
@@ -250,14 +248,14 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
/* 126 */ SyscallDesc("setreuid", unimplementedFunc),
/* 127 */ SyscallDesc("setregid", unimplementedFunc),
/* 128 */ SyscallDesc("rename", renameFunc),
- /* 129 */ SyscallDesc("truncate", unimplementedFunc),
- /* 130 */ SyscallDesc("ftruncate", unimplementedFunc),
+ /* 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),
+ /* 136 */ SyscallDesc("mkdir", mkdirFunc),
/* 137 */ SyscallDesc("rmdir", unimplementedFunc),
/* 138 */ SyscallDesc("osf_utimes", unimplementedFunc),
/* 139 */ SyscallDesc("osf_old_sigreturn", unimplementedFunc),
@@ -465,7 +463,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
/* 338 */ SyscallDesc("afs_syscall", unimplementedFunc),
/* 339 */ SyscallDesc("uname", unameFunc),
/* 340 */ SyscallDesc("nanosleep", unimplementedFunc),
- /* 341 */ SyscallDesc("mremap", unimplementedFunc),
+ /* 341 */ SyscallDesc("mremap", mremapFunc<AlphaLinux>),
/* 342 */ SyscallDesc("nfsservctl", unimplementedFunc),
/* 343 */ SyscallDesc("setresuid", unimplementedFunc),
/* 344 */ SyscallDesc("getresuid", unimplementedFunc),
@@ -491,7 +489,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
/* 364 */ SyscallDesc("getrusage", getrusageFunc<AlphaLinux>),
/* 365 */ SyscallDesc("wait4", unimplementedFunc),
/* 366 */ SyscallDesc("adjtimex", unimplementedFunc),
- /* 367 */ SyscallDesc("getcwd", unimplementedFunc),
+ /* 367 */ SyscallDesc("getcwd", getcwdFunc),
/* 368 */ SyscallDesc("capget", unimplementedFunc),
/* 369 */ SyscallDesc("capset", unimplementedFunc),
/* 370 */ SyscallDesc("sendfile", unimplementedFunc),
@@ -581,7 +579,7 @@ AlphaLinuxProcess::AlphaLinuxProcess(LiveProcessParams * params,
SyscallDesc*
AlphaLinuxProcess::getDesc(int callnum)
{
- if (callnum < 0 || callnum > Num_Syscall_Descs)
+ if (callnum < 0 || callnum >= Num_Syscall_Descs)
return NULL;
return &syscallDescs[callnum];
}
diff --git a/src/arch/alpha/linux/process.hh b/src/arch/alpha/linux/process.hh
index 8d7c24e37..9ab7b0501 100644
--- a/src/arch/alpha/linux/process.hh
+++ b/src/arch/alpha/linux/process.hh
@@ -51,4 +51,5 @@ class AlphaLinuxProcess : public AlphaLiveProcess
};
} // namespace AlphaISA
+
#endif // __ALPHA_LINUX_PROCESS_HH__
diff --git a/src/arch/alpha/linux/system.cc b/src/arch/alpha/linux/system.cc
index 102598716..1d9332a58 100644
--- a/src/arch/alpha/linux/system.cc
+++ b/src/arch/alpha/linux/system.cc
@@ -157,7 +157,6 @@ LinuxAlphaSystem::~LinuxAlphaSystem()
delete printThreadEvent;
}
-
void
LinuxAlphaSystem::setDelayLoop(ThreadContext *tc)
{
@@ -169,11 +168,9 @@ LinuxAlphaSystem::setDelayLoop(ThreadContext *tc)
vp = tc->getVirtPort();
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
- tc->delVirtPort(vp);
}
}
-
void
LinuxAlphaSystem::SkipDelayLoopEvent::process(ThreadContext *tc)
{
diff --git a/src/arch/alpha/linux/system.hh b/src/arch/alpha/linux/system.hh
index 00cde826a..3e4de7b2a 100644
--- a/src/arch/alpha/linux/system.hh
+++ b/src/arch/alpha/linux/system.hh
@@ -43,9 +43,6 @@ class IdleStartEvent;
#include "kern/linux/events.hh"
#include "params/LinuxAlphaSystem.hh"
-using namespace AlphaISA;
-using namespace Linux;
-
/**
* This class contains linux specific system code (Loading, Events).
* It points to objects that are the system binaries to load and patches them
@@ -54,23 +51,20 @@ using namespace Linux;
class LinuxAlphaSystem : public AlphaSystem
{
private:
- class SkipDelayLoopEvent : public SkipFuncEvent
+ struct SkipDelayLoopEvent : public SkipFuncEvent
{
- public:
SkipDelayLoopEvent(PCEventQueue *q, const std::string &desc, Addr addr)
: SkipFuncEvent(q, desc, addr) {}
virtual void process(ThreadContext *tc);
};
- class PrintThreadInfo : public PCEvent
+ struct PrintThreadInfo : public PCEvent
{
- public:
PrintThreadInfo(PCEventQueue *q, const std::string &desc, Addr addr)
: PCEvent(q, desc, addr) {}
virtual void process(ThreadContext *tc);
};
-
/**
* Addresses defining where the kernel bootloader places various
* elements. Details found in include/asm-alpha/system.h
@@ -112,7 +106,7 @@ class LinuxAlphaSystem : public AlphaSystem
* PC based event to skip the dprink() call and emulate its
* functionality
*/
- DebugPrintkEvent *debugPrintkEvent;
+ Linux::DebugPrintkEvent *debugPrintkEvent;
/**
* Skip calculate_delay_loop() rather than waiting for this to be
diff --git a/src/arch/alpha/linux/threadinfo.hh b/src/arch/alpha/linux/threadinfo.hh
index b0c8284be..db723bed3 100644
--- a/src/arch/alpha/linux/threadinfo.hh
+++ b/src/arch/alpha/linux/threadinfo.hh
@@ -55,7 +55,7 @@ class ThreadInfo
CopyOut(tc, &data, addr, sizeof(T));
- data = TheISA::gtoh(data);
+ data = AlphaISA::gtoh(data);
return true;
}
@@ -76,7 +76,7 @@ class ThreadInfo
Addr sp;
if (!addr)
- addr = tc->readMiscRegNoEffect(TheISA::IPR_PALtemp23);
+ addr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23);
FunctionalPort *p = tc->getPhysPort();
p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
@@ -147,6 +147,6 @@ class ThreadInfo
}
};
-/* namespace Linux */ }
+} // namespace Linux
#endif // __ARCH_ALPHA_LINUX_LINUX_THREADINFO_HH__
diff --git a/src/arch/alpha/locked_mem.hh b/src/arch/alpha/locked_mem.hh
index df66b92bc..e8928ba08 100644
--- a/src/arch/alpha/locked_mem.hh
+++ b/src/arch/alpha/locked_mem.hh
@@ -49,9 +49,8 @@
#include "base/misc.hh"
#include "mem/request.hh"
+namespace AlphaISA {
-namespace AlphaISA
-{
template <class XC>
inline void
handleLockedRead(XC *xc, Request *req)
@@ -86,9 +85,9 @@ handleLockedWrite(XC *xc, Request *req)
stCondFailures++;
xc->setStCondFailures(stCondFailures);
if (stCondFailures % 100000 == 0) {
- warn("cpu %d: %d consecutive "
+ warn("context %d: %d consecutive "
"store conditional failures\n",
- xc->readCpuId(), stCondFailures);
+ xc->contextId(), stCondFailures);
}
// store conditional failed already, so don't issue it to mem
@@ -99,7 +98,6 @@ handleLockedWrite(XC *xc, Request *req)
return true;
}
-
} // namespace AlphaISA
-#endif
+#endif // __ARCH_ALPHA_LOCKED_MEM_HH__
diff --git a/src/arch/alpha/syscallreturn.hh b/src/arch/alpha/microcode_rom.hh
index 47b4ac8c7..ef0602580 100644
--- a/src/arch/alpha/syscallreturn.hh
+++ b/src/arch/alpha/microcode_rom.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2008 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,34 +25,17 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * Authors: Steve Reinhardt
- * Gabe Black
+ * Authors: Gabe Black
*/
-#ifndef __ARCH_ALPHA_SYSCALLRETURN_HH__
-#define __ARCH_ALPHA_SYSCALLRETURN_HH__
+#ifndef __ARCH_ALPHA_MICROCODE_ROM_HH__
+#define __ARCH_ALPHA_MICROCODE_ROM_HH__
-#include "cpu/thread_context.hh"
-#include "sim/syscallreturn.hh"
+#include "sim/microcode_rom.hh"
namespace AlphaISA
{
- static inline void setSyscallReturn(SyscallReturn return_value,
- ThreadContext * tc)
- {
- // 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
- tc->setIntReg(SyscallSuccessReg, 0);
- tc->setIntReg(ReturnValueReg, return_value.value());
- } else {
- // got an error, return details
- tc->setIntReg(SyscallSuccessReg, (IntReg)-1);
- tc->setIntReg(ReturnValueReg, -return_value.value());
- }
- }
+ using ::MicrocodeRom;
}
-#endif
+#endif // __ARCH_ALPHA_MICROCODE_ROM_HH__
diff --git a/src/arch/alpha/miscregfile.cc b/src/arch/alpha/miscregfile.cc
index cb5875349..61a86f1fb 100644
--- a/src/arch/alpha/miscregfile.cc
+++ b/src/arch/alpha/miscregfile.cc
@@ -30,121 +30,121 @@
* Kevin Lim
*/
+#include <cassert>
+
#include "arch/alpha/miscregfile.hh"
#include "base/misc.hh"
-namespace AlphaISA
-{
+namespace AlphaISA {
- void
- MiscRegFile::serialize(std::ostream &os)
- {
- SERIALIZE_SCALAR(fpcr);
- SERIALIZE_SCALAR(uniq);
- SERIALIZE_SCALAR(lock_flag);
- SERIALIZE_SCALAR(lock_addr);
- SERIALIZE_ARRAY(ipr, NumInternalProcRegs);
- }
+void
+MiscRegFile::serialize(std::ostream &os)
+{
+ SERIALIZE_SCALAR(fpcr);
+ SERIALIZE_SCALAR(uniq);
+ SERIALIZE_SCALAR(lock_flag);
+ SERIALIZE_SCALAR(lock_addr);
+ SERIALIZE_ARRAY(ipr, NumInternalProcRegs);
+}
- void
- MiscRegFile::unserialize(Checkpoint *cp, const std::string &section)
- {
- UNSERIALIZE_SCALAR(fpcr);
- UNSERIALIZE_SCALAR(uniq);
- UNSERIALIZE_SCALAR(lock_flag);
- UNSERIALIZE_SCALAR(lock_addr);
- UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs);
- }
+void
+MiscRegFile::unserialize(Checkpoint *cp, const std::string &section)
+{
+ UNSERIALIZE_SCALAR(fpcr);
+ UNSERIALIZE_SCALAR(uniq);
+ UNSERIALIZE_SCALAR(lock_flag);
+ UNSERIALIZE_SCALAR(lock_addr);
+ UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs);
+}
- MiscReg
- MiscRegFile::readRegNoEffect(int misc_reg)
- {
- switch(misc_reg) {
- case MISCREG_FPCR:
- return fpcr;
- case MISCREG_UNIQ:
- return uniq;
- case MISCREG_LOCKFLAG:
- return lock_flag;
- case MISCREG_LOCKADDR:
- return lock_addr;
- case MISCREG_INTR:
- return intr_flag;
- default:
- assert(misc_reg < NumInternalProcRegs);
- return ipr[misc_reg];
- }
+MiscReg
+MiscRegFile::readRegNoEffect(int misc_reg)
+{
+ switch (misc_reg) {
+ case MISCREG_FPCR:
+ return fpcr;
+ case MISCREG_UNIQ:
+ return uniq;
+ case MISCREG_LOCKFLAG:
+ return lock_flag;
+ case MISCREG_LOCKADDR:
+ return lock_addr;
+ case MISCREG_INTR:
+ return intr_flag;
+ default:
+ assert(misc_reg < NumInternalProcRegs);
+ return ipr[misc_reg];
}
+}
- MiscReg
- MiscRegFile::readReg(int misc_reg, ThreadContext *tc)
- {
- switch(misc_reg) {
- case MISCREG_FPCR:
- return fpcr;
- case MISCREG_UNIQ:
- return uniq;
- case MISCREG_LOCKFLAG:
- return lock_flag;
- case MISCREG_LOCKADDR:
- return lock_addr;
- case MISCREG_INTR:
- return intr_flag;
- default:
- return readIpr(misc_reg, tc);
- }
+MiscReg
+MiscRegFile::readReg(int misc_reg, ThreadContext *tc)
+{
+ switch (misc_reg) {
+ case MISCREG_FPCR:
+ return fpcr;
+ case MISCREG_UNIQ:
+ return uniq;
+ case MISCREG_LOCKFLAG:
+ return lock_flag;
+ case MISCREG_LOCKADDR:
+ return lock_addr;
+ case MISCREG_INTR:
+ return intr_flag;
+ default:
+ return readIpr(misc_reg, tc);
}
+}
- void
- MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val)
- {
- switch(misc_reg) {
- case MISCREG_FPCR:
- fpcr = val;
- return;
- case MISCREG_UNIQ:
- uniq = val;
- return;
- case MISCREG_LOCKFLAG:
- lock_flag = val;
- return;
- case MISCREG_LOCKADDR:
- lock_addr = val;
- return;
- case MISCREG_INTR:
- intr_flag = val;
- return;
- default:
- assert(misc_reg < NumInternalProcRegs);
- ipr[misc_reg] = val;
- return;
- }
+void
+MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val)
+{
+ switch (misc_reg) {
+ case MISCREG_FPCR:
+ fpcr = val;
+ return;
+ case MISCREG_UNIQ:
+ uniq = val;
+ return;
+ case MISCREG_LOCKFLAG:
+ lock_flag = val;
+ return;
+ case MISCREG_LOCKADDR:
+ lock_addr = val;
+ return;
+ case MISCREG_INTR:
+ intr_flag = val;
+ return;
+ default:
+ assert(misc_reg < NumInternalProcRegs);
+ ipr[misc_reg] = val;
+ return;
}
+}
- void
- MiscRegFile::setReg(int misc_reg, const MiscReg &val,
- ThreadContext *tc)
- {
- switch(misc_reg) {
- case MISCREG_FPCR:
- fpcr = val;
- return;
- case MISCREG_UNIQ:
- uniq = val;
- return;
- case MISCREG_LOCKFLAG:
- lock_flag = val;
- return;
- case MISCREG_LOCKADDR:
- lock_addr = val;
- return;
- case MISCREG_INTR:
- intr_flag = val;
- return;
- default:
- setIpr(misc_reg, val, tc);
- return;
- }
+void
+MiscRegFile::setReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
+{
+ switch (misc_reg) {
+ case MISCREG_FPCR:
+ fpcr = val;
+ return;
+ case MISCREG_UNIQ:
+ uniq = val;
+ return;
+ case MISCREG_LOCKFLAG:
+ lock_flag = val;
+ return;
+ case MISCREG_LOCKADDR:
+ lock_addr = val;
+ return;
+ case MISCREG_INTR:
+ intr_flag = val;
+ return;
+ default:
+ setIpr(misc_reg, val, tc);
+ return;
}
-
}
+
+} // namespace AlphaISA
diff --git a/src/arch/alpha/miscregfile.hh b/src/arch/alpha/miscregfile.hh
index 022b6404a..6105ce683 100644
--- a/src/arch/alpha/miscregfile.hh
+++ b/src/arch/alpha/miscregfile.hh
@@ -32,85 +32,79 @@
#ifndef __ARCH_ALPHA_MISCREGFILE_HH__
#define __ARCH_ALPHA_MISCREGFILE_HH__
+#include <iosfwd>
+
#include "arch/alpha/ipr.hh"
#include "arch/alpha/types.hh"
#include "sim/host.hh"
#include "sim/serialize.hh"
-#include <iostream>
-
class Checkpoint;
class ThreadContext;
-namespace AlphaISA
-{
- enum MiscRegIndex
- {
- MISCREG_FPCR = NumInternalProcRegs,
- MISCREG_UNIQ,
- MISCREG_LOCKFLAG,
- MISCREG_LOCKADDR,
- MISCREG_INTR
- };
-
- static inline std::string getMiscRegName(RegIndex)
- {
- return "";
- }
-
- class MiscRegFile {
- protected:
- uint64_t fpcr; // floating point condition codes
- uint64_t uniq; // process-unique register
- bool lock_flag; // lock flag for LL/SC
- Addr lock_addr; // lock address for LL/SC
- int intr_flag;
-
- public:
- MiscRegFile()
- {
- initializeIprTable();
- }
+namespace AlphaISA {
- MiscReg readRegNoEffect(int misc_reg);
-
- MiscReg readReg(int misc_reg, ThreadContext *tc);
+enum MiscRegIndex
+{
+ MISCREG_FPCR = NumInternalProcRegs,
+ MISCREG_UNIQ,
+ MISCREG_LOCKFLAG,
+ MISCREG_LOCKADDR,
+ MISCREG_INTR
+};
+
+class MiscRegFile
+{
+ public:
+ friend class RegFile;
+ typedef uint64_t InternalProcReg;
- //These functions should be removed once the simplescalar cpu model
- //has been replaced.
- int getInstAsid();
- int getDataAsid();
+ protected:
+ uint64_t fpcr; // floating point condition codes
+ uint64_t uniq; // process-unique register
+ bool lock_flag; // lock flag for LL/SC
+ Addr lock_addr; // lock address for LL/SC
+ int intr_flag;
- void setRegNoEffect(int misc_reg, const MiscReg &val);
+ InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
- void setReg(int misc_reg, const MiscReg &val,
- ThreadContext *tc);
+ protected:
+ InternalProcReg readIpr(int idx, ThreadContext *tc);
+ void setIpr(int idx, InternalProcReg val, ThreadContext *tc);
- void clear()
- {
- fpcr = uniq = 0;
- lock_flag = 0;
- lock_addr = 0;
- intr_flag = 0;
- }
+ public:
+ MiscRegFile()
+ {
+ initializeIprTable();
+ }
- void serialize(std::ostream &os);
+ // These functions should be removed once the simplescalar cpu
+ // model has been replaced.
+ int getInstAsid();
+ int getDataAsid();
- void unserialize(Checkpoint *cp, const std::string &section);
- protected:
- typedef uint64_t InternalProcReg;
+ MiscReg readRegNoEffect(int misc_reg);
+ MiscReg readReg(int misc_reg, ThreadContext *tc);
- InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
+ void setRegNoEffect(int misc_reg, const MiscReg &val);
+ void setReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
- private:
- InternalProcReg readIpr(int idx, ThreadContext *tc);
+ void
+ clear()
+ {
+ fpcr = 0;
+ uniq = 0;
+ lock_flag = 0;
+ lock_addr = 0;
+ intr_flag = 0;
+ }
- void setIpr(int idx, InternalProcReg val, ThreadContext *tc);
- friend class RegFile;
- };
+ void serialize(std::ostream &os);
+ void unserialize(Checkpoint *cp, const std::string &section);
+};
- void copyIprs(ThreadContext *src, ThreadContext *dest);
+void copyIprs(ThreadContext *src, ThreadContext *dest);
-}
+} // namespace AlphaISA
-#endif
+#endif // __ARCH_ALPHA_MISCREGFILE_HH__
diff --git a/src/arch/alpha/mmaped_ipr.hh b/src/arch/alpha/mmaped_ipr.hh
index 2b4ba8745..af2469ca7 100644
--- a/src/arch/alpha/mmaped_ipr.hh
+++ b/src/arch/alpha/mmaped_ipr.hh
@@ -39,9 +39,8 @@
#include "mem/packet.hh"
+namespace AlphaISA {
-namespace AlphaISA
-{
inline Tick
handleIprRead(ThreadContext *xc, Packet *pkt)
{
@@ -58,4 +57,4 @@ handleIprWrite(ThreadContext *xc, Packet *pkt)
} // namespace AlphaISA
-#endif
+#endif // __ARCH_ALPHA_MMAPED_IPR_HH__
diff --git a/src/arch/alpha/osfpal.cc b/src/arch/alpha/osfpal.cc
index ed1d255a6..58a3d31eb 100644
--- a/src/arch/alpha/osfpal.cc
+++ b/src/arch/alpha/osfpal.cc
@@ -30,275 +30,273 @@
#include "arch/alpha/osfpal.hh"
-namespace {
- const char *strings[PAL::NumCodes] = {
+const char *
+PAL::name(int index)
+{
+ static 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
+ "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
+ "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
+ 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;
diff --git a/src/arch/alpha/osfpal.hh b/src/arch/alpha/osfpal.hh
index cf3940b85..2618e9dbd 100644
--- a/src/arch/alpha/osfpal.hh
+++ b/src/arch/alpha/osfpal.hh
@@ -28,8 +28,8 @@
* Authors: Nathan Binkert
*/
-#ifndef __OSFPAL_HH__
-#define __OSFPAL_HH__
+#ifndef __ARCH_ALPHA_OSFPAL_HH__
+#define __ARCH_ALPHA_OSFPAL_HH__
struct PAL
{
@@ -79,4 +79,4 @@ struct PAL
static const char *name(int index);
};
-#endif // __OSFPAL_HH__
+#endif // __ARCH_ALPHA_OSFPAL_HH__
diff --git a/src/arch/alpha/pagetable.cc b/src/arch/alpha/pagetable.cc
index 3f9537834..6640e72e2 100644
--- a/src/arch/alpha/pagetable.cc
+++ b/src/arch/alpha/pagetable.cc
@@ -31,33 +31,34 @@
#include "arch/alpha/pagetable.hh"
#include "sim/serialize.hh"
-namespace AlphaISA
+namespace AlphaISA {
+
+void
+TlbEntry::serialize(std::ostream &os)
{
- void
- TlbEntry::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);
- }
+ 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
- TlbEntry::unserialize(Checkpoint *cp, const std::string &section)
- {
- UNSERIALIZE_SCALAR(tag);
- UNSERIALIZE_SCALAR(ppn);
- UNSERIALIZE_SCALAR(xre);
- UNSERIALIZE_SCALAR(xwe);
- UNSERIALIZE_SCALAR(asn);
- UNSERIALIZE_SCALAR(asma);
- UNSERIALIZE_SCALAR(fonr);
- UNSERIALIZE_SCALAR(fonw);
- UNSERIALIZE_SCALAR(valid);
- }
+void
+TlbEntry::unserialize(Checkpoint *cp, const std::string &section)
+{
+ UNSERIALIZE_SCALAR(tag);
+ UNSERIALIZE_SCALAR(ppn);
+ UNSERIALIZE_SCALAR(xre);
+ UNSERIALIZE_SCALAR(xwe);
+ UNSERIALIZE_SCALAR(asn);
+ UNSERIALIZE_SCALAR(asma);
+ UNSERIALIZE_SCALAR(fonr);
+ UNSERIALIZE_SCALAR(fonw);
+ UNSERIALIZE_SCALAR(valid);
}
+
+} //namespace AlphaISA
diff --git a/src/arch/alpha/pagetable.hh b/src/arch/alpha/pagetable.hh
index 8ce5b4e5d..59df93bef 100644
--- a/src/arch/alpha/pagetable.hh
+++ b/src/arch/alpha/pagetable.hh
@@ -38,97 +38,109 @@
namespace AlphaISA {
- struct VAddr
+struct VAddr
+{
+ static const int ImplBits = 43;
+ static const Addr ImplMask = (ULL(1) << ImplBits) - 1;
+ static const Addr UnImplMask = ~ImplMask;
+
+ Addr addr;
+
+ VAddr(Addr a) : addr(a) {}
+ operator Addr() const { return addr; }
+ const VAddr &operator=(Addr a) { addr = a; return *this; }
+
+ Addr vpn() const { return (addr & ImplMask) >> PageShift; }
+ Addr page() const { return addr & PageMask; }
+ Addr offset() const { return addr & PageOffset; }
+
+ Addr level3() const
+ { return PteAddr(addr >> PageShift); }
+ Addr level2() const
+ { return PteAddr(addr >> (NPtePageShift + PageShift)); }
+ Addr level1() const
+ { return PteAddr(addr >> (2 * NPtePageShift + PageShift)); }
+};
+
+struct PageTableEntry
+{
+ PageTableEntry(uint64_t e) : entry(e) {}
+ uint64_t entry;
+ operator uint64_t() const { return entry; }
+ const PageTableEntry &operator=(uint64_t e) { entry = e; return *this; }
+ const PageTableEntry &operator=(const PageTableEntry &e)
+ { entry = e.entry; return *this; }
+
+ Addr _pfn() const { return (entry >> 32) & 0xffffffff; }
+ Addr _sw() const { return (entry >> 16) & 0xffff; }
+ int _rsv0() const { return (entry >> 14) & 0x3; }
+ bool _uwe() const { return (entry >> 13) & 0x1; }
+ bool _kwe() const { return (entry >> 12) & 0x1; }
+ int _rsv1() const { return (entry >> 10) & 0x3; }
+ bool _ure() const { return (entry >> 9) & 0x1; }
+ bool _kre() const { return (entry >> 8) & 0x1; }
+ bool _nomb() const { return (entry >> 7) & 0x1; }
+ int _gh() const { return (entry >> 5) & 0x3; }
+ bool _asm_() const { return (entry >> 4) & 0x1; }
+ bool _foe() const { return (entry >> 3) & 0x1; }
+ bool _fow() const { return (entry >> 2) & 0x1; }
+ bool _for() const { return (entry >> 1) & 0x1; }
+ bool valid() const { return (entry >> 0) & 0x1; }
+
+ Addr paddr() const { return _pfn() << PageShift; }
+};
+
+// ITB/DTB table entry
+struct TlbEntry
+{
+ Addr tag; // virtual page number tag
+ Addr ppn; // physical page number
+ uint8_t xre; // read permissions - VMEM_PERM_* mask
+ uint8_t xwe; // write permissions - VMEM_PERM_* mask
+ uint8_t asn; // address space number
+ bool asma; // address space match
+ bool fonr; // fault on read
+ bool fonw; // fault on write
+ bool valid; // valid page table entry
+
+
+ //Construct an entry that maps to physical address addr.
+ TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr)
{
- static const int ImplBits = 43;
- static const Addr ImplMask = (ULL(1) << ImplBits) - 1;
- static const Addr UnImplMask = ~ImplMask;
-
- VAddr(Addr a) : addr(a) {}
- Addr addr;
- operator Addr() const { return addr; }
- const VAddr &operator=(Addr a) { addr = a; return *this; }
-
- Addr vpn() const { return (addr & ImplMask) >> PageShift; }
- Addr page() const { return addr & PageMask; }
- Addr offset() const { return addr & PageOffset; }
-
- Addr level3() const
- { return AlphaISA::PteAddr(addr >> PageShift); }
- Addr level2() const
- { return AlphaISA::PteAddr(addr >> NPtePageShift + PageShift); }
- Addr level1() const
- { return AlphaISA::PteAddr(addr >> 2 * NPtePageShift + PageShift); }
- };
-
- struct PageTableEntry
+ VAddr vaddr(_vaddr);
+ VAddr paddr(_paddr);
+ tag = vaddr.vpn();
+ ppn = paddr.vpn();
+ xre = 15;
+ xwe = 15;
+ asn = _asn;
+ asma = false;
+ fonr = false;
+ fonw = false;
+ valid = true;
+ }
+
+ TlbEntry()
+ {}
+
+ void
+ updateVaddr(Addr new_vaddr)
{
- PageTableEntry(uint64_t e) : entry(e) {}
- uint64_t entry;
- operator uint64_t() const { return entry; }
- const PageTableEntry &operator=(uint64_t e) { entry = e; return *this; }
- const PageTableEntry &operator=(const PageTableEntry &e)
- { entry = e.entry; return *this; }
-
- Addr _pfn() const { return (entry >> 32) & 0xffffffff; }
- Addr _sw() const { return (entry >> 16) & 0xffff; }
- int _rsv0() const { return (entry >> 14) & 0x3; }
- bool _uwe() const { return (entry >> 13) & 0x1; }
- bool _kwe() const { return (entry >> 12) & 0x1; }
- int _rsv1() const { return (entry >> 10) & 0x3; }
- bool _ure() const { return (entry >> 9) & 0x1; }
- bool _kre() const { return (entry >> 8) & 0x1; }
- bool _nomb() const { return (entry >> 7) & 0x1; }
- int _gh() const { return (entry >> 5) & 0x3; }
- bool _asm_() const { return (entry >> 4) & 0x1; }
- bool _foe() const { return (entry >> 3) & 0x1; }
- bool _fow() const { return (entry >> 2) & 0x1; }
- bool _for() const { return (entry >> 1) & 0x1; }
- bool valid() const { return (entry >> 0) & 0x1; }
-
- Addr paddr() const { return _pfn() << PageShift; }
- };
-
- // ITB/DTB table entry
- struct TlbEntry
+ VAddr vaddr(new_vaddr);
+ tag = vaddr.vpn();
+ }
+
+ Addr
+ pageStart()
{
- //Construct an entry that maps to physical address addr.
- TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr)
- {
- VAddr vaddr(_vaddr);
- VAddr paddr(_paddr);
- tag = vaddr.vpn();
- ppn = paddr.vpn();
- xre = 15;
- xwe = 15;
- asn = _asn;
- asma = false;
- fonr = false;
- fonw = false;
- valid = true;
- }
- TlbEntry()
- {}
-
- Addr tag; // virtual page number tag
- Addr ppn; // physical page number
- uint8_t xre; // read permissions - VMEM_PERM_* mask
- uint8_t xwe; // write permissions - VMEM_PERM_* mask
- uint8_t asn; // address space number
- bool asma; // address space match
- bool fonr; // fault on read
- bool fonw; // fault on write
- bool valid; // valid page table entry
-
- Addr pageStart()
- {
- return ppn << PageShift;
- }
-
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
- };
+ return ppn << PageShift;
+ }
+ void serialize(std::ostream &os);
+ void unserialize(Checkpoint *cp, const std::string &section);
};
+
+} // namespace AlphaISA
+
#endif // __ARCH_ALPHA_PAGETABLE_H__
diff --git a/src/arch/alpha/predecoder.hh b/src/arch/alpha/predecoder.hh
index 725b35b9d..5502342e1 100644
--- a/src/arch/alpha/predecoder.hh
+++ b/src/arch/alpha/predecoder.hh
@@ -38,62 +38,72 @@
class ThreadContext;
-namespace AlphaISA
+namespace AlphaISA {
+
+class Predecoder
{
- class Predecoder
+ protected:
+ ThreadContext *tc;
+
+ // The extended machine instruction being generated
+ ExtMachInst ext_inst;
+
+ public:
+ Predecoder(ThreadContext * _tc)
+ : tc(_tc)
+ {}
+
+ ThreadContext *
+ getTC()
{
- protected:
- ThreadContext * tc;
- //The extended machine instruction being generated
- ExtMachInst ext_inst;
-
- public:
- Predecoder(ThreadContext * _tc) : tc(_tc)
- {}
-
- ThreadContext * getTC()
- {
- return tc;
- }
-
- void setTC(ThreadContext * _tc)
- {
- tc = _tc;
- }
-
- void process()
- {
- }
-
- void reset()
- {}
-
- //Use this to give data to the predecoder. This should be used
- //when there is control flow.
- void moreBytes(Addr pc, Addr fetchPC, MachInst inst)
- {
- ext_inst = inst;
+ return tc;
+ }
+
+ void
+ setTC(ThreadContext * _tc)
+ {
+ tc = _tc;
+ }
+
+ void
+ process()
+ { }
+
+ void
+ reset()
+ { }
+
+ // Use this to give data to the predecoder. This should be used
+ // when there is control flow.
+ void
+ moreBytes(Addr pc, Addr fetchPC, MachInst inst)
+ {
+ ext_inst = inst;
#if FULL_SYSTEM
- ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
+ ext_inst |= (static_cast<ExtMachInst>(pc & 0x1) << 32);
#endif
- }
-
- bool needMoreBytes()
- {
- return true;
- }
-
- bool extMachInstReady()
- {
- return true;
- }
-
- //This returns a constant reference to the ExtMachInst to avoid a copy
- const ExtMachInst & getExtMachInst()
- {
- return ext_inst;
- }
- };
+ }
+
+ bool
+ needMoreBytes()
+ {
+ return true;
+ }
+
+ bool
+ extMachInstReady()
+ {
+ return true;
+ }
+
+ // This returns a constant reference to the ExtMachInst to avoid a copy
+ const ExtMachInst &
+ getExtMachInst()
+ {
+ return ext_inst;
+ }
};
+} // namespace AlphaISA
+
#endif // __ARCH_ALPHA_PREDECODER_HH__
diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc
index c2d23ecdd..9c6e62815 100644
--- a/src/arch/alpha/process.cc
+++ b/src/arch/alpha/process.cc
@@ -32,16 +32,20 @@
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/process.hh"
#include "base/loader/object_file.hh"
+#include "base/loader/elf_object.hh"
#include "base/misc.hh"
#include "cpu/thread_context.hh"
+#include "mem/page_table.hh"
+#include "sim/process_impl.hh"
#include "sim/system.hh"
-
using namespace AlphaISA;
using namespace std;
-AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams * params,
- ObjectFile *objFile)
+static const int SyscallSuccessReg = 19;
+
+AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams *params,
+ ObjectFile *objFile)
: LiveProcess(params, objFile)
{
brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
@@ -61,20 +65,165 @@ AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams * params,
}
void
+AlphaLiveProcess::argsInit(int intSize, int pageSize)
+{
+ objFile->loadSections(initVirtMem);
+
+ typedef AuxVector<uint64_t> auxv_t;
+ std::vector<auxv_t> auxv;
+
+ ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
+ if(elfObject)
+ {
+ // modern glibc uses a bunch of auxiliary vectors to set up
+ // TLS as well as do a bunch of other stuff
+ // these vectors go on the bottom of the stack, below argc/argv/envp
+ // pointers but above actual arg strings
+ // I don't have all the ones glibc looks at here, but so far it doesn't
+ // seem to be a problem.
+ // check out _dl_aux_init() in glibc/elf/dl-support.c for details
+ // --Lisa
+ auxv.push_back(auxv_t(M5_AT_PAGESZ, AlphaISA::VMPageSize));
+ auxv.push_back(auxv_t(M5_AT_CLKTCK, 100));
+ auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable()));
+ DPRINTF(Loader, "auxv at PHDR %08p\n", elfObject->programHeaderTable());
+ auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));
+ auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));
+ auxv.push_back(auxv_t(M5_AT_UID, uid()));
+ auxv.push_back(auxv_t(M5_AT_EUID, euid()));
+ auxv.push_back(auxv_t(M5_AT_GID, gid()));
+ auxv.push_back(auxv_t(M5_AT_EGID, egid()));
+
+ }
+
+ // Calculate how much space we need for arg & env & auxv arrays.
+ int argv_array_size = intSize * (argv.size() + 1);
+ int envp_array_size = intSize * (envp.size() + 1);
+ int auxv_array_size = intSize * 2 * (auxv.size() + 1);
+
+ int arg_data_size = 0;
+ for (int i = 0; i < argv.size(); ++i) {
+ arg_data_size += argv[i].size() + 1;
+ }
+ int env_data_size = 0;
+ for (int i = 0; i < envp.size(); ++i) {
+ env_data_size += envp[i].size() + 1;
+ }
+
+ int space_needed =
+ argv_array_size +
+ envp_array_size +
+ auxv_array_size +
+ arg_data_size +
+ env_data_size;
+
+ if (space_needed < 32*1024)
+ space_needed = 32*1024;
+
+ // set bottom of stack
+ stack_min = stack_base - space_needed;
+ // align it
+ stack_min = roundDown(stack_min, pageSize);
+ stack_size = stack_base - stack_min;
+ // map memory
+ pTable->allocate(stack_min, roundUp(stack_size, pageSize));
+
+ // map out initial stack contents
+ Addr argv_array_base = stack_min + intSize; // room for argc
+ Addr envp_array_base = argv_array_base + argv_array_size;
+ Addr auxv_array_base = envp_array_base + envp_array_size;
+ Addr arg_data_base = auxv_array_base + auxv_array_size;
+ Addr env_data_base = arg_data_base + arg_data_size;
+
+ // write contents to stack
+ uint64_t argc = argv.size();
+ if (intSize == 8)
+ argc = htog((uint64_t)argc);
+ else if (intSize == 4)
+ argc = htog((uint32_t)argc);
+ else
+ panic("Unknown int size");
+
+ initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize);
+
+ copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
+ copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
+
+ //Copy the aux stuff
+ for(int x = 0; x < auxv.size(); x++)
+ {
+ initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize,
+ (uint8_t*)&(auxv[x].a_type), intSize);
+ initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
+ (uint8_t*)&(auxv[x].a_val), intSize);
+ }
+
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
+
+ setSyscallArg(tc, 0, argc);
+ setSyscallArg(tc, 1, argv_array_base);
+ tc->setIntReg(StackPointerReg, stack_min);
+
+ Addr prog_entry = objFile->entryPoint();
+ tc->setPC(prog_entry);
+ tc->setNextPC(prog_entry + sizeof(MachInst));
+
+#if THE_ISA != ALPHA_ISA //e.g. MIPS or Sparc
+ tc->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
+#endif
+
+
+}
+
+void
AlphaLiveProcess::startup()
{
if (checkpointRestored)
return;
+ Process::startup();
+
argsInit(MachineBytes, VMPageSize);
- threadContexts[0]->setIntReg(GlobalPointerReg, objFile->globalPointer());
- //Opperate in user mode
- threadContexts[0]->setMiscRegNoEffect(IPR_ICM, 0x18);
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
+ tc->setIntReg(GlobalPointerReg, objFile->globalPointer());
+ //Operate in user mode
+ tc->setMiscRegNoEffect(IPR_ICM, 0x18);
//No super page mapping
- threadContexts[0]->setMiscRegNoEffect(IPR_MCSR, 0);
+ tc->setMiscRegNoEffect(IPR_MCSR, 0);
//Set this to 0 for now, but it should be unique for each process
- threadContexts[0]->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57);
+ tc->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57);
}
+AlphaISA::IntReg
+AlphaLiveProcess::getSyscallArg(ThreadContext *tc, int i)
+{
+ assert(i < 6);
+ return tc->readIntReg(FirstArgumentReg + i);
+}
+
+void
+AlphaLiveProcess::setSyscallArg(ThreadContext *tc,
+ int i, AlphaISA::IntReg val)
+{
+ assert(i < 6);
+ tc->setIntReg(FirstArgumentReg + i, val);
+}
+void
+AlphaLiveProcess::setSyscallReturn(ThreadContext *tc,
+ SyscallReturn return_value)
+{
+ // 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
+ tc->setIntReg(SyscallSuccessReg, 0);
+ tc->setIntReg(ReturnValueReg, return_value.value());
+ } else {
+ // got an error, return details
+ tc->setIntReg(SyscallSuccessReg, (IntReg)-1);
+ tc->setIntReg(ReturnValueReg, -return_value.value());
+ }
+}
diff --git a/src/arch/alpha/process.hh b/src/arch/alpha/process.hh
index c66b97d23..6d083c5ac 100644
--- a/src/arch/alpha/process.hh
+++ b/src/arch/alpha/process.hh
@@ -29,24 +29,24 @@
* Ali Saidi
*/
-#ifndef __ALPHA_PROCESS_HH__
-#define __ALPHA_PROCESS_HH__
+#ifndef __ARCH_ALPHA_PROCESS_HH__
+#define __ARCH_ALPHA_PROCESS_HH__
-#include <string>
-#include <vector>
#include "sim/process.hh"
-class ObjectFile;
-class System;
-
-
class AlphaLiveProcess : public LiveProcess
{
protected:
- AlphaLiveProcess(LiveProcessParams * params, ObjectFile *objFile);
+ AlphaLiveProcess(LiveProcessParams *params, ObjectFile *objFile);
void startup();
-};
+ void argsInit(int intSize, int pageSize);
+
+ public:
+ AlphaISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ void setSyscallArg(ThreadContext *tc, int i, AlphaISA::IntReg val);
+ void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
+};
-#endif // __ALPHA_PROCESS_HH__
+#endif // __ARCH_ALPHA_PROCESS_HH__
diff --git a/src/arch/alpha/regfile.cc b/src/arch/alpha/regfile.cc
index 2653310d7..b3aa55b19 100644
--- a/src/arch/alpha/regfile.cc
+++ b/src/arch/alpha/regfile.cc
@@ -33,67 +33,68 @@
#include "arch/alpha/regfile.hh"
#include "cpu/thread_context.hh"
-namespace AlphaISA
+using namespace std;
+
+namespace AlphaISA {
+
+void
+RegFile::serialize(EventManager *em, ostream &os)
{
- void
- RegFile::serialize(std::ostream &os)
- {
- intRegFile.serialize(os);
- floatRegFile.serialize(os);
- miscRegFile.serialize(os);
- SERIALIZE_SCALAR(pc);
- SERIALIZE_SCALAR(npc);
+ intRegFile.serialize(os);
+ floatRegFile.serialize(os);
+ miscRegFile.serialize(os);
+ SERIALIZE_SCALAR(pc);
+ SERIALIZE_SCALAR(npc);
#if FULL_SYSTEM
- SERIALIZE_SCALAR(intrflag);
+ SERIALIZE_SCALAR(intrflag);
#endif
- }
+}
- void
- RegFile::unserialize(Checkpoint *cp, const std::string &section)
- {
- intRegFile.unserialize(cp, section);
- floatRegFile.unserialize(cp, section);
- miscRegFile.unserialize(cp, section);
- UNSERIALIZE_SCALAR(pc);
- UNSERIALIZE_SCALAR(npc);
+void
+RegFile::unserialize(EventManager *em, Checkpoint *cp, const string &section)
+{
+ intRegFile.unserialize(cp, section);
+ floatRegFile.unserialize(cp, section);
+ miscRegFile.unserialize(cp, section);
+ UNSERIALIZE_SCALAR(pc);
+ UNSERIALIZE_SCALAR(npc);
#if FULL_SYSTEM
- UNSERIALIZE_SCALAR(intrflag);
+ UNSERIALIZE_SCALAR(intrflag);
#endif
- }
+}
- void
- copyRegs(ThreadContext *src, ThreadContext *dest)
- {
- // First loop through the integer registers.
- for (int i = 0; i < NumIntRegs; ++i) {
- dest->setIntReg(i, src->readIntReg(i));
- }
+void
+copyRegs(ThreadContext *src, ThreadContext *dest)
+{
+ // First loop through the integer registers.
+ for (int i = 0; i < NumIntRegs; ++i)
+ dest->setIntReg(i, src->readIntReg(i));
- // Then loop through the floating point registers.
- for (int i = 0; i < TheISA::NumFloatRegs; ++i) {
- dest->setFloatRegBits(i, src->readFloatRegBits(i));
- }
+ // Then loop through the floating point registers.
+ for (int i = 0; i < NumFloatRegs; ++i)
+ dest->setFloatRegBits(i, src->readFloatRegBits(i));
- // Copy misc. registers
- copyMiscRegs(src, dest);
+ // Copy misc. registers
+ copyMiscRegs(src, dest);
- // Lastly copy PC/NPC
- dest->setPC(src->readPC());
- dest->setNextPC(src->readNextPC());
- }
+ // Lastly copy PC/NPC
+ dest->setPC(src->readPC());
+ dest->setNextPC(src->readNextPC());
+}
- void
- copyMiscRegs(ThreadContext *src, ThreadContext *dest)
- {
- dest->setMiscRegNoEffect(AlphaISA::MISCREG_FPCR,
- src->readMiscRegNoEffect(AlphaISA::MISCREG_FPCR));
- dest->setMiscRegNoEffect(AlphaISA::MISCREG_UNIQ,
- src->readMiscRegNoEffect(AlphaISA::MISCREG_UNIQ));
- dest->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG,
- src->readMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG));
- dest->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKADDR,
- src->readMiscRegNoEffect(AlphaISA::MISCREG_LOCKADDR));
+void
+copyMiscRegs(ThreadContext *src, ThreadContext *dest)
+{
+ dest->setMiscRegNoEffect(MISCREG_FPCR,
+ src->readMiscRegNoEffect(MISCREG_FPCR));
+ dest->setMiscRegNoEffect(MISCREG_UNIQ,
+ src->readMiscRegNoEffect(MISCREG_UNIQ));
+ dest->setMiscRegNoEffect(MISCREG_LOCKFLAG,
+ src->readMiscRegNoEffect(MISCREG_LOCKFLAG));
+ dest->setMiscRegNoEffect(MISCREG_LOCKADDR,
+ src->readMiscRegNoEffect(MISCREG_LOCKADDR));
- copyIprs(src, dest);
- }
+ copyIprs(src, dest);
}
+
+} // namespace AlphaISA
diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh
index 792a518fb..e431e7570 100644
--- a/src/arch/alpha/regfile.hh
+++ b/src/arch/alpha/regfile.hh
@@ -43,163 +43,187 @@
//XXX These should be implemented by someone who knows the alpha stuff better
class Checkpoint;
+class EventManager;
class ThreadContext;
-namespace AlphaISA
-{
-
- class RegFile {
+namespace AlphaISA {
- protected:
- Addr pc; // program counter
- Addr npc; // next-cycle program counter
- Addr nnpc;
+class RegFile {
+ protected:
+ Addr pc; // program counter
+ Addr npc; // next-cycle program counter
+ Addr nnpc; // next next-cycle program counter
- public:
- Addr readPC()
- {
- return pc;
- }
-
- void setPC(Addr val)
- {
- pc = val;
- }
+ public:
+ Addr
+ readPC()
+ {
+ return pc;
+ }
- Addr readNextPC()
- {
- return npc;
- }
+ void
+ setPC(Addr val)
+ {
+ pc = val;
+ }
- void setNextPC(Addr val)
- {
- npc = val;
- }
+ Addr
+ readNextPC()
+ {
+ return npc;
+ }
- Addr readNextNPC()
- {
- return npc + sizeof(MachInst);
- }
+ void
+ setNextPC(Addr val)
+ {
+ npc = val;
+ }
- void setNextNPC(Addr val)
- { }
+ Addr
+ readNextNPC()
+ {
+ return npc + sizeof(MachInst);
+ }
- protected:
- IntRegFile intRegFile; // (signed) integer register file
- FloatRegFile floatRegFile; // floating point register file
- MiscRegFile miscRegFile; // control register file
+ void
+ setNextNPC(Addr val)
+ { }
- public:
+ 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
+ int intrflag; // interrupt flag
- void clear()
- {
- intRegFile.clear();
- floatRegFile.clear();
- miscRegFile.clear();
- }
-
- MiscReg readMiscRegNoEffect(int miscReg)
- {
- return miscRegFile.readRegNoEffect(miscReg);
- }
-
- MiscReg readMiscReg(int miscReg, ThreadContext *tc)
- {
- return miscRegFile.readReg(miscReg, tc);
- }
+ int
+ instAsid()
+ {
+ return miscRegFile.getInstAsid();
+ }
- void setMiscRegNoEffect(int miscReg, const MiscReg &val)
- {
- miscRegFile.setRegNoEffect(miscReg, val);
- }
+ int
+ dataAsid()
+ {
+ return miscRegFile.getDataAsid();
+ }
+#endif // FULL_SYSTEM
- void setMiscReg(int miscReg, const MiscReg &val,
- ThreadContext * tc)
- {
- miscRegFile.setReg(miscReg, val, tc);
- }
+ void
+ clear()
+ {
+ intRegFile.clear();
+ floatRegFile.clear();
+ miscRegFile.clear();
+ }
- FloatReg readFloatReg(int floatReg)
- {
- return floatRegFile.d[floatReg];
- }
+ MiscReg
+ readMiscRegNoEffect(int miscReg)
+ {
+ return miscRegFile.readRegNoEffect(miscReg);
+ }
- FloatReg readFloatReg(int floatReg, int width)
- {
- return readFloatReg(floatReg);
- }
+ MiscReg
+ readMiscReg(int miscReg, ThreadContext *tc)
+ {
+ return miscRegFile.readReg(miscReg, tc);
+ }
- FloatRegBits readFloatRegBits(int floatReg)
- {
- return floatRegFile.q[floatReg];
- }
+ void
+ setMiscRegNoEffect(int miscReg, const MiscReg &val)
+ {
+ miscRegFile.setRegNoEffect(miscReg, val);
+ }
- FloatRegBits readFloatRegBits(int floatReg, int width)
- {
- return readFloatRegBits(floatReg);
- }
+ void
+ setMiscReg(int miscReg, const MiscReg &val, ThreadContext *tc)
+ {
+ miscRegFile.setReg(miscReg, val, tc);
+ }
- void setFloatReg(int floatReg, const FloatReg &val)
- {
- floatRegFile.d[floatReg] = val;
- }
+ FloatReg
+ readFloatReg(int floatReg)
+ {
+ return floatRegFile.d[floatReg];
+ }
- void setFloatReg(int floatReg, const FloatReg &val, int width)
- {
- setFloatReg(floatReg, val);
- }
+ FloatReg
+ readFloatReg(int floatReg, int width)
+ {
+ return readFloatReg(floatReg);
+ }
- void setFloatRegBits(int floatReg, const FloatRegBits &val)
- {
- floatRegFile.q[floatReg] = val;
- }
+ FloatRegBits
+ readFloatRegBits(int floatReg)
+ {
+ return floatRegFile.q[floatReg];
+ }
- void setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
- {
- setFloatRegBits(floatReg, val);
- }
+ FloatRegBits
+ readFloatRegBits(int floatReg, int width)
+ {
+ return readFloatRegBits(floatReg);
+ }
- IntReg readIntReg(int intReg)
- {
- return intRegFile.readReg(intReg);
- }
+ void
+ setFloatReg(int floatReg, const FloatReg &val)
+ {
+ floatRegFile.d[floatReg] = val;
+ }
- void setIntReg(int intReg, const IntReg &val)
- {
- intRegFile.setReg(intReg, val);
- }
+ void
+ setFloatReg(int floatReg, const FloatReg &val, int width)
+ {
+ setFloatReg(floatReg, val);
+ }
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
+ void
+ setFloatRegBits(int floatReg, const FloatRegBits &val)
+ {
+ floatRegFile.q[floatReg] = val;
+ }
- void changeContext(RegContextParam param, RegContextVal val)
- {
- //This would be an alternative place to call/implement
- //the swapPALShadow function
- }
- };
+ void
+ setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
+ {
+ setFloatRegBits(floatReg, val);
+ }
- static inline int flattenIntIndex(ThreadContext * tc, int reg)
+ IntReg
+ readIntReg(int intReg)
{
- return reg;
+ return intRegFile.readReg(intReg);
}
- static inline int flattenFloatIndex(ThreadContext * tc, int reg)
+ void
+ setIntReg(int intReg, const IntReg &val)
{
- return reg;
+ intRegFile.setReg(intReg, val);
}
- void copyRegs(ThreadContext *src, ThreadContext *dest);
+ void serialize(EventManager *em, std::ostream &os);
+ void unserialize(EventManager *em, Checkpoint *cp,
+ const std::string &section);
+};
+
+static inline int
+flattenIntIndex(ThreadContext * tc, int reg)
+{
+ return reg;
+}
+
+static inline int
+flattenFloatIndex(ThreadContext * tc, int reg)
+{
+ return reg;
+}
+
+void copyRegs(ThreadContext *src, ThreadContext *dest);
+
+void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
- void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
} // namespace AlphaISA
-#endif
+#endif // __ARCH_ALPHA_REGFILE_HH__
diff --git a/src/arch/alpha/remote_gdb.cc b/src/arch/alpha/remote_gdb.cc
index ea5db36f4..c47293b98 100644
--- a/src/arch/alpha/remote_gdb.cc
+++ b/src/arch/alpha/remote_gdb.cc
@@ -30,7 +30,7 @@
/*
* Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
@@ -38,8 +38,8 @@
*
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratories.
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratories.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -51,8 +51,8 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -69,7 +69,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
+ * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
*/
/*-
@@ -89,8 +89,8 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
@@ -117,9 +117,9 @@
*/
#include <sys/signal.h>
+#include <unistd.h>
#include <string>
-#include <unistd.h>
#include "config/full_system.hh"
#if FULL_SYSTEM
@@ -140,19 +140,17 @@
#include "sim/system.hh"
using namespace std;
-using namespace TheISA;
+using namespace AlphaISA;
-RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
- : BaseRemoteGDB(_system, c, KGDB_NUMREGS)
+RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc)
+ : BaseRemoteGDB(_system, tc, KGDB_NUMREGS)
{
memset(gdbregs.regs, 0, gdbregs.bytes());
}
-///////////////////////////////////////////////////////////
-// RemoteGDB::acc
-//
-// Determine if the mapping at va..(va+len) is valid.
-//
+/*
+ * Determine if the mapping at va..(va+len) is valid.
+ */
bool
RemoteGDB::acc(Addr va, size_t len)
{
@@ -161,12 +159,12 @@ RemoteGDB::acc(Addr va, size_t len)
#else
Addr last_va;
- va = TheISA::TruncPage(va);
- last_va = TheISA::RoundPage(va + len);
+ va = TruncPage(va);
+ last_va = RoundPage(va + len);
do {
- if (TheISA::IsK0Seg(va)) {
- if (va < (TheISA::K0SegBase + pmem->size())) {
+ if (IsK0Seg(va)) {
+ if (va < (K0SegBase + pmem->size())) {
DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= "
"%#x < K0SEG + size\n", va);
return true;
@@ -177,23 +175,25 @@ RemoteGDB::acc(Addr va, size_t len)
}
}
- /**
- * This code says that all accesses to palcode (instruction and data)
- * are valid since there isn't a va->pa mapping because palcode is
- * accessed physically. At some point this should probably be cleaned up
- * but there is no easy way to do it.
- */
+ /**
+ * This code says that all accesses to palcode (instruction
+ * and data) are valid since there isn't a va->pa mapping
+ * because palcode is accessed physically. At some point this
+ * should probably be cleaned up but there is no easy way to
+ * do it.
+ */
- if (AlphaISA::PcPAL(va) || va < 0x10000)
+ if (PcPAL(va) || va < 0x10000)
return true;
- Addr ptbr = context->readMiscRegNoEffect(AlphaISA::IPR_PALtemp20);
- TheISA::PageTableEntry pte = TheISA::kernel_pte_lookup(context->getPhysPort(), ptbr, va);
+ Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20);
+ PageTableEntry pte =
+ kernel_pte_lookup(context->getPhysPort(), ptbr, va);
if (!pte.valid()) {
DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
return false;
}
- va += TheISA::PageBytes;
+ va += PageBytes;
} while (va < last_va);
DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va);
@@ -201,11 +201,10 @@ RemoteGDB::acc(Addr va, size_t len)
#endif
}
-///////////////////////////////////////////////////////////
-// RemoteGDB::getregs
-//
-// Translate the kernel debugger register format into
-// the GDB register format.
+/*
+ * Translate the kernel debugger register format into the GDB register
+ * format.
+ */
void
RemoteGDB::getregs()
{
@@ -214,45 +213,43 @@ RemoteGDB::getregs()
gdbregs.regs[KGDB_REG_PC] = context->readPC();
// @todo: Currently this is very Alpha specific.
- if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) {
- for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
- gdbregs.regs[i] = context->readIntReg(AlphaISA::reg_redir[i]);
+ if (PcPAL(gdbregs.regs[KGDB_REG_PC])) {
+ for (int i = 0; i < NumIntArchRegs; ++i) {
+ gdbregs.regs[i] = context->readIntReg(reg_redir[i]);
}
} else {
- for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
+ for (int i = 0; i < NumIntArchRegs; ++i) {
gdbregs.regs[i] = context->readIntReg(i);
}
}
#ifdef KGDB_FP_REGS
- for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) {
+ for (int i = 0; i < NumFloatArchRegs; ++i) {
gdbregs.regs[i + KGDB_REG_F0] = context->readFloatRegBits(i);
}
#endif
}
-///////////////////////////////////////////////////////////
-// RemoteGDB::setregs
-//
-// Translate the GDB register format into the kernel
-// debugger register format.
-//
+/*
+ * Translate the GDB register format into the kernel debugger register
+ * format.
+ */
void
RemoteGDB::setregs()
{
// @todo: Currently this is very Alpha specific.
- if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) {
- for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
- context->setIntReg(AlphaISA::reg_redir[i], gdbregs.regs[i]);
+ if (PcPAL(gdbregs.regs[KGDB_REG_PC])) {
+ for (int i = 0; i < NumIntArchRegs; ++i) {
+ context->setIntReg(reg_redir[i], gdbregs.regs[i]);
}
} else {
- for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
+ for (int i = 0; i < NumIntArchRegs; ++i) {
context->setIntReg(i, gdbregs.regs[i]);
}
}
#ifdef KGDB_FP_REGS
- for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) {
+ for (int i = 0; i < NumFloatArchRegs; ++i) {
context->setFloatRegBits(i, gdbregs.regs[i + KGDB_REG_F0]);
}
#endif
diff --git a/src/arch/alpha/remote_gdb.hh b/src/arch/alpha/remote_gdb.hh
index 7bef183c3..43d0580d8 100644
--- a/src/arch/alpha/remote_gdb.hh
+++ b/src/arch/alpha/remote_gdb.hh
@@ -44,31 +44,29 @@ class System;
class ThreadContext;
class PhysicalMemory;
-namespace AlphaISA
-{
- class RemoteGDB : public BaseRemoteGDB
- {
- protected:
- // Machine memory
- bool write(Addr addr, size_t size, const char *data);
+namespace AlphaISA {
- public:
- RemoteGDB(System *system, ThreadContext *context);
+class RemoteGDB : public BaseRemoteGDB
+{
+ protected:
+ Addr notTakenBkpt;
+ Addr takenBkpt;
- bool acc(Addr addr, size_t len);
+ protected:
+ void getregs();
+ void setregs();
- protected:
- void getregs();
- void setregs();
+ void clearSingleStep();
+ void setSingleStep();
- void clearSingleStep();
- void setSingleStep();
+ // Machine memory
+ bool acc(Addr addr, size_t len);
+ bool write(Addr addr, size_t size, const char *data);
- protected:
+ public:
+ RemoteGDB(System *system, ThreadContext *context);
+};
- Addr notTakenBkpt;
- Addr takenBkpt;
- };
-}
+} // namespace AlphaISA
-#endif /* __ARCH_ALPHA_REMOTE_GDB_H__ */
+#endif // __ARCH_ALPHA_REMOTE_GDB_HH__
diff --git a/src/arch/alpha/stacktrace.cc b/src/arch/alpha/stacktrace.cc
index c16498e72..1b5a9be34 100644
--- a/src/arch/alpha/stacktrace.cc
+++ b/src/arch/alpha/stacktrace.cc
@@ -41,330 +41,326 @@
using namespace std;
-namespace AlphaISA
+namespace AlphaISA {
+
+ProcessInfo::ProcessInfo(ThreadContext *_tc)
+ : tc(_tc)
{
- ProcessInfo::ProcessInfo(ThreadContext *_tc)
- : tc(_tc)
- {
- Addr addr = 0;
+ Addr addr = 0;
+ VirtualPort *vp = tc->getVirtPort();
+ SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
- VirtualPort *vp;
+ if (!symtab->findAddress("thread_info_size", addr))
+ panic("thread info not compiled into kernel\n");
+ thread_info_size = vp->readGtoH<int32_t>(addr);
- vp = tc->getVirtPort();
+ if (!symtab->findAddress("task_struct_size", addr))
+ panic("thread info not compiled into kernel\n");
+ task_struct_size = vp->readGtoH<int32_t>(addr);
- if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
- panic("thread info not compiled into kernel\n");
- thread_info_size = vp->readGtoH<int32_t>(addr);
+ if (!symtab->findAddress("thread_info_task", addr))
+ panic("thread info not compiled into kernel\n");
+ task_off = vp->readGtoH<int32_t>(addr);
- if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
- panic("thread info not compiled into kernel\n");
- task_struct_size = vp->readGtoH<int32_t>(addr);
+ if (!symtab->findAddress("task_struct_pid", addr))
+ panic("thread info not compiled into kernel\n");
+ pid_off = vp->readGtoH<int32_t>(addr);
- if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
- panic("thread info not compiled into kernel\n");
- task_off = vp->readGtoH<int32_t>(addr);
+ if (!symtab->findAddress("task_struct_comm", addr))
+ panic("thread info not compiled into kernel\n");
+ name_off = vp->readGtoH<int32_t>(addr);
+}
- if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
- panic("thread info not compiled into kernel\n");
- pid_off = vp->readGtoH<int32_t>(addr);
+Addr
+ProcessInfo::task(Addr ksp) const
+{
+ Addr base = ksp & ~0x3fff;
+ if (base == ULL(0xfffffc0000000000))
+ return 0;
- if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
- panic("thread info not compiled into kernel\n");
- name_off = vp->readGtoH<int32_t>(addr);
+ Addr tsk;
- tc->delVirtPort(vp);
- }
+ VirtualPort *vp;
- Addr
- ProcessInfo::task(Addr ksp) const
- {
- Addr base = ksp & ~0x3fff;
- if (base == ULL(0xfffffc0000000000))
- return 0;
+ vp = tc->getVirtPort();
+ tsk = vp->readGtoH<Addr>(base + task_off);
- Addr tsk;
+ return tsk;
+}
- VirtualPort *vp;
+int
+ProcessInfo::pid(Addr ksp) const
+{
+ Addr task = this->task(ksp);
+ if (!task)
+ return -1;
- vp = tc->getVirtPort();
- tsk = vp->readGtoH<Addr>(base + task_off);
- tc->delVirtPort(vp);
+ uint16_t pd;
- return tsk;
- }
+ VirtualPort *vp;
- int
- ProcessInfo::pid(Addr ksp) const
- {
- Addr task = this->task(ksp);
- if (!task)
- return -1;
+ vp = tc->getVirtPort();
+ pd = vp->readGtoH<uint16_t>(task + pid_off);
- uint16_t pd;
+ return pd;
+}
- VirtualPort *vp;
+string
+ProcessInfo::name(Addr ksp) const
+{
+ Addr task = this->task(ksp);
+ if (!task)
+ return "console";
- vp = tc->getVirtPort();
- pd = vp->readGtoH<uint16_t>(task + pid_off);
- tc->delVirtPort(vp);
+ char comm[256];
+ CopyStringOut(tc, comm, task + name_off, sizeof(comm));
+ if (!comm[0])
+ return "startup";
- return pd;
- }
+ return comm;
+}
- string
- ProcessInfo::name(Addr ksp) const
- {
- Addr task = this->task(ksp);
- if (!task)
- return "console";
+StackTrace::StackTrace()
+ : tc(0), stack(64)
+{
+}
- char comm[256];
- CopyStringOut(tc, comm, task + name_off, sizeof(comm));
- if (!comm[0])
- return "startup";
+StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst)
+ : tc(0), stack(64)
+{
+ trace(_tc, inst);
+}
- return comm;
- }
+StackTrace::~StackTrace()
+{
+}
- StackTrace::StackTrace()
- : tc(0), stack(64)
- {
- }
+void
+StackTrace::trace(ThreadContext *_tc, bool is_call)
+{
+ tc = _tc;
- StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst)
- : tc(0), stack(64)
- {
- trace(_tc, inst);
- }
+ System *sys = tc->getSystemPtr();
- StackTrace::~StackTrace()
- {
- }
+ bool usermode =
+ (tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0;
- void
- StackTrace::trace(ThreadContext *_tc, bool is_call)
- {
- tc = _tc;
+ Addr pc = tc->readNextPC();
+ bool kernel = sys->kernelStart <= pc && pc <= sys->kernelEnd;
- bool usermode = (tc->readMiscRegNoEffect(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
+ if (usermode) {
+ stack.push_back(user);
+ return;
+ }
- Addr pc = tc->readNextPC();
- bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
- pc <= tc->getSystemPtr()->kernelEnd;
+ if (!kernel) {
+ stack.push_back(console);
+ return;
+ }
- if (usermode) {
- stack.push_back(user);
- return;
- }
+ SymbolTable *symtab = sys->kernelSymtab;
+ Addr ksp = tc->readIntReg(StackPointerReg);
+ Addr bottom = ksp & ~0x3fff;
- if (!kernel) {
- stack.push_back(console);
- return;
- }
+ if (is_call) {
+ Addr addr;
+ if (!symtab->findNearestAddr(pc, addr))
+ panic("could not find address %#x", pc);
+
+ stack.push_back(addr);
+ pc = tc->readPC();
+ }
- SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
- Addr ksp = tc->readIntReg(TheISA::StackPointerReg);
- Addr bottom = ksp & ~0x3fff;
+ while (ksp > bottom) {
Addr addr;
+ if (!symtab->findNearestAddr(pc, addr))
+ panic("could not find symbol for pc=%#x", pc);
+ assert(pc >= addr && "symbol botch: callpc < func");
- if (is_call) {
- if (!symtab->findNearestAddr(pc, addr))
- panic("could not find address %#x", pc);
+ stack.push_back(addr);
- stack.push_back(addr);
- pc = tc->readPC();
- }
+ if (isEntry(addr))
+ return;
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))
+ if (decodePrologue(ksp, pc, addr, size, ra)) {
+ if (!ra)
return;
- if (decodePrologue(ksp, pc, addr, size, ra)) {
- if (!ra)
- return;
-
- if (size <= 0) {
- stack.push_back(unknown);
- return;
- }
-
- pc = ra;
- ksp += size;
- } else {
+ if (size <= 0) {
stack.push_back(unknown);
return;
}
- bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
- pc <= tc->getSystemPtr()->kernelEnd;
- if (!kernel)
- return;
-
- if (stack.size() >= 1000)
- panic("unwinding too far");
+ pc = ra;
+ ksp += size;
+ } else {
+ stack.push_back(unknown);
+ return;
}
- panic("unwinding too far");
+ bool kernel = sys->kernelStart <= pc && pc <= sys->kernelEnd;
+ if (!kernel)
+ return;
+
+ if (stack.size() >= 1000)
+ panic("unwinding too far");
}
- bool
- StackTrace::isEntry(Addr addr)
- {
- if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp12))
- return true;
+ panic("unwinding too far");
+}
- if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp7))
- return true;
+bool
+StackTrace::isEntry(Addr addr)
+{
+ if (addr == tc->readMiscRegNoEffect(IPR_PALtemp12))
+ return true;
- if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp11))
- return true;
+ if (addr == tc->readMiscRegNoEffect(IPR_PALtemp7))
+ return true;
- if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp21))
- return true;
+ if (addr == tc->readMiscRegNoEffect(IPR_PALtemp11))
+ return true;
- if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp9))
- return true;
+ if (addr == tc->readMiscRegNoEffect(IPR_PALtemp21))
+ return true;
- if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp2))
- return true;
+ if (addr == tc->readMiscRegNoEffect(IPR_PALtemp9))
+ return true;
- return false;
- }
+ if (addr == tc->readMiscRegNoEffect(IPR_PALtemp2))
+ return true;
- bool
- StackTrace::decodeStack(MachInst inst, int &disp)
- {
- // lda $sp, -disp($sp)
- //
- // Opcode<31:26> == 0x08
- // RA<25:21> == 30
- // RB<20:16> == 30
- // Disp<15:0>
- const MachInst mem_mask = 0xffff0000;
- const MachInst lda_pattern = 0x23de0000;
- const MachInst lda_disp_mask = 0x0000ffff;
-
- // subq $sp, disp, $sp
- // addq $sp, disp, $sp
- //
- // Opcode<31:26> == 0x10
- // RA<25:21> == 30
- // Lit<20:13>
- // One<12> = 1
- // Func<11:5> == 0x20 (addq)
- // Func<11:5> == 0x29 (subq)
- // RC<4:0> == 30
- const MachInst intop_mask = 0xffe01fff;
- const MachInst addq_pattern = 0x43c0141e;
- const MachInst subq_pattern = 0x43c0153e;
- const MachInst intop_disp_mask = 0x001fe000;
- const int intop_disp_shift = 13;
-
- if ((inst & mem_mask) == lda_pattern)
- disp = -sext<16>(inst & lda_disp_mask);
- else if ((inst & intop_mask) == addq_pattern)
- disp = -int((inst & intop_disp_mask) >> intop_disp_shift);
- else if ((inst & intop_mask) == subq_pattern)
- disp = int((inst & intop_disp_mask) >> intop_disp_shift);
- else
- return false;
+ return false;
+}
- return true;
- }
+bool
+StackTrace::decodeStack(MachInst inst, int &disp)
+{
+ // lda $sp, -disp($sp)
+ //
+ // Opcode<31:26> == 0x08
+ // RA<25:21> == 30
+ // RB<20:16> == 30
+ // Disp<15:0>
+ const MachInst mem_mask = 0xffff0000;
+ const MachInst lda_pattern = 0x23de0000;
+ const MachInst lda_disp_mask = 0x0000ffff;
+
+ // subq $sp, disp, $sp
+ // addq $sp, disp, $sp
+ //
+ // Opcode<31:26> == 0x10
+ // RA<25:21> == 30
+ // Lit<20:13>
+ // One<12> = 1
+ // Func<11:5> == 0x20 (addq)
+ // Func<11:5> == 0x29 (subq)
+ // RC<4:0> == 30
+ const MachInst intop_mask = 0xffe01fff;
+ const MachInst addq_pattern = 0x43c0141e;
+ const MachInst subq_pattern = 0x43c0153e;
+ const MachInst intop_disp_mask = 0x001fe000;
+ const int intop_disp_shift = 13;
+
+ if ((inst & mem_mask) == lda_pattern)
+ disp = -sext<16>(inst & lda_disp_mask);
+ else if ((inst & intop_mask) == addq_pattern)
+ disp = -int((inst & intop_disp_mask) >> intop_disp_shift);
+ else if ((inst & intop_mask) == subq_pattern)
+ disp = int((inst & intop_disp_mask) >> intop_disp_shift);
+ else
+ return false;
- bool
- StackTrace::decodeSave(MachInst inst, int &reg, int &disp)
- {
- // lda $stq, disp($sp)
- //
- // Opcode<31:26> == 0x08
- // RA<25:21> == ?
- // RB<20:16> == 30
- // Disp<15:0>
- const MachInst stq_mask = 0xfc1f0000;
- const MachInst stq_pattern = 0xb41e0000;
- const MachInst stq_disp_mask = 0x0000ffff;
- const MachInst reg_mask = 0x03e00000;
- const int reg_shift = 21;
-
- if ((inst & stq_mask) == stq_pattern) {
- reg = (inst & reg_mask) >> reg_shift;
- disp = sext<16>(inst & stq_disp_mask);
- } else {
- return false;
- }
+ return true;
+}
- return true;
+bool
+StackTrace::decodeSave(MachInst inst, int &reg, int &disp)
+{
+ // lda $stq, disp($sp)
+ //
+ // Opcode<31:26> == 0x08
+ // RA<25:21> == ?
+ // RB<20:16> == 30
+ // Disp<15:0>
+ const MachInst stq_mask = 0xfc1f0000;
+ const MachInst stq_pattern = 0xb41e0000;
+ const MachInst stq_disp_mask = 0x0000ffff;
+ const MachInst reg_mask = 0x03e00000;
+ const int reg_shift = 21;
+
+ if ((inst & stq_mask) == stq_pattern) {
+ reg = (inst & reg_mask) >> reg_shift;
+ disp = sext<16>(inst & stq_disp_mask);
+ } else {
+ return false;
}
- /*
- * Decode the function prologue for the function we're in, and note
- * which registers are stored where, and how large the stack frame is.
- */
- bool
- StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
- int &size, Addr &ra)
- {
- size = 0;
- ra = 0;
-
- for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
- MachInst inst;
- CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst));
-
- int reg, disp;
- if (decodeStack(inst, disp)) {
- if (size) {
- // panic("decoding frame size again");
- return true;
- }
- size += disp;
- } else if (decodeSave(inst, reg, disp)) {
- if (!ra && reg == ReturnAddressReg) {
- CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr));
- if (!ra) {
- // panic("no return address value pc=%#x\n", pc);
- return false;
- }
+ return true;
+}
+
+/*
+ * Decode the function prologue for the function we're in, and note
+ * which registers are stored where, and how large the stack frame is.
+ */
+bool
+StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, int &size,
+ Addr &ra)
+{
+ size = 0;
+ ra = 0;
+
+ for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
+ MachInst inst;
+ CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst));
+
+ int reg, disp;
+ if (decodeStack(inst, disp)) {
+ if (size) {
+ // panic("decoding frame size again");
+ return true;
+ }
+ size += disp;
+ } else if (decodeSave(inst, reg, disp)) {
+ if (!ra && reg == ReturnAddressReg) {
+ CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr));
+ if (!ra) {
+ // panic("no return address value pc=%#x\n", pc);
+ return false;
}
}
}
-
- return true;
}
+ return true;
+}
+
#if TRACING_ON
- void
- StackTrace::dump()
- {
- StringWrap name(tc->getCpuPtr()->name());
- SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
-
- DPRINTFN("------ Stack ------\n");
-
- string symbol;
- for (int i = 0, size = stack.size(); i < size; ++i) {
- Addr addr = stack[size - i - 1];
- if (addr == user)
- symbol = "user";
- else if (addr == console)
- symbol = "console";
- else if (addr == unknown)
- symbol = "unknown";
- else
- symtab->findSymbol(addr, symbol);
-
- DPRINTFN("%#x: %s\n", addr, symbol);
- }
+void
+StackTrace::dump()
+{
+ StringWrap name(tc->getCpuPtr()->name());
+ SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
+
+ DPRINTFN("------ Stack ------\n");
+
+ string symbol;
+ for (int i = 0, size = stack.size(); i < size; ++i) {
+ Addr addr = stack[size - i - 1];
+ if (addr == user)
+ symbol = "user";
+ else if (addr == console)
+ symbol = "console";
+ else if (addr == unknown)
+ symbol = "unknown";
+ else
+ symtab->findSymbol(addr, symbol);
+
+ DPRINTFN("%#x: %s\n", addr, symbol);
}
-#endif
}
+#endif
+
+} // namespace AlphaISA
diff --git a/src/arch/alpha/stacktrace.hh b/src/arch/alpha/stacktrace.hh
index 834abbc2f..db42c4399 100644
--- a/src/arch/alpha/stacktrace.hh
+++ b/src/arch/alpha/stacktrace.hh
@@ -36,90 +36,90 @@
class ThreadContext;
-namespace AlphaISA
-{
- class StackTrace;
+namespace AlphaISA {
- class ProcessInfo
- {
- private:
- ThreadContext *tc;
+class StackTrace;
+
+class ProcessInfo
+{
+ private:
+ ThreadContext *tc;
- int thread_info_size;
- int task_struct_size;
- int task_off;
- int pid_off;
- int name_off;
+ int thread_info_size;
+ int task_struct_size;
+ int task_off;
+ int pid_off;
+ int name_off;
- public:
- ProcessInfo(ThreadContext *_tc);
+ public:
+ ProcessInfo(ThreadContext *_tc);
- Addr task(Addr ksp) const;
- int pid(Addr ksp) const;
- std::string name(Addr ksp) const;
- };
+ Addr task(Addr ksp) const;
+ int pid(Addr ksp) const;
+ std::string name(Addr ksp) const;
+};
- class StackTrace
- {
- protected:
- typedef TheISA::MachInst MachInst;
- private:
- ThreadContext *tc;
- std::vector<Addr> stack;
+class StackTrace
+{
+ private:
+ ThreadContext *tc;
+ std::vector<Addr> stack;
- private:
- bool isEntry(Addr addr);
- bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
- bool decodeSave(MachInst inst, int &reg, int &disp);
- bool decodeStack(MachInst inst, int &disp);
+ private:
+ bool isEntry(Addr addr);
+ bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
+ bool decodeSave(MachInst inst, int &reg, int &disp);
+ bool decodeStack(MachInst inst, int &disp);
- void trace(ThreadContext *tc, bool is_call);
+ void trace(ThreadContext *tc, bool is_call);
- public:
- StackTrace();
- StackTrace(ThreadContext *tc, StaticInstPtr inst);
- ~StackTrace();
+ public:
+ StackTrace();
+ StackTrace(ThreadContext *tc, StaticInstPtr inst);
+ ~StackTrace();
- void clear()
- {
- tc = 0;
- stack.clear();
- }
+ void
+ clear()
+ {
+ tc = 0;
+ stack.clear();
+ }
- bool valid() const { return tc != NULL; }
- bool trace(ThreadContext *tc, StaticInstPtr inst);
+ bool valid() const { return tc != NULL; }
+ bool trace(ThreadContext *tc, StaticInstPtr inst);
- public:
- const std::vector<Addr> &getstack() const { return stack; }
+ public:
+ const std::vector<Addr> &getstack() const { return stack; }
- static const int user = 1;
- static const int console = 2;
- static const int unknown = 3;
+ static const int user = 1;
+ static const int console = 2;
+ static const int unknown = 3;
#if TRACING_ON
- private:
- void dump();
+ private:
+ void dump();
- public:
- void dprintf() { if (DTRACE(Stack)) dump(); }
+ public:
+ void dprintf() { if (DTRACE(Stack)) dump(); }
#else
- public:
- void dprintf() {}
+ public:
+ void dprintf() {}
#endif
- };
+};
- inline bool
- StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
- {
- if (!inst->isCall() && !inst->isReturn())
- return false;
+inline bool
+StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
+{
+ if (!inst->isCall() && !inst->isReturn())
+ return false;
- if (valid())
- clear();
+ if (valid())
+ clear();
- trace(tc, !inst->isReturn());
- return true;
- }
+ trace(tc, !inst->isReturn());
+ return true;
}
+} // namespace AlphaISA
+
#endif // __ARCH_ALPHA_STACKTRACE_HH__
diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc
index 2af62ceea..72d918870 100644
--- a/src/arch/alpha/system.cc
+++ b/src/arch/alpha/system.cc
@@ -42,8 +42,7 @@
#include "params/AlphaSystem.hh"
#include "sim/byteswap.hh"
-
-using namespace LittleEndianGuest;
+using namespace AlphaISA;
AlphaSystem::AlphaSystem(Params *p)
: System(p)
@@ -67,8 +66,8 @@ AlphaSystem::AlphaSystem(Params *p)
// Load program sections into memory
- pal->loadSections(&functionalPort, AlphaISA::LoadAddrMask);
- console->loadSections(&functionalPort, AlphaISA::LoadAddrMask);
+ pal->loadSections(&functionalPort, LoadAddrMask);
+ console->loadSections(&functionalPort, LoadAddrMask);
// load symbols
if (!console->loadGlobalSymbols(consoleSymtab))
@@ -117,7 +116,6 @@ AlphaSystem::AlphaSystem(Params *p)
virtPort.write(addr+0x58, data);
} else
panic("could not find hwrpb\n");
-
}
AlphaSystem::~AlphaSystem()
@@ -142,9 +140,9 @@ AlphaSystem::~AlphaSystem()
* 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
+ * 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
@@ -172,11 +170,11 @@ AlphaSystem::fixFuncEventAddr(Addr addr)
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));
+ uint32_t i2 = virtPort.read<uint32_t>(addr + sizeof(MachInst));
if ((i1 & inst_mask) == gp_ldah_pattern &&
(i2 & inst_mask) == gp_lda_pattern) {
- Addr new_addr = addr + 2* sizeof(AlphaISA::MachInst);
+ Addr new_addr = addr + 2 * sizeof(MachInst);
DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr);
return new_addr;
} else {
@@ -184,15 +182,15 @@ AlphaSystem::fixFuncEventAddr(Addr addr)
}
}
-
void
AlphaSystem::setAlphaAccess(Addr access)
{
Addr addr = 0;
if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
- virtPort.write(addr, htog(EV5::Phys2K0Seg(access)));
- } else
+ virtPort.write(addr, htog(Phys2K0Seg(access)));
+ } else {
panic("could not find m5AlphaAccess\n");
+ }
}
void
@@ -203,7 +201,6 @@ AlphaSystem::serialize(std::ostream &os)
palSymtab->serialize("pal_symtab", os);
}
-
void
AlphaSystem::unserialize(Checkpoint *cp, const std::string &section)
{
diff --git a/src/arch/alpha/system.hh b/src/arch/alpha/system.hh
index a934550b7..da42ab263 100644
--- a/src/arch/alpha/system.hh
+++ b/src/arch/alpha/system.hh
@@ -49,10 +49,10 @@ class AlphaSystem : public System
AlphaSystem(Params *p);
~AlphaSystem();
-/**
- * Serialization stuff
- */
public:
+ /**
+ * Serialization stuff
+ */
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
@@ -77,26 +77,28 @@ class AlphaSystem : public System
/** 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 *addPalFuncEvent(const char *lbl)
+ T *
+ addPalFuncEvent(const char *lbl)
{
return addFuncEvent<T>(palSymtab, lbl);
}
/** Add a function-based event to the console code. */
template <class T>
- T *addConsoleFuncEvent(const char *lbl)
+ T *
+ addConsoleFuncEvent(const char *lbl)
{
return addFuncEvent<T>(consoleSymtab, lbl);
}
virtual Addr fixFuncEventAddr(Addr addr);
-
};
-#endif
+#endif // __ARCH_ALPHA_SYSTEM_HH__
diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc
index 77bf5e285..2b0afacfe 100644
--- a/src/arch/alpha/tlb.cc
+++ b/src/arch/alpha/tlb.cc
@@ -43,19 +43,20 @@
#include "cpu/thread_context.hh"
using namespace std;
-using namespace EV5;
namespace AlphaISA {
+
///////////////////////////////////////////////////////////////////////
//
// Alpha TLB
//
+
#ifdef DEBUG
bool uncacheBit39 = false;
bool uncacheBit40 = false;
#endif
-#define MODE2MASK(X) (1 << (X))
+#define MODE2MASK(X) (1 << (X))
TLB::TLB(const Params *p)
: BaseTLB(p), size(p->size), nlu(0)
@@ -114,20 +115,20 @@ TLB::lookup(Addr vpn, uint8_t asn)
return retval;
}
-
Fault
-TLB::checkCacheability(RequestPtr &req)
+TLB::checkCacheability(RequestPtr &req, bool itb)
{
-// 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.
- */
+ // 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
@@ -141,13 +142,20 @@ TLB::checkCacheability(RequestPtr &req)
return new UnimpFault("IPR memory space not implemented!");
} else {
// mark request as uncacheable
- req->setFlags(req->getFlags() | UNCACHEABLE);
+ req->setFlags(Request::UNCACHEABLE);
#if !ALPHA_TLASER
- // Clear bits 42:35 of the physical address (10-2 in Tsunami manual)
+ // Clear bits 42:35 of the physical address (10-2 in
+ // Tsunami manual)
req->setPaddr(req->getPaddr() & PAddrUncachedMask);
#endif
}
+ // We shouldn't be able to read from an uncachable address in Alpha as
+ // we don't have a ROM and we don't want to try to fetch from a device
+ // register as we destroy any data that is clear-on-read.
+ if (req->isUncacheable() && itb)
+ return new UnimpFault("CPU trying to fetch from uncached I/O");
+
}
return NoFault;
}
@@ -216,7 +224,8 @@ TLB::flushProcesses()
++i;
if (!entry->asma) {
- DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, entry->tag, entry->ppn);
+ DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index,
+ entry->tag, entry->ppn);
entry->valid = false;
lookupTable.erase(cur);
}
@@ -279,7 +288,6 @@ TLB::unserialize(Checkpoint *cp, const string &section)
}
}
-
///////////////////////////////////////////////////////////////////////
//
// Alpha ITB
@@ -308,13 +316,12 @@ ITB::regStats()
accesses = hits + misses;
}
-
Fault
-ITB::translate(RequestPtr &req, ThreadContext *tc)
+ITB::translateAtomic(RequestPtr req, ThreadContext *tc)
{
//If this is a pal pc, then set PHYSICAL
- if(FULL_SYSTEM && PcPAL(req->getPC()))
- req->setFlags(req->getFlags() | PHYSICAL);
+ if (FULL_SYSTEM && PcPAL(req->getPC()))
+ req->setFlags(Request::PHYSICAL);
if (PcPAL(req->getPC())) {
// strip off PAL PC marker (lsb is 1)
@@ -323,7 +330,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
return NoFault;
}
- if (req->getFlags() & PHYSICAL) {
+ if (req->getFlags() & Request::PHYSICAL) {
req->setPaddr(req->getVaddr());
} else {
// verify that this is a good virtual address
@@ -390,15 +397,23 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
if (req->getPaddr() & ~PAddrImplMask)
return genMachineCheckFault();
- return checkCacheability(req);
+ return checkCacheability(req, true);
}
+void
+ITB::translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation)
+{
+ assert(translation);
+ translation->finish(translateAtomic(req, tc), req, tc, false);
+}
+
///////////////////////////////////////////////////////////////////////
//
// Alpha DTB
//
- DTB::DTB(const Params *p)
+DTB::DTB(const Params *p)
: TLB(p)
{}
@@ -472,14 +487,13 @@ DTB::regStats()
}
Fault
-DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
+DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write)
{
Addr pc = tc->readPC();
mode_type mode =
(mode_type)DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM));
-
/**
* Check for alignment faults
*/
@@ -491,13 +505,13 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
}
if (PcPAL(pc)) {
- mode = (req->getFlags() & ALTMODE) ?
+ mode = (req->getFlags() & Request::ALTMODE) ?
(mode_type)ALT_MODE_AM(
tc->readMiscRegNoEffect(IPR_ALT_MODE))
: mode_kernel;
}
- if (req->getFlags() & PHYSICAL) {
+ if (req->getFlags() & Request::PHYSICAL) {
req->setPaddr(req->getVaddr());
} else {
// verify that this is a good virtual address
@@ -517,14 +531,15 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
if (VAddrSpaceEV6(req->getVaddr()) == 0x7e)
#endif
{
-
// only valid in kernel mode
if (DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)) !=
mode_kernel) {
if (write) { write_acv++; } else { read_acv++; }
uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) |
MM_STAT_ACV_MASK);
- return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
+
+ return new DtbAcvFault(req->getVaddr(), req->getFlags(),
+ flags);
}
req->setPaddr(req->getVaddr() & PAddrImplMask);
@@ -553,7 +568,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
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) ?
+ return (req->getFlags() & Request::VPTE) ?
(Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(),
flags)) :
(Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(),
@@ -570,25 +585,28 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
uint64_t flags = MM_STAT_WR_MASK |
MM_STAT_ACV_MASK |
(entry->fonw ? MM_STAT_FONW_MASK : 0);
- return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
+ return new DtbPageFault(req->getVaddr(), req->getFlags(),
+ flags);
}
if (entry->fonw) {
write_acv++;
- uint64_t flags = MM_STAT_WR_MASK |
- MM_STAT_FONW_MASK;
- return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
+ uint64_t flags = MM_STAT_WR_MASK | MM_STAT_FONW_MASK;
+ return new DtbPageFault(req->getVaddr(), req->getFlags(),
+ flags);
}
} else {
if (!(entry->xre & MODE2MASK(mode))) {
read_acv++;
uint64_t flags = MM_STAT_ACV_MASK |
(entry->fonr ? MM_STAT_FONR_MASK : 0);
- return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
+ return new DtbAcvFault(req->getVaddr(), req->getFlags(),
+ flags);
}
if (entry->fonr) {
read_acv++;
uint64_t flags = MM_STAT_FONR_MASK;
- return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
+ return new DtbPageFault(req->getVaddr(), req->getFlags(),
+ flags);
}
}
}
@@ -606,6 +624,14 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
return checkCacheability(req);
}
+void
+DTB::translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation, bool write)
+{
+ assert(translation);
+ translation->finish(translateAtomic(req, tc, write), req, tc, write);
+}
+
TlbEntry &
TLB::index(bool advance)
{
diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh
index e61ae5c6d..643889534 100644
--- a/src/arch/alpha/tlb.hh
+++ b/src/arch/alpha/tlb.hh
@@ -29,8 +29,8 @@
* Steve Reinhardt
*/
-#ifndef __ALPHA_MEMORY_HH__
-#define __ALPHA_MEMORY_HH__
+#ifndef __ARCH_ALPHA_TLB_HH__
+#define __ARCH_ALPHA_TLB_HH__
#include <map>
@@ -48,110 +48,120 @@
class ThreadContext;
-namespace AlphaISA
+namespace AlphaISA {
+
+class TlbEntry;
+
+class TLB : public BaseTLB
{
- class TlbEntry;
+ protected:
+ typedef std::multimap<Addr, int> PageTable;
+ PageTable lookupTable; // Quick lookup into page table
+
+ TlbEntry *table; // the Page Table
+ int size; // TLB Size
+ int nlu; // not last used entry (for replacement)
+
+ void nextnlu() { if (++nlu >= size) nlu = 0; }
+ TlbEntry *lookup(Addr vpn, uint8_t asn);
+
+ public:
+ typedef AlphaTLBParams Params;
+ TLB(const Params *p);
+ virtual ~TLB();
+
+ int getsize() const { return size; }
- class TLB : public BaseTLB
+ TlbEntry &index(bool advance = true);
+ void insert(Addr vaddr, TlbEntry &entry);
+
+ void flushAll();
+ void flushProcesses();
+ void flushAddr(Addr addr, uint8_t asn);
+
+ void
+ demapPage(Addr vaddr, uint64_t asn)
{
- protected:
- typedef std::multimap<Addr, int> PageTable;
- PageTable lookupTable; // Quick lookup into page table
-
- TlbEntry *table; // the Page Table
- int size; // TLB Size
- int nlu; // not last used entry (for replacement)
-
- void nextnlu() { if (++nlu >= size) nlu = 0; }
- TlbEntry *lookup(Addr vpn, uint8_t asn);
-
- public:
- typedef AlphaTLBParams Params;
- TLB(const Params *p);
- virtual ~TLB();
-
- int getsize() const { return size; }
-
- TlbEntry &index(bool advance = true);
- void insert(Addr vaddr, TlbEntry &entry);
-
- void flushAll();
- void flushProcesses();
- void flushAddr(Addr addr, uint8_t asn);
-
- void demapPage(Addr vaddr, uint64_t asn)
- {
- assert(asn < (1 << 8));
- flushAddr(vaddr, asn);
- }
-
- // static helper functions... really EV5 VM traits
- static bool validVirtualAddress(Addr vaddr) {
- // unimplemented bits must be all 0 or all 1
- Addr unimplBits = vaddr & EV5::VAddrUnImplMask;
- return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask);
- }
-
- static Fault checkCacheability(RequestPtr &req);
-
- // Checkpointing
- virtual void serialize(std::ostream &os);
- virtual void unserialize(Checkpoint *cp, const std::string &section);
-
- // Most recently used page table entries
- TlbEntry *EntryCache[3];
- inline void flushCache()
- {
- memset(EntryCache, 0, 3 * sizeof(TlbEntry*));
- }
-
- inline TlbEntry* updateCache(TlbEntry *entry) {
- EntryCache[2] = EntryCache[1];
- EntryCache[1] = EntryCache[0];
- EntryCache[0] = entry;
- return entry;
- }
- };
-
- class ITB : public TLB
+ assert(asn < (1 << 8));
+ flushAddr(vaddr, asn);
+ }
+
+ // static helper functions... really EV5 VM traits
+ static bool
+ validVirtualAddress(Addr vaddr)
{
- protected:
- mutable Stats::Scalar<> hits;
- mutable Stats::Scalar<> misses;
- mutable Stats::Scalar<> acv;
- mutable Stats::Formula accesses;
+ // unimplemented bits must be all 0 or all 1
+ Addr unimplBits = vaddr & VAddrUnImplMask;
+ return unimplBits == 0 || unimplBits == VAddrUnImplMask;
+ }
- public:
- typedef AlphaITBParams Params;
- ITB(const Params *p);
- virtual void regStats();
+ static Fault checkCacheability(RequestPtr &req, bool itb = false);
- Fault translate(RequestPtr &req, ThreadContext *tc);
- };
+ // Checkpointing
+ virtual void serialize(std::ostream &os);
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
- class DTB : public TLB
+ // Most recently used page table entries
+ TlbEntry *EntryCache[3];
+ inline void
+ flushCache()
{
- 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:
- typedef AlphaDTBParams Params;
- DTB(const Params *p);
- virtual void regStats();
-
- Fault translate(RequestPtr &req, ThreadContext *tc, bool write);
- };
-}
-
-#endif // __ALPHA_MEMORY_HH__
+ memset(EntryCache, 0, 3 * sizeof(TlbEntry*));
+ }
+
+ inline TlbEntry *
+ updateCache(TlbEntry *entry) {
+ EntryCache[2] = EntryCache[1];
+ EntryCache[1] = EntryCache[0];
+ EntryCache[0] = entry;
+ return entry;
+ }
+};
+
+class ITB : public TLB
+{
+ protected:
+ mutable Stats::Scalar hits;
+ mutable Stats::Scalar misses;
+ mutable Stats::Scalar acv;
+ mutable Stats::Formula accesses;
+
+ public:
+ typedef AlphaITBParams Params;
+ ITB(const Params *p);
+ virtual void regStats();
+
+ Fault translateAtomic(RequestPtr req, ThreadContext *tc);
+ void translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation);
+};
+
+class DTB : public TLB
+{
+ protected:
+ mutable Stats::Scalar read_hits;
+ mutable Stats::Scalar read_misses;
+ mutable Stats::Scalar read_acv;
+ mutable Stats::Scalar read_accesses;
+ mutable Stats::Scalar write_hits;
+ mutable Stats::Scalar write_misses;
+ mutable Stats::Scalar write_acv;
+ mutable Stats::Scalar write_accesses;
+ Stats::Formula hits;
+ Stats::Formula misses;
+ Stats::Formula acv;
+ Stats::Formula accesses;
+
+ public:
+ typedef AlphaDTBParams Params;
+ DTB(const Params *p);
+ virtual void regStats();
+
+ Fault translateAtomic(RequestPtr req, ThreadContext *tc, bool write);
+ void translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation, bool write);
+};
+
+} // namespace AlphaISA
+
+#endif // __ARCH_ALPHA_TLB_HH__
diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc
index 6823d820a..8fa3cdeda 100644
--- a/src/arch/alpha/tru64/process.cc
+++ b/src/arch/alpha/tru64/process.cc
@@ -32,10 +32,8 @@
#include "arch/alpha/tru64/tru64.hh"
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/tru64/process.hh"
-
#include "cpu/thread_context.hh"
#include "kern/tru64/tru64.hh"
-
#include "sim/process.hh"
#include "sim/syscall_emul.hh"
@@ -47,7 +45,7 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- TypedBufferArg<AlphaTru64::utsname> name(tc->getSyscallArg(0));
+ TypedBufferArg<AlphaTru64::utsname> name(process->getSyscallArg(tc, 0));
strcpy(name->sysname, "OSF1");
strcpy(name->nodename, "m5.eecs.umich.edu");
@@ -64,34 +62,35 @@ static SyscallReturn
getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- unsigned op = tc->getSyscallArg(0);
- unsigned nbytes = tc->getSyscallArg(2);
+ unsigned op = process->getSyscallArg(tc, 0);
+ unsigned nbytes = process->getSyscallArg(tc, 2);
switch (op) {
case AlphaTru64::GSI_MAX_CPU: {
- TypedBufferArg<uint32_t> max_cpu(tc->getSyscallArg(1));
+ TypedBufferArg<uint32_t> max_cpu(process->getSyscallArg(tc, 1));
*max_cpu = htog((uint32_t)process->numCpus());
max_cpu.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_CPUS_IN_BOX: {
- TypedBufferArg<uint32_t> cpus_in_box(tc->getSyscallArg(1));
+ TypedBufferArg<uint32_t> cpus_in_box(process->getSyscallArg(tc, 1));
*cpus_in_box = htog((uint32_t)process->numCpus());
cpus_in_box.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_PHYSMEM: {
- TypedBufferArg<uint64_t> physmem(tc->getSyscallArg(1));
- *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
+ TypedBufferArg<uint64_t> physmem(process->getSyscallArg(tc, 1));
+ *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
physmem.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_CPU_INFO: {
- TypedBufferArg<AlphaTru64::cpu_info> infop(tc->getSyscallArg(1));
+ TypedBufferArg<AlphaTru64::cpu_info>
+ infop(process->getSyscallArg(tc, 1));
infop->current_cpu = htog(0);
infop->cpus_in_box = htog(process->numCpus());
@@ -108,14 +107,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
}
case AlphaTru64::GSI_PROC_TYPE: {
- TypedBufferArg<uint64_t> proc_type(tc->getSyscallArg(1));
+ TypedBufferArg<uint64_t> proc_type(process->getSyscallArg(tc, 1));
*proc_type = htog((uint64_t)11);
proc_type.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_PLATFORM_NAME: {
- BufferArg bufArg(tc->getSyscallArg(1), nbytes);
+ BufferArg bufArg(process->getSyscallArg(tc, 1), nbytes);
strncpy((char *)bufArg.bufferPtr(),
"COMPAQ Professional Workstation XP1000",
nbytes);
@@ -124,7 +123,7 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
}
case AlphaTru64::GSI_CLK_TCK: {
- TypedBufferArg<uint64_t> clk_hz(tc->getSyscallArg(1));
+ TypedBufferArg<uint64_t> clk_hz(process->getSyscallArg(tc, 1));
*clk_hz = htog((uint64_t)1024);
clk_hz.copyOut(tc->getMemPort());
return 1;
@@ -143,12 +142,12 @@ static SyscallReturn
setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- unsigned op = tc->getSyscallArg(0);
+ unsigned op = process->getSyscallArg(tc, 0);
switch (op) {
case AlphaTru64::SSI_IEEE_FP_CONTROL:
warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n",
- tc->getSyscallArg(1));
+ process->getSyscallArg(tc, 1));
break;
default:
@@ -159,26 +158,24 @@ setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
return 0;
}
-
/// Target table() handler.
-static
-SyscallReturn tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
- ThreadContext *tc)
+static SyscallReturn
+tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+ ThreadContext *tc)
{
using namespace std;
- using namespace TheISA;
- int id = tc->getSyscallArg(0); // table ID
- int index = tc->getSyscallArg(1); // index into table
+ int id = process->getSyscallArg(tc, 0); // table ID
+ int index = process->getSyscallArg(tc, 1); // index into table
// arg 2 is buffer pointer; type depends on table ID
- int nel = tc->getSyscallArg(3); // number of elements
- int lel = tc->getSyscallArg(4); // expected element size
+ int nel = process->getSyscallArg(tc, 3); // number of elements
+ int lel = process->getSyscallArg(tc, 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(tc->getSyscallArg(2));
+ TypedBufferArg<Tru64::tbl_sysinfo> elp(process->getSyscallArg(tc, 2));
const int clk_hz = one_million;
elp->si_user = htog(curTick / (Clock::Frequency / clk_hz));
@@ -219,7 +216,7 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = {
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", unimplementedFunc),
/* 16 */ SyscallDesc("chown", unimplementedFunc),
- /* 17 */ SyscallDesc("obreak", obreakFunc),
+ /* 17 */ SyscallDesc("obreak", brkFunc),
/* 18 */ SyscallDesc("pre_F64_getfsstat", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getpid", getpidPseudoFunc),
@@ -260,9 +257,9 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = {
/* 55 */ SyscallDesc("reboot", unimplementedFunc),
/* 56 */ SyscallDesc("revoke", unimplementedFunc),
/* 57 */ SyscallDesc("symlink", unimplementedFunc),
- /* 58 */ SyscallDesc("readlink", unimplementedFunc),
+ /* 58 */ SyscallDesc("readlink", readlinkFunc),
/* 59 */ SyscallDesc("execve", unimplementedFunc),
- /* 60 */ SyscallDesc("umask", unimplementedFunc),
+ /* 60 */ SyscallDesc("umask", umaskFunc),
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
/* 62 */ SyscallDesc("old_fstat", unimplementedFunc),
/* 63 */ SyscallDesc("getpgrp", unimplementedFunc),
@@ -339,7 +336,7 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = {
/* 133 */ SyscallDesc("sendto", unimplementedFunc),
/* 134 */ SyscallDesc("shutdown", unimplementedFunc),
/* 135 */ SyscallDesc("socketpair", unimplementedFunc),
- /* 136 */ SyscallDesc("mkdir", unimplementedFunc),
+ /* 136 */ SyscallDesc("mkdir", mkdirFunc),
/* 137 */ SyscallDesc("rmdir", unimplementedFunc),
/* 138 */ SyscallDesc("utimes", unimplementedFunc),
/* 139 */ SyscallDesc("obsolete 4.2 sigreturn", unimplementedFunc),
@@ -472,15 +469,14 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = {
/* 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),
+ /* 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),
@@ -507,7 +503,8 @@ SyscallDesc AlphaTru64Process::machSyscallDescs[] = {
/* 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),
+ /* 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),
@@ -572,9 +569,8 @@ AlphaTru64Process::getDesc(int callnum)
return &syscallDescs[callnum];
}
-
-AlphaTru64Process::AlphaTru64Process(LiveProcessParams * params,
- ObjectFile *objFile)
+AlphaTru64Process::AlphaTru64Process(LiveProcessParams *params,
+ ObjectFile *objFile)
: AlphaLiveProcess(params, objFile),
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)),
Num_Mach_Syscall_Descs(sizeof(machSyscallDescs) / sizeof(SyscallDesc))
diff --git a/src/arch/alpha/tru64/process.hh b/src/arch/alpha/tru64/process.hh
index 16bc499c6..6d7a76555 100644
--- a/src/arch/alpha/tru64/process.hh
+++ b/src/arch/alpha/tru64/process.hh
@@ -28,12 +28,13 @@
* Authors: Steve Reinhardt
*/
-#ifndef __ALPHA_TRU64_PROCESS_HH__
-#define __ALPHA_TRU64_PROCESS_HH__
+#ifndef __ARCH_ALPHA_TRU64_PROCESS_HH__
+#define __ARCH_ALPHA_TRU64_PROCESS_HH__
#include "arch/alpha/process.hh"
namespace AlphaISA {
+
/// A process with emulated Alpha Tru64 syscalls.
class AlphaTru64Process : public AlphaLiveProcess
{
@@ -51,9 +52,9 @@ class AlphaTru64Process : public AlphaLiveProcess
const int Num_Syscall_Descs;
const int Num_Mach_Syscall_Descs;
- virtual SyscallDesc* getDesc(int callnum);
+ virtual SyscallDesc *getDesc(int callnum);
};
} // namespace AlphaISA
-#endif // __ALPHA_TRU64_PROCESS_HH__
+#endif // __ARCH_ALPHA_TRU64_PROCESS_HH__
diff --git a/src/arch/alpha/tru64/tru64.cc b/src/arch/alpha/tru64/tru64.cc
index 56b04846f..c72e975f0 100644
--- a/src/arch/alpha/tru64/tru64.cc
+++ b/src/arch/alpha/tru64/tru64.cc
@@ -33,34 +33,34 @@
// 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 },
+ { 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 },
+ { AlphaTru64::TGT_O_NONBLOCK, _O_NONBLOCK },
#endif
#ifdef _O_NOCTTY
- { AlphaTru64::TGT_O_NOCTTY, _O_NOCTTY },
+ { AlphaTru64::TGT_O_NOCTTY, _O_NOCTTY },
#endif
#ifdef _O_SYNC
- { AlphaTru64::TGT_O_SYNC, _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 },
+ { 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 },
+ { AlphaTru64::TGT_O_SYNC, O_SYNC },
#endif
#endif /* _MSC_VER */
};
diff --git a/src/arch/alpha/tru64/tru64.hh b/src/arch/alpha/tru64/tru64.hh
index 90e5f12dc..4ba35fc50 100644
--- a/src/arch/alpha/tru64/tru64.hh
+++ b/src/arch/alpha/tru64/tru64.hh
@@ -28,14 +28,13 @@
* Authors: Korey Sewell
*/
-#ifndef __ALPHA_ALPHA_TRU64_HH
-#define __ALPHA_ALPHA_TRU64_HH
+#ifndef __ALPHA_ALPHA_TRU64_TRU64_HH__
+#define __ALPHA_ALPHA_TRU64_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.
@@ -46,21 +45,21 @@ class AlphaTru64 : public Tru64
//@{
/// 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
+ 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().
@@ -68,13 +67,13 @@ class AlphaTru64 : public Tru64
//@{
/// 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_PLATFORM_NAME = 103; //!< platform name 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 # CPUs on 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
//@}
//@{
@@ -124,6 +123,4 @@ class AlphaTru64 : public Tru64
};
};
-
-
-#endif
+#endif // __ALPHA_ALPHA_TRU64_TRU64_HH__
diff --git a/src/arch/alpha/types.hh b/src/arch/alpha/types.hh
index f6648b776..7905114b8 100644
--- a/src/arch/alpha/types.hh
+++ b/src/arch/alpha/types.hh
@@ -32,47 +32,43 @@
#ifndef __ARCH_ALPHA_TYPES_HH__
#define __ARCH_ALPHA_TYPES_HH__
-#include <inttypes.h>
+#include "sim/host.hh"
-namespace AlphaISA
-{
-
- typedef uint32_t MachInst;
- typedef uint64_t ExtMachInst;
- typedef uint8_t RegIndex;
+namespace AlphaISA {
- typedef uint64_t IntReg;
- typedef uint64_t LargestRead;
+typedef uint32_t MachInst;
+typedef uint64_t ExtMachInst;
+typedef uint8_t RegIndex;
- // floating point register file entry type
- typedef double FloatReg;
- typedef uint64_t FloatRegBits;
+typedef uint64_t IntReg;
+typedef uint64_t LargestRead;
- // control register file contents
- typedef uint64_t MiscReg;
+// floating point register file entry type
+typedef double FloatReg;
+typedef uint64_t FloatRegBits;
- typedef union {
- IntReg intreg;
- FloatReg fpreg;
- MiscReg ctrlreg;
- } AnyReg;
+// control register file contents
+typedef uint64_t MiscReg;
- enum RegContextParam
- {
- CONTEXT_PALMODE
- };
+union AnyReg
+{
+ IntReg intreg;
+ FloatReg fpreg;
+ MiscReg ctrlreg;
+};
- typedef bool RegContextVal;
+enum annotes
+{
+ ANNOTE_NONE = 0,
+ // An impossible number for instruction annotations
+ ITOUCH_ANNOTE = 0xffffffff,
+};
- enum annotes {
- ANNOTE_NONE = 0,
- // An impossible number for instruction annotations
- ITOUCH_ANNOTE = 0xffffffff,
- };
+struct CoreSpecific
+{
+ int core_type;
+};
- struct CoreSpecific {
- int core_type;
- };
} // namespace AlphaISA
-#endif
+#endif // __ARCH_ALPHA_TYPES_HH__
diff --git a/src/arch/alpha/utility.cc b/src/arch/alpha/utility.cc
index f1864203b..763da0d4f 100644
--- a/src/arch/alpha/utility.cc
+++ b/src/arch/alpha/utility.cc
@@ -36,28 +36,28 @@
#include "mem/vport.hh"
#endif
-namespace AlphaISA
-{
+namespace AlphaISA {
-uint64_t getArgument(ThreadContext *tc, int number, bool fp)
+uint64_t
+getArgument(ThreadContext *tc, int number, bool fp)
{
#if FULL_SYSTEM
+ const int NumArgumentRegs = 6;
if (number < NumArgumentRegs) {
if (fp)
- return tc->readFloatRegBits(ArgumentReg[number]);
+ return tc->readFloatRegBits(16 + number);
else
- return tc->readIntReg(ArgumentReg[number]);
+ return tc->readIntReg(16 + number);
} else {
Addr sp = tc->readIntReg(StackPointerReg);
- VirtualPort *vp = tc->getVirtPort(tc);
+ VirtualPort *vp = tc->getVirtPort();
uint64_t arg = vp->read<uint64_t>(sp +
(number-NumArgumentRegs) * sizeof(uint64_t));
- tc->delVirtPort(vp);
return arg;
}
#else
panic("getArgument() is Full system only\n");
- M5_DUMMY_RETURN
+ M5_DUMMY_RETURN;
#endif
}
diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh
index 11357bc44..76c6c5726 100644
--- a/src/arch/alpha/utility.hh
+++ b/src/arch/alpha/utility.hh
@@ -32,127 +32,137 @@
#ifndef __ARCH_ALPHA_UTILITY_HH__
#define __ARCH_ALPHA_UTILITY_HH__
-#include "config/full_system.hh"
#include "arch/alpha/types.hh"
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/regfile.hh"
#include "base/misc.hh"
+#include "config/full_system.hh"
#include "cpu/thread_context.hh"
-namespace AlphaISA
+namespace AlphaISA {
+
+uint64_t getArgument(ThreadContext *tc, int number, bool fp);
+
+inline bool
+inUserMode(ThreadContext *tc)
+{
+ return (tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0;
+}
+
+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;
+}
- uint64_t getArgument(ThreadContext *tc, int number, bool fp);
-
- static inline bool
- inUserMode(ThreadContext *tc)
- {
- return (tc->readMiscRegNoEffect(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
- }
-
- 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 &reg_file,
- int regnum);
-
- void restoreMachineReg(RegFile &regs, const AnyReg &reg,
- int regnum);
-
- /**
- * Function to insure ISA semantics about 0 registers.
- * @param tc The thread context.
- */
- template <class TC>
- void zeroRegisters(TC *tc);
-
- // Alpha IPR register accessors
- inline bool PcPAL(Addr addr) { return addr & 0x3; }
- inline void startupCPU(ThreadContext *tc, int cpuId) {
- tc->activate(0);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // 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 initIPRs(ThreadContext *tc, int cpuId);
+// 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 &reg_file, int regnum);
+void restoreMachineReg(RegFile &regs, const AnyReg &reg, int regnum);
+
+/**
+ * Function to insure ISA semantics about 0 registers.
+ * @param tc The thread context.
+ */
+template <class TC>
+void zeroRegisters(TC *tc);
+
+// Alpha IPR register accessors
+inline bool PcPAL(Addr addr) { return addr & 0x3; }
+inline void startupCPU(ThreadContext *tc, int cpuId) { tc->activate(0); }
+
+////////////////////////////////////////////////////////////////////////
+//
+// 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 initIPRs(ThreadContext *tc, int cpuId);
#if FULL_SYSTEM
- void initCPU(ThreadContext *tc, int cpuId);
-
- /**
- * Function to check for and process any interrupts.
- * @param tc The thread context.
- */
- template <class TC>
- void processInterrupts(TC *tc);
+void initCPU(ThreadContext *tc, int cpuId);
+
+/**
+ * Function to check for and process any interrupts.
+ * @param tc The thread context.
+ */
+template <class TC>
+void processInterrupts(TC *tc);
#endif
} // namespace AlphaISA
-#endif
+#endif // __ARCH_ALPHA_UTILITY_HH__
diff --git a/src/arch/alpha/vtophys.cc b/src/arch/alpha/vtophys.cc
index 6ffbea181..4a043d8d1 100644
--- a/src/arch/alpha/vtophys.cc
+++ b/src/arch/alpha/vtophys.cc
@@ -40,27 +40,28 @@
#include "mem/vport.hh"
using namespace std;
-using namespace AlphaISA;
-AlphaISA::PageTableEntry
-AlphaISA::kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr)
+namespace AlphaISA {
+
+PageTableEntry
+kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, VAddr vaddr)
{
Addr level1_pte = ptbr + vaddr.level1();
- AlphaISA::PageTableEntry level1 = mem->read<uint64_t>(level1_pte);
+ 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);
+ 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);
+ PageTableEntry level3 = mem->read<uint64_t>(level3_pte);
if (!level3.valid()) {
DPRINTF(VtoPhys, "level 3 PTE not valid, va = %#x\n", vaddr);
return 0;
@@ -69,13 +70,13 @@ AlphaISA::kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vadd
}
Addr
-AlphaISA::vtophys(Addr vaddr)
+vtophys(Addr vaddr)
{
Addr paddr = 0;
- if (AlphaISA::IsUSeg(vaddr))
+ if (IsUSeg(vaddr))
DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr);
- else if (AlphaISA::IsK0Seg(vaddr))
- paddr = AlphaISA::K0Seg2Phys(vaddr);
+ else if (IsK0Seg(vaddr))
+ paddr = K0Seg2Phys(vaddr);
else
panic("vtophys: ptbr is not set on virtual lookup");
@@ -85,22 +86,22 @@ AlphaISA::vtophys(Addr vaddr)
}
Addr
-AlphaISA::vtophys(ThreadContext *tc, Addr addr)
+vtophys(ThreadContext *tc, Addr addr)
{
- AlphaISA::VAddr vaddr = addr;
- Addr ptbr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp20);
+ VAddr vaddr = addr;
+ Addr ptbr = tc->readMiscRegNoEffect(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)) {
+ if (PcPAL(vaddr) && (vaddr < PalMax)) {
paddr = vaddr & ~ULL(1);
} else {
- if (AlphaISA::IsK0Seg(vaddr)) {
- paddr = AlphaISA::K0Seg2Phys(vaddr);
+ if (IsK0Seg(vaddr)) {
+ paddr = K0Seg2Phys(vaddr);
} else if (!ptbr) {
paddr = vaddr;
} else {
- AlphaISA::PageTableEntry pte =
+ PageTableEntry pte =
kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr);
if (pte.valid())
paddr = pte.paddr() | vaddr.offset();
@@ -113,3 +114,4 @@ AlphaISA::vtophys(ThreadContext *tc, Addr addr)
return paddr;
}
+} // namespace AlphaISA
diff --git a/src/arch/alpha/vtophys.hh b/src/arch/alpha/vtophys.hh
index bd2ee8468..b13afd090 100644
--- a/src/arch/alpha/vtophys.hh
+++ b/src/arch/alpha/vtophys.hh
@@ -41,12 +41,13 @@ class FunctionalPort;
namespace AlphaISA {
- PageTableEntry
- kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr);
+PageTableEntry kernel_pte_lookup(FunctionalPort *mem, Addr ptbr,
+ VAddr vaddr);
- Addr vtophys(Addr vaddr);
- Addr vtophys(ThreadContext *tc, Addr vaddr);
+Addr vtophys(Addr vaddr);
+Addr vtophys(ThreadContext *tc, Addr vaddr);
+
+} // namespace AlphaISA
-};
#endif // __ARCH_ALPHA_VTOPHYS_H__
diff --git a/src/arch/arm/ArmTLB.py b/src/arch/arm/ArmTLB.py
index 21253edef..fa9faaddf 100644
--- a/src/arch/arm/ArmTLB.py
+++ b/src/arch/arm/ArmTLB.py
@@ -34,25 +34,21 @@ from m5.params import *
class ArmTLB(SimObject):
abstract = True
type = 'ArmTLB'
- cxx_namespace = 'ArmISA'
- cxx_class = 'TLB'
+ cxx_class = 'ArmISA::TLB'
size = Param.Int("TLB size")
class ArmDTB(ArmTLB):
type = 'ArmDTB'
- cxx_namespace = 'ArmISA'
- cxx_class = 'DTB'
+ cxx_class = 'ArmISA::DTB'
size = 64
class ArmITB(ArmTLB):
type = 'ArmITB'
- cxx_namespace = 'ArmISA'
- cxx_class = 'ITB'
+ cxx_class = 'ArmISA::ITB'
size = 64
class ArmUTB(ArmTLB):
type = 'ArmUTB'
- cxx_namespace = 'ArmISA'
- cxx_class = 'UTB'
+ cxx_class = 'ArmISA::UTB'
size = 64
diff --git a/src/arch/arm/isa_traits.hh b/src/arch/arm/isa_traits.hh
index 253114ad1..cf07699ce 100644
--- a/src/arch/arm/isa_traits.hh
+++ b/src/arch/arm/isa_traits.hh
@@ -131,9 +131,6 @@ namespace ArmISA
const int ZeroReg = NumIntArchRegs;
const int AddrReg = ZeroReg + 1; // Used to generate address for uops
- const int ArgumentReg[] = {0, 1, 2, 3};
- const int NumArgumentRegs = sizeof(ArgumentReg)/ sizeof(const int);
-
const int SyscallNumReg = ReturnValueReg;
const int SyscallPseudoReturnReg = ReturnValueReg;
const int SyscallSuccessReg = ReturnValueReg;
diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc
index 6d3153063..46b2f9bee 100644
--- a/src/arch/arm/linux/process.cc
+++ b/src/arch/arm/linux/process.cc
@@ -49,7 +49,7 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
+ TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
@@ -79,7 +79,7 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = {
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", chmodFunc<ArmLinux>),
/* 16 */ SyscallDesc("lchown", chownFunc),
- /* 17 */ SyscallDesc("break", obreakFunc), //???
+ /* 17 */ SyscallDesc("break", brkFunc), //???
/* 18 */ SyscallDesc("unused#18", unimplementedFunc), //???
/* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getpid", getpidFunc),
@@ -107,7 +107,7 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = {
/* 42 */ SyscallDesc("pipe", unimplementedFunc),
/* 43 */ SyscallDesc("times", unimplementedFunc),
/* 44 */ SyscallDesc("prof", unimplementedFunc),
- /* 45 */ SyscallDesc("brk", obreakFunc),
+ /* 45 */ SyscallDesc("brk", brkFunc),
/* 46 */ SyscallDesc("setgid", unimplementedFunc),
/* 47 */ SyscallDesc("getgid", getgidFunc),
/* 48 */ SyscallDesc("signal", ignoreFunc),
diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc
index 00ba414ba..365d5b22c 100644
--- a/src/arch/arm/process.cc
+++ b/src/arch/arm/process.cc
@@ -43,8 +43,7 @@
using namespace std;
using namespace ArmISA;
-ArmLiveProcess::ArmLiveProcess(LiveProcessParams * params,
- ObjectFile *objFile)
+ArmLiveProcess::ArmLiveProcess(LiveProcessParams *params, ObjectFile *objFile)
: LiveProcess(params, objFile)
{
stack_base = 0xc0000000L;
@@ -147,12 +146,35 @@ ArmLiveProcess::argsInit(int intSize, int pageSize)
initVirtMem->writeBlob(0xffff0fe0, insns, 8);
*/
- threadContexts[0]->setIntReg(ArgumentReg1, argc);
- threadContexts[0]->setIntReg(ArgumentReg2, argv_array_base);
- threadContexts[0]->setIntReg(StackPointerReg, stack_min);
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
+
+ tc->setIntReg(ArgumentReg1, argc);
+ tc->setIntReg(ArgumentReg2, argv_array_base);
+ tc->setIntReg(StackPointerReg, stack_min);
Addr prog_entry = objFile->entryPoint();
- threadContexts[0]->setPC(prog_entry);
- threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
+ tc->setPC(prog_entry);
+ tc->setNextPC(prog_entry + sizeof(MachInst));
+}
+
+ArmISA::IntReg
+ArmLiveProcess::getSyscallArg(ThreadContext *tc, int i)
+{
+ assert(i < 4);
+ return tc->readIntReg(ArgumentReg0 + i);
}
+void
+ArmLiveProcess::setSyscallArg(ThreadContext *tc,
+ int i, ArmISA::IntReg val)
+{
+ assert(i < 4);
+ tc->setIntReg(ArgumentReg0 + i, val);
+}
+
+void
+ArmLiveProcess::setSyscallReturn(ThreadContext *tc,
+ SyscallReturn return_value)
+{
+ tc->setIntReg(ReturnValueReg, return_value.value());
+}
diff --git a/src/arch/arm/process.hh b/src/arch/arm/process.hh
index b97f4b0d2..8954d3719 100644
--- a/src/arch/arm/process.hh
+++ b/src/arch/arm/process.hh
@@ -53,6 +53,9 @@ class ArmLiveProcess : public LiveProcess
public:
void argsInit(int intSize, int pageSize);
+ ArmISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val);
+ void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
};
#endif // __ARM_PROCESS_HH__
diff --git a/src/arch/arm/regfile/regfile.cc b/src/arch/arm/regfile/regfile.cc
index 5de0b3076..a4d6e9a4a 100644
--- a/src/arch/arm/regfile/regfile.cc
+++ b/src/arch/arm/regfile/regfile.cc
@@ -55,7 +55,7 @@ MiscRegFile::copyMiscRegs(ThreadContext *tc)
}
void
-RegFile::serialize(std::ostream &os)
+RegFile::serialize(EventManager *em, ostream &os)
{
intRegFile.serialize(os);
//SERIALIZE_ARRAY(floatRegFile, NumFloatRegs);
@@ -69,7 +69,7 @@ RegFile::serialize(std::ostream &os)
}
void
-RegFile::unserialize(Checkpoint *cp, const std::string &section)
+RegFile::unserialize(EventManager *em, Checkpoint *cp, const string &section)
{
intRegFile.unserialize(cp, section);
//UNSERIALIZE_ARRAY(floatRegFile);
diff --git a/src/arch/arm/regfile/regfile.hh b/src/arch/arm/regfile/regfile.hh
index 86799f18d..7f4d21353 100644
--- a/src/arch/arm/regfile/regfile.hh
+++ b/src/arch/arm/regfile/regfile.hh
@@ -38,11 +38,13 @@
#include "sim/faults.hh"
class Checkpoint;
+class EventManager;
class ThreadContext;
namespace ArmISA
{
- class RegFile {
+ class RegFile
+ {
protected:
IntRegFile intRegFile; // (signed) integer register file
FloatRegFile floatRegFile; // floating point register file
@@ -176,8 +178,9 @@ namespace ArmISA
//nnpc = val;
}
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
+ void serialize(EventManager *em, std::ostream &os);
+ void unserialize(EventManager *em, Checkpoint *cp,
+ const std::string &section);
void changeContext(RegContextParam param, RegContextVal val)
{
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index d0cc57a1d..78eebddfe 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -29,6 +29,7 @@
*
* Authors: Nathan Binkert
* Steve Reinhardt
+ * Jaidev Patwardhan
* Stephen Hines
*/
@@ -149,7 +150,7 @@ TLB::checkCacheability(RequestPtr &req)
// or by the TLB entry
if((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) {
// mark request as uncacheable
- req->setFlags(req->getFlags() | UNCACHEABLE);
+ req->setFlags(req->getFlags() | Request::UNCACHEABLE);
}
return NoFault;
}
@@ -278,7 +279,7 @@ TLB::regStats()
}
Fault
-ITB::translate(RequestPtr &req, ThreadContext *tc)
+ITB::translateAtomic(RequestPtr req, ThreadContext *tc)
{
#if !FULL_SYSTEM
Process * p = tc->getProcessPtr();
@@ -293,8 +294,17 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
#endif
}
+void
+ITB::translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation)
+{
+ assert(translation);
+ translation->finish(translateAtomic(req, tc), req, tc, false);
+}
+
+
Fault
-DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
+DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write)
{
#if !FULL_SYSTEM
Process * p = tc->getProcessPtr();
@@ -309,6 +319,14 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
#endif
}
+void
+DTB::translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation, bool write)
+{
+ assert(translation);
+ translation->finish(translateAtomic(req, tc, write), req, tc, write);
+}
+
///////////////////////////////////////////////////////////////////////
//
// Arm ITB
diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh
index 59fe1a60d..fea317ef3 100644
--- a/src/arch/arm/tlb.hh
+++ b/src/arch/arm/tlb.hh
@@ -62,6 +62,12 @@ struct TlbEntry
TlbEntry() {}
TlbEntry(Addr asn, Addr vaddr, Addr paddr) : _pageStart(paddr) {}
+ void
+ updateVaddr(Addr new_vaddr)
+ {
+ panic("unimplemented");
+ }
+
Addr pageStart()
{
return _pageStart;
@@ -92,14 +98,14 @@ class TLB : public BaseTLB
void nextnlu() { if (++nlu >= size) nlu = 0; }
ArmISA::PTE *lookup(Addr vpn, uint8_t asn) const;
- 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;
+ 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 invalids;
@@ -136,23 +142,30 @@ class TLB : public BaseTLB
void regStats();
};
-class ITB : public TLB {
+class ITB : public TLB
+{
public:
typedef ArmTLBParams Params;
ITB(const Params *p);
- Fault translate(RequestPtr &req, ThreadContext *tc);
+ Fault translateAtomic(RequestPtr req, ThreadContext *tc);
+ void translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation);
};
-class DTB : public TLB {
+class DTB : public TLB
+{
public:
typedef ArmTLBParams Params;
DTB(const Params *p);
- Fault translate(RequestPtr &req, ThreadContext *tc, bool write = false);
+ Fault translateAtomic(RequestPtr req, ThreadContext *tc, bool write);
+ void translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation, bool write);
};
-class UTB : public ITB, public DTB {
+class UTB : public ITB, public DTB
+{
public:
typedef ArmTLBParams Params;
UTB(const Params *p);
diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py
index bbdd95bb0..25cf84b30 100755
--- a/src/arch/isa_parser.py
+++ b/src/arch/isa_parser.py
@@ -116,7 +116,7 @@ t_SEMI = r';'
t_DOT = r'\.'
t_COLON = r':'
t_DBLCOLON = r'::'
-t_ASTERISK = r'\*'
+t_ASTERISK = r'\*'
# Identifiers and reserved words
reserved_map = { }
@@ -480,7 +480,7 @@ def p_excess_args_param(t):
#
# A decode block looks like:
-# decode <field1> [, <field2>]* [default <inst>] { ... }
+# decode <field1> [, <field2>]* [default <inst>] { ... }
#
def p_decode_block(t):
'decode_block : DECODE ID opt_default LBRACE decode_stmt_list RBRACE'
@@ -1149,7 +1149,7 @@ def buildOperandTypeMap(userDict, lineno):
ctype = 'uint%d_t' % size
is_signed = 0
elif desc == 'float':
- is_signed = 1 # shouldn't really matter
+ is_signed = 1 # shouldn't really matter
if size == 32:
ctype = 'float'
elif size == 64:
@@ -1595,9 +1595,9 @@ def buildOperandNameMap(userDict, lineno):
operands = userDict.keys()
operandsREString = (r'''
- (?<![\w\.]) # neg. lookbehind assertion: prevent partial matches
+ (?<![\w\.]) # neg. lookbehind assertion: prevent partial matches
((%s)(?:\.(\w+))?) # match: operand with optional '.' then suffix
- (?![\w\.]) # neg. lookahead assertion: prevent partial matches
+ (?![\w\.]) # neg. lookahead assertion: prevent partial matches
'''
% string.join(operands, '|'))
diff --git a/src/arch/isa_specific.hh b/src/arch/isa_specific.hh
index c10ce7350..de070bbf9 100644
--- a/src/arch/isa_specific.hh
+++ b/src/arch/isa_specific.hh
@@ -38,7 +38,7 @@
//To use them, do something like:
//
//#if THE_ISA == YOUR_FAVORITE_ISA
-// conditional_code
+// conditional_code
//#endif
//
//Note that this is how this file sets up the TheISA macro.
diff --git a/src/arch/micro_asm.py b/src/arch/micro_asm.py
index 36c9919c0..3433a8076 100644
--- a/src/arch/micro_asm.py
+++ b/src/arch/micro_asm.py
@@ -141,7 +141,7 @@ def handle_statement(parser, container, statement):
try:
for label in statement.labels:
container.labels[label.text] = microop
- if label.extern:
+ if label.is_extern:
container.externs[label.text] = microop
container.add_microop(statement.mnemonic, microop)
except:
@@ -242,7 +242,10 @@ def t_params_PARAMS(t):
def t_asm_ID(t):
r'[A-Za-z_]\w*'
t.type = reserved_map.get(t.value, 'ID')
- t.lexer.begin('params')
+ # If the ID is really "extern", we shouldn't start looking for parameters
+ # yet. The real ID, the label itself, is coming up.
+ if t.type != 'EXTERN':
+ t.lexer.begin('params')
return t
# If there is a label and you're -not- in the assembler (which would be caught
diff --git a/src/arch/mips/MipsInterrupts.py b/src/arch/mips/MipsInterrupts.py
new file mode 100644
index 000000000..06cd54263
--- /dev/null
+++ b/src/arch/mips/MipsInterrupts.py
@@ -0,0 +1,33 @@
+# Copyright (c) 2008 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+from m5.SimObject import SimObject
+
+class MipsInterrupts(SimObject):
+ type = 'MipsInterrupts'
+ cxx_class = 'MipsISA::Interrupts'
diff --git a/src/arch/mips/MipsTLB.py b/src/arch/mips/MipsTLB.py
index ce8847365..41d46c572 100644
--- a/src/arch/mips/MipsTLB.py
+++ b/src/arch/mips/MipsTLB.py
@@ -32,28 +32,25 @@
from m5.SimObject import SimObject
from m5.params import *
-class MipsTLB(SimObject):
- abstract = True
+from BaseTLB import BaseTLB
+
+class MipsTLB(BaseTLB):
type = 'MipsTLB'
- cxx_namespace = 'MipsISA'
- cxx_class = 'TLB'
+ abstract = True
size = Param.Int("TLB size")
class MipsDTB(MipsTLB):
type = 'MipsDTB'
- cxx_namespace = 'MipsISA'
- cxx_class = 'DTB'
+ cxx_class = 'MipsISA::DTB'
size = 64
class MipsITB(MipsTLB):
type = 'MipsITB'
- cxx_namespace = 'MipsISA'
- cxx_class = 'ITB'
+ cxx_class = 'MipsISA::ITB'
size = 64
class MipsUTB(MipsTLB):
type = 'MipsUTB'
- cxx_namespace = 'MipsISA'
- cxx_class = 'UTB'
+ cxx_class = 'MipsISA::UTB'
size = 64
diff --git a/src/arch/mips/SConscript b/src/arch/mips/SConscript
index 8be445c99..0b470def6 100644
--- a/src/arch/mips/SConscript
+++ b/src/arch/mips/SConscript
@@ -48,6 +48,7 @@ if env['TARGET_ISA'] == 'mips':
if env['FULL_SYSTEM']:
SimObject('MipsSystem.py')
+ SimObject('MipsInterrupts.py')
Source('idle_event.cc')
Source('mips_core_specific.cc')
Source('vtophys.cc')
diff --git a/src/arch/mips/bare_iron/system.hh b/src/arch/mips/bare_iron/system.hh
index ab4e02344..e593f832c 100755
--- a/src/arch/mips/bare_iron/system.hh
+++ b/src/arch/mips/bare_iron/system.hh
@@ -39,8 +39,6 @@ class IdleStartEvent;
#include "arch/mips/system.hh"
#include "params/BareIronMipsSystem.hh"
-using namespace MipsISA;
-
/**
* This class contains linux specific system code (Loading, Events).
* It points to objects that are the system binaries to load and patches them
diff --git a/src/arch/mips/dsp.cc b/src/arch/mips/dsp.cc
index 8e2db3f0b..6e4f7afea 100755
--- a/src/arch/mips/dsp.cc
+++ b/src/arch/mips/dsp.cc
@@ -40,92 +40,84 @@ using namespace MipsISA;
using namespace std;
int32_t
-MipsISA::bitrev( int32_t value )
+MipsISA::bitrev(int32_t value)
{
int32_t result = 0;
- int i, shift;
+ int shift;
- for( i=0; i<16; i++ )
- {
- shift = 2*i - 15;
+ for (int i = 0; i < 16; i++) {
+ shift = 2 * i - 15;
- if( shift < 0 )
- result |= (value & 1L<<i) << -shift;
+ if (shift < 0)
+ result |= (value & 1 << i) << -shift;
else
- result |= (value & 1L<<i) >> shift;
+ result |= (value & 1 << i) >> shift;
}
return result;
}
uint64_t
-MipsISA::dspSaturate( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow )
+MipsISA::dspSaturate(uint64_t value, int32_t fmt, int32_t sign,
+ uint32_t *overflow)
{
- int64_t svalue;
+ int64_t svalue = (int64_t)value;
- svalue = (int64_t)value;
-
- switch( sign )
- {
+ switch (sign) {
case SIGNED:
- if( svalue > (int64_t)FIXED_SMAX[fmt] )
- {
+ if (svalue > (int64_t)FIXED_SMAX[fmt]) {
*overflow = 1;
svalue = (int64_t)FIXED_SMAX[fmt];
- }
- else if( svalue < (int64_t)FIXED_SMIN[fmt] )
- {
+ } else if (svalue < (int64_t)FIXED_SMIN[fmt]) {
*overflow = 1;
svalue = (int64_t)FIXED_SMIN[fmt];
}
break;
case UNSIGNED:
- if( svalue > (int64_t)FIXED_UMAX[fmt] )
- {
+ if (svalue > (int64_t)FIXED_UMAX[fmt]) {
*overflow = 1;
svalue = FIXED_UMAX[fmt];
- }
- else if( svalue < (int64_t)FIXED_UMIN[fmt] )
- {
+ } else if (svalue < (int64_t)FIXED_UMIN[fmt]) {
*overflow = 1;
svalue = FIXED_UMIN[fmt];
}
break;
}
- return( (uint64_t)svalue );
+ return (uint64_t)svalue;
}
uint64_t
-MipsISA::checkOverflow( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow )
+MipsISA::checkOverflow(uint64_t value, int32_t fmt, int32_t sign,
+ uint32_t *overflow)
{
- int64_t svalue;
-
- svalue = (int64_t)value;
+ int64_t svalue = (int64_t)value;
- switch( sign )
+ switch (sign)
{
case SIGNED:
- if( svalue > (int64_t)FIXED_SMAX[fmt] || svalue < (int64_t)FIXED_SMIN[fmt] )
+ if (svalue > (int64_t)FIXED_SMAX[fmt] ||
+ svalue < (int64_t)FIXED_SMIN[fmt])
*overflow = 1;
break;
case UNSIGNED:
- if( svalue > (int64_t)FIXED_UMAX[fmt] || svalue < (int64_t)FIXED_UMIN[fmt] )
+ if (svalue > (int64_t)FIXED_UMAX[fmt] ||
+ svalue < (int64_t)FIXED_UMIN[fmt])
*overflow = 1;
break;
}
- return( (uint64_t)svalue );
+ return (uint64_t)svalue;
}
uint64_t
-MipsISA::signExtend( uint64_t value, int32_t fmt )
+MipsISA::signExtend(uint64_t value, int32_t fmt)
{
int32_t signpos = SIMD_NBITS[fmt];
- uint64_t sign = uint64_t(1)<<(signpos-1);
+ uint64_t sign = uint64_t(1) << (signpos - 1);
uint64_t ones = ~(0ULL);
- if( value & sign )
+ if (value & sign)
value |= (ones << signpos); // extend with ones
else
value &= (ones >> (64 - signpos)); // extend with zeros
@@ -134,231 +126,230 @@ MipsISA::signExtend( uint64_t value, int32_t fmt )
}
uint64_t
-MipsISA::addHalfLsb( uint64_t value, int32_t lsbpos )
+MipsISA::addHalfLsb(uint64_t value, int32_t lsbpos)
{
- return( value += ULL(1) << (lsbpos-1) );
+ return value += ULL(1) << (lsbpos - 1);
}
int32_t
-MipsISA::dspAbs( int32_t a, int32_t fmt, uint32_t *dspctl )
+MipsISA::dspAbs(int32_t a, int32_t fmt, uint32_t *dspctl)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
int32_t result;
int64_t svalue;
uint32_t ouflag = 0;
uint64_t a_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, fmt, SIGNED );
+ simdUnpack(a, a_values, fmt, SIGNED);
- for( i=0; i<nvals; i++ )
- {
+ for (int i = 0; i < nvals; i++) {
svalue = (int64_t)a_values[i];
- if( a_values[i] == FIXED_SMIN[fmt] )
- {
+ if (a_values[i] == FIXED_SMIN[fmt]) {
a_values[i] = FIXED_SMAX[fmt];
ouflag = 1;
- }
- else if( svalue < 0 )
- {
- a_values[i] = uint64_t( 0 - svalue );
+ } else if (svalue < 0) {
+ a_values[i] = uint64_t(0 - svalue);
}
}
- simdPack( a_values, &result, fmt );
+ simdPack(a_values, &result, fmt);
- if( ouflag )
- writeDSPControl( dspctl, (ouflag<<4)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
+ if (ouflag)
+ writeDSPControl(dspctl, (ouflag << 4) << DSP_CTL_POS[DSP_OUFLAG],
+ 1 << DSP_OUFLAG);
- return( result );
+ return result;
}
int32_t
-MipsISA::dspAdd( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl )
+MipsISA::dspAdd(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
+ int32_t sign, uint32_t *dspctl)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
int32_t result;
uint32_t ouflag = 0;
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, fmt, sign );
- simdUnpack( b, b_values, fmt, sign );
+ simdUnpack(a, a_values, fmt, sign);
+ simdUnpack(b, b_values, fmt, sign);
- for( i=0; i<nvals; i++ )
+ for (int i = 0; i < nvals; i++)
{
- if( saturate )
- a_values[i] = dspSaturate( a_values[i] + b_values[i], fmt, sign, &ouflag );
+ if (saturate)
+ a_values[i] = dspSaturate(a_values[i] + b_values[i], fmt, sign,
+ &ouflag);
else
- a_values[i] = checkOverflow( a_values[i] + b_values[i], fmt, sign, &ouflag );
+ a_values[i] = checkOverflow(a_values[i] + b_values[i], fmt, sign,
+ &ouflag);
}
- simdPack( a_values, &result, fmt );
+ simdPack(a_values, &result, fmt);
- if( ouflag )
- writeDSPControl( dspctl, (ouflag<<4)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
+ if (ouflag)
+ writeDSPControl(dspctl, (ouflag << 4) << DSP_CTL_POS[DSP_OUFLAG],
+ 1 << DSP_OUFLAG);
- return( result );
+ return result;
}
int32_t
-MipsISA::dspAddh( int32_t a, int32_t b, int32_t fmt, int32_t round, int32_t sign )
+MipsISA::dspAddh(int32_t a, int32_t b, int32_t fmt, int32_t round,
+ int32_t sign)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
int32_t result;
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, fmt, sign );
- simdUnpack( b, b_values, fmt, sign );
+ simdUnpack(a, a_values, fmt, sign);
+ simdUnpack(b, b_values, fmt, sign);
- for( i=0; i<nvals; i++ )
- {
- if( round )
- a_values[i] = addHalfLsb( a_values[i] + b_values[i], 1 ) >> 1;
+ for (int i = 0; i < nvals; i++) {
+ if (round)
+ a_values[i] = addHalfLsb(a_values[i] + b_values[i], 1) >> 1;
else
- a_values[i] = ( a_values[i] + b_values[i] ) >> 1;
+ a_values[i] = (a_values[i] + b_values[i]) >> 1;
}
- simdPack( a_values, &result, fmt );
+ simdPack(a_values, &result, fmt);
- return( result );
+ return result;
}
int32_t
-MipsISA::dspSub( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl )
+MipsISA::dspSub(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
+ int32_t sign, uint32_t *dspctl)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
int32_t result;
uint32_t ouflag = 0;
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, fmt, sign );
- simdUnpack( b, b_values, fmt, sign );
+ simdUnpack(a, a_values, fmt, sign);
+ simdUnpack(b, b_values, fmt, sign);
- for( i=0; i<nvals; i++ )
- {
- if( saturate )
- a_values[i] = dspSaturate( a_values[i] - b_values[i], fmt, sign, &ouflag );
+ for (int i = 0; i < nvals; i++) {
+ if (saturate)
+ a_values[i] = dspSaturate(a_values[i] - b_values[i], fmt, sign,
+ &ouflag);
else
- a_values[i] = checkOverflow( a_values[i] - b_values[i], fmt, sign, &ouflag );
+ a_values[i] = checkOverflow(a_values[i] - b_values[i], fmt, sign,
+ &ouflag);
}
- simdPack( a_values, &result, fmt );
+ simdPack(a_values, &result, fmt);
- if( ouflag )
- writeDSPControl( dspctl, (ouflag<<4)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
+ if (ouflag)
+ writeDSPControl(dspctl, (ouflag << 4) << DSP_CTL_POS[DSP_OUFLAG],
+ 1 << DSP_OUFLAG);
- return( result );
+ return result;
}
int32_t
-MipsISA::dspSubh( int32_t a, int32_t b, int32_t fmt, int32_t round, int32_t sign )
+MipsISA::dspSubh(int32_t a, int32_t b, int32_t fmt, int32_t round,
+ int32_t sign)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
int32_t result;
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, fmt, sign );
- simdUnpack( b, b_values, fmt, sign );
+ simdUnpack(a, a_values, fmt, sign);
+ simdUnpack(b, b_values, fmt, sign);
- for( i=0; i<nvals; i++ )
+ for (int i = 0; i < nvals; i++)
{
- if( round )
- a_values[i] = addHalfLsb( a_values[i] - b_values[i], 1 ) >> 1;
+ if (round)
+ a_values[i] = addHalfLsb(a_values[i] - b_values[i], 1) >> 1;
else
- a_values[i] = ( a_values[i] - b_values[i] ) >> 1;
+ a_values[i] = (a_values[i] - b_values[i]) >> 1;
}
- simdPack( a_values, &result, fmt );
+ simdPack(a_values, &result, fmt);
- return( result );
+ return result;
}
int32_t
-MipsISA::dspShll( int32_t a, uint32_t sa, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl )
+MipsISA::dspShll(int32_t a, uint32_t sa, int32_t fmt, int32_t saturate,
+ int32_t sign, uint32_t *dspctl)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
int32_t result;
uint32_t ouflag = 0;
uint64_t a_values[SIMD_MAX_VALS];
- sa = bits( sa, SIMD_LOG2N[fmt]-1, 0 );
- simdUnpack( a, a_values, fmt, sign );
+ sa = bits(sa, SIMD_LOG2N[fmt] - 1, 0);
+ simdUnpack(a, a_values, fmt, sign);
- for( i=0; i<nvals; i++ )
+ for (int i = 0; i < nvals; i++)
{
- if( saturate )
- a_values[i] = dspSaturate( a_values[i] << sa, fmt, sign, &ouflag );
+ if (saturate)
+ a_values[i] = dspSaturate(a_values[i] << sa, fmt, sign, &ouflag);
else
- a_values[i] = checkOverflow( a_values[i] << sa, fmt, sign, &ouflag );
+ a_values[i] = checkOverflow(a_values[i] << sa, fmt, sign, &ouflag);
}
- simdPack( a_values, &result, fmt );
+ simdPack(a_values, &result, fmt);
- if( ouflag )
- writeDSPControl( dspctl, (ouflag<<6)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
+ if (ouflag)
+ writeDSPControl(dspctl, (ouflag << 6) << DSP_CTL_POS[DSP_OUFLAG],
+ 1 << DSP_OUFLAG);
- return( result );
+ return result;
}
int32_t
-MipsISA::dspShrl( int32_t a, uint32_t sa, int32_t fmt, int32_t sign )
+MipsISA::dspShrl(int32_t a, uint32_t sa, int32_t fmt, int32_t sign)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
int32_t result;
uint64_t a_values[SIMD_MAX_VALS];
- sa = bits( sa, SIMD_LOG2N[fmt]-1, 0 );
+ sa = bits(sa, SIMD_LOG2N[fmt] - 1, 0);
- simdUnpack( a, a_values, fmt, UNSIGNED );
+ simdUnpack(a, a_values, fmt, UNSIGNED);
- for( i=0; i<nvals; i++ )
+ for (int i = 0; i < nvals; i++)
a_values[i] = a_values[i] >> sa;
- simdPack( a_values, &result, fmt );
+ simdPack(a_values, &result, fmt);
- return( result );
+ return result;
}
int32_t
-MipsISA::dspShra( int32_t a, uint32_t sa, int32_t fmt, int32_t round, int32_t sign, uint32_t *dspctl )
+MipsISA::dspShra(int32_t a, uint32_t sa, int32_t fmt, int32_t round,
+ int32_t sign, uint32_t *dspctl)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
int32_t result;
uint64_t a_values[SIMD_MAX_VALS];
- sa = bits( sa, SIMD_LOG2N[fmt]-1, 0 );
+ sa = bits(sa, SIMD_LOG2N[fmt] - 1, 0);
- simdUnpack( a, a_values, fmt, SIGNED );
+ simdUnpack(a, a_values, fmt, SIGNED);
- for( i=0; i<nvals; i++ )
- {
- if( round )
- a_values[i] = addHalfLsb( a_values[i], sa ) >> sa;
+ for (int i = 0; i < nvals; i++) {
+ if (round)
+ a_values[i] = addHalfLsb(a_values[i], sa) >> sa;
else
a_values[i] = a_values[i] >> sa;
}
- simdPack( a_values, &result, fmt );
+ simdPack(a_values, &result, fmt);
- return( result );
+ return result;
}
int32_t
-MipsISA::dspMulq( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t round, uint32_t *dspctl )
+MipsISA::dspMulq(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
+ int32_t round, uint32_t *dspctl)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
int sa = SIMD_NBITS[fmt];
int32_t result;
@@ -367,102 +358,104 @@ MipsISA::dspMulq( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t r
uint64_t b_values[SIMD_MAX_VALS];
int64_t temp;
- simdUnpack( a, a_values, fmt, SIGNED );
- simdUnpack( b, b_values, fmt, SIGNED );
+ simdUnpack(a, a_values, fmt, SIGNED);
+ simdUnpack(b, b_values, fmt, SIGNED);
- for( i=0; i<nvals; i++ )
- {
- if( round )
- temp = (int64_t)addHalfLsb( a_values[i] * b_values[i] << 1, sa ) >> sa;
+ for (int i = 0; i < nvals; i++) {
+ if (round)
+ temp =
+ (int64_t)addHalfLsb(a_values[i] * b_values[i] << 1, sa) >> sa;
else
temp = (int64_t)(a_values[i] * b_values[i]) >> (sa - 1);
- if( a_values[i] == FIXED_SMIN[fmt] &&
- b_values[i] == FIXED_SMIN[fmt] )
- {
+ if (a_values[i] == FIXED_SMIN[fmt] && b_values[i] == FIXED_SMIN[fmt]) {
ouflag = 1;
- if( saturate )
+ if (saturate)
temp = FIXED_SMAX[fmt];
}
a_values[i] = temp;
}
- simdPack( a_values, &result, fmt );
+ simdPack(a_values, &result, fmt);
- if( ouflag )
- writeDSPControl( dspctl, (ouflag<<5)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
+ if (ouflag)
+ writeDSPControl(dspctl, (ouflag << 5) << DSP_CTL_POS[DSP_OUFLAG],
+ 1 << DSP_OUFLAG);
- return( result );
+ return result;
}
int32_t
-MipsISA::dspMul( int32_t a, int32_t b, int32_t fmt, int32_t saturate, uint32_t *dspctl )
+MipsISA::dspMul(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
+ uint32_t *dspctl)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
int32_t result;
uint32_t ouflag = 0;
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, fmt, SIGNED );
- simdUnpack( b, b_values, fmt, SIGNED );
+ simdUnpack(a, a_values, fmt, SIGNED);
+ simdUnpack(b, b_values, fmt, SIGNED);
- for( i=0; i<nvals; i++ )
+ for (int i = 0; i < nvals; i++)
{
- if( saturate )
- a_values[i] = dspSaturate( a_values[i] * b_values[i], fmt, SIGNED, &ouflag );
+ if (saturate)
+ a_values[i] = dspSaturate(a_values[i] * b_values[i], fmt, SIGNED,
+ &ouflag);
else
- a_values[i] = checkOverflow( a_values[i] * b_values[i], fmt, SIGNED, &ouflag );
+ a_values[i] = checkOverflow(a_values[i] * b_values[i], fmt, SIGNED,
+ &ouflag);
}
- simdPack( a_values, &result, fmt );
+ simdPack(a_values, &result, fmt);
- if( ouflag )
- writeDSPControl( dspctl, (ouflag<<5)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
+ if (ouflag)
+ writeDSPControl(dspctl, (ouflag << 5) << DSP_CTL_POS[DSP_OUFLAG],
+ 1 << DSP_OUFLAG);
- return( result );
+ return result;
}
int32_t
-MipsISA::dspMuleu( int32_t a, int32_t b, int32_t mode, uint32_t *dspctl )
+MipsISA::dspMuleu(int32_t a, int32_t b, int32_t mode, uint32_t *dspctl)
{
- int i = 0;
int nvals = SIMD_NVALS[SIMD_FMT_PH];
int32_t result;
uint32_t ouflag = 0;
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, SIMD_FMT_QB, UNSIGNED );
- simdUnpack( b, b_values, SIMD_FMT_PH, UNSIGNED );
+ simdUnpack(a, a_values, SIMD_FMT_QB, UNSIGNED);
+ simdUnpack(b, b_values, SIMD_FMT_PH, UNSIGNED);
- switch( mode )
- {
+ switch (mode) {
case MODE_L:
- for( i=0; i<nvals; i++ )
- b_values[i] = dspSaturate( a_values[i+2] * b_values[i], SIMD_FMT_PH, UNSIGNED, &ouflag );
+ for (int i = 0; i < nvals; i++)
+ b_values[i] = dspSaturate(a_values[i + 2] * b_values[i],
+ SIMD_FMT_PH, UNSIGNED, &ouflag);
break;
case MODE_R:
- for( i=0; i<nvals; i++ )
- b_values[i] = dspSaturate( a_values[i] * b_values[i], SIMD_FMT_PH, UNSIGNED, &ouflag );
+ for (int i = 0; i < nvals; i++)
+ b_values[i] = dspSaturate(a_values[i] * b_values[i], SIMD_FMT_PH,
+ UNSIGNED, &ouflag);
break;
}
- simdPack( b_values, &result, SIMD_FMT_PH );
+ simdPack(b_values, &result, SIMD_FMT_PH);
- if( ouflag )
- writeDSPControl( dspctl, (ouflag<<5)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
+ if (ouflag)
+ writeDSPControl(dspctl, (ouflag << 5) << DSP_CTL_POS[DSP_OUFLAG],
+ 1 << DSP_OUFLAG);
- return( result );
+ return result;
}
int32_t
-MipsISA::dspMuleq( int32_t a, int32_t b, int32_t mode, uint32_t *dspctl )
+MipsISA::dspMuleq(int32_t a, int32_t b, int32_t mode, uint32_t *dspctl)
{
- int i = 0;
int nvals = SIMD_NVALS[SIMD_FMT_W];
int32_t result;
uint32_t ouflag = 0;
@@ -470,36 +463,36 @@ MipsISA::dspMuleq( int32_t a, int32_t b, int32_t mode, uint32_t *dspctl )
uint64_t b_values[SIMD_MAX_VALS];
uint64_t c_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, SIMD_FMT_PH, SIGNED );
- simdUnpack( b, b_values, SIMD_FMT_PH, SIGNED );
+ simdUnpack(a, a_values, SIMD_FMT_PH, SIGNED);
+ simdUnpack(b, b_values, SIMD_FMT_PH, SIGNED);
- switch( mode )
- {
+ switch (mode) {
case MODE_L:
- for( i=0; i<nvals; i++ )
- c_values[i] = dspSaturate( a_values[i+1] * b_values[i+1] << 1,
- SIMD_FMT_W, SIGNED, &ouflag );
+ for (int i = 0; i < nvals; i++)
+ c_values[i] = dspSaturate(a_values[i + 1] * b_values[i + 1] << 1,
+ SIMD_FMT_W, SIGNED, &ouflag);
break;
case MODE_R:
- for( i=0; i<nvals; i++ )
- c_values[i] = dspSaturate( a_values[i] * b_values[i] << 1,
- SIMD_FMT_W, SIGNED, &ouflag );
+ for (int i = 0; i < nvals; i++)
+ c_values[i] = dspSaturate(a_values[i] * b_values[i] << 1,
+ SIMD_FMT_W, SIGNED, &ouflag);
break;
}
- simdPack( c_values, &result, SIMD_FMT_W );
+ simdPack(c_values, &result, SIMD_FMT_W);
- if( ouflag )
- writeDSPControl( dspctl, (ouflag<<5)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
+ if (ouflag)
+ writeDSPControl(dspctl, (ouflag << 5) << DSP_CTL_POS[DSP_OUFLAG],
+ 1 << DSP_OUFLAG);
- return( result );
+ return result;
}
int64_t
-MipsISA::dspDpaq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t infmt,
- int32_t outfmt, int32_t postsat, int32_t mode, uint32_t *dspctl )
+MipsISA::dspDpaq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
+ int32_t infmt, int32_t outfmt, int32_t postsat, int32_t mode,
+ uint32_t *dspctl)
{
- int i = 0;
int nvals = SIMD_NVALS[infmt];
int64_t result = 0;
int64_t temp = 0;
@@ -507,74 +500,66 @@ MipsISA::dspDpaq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t infmt
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, infmt, SIGNED );
- simdUnpack( b, b_values, infmt, SIGNED );
+ simdUnpack(a, a_values, infmt, SIGNED);
+ simdUnpack(b, b_values, infmt, SIGNED);
- for( i=0; i<nvals; i++ )
- {
- switch( mode )
- {
+ for (int i = 0; i < nvals; i++) {
+ switch (mode) {
case MODE_X:
- if( a_values[nvals-1-i] == FIXED_SMIN[infmt] &&
- b_values[i] == FIXED_SMIN[infmt] )
- {
+ if (a_values[nvals - 1 - i] == FIXED_SMIN[infmt] &&
+ b_values[i] == FIXED_SMIN[infmt]) {
result += FIXED_SMAX[outfmt];
ouflag = 1;
}
else
- result += a_values[nvals-1-i] * b_values[i] << 1;
+ result += a_values[nvals - 1 - i] * b_values[i] << 1;
break;
default:
- if( a_values[i] == FIXED_SMIN[infmt] &&
- b_values[i] == FIXED_SMIN[infmt] )
- {
+ if (a_values[i] == FIXED_SMIN[infmt] &&
+ b_values[i] == FIXED_SMIN[infmt]) {
result += FIXED_SMAX[outfmt];
ouflag = 1;
- }
- else
+ } else {
result += a_values[i] * b_values[i] << 1;
+ }
break;
}
}
- if( postsat )
- {
- if( outfmt == SIMD_FMT_L )
- {
- int signa = bits( dspac, 63, 63 );
- int signb = bits( result, 63, 63 );
+ if (postsat) {
+ if (outfmt == SIMD_FMT_L) {
+ int signa = bits(dspac, 63, 63);
+ int signb = bits(result, 63, 63);
temp = dspac + result;
- if( ( signa == signb ) &&
- ( bits( temp, 63, 63 ) != signa ) )
- {
+ if (signa == signb && bits(temp, 63, 63) != signa) {
ouflag = 1;
- if( signa )
+ if (signa)
dspac = FIXED_SMIN[outfmt];
else
dspac = FIXED_SMAX[outfmt];
- }
- else
+ } else {
dspac = temp;
+ }
+ } else {
+ dspac = dspSaturate(dspac + result, outfmt, SIGNED, &ouflag);
}
- else
- dspac = dspSaturate( dspac + result, outfmt, SIGNED, &ouflag );
- }
- else
+ } else {
dspac += result;
+ }
- if( ouflag )
- *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 );
+ if (ouflag)
+ *dspctl = insertBits(*dspctl, 16 + ac, 16 + ac, 1);
- return( dspac );
+ return dspac;
}
int64_t
-MipsISA::dspDpsq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t infmt,
- int32_t outfmt, int32_t postsat, int32_t mode, uint32_t *dspctl )
+MipsISA::dspDpsq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
+ int32_t infmt, int32_t outfmt, int32_t postsat, int32_t mode,
+ uint32_t *dspctl)
{
- int i = 0;
int nvals = SIMD_NVALS[infmt];
int64_t result = 0;
int64_t temp = 0;
@@ -582,93 +567,82 @@ MipsISA::dspDpsq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t infmt
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, infmt, SIGNED );
- simdUnpack( b, b_values, infmt, SIGNED );
+ simdUnpack(a, a_values, infmt, SIGNED);
+ simdUnpack(b, b_values, infmt, SIGNED);
- for( i=0; i<nvals; i++ )
- {
- switch( mode )
- {
+ for (int i = 0; i < nvals; i++) {
+ switch (mode) {
case MODE_X:
- if( a_values[nvals-1-i] == FIXED_SMIN[infmt] &&
- b_values[i] == FIXED_SMIN[infmt] )
- {
+ if (a_values[nvals - 1 - i] == FIXED_SMIN[infmt] &&
+ b_values[i] == FIXED_SMIN[infmt]) {
result += FIXED_SMAX[outfmt];
ouflag = 1;
+ } else {
+ result += a_values[nvals - 1 - i] * b_values[i] << 1;
}
- else
- result += a_values[nvals-1-i] * b_values[i] << 1;
break;
default:
- if( a_values[i] == FIXED_SMIN[infmt] &&
- b_values[i] == FIXED_SMIN[infmt] )
- {
+ if (a_values[i] == FIXED_SMIN[infmt] &&
+ b_values[i] == FIXED_SMIN[infmt]) {
result += FIXED_SMAX[outfmt];
ouflag = 1;
- }
- else
+ } else {
result += a_values[i] * b_values[i] << 1;
+ }
break;
}
}
- if( postsat )
- {
- if( outfmt == SIMD_FMT_L )
- {
- int signa = bits( dspac, 63, 63 );
- int signb = bits( -result, 63, 63 );
+ if (postsat) {
+ if (outfmt == SIMD_FMT_L) {
+ int signa = bits(dspac, 63, 63);
+ int signb = bits(-result, 63, 63);
temp = dspac - result;
- if( ( signa == signb ) &&
- ( bits( temp, 63, 63 ) != signa ) )
- {
+ if (signa == signb && bits(temp, 63, 63) != signa) {
ouflag = 1;
- if( signa )
+ if (signa)
dspac = FIXED_SMIN[outfmt];
else
dspac = FIXED_SMAX[outfmt];
- }
- else
+ } else {
dspac = temp;
+ }
+ } else {
+ dspac = dspSaturate(dspac - result, outfmt, SIGNED, &ouflag);
}
- else
- dspac = dspSaturate( dspac - result, outfmt, SIGNED, &ouflag );
- }
- else
+ } else {
dspac -= result;
+ }
- if( ouflag )
- *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 );
+ if (ouflag)
+ *dspctl = insertBits(*dspctl, 16 + ac, 16 + ac, 1);
- return( dspac );
+ return dspac;
}
int64_t
-MipsISA::dspDpa( int64_t dspac, int32_t a, int32_t b, int32_t ac,
- int32_t fmt, int32_t sign, int32_t mode )
+MipsISA::dspDpa(int64_t dspac, int32_t a, int32_t b, int32_t ac,
+ int32_t fmt, int32_t sign, int32_t mode)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, fmt, sign );
- simdUnpack( b, b_values, fmt, sign );
+ simdUnpack(a, a_values, fmt, sign);
+ simdUnpack(b, b_values, fmt, sign);
- for( i=0; i<2; i++ )
- {
- switch( mode )
- {
+ for (int i = 0; i < 2; i++) {
+ switch (mode) {
case MODE_L:
- dspac += a_values[nvals-1-i] * b_values[nvals-1-i];
+ dspac += a_values[nvals - 1 - i] * b_values[nvals - 1 - i];
break;
case MODE_R:
- dspac += a_values[nvals-3-i] * b_values[nvals-3-i];
+ dspac += a_values[nvals - 3 - i] * b_values[nvals - 3 - i];
break;
case MODE_X:
- dspac += a_values[nvals-1-i] * b_values[i];
+ dspac += a_values[nvals - 1 - i] * b_values[i];
break;
}
}
@@ -677,29 +651,26 @@ MipsISA::dspDpa( int64_t dspac, int32_t a, int32_t b, int32_t ac,
}
int64_t
-MipsISA::dspDps( int64_t dspac, int32_t a, int32_t b, int32_t ac,
- int32_t fmt, int32_t sign, int32_t mode )
+MipsISA::dspDps(int64_t dspac, int32_t a, int32_t b, int32_t ac,
+ int32_t fmt, int32_t sign, int32_t mode)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, fmt, sign );
- simdUnpack( b, b_values, fmt, sign );
+ simdUnpack(a, a_values, fmt, sign);
+ simdUnpack(b, b_values, fmt, sign);
- for( i=0; i<2; i++ )
- {
- switch( mode )
- {
+ for (int i = 0; i < 2; i++) {
+ switch (mode) {
case MODE_L:
- dspac -= a_values[nvals-1-i] * b_values[nvals-1-i];
+ dspac -= a_values[nvals - 1 - i] * b_values[nvals - 1 - i];
break;
case MODE_R:
- dspac -= a_values[nvals-3-i] * b_values[nvals-3-i];
+ dspac -= a_values[nvals - 3 - i] * b_values[nvals - 3 - i];
break;
case MODE_X:
- dspac -= a_values[nvals-1-i] * b_values[i];
+ dspac -= a_values[nvals - 1 - i] * b_values[i];
break;
}
}
@@ -708,36 +679,33 @@ MipsISA::dspDps( int64_t dspac, int32_t a, int32_t b, int32_t ac,
}
int64_t
-MipsISA::dspMaq( int64_t dspac, int32_t a, int32_t b, int32_t ac,
- int32_t fmt, int32_t mode, int32_t saturate, uint32_t *dspctl )
+MipsISA::dspMaq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
+ int32_t fmt, int32_t mode, int32_t saturate, uint32_t *dspctl)
{
- int i = 0;
- int nvals = SIMD_NVALS[fmt-1];
+ int nvals = SIMD_NVALS[fmt - 1];
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
int64_t temp = 0;
uint32_t ouflag = 0;
- simdUnpack( a, a_values, fmt, SIGNED );
- simdUnpack( b, b_values, fmt, SIGNED );
+ simdUnpack(a, a_values, fmt, SIGNED);
+ simdUnpack(b, b_values, fmt, SIGNED);
- for( i=0; i<nvals; i++ )
- {
- switch( mode )
- {
+ for (int i = 0; i < nvals; i++) {
+ switch (mode) {
case MODE_L:
- temp = a_values[i+1] * b_values[i+1] << 1;
- if( a_values[i+1] == FIXED_SMIN[fmt] && b_values[i+1] == FIXED_SMIN[fmt] )
- {
- temp = (int64_t)FIXED_SMAX[fmt-1];
+ temp = a_values[i + 1] * b_values[i + 1] << 1;
+ if (a_values[i + 1] == FIXED_SMIN[fmt] &&
+ b_values[i + 1] == FIXED_SMIN[fmt]) {
+ temp = (int64_t)FIXED_SMAX[fmt - 1];
ouflag = 1;
}
break;
case MODE_R:
temp = a_values[i] * b_values[i] << 1;
- if( a_values[i] == FIXED_SMIN[fmt] && b_values[i] == FIXED_SMIN[fmt] )
- {
- temp = (int64_t)FIXED_SMAX[fmt-1];
+ if (a_values[i] == FIXED_SMIN[fmt] &&
+ b_values[i] == FIXED_SMIN[fmt]) {
+ temp = (int64_t)FIXED_SMAX[fmt - 1];
ouflag = 1;
}
break;
@@ -745,23 +713,23 @@ MipsISA::dspMaq( int64_t dspac, int32_t a, int32_t b, int32_t ac,
temp += dspac;
- if( saturate )
- temp = dspSaturate( temp, fmt-1, SIGNED, &ouflag );
- if( ouflag )
- *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 );
+ if (saturate)
+ temp = dspSaturate(temp, fmt - 1, SIGNED, &ouflag);
+ if (ouflag)
+ *dspctl = insertBits(*dspctl, 16 + ac, 16 + ac, 1);
}
return temp;
}
int64_t
-MipsISA::dspMulsa( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt )
+MipsISA::dspMulsa(int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt)
{
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, fmt, SIGNED );
- simdUnpack( b, b_values, fmt, SIGNED );
+ simdUnpack(a, a_values, fmt, SIGNED);
+ simdUnpack(b, b_values, fmt, SIGNED);
dspac += a_values[1] * b_values[1] - a_values[0] * b_values[0];
@@ -769,132 +737,140 @@ MipsISA::dspMulsa( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt
}
int64_t
-MipsISA::dspMulsaq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt, uint32_t *dspctl )
+MipsISA::dspMulsaq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
+ int32_t fmt, uint32_t *dspctl)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
int64_t temp[2];
uint32_t ouflag = 0;
- simdUnpack( a, a_values, fmt, SIGNED );
- simdUnpack( b, b_values, fmt, SIGNED );
+ simdUnpack(a, a_values, fmt, SIGNED);
+ simdUnpack(b, b_values, fmt, SIGNED);
- for( i=nvals-1; i>-1; i-- )
- {
+ for (int i = nvals - 1; i > -1; i--) {
temp[i] = a_values[i] * b_values[i] << 1;
- if( a_values[i] == FIXED_SMIN[fmt] &&
- b_values[i] == FIXED_SMIN[fmt] )
- {
- temp[i] = FIXED_SMAX[fmt-1];
+ if (a_values[i] == FIXED_SMIN[fmt] && b_values[i] == FIXED_SMIN[fmt]) {
+ temp[i] = FIXED_SMAX[fmt - 1];
ouflag = 1;
}
}
dspac += temp[1] - temp[0];
- if( ouflag )
- *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 );
+ if (ouflag)
+ *dspctl = insertBits(*dspctl, 16 + ac, 16 + ac, 1);
return dspac;
}
void
-MipsISA::dspCmp( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, uint32_t *dspctl )
+MipsISA::dspCmp(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op,
+ uint32_t *dspctl)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
int ccond = 0;
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, fmt, sign );
- simdUnpack( b, b_values, fmt, sign );
+ simdUnpack(a, a_values, fmt, sign);
+ simdUnpack(b, b_values, fmt, sign);
- for( i=0; i<nvals; i++ )
- {
+ for (int i = 0; i < nvals; i++) {
int cc = 0;
- switch( op )
- {
- case CMP_EQ: cc = ( a_values[i] == b_values[i] ); break;
- case CMP_LT: cc = ( a_values[i] < b_values[i] ); break;
- case CMP_LE: cc = ( a_values[i] <= b_values[i] ); break;
+ switch (op) {
+ case CMP_EQ:
+ cc = (a_values[i] == b_values[i]);
+ break;
+ case CMP_LT:
+ cc = (a_values[i] < b_values[i]);
+ break;
+ case CMP_LE:
+ cc = (a_values[i] <= b_values[i]);
+ break;
}
- ccond |= cc << ( DSP_CTL_POS[DSP_CCOND] + i );
+ ccond |= cc << (DSP_CTL_POS[DSP_CCOND] + i);
}
- writeDSPControl( dspctl, ccond, 1<<DSP_CCOND );
+ writeDSPControl(dspctl, ccond, 1 << DSP_CCOND);
}
int32_t
-MipsISA::dspCmpg( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op )
+MipsISA::dspCmpg(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
int32_t result = 0;
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, fmt, sign );
- simdUnpack( b, b_values, fmt, sign );
+ simdUnpack(a, a_values, fmt, sign);
+ simdUnpack(b, b_values, fmt, sign);
- for( i=0; i<nvals; i++ )
- {
+ for (int i = 0; i < nvals; i++) {
int cc = 0;
- switch( op )
- {
- case CMP_EQ: cc = ( a_values[i] == b_values[i] ); break;
- case CMP_LT: cc = ( a_values[i] < b_values[i] ); break;
- case CMP_LE: cc = ( a_values[i] <= b_values[i] ); break;
+ switch (op) {
+ case CMP_EQ:
+ cc = (a_values[i] == b_values[i]);
+ break;
+ case CMP_LT:
+ cc = (a_values[i] < b_values[i]);
+ break;
+ case CMP_LE:
+ cc = (a_values[i] <= b_values[i]);
+ break;
}
result |= cc << i;
}
- return( result );
+ return result;
}
int32_t
-MipsISA::dspCmpgd( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, uint32_t *dspctl )
+MipsISA::dspCmpgd(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op,
+ uint32_t *dspctl)
{
- int i = 0;;
int nvals = SIMD_NVALS[fmt];
int32_t result = 0;
int ccond = 0;
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, fmt, sign );
- simdUnpack( b, b_values, fmt, sign );
+ simdUnpack(a, a_values, fmt, sign);
+ simdUnpack(b, b_values, fmt, sign);
- for( i=0; i<nvals; i++ )
- {
- int cc = 0;;
+ for (int i = 0; i < nvals; i++) {
+ int cc = 0;
- switch( op )
- {
- case CMP_EQ: cc = ( a_values[i] == b_values[i] ); break;
- case CMP_LT: cc = ( a_values[i] < b_values[i] ); break;
- case CMP_LE: cc = ( a_values[i] <= b_values[i] ); break;
+ switch (op) {
+ case CMP_EQ:
+ cc = (a_values[i] == b_values[i]);
+ break;
+ case CMP_LT:
+ cc = (a_values[i] < b_values[i]);
+ break;
+ case CMP_LE:
+ cc = (a_values[i] <= b_values[i]);
+ break;
}
result |= cc << i;
- ccond |= cc << ( DSP_CTL_POS[DSP_CCOND] + i );
+ ccond |= cc << (DSP_CTL_POS[DSP_CCOND] + i);
}
- writeDSPControl( dspctl, ccond, 1<<DSP_CCOND );
+ writeDSPControl(dspctl, ccond, 1 << DSP_CCOND);
- return( result );
+ return result;
}
int32_t
-MipsISA::dspPrece( int32_t a, int32_t infmt, int32_t insign, int32_t outfmt, int32_t outsign, int32_t mode )
+MipsISA::dspPrece(int32_t a, int32_t infmt, int32_t insign, int32_t outfmt,
+ int32_t outsign, int32_t mode)
{
- int i = 0;
int sa = 0;
int ninvals = SIMD_NVALS[infmt];
int noutvals = SIMD_NVALS[outfmt];
@@ -902,62 +878,68 @@ MipsISA::dspPrece( int32_t a, int32_t infmt, int32_t insign, int32_t outfmt, int
uint64_t in_values[SIMD_MAX_VALS];
uint64_t out_values[SIMD_MAX_VALS];
- if( insign == SIGNED && outsign == SIGNED )
+ if (insign == SIGNED && outsign == SIGNED)
sa = SIMD_NBITS[infmt];
- else if( insign == UNSIGNED && outsign == SIGNED )
+ else if (insign == UNSIGNED && outsign == SIGNED)
sa = SIMD_NBITS[infmt] - 1;
- else if( insign == UNSIGNED && outsign == UNSIGNED )
+ else if (insign == UNSIGNED && outsign == UNSIGNED)
sa = 0;
- simdUnpack( a, in_values, infmt, insign );
+ simdUnpack(a, in_values, infmt, insign);
- for( i=0; i<noutvals; i++ )
- {
- switch( mode )
- {
- case MODE_L: out_values[i] = in_values[i+(ninvals>>1)] << sa; break;
- case MODE_R: out_values[i] = in_values[i] << sa; break;
- case MODE_LA: out_values[i] = in_values[(i<<1)+1] << sa; break;
- case MODE_RA: out_values[i] = in_values[i<<1] << sa; break;
+ for (int i = 0; i<noutvals; i++) {
+ switch (mode) {
+ case MODE_L:
+ out_values[i] = in_values[i + (ninvals >> 1)] << sa;
+ break;
+ case MODE_R:
+ out_values[i] = in_values[i] << sa;
+ break;
+ case MODE_LA:
+ out_values[i] = in_values[(i << 1) + 1] << sa;
+ break;
+ case MODE_RA:
+ out_values[i] = in_values[i << 1] << sa;
+ break;
}
}
- simdPack( out_values, &result, outfmt );
+ simdPack(out_values, &result, outfmt);
- return( result );
+ return result;
}
int32_t
-MipsISA::dspPrecrqu( int32_t a, int32_t b, uint32_t *dspctl )
+MipsISA::dspPrecrqu(int32_t a, int32_t b, uint32_t *dspctl)
{
- int i = 0;
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
uint64_t r_values[SIMD_MAX_VALS];
uint32_t ouflag = 0;
int32_t result = 0;
- simdUnpack( a, a_values, SIMD_FMT_PH, SIGNED );
- simdUnpack( b, b_values, SIMD_FMT_PH, SIGNED );
+ simdUnpack(a, a_values, SIMD_FMT_PH, SIGNED);
+ simdUnpack(b, b_values, SIMD_FMT_PH, SIGNED);
- for( i=0; i<2; i++ )
- {
- r_values[i] = dspSaturate( (int64_t)b_values[i] >> SIMD_NBITS[SIMD_FMT_QB] - 1,
- SIMD_FMT_QB, UNSIGNED, &ouflag );
- r_values[i+2] = dspSaturate( (int64_t)a_values[i] >> SIMD_NBITS[SIMD_FMT_QB] - 1,
- SIMD_FMT_QB, UNSIGNED, &ouflag );
+ for (int i = 0; i<2; i++) {
+ r_values[i] =
+ dspSaturate((int64_t)b_values[i] >> (SIMD_NBITS[SIMD_FMT_QB] - 1),
+ SIMD_FMT_QB, UNSIGNED, &ouflag);
+ r_values[i + 2] =
+ dspSaturate((int64_t)a_values[i] >> (SIMD_NBITS[SIMD_FMT_QB] - 1),
+ SIMD_FMT_QB, UNSIGNED, &ouflag);
}
- simdPack( r_values, &result, SIMD_FMT_QB );
+ simdPack(r_values, &result, SIMD_FMT_QB);
- if( ouflag )
- *dspctl = insertBits( *dspctl, 22, 22, 1 );
+ if (ouflag)
+ *dspctl = insertBits(*dspctl, 22, 22, 1);
return result;
}
int32_t
-MipsISA::dspPrecrq( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl )
+MipsISA::dspPrecrq(int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl)
{
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
@@ -965,245 +947,226 @@ MipsISA::dspPrecrq( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl )
uint32_t ouflag = 0;
int32_t result;
- simdUnpack( a, a_values, fmt, SIGNED );
- simdUnpack( b, b_values, fmt, SIGNED );
+ simdUnpack(a, a_values, fmt, SIGNED);
+ simdUnpack(b, b_values, fmt, SIGNED);
- r_values[1] = dspSaturate( (int64_t)addHalfLsb( a_values[0], 16 ) >> 16,
- fmt+1, SIGNED, &ouflag );
- r_values[0] = dspSaturate( (int64_t)addHalfLsb( b_values[0], 16 ) >> 16,
- fmt+1, SIGNED, &ouflag );
+ r_values[1] = dspSaturate((int64_t)addHalfLsb(a_values[0], 16) >> 16,
+ fmt + 1, SIGNED, &ouflag);
+ r_values[0] = dspSaturate((int64_t)addHalfLsb(b_values[0], 16) >> 16,
+ fmt + 1, SIGNED, &ouflag);
- simdPack( r_values, &result, fmt+1 );
+ simdPack(r_values, &result, fmt + 1);
- if( ouflag )
- *dspctl = insertBits( *dspctl, 22, 22, 1 );
+ if (ouflag)
+ *dspctl = insertBits(*dspctl, 22, 22, 1);
return result;
}
int32_t
-MipsISA::dspPrecrSra( int32_t a, int32_t b, int32_t sa, int32_t fmt, int32_t round )
+MipsISA::dspPrecrSra(int32_t a, int32_t b, int32_t sa, int32_t fmt,
+ int32_t round)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
uint64_t c_values[SIMD_MAX_VALS];
int32_t result = 0;
- simdUnpack( a, a_values, fmt, SIGNED );
- simdUnpack( b, b_values, fmt, SIGNED );
+ simdUnpack(a, a_values, fmt, SIGNED);
+ simdUnpack(b, b_values, fmt, SIGNED);
- for( i=0; i<nvals; i++ )
- {
- if( round )
- {
- c_values[i] = addHalfLsb( b_values[i], sa ) >> sa;
- c_values[i+1] = addHalfLsb( a_values[i], sa ) >> sa;
- }
- else
- {
+ for (int i = 0; i < nvals; i++) {
+ if (round) {
+ c_values[i] = addHalfLsb(b_values[i], sa) >> sa;
+ c_values[i + 1] = addHalfLsb(a_values[i], sa) >> sa;
+ } else {
c_values[i] = b_values[i] >> sa;
- c_values[i+1] = a_values[i] >> sa;
+ c_values[i + 1] = a_values[i] >> sa;
}
}
- simdPack( c_values, &result, fmt+1 );
+ simdPack(c_values, &result, fmt + 1);
return result;
}
int32_t
-MipsISA::dspPick( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl )
+MipsISA::dspPick(int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
int32_t result;
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
uint64_t c_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, fmt, UNSIGNED );
- simdUnpack( b, b_values, fmt, UNSIGNED );
+ simdUnpack(a, a_values, fmt, UNSIGNED);
+ simdUnpack(b, b_values, fmt, UNSIGNED);
- for( i=0; i<nvals; i++ )
- {
+ for (int i = 0; i < nvals; i++) {
int condbit = DSP_CTL_POS[DSP_CCOND] + i;
- if( bits( *dspctl, condbit, condbit ) == 1 )
+ if (bits(*dspctl, condbit, condbit) == 1)
c_values[i] = a_values[i];
else
c_values[i] = b_values[i];
}
- simdPack( c_values, &result, fmt );
+ simdPack(c_values, &result, fmt);
- return( result );
+ return result;
}
int32_t
-MipsISA::dspPack( int32_t a, int32_t b, int32_t fmt )
+MipsISA::dspPack(int32_t a, int32_t b, int32_t fmt)
{
int32_t result;
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
uint64_t c_values[SIMD_MAX_VALS];
- simdUnpack( a, a_values, fmt, UNSIGNED );
- simdUnpack( b, b_values, fmt, UNSIGNED );
+ simdUnpack(a, a_values, fmt, UNSIGNED);
+ simdUnpack(b, b_values, fmt, UNSIGNED);
c_values[0] = b_values[1];
c_values[1] = a_values[0];
- simdPack( c_values, &result, fmt );
+ simdPack(c_values, &result, fmt);
- return( result );
+ return result;
}
int32_t
-MipsISA::dspExtr( int64_t dspac, int32_t fmt, int32_t sa, int32_t round, int32_t saturate, uint32_t *dspctl )
+MipsISA::dspExtr(int64_t dspac, int32_t fmt, int32_t sa, int32_t round,
+ int32_t saturate, uint32_t *dspctl)
{
int32_t result = 0;
uint32_t ouflag = 0;
int64_t temp = 0;
- sa = bits( sa, 4, 0 );
+ sa = bits(sa, 4, 0);
- if( sa > 0 )
- {
- if( round )
- {
- temp = (int64_t)addHalfLsb( dspac, sa );
+ if (sa > 0) {
+ if (round) {
+ temp = (int64_t)addHalfLsb(dspac, sa);
- if( dspac > 0 && temp < 0 )
- {
+ if (dspac > 0 && temp < 0) {
ouflag = 1;
- if( saturate )
+ if (saturate)
temp = FIXED_SMAX[SIMD_FMT_L];
}
temp = temp >> sa;
- }
- else
+ } else {
temp = dspac >> sa;
- }
- else
+ }
+ } else {
temp = dspac;
+ }
- dspac = checkOverflow( dspac, fmt, SIGNED, &ouflag );
+ dspac = checkOverflow(dspac, fmt, SIGNED, &ouflag);
- if( ouflag )
- {
- *dspctl = insertBits( *dspctl, 23, 23, ouflag );
+ if (ouflag) {
+ *dspctl = insertBits(*dspctl, 23, 23, ouflag);
- if( saturate )
- result = (int32_t)dspSaturate( temp, fmt, SIGNED, &ouflag );
+ if (saturate)
+ result = (int32_t)dspSaturate(temp, fmt, SIGNED, &ouflag);
else
result = (int32_t)temp;
- }
- else
+ } else {
result = (int32_t)temp;
+ }
- return( result );
+ return result;
}
int32_t
-MipsISA::dspExtp( int64_t dspac, int32_t size, uint32_t *dspctl )
+MipsISA::dspExtp(int64_t dspac, int32_t size, uint32_t *dspctl)
{
int32_t pos = 0;
int32_t result = 0;
- pos = bits( *dspctl, 5, 0 );
- size = bits( size, 4, 0 );
+ pos = bits(*dspctl, 5, 0);
+ size = bits(size, 4, 0);
- if( pos - (size+1) >= -1 )
- {
- result = bits( dspac, pos, pos-size );
- *dspctl = insertBits( *dspctl, 14, 14, 0 );
- }
- else
- {
+ if (pos - (size + 1) >= -1) {
+ result = bits(dspac, pos, pos - size);
+ *dspctl = insertBits(*dspctl, 14, 14, 0);
+ } else {
result = 0;
- *dspctl = insertBits( *dspctl, 14, 14, 1 );
+ *dspctl = insertBits(*dspctl, 14, 14, 1);
}
- return( result );
+ return result;
}
int32_t
-MipsISA::dspExtpd( int64_t dspac, int32_t size, uint32_t *dspctl )
+MipsISA::dspExtpd(int64_t dspac, int32_t size, uint32_t *dspctl)
{
int32_t pos = 0;
int32_t result = 0;
- pos = bits( *dspctl, 5, 0 );
- size = bits( size, 4, 0 );
-
- if( pos - (size+1) >= -1 )
- {
- result = bits( dspac, pos, pos-size );
- *dspctl = insertBits( *dspctl, 14, 14, 0 );
- if( pos - (size+1) >= 0 )
- *dspctl = insertBits( *dspctl, 5, 0, pos - (size+1) );
- else if( (pos - (size+1)) == -1 )
- *dspctl = insertBits( *dspctl, 5, 0, 63 );
- }
- else
- {
+ pos = bits(*dspctl, 5, 0);
+ size = bits(size, 4, 0);
+
+ if (pos - (size + 1) >= -1) {
+ result = bits(dspac, pos, pos - size);
+ *dspctl = insertBits(*dspctl, 14, 14, 0);
+ if (pos - (size + 1) >= 0)
+ *dspctl = insertBits(*dspctl, 5, 0, pos - (size + 1));
+ else if ((pos - (size + 1)) == -1)
+ *dspctl = insertBits(*dspctl, 5, 0, 63);
+ } else {
result = 0;
- *dspctl = insertBits( *dspctl, 14, 14, 1 );
+ *dspctl = insertBits(*dspctl, 14, 14, 1);
}
- return( result );
+ return result;
}
void
-MipsISA::simdPack( uint64_t *values_ptr, int32_t *reg, int32_t fmt )
+MipsISA::simdPack(uint64_t *values_ptr, int32_t *reg, int32_t fmt)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
int nbits = SIMD_NBITS[fmt];
*reg = 0;
- for( i=0; i<nvals; i++ )
- *reg |= (int32_t)bits( values_ptr[i], nbits-1, 0 ) << nbits*i;
+ for (int i = 0; i < nvals; i++)
+ *reg |= (int32_t)bits(values_ptr[i], nbits - 1, 0) << nbits * i;
}
void
-MipsISA::simdUnpack( int32_t reg, uint64_t *values_ptr, int32_t fmt, int32_t sign )
+MipsISA::simdUnpack(int32_t reg, uint64_t *values_ptr, int32_t fmt, int32_t sign)
{
- int i = 0;
int nvals = SIMD_NVALS[fmt];
int nbits = SIMD_NBITS[fmt];
- switch( sign )
- {
- case SIGNED:
- for( i=0; i<nvals; i++ )
- {
- values_ptr[i] = (uint64_t)bits( reg, nbits*(i+1)-1, nbits*i );
- values_ptr[i] = signExtend( values_ptr[i], fmt );
+ switch (sign) {
+ case SIGNED:
+ for (int i = 0; i < nvals; i++) {
+ uint64_t tmp = (uint64_t)bits(reg, nbits * (i + 1) - 1, nbits * i);
+ values_ptr[i] = signExtend(tmp, fmt);
}
break;
- case UNSIGNED:
- for( i=0; i<nvals; i++ )
- {
- values_ptr[i] = (uint64_t)bits( reg, nbits*(i+1)-1, nbits*i );
+ case UNSIGNED:
+ for (int i = 0; i < nvals; i++) {
+ values_ptr[i] =
+ (uint64_t)bits(reg, nbits * (i + 1) - 1, nbits * i);
}
break;
}
}
void
-MipsISA::writeDSPControl( uint32_t *dspctl, uint32_t value, uint32_t mask )
+MipsISA::writeDSPControl(uint32_t *dspctl, uint32_t value, uint32_t mask)
{
uint32_t fmask = 0;
- if( mask & 0x01 ) fmask |= DSP_CTL_MASK[DSP_POS];
- if( mask & 0x02 ) fmask |= DSP_CTL_MASK[DSP_SCOUNT];
- if( mask & 0x04 ) fmask |= DSP_CTL_MASK[DSP_C];
- if( mask & 0x08 ) fmask |= DSP_CTL_MASK[DSP_OUFLAG];
- if( mask & 0x10 ) fmask |= DSP_CTL_MASK[DSP_CCOND];
- if( mask & 0x20 ) fmask |= DSP_CTL_MASK[DSP_EFI];
+ if (mask & 0x01) fmask |= DSP_CTL_MASK[DSP_POS];
+ if (mask & 0x02) fmask |= DSP_CTL_MASK[DSP_SCOUNT];
+ if (mask & 0x04) fmask |= DSP_CTL_MASK[DSP_C];
+ if (mask & 0x08) fmask |= DSP_CTL_MASK[DSP_OUFLAG];
+ if (mask & 0x10) fmask |= DSP_CTL_MASK[DSP_CCOND];
+ if (mask & 0x20) fmask |= DSP_CTL_MASK[DSP_EFI];
*dspctl &= ~fmask;
value &= fmask;
@@ -1211,16 +1174,16 @@ MipsISA::writeDSPControl( uint32_t *dspctl, uint32_t value, uint32_t mask )
}
uint32_t
-MipsISA::readDSPControl( uint32_t *dspctl, uint32_t mask )
+MipsISA::readDSPControl(uint32_t *dspctl, uint32_t mask)
{
uint32_t fmask = 0;
- if( mask & 0x01 ) fmask |= DSP_CTL_MASK[DSP_POS];
- if( mask & 0x02 ) fmask |= DSP_CTL_MASK[DSP_SCOUNT];
- if( mask & 0x04 ) fmask |= DSP_CTL_MASK[DSP_C];
- if( mask & 0x08 ) fmask |= DSP_CTL_MASK[DSP_OUFLAG];
- if( mask & 0x10 ) fmask |= DSP_CTL_MASK[DSP_CCOND];
- if( mask & 0x20 ) fmask |= DSP_CTL_MASK[DSP_EFI];
+ if (mask & 0x01) fmask |= DSP_CTL_MASK[DSP_POS];
+ if (mask & 0x02) fmask |= DSP_CTL_MASK[DSP_SCOUNT];
+ if (mask & 0x04) fmask |= DSP_CTL_MASK[DSP_C];
+ if (mask & 0x08) fmask |= DSP_CTL_MASK[DSP_OUFLAG];
+ if (mask & 0x10) fmask |= DSP_CTL_MASK[DSP_CCOND];
+ if (mask & 0x20) fmask |= DSP_CTL_MASK[DSP_EFI];
- return( *dspctl & fmask );
+ return *dspctl & fmask;
}
diff --git a/src/arch/mips/dsp.hh b/src/arch/mips/dsp.hh
index fb8d5c4f6..fde4b332a 100755
--- a/src/arch/mips/dsp.hh
+++ b/src/arch/mips/dsp.hh
@@ -41,131 +41,164 @@ class ThreadContext;
namespace MipsISA {
- // SIMD formats
- enum {
- SIMD_FMT_L, // long word
- SIMD_FMT_W, // word
- SIMD_FMT_PH, // paired halfword
- SIMD_FMT_QB, // quad byte
- SIMD_NUM_FMTS
- };
-
- // DSPControl Fields
- enum {
- DSP_POS, // insertion bitfield position
- DSP_SCOUNT, // insertion bitfield size
- DSP_C, // carry bit
- DSP_OUFLAG, // overflow-underflow flag
- DSP_CCOND, // condition code
- DSP_EFI, // extract fail indicator bit
- DSP_NUM_FIELDS
- };
-
- // compare instruction operations
- enum {
- CMP_EQ, // equal
- CMP_LT, // less than
- CMP_LE // less than or equal
- };
-
- // SIMD operation order modes
- enum {
- MODE_L, // left
- MODE_R, // right
- MODE_LA, // left-alternate
- MODE_RA, // right-alternate
- MODE_X // cross
- };
-
- // dsp operation parameters
- enum { UNSIGNED, SIGNED };
- enum { NOSATURATE, SATURATE };
- enum { NOROUND, ROUND };
-
- // DSPControl field positions and masks
- const uint32_t DSP_CTL_POS[DSP_NUM_FIELDS] = { 0, 7, 13, 16, 24, 14 };
- const uint32_t DSP_CTL_MASK[DSP_NUM_FIELDS] = { 0x0000003f, 0x00001f80, 0x00002000,
- 0x00ff0000, 0x0f000000, 0x00004000 };
-
- // SIMD format constants
- const uint32_t SIMD_MAX_VALS = 4; // maximum values per register
- const uint32_t SIMD_NVALS[SIMD_NUM_FMTS] = { 1, 1, 2, 4 }; // number of values in fmt
- const uint32_t SIMD_NBITS[SIMD_NUM_FMTS] = { 64, 32, 16, 8 }; // number of bits per value
- const uint32_t SIMD_LOG2N[SIMD_NUM_FMTS] = { 6, 5, 4, 3 }; // log2( bits per value )
-
- // DSP maximum values
- const uint64_t FIXED_L_SMAX = ULL(0x7fffffffffffffff);
- const uint64_t FIXED_W_SMAX = ULL(0x000000007fffffff);
- const uint64_t FIXED_H_SMAX = ULL(0x0000000000007fff);
- const uint64_t FIXED_B_SMAX = ULL(0x000000000000007f);
- const uint64_t FIXED_L_UMAX = ULL(0xffffffffffffffff);
- const uint64_t FIXED_W_UMAX = ULL(0x00000000ffffffff);
- const uint64_t FIXED_H_UMAX = ULL(0x000000000000ffff);
- const uint64_t FIXED_B_UMAX = ULL(0x00000000000000ff);
- const uint64_t FIXED_SMAX[SIMD_NUM_FMTS] = { FIXED_L_SMAX, FIXED_W_SMAX, FIXED_H_SMAX, FIXED_B_SMAX };
- const uint64_t FIXED_UMAX[SIMD_NUM_FMTS] = { FIXED_L_UMAX, FIXED_W_UMAX, FIXED_H_UMAX, FIXED_B_UMAX };
-
- // DSP minimum values
- const uint64_t FIXED_L_SMIN = ULL(0x8000000000000000);
- const uint64_t FIXED_W_SMIN = ULL(0xffffffff80000000);
- const uint64_t FIXED_H_SMIN = ULL(0xffffffffffff8000);
- const uint64_t FIXED_B_SMIN = ULL(0xffffffffffffff80);
- const uint64_t FIXED_L_UMIN = ULL(0x0000000000000000);
- const uint64_t FIXED_W_UMIN = ULL(0x0000000000000000);
- const uint64_t FIXED_H_UMIN = ULL(0x0000000000000000);
- const uint64_t FIXED_B_UMIN = ULL(0x0000000000000000);
- const uint64_t FIXED_SMIN[SIMD_NUM_FMTS] = { FIXED_L_SMIN, FIXED_W_SMIN, FIXED_H_SMIN, FIXED_B_SMIN };
- const uint64_t FIXED_UMIN[SIMD_NUM_FMTS] = { FIXED_L_UMIN, FIXED_W_UMIN, FIXED_H_UMIN, FIXED_B_UMIN };
-
- // DSP utility functions
- int32_t bitrev( int32_t value );
- uint64_t dspSaturate( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow );
- uint64_t checkOverflow( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow );
- uint64_t signExtend( uint64_t value, int32_t signpos );
- uint64_t addHalfLsb( uint64_t value, int32_t lsbpos );
- int32_t dspAbs( int32_t a, int32_t fmt, uint32_t *dspctl );
- int32_t dspAdd( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl );
- int32_t dspAddh( int32_t a, int32_t b, int32_t fmt, int32_t round, int32_t sign );
- int32_t dspSub( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl );
- int32_t dspSubh( int32_t a, int32_t b, int32_t fmt, int32_t round, int32_t sign );
- int32_t dspShll( int32_t a, uint32_t sa, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl );
- int32_t dspShrl( int32_t a, uint32_t sa, int32_t fmt, int32_t sign );
- int32_t dspShra( int32_t a, uint32_t sa, int32_t fmt, int32_t round, int32_t sign, uint32_t *dspctl );
- int32_t dspMul( int32_t a, int32_t b, int32_t fmt, int32_t saturate, uint32_t *dspctl );
- int32_t dspMulq( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t round, uint32_t *dspctl );
- int32_t dspMuleu( int32_t a, int32_t b, int32_t mode, uint32_t *dspctl );
- int32_t dspMuleq( int32_t a, int32_t b, int32_t mode, uint32_t *dspctl );
- int64_t dspDpaq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t infmt,
- int32_t outfmt, int32_t postsat, int32_t mode, uint32_t *dspctl );
- int64_t dspDpsq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t infmt,
- int32_t outfmt, int32_t postsat, int32_t mode, uint32_t *dspctl );
- int64_t dspDpa( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt, int32_t sign, int32_t mode );
- int64_t dspDps( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt, int32_t sign, int32_t mode );
- int64_t dspMaq( int64_t dspac, int32_t a, int32_t b, int32_t ac,
- int32_t fmt, int32_t mode, int32_t saturate, uint32_t *dspctl );
- int64_t dspMulsa( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt );
- int64_t dspMulsaq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt, uint32_t *dspctl );
- void dspCmp( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, uint32_t *dspctl );
- int32_t dspCmpg( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op );
- int32_t dspCmpgd( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, uint32_t *dspctl );
- int32_t dspPrece( int32_t a, int32_t infmt, int32_t insign, int32_t outfmt, int32_t outsign, int32_t mode );
- int32_t dspPrecrqu( int32_t a, int32_t b, uint32_t *dspctl );
- int32_t dspPrecrq( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl );
- int32_t dspPrecrSra( int32_t a, int32_t b, int32_t sa, int32_t fmt, int32_t round );
- int32_t dspPick( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl );
- int32_t dspPack( int32_t a, int32_t b, int32_t fmt );
- int32_t dspExtr( int64_t dspac, int32_t fmt, int32_t sa, int32_t round,
- int32_t saturate, uint32_t *dspctl );
- int32_t dspExtp( int64_t dspac, int32_t size, uint32_t *dspctl );
- int32_t dspExtpd( int64_t dspac, int32_t size, uint32_t *dspctl );
-
- // SIMD pack/unpack utility functions
- void simdPack( uint64_t *values_ptr, int32_t *reg, int32_t fmt );
- void simdUnpack( int32_t reg, uint64_t *values_ptr, int32_t fmt, int32_t sign );
-
- // DSPControl r/w utility functions
- void writeDSPControl( uint32_t *dspctl, uint32_t value, uint32_t mask );
- uint32_t readDSPControl( uint32_t *dspctl, uint32_t mask );
+// SIMD formats
+enum {
+ SIMD_FMT_L, // long word
+ SIMD_FMT_W, // word
+ SIMD_FMT_PH, // paired halfword
+ SIMD_FMT_QB, // quad byte
+ SIMD_NUM_FMTS
};
-#endif
+// DSPControl Fields
+enum {
+ DSP_POS, // insertion bitfield position
+ DSP_SCOUNT, // insertion bitfield size
+ DSP_C, // carry bit
+ DSP_OUFLAG, // overflow-underflow flag
+ DSP_CCOND, // condition code
+ DSP_EFI, // extract fail indicator bit
+ DSP_NUM_FIELDS
+};
+
+// compare instruction operations
+enum {
+ CMP_EQ, // equal
+ CMP_LT, // less than
+ CMP_LE // less than or equal
+};
+
+// SIMD operation order modes
+enum {
+ MODE_L, // left
+ MODE_R, // right
+ MODE_LA, // left-alternate
+ MODE_RA, // right-alternate
+ MODE_X // cross
+};
+
+// dsp operation parameters
+enum { UNSIGNED, SIGNED };
+enum { NOSATURATE, SATURATE };
+enum { NOROUND, ROUND };
+
+// DSPControl field positions and masks
+const uint32_t DSP_CTL_POS[DSP_NUM_FIELDS] = { 0, 7, 13, 16, 24, 14 };
+const uint32_t DSP_CTL_MASK[DSP_NUM_FIELDS] =
+{ 0x0000003f, 0x00001f80, 0x00002000,
+ 0x00ff0000, 0x0f000000, 0x00004000 };
+
+/*
+ * SIMD format constants
+ */
+
+// maximum values per register
+const uint32_t SIMD_MAX_VALS = 4;
+// number of values in fmt
+const uint32_t SIMD_NVALS[SIMD_NUM_FMTS] = { 1, 1, 2, 4 };
+// number of bits per value
+const uint32_t SIMD_NBITS[SIMD_NUM_FMTS] = { 64, 32, 16, 8 };
+// log2(bits per value)
+const uint32_t SIMD_LOG2N[SIMD_NUM_FMTS] = { 6, 5, 4, 3 };
+
+
+// DSP maximum values
+const uint64_t FIXED_L_SMAX = ULL(0x7fffffffffffffff);
+const uint64_t FIXED_W_SMAX = ULL(0x000000007fffffff);
+const uint64_t FIXED_H_SMAX = ULL(0x0000000000007fff);
+const uint64_t FIXED_B_SMAX = ULL(0x000000000000007f);
+const uint64_t FIXED_L_UMAX = ULL(0xffffffffffffffff);
+const uint64_t FIXED_W_UMAX = ULL(0x00000000ffffffff);
+const uint64_t FIXED_H_UMAX = ULL(0x000000000000ffff);
+const uint64_t FIXED_B_UMAX = ULL(0x00000000000000ff);
+const uint64_t FIXED_SMAX[SIMD_NUM_FMTS] =
+{ FIXED_L_SMAX, FIXED_W_SMAX, FIXED_H_SMAX, FIXED_B_SMAX };
+const uint64_t FIXED_UMAX[SIMD_NUM_FMTS] =
+{ FIXED_L_UMAX, FIXED_W_UMAX, FIXED_H_UMAX, FIXED_B_UMAX };
+
+// DSP minimum values
+const uint64_t FIXED_L_SMIN = ULL(0x8000000000000000);
+const uint64_t FIXED_W_SMIN = ULL(0xffffffff80000000);
+const uint64_t FIXED_H_SMIN = ULL(0xffffffffffff8000);
+const uint64_t FIXED_B_SMIN = ULL(0xffffffffffffff80);
+const uint64_t FIXED_L_UMIN = ULL(0x0000000000000000);
+const uint64_t FIXED_W_UMIN = ULL(0x0000000000000000);
+const uint64_t FIXED_H_UMIN = ULL(0x0000000000000000);
+const uint64_t FIXED_B_UMIN = ULL(0x0000000000000000);
+const uint64_t FIXED_SMIN[SIMD_NUM_FMTS] =
+{ FIXED_L_SMIN, FIXED_W_SMIN, FIXED_H_SMIN, FIXED_B_SMIN };
+const uint64_t FIXED_UMIN[SIMD_NUM_FMTS] =
+{ FIXED_L_UMIN, FIXED_W_UMIN, FIXED_H_UMIN, FIXED_B_UMIN };
+
+// DSP utility functions
+int32_t bitrev(int32_t value);
+uint64_t dspSaturate(uint64_t value, int32_t fmt, int32_t sign,
+ uint32_t *overflow);
+uint64_t checkOverflow(uint64_t value, int32_t fmt, int32_t sign,
+ uint32_t *overflow);
+uint64_t signExtend(uint64_t value, int32_t signpos);
+uint64_t addHalfLsb(uint64_t value, int32_t lsbpos);
+int32_t dspAbs(int32_t a, int32_t fmt, uint32_t *dspctl);
+int32_t dspAdd(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
+ int32_t sign, uint32_t *dspctl);
+int32_t dspAddh(int32_t a, int32_t b, int32_t fmt, int32_t round,
+ int32_t sign);
+int32_t dspSub(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
+ int32_t sign, uint32_t *dspctl);
+int32_t dspSubh(int32_t a, int32_t b, int32_t fmt, int32_t round,
+ int32_t sign);
+int32_t dspShll(int32_t a, uint32_t sa, int32_t fmt, int32_t saturate,
+ int32_t sign, uint32_t *dspctl);
+int32_t dspShrl(int32_t a, uint32_t sa, int32_t fmt, int32_t sign);
+int32_t dspShra(int32_t a, uint32_t sa, int32_t fmt, int32_t round,
+ int32_t sign, uint32_t *dspctl);
+int32_t dspMul(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
+ uint32_t *dspctl);
+int32_t dspMulq(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
+ int32_t round, uint32_t *dspctl);
+int32_t dspMuleu(int32_t a, int32_t b, int32_t mode, uint32_t *dspctl);
+int32_t dspMuleq(int32_t a, int32_t b, int32_t mode, uint32_t *dspctl);
+int64_t dspDpaq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
+ int32_t infmt, int32_t outfmt, int32_t postsat, int32_t mode,
+ uint32_t *dspctl);
+int64_t dspDpsq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
+ int32_t infmt, int32_t outfmt, int32_t postsat, int32_t mode,
+ uint32_t *dspctl);
+int64_t dspDpa(int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt,
+ int32_t sign, int32_t mode);
+int64_t dspDps(int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt,
+ int32_t sign, int32_t mode);
+int64_t dspMaq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
+ int32_t fmt, int32_t mode, int32_t saturate, uint32_t *dspctl);
+int64_t dspMulsa(int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt);
+int64_t dspMulsaq(int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt,
+ uint32_t *dspctl);
+void dspCmp(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op,
+ uint32_t *dspctl);
+int32_t dspCmpg(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op);
+int32_t dspCmpgd(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op,
+ uint32_t *dspctl);
+int32_t dspPrece(int32_t a, int32_t infmt, int32_t insign, int32_t outfmt,
+ int32_t outsign, int32_t mode);
+int32_t dspPrecrqu(int32_t a, int32_t b, uint32_t *dspctl);
+int32_t dspPrecrq(int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl);
+int32_t dspPrecrSra(int32_t a, int32_t b, int32_t sa, int32_t fmt,
+ int32_t round);
+int32_t dspPick(int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl);
+int32_t dspPack(int32_t a, int32_t b, int32_t fmt);
+int32_t dspExtr(int64_t dspac, int32_t fmt, int32_t sa, int32_t round,
+ int32_t saturate, uint32_t *dspctl);
+int32_t dspExtp(int64_t dspac, int32_t size, uint32_t *dspctl);
+int32_t dspExtpd(int64_t dspac, int32_t size, uint32_t *dspctl);
+
+// SIMD pack/unpack utility functions
+void simdPack(uint64_t *values_ptr, int32_t *reg, int32_t fmt);
+void simdUnpack(int32_t reg, uint64_t *values_ptr, int32_t fmt, int32_t sign);
+
+// DSPControl r/w utility functions
+void writeDSPControl(uint32_t *dspctl, uint32_t value, uint32_t mask);
+uint32_t readDSPControl(uint32_t *dspctl, uint32_t mask);
+
+} /* namespace MipsISA */
+
+#endif // __ARCH_MIPS_DSP_HH__
diff --git a/src/arch/mips/idle_event.cc b/src/arch/mips/idle_event.cc
index d1d4f7c63..0aea08834 100644
--- a/src/arch/mips/idle_event.cc
+++ b/src/arch/mips/idle_event.cc
@@ -34,7 +34,7 @@
#include "arch/mips/kernel_stats.hh"
#include "cpu/thread_context.hh"
-using namespace TheISA;
+using namespace MipsISA;
void
IdleStartEvent::process(ThreadContext *tc)
diff --git a/src/arch/mips/interrupts.cc b/src/arch/mips/interrupts.cc
index c91ee1e99..99f96fafc 100755
--- a/src/arch/mips/interrupts.cc
+++ b/src/arch/mips/interrupts.cc
@@ -76,7 +76,7 @@ static inline void setCauseIP_(ThreadContext *tc, uint8_t val) {
intstatus &= ~(1 << int_num);
}
- void Interrupts::clear_all()
+ void Interrupts::clearAll()
{
DPRINTF(Interrupt, "Interrupts all cleared\n");
intstatus = 0;
@@ -156,12 +156,6 @@ static inline void setCauseIP_(ThreadContext *tc, uint8_t val) {
return false;
}
-
- uint64_t Interrupts::get_vec(int int_num)
- {
- panic("MipsISA::Interrupts::get_vec() is not implemented. \n");
- M5_DUMMY_RETURN
- }
*/
void Interrupts::post(int int_num, ThreadContext* tc)
{
@@ -195,14 +189,14 @@ void Interrupts::clear(int int_num, int index)
fatal("Must use Thread COntext when clearing MIPS Interrupts in M5");
}
-void Interrupts::clear_all(ThreadContext *tc)
+void Interrupts::clearAll(ThreadContext *tc)
{
DPRINTF(Interrupt, "Interrupts all cleared\n");
uint8_t intstatus = 0;
setCauseIP_(tc, intstatus);
}
-void Interrupts::clear_all()
+void Interrupts::clearAll()
{
fatal("Must use Thread COntext when clearing MIPS Interrupts in M5");
}
@@ -252,12 +246,6 @@ void Interrupts::updateIntrInfo(ThreadContext *tc) const
;
}
-uint64_t Interrupts::get_vec(int int_num)
-{
- panic("MipsISA::Interrupts::get_vec() is not implemented. \n");
- M5_DUMMY_RETURN
- }
-
bool Interrupts::interruptsPending(ThreadContext *tc) const
{
//if there is a on cpu timer interrupt (i.e. Compare == Count)
diff --git a/src/arch/mips/interrupts.hh b/src/arch/mips/interrupts.hh
index f0e928088..af71e4636 100755
--- a/src/arch/mips/interrupts.hh
+++ b/src/arch/mips/interrupts.hh
@@ -57,23 +57,23 @@ class Interrupts
// for posting an interrupt. It sets a bit
// in intstatus corresponding to Cause IP*. The
// MIPS register Cause is updated by updateIntrInfo
- // which is called by check_interrupts
+ // which is called by checkInterrupts
//
void post(int int_num, int index);
// clear(int int_num, int index) is responsible
// for clearing an interrupt. It clear a bit
// in intstatus corresponding to Cause IP*. The
// MIPS register Cause is updated by updateIntrInfo
- // which is called by check_interrupts
+ // which is called by checkInterrupts
//
void clear(int int_num, int index);
- // clear_all() is responsible
+ // clearAll() is responsible
// for clearing all interrupts. It clears all bits
// in intstatus corresponding to Cause IP*. The
// MIPS register Cause is updated by updateIntrInfo
- // which is called by check_interrupts
+ // which is called by checkInterrupts
//
- void clear_all();
+ void clearAll();
// getInterrupt(ThreadContext * tc) checks if an interrupt
// should be returned. It ands the interrupt mask and
@@ -91,9 +91,7 @@ class Interrupts
void updateIntrInfoCpuTimerIntr(ThreadContext *tc) const;
bool onCpuTimerInterrupt(ThreadContext *tc) const;
- uint64_t get_vec(int int_num);
-
- bool check_interrupts(ThreadContext * tc) const{
+ bool checkInterrupts(ThreadContext *tc) const {
//return (intstatus != 0) && !(tc->readPC() & 0x3);
if (oncputimerintr == false){
updateIntrInfo(tc);
@@ -121,7 +119,7 @@ class Interrupts
// for posting an interrupt. It sets a bit
// in intstatus corresponding to Cause IP*. The
// MIPS register Cause is updated by updateIntrInfo
- // which is called by check_interrupts
+ // which is called by checkInterrupts
//
void post(int int_num, ThreadContext* tc);
void post(int int_num, int index);
@@ -130,19 +128,19 @@ class Interrupts
// for clearing an interrupt. It clear a bit
// in intstatus corresponding to Cause IP*. The
// MIPS register Cause is updated by updateIntrInfo
- // which is called by check_interrupts
+ // which is called by checkInterrupts
//
void clear(int int_num, ThreadContext* tc);
void clear(int int_num, int index);
- // clear_all() is responsible
+ // clearAll() is responsible
// for clearing all interrupts. It clears all bits
// in intstatus corresponding to Cause IP*. The
// MIPS register Cause is updated by updateIntrInfo
- // which is called by check_interrupts
+ // which is called by checkInterrupts
//
- void clear_all(ThreadContext* tc);
- void clear_all();
+ void clearAll(ThreadContext* tc);
+ void clearAll();
// getInterrupt(ThreadContext * tc) checks if an interrupt
// should be returned. It ands the interrupt mask and
@@ -160,9 +158,9 @@ class Interrupts
bool interruptsPending(ThreadContext *tc) const;
bool onCpuTimerInterrupt(ThreadContext *tc) const;
- uint64_t get_vec(int int_num);
-
- bool check_interrupts(ThreadContext * tc) const{
+ bool
+ checkInterrupts(ThreadContext *tc) const
+ {
return interruptsPending(tc);
}
diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa
index b1cd03ca1..8af504e55 100644
--- a/src/arch/mips/isa/decoder.isa
+++ b/src/arch/mips/isa/decoder.isa
@@ -416,16 +416,16 @@ decode OPCODE_HI default Unknown::unknown() {
Ctrl_Base_DepTag);
break;
case 25:
- data = 0 | fcsr_val & 0xFE000000 >> 24
- | fcsr_val & 0x00800000 >> 23;
+ data = (fcsr_val & 0xFE000000 >> 24)
+ | (fcsr_val & 0x00800000 >> 23);
break;
case 26:
- data = 0 | fcsr_val & 0x0003F07C;
+ data = fcsr_val & 0x0003F07C;
break;
case 28:
- data = 0 | fcsr_val & 0x00000F80
- | fcsr_val & 0x01000000 >> 21
- | fcsr_val & 0x00000003;
+ data = (fcsr_val & 0x00000F80)
+ | (fcsr_val & 0x01000000 >> 21)
+ | (fcsr_val & 0x00000003);
break;
case 31:
data = fcsr_val;
@@ -603,7 +603,8 @@ decode OPCODE_HI default Unknown::unknown() {
0xA: rdpgpr({{
if(Config_AR >= 1)
{ // Rev 2 of the architecture
- Rd = xc->tcBase()->readIntReg(RT + NumIntRegs * SRSCtl_PSS);
+ panic("Shadow Sets Not Fully Implemented.\n");
+ //Rd = xc->tcBase()->readIntReg(RT + NumIntRegs * SRSCtl_PSS);
}
else
{
@@ -613,7 +614,8 @@ decode OPCODE_HI default Unknown::unknown() {
0xE: wrpgpr({{
if(Config_AR >= 1)
{ // Rev 2 of the architecture
- xc->tcBase()->setIntReg(RD + NumIntRegs * SRSCtl_PSS,Rt);
+ panic("Shadow Sets Not Fully Implemented.\n");
+ //xc->tcBase()->setIntReg(RD + NumIntRegs * SRSCtl_PSS,Rt);
// warn("Writing %d to %d, PSS: %d, SRS: %x\n",Rt,RD + NumIntRegs * SRSCtl_PSS, SRSCtl_PSS,SRSCtl);
}
else
@@ -1963,7 +1965,7 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: decode OP_LO {
format IntOp {
0x0: append({{ Rt.uw = (Rt.uw << RD) | bits(Rs.uw,RD-1,0); }});
- 0x1: prepend({{ Rt.uw = (Rt.uw >> RD) | (bits(Rs.uw,RD-1,0) << 32-RD); }});
+ 0x1: prepend({{ Rt.uw = (Rt.uw >> RD) | (bits(Rs.uw, RD - 1, 0) << (32 - RD)); }});
}
}
0x2: decode OP_LO {
@@ -2050,11 +2052,11 @@ decode OPCODE_HI default Unknown::unknown() {
format LoadUnalignedMemory {
0x2: lwl({{ uint32_t mem_shift = 24 - (8 * byte_offset);
Rt.uw = mem_word << mem_shift |
- Rt.uw & mask(mem_shift);
+ (Rt.uw & mask(mem_shift));
}});
0x6: lwr({{ uint32_t mem_shift = 8 * byte_offset;
- Rt.uw = Rt.uw & (mask(mem_shift) << (32 - mem_shift)) |
- mem_word >> mem_shift;
+ Rt.uw = (Rt.uw & (mask(mem_shift) << (32 - mem_shift))) |
+ (mem_word >> mem_shift);
}});
}
}
@@ -2069,12 +2071,12 @@ decode OPCODE_HI default Unknown::unknown() {
format StoreUnalignedMemory {
0x2: swl({{ uint32_t reg_shift = 24 - (8 * byte_offset);
uint32_t mem_shift = 32 - reg_shift;
- mem_word = mem_word & (mask(reg_shift) << mem_shift) |
- Rt.uw >> reg_shift;
+ mem_word = (mem_word & (mask(reg_shift) << mem_shift)) |
+ (Rt.uw >> reg_shift);
}});
0x6: swr({{ uint32_t reg_shift = 8 * byte_offset;
mem_word = Rt.uw << reg_shift |
- mem_word & (mask(reg_shift));
+ (mem_word & (mask(reg_shift)));
}});
}
format CP0Control {
diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa
index f0210c29b..8596308e2 100644
--- a/src/arch/mips/isa/formats/mem.isa
+++ b/src/arch/mips/isa/formats/mem.isa
@@ -43,7 +43,7 @@ output header {{
protected:
/// Memory request flags. See mem_req_base.hh.
- unsigned memAccessFlags;
+ Request::Flags memAccessFlags;
/// Pointer to EAComp object.
const StaticInstPtr eaCompPtr;
/// Pointer to MemAcc object.
@@ -57,7 +57,7 @@ output header {{
StaticInstPtr _eaCompPtr = nullStaticInstPtr,
StaticInstPtr _memAccPtr = nullStaticInstPtr)
: MipsStaticInst(mnem, _machInst, __opClass),
- memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
+ eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
disp(sext<16>(OFFSET))
{
}
@@ -70,7 +70,7 @@ output header {{
const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
const StaticInstPtr &memAccInst() const { return memAccPtr; }
- unsigned memAccFlags() { return memAccessFlags; }
+ Request::Flags memAccFlags() { return memAccessFlags; }
};
/**
diff --git a/src/arch/mips/isa/formats/mt.isa b/src/arch/mips/isa/formats/mt.isa
index 81fdc2898..1928ee903 100644
--- a/src/arch/mips/isa/formats/mt.isa
+++ b/src/arch/mips/isa/formats/mt.isa
@@ -196,7 +196,7 @@ def format MT_Control(code, *opt_flags) {{
def format MT_MFTR(code, *flags) {{
flags += ('IsNonSpeculative', )
-# code = 'std::cerr << curTick << \": T\" << xc->tcBase()->getThreadNum() << \": Executing MT INST: ' + name + '\" << endl;\n' + code
+# code = 'std::cerr << curTick << \": T\" << xc->tcBase()->threadId() << \": Executing MT INST: ' + name + '\" << endl;\n' + code
code += 'if (MT_H == 1) {\n'
code += 'data = bits(data, top_bit, bottom_bit);\n'
@@ -212,7 +212,7 @@ def format MT_MFTR(code, *flags) {{
def format MT_MTTR(code, *flags) {{
flags += ('IsNonSpeculative', )
-# code = 'std::cerr << curTick << \": T\" << xc->tcBase()->getThreadNum() << \": Executing MT INST: ' + name + '\" << endl;\n' + code
+# code = 'std::cerr << curTick << \": T\" << xc->tcBase()->threadId() << \": Executing MT INST: ' + name + '\" << endl;\n' + code
iop = InstObjParams(name, Name, 'MTOp', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
diff --git a/src/arch/mips/isa/formats/util.isa b/src/arch/mips/isa/formats/util.isa
index 0405aa5b3..f729cbf63 100644
--- a/src/arch/mips/isa/formats/util.isa
+++ b/src/arch/mips/isa/formats/util.isa
@@ -61,6 +61,7 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
inst_flags)
if mem_flags:
+ mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
iop.constructor += s
memacc_iop.constructor += s
diff --git a/src/arch/mips/isa_traits.hh b/src/arch/mips/isa_traits.hh
index fe28ad601..12c887132 100644
--- a/src/arch/mips/isa_traits.hh
+++ b/src/arch/mips/isa_traits.hh
@@ -147,11 +147,11 @@ namespace MipsISA
// MIPS modes
enum mode_type
{
- mode_kernel = 0, // kernel
- mode_supervisor = 1, // supervisor
- mode_user = 2, // user mode
+ mode_kernel = 0, // kernel
+ mode_supervisor = 1, // supervisor
+ mode_user = 2, // user mode
mode_debug = 3, // debug mode
- mode_number // number of modes
+ mode_number // number of modes
};
inline mode_type getOperatingMode(MiscReg Stat)
@@ -181,6 +181,8 @@ namespace MipsISA
const int NumIntRegs = NumIntArchRegs*NumShadowRegSets + NumIntSpecialRegs; //HI & LO Regs
const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;//
+ const int TotalArchRegs = NumIntArchRegs * NumShadowRegSets;
+
// Static instruction parameters
const int MaxInstSrcRegs = 10;
const int MaxInstDestRegs = 8;
@@ -188,13 +190,6 @@ namespace MipsISA
// semantically meaningful register indices
const int ZeroReg = 0;
const int AssemblerReg = 1;
- const int ReturnValueReg = 2;
- const int ReturnValueReg1 = 2;
- const int ReturnValueReg2 = 3;
- const int ArgumentReg0 = 4;
- const int ArgumentReg1 = 5;
- const int ArgumentReg2 = 6;
- const int ArgumentReg3 = 7;
const int KernelReg0 = 26;
const int KernelReg1 = 27;
const int GlobalPointerReg = 28;
@@ -202,14 +197,9 @@ namespace MipsISA
const int FramePointerReg = 30;
const int ReturnAddressReg = 31;
- const int ArgumentReg[] = {4, 5, 6, 7};
- const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int);
-
- const int SyscallNumReg = ReturnValueReg1;
- const int SyscallPseudoReturnReg = ReturnValueReg2;
- const int SyscallSuccessReg = ArgumentReg3;
+ const int SyscallPseudoReturnReg = 3;
- const int LogVMPageSize = 13; // 8K bytes
+ const int LogVMPageSize = 13; // 8K bytes
const int VMPageSize = (1 << LogVMPageSize);
const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
@@ -391,6 +381,4 @@ namespace MipsISA
};
-using namespace MipsISA;
-
#endif // __ARCH_MIPS_ISA_TRAITS_HH__
diff --git a/src/arch/mips/linux/linux.cc b/src/arch/mips/linux/linux.cc
index 4499107d7..8745731dc 100644
--- a/src/arch/mips/linux/linux.cc
+++ b/src/arch/mips/linux/linux.cc
@@ -35,34 +35,34 @@
// 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 },
+ { 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 },
+ { MipsLinux::TGT_O_NONBLOCK, _O_NONBLOCK },
#endif
#ifdef _O_NOCTTY
- { MipsLinux::TGT_O_NOCTTY, _O_NOCTTY },
+ { MipsLinux::TGT_O_NOCTTY, _O_NOCTTY },
#endif
#ifdef _O_SYNC
- { MipsLinux::TGT_O_SYNC, _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 },
+ { 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 },
+ { MipsLinux::TGT_O_SYNC, O_SYNC },
#endif
#endif /* _MSC_VER */
};
diff --git a/src/arch/mips/linux/linux.hh b/src/arch/mips/linux/linux.hh
index fcfaa18ea..aaeba0a42 100644
--- a/src/arch/mips/linux/linux.hh
+++ b/src/arch/mips/linux/linux.hh
@@ -32,9 +32,6 @@
#define __ARCH_MIPS_LINUX_LINUX_HH__
#include "kern/linux/linux.hh"
-#include <string>
-
-using std::string;
class MipsLinux : public Linux
{
@@ -49,21 +46,21 @@ class MipsLinux : public Linux
//@{
/// 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
+ 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().
@@ -72,12 +69,12 @@ class MipsLinux : public Linux
//@{
/// 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_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_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
//@}
//@{
@@ -94,15 +91,15 @@ class MipsLinux : public Linux
//@{
/// ioctl() command codes.
- static const unsigned TIOCGETP = 0x7408;
- static const unsigned TIOCSETP = 0x7409;
- static const unsigned TIOCSETN = 0x740a;
- static const unsigned TIOCSETC = 0x7411;
- static const unsigned TIOCGETC = 0x7412;
- static const unsigned FIONREAD = 0x467f;
- static const unsigned TIOCISATTY = 0x5480;
- static const unsigned TIOCGETS = 0x540d;
- static const unsigned TIOCGETA = 0x7417;
+ static const unsigned TIOCGETP_ = 0x7408;
+ static const unsigned TIOCSETP_ = 0x7409;
+ static const unsigned TIOCSETN_ = 0x740a;
+ static const unsigned TIOCSETC_ = 0x7411;
+ static const unsigned TIOCGETC_ = 0x7412;
+ static const unsigned FIONREAD_ = 0x467f;
+ static const unsigned TIOCISATTY_ = 0x5480;
+ static const unsigned TIOCGETS_ = 0x540d;
+ static const unsigned TIOCGETA_ = 0x7417;
//@}
/// For table().
diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc
index 06e6e2cf4..24e71305a 100644
--- a/src/arch/mips/linux/process.cc
+++ b/src/arch/mips/linux/process.cc
@@ -51,7 +51,7 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
+ TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
strcpy(name->sysname, "Linux");
strcpy(name->nodename,"m5.eecs.umich.edu");
@@ -70,13 +70,13 @@ static SyscallReturn
sys_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- unsigned op = tc->getSyscallArg(0);
- // unsigned nbytes = tc->getSyscallArg(2);
+ unsigned op = process->getSyscallArg(tc, 0);
+ // unsigned nbytes = process->getSyscallArg(tc, 2);
switch (op) {
case 45: { // GSI_IEEE_FP_CONTROL
- TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1));
+ TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
// I don't think this exactly matches the HW FPCR
*fpcr = 0;
fpcr.copyOut(tc->getMemPort());
@@ -97,13 +97,13 @@ static SyscallReturn
sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- unsigned op = tc->getSyscallArg(0);
- // unsigned nbytes = tc->getSyscallArg(2);
+ unsigned op = process->getSyscallArg(tc, 0);
+ // unsigned nbytes = process->getSyscallArg(tc, 2);
switch (op) {
case 14: { // SSI_IEEE_FP_CONTROL
- TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1));
+ TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
// I don't think this exactly matches the HW FPCR
fpcr.copyIn(tc->getMemPort());
DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): "
@@ -138,7 +138,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", chmodFunc<MipsLinux>),
/* 16 */ SyscallDesc("lchown", chownFunc),
- /* 17 */ SyscallDesc("break", obreakFunc),
+ /* 17 */ SyscallDesc("break", brkFunc),
/* 18 */ SyscallDesc("unused#18", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getpid", getpidFunc),
@@ -160,13 +160,13 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 36 */ SyscallDesc("sync", unimplementedFunc),
/* 37 */ SyscallDesc("kill", unimplementedFunc),
/* 38 */ SyscallDesc("rename", unimplementedFunc),
- /* 39 */ SyscallDesc("mkdir", unimplementedFunc),
+ /* 39 */ SyscallDesc("mkdir", mkdirFunc),
/* 40 */ SyscallDesc("rmdir", unimplementedFunc),
/* 41 */ SyscallDesc("dup", unimplementedFunc),
/* 42 */ SyscallDesc("pipe", pipePseudoFunc),
/* 43 */ SyscallDesc("times", unimplementedFunc),
/* 44 */ SyscallDesc("prof", unimplementedFunc),
- /* 45 */ SyscallDesc("brk", obreakFunc),
+ /* 45 */ SyscallDesc("brk", brkFunc),
/* 46 */ SyscallDesc("setgid", unimplementedFunc),
/* 47 */ SyscallDesc("getgid", getgidFunc),
/* 48 */ SyscallDesc("signal", ignoreFunc),
@@ -175,13 +175,13 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 51 */ SyscallDesc("acct", unimplementedFunc),
/* 52 */ SyscallDesc("umount2", unimplementedFunc),
/* 53 */ SyscallDesc("lock", unimplementedFunc),
- /* 54 */ SyscallDesc("ioctl", unimplementedFunc/*ioctlFunc<MipsLinux>*/),
+ /* 54 */ SyscallDesc("ioctl", ioctlFunc<MipsLinux>),
/* 55 */ SyscallDesc("fcntl", fcntlFunc),
/* 56 */ SyscallDesc("mpx", unimplementedFunc),
/* 57 */ SyscallDesc("setpgid", unimplementedFunc),
/* 58 */ SyscallDesc("ulimit", unimplementedFunc),
/* 59 */ SyscallDesc("unused#59", unimplementedFunc),
- /* 60 */ SyscallDesc("umask", unimplementedFunc),
+ /* 60 */ SyscallDesc("umask", umaskFunc),
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
/* 62 */ SyscallDesc("ustat", unimplementedFunc),
/* 63 */ SyscallDesc("dup2", unimplementedFunc),
@@ -206,7 +206,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 82 */ SyscallDesc("reserved#82", unimplementedFunc),
/* 83 */ SyscallDesc("symlink", unimplementedFunc),
/* 84 */ SyscallDesc("unused#84", unimplementedFunc),
- /* 85 */ SyscallDesc("readlink", unimplementedFunc),
+ /* 85 */ SyscallDesc("readlink", readlinkFunc),
/* 86 */ SyscallDesc("uselib", unimplementedFunc),
/* 87 */ SyscallDesc("swapon", gethostnameFunc),
/* 88 */ SyscallDesc("reboot", unimplementedFunc),
@@ -288,7 +288,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 164 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
/* 165 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
/* 166 */ SyscallDesc("nanosleep", unimplementedFunc),
- /* 167 */ SyscallDesc("mremap", unimplementedFunc),
+ /* 167 */ SyscallDesc("mremap", mremapFunc<MipsLinux>),
/* 168 */ SyscallDesc("accept", unimplementedFunc),
/* 169 */ SyscallDesc("bind", unimplementedFunc),
/* 170 */ SyscallDesc("connect", unimplementedFunc),
@@ -324,7 +324,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 200 */ SyscallDesc("pread64", unimplementedFunc),
/* 201 */ SyscallDesc("pwrite64", unimplementedFunc),
/* 202 */ SyscallDesc("chown", unimplementedFunc),
- /* 203 */ SyscallDesc("getcwd", unimplementedFunc),
+ /* 203 */ SyscallDesc("getcwd", getcwdFunc),
/* 204 */ SyscallDesc("capget", unimplementedFunc),
/* 205 */ SyscallDesc("capset", unimplementedFunc),
/* 206 */ SyscallDesc("sigalstack", unimplementedFunc),
@@ -425,7 +425,7 @@ 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)
+ if (m5_sys_idx < 0 || m5_sys_idx >= Num_Syscall_Descs)
return NULL;
return &syscallDescs[m5_sys_idx];
diff --git a/src/arch/mips/linux/system.cc b/src/arch/mips/linux/system.cc
index bed863e9d..23062c96b 100644
--- a/src/arch/mips/linux/system.cc
+++ b/src/arch/mips/linux/system.cc
@@ -168,7 +168,6 @@ LinuxMipsSystem::setDelayLoop(ThreadContext *tc)
vp = tc->getVirtPort();
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
- tc->delVirtPort(vp);
}
}
diff --git a/src/arch/mips/linux/system.hh b/src/arch/mips/linux/system.hh
index 24fb604ed..984f74694 100644
--- a/src/arch/mips/linux/system.hh
+++ b/src/arch/mips/linux/system.hh
@@ -43,9 +43,6 @@ class IdleStartEvent;
#include "kern/linux/events.hh"
#include "params/LinuxMipsSystem.hh"
-using namespace MipsISA;
-using namespace Linux;
-
/**
* This class contains linux specific system code (Loading, Events).
* It points to objects that are the system binaries to load and patches them
@@ -112,7 +109,7 @@ class LinuxMipsSystem : public MipsSystem
* PC based event to skip the dprink() call and emulate its
* functionality
*/
- DebugPrintkEvent *debugPrintkEvent;
+ Linux::DebugPrintkEvent *debugPrintkEvent;
/**
* Skip calculate_delay_loop() rather than waiting for this to be
diff --git a/src/arch/mips/linux/threadinfo.hh b/src/arch/mips/linux/threadinfo.hh
index 25ee74dd3..b0d0cd811 100644
--- a/src/arch/mips/linux/threadinfo.hh
+++ b/src/arch/mips/linux/threadinfo.hh
@@ -55,7 +55,7 @@ class ThreadInfo
CopyOut(tc, &data, addr, sizeof(T));
- data = TheISA::gtoh(data);
+ data = MipsISA::gtoh(data);
return true;
}
@@ -77,7 +77,7 @@ class ThreadInfo
Addr sp;
if (!addr)
- addr = tc->readMiscRegNoEffect(0/*TheISA::IPR_PALtemp23*/);
+ addr = tc->readMiscRegNoEffect(0/*MipsISA::IPR_PALtemp23*/);
FunctionalPort *p = tc->getPhysPort();
p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
diff --git a/src/arch/mips/locked_mem.hh b/src/arch/mips/locked_mem.hh
index 34da79ed9..021b8cf73 100644
--- a/src/arch/mips/locked_mem.hh
+++ b/src/arch/mips/locked_mem.hh
@@ -49,11 +49,10 @@ template <class XC>
inline void
handleLockedRead(XC *xc, Request *req)
{
- unsigned tid = req->getThreadNum();
- xc->setMiscRegNoEffect(LLAddr, req->getPaddr() & ~0xf, tid);
- xc->setMiscRegNoEffect(LLFlag, true, tid);
+ xc->setMiscRegNoEffect(LLAddr, req->getPaddr() & ~0xf);
+ xc->setMiscRegNoEffect(LLFlag, true);
DPRINTF(LLSC, "[tid:%i]: Load-Link Flag Set & Load-Link Address set to %x.\n",
- tid, req->getPaddr() & ~0xf);
+ req->threadId(), req->getPaddr() & ~0xf);
}
@@ -61,22 +60,20 @@ template <class XC>
inline bool
handleLockedWrite(XC *xc, Request *req)
{
- unsigned tid = req->getThreadNum();
-
if (req->isUncacheable()) {
// Funky Turbolaser mailbox access...don't update
// result register (see stq_c in decoder.isa)
req->setExtraData(2);
} else {
// standard store conditional
- bool lock_flag = xc->readMiscRegNoEffect(LLFlag, tid);
- Addr lock_addr = xc->readMiscRegNoEffect(LLAddr, tid);
+ bool lock_flag = xc->readMiscRegNoEffect(LLFlag);
+ Addr lock_addr = xc->readMiscRegNoEffect(LLAddr);
if (!lock_flag || (req->getPaddr() & ~0xf) != lock_addr) {
// Lock flag not set or addr mismatch in CPU;
// don't even bother sending to memory system
req->setExtraData(0);
- xc->setMiscRegNoEffect(LLFlag, false, tid);
+ xc->setMiscRegNoEffect(LLFlag, false);
// the rest of this code is not architectural;
// it's just a debugging aid to help detect
@@ -86,9 +83,9 @@ handleLockedWrite(XC *xc, Request *req)
stCondFailures++;
xc->setStCondFailures(stCondFailures);
if (stCondFailures % 10 == 0) {
- warn("%i: cpu %d: %d consecutive "
+ warn("%i: context %d: %d consecutive "
"store conditional failures\n",
- curTick, xc->readCpuId(), stCondFailures);
+ curTick, xc->contextId(), stCondFailures);
}
if (stCondFailures == 5000) {
@@ -97,10 +94,10 @@ handleLockedWrite(XC *xc, Request *req)
if (!lock_flag){
DPRINTF(LLSC, "[tid:%i]: Lock Flag Set, Store Conditional Failed.\n",
- tid);
+ req->threadId());
} else if ((req->getPaddr() & ~0xf) != lock_addr) {
DPRINTF(LLSC, "[tid:%i]: Load-Link Address Mismatch, Store Conditional Failed.\n",
- tid);
+ req->threadId());
}
// store conditional failed already, so don't issue it to mem
return false;
diff --git a/src/arch/mips/syscallreturn.hh b/src/arch/mips/microcode_rom.hh
index 24a40ddcc..a5be81e2a 100644
--- a/src/arch/mips/syscallreturn.hh
+++ b/src/arch/mips/microcode_rom.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007 MIPS Technologies, Inc.
+ * Copyright (c) 2008 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,30 +26,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
- * Korey Sewell
*/
-#ifndef __ARCH_MIPS_SYSCALLRETURN_HH__
-#define __ARCH_MIPS_SYSCALLRETURN_HH__
+#ifndef __ARCH_MIPS_MICROCODE_ROM_HH__
+#define __ARCH_MIPS_MICROCODE_ROM_HH__
-#include "sim/syscallreturn.hh"
-#include "cpu/thread_context.hh"
+#include "sim/microcode_rom.hh"
namespace MipsISA
{
- static inline void setSyscallReturn(SyscallReturn return_value,
- ThreadContext *tc)
- {
- if (return_value.successful()) {
- // no error
- tc->setIntReg(SyscallSuccessReg, 0);
- tc->setIntReg(ReturnValueReg1, return_value.value());
- } else {
- // got an error, return details
- tc->setIntReg(SyscallSuccessReg, (IntReg) -1);
- tc->setIntReg(ReturnValueReg1, -return_value.value());
- }
- }
+ using ::MicrocodeRom;
}
-#endif
+#endif // __ARCH_MIPS_MICROCODE_ROM_HH__
diff --git a/src/arch/mips/mips_core_specific.cc b/src/arch/mips/mips_core_specific.cc
index a17ebcdf3..80d856b0c 100755
--- a/src/arch/mips/mips_core_specific.cc
+++ b/src/arch/mips/mips_core_specific.cc
@@ -113,13 +113,13 @@ MipsISA::processInterrupts(CPU *cpu)
/*int
MipsISA::MiscRegFile::getInstAsid()
{
- return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]);
+ return AlphaISA::ITB_ASN_ASN(ipr[IPR_ITB_ASN]);
}
int
MipsISA::MiscRegFile::getDataAsid()
{
- return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]);
+ return AlphaISA::DTB_ASN_ASN(ipr[IPR_DTB_ASN]);
}*/
diff --git a/src/arch/mips/mt.hh b/src/arch/mips/mt.hh
index 6765c27a9..d0c333d86 100755
--- a/src/arch/mips/mt.hh
+++ b/src/arch/mips/mt.hh
@@ -45,7 +45,6 @@
#include "base/misc.hh"
#include <iostream>
-using namespace std;
namespace MipsISA
{
@@ -78,7 +77,7 @@ haltThread(TC *tc)
// @TODO: Needs to check if this is a branch and if so, take previous instruction
tc->setMiscReg(TCRestart, tc->readNextPC());
- warn("%i: Halting thread %i in %s @ PC %x, setting restart PC to %x", curTick, tc->getThreadNum(), tc->getCpuPtr()->name(),
+ warn("%i: Halting thread %i in %s @ PC %x, setting restart PC to %x", curTick, tc->threadId(), tc->getCpuPtr()->name(),
tc->readPC(), tc->readNextPC());
}
}
@@ -98,7 +97,7 @@ restoreThread(TC *tc)
tc->setNextNPC(pc + 8);
tc->activate(0);
- warn("%i: Restoring thread %i in %s @ PC %x", curTick, tc->getThreadNum(), tc->getCpuPtr()->name(),
+ warn("%i: Restoring thread %i in %s @ PC %x", curTick, tc->threadId(), tc->getCpuPtr()->name(),
tc->readPC());
}
}
@@ -164,7 +163,7 @@ forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt)
success = 1;
}
} else {
- std::cerr << "Bad VPEs" << endl;
+ std::cerr << "Bad VPEs" << std::endl;
}
}
@@ -217,10 +216,10 @@ yieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask)
if (ok == 1) {
unsigned tcstatus = tc->readMiscRegNoEffect(TCStatus);
tc->setMiscReg(TCStatus, insertBits(tcstatus, TCS_A, TCS_A, 0));
- warn("%i: Deactivating Hardware Thread Context #%i", curTick, tc->getThreadNum());
+ warn("%i: Deactivating Hardware Thread Context #%i", curTick, tc->threadId());
}
} else if (src_reg > 0) {
- if (src_reg & !yield_mask != 0) {
+ if (src_reg && !yield_mask != 0) {
unsigned vpe_control = tc->readMiscReg(VPEControl);
tc->setMiscReg(VPEControl, insertBits(vpe_control, VPEC_EXCPT_HI, VPEC_EXCPT_LO, 2));
fault = new ThreadFault();
@@ -238,7 +237,7 @@ yieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask)
fault = new ThreadFault();
} else {
//tc->ScheduleOtherThreads();
- //std::cerr << "T" << tc->getThreadNum() << "YIELD: Schedule Other Threads.\n" << std::endl;
+ //std::cerr << "T" << tc->threadId() << "YIELD: Schedule Other Threads.\n" << std::endl;
//tc->suspend();
// Save last known PC in TCRestart
// @TODO: Needs to check if this is a branch and if so, take previous instruction
diff --git a/src/arch/mips/pagetable.hh b/src/arch/mips/pagetable.hh
index 8c43a7b0c..bbed94194 100755
--- a/src/arch/mips/pagetable.hh
+++ b/src/arch/mips/pagetable.hh
@@ -59,9 +59,9 @@ namespace MipsISA {
Addr level3() const
{ return MipsISA::PteAddr(addr >> PageShift); }
Addr level2() const
- { return MipsISA::PteAddr(addr >> NPtePageShift + PageShift); }
+ { return MipsISA::PteAddr(addr >> (NPtePageShift + PageShift)); }
Addr level1() const
- { return MipsISA::PteAddr(addr >> 2 * NPtePageShift + PageShift); }
+ { return MipsISA::PteAddr(addr >> (2 * NPtePageShift + PageShift)); }
};
// ITB/DTB page table entry
diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc
index b7bd22d78..784ddfe33 100644
--- a/src/arch/mips/process.cc
+++ b/src/arch/mips/process.cc
@@ -40,6 +40,10 @@
using namespace std;
using namespace MipsISA;
+static const int SyscallSuccessReg = 7;
+static const int FirstArgumentReg = 4;
+static const int ReturnValueReg = 2;
+
MipsLiveProcess::MipsLiveProcess(LiveProcessParams * params,
ObjectFile *objFile)
: LiveProcess(params, objFile)
@@ -64,3 +68,33 @@ MipsLiveProcess::startup()
{
argsInit(MachineBytes, VMPageSize);
}
+
+MipsISA::IntReg
+MipsLiveProcess::getSyscallArg(ThreadContext *tc, int i)
+{
+ assert(i < 6);
+ return tc->readIntReg(FirstArgumentReg + i);
+}
+
+void
+MipsLiveProcess::setSyscallArg(ThreadContext *tc,
+ int i, MipsISA::IntReg val)
+{
+ assert(i < 6);
+ tc->setIntReg(FirstArgumentReg + i, val);
+}
+
+void
+MipsLiveProcess::setSyscallReturn(ThreadContext *tc,
+ SyscallReturn return_value)
+{
+ if (return_value.successful()) {
+ // no error
+ tc->setIntReg(SyscallSuccessReg, 0);
+ tc->setIntReg(ReturnValueReg, return_value.value());
+ } else {
+ // got an error, return details
+ tc->setIntReg(SyscallSuccessReg, (IntReg) -1);
+ tc->setIntReg(ReturnValueReg, -return_value.value());
+ }
+}
diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh
index 18bf289b8..87c62330f 100644
--- a/src/arch/mips/process.hh
+++ b/src/arch/mips/process.hh
@@ -47,6 +47,10 @@ class MipsLiveProcess : public LiveProcess
virtual void startup();
+ public:
+ MipsISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ void setSyscallArg(ThreadContext *tc, int i, MipsISA::IntReg val);
+ void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
};
diff --git a/src/arch/mips/regfile.cc b/src/arch/mips/regfile.cc
index 0c670af6d..663115bb6 100644
--- a/src/arch/mips/regfile.cc
+++ b/src/arch/mips/regfile.cc
@@ -188,12 +188,6 @@ RegFile::unserialize(Checkpoint *cp, const std::string &section)
}
-
-void RegFile::changeContext(RegContextParam param, RegContextVal val)
-{
- panic("Change Context Not Implemented for MipsISA");
-}
-
static inline int flattenIntIndex(ThreadContext * tc, int reg)
{
return reg;
@@ -206,12 +200,6 @@ MipsISA::copyRegs(ThreadContext *src, ThreadContext *dest)
}
void
-MipsISA::copyRegs(ThreadContext *src, ThreadContext *dest);
-{
- panic("Copy Regs Not Implemented Yet\n");
-}
-
-void
MipsISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
{
panic("Copy Misc. Regs Not Implemented Yet\n");
diff --git a/src/arch/mips/regfile/float_regfile.hh b/src/arch/mips/regfile/float_regfile.hh
index 1537855df..0c0ecc7eb 100644
--- a/src/arch/mips/regfile/float_regfile.hh
+++ b/src/arch/mips/regfile/float_regfile.hh
@@ -44,11 +44,6 @@ class Checkpoint;
namespace MipsISA
{
- static inline std::string getFloatRegName(RegIndex)
- {
- return "";
- }
-
const uint32_t MIPS32_QNAN = 0x7fbfffff;
const uint64_t MIPS64_QNAN = ULL(0x7fbfffffffffffff);
diff --git a/src/arch/mips/regfile/int_regfile.cc b/src/arch/mips/regfile/int_regfile.cc
index c46ecf0b3..88de4be94 100644
--- a/src/arch/mips/regfile/int_regfile.cc
+++ b/src/arch/mips/regfile/int_regfile.cc
@@ -37,7 +37,6 @@
using namespace MipsISA;
using namespace std;
-
void
IntRegFile::clear()
{
@@ -45,29 +44,33 @@ IntRegFile::clear()
currShadowSet=0;
}
+int
+IntRegFile::readShadowSet()
+{
+ return currShadowSet;
+}
+
void
IntRegFile::setShadowSet(int css)
{
- DPRINTF(MipsPRA,"Setting Shadow Set to :%d (%s)\n",css,currShadowSet);
+ DPRINTF(MipsPRA, "Setting Shadow Set to :%d (%s)\n", css, currShadowSet);
currShadowSet = css;
}
IntReg
IntRegFile::readReg(int intReg)
{
- if(intReg < NumIntRegs)
- { // Regular GPR Read
- DPRINTF(MipsPRA,"Reading Reg: %d, CurrShadowSet: %d\n",intReg,currShadowSet);
- if(intReg >= NumIntArchRegs*NumShadowRegSets){
- return regs[intReg+NumIntRegs*currShadowSet];
- }
- else {
- return regs[(intReg + NumIntArchRegs*currShadowSet) % NumIntArchRegs];
- }
- }
- else
- { // Read from shadow GPR .. probably called by RDPGPR
- return regs[intReg];
+ if (intReg < NumIntArchRegs) {
+ // Regular GPR Read
+ DPRINTF(MipsPRA, "Reading Reg: %d, CurrShadowSet: %d\n", intReg,
+ currShadowSet);
+
+ return regs[intReg + NumIntArchRegs * currShadowSet];
+ } else {
+ unsigned special_reg_num = intReg - NumIntArchRegs;
+
+ // Read A Special Reg
+ return regs[TotalArchRegs + special_reg_num];
}
}
@@ -75,20 +78,15 @@ Fault
IntRegFile::setReg(int intReg, const IntReg &val)
{
if (intReg != ZeroReg) {
+ if (intReg < NumIntArchRegs) {
+ regs[intReg + NumIntArchRegs * currShadowSet] = val;
+ } else {
+ unsigned special_reg_num = intReg - NumIntArchRegs;
- if(intReg < NumIntRegs)
- {
- if(intReg >= NumIntArchRegs*NumShadowRegSets){
- regs[intReg] = val;
- }
- else{
- regs[intReg+NumIntRegs*currShadowSet] = val;
- }
- }
- else{
- regs[intReg] = val;
+ regs[TotalArchRegs + special_reg_num] = val;
}
}
+
return NoFault;
}
@@ -103,4 +101,3 @@ IntRegFile::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ARRAY(regs, NumIntRegs);
}
-
diff --git a/src/arch/mips/regfile/int_regfile.hh b/src/arch/mips/regfile/int_regfile.hh
index 8ddd276e6..c5a6bb345 100644
--- a/src/arch/mips/regfile/int_regfile.hh
+++ b/src/arch/mips/regfile/int_regfile.hh
@@ -42,13 +42,8 @@ class Checkpoint;
namespace MipsISA
{
- static inline std::string getIntRegName(RegIndex)
- {
- return "";
- }
-
enum MiscIntRegNums {
- LO = NumIntArchRegs*NumShadowRegSets,
+ LO = NumIntArchRegs,
HI,
DSPACX0,
DSPLo1,
@@ -72,6 +67,7 @@ namespace MipsISA
int currShadowSet;
public:
void clear();
+ int readShadowSet();
void setShadowSet(int css);
IntReg readReg(int intReg);
Fault setReg(int intReg, const IntReg &val);
diff --git a/src/arch/mips/regfile/misc_regfile.cc b/src/arch/mips/regfile/misc_regfile.cc
index dc6ae0baf..a00bf166e 100755..100644
--- a/src/arch/mips/regfile/misc_regfile.cc
+++ b/src/arch/mips/regfile/misc_regfile.cc
@@ -40,42 +40,55 @@
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
+//#include "params/DerivO3CPU.hh"
+
using namespace std;
+using namespace MipsISA;
std::string MiscRegFile::miscRegNames[NumMiscRegs] =
-{"Index", "MVPControl", "MVPConf0", "MVPConf1", "", "", "", "",
- "Random", "VPEControl", "VPEConf0", "VPEConf1", "YQMask", "VPESchedule", "VPEScheFBack", "VPEOpt",
- "EntryLo0", "TCStatus", "TCBind", "TCRestart", "TCHalt", "TCContext", "TCSchedule", "TCScheFBack",
- "EntryLo1", "", "", "", "", "", "", "",
- "Context", "ContextConfig", "", "", "", "", "", "",
- "PageMask", "PageGrain", "", "", "", "", "", "",
- "Wired", "SRSConf0", "SRCConf1", "SRSConf2", "SRSConf3", "SRSConf4", "", "",
- "HWREna", "", "", "", "", "", "", "",
- "BadVAddr", "", "", "", "", "", "", "",
- "Count", "", "", "", "", "", "", "",
- "EntryHi", "", "", "", "", "", "", "",
- "Compare", "", "", "", "", "", "", "",
- "Status", "IntCtl", "SRSCtl", "SRSMap", "", "", "", "",
- "Cause", "", "", "", "", "", "", "",
- "EPC", "", "", "", "", "", "", "",
- "PRId", "EBase", "", "", "", "", "", "",
- "Config", "Config1", "Config2", "Config3", "", "", "", "",
- "LLAddr", "", "", "", "", "", "", "",
- "WatchLo0", "WatchLo1", "WatchLo2", "WatchLo3", "WatchLo4", "WatchLo5", "WatchLo6", "WatchLo7",
- "WatchHi0", "WatchHi1", "WatchHi2", "WatchHi3", "WatchHi4", "WatchHi5", "WatchHi6", "WatchHi7",
- "XCContext64", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "Debug", "TraceControl1", "TraceControl2", "UserTraceData", "TraceBPC", "", "", "",
- "DEPC", "", "", "", "", "", "", "",
- "PerfCnt0", "PerfCnt1", "PerfCnt2", "PerfCnt3", "PerfCnt4", "PerfCnt5", "PerfCnt6", "PerfCnt7",
- "ErrCtl", "", "", "", "", "", "", "",
- "CacheErr0", "CacheErr1", "CacheErr2", "CacheErr3", "", "", "", "",
- "TagLo0", "DataLo1", "TagLo2", "DataLo3", "TagLo4", "DataLo5", "TagLo6", "DataLo7",
- "TagHi0", "DataHi1", "TagHi2", "DataHi3", "TagHi4", "DataHi5", "TagHi6", "DataHi7",
- "ErrorEPC", "", "", "", "", "", "", "",
- "DESAVE", "", "", "", "", "", "", "",
- "LLFlag"
+{
+ "Index", "MVPControl", "MVPConf0", "MVPConf1", "", "", "", "",
+ "Random", "VPEControl", "VPEConf0", "VPEConf1",
+ "YQMask", "VPESchedule", "VPEScheFBack", "VPEOpt",
+ "EntryLo0", "TCStatus", "TCBind", "TCRestart",
+ "TCHalt", "TCContext", "TCSchedule", "TCScheFBack",
+ "EntryLo1", "", "", "", "", "", "", "",
+ "Context", "ContextConfig", "", "", "", "", "", "",
+ "PageMask", "PageGrain", "", "", "", "", "", "",
+ "Wired", "SRSConf0", "SRCConf1", "SRSConf2",
+ "SRSConf3", "SRSConf4", "", "",
+ "HWREna", "", "", "", "", "", "", "",
+ "BadVAddr", "", "", "", "", "", "", "",
+ "Count", "", "", "", "", "", "", "",
+ "EntryHi", "", "", "", "", "", "", "",
+ "Compare", "", "", "", "", "", "", "",
+ "Status", "IntCtl", "SRSCtl", "SRSMap", "", "", "", "",
+ "Cause", "", "", "", "", "", "", "",
+ "EPC", "", "", "", "", "", "", "",
+ "PRId", "EBase", "", "", "", "", "", "",
+ "Config", "Config1", "Config2", "Config3", "", "", "", "",
+ "LLAddr", "", "", "", "", "", "", "",
+ "WatchLo0", "WatchLo1", "WatchLo2", "WatchLo3",
+ "WatchLo4", "WatchLo5", "WatchLo6", "WatchLo7",
+ "WatchHi0", "WatchHi1", "WatchHi2", "WatchHi3",
+ "WatchHi4", "WatchHi5", "WatchHi6", "WatchHi7",
+ "XCContext64", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "Debug", "TraceControl1", "TraceControl2", "UserTraceData",
+ "TraceBPC", "", "", "",
+ "DEPC", "", "", "", "", "", "", "",
+ "PerfCnt0", "PerfCnt1", "PerfCnt2", "PerfCnt3",
+ "PerfCnt4", "PerfCnt5", "PerfCnt6", "PerfCnt7",
+ "ErrCtl", "", "", "", "", "", "", "",
+ "CacheErr0", "CacheErr1", "CacheErr2", "CacheErr3", "", "", "", "",
+ "TagLo0", "DataLo1", "TagLo2", "DataLo3",
+ "TagLo4", "DataLo5", "TagLo6", "DataLo7",
+ "TagHi0", "DataHi1", "TagHi2", "DataHi3",
+ "TagHi4", "DataHi5", "TagHi6", "DataHi7",
+ "ErrorEPC", "", "", "", "", "", "", "",
+ "DESAVE", "", "", "", "", "", "", "",
+ "LLFlag"
};
MiscRegFile::MiscRegFile()
@@ -170,11 +183,12 @@ void
MiscRegFile::reset(std::string core_name, unsigned num_threads,
unsigned num_vpes, BaseCPU *_cpu)
{
-
DPRINTF(MipsPRA, "Resetting CP0 State with %i TCs and %i VPEs\n",
num_threads, num_vpes);
cpu = _cpu;
- const BaseCPU::Params *p = _cpu->params;
+
+ MipsISA::CoreSpecific &cp = cpu->coreParams;
+
// Do Default CP0 initialization HERE
// Do Initialization for MT cores here (eventually use
@@ -183,10 +197,10 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads,
DPRINTF(MipsPRA, "Initializing CP0 State.... ");
MiscReg ProcID = readRegNoEffect(PRId);
- replaceBits(ProcID,PRIdCoOp_HI,PRIdCoOp_LO,p->coreParams.CP0_PRId_CompanyOptions);
- replaceBits(ProcID,PRIdCoID_HI,PRIdCoID_LO,p->coreParams.CP0_PRId_CompanyID);
- replaceBits(ProcID,PRIdProc_ID_HI,PRIdProc_ID_LO,p->coreParams.CP0_PRId_ProcessorID);
- replaceBits(ProcID,PRIdRev_HI,PRIdRev_LO,p->coreParams.CP0_PRId_Revision);
+ replaceBits(ProcID,PRIdCoOp_HI,PRIdCoOp_LO,cp.CP0_PRId_CompanyOptions);
+ replaceBits(ProcID,PRIdCoID_HI,PRIdCoID_LO,cp.CP0_PRId_CompanyID);
+ replaceBits(ProcID,PRIdProc_ID_HI,PRIdProc_ID_LO,cp.CP0_PRId_ProcessorID);
+ replaceBits(ProcID,PRIdRev_HI,PRIdRev_LO,cp.CP0_PRId_Revision);
setRegNoEffect(PRId,ProcID);
// Now, create Write Mask for ProcID register
MiscReg ProcID_Mask = 0; // Read-Only register
@@ -195,11 +209,11 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads,
// Config
MiscReg cfg = readRegNoEffect(Config);
- replaceBits(cfg, Config_BE_HI, Config_BE_LO, p->coreParams.CP0_Config_BE);
- replaceBits(cfg, Config_AT_HI, Config_AT_LO, p->coreParams.CP0_Config_AT);
- replaceBits(cfg, Config_AR_HI, Config_AR_LO, p->coreParams.CP0_Config_AR);
- replaceBits(cfg, Config_MT_HI, Config_MT_LO, p->coreParams.CP0_Config_MT);
- replaceBits(cfg, Config_VI_HI, Config_VI_LO, p->coreParams.CP0_Config_VI);
+ replaceBits(cfg, Config_BE_HI, Config_BE_LO, cp.CP0_Config_BE);
+ replaceBits(cfg, Config_AT_HI, Config_AT_LO, cp.CP0_Config_AT);
+ replaceBits(cfg, Config_AR_HI, Config_AR_LO, cp.CP0_Config_AR);
+ replaceBits(cfg, Config_MT_HI, Config_MT_LO, cp.CP0_Config_MT);
+ replaceBits(cfg, Config_VI_HI, Config_VI_LO, cp.CP0_Config_VI);
replaceBits(cfg, Config_M, 1);
setRegNoEffect(Config, cfg);
// Now, create Write Mask for Config register
@@ -209,20 +223,21 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads,
// Config1
MiscReg cfg1 = readRegNoEffect(Config1);
- replaceBits(cfg1, Config1_MMUSize_HI, Config1_MMUSize_LO, p->coreParams.CP0_Config1_MMU);
- replaceBits(cfg1, Config1_IS_HI, Config1_IS_LO, p->coreParams.CP0_Config1_IS);
- replaceBits(cfg1, Config1_IL_HI, Config1_IL_LO, p->coreParams.CP0_Config1_IL);
- replaceBits(cfg1, Config1_IA_HI, Config1_IA_LO, p->coreParams.CP0_Config1_IA);
- replaceBits(cfg1, Config1_DS_HI, Config1_DS_LO, p->coreParams.CP0_Config1_DS);
- replaceBits(cfg1, Config1_DL_HI, Config1_DL_LO, p->coreParams.CP0_Config1_DL);
- replaceBits(cfg1, Config1_DA_HI, Config1_DA_LO, p->coreParams.CP0_Config1_DA);
- replaceBits(cfg1, Config1_FP_HI, Config1_FP_LO, p->coreParams.CP0_Config1_FP);
- replaceBits(cfg1, Config1_EP_HI, Config1_EP_LO, p->coreParams.CP0_Config1_EP);
- replaceBits(cfg1, Config1_WR_HI, Config1_WR_LO, p->coreParams.CP0_Config1_WR);
- replaceBits(cfg1, Config1_MD_HI, Config1_MD_LO, p->coreParams.CP0_Config1_MD);
- replaceBits(cfg1, Config1_C2_HI, Config1_C2_LO, p->coreParams.CP0_Config1_C2);
- replaceBits(cfg1, Config1_PC_HI, Config1_PC_LO, p->coreParams.CP0_Config1_PC);
- replaceBits(cfg1, Config1_M, p->coreParams.CP0_Config1_M);
+ replaceBits(cfg1, Config1_MMUSize_HI, Config1_MMUSize_LO,
+ cp.CP0_Config1_MMU);
+ replaceBits(cfg1, Config1_IS_HI, Config1_IS_LO, cp.CP0_Config1_IS);
+ replaceBits(cfg1, Config1_IL_HI, Config1_IL_LO, cp.CP0_Config1_IL);
+ replaceBits(cfg1, Config1_IA_HI, Config1_IA_LO, cp.CP0_Config1_IA);
+ replaceBits(cfg1, Config1_DS_HI, Config1_DS_LO, cp.CP0_Config1_DS);
+ replaceBits(cfg1, Config1_DL_HI, Config1_DL_LO, cp.CP0_Config1_DL);
+ replaceBits(cfg1, Config1_DA_HI, Config1_DA_LO, cp.CP0_Config1_DA);
+ replaceBits(cfg1, Config1_FP_HI, Config1_FP_LO, cp.CP0_Config1_FP);
+ replaceBits(cfg1, Config1_EP_HI, Config1_EP_LO, cp.CP0_Config1_EP);
+ replaceBits(cfg1, Config1_WR_HI, Config1_WR_LO, cp.CP0_Config1_WR);
+ replaceBits(cfg1, Config1_MD_HI, Config1_MD_LO, cp.CP0_Config1_MD);
+ replaceBits(cfg1, Config1_C2_HI, Config1_C2_LO, cp.CP0_Config1_C2);
+ replaceBits(cfg1, Config1_PC_HI, Config1_PC_LO, cp.CP0_Config1_PC);
+ replaceBits(cfg1, Config1_M, cp.CP0_Config1_M);
setRegNoEffect(Config1, cfg1);
// Now, create Write Mask for Config register
MiscReg cfg1_Mask = 0; // Read Only Register
@@ -231,15 +246,15 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads,
// Config2
MiscReg cfg2 = readRegNoEffect(Config2);
- replaceBits(cfg2, Config2_TU_HI, Config2_TU_LO, p->coreParams.CP0_Config2_TU);
- replaceBits(cfg2, Config2_TS_HI, Config2_TS_LO, p->coreParams.CP0_Config2_TS);
- replaceBits(cfg2, Config2_TL_HI, Config2_TL_LO, p->coreParams.CP0_Config2_TL);
- replaceBits(cfg2, Config2_TA_HI, Config2_TA_LO, p->coreParams.CP0_Config2_TA);
- replaceBits(cfg2, Config2_SU_HI, Config2_SU_LO, p->coreParams.CP0_Config2_SU);
- replaceBits(cfg2, Config2_SS_HI, Config2_SS_LO, p->coreParams.CP0_Config2_SS);
- replaceBits(cfg2, Config2_SL_HI, Config2_SL_LO, p->coreParams.CP0_Config2_SL);
- replaceBits(cfg2, Config2_SA_HI, Config2_SA_LO, p->coreParams.CP0_Config2_SA);
- replaceBits(cfg2, Config2_M, p->coreParams.CP0_Config2_M);
+ replaceBits(cfg2, Config2_TU_HI, Config2_TU_LO, cp.CP0_Config2_TU);
+ replaceBits(cfg2, Config2_TS_HI, Config2_TS_LO, cp.CP0_Config2_TS);
+ replaceBits(cfg2, Config2_TL_HI, Config2_TL_LO, cp.CP0_Config2_TL);
+ replaceBits(cfg2, Config2_TA_HI, Config2_TA_LO, cp.CP0_Config2_TA);
+ replaceBits(cfg2, Config2_SU_HI, Config2_SU_LO, cp.CP0_Config2_SU);
+ replaceBits(cfg2, Config2_SS_HI, Config2_SS_LO, cp.CP0_Config2_SS);
+ replaceBits(cfg2, Config2_SL_HI, Config2_SL_LO, cp.CP0_Config2_SL);
+ replaceBits(cfg2, Config2_SA_HI, Config2_SA_LO, cp.CP0_Config2_SA);
+ replaceBits(cfg2, Config2_M, cp.CP0_Config2_M);
setRegNoEffect(Config2, cfg2);
// Now, create Write Mask for Config register
MiscReg cfg2_Mask = 0x7000F000; // Read Only Register
@@ -248,14 +263,14 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads,
// Config3
MiscReg cfg3 = readRegNoEffect(Config3);
- replaceBits(cfg3, Config3_DSPP_HI, Config3_DSPP_LO, p->coreParams.CP0_Config3_DSPP);
- replaceBits(cfg3, Config3_LPA_HI, Config3_LPA_LO, p->coreParams.CP0_Config3_LPA);
- replaceBits(cfg3, Config3_VEIC_HI, Config3_VEIC_LO, p->coreParams.CP0_Config3_VEIC);
- replaceBits(cfg3, Config3_VINT_HI, Config3_VINT_LO, p->coreParams.CP0_Config3_VInt);
- replaceBits(cfg3, Config3_SP_HI, Config3_SP_LO, p->coreParams.CP0_Config3_SP);
- replaceBits(cfg3, Config3_MT_HI, Config3_MT_LO, p->coreParams.CP0_Config3_MT);
- replaceBits(cfg3, Config3_SM_HI, Config3_SM_LO, p->coreParams.CP0_Config3_SM);
- replaceBits(cfg3, Config3_TL_HI, Config3_TL_LO, p->coreParams.CP0_Config3_TL);
+ replaceBits(cfg3, Config3_DSPP_HI, Config3_DSPP_LO, cp.CP0_Config3_DSPP);
+ replaceBits(cfg3, Config3_LPA_HI, Config3_LPA_LO, cp.CP0_Config3_LPA);
+ replaceBits(cfg3, Config3_VEIC_HI, Config3_VEIC_LO, cp.CP0_Config3_VEIC);
+ replaceBits(cfg3, Config3_VINT_HI, Config3_VINT_LO, cp.CP0_Config3_VInt);
+ replaceBits(cfg3, Config3_SP_HI, Config3_SP_LO, cp.CP0_Config3_SP);
+ replaceBits(cfg3, Config3_MT_HI, Config3_MT_LO, cp.CP0_Config3_MT);
+ replaceBits(cfg3, Config3_SM_HI, Config3_SM_LO, cp.CP0_Config3_SM);
+ replaceBits(cfg3, Config3_TL_HI, Config3_TL_LO, cp.CP0_Config3_TL);
setRegNoEffect(Config3, cfg3);
// Now, create Write Mask for Config register
MiscReg cfg3_Mask = 0; // Read Only Register
@@ -264,7 +279,7 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads,
// EBase - CPUNum
MiscReg EB = readRegNoEffect(EBase);
- replaceBits(EB, EBase_CPUNum_HI, EBase_CPUNum_LO, p->coreParams.CP0_EBase_CPUNum);
+ replaceBits(EB, EBase_CPUNum_HI, EBase_CPUNum_LO, cp.CP0_EBase_CPUNum);
replaceBits(EB, 31, 31, 1);
setRegNoEffect(EBase, EB);
// Now, create Write Mask for Config register
@@ -275,7 +290,7 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads,
// SRS Control - HSS (Highest Shadow Set)
MiscReg SC = readRegNoEffect(SRSCtl);
- replaceBits(SC, SRSCtl_HSS_HI,SRSCtl_HSS_LO,p->coreParams.CP0_SrsCtl_HSS);
+ replaceBits(SC, SRSCtl_HSS_HI,SRSCtl_HSS_LO,cp.CP0_SrsCtl_HSS);
setRegNoEffect(SRSCtl, SC);
// Now, create Write Mask for the SRS Ctl register
MiscReg SC_Mask = 0x0000F3C0;
@@ -284,8 +299,8 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads,
// IntCtl - IPTI, IPPCI
MiscReg IC = readRegNoEffect(IntCtl);
- replaceBits(IC, IntCtl_IPTI_HI,IntCtl_IPTI_LO,p->coreParams.CP0_IntCtl_IPTI);
- replaceBits(IC, IntCtl_IPPCI_HI,IntCtl_IPPCI_LO,p->coreParams.CP0_IntCtl_IPPCI);
+ replaceBits(IC, IntCtl_IPTI_HI,IntCtl_IPTI_LO,cp.CP0_IntCtl_IPTI);
+ replaceBits(IC, IntCtl_IPPCI_HI,IntCtl_IPPCI_LO,cp.CP0_IntCtl_IPPCI);
setRegNoEffect(IntCtl, IC);
// Now, create Write Mask for the IntCtl register
MiscReg IC_Mask = 0x000003E0;
@@ -294,7 +309,7 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads,
// Watch Hi - M - FIXME (More than 1 Watch register)
MiscReg WHi = readRegNoEffect(WatchHi0);
- replaceBits(WHi, WatchHi_M, p->coreParams.CP0_WatchHi_M);
+ replaceBits(WHi, WatchHi_M, cp.CP0_WatchHi_M);
setRegNoEffect(WatchHi0, WHi);
// Now, create Write Mask for the IntCtl register
MiscReg wh_Mask = 0x7FFF0FFF;
@@ -303,8 +318,8 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads,
// Perf Ctr - M - FIXME (More than 1 PerfCnt Pair)
MiscReg PCtr = readRegNoEffect(PerfCnt0);
- replaceBits(PCtr, PerfCntCtl_M, p->coreParams.CP0_PerfCtr_M);
- replaceBits(PCtr, PerfCntCtl_W, p->coreParams.CP0_PerfCtr_W);
+ replaceBits(PCtr, PerfCntCtl_M, cp.CP0_PerfCtr_M);
+ replaceBits(PCtr, PerfCntCtl_W, cp.CP0_PerfCtr_W);
setRegNoEffect(PerfCnt0, PCtr);
// Now, create Write Mask for the IntCtl register
MiscReg pc_Mask = 0x00007FF;
@@ -322,7 +337,7 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads,
// PageGrain
MiscReg pagegrain = readRegNoEffect(PageGrain);
- replaceBits(pagegrain,PageGrain_ESP,p->coreParams.CP0_Config3_SP);
+ replaceBits(pagegrain,PageGrain_ESP,cp.CP0_Config3_SP);
setRegNoEffect(PageGrain, pagegrain);
// Now, create Write Mask for the IntCtl register
MiscReg pg_Mask = 0x10000000;
@@ -331,12 +346,18 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads,
// Status
MiscReg stat = readRegNoEffect(Status);
- // Only CU0 and IE are modified on a reset - everything else needs to be controlled
- // on a per CPU model basis
- // replaceBits(stat, Status_CU0_HI,Status_CU0_LO, 1); // Enable CP0 on reset
+ // Only CU0 and IE are modified on a reset - everything else needs
+ // to be controlled on a per CPU model basis
+
+ // Enable CP0 on reset
+ // replaceBits(stat, Status_CU0_HI,Status_CU0_LO, 1);
+
+ // Enable ERL bit on a reset
+ replaceBits(stat, Status_ERL_HI, Status_ERL_LO, 1);
+
+ // Enable BEV bit on a reset
+ replaceBits(stat, Status_BEV_HI, Status_BEV_LO, 1);
- replaceBits(stat, Status_ERL_HI, Status_ERL_LO, 1); // Enable ERL bit on a reset
- replaceBits(stat, Status_BEV_HI, Status_BEV_LO, 1); // Enable BEV bit on a reset
setRegNoEffect(Status, stat);
// Now, create Write Mask for the Status register
MiscReg stat_Mask = 0xFF78FF17;
@@ -417,12 +438,6 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads,
}
-inline std::string
-MipsISA::getMiscRegName(unsigned reg_idx)
-{
- return MiscRegFile::miscRegNames[reg_idx];
-}
-
inline unsigned
MiscRegFile::getVPENum(unsigned tid)
{
@@ -437,7 +452,8 @@ MiscRegFile::readRegNoEffect(int reg_idx, unsigned tid)
unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
? tid : getVPENum(tid);
DPRINTF(MipsPRA, "Reading CP0 Register:%u Select:%u (%s) (%lx).\n",
- misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg),miscRegFile[misc_reg][reg_sel]);
+ misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg],
+ miscRegFile[misc_reg][reg_sel]);
return miscRegFile[misc_reg][reg_sel];
}
@@ -451,8 +467,10 @@ MiscRegFile::readReg(int reg_idx,
int misc_reg = reg_idx - Ctrl_Base_DepTag;
unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
? tid : getVPENum(tid);
- DPRINTF(MipsPRA, "Reading CP0 Register:%u Select:%u (%s) with effect (%lx).\n",
- misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg),miscRegFile[misc_reg][reg_sel]);
+ DPRINTF(MipsPRA,
+ "Reading CP0 Register:%u Select:%u (%s) with effect (%lx).\n",
+ misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg],
+ miscRegFile[misc_reg][reg_sel]);
switch (misc_reg)
@@ -468,8 +486,10 @@ MiscRegFile::setRegNoEffect(int reg_idx, const MiscReg &val, unsigned tid)
int misc_reg = reg_idx - Ctrl_Base_DepTag;
unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
? tid : getVPENum(tid);
- DPRINTF(MipsPRA, "[tid:%i]: Setting (direct set) CP0 Register:%u Select:%u (%s) to %#x.\n",
- tid, misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), val);
+ DPRINTF(MipsPRA,
+ "[tid:%i]: Setting (direct set) CP0 Register:%u "
+ "Select:%u (%s) to %#x.\n",
+ tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val);
miscRegFile[misc_reg][reg_sel] = val;
}
@@ -480,7 +500,9 @@ MiscRegFile::setRegMask(int reg_idx, const MiscReg &val, unsigned tid)
int misc_reg = reg_idx - Ctrl_Base_DepTag;
unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
? tid : getVPENum(tid);
- DPRINTF(MipsPRA,"[tid:%i]: Setting CP0 Register: %u Select: %u (%s) to %#x\n",tid, misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), val);
+ DPRINTF(MipsPRA,
+ "[tid:%i]: Setting CP0 Register: %u Select: %u (%s) to %#x\n",
+ tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val);
miscRegFile_WriteMask[misc_reg][reg_sel] = val;
}
@@ -497,8 +519,10 @@ MiscRegFile::setReg(int reg_idx, const MiscReg &val,
int reg_sel = (bankType[misc_reg] == perThreadContext)
? tid : getVPENum(tid);
- DPRINTF(MipsPRA, "[tid:%i]: Setting CP0 Register:%u Select:%u (%s) to %#x, with effect.\n",
- tid, misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), val);
+ DPRINTF(MipsPRA,
+ "[tid:%i]: Setting CP0 Register:%u "
+ "Select:%u (%s) to %#x, with effect.\n",
+ tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val);
MiscReg cp0_val = filterCP0Write(misc_reg, reg_sel, val);
@@ -506,16 +530,28 @@ MiscRegFile::setReg(int reg_idx, const MiscReg &val,
scheduleCP0Update(1);
}
-/** This method doesn't need to adjust the Control Register Offset since
- it has already been done in the calling method (setRegWithEffect) */
-MiscReg MiscRegFile::filterCP0Write(int misc_reg, int reg_sel, const MiscReg &val)
+/**
+ * This method doesn't need to adjust the Control Register Offset
+ * since it has already been done in the calling method
+ * (setRegWithEffect)
+*/
+MiscReg
+MiscRegFile::filterCP0Write(int misc_reg, int reg_sel, const MiscReg &val)
{
MiscReg retVal = val;
- retVal &= miscRegFile_WriteMask[misc_reg][reg_sel]; // Mask off read-only regions
+
+ // Mask off read-only regions
+ retVal &= miscRegFile_WriteMask[misc_reg][reg_sel];
MiscReg curVal = miscRegFile[misc_reg][reg_sel];
- curVal &= (~miscRegFile_WriteMask[misc_reg][reg_sel]); // Mask off current alue with inverse mask (clear writeable bits)
+ // Mask off current alue with inverse mask (clear writeable bits)
+ curVal &= (~miscRegFile_WriteMask[misc_reg][reg_sel]);
retVal |= curVal; // Combine the two
- DPRINTF(MipsPRA,"filterCP0Write: Mask: %lx, Inverse Mask: %lx, write Val: %x, current val: %lx, written val: %x\n",miscRegFile_WriteMask[misc_reg][reg_sel],~miscRegFile_WriteMask[misc_reg][reg_sel],val,miscRegFile[misc_reg][reg_sel],retVal);
+ DPRINTF(MipsPRA,
+ "filterCP0Write: Mask: %lx, Inverse Mask: %lx, write Val: %x, "
+ "current val: %lx, written val: %x\n",
+ miscRegFile_WriteMask[misc_reg][reg_sel],
+ ~miscRegFile_WriteMask[misc_reg][reg_sel],
+ val, miscRegFile[misc_reg][reg_sel], retVal);
return retVal;
}
void
@@ -526,7 +562,7 @@ MiscRegFile::scheduleCP0Update(int delay)
//schedule UPDATE
CP0Event *cp0_event = new CP0Event(this, cpu, UpdateCP0);
- cp0_event->schedule(curTick + cpu->ticks(delay));
+ cpu->schedule(cp0_event, curTick + cpu->ticks(delay));
}
}
@@ -560,7 +596,7 @@ MiscRegFile::updateCPU()
}
MiscRegFile::CP0Event::CP0Event(CP0 *_cp0, BaseCPU *_cpu, CP0EventType e_type)
- : Event(&mainEventQueue, CPU_Tick_Pri), cp0(_cp0), cpu(_cpu), cp0EventType(e_type)
+ : Event(CPU_Tick_Pri), cp0(_cp0), cpu(_cpu), cp0EventType(e_type)
{ }
void
@@ -585,10 +621,7 @@ MiscRegFile::CP0Event::description() const
void
MiscRegFile::CP0Event::scheduleEvent(int delay)
{
- if (squashed())
- reschedule(curTick + cpu->ticks(delay));
- else if (!scheduled())
- schedule(curTick + cpu->ticks(delay));
+ cpu->reschedule(this, curTick + cpu->ticks(delay), true);
}
void
diff --git a/src/arch/mips/regfile/misc_regfile.hh b/src/arch/mips/regfile/misc_regfile.hh
index 5f19579b3..c611d94cc 100644
--- a/src/arch/mips/regfile/misc_regfile.hh
+++ b/src/arch/mips/regfile/misc_regfile.hh
@@ -75,7 +75,8 @@ namespace MipsISA
void clear(unsigned tid_or_vpn = 0);
- void reset(std::string core_name, unsigned num_threads, unsigned num_vpes, BaseCPU *_cpu);
+ void reset(std::string core_name, unsigned num_threads,
+ unsigned num_vpes, BaseCPU *_cpu);
void expandForMultithreading(unsigned num_threads, unsigned num_vpes);
@@ -98,7 +99,8 @@ namespace MipsISA
MiscReg filterCP0Write(int misc_reg, int reg_sel, const MiscReg &val);
void setRegMask(int misc_reg, const MiscReg &val, unsigned tid = 0);
- void setRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid = 0);
+ void setRegNoEffect(int misc_reg, const MiscReg &val,
+ unsigned tid = 0);
//template <class TC>
void setReg(int misc_reg, const MiscReg &val,
@@ -160,8 +162,6 @@ namespace MipsISA
static std::string miscRegNames[NumMiscRegs];
};
-
- inline std::string getMiscRegName(unsigned reg_idx);
} // namespace MipsISA
#endif
diff --git a/src/arch/mips/regfile/regfile.cc b/src/arch/mips/regfile/regfile.cc
index 996c14f14..a1c8eab6a 100644
--- a/src/arch/mips/regfile/regfile.cc
+++ b/src/arch/mips/regfile/regfile.cc
@@ -193,7 +193,7 @@ RegFile::setNextNPC(Addr val)
}
void
-RegFile::serialize(std::ostream &os)
+RegFile::serialize(EventManager *em, std::ostream &os)
{
intRegFile.serialize(os);
//SERIALIZE_ARRAY(floatRegFile, NumFloatRegs);
@@ -207,7 +207,8 @@ RegFile::serialize(std::ostream &os)
}
void
-RegFile::unserialize(Checkpoint *cp, const std::string &section)
+RegFile::unserialize(EventManager *em, Checkpoint *cp,
+ const std::string &section)
{
intRegFile.unserialize(cp, section);
//UNSERIALIZE_ARRAY(floatRegFile);
diff --git a/src/arch/mips/regfile/regfile.hh b/src/arch/mips/regfile/regfile.hh
index 8304b7cda..ebf793396 100644
--- a/src/arch/mips/regfile/regfile.hh
+++ b/src/arch/mips/regfile/regfile.hh
@@ -41,22 +41,23 @@
//#include "cpu/base.hh"
#include "sim/faults.hh"
-class Checkpoint;
class BaseCPU;
+class Checkpoint;
+class EventManager;
namespace MipsISA
{
class RegFile {
protected:
- Addr pc; // program counter
- Addr npc; // next-cycle program counter
- Addr nnpc; // next-next-cycle program counter
+ 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
- IntRegFile intRegFile; // (signed) integer register file
- FloatRegFile floatRegFile; // floating point register file
- MiscRegFile miscRegFile; // control register file
+ IntRegFile intRegFile; // (signed) integer register file
+ FloatRegFile floatRegFile; // floating point register file
+ MiscRegFile miscRegFile; // control register file
public:
void clear();
@@ -99,12 +100,9 @@ namespace MipsISA
Addr readNextNPC();
void setNextNPC(Addr val);
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
-
- void changeContext(RegContextParam param, RegContextVal val)
- {
- }
+ void serialize(EventManager *em, std::ostream &os);
+ void unserialize(EventManager *em, Checkpoint *cp,
+ const std::string &section);
};
diff --git a/src/arch/mips/stacktrace.cc b/src/arch/mips/stacktrace.cc
index 6c6f6bb3c..04a9a0f18 100644
--- a/src/arch/mips/stacktrace.cc
+++ b/src/arch/mips/stacktrace.cc
@@ -70,8 +70,6 @@ ProcessInfo::ProcessInfo(ThreadContext *_tc)
// if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
// panic("thread info not compiled into kernel\n");
// name_off = vp->readGtoH<int32_t>(addr);
-
- tc->delVirtPort(vp);
}
Addr
@@ -87,7 +85,6 @@ ProcessInfo::task(Addr ksp) const
vp = tc->getVirtPort();
tsk = vp->readGtoH<Addr>(base + task_off);
- tc->delVirtPort(vp);
return tsk;
}
@@ -105,7 +102,6 @@ ProcessInfo::pid(Addr ksp) const
vp = tc->getVirtPort();
pd = vp->readGtoH<uint16_t>(task + pid_off);
- tc->delVirtPort(vp);
return pd;
}
@@ -163,7 +159,7 @@ StackTrace::trace(ThreadContext *_tc, bool is_call)
// }
// SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
-// Addr ksp = tc->readIntReg(TheISA::StackPointerReg);
+// Addr ksp = tc->readIntReg(MipsISA::StackPointerReg);
// Addr bottom = ksp & ~0x3fff;
// Addr addr;
diff --git a/src/arch/mips/stacktrace.hh b/src/arch/mips/stacktrace.hh
index e2424523f..4c02cc86c 100644
--- a/src/arch/mips/stacktrace.hh
+++ b/src/arch/mips/stacktrace.hh
@@ -61,7 +61,7 @@ class ProcessInfo
class StackTrace
{
protected:
- typedef TheISA::MachInst MachInst;
+ typedef MipsISA::MachInst MachInst;
private:
ThreadContext *tc;
std::vector<Addr> stack;
diff --git a/src/arch/mips/system.cc b/src/arch/mips/system.cc
index 605acfe32..73bc33161 100755
--- a/src/arch/mips/system.cc
+++ b/src/arch/mips/system.cc
@@ -134,9 +134,9 @@ MipsSystem::~MipsSystem()
* 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
+ * 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
@@ -185,7 +185,7 @@ MipsSystem::setMipsAccess(Addr access)
{
Addr addr = 0;
if (consoleSymtab->findAddress("m5MipsAccess", addr)) {
- // virtPort.write(addr, htog(EV5::Phys2K0Seg(access)));
+ // virtPort.write(addr, htog(AlphaISA::Phys2K0Seg(access)));
} else
panic("could not find m5MipsAccess\n");
}
diff --git a/src/arch/mips/tlb.cc b/src/arch/mips/tlb.cc
index d78aefab4..eac44eba8 100644
--- a/src/arch/mips/tlb.cc
+++ b/src/arch/mips/tlb.cc
@@ -59,7 +59,7 @@ using namespace MipsISA;
// MIPS TLB
//
-#define MODE2MASK(X) (1 << (X))
+#define MODE2MASK(X) (1 << (X))
TLB::TLB(const Params *p)
: BaseTLB(p), size(p->size), nlu(0)
@@ -91,7 +91,7 @@ TLB::lookup(Addr vpn, uint8_t asn) const
Addr Mask = pte->Mask;
Addr InvMask = ~Mask;
Addr VPN = pte->VPN;
- // warn("Valid: %d - %d\n",pte->V0,pte->V1);
+ // warn("Valid: %d - %d\n",pte->V0,pte->V1);
if(((vpn & InvMask) == (VPN & InvMask)) && (pte->G || (asn == pte->asid)))
{ // We have a VPN + ASID Match
retval = pte;
@@ -149,7 +149,7 @@ TLB::checkCacheability(RequestPtr &req)
// or by the TLB entry
if((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) {
// mark request as uncacheable
- req->setFlags(req->getFlags() | UNCACHEABLE);
+ req->setFlags(Request::UNCACHEABLE);
}
return NoFault;
}
@@ -310,7 +310,7 @@ TLB::regStats()
}
Fault
-ITB::translate(RequestPtr &req, ThreadContext *tc)
+ITB::translateAtomic(RequestPtr req, ThreadContext *tc)
{
#if !FULL_SYSTEM
Process * p = tc->getProcessPtr();
@@ -389,7 +389,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
}
else
{// Ok, this is really a match, set paddr
- // hits++;
+ // hits++;
Addr PAddr;
if(EvenOdd == 0){
PAddr = pte->PFN0;
@@ -406,7 +406,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
}
else
{ // Didn't find any match, return a TLB Refill Exception
- // misses++;
+ // misses++;
ItbRefillFault *Flt=new ItbRefillFault();
/* EntryHi VPN, ASID fields must be set */
Flt->EntryHi_Asid = Asid;
@@ -426,8 +426,16 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
#endif
}
+void
+ITB::translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation)
+{
+ assert(translation);
+ translation->finish(translateAtomic(req, tc), req, tc, false);
+}
+
Fault
-DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
+DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write)
{
#if !FULL_SYSTEM
Process * p = tc->getProcessPtr();
@@ -494,7 +502,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
if(Valid == false)
{//Invalid entry
- // invalids++;
+ // invalids++;
DtbInvalidFault *Flt = new DtbInvalidFault();
/* EntryHi VPN, ASID fields must be set */
Flt->EntryHi_Asid = Asid;
@@ -512,7 +520,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
}
else
{// Ok, this is really a match, set paddr
- // hits++;
+ // hits++;
if(!Dirty)
{
TLBModifiedFault *Flt = new TLBModifiedFault();
@@ -544,7 +552,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
}
else
{ // Didn't find any match, return a TLB Refill Exception
- // misses++;
+ // misses++;
DtbRefillFault *Flt=new DtbRefillFault();
/* EntryHi VPN, ASID fields must be set */
Flt->EntryHi_Asid = Asid;
@@ -564,6 +572,14 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
#endif
}
+void
+DTB::translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation, bool write)
+{
+ assert(translation);
+ translation->finish(translateAtomic(req, tc, write), req, tc, write);
+}
+
///////////////////////////////////////////////////////////////////////
//
// Mips ITB
@@ -577,19 +593,19 @@ ITB::ITB(const Params *p)
// ITB::regStats()
// {
// /* hits - causes failure for some reason
-// .name(name() + ".hits")
-// .desc("ITB hits");
+// .name(name() + ".hits")
+// .desc("ITB hits");
// misses
-// .name(name() + ".misses")
-// .desc("ITB misses");
+// .name(name() + ".misses")
+// .desc("ITB misses");
// acv
-// .name(name() + ".acv")
-// .desc("ITB acv");
+// .name(name() + ".acv")
+// .desc("ITB acv");
// accesses
-// .name(name() + ".accesses")
-// .desc("ITB accesses");
+// .name(name() + ".accesses")
+// .desc("ITB accesses");
-// accesses = hits + misses + invalids; */
+// accesses = hits + misses + invalids; */
// }
diff --git a/src/arch/mips/tlb.hh b/src/arch/mips/tlb.hh
index 4333777ff..dc0babf9a 100644
--- a/src/arch/mips/tlb.hh
+++ b/src/arch/mips/tlb.hh
@@ -68,6 +68,9 @@ struct TlbEntry
return _pageStart;
}
+ void
+ updateVaddr(Addr new_vaddr) {}
+
void serialize(std::ostream &os)
{
SERIALIZE_SCALAR(_pageStart);
@@ -84,23 +87,23 @@ class TLB : public BaseTLB
{
protected:
typedef std::multimap<Addr, int> PageTable;
- PageTable lookupTable; // Quick lookup into page table
+ PageTable lookupTable; // Quick lookup into page table
- MipsISA::PTE *table; // the Page Table
- int size; // TLB Size
- int nlu; // not last used entry (for replacement)
+ MipsISA::PTE *table; // the Page Table
+ int size; // TLB Size
+ int nlu; // not last used entry (for replacement)
void nextnlu() { if (++nlu >= size) nlu = 0; }
MipsISA::PTE *lookup(Addr vpn, uint8_t asn) const;
- 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;
+ 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 invalids;
@@ -142,7 +145,9 @@ class ITB : public TLB {
typedef MipsTLBParams Params;
ITB(const Params *p);
- Fault translate(RequestPtr &req, ThreadContext *tc);
+ Fault translateAtomic(RequestPtr req, ThreadContext *tc);
+ void translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation);
};
class DTB : public TLB {
@@ -150,7 +155,10 @@ class DTB : public TLB {
typedef MipsTLBParams Params;
DTB(const Params *p);
- Fault translate(RequestPtr &req, ThreadContext *tc, bool write = false);
+ Fault translateAtomic(RequestPtr req, ThreadContext *tc,
+ bool write = false);
+ void translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation, bool write = false);
};
class UTB : public ITB, public DTB {
diff --git a/src/arch/mips/types.hh b/src/arch/mips/types.hh
index 4208cb2d8..b459d9e14 100644
--- a/src/arch/mips/types.hh
+++ b/src/arch/mips/types.hh
@@ -60,9 +60,6 @@ namespace MipsISA
MiscReg ctrlreg;
} AnyReg;
- typedef int RegContextParam;
- typedef int RegContextVal;
-
//used in FP convert & round function
enum ConvertType{
SINGLE_TO_DOUBLE,
diff --git a/src/arch/mips/utility.cc b/src/arch/mips/utility.cc
index c254811fa..5908caf68 100644
--- a/src/arch/mips/utility.cc
+++ b/src/arch/mips/utility.cc
@@ -59,10 +59,9 @@ getArgument(ThreadContext *tc, int number, bool fp)
return tc->readIntReg(ArgumentReg[number]);
} else {
Addr sp = tc->readIntReg(StackPointerReg);
- VirtualPort *vp = tc->getVirtPort(tc);
+ VirtualPort *vp = tc->getVirtPort();
uint64_t arg = vp->read<uint64_t>(sp +
(number-NumArgumentRegs) * sizeof(uint64_t));
- tc->delVirtPort(vp);
return arg;
}
#else
@@ -146,7 +145,7 @@ genCCVector(uint32_t fcsr, int cc_num, uint32_t cc_val)
{
int cc_idx = (cc_num == 0) ? 23 : cc_num + 24;
- fcsr = bits(fcsr, 31, cc_idx + 1) << cc_idx + 1 |
+ fcsr = bits(fcsr, 31, cc_idx + 1) << (cc_idx + 1) |
cc_val << cc_idx |
bits(fcsr, cc_idx - 1, 0);
@@ -260,7 +259,7 @@ zeroRegisters(CPU *cpu)
void
startupCPU(ThreadContext *tc, int cpuId)
{
- tc->activate(0/*tc->getThreadNum()*/);
+ tc->activate(0/*tc->threadId()*/);
}
} // namespace MipsISA
diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript
index a86c00250..940cf2076 100644
--- a/src/arch/sparc/SConscript
+++ b/src/arch/sparc/SConscript
@@ -44,11 +44,14 @@ if env['TARGET_ISA'] == 'sparc':
Source('utility.cc')
SimObject('SparcTLB.py')
- TraceFlag('Sparc')
+ TraceFlag('Sparc', "Generic SPARC ISA stuff")
+ TraceFlag('RegisterWindows', "Register window manipulation")
if env['FULL_SYSTEM']:
SimObject('SparcSystem.py')
+ SimObject('SparcInterrupts.py')
+ Source('interrupts.cc')
Source('stacktrace.cc')
Source('system.cc')
Source('ua2005.cc')
diff --git a/src/arch/sparc/SparcInterrupts.py b/src/arch/sparc/SparcInterrupts.py
new file mode 100644
index 000000000..2cc964c2d
--- /dev/null
+++ b/src/arch/sparc/SparcInterrupts.py
@@ -0,0 +1,33 @@
+# Copyright (c) 2008 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+from m5.SimObject import SimObject
+
+class SparcInterrupts(SimObject):
+ type = 'SparcInterrupts'
+ cxx_class = 'SparcISA::Interrupts'
diff --git a/src/arch/sparc/SparcTLB.py b/src/arch/sparc/SparcTLB.py
index 2d0257cd7..6758d612a 100644
--- a/src/arch/sparc/SparcTLB.py
+++ b/src/arch/sparc/SparcTLB.py
@@ -28,21 +28,20 @@
from m5.SimObject import SimObject
from m5.params import *
-class SparcTLB(SimObject):
+
+from BaseTLB import BaseTLB
+
+class SparcTLB(BaseTLB):
type = 'SparcTLB'
abstract = True
size = Param.Int("TLB size")
class SparcDTB(SparcTLB):
type = 'SparcDTB'
- cxx_namespace = 'SparcISA'
- cxx_class = 'DTB'
-
+ cxx_class = 'SparcISA::DTB'
size = 64
class SparcITB(SparcTLB):
type = 'SparcITB'
- cxx_namespace = 'SparcISA'
- cxx_class = 'ITB'
-
+ cxx_class = 'SparcISA::ITB'
size = 64
diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc
index e201cef95..9c189d164 100644
--- a/src/arch/sparc/faults.cc
+++ b/src/arch/sparc/faults.cc
@@ -546,7 +546,7 @@ void SparcFaultBase::invoke(ThreadContext * tc)
doNormalFault(tc, trapType(), true);
getHyperVector(tc, PC, NPC, 2);
} else if (level == Hyperprivileged ||
- level == Privileged && trapType() >= 384) {
+ (level == Privileged && trapType() >= 384)) {
doNormalFault(tc, trapType(), true);
getHyperVector(tc, PC, NPC, trapType());
} else {
diff --git a/src/arch/sparc/floatregfile.cc b/src/arch/sparc/floatregfile.cc
index e1b5ea7c8..2d1af2218 100644
--- a/src/arch/sparc/floatregfile.cc
+++ b/src/arch/sparc/floatregfile.cc
@@ -41,20 +41,6 @@ using namespace std;
class Checkpoint;
-string SparcISA::getFloatRegName(RegIndex index)
-{
- static std::string floatRegName[NumFloatRegs] =
- {"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
- "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
- "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
- "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
- "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63"};
- return floatRegName[index];
-}
-
void FloatRegFile::clear()
{
memset(regSpace, 0, sizeof(regSpace));
@@ -75,7 +61,8 @@ FloatReg FloatRegFile::readReg(int floatReg, int width)
result32 = htog(result32);
memcpy(&fresult32, &result32, sizeof(result32));
result = fresult32;
- DPRINTF(Sparc, "Read FP32 register %d = [%f]0x%x\n", floatReg, result, result32);
+ DPRINTF(FloatRegs, "Read FP32 register %d = [%f]0x%x\n",
+ floatReg, result, result32);
break;
case DoubleWidth:
uint64_t result64;
@@ -84,7 +71,8 @@ FloatReg FloatRegFile::readReg(int floatReg, int width)
result64 = htog(result64);
memcpy(&fresult64, &result64, sizeof(result64));
result = fresult64;
- DPRINTF(Sparc, "Read FP64 register %d = [%f]0x%x\n", floatReg, result, result64);
+ DPRINTF(FloatRegs, "Read FP64 register %d = [%f]0x%x\n",
+ floatReg, result, result64);
break;
case QuadWidth:
panic("Quad width FP not implemented.");
@@ -107,13 +95,15 @@ FloatRegBits FloatRegFile::readRegBits(int floatReg, int width)
uint32_t result32;
memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
result = htog(result32);
- DPRINTF(Sparc, "Read FP32 bits register %d = 0x%x\n", floatReg, result);
+ DPRINTF(FloatRegs, "Read FP32 bits register %d = 0x%x\n",
+ floatReg, result);
break;
case DoubleWidth:
uint64_t result64;
memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
result = htog(result64);
- DPRINTF(Sparc, "Read FP64 bits register %d = 0x%x\n", floatReg, result);
+ DPRINTF(FloatRegs, "Read FP64 bits register %d = 0x%x\n",
+ floatReg, result);
break;
case QuadWidth:
panic("Quad width FP not implemented.");
@@ -141,14 +131,16 @@ Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width)
memcpy(&result32, &fresult32, sizeof(result32));
result32 = gtoh(result32);
memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
- DPRINTF(Sparc, "Write FP64 register %d = 0x%x\n", floatReg, result32);
+ DPRINTF(FloatRegs, "Write FP64 register %d = 0x%x\n",
+ floatReg, result32);
break;
case DoubleWidth:
fresult64 = val;
memcpy(&result64, &fresult64, sizeof(result64));
result64 = gtoh(result64);
memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
- DPRINTF(Sparc, "Write FP64 register %d = 0x%x\n", floatReg, result64);
+ DPRINTF(FloatRegs, "Write FP64 register %d = 0x%x\n",
+ floatReg, result64);
break;
case QuadWidth:
panic("Quad width FP not implemented.");
@@ -171,12 +163,14 @@ Fault FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width)
case SingleWidth:
result32 = gtoh((uint32_t)val);
memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
- DPRINTF(Sparc, "Write FP64 bits register %d = 0x%x\n", floatReg, result32);
+ DPRINTF(FloatRegs, "Write FP64 bits register %d = 0x%x\n",
+ floatReg, result32);
break;
case DoubleWidth:
result64 = gtoh((uint64_t)val);
memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
- DPRINTF(Sparc, "Write FP64 bits register %d = 0x%x\n", floatReg, result64);
+ DPRINTF(FloatRegs, "Write FP64 bits register %d = 0x%x\n",
+ floatReg, result64);
break;
case QuadWidth:
panic("Quad width FP not implemented.");
diff --git a/src/arch/sparc/floatregfile.hh b/src/arch/sparc/floatregfile.hh
index 72803a5e0..265e71b4a 100644
--- a/src/arch/sparc/floatregfile.hh
+++ b/src/arch/sparc/floatregfile.hh
@@ -42,8 +42,6 @@ class Checkpoint;
namespace SparcISA
{
- std::string getFloatRegName(RegIndex);
-
const int NumFloatArchRegs = 64;
const int NumFloatRegs = 64;
diff --git a/src/arch/sparc/interrupts.cc b/src/arch/sparc/interrupts.cc
new file mode 100644
index 000000000..96d61e559
--- /dev/null
+++ b/src/arch/sparc/interrupts.cc
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2008 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "arch/sparc/interrupts.hh"
+
+SparcISA::Interrupts *
+SparcInterruptsParams::create()
+{
+ return new SparcISA::Interrupts(this);
+}
diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh
index 4ad3385fb..ec930e2b0 100644
--- a/src/arch/sparc/interrupts.hh
+++ b/src/arch/sparc/interrupts.hh
@@ -35,25 +35,43 @@
#include "arch/sparc/faults.hh"
#include "arch/sparc/isa_traits.hh"
#include "cpu/thread_context.hh"
+#include "params/SparcInterrupts.hh"
+#include "sim/sim_object.hh"
namespace SparcISA
{
-class Interrupts
+class Interrupts : public SimObject
{
-
private:
+ BaseCPU * cpu;
uint64_t interrupts[NumInterruptTypes];
uint64_t intStatus;
public:
- Interrupts()
+
+ void
+ setCPU(BaseCPU * _cpu)
+ {
+ cpu = _cpu;
+ }
+
+ typedef SparcInterruptsParams Params;
+
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+ Interrupts(Params * p) : SimObject(p), cpu(NULL)
{
- clear_all();
+ clearAll();
}
- int InterruptLevel(uint64_t softint)
+ int
+ InterruptLevel(uint64_t softint)
{
if (softint & 0x10000 || softint & 0x1)
return 14;
@@ -66,7 +84,8 @@ class Interrupts
return 0;
}
- void post(int int_num, int index)
+ void
+ post(int int_num, int index)
{
DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
assert(int_num >= 0 && int_num < NumInterruptTypes);
@@ -76,7 +95,8 @@ class Interrupts
intStatus |= ULL(1) << int_num;
}
- void clear(int int_num, int index)
+ void
+ clear(int int_num, int index)
{
DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
assert(int_num >= 0 && int_num < NumInterruptTypes);
@@ -87,7 +107,8 @@ class Interrupts
intStatus &= ~(ULL(1) << int_num);
}
- void clear_all()
+ void
+ clearAll()
{
for (int i = 0; i < NumInterruptTypes; ++i) {
interrupts[i] = 0;
@@ -95,12 +116,14 @@ class Interrupts
intStatus = 0;
}
- bool check_interrupts(ThreadContext * tc) const
+ bool
+ checkInterrupts(ThreadContext *tc) const
{
return intStatus;
}
- Fault getInterrupt(ThreadContext * tc)
+ Fault
+ getInterrupt(ThreadContext *tc)
{
int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
@@ -143,8 +166,8 @@ class Interrupts
return new DevMondo;
}
if (interrupts[IT_SOFT_INT]) {
- return new
- InterruptLevelN(InterruptLevel(interrupts[IT_SOFT_INT]));
+ int level = InterruptLevel(interrupts[IT_SOFT_INT]);
+ return new InterruptLevelN(level);
}
if (interrupts[IT_RES_ERROR]) {
@@ -155,24 +178,28 @@ class Interrupts
return NoFault;
}
- void updateIntrInfo(ThreadContext * tc)
+ void
+ updateIntrInfo(ThreadContext *tc)
{
}
- uint64_t get_vec(int int_num)
+ uint64_t
+ get_vec(int int_num)
{
assert(int_num >= 0 && int_num < NumInterruptTypes);
return interrupts[int_num];
}
- void serialize(std::ostream &os)
+ void
+ serialize(std::ostream &os)
{
SERIALIZE_ARRAY(interrupts,NumInterruptTypes);
SERIALIZE_SCALAR(intStatus);
}
- void unserialize(Checkpoint *cp, const std::string &section)
+ void
+ unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes);
UNSERIALIZE_SCALAR(intStatus);
diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc
index 39a613a0d..54c30d1cc 100644
--- a/src/arch/sparc/intregfile.cc
+++ b/src/arch/sparc/intregfile.cc
@@ -41,138 +41,40 @@ using namespace std;
class Checkpoint;
-string SparcISA::getIntRegName(RegIndex index)
-{
- static std::string intRegName[NumIntArchRegs] =
- {"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
- "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
- "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
- "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7"};
- return intRegName[index];
-}
-
-int IntRegFile::flattenIndex(int reg)
-{
- int flatIndex = offset[reg >> FrameOffsetBits]
- | (reg & FrameOffsetMask);
- DPRINTF(Sparc, "Flattened index %d into %d.\n", reg, flatIndex);
- return flatIndex;
-}
-
void IntRegFile::clear()
{
- int x;
- for (x = 0; x < MaxGL; x++)
- memset(regGlobals[x], 0, sizeof(IntReg) * RegsPerFrame);
- for(int x = 0; x < 2 * NWindows; x++)
- memset(regSegments[x], 0, sizeof(IntReg) * RegsPerFrame);
memset(regs, 0, sizeof(IntReg) * NumIntRegs);
}
IntRegFile::IntRegFile()
{
- offset[Globals] = 0;
- regView[Globals] = regGlobals[0];
- setCWP(0);
clear();
}
IntReg IntRegFile::readReg(int intReg)
{
- DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, regs[intReg]);
+ DPRINTF(IntRegs, "Read register %d = 0x%x\n", intReg, regs[intReg]);
return regs[intReg];
- /* XXX Currently not used. When used again regView/offset need to be
- * serialized!
- IntReg val;
- if(intReg < NumIntArchRegs)
- val = regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask];
- else if((intReg -= NumIntArchRegs) < NumMicroIntRegs)
- val = microRegs[intReg];
- else
- panic("Tried to read non-existant integer register %d, %d\n",
- NumIntArchRegs + NumMicroIntRegs + intReg, intReg);
-
- DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val);
- return val;
- */
}
void IntRegFile::setReg(int intReg, const IntReg &val)
{
if(intReg)
{
- DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val);
+ DPRINTF(IntRegs, "Wrote register %d = 0x%x\n", intReg, val);
regs[intReg] = val;
}
return;
- /* XXX Currently not used. When used again regView/offset need to be
- * serialized!
- if(intReg)
- {
- DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val);
- if(intReg < NumIntArchRegs)
- regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val;
- else if((intReg -= NumIntArchRegs) < NumMicroIntRegs)
- microRegs[intReg] = val;
- else
- panic("Tried to set non-existant integer register\n");
- } */
-}
-
-//This doesn't effect the actual CWP register.
-//It's purpose is to adjust the view of the register file
-//to what it would be if CWP = cwp.
-void IntRegFile::setCWP(int cwp)
-{
- int index = ((NWindows - cwp) % NWindows) * 2;
- if (index < 0)
- panic("Index less than 0. cwp=%d nwin=%d\n", cwp, NWindows);
- offset[Outputs] = FrameOffset + (index * RegsPerFrame);
- offset[Locals] = FrameOffset + ((index+1) * RegsPerFrame);
- offset[Inputs] = FrameOffset +
- (((index+2) % (NWindows * 2)) * RegsPerFrame);
- regView[Outputs] = regSegments[index];
- regView[Locals] = regSegments[index+1];
- regView[Inputs] = regSegments[(index+2) % (NWindows * 2)];
-
- DPRINTF(Sparc, "Changed the CWP value to %d\n", cwp);
-}
-
-void IntRegFile::setGlobals(int gl)
-{
- DPRINTF(Sparc, "Now using %d globals\n", gl);
-
- regView[Globals] = regGlobals[gl];
- offset[Globals] = RegGlobalOffset + gl * RegsPerFrame;
-
- if (regView[Globals] == regView[Inputs] ||
- regView[Globals] == regView[Locals] ||
- regView[Globals] == regView[Outputs] )
- panic("Two register arrays set to the same thing!\n");
}
void IntRegFile::serialize(std::ostream &os)
{
SERIALIZE_ARRAY(regs, NumIntRegs);
SERIALIZE_ARRAY(microRegs, NumMicroIntRegs);
-
- /* the below doesn't seem needed unless gabe makes regview work*/
- unsigned int x;
- for(x = 0; x < MaxGL; x++)
- SERIALIZE_ARRAY(regGlobals[x], RegsPerFrame);
- for(x = 0; x < 2 * NWindows; x++)
- SERIALIZE_ARRAY(regSegments[x], RegsPerFrame);
}
void IntRegFile::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ARRAY(regs, NumIntRegs);
UNSERIALIZE_ARRAY(microRegs, NumMicroIntRegs);
-
- /* the below doesn't seem needed unless gabe makes regview work*/
- unsigned int x;
- for(x = 0; x < MaxGL; x++)
- UNSERIALIZE_ARRAY(regGlobals[x], RegsPerFrame);
- for(unsigned int x = 0; x < 2 * NWindows; x++)
- UNSERIALIZE_ARRAY(regSegments[x], RegsPerFrame);
}
diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh
index 83ef1d17b..f669f6b0d 100644
--- a/src/arch/sparc/intregfile.hh
+++ b/src/arch/sparc/intregfile.hh
@@ -42,53 +42,17 @@ class Checkpoint;
namespace SparcISA
{
- class RegFile;
-
- //This function translates integer register file indices into names
- std::string getIntRegName(RegIndex);
-
const int NumIntArchRegs = 32;
const int NumIntRegs = (MaxGL + 1) * 8 + NWindows * 16 + NumMicroIntRegs;
class IntRegFile
{
- private:
- friend class RegFile;
protected:
- //The number of bits needed to index into each 8 register frame
- static const int FrameOffsetBits = 3;
- //The number of bits to choose between the 4 sets of 8 registers
- static const int FrameNumBits = 2;
-
- //The number of registers per "frame" (8)
- static const int RegsPerFrame = 1 << FrameOffsetBits;
- //A mask to get the frame number
- static const uint64_t FrameNumMask =
- (FrameNumBits == sizeof(int)) ?
- (unsigned int)(-1) :
- (1 << FrameNumBits) - 1;
- static const uint64_t FrameOffsetMask =
- (FrameOffsetBits == sizeof(int)) ?
- (unsigned int)(-1) :
- (1 << FrameOffsetBits) - 1;
-
- IntReg regGlobals[MaxGL+1][RegsPerFrame];
- IntReg regSegments[2 * NWindows][RegsPerFrame];
IntReg microRegs[NumMicroIntRegs];
IntReg regs[NumIntRegs];
- enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames};
-
- IntReg * regView[NumFrames];
-
- static const int RegGlobalOffset = 0;
- static const int FrameOffset = (MaxGL + 1) * RegsPerFrame;
- int offset[NumFrames];
-
public:
- int flattenIndex(int reg);
-
void clear();
IntRegFile();
@@ -100,14 +64,6 @@ namespace SparcISA
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
-
- protected:
- //This doesn't effect the actual CWP register.
- //It's purpose is to adjust the view of the register file
- //to what it would be if CWP = cwp.
- void setCWP(int cwp);
-
- void setGlobals(int gl);
};
}
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index c35b231ff..e34ca033f 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -1231,16 +1231,14 @@ decode OP default Unknown::unknown()
0x23: Load::lddf({{Frd.udw = Mem.udw;}});
0x24: Store::stf({{Mem.uw = Frds.uw;}});
0x25: decode RD {
- 0x0: Store::stfsr({{fault = checkFpEnableFault(xc);
- if (fault)
- return fault;
- Mem.uw = Fsr<31:0>;
- Fsr = insertBits(Fsr,16,14,0);}});
- 0x1: Store::stxfsr({{fault = checkFpEnableFault(xc);
- if (fault)
- return fault;
- Mem.udw = Fsr;
- Fsr = insertBits(Fsr,16,14,0);}});
+ 0x0: StoreFsr::stfsr({{fault = checkFpEnableFault(xc);
+ if (fault)
+ return fault;
+ Mem.uw = Fsr<31:0>;}});
+ 0x1: StoreFsr::stxfsr({{fault = checkFpEnableFault(xc);
+ if (fault)
+ return fault;
+ Mem.udw = Fsr;}});
default: FailUnimpl::stfsrOther();
}
0x26: stqf({{fault = new FpDisabled;}});
diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa
index e3c043cf3..c7bb3e435 100644
--- a/src/arch/sparc/isa/formats/mem/basicmem.isa
+++ b/src/arch/sparc/isa/formats/mem/basicmem.isa
@@ -108,6 +108,16 @@ def format Store(code, *opt_flags) {{
StoreFuncs, '', name, Name, 0, opt_flags)
}};
+def format StoreFsr(code, *opt_flags) {{
+ code = filterDoubles(code)
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doMemFormat(code,
+ StoreFuncs, '', name, Name, 0, opt_flags,
+ 'Fsr = insertBits(Fsr,16,14,0);')
+}};
+
def format TwinLoad(code, *opt_flags) {{
(header_output,
decoder_output,
diff --git a/src/arch/sparc/isa/formats/mem/swap.isa b/src/arch/sparc/isa/formats/mem/swap.isa
index 2ebe9aa15..046f89822 100644
--- a/src/arch/sparc/isa/formats/mem/swap.isa
+++ b/src/arch/sparc/isa/formats/mem/swap.isa
@@ -133,6 +133,7 @@ let {{
def format Swap(code, postacc_code, mem_flags, *opt_flags) {{
mem_flags = makeList(mem_flags)
+ mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
flags = string.join(mem_flags, '|')
(header_output,
@@ -144,6 +145,7 @@ def format Swap(code, postacc_code, mem_flags, *opt_flags) {{
def format SwapAlt(code, postacc_code, mem_flags, *opt_flags) {{
mem_flags = makeList(mem_flags)
+ mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
mem_flags.append("EXT_ASI")
flags = string.join(mem_flags, '|')
(header_output,
@@ -175,6 +177,7 @@ let {{
def format CasAlt(code, postacc_code, mem_flags, *opt_flags) {{
mem_flags = makeList(mem_flags)
+ mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
mem_flags.append("EXT_ASI")
flags = string.join(mem_flags, '|')
(header_output,
diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa
index 38cde9a50..31efb9cf6 100644
--- a/src/arch/sparc/isa/formats/mem/util.isa
+++ b/src/arch/sparc/isa/formats/mem/util.isa
@@ -264,11 +264,6 @@ def template StoreInitiateAcc {{
fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
EA, %(asi_val)s, 0);
}
- if(fault == NoFault)
- {
- //Write the resulting state to the execution context
- %(op_wb)s;
- }
return fault;
}
}};
@@ -277,6 +272,15 @@ def template StoreCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
+ Fault fault = NoFault;
+ %(op_decl)s;
+
+ %(op_rd)s;
+ %(postacc_code)s;
+ if (fault == NoFault)
+ {
+ %(op_wb)s;
+ }
return NoFault;
}
}};
@@ -314,10 +318,11 @@ let {{
# are split into ones that are available in priv and hpriv, and
# those that are only available in hpriv
AlternateASIPrivFaultCheck = '''
- if(!bits(Pstate,2,2) && !bits(Hpstate,2,2) && !AsiIsUnPriv((ASI)EXT_ASI) ||
- !bits(Hpstate,2,2) && AsiIsHPriv((ASI)EXT_ASI))
- fault = new PrivilegedAction;
- else if(AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2))
+ if ((!bits(Pstate,2,2) && !bits(Hpstate,2,2) &&
+ !AsiIsUnPriv((ASI)EXT_ASI)) ||
+ (!bits(Hpstate,2,2) && AsiIsHPriv((ASI)EXT_ASI)))
+ fault = new PrivilegedAction;
+ else if (AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2))
fault = new PrivilegedAction;
'''
diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh
index 133817eb5..501f2f990 100644
--- a/src/arch/sparc/isa_traits.hh
+++ b/src/arch/sparc/isa_traits.hh
@@ -66,18 +66,14 @@ namespace SparcISA
};
// semantically meaningful register indices
- const int ZeroReg = 0; // architecturally meaningful
+ const int ZeroReg = 0; // architecturally meaningful
// the rest of these depend on the ABI
- const int StackPointerReg = 14;
const int ReturnAddressReg = 31; // post call, precall is 15
- const int ReturnValueReg = 8; // Post return, 24 is pre-return.
+ const int StackPointerReg = 14;
const int FramePointerReg = 30;
- const int ArgumentReg[] = {8, 9, 10, 11, 12, 13};
- const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int);
-
// Some OS syscall use a second register (o1) to return a second value
- const int SyscallPseudoReturnReg = ArgumentReg[1];
+ const int SyscallPseudoReturnReg = 9;
//8K. This value is implmentation specific; and should probably
//be somewhere else.
diff --git a/src/arch/sparc/linux/linux.cc b/src/arch/sparc/linux/linux.cc
index 1211d5f65..102e5af3b 100644
--- a/src/arch/sparc/linux/linux.cc
+++ b/src/arch/sparc/linux/linux.cc
@@ -34,34 +34,34 @@
// open(2) flags translation table
OpenFlagTransTable SparcLinux::openFlagTable[] = {
#ifdef _MSC_VER
- { SparcLinux::TGT_O_RDONLY, _O_RDONLY },
- { SparcLinux::TGT_O_WRONLY, _O_WRONLY },
- { SparcLinux::TGT_O_RDWR, _O_RDWR },
- { SparcLinux::TGT_O_APPEND, _O_APPEND },
- { SparcLinux::TGT_O_CREAT, _O_CREAT },
- { SparcLinux::TGT_O_TRUNC, _O_TRUNC },
- { SparcLinux::TGT_O_EXCL, _O_EXCL },
+ { SparcLinux::TGT_O_RDONLY, _O_RDONLY },
+ { SparcLinux::TGT_O_WRONLY, _O_WRONLY },
+ { SparcLinux::TGT_O_RDWR, _O_RDWR },
+ { SparcLinux::TGT_O_APPEND, _O_APPEND },
+ { SparcLinux::TGT_O_CREAT, _O_CREAT },
+ { SparcLinux::TGT_O_TRUNC, _O_TRUNC },
+ { SparcLinux::TGT_O_EXCL, _O_EXCL },
#ifdef _O_NONBLOCK
- { SparcLinux::TGT_O_NONBLOCK, _O_NONBLOCK },
+ { SparcLinux::TGT_O_NONBLOCK, _O_NONBLOCK },
#endif
#ifdef _O_NOCTTY
- { SparcLinux::TGT_O_NOCTTY, _O_NOCTTY },
+ { SparcLinux::TGT_O_NOCTTY, _O_NOCTTY },
#endif
#ifdef _O_SYNC
- { SparcLinux::TGT_O_SYNC, _O_SYNC },
+ { SparcLinux::TGT_O_SYNC, _O_SYNC },
#endif
#else /* !_MSC_VER */
- { SparcLinux::TGT_O_RDONLY, O_RDONLY },
- { SparcLinux::TGT_O_WRONLY, O_WRONLY },
- { SparcLinux::TGT_O_RDWR, O_RDWR },
- { SparcLinux::TGT_O_APPEND, O_APPEND },
- { SparcLinux::TGT_O_CREAT, O_CREAT },
- { SparcLinux::TGT_O_TRUNC, O_TRUNC },
- { SparcLinux::TGT_O_EXCL, O_EXCL },
- { SparcLinux::TGT_O_NONBLOCK, O_NONBLOCK },
- { SparcLinux::TGT_O_NOCTTY, O_NOCTTY },
+ { SparcLinux::TGT_O_RDONLY, O_RDONLY },
+ { SparcLinux::TGT_O_WRONLY, O_WRONLY },
+ { SparcLinux::TGT_O_RDWR, O_RDWR },
+ { SparcLinux::TGT_O_APPEND, O_APPEND },
+ { SparcLinux::TGT_O_CREAT, O_CREAT },
+ { SparcLinux::TGT_O_TRUNC, O_TRUNC },
+ { SparcLinux::TGT_O_EXCL, O_EXCL },
+ { SparcLinux::TGT_O_NONBLOCK, O_NONBLOCK },
+ { SparcLinux::TGT_O_NOCTTY, O_NOCTTY },
#ifdef O_SYNC
- { SparcLinux::TGT_O_SYNC, O_SYNC },
+ { SparcLinux::TGT_O_SYNC, O_SYNC },
#endif
#endif /* _MSC_VER */
};
diff --git a/src/arch/sparc/linux/linux.hh b/src/arch/sparc/linux/linux.hh
index f396eb5cd..b1dc691ce 100644
--- a/src/arch/sparc/linux/linux.hh
+++ b/src/arch/sparc/linux/linux.hh
@@ -58,21 +58,21 @@ class SparcLinux : public Linux
static OpenFlagTransTable openFlagTable[];
- static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY
- static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY
- static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR
- static const int TGT_O_NONBLOCK = 0x00004000; //!< O_NONBLOCK
- static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND
- static const int TGT_O_CREAT = 0x00000200; //!< O_CREAT
- static const int TGT_O_TRUNC = 0x00000400; //!< O_TRUNC
- static const int TGT_O_EXCL = 0x00000800; //!< O_EXCL
- static const int TGT_O_NOCTTY = 0x00008000; //!< O_NOCTTY
- static const int TGT_O_SYNC = 0x00002000; //!< O_SYNC
-// static const int TGT_O_DRD = 0x00010000; //!< O_DRD
-// static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO
-// static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE
-// static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC
-// static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC
+ static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY
+ static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY
+ static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR
+ static const int TGT_O_NONBLOCK = 0x00004000; //!< O_NONBLOCK
+ static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND
+ static const int TGT_O_CREAT = 0x00000200; //!< O_CREAT
+ static const int TGT_O_TRUNC = 0x00000400; //!< O_TRUNC
+ static const int TGT_O_EXCL = 0x00000800; //!< O_EXCL
+ static const int TGT_O_NOCTTY = 0x00008000; //!< O_NOCTTY
+ static const int TGT_O_SYNC = 0x00002000; //!< O_SYNC
+// static const int TGT_O_DRD = 0x00010000; //!< O_DRD
+// static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO
+// static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE
+// static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC
+// static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC
static const int NUM_OPEN_FLAGS;
diff --git a/src/arch/sparc/linux/process.cc b/src/arch/sparc/linux/process.cc
index f4ec28c00..2078c1dce 100644
--- a/src/arch/sparc/linux/process.cc
+++ b/src/arch/sparc/linux/process.cc
@@ -47,7 +47,7 @@ using namespace SparcISA;
SyscallDesc*
SparcLinuxProcess::getDesc(int callnum)
{
- if (callnum < 0 || callnum > Num_Syscall_Descs)
+ if (callnum < 0 || callnum >= Num_Syscall_Descs)
return NULL;
return &syscallDescs[callnum];
}
@@ -55,7 +55,7 @@ SparcLinuxProcess::getDesc(int callnum)
SyscallDesc*
SparcLinuxProcess::getDesc32(int callnum)
{
- if (callnum < 0 || callnum > Num_Syscall32_Descs)
+ if (callnum < 0 || callnum >= Num_Syscall32_Descs)
return NULL;
return &syscall32Descs[callnum];
}
diff --git a/src/arch/sparc/linux/process.hh b/src/arch/sparc/linux/process.hh
index 06eee9235..a76b4b3b2 100644
--- a/src/arch/sparc/linux/process.hh
+++ b/src/arch/sparc/linux/process.hh
@@ -32,7 +32,6 @@
#define __SPARC_LINUX_PROCESS_HH__
#include "arch/sparc/linux/linux.hh"
-#include "arch/sparc/syscallreturn.hh"
#include "arch/sparc/process.hh"
#include "sim/process.hh"
diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc
index 03c8bafe2..8496fca13 100644
--- a/src/arch/sparc/linux/syscalls.cc
+++ b/src/arch/sparc/linux/syscalls.cc
@@ -29,7 +29,6 @@
*/
#include "arch/sparc/linux/process.hh"
-#include "arch/sparc/syscallreturn.hh"
#include "sim/syscall_emul.hh"
class LiveProcess;
@@ -42,7 +41,7 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
+ TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
@@ -60,9 +59,9 @@ SyscallReturn getresuidFunc(SyscallDesc *desc, int num,
LiveProcess *p, ThreadContext *tc)
{
const IntReg id = htog(100);
- Addr ruid = tc->getSyscallArg(0);
- Addr euid = tc->getSyscallArg(1);
- Addr suid = tc->getSyscallArg(2);
+ Addr ruid = p->getSyscallArg(tc, 0);
+ Addr euid = p->getSyscallArg(tc, 1);
+ Addr suid = p->getSyscallArg(tc, 2);
//Handle the EFAULT case
//Set the ruid
if(ruid)
@@ -106,7 +105,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = {
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", unimplementedFunc),
/* 16 */ SyscallDesc("lchown", unimplementedFunc), //32 bit
- /* 17 */ SyscallDesc("brk", obreakFunc),
+ /* 17 */ SyscallDesc("brk", brkFunc),
/* 18 */ SyscallDesc("perfctr", unimplementedFunc), //32 bit
/* 19 */ SyscallDesc("lseek", lseekFunc), //32 bit
/* 20 */ SyscallDesc("getpid", getpidFunc),
@@ -147,7 +146,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = {
/* 55 */ SyscallDesc("reboot", unimplementedFunc), //32 bit
/* 56 */ SyscallDesc("mmap2", unimplementedFunc), //32 bit
/* 57 */ SyscallDesc("symlink", unimplementedFunc),
- /* 58 */ SyscallDesc("readlink", unimplementedFunc), //32 bit
+ /* 58 */ SyscallDesc("readlink", readlinkFunc), //32 bit
/* 59 */ SyscallDesc("execve", unimplementedFunc), //32 bit
/* 60 */ SyscallDesc("umask", unimplementedFunc), //32 bit
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
@@ -208,7 +207,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = {
/* 116 */ SyscallDesc("gettimeofday", unimplementedFunc), //32 bit
/* 117 */ SyscallDesc("getrusage", unimplementedFunc), //32 bit
/* 118 */ SyscallDesc("getsockopt", unimplementedFunc),
- /* 119 */ SyscallDesc("getcwd", unimplementedFunc),
+ /* 119 */ SyscallDesc("getcwd", getcwdFunc),
/* 120 */ SyscallDesc("readv", unimplementedFunc),
/* 121 */ SyscallDesc("writev", unimplementedFunc),
/* 122 */ SyscallDesc("settimeofday", unimplementedFunc), //32 bit
@@ -225,7 +224,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = {
/* 133 */ SyscallDesc("sendto", unimplementedFunc),
/* 134 */ SyscallDesc("shutdown", unimplementedFunc),
/* 135 */ SyscallDesc("socketpair", unimplementedFunc),
- /* 136 */ SyscallDesc("mkdir", unimplementedFunc), //32 bit
+ /* 136 */ SyscallDesc("mkdir", mkdirFunc), //32 bit
/* 137 */ SyscallDesc("rmdir", unimplementedFunc),
/* 138 */ SyscallDesc("utimes", unimplementedFunc), //32 bit
/* 139 */ SyscallDesc("stat64", unimplementedFunc),
@@ -339,7 +338,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = {
/* 247 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), //32 bit
/* 248 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), //32 bit
/* 249 */ SyscallDesc("nanosleep", unimplementedFunc),
- /* 250 */ SyscallDesc("mremap", unimplementedFunc), //32 bit
+ /* 250 */ SyscallDesc("mremap", mremapFunc<Sparc32Linux>), //32 bit
/* 251 */ SyscallDesc("_sysctl", unimplementedFunc), //32 bit
/* 252 */ SyscallDesc("getsid", unimplementedFunc), //32 bit
/* 253 */ SyscallDesc("fdatasync", unimplementedFunc),
@@ -409,7 +408,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", chmodFunc<Linux>),
/* 16 */ SyscallDesc("lchown", unimplementedFunc),
- /* 17 */ SyscallDesc("brk", obreakFunc),
+ /* 17 */ SyscallDesc("brk", brkFunc),
/* 18 */ SyscallDesc("perfctr", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getpid", getpidFunc),
@@ -450,7 +449,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 55 */ SyscallDesc("reboot", unimplementedFunc),
/* 56 */ SyscallDesc("mmap2", unimplementedFunc),
/* 57 */ SyscallDesc("symlink", unimplementedFunc),
- /* 58 */ SyscallDesc("readlink", unimplementedFunc),
+ /* 58 */ SyscallDesc("readlink", readlinkFunc),
/* 59 */ SyscallDesc("execve", unimplementedFunc),
/* 60 */ SyscallDesc("umask", unimplementedFunc),
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
@@ -528,7 +527,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 133 */ SyscallDesc("sendto", unimplementedFunc),
/* 134 */ SyscallDesc("shutdown", unimplementedFunc),
/* 135 */ SyscallDesc("socketpair", unimplementedFunc),
- /* 136 */ SyscallDesc("mkdir", unimplementedFunc),
+ /* 136 */ SyscallDesc("mkdir", mkdirFunc),
/* 137 */ SyscallDesc("rmdir", unimplementedFunc),
/* 138 */ SyscallDesc("utimes", unimplementedFunc),
/* 139 */ SyscallDesc("stat64", unimplementedFunc),
@@ -642,7 +641,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 247 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
/* 248 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
/* 249 */ SyscallDesc("nanosleep", unimplementedFunc),
- /* 250 */ SyscallDesc("mremap", unimplementedFunc),
+ /* 250 */ SyscallDesc("mremap", mremapFunc<SparcLinux>),
/* 251 */ SyscallDesc("_sysctl", unimplementedFunc),
/* 252 */ SyscallDesc("getsid", unimplementedFunc),
/* 253 */ SyscallDesc("fdatasync", unimplementedFunc),
diff --git a/src/arch/sparc/syscallreturn.hh b/src/arch/sparc/microcode_rom.hh
index cf13fc3e8..e46000dcc 100644
--- a/src/arch/sparc/syscallreturn.hh
+++ b/src/arch/sparc/microcode_rom.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2008 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,37 +28,14 @@
* Authors: Gabe Black
*/
-#ifndef __ARCH_SPARC_SYSCALLRETURN_HH__
-#define __ARCH_SPARC_SYSCALLRETURN_HH__
+#ifndef __ARCH_SPARC_MICROCODE_ROM_HH__
+#define __ARCH_SPARC_MICROCODE_ROM_HH__
-#include <inttypes.h>
-
-#include "sim/syscallreturn.hh"
-#include "arch/sparc/regfile.hh"
-#include "cpu/thread_context.hh"
+#include "sim/microcode_rom.hh"
namespace SparcISA
{
- static inline void setSyscallReturn(SyscallReturn return_value,
- ThreadContext * tc)
- {
- // check for error condition. SPARC syscall convention is to
- // indicate success/failure in reg the carry bit of the ccr
- // and put the return value itself in the standard return value reg ().
- if (return_value.successful()) {
- // no error, clear XCC.C
- tc->setIntReg(NumIntArchRegs + 2,
- tc->readIntReg(NumIntArchRegs + 2) & 0xEE);
- //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) & 0xEE);
- tc->setIntReg(ReturnValueReg, return_value.value());
- } else {
- // got an error, set XCC.C
- tc->setIntReg(NumIntArchRegs + 2,
- tc->readIntReg(NumIntArchRegs + 2) | 0x11);
- //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) | 0x11);
- tc->setIntReg(ReturnValueReg, -return_value.value());
- }
- }
-};
+ using ::MicrocodeRom;
+}
-#endif
+#endif // __ARCH_SPARC_MICROCODE_ROM_HH__
diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc
index 7b9c73433..38eba3862 100644
--- a/src/arch/sparc/miscregfile.cc
+++ b/src/arch/sparc/miscregfile.cc
@@ -42,27 +42,6 @@ using namespace std;
class Checkpoint;
-//These functions map register indices to names
-string SparcISA::getMiscRegName(RegIndex index)
-{
- static::string miscRegName[NumMiscRegs] =
- {/*"y", "ccr",*/ "asi", "tick", "fprs", "pcr", "pic",
- "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
- "stick", "stick_cmpr",
- "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
- "pil", "cwp", /*"cansave", "canrestore", "cleanwin", "otherwin",
- "wstate",*/ "gl",
- "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
- "hstick_cmpr",
- "fsr", "prictx", "secctx", "partId", "lsuCtrlReg",
- "scratch0", "scratch1", "scratch2", "scratch3", "scratch4",
- "scratch5", "scratch6", "scratch7", "cpuMondoHead", "cpuMondoTail",
- "devMondoHead", "devMondoTail", "resErrorHead", "resErrorTail",
- "nresErrorHead", "nresErrorTail", "TlbData" };
-
- return miscRegName[index];
-}
-
enum RegMask
{
PSTATE_MASK = (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12)
@@ -227,7 +206,7 @@ MiscReg MiscRegFile::readRegNoEffect(int miscReg)
/** Floating Point Status Register */
case MISCREG_FSR:
- DPRINTF(Sparc, "FSR read as: %#x\n", fsr);
+ DPRINTF(MiscRegs, "FSR read as: %#x\n", fsr);
return fsr;
case MISCREG_MMU_P_CONTEXT:
@@ -322,12 +301,13 @@ MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc)
return readFSReg(miscReg, tc);
#else
case MISCREG_HPSTATE:
- //HPSTATE is special because because sometimes in privilege checks for instructions
- //it will read HPSTATE to make sure the priv. level is ok
- //So, we'll just have to tell it it isn't, instead of panicing.
+ //HPSTATE is special because because sometimes in privilege
+ //checks for instructions it will read HPSTATE to make sure
+ //the priv. level is ok So, we'll just have to tell it it
+ //isn't, instead of panicing.
return 0;
- panic("Accessing Fullsystem register %s in SE mode\n",getMiscRegName(miscReg));
+ panic("Accessing Fullsystem register %d in SE mode\n", miscReg);
#endif
}
@@ -444,7 +424,7 @@ void MiscRegFile::setRegNoEffect(int miscReg, const MiscReg &val)
/** Floating Point Status Register */
case MISCREG_FSR:
fsr = val;
- DPRINTF(Sparc, "FSR written with: %#x\n", fsr);
+ DPRINTF(MiscRegs, "FSR written with: %#x\n", fsr);
break;
case MISCREG_MMU_P_CONTEXT:
@@ -540,20 +520,17 @@ void MiscRegFile::setReg(int miscReg,
tl = val;
#if FULL_SYSTEM
if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
- tc->getCpuPtr()->post_interrupt(IT_TRAP_LEVEL_ZERO,0);
+ tc->getCpuPtr()->postInterrupt(IT_TRAP_LEVEL_ZERO, 0);
else
- tc->getCpuPtr()->clear_interrupt(IT_TRAP_LEVEL_ZERO,0);
+ tc->getCpuPtr()->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0);
#endif
return;
case MISCREG_CWP:
new_val = val >= NWindows ? NWindows - 1 : val;
if (val >= NWindows)
new_val = NWindows - 1;
-
- tc->changeRegFileContext(CONTEXT_CWP, new_val);
break;
case MISCREG_GL:
- tc->changeRegFileContext(CONTEXT_GLOBALS, val);
break;
case MISCREG_PIL:
case MISCREG_SOFTINT:
@@ -584,13 +561,15 @@ void MiscRegFile::setReg(int miscReg,
//HPSTATE is special because normal trap processing saves HPSTATE when
//it goes into a trap, and restores it when it returns.
return;
- panic("Accessing Fullsystem register %s to %#x in SE mode\n", getMiscRegName(miscReg), val);
+ panic("Accessing Fullsystem register %d to %#x in SE mode\n",
+ miscReg, val);
#endif
}
setRegNoEffect(miscReg, new_val);
}
-void MiscRegFile::serialize(std::ostream & os)
+void
+MiscRegFile::serialize(EventManager *em, std::ostream &os)
{
SERIALIZE_SCALAR(asi);
SERIALIZE_SCALAR(tick);
@@ -667,7 +646,9 @@ void MiscRegFile::serialize(std::ostream & os)
#endif
}
-void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
+void
+MiscRegFile::unserialize(EventManager *em, Checkpoint *cp,
+ const string &section)
{
UNSERIALIZE_SCALAR(asi);
UNSERIALIZE_SCALAR(tick);
@@ -726,15 +707,15 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
if (tick_cmp) {
tickCompare = new TickCompareEvent(this, tc);
- tickCompare->schedule(tick_cmp);
+ em->schedule(tickCompare, tick_cmp);
}
if (stick_cmp) {
sTickCompare = new STickCompareEvent(this, tc);
- sTickCompare->schedule(stick_cmp);
+ em->schedule(sTickCompare, stick_cmp);
}
if (hstick_cmp) {
hSTickCompare = new HSTickCompareEvent(this, tc);
- hSTickCompare->schedule(hstick_cmp);
+ em->schedule(hSTickCompare, hstick_cmp);
}
}
}
diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh
index 3e17779a9..9eff7fcac 100644
--- a/src/arch/sparc/miscregfile.hh
+++ b/src/arch/sparc/miscregfile.hh
@@ -43,9 +43,6 @@ class Checkpoint;
namespace SparcISA
{
- //These functions map register indices to names
- std::string getMiscRegName(RegIndex);
-
enum MiscRegIndex
{
/** Ancillary State Registers */
@@ -171,50 +168,50 @@ namespace SparcISA
private:
/* ASR Registers */
- //uint64_t y; // Y (used in obsolete multiplication)
- //uint8_t ccr; // Condition Code Register
- uint8_t asi; // Address Space Identifier
- uint64_t tick; // Hardware clock-tick counter
- uint8_t fprs; // Floating-Point Register State
- uint64_t gsr; // General Status Register
+ //uint64_t y; // Y (used in obsolete multiplication)
+ //uint8_t ccr; // Condition Code Register
+ uint8_t asi; // Address Space Identifier
+ uint64_t tick; // Hardware clock-tick counter
+ uint8_t fprs; // Floating-Point Register State
+ uint64_t gsr; // General Status Register
uint64_t softint;
- uint64_t tick_cmpr; // Hardware tick compare registers
- uint64_t stick; // Hardware clock-tick counter
- uint64_t stick_cmpr; // Hardware tick compare registers
+ uint64_t tick_cmpr; // Hardware tick compare registers
+ uint64_t stick; // Hardware clock-tick counter
+ uint64_t stick_cmpr; // Hardware tick compare registers
/* Privileged Registers */
- uint64_t tpc[MaxTL]; // Trap Program Counter (value from
+ uint64_t tpc[MaxTL]; // Trap Program Counter (value from
// previous trap level)
- uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
+ uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
// previous trap level)
- uint64_t tstate[MaxTL]; // Trap State
- uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
+ uint64_t tstate[MaxTL]; // Trap State
+ uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
// on the previous level)
- uint64_t tba; // Trap Base Address
-
- uint16_t pstate; // Process State Register
- uint8_t tl; // Trap Level
- uint8_t pil; // Process Interrupt Register
- uint8_t cwp; // Current Window Pointer
- //uint8_t cansave; // Savable windows
- //uint8_t canrestore; // Restorable windows
- //uint8_t cleanwin; // Clean windows
- //uint8_t otherwin; // Other windows
- //uint8_t wstate; // Window State
+ uint64_t tba; // Trap Base Address
+
+ uint16_t pstate; // Process State Register
+ uint8_t tl; // Trap Level
+ uint8_t pil; // Process Interrupt Register
+ uint8_t cwp; // Current Window Pointer
+ //uint8_t cansave; // Savable windows
+ //uint8_t canrestore; // Restorable windows
+ //uint8_t cleanwin; // Clean windows
+ //uint8_t otherwin; // Other windows
+ //uint8_t wstate; // Window State
uint8_t gl; // Global level register
/** Hyperprivileged Registers */
- uint64_t hpstate; // Hyperprivileged State Register
+ uint64_t hpstate; // Hyperprivileged State Register
uint64_t htstate[MaxTL];// Hyperprivileged Trap State Register
uint64_t hintp;
- uint64_t htba; // Hyperprivileged Trap Base Address register
- uint64_t hstick_cmpr; // Hardware tick compare registers
+ uint64_t htba; // Hyperprivileged Trap Base Address register
+ uint64_t hstick_cmpr; // Hardware tick compare registers
uint64_t strandStatusReg;// Per strand status register
/** Floating point misc registers. */
- uint64_t fsr; // Floating-Point State Register
+ uint64_t fsr; // Floating-Point State Register
/** MMU Internal Registers */
uint16_t priContext;
@@ -288,9 +285,10 @@ namespace SparcISA
return priContext | (uint32_t)partId << 13;
}
- void serialize(std::ostream & os);
+ void serialize(EventManager *em, std::ostream & os);
- void unserialize(Checkpoint * cp, const std::string & section);
+ void unserialize(EventManager *em, Checkpoint *cp,
+ const std::string & section);
void copyMiscRegs(ThreadContext * tc);
diff --git a/src/arch/sparc/pagetable.hh b/src/arch/sparc/pagetable.hh
index bf7f34b60..cbdabe4c3 100644
--- a/src/arch/sparc/pagetable.hh
+++ b/src/arch/sparc/pagetable.hh
@@ -31,6 +31,8 @@
#ifndef __ARCH_SPARC_PAGETABLE_HH__
#define __ARCH_SPARC_PAGETABLE_HH__
+#include <cassert>
+
#include "arch/sparc/isa_traits.hh"
#include "base/bitfield.hh"
#include "base/misc.hh"
@@ -38,8 +40,8 @@
class Checkpoint;
-namespace SparcISA
-{
+namespace SparcISA {
+
struct VAddr
{
VAddr(Addr a) { panic("not implemented yet."); }
@@ -54,8 +56,15 @@ class TteTag
public:
TteTag() : entry(0), populated(false) {}
TteTag(uint64_t e) : entry(e), populated(true) {}
- const TteTag &operator=(uint64_t e) { populated = true;
- entry = e; return *this; }
+
+ const TteTag &
+ operator=(uint64_t e)
+ {
+ populated = true;
+ entry = e;
+ return *this;
+ }
+
bool valid() const {assert(populated); return !bits(entry,62,62); }
Addr va() const {assert(populated); return bits(entry,41,0); }
};
@@ -76,13 +85,13 @@ class PageTableEntry
uint64_t entry4u;
bool populated;
-
public:
- PageTableEntry() : entry(0), type(invalid), populated(false) {}
+ PageTableEntry()
+ : entry(0), type(invalid), populated(false)
+ {}
PageTableEntry(uint64_t e, EntryType t = sun4u)
: entry(e), type(t), populated(true)
-
{
populate(entry, type);
}
@@ -113,49 +122,74 @@ class PageTableEntry
}
}
- void clear()
+ void
+ clear()
{
populated = false;
}
static int pageSizes[6];
-
uint64_t operator()() const { assert(populated); return entry4u; }
- const PageTableEntry &operator=(uint64_t e) { populated = true;
- entry4u = e; return *this; }
-
- const PageTableEntry &operator=(const PageTableEntry &e)
- { populated = true; entry4u = e.entry4u; type = e.type; return *this; }
-
- bool valid() const { return bits(entry4u,63,63) && populated; }
- uint8_t _size() const { assert(populated);
- return bits(entry4u, 62,61) |
- bits(entry4u, 48,48) << 2; }
- Addr size() const { assert(_size() < 6); return pageSizes[_size()]; }
- Addr sizeMask() const { assert(_size() < 6); return pageSizes[_size()]-1;}
- bool ie() const { return bits(entry4u, 59,59); }
- Addr pfn() const { assert(populated); return bits(entry4u,39,13); }
- Addr paddr() const { assert(populated); return mbits(entry4u, 39,13);}
- bool locked() const { assert(populated); return bits(entry4u,6,6); }
- bool cv() const { assert(populated); return bits(entry4u,4,4); }
- bool cp() const { assert(populated); return bits(entry4u,5,5); }
- bool priv() const { assert(populated); return bits(entry4u,2,2); }
- bool writable() const { assert(populated); return bits(entry4u,1,1); }
- bool nofault() const { assert(populated); return bits(entry4u,60,60); }
- bool sideffect() const { assert(populated); return bits(entry4u,3,3); }
- Addr paddrMask() const { assert(populated);
- return mbits(entry4u, 39,13) & ~sizeMask(); }
+ const PageTableEntry &
+ operator=(uint64_t e)
+ {
+ populated = true;
+ entry4u = e;
+ return *this;
+ }
+
+ const PageTableEntry &
+ operator=(const PageTableEntry &e)
+ {
+ populated = true;
+ entry4u = e.entry4u;
+ type = e.type;
+ return *this;
+ }
+
+ bool valid() const { return bits(entry4u,63,63) && populated; }
+
+ uint8_t
+ _size() const
+ {
+ assert(populated);
+ return bits(entry4u, 62,61) | bits(entry4u, 48,48) << 2;
+ }
+
+ Addr size() const { assert(_size() < 6); return pageSizes[_size()]; }
+ Addr sizeMask() const { return size() - 1; }
+ bool ie() const { return bits(entry4u, 59,59); }
+ Addr pfn() const { assert(populated); return bits(entry4u,39,13); }
+ Addr paddr() const { assert(populated); return mbits(entry4u, 39,13);}
+ bool locked() const { assert(populated); return bits(entry4u,6,6); }
+ bool cv() const { assert(populated); return bits(entry4u,4,4); }
+ bool cp() const { assert(populated); return bits(entry4u,5,5); }
+ bool priv() const { assert(populated); return bits(entry4u,2,2); }
+ bool writable() const { assert(populated); return bits(entry4u,1,1); }
+ bool nofault() const { assert(populated); return bits(entry4u,60,60); }
+ bool sideffect() const { assert(populated); return bits(entry4u,3,3); }
+ Addr paddrMask() const { assert(populated); return paddr() & ~sizeMask(); }
+
+ Addr
+ translate(Addr vaddr) const
+ {
+ assert(populated);
+ Addr mask = sizeMask();
+ return (paddr() & ~mask) | (vaddr & mask);
+ }
};
-struct TlbRange {
+struct TlbRange
+{
Addr va;
Addr size;
int contextId;
int partitionId;
bool real;
- inline bool operator<(const TlbRange &r2) const
+ inline bool
+ operator<(const TlbRange &r2) const
{
if (real && !r2.real)
return true;
@@ -178,7 +212,9 @@ struct TlbRange {
return true;
return false;
}
- inline bool operator==(const TlbRange &r2) const
+
+ inline bool
+ operator==(const TlbRange &r2) const
{
return va == r2.va &&
size == r2.size &&
@@ -189,7 +225,11 @@ struct TlbRange {
};
-struct TlbEntry {
+struct TlbEntry
+{
+ TlbEntry()
+ {}
+
TlbEntry(Addr asn, Addr vaddr, Addr paddr)
{
uint64_t entry = 0;
@@ -215,8 +255,7 @@ struct TlbEntry {
valid = true;
}
- TlbEntry()
- {}
+
TlbRange range;
PageTableEntry pte;
bool used;
@@ -227,13 +266,17 @@ struct TlbEntry {
return pte.paddr();
}
+ void
+ updateVaddr(Addr new_vaddr)
+ {
+ range.va = new_vaddr;
+ }
+
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
-
};
-
-}; // namespace SparcISA
+} // namespace SparcISA
#endif // __ARCH_SPARC_PAGE_TABLE_HH__
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index 6e490e05e..b2b539816 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -46,6 +46,9 @@
using namespace std;
using namespace SparcISA;
+static const int FirstArgumentReg = 8;
+static const int ReturnValueReg = 8;
+
SparcLiveProcess::SparcLiveProcess(LiveProcessParams * params,
ObjectFile *objFile, Addr _StackBias)
@@ -112,44 +115,45 @@ SparcLiveProcess::startup()
{
Process::startup();
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
//From the SPARC ABI
//Setup default FP state
- threadContexts[0]->setMiscRegNoEffect(MISCREG_FSR, 0);
+ tc->setMiscRegNoEffect(MISCREG_FSR, 0);
- threadContexts[0]->setMiscRegNoEffect(MISCREG_TICK, 0);
+ tc->setMiscRegNoEffect(MISCREG_TICK, 0);
/*
* Register window management registers
*/
//No windows contain info from other programs
- //threadContexts[0]->setMiscRegNoEffect(MISCREG_OTHERWIN, 0);
- threadContexts[0]->setIntReg(NumIntArchRegs + 6, 0);
+ //tc->setMiscRegNoEffect(MISCREG_OTHERWIN, 0);
+ tc->setIntReg(NumIntArchRegs + 6, 0);
//There are no windows to pop
- //threadContexts[0]->setMiscRegNoEffect(MISCREG_CANRESTORE, 0);
- threadContexts[0]->setIntReg(NumIntArchRegs + 4, 0);
+ //tc->setMiscRegNoEffect(MISCREG_CANRESTORE, 0);
+ tc->setIntReg(NumIntArchRegs + 4, 0);
//All windows are available to save into
- //threadContexts[0]->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2);
- threadContexts[0]->setIntReg(NumIntArchRegs + 3, NWindows - 2);
+ //tc->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2);
+ tc->setIntReg(NumIntArchRegs + 3, NWindows - 2);
//All windows are "clean"
- //threadContexts[0]->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows);
- threadContexts[0]->setIntReg(NumIntArchRegs + 5, NWindows);
+ //tc->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows);
+ tc->setIntReg(NumIntArchRegs + 5, NWindows);
//Start with register window 0
- threadContexts[0]->setMiscRegNoEffect(MISCREG_CWP, 0);
+ tc->setMiscRegNoEffect(MISCREG_CWP, 0);
//Always use spill and fill traps 0
- //threadContexts[0]->setMiscRegNoEffect(MISCREG_WSTATE, 0);
- threadContexts[0]->setIntReg(NumIntArchRegs + 7, 0);
+ //tc->setMiscRegNoEffect(MISCREG_WSTATE, 0);
+ tc->setIntReg(NumIntArchRegs + 7, 0);
//Set the trap level to 0
- threadContexts[0]->setMiscRegNoEffect(MISCREG_TL, 0);
+ tc->setMiscRegNoEffect(MISCREG_TL, 0);
//Set the ASI register to something fixed
- threadContexts[0]->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY);
+ tc->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY);
/*
* T1 specific registers
*/
//Turn on the icache, dcache, dtb translation, and itb translation.
- threadContexts[0]->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL, 15);
+ tc->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL, 15);
}
void
@@ -160,8 +164,9 @@ Sparc32LiveProcess::startup()
SparcLiveProcess::startup();
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
//The process runs in user mode with 32 bit addresses
- threadContexts[0]->setMiscReg(MISCREG_PSTATE, 0x0a);
+ tc->setMiscReg(MISCREG_PSTATE, 0x0a);
argsInit(32 / 8, VMPageSize);
}
@@ -174,8 +179,9 @@ Sparc64LiveProcess::startup()
SparcLiveProcess::startup();
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
//The process runs in user mode
- threadContexts[0]->setMiscReg(MISCREG_PSTATE, 0x02);
+ tc->setMiscReg(MISCREG_PSTATE, 0x02);
argsInit(sizeof(IntReg), VMPageSize);
}
@@ -186,7 +192,7 @@ SparcLiveProcess::argsInit(int pageSize)
{
int intSize = sizeof(IntType);
- typedef M5_auxv_t<IntType> auxv_t;
+ typedef AuxVector<IntType> auxv_t;
std::vector<auxv_t> auxv;
@@ -335,18 +341,18 @@ SparcLiveProcess::argsInit(int pageSize)
IntType window_save_base = argc_base - window_save_size;
#endif
- DPRINTF(Sparc, "The addresses of items on the initial stack:\n");
- DPRINTF(Sparc, "%#x - sentry NULL\n", sentry_base);
- DPRINTF(Sparc, "filename = %s\n", filename);
- DPRINTF(Sparc, "%#x - file name\n", file_name_base);
- DPRINTF(Sparc, "%#x - env data\n", env_data_base);
- DPRINTF(Sparc, "%#x - arg data\n", arg_data_base);
- DPRINTF(Sparc, "%#x - auxv array\n", auxv_array_base);
- DPRINTF(Sparc, "%#x - envp array\n", envp_array_base);
- DPRINTF(Sparc, "%#x - argv array\n", argv_array_base);
- DPRINTF(Sparc, "%#x - argc \n", argc_base);
- DPRINTF(Sparc, "%#x - window save\n", window_save_base);
- DPRINTF(Sparc, "%#x - stack min\n", stack_min);
+ DPRINTF(Stack, "The addresses of items on the initial stack:\n");
+ DPRINTF(Stack, "%#x - sentry NULL\n", sentry_base);
+ DPRINTF(Stack, "filename = %s\n", filename);
+ DPRINTF(Stack, "%#x - file name\n", file_name_base);
+ DPRINTF(Stack, "%#x - env data\n", env_data_base);
+ DPRINTF(Stack, "%#x - arg data\n", arg_data_base);
+ DPRINTF(Stack, "%#x - auxv array\n", auxv_array_base);
+ DPRINTF(Stack, "%#x - envp array\n", envp_array_base);
+ DPRINTF(Stack, "%#x - argv array\n", argv_array_base);
+ DPRINTF(Stack, "%#x - argc \n", argc_base);
+ DPRINTF(Stack, "%#x - window save\n", window_save_base);
+ DPRINTF(Stack, "%#x - stack min\n", stack_min);
assert(window_save_base == stack_min);
@@ -354,7 +360,7 @@ SparcLiveProcess::argsInit(int pageSize)
// figure out argc
IntType argc = argv.size();
- IntType guestArgc = TheISA::htog(argc);
+ IntType guestArgc = SparcISA::htog(argc);
//Write out the sentry void *
uint64_t sentry_NULL = 0;
@@ -391,20 +397,21 @@ SparcLiveProcess::argsInit(int pageSize)
fillStart = stack_base;
spillStart = fillStart + sizeof(MachInst) * numFillInsts;
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
//Set up the thread context to start running the process
//assert(NumArgumentRegs >= 2);
- //threadContexts[0]->setIntReg(ArgumentReg[0], argc);
- //threadContexts[0]->setIntReg(ArgumentReg[1], argv_array_base);
- threadContexts[0]->setIntReg(StackPointerReg, stack_min - StackBias);
+ //tc->setIntReg(ArgumentReg[0], argc);
+ //tc->setIntReg(ArgumentReg[1], argv_array_base);
+ tc->setIntReg(StackPointerReg, stack_min - StackBias);
// %g1 is a pointer to a function that should be run at exit. Since we
// don't have anything like that, it should be set to 0.
- threadContexts[0]->setIntReg(1, 0);
+ tc->setIntReg(1, 0);
Addr prog_entry = objFile->entryPoint();
- threadContexts[0]->setPC(prog_entry);
- threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
- threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
+ tc->setPC(prog_entry);
+ tc->setNextPC(prog_entry + sizeof(MachInst));
+ tc->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
//Align the "stack_min" to a page boundary.
stack_min = roundDown(stack_min, pageSize);
@@ -505,3 +512,63 @@ void Sparc64LiveProcess::flushWindows(ThreadContext *tc)
tc->setIntReg(NumIntArchRegs + 4, Canrestore);
tc->setMiscReg(MISCREG_CWP, origCWP);
}
+
+IntReg
+Sparc32LiveProcess::getSyscallArg(ThreadContext *tc, int i)
+{
+ assert(i < 6);
+ return bits(tc->readIntReg(FirstArgumentReg + i), 31, 0);
+}
+
+void
+Sparc32LiveProcess::setSyscallArg(ThreadContext *tc, int i, IntReg val)
+{
+ assert(i < 6);
+ tc->setIntReg(FirstArgumentReg + i, bits(val, 31, 0));
+}
+
+IntReg
+Sparc64LiveProcess::getSyscallArg(ThreadContext *tc, int i)
+{
+ assert(i < 6);
+ return tc->readIntReg(FirstArgumentReg + i);
+}
+
+void
+Sparc64LiveProcess::setSyscallArg(ThreadContext *tc, int i, IntReg val)
+{
+ assert(i < 6);
+ tc->setIntReg(FirstArgumentReg + i, val);
+}
+
+void
+SparcLiveProcess::setSyscallReturn(ThreadContext *tc,
+ SyscallReturn return_value)
+{
+ // check for error condition. SPARC syscall convention is to
+ // indicate success/failure in reg the carry bit of the ccr
+ // and put the return value itself in the standard return value reg ().
+ if (return_value.successful()) {
+ // no error, clear XCC.C
+ tc->setIntReg(NumIntArchRegs + 2,
+ tc->readIntReg(NumIntArchRegs + 2) & 0xEE);
+ //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) & 0xEE);
+ IntReg val = return_value.value();
+ if (bits(tc->readMiscRegNoEffect(
+ SparcISA::MISCREG_PSTATE), 3, 3)) {
+ val = bits(val, 31, 0);
+ }
+ tc->setIntReg(ReturnValueReg, val);
+ } else {
+ // got an error, set XCC.C
+ tc->setIntReg(NumIntArchRegs + 2,
+ tc->readIntReg(NumIntArchRegs + 2) | 0x11);
+ //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) | 0x11);
+ IntReg val = -return_value.value();
+ if (bits(tc->readMiscRegNoEffect(
+ SparcISA::MISCREG_PSTATE), 3, 3)) {
+ val = bits(val, 31, 0);
+ }
+ tc->setIntReg(ReturnValueReg, val);
+ }
+}
diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh
index a37760139..fdb9734ba 100644
--- a/src/arch/sparc/process.hh
+++ b/src/arch/sparc/process.hh
@@ -69,26 +69,7 @@ class SparcLiveProcess : public LiveProcess
{ return spillStart; }
virtual void flushWindows(ThreadContext *tc) = 0;
-};
-
-template<class IntType>
-struct M5_auxv_t
-{
- IntType a_type;
- union {
- IntType a_val;
- IntType a_ptr;
- IntType a_fcn;
- };
-
- M5_auxv_t()
- {}
-
- M5_auxv_t(IntType type, IntType val)
- {
- a_type = SparcISA::htog(type);
- a_val = SparcISA::htog(val);
- }
+ void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
};
class Sparc32LiveProcess : public SparcLiveProcess
@@ -113,6 +94,9 @@ class Sparc32LiveProcess : public SparcLiveProcess
void argsInit(int intSize, int pageSize);
void flushWindows(ThreadContext *tc);
+
+ SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val);
};
class Sparc64LiveProcess : public SparcLiveProcess
@@ -138,6 +122,9 @@ class Sparc64LiveProcess : public SparcLiveProcess
void argsInit(int intSize, int pageSize);
void flushWindows(ThreadContext *tc);
+
+ SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val);
};
#endif // __SPARC_PROCESS_HH__
diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc
index d6be52424..1c172a4d5 100644
--- a/src/arch/sparc/regfile.cc
+++ b/src/arch/sparc/regfile.cc
@@ -155,7 +155,7 @@ int SparcISA::flattenIntIndex(ThreadContext * tc, int reg)
{
int gl = tc->readMiscRegNoEffect(MISCREG_GL);
int cwp = tc->readMiscRegNoEffect(MISCREG_CWP);
- //DPRINTF(Sparc, "Global Level = %d, Current Window Pointer = %d\n", gl, cwp);
+ //DPRINTF(RegisterWindows, "Global Level = %d, Current Window Pointer = %d\n", gl, cwp);
int newReg;
//The total number of global registers
int numGlobals = (MaxGL + 1) * 8;
@@ -214,46 +214,33 @@ int SparcISA::flattenIntIndex(ThreadContext * tc, int reg)
}
else
panic("Tried to flatten invalid register index %d!\n", reg);
- DPRINTF(Sparc, "Flattened register %d to %d.\n", reg, newReg);
+ DPRINTF(RegisterWindows, "Flattened register %d to %d.\n", reg, newReg);
return newReg;
//return intRegFile.flattenIndex(reg);
}
-void RegFile::serialize(std::ostream &os)
+void
+RegFile::serialize(EventManager *em, ostream &os)
{
intRegFile.serialize(os);
floatRegFile.serialize(os);
- miscRegFile.serialize(os);
+ miscRegFile.serialize(em, os);
SERIALIZE_SCALAR(pc);
SERIALIZE_SCALAR(npc);
SERIALIZE_SCALAR(nnpc);
}
-void RegFile::unserialize(Checkpoint *cp, const std::string &section)
+void
+RegFile::unserialize(EventManager *em, Checkpoint *cp, const string &section)
{
intRegFile.unserialize(cp, section);
floatRegFile.unserialize(cp, section);
- miscRegFile.unserialize(cp, section);
+ miscRegFile.unserialize(em, cp, section);
UNSERIALIZE_SCALAR(pc);
UNSERIALIZE_SCALAR(npc);
UNSERIALIZE_SCALAR(nnpc);
}
-void RegFile::changeContext(RegContextParam param, RegContextVal val)
-{
- switch(param)
- {
- case CONTEXT_CWP:
- intRegFile.setCWP(val);
- break;
- case CONTEXT_GLOBALS:
- intRegFile.setGlobals(val);
- break;
- default:
- panic("Tried to set illegal context parameter in the SPARC regfile.\n");
- }
-}
-
void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
{
@@ -366,12 +353,12 @@ void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
void SparcISA::copyRegs(ThreadContext *src, ThreadContext *dest)
{
// First loop through the integer registers.
- for (int i = 0; i < TheISA::NumIntRegs; ++i) {
+ for (int i = 0; i < SparcISA::NumIntRegs; ++i) {
dest->setIntReg(i, src->readIntReg(i));
}
// Then loop through the floating point registers.
- for (int i = 0; i < TheISA::NumFloatRegs; ++i) {
+ for (int i = 0; i < SparcISA::NumFloatRegs; ++i) {
dest->setFloatRegBits(i, src->readFloatRegBits(i));
}
diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh
index c03f69fc5..505d7c8d7 100644
--- a/src/arch/sparc/regfile.hh
+++ b/src/arch/sparc/regfile.hh
@@ -48,8 +48,8 @@ namespace SparcISA
class RegFile
{
protected:
- Addr pc; // Program Counter
- Addr npc; // Next Program Counter
+ Addr pc; // Program Counter
+ Addr npc; // Next Program Counter
Addr nnpc;
public:
@@ -63,16 +63,14 @@ namespace SparcISA
void setNextNPC(Addr val);
protected:
- IntRegFile intRegFile; // integer register file
- FloatRegFile floatRegFile; // floating point register file
- MiscRegFile miscRegFile; // control register file
+ IntRegFile intRegFile; // integer register file
+ FloatRegFile floatRegFile; // floating point register file
+ MiscRegFile miscRegFile; // control register file
public:
void clear();
- int FlattenIntIndex(int reg);
-
MiscReg readMiscRegNoEffect(int miscReg);
MiscReg readMiscReg(int miscReg, ThreadContext *tc);
@@ -112,12 +110,11 @@ namespace SparcISA
void setIntReg(int intReg, const IntReg &val);
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
+ void serialize(EventManager *em, std::ostream &os);
+ void unserialize(EventManager *em, Checkpoint *cp,
+ const std::string &section);
public:
-
- void changeContext(RegContextParam param, RegContextVal val);
};
int flattenIntIndex(ThreadContext * tc, int reg);
diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc
index 67cc5b0d1..615c5b551 100644
--- a/src/arch/sparc/remote_gdb.cc
+++ b/src/arch/sparc/remote_gdb.cc
@@ -30,7 +30,7 @@
/*
* Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
@@ -38,8 +38,8 @@
*
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratories.
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratories.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -51,8 +51,8 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -69,7 +69,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
+ * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
*/
/*-
@@ -89,8 +89,8 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
@@ -137,7 +137,7 @@
#include "sim/system.hh"
using namespace std;
-using namespace TheISA;
+using namespace SparcISA;
RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
: BaseRemoteGDB(_system, c, NumGDBRegs), nextBkpt(0)
@@ -146,7 +146,7 @@ RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
///////////////////////////////////////////////////////////
// RemoteGDB::acc
//
-// Determine if the mapping at va..(va+len) is valid.
+// Determine if the mapping at va..(va+len) is valid.
//
bool
RemoteGDB::acc(Addr va, size_t len)
@@ -171,8 +171,8 @@ RemoteGDB::acc(Addr va, size_t len)
///////////////////////////////////////////////////////////
// RemoteGDB::getregs
//
-// Translate the kernel debugger register format into
-// the GDB register format.
+// Translate the kernel debugger register format into
+// the GDB register format.
void
RemoteGDB::getregs()
{
@@ -217,8 +217,8 @@ RemoteGDB::getregs()
///////////////////////////////////////////////////////////
// RemoteGDB::setregs
//
-// Translate the GDB register format into the kernel
-// debugger register format.
+// Translate the GDB register format into the kernel
+// debugger register format.
//
void
RemoteGDB::setregs()
diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc
index 40d172690..22924736b 100644
--- a/src/arch/sparc/solaris/process.cc
+++ b/src/arch/sparc/solaris/process.cc
@@ -48,7 +48,7 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- TypedBufferArg<Solaris::utsname> name(tc->getSyscallArg(0));
+ TypedBufferArg<Solaris::utsname> name(process->getSyscallArg(tc, 0));
strcpy(name->sysname, "SunOS");
strcpy(name->nodename, "m5.eecs.umich.edu");
@@ -80,7 +80,7 @@ SyscallDesc SparcSolarisProcess::syscallDescs[] = {
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", chmodFunc<Solaris>),
/* 16 */ SyscallDesc("chown", chownFunc),
- /* 17 */ SyscallDesc("brk", obreakFunc),
+ /* 17 */ SyscallDesc("brk", brkFunc),
/* 18 */ SyscallDesc("stat", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getpid", getpidFunc),
@@ -123,7 +123,7 @@ SyscallDesc SparcSolarisProcess::syscallDescs[] = {
/* 57 */ SyscallDesc("utssys", unimplementedFunc),
/* 58 */ SyscallDesc("fdsync", unimplementedFunc),
/* 59 */ SyscallDesc("execve", unimplementedFunc),
- /* 60 */ SyscallDesc("umask", unimplementedFunc),
+ /* 60 */ SyscallDesc("umask", umaskFunc),
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
/* 62 */ SyscallDesc("fcntl", unimplementedFunc),
/* 63 */ SyscallDesc("ulimit", unimplementedFunc),
@@ -153,7 +153,7 @@ SyscallDesc SparcSolarisProcess::syscallDescs[] = {
/* 87 */ SyscallDesc("poll", unimplementedFunc),
/* 88 */ SyscallDesc("lstat", unimplementedFunc),
/* 89 */ SyscallDesc("symlink", unimplementedFunc),
- /* 90 */ SyscallDesc("readlink", unimplementedFunc),
+ /* 90 */ SyscallDesc("readlink", readlinkFunc),
/* 91 */ SyscallDesc("setgroups", unimplementedFunc),
/* 92 */ SyscallDesc("getgroups", unimplementedFunc),
/* 93 */ SyscallDesc("fchmod", unimplementedFunc),
@@ -336,7 +336,7 @@ SparcSolarisProcess::SparcSolarisProcess(LiveProcessParams * params,
SyscallDesc*
SparcSolarisProcess::getDesc(int callnum)
{
- if (callnum < 0 || callnum > Num_Syscall_Descs)
+ if (callnum < 0 || callnum >= Num_Syscall_Descs)
return NULL;
return &syscallDescs[callnum];
}
diff --git a/src/arch/sparc/solaris/solaris.cc b/src/arch/sparc/solaris/solaris.cc
index c53caa72a..3cc910005 100644
--- a/src/arch/sparc/solaris/solaris.cc
+++ b/src/arch/sparc/solaris/solaris.cc
@@ -35,40 +35,40 @@
// open(2) flags translation table
OpenFlagTransTable SparcSolaris::openFlagTable[] = {
#ifdef _MSC_VER
- { SparcSolaris::TGT_O_RDONLY, _O_RDONLY },
- { SparcSolaris::TGT_O_WRONLY, _O_WRONLY },
- { SparcSolaris::TGT_O_RDWR, _O_RDWR },
- { SparcSolaris::TGT_O_APPEND, _O_APPEND },
- { SparcSolaris::TGT_O_CREAT, _O_CREAT },
- { SparcSolaris::TGT_O_TRUNC, _O_TRUNC },
- { SparcSolaris::TGT_O_EXCL, _O_EXCL },
+ { SparcSolaris::TGT_O_RDONLY, _O_RDONLY },
+ { SparcSolaris::TGT_O_WRONLY, _O_WRONLY },
+ { SparcSolaris::TGT_O_RDWR, _O_RDWR },
+ { SparcSolaris::TGT_O_APPEND, _O_APPEND },
+ { SparcSolaris::TGT_O_CREAT, _O_CREAT },
+ { SparcSolaris::TGT_O_TRUNC, _O_TRUNC },
+ { SparcSolaris::TGT_O_EXCL, _O_EXCL },
#ifdef _O_NONBLOCK
- { SparcSolaris::TGT_O_NONBLOCK, _O_NONBLOCK },
- { SparcSolaris::TGT_O_NDELAY , _O_NONBLOCK },
+ { SparcSolaris::TGT_O_NONBLOCK, _O_NONBLOCK },
+ { SparcSolaris::TGT_O_NDELAY , _O_NONBLOCK },
#endif
#ifdef _O_NOCTTY
- { SparcSolaris::TGT_O_NOCTTY, _O_NOCTTY },
+ { SparcSolaris::TGT_O_NOCTTY, _O_NOCTTY },
#endif
#ifdef _O_SYNC
- { SparcSolaris::TGT_O_SYNC, _O_SYNC },
- { SparcSolaris::TGT_O_DSYNC, _O_SYNC },
- { SparcSolaris::TGT_O_RSYNC, _O_SYNC },
+ { SparcSolaris::TGT_O_SYNC, _O_SYNC },
+ { SparcSolaris::TGT_O_DSYNC, _O_SYNC },
+ { SparcSolaris::TGT_O_RSYNC, _O_SYNC },
#endif
#else /* !_MSC_VER */
- { SparcSolaris::TGT_O_RDONLY, O_RDONLY },
- { SparcSolaris::TGT_O_WRONLY, O_WRONLY },
- { SparcSolaris::TGT_O_RDWR, O_RDWR },
- { SparcSolaris::TGT_O_APPEND, O_APPEND },
- { SparcSolaris::TGT_O_CREAT, O_CREAT },
- { SparcSolaris::TGT_O_TRUNC, O_TRUNC },
- { SparcSolaris::TGT_O_EXCL, O_EXCL },
- { SparcSolaris::TGT_O_NONBLOCK, O_NONBLOCK },
- { SparcSolaris::TGT_O_NDELAY , O_NONBLOCK },
- { SparcSolaris::TGT_O_NOCTTY, O_NOCTTY },
+ { SparcSolaris::TGT_O_RDONLY, O_RDONLY },
+ { SparcSolaris::TGT_O_WRONLY, O_WRONLY },
+ { SparcSolaris::TGT_O_RDWR, O_RDWR },
+ { SparcSolaris::TGT_O_APPEND, O_APPEND },
+ { SparcSolaris::TGT_O_CREAT, O_CREAT },
+ { SparcSolaris::TGT_O_TRUNC, O_TRUNC },
+ { SparcSolaris::TGT_O_EXCL, O_EXCL },
+ { SparcSolaris::TGT_O_NONBLOCK, O_NONBLOCK },
+ { SparcSolaris::TGT_O_NDELAY , O_NONBLOCK },
+ { SparcSolaris::TGT_O_NOCTTY, O_NOCTTY },
#ifdef O_SYNC
- { SparcSolaris::TGT_O_SYNC, O_SYNC },
- { SparcSolaris::TGT_O_DSYNC, O_SYNC },
- { SparcSolaris::TGT_O_RSYNC, O_SYNC },
+ { SparcSolaris::TGT_O_SYNC, O_SYNC },
+ { SparcSolaris::TGT_O_DSYNC, O_SYNC },
+ { SparcSolaris::TGT_O_RSYNC, O_SYNC },
#endif
#endif /* _MSC_VER */
};
diff --git a/src/arch/sparc/solaris/solaris.hh b/src/arch/sparc/solaris/solaris.hh
index 0564faba4..df2565027 100644
--- a/src/arch/sparc/solaris/solaris.hh
+++ b/src/arch/sparc/solaris/solaris.hh
@@ -39,22 +39,22 @@ class SparcSolaris : public Solaris
static OpenFlagTransTable openFlagTable[];
- static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY
- static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY
- static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR
- static const int TGT_O_NDELAY = 0x00000004; //!< O_NONBLOCK
- static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND
+ 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_NDELAY = 0x00000004; //!< O_NONBLOCK
+ static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND
static const int TGT_O_SYNC = 0x00000010; //!< O_SYNC
static const int TGT_O_DSYNC = 0x00000040; //!< O_SYNC
static const int TGT_O_RSYNC = 0x00008000; //!< O_SYNC
static const int TGT_O_NONBLOCK = 0x00000080; //!< O_NONBLOCK
static const int TGT_O_PRIV = 0x00001000; //??
static const int TGT_O_LARGEFILE = 0x00002000; //??
- 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_XATTR = 0x00004000; //??
+ 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_XATTR = 0x00004000; //??
static const int NUM_OPEN_FLAGS;
diff --git a/src/arch/sparc/sparc_traits.hh b/src/arch/sparc/sparc_traits.hh
index 715c08c03..e154ba274 100644
--- a/src/arch/sparc/sparc_traits.hh
+++ b/src/arch/sparc/sparc_traits.hh
@@ -47,8 +47,8 @@ namespace SparcISA
// const int NumRegularIntRegs = MaxGL * 8 + NWindows * 16;
// const int NumMicroIntRegs = 1;
// const int NumIntRegs =
-// NumRegularIntRegs +
-// NumMicroIntRegs;
+// NumRegularIntRegs +
+// NumMicroIntRegs;
// const int NumFloatRegs = 64;
// const int NumMiscRegs = 40;
}
diff --git a/src/arch/sparc/stacktrace.cc b/src/arch/sparc/stacktrace.cc
index 2d7991267..3ab0edb57 100644
--- a/src/arch/sparc/stacktrace.cc
+++ b/src/arch/sparc/stacktrace.cc
@@ -70,8 +70,6 @@ namespace SparcISA
if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
panic("thread info not compiled into kernel\n");
name_off = vp->readGtoH<int32_t>(addr);
-
- tc->delVirtPort(vp);
}
Addr
@@ -87,7 +85,6 @@ namespace SparcISA
vp = tc->getVirtPort();
tsk = vp->readGtoH<Addr>(base + task_off);
- tc->delVirtPort(vp);
return tsk;
}
@@ -105,7 +102,6 @@ namespace SparcISA
vp = tc->getVirtPort();
pd = vp->readGtoH<uint16_t>(task + pid_off);
- tc->delVirtPort(vp);
return pd;
}
@@ -163,7 +159,7 @@ namespace SparcISA
}
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
- Addr ksp = tc->readIntReg(TheISA::StackPointerReg);
+ Addr ksp = tc->readIntReg(SparcISA::StackPointerReg);
Addr bottom = ksp & ~0x3fff;
Addr addr;
diff --git a/src/arch/sparc/stacktrace.hh b/src/arch/sparc/stacktrace.hh
index 4bc5d779b..929990fcb 100644
--- a/src/arch/sparc/stacktrace.hh
+++ b/src/arch/sparc/stacktrace.hh
@@ -61,7 +61,7 @@ namespace SparcISA
class StackTrace
{
protected:
- typedef TheISA::MachInst MachInst;
+ typedef SparcISA::MachInst MachInst;
private:
ThreadContext *tc;
std::vector<Addr> stack;
diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc
index 22df44908..95ad0229e 100644
--- a/src/arch/sparc/tlb.cc
+++ b/src/arch/sparc/tlb.cc
@@ -51,7 +51,7 @@ TLB::TLB(const Params *p)
{
// To make this work you'll have to change the hypervisor and OS
if (size > 64)
- fatal("SPARC T1 TLB registers don't support more than 64 TLB entries.");
+ fatal("SPARC T1 TLB registers don't support more than 64 TLB entries");
tlb = new TlbEntry[size];
std::memset(tlb, 0, sizeof(TlbEntry) * size);
@@ -87,8 +87,6 @@ void
TLB::insert(Addr va, int partition_id, int context_id, bool real,
const PageTableEntry& PTE, int entry)
{
-
-
MapIter i;
TlbEntry *new_entry = NULL;
// TlbRange tr;
@@ -103,8 +101,9 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real,
tr.real = real;
*/
- DPRINTF(TLB, "TLB: Inserting TLB Entry; va=%#x pa=%#x pid=%d cid=%d r=%d entryid=%d\n",
- va, PTE.paddr(), partition_id, context_id, (int)real, entry);
+ DPRINTF(TLB,
+ "TLB: Inserting Entry; va=%#x pa=%#x pid=%d cid=%d r=%d entryid=%d\n",
+ va, PTE.paddr(), partition_id, context_id, (int)real, entry);
// Demap any entry that conflicts
for (x = 0; x < size; x++) {
@@ -128,7 +127,6 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real,
}
}
-
/*
i = lookupTable.find(tr);
if (i != lookupTable.end()) {
@@ -195,25 +193,22 @@ insertAllLocked:
new_entry->valid = true;
usedEntries++;
-
-
i = lookupTable.insert(new_entry->range, new_entry);
assert(i != lookupTable.end());
- // If all entries have there used bit set, clear it on them all, but the
- // one we just inserted
+ // If all entries have their used bit set, clear it on them all,
+ // but the one we just inserted
if (usedEntries == size) {
clearUsedBits();
new_entry->used = true;
usedEntries++;
}
-
}
TlbEntry*
-TLB::lookup(Addr va, int partition_id, bool real, int context_id, bool
- update_used)
+TLB::lookup(Addr va, int partition_id, bool real, int context_id,
+ bool update_used)
{
MapIter i;
TlbRange tr;
@@ -240,8 +235,8 @@ TLB::lookup(Addr va, int partition_id, bool real, int context_id, bool
DPRINTF(TLB, "TLB: Valid entry found pa: %#x size: %#x\n", t->pte.paddr(),
t->pte.size());
- // Update the used bits only if this is a real access (not a fake one from
- // virttophys()
+ // Update the used bits only if this is a real access (not a fake
+ // one from virttophys()
if (!t->used && update_used) {
t->used = true;
usedEntries++;
@@ -304,11 +299,10 @@ TLB::demapPage(Addr va, int partition_id, bool real, int context_id)
void
TLB::demapContext(int partition_id, int context_id)
{
- int x;
DPRINTF(IPR, "TLB: Demapping Context pid=%#d cid=%d\n",
partition_id, context_id);
cacheValid = false;
- for (x = 0; x < size; x++) {
+ for (int x = 0; x < size; x++) {
if (tlb[x].range.contextId == context_id &&
tlb[x].range.partitionId == partition_id) {
if (tlb[x].valid == true) {
@@ -327,10 +321,9 @@ TLB::demapContext(int partition_id, int context_id)
void
TLB::demapAll(int partition_id)
{
- int x;
DPRINTF(TLB, "TLB: Demapping All pid=%#d\n", partition_id);
cacheValid = false;
- for (x = 0; x < size; x++) {
+ for (int x = 0; x < size; x++) {
if (tlb[x].valid && !tlb[x].pte.locked() &&
tlb[x].range.partitionId == partition_id) {
freeList.push_front(&tlb[x]);
@@ -347,11 +340,10 @@ TLB::demapAll(int partition_id)
void
TLB::invalidateAll()
{
- int x;
cacheValid = false;
-
lookupTable.clear();
- for (x = 0; x < size; x++) {
+
+ for (int x = 0; x < size; x++) {
if (tlb[x].valid == true)
freeList.push_back(&tlb[x]);
tlb[x].valid = false;
@@ -361,7 +353,8 @@ TLB::invalidateAll()
}
uint64_t
-TLB::TteRead(int entry) {
+TLB::TteRead(int entry)
+{
if (entry >= size)
panic("entry: %d\n", entry);
@@ -373,7 +366,8 @@ TLB::TteRead(int entry) {
}
uint64_t
-TLB::TagRead(int entry) {
+TLB::TagRead(int entry)
+{
assert(entry < size);
uint64_t tag;
if (!tlb[entry].valid)
@@ -442,7 +436,7 @@ DTB::writeSfsr(Addr a, bool write, ContextType ct,
}
Fault
-ITB::translate(RequestPtr &req, ThreadContext *tc)
+ITB::translateAtomic(RequestPtr req, ThreadContext *tc)
{
uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
@@ -459,9 +453,8 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
if (cacheEntry) {
if (cacheEntry->range.va < vaddr + sizeof(MachInst) &&
cacheEntry->range.va + cacheEntry->range.size >= vaddr) {
- req->setPaddr(cacheEntry->pte.paddr() & ~(cacheEntry->pte.size()-1) |
- vaddr & cacheEntry->pte.size()-1 );
- return NoFault;
+ req->setPaddr(cacheEntry->pte.translate(vaddr));
+ return NoFault;
}
} else {
req->setPaddr(vaddr & PAddrImplMask);
@@ -550,18 +543,26 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
cacheState = tlbdata;
cacheEntry = e;
- req->setPaddr(e->pte.paddr() & ~(e->pte.size()-1) |
- vaddr & e->pte.size()-1 );
+ req->setPaddr(e->pte.translate(vaddr));
DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr());
return NoFault;
}
-
+void
+ITB::translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation)
+{
+ assert(translation);
+ translation->finish(translateAtomic(req, tc), req, tc, false);
+}
Fault
-DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
+DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write)
{
- /* @todo this could really use some profiling and fixing to make it faster! */
+ /*
+ * @todo this could really use some profiling and fixing to make
+ * it faster!
+ */
uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
Addr vaddr = req->getVaddr();
Addr size = req->getSize();
@@ -569,7 +570,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
asi = (ASI)req->getAsi();
bool implicit = false;
bool hpriv = bits(tlbdata,0,0);
- bool unaligned = (vaddr & size-1);
+ bool unaligned = vaddr & (size - 1);
DPRINTF(TLB, "TLB: DTB Request to translate va=%#x size=%d asi=%#x\n",
vaddr, size, asi);
@@ -599,11 +600,11 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
if (cacheAsi[0] == asi &&
ce_va < vaddr + size && ce_va + ce->range.size > vaddr &&
(!write || ce->pte.writable())) {
- req->setPaddr(ce->pte.paddrMask() | vaddr & ce->pte.sizeMask());
- if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1)
- req->setFlags(req->getFlags() | UNCACHEABLE);
- DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr());
- return NoFault;
+ req->setPaddr(ce->pte.translate(vaddr));
+ if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1)
+ req->setFlags(Request::UNCACHEABLE);
+ DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr());
+ return NoFault;
} // if matched
} // if cache entry valid
if (cacheEntry[1]) {
@@ -612,11 +613,11 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
if (cacheAsi[1] == asi &&
ce_va < vaddr + size && ce_va + ce->range.size > vaddr &&
(!write || ce->pte.writable())) {
- req->setPaddr(ce->pte.paddrMask() | vaddr & ce->pte.sizeMask());
- if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1)
- req->setFlags(req->getFlags() | UNCACHEABLE);
- DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr());
- return NoFault;
+ req->setPaddr(ce->pte.translate(vaddr));
+ if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1)
+ req->setFlags(Request::UNCACHEABLE);
+ DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr());
+ return NoFault;
} // if matched
} // if cache entry valid
}
@@ -639,7 +640,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
TlbEntry *e;
DPRINTF(TLB, "TLB: priv:%d hpriv:%d red:%d lsudm:%d part_id: %#X\n",
- priv, hpriv, red, lsu_dm, part_id);
+ priv, hpriv, red, lsu_dm, part_id);
if (implicit) {
if (tl > 0) {
@@ -725,11 +726,10 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
return new DataAccessException;
}
-
if ((!lsu_dm && !hpriv && !red) || AsiIsReal(asi)) {
real = true;
context = 0;
- };
+ }
if (hpriv && (implicit || (!AsiIsAsIfUser(asi) && !AsiIsReal(asi)))) {
req->setPaddr(vaddr & PAddrImplMask);
@@ -776,9 +776,8 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
return new DataAccessException;
}
-
if (e->pte.sideffect() || (e->pte.paddr() >> 39) & 1)
- req->setFlags(req->getFlags() | UNCACHEABLE);
+ req->setFlags(Request::UNCACHEABLE);
// cache translation date for next translation
cacheState = tlbdata;
@@ -796,8 +795,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
cacheAsi[0] = (ASI)0;
}
cacheValid = true;
- req->setPaddr(e->pte.paddr() & ~(e->pte.size()-1) |
- vaddr & e->pte.size()-1);
+ req->setPaddr(e->pte.translate(vaddr));
DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr());
return NoFault;
@@ -811,8 +809,8 @@ handleIntRegAccess:
return new PrivilegedAction;
}
- if (asi == ASI_SWVR_UDB_INTR_W && !write ||
- asi == ASI_SWVR_UDB_INTR_R && write) {
+ if ((asi == ASI_SWVR_UDB_INTR_W && !write) ||
+ (asi == ASI_SWVR_UDB_INTR_R && write)) {
writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
return new DataAccessException;
}
@@ -832,7 +830,7 @@ handleQueueRegAccess:
writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
return new PrivilegedAction;
}
- if (!hpriv && vaddr & 0xF || vaddr > 0x3f8 || vaddr < 0x3c0) {
+ if ((!hpriv && vaddr & 0xF) || vaddr > 0x3f8 || vaddr < 0x3c0) {
writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
return new DataAccessException;
}
@@ -857,6 +855,14 @@ handleMmuRegAccess:
return NoFault;
};
+void
+DTB::translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation, bool write)
+{
+ assert(translation);
+ translation->finish(translateAtomic(req, tc, write), req, tc, write);
+}
+
#if FULL_SYSTEM
Tick
@@ -869,7 +875,7 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
DPRINTF(IPR, "Memory Mapped IPR Read: asi=%#X a=%#x\n",
(uint32_t)pkt->req->getAsi(), pkt->getAddr());
- ITB * itb = tc->getITBPtr();
+ ITB *itb = tc->getITBPtr();
switch (asi) {
case ASI_LSU_CONTROL_REG:
@@ -1018,12 +1024,22 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
itb->cx_config));
break;
case ASI_SWVR_INTR_RECEIVE:
- pkt->set(tc->getCpuPtr()->get_interrupts(IT_INT_VEC));
+ {
+ SparcISA::Interrupts * interrupts =
+ dynamic_cast<SparcISA::Interrupts *>(
+ tc->getCpuPtr()->getInterruptController());
+ pkt->set(interrupts->get_vec(IT_INT_VEC));
+ }
break;
case ASI_SWVR_UDB_INTR_R:
- temp = findMsbSet(tc->getCpuPtr()->get_interrupts(IT_INT_VEC));
- tc->getCpuPtr()->clear_interrupt(IT_INT_VEC, temp);
- pkt->set(temp);
+ {
+ SparcISA::Interrupts * interrupts =
+ dynamic_cast<SparcISA::Interrupts *>(
+ tc->getCpuPtr()->getInterruptController());
+ temp = findMsbSet(interrupts->get_vec(IT_INT_VEC));
+ tc->getCpuPtr()->clearInterrupt(IT_INT_VEC, temp);
+ pkt->set(temp);
+ }
break;
default:
doMmuReadError:
@@ -1055,7 +1071,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
DPRINTF(IPR, "Memory Mapped IPR Write: asi=%#X a=%#x d=%#X\n",
(uint32_t)asi, va, data);
- ITB * itb = tc->getITBPtr();
+ ITB *itb = tc->getITBPtr();
switch (asi) {
case ASI_LSU_CONTROL_REG:
@@ -1129,7 +1145,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
break;
case ASI_SPARC_ERROR_EN_REG:
case ASI_SPARC_ERROR_STATUS_REG:
- warn("Ignoring write to SPARC ERROR regsiter\n");
+ inform("Ignoring write to SPARC ERROR regsiter\n");
break;
case ASI_HYP_SCRATCHPAD:
case ASI_SCRATCHPAD:
@@ -1173,7 +1189,8 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
real_insert = bits(va, 9,9);
pte.populate(data, bits(va,10,10) ? PageTableEntry::sun4v :
PageTableEntry::sun4u);
- insert(va_insert, part_insert, ct_insert, real_insert, pte, entry_insert);
+ insert(va_insert, part_insert, ct_insert, real_insert, pte,
+ entry_insert);
break;
case ASI_IMMU_DEMAP:
ignore = false;
@@ -1261,18 +1278,23 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
}
break;
case ASI_SWVR_INTR_RECEIVE:
- int msb;
- // clear all the interrupts that aren't set in the write
- while(tc->getCpuPtr()->get_interrupts(IT_INT_VEC) & data) {
- msb = findMsbSet(tc->getCpuPtr()->get_interrupts(IT_INT_VEC) & data);
- tc->getCpuPtr()->clear_interrupt(IT_INT_VEC, msb);
+ {
+ int msb;
+ // clear all the interrupts that aren't set in the write
+ SparcISA::Interrupts * interrupts =
+ dynamic_cast<SparcISA::Interrupts *>(
+ tc->getCpuPtr()->getInterruptController());
+ while (interrupts->get_vec(IT_INT_VEC) & data) {
+ msb = findMsbSet(interrupts->get_vec(IT_INT_VEC) & data);
+ tc->getCpuPtr()->clearInterrupt(IT_INT_VEC, msb);
+ }
}
break;
case ASI_SWVR_UDB_INTR_W:
tc->getSystemPtr()->threadContexts[bits(data,12,8)]->getCpuPtr()->
- post_interrupt(bits(data,5,0),0);
+ postInterrupt(bits(data, 5, 0), 0);
break;
- default:
+ default:
doMmuWriteError:
panic("need to impl DTB::doMmuRegWrite() got asi=%#x, va=%#x d=%#x\n",
(uint32_t)pkt->req->getAsi(), pkt->getAddr(), data);
@@ -1310,10 +1332,6 @@ DTB::GetTsbPtr(ThreadContext *tc, Addr addr, int ctx, Addr *ptrs)
itb->cx_config);
}
-
-
-
-
uint64_t
DTB::MakeTsbPtr(TsbPageSize ps, uint64_t tag_access, uint64_t c0_tsb,
uint64_t c0_config, uint64_t cX_tsb, uint64_t cX_config)
@@ -1341,7 +1359,6 @@ DTB::MakeTsbPtr(TsbPageSize ps, uint64_t tag_access, uint64_t c0_tsb,
return ptr;
}
-
void
TLB::serialize(std::ostream &os)
{
diff --git a/src/arch/sparc/tlb.hh b/src/arch/sparc/tlb.hh
index 2f7d08320..4fe532d4a 100644
--- a/src/arch/sparc/tlb.hh
+++ b/src/arch/sparc/tlb.hh
@@ -109,9 +109,9 @@ class TLB : public BaseTLB
* @param paritition_id partition this entry is for
* @param real is this a real->phys or virt->phys translation
* @param context_id if this is virt->phys what context
- * @param update_used should ew update the used bits in the entries on not
- * useful if we are trying to do a va->pa without mucking with any state for
- * a debug read for example.
+ * @param update_used should ew update the used bits in the
+ * entries on not useful if we are trying to do a va->pa without
+ * mucking with any state for a debug read for example.
* @return A pointer to a tlb entry
*/
TlbEntry *lookup(Addr va, int partition_id, bool real, int context_id = 0,
@@ -177,7 +177,9 @@ class ITB : public TLB
cacheEntry = NULL;
}
- Fault translate(RequestPtr &req, ThreadContext *tc);
+ Fault translateAtomic(RequestPtr req, ThreadContext *tc);
+ void translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation);
private:
void writeSfsr(bool write, ContextType ct,
bool se, FaultTypes ft, int asi);
@@ -199,7 +201,10 @@ class DTB : public TLB
cacheEntry[1] = NULL;
}
- Fault translate(RequestPtr &req, ThreadContext *tc, bool write);
+ Fault translateAtomic(RequestPtr req,
+ ThreadContext *tc, bool write=false);
+ void translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation, bool write=false);
#if FULL_SYSTEM
Tick doMmuRegRead(ThreadContext *tc, Packet *pkt);
Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt);
diff --git a/src/arch/sparc/tlb_map.hh b/src/arch/sparc/tlb_map.hh
index 8285db939..fa49584ba 100644
--- a/src/arch/sparc/tlb_map.hh
+++ b/src/arch/sparc/tlb_map.hh
@@ -52,7 +52,7 @@ class TlbMap
i = tree.upper_bound(r);
- if (i == tree.begin())
+ if (i == tree.begin()) {
if (r.real == i->first.real &&
r.partitionId == i->first.partitionId &&
i->first.va < r.va + r.size &&
@@ -62,6 +62,7 @@ class TlbMap
else
// Nothing could match, so return end()
return tree.end();
+ }
i--;
diff --git a/src/arch/sparc/types.hh b/src/arch/sparc/types.hh
index d19e2a99f..dd369cc26 100644
--- a/src/arch/sparc/types.hh
+++ b/src/arch/sparc/types.hh
@@ -51,14 +51,6 @@ namespace SparcISA
MiscReg ctrlreg;
} AnyReg;
- enum RegContextParam
- {
- CONTEXT_CWP,
- CONTEXT_GLOBALS
- };
-
- typedef int RegContextVal;
-
typedef uint16_t RegIndex;
struct CoreSpecific {
diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc
index fe733813c..880d2c3eb 100644
--- a/src/arch/sparc/ua2005.cc
+++ b/src/arch/sparc/ua2005.cc
@@ -35,34 +35,59 @@
#include "sim/system.hh"
using namespace SparcISA;
+using namespace std;
void
MiscRegFile::checkSoftInt(ThreadContext *tc)
{
+ BaseCPU *cpu = tc->getCpuPtr();
+
// If PIL < 14, copy over the tm and sm bits
if (pil < 14 && softint & 0x10000)
- tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,16);
+ cpu->postInterrupt(IT_SOFT_INT, 16);
else
- tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,16);
+ cpu->clearInterrupt(IT_SOFT_INT, 16);
if (pil < 14 && softint & 0x1)
- tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,0);
+ cpu->postInterrupt(IT_SOFT_INT, 0);
else
- tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,0);
+ cpu->clearInterrupt(IT_SOFT_INT, 0);
// Copy over any of the other bits that are set
for (int bit = 15; bit > 0; --bit) {
if (1 << bit & softint && bit > pil)
- tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,bit);
+ cpu->postInterrupt(IT_SOFT_INT, bit);
else
- tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,bit);
+ cpu->clearInterrupt(IT_SOFT_INT, bit);
}
}
+//These functions map register indices to names
+static inline string
+getMiscRegName(RegIndex index)
+{
+ static string miscRegName[NumMiscRegs] =
+ {/*"y", "ccr",*/ "asi", "tick", "fprs", "pcr", "pic",
+ "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
+ "stick", "stick_cmpr",
+ "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
+ "pil", "cwp", /*"cansave", "canrestore", "cleanwin", "otherwin",
+ "wstate",*/ "gl",
+ "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
+ "hstick_cmpr",
+ "fsr", "prictx", "secctx", "partId", "lsuCtrlReg",
+ "scratch0", "scratch1", "scratch2", "scratch3", "scratch4",
+ "scratch5", "scratch6", "scratch7", "cpuMondoHead", "cpuMondoTail",
+ "devMondoHead", "devMondoTail", "resErrorHead", "resErrorTail",
+ "nresErrorHead", "nresErrorTail", "TlbData" };
+ return miscRegName[index];
+}
void
MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
{
+ BaseCPU *cpu = tc->getCpuPtr();
+
int64_t time;
switch (miscReg) {
/* Full system only ASRs */
@@ -80,12 +105,12 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
tickCompare = new TickCompareEvent(this, tc);
setRegNoEffect(miscReg, val);
if ((tick_cmpr & ~mask(63)) && tickCompare->scheduled())
- tickCompare->deschedule();
+ cpu->deschedule(tickCompare);
time = (tick_cmpr & mask(63)) - (tick & mask(63));
if (!(tick_cmpr & ~mask(63)) && time > 0) {
if (tickCompare->scheduled())
- tickCompare->deschedule();
- tickCompare->schedule(time * tc->getCpuPtr()->ticks(1));
+ cpu->deschedule(tickCompare);
+ cpu->schedule(tickCompare, curTick + time * cpu->ticks(1));
}
panic("writing to TICK compare register %#X\n", val);
break;
@@ -95,13 +120,13 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
sTickCompare = new STickCompareEvent(this, tc);
setRegNoEffect(miscReg, val);
if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled())
- sTickCompare->deschedule();
+ cpu->deschedule(sTickCompare);
time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
- tc->getCpuPtr()->instCount();
+ cpu->instCount();
if (!(stick_cmpr & ~mask(63)) && time > 0) {
if (sTickCompare->scheduled())
- sTickCompare->deschedule();
- sTickCompare->schedule(time * tc->getCpuPtr()->ticks(1) + curTick);
+ cpu->deschedule(sTickCompare);
+ cpu->schedule(sTickCompare, curTick + time * cpu->ticks(1));
}
DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val);
break;
@@ -120,9 +145,9 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
case MISCREG_HINTP:
setRegNoEffect(miscReg, val);
if (hintp)
- tc->getCpuPtr()->post_interrupt(IT_HINTP,0);
+ cpu->postInterrupt(IT_HINTP, 0);
else
- tc->getCpuPtr()->clear_interrupt(IT_HINTP,0);
+ cpu->clearInterrupt(IT_HINTP, 0);
break;
case MISCREG_HTBA:
@@ -134,25 +159,25 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
case MISCREG_QUEUE_CPU_MONDO_TAIL:
setRegNoEffect(miscReg, val);
if (cpu_mondo_head != cpu_mondo_tail)
- tc->getCpuPtr()->post_interrupt(IT_CPU_MONDO,0);
+ cpu->postInterrupt(IT_CPU_MONDO, 0);
else
- tc->getCpuPtr()->clear_interrupt(IT_CPU_MONDO,0);
+ cpu->clearInterrupt(IT_CPU_MONDO, 0);
break;
case MISCREG_QUEUE_DEV_MONDO_HEAD:
case MISCREG_QUEUE_DEV_MONDO_TAIL:
setRegNoEffect(miscReg, val);
if (dev_mondo_head != dev_mondo_tail)
- tc->getCpuPtr()->post_interrupt(IT_DEV_MONDO,0);
+ cpu->postInterrupt(IT_DEV_MONDO, 0);
else
- tc->getCpuPtr()->clear_interrupt(IT_DEV_MONDO,0);
+ cpu->clearInterrupt(IT_DEV_MONDO, 0);
break;
case MISCREG_QUEUE_RES_ERROR_HEAD:
case MISCREG_QUEUE_RES_ERROR_TAIL:
setRegNoEffect(miscReg, val);
if (res_error_head != res_error_tail)
- tc->getCpuPtr()->post_interrupt(IT_RES_ERROR,0);
+ cpu->postInterrupt(IT_RES_ERROR, 0);
else
- tc->getCpuPtr()->clear_interrupt(IT_RES_ERROR,0);
+ cpu->clearInterrupt(IT_RES_ERROR, 0);
break;
case MISCREG_QUEUE_NRES_ERROR_HEAD:
case MISCREG_QUEUE_NRES_ERROR_TAIL:
@@ -165,13 +190,13 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
hSTickCompare = new HSTickCompareEvent(this, tc);
setRegNoEffect(miscReg, val);
if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled())
- hSTickCompare->deschedule();
+ cpu->deschedule(hSTickCompare);
time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
- tc->getCpuPtr()->instCount();
+ cpu->instCount();
if (!(hstick_cmpr & ~mask(63)) && time > 0) {
if (hSTickCompare->scheduled())
- hSTickCompare->deschedule();
- hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->ticks(1));
+ cpu->deschedule(hSTickCompare);
+ cpu->schedule(hSTickCompare, curTick + time * cpu->ticks(1));
}
DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val);
break;
@@ -181,9 +206,9 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
setRegNoEffect(miscReg, val | HPSTATE::id);
#if FULL_SYSTEM
if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
- tc->getCpuPtr()->post_interrupt(IT_TRAP_LEVEL_ZERO,0);
+ cpu->postInterrupt(IT_TRAP_LEVEL_ZERO, 0);
else
- tc->getCpuPtr()->clear_interrupt(IT_TRAP_LEVEL_ZERO,0);
+ cpu->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0);
#endif
break;
case MISCREG_HTSTATE:
@@ -200,11 +225,12 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
tc->suspend();
if (tc->getKernelStats())
tc->getKernelStats()->quiesce();
- }
+ }
break;
default:
- panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg));
+ panic("Invalid write to FS misc register %s\n",
+ getMiscRegName(miscReg));
}
}
@@ -250,12 +276,13 @@ MiscRegFile::readFSReg(int miscReg, ThreadContext * tc)
sys = tc->getSystemPtr();
temp = readRegNoEffect(miscReg) & (STS::active | STS::speculative);
- // Check that the CPU array is fully populated (by calling getNumCPus())
- assert(sys->getNumCPUs() > tc->readCpuId());
+ // Check that the CPU array is fully populated
+ // (by calling getNumCPus())
+ assert(sys->numContexts() > tc->contextId());
- temp |= tc->readCpuId() << STS::shft_id;
+ temp |= tc->contextId() << STS::shft_id;
- for (x = tc->readCpuId() & ~3; x < sys->threadContexts.size(); x++) {
+ for (x = tc->contextId() & ~3; x < sys->threadContexts.size(); x++) {
switch (sys->threadContexts[x]->status()) {
case ThreadContext::Active:
temp |= STS::st_run << (STS::shft_fsm0 -
@@ -280,16 +307,6 @@ MiscRegFile::readFSReg(int miscReg, ThreadContext * tc)
panic("Invalid read to FS misc register\n");
}
}
-/*
- In Niagra STICK==TICK so this isn't needed
- case MISCREG_STICK:
- SparcSystem *sys;
- sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
- assert(sys != NULL);
- return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63)));
-*/
-
-
void
MiscRegFile::processTickCompare(ThreadContext *tc)
@@ -300,12 +317,14 @@ MiscRegFile::processTickCompare(ThreadContext *tc)
void
MiscRegFile::processSTickCompare(ThreadContext *tc)
{
+ BaseCPU *cpu = tc->getCpuPtr();
+
// since our microcode instructions take two cycles we need to check if
// we're actually at the correct cycle or we need to wait a little while
// more
int ticks;
ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
- tc->getCpuPtr()->instCount();
+ cpu->instCount();
assert(ticks >= 0 && "stick compare missed interrupt cycle");
if (ticks == 0 || tc->status() == ThreadContext::Suspended) {
@@ -315,12 +334,14 @@ MiscRegFile::processSTickCompare(ThreadContext *tc)
setReg(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc);
}
} else
- sTickCompare->schedule(ticks * tc->getCpuPtr()->ticks(1) + curTick);
+ cpu->schedule(sTickCompare, curTick + ticks * cpu->ticks(1));
}
void
MiscRegFile::processHSTickCompare(ThreadContext *tc)
{
+ BaseCPU *cpu = tc->getCpuPtr();
+
// since our microcode instructions take two cycles we need to check if
// we're actually at the correct cycle or we need to wait a little while
// more
@@ -330,7 +351,7 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc)
return;
ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
- tc->getCpuPtr()->instCount();
+ cpu->instCount();
assert(ticks >= 0 && "hstick compare missed interrupt cycle");
if (ticks == 0 || tc->status() == ThreadContext::Suspended) {
@@ -341,6 +362,6 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc)
}
// Need to do something to cause interrupt to happen here !!! @todo
} else
- hSTickCompare->schedule(ticks * tc->getCpuPtr()->ticks(1) + curTick);
+ cpu->schedule(hSTickCompare, curTick + ticks * cpu->ticks(1));
}
diff --git a/src/arch/sparc/utility.cc b/src/arch/sparc/utility.cc
index 6d4358603..d4cc286e6 100644
--- a/src/arch/sparc/utility.cc
+++ b/src/arch/sparc/utility.cc
@@ -46,14 +46,14 @@ namespace SparcISA {
//first 6 arguments which the caller may use but doesn't have to.
uint64_t getArgument(ThreadContext *tc, int number, bool fp) {
#if FULL_SYSTEM
+ const int NumArgumentRegs = 6;
if (number < NumArgumentRegs) {
- return tc->readIntReg(ArgumentReg[number]);
+ return tc->readIntReg(8 + number);
} else {
Addr sp = tc->readIntReg(StackPointerReg);
- VirtualPort *vp = tc->getVirtPort(tc);
+ VirtualPort *vp = tc->getVirtPort();
uint64_t arg = vp->read<uint64_t>(sp + 92 +
(number-NumArgumentRegs) * sizeof(uint64_t));
- tc->delVirtPort(vp);
return arg;
}
#else
diff --git a/src/arch/sparc/vtophys.cc b/src/arch/sparc/vtophys.cc
index 9a93950d2..f23fb8304 100644
--- a/src/arch/sparc/vtophys.cc
+++ b/src/arch/sparc/vtophys.cc
@@ -40,85 +40,93 @@
using namespace std;
-namespace SparcISA
+namespace SparcISA {
+
+Addr
+vtophys(Addr vaddr)
{
- Addr vtophys(Addr vaddr)
- {
- // In SPARC it's almost always impossible to turn a VA->PA w/o a context
- // The only times we can kinda do it are if we have a SegKPM mapping
- // and can find the real address in the tlb or we have a physical
- // adddress already (beacuse we are looking at the hypervisor)
- // Either case is rare, so we'll just panic.
-
- panic("vtophys() without context on SPARC largly worthless\n");
- M5_DUMMY_RETURN
- }
+ // In SPARC it's almost always impossible to turn a VA->PA w/o a
+ // context The only times we can kinda do it are if we have a
+ // SegKPM mapping and can find the real address in the tlb or we
+ // have a physical adddress already (beacuse we are looking at the
+ // hypervisor) Either case is rare, so we'll just panic.
+
+ panic("vtophys() without context on SPARC largly worthless\n");
+ M5_DUMMY_RETURN;
+}
+
+Addr
+vtophys(ThreadContext *tc, Addr addr)
+{
+ // Here we have many options and are really implementing something like
+ // a fill handler to find the address since there isn't a multilevel
+ // table for us to walk around.
+ //
+ // 1. We are currently hyperpriv, return the address unmodified
+ // 2. The mmu is off return(ra->pa)
+ // 3. We are currently priv, use ctx0* tsbs to find the page
+ // 4. We are not priv, use ctxN0* tsbs to find the page
+ // For all accesses we check the tlbs first since it's possible that
+ // long standing pages (e.g. locked kernel mappings) won't be in the tsb
+ uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
+
+ bool hpriv = bits(tlbdata,0,0);
+ //bool priv = bits(tlbdata,2,2);
+ bool addr_mask = bits(tlbdata,3,3);
+ bool data_real = !bits(tlbdata,5,5);
+ bool inst_real = !bits(tlbdata,4,4);
+ bool ctx_zero = bits(tlbdata,18,16) > 0;
+ int part_id = bits(tlbdata,15,8);
+ int pri_context = bits(tlbdata,47,32);
+ //int sec_context = bits(tlbdata,63,48);
- Addr vtophys(ThreadContext *tc, Addr addr)
- {
- // Here we have many options and are really implementing something like
- // a fill handler to find the address since there isn't a multilevel
- // table for us to walk around.
- //
- // 1. We are currently hyperpriv, return the address unmodified
- // 2. The mmu is off return(ra->pa)
- // 3. We are currently priv, use ctx0* tsbs to find the page
- // 4. We are not priv, use ctxN0* tsbs to find the page
- // For all accesses we check the tlbs first since it's possible that
- // long standing pages (e.g. locked kernel mappings) won't be in the tsb
- uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
-
- bool hpriv = bits(tlbdata,0,0);
- //bool priv = bits(tlbdata,2,2);
- bool addr_mask = bits(tlbdata,3,3);
- bool data_real = !bits(tlbdata,5,5);
- bool inst_real = !bits(tlbdata,4,4);
- bool ctx_zero = bits(tlbdata,18,16) > 0;
- int part_id = bits(tlbdata,15,8);
- int pri_context = bits(tlbdata,47,32);
- //int sec_context = bits(tlbdata,63,48);
-
- FunctionalPort *mem = tc->getPhysPort();
- ITB* itb = tc->getITBPtr();
- DTB* dtb = tc->getDTBPtr();
- TlbEntry* tbe;
- PageTableEntry pte;
- Addr tsbs[4];
- Addr va_tag;
- TteTag ttetag;
-
- if (hpriv)
- return addr;
-
- if (addr_mask)
- addr = addr & VAddrAMask;
-
- tbe = dtb->lookup(addr, part_id, data_real, ctx_zero ? 0 : pri_context , false);
- if (tbe) goto foundtbe;
-
- tbe = itb->lookup(addr, part_id, inst_real, ctx_zero ? 0 : pri_context, false);
- if (tbe) goto foundtbe;
-
- // We didn't find it in the tlbs, so lets look at the TSBs
- dtb->GetTsbPtr(tc, addr, ctx_zero ? 0 : pri_context, tsbs);
- va_tag = bits(addr, 63, 22);
- for (int x = 0; x < 4; x++) {
- ttetag = betoh(mem->read<uint64_t>(tsbs[x]));
- if (ttetag.valid() && ttetag.va() == va_tag) {
- pte.populate(betoh(mem->read<uint64_t>(tsbs[x]) + sizeof(uint64_t)),
- PageTableEntry::sun4v); // I think it's sun4v at least!
- DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TTE\n", addr,
- pte.paddrMask() | addr & pte.sizeMask());
- goto foundpte;
- }
+ FunctionalPort *mem = tc->getPhysPort();
+ ITB* itb = tc->getITBPtr();
+ DTB* dtb = tc->getDTBPtr();
+ TlbEntry* tbe;
+ PageTableEntry pte;
+ Addr tsbs[4];
+ Addr va_tag;
+ TteTag ttetag;
+
+ if (hpriv)
+ return addr;
+
+ if (addr_mask)
+ addr = addr & VAddrAMask;
+
+ tbe = dtb->lookup(addr, part_id, data_real, ctx_zero ? 0 : pri_context ,
+ false);
+ if (tbe)
+ goto foundtbe;
+
+ tbe = itb->lookup(addr, part_id, inst_real, ctx_zero ? 0 : pri_context,
+ false);
+ if (tbe)
+ goto foundtbe;
+
+ // We didn't find it in the tlbs, so lets look at the TSBs
+ dtb->GetTsbPtr(tc, addr, ctx_zero ? 0 : pri_context, tsbs);
+ va_tag = bits(addr, 63, 22);
+ for (int x = 0; x < 4; x++) {
+ ttetag = betoh(mem->read<uint64_t>(tsbs[x]));
+ if (ttetag.valid() && ttetag.va() == va_tag) {
+ uint64_t entry = mem->read<uint64_t>(tsbs[x]) + sizeof(uint64_t);
+ // I think it's sun4v at least!
+ pte.populate(betoh(entry), PageTableEntry::sun4v);
+ DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TTE\n",
+ addr, pte.translate(addr));
+ goto foundpte;
}
- panic("couldn't translate %#x\n", addr);
-
-foundtbe:
- pte = tbe->pte;
- DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TLB\n", addr,
- pte.paddrMask() | addr & pte.sizeMask());
-foundpte:
- return pte.paddrMask() | addr & pte.sizeMask();
}
+ panic("couldn't translate %#x\n", addr);
+
+ foundtbe:
+ pte = tbe->pte;
+ DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TLB\n", addr,
+ pte.translate(addr));
+ foundpte:
+ return pte.translate(addr);
}
+
+} /* namespace SparcISA */
diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript
index 674cd54c2..4c0460e28 100644
--- a/src/arch/x86/SConscript
+++ b/src/arch/x86/SConscript
@@ -86,6 +86,7 @@
Import('*')
if env['TARGET_ISA'] == 'x86':
+ Source('cpuid.cc')
Source('emulenv.cc')
Source('floatregfile.cc')
Source('faults.cc')
@@ -105,16 +106,22 @@ if env['TARGET_ISA'] == 'x86':
Source('utility.cc')
SimObject('X86TLB.py')
- TraceFlag('Predecoder')
- TraceFlag('X86')
+ TraceFlag('Predecoder', "Predecoder debug output")
+ TraceFlag('X86', "Generic X86 ISA debugging")
if env['FULL_SYSTEM']:
+ TraceFlag('LocalApic', "Local APIC debugging")
+ TraceFlag('PageTableWalker', \
+ "Page table walker state machine debugging")
+ TraceFlag('Faults', "Trace all faults/exceptions/traps")
+
+ SimObject('X86LocalApic.py')
SimObject('X86System.py')
# Full-system sources
+ Source('interrupts.cc')
Source('linux/system.cc')
Source('pagetable_walker.cc')
- Source('smbios.cc')
Source('system.cc')
Source('stacktrace.cc')
Source('vtophys.cc')
@@ -170,7 +177,6 @@ if env['TARGET_ISA'] == 'x86':
'general_purpose/load_segment_registers.py',
'general_purpose/logical.py',
'general_purpose/no_operation.py',
- 'general_purpose/processor_information.py',
'general_purpose/rotate_and_shift/__init__.py',
'general_purpose/rotate_and_shift/rotate.py',
'general_purpose/rotate_and_shift/shift.py',
@@ -182,7 +188,9 @@ if env['TARGET_ISA'] == 'x86':
'general_purpose/string/scan_string.py',
'general_purpose/string/store_string.py',
'general_purpose/system_calls.py',
+ 'romutil.py',
'system/__init__.py',
+ 'system/control_registers.py',
'system/halt.py',
'system/invlpg.py',
'system/undefined_operation.py',
diff --git a/src/arch/x86/SConsopts b/src/arch/x86/SConsopts
index d8b7cbed1..f8b700271 100644
--- a/src/arch/x86/SConsopts
+++ b/src/arch/x86/SConsopts
@@ -3,43 +3,16 @@
# Copyright (c) 2007 The Hewlett-Packard Development Company
# All rights reserved.
#
-# Redistribution and use of this software in source and binary forms,
-# with or without modification, are permitted provided that the
-# following conditions are met:
-#
-# The software must be used only for Non-Commercial Use which means any
-# use which is NOT directed to receiving any direct monetary
-# compensation for, or commercial advantage from such use. Illustrative
-# examples of non-commercial use are academic research, personal study,
-# teaching, education and corporate research & development.
-# Illustrative examples of commercial use are distributing products for
-# commercial advantage and providing services using the software for
-# commercial advantage.
-#
-# If you wish to use this software or functionality therein that may be
-# covered by patents for commercial use, please contact:
-# Director of Intellectual Property Licensing
-# Office of Strategy and Technology
-# Hewlett-Packard Company
-# 1501 Page Mill Road
-# Palo Alto, California 94304
-#
-# Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer. Redistributions
-# in binary form must reproduce the above copyright notice, this list of
-# conditions and the following disclaimer in the documentation and/or
-# other materials provided with the distribution. Neither the name of
-# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+# 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. No right of
-# sublicense is granted herewith. Derivatives of the software and
-# output created using the software may be prepared, but only for
-# Non-Commercial Uses. Derivatives of the software may be shared with
-# others provided: (i) the others agree to abide by the list of
-# conditions herein which includes the Non-Commercial Use restrictions;
-# and (ii) such Derivatives of the software include the above copyright
-# notice to acknowledge the contribution from this software where
-# applicable, this list of conditions and the disclaimer below.
+# this software 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
diff --git a/src/arch/x86/X86LocalApic.py b/src/arch/x86/X86LocalApic.py
new file mode 100644
index 000000000..483c65ef8
--- /dev/null
+++ b/src/arch/x86/X86LocalApic.py
@@ -0,0 +1,36 @@
+# Copyright (c) 2008 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+from m5.params import *
+from Device import BasicPioDevice
+
+class X86LocalApic(BasicPioDevice):
+ type = 'X86LocalApic'
+ cxx_class = 'X86ISA::Interrupts'
+ pio_latency = Param.Latency('1ns', 'Programmed IO latency in simticks')
+ int_port = Port("Port for sending and receiving interrupt messages")
diff --git a/src/arch/x86/X86System.py b/src/arch/x86/X86System.py
index f73764540..527831205 100644
--- a/src/arch/x86/X86System.py
+++ b/src/arch/x86/X86System.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2007 The Hewlett-Packard Development Company
+# Copyright (c) 2007-2008 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
@@ -54,10 +54,27 @@
# Authors: Gabe Black
from m5.params import *
+from E820 import X86E820Table, X86E820Entry
+from SMBios import X86SMBiosSMBiosTable
+from IntelMP import X86IntelMPFloatingPointer, X86IntelMPConfigTable
+from ACPI import X86ACPIRSDP
from System import System
class X86System(System):
type = 'X86System'
+ smbios_table = Param.X86SMBiosSMBiosTable(
+ X86SMBiosSMBiosTable(), 'table of smbios/dmi information')
+ intel_mp_pointer = Param.X86IntelMPFloatingPointer(
+ X86IntelMPFloatingPointer(),
+ 'intel mp spec floating pointer structure')
+ intel_mp_table = Param.X86IntelMPConfigTable(
+ X86IntelMPConfigTable(),
+ 'intel mp spec configuration table')
+ acpi_description_table_pointer = Param.X86ACPIRSDP(
+ X86ACPIRSDP(), 'ACPI root description pointer structure')
class LinuxX86System(X86System):
type = 'LinuxX86System'
+
+ e820_table = Param.X86E820Table(
+ X86E820Table(), 'E820 map of physical memory')
diff --git a/src/arch/x86/X86TLB.py b/src/arch/x86/X86TLB.py
index dc080f37e..d5ae95372 100644
--- a/src/arch/x86/X86TLB.py
+++ b/src/arch/x86/X86TLB.py
@@ -54,23 +54,20 @@
# Authors: Gabe Black
from MemObject import MemObject
-from m5.SimObject import SimObject
from m5.params import *
from m5.proxy import *
from m5 import build_env
+from BaseTLB import BaseTLB
if build_env['FULL_SYSTEM']:
class X86PagetableWalker(MemObject):
type = 'X86PagetableWalker'
- cxx_namespace = 'X86ISA'
- cxx_class = 'Walker'
+ cxx_class = 'X86ISA::Walker'
port = Port("Port for the hardware table walker")
system = Param.System(Parent.any, "system object")
-class X86TLB(SimObject):
+class X86TLB(BaseTLB):
type = 'X86TLB'
- cxx_namespace = 'X86ISA'
- cxx_class = 'TLB'
abstract = True
size = Param.Int("TLB size")
if build_env['FULL_SYSTEM']:
@@ -79,14 +76,10 @@ class X86TLB(SimObject):
class X86DTB(X86TLB):
type = 'X86DTB'
- cxx_namespace = 'X86ISA'
- cxx_class = 'DTB'
-
+ cxx_class = 'X86ISA::DTB'
size = 64
class X86ITB(X86TLB):
type = 'X86ITB'
- cxx_namespace = 'X86ISA'
- cxx_class = 'ITB'
-
+ cxx_class = 'X86ISA::ITB'
size = 64
diff --git a/src/arch/x86/apicregs.hh b/src/arch/x86/apicregs.hh
new file mode 100644
index 000000000..464c3af2d
--- /dev/null
+++ b/src/arch/x86/apicregs.hh
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2008 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_X86_APICREGS_HH__
+#define __ARCH_X86_APICREGS_HH__
+
+namespace X86ISA
+{
+ enum ApicRegIndex
+ {
+ APIC_ID,
+ APIC_VERSION,
+ APIC_TASK_PRIORITY,
+ APIC_ARBITRATION_PRIORITY,
+ APIC_PROCESSOR_PRIORITY,
+ APIC_EOI,
+ APIC_LOGICAL_DESTINATION,
+ APIC_DESTINATION_FORMAT,
+ APIC_SPURIOUS_INTERRUPT_VECTOR,
+
+ APIC_IN_SERVICE_BASE,
+
+ APIC_TRIGGER_MODE_BASE = APIC_IN_SERVICE_BASE + 16,
+
+ APIC_INTERRUPT_REQUEST_BASE = APIC_TRIGGER_MODE_BASE + 16,
+
+ APIC_ERROR_STATUS = APIC_INTERRUPT_REQUEST_BASE + 16,
+ APIC_INTERRUPT_COMMAND_LOW,
+ APIC_INTERRUPT_COMMAND_HIGH,
+ APIC_LVT_TIMER,
+ APIC_LVT_THERMAL_SENSOR,
+ APIC_LVT_PERFORMANCE_MONITORING_COUNTERS,
+ APIC_LVT_LINT0,
+ APIC_LVT_LINT1,
+ APIC_LVT_ERROR,
+ APIC_INITIAL_COUNT,
+ APIC_CURRENT_COUNT,
+ APIC_DIVIDE_CONFIGURATION,
+
+ APIC_INTERNAL_STATE,
+
+ NUM_APIC_REGS
+ };
+
+ static inline ApicRegIndex
+ APIC_IN_SERVICE(int index)
+ {
+ return (ApicRegIndex)(APIC_IN_SERVICE_BASE + index);
+ }
+
+ static inline ApicRegIndex
+ APIC_TRIGGER_MODE(int index)
+ {
+ return (ApicRegIndex)(APIC_TRIGGER_MODE_BASE + index);
+ }
+
+ static inline ApicRegIndex
+ APIC_INTERRUPT_REQUEST(int index)
+ {
+ return (ApicRegIndex)(APIC_INTERRUPT_REQUEST_BASE + index);
+ }
+}
+
+#endif
diff --git a/src/arch/x86/bios/ACPI.py b/src/arch/x86/bios/ACPI.py
new file mode 100644
index 000000000..6f7cae946
--- /dev/null
+++ b/src/arch/x86/bios/ACPI.py
@@ -0,0 +1,99 @@
+# Copyright (c) 2008 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use of this software in source and binary forms,
+# with or without modification, are permitted provided that the
+# following conditions are met:
+#
+# The software must be used only for Non-Commercial Use which means any
+# use which is NOT directed to receiving any direct monetary
+# compensation for, or commercial advantage from such use. Illustrative
+# examples of non-commercial use are academic research, personal study,
+# teaching, education and corporate research & development.
+# Illustrative examples of commercial use are distributing products for
+# commercial advantage and providing services using the software for
+# commercial advantage.
+#
+# If you wish to use this software or functionality therein that may be
+# covered by patents for commercial use, please contact:
+# Director of Intellectual Property Licensing
+# Office of Strategy and Technology
+# Hewlett-Packard Company
+# 1501 Page Mill Road
+# Palo Alto, California 94304
+#
+# Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer. Redistributions
+# in binary form must reproduce the above copyright notice, this list of
+# conditions and the following disclaimer in the documentation and/or
+# other materials provided with the distribution. Neither the name of
+# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission. No right of
+# sublicense is granted herewith. Derivatives of the software and
+# output created using the software may be prepared, but only for
+# Non-Commercial Uses. Derivatives of the software may be shared with
+# others provided: (i) the others agree to abide by the list of
+# conditions herein which includes the Non-Commercial Use restrictions;
+# and (ii) such Derivatives of the software include the above copyright
+# notice to acknowledge the contribution from this software where
+# applicable, this list of conditions and the disclaimer below.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+from m5.params import *
+from m5.SimObject import SimObject
+
+# ACPI description table header. Subclasses contain and handle the actual
+# contents as appropriate for that type of table.
+class X86ACPISysDescTable(SimObject):
+ type = 'X86ACPISysDescTable'
+ cxx_class = 'X86ISA::ACPI::SysDescTable'
+ abstract = True
+
+ oem_id = Param.String('', 'string identifying the oem')
+ oem_table_id = Param.String('', 'oem table ID')
+ oem_revision = Param.UInt32(0, 'oem revision number for the table')
+
+ creator_id = Param.String('',
+ 'string identifying the generator of the table')
+ creator_revision = Param.UInt32(0,
+ 'revision number for the creator of the table')
+
+class X86ACPIRSDT(X86ACPISysDescTable):
+ type = 'X86ACPIRSDT'
+ cxx_class = 'X86ISA::ACPI::RSDT'
+
+ entries = VectorParam.X86ACPISysDescTable([], 'system description tables')
+
+class X86ACPIXSDT(X86ACPISysDescTable):
+ type = 'X86ACPIXSDT'
+ cxx_class = 'X86ISA::ACPI::XSDT'
+
+ entries = VectorParam.X86ACPISysDescTable([], 'system description tables')
+
+# Root System Description Pointer Structure
+class X86ACPIRSDP(SimObject):
+ type = 'X86ACPIRSDP'
+ cxx_class = 'X86ISA::ACPI::RSDP'
+
+ oem_id = Param.String('', 'string identifying the oem')
+ # Because 0 encodes ACPI 1.0, 2 encodes ACPI 3.0, the version implemented
+ # here.
+ revision = Param.UInt8(2, 'revision of ACPI being used, zero indexed')
+
+ rsdt = Param.X86ACPIRSDT(NULL, 'root system description table')
+ xsdt = Param.X86ACPIXSDT(X86ACPIXSDT(),
+ 'extended system description table')
diff --git a/src/arch/x86/bios/E820.py b/src/arch/x86/bios/E820.py
new file mode 100644
index 000000000..288c253fb
--- /dev/null
+++ b/src/arch/x86/bios/E820.py
@@ -0,0 +1,71 @@
+# Copyright (c) 2008 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use of this software in source and binary forms,
+# with or without modification, are permitted provided that the
+# following conditions are met:
+#
+# The software must be used only for Non-Commercial Use which means any
+# use which is NOT directed to receiving any direct monetary
+# compensation for, or commercial advantage from such use. Illustrative
+# examples of non-commercial use are academic research, personal study,
+# teaching, education and corporate research & development.
+# Illustrative examples of commercial use are distributing products for
+# commercial advantage and providing services using the software for
+# commercial advantage.
+#
+# If you wish to use this software or functionality therein that may be
+# covered by patents for commercial use, please contact:
+# Director of Intellectual Property Licensing
+# Office of Strategy and Technology
+# Hewlett-Packard Company
+# 1501 Page Mill Road
+# Palo Alto, California 94304
+#
+# Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer. Redistributions
+# in binary form must reproduce the above copyright notice, this list of
+# conditions and the following disclaimer in the documentation and/or
+# other materials provided with the distribution. Neither the name of
+# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission. No right of
+# sublicense is granted herewith. Derivatives of the software and
+# output created using the software may be prepared, but only for
+# Non-Commercial Uses. Derivatives of the software may be shared with
+# others provided: (i) the others agree to abide by the list of
+# conditions herein which includes the Non-Commercial Use restrictions;
+# and (ii) such Derivatives of the software include the above copyright
+# notice to acknowledge the contribution from this software where
+# applicable, this list of conditions and the disclaimer below.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+from m5.params import *
+from m5.SimObject import SimObject
+
+class X86E820Entry(SimObject):
+ type = 'X86E820Entry'
+ cxx_class = 'X86ISA::E820Entry'
+
+ addr = Param.Addr(0, 'address of the beginning of the region')
+ size = Param.MemorySize('0B', 'size of the region')
+ range_type = Param.UInt64('type of the region')
+
+class X86E820Table(SimObject):
+ type = 'X86E820Table'
+ cxx_class = 'X86ISA::E820Table'
+
+ entries = VectorParam.X86E820Entry([], 'entries for the e820 table')
diff --git a/src/arch/x86/bios/IntelMP.py b/src/arch/x86/bios/IntelMP.py
new file mode 100644
index 000000000..04e79b6ac
--- /dev/null
+++ b/src/arch/x86/bios/IntelMP.py
@@ -0,0 +1,242 @@
+# Copyright (c) 2008 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use of this software in source and binary forms,
+# with or without modification, are permitted provided that the
+# following conditions are met:
+#
+# The software must be used only for Non-Commercial Use which means any
+# use which is NOT directed to receiving any direct monetary
+# compensation for, or commercial advantage from such use. Illustrative
+# examples of non-commercial use are academic research, personal study,
+# teaching, education and corporate research & development.
+# Illustrative examples of commercial use are distributing products for
+# commercial advantage and providing services using the software for
+# commercial advantage.
+#
+# If you wish to use this software or functionality therein that may be
+# covered by patents for commercial use, please contact:
+# Director of Intellectual Property Licensing
+# Office of Strategy and Technology
+# Hewlett-Packard Company
+# 1501 Page Mill Road
+# Palo Alto, California 94304
+#
+# Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer. Redistributions
+# in binary form must reproduce the above copyright notice, this list of
+# conditions and the following disclaimer in the documentation and/or
+# other materials provided with the distribution. Neither the name of
+# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission. No right of
+# sublicense is granted herewith. Derivatives of the software and
+# output created using the software may be prepared, but only for
+# Non-Commercial Uses. Derivatives of the software may be shared with
+# others provided: (i) the others agree to abide by the list of
+# conditions herein which includes the Non-Commercial Use restrictions;
+# and (ii) such Derivatives of the software include the above copyright
+# notice to acknowledge the contribution from this software where
+# applicable, this list of conditions and the disclaimer below.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+from m5.params import *
+from m5.SimObject import SimObject
+
+class X86IntelMPFloatingPointer(SimObject):
+ type = 'X86IntelMPFloatingPointer'
+ cxx_class = 'X86ISA::IntelMP::FloatingPointer'
+
+ # The minor revision of the spec to support. The major version is assumed
+ # to be 1 in accordance with the spec.
+ spec_rev = Param.UInt8(4, 'minor revision of the MP spec supported')
+ # If no default configuration is used, set this to 0.
+ default_config = Param.UInt8(0, 'which default configuration to use')
+ imcr_present = Param.Bool(True,
+ 'whether the IMCR register is present in the APIC')
+
+class X86IntelMPConfigTable(SimObject):
+ type = 'X86IntelMPConfigTable'
+ cxx_class = 'X86ISA::IntelMP::ConfigTable'
+
+ spec_rev = Param.UInt8(4, 'minor revision of the MP spec supported')
+ oem_id = Param.String("", 'system manufacturer')
+ product_id = Param.String("", 'product family')
+ oem_table_addr = Param.UInt32(0,
+ 'pointer to the optional oem configuration table')
+ oem_table_size = Param.UInt16(0, 'size of the oem configuration table')
+ local_apic = Param.UInt32(0xFEE00000, 'address of the local APIC')
+
+ base_entries = VectorParam.X86IntelMPBaseConfigEntry([],
+ 'base configuration table entries')
+
+ ext_entries = VectorParam.X86IntelMPExtConfigEntry([],
+ 'extended configuration table entries')
+
+ def add_entry(self, entry):
+ if isinstance(entry, X86IntelMPBaseConfigEntry):
+ self.base_entries.append(entry)
+ elif isinstance(entry, X86IntelMPExtConfigEntry):
+ self.ext_entries.append(entry)
+ else:
+ panic("Don't know what type of Intel MP entry %s is." \
+ % entry.__class__.__name__)
+
+class X86IntelMPBaseConfigEntry(SimObject):
+ type = 'X86IntelMPBaseConfigEntry'
+ cxx_class = 'X86ISA::IntelMP::BaseConfigEntry'
+ abstract = True
+
+class X86IntelMPExtConfigEntry(SimObject):
+ type = 'X86IntelMPExtConfigEntry'
+ cxx_class = 'X86ISA::IntelMP::ExtConfigEntry'
+ abstract = True
+
+class X86IntelMPProcessor(X86IntelMPBaseConfigEntry):
+ type = 'X86IntelMPProcessor'
+ cxx_class = 'X86ISA::IntelMP::Processor'
+
+ local_apic_id = Param.UInt8(0, 'local APIC id')
+ local_apic_version = Param.UInt8(0,
+ 'bits 0-7 of the local APIC version register')
+ enable = Param.Bool(True, 'if this processor is usable')
+ bootstrap = Param.Bool(False, 'if this is the bootstrap processor')
+
+ stepping = Param.UInt8(0, 'Processor stepping')
+ model = Param.UInt8(0, 'Processor model')
+ family = Param.UInt8(0, 'Processor family')
+
+ feature_flags = Param.UInt32(0, 'flags returned by the CPUID instruction')
+
+class X86IntelMPBus(X86IntelMPBaseConfigEntry):
+ type = 'X86IntelMPBus'
+ cxx_class = 'X86ISA::IntelMP::Bus'
+
+ bus_id = Param.UInt8(0, 'bus id assigned by the bios')
+ bus_type = Param.String("", 'string that identify the bus type')
+ # Legal values for bus_type are:
+ #
+ # "CBUS", "CBUSII", "EISA", "FUTURE", "INTERN", "ISA", "MBI", "MBII",
+ # "MCA", "MPI", "MPSA", "NUBUS", "PCI", "PCMCIA", "TC", "VL", "VME",
+ # "XPRESS"
+
+class X86IntelMPIOAPIC(X86IntelMPBaseConfigEntry):
+ type = 'X86IntelMPIOAPIC'
+ cxx_class = 'X86ISA::IntelMP::IOAPIC'
+
+ id = Param.UInt8(0, 'id of this APIC')
+ version = Param.UInt8(0, 'bits 0-7 of the version register')
+
+ enable = Param.Bool(True, 'if this APIC is usable')
+
+ address = Param.UInt32(0xfec00000, 'address of this APIC')
+
+class X86IntelMPInterruptType(Enum):
+ map = {'INT' : 0,
+ 'NMI' : 1,
+ 'SMI' : 2,
+ 'ExtInt' : 3
+ }
+
+class X86IntelMPPolarity(Enum):
+ map = {'ConformPolarity' : 0,
+ 'ActiveHigh' : 1,
+ 'ActiveLow' : 3
+ }
+
+class X86IntelMPTriggerMode(Enum):
+ map = {'ConformTrigger' : 0,
+ 'EdgeTrigger' : 1,
+ 'LevelTrigger' : 3
+ }
+
+class X86IntelMPIOIntAssignment(X86IntelMPBaseConfigEntry):
+ type = 'X86IntelMPIOIntAssignment'
+ cxx_class = 'X86ISA::IntelMP::IOIntAssignment'
+
+ interrupt_type = Param.X86IntelMPInterruptType('INT', 'type of interrupt')
+
+ polarity = Param.X86IntelMPPolarity('ConformPolarity', 'polarity')
+ trigger = Param.X86IntelMPTriggerMode('ConformTrigger', 'trigger mode')
+
+ source_bus_id = Param.UInt8(0,
+ 'id of the bus from which the interrupt signal comes')
+ source_bus_irq = Param.UInt8(0,
+ 'which interrupt signal from the source bus')
+
+ dest_io_apic_id = Param.UInt8(0,
+ 'id of the IO APIC the interrupt is going to')
+ dest_io_apic_intin = Param.UInt8(0,
+ 'the INTIN pin on the IO APIC the interrupt is connected to')
+
+class X86IntelMPLocalIntAssignment(X86IntelMPBaseConfigEntry):
+ type = 'X86IntelMPLocalIntAssignment'
+ cxx_class = 'X86ISA::IntelMP::LocalIntAssignment'
+
+ interrupt_type = Param.X86IntelMPInterruptType('INT', 'type of interrupt')
+
+ polarity = Param.X86IntelMPPolarity('ConformPolarity', 'polarity')
+ trigger = Param.X86IntelMPTriggerMode('ConformTrigger', 'trigger mode')
+
+ source_bus_id = Param.UInt8(0,
+ 'id of the bus from which the interrupt signal comes')
+ source_bus_irq = Param.UInt8(0,
+ 'which interrupt signal from the source bus')
+
+ dest_local_apic_id = Param.UInt8(0,
+ 'id of the local APIC the interrupt is going to')
+ dest_local_apic_intin = Param.UInt8(0,
+ 'the INTIN pin on the local APIC the interrupt is connected to')
+
+class X86IntelMPAddressType(Enum):
+ map = {"IOAddress" : 0,
+ "MemoryAddress" : 1,
+ "PrefetchAddress" : 2
+ }
+
+class X86IntelMPAddrSpaceMapping(X86IntelMPExtConfigEntry):
+ type = 'X86IntelMPAddrSpaceMapping'
+ cxx_class = 'X86ISA::IntelMP::AddrSpaceMapping'
+
+ bus_id = Param.UInt8(0, 'id of the bus the address space is mapped to')
+ address_type = Param.X86IntelMPAddressType('IOAddress',
+ 'address type used to access bus')
+ address = Param.Addr(0, 'starting address of the mapping')
+ length = Param.UInt64(0, 'length of mapping in bytes')
+
+class X86IntelMPBusHierarchy(X86IntelMPExtConfigEntry):
+ type = 'X86IntelMPBusHierarchy'
+ cxx_class = 'X86ISA::IntelMP::BusHierarchy'
+
+ bus_id = Param.UInt8(0, 'id of the bus being described')
+ subtractive_decode = Param.Bool(False,
+ 'whether this bus contains all addresses not used by its children')
+ parent_bus = Param.UInt8(0, 'bus id of this busses parent')
+
+class X86IntelMPRangeList(Enum):
+ map = {"ISACompatible" : 0,
+ "VGACompatible" : 1
+ }
+
+class X86IntelMPCompatAddrSpaceMod(X86IntelMPExtConfigEntry):
+ type = 'X86IntelMPCompatAddrSpaceMod'
+ cxx_class = 'X86ISA::IntelMP::CompatAddrSpaceMod'
+
+ bus_id = Param.UInt8(0, 'id of the bus being described')
+ add = Param.Bool(False,
+ 'if the range should be added to the original mapping')
+ range_list = Param.X86IntelMPRangeList('ISACompatible',
+ 'which predefined range of addresses to use')
diff --git a/src/arch/x86/bios/SConscript b/src/arch/x86/bios/SConscript
new file mode 100644
index 000000000..912d6599c
--- /dev/null
+++ b/src/arch/x86/bios/SConscript
@@ -0,0 +1,77 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2007-2008 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use of this software in source and binary forms,
+# with or without modification, are permitted provided that the
+# following conditions are met:
+#
+# The software must be used only for Non-Commercial Use which means any
+# use which is NOT directed to receiving any direct monetary
+# compensation for, or commercial advantage from such use. Illustrative
+# examples of non-commercial use are academic research, personal study,
+# teaching, education and corporate research & development.
+# Illustrative examples of commercial use are distributing products for
+# commercial advantage and providing services using the software for
+# commercial advantage.
+#
+# If you wish to use this software or functionality therein that may be
+# covered by patents for commercial use, please contact:
+# Director of Intellectual Property Licensing
+# Office of Strategy and Technology
+# Hewlett-Packard Company
+# 1501 Page Mill Road
+# Palo Alto, California 94304
+#
+# Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer. Redistributions
+# in binary form must reproduce the above copyright notice, this list of
+# conditions and the following disclaimer in the documentation and/or
+# other materials provided with the distribution. Neither the name of
+# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission. No right of
+# sublicense is granted herewith. Derivatives of the software and
+# output created using the software may be prepared, but only for
+# Non-Commercial Uses. Derivatives of the software may be shared with
+# others provided: (i) the others agree to abide by the list of
+# conditions herein which includes the Non-Commercial Use restrictions;
+# and (ii) such Derivatives of the software include the above copyright
+# notice to acknowledge the contribution from this software where
+# applicable, this list of conditions and the disclaimer below.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+Import('*')
+
+if env['TARGET_ISA'] == 'x86':
+ if env['FULL_SYSTEM']:
+ # The table generated by the bootloader using the BIOS and passed to
+ # the operating system which maps out physical memory.
+ SimObject('E820.py')
+ Source('e820.cc')
+
+ # The DMI tables.
+ SimObject('SMBios.py')
+ Source('smbios.cc')
+
+ # Intel Multiprocessor Specification Configuration Table
+ SimObject('IntelMP.py')
+ Source('intelmp.cc')
+
+ # ACPI system description tables
+ SimObject('ACPI.py')
+ Source('acpi.cc')
diff --git a/src/arch/x86/bios/SMBios.py b/src/arch/x86/bios/SMBios.py
new file mode 100644
index 000000000..4947b2854
--- /dev/null
+++ b/src/arch/x86/bios/SMBios.py
@@ -0,0 +1,140 @@
+# Copyright (c) 2008 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use of this software in source and binary forms,
+# with or without modification, are permitted provided that the
+# following conditions are met:
+#
+# The software must be used only for Non-Commercial Use which means any
+# use which is NOT directed to receiving any direct monetary
+# compensation for, or commercial advantage from such use. Illustrative
+# examples of non-commercial use are academic research, personal study,
+# teaching, education and corporate research & development.
+# Illustrative examples of commercial use are distributing products for
+# commercial advantage and providing services using the software for
+# commercial advantage.
+#
+# If you wish to use this software or functionality therein that may be
+# covered by patents for commercial use, please contact:
+# Director of Intellectual Property Licensing
+# Office of Strategy and Technology
+# Hewlett-Packard Company
+# 1501 Page Mill Road
+# Palo Alto, California 94304
+#
+# Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer. Redistributions
+# in binary form must reproduce the above copyright notice, this list of
+# conditions and the following disclaimer in the documentation and/or
+# other materials provided with the distribution. Neither the name of
+# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission. No right of
+# sublicense is granted herewith. Derivatives of the software and
+# output created using the software may be prepared, but only for
+# Non-Commercial Uses. Derivatives of the software may be shared with
+# others provided: (i) the others agree to abide by the list of
+# conditions herein which includes the Non-Commercial Use restrictions;
+# and (ii) such Derivatives of the software include the above copyright
+# notice to acknowledge the contribution from this software where
+# applicable, this list of conditions and the disclaimer below.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+from m5.params import *
+from m5.SimObject import SimObject
+
+class X86SMBiosSMBiosStructure(SimObject):
+ type = 'X86SMBiosSMBiosStructure'
+ cxx_class = 'X86ISA::SMBios::SMBiosStructure'
+ abstract = True
+
+class Characteristic(Enum):
+ map = {'Unknown' : 2,
+ 'Unsupported' : 3,
+ 'ISA' : 4,
+ 'MCA' : 5,
+ 'EISA' : 6,
+ 'PCI' : 7,
+ 'PCMCIA' : 8,
+ 'PnP' : 9,
+ 'APM' : 10,
+ 'Flash' : 11,
+ 'Shadow' : 12,
+ 'VL_Vesa' : 13,
+ 'ESCD' : 14,
+ 'CDBoot' : 15,
+ 'SelectBoot' : 16,
+ 'Socketed' : 17,
+ 'PCMCIABoot' : 18,
+ 'EDD' : 19,
+ 'NEC9800' : 20,
+ 'Toshiba' : 21,
+ 'Floppy_5_25_360KB' : 22,
+ 'Floppy_5_25_1_2MB' : 23,
+ 'Floppy_3_5_720KB' : 24,
+ 'Floppy_3_5_2_88MB' : 25,
+ 'PrintScreen' : 26,
+ 'Keyboard8024' : 27,
+ 'Serial' : 28,
+ 'Printer' : 29,
+ 'CGA_Mono' : 30,
+ 'NEC_PC_98' : 31
+ }
+
+class ExtCharacteristic(Enum):
+ map = {'ACPI' : 0,
+ 'USBLegacy' : 1,
+ 'AGP' : 2,
+ 'I20Boot' : 3,
+ 'LS_120Boot' : 4,
+ 'ZIPBoot' : 5,
+ 'FirewireBoot' : 6,
+ 'SmartBattery' : 7,
+ 'BootSpec' : 8,
+ 'NetServiceBoot' : 9,
+ 'TargetContent' : 10
+ }
+
+class X86SMBiosBiosInformation(X86SMBiosSMBiosStructure):
+ type = 'X86SMBiosBiosInformation'
+ cxx_class = 'X86ISA::SMBios::BiosInformation'
+
+ vendor = Param.String("", "vendor name string")
+ version = Param.String("", "version string")
+ starting_addr_segment = \
+ Param.UInt16(0, "segment location of bios starting address")
+ release_date = Param.String("06/08/2008", "release date")
+ rom_size = Param.UInt8(0, "rom size")
+ characteristics = VectorParam.Characteristic([],
+ "bios characteristic bit vector")
+ characteristic_ext_bytes = VectorParam.ExtCharacteristic([],
+ "extended bios characteristic bit vector")
+ major = Param.UInt8(0, "major version number")
+ minor = Param.UInt8(0, "minor version number")
+ emb_cont_firmware_major = Param.UInt8(0,
+ "embedded controller firmware major version number")
+
+ emb_cont_firmware_minor = Param.UInt8(0,
+ "embedded controller firmware minor version number")
+
+class X86SMBiosSMBiosTable(SimObject):
+ type = 'X86SMBiosSMBiosTable'
+ cxx_class = 'X86ISA::SMBios::SMBiosTable'
+
+ major_version = Param.UInt8(2, "major version number")
+ minor_version = Param.UInt8(5, "minor version number")
+
+ structures = VectorParam.X86SMBiosSMBiosStructure([], "smbios structures")
diff --git a/src/arch/x86/bios/acpi.cc b/src/arch/x86/bios/acpi.cc
new file mode 100644
index 000000000..15b3901eb
--- /dev/null
+++ b/src/arch/x86/bios/acpi.cc
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2008 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer. Redistributions
+ * in binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution. Neither the name of
+ * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "arch/x86/bios/acpi.hh"
+#include "mem/port.hh"
+#include "sim/byteswap.hh"
+#include "sim/sim_object.hh"
+
+#include "params/X86ACPIRSDP.hh"
+
+#include "params/X86ACPISysDescTable.hh"
+#include "params/X86ACPIRSDT.hh"
+#include "params/X86ACPIXSDT.hh"
+
+using namespace std;
+
+const char X86ISA::ACPI::RSDP::signature[] = "RSD PTR ";
+
+X86ISA::ACPI::RSDP::RSDP(Params *p) : SimObject(p), oemID(p->oem_id),
+ revision(p->revision), rsdt(p->rsdt), xsdt(p->xsdt)
+{}
+
+X86ISA::ACPI::SysDescTable::SysDescTable(Params *p,
+ const char * _signature, uint8_t _revision) : SimObject(p),
+ signature(_signature), revision(_revision),
+ oemID(p->oem_id), oemTableID(p->oem_table_id),
+ oemRevision(p->oem_revision),
+ creatorID(p->creator_id), creatorRevision(p->creator_revision)
+{}
+
+X86ISA::ACPI::RSDT::RSDT(Params *p) :
+ SysDescTable(p, "RSDT", 1), entries(p->entries)
+{}
+
+X86ISA::ACPI::XSDT::XSDT(Params *p) :
+ SysDescTable(p, "XSDT", 1), entries(p->entries)
+{}
+
+X86ISA::ACPI::RSDP *
+X86ACPIRSDPParams::create()
+{
+ return new X86ISA::ACPI::RSDP(this);
+}
+
+X86ISA::ACPI::RSDT *
+X86ACPIRSDTParams::create()
+{
+ return new X86ISA::ACPI::RSDT(this);
+}
+
+X86ISA::ACPI::XSDT *
+X86ACPIXSDTParams::create()
+{
+ return new X86ISA::ACPI::XSDT(this);
+}
diff --git a/src/arch/x86/bios/acpi.hh b/src/arch/x86/bios/acpi.hh
new file mode 100644
index 000000000..7bca17790
--- /dev/null
+++ b/src/arch/x86/bios/acpi.hh
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2008 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer. Redistributions
+ * in binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution. Neither the name of
+ * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_X86_BIOS_ACPI_HH__
+#define __ARCH_X86_BIOS_ACPI_HH__
+
+#include "sim/host.hh"
+#include "sim/sim_object.hh"
+
+#include <vector>
+#include <string>
+
+class Port;
+
+class X86ACPIRSDPParams;
+
+class X86ACPISysDescTableParams;
+class X86ACPIRSDTParams;
+class X86ACPIXSDTParams;
+
+namespace X86ISA
+{
+
+namespace ACPI
+{
+
+class RSDT;
+class XSDT;
+class SysDescTable;
+
+class RSDP : public SimObject
+{
+ protected:
+ typedef X86ACPIRSDPParams Params;
+
+ static const char signature[];
+
+ std::string oemID;
+ uint8_t revision;
+
+ RSDT * rsdt;
+ XSDT * xsdt;
+
+ public:
+ RSDP(Params *p);
+};
+
+class SysDescTable : public SimObject
+{
+ protected:
+ typedef X86ACPISysDescTableParams Params;
+
+ const char * signature;
+ uint8_t revision;
+
+ std::string oemID;
+ std::string oemTableID;
+ uint32_t oemRevision;
+
+ std::string creatorID;
+ uint32_t creatorRevision;
+
+ public:
+ SysDescTable(Params *p, const char * _signature, uint8_t _revision);
+};
+
+class RSDT : public SysDescTable
+{
+ protected:
+ typedef X86ACPIRSDTParams Params;
+
+ std::vector<SysDescTable *> entries;
+
+ public:
+ RSDT(Params *p);
+};
+
+class XSDT : public SysDescTable
+{
+ protected:
+ typedef X86ACPIXSDTParams Params;
+
+ std::vector<SysDescTable *> entries;
+
+ public:
+ XSDT(Params *p);
+};
+
+} // namespace ACPI
+
+} // namespace X86ISA
+
+#endif // __ARCH_X86_BIOS_E820_HH__
diff --git a/src/arch/x86/bios/e820.cc b/src/arch/x86/bios/e820.cc
new file mode 100644
index 000000000..47adb703a
--- /dev/null
+++ b/src/arch/x86/bios/e820.cc
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2008 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer. Redistributions
+ * in binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution. Neither the name of
+ * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "arch/x86/bios/e820.hh"
+#include "arch/x86/isa_traits.hh"
+#include "mem/port.hh"
+#include "sim/byteswap.hh"
+
+using namespace std;
+using namespace X86ISA;
+
+template<class T>
+void writeVal(T val, Port * port, Addr &addr)
+{
+ T guestVal = htog(val);
+ port->writeBlob(addr, (uint8_t *)&guestVal, sizeof(T));
+ addr += sizeof(T);
+}
+
+void X86ISA::E820Table::writeTo(Port * port, Addr countAddr, Addr addr)
+{
+ uint8_t e820Nr = entries.size();
+
+ // Make sure the number of entries isn't bigger than what the kernel
+ // would be capable of handling.
+ assert(e820Nr <= 128);
+
+ uint8_t guestE820Nr = htog(e820Nr);
+
+ port->writeBlob(countAddr, (uint8_t *)&guestE820Nr, sizeof(guestE820Nr));
+
+ for (int i = 0; i < e820Nr; i++) {
+ writeVal(entries[i]->addr, port, addr);
+ writeVal(entries[i]->size, port, addr);
+ writeVal(entries[i]->type, port, addr);
+ }
+}
+
+E820Table *
+X86E820TableParams::create()
+{
+ return new E820Table(this);
+}
+
+E820Entry *
+X86E820EntryParams::create()
+{
+ return new E820Entry(this);
+}
diff --git a/src/arch/x86/syscallreturn.hh b/src/arch/x86/bios/e820.hh
index 6a7fdba58..da738343b 100644
--- a/src/arch/x86/syscallreturn.hh
+++ b/src/arch/x86/bios/e820.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * Copyright (c) 2008 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
@@ -55,20 +55,46 @@
* Authors: Gabe Black
*/
-#ifndef __ARCH_X86_SYSCALLRETURN_HH__
-#define __ARCH_X86_SYSCALLRETURN_HH__
+#ifndef __ARCH_X86_BIOS_E820_HH__
+#define __ARCH_X86_BIOS_E820_HH__
-#include "base/misc.hh"
-#include "cpu/thread_context.hh"
-#include "sim/syscallreturn.hh"
+#include "params/X86E820Entry.hh"
+#include "params/X86E820Table.hh"
+#include "sim/host.hh"
+#include "sim/sim_object.hh"
+
+#include <vector>
+
+class Port;
namespace X86ISA
{
- static inline void setSyscallReturn(SyscallReturn return_value,
- ThreadContext * tc)
+ class E820Entry : public SimObject
{
- tc->setIntReg(INTREG_RAX, return_value.value());
- }
+ public:
+ Addr addr;
+ Addr size;
+ uint32_t type;
+
+ public:
+ typedef X86E820EntryParams Params;
+ E820Entry(Params *p) :
+ SimObject(p), addr(p->addr), size(p->size), type(p->range_type)
+ {}
+ };
+
+ class E820Table : public SimObject
+ {
+ public:
+ std::vector<E820Entry *> entries;
+
+ public:
+ typedef X86E820TableParams Params;
+ E820Table(Params *p) : SimObject(p), entries(p->entries)
+ {}
+
+ void writeTo(Port * port, Addr countAddr, Addr addr);
+ };
};
-#endif // __ARCH_X86_SYSCALLRETURN_HH__
+#endif // __ARCH_X86_BIOS_E820_HH__
diff --git a/src/arch/x86/bios/intelmp.cc b/src/arch/x86/bios/intelmp.cc
new file mode 100644
index 000000000..2332e7a5c
--- /dev/null
+++ b/src/arch/x86/bios/intelmp.cc
@@ -0,0 +1,476 @@
+/*
+ * Copyright (c) 2008 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer. Redistributions
+ * in binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution. Neither the name of
+ * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "arch/x86/bios/intelmp.hh"
+#include "arch/x86/isa_traits.hh"
+#include "base/misc.hh"
+#include "mem/port.hh"
+#include "sim/byteswap.hh"
+#include "sim/host.hh"
+
+// Config entry types
+#include "params/X86IntelMPBaseConfigEntry.hh"
+#include "params/X86IntelMPExtConfigEntry.hh"
+
+// General table structures
+#include "params/X86IntelMPConfigTable.hh"
+#include "params/X86IntelMPFloatingPointer.hh"
+
+// Base entry types
+#include "params/X86IntelMPBus.hh"
+#include "params/X86IntelMPIOAPIC.hh"
+#include "params/X86IntelMPIOIntAssignment.hh"
+#include "params/X86IntelMPLocalIntAssignment.hh"
+#include "params/X86IntelMPProcessor.hh"
+
+// Extended entry types
+#include "params/X86IntelMPAddrSpaceMapping.hh"
+#include "params/X86IntelMPBusHierarchy.hh"
+#include "params/X86IntelMPCompatAddrSpaceMod.hh"
+
+using namespace std;
+
+const char X86ISA::IntelMP::FloatingPointer::signature[] = "_MP_";
+
+template<class T>
+uint8_t
+writeOutField(FunctionalPort * port, Addr addr, T val)
+{
+ T guestVal = X86ISA::htog(val);
+ port->writeBlob(addr, (uint8_t *)(&guestVal), sizeof(T));
+
+ uint8_t checkSum = 0;
+ while(guestVal) {
+ checkSum += guestVal;
+ guestVal >>= 8;
+ }
+ return checkSum;
+}
+
+uint8_t
+writeOutString(FunctionalPort * port, Addr addr, string str, int length)
+{
+ char cleanedString[length + 1];
+ cleanedString[length] = 0;
+
+ if (str.length() > length) {
+ memcpy(cleanedString, str.c_str(), length);
+ warn("Intel MP configuration table string \"%s\" "
+ "will be truncated to \"%s\".\n", str, cleanedString);
+ } else {
+ memcpy(cleanedString, str.c_str(), str.length());
+ memset(cleanedString + str.length(), 0, length - str.length());
+ }
+ port->writeBlob(addr, (uint8_t *)(&cleanedString), length);
+
+ uint8_t checkSum = 0;
+ for (int i = 0; i < length; i++)
+ checkSum += cleanedString[i];
+
+ return checkSum;
+}
+
+Addr
+X86ISA::IntelMP::FloatingPointer::writeOut(FunctionalPort * port, Addr addr)
+{
+ // Make sure that either a config table is present or a default
+ // configuration was found but not both.
+ if (!tableAddr && !defaultConfig)
+ fatal("Either an MP configuration table or a default configuration "
+ "must be used.");
+ if (tableAddr && defaultConfig)
+ fatal("Both an MP configuration table and a default configuration "
+ "were set.");
+
+ uint8_t checkSum = 0;
+
+ port->writeBlob(addr, (uint8_t *)signature, 4);
+ for (int i = 0; i < 4; i++)
+ checkSum += signature[i];
+
+ checkSum += writeOutField(port, addr + 4, tableAddr);
+
+ // The length of the structure in paragraphs, aka 16 byte chunks.
+ uint8_t length = 1;
+ port->writeBlob(addr + 8, &length, 1);
+ checkSum += length;
+
+ port->writeBlob(addr + 9, &specRev, 1);
+ checkSum += specRev;
+
+ port->writeBlob(addr + 11, &defaultConfig, 1);
+ checkSum += defaultConfig;
+
+ uint32_t features2_5 = imcrPresent ? (1 << 7) : 0;
+ checkSum += writeOutField(port, addr + 12, features2_5);
+
+ checkSum = -checkSum;
+ port->writeBlob(addr + 10, &checkSum, 1);
+
+ return 16;
+}
+
+X86ISA::IntelMP::FloatingPointer::FloatingPointer(Params * p) :
+ SimObject(p), tableAddr(0), specRev(p->spec_rev),
+ defaultConfig(p->default_config), imcrPresent(p->imcr_present)
+{}
+
+X86ISA::IntelMP::FloatingPointer *
+X86IntelMPFloatingPointerParams::create()
+{
+ return new X86ISA::IntelMP::FloatingPointer(this);
+}
+
+Addr
+X86ISA::IntelMP::BaseConfigEntry::writeOut(FunctionalPort * port,
+ Addr addr, uint8_t &checkSum)
+{
+ port->writeBlob(addr, &type, 1);
+ checkSum += type;
+ return 1;
+}
+
+X86ISA::IntelMP::BaseConfigEntry::BaseConfigEntry(Params * p, uint8_t _type) :
+ SimObject(p), type(_type)
+{}
+
+Addr
+X86ISA::IntelMP::ExtConfigEntry::writeOut(FunctionalPort * port,
+ Addr addr, uint8_t &checkSum)
+{
+ port->writeBlob(addr, &type, 1);
+ checkSum += type;
+ port->writeBlob(addr + 1, &length, 1);
+ checkSum += length;
+ return 1;
+}
+
+X86ISA::IntelMP::ExtConfigEntry::ExtConfigEntry(Params * p,
+ uint8_t _type, uint8_t _length) :
+ SimObject(p), type(_type), length(_length)
+{}
+
+const char X86ISA::IntelMP::ConfigTable::signature[] = "PCMP";
+
+Addr
+X86ISA::IntelMP::ConfigTable::writeOut(FunctionalPort * port, Addr addr)
+{
+ uint8_t checkSum = 0;
+
+ port->writeBlob(addr, (uint8_t *)signature, 4);
+ for (int i = 0; i < 4; i++)
+ checkSum += signature[i];
+
+ // Base table length goes here but will be calculated later.
+
+ port->writeBlob(addr + 6, (uint8_t *)(&specRev), 1);
+ checkSum += specRev;
+
+ // The checksum goes here but is still being calculated.
+
+ checkSum += writeOutString(port, addr + 8, oemID, 8);
+ checkSum += writeOutString(port, addr + 16, productID, 12);
+
+ checkSum += writeOutField(port, addr + 28, oemTableAddr);
+ checkSum += writeOutField(port, addr + 32, oemTableSize);
+ checkSum += writeOutField(port, addr + 34, (uint16_t)baseEntries.size());
+ checkSum += writeOutField(port, addr + 36, localApic);
+
+ uint8_t reserved = 0;
+ port->writeBlob(addr + 43, &reserved, 1);
+ checkSum += reserved;
+
+ vector<BaseConfigEntry *>::iterator baseEnt;
+ uint16_t offset = 44;
+ for (baseEnt = baseEntries.begin();
+ baseEnt != baseEntries.end(); baseEnt++) {
+ offset += (*baseEnt)->writeOut(port, addr + offset, checkSum);
+ }
+
+ // We've found the end of the base table this point.
+ checkSum += writeOutField(port, addr + 4, offset);
+
+ vector<ExtConfigEntry *>::iterator extEnt;
+ uint16_t extOffset = 0;
+ uint8_t extCheckSum = 0;
+ for (extEnt = extEntries.begin();
+ extEnt != extEntries.end(); extEnt++) {
+ extOffset += (*extEnt)->writeOut(port,
+ addr + offset + extOffset, extCheckSum);
+ }
+
+ checkSum += writeOutField(port, addr + 40, extOffset);
+ extCheckSum = -extCheckSum;
+ checkSum += writeOutField(port, addr + 42, extCheckSum);
+
+ // And now, we finally have the whole check sum completed.
+ checkSum = -checkSum;
+ writeOutField(port, addr + 7, checkSum);
+
+ return offset + extOffset;
+};
+
+X86ISA::IntelMP::ConfigTable::ConfigTable(Params * p) : SimObject(p),
+ specRev(p->spec_rev), oemID(p->oem_id), productID(p->product_id),
+ oemTableAddr(p->oem_table_addr), oemTableSize(p->oem_table_size),
+ localApic(p->local_apic),
+ baseEntries(p->base_entries), extEntries(p->ext_entries)
+{}
+
+X86ISA::IntelMP::ConfigTable *
+X86IntelMPConfigTableParams::create()
+{
+ return new X86ISA::IntelMP::ConfigTable(this);
+}
+
+Addr
+X86ISA::IntelMP::Processor::writeOut(
+ FunctionalPort * port, Addr addr, uint8_t &checkSum)
+{
+ BaseConfigEntry::writeOut(port, addr, checkSum);
+ checkSum += writeOutField(port, addr + 1, localApicID);
+ checkSum += writeOutField(port, addr + 2, localApicVersion);
+ checkSum += writeOutField(port, addr + 3, cpuFlags);
+ checkSum += writeOutField(port, addr + 4, cpuSignature);
+ checkSum += writeOutField(port, addr + 8, featureFlags);
+
+ uint32_t reserved = 0;
+ port->writeBlob(addr + 12, (uint8_t *)(&reserved), 4);
+ port->writeBlob(addr + 16, (uint8_t *)(&reserved), 4);
+ return 20;
+}
+
+X86ISA::IntelMP::Processor::Processor(Params * p) : BaseConfigEntry(p, 0),
+ localApicID(p->local_apic_id), localApicVersion(p->local_apic_version),
+ cpuFlags(0), cpuSignature(0), featureFlags(p->feature_flags)
+{
+ if (p->enable)
+ cpuFlags |= (1 << 0);
+ if (p->bootstrap)
+ cpuFlags |= (1 << 1);
+
+ replaceBits(cpuSignature, 0, 3, p->stepping);
+ replaceBits(cpuSignature, 4, 7, p->model);
+ replaceBits(cpuSignature, 8, 11, p->family);
+}
+
+X86ISA::IntelMP::Processor *
+X86IntelMPProcessorParams::create()
+{
+ return new X86ISA::IntelMP::Processor(this);
+}
+
+Addr
+X86ISA::IntelMP::Bus::writeOut(
+ FunctionalPort * port, Addr addr, uint8_t &checkSum)
+{
+ BaseConfigEntry::writeOut(port, addr, checkSum);
+ checkSum += writeOutField(port, addr + 1, busID);
+ checkSum += writeOutString(port, addr + 2, busType, 6);
+ return 8;
+}
+
+X86ISA::IntelMP::Bus::Bus(Params * p) : BaseConfigEntry(p, 1),
+ busID(p->bus_id), busType(p->bus_type)
+{}
+
+X86ISA::IntelMP::Bus *
+X86IntelMPBusParams::create()
+{
+ return new X86ISA::IntelMP::Bus(this);
+}
+
+Addr
+X86ISA::IntelMP::IOAPIC::writeOut(
+ FunctionalPort * port, Addr addr, uint8_t &checkSum)
+{
+ BaseConfigEntry::writeOut(port, addr, checkSum);
+ checkSum += writeOutField(port, addr + 1, id);
+ checkSum += writeOutField(port, addr + 2, version);
+ checkSum += writeOutField(port, addr + 3, flags);
+ checkSum += writeOutField(port, addr + 4, address);
+ return 8;
+}
+
+X86ISA::IntelMP::IOAPIC::IOAPIC(Params * p) : BaseConfigEntry(p, 2),
+ id(p->id), version(p->version), flags(0), address(p->address)
+{
+ if (p->enable)
+ flags |= 1;
+}
+
+X86ISA::IntelMP::IOAPIC *
+X86IntelMPIOAPICParams::create()
+{
+ return new X86ISA::IntelMP::IOAPIC(this);
+}
+
+Addr
+X86ISA::IntelMP::IntAssignment::writeOut(
+ FunctionalPort * port, Addr addr, uint8_t &checkSum)
+{
+ BaseConfigEntry::writeOut(port, addr, checkSum);
+ checkSum += writeOutField(port, addr + 1, interruptType);
+ checkSum += writeOutField(port, addr + 2, flags);
+ checkSum += writeOutField(port, addr + 4, sourceBusID);
+ checkSum += writeOutField(port, addr + 5, sourceBusIRQ);
+ checkSum += writeOutField(port, addr + 6, destApicID);
+ checkSum += writeOutField(port, addr + 7, destApicIntIn);
+ return 8;
+}
+
+X86ISA::IntelMP::IOIntAssignment::IOIntAssignment(Params * p) :
+ IntAssignment(p, p->interrupt_type, p->polarity, p->trigger, 3,
+ p->source_bus_id, p->source_bus_irq,
+ p->dest_io_apic_id, p->dest_io_apic_intin)
+{}
+
+X86ISA::IntelMP::IOIntAssignment *
+X86IntelMPIOIntAssignmentParams::create()
+{
+ return new X86ISA::IntelMP::IOIntAssignment(this);
+}
+
+X86ISA::IntelMP::LocalIntAssignment::LocalIntAssignment(Params * p) :
+ IntAssignment(p, p->interrupt_type, p->polarity, p->trigger, 4,
+ p->source_bus_id, p->source_bus_irq,
+ p->dest_local_apic_id, p->dest_local_apic_intin)
+{}
+
+X86ISA::IntelMP::LocalIntAssignment *
+X86IntelMPLocalIntAssignmentParams::create()
+{
+ return new X86ISA::IntelMP::LocalIntAssignment(this);
+}
+
+Addr
+X86ISA::IntelMP::AddrSpaceMapping::writeOut(
+ FunctionalPort * port, Addr addr, uint8_t &checkSum)
+{
+ ExtConfigEntry::writeOut(port, addr, checkSum);
+ checkSum += writeOutField(port, addr + 2, busID);
+ checkSum += writeOutField(port, addr + 3, addrType);
+ checkSum += writeOutField(port, addr + 4, addr);
+ checkSum += writeOutField(port, addr + 12, addrLength);
+ return length;
+}
+
+X86ISA::IntelMP::AddrSpaceMapping::AddrSpaceMapping(Params * p) :
+ ExtConfigEntry(p, 128, 20),
+ busID(p->bus_id), addrType(p->address_type),
+ addr(p->address), addrLength(p->length)
+{}
+
+X86ISA::IntelMP::AddrSpaceMapping *
+X86IntelMPAddrSpaceMappingParams::create()
+{
+ return new X86ISA::IntelMP::AddrSpaceMapping(this);
+}
+
+Addr
+X86ISA::IntelMP::BusHierarchy::writeOut(
+ FunctionalPort * port, Addr addr, uint8_t &checkSum)
+{
+ ExtConfigEntry::writeOut(port, addr, checkSum);
+ checkSum += writeOutField(port, addr + 2, busID);
+ checkSum += writeOutField(port, addr + 3, info);
+ checkSum += writeOutField(port, addr + 4, parentBus);
+
+ uint32_t reserved = 0;
+ port->writeBlob(addr + 5, (uint8_t *)(&reserved), 3);
+
+ return length;
+}
+
+X86ISA::IntelMP::BusHierarchy::BusHierarchy(Params * p) :
+ ExtConfigEntry(p, 129, 8),
+ busID(p->bus_id), info(0), parentBus(p->parent_bus)
+{
+ if (p->subtractive_decode)
+ info |= 1;
+}
+
+X86ISA::IntelMP::BusHierarchy *
+X86IntelMPBusHierarchyParams::create()
+{
+ return new X86ISA::IntelMP::BusHierarchy(this);
+}
+
+Addr
+X86ISA::IntelMP::CompatAddrSpaceMod::writeOut(
+ FunctionalPort * port, Addr addr, uint8_t &checkSum)
+{
+ ExtConfigEntry::writeOut(port, addr, checkSum);
+ checkSum += writeOutField(port, addr + 2, busID);
+ checkSum += writeOutField(port, addr + 3, mod);
+ checkSum += writeOutField(port, addr + 4, rangeList);
+ return length;
+}
+
+X86ISA::IntelMP::CompatAddrSpaceMod::CompatAddrSpaceMod(Params * p) :
+ ExtConfigEntry(p, 130, 8),
+ busID(p->bus_id), mod(0), rangeList(p->range_list)
+{
+ if (p->add)
+ mod |= 1;
+}
+
+X86ISA::IntelMP::CompatAddrSpaceMod *
+X86IntelMPCompatAddrSpaceModParams::create()
+{
+ return new X86ISA::IntelMP::CompatAddrSpaceMod(this);
+}
diff --git a/src/arch/x86/bios/intelmp.hh b/src/arch/x86/bios/intelmp.hh
new file mode 100644
index 000000000..e8d1d656e
--- /dev/null
+++ b/src/arch/x86/bios/intelmp.hh
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2008 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer. Redistributions
+ * in binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution. Neither the name of
+ * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_X86_BIOS_INTELMP_HH__
+#define __ARCH_X86_BIOS_INTELMP_HH__
+
+#include <string>
+#include <vector>
+
+#include "base/bitfield.hh"
+#include "sim/sim_object.hh"
+
+#include "enums/X86IntelMPAddressType.hh"
+#include "enums/X86IntelMPInterruptType.hh"
+#include "enums/X86IntelMPPolarity.hh"
+#include "enums/X86IntelMPRangeList.hh"
+#include "enums/X86IntelMPTriggerMode.hh"
+
+class FunctionalPort;
+
+// Config entry types
+class X86IntelMPBaseConfigEntryParams;
+class X86IntelMPExtConfigEntryParams;
+
+// General table structures
+class X86IntelMPConfigTableParams;
+class X86IntelMPFloatingPointerParams;
+
+// Base entry types
+class X86IntelMPBusParams;
+class X86IntelMPIOAPICParams;
+class X86IntelMPIOIntAssignmentParams;
+class X86IntelMPLocalIntAssignmentParams;
+class X86IntelMPProcessorParams;
+
+// Extended entry types
+class X86IntelMPAddrSpaceMappingParams;
+class X86IntelMPBusHierarchyParams;
+class X86IntelMPCompatAddrSpaceModParams;
+
+namespace X86ISA
+{
+
+namespace IntelMP
+{
+
+class FloatingPointer : public SimObject
+{
+ protected:
+ typedef X86IntelMPFloatingPointerParams Params;
+
+ uint32_t tableAddr;
+ uint8_t specRev;
+ uint8_t defaultConfig;
+ bool imcrPresent;
+
+ static const char signature[];
+
+ public:
+
+ Addr writeOut(FunctionalPort * port, Addr addr);
+
+ Addr getTableAddr()
+ {
+ return tableAddr;
+ }
+
+ void setTableAddr(Addr addr)
+ {
+ tableAddr = addr;
+ }
+
+ FloatingPointer(Params * p);
+};
+
+class BaseConfigEntry : public SimObject
+{
+ protected:
+ typedef X86IntelMPBaseConfigEntryParams Params;
+
+ uint8_t type;
+
+ public:
+
+ virtual Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+
+ BaseConfigEntry(Params * p, uint8_t _type);
+};
+
+class ExtConfigEntry : public SimObject
+{
+ protected:
+ typedef X86IntelMPExtConfigEntryParams Params;
+
+ uint8_t type;
+ uint8_t length;
+
+ public:
+
+ virtual Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+
+ ExtConfigEntry(Params * p, uint8_t _type, uint8_t _length);
+};
+
+class ConfigTable : public SimObject
+{
+ protected:
+ typedef X86IntelMPConfigTableParams Params;
+
+ static const char signature[];
+
+ uint8_t specRev;
+ std::string oemID;
+ std::string productID;
+ uint32_t oemTableAddr;
+ uint16_t oemTableSize;
+ uint32_t localApic;
+
+ std::vector<BaseConfigEntry *> baseEntries;
+ std::vector<ExtConfigEntry *> extEntries;
+
+ public:
+ Addr writeOut(FunctionalPort * port, Addr addr);
+
+ ConfigTable(Params * p);
+};
+
+class Processor : public BaseConfigEntry
+{
+ protected:
+ typedef X86IntelMPProcessorParams Params;
+
+ uint8_t localApicID;
+ uint8_t localApicVersion;
+ uint8_t cpuFlags;
+ uint32_t cpuSignature;
+ uint32_t featureFlags;
+
+ public:
+ Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+
+ Processor(Params * p);
+};
+
+class Bus : public BaseConfigEntry
+{
+ protected:
+ typedef X86IntelMPBusParams Params;
+
+ uint8_t busID;
+ std::string busType;
+
+ public:
+ Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+
+ Bus(Params * p);
+};
+
+class IOAPIC : public BaseConfigEntry
+{
+ protected:
+ typedef X86IntelMPIOAPICParams Params;
+
+ uint8_t id;
+ uint8_t version;
+ uint8_t flags;
+ uint32_t address;
+
+ public:
+ Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+
+ IOAPIC(Params * p);
+};
+
+class IntAssignment : public BaseConfigEntry
+{
+ protected:
+ uint8_t interruptType;
+
+ uint16_t flags;
+
+ uint8_t sourceBusID;
+ uint8_t sourceBusIRQ;
+
+ uint8_t destApicID;
+ uint8_t destApicIntIn;
+
+ public:
+ Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+
+ IntAssignment(X86IntelMPBaseConfigEntryParams * p,
+ Enums::X86IntelMPInterruptType _interruptType,
+ Enums::X86IntelMPPolarity polarity,
+ Enums::X86IntelMPTriggerMode trigger,
+ uint8_t _type,
+ uint8_t _sourceBusID, uint8_t _sourceBusIRQ,
+ uint8_t _destApicID, uint8_t _destApicIntIn) :
+ BaseConfigEntry(p, _type),
+ interruptType(_interruptType), flags(0),
+ sourceBusID(_sourceBusID), sourceBusIRQ(_sourceBusIRQ),
+ destApicID(_destApicID), destApicIntIn(_destApicIntIn)
+ {
+ replaceBits(flags, 0, 1, polarity);
+ replaceBits(flags, 2, 3, trigger);
+ }
+};
+
+class IOIntAssignment : public IntAssignment
+{
+ protected:
+ typedef X86IntelMPIOIntAssignmentParams Params;
+
+ public:
+ IOIntAssignment(Params * p);
+};
+
+class LocalIntAssignment : public IntAssignment
+{
+ protected:
+ typedef X86IntelMPLocalIntAssignmentParams Params;
+
+ public:
+ LocalIntAssignment(Params * p);
+};
+
+class AddrSpaceMapping : public ExtConfigEntry
+{
+ protected:
+ typedef X86IntelMPAddrSpaceMappingParams Params;
+
+ uint8_t busID;
+ uint8_t addrType;
+ uint64_t addr;
+ uint64_t addrLength;
+
+ public:
+ Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+
+ AddrSpaceMapping(Params * p);
+};
+
+class BusHierarchy : public ExtConfigEntry
+{
+ protected:
+ typedef X86IntelMPBusHierarchyParams Params;
+
+ uint8_t busID;
+ uint8_t info;
+ uint8_t parentBus;
+
+ public:
+ Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+
+ BusHierarchy(Params * p);
+};
+
+class CompatAddrSpaceMod : public ExtConfigEntry
+{
+ protected:
+ typedef X86IntelMPCompatAddrSpaceModParams Params;
+
+ uint8_t busID;
+ uint8_t mod;
+ uint32_t rangeList;
+
+ public:
+ Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+
+ CompatAddrSpaceMod(Params * p);
+};
+
+} //IntelMP
+
+} //X86ISA
+
+#endif
diff --git a/src/arch/x86/smbios.cc b/src/arch/x86/bios/smbios.cc
index 319650c1f..95ade1e4d 100644
--- a/src/arch/x86/smbios.cc
+++ b/src/arch/x86/bios/smbios.cc
@@ -85,12 +85,17 @@
* Authors: Gabe Black
*/
-#include "arch/x86/smbios.hh"
+#include "arch/x86/bios/smbios.hh"
#include "arch/x86/isa_traits.hh"
#include "mem/port.hh"
+#include "params/X86SMBiosBiosInformation.hh"
+#include "params/X86SMBiosSMBiosStructure.hh"
+#include "params/X86SMBiosSMBiosTable.hh"
#include "sim/byteswap.hh"
#include "sim/host.hh"
+using namespace std;
+
const char X86ISA::SMBios::SMBiosTable::SMBiosHeader::anchorString[] = "_SM_";
const uint8_t X86ISA::SMBios::SMBiosTable::
SMBiosHeader::formattedArea[] = {0,0,0,0,0};
@@ -101,6 +106,116 @@ const uint8_t X86ISA::SMBios::SMBiosTable::
const char X86ISA::SMBios::SMBiosTable::
SMBiosHeader::IntermediateHeader::anchorString[] = "_DMI_";
+template <class T>
+uint64_t
+composeBitVector(T vec)
+{
+ uint64_t val = 0;
+ typename T::iterator vecIt;
+ for (vecIt = vec.begin(); vecIt != vec.end(); vecIt++) {
+ val |= (1 << (*vecIt));
+ }
+ return val;
+}
+
+uint16_t
+X86ISA::SMBios::SMBiosStructure::writeOut(FunctionalPort * port, Addr addr)
+{
+ port->writeBlob(addr, (uint8_t *)(&type), 1);
+
+ uint8_t length = getLength();
+ port->writeBlob(addr + 1, (uint8_t *)(&length), 1);
+
+ uint16_t handleGuest = X86ISA::htog(handle);
+ port->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2);
+
+ return length + getStringLength();
+}
+
+X86ISA::SMBios::SMBiosStructure::SMBiosStructure(Params * p, uint8_t _type) :
+ SimObject(p), type(_type), handle(0), stringFields(false)
+{}
+
+void
+X86ISA::SMBios::SMBiosStructure::writeOutStrings(
+ FunctionalPort * port, Addr addr)
+{
+ std::vector<std::string>::iterator it;
+ Addr offset = 0;
+
+ const uint8_t nullTerminator = 0;
+
+ // If there are string fields but none of them are used, that's a
+ // special case which is handled by this if.
+ if (strings.size() == 0 && stringFields) {
+ port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
+ offset++;
+ } else {
+ for (it = strings.begin(); it != strings.end(); it++) {
+ port->writeBlob(addr + offset,
+ (uint8_t *)it->c_str(), it->length() + 1);
+ offset += it->length() + 1;
+ }
+ }
+ port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
+}
+
+int
+X86ISA::SMBios::SMBiosStructure::getStringLength()
+{
+ int size = 0;
+ std::vector<std::string>::iterator it;
+
+ for (it = strings.begin(); it != strings.end(); it++) {
+ size += it->length() + 1;
+ }
+
+ return size + 1;
+}
+
+int
+X86ISA::SMBios::SMBiosStructure::addString(string & newString)
+{
+ stringFields = true;
+ // If a string is empty, treat it as not existing. The index for empty
+ // strings is 0.
+ if (newString.length() == 0)
+ return 0;
+ strings.push_back(newString);
+ return strings.size();
+}
+
+string
+X86ISA::SMBios::SMBiosStructure::readString(int n)
+{
+ assert(n > 0 && n <= strings.size());
+ return strings[n - 1];
+}
+
+void
+X86ISA::SMBios::SMBiosStructure::setString(int n, std::string & newString)
+{
+ assert(n > 0 && n <= strings.size());
+ strings[n - 1] = newString;
+}
+
+X86ISA::SMBios::BiosInformation::BiosInformation(Params * p) :
+ SMBiosStructure(p, Type),
+ startingAddrSegment(p->starting_addr_segment),
+ romSize(p->rom_size),
+ majorVer(p->major), minorVer(p->minor),
+ embContFirmwareMajor(p->emb_cont_firmware_major),
+ embContFirmwareMinor(p->emb_cont_firmware_minor)
+ {
+ vendor = addString(p->vendor);
+ version = addString(p->version);
+ releaseDate = addString(p->release_date);
+
+ characteristics = composeBitVector(p->characteristics);
+ characteristicExtBytes =
+ composeBitVector(p->characteristic_ext_bytes);
+ }
+
uint16_t
X86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr)
{
@@ -122,8 +237,8 @@ X86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr)
X86ISA::htog(characteristicExtBytes);
port->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2);
- port->writeBlob(addr + 0x14, (uint8_t *)(&major), 1);
- port->writeBlob(addr + 0x15, (uint8_t *)(&minor), 1);
+ port->writeBlob(addr + 0x14, (uint8_t *)(&majorVer), 1);
+ port->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1);
port->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1);
port->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1);
@@ -132,9 +247,22 @@ X86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr)
return size;
}
+X86ISA::SMBios::SMBiosTable::SMBiosTable(Params * p) :
+ SimObject(p), structures(p->structures)
+{
+ smbiosHeader.majorVersion = p->major_version;
+ smbiosHeader.minorVersion = p->minor_version;
+ assert(p->major_version <= 9);
+ assert(p->minor_version <= 9);
+ smbiosHeader.intermediateHeader.smbiosBCDRevision =
+ (p->major_version << 4) | p->minor_version;
+}
+
void
-X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr)
+X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
+ Addr &headerSize, Addr &structSize)
{
+ headerSize = 0x1F;
/*
* The main header
@@ -205,14 +333,16 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr)
Addr base = smbiosHeader.intermediateHeader.tableAddr;
Addr offset = 0;
uint16_t maxSize = 0;
- std::vector<SMBiosStructure>::iterator it;
+ std::vector<SMBiosStructure *>::iterator it;
for (it = structures.begin(); it != structures.end(); it++) {
- uint16_t size = it->writeOut(port, base + offset);
+ uint16_t size = (*it)->writeOut(port, base + offset);
if (size > maxSize)
maxSize = size;
offset += size;
}
+ structSize = offset;
+
/*
* Header
*/
@@ -243,3 +373,15 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr)
intChecksum = -intChecksum;
port->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1);
}
+
+X86ISA::SMBios::BiosInformation *
+X86SMBiosBiosInformationParams::create()
+{
+ return new X86ISA::SMBios::BiosInformation(this);
+}
+
+X86ISA::SMBios::SMBiosTable *
+X86SMBiosSMBiosTableParams::create()
+{
+ return new X86ISA::SMBios::SMBiosTable(this);
+}
diff --git a/src/arch/x86/smbios.hh b/src/arch/x86/bios/smbios.hh
index c126de220..1c50d0b48 100644
--- a/src/arch/x86/smbios.hh
+++ b/src/arch/x86/bios/smbios.hh
@@ -85,16 +85,21 @@
* Authors: Gabe Black
*/
-#ifndef __ARCH_X86_SMBIOS_HH__
-#define __ARCH_X86_SMBIOS_HH__
+#ifndef __ARCH_X86_BIOS_SMBIOS_HH__
+#define __ARCH_X86_BIOS_SMBIOS_HH__
#include <string>
#include <vector>
-#include "arch/x86/isa_traits.hh"
-#include "mem/port.hh"
-#include "sim/byteswap.hh"
+#include "enums/Characteristic.hh"
+#include "enums/ExtCharacteristic.hh"
#include "sim/host.hh"
+#include "sim/sim_object.hh"
+
+class FunctionalPort;
+class X86SMBiosBiosInformationParams;
+class X86SMBiosSMBiosStructureParams;
+class X86SMBiosSMBiosTableParams;
namespace X86ISA
{
@@ -102,8 +107,11 @@ namespace X86ISA
namespace SMBios
{
-class SMBiosStructure
+class SMBiosStructure : public SimObject
{
+ protected:
+ typedef X86SMBiosSMBiosStructureParams Params;
+
public:
virtual
@@ -126,73 +134,33 @@ class SMBiosStructure
return 4;
}
- virtual uint16_t
- writeOut(FunctionalPort * port, Addr addr)
- {
- port->writeBlob(addr, (uint8_t *)(&type), 1);
-
- uint8_t length = getLength();
- port->writeBlob(addr + 1, (uint8_t *)(&length), 1);
-
- uint16_t handleGuest = X86ISA::htog(handle);
- port->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2);
-
- return length + getStringLength();
- }
+ virtual uint16_t writeOut(FunctionalPort * port, Addr addr);
protected:
- std::vector<std::string> strings;
-
- void writeOutStrings(FunctionalPort * port, Addr addr)
- {
- std::vector<std::string>::iterator it;
- Addr offset = 0;
-
- for (it = strings.begin(); it != strings.end(); it++) {
- port->writeBlob(addr + offset,
- (uint8_t *)it->c_str(), it->length() + 1);
- offset += it->length() + 1;
- }
+ bool stringFields;
- const uint8_t nullTerminator = 0;
- port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
- }
+ SMBiosStructure(Params * p, uint8_t _type);
- int getStringLength()
- {
- int size = 0;
- std::vector<std::string>::iterator it;
+ std::vector<std::string> strings;
- for (it = strings.begin(); it != strings.end(); it++) {
- size += it->length() + 1;
- }
+ void writeOutStrings(FunctionalPort * port, Addr addr);
- return size + 1;
- }
+ int getStringLength();
public:
- int addString(std::string & newString)
- {
- strings.push_back(newString);
- return strings.size();
- }
-
- std::string readString(int n)
- {
- assert(n > 0 && n <= strings.size());
- return strings[n - 1];
- }
-
- void setString(int n, std::string & newString)
- {
- assert(n > 0 && n <= strings.size());
- strings[n - 1] = newString;
- }
+ int addString(std::string & newString);
+ std::string readString(int n);
+ void setString(int n, std::string & newString);
};
class BiosInformation : public SMBiosStructure
{
+ protected:
+ const static uint8_t Type = 0;
+
+ typedef X86SMBiosBiosInformationParams Params;
+
public:
// Offset 04h, 1 byte
uint8_t vendor;
@@ -211,21 +179,25 @@ class BiosInformation : public SMBiosStructure
// Offset 12h, 2 bytes
uint16_t characteristicExtBytes;
// Offset 14h, 1 byte
- uint8_t major;
+ uint8_t majorVer;
// Offset 15h, 1 byte
- uint8_t minor;
+ uint8_t minorVer;
// Offset 16h, 1 byte
uint8_t embContFirmwareMajor;
// Offset 17h, 1 byte
uint8_t embContFirmwareMinor;
+ BiosInformation(Params * p);
+
uint8_t getLength() { return 0x18; }
uint16_t writeOut(FunctionalPort * port, Addr addr);
};
-class SMBiosTable
+class SMBiosTable : public SimObject
{
- public:
+ protected:
+ typedef X86SMBiosSMBiosTableParams Params;
+
struct SMBiosHeader
{
SMBiosHeader()
@@ -281,9 +253,23 @@ class SMBiosTable
} intermediateHeader;
} smbiosHeader;
- void writeOut(FunctionalPort * port, Addr addr);
+ std::vector<SMBiosStructure *> structures;
+
+ public:
+ SMBiosTable(Params * p);
+
+ Addr getTableAddr()
+ {
+ return smbiosHeader.intermediateHeader.tableAddr;
+ }
+
+ void setTableAddr(Addr addr)
+ {
+ smbiosHeader.intermediateHeader.tableAddr = addr;
+ }
- std::vector<SMBiosStructure> structures;
+ void writeOut(FunctionalPort * port, Addr addr,
+ Addr &headerSize, Addr &structSize);
};
} //SMBios
diff --git a/src/arch/x86/cpuid.cc b/src/arch/x86/cpuid.cc
new file mode 100644
index 000000000..247965df4
--- /dev/null
+++ b/src/arch/x86/cpuid.cc
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2008 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "arch/x86/cpuid.hh"
+#include "base/bitfield.hh"
+#include "cpu/thread_context.hh"
+
+namespace X86ISA {
+ enum StandardCpuidFunction {
+ VendorAndLargestStdFunc,
+ FamilyModelStepping,
+ NumStandardCpuidFuncs
+ };
+
+ enum ExtendedCpuidFunctions {
+ VendorAndLargestExtFunc,
+ FamilyModelSteppingBrandFeatures,
+ NameString1,
+ NameString2,
+ NameString3,
+ L1CacheAndTLB,
+ L2L3CacheAndL2TLB,
+ APMInfo,
+
+ /*
+ * The following are defined by the spec but not yet implemented
+ */
+/* LongModeAddressSize,
+ // Function 9 is reserved
+ SVMInfo = 10,
+ // Functions 11-24 are reserved
+ TLB1GBPageInfo = 25,
+ PerformanceInfo,*/
+
+ NumExtendedCpuidFuncs
+ };
+
+ static const int vendorStringSize = 13;
+ static const char vendorString[vendorStringSize] = "AuthenticAMD";
+ static const int nameStringSize = 48;
+ static const char nameString[nameStringSize] = "Fake M5 x86_64 CPU";
+
+ uint64_t
+ stringToRegister(const char *str)
+ {
+ uint64_t reg = 0;
+ for (int pos = 3; pos >=0; pos--) {
+ reg <<= 8;
+ reg |= str[pos];
+ }
+ return reg;
+ }
+
+ bool
+ doCpuid(ThreadContext * tc, uint32_t function, CpuidResult &result)
+ {
+ uint16_t family = bits(function, 31, 16);
+ uint16_t funcNum = bits(function, 15, 0);
+ if (family == 0x8000) {
+ // The extended functions
+ switch (funcNum) {
+ case VendorAndLargestExtFunc:
+ assert(vendorStringSize >= 12);
+ result = CpuidResult(
+ NumExtendedCpuidFuncs - 1,
+ stringToRegister(vendorString),
+ stringToRegister(vendorString + 4),
+ stringToRegister(vendorString + 8));
+ break;
+ case FamilyModelSteppingBrandFeatures:
+ result = CpuidResult(0x00020f51, 0x00000405,
+ 0xe3d3fbff, 0x00000001);
+ break;
+ case NameString1:
+ case NameString2:
+ case NameString3:
+ {
+ // Zero fill anything beyond the end of the string. This
+ // should go away once the string is a vetted parameter.
+ char cleanName[nameStringSize];
+ memset(cleanName, '\0', nameStringSize);
+ strncpy(cleanName, nameString, nameStringSize);
+
+ int offset = (funcNum - NameString1) * 16;
+ assert(nameStringSize >= offset + 16);
+ result = CpuidResult(
+ stringToRegister(cleanName + offset + 0),
+ stringToRegister(cleanName + offset + 4),
+ stringToRegister(cleanName + offset + 8),
+ stringToRegister(cleanName + offset + 12));
+ }
+ break;
+ case L1CacheAndTLB:
+ result = CpuidResult(0xff08ff08, 0xff20ff20,
+ 0x40020140, 0x40020140);
+ break;
+ case L2L3CacheAndL2TLB:
+ result = CpuidResult(0x00000000, 0x42004200,
+ 0x00000000, 0x04008140);
+ break;
+ case APMInfo:
+ result = CpuidResult(0x80000018, 0x68747541,
+ 0x69746e65, 0x444d4163);
+ break;
+/* case LongModeAddressSize:
+ case SVMInfo:
+ case TLB1GBPageInfo:
+ case PerformanceInfo:*/
+ default:
+ return false;
+ }
+ } else if(family == 0x0000) {
+ // The standard functions
+ switch (funcNum) {
+ case VendorAndLargestStdFunc:
+ assert(vendorStringSize >= 12);
+ result = CpuidResult(
+ NumStandardCpuidFuncs - 1,
+ stringToRegister(vendorString),
+ stringToRegister(vendorString + 4),
+ stringToRegister(vendorString + 8));
+ break;
+ case FamilyModelStepping:
+ result = CpuidResult(0x00020f51, 0000000405,
+ 0xe3d3fbff, 0x00000001);
+ break;
+ default:
+ return false;
+ }
+ }
+ return true;
+ }
+} //namespace X86ISA
diff --git a/src/arch/arm/syscallreturn.hh b/src/arch/x86/cpuid.hh
index ad46c2232..5cb4c7972 100644
--- a/src/arch/arm/syscallreturn.hh
+++ b/src/arch/x86/cpuid.hh
@@ -1,6 +1,5 @@
/*
- * Copyright (c) 2003-2005 The Regents of The University of Michigan
- * Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2008 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,31 +26,36 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
- * Korey Sewell
- * Stephen Hines
*/
-#ifndef __ARCH_ARM_SYSCALLRETURN_HH__
-#define __ARCH_ARM_SYSCALLRETURN_HH__
+#ifndef __ARCH_X86_CPUID_HH__
+#define __ARCH_X86_CPUID_HH__
-#include "sim/syscallreturn.hh"
-#include "cpu/thread_context.hh"
+#include <inttypes.h>
-namespace ArmISA
+class ThreadContext;
+
+namespace X86ISA
{
- static inline void setSyscallReturn(SyscallReturn return_value,
- ThreadContext *tc)
+ struct CpuidResult
{
- if (return_value.successful()) {
- // no error
- //regs->setIntReg(SyscallSuccessReg, 0);
- tc->setIntReg(ReturnValueReg, return_value.value());
- } else {
- // got an error, return details
- //regs->setIntReg(SyscallSuccessReg, (IntReg) -1);
- tc->setIntReg(ReturnValueReg, return_value.value());
- }
- }
-}
+ uint64_t rax;
+ uint64_t rbx;
+ uint64_t rcx;
+ uint64_t rdx;
+
+ // These are not in alphebetical order on purpose. The order reflects
+ // how the CPUID orders the registers when it returns results.
+ CpuidResult(uint64_t _rax, uint64_t _rbx,
+ uint64_t _rdx, uint64_t _rcx) :
+ rax(_rax), rbx(_rbx), rcx(_rcx), rdx(_rdx)
+ {}
+
+ CpuidResult()
+ {}
+ };
+
+ bool doCpuid(ThreadContext * tc, uint32_t function, CpuidResult &result);
+} // namespace X86ISA
#endif
diff --git a/src/arch/x86/emulenv.cc b/src/arch/x86/emulenv.cc
index 31b705d79..0d7b32130 100644
--- a/src/arch/x86/emulenv.cc
+++ b/src/arch/x86/emulenv.cc
@@ -55,6 +55,8 @@
* Authors: Gabe Black
*/
+#include <cassert>
+
#include "arch/x86/emulenv.hh"
#include "base/misc.hh"
@@ -91,7 +93,7 @@ void EmulEnv::doModRM(const ExtMachInst & machInst)
//Figure out what segment to use. This won't be entirely accurate since
//the presence of a displacement is supposed to make the instruction
//default to the data segment.
- if (base != INTREG_RBP && base != INTREG_RSP ||
+ if ((base != INTREG_RBP && base != INTREG_RSP) ||
0/*Has an immediate offset*/) {
seg = SEGMENT_REG_DS;
//Handle any segment override that might have been in the instruction
@@ -103,3 +105,11 @@ void EmulEnv::doModRM(const ExtMachInst & machInst)
}
}
+void EmulEnv::setSeg(const ExtMachInst & machInst)
+{
+ seg = SEGMENT_REG_DS;
+ //Handle any segment override that might have been in the instruction
+ int segFromInst = machInst.legacy.seg;
+ if (segFromInst)
+ seg = (SegmentRegIndex)(segFromInst - 1);
+}
diff --git a/src/arch/x86/emulenv.hh b/src/arch/x86/emulenv.hh
index 1044dbdf9..cdb1bf863 100644
--- a/src/arch/x86/emulenv.hh
+++ b/src/arch/x86/emulenv.hh
@@ -86,6 +86,7 @@ namespace X86ISA
{;}
void doModRM(const ExtMachInst & machInst);
+ void setSeg(const ExtMachInst & machInst);
};
};
diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc
index 1c94a1251..b81400cc3 100644
--- a/src/arch/x86/faults.cc
+++ b/src/arch/x86/faults.cc
@@ -85,6 +85,7 @@
* Authors: Gabe Black
*/
+#include "arch/x86/decoder.hh"
#include "arch/x86/faults.hh"
#include "base/trace.hh"
#include "config/full_system.hh"
@@ -100,71 +101,90 @@
namespace X86ISA
{
#if FULL_SYSTEM
- void X86Trap::invoke(ThreadContext * tc)
+ void X86FaultBase::invoke(ThreadContext * tc)
{
- panic("X86 faults are not implemented!");
+ Addr pc = tc->readPC();
+ DPRINTF(Faults, "RIP %#x: vector %d: %s\n", pc, vector, describe());
+ using namespace X86ISAInst::RomLabels;
+ HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
+ MicroPC entry;
+ if (m5reg.mode == LongMode) {
+ if (isSoft()) {
+ entry = extern_label_longModeSoftInterrupt;
+ } else {
+ entry = extern_label_longModeInterrupt;
+ }
+ } else {
+ entry = extern_label_legacyModeInterrupt;
+ }
+ tc->setIntReg(INTREG_MICRO(1), vector);
+ tc->setIntReg(INTREG_MICRO(7), pc);
+ if (errorCode != (uint64_t)(-1)) {
+ if (m5reg.mode == LongMode) {
+ entry = extern_label_longModeInterruptWithError;
+ } else {
+ panic("Legacy mode interrupts with error codes "
+ "aren't implementde.\n");
+ }
+ // Software interrupts shouldn't have error codes. If one does,
+ // there would need to be microcode to set it up.
+ assert(!isSoft());
+ tc->setIntReg(INTREG_MICRO(15), errorCode);
+ }
+ tc->setMicroPC(romMicroPC(entry));
+ tc->setNextMicroPC(romMicroPC(entry) + 1);
}
- void X86Abort::invoke(ThreadContext * tc)
+ std::string
+ X86FaultBase::describe() const
{
- panic("X86 faults are not implemented!");
- }
+ std::stringstream ss;
+ ccprintf(ss, "%s", mnemonic());
+ if (errorCode != (uint64_t)(-1)) {
+ ccprintf(ss, "(%#x)", errorCode);
+ }
- void X86Interrupt::invoke(ThreadContext * tc)
- {
- panic("X86 faults are not implemented!");
+ return ss.str();
}
-
- void FakeITLBFault::invoke(ThreadContext * tc)
+
+ void X86Trap::invoke(ThreadContext * tc)
{
- // Start the page table walker.
- tc->getITBPtr()->walk(tc, vaddr);
+ X86FaultBase::invoke(tc);
+ // This is the same as a fault, but it happens -after- the instruction.
+ tc->setPC(tc->readNextPC());
+ tc->setNextPC(tc->readNextNPC());
+ tc->setNextNPC(tc->readNextNPC() + sizeof(MachInst));
}
- void FakeDTLBFault::invoke(ThreadContext * tc)
+ void X86Abort::invoke(ThreadContext * tc)
{
- // Start the page table walker.
- tc->getDTBPtr()->walk(tc, vaddr);
+ panic("Abort exception!");
}
-#else // !FULL_SYSTEM
- void FakeITLBFault::invoke(ThreadContext * tc)
+ void PageFault::invoke(ThreadContext * tc)
{
- DPRINTF(TLB, "Invoking an ITLB fault for address %#x at pc %#x.\n",
- vaddr, tc->readPC());
- Process *p = tc->getProcessPtr();
- TlbEntry entry;
- bool success = p->pTable->lookup(vaddr, entry);
- if(!success) {
- panic("Tried to execute unmapped address %#x.\n", vaddr);
+ HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
+ X86FaultBase::invoke(tc);
+ /*
+ * If something bad happens while trying to enter the page fault
+ * handler, I'm pretty sure that's a double fault and then all bets are
+ * off. That means it should be safe to update this state now.
+ */
+ if (m5reg.mode == LongMode) {
+ tc->setMiscReg(MISCREG_CR2, addr);
} else {
- Addr alignedVaddr = p->pTable->pageAlign(vaddr);
- DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr,
- entry.pageStart());
- tc->getITBPtr()->insert(alignedVaddr, entry);
+ tc->setMiscReg(MISCREG_CR2, (uint32_t)addr);
}
}
- void FakeDTLBFault::invoke(ThreadContext * tc)
+ std::string
+ PageFault::describe() const
{
- DPRINTF(TLB, "Invoking an DTLB fault for address %#x at pc %#x.\n",
- vaddr, tc->readPC());
- Process *p = tc->getProcessPtr();
- TlbEntry entry;
- bool success = p->pTable->lookup(vaddr, entry);
- if(!success) {
- p->checkAndAllocNextPage(vaddr);
- success = p->pTable->lookup(vaddr, entry);
- }
- if(!success) {
- panic("Tried to access unmapped address %#x.\n", vaddr);
- } else {
- Addr alignedVaddr = p->pTable->pageAlign(vaddr);
- DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr,
- entry.pageStart());
- tc->getDTBPtr()->insert(alignedVaddr, entry);
- }
+ std::stringstream ss;
+ ccprintf(ss, "%s at %#x", X86FaultBase::describe(), addr);
+ return ss.str();
}
+
#endif
} // namespace X86ISA
diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh
index 78a55d0e1..fe5132994 100644
--- a/src/arch/x86/faults.hh
+++ b/src/arch/x86/faults.hh
@@ -58,9 +58,12 @@
#ifndef __ARCH_X86_FAULTS_HH__
#define __ARCH_X86_FAULTS_HH__
+#include "base/bitunion.hh"
#include "base/misc.hh"
#include "sim/faults.hh"
+#include <string>
+
namespace X86ISA
{
// Base class for all x86 "faults" where faults is in the m5 sense
@@ -69,11 +72,13 @@ namespace X86ISA
protected:
const char * faultName;
const char * mnem;
+ uint8_t vector;
uint64_t errorCode;
X86FaultBase(const char * _faultName, const char * _mnem,
- uint64_t _errorCode = 0) :
- faultName(_faultName), mnem(_mnem), errorCode(_errorCode)
+ const uint8_t _vector, uint64_t _errorCode = (uint64_t)-1)
+ : faultName(_faultName), mnem(_mnem),
+ vector(_vector), errorCode(_errorCode)
{
}
@@ -91,6 +96,17 @@ namespace X86ISA
{
return mnem;
}
+
+ virtual bool isSoft()
+ {
+ return false;
+ }
+
+#if FULL_SYSTEM
+ void invoke(ThreadContext * tc);
+
+ virtual std::string describe() const;
+#endif
};
// Base class for x86 faults which behave as if the underlying instruction
@@ -99,8 +115,8 @@ namespace X86ISA
{
protected:
X86Fault(const char * name, const char * mnem,
- uint64_t _errorCode = 0) :
- X86FaultBase(name, mnem, _errorCode)
+ const uint8_t vector, uint64_t _errorCode = (uint64_t)-1)
+ : X86FaultBase(name, mnem, vector, _errorCode)
{}
};
@@ -110,8 +126,8 @@ namespace X86ISA
{
protected:
X86Trap(const char * name, const char * mnem,
- uint64_t _errorCode = 0) :
- X86FaultBase(name, mnem, _errorCode)
+ const uint8_t vector, uint64_t _errorCode = (uint64_t)-1)
+ : X86FaultBase(name, mnem, vector, _errorCode)
{}
#if FULL_SYSTEM
@@ -124,8 +140,8 @@ namespace X86ISA
{
protected:
X86Abort(const char * name, const char * mnem,
- uint64_t _errorCode = 0) :
- X86FaultBase(name, mnem, _errorCode)
+ const uint8_t vector, uint64_t _errorCode = (uint64_t)-1)
+ : X86FaultBase(name, mnem, vector, _errorCode)
{}
#if FULL_SYSTEM
@@ -138,13 +154,9 @@ namespace X86ISA
{
protected:
X86Interrupt(const char * name, const char * mnem,
- uint64_t _errorCode = 0) :
- X86FaultBase(name, mnem, _errorCode)
+ const uint8_t _vector, uint64_t _errorCode = (uint64_t)-1)
+ : X86FaultBase(name, mnem, _vector, _errorCode)
{}
-
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
};
class UnimpInstFault : public FaultBase
@@ -201,7 +213,7 @@ namespace X86ISA
{
public:
DivideByZero() :
- X86Fault("Divide-by-Zero-Error", "#DE")
+ X86Fault("Divide-by-Zero-Error", "#DE", 0)
{}
};
@@ -209,15 +221,15 @@ namespace X86ISA
{
public:
DebugException() :
- X86FaultBase("Debug", "#DB")
+ X86FaultBase("Debug", "#DB", 1)
{}
};
class NonMaskableInterrupt : public X86Interrupt
{
public:
- NonMaskableInterrupt() :
- X86Interrupt("Non-Maskable-Interrupt", "#NMI")
+ NonMaskableInterrupt(uint8_t _vector) :
+ X86Interrupt("Non Maskable Interrupt", "#NMI", 2, _vector)
{}
};
@@ -225,7 +237,7 @@ namespace X86ISA
{
public:
Breakpoint() :
- X86Trap("Breakpoint", "#BP")
+ X86Trap("Breakpoint", "#BP", 3)
{}
};
@@ -233,7 +245,7 @@ namespace X86ISA
{
public:
OverflowTrap() :
- X86Trap("Overflow", "#OF")
+ X86Trap("Overflow", "#OF", 4)
{}
};
@@ -241,7 +253,7 @@ namespace X86ISA
{
public:
BoundRange() :
- X86Fault("Bound-Range", "#BR")
+ X86Fault("Bound-Range", "#BR", 5)
{}
};
@@ -249,7 +261,7 @@ namespace X86ISA
{
public:
InvalidOpcode() :
- X86Fault("Invalid-Opcode", "#UD")
+ X86Fault("Invalid-Opcode", "#UD", 6)
{}
};
@@ -257,7 +269,7 @@ namespace X86ISA
{
public:
DeviceNotAvailable() :
- X86Fault("Device-Not-Available", "#NM")
+ X86Fault("Device-Not-Available", "#NM", 7)
{}
};
@@ -265,132 +277,156 @@ namespace X86ISA
{
public:
DoubleFault() :
- X86Abort("Double-Fault", "#DF")
+ X86Abort("Double-Fault", "#DF", 8, 0)
{}
};
class InvalidTSS : public X86Fault
{
public:
- InvalidTSS() :
- X86Fault("Invalid-TSS", "#TS")
+ InvalidTSS(uint32_t _errorCode) :
+ X86Fault("Invalid-TSS", "#TS", 10, _errorCode)
{}
};
class SegmentNotPresent : public X86Fault
{
public:
- SegmentNotPresent() :
- X86Fault("Segment-Not-Present", "#NP")
+ SegmentNotPresent(uint32_t _errorCode) :
+ X86Fault("Segment-Not-Present", "#NP", 11, _errorCode)
{}
};
class StackFault : public X86Fault
{
public:
- StackFault() :
- X86Fault("Stack", "#SS")
+ StackFault(uint32_t _errorCode) :
+ X86Fault("Stack", "#SS", 12, _errorCode)
{}
};
class GeneralProtection : public X86Fault
{
public:
- GeneralProtection(uint64_t _errorCode) :
- X86Fault("General-Protection", "#GP", _errorCode)
+ GeneralProtection(uint32_t _errorCode) :
+ X86Fault("General-Protection", "#GP", 13, _errorCode)
{}
};
class PageFault : public X86Fault
{
+ protected:
+ BitUnion32(PageFaultErrorCode)
+ Bitfield<0> present;
+ Bitfield<1> write;
+ Bitfield<2> user;
+ Bitfield<3> reserved;
+ Bitfield<4> fetch;
+ EndBitUnion(PageFaultErrorCode)
+
+ Addr addr;
+
public:
- PageFault() :
- X86Fault("Page-Fault", "#PF")
+ PageFault(Addr _addr, uint32_t _errorCode) :
+ X86Fault("Page-Fault", "#PF", 14, _errorCode), addr(_addr)
{}
+
+ PageFault(Addr _addr, bool present, bool write,
+ bool user, bool reserved, bool fetch) :
+ X86Fault("Page-Fault", "#PF", 14, 0), addr(_addr)
+ {
+ PageFaultErrorCode code = 0;
+ code.present = present;
+ code.write = write;
+ code.user = user;
+ code.reserved = reserved;
+ code.fetch = fetch;
+ errorCode = code;
+ }
+
+#if FULL_SYSTEM
+ void invoke(ThreadContext * tc);
+
+ virtual std::string describe() const;
+#endif
};
class X87FpExceptionPending : public X86Fault
{
public:
X87FpExceptionPending() :
- X86Fault("x87 Floating-Point Exception Pending", "#MF")
+ X86Fault("x87 Floating-Point Exception Pending", "#MF", 16)
{}
};
- class AlignmentCheck : X86Fault
+ class AlignmentCheck : public X86Fault
{
public:
AlignmentCheck() :
- X86Fault("Alignment-Check", "#AC")
+ X86Fault("Alignment-Check", "#AC", 17, 0)
{}
};
- class MachineCheck : X86Abort
+ class MachineCheck : public X86Abort
{
public:
MachineCheck() :
- X86Abort("Machine-Check", "#MC")
+ X86Abort("Machine-Check", "#MC", 18)
{}
};
- class SIMDFloatingPointFault : X86Fault
+ class SIMDFloatingPointFault : public X86Fault
{
public:
SIMDFloatingPointFault() :
- X86Fault("SIMD Floating-Point", "#XF")
+ X86Fault("SIMD Floating-Point", "#XF", 19)
{}
};
- class SecurityException : X86FaultBase
+ class SecurityException : public X86FaultBase
{
public:
SecurityException() :
- X86FaultBase("Security Exception", "#SX")
+ X86FaultBase("Security Exception", "#SX", 30)
{}
};
- class ExternalInterrupt : X86Interrupt
+ class ExternalInterrupt : public X86Interrupt
{
public:
- ExternalInterrupt() :
- X86Interrupt("External Interrupt", "#INTR")
+ ExternalInterrupt(uint8_t _vector) :
+ X86Interrupt("External Interrupt", "#INTR", _vector)
{}
};
- class SoftwareInterrupt : X86Interrupt
+ class SystemManagementInterrupt : public X86Interrupt
{
public:
- SoftwareInterrupt() :
- X86Interrupt("Software Interrupt", "INTn")
+ SystemManagementInterrupt() :
+ X86Interrupt("System Management Interrupt", "#SMI", 0)
{}
};
- // These faults aren't part of the ISA definition. They trigger filling
- // the tlb on a miss and are to take the place of a hardware table walker.
- class FakeITLBFault : public X86Fault
+ class InitInterrupt : public X86Interrupt
{
- protected:
- Addr vaddr;
+ uint8_t vector;
public:
- FakeITLBFault(Addr _vaddr) :
- X86Fault("fake instruction tlb fault", "itlb"),
- vaddr(_vaddr)
+ InitInterrupt(uint8_t _vector) :
+ X86Interrupt("INIT Interrupt", "#INIT", _vector)
{}
-
- void invoke(ThreadContext * tc);
};
- class FakeDTLBFault : public X86Fault
+ class SoftwareInterrupt : public X86Interrupt
{
- protected:
- Addr vaddr;
public:
- FakeDTLBFault(Addr _vaddr) :
- X86Fault("fake data tlb fault", "dtlb"),
- vaddr(_vaddr)
+ SoftwareInterrupt(uint8_t _vector) :
+ X86Interrupt("Software Interrupt", "#INTR", _vector)
{}
- void invoke(ThreadContext * tc);
+ bool isSoft()
+ {
+ return true;
+ }
};
};
diff --git a/src/arch/x86/floatregfile.cc b/src/arch/x86/floatregfile.cc
index 1c49ea9c6..fce7f4868 100644
--- a/src/arch/x86/floatregfile.cc
+++ b/src/arch/x86/floatregfile.cc
@@ -96,15 +96,6 @@ using namespace std;
class Checkpoint;
-string X86ISA::getFloatRegName(RegIndex index)
-{
- static std::string floatRegName[NumFloatRegs] =
- {"mmx0", "mmx1", "mmx2", "mmx3", "mmx4", "mmx5", "mmx6", "mmx7",
- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
- "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"};
- return floatRegName[index];
-}
-
void FloatRegFile::clear()
{
memset(q, 0, sizeof(FloatReg) * NumFloatRegs);
@@ -113,27 +104,27 @@ void FloatRegFile::clear()
FloatReg FloatRegFile::readReg(int floatReg, int width)
{
FloatReg reg = d[floatReg];
- DPRINTF(X86, "Reading %f from register %d.\n", reg, floatReg);
+ DPRINTF(FloatRegs, "Reading %f from register %d.\n", reg, floatReg);
return reg;
}
FloatRegBits FloatRegFile::readRegBits(int floatReg, int width)
{
FloatRegBits reg = q[floatReg];
- DPRINTF(X86, "Reading %#x from register %d.\n", reg, floatReg);
+ DPRINTF(FloatRegs, "Reading %#x from register %d.\n", reg, floatReg);
return reg;
}
Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width)
{
- DPRINTF(X86, "Writing %f to register %d.\n", val, floatReg);
+ DPRINTF(FloatRegs, "Writing %f to register %d.\n", val, floatReg);
d[floatReg] = val;
return NoFault;
}
Fault FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width)
{
- DPRINTF(X86, "Writing bits %#x to register %d.\n", val, floatReg);
+ DPRINTF(FloatRegs, "Writing bits %#x to register %d.\n", val, floatReg);
q[floatReg] = val;
return NoFault;
}
diff --git a/src/arch/x86/floatregfile.hh b/src/arch/x86/floatregfile.hh
index b77ddb0eb..ab239dd7d 100644
--- a/src/arch/x86/floatregfile.hh
+++ b/src/arch/x86/floatregfile.hh
@@ -98,8 +98,6 @@ class Checkpoint;
namespace X86ISA
{
- std::string getFloatRegName(RegIndex);
-
//Each 128 bit xmm register is broken into two effective 64 bit registers.
const int NumFloatRegs =
NumMMXRegs + 2 * NumXMMRegs + NumMicroFpRegs;
diff --git a/src/arch/x86/insts/macroop.hh b/src/arch/x86/insts/macroop.hh
new file mode 100644
index 000000000..d6925a1a5
--- /dev/null
+++ b/src/arch/x86/insts/macroop.hh
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer. Redistributions
+ * in binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution. Neither the name of
+ * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_X86_INSTS_MACROOP_HH__
+#define __ARCH_X86_INSTS_MACROOP_HH__
+
+#include "arch/x86/emulenv.hh"
+#include "arch/x86/types.hh"
+#include "arch/x86/insts/static_inst.hh"
+
+namespace X86ISA
+{
+// Base class for combinationally generated macroops
+class MacroopBase : public X86StaticInst
+{
+ protected:
+ const char *macrocodeBlock;
+
+ const uint32_t numMicroops;
+ X86ISA::EmulEnv env;
+
+ //Constructor.
+ MacroopBase(const char *mnem, ExtMachInst _machInst,
+ uint32_t _numMicroops, X86ISA::EmulEnv _env) :
+ X86StaticInst(mnem, _machInst, No_OpClass),
+ numMicroops(_numMicroops), env(_env)
+ {
+ assert(numMicroops);
+ microops = new StaticInstPtr[numMicroops];
+ flags[IsMacroop] = true;
+ }
+
+ ~MacroopBase()
+ {
+ delete [] microops;
+ }
+
+ StaticInstPtr * microops;
+
+ StaticInstPtr fetchMicroop(MicroPC microPC)
+ {
+ assert(microPC < numMicroops);
+ return microops[microPC];
+ }
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ return mnemonic;
+ }
+
+ public:
+ ExtMachInst
+ getExtMachInst()
+ {
+ return machInst;
+ }
+
+ X86ISA::EmulEnv
+ getEmulEnv()
+ {
+ return env;
+ }
+};
+}
+
+#endif //__ARCH_X86_INSTS_MACROOP_HH__
diff --git a/src/arch/x86/insts/microldstop.cc b/src/arch/x86/insts/microldstop.cc
index 9638a2ae3..7cc6a330f 100644
--- a/src/arch/x86/insts/microldstop.cc
+++ b/src/arch/x86/insts/microldstop.cc
@@ -64,7 +64,6 @@ namespace X86ISA
const SymbolTable *symtab) const
{
std::stringstream response;
- bool someAddr = false;
printMnemonic(response, instMnem, mnemonic);
if(flags[IsLoad])
@@ -72,32 +71,8 @@ namespace X86ISA
else
printSrcReg(response, 2, dataSize);
response << ", ";
- printSegment(response, segment);
- response << ":[";
- if(scale != 0 && _srcRegIdx[0] != ZeroReg)
- {
- if(scale != 1)
- ccprintf(response, "%d*", scale);
- printSrcReg(response, 0, addressSize);
- someAddr = true;
- }
- if(_srcRegIdx[1] != ZeroReg)
- {
- if(someAddr)
- response << " + ";
- printSrcReg(response, 1, addressSize);
- someAddr = true;
- }
- if(disp != 0)
- {
- if(someAddr)
- response << " + ";
- ccprintf(response, "%#x", disp);
- someAddr = true;
- }
- if(!someAddr)
- response << "0";
- response << "]";
+ printMem(response, segment, scale, index, base, disp,
+ addressSize, false);
return response.str();
}
}
diff --git a/src/arch/x86/insts/microldstop.hh b/src/arch/x86/insts/microldstop.hh
index 5b1210d69..1774454c3 100644
--- a/src/arch/x86/insts/microldstop.hh
+++ b/src/arch/x86/insts/microldstop.hh
@@ -59,9 +59,18 @@
#define __ARCH_X86_INSTS_MICROLDSTOP_HH__
#include "arch/x86/insts/microop.hh"
+#include "mem/packet.hh"
+#include "mem/request.hh"
namespace X86ISA
{
+ static const Request::FlagsType SegmentFlagMask = mask(4);
+ static const int FlagShift = 4;
+ enum FlagBit {
+ CPL0FlagBit = 1,
+ AddrSizeFlagBit = 2
+ };
+
/**
* Base class for load and store ops
*/
@@ -76,6 +85,7 @@ namespace X86ISA
const RegIndex data;
const uint8_t dataSize;
const uint8_t addressSize;
+ const Request::FlagsType memFlags;
RegIndex foldOBit, foldABit;
//Constructor
@@ -86,13 +96,15 @@ namespace X86ISA
uint64_t _disp, uint8_t _segment,
RegIndex _data,
uint8_t _dataSize, uint8_t _addressSize,
+ Request::FlagsType _memFlags,
OpClass __opClass) :
X86MicroopBase(machInst, mnem, _instMnem,
isMicro, isDelayed, isFirst, isLast, __opClass),
scale(_scale), index(_index), base(_base),
disp(_disp), segment(_segment),
data(_data),
- dataSize(_dataSize), addressSize(_addressSize)
+ dataSize(_dataSize), addressSize(_addressSize),
+ memFlags(_memFlags | _segment)
{
foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
foldABit =
@@ -149,6 +161,25 @@ namespace X86ISA
}
return fault;
}
+
+ uint64_t
+ get(PacketPtr pkt) const
+ {
+ switch(dataSize)
+ {
+ case 1:
+ return pkt->get<uint8_t>();
+ case 2:
+ return pkt->get<uint16_t>();
+ case 4:
+ return pkt->get<uint32_t>();
+ case 8:
+ return pkt->get<uint64_t>();
+ default:
+ panic("Bad operand size %d for read at %#x.\n",
+ dataSize, pkt->getAddr());
+ }
+ }
};
}
diff --git a/src/arch/x86/insts/microop.cc b/src/arch/x86/insts/microop.cc
index 494c0b303..c7bfc3703 100644
--- a/src/arch/x86/insts/microop.cc
+++ b/src/arch/x86/insts/microop.cc
@@ -98,7 +98,7 @@ namespace X86ISA
case ConditionTests::SxOF:
return ccflags.sf ^ ccflags.of;
case ConditionTests::SxOvZF:
- return ccflags.sf ^ ccflags.of | ccflags.zf;
+ return (ccflags.sf ^ ccflags.of) | ccflags.zf;
case ConditionTests::False:
return false;
case ConditionTests::NotECF:
@@ -131,7 +131,7 @@ namespace X86ISA
case ConditionTests::NotSxOF:
return !(ccflags.sf ^ ccflags.of);
case ConditionTests::NotSxOvZF:
- return !(ccflags.sf ^ ccflags.of | ccflags.zf);
+ return !((ccflags.sf ^ ccflags.of) | ccflags.zf);
}
panic("Unknown condition: %d\n", condition);
return true;
diff --git a/src/arch/x86/insts/microregop.cc b/src/arch/x86/insts/microregop.cc
index 080926627..2ea975746 100644
--- a/src/arch/x86/insts/microregop.cc
+++ b/src/arch/x86/insts/microregop.cc
@@ -67,6 +67,9 @@ namespace X86ISA
bool subtract) const
{
DPRINTF(X86, "flagMask = %#x\n", flagMask);
+ if (_destRegIdx[0] & (1 << 6)) {
+ _dest >>= 8;
+ }
uint64_t flags = oldFlags & ~flagMask;
if(flagMask & (ECFBit | CFBit))
{
diff --git a/src/arch/x86/insts/static_inst.cc b/src/arch/x86/insts/static_inst.cc
index 0c1508d5a..f4ed44603 100644
--- a/src/arch/x86/insts/static_inst.cc
+++ b/src/arch/x86/insts/static_inst.cc
@@ -63,13 +63,13 @@ namespace X86ISA
void X86StaticInst::printMnemonic(std::ostream &os,
const char * mnemonic) const
{
- ccprintf(os, "\t%s ", mnemonic);
+ ccprintf(os, " %s ", mnemonic);
}
void X86StaticInst::printMnemonic(std::ostream &os,
const char * instMnemonic, const char * mnemonic) const
{
- ccprintf(os, "\t%s : %s ", instMnemonic, mnemonic);
+ ccprintf(os, " %s : %s ", instMnemonic, mnemonic);
}
void X86StaticInst::printSegment(std::ostream &os, int segment) const
@@ -240,6 +240,44 @@ namespace X86ISA
}
}
+ void X86StaticInst::printMem(std::ostream &os, uint8_t segment,
+ uint8_t scale, RegIndex index, RegIndex base,
+ uint64_t disp, uint8_t addressSize, bool rip) const
+ {
+ bool someAddr = false;
+ printSegment(os, segment);
+ os << ":[";
+ if (rip) {
+ os << "rip";
+ someAddr = true;
+ } else {
+ if (scale != 0 && index != ZeroReg)
+ {
+ if(scale != 1)
+ ccprintf(os, "%d*", scale);
+ printReg(os, index, addressSize);
+ someAddr = true;
+ }
+ if (base != ZeroReg)
+ {
+ if(someAddr)
+ os << " + ";
+ printReg(os, base, addressSize);
+ someAddr = true;
+ }
+ }
+ if (disp != 0)
+ {
+ if(someAddr)
+ os << " + ";
+ ccprintf(os, "%#x", disp);
+ someAddr = true;
+ }
+ if (!someAddr)
+ os << "0";
+ os << "]";
+ }
+
std::string X86StaticInst::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
diff --git a/src/arch/x86/insts/static_inst.hh b/src/arch/x86/insts/static_inst.hh
index e5c333e75..8480f2713 100644
--- a/src/arch/x86/insts/static_inst.hh
+++ b/src/arch/x86/insts/static_inst.hh
@@ -89,6 +89,9 @@ namespace X86ISA
void printReg(std::ostream &os, int reg, int size) const;
void printSrcReg(std::ostream &os, int reg, int size) const;
void printDestReg(std::ostream &os, int reg, int size) const;
+ void printMem(std::ostream &os, uint8_t segment,
+ uint8_t scale, RegIndex index, RegIndex base,
+ uint64_t disp, uint8_t addressSize, bool rip) const;
inline uint64_t merge(uint64_t into, uint64_t val, int size) const
{
diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc
new file mode 100644
index 000000000..30c532c2b
--- /dev/null
+++ b/src/arch/x86/interrupts.cc
@@ -0,0 +1,569 @@
+/*
+ * Copyright (c) 2008 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer. Redistributions
+ * in binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution. Neither the name of
+ * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "arch/x86/apicregs.hh"
+#include "arch/x86/interrupts.hh"
+#include "arch/x86/intmessage.hh"
+#include "cpu/base.hh"
+#include "mem/packet_access.hh"
+
+int
+divideFromConf(uint32_t conf)
+{
+ // This figures out what division we want from the division configuration
+ // register in the local APIC. The encoding is a little odd but it can
+ // be deciphered fairly easily.
+ int shift = ((conf & 0x8) >> 1) | (conf & 0x3);
+ shift = (shift + 1) % 8;
+ return 1 << shift;
+}
+
+namespace X86ISA
+{
+
+ApicRegIndex
+decodeAddr(Addr paddr)
+{
+ ApicRegIndex regNum;
+ paddr &= ~mask(3);
+ switch (paddr)
+ {
+ case 0x20:
+ regNum = APIC_ID;
+ break;
+ case 0x30:
+ regNum = APIC_VERSION;
+ break;
+ case 0x80:
+ regNum = APIC_TASK_PRIORITY;
+ break;
+ case 0x90:
+ regNum = APIC_ARBITRATION_PRIORITY;
+ break;
+ case 0xA0:
+ regNum = APIC_PROCESSOR_PRIORITY;
+ break;
+ case 0xB0:
+ regNum = APIC_EOI;
+ break;
+ case 0xD0:
+ regNum = APIC_LOGICAL_DESTINATION;
+ break;
+ case 0xE0:
+ regNum = APIC_DESTINATION_FORMAT;
+ break;
+ case 0xF0:
+ regNum = APIC_SPURIOUS_INTERRUPT_VECTOR;
+ break;
+ case 0x100:
+ case 0x108:
+ case 0x110:
+ case 0x118:
+ case 0x120:
+ case 0x128:
+ case 0x130:
+ case 0x138:
+ case 0x140:
+ case 0x148:
+ case 0x150:
+ case 0x158:
+ case 0x160:
+ case 0x168:
+ case 0x170:
+ case 0x178:
+ regNum = APIC_IN_SERVICE((paddr - 0x100) / 0x8);
+ break;
+ case 0x180:
+ case 0x188:
+ case 0x190:
+ case 0x198:
+ case 0x1A0:
+ case 0x1A8:
+ case 0x1B0:
+ case 0x1B8:
+ case 0x1C0:
+ case 0x1C8:
+ case 0x1D0:
+ case 0x1D8:
+ case 0x1E0:
+ case 0x1E8:
+ case 0x1F0:
+ case 0x1F8:
+ regNum = APIC_TRIGGER_MODE((paddr - 0x180) / 0x8);
+ break;
+ case 0x200:
+ case 0x208:
+ case 0x210:
+ case 0x218:
+ case 0x220:
+ case 0x228:
+ case 0x230:
+ case 0x238:
+ case 0x240:
+ case 0x248:
+ case 0x250:
+ case 0x258:
+ case 0x260:
+ case 0x268:
+ case 0x270:
+ case 0x278:
+ regNum = APIC_INTERRUPT_REQUEST((paddr - 0x200) / 0x8);
+ break;
+ case 0x280:
+ regNum = APIC_ERROR_STATUS;
+ break;
+ case 0x300:
+ regNum = APIC_INTERRUPT_COMMAND_LOW;
+ break;
+ case 0x310:
+ regNum = APIC_INTERRUPT_COMMAND_HIGH;
+ break;
+ case 0x320:
+ regNum = APIC_LVT_TIMER;
+ break;
+ case 0x330:
+ regNum = APIC_LVT_THERMAL_SENSOR;
+ break;
+ case 0x340:
+ regNum = APIC_LVT_PERFORMANCE_MONITORING_COUNTERS;
+ break;
+ case 0x350:
+ regNum = APIC_LVT_LINT0;
+ break;
+ case 0x360:
+ regNum = APIC_LVT_LINT1;
+ break;
+ case 0x370:
+ regNum = APIC_LVT_ERROR;
+ break;
+ case 0x380:
+ regNum = APIC_INITIAL_COUNT;
+ break;
+ case 0x390:
+ regNum = APIC_CURRENT_COUNT;
+ break;
+ case 0x3E0:
+ regNum = APIC_DIVIDE_CONFIGURATION;
+ break;
+ default:
+ // A reserved register field.
+ panic("Accessed reserved register field %#x.\n", paddr);
+ break;
+ }
+ return regNum;
+}
+}
+
+Tick
+X86ISA::Interrupts::read(PacketPtr pkt)
+{
+ Addr offset = pkt->getAddr() - pioAddr;
+ //Make sure we're at least only accessing one register.
+ if ((offset & ~mask(3)) != ((offset + pkt->getSize()) & ~mask(3)))
+ panic("Accessed more than one register at a time in the APIC!\n");
+ ApicRegIndex reg = decodeAddr(offset);
+ uint32_t val = htog(readReg(reg));
+ DPRINTF(LocalApic,
+ "Reading Local APIC register %d at offset %#x as %#x.\n",
+ reg, offset, val);
+ pkt->setData(((uint8_t *)&val) + (offset & mask(3)));
+ pkt->makeAtomicResponse();
+ return latency;
+}
+
+Tick
+X86ISA::Interrupts::write(PacketPtr pkt)
+{
+ Addr offset = pkt->getAddr() - pioAddr;
+ //Make sure we're at least only accessing one register.
+ if ((offset & ~mask(3)) != ((offset + pkt->getSize()) & ~mask(3)))
+ panic("Accessed more than one register at a time in the APIC!\n");
+ ApicRegIndex reg = decodeAddr(offset);
+ uint32_t val = regs[reg];
+ pkt->writeData(((uint8_t *)&val) + (offset & mask(3)));
+ DPRINTF(LocalApic,
+ "Writing Local APIC register %d at offset %#x as %#x.\n",
+ reg, offset, gtoh(val));
+ setReg(reg, gtoh(val));
+ pkt->makeAtomicResponse();
+ return latency;
+}
+void
+X86ISA::Interrupts::requestInterrupt(uint8_t vector,
+ uint8_t deliveryMode, bool level)
+{
+ /*
+ * Fixed and lowest-priority delivery mode interrupts are handled
+ * using the IRR/ISR registers, checking against the TPR, etc.
+ * The SMI, NMI, ExtInt, INIT, etc interrupts go straight through.
+ */
+ if (deliveryMode == DeliveryMode::Fixed ||
+ deliveryMode == DeliveryMode::LowestPriority) {
+ DPRINTF(LocalApic, "Interrupt is an %s.\n",
+ DeliveryMode::names[deliveryMode]);
+ // Queue up the interrupt in the IRR.
+ if (vector > IRRV)
+ IRRV = vector;
+ if (!getRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector)) {
+ setRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector);
+ if (level) {
+ setRegArrayBit(APIC_TRIGGER_MODE_BASE, vector);
+ } else {
+ clearRegArrayBit(APIC_TRIGGER_MODE_BASE, vector);
+ }
+ }
+ } else if (!DeliveryMode::isReserved(deliveryMode)) {
+ DPRINTF(LocalApic, "Interrupt is an %s.\n",
+ DeliveryMode::names[deliveryMode]);
+ if (deliveryMode == DeliveryMode::SMI && !pendingSmi) {
+ pendingUnmaskableInt = pendingSmi = true;
+ smiVector = vector;
+ } else if (deliveryMode == DeliveryMode::NMI && !pendingNmi) {
+ pendingUnmaskableInt = pendingNmi = true;
+ nmiVector = vector;
+ } else if (deliveryMode == DeliveryMode::ExtInt && !pendingExtInt) {
+ pendingExtInt = true;
+ extIntVector = vector;
+ } else if (deliveryMode == DeliveryMode::INIT && !pendingInit) {
+ pendingUnmaskableInt = pendingInit = true;
+ initVector = vector;
+ }
+ }
+ cpu->wakeup();
+}
+
+Tick
+X86ISA::Interrupts::recvMessage(PacketPtr pkt)
+{
+ uint8_t id = 0;
+ Addr offset = pkt->getAddr() - x86InterruptAddress(id, 0);
+ assert(pkt->cmd == MemCmd::MessageReq);
+ switch(offset)
+ {
+ case 0:
+ {
+ TriggerIntMessage message = pkt->get<TriggerIntMessage>();
+ DPRINTF(LocalApic,
+ "Got Trigger Interrupt message with vector %#x.\n",
+ message.vector);
+ // Make sure we're really supposed to get this.
+ assert((message.destMode == 0 && message.destination == id) ||
+ (bits((int)message.destination, id)));
+
+ requestInterrupt(message.vector,
+ message.deliveryMode, message.trigger);
+ }
+ break;
+ default:
+ panic("Local apic got unknown interrupt message at offset %#x.\n",
+ offset);
+ break;
+ }
+ delete pkt->req;
+ delete pkt;
+ return latency;
+}
+
+
+uint32_t
+X86ISA::Interrupts::readReg(ApicRegIndex reg)
+{
+ if (reg >= APIC_TRIGGER_MODE(0) &&
+ reg <= APIC_TRIGGER_MODE(15)) {
+ panic("Local APIC Trigger Mode registers are unimplemented.\n");
+ }
+ switch (reg) {
+ case APIC_ARBITRATION_PRIORITY:
+ panic("Local APIC Arbitration Priority register unimplemented.\n");
+ break;
+ case APIC_PROCESSOR_PRIORITY:
+ panic("Local APIC Processor Priority register unimplemented.\n");
+ break;
+ case APIC_ERROR_STATUS:
+ regs[APIC_INTERNAL_STATE] &= ~ULL(0x1);
+ break;
+ case APIC_INTERRUPT_COMMAND_LOW:
+ panic("Local APIC Interrupt Command low"
+ " register unimplemented.\n");
+ break;
+ case APIC_INTERRUPT_COMMAND_HIGH:
+ panic("Local APIC Interrupt Command high"
+ " register unimplemented.\n");
+ break;
+ case APIC_CURRENT_COUNT:
+ {
+ if (apicTimerEvent.scheduled()) {
+ assert(clock);
+ // Compute how many m5 ticks happen per count.
+ uint64_t ticksPerCount = clock *
+ divideFromConf(regs[APIC_DIVIDE_CONFIGURATION]);
+ // Compute how many m5 ticks are left.
+ uint64_t val = apicTimerEvent.when() - curTick;
+ // Turn that into a count.
+ val = (val + ticksPerCount - 1) / ticksPerCount;
+ return val;
+ } else {
+ return 0;
+ }
+ }
+ default:
+ break;
+ }
+ return regs[reg];
+}
+
+void
+X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
+{
+ uint32_t newVal = val;
+ if (reg >= APIC_IN_SERVICE(0) &&
+ reg <= APIC_IN_SERVICE(15)) {
+ panic("Local APIC In-Service registers are unimplemented.\n");
+ }
+ if (reg >= APIC_TRIGGER_MODE(0) &&
+ reg <= APIC_TRIGGER_MODE(15)) {
+ panic("Local APIC Trigger Mode registers are unimplemented.\n");
+ }
+ if (reg >= APIC_INTERRUPT_REQUEST(0) &&
+ reg <= APIC_INTERRUPT_REQUEST(15)) {
+ panic("Local APIC Interrupt Request registers "
+ "are unimplemented.\n");
+ }
+ switch (reg) {
+ case APIC_ID:
+ newVal = val & 0xFF;
+ break;
+ case APIC_VERSION:
+ // The Local APIC Version register is read only.
+ return;
+ case APIC_TASK_PRIORITY:
+ newVal = val & 0xFF;
+ break;
+ case APIC_ARBITRATION_PRIORITY:
+ panic("Local APIC Arbitration Priority register unimplemented.\n");
+ break;
+ case APIC_PROCESSOR_PRIORITY:
+ panic("Local APIC Processor Priority register unimplemented.\n");
+ break;
+ case APIC_EOI:
+ // Remove the interrupt that just completed from the local apic state.
+ clearRegArrayBit(APIC_IN_SERVICE_BASE, ISRV);
+ updateISRV();
+ return;
+ case APIC_LOGICAL_DESTINATION:
+ newVal = val & 0xFF000000;
+ break;
+ case APIC_DESTINATION_FORMAT:
+ newVal = val | 0x0FFFFFFF;
+ break;
+ case APIC_SPURIOUS_INTERRUPT_VECTOR:
+ regs[APIC_INTERNAL_STATE] &= ~ULL(1 << 1);
+ regs[APIC_INTERNAL_STATE] |= val & (1 << 8);
+ if (val & (1 << 9))
+ warn("Focus processor checking not implemented.\n");
+ break;
+ case APIC_ERROR_STATUS:
+ {
+ if (regs[APIC_INTERNAL_STATE] & 0x1) {
+ regs[APIC_INTERNAL_STATE] &= ~ULL(0x1);
+ newVal = 0;
+ } else {
+ regs[APIC_INTERNAL_STATE] |= ULL(0x1);
+ return;
+ }
+
+ }
+ break;
+ case APIC_INTERRUPT_COMMAND_LOW:
+ panic("Local APIC Interrupt Command low"
+ " register unimplemented.\n");
+ break;
+ case APIC_INTERRUPT_COMMAND_HIGH:
+ panic("Local APIC Interrupt Command high"
+ " register unimplemented.\n");
+ break;
+ case APIC_LVT_TIMER:
+ case APIC_LVT_THERMAL_SENSOR:
+ case APIC_LVT_PERFORMANCE_MONITORING_COUNTERS:
+ case APIC_LVT_LINT0:
+ case APIC_LVT_LINT1:
+ case APIC_LVT_ERROR:
+ {
+ uint64_t readOnlyMask = (1 << 12) | (1 << 14);
+ newVal = (val & ~readOnlyMask) |
+ (regs[reg] & readOnlyMask);
+ }
+ break;
+ case APIC_INITIAL_COUNT:
+ {
+ assert(clock);
+ newVal = bits(val, 31, 0);
+ // Compute how many timer ticks we're being programmed for.
+ uint64_t newCount = newVal *
+ (divideFromConf(regs[APIC_DIVIDE_CONFIGURATION]));
+ // Schedule on the edge of the next tick plus the new count.
+ Tick offset = curTick % clock;
+ if (offset) {
+ reschedule(apicTimerEvent,
+ curTick + (newCount + 1) * clock - offset, true);
+ } else {
+ reschedule(apicTimerEvent,
+ curTick + newCount * clock, true);
+ }
+ }
+ break;
+ case APIC_CURRENT_COUNT:
+ //Local APIC Current Count register is read only.
+ return;
+ case APIC_DIVIDE_CONFIGURATION:
+ newVal = val & 0xB;
+ break;
+ default:
+ break;
+ }
+ regs[reg] = newVal;
+ return;
+}
+
+bool
+X86ISA::Interrupts::checkInterrupts(ThreadContext *tc) const
+{
+ RFLAGS rflags = tc->readMiscRegNoEffect(MISCREG_RFLAGS);
+ if (pendingUnmaskableInt) {
+ DPRINTF(LocalApic, "Reported pending unmaskable interrupt.\n");
+ return true;
+ }
+ if (rflags.intf) {
+ if (pendingExtInt) {
+ DPRINTF(LocalApic, "Reported pending external interrupt.\n");
+ return true;
+ }
+ if (IRRV > ISRV && bits(IRRV, 7, 4) >
+ bits(regs[APIC_TASK_PRIORITY], 7, 4)) {
+ DPRINTF(LocalApic, "Reported pending regular interrupt.\n");
+ return true;
+ }
+ }
+ return false;
+}
+
+Fault
+X86ISA::Interrupts::getInterrupt(ThreadContext *tc)
+{
+ assert(checkInterrupts(tc));
+ // These are all probably fairly uncommon, so we'll make them easier to
+ // check for.
+ if (pendingUnmaskableInt) {
+ if (pendingSmi) {
+ DPRINTF(LocalApic, "Generated SMI fault object.\n");
+ return new SystemManagementInterrupt();
+ } else if (pendingNmi) {
+ DPRINTF(LocalApic, "Generated NMI fault object.\n");
+ return new NonMaskableInterrupt(nmiVector);
+ } else if (pendingInit) {
+ DPRINTF(LocalApic, "Generated INIT fault object.\n");
+ return new InitInterrupt(initVector);
+ } else {
+ panic("pendingUnmaskableInt set, but no unmaskable "
+ "ints were pending.\n");
+ return NoFault;
+ }
+ } else if (pendingExtInt) {
+ DPRINTF(LocalApic, "Generated external interrupt fault object.\n");
+ return new ExternalInterrupt(extIntVector);
+ } else {
+ DPRINTF(LocalApic, "Generated regular interrupt fault object.\n");
+ // The only thing left are fixed and lowest priority interrupts.
+ return new ExternalInterrupt(IRRV);
+ }
+}
+
+void
+X86ISA::Interrupts::updateIntrInfo(ThreadContext *tc)
+{
+ assert(checkInterrupts(tc));
+ if (pendingUnmaskableInt) {
+ if (pendingSmi) {
+ DPRINTF(LocalApic, "SMI sent to core.\n");
+ pendingSmi = false;
+ } else if (pendingNmi) {
+ DPRINTF(LocalApic, "NMI sent to core.\n");
+ pendingNmi = false;
+ } else if (pendingInit) {
+ DPRINTF(LocalApic, "Init sent to core.\n");
+ pendingInit = false;
+ }
+ if (!(pendingSmi || pendingNmi || pendingInit))
+ pendingUnmaskableInt = false;
+ } else if (pendingExtInt) {
+ pendingExtInt = false;
+ } else {
+ DPRINTF(LocalApic, "Interrupt %d sent to core.\n", IRRV);
+ // Mark the interrupt as "in service".
+ ISRV = IRRV;
+ setRegArrayBit(APIC_IN_SERVICE_BASE, ISRV);
+ // Clear it out of the IRR.
+ clearRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, IRRV);
+ updateIRRV();
+ }
+}
+
+X86ISA::Interrupts *
+X86LocalApicParams::create()
+{
+ return new X86ISA::Interrupts(this);
+}
diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh
index cf9109e22..c5e3bde0d 100644
--- a/src/arch/x86/interrupts.hh
+++ b/src/arch/x86/interrupts.hh
@@ -58,73 +58,274 @@
#ifndef __ARCH_X86_INTERRUPTS_HH__
#define __ARCH_X86_INTERRUPTS_HH__
+#include "arch/x86/apicregs.hh"
#include "arch/x86/faults.hh"
+#include "arch/x86/intmessage.hh"
+#include "base/bitfield.hh"
#include "cpu/thread_context.hh"
+#include "dev/io_device.hh"
+#include "dev/x86/intdev.hh"
+#include "params/X86LocalApic.hh"
+#include "sim/eventq.hh"
-namespace X86ISA
-{
+class ThreadContext;
+class BaseCPU;
+
+namespace X86ISA {
-class Interrupts
+class Interrupts : public BasicPioDevice, IntDev
{
+ protected:
+ // Storage for the APIC registers
+ uint32_t regs[NUM_APIC_REGS];
+
+ BitUnion32(LVTEntry)
+ Bitfield<7, 0> vector;
+ Bitfield<10, 8> deliveryMode;
+ Bitfield<12> status;
+ Bitfield<13> polarity;
+ Bitfield<14> remoteIRR;
+ Bitfield<15> trigger;
+ Bitfield<16> masked;
+ Bitfield<17> periodic;
+ EndBitUnion(LVTEntry)
+
+ /*
+ * Timing related stuff.
+ */
+ Tick latency;
+ Tick clock;
+
+ class ApicTimerEvent : public Event
+ {
+ private:
+ Interrupts *localApic;
+ public:
+ ApicTimerEvent(Interrupts *_localApic) :
+ Event(), localApic(_localApic)
+ {}
+
+ void process()
+ {
+ assert(localApic);
+ if (localApic->triggerTimerInterrupt()) {
+ localApic->setReg(APIC_INITIAL_COUNT,
+ localApic->readReg(APIC_INITIAL_COUNT));
+ }
+ }
+ };
+
+ ApicTimerEvent apicTimerEvent;
+
+ /*
+ * A set of variables to keep track of interrupts that don't go through
+ * the IRR.
+ */
+ bool pendingSmi;
+ uint8_t smiVector;
+ bool pendingNmi;
+ uint8_t nmiVector;
+ bool pendingExtInt;
+ uint8_t extIntVector;
+ bool pendingInit;
+ uint8_t initVector;
+
+ // This is a quick check whether any of the above (except ExtInt) are set.
+ bool pendingUnmaskableInt;
+
+ /*
+ * IRR and ISR maintenance.
+ */
+ uint8_t IRRV;
+ uint8_t ISRV;
+
+ int
+ findRegArrayMSB(ApicRegIndex base)
+ {
+ int offset = 7;
+ do {
+ if (regs[base + offset] != 0) {
+ return offset * 32 + findMsbSet(regs[base + offset]);
+ }
+ } while (offset--);
+ return 0;
+ }
+
+ void
+ updateIRRV()
+ {
+ IRRV = findRegArrayMSB(APIC_INTERRUPT_REQUEST_BASE);
+ }
+
+ void
+ updateISRV()
+ {
+ ISRV = findRegArrayMSB(APIC_IN_SERVICE_BASE);
+ }
+
+ void
+ setRegArrayBit(ApicRegIndex base, uint8_t vector)
+ {
+ regs[base + (vector % 32)] |= (1 << (vector >> 5));
+ }
+
+ void
+ clearRegArrayBit(ApicRegIndex base, uint8_t vector)
+ {
+ regs[base + (vector % 32)] &= ~(1 << (vector >> 5));
+ }
+
+ bool
+ getRegArrayBit(ApicRegIndex base, uint8_t vector)
+ {
+ return bits(regs[base + (vector % 32)], vector >> 5);
+ }
+
+ void requestInterrupt(uint8_t vector, uint8_t deliveryMode, bool level);
+
+ BaseCPU *cpu;
+
public:
- Interrupts()
+ /*
+ * Params stuff.
+ */
+ typedef X86LocalApicParams Params;
+
+ void
+ setCPU(BaseCPU * newCPU)
{
- clear_all();
+ cpu = newCPU;
}
- int InterruptLevel(uint64_t softint)
+ void
+ setClock(Tick newClock)
{
- panic("Interrupts::InterruptLevel unimplemented!\n");
- return 0;
+ clock = newClock;
}
- void post(int int_num, int index)
+ const Params *
+ params() const
{
- panic("Interrupts::post unimplemented!\n");
+ return dynamic_cast<const Params *>(_params);
}
- void clear(int int_num, int index)
+ /*
+ * Functions to interact with the interrupt port from IntDev.
+ */
+ Tick read(PacketPtr pkt);
+ Tick write(PacketPtr pkt);
+ Tick recvMessage(PacketPtr pkt);
+
+ bool
+ triggerTimerInterrupt()
{
- warn("Interrupts::clear unimplemented!\n");
+ LVTEntry entry = regs[APIC_LVT_TIMER];
+ if (!entry.masked)
+ requestInterrupt(entry.vector, entry.deliveryMode, entry.trigger);
+ return entry.periodic;
}
- void clear_all()
+ void addressRanges(AddrRangeList &range_list)
{
- warn("Interrupts::clear_all unimplemented!\n");
+ range_list.clear();
+ range_list.push_back(RangeEx(x86LocalAPICAddress(0, 0),
+ x86LocalAPICAddress(0, 0) + PageBytes));
}
- bool check_interrupts(ThreadContext * tc) const
+ void getIntAddrRange(AddrRangeList &range_list)
{
- return false;
+ range_list.clear();
+ range_list.push_back(RangeEx(x86InterruptAddress(0, 0),
+ x86InterruptAddress(0, 0) + PhysAddrAPICRangeSize));
}
- Fault getInterrupt(ThreadContext * tc)
+ Port *getPort(const std::string &if_name, int idx = -1)
{
- return NoFault;
+ if (if_name == "int_port")
+ return intPort;
+ return BasicPioDevice::getPort(if_name, idx);
}
- void updateIntrInfo(ThreadContext * tc)
+ /*
+ * Functions to access and manipulate the APIC's registers.
+ */
+
+ uint32_t readReg(ApicRegIndex miscReg);
+ void setReg(ApicRegIndex reg, uint32_t val);
+ void
+ setRegNoEffect(ApicRegIndex reg, uint32_t val)
{
- panic("Interrupts::updateIntrInfo unimplemented!\n");
+ regs[reg] = val;
}
- uint64_t get_vec(int int_num)
+ /*
+ * Constructor.
+ */
+
+ Interrupts(Params * p)
+ : BasicPioDevice(p), IntDev(this), latency(p->pio_latency), clock(0),
+ apicTimerEvent(this),
+ pendingSmi(false), smiVector(0),
+ pendingNmi(false), nmiVector(0),
+ pendingExtInt(false), extIntVector(0),
+ pendingInit(false), initVector(0),
+ pendingUnmaskableInt(false)
{
- panic("Interrupts::get_vec unimplemented!\n");
- return 0;
+ pioSize = PageBytes;
+ memset(regs, 0, sizeof(regs));
+ //Set the local apic DFR to the flat model.
+ regs[APIC_DESTINATION_FORMAT] = (uint32_t)(-1);
+ ISRV = 0;
+ IRRV = 0;
}
- void serialize(std::ostream & os)
+ /*
+ * Functions for retrieving interrupts for the CPU to handle.
+ */
+
+ bool checkInterrupts(ThreadContext *tc) const;
+ Fault getInterrupt(ThreadContext *tc);
+ void updateIntrInfo(ThreadContext *tc);
+
+ /*
+ * Serialization.
+ */
+
+ void
+ serialize(std::ostream &os)
{
panic("Interrupts::serialize unimplemented!\n");
}
- void unserialize(Checkpoint * cp, const std::string & section)
+ void
+ unserialize(Checkpoint *cp, const std::string &section)
{
panic("Interrupts::unserialize unimplemented!\n");
}
-};
+ /*
+ * Old functions needed for compatability but which will be phased out
+ * eventually.
+ */
+ void
+ post(int int_num, int index)
+ {
+ panic("Interrupts::post unimplemented!\n");
+ }
+
+ void
+ clear(int int_num, int index)
+ {
+ panic("Interrupts::clear unimplemented!\n");
+ }
+
+ void
+ clearAll()
+ {
+ panic("Interrupts::clearAll unimplemented!\n");
+ }
};
+} // namespace X86ISA
+
#endif // __ARCH_X86_INTERRUPTS_HH__
diff --git a/src/arch/x86/intmessage.hh b/src/arch/x86/intmessage.hh
new file mode 100644
index 000000000..f5f8519e2
--- /dev/null
+++ b/src/arch/x86/intmessage.hh
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2008 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_X86_INTMESSAGE_HH__
+#define __ARCH_X86_INTMESSAGE_HH__
+
+#include "arch/x86/x86_traits.hh"
+#include "base/bitunion.hh"
+#include "mem/packet.hh"
+#include "mem/request.hh"
+#include "sim/host.hh"
+
+namespace X86ISA
+{
+ BitUnion32(TriggerIntMessage)
+ Bitfield<7, 0> destination;
+ Bitfield<15, 8> vector;
+ Bitfield<18, 16> deliveryMode;
+ Bitfield<19> destMode;
+ Bitfield<20> level;
+ Bitfield<21> trigger;
+ EndBitUnion(TriggerIntMessage)
+
+ namespace DeliveryMode
+ {
+ enum IntDeliveryMode {
+ Fixed = 0,
+ LowestPriority = 1,
+ SMI = 2,
+ NMI = 4,
+ INIT = 5,
+ ExtInt = 7,
+ NumModes
+ };
+
+ static const char * const names[NumModes] = {
+ "Fixed", "LowestPriority", "SMI", "Reserved",
+ "NMI", "INIT", "Reserved", "ExtInt"
+ };
+
+ static inline bool
+ isReserved(int mode)
+ {
+ return mode == 3 || mode == 6;
+ }
+ }
+
+ static const Addr TriggerIntOffset = 0;
+
+ static inline PacketPtr
+ prepIntRequest(const uint8_t id, Addr offset, Addr size)
+ {
+ RequestPtr req = new Request(x86InterruptAddress(id, offset),
+ size, Request::UNCACHEABLE);
+ PacketPtr pkt = new Packet(req, MemCmd::MessageReq, Packet::Broadcast);
+ pkt->allocate();
+ return pkt;
+ }
+
+ template<class T>
+ PacketPtr
+ buildIntRequest(const uint8_t id, T payload, Addr offset, Addr size)
+ {
+ PacketPtr pkt = prepIntRequest(id, offset, size);
+ pkt->set<T>(payload);
+ return pkt;
+ }
+
+ static inline PacketPtr
+ buildIntRequest(const uint8_t id, TriggerIntMessage payload)
+ {
+ return buildIntRequest(id, payload, TriggerIntOffset,
+ sizeof(TriggerIntMessage));
+ }
+
+ static inline PacketPtr
+ buildIntResponse()
+ {
+ panic("buildIntResponse not implemented.\n");
+ }
+}
+
+#endif
diff --git a/src/arch/x86/intregfile.cc b/src/arch/x86/intregfile.cc
index 9c9ea134e..58a37cb9e 100644
--- a/src/arch/x86/intregfile.cc
+++ b/src/arch/x86/intregfile.cc
@@ -97,17 +97,6 @@ using namespace std;
class Checkpoint;
-string X86ISA::getIntRegName(RegIndex index)
-{
- //These might appear to be out of order, but they match
- //the encoding for the registers. Who knows why the indexes
- //are out of order
- static std::string intRegName[NumIntArchRegs] =
- {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"};
- return intRegName[index];
-}
-
int IntRegFile::flattenIndex(int reg)
{
return reg;
@@ -120,13 +109,15 @@ void IntRegFile::clear()
IntReg IntRegFile::readReg(int intReg)
{
- DPRINTF(X86, "Read int reg %d and got value %#x\n", intReg, regs[intReg]);
+ DPRINTF(IntRegs, "Read int reg %d and got value %#x\n",
+ intReg, regs[intReg]);
return regs[intReg];
}
void IntRegFile::setReg(int intReg, const IntReg &val)
{
- DPRINTF(X86, "Setting int reg %d to value %#x\n", intReg, val);
+ DPRINTF(IntRegs, "Setting int reg %d to value %#x\n",
+ intReg, val);
regs[intReg] = val;
}
diff --git a/src/arch/x86/intregfile.hh b/src/arch/x86/intregfile.hh
index b4d256a04..131245352 100644
--- a/src/arch/x86/intregfile.hh
+++ b/src/arch/x86/intregfile.hh
@@ -100,9 +100,6 @@ namespace X86ISA
{
class Regfile;
- //This function translates integer register file indices into names
- std::string getIntRegName(RegIndex);
-
const int NumIntArchRegs = NUM_INTREGS;
const int NumIntRegs =
NumIntArchRegs + NumMicroIntRegs +
diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
index 332ae1641..817986232 100644
--- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
@@ -1,4 +1,4 @@
-// Copyright (c) 2007 The Hewlett-Packard Development Company
+// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@@ -418,12 +418,27 @@
default: Inst::RET_FAR();
}
0x4: int3();
+#if FULL_SYSTEM
0x5: int_Ib();
+#else
+ // Really only the LSB matters, but the predecoder will sign
+ // extend it, and there's no easy way to specify only checking
+ // the first byte.
+ 0x5: decode IMMEDIATE {
+ 0xffffffffffffff80:
+ SyscallInst::int80('xc->syscall(Rax)', IsSyscall);
+ default: int_Ib();
+ }
+#endif
0x6: decode MODE_SUBMODE {
0x0: Inst::UD2();
default: into();
}
- 0x7: iret();
+ 0x7: decode MODE_SUBMODE {
+ 0x4: Inst::IRET_REAL();
+ 0x3: Inst::IRET_VIRT();
+ default: Inst::IRET_PROT();
+ }
}
}
0x1A: decode OPCODE_OP_BOTTOM3 {
@@ -549,8 +564,8 @@
0x1F: decode OPCODE_OP_BOTTOM3 {
0x0: CLC();
0x1: STC();
- 0x2: WarnUnimpl::cli();
- 0x3: WarnUnimpl::sti();
+ 0x2: CLI();
+ 0x3: STI();
0x4: CLD();
0x5: STD();
//0x6: group4();
diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
index 8135a1fdb..1ee62142a 100644
--- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
@@ -93,8 +93,8 @@
0x00: decode MODRM_REG {
0x0: sldt_Mw_or_Rv();
0x1: str_Mw_or_Rv();
- 0x2: lldt_Mw_or_Rv();
- 0x3: ltr_Mw_or_Rv();
+ 0x2: Inst::LLDT(Ew);
+ 0x3: Inst::LTR(Ew);
0x4: verr_Mw_or_Rv();
0x5: verw_Mw_or_Rv();
//0x6: jmpe_Ev(); // IA-64
@@ -128,7 +128,7 @@
0x4: smsw_Rv();
0x6: lmsw_Rv();
0x7: decode MODRM_RM {
- 0x0: swapgs();
+ 0x0: Inst::SWAPGS();
0x1: rdtscp();
default: Inst::UD2();
}
@@ -163,17 +163,117 @@
}
0x02: lar_Gv_Ew();
0x03: lsl_Gv_Ew();
- //sandpile.org doesn't seem to know what this is... ?
- 0x04: loadall_or_reset_or_hang();
+ // sandpile.org doesn't seem to know what this is...? We'll
+ // use it for pseudo instructions. We've got 16 bits of space
+ // to play with so there can be quite a few pseudo
+ // instructions.
+ //0x04: loadall_or_reset_or_hang();
+ 0x4: decode IMMEDIATE {
+ format BasicOperate {
#if FULL_SYSTEM
- 0x05: syscall();
+ 0x00: m5arm({{
+ PseudoInst::arm(xc->tcBase());
+ }}, IsNonSpeculative);
+ 0x01: m5quiesce({{
+ PseudoInst::quiesce(xc->tcBase());
+ }}, IsNonSpeculative);
+ 0x02: m5quiesceNs({{
+ PseudoInst::quiesceNs(xc->tcBase(), Rdi);
+ }}, IsNonSpeculative);
+ 0x03: m5quiesceCycle({{
+ PseudoInst::quiesceCycles(xc->tcBase(), Rdi);
+ }}, IsNonSpeculative);
+ 0x04: m5quiesceTime({{
+ Rax = PseudoInst::quiesceTime(xc->tcBase());
+ }}, IsNonSpeculative);
+#endif
+ 0x07: m5rpns({{
+ Rax = PseudoInst::rpns(xc->tcBase());
+ }}, IsNonSpeculative);
+ 0x21: m5exit({{
+ PseudoInst::m5exit(xc->tcBase(), Rdi);
+ }}, IsNonSpeculative);
+#if FULL_SYSTEM
+ 0x30: m5initparam({{
+ Rax = xc->tcBase()->getCpuPtr()->
+ system->init_param;
+ }}, IsNonSpeculative);
+ 0x31: m5loadsymbol({{
+ PseudoInst::loadsymbol(xc->tcBase());
+ }}, IsNonSpeculative);
+#endif
+ 0x40: m5resetstats({{
+ PseudoInst::resetstats(xc->tcBase(), Rdi, Rsi);
+ }}, IsNonSpeculative);
+ 0x41: m5dumpstats({{
+ PseudoInst::dumpstats(xc->tcBase(), Rdi, Rsi);
+ }}, IsNonSpeculative);
+ 0x42: m5dumpresetstats({{
+ PseudoInst::dumpresetstats(xc->tcBase(), Rdi, Rsi);
+ }}, IsNonSpeculative);
+ 0x43: m5checkpoint({{
+ PseudoInst::m5checkpoint(xc->tcBase(), Rdi, Rsi);
+ }}, IsNonSpeculative);
+#if FULL_SYSTEM
+ 0x50: m5readfile({{
+ Rax = PseudoInst::readfile(
+ xc->tcBase(), Rdi, Rsi, Rdx);
+ }}, IsNonSpeculative);
+#endif
+ 0x51: m5debugbreak({{
+ PseudoInst::debugbreak(xc->tcBase());
+ }}, IsNonSpeculative);
+ 0x52: m5switchcpu({{
+ PseudoInst::switchcpu(xc->tcBase());
+ }}, IsNonSpeculative);
+#if FULL_SYSTEM
+ 0x53: m5addsymbol({{
+ PseudoInst::addsymbol(xc->tcBase(), Rdi, Rsi);
+ }}, IsNonSpeculative);
+#endif
+ 0x54: m5panic({{
+ panic("M5 panic instruction called at pc=%#x.\n",
+ xc->readPC());
+ }}, IsNonSpeculative);
+ 0x55: m5reserved1({{
+ warn("M5 reserved opcode 1 ignored.\n");
+ }}, IsNonSpeculative);
+ 0x56: m5reserved2({{
+ warn("M5 reserved opcode 2 ignored.\n");
+ }}, IsNonSpeculative);
+ 0x57: m5reserved3({{
+ warn("M5 reserved opcode 3 ignored.\n");
+ }}, IsNonSpeculative);
+ 0x58: m5reserved4({{
+ warn("M5 reserved opcode 4 ignored.\n");
+ }}, IsNonSpeculative);
+ 0x59: m5reserved5({{
+ warn("M5 reserved opcode 5 ignored.\n");
+ }}, IsNonSpeculative);
+ default: Inst::UD2();
+ }
+ }
+#if FULL_SYSTEM
+ 0x05: decode MODE_MODE {
+ 0x0: decode MODE_SUBMODE {
+ 0x0: Inst::SYSCALL_64();
+ 0x1: Inst::SYSCALL_COMPAT();
+ }
+ 0x1: Inst::SYSCALL_LEGACY();
+ }
#else
- 0x05: SyscallInst::syscall('xc->syscall(rax)', IsSyscall);
+ 0x05: SyscallInst::syscall('xc->syscall(Rax)', IsSyscall);
#endif
- 0x06: clts();
- //sandpile.org says (AMD) after sysret, so I might want to check
- //if that means amd64 or AMD machines
- 0x07: loadall_or_sysret();
+ 0x06: Inst::CLTS();
+ 0x07: decode MODE_SUBMODE {
+ 0x0: decode OPSIZE {
+ // Return to 64 bit mode.
+ 0x8: Inst::SYSRET_TO_64();
+ // Return to compatibility mode.
+ default: Inst::SYSRET_TO_COMPAT();
+ }
+ default: Inst::SYSRET_NON_64();
+ }
}
0x01: decode OPCODE_OP_BOTTOM3 {
0x0: invd();
@@ -181,9 +281,9 @@
0x2: Inst::UD2();
0x3: Inst::UD2();
0x4: Inst::UD2();
- 0x5: threednow();
- 0x6: threednow();
- 0x7: threednow();
+ 0x5: Inst::PREFETCH(Mb);
+ 0x6: FailUnimpl::femms();
+ 0x7: FailUnimpl::threednow();
}
0x02: decode LEGACY_DECODEVAL {
// no prefix
@@ -235,7 +335,7 @@
//group17();
0x0: decode MODRM_REG {
0x0: prefetch_nta();
- 0x1: prefetch_t0();
+ 0x1: Inst::PREFETCH_T0(Mb);
0x2: prefetch_t1();
0x3: prefetch_t2();
default: Inst::HINT_NOP();
@@ -252,9 +352,9 @@
// no prefix
0x0: decode OPCODE_OP_BOTTOM3 {
0x0: Inst::MOV(Rd,Cd);
- 0x1: mov_Rd_Dd();
+ 0x1: Inst::MOV(Rd,Dd);
0x2: Inst::MOV(Cd,Rd);
- 0x3: mov_Dd_Rd();
+ 0x3: Inst::MOV(Dd,Rd);
0x4: mov_Rd_Td();
0x6: mov_Td_Rd();
default: Inst::UD2();
@@ -317,10 +417,14 @@
}
0x06: decode OPCODE_OP_BOTTOM3 {
0x0: Inst::WRMSR();
- 0x1: rdtsc();
+ 0x1: Inst::RDTSC();
0x2: Inst::RDMSR();
0x3: rdpmc();
+#if FULL_SYSTEM
0x4: sysenter();
+#else
+ 0x4: SyscallInst::sysenter('xc->syscall(Rax)', IsSyscall);
+#endif
0x5: sysexit();
0x6: Inst::UD2();
0x7: getsec();
@@ -707,7 +811,14 @@
0x14: decode OPCODE_OP_BOTTOM3 {
0x0: push_fs();
0x1: pop_fs();
- 0x2: Inst::CPUID(rAd);
+ 0x2: CPUIDInst::CPUID({{
+ CpuidResult result;
+ success = doCpuid(xc->tcBase(), Rax, result);
+ Rax = result.rax;
+ Rbx = result.rbx;
+ Rcx = result.rcx;
+ Rdx = result.rdx;
+ }});
0x3: Inst::BT(Ev,Gv);
0x4: shld_Ev_Gv_Ib();
0x5: shld_Ev_Gv_rCl();
@@ -719,20 +830,28 @@
0x1: pop_gs();
0x2: rsm_smm();
0x3: Inst::BTS(Ev,Gv);
- 0x4: shrd_Ev_Gv_Ib();
+ 0x4: Inst::SHRD(Ev,Gv,Ib);
0x5: shrd_Ev_Gv_rCl();
//0x6: group16();
- 0x6: decode MODRM_MOD {
- 0x3: decode MODRM_REG {
- 0x5: lfence();
- 0x6: mfence();
- 0x7: sfence();
+ 0x6: decode MODRM_REG {
+ 0x0: fxsave();
+ 0x1: fxrstor();
+ 0x2: ldmxcsr();
+ 0x3: stmxcsr();
+ 0x4: Inst::UD2();
+ 0x5: decode MODRM_MOD {
+ 0x3: BasicOperate::LFENCE(
+ {{/*Nothing*/}}, IsReadBarrier);
default: Inst::UD2();
}
- default: decode MODRM_REG {
- 0x0: fxsave();
- 0x1: fxrstor();
- 0x7: clflush();
+ 0x6: decode MODRM_MOD {
+ 0x3: BasicOperate::MFENCE(
+ {{/*Nothing*/}}, IsMemBarrier);
+ default: Inst::UD2();
+ }
+ 0x7: decode MODRM_MOD {
+ 0x3: BasicOperate::SFENCE(
+ {{/*Nothing*/}}, IsWriteBarrier);
default: Inst::UD2();
}
}
@@ -775,8 +894,8 @@
0x7: Inst::MOVSX_W(Gv,Ev);
}
0x18: decode OPCODE_OP_BOTTOM3 {
- 0x0: xadd_Eb_Gb();
- 0x1: xadd_Ev_Gv();
+ 0x0: Inst::XADD(Eb,Gb);
+ 0x1: Inst::XADD(Ev,Gv);
//0x7: group9();
0x7: decode MODRM_REG {
0x1: cmpxchg_Mq();
@@ -820,7 +939,11 @@
default: Inst::UD2();
}
}
- 0x19: bswap_B();
+ 0x19: decode OPSIZE {
+ 4: Inst::BSWAP_D(Bd);
+ 8: Inst::BSWAP_Q(Bq);
+ default: Inst::UD2();
+ }
0x1A: decode LEGACY_DECODEVAL {
// no prefix
0x0: decode OPCODE_OP_BOTTOM3 {
diff --git a/src/arch/x86/isa/formats/basic.isa b/src/arch/x86/isa/formats/basic.isa
index 7aea7085f..b96bae238 100644
--- a/src/arch/x86/isa/formats/basic.isa
+++ b/src/arch/x86/isa/formats/basic.isa
@@ -147,3 +147,11 @@ def template BasicDecode {{
def template BasicDecodeWithMnemonic {{
return new %(class_name)s("%(mnemonic)s", machInst);
}};
+
+def format BasicOperate(code, *flags) {{
+ iop = InstObjParams(name, Name, 'X86ISA::X86StaticInst', code, flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
diff --git a/src/arch/x86/isa/formats/cpuid.isa b/src/arch/x86/isa/formats/cpuid.isa
new file mode 100644
index 000000000..204270556
--- /dev/null
+++ b/src/arch/x86/isa/formats/cpuid.isa
@@ -0,0 +1,110 @@
+// Copyright (c) 2008 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer. Redistributions
+// in binary form must reproduce the above copyright notice, this list of
+// conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution. Neither the name of
+// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Gabe Black
+
+output header {{
+ class CPUIDInst : public X86ISA::X86StaticInst
+ {
+ public:
+ static const RegIndex foldOBit = 0;
+ /// Constructor
+ CPUIDInst(const char *_mnemonic, ExtMachInst _machInst,
+ OpClass __opClass) :
+ X86ISA::X86StaticInst(_mnemonic, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ std::string CPUIDInst::generateDisassembly(Addr PC,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+
+ printMnemonic(response, mnemonic);
+ ccprintf(response, " ");
+ printReg(response, _srcRegIdx[0], machInst.opSize);
+ return response.str();
+ }
+}};
+
+def template CPUIDExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ // If the CPUID instruction used a valid function number, this will
+ // be set to true. Otherwise, the instruction does nothing.
+ bool success;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
+ if (success) {
+ %(op_wb)s;
+ }
+ return NoFault;
+ }
+}};
+
+def format CPUIDInst(code, *opt_flags) {{
+ iop = InstObjParams(name, Name, 'CPUIDInst', code, opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = CPUIDExecute.subst(iop)
+}};
+
diff --git a/src/arch/x86/isa/formats/formats.isa b/src/arch/x86/isa/formats/formats.isa
index 6906413c0..81179ab45 100644
--- a/src/arch/x86/isa/formats/formats.isa
+++ b/src/arch/x86/isa/formats/formats.isa
@@ -85,6 +85,9 @@
//Templates from this format are used later
##include "basic.isa"
+//Include a format to generate a CPUID instruction.
+##include "cpuid.isa"
+
//Include the "unknown" format
##include "unknown.isa"
diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa
index 6724ea9b0..8626f117a 100644
--- a/src/arch/x86/isa/includes.isa
+++ b/src/arch/x86/isa/includes.isa
@@ -26,7 +26,7 @@
//
// Authors: Gabe Black
-// Copyright (c) 2007 The Hewlett-Packard Development Company
+// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@@ -97,6 +97,7 @@ output header {{
#include <iostream>
#include "arch/x86/emulenv.hh"
+#include "arch/x86/insts/macroop.hh"
#include "arch/x86/insts/microfpop.hh"
#include "arch/x86/insts/microldstop.hh"
#include "arch/x86/insts/microregop.hh"
@@ -113,10 +114,13 @@ output header {{
output decoder {{
#include "arch/x86/faults.hh"
#include "arch/x86/floatregs.hh"
+#include "arch/x86/microcode_rom.hh"
#include "arch/x86/miscregs.hh"
#include "arch/x86/segmentregs.hh"
+#include "arch/x86/tlb.hh"
#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
+#include "base/misc.hh"
#include "cpu/thread_context.hh" // for Jump::branchTarget()
#include "mem/packet.hh"
@@ -144,6 +148,7 @@ output exec {{
#include <limits>
#include <cmath>
+#include "arch/x86/cpuid.hh"
#include "arch/x86/miscregs.hh"
#include "arch/x86/tlb.hh"
#include "base/bigint.hh"
@@ -152,6 +157,8 @@ output exec {{
#include "sim/sim_exit.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
+#include "mem/request.hh"
+#include "sim/pseudo_inst.hh"
using namespace X86ISA;
using namespace std;
diff --git a/src/arch/x86/isa/insts/__init__.py b/src/arch/x86/isa/insts/__init__.py
index 0ef617a87..d7a8bde19 100644
--- a/src/arch/x86/isa/insts/__init__.py
+++ b/src/arch/x86/isa/insts/__init__.py
@@ -53,7 +53,8 @@
#
# Authors: Gabe Black
-categories = ["general_purpose",
+categories = ["romutil",
+ "general_purpose",
"simd128",
"simd64",
"system",
diff --git a/src/arch/x86/isa/insts/general_purpose/__init__.py b/src/arch/x86/isa/insts/general_purpose/__init__.py
index 4f77cb233..23f955f08 100644
--- a/src/arch/x86/isa/insts/general_purpose/__init__.py
+++ b/src/arch/x86/isa/insts/general_purpose/__init__.py
@@ -65,7 +65,6 @@ categories = ["arithmetic",
"load_segment_registers",
"logical",
"no_operation",
- "processor_information",
"rotate_and_shift",
"semaphores",
"string",
diff --git a/src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py b/src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py
index a9b53acac..19d1c7789 100644
--- a/src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py
+++ b/src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py
@@ -246,7 +246,7 @@ def macroop DIV_B_R
divLoopTop:
div2 t1, rax, t1, dataSize=1
div2 t1, rax, t1, flags=(EZF,), dataSize=1
- bri t0, label("divLoopTop"), flags=(nCEZF,)
+ br label("divLoopTop"), flags=(nCEZF,)
#Unload the answer
divq rax, dataSize=1
@@ -269,7 +269,7 @@ def macroop DIV_B_M
divLoopTop:
div2 t1, rax, t1, dataSize=1
div2 t1, rax, t1, flags=(EZF,), dataSize=1
- bri t0, label("divLoopTop"), flags=(nCEZF,)
+ br label("divLoopTop"), flags=(nCEZF,)
#Unload the answer
divq rax, dataSize=1
@@ -293,7 +293,7 @@ def macroop DIV_B_P
divLoopTop:
div2 t1, rax, t1, dataSize=1
div2 t1, rax, t1, flags=(EZF,), dataSize=1
- bri t0, label("divLoopTop"), flags=(nCEZF,)
+ br label("divLoopTop"), flags=(nCEZF,)
#Unload the answer
divq rax, dataSize=1
@@ -321,7 +321,7 @@ divLoopTop:
div2 t1, rax, t1
div2 t1, rax, t1
div2 t1, rax, t1, flags=(EZF,)
- bri t0, label("divLoopTop"), flags=(nCEZF,)
+ br label("divLoopTop"), flags=(nCEZF,)
#Unload the answer
divq rax
@@ -347,7 +347,7 @@ divLoopTop:
div2 t1, rax, t1
div2 t1, rax, t1
div2 t1, rax, t1, flags=(EZF,)
- bri t0, label("divLoopTop"), flags=(nCEZF,)
+ br label("divLoopTop"), flags=(nCEZF,)
#Unload the answer
divq rax
@@ -374,7 +374,7 @@ divLoopTop:
div2 t1, rax, t1
div2 t1, rax, t1
div2 t1, rax, t1, flags=(EZF,)
- bri t0, label("divLoopTop"), flags=(nCEZF,)
+ br label("divLoopTop"), flags=(nCEZF,)
#Unload the answer
divq rax
@@ -422,7 +422,7 @@ def macroop IDIV_B_R
divLoopTop:
div2 t4, t1, t4, dataSize=1
div2 t4, t1, t4, flags=(EZF,), dataSize=1
- bri t0, label("divLoopTop"), flags=(nCEZF,)
+ br label("divLoopTop"), flags=(nCEZF,)
#Unload the answer
divq t5, dataSize=1
@@ -495,7 +495,7 @@ def macroop IDIV_B_M
divLoopTop:
div2 t4, t1, t4, dataSize=1
div2 t4, t1, t4, flags=(EZF,), dataSize=1
- bri t0, label("divLoopTop"), flags=(nCEZF,)
+ br label("divLoopTop"), flags=(nCEZF,)
#Unload the answer
divq t5, dataSize=1
@@ -569,7 +569,7 @@ def macroop IDIV_B_P
divLoopTop:
div2 t4, t1, t4, dataSize=1
div2 t4, t1, t4, flags=(EZF,), dataSize=1
- bri t0, label("divLoopTop"), flags=(nCEZF,)
+ br label("divLoopTop"), flags=(nCEZF,)
#Unload the answer
divq t5, dataSize=1
@@ -646,7 +646,7 @@ divLoopTop:
div2 t4, t1, t4
div2 t4, t1, t4
div2 t4, t1, t4, flags=(EZF,)
- bri t0, label("divLoopTop"), flags=(nCEZF,)
+ br label("divLoopTop"), flags=(nCEZF,)
#Unload the answer
divq t5
@@ -721,7 +721,7 @@ divLoopTop:
div2 t4, t1, t4
div2 t4, t1, t4
div2 t4, t1, t4, flags=(EZF,)
- bri t0, label("divLoopTop"), flags=(nCEZF,)
+ br label("divLoopTop"), flags=(nCEZF,)
#Unload the answer
divq t5
@@ -797,7 +797,7 @@ divLoopTop:
div2 t4, t1, t4
div2 t4, t1, t4
div2 t4, t1, t4, flags=(EZF,)
- bri t0, label("divLoopTop"), flags=(nCEZF,)
+ br label("divLoopTop"), flags=(nCEZF,)
#Unload the answer
divq t5
diff --git a/src/arch/x86/isa/insts/general_purpose/cache_and_memory_management.py b/src/arch/x86/isa/insts/general_purpose/cache_and_memory_management.py
index b5fc43fcd..dbd2d8b84 100644
--- a/src/arch/x86/isa/insts/general_purpose/cache_and_memory_management.py
+++ b/src/arch/x86/isa/insts/general_purpose/cache_and_memory_management.py
@@ -53,20 +53,42 @@
#
# Authors: Gabe Black
-microcode = ""
+microcode = '''
+def macroop PREFETCH_M
+{
+ ld t0, seg, sib, disp, dataSize=1, prefetch=True
+};
+
+def macroop PREFETCH_P
+{
+ rdip t7
+ ld t0, seg, riprel, disp, dataSize=1, prefetch=True
+};
+
+def macroop PREFETCH_T0_M
+{
+ ld t0, seg, sib, disp, dataSize=1, prefetch=True
+};
+
+def macroop PREFETCH_T0_P
+{
+ rdip t7
+ ld t0, seg, riprel, disp, dataSize=1, prefetch=True
+};
+
+'''
+
#let {{
# class LFENCE(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class SFENCE(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class MFENCE(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class PREFETCHlevel(Inst):
-# "GenFault ${new UnimpInstFault}"
-# class PREFETCH(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class PREFETCHW(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class CLFLUSH(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
#}};
diff --git a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py
index 71059e80d..22364e038 100644
--- a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py
+++ b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py
@@ -82,11 +82,11 @@
# Authors: Gabe Black
microcode = '''
-def macroop BSF_R_R {
+def macroop BSR_R_R {
# Determine if the input was zero, and also move it to a temp reg.
movi t1, t1, t0, dataSize=8
and t1, regm, regm, flags=(ZF,)
- bri t0, label("end"), flags=(CZF,)
+ br label("end"), flags=(CZF,)
# Zero out the result register
movi reg, reg, 0x0
@@ -125,20 +125,19 @@ def macroop BSF_R_R {
srli t3, t1, 1, dataSize=8, flags=(EZF,)
ori t4, reg, 0x1
mov reg, reg, t4, flags=(nCEZF,)
- mov t1, t1, t3, flags=(nCEZF,)
end:
fault "NoFault"
};
-def macroop BSF_R_M {
+def macroop BSR_R_M {
movi t1, t1, t0, dataSize=8
ld t1, seg, sib, disp
# Determine if the input was zero, and also move it to a temp reg.
and t1, t1, t1, flags=(ZF,)
- bri t0, label("end"), flags=(CZF,)
+ br label("end"), flags=(CZF,)
# Zero out the result register
movi reg, reg, 0x0
@@ -177,13 +176,12 @@ def macroop BSF_R_M {
srli t3, t1, 1, dataSize=8, flags=(EZF,)
ori t4, reg, 0x1
mov reg, reg, t4, flags=(nCEZF,)
- mov t1, t1, t3, flags=(nCEZF,)
end:
fault "NoFault"
};
-def macroop BSF_R_P {
+def macroop BSR_R_P {
rdip t7
movi t1, t1, t0, dataSize=8
@@ -191,7 +189,7 @@ def macroop BSF_R_P {
# Determine if the input was zero, and also move it to a temp reg.
and t1, t1, t1, flags=(ZF,)
- bri t0, label("end"), flags=(CZF,)
+ br label("end"), flags=(CZF,)
# Zero out the result register
movi reg, reg, 0x0
@@ -230,17 +228,16 @@ def macroop BSF_R_P {
srli t3, t1, 1, dataSize=8, flags=(EZF,)
ori t4, reg, 0x1
mov reg, reg, t4, flags=(nCEZF,)
- mov t1, t1, t3, flags=(nCEZF,)
end:
fault "NoFault"
};
-def macroop BSR_R_R {
+def macroop BSF_R_R {
# Determine if the input was zero, and also move it to a temp reg.
mov t1, t1, t0, dataSize=8
and t1, regm, regm, flags=(ZF,)
- bri t0, label("end"), flags=(CZF,)
+ br label("end"), flags=(CZF,)
# Zero out the result register
movi reg, reg, 0
@@ -248,48 +245,54 @@ def macroop BSR_R_R {
subi t2, t1, 1
xor t1, t2, t1
+
# Bit 6
- srli t3, t1, 32, dataSize=8
- andi t3, t3, 32
- or reg, reg, t3
+ srli t3, t1, 32, dataSize=8, flags=(EZF,)
+ ori t4, reg, 32
+ mov reg, reg, t4, flags=(nCEZF,)
+ mov t1, t1, t3, flags=(nCEZF,)
# Bit 5
- srli t3, t1, 16, dataSize=8
- andi t3, t3, 16
- or reg, reg, t3
+ srli t3, t1, 16, dataSize=8, flags=(EZF,)
+ ori t4, reg, 16
+ mov reg, reg, t4, flags=(nCEZF,)
+ mov t1, t1, t3, flags=(nCEZF,)
# Bit 4
- srli t3, t1, 8, dataSize=8
- andi t3, t3, 8
- or reg, reg, t3
+ srli t3, t1, 8, dataSize=8, flags=(EZF,)
+ ori t4, reg, 8
+ mov reg, reg, t4, flags=(nCEZF,)
+ mov t1, t1, t3, flags=(nCEZF,)
# Bit 3
- srli t3, t1, 4, dataSize=8
- andi t3, t3, 4
- or reg, reg, t3
+ srli t3, t1, 4, dataSize=8, flags=(EZF,)
+ ori t4, reg, 4
+ mov reg, reg, t4, flags=(nCEZF,)
+ mov t1, t1, t3, flags=(nCEZF,)
# Bit 2
- srli t3, t1, 2, dataSize=8
- andi t3, t3, 2
- or reg, reg, t3
+ srli t3, t1, 2, dataSize=8, flags=(EZF,)
+ ori t4, reg, 2
+ mov reg, reg, t4, flags=(nCEZF,)
+ mov t1, t1, t3, flags=(nCEZF,)
# Bit 1
- srli t3, t1, 1, dataSize=8
- andi t3, t3, 1
- or reg, reg, t3
+ srli t3, t1, 1, dataSize=8, flags=(EZF,)
+ ori t4, reg, 1
+ mov reg, reg, t4, flags=(nCEZF,)
end:
fault "NoFault"
};
-def macroop BSR_R_M {
+def macroop BSF_R_M {
mov t1, t1, t0, dataSize=8
ld t1, seg, sib, disp
# Determine if the input was zero, and also move it to a temp reg.
and t1, t1, t1, flags=(ZF,)
- bri t0, label("end"), flags=(CZF,)
+ br label("end"), flags=(CZF,)
# Zero out the result register
mov reg, reg, t0
@@ -298,40 +301,46 @@ def macroop BSR_R_M {
xor t1, t2, t1
# Bit 6
- srli t3, t1, 32, dataSize=8
- andi t3, t3, 32
- or reg, reg, t3
+ srli t3, t1, 32, dataSize=8, flags=(EZF,)
+ ori t4, reg, 32
+ mov reg, reg, t4, flags=(nCEZF,)
+ mov t1, t1, t3, flags=(nCEZF,)
# Bit 5
- srli t3, t1, 16, dataSize=8
- andi t3, t3, 16
- or reg, reg, t3
+ srli t3, t1, 16, dataSize=8, flags=(EZF,)
+ ori t4, reg, 16
+ mov reg, reg, t4, flags=(nCEZF,)
+ mov t1, t1, t3, flags=(nCEZF,)
# Bit 4
- srli t3, t1, 8, dataSize=8
- andi t3, t3, 8
- or reg, reg, t3
+ srli t3, t1, 8, dataSize=8, flags=(EZF,)
+ ori t4, reg, 8
+ mov reg, reg, t4, flags=(nCEZF,)
+ mov t1, t1, t3, flags=(nCEZF,)
# Bit 3
- srli t3, t1, 4, dataSize=8
- andi t3, t3, 4
- or reg, reg, t3
+ srli t3, t1, 4, dataSize=8, flags=(EZF,)
+ ori t4, reg, 4
+ mov reg, reg, t4, flags=(nCEZF,)
+ mov t1, t1, t3, flags=(nCEZF,)
# Bit 2
- srli t3, t1, 2, dataSize=8
- andi t3, t3, 2
- or reg, reg, t3
+ srli t3, t1, 2, dataSize=8, flags=(EZF,)
+ ori t4, reg, 2
+ mov reg, reg, t4, flags=(nCEZF,)
+ mov t1, t1, t3, flags=(nCEZF,)
# Bit 1
- srli t3, t1, 1, dataSize=8
- andi t3, t3, 1
- or reg, reg, t3
+ srli t3, t1, 1, dataSize=8, flags=(EZF,)
+ ori t4, reg, 1
+ mov reg, reg, t4, flags=(nCEZF,)
+ mov t1, t1, t3, flags=(nCEZF,)
end:
fault "NoFault"
};
-def macroop BSR_R_P {
+def macroop BSF_R_P {
rdip t7
mov t1, t1, t0, dataSize=8
@@ -339,7 +348,7 @@ def macroop BSR_R_P {
# Determine if the input was zero, and also move it to a temp reg.
and t1, t1, t1, flags=(ZF,)
- bri t0, label("end"), flags=(CZF,)
+ br label("end"), flags=(CZF,)
# Zero out the result register
mov reg, reg, t0
@@ -348,34 +357,40 @@ def macroop BSR_R_P {
xor t1, t2, t1
# Bit 6
- srli t3, t1, 32, dataSize=8
- andi t3, t3, 32
- or reg, reg, t3
+ srli t3, t1, 32, dataSize=8, flags=(EZF,)
+ ori t4, reg, 32
+ mov reg, reg, t4, flags=(nCEZF,)
+ mov t1, t1, t3, flags=(nCEZF,)
# Bit 5
- srli t3, t1, 16, dataSize=8
- andi t3, t3, 16
- or reg, reg, t3
+ srli t3, t1, 16, dataSize=8, flags=(EZF,)
+ ori t4, reg, 16
+ mov reg, reg, t4, flags=(nCEZF,)
+ mov t1, t1, t3, flags=(nCEZF,)
# Bit 4
- srli t3, t1, 8, dataSize=8
- andi t3, t3, 8
- or reg, reg, t3
+ srli t3, t1, 8, dataSize=8, flags=(EZF,)
+ ori t4, reg, 8
+ mov reg, reg, t4, flags=(nCEZF,)
+ mov t1, t1, t3, flags=(nCEZF,)
# Bit 3
- srli t3, t1, 4, dataSize=8
- andi t3, t3, 4
- or reg, reg, t3
+ srli t3, t1, 4, dataSize=8, flags=(EZF,)
+ ori t4, reg, 4
+ mov reg, reg, t4, flags=(nCEZF,)
+ mov t1, t1, t3, flags=(nCEZF,)
# Bit 2
- srli t3, t1, 2, dataSize=8
- andi t3, t3, 2
- or reg, reg, t3
+ srli t3, t1, 2, dataSize=8, flags=(EZF,)
+ ori t4, reg, 2
+ mov reg, reg, t4, flags=(nCEZF,)
+ mov t1, t1, t3, flags=(nCEZF,)
# Bit 1
- srli t3, t1, 1, dataSize=8
- andi t3, t3, 1
- or reg, reg, t3
+ srli t3, t1, 1, dataSize=8, flags=(EZF,)
+ ori t4, reg, 1
+ mov reg, reg, t4, flags=(nCEZF,)
+ mov t1, t1, t3, flags=(nCEZF,)
end:
fault "NoFault"
diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py
index 45a7822fb..7abafe253 100644
--- a/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py
+++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py
@@ -103,5 +103,5 @@ def macroop CALL_NEAR_P
'''
#let {{
# class CALL(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
#}};
diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py
index 7039b4b5c..8203f7c2c 100644
--- a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py
+++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2007 The Hewlett-Packard Development Company
+# Copyright (c) 2007-2008 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
@@ -53,16 +53,194 @@
#
# Authors: Gabe Black
-microcode = ""
+microcode = '''
+def macroop IRET_REAL {
+ panic "Real mode iret isn't implemented!"
+};
+
+def macroop IRET_PROT {
+ .adjust_env oszIn64Override
+
+ # Check for a nested task. This isn't supported at the moment.
+ rflag t1, NT
+ panic "Task switching with iret is unimplemented!", flags=(nCEZF,)
+
+ #t1 = temp_RIP
+ #t2 = temp_CS
+ #t3 = temp_RFLAGS
+ #t4 = handy m5 register
+
+ # Pop temp_RIP, temp_CS, and temp_RFLAGS
+ ld t1, ss, [1, t0, rsp], "0 * env.stackSize", dataSize=ssz
+ ld t2, ss, [1, t0, rsp], "1 * env.stackSize", dataSize=ssz
+ ld t3, ss, [1, t0, rsp], "2 * env.stackSize", dataSize=ssz
+
+ # Read the handy m5 register for use later
+ rdm5reg t4
+
+
+###
+### Handle if we're returning to virtual 8086 mode.
+###
+
+ #IF ((temp_RFLAGS.VM=1) && (CPL=0) && (LEGACY_MODE))
+ # IRET_FROM_PROTECTED_TO_VIRTUAL
+
+ #temp_RFLAGS.VM != 1
+ rcri t0, t3, 18, flags=(ECF,)
+ br label("protToVirtFallThrough"), flags=(nCECF,)
+
+ #CPL=0
+ andi t0, t4, 0x30, flags=(EZF,)
+ br label("protToVirtFallThrough"), flags=(nCEZF,)
+
+ #(LEGACY_MODE)
+ rcri t0, t4, 1, flags=(ECF,)
+ br label("protToVirtFallThrough"), flags=(nCECF,)
+
+ panic "iret to virtual mode not supported"
+
+protToVirtFallThrough:
+
+
+
+ #temp_CPL = temp_CS.rpl
+ andi t5, t2, 0x3
+
+
+###
+### Read in the info for the new CS segment.
+###
+
+ #CS = READ_DESCRIPTOR (temp_CS, iret_chk)
+ andi t0, t2, 0xFC, flags=(EZF,), dataSize=2
+ br label("processCSDescriptor"), flags=(CEZF,)
+ andi t6, t2, 0xF8, dataSize=8
+ andi t0, t2, 0x4, flags=(EZF,), dataSize=2
+ br label("globalCSDescriptor"), flags=(CEZF,)
+ ld t8, tsl, [1, t0, t6], dataSize=8
+ br label("processCSDescriptor")
+globalCSDescriptor:
+ ld t8, tsg, [1, t0, t6], dataSize=8
+processCSDescriptor:
+ chks t2, t6, dataSize=8
+
+
+###
+### Get the new stack pointer and stack segment off the old stack if necessary,
+### and piggyback on the logic to check the new RIP value.
+###
+ #IF ((64BIT_MODE) || (temp_CPL!=CPL))
+ #{
+
+ #(64BIT_MODE)
+ andi t0, t4, 0xE, flags=(EZF,)
+ # Since we just found out we're in 64 bit mode, take advantage and
+ # do the appropriate RIP checks.
+ br label("doPopStackStuffAndCheckRIP"), flags=(CEZF,)
+
+ # Here, we know we're -not- in 64 bit mode, so we should do the
+ # appropriate/other RIP checks.
+ # if temp_RIP > CS.limit throw #GP(0)
+ rdlimit t6, cs, dataSize=8
+ subi t0, t1, t6, flags=(ECF,)
+ fault "new GeneralProtection(0)", flags=(CECF,)
+
+ #(temp_CPL!=CPL)
+ srli t7, t4, 4
+ xor t7, t7, t5
+ andi t0, t7, 0x3, flags=(EZF,)
+ br label("doPopStackStuff"), flags=(nCEZF,)
+ # We can modify user visible state here because we're know
+ # we're done with things that can fault.
+ addi rsp, rsp, "3 * env.stackSize"
+ br label("fallThroughPopStackStuff")
+
+doPopStackStuffAndCheckRIP:
+ # Check if the RIP is canonical.
+ sra t7, t1, 47, flags=(EZF,), dataSize=ssz
+ # if t7 isn't 0 or -1, it wasn't canonical.
+ br label("doPopStackStuff"), flags=(CEZF,)
+ addi t0, t7, 1, flags=(EZF,), dataSize=ssz
+ fault "new GeneralProtection(0)", flags=(nCEZF,)
+
+doPopStackStuff:
+ # POP.v temp_RSP
+ ld t6, ss, [1, t0, rsp], "3 * env.dataSize", dataSize=ssz
+ # POP.v temp_SS
+ ld t9, ss, [1, t0, rsp], "4 * env.dataSize", dataSize=ssz
+ # SS = READ_DESCRIPTOR (temp_SS, ss_chk)
+ andi t0, t9, 0xFC, flags=(EZF,), dataSize=2
+ br label("processSSDescriptor"), flags=(CEZF,)
+ andi t7, t9, 0xF8, dataSize=8
+ andi t0, t9, 0x4, flags=(EZF,), dataSize=2
+ br label("globalSSDescriptor"), flags=(CEZF,)
+ ld t7, tsl, [1, t0, t7], dataSize=8
+ br label("processSSDescriptor")
+globalSSDescriptor:
+ ld t7, tsg, [1, t0, t7], dataSize=8
+processSSDescriptor:
+ chks t9, t7, dataSize=8
+
+ # This actually updates state which is wrong. It should wait until we know
+ # we're not going to fault. Unfortunately, that's hard to do.
+ wrdl ss, t7, t9
+ wrsel ss, t9
+
+###
+### From this point downwards, we can't fault. We can update user visible state.
+###
+ # RSP.s = temp_RSP
+ mov rsp, rsp, t6, dataSize=ssz
+
+ #}
+
+fallThroughPopStackStuff:
+
+ # Update CS
+ wrdl cs, t8, t2
+ wrsel cs, t2
+
+ #CPL = temp_CPL
+
+ #IF (changing CPL)
+ #{
+ srli t7, t4, 4
+ xor t7, t7, t5
+ andi t0, t7, 0x3, flags=(EZF,)
+ br label("skipSegmentSquashing"), flags=(CEZF,)
+
+ # The attribute register needs to keep track of more info before this will
+ # work the way it needs to.
+ # FOR (seg = ES, DS, FS, GS)
+ # IF ((seg.attr.dpl < cpl && ((seg.attr.type = 'data')
+ # || (seg.attr.type = 'non-conforming-code')))
+ # {
+ # seg = NULL
+ # }
+ #}
+
+skipSegmentSquashing:
+
+ # Ignore this for now.
+ #RFLAGS.v = temp_RFLAGS
+ wrflags t0, t3
+ # VIF,VIP,IOPL only changed if (old_CPL = 0)
+ # IF only changed if (old_CPL <= old_RFLAGS.IOPL)
+ # VM unchanged
+ # RF cleared
+
+ #RIP = temp_RIP
+ wrip t0, t1, dataSize=ssz
+};
+
+def macroop IRET_VIRT {
+ panic "Virtual mode iret isn't implemented!"
+};
+'''
#let {{
# class INT(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class INTO(Inst):
-# "GenFault ${new UnimpInstFault}"
-# class IRET(Inst):
-# "GenFault ${new UnimpInstFault}"
-# class IRETD(Inst):
-# "GenFault ${new UnimpInstFault}"
-# class IRETQ(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
#}};
diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py
index 0b2e81cbd..57ec9da26 100644
--- a/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py
+++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2007 The Hewlett-Packard Development Company
+# Copyright (c) 2007-2008 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
@@ -85,7 +85,7 @@ def macroop RET_FAR {
ld t1, ss, [1, t0, rsp]
# Get the return CS
- ld t2, ss, [1, t0, rsp], dsz
+ ld t2, ss, [1, t0, rsp], ssz
# Get the rpl
andi t3, t2, 0x3
@@ -96,14 +96,23 @@ def macroop RET_FAR {
# that doesn't happen yet.
# Do stuff if they're equal
- chks t4, t2, flags=(EZF,)
- fault "new GeneralProtection(0)", flags=(CEZF,)
- ld t3, flatseg, [1, t0, t4], addressSize=8, dataSize=8
- wrdl cs, t3, t2
+ andi t0, t2, 0xFC, flags=(EZF,), dataSize=2
+ br label("processDescriptor"), flags=(CEZF,)
+ andi t3, t2, 0xF8, dataSize=8
+ andi t0, t2, 0x4, flags=(EZF,), dataSize=2
+ br label("globalDescriptor"), flags=(CEZF,)
+ ld t3, tsl, [1, t0, t3], dataSize=8
+ br label("processDescriptor")
+globalDescriptor:
+ ld t3, tsg, [1, t0, t3], dataSize=8
+processDescriptor:
+ chks t2, t3, IretCheck, dataSize=8
# There should be validity checks on the RIP checks here, but I'll do
# that later.
+ wrdl cs, t3, t2
+ wrsel cs, t2
wrip t0, t1
- bri t0, label("end")
+ br label("end")
# Do other stuff if they're not.
end:
diff --git a/src/arch/x86/isa/insts/general_purpose/data_conversion/ascii_adjust.py b/src/arch/x86/isa/insts/general_purpose/data_conversion/ascii_adjust.py
index a1e322e56..2cbdd1ad8 100644
--- a/src/arch/x86/isa/insts/general_purpose/data_conversion/ascii_adjust.py
+++ b/src/arch/x86/isa/insts/general_purpose/data_conversion/ascii_adjust.py
@@ -56,11 +56,11 @@
microcode = ""
#let {{
# class AAA(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class AAD(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class AAM(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class AAS(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
#}};
diff --git a/src/arch/x86/isa/insts/general_purpose/data_conversion/bcd_adjust.py b/src/arch/x86/isa/insts/general_purpose/data_conversion/bcd_adjust.py
index 213724768..d220fdeb6 100644
--- a/src/arch/x86/isa/insts/general_purpose/data_conversion/bcd_adjust.py
+++ b/src/arch/x86/isa/insts/general_purpose/data_conversion/bcd_adjust.py
@@ -56,7 +56,7 @@
microcode = ""
#let {{
# class DAA(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class DAS(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
#}};
diff --git a/src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py b/src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py
index b98d09816..ac2343462 100644
--- a/src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py
+++ b/src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py
@@ -53,8 +53,26 @@
#
# Authors: Gabe Black
-microcode = ""
+microcode = '''
+def macroop BSWAP_D_R
+{
+ roli reg, reg, 8, dataSize=2
+ roli reg, reg, 16, dataSize=4
+ roli reg, reg, 8, dataSize=2
+};
+
+def macroop BSWAP_Q_R
+{
+ roli reg, reg, 8, dataSize=2
+ roli reg, reg, 16, dataSize=4
+ roli reg, reg, 8, dataSize=2
+ roli reg, reg, 32, dataSize=8
+ roli reg, reg, 8, dataSize=2
+ roli reg, reg, 16, dataSize=4
+ roli reg, reg, 8, dataSize=2
+};
+'''
#let {{
# class BSWAP(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
#}};
diff --git a/src/arch/x86/isa/insts/general_purpose/data_conversion/extract_sign_mask.py b/src/arch/x86/isa/insts/general_purpose/data_conversion/extract_sign_mask.py
index 1e0810594..01fa280fc 100644
--- a/src/arch/x86/isa/insts/general_purpose/data_conversion/extract_sign_mask.py
+++ b/src/arch/x86/isa/insts/general_purpose/data_conversion/extract_sign_mask.py
@@ -56,7 +56,7 @@
microcode = ""
#let {{
# class MOVMSKPS(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class MOVMSKPD(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
#}};
diff --git a/src/arch/x86/isa/insts/general_purpose/data_conversion/translate.py b/src/arch/x86/isa/insts/general_purpose/data_conversion/translate.py
index d6ae7885a..c334693e5 100644
--- a/src/arch/x86/isa/insts/general_purpose/data_conversion/translate.py
+++ b/src/arch/x86/isa/insts/general_purpose/data_conversion/translate.py
@@ -55,7 +55,7 @@
microcode = '''
def macroop XLAT {
- zexti t1, rax, 7
+ zexti t1, rax, 7, dataSize=8
# Here, t1 can be used directly. The value of al is supposed to be treated
# as unsigned. Since we zero extended it from 8 bits above and the address
# size has to be at least 16 bits, t1 will not be sign extended.
diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py
index 3b8608c48..60c046d04 100644
--- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py
+++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2007 The Hewlett-Packard Development Company
+# Copyright (c) 2007-2008 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
@@ -126,18 +126,19 @@ def macroop MOVSXD_R_P {
};
def macroop MOVSX_B_R_R {
- sexti reg, regm, 7
+ mov t1, t1, regm, dataSize=1
+ sexti reg, t1, 7
};
def macroop MOVSX_B_R_M {
- ld reg, seg, sib, disp, dataSize=1
- sexti reg, reg, 7
+ ld t1, seg, sib, disp, dataSize=1
+ sexti reg, t1, 7
};
def macroop MOVSX_B_R_P {
rdip t7
- ld reg, seg, riprel, disp, dataSize=1
- sexti reg, reg, 7
+ ld t1, seg, riprel, disp, dataSize=1
+ sexti reg, t1, 7
};
def macroop MOVSX_W_R_R {
@@ -160,7 +161,8 @@ def macroop MOVSX_W_R_P {
#
def macroop MOVZX_B_R_R {
- zexti reg, regm, 7
+ mov t1, t1, regm, dataSize=1
+ zexti reg, t1, 7
};
def macroop MOVZX_B_R_M {
@@ -190,13 +192,25 @@ def macroop MOVZX_W_R_P {
};
def macroop MOV_C_R {
+ .adjust_env maxOsz
wrcr reg, regm
};
def macroop MOV_R_C {
+ .adjust_env maxOsz
rdcr reg, regm
};
+def macroop MOV_D_R {
+ .adjust_env maxOsz
+ wrdr reg, regm
+};
+
+def macroop MOV_R_D {
+ .adjust_env maxOsz
+ rddr reg, regm
+};
+
def macroop MOV_R_S {
rdsel reg, regm
};
@@ -213,7 +227,7 @@ def macroop MOV_P_S {
};
def macroop MOV_REAL_S_R {
- zext t2, regm, 15
+ zexti t2, regm, 15, dataSize=8
slli t3, t2, 2, dataSize=8
wrsel reg, regm
wrbase reg, t3
@@ -221,87 +235,121 @@ def macroop MOV_REAL_S_R {
def macroop MOV_REAL_S_M {
ld t1, seg, sib, disp, dataSize=2
- zext t2, t1, 15
+ zexti t2, t1, 15, dataSize=8
slli t3, t2, 2, dataSize=8
wrsel reg, t1
wrbase reg, t3
};
def macroop MOV_REAL_S_P {
- rdip t7
- ld t1, seg, riprel, disp, dataSize=2
- zext t2, t1, 15
- slli t3, t2, 2, dataSize=8
- wrsel reg, t1
- wrbase reg, t3
+ panic "RIP relative addressing shouldn't happen in real mode"
};
def macroop MOV_S_R {
- chks t1, regm, flags=(EZF,), dataSize=8
- bri t0, label("end"), flags=(CEZF,)
- ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
- wrdl reg, t2, regm
-end:
+ andi t0, regm, 0xFC, flags=(EZF,), dataSize=2
+ br label("processDescriptor"), flags=(CEZF,)
+ andi t2, regm, 0xF8, dataSize=8
+ andi t0, regm, 0x4, flags=(EZF,), dataSize=2
+ br label("globalDescriptor"), flags=(CEZF,)
+ ld t3, tsl, [1, t0, t2], dataSize=8, addressSize=8
+ br label("processDescriptor")
+globalDescriptor:
+ ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8
+processDescriptor:
+ chks regm, t3, dataSize=8
+ wrdl reg, t3, regm
wrsel reg, regm
};
def macroop MOV_S_M {
ld t1, seg, sib, disp, dataSize=2
- chks t2, t1, flags=(EZF,), dataSize=8
- bri t0, label("end"), flags=(CEZF,)
- ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
- wrdl reg, t2, t1
-end:
+ andi t0, t1, 0xFC, flags=(EZF,), dataSize=2
+ br label("processDescriptor"), flags=(CEZF,)
+ andi t2, t1, 0xF8, dataSize=8
+ andi t0, t1, 0x4, flags=(EZF,), dataSize=2
+ br label("globalDescriptor"), flags=(CEZF,)
+ ld t3, tsl, [1, t0, t2], dataSize=8, addressSize=8
+ br label("processDescriptor")
+globalDescriptor:
+ ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8
+processDescriptor:
+ chks t1, t3, dataSize=8
+ wrdl reg, t3, t1
wrsel reg, t1
};
def macroop MOV_S_P {
rdip t7
ld t1, seg, riprel, disp, dataSize=2
- chks t2, t1, flags=(EZF,), dataSize=8
- bri t0, label("end"), flags=(CEZF,)
- ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
- wrdl reg, t2, t1
-end:
+ andi t0, t1, 0xFC, flags=(EZF,), dataSize=2
+ br label("processDescriptor"), flags=(CEZF,)
+ andi t2, t1, 0xF8, dataSize=8
+ andi t0, t1, 0x4, flags=(EZF,), dataSize=2
+ br label("globalDescriptor"), flags=(CEZF,)
+ ld t3, tsl, [1, t0, t2], dataSize=8, addressSize=8
+ br label("processDescriptor")
+globalDescriptor:
+ ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8
+processDescriptor:
+ chks t1, t3, dataSize=8
+ wrdl reg, t3, t1
wrsel reg, t1
};
def macroop MOVSS_S_R {
- chks t1, regm, flags=(EZF,), dataSize=8
- # This actually needs to use the selector as the error code, but it would
- # be hard to get that information into the instruction at the moment.
- fault "new GeneralProtection(0)", flags=(CEZF,)
- ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
- wrdl reg, t2, regm
+ andi t0, regm, 0xFC, flags=(EZF,), dataSize=2
+ br label("processDescriptor"), flags=(CEZF,)
+ andi t2, regm, 0xF8, dataSize=8
+ andi t0, regm, 0x4, flags=(EZF,), dataSize=2
+ br label("globalDescriptor"), flags=(CEZF,)
+ ld t3, tsl, [1, t0, t2], dataSize=8, addressSize=8
+ br label("processDescriptor")
+globalDescriptor:
+ ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8
+processDescriptor:
+ chks regm, t3, SSCheck, dataSize=8
+ wrdl reg, t3, regm
wrsel reg, regm
};
def macroop MOVSS_S_M {
ld t1, seg, sib, disp, dataSize=2
- chks t2, t1, flags=(EZF,), dataSize=8
- # This actually needs to use the selector as the error code, but it would
- # be hard to get that information into the instruction at the moment.
- fault "new GeneralProtection(0)", flags=(CEZF,)
- ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
- wrdl reg, t2, t1
+ andi t0, t1, 0xFC, flags=(EZF,), dataSize=2
+ br label("processDescriptor"), flags=(CEZF,)
+ andi t2, t1, 0xF8, dataSize=8
+ andi t0, t1, 0x4, flags=(EZF,), dataSize=2
+ br label("globalDescriptor"), flags=(CEZF,)
+ ld t3, tsl, [1, t0, t2], dataSize=8, addressSize=8
+ br label("processDescriptor")
+globalDescriptor:
+ ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8
+processDescriptor:
+ chks t1, t3, SSCheck, dataSize=8
+ wrdl reg, t3, t1
wrsel reg, t1
};
def macroop MOVSS_S_P {
rdip t7
ld t1, seg, riprel, disp, dataSize=2
- chks t2, t1, flags=(EZF,), dataSize=8
- # This actually needs to use the selector as the error code, but it would
- # be hard to get that information into the instruction at the moment.
- fault "new GeneralProtection(0)", flags=(CEZF,)
- ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
- wrdl reg, t2, t1
+ andi t0, t1, 0xFC, flags=(EZF,), dataSize=2
+ br label("processDescriptor"), flags=(CEZF,)
+ andi t2, t1, 0xF8, dataSize=8
+ andi t0, t1, 0x4, flags=(EZF,), dataSize=2
+ br label("globalDescriptor"), flags=(CEZF,)
+ ld t3, tsl, [1, t0, t2], dataSize=8, addressSize=8
+ br label("processDescriptor")
+globalDescriptor:
+ ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8
+processDescriptor:
+ chks t1, t3, SSCheck, dataSize=8
+ wrdl reg, t3, t1
wrsel reg, t1
};
'''
#let {{
# class MOVD(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class MOVNTI(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
#}};
diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py
index 6c51f3171..82fdffc63 100644
--- a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py
+++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2007 The Hewlett-Packard Development Company
+# Copyright (c) 2007-2008 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
@@ -58,8 +58,8 @@ def macroop POP_R {
# Make the default data size of pops 64 bits in 64 bit mode
.adjust_env oszIn64Override
- ld t1, ss, [1, t0, rsp]
- addi rsp, rsp, dsz
+ ld t1, ss, [1, t0, rsp], dataSize=ssz
+ addi rsp, rsp, ssz, dataSize=asz
mov reg, reg, t1
};
@@ -67,10 +67,10 @@ def macroop POP_M {
# Make the default data size of pops 64 bits in 64 bit mode
.adjust_env oszIn64Override
- ld t1, ss, [1, t0, rsp]
- cda seg, sib, disp
- addi rsp, rsp, dsz
- st t1, seg, sib, disp
+ ld t1, ss, [1, t0, rsp], dataSize=ssz
+ cda seg, sib, disp, dataSize=ssz
+ addi rsp, rsp, ssz, dataSize=asz
+ st t1, seg, sib, disp, dataSize=ssz
};
def macroop POP_P {
@@ -78,17 +78,17 @@ def macroop POP_P {
.adjust_env oszIn64Override
rdip t7
- ld t1, ss, [1, t0, rsp]
- cda seg, sib, disp
- addi rsp, rsp, dsz
- st t1, seg, riprel, disp
+ ld t1, ss, [1, t0, rsp], dataSize=ssz
+ cda seg, sib, disp, dataSize=ssz
+ addi rsp, rsp, ssz, dataSize=asz
+ st t1, seg, riprel, disp, dataSize=ssz
};
def macroop PUSH_R {
# Make the default data size of pops 64 bits in 64 bit mode
.adjust_env oszIn64Override
- stupd reg, ss, [1, t0, rsp], "-env.dataSize"
+ stupd reg, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
};
def macroop PUSH_I {
@@ -96,15 +96,15 @@ def macroop PUSH_I {
.adjust_env oszIn64Override
limm t1, imm
- stupd t1, ss, [1, t0, rsp], "-env.dataSize"
+ stupd t1, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
};
def macroop PUSH_M {
# Make the default data size of pops 64 bits in 64 bit mode
.adjust_env oszIn64Override
- ld t1, seg, sib, disp
- stupd t1, ss, [1, t0, rsp], "-env.dataSize"
+ ld t1, seg, sib, disp, dataSize=ssz
+ stupd t1, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
};
def macroop PUSH_P {
@@ -112,48 +112,48 @@ def macroop PUSH_P {
.adjust_env oszIn64Override
rdip t7
- ld t1, seg, riprel, disp
- stupd t1, ss, [1, t0, rsp], "-env.dataSize"
+ ld t1, seg, riprel, disp, dataSize=ssz
+ stupd t1, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
};
def macroop PUSHA {
# Check all the stack addresses. We'll assume that if the beginning and
# end are ok, then the stuff in the middle should be as well.
- cda ss, [1, t0, rsp], "-env.dataSize"
- cda ss, [1, t0, rsp], "-8 * env.dataSize"
- stupd rax, ss, [1, t0, rsp], "-env.dataSize"
- stupd rcx, ss, [1, t0, rsp], "-env.dataSize"
- stupd rdx, ss, [1, t0, rsp], "-env.dataSize"
- stupd rbx, ss, [1, t0, rsp], "-env.dataSize"
- stupd rsp, ss, [1, t0, rsp], "-env.dataSize"
- stupd rbp, ss, [1, t0, rsp], "-env.dataSize"
- stupd rsi, ss, [1, t0, rsp], "-env.dataSize"
- stupd rdi, ss, [1, t0, rsp], "-env.dataSize"
+ cda ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
+ cda ss, [1, t0, rsp], "-8 * env.stackSize", dataSize=ssz
+ stupd rax, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
+ stupd rcx, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
+ stupd rdx, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
+ stupd rbx, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
+ stupd rsp, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
+ stupd rbp, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
+ stupd rsi, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
+ stupd rdi, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
};
def macroop POPA {
# Check all the stack addresses. We'll assume that if the beginning and
# end are ok, then the stuff in the middle should be as well.
- ld t1, ss, [1, t0, rsp], "0 * env.dataSize"
- ld t2, ss, [1, t0, rsp], "7 * env.dataSize"
- mov rdi, rdi, t1
- ld rsi, ss, [1, t0, rsp], "1 * env.dataSize"
- ld rbp, ss, [1, t0, rsp], "2 * env.dataSize"
- ld rbx, ss, [1, t0, rsp], "4 * env.dataSize"
- ld rdx, ss, [1, t0, rsp], "5 * env.dataSize"
- ld rcx, ss, [1, t0, rsp], "6 * env.dataSize"
- mov rax, rax, t2
- addi rsp, rsp, "8 * env.dataSize"
+ ld t1, ss, [1, t0, rsp], "0 * env.stackSize", dataSize=ssz
+ ld t2, ss, [1, t0, rsp], "7 * env.stackSize", dataSize=ssz
+ mov rdi, rdi, t1, dataSize=ssz
+ ld rsi, ss, [1, t0, rsp], "1 * env.stackSize", dataSize=ssz
+ ld rbp, ss, [1, t0, rsp], "2 * env.stackSize", dataSize=ssz
+ ld rbx, ss, [1, t0, rsp], "4 * env.stackSize", dataSize=ssz
+ ld rdx, ss, [1, t0, rsp], "5 * env.stackSize", dataSize=ssz
+ ld rcx, ss, [1, t0, rsp], "6 * env.stackSize", dataSize=ssz
+ mov rax, rax, t2, dataSize=ssz
+ addi rsp, rsp, "8 * env.stackSize", dataSize=asz
};
def macroop LEAVE {
# Make the default data size of pops 64 bits in 64 bit mode
.adjust_env oszIn64Override
- mov t1, t1, rbp
- ld rbp, ss, [1, t0, t1]
- mov rsp, rsp, t1
- addi rsp, rsp, dsz
+ mov t1, t1, rbp, dataSize=asz
+ ld rbp, ss, [1, t0, t1], dataSize=ssz
+ mov rsp, rsp, t1, dataSize=asz
+ addi rsp, rsp, ssz, dataSize=asz
};
def macroop ENTER_I_I {
@@ -162,41 +162,41 @@ def macroop ENTER_I_I {
# Pull the different components out of the immediate
limm t1, imm
- zexti t2, t1, 15, dataSize=2
+ zexti t2, t1, 15, dataSize=8
srl t1, t1, 16
- zexti t1, t1, 5
+ zexti t1, t1, 5, dataSize=8
# t1 is now the masked nesting level, and t2 is the amount of storage.
# Push rbp.
- stupd rbp, ss, [1, t0, rsp], "-env.dataSize"
+ stupd rbp, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
# Save the stack pointer for later
- mov t6, t6, rsp
+ mov t6, t6, rsp, dataSize=asz
# If the nesting level is zero, skip all this stuff.
subi t0, t1, t0, flags=(EZF,), dataSize=2
- bri t0, label("skipLoop"), flags=(CEZF,)
+ br label("skipLoop"), flags=(CEZF,)
# If the level was 1, only push the saved rbp
subi t0, t1, 1, flags=(EZF,)
- bri t0, label("bottomOfLoop"), flags=(CEZF,)
+ br label("bottomOfLoop"), flags=(CEZF,)
limm t4, "ULL(-1)", dataSize=8
topOfLoop:
- ld t5, ss, [dsz, t4, rbp]
- stupd t5, ss, [1, t0, rsp], "-env.dataSize"
+ ld t5, ss, [ssz, t4, rbp], dataSize=ssz
+ stupd t5, ss, [1, t0, rsp], "-env.stackSize"
# If we're not done yet, loop
subi t4, t4, 1, dataSize=8
add t0, t4, t1, flags=(EZF,)
- bri t0, label("topOfLoop"), flags=(nCEZF,)
+ br label("topOfLoop"), flags=(nCEZF,)
bottomOfLoop:
# Push the old rbp onto the stack
- stupd t6, ss, [1, t0, rsp], "-env.dataSize"
+ stupd t6, ss, [1, t0, rsp], "-env.stackSize"
skipLoop:
- sub rsp, rsp, t2
- mov rbp, rbp, t6
+ sub rsp, rsp, t2, dataSize=asz
+ mov rbp, rbp, t6, dataSize=asz
};
'''
diff --git a/src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py b/src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py
index fe60350c1..59f6aaec2 100644
--- a/src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py
+++ b/src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2007 The Hewlett-Packard Development Company
+# Copyright (c) 2007-2008 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
@@ -57,17 +57,15 @@ microcode = '''
def macroop PUSHF {
.adjust_env oszIn64Override
- # This should really read the whole flags register, not just user flags.
- ruflags t1
- stupd t1, ss, [1, t0, rsp], "-env.dataSize"
+ rflags t1
+ stupd t1, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
};
def macroop POPF {
.adjust_env oszIn64Override
- ld t1, ss, [1, t0, rsp]
- addi rsp, rsp, dsz
- # This should really write the whole flags register, not just user flags.
- wruflags t1, t0
+ ld t1, ss, [1, t0, rsp], dataSize=ssz
+ addi rsp, rsp, ssz
+ wrflags t1, t0
};
'''
diff --git a/src/arch/x86/isa/insts/general_purpose/flags/set_and_clear.py b/src/arch/x86/isa/insts/general_purpose/flags/set_and_clear.py
index 4c655e0b2..e151dc61d 100644
--- a/src/arch/x86/isa/insts/general_purpose/flags/set_and_clear.py
+++ b/src/arch/x86/isa/insts/general_purpose/flags/set_and_clear.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2007 The Hewlett-Packard Development Company
+# Copyright (c) 2007-2008 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
@@ -84,10 +84,18 @@ def macroop CMC {
ruflags t1
wruflagsi t1, "CFBit"
};
+
+def macroop STI {
+ rflags t1
+ limm t2, "IFBit"
+ or t1, t1, t2
+ wrflags t1, t0
+};
+
+def macroop CLI {
+ rflags t1
+ limm t2, "~IFBit"
+ and t1, t1, t2
+ wrflags t1, t0
+};
'''
-#let {{
-# class CLI(Inst):
-# "GenFault ${new UnimpInstFault}"
-# class STI(Inst):
-# "GenFault ${new UnimpInstFault}"
-#}};
diff --git a/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py b/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py
index 1986a322e..4e3c9b316 100644
--- a/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py
+++ b/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py
@@ -84,25 +84,23 @@
microcode = '''
def macroop IN_R_I {
.adjust_imm trimImm(8)
- limm t1, "IntAddrPrefixIO", dataSize=8
- ld reg, intseg, [1, t1, t0], imm, addressSize=8
+ limm t1, imm, dataSize=asz
+ ld reg, intseg, [1, t1, t0], "IntAddrPrefixIO << 3", addressSize=8
};
def macroop IN_R_R {
- limm t1, "IntAddrPrefixIO", dataSize=8
- zexti t2, regm, 15, dataSize=2
- ld reg, intseg, [1, t1, t2], addressSize=8
+ zexti t2, regm, 15, dataSize=8
+ ld reg, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=8
};
def macroop OUT_I_R {
.adjust_imm trimImm(8)
- limm t1, "IntAddrPrefixIO", dataSize=8
- st reg, intseg, [1, t1, t0], imm, addressSize=8
+ limm t1, imm, dataSize=8
+ st reg, intseg, [1, t1, t0], "IntAddrPrefixIO << 3", addressSize=8
};
def macroop OUT_R_R {
- limm t1, "IntAddrPrefixIO", dataSize=8
- zexti t2, reg, 15, dataSize=2
- st regm, intseg, [1, t1, t2], addressSize=8
+ zexti t2, reg, 15, dataSize=8
+ st regm, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=8
};
'''
diff --git a/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py b/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py
index b44203d9c..b3bc5ab67 100644
--- a/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py
+++ b/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2007 The Hewlett-Packard Development Company
+# Copyright (c) 2007-2008 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
@@ -61,32 +61,33 @@ def macroop INS_M_R {
subi t4, t0, dsz, dataSize=asz
mov t3, t3, t4, flags=(nCEZF,), dataSize=asz
- limm t1, "IntAddrPrefixIO"
- zexti t2, reg, 15, dataSize=2
+ zexti t2, reg, 15, dataSize=8
- ld t6, intseg, [1, t1, t2], addressSize=8
+ ld t6, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=8
st t6, es, [1, t0, rdi]
add rdi, rdi, t3, dataSize=asz
};
def macroop INS_E_M_R {
+ and t0, rcx, rcx, flags=(EZF,), dataSize=asz
+ br label("end"), flags=(CEZF,)
# Find the constant we need to either add or subtract from rdi
ruflag t0, 10
movi t3, t3, dsz, flags=(CEZF,), dataSize=asz
subi t4, t0, dsz, dataSize=asz
mov t3, t3, t4, flags=(nCEZF,), dataSize=asz
- limm t1, "IntAddrPrefixIO"
- zexti t2, reg, 15, dataSize=2
+ zexti t2, reg, 15, dataSize=8
topOfLoop:
- ld t6, intseg, [1, t1, t2], addressSize=8
+ ld t6, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=8
st t6, es, [1, t0, rdi]
subi rcx, rcx, 1, flags=(EZF,), dataSize=asz
add rdi, rdi, t3, dataSize=asz
- bri t0, label("topOfLoop"), flags=(nCEZF,)
+ br label("topOfLoop"), flags=(nCEZF,)
+end:
fault "NoFault"
};
@@ -97,32 +98,33 @@ def macroop OUTS_R_M {
subi t4, t0, dsz, dataSize=asz
mov t3, t3, t4, flags=(nCEZF,), dataSize=asz
- limm t1, "IntAddrPrefixIO"
- zexti t2, reg, 15, dataSize=2
+ zexti t2, reg, 15, dataSize=8
ld t6, ds, [1, t0, rsi]
- st t6, intseg, [1, t1, t2], addressSize=8
+ st t6, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=8
add rsi, rsi, t3, dataSize=asz
};
def macroop OUTS_E_R_M {
+ and t0, rcx, rcx, flags=(EZF,), dataSize=asz
+ br label("end"), flags=(CEZF,)
# Find the constant we need to either add or subtract from rdi
ruflag t0, 10
movi t3, t3, dsz, flags=(CEZF,), dataSize=asz
subi t4, t0, dsz, dataSize=asz
mov t3, t3, t4, flags=(nCEZF,), dataSize=asz
- limm t1, "IntAddrPrefixIO"
- zexti t2, reg, 15, dataSize=2
+ zexti t2, reg, 15, dataSize=8
topOfLoop:
ld t6, ds, [1, t0, rsi]
- st t6, intseg, [1, t1, t2], addressSize=8
+ st t6, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=8
subi rcx, rcx, 1, flags=(EZF,), dataSize=asz
add rsi, rsi, t3, dataSize=asz
- bri t0, label("topOfLoop"), flags=(nCEZF,)
+ br label("topOfLoop"), flags=(nCEZF,)
+end:
fault "NoFault"
};
'''
diff --git a/src/arch/x86/isa/insts/general_purpose/load_segment_registers.py b/src/arch/x86/isa/insts/general_purpose/load_segment_registers.py
index 8aec4b99e..e6633ee1a 100644
--- a/src/arch/x86/isa/insts/general_purpose/load_segment_registers.py
+++ b/src/arch/x86/isa/insts/general_purpose/load_segment_registers.py
@@ -56,17 +56,17 @@
microcode = ""
#let {{
# class LDS(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class LES(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class LFS(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class LGS(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class LSS(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class MOV_SEG(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class POP(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
#}};
diff --git a/src/arch/x86/isa/insts/general_purpose/processor_information.py b/src/arch/x86/isa/insts/general_purpose/processor_information.py
deleted file mode 100644
index 6070169ac..000000000
--- a/src/arch/x86/isa/insts/general_purpose/processor_information.py
+++ /dev/null
@@ -1,405 +0,0 @@
-# Copyright (c) 2007 The Hewlett-Packard Development Company
-# All rights reserved.
-#
-# Redistribution and use of this software in source and binary forms,
-# with or without modification, are permitted provided that the
-# following conditions are met:
-#
-# The software must be used only for Non-Commercial Use which means any
-# use which is NOT directed to receiving any direct monetary
-# compensation for, or commercial advantage from such use. Illustrative
-# examples of non-commercial use are academic research, personal study,
-# teaching, education and corporate research & development.
-# Illustrative examples of commercial use are distributing products for
-# commercial advantage and providing services using the software for
-# commercial advantage.
-#
-# If you wish to use this software or functionality therein that may be
-# covered by patents for commercial use, please contact:
-# Director of Intellectual Property Licensing
-# Office of Strategy and Technology
-# Hewlett-Packard Company
-# 1501 Page Mill Road
-# Palo Alto, California 94304
-#
-# Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer. Redistributions
-# in binary form must reproduce the above copyright notice, this list of
-# conditions and the following disclaimer in the documentation and/or
-# other materials provided with the distribution. Neither the name of
-# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission. No right of
-# sublicense is granted herewith. Derivatives of the software and
-# output created using the software may be prepared, but only for
-# Non-Commercial Uses. Derivatives of the software may be shared with
-# others provided: (i) the others agree to abide by the list of
-# conditions herein which includes the Non-Commercial Use restrictions;
-# and (ii) such Derivatives of the software include the above copyright
-# notice to acknowledge the contribution from this software where
-# applicable, this list of conditions and the disclaimer below.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Authors: Gabe Black
-
-microcode = '''
-def macroop CPUID_R {
-
-#
-# Find which type of cpuid function it is by checking bit 31. Also clear that
-# bit to form an offset into the functions of that type.
-#
- limm t1, 0x80000000, dataSize=4
- and t2, t1, rax, flags=(EZF,)
- # clear the bit
- xor t1, t2, rax
-
-#
-# Do range checking on the offset
-#
- # If EZF is set, the function is standard and the max is 0x1.
- movi t2, t2, 0x1, flags=(CEZF,)
- # If EZF is cleared, the function is extended and the max is 0x18.
- movi t2, t2, 0x18, flags=(nCEZF,)
- subi t0, t1, t2, flags=(ECF,)
- # ECF will be set if the offset is too large.
- bri t0, label("end"), flags=(nCECF,)
-
-
-#
-# Jump to the right portion
-#
- movi t2, t2, label("standardStart"), flags=(CEZF,)
- movi t2, t2, label("extendedStart"), flags=(nCEZF,)
- # This gives each function 8 microops to use. It's wasteful because only
- # 5 will be needed, but a multiply would be expensive. In the system
- # described in the RISC86 patent, the fifth instruction would really be
- # the sequencing field on an op quad, so each function would be implemented
- # by -exactly- one op quad. Since we're approximating, this should be ok.
- slli t1, t1, 3
- br t2, t1
-
-#############################################################################
-#############################################################################
-
-#
-# Standard functions.
-#
-
-standardStart:
-
-# 0x00000000 -- Processor Vendor and Largest Standard Function Number
- limm rax, 0x00000001, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x00000001 -- Family, Model, Stepping Identifiers
- limm rax, 0x00020f51, dataSize=4
- limm rbx, 0x00000405, dataSize=4
- limm rdx, 0xe3d3fbff, dataSize=4
- limm rcx, 0x00000001, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-#
-# Extended functions.
-#
-
-extendedStart:
-
-# 0x80000000 -- Processor Vendor and Largest Extended Function Number
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000001 -- EAX: AMD Family, Model, Stepping
-# EBX: BrandId Identifier
-# ECX: Feature Identifiers
-# EDX: Feature Identifiers
- limm rax, 0x00020f51, dataSize=4
- limm rbx, 0x00000405, dataSize=4
- limm rdx, 0xe3d3fbff, dataSize=4
- limm rcx, 0x00000001, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000002 -- Processor Name String Identifier
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000003 -- Processor Name String Identifier
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000004 -- Processor Name String Identifier
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000005 -- L1 Cache and TLB Identifiers
- limm rax, 0xff08ff08, dataSize=4
- limm rbx, 0xff20ff20, dataSize=4
- limm rdx, 0x40020140, dataSize=4
- limm rcx, 0x40020140, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000006 -- L2/L3 Cache and L2 TLB Identifiers
- limm rax, 0x00000000, dataSize=4
- limm rbx, 0x42004200, dataSize=4
- limm rdx, 0x00000000, dataSize=4
- limm rcx, 0x04008140, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000007 -- Advanced Power Management Information
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000008 -- Long Mode Address Size Identification
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000009 -- Reserved
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x8000000A -- SVM Revision and Feature Identification
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x8000000B -- Reserved
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x8000000C -- Reserved
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x8000000D -- Reserved
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x8000000E -- Reserved
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x8000000F -- Reserved
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000010 -- Reserved
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000011 -- Reserved
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000012 -- Reserved
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000013 -- Reserved
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000014 -- Reserved
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000015 -- Reserved
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000016 -- Reserved
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000017 -- Reserved
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-# 0x80000018 -- Reserved
- # JUNK VALUES
- limm rax, 0x80000018, dataSize=4
- limm rbx, 0x68747541, dataSize=4
- limm rdx, 0x69746e65, dataSize=4
- limm rcx, 0x444d4163, dataSize=4
- bri t0, label("end")
- fault "NoFault"
- fault "NoFault"
- fault "NoFault"
-
-end:
- fault "NoFault"
-};
-'''
diff --git a/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py b/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py
index ed7d761b8..caaeca974 100644
--- a/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py
+++ b/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py
@@ -56,13 +56,13 @@
microcode = '''
def macroop SAL_R_I
{
- slli reg, reg, imm, flags=(SF,ZF,PF)
+ slli reg, reg, imm, flags=(CF,OF,SF,ZF,PF)
};
def macroop SAL_M_I
{
ldst t1, seg, sib, disp
- slli t1, t1, imm, flags=(SF,ZF,PF)
+ slli t1, t1, imm, flags=(CF,OF,SF,ZF,PF)
st t1, seg, sib, disp
};
@@ -70,19 +70,19 @@ def macroop SAL_P_I
{
rdip t7
ldst t1, seg, riprel, disp
- slli t1, t1, imm, flags=(SF,ZF,PF)
+ slli t1, t1, imm, flags=(CF,OF,SF,ZF,PF)
st t1, seg, riprel, disp
};
def macroop SAL_1_R
{
- slli reg, reg, 1, flags=(SF,ZF,PF)
+ slli reg, reg, 1, flags=(CF,OF,SF,ZF,PF)
};
def macroop SAL_1_M
{
ldst t1, seg, sib, disp
- slli t1, t1, 1, flags=(SF,ZF,PF)
+ slli t1, t1, 1, flags=(CF,OF,SF,ZF,PF)
st t1, seg, sib, disp
};
@@ -90,19 +90,19 @@ def macroop SAL_1_P
{
rdip t7
ldst t1, seg, riprel, disp
- slli t1, t1, 1, flags=(SF,ZF,PF)
+ slli t1, t1, 1, flags=(CF,OF,SF,ZF,PF)
st t1, seg, riprel, disp
};
def macroop SAL_R_R
{
- sll reg, reg, regm, flags=(SF,ZF,PF)
+ sll reg, reg, regm, flags=(CF,OF,SF,ZF,PF)
};
def macroop SAL_M_R
{
ldst t1, seg, sib, disp
- sll t1, t1, reg, flags=(SF,ZF,PF)
+ sll t1, t1, reg, flags=(CF,OF,SF,ZF,PF)
st t1, seg, sib, disp
};
@@ -110,19 +110,19 @@ def macroop SAL_P_R
{
rdip t7
ldst t1, seg, riprel, disp
- sll t1, t1, reg, flags=(SF,ZF,PF)
+ sll t1, t1, reg, flags=(CF,OF,SF,ZF,PF)
st t1, seg, riprel, disp
};
def macroop SHR_R_I
{
- srli reg, reg, imm, flags=(SF,ZF,PF)
+ srli reg, reg, imm, flags=(CF,OF,SF,ZF,PF)
};
def macroop SHR_M_I
{
ldst t1, seg, sib, disp
- srli t1, t1, imm, flags=(SF,ZF,PF)
+ srli t1, t1, imm, flags=(CF,OF,SF,ZF,PF)
st t1, seg, sib, disp
};
@@ -130,19 +130,19 @@ def macroop SHR_P_I
{
rdip t7
ldst t1, seg, riprel, disp
- srli t1, t1, imm, flags=(SF,ZF,PF)
+ srli t1, t1, imm, flags=(CF,OF,SF,ZF,PF)
st t1, seg, riprel, disp
};
def macroop SHR_1_R
{
- srli reg, reg, 1, flags=(SF,ZF,PF)
+ srli reg, reg, 1, flags=(CF,OF,SF,ZF,PF)
};
def macroop SHR_1_M
{
ldst t1, seg, sib, disp
- srli t1, t1, 1, flags=(SF,ZF,PF)
+ srli t1, t1, 1, flags=(CF,OF,SF,ZF,PF)
st t1, seg, sib, disp
};
@@ -150,19 +150,19 @@ def macroop SHR_1_P
{
rdip t7
ldst t1, seg, riprel, disp
- srli t1, t1, 1, flags=(SF,ZF,PF)
+ srli t1, t1, 1, flags=(CF,OF,SF,ZF,PF)
st t1, seg, riprel, disp
};
def macroop SHR_R_R
{
- srl reg, reg, regm, flags=(SF,ZF,PF)
+ srl reg, reg, regm, flags=(CF,OF,SF,ZF,PF)
};
def macroop SHR_M_R
{
ldst t1, seg, sib, disp
- srl t1, t1, reg, flags=(SF,ZF,PF)
+ srl t1, t1, reg, flags=(CF,OF,SF,ZF,PF)
st t1, seg, sib, disp
};
@@ -170,19 +170,54 @@ def macroop SHR_P_R
{
rdip t7
ldst t1, seg, riprel, disp
- srl t1, t1, reg, flags=(SF,ZF,PF)
+ srl t1, t1, reg, flags=(CF,OF,SF,ZF,PF)
+ st t1, seg, riprel, disp
+};
+
+# SHRD will not set OF correctly when the shift count is 1.
+def macroop SHRD_R_R_I
+{
+ srli t1, reg, imm, flags=(CF,)
+ rori t2, regm, imm
+ srli t3, regm, imm
+ xor t2, t2, t3
+ or reg, t1, t2
+};
+
+# SHRD will not set OF correctly when the shift count is 1.
+def macroop SHRD_M_R_I
+{
+ ldst t1, seg, sib, disp
+ srli t1, t1, imm, flags=(CF,)
+ rori t2, reg, imm
+ srli t3, reg, imm
+ xor t2, t2, t3
+ or t1, t1, t2
+ st t1, seg, sib, disp
+};
+
+# SHRD will not set OF correctly when the shift count is 1.
+def macroop SHRD_P_R_I
+{
+ rdip t7
+ ldst t1, seg, riprel, disp
+ srli t1, t1, imm, flags=(CF,)
+ rori t2, reg, imm
+ srli t3, reg, imm
+ xor t2, t2, t3
+ or t1, t1, t2
st t1, seg, riprel, disp
};
def macroop SAR_R_I
{
- srai reg, reg, imm, flags=(SF,ZF,PF)
+ srai reg, reg, imm, flags=(CF,OF,SF,ZF,PF)
};
def macroop SAR_M_I
{
ldst t1, seg, sib, disp
- srai t1, t1, imm, flags=(SF,ZF,PF)
+ srai t1, t1, imm, flags=(CF,OF,SF,ZF,PF)
st t1, seg, sib, disp
};
@@ -190,19 +225,19 @@ def macroop SAR_P_I
{
rdip t7
ldst t1, seg, riprel, disp
- srai t1, t1, imm, flags=(SF,ZF,PF)
+ srai t1, t1, imm, flags=(CF,OF,SF,ZF,PF)
st t1, seg, riprel, disp
};
def macroop SAR_1_R
{
- srai reg, reg, 1, flags=(SF,ZF,PF)
+ srai reg, reg, 1, flags=(CF,OF,SF,ZF,PF)
};
def macroop SAR_1_M
{
ldst t1, seg, sib, disp
- srai t1, t1, 1, flags=(SF,ZF,PF)
+ srai t1, t1, 1, flags=(CF,OF,SF,ZF,PF)
st t1, seg, sib, disp
};
@@ -210,19 +245,19 @@ def macroop SAR_1_P
{
rdip t7
ldst t1, seg, riprel, disp
- srai t1, t1, 1, flags=(SF,ZF,PF)
+ srai t1, t1, 1, flags=(CF,OF,SF,ZF,PF)
st t1, seg, riprel, disp
};
def macroop SAR_R_R
{
- sra reg, reg, regm, flags=(SF,ZF,PF)
+ sra reg, reg, regm, flags=(CF,OF,SF,ZF,PF)
};
def macroop SAR_M_R
{
ldst t1, seg, sib, disp
- sra t1, t1, reg, flags=(SF,ZF,PF)
+ sra t1, t1, reg, flags=(CF,OF,SF,ZF,PF)
st t1, seg, sib, disp
};
@@ -230,7 +265,7 @@ def macroop SAR_P_R
{
rdip t7
ldst t1, seg, riprel, disp
- sra t1, t1, reg, flags=(SF,ZF,PF)
+ sra t1, t1, reg, flags=(CF,OF,SF,ZF,PF)
st t1, seg, riprel, disp
};
'''
diff --git a/src/arch/x86/isa/insts/general_purpose/semaphores.py b/src/arch/x86/isa/insts/general_purpose/semaphores.py
index 27a31dbd9..f23241863 100644
--- a/src/arch/x86/isa/insts/general_purpose/semaphores.py
+++ b/src/arch/x86/isa/insts/general_purpose/semaphores.py
@@ -78,10 +78,30 @@ def macroop CMPXCHG_P_R {
st t1, seg, riprel, disp
mov rax, rax, t1, flags=(nCZF,)
};
+
+def macroop XADD_M_R {
+ ldst t1, seg, sib, disp
+ add t2, t1, reg, flags=(OF,SF,ZF,AF,PF,CF)
+ st t2, seg, sib, disp
+ mov reg, reg, t1
+};
+
+def macroop XADD_P_R {
+ rdip t7
+ ldst t1, seg, riprel, disp
+ add t2, t1, reg, flags=(OF,SF,ZF,AF,PF,CF)
+ st t2, seg, riprel, disp
+ mov reg, reg, t1
+};
+
+def macroop XADD_R_R {
+ add t2, regm, reg, flags=(OF,SF,ZF,AF,PF,CF)
+ mov regm, regm, reg
+ mov reg, reg, t2
+};
+
'''
#let {{
-# class XADD(Inst):
-# "GenFault ${new UnimpInstFault}"
# class XCHG(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
#}};
diff --git a/src/arch/x86/isa/insts/general_purpose/string/compare_strings.py b/src/arch/x86/isa/insts/general_purpose/string/compare_strings.py
index 71b8511b4..561b8a415 100644
--- a/src/arch/x86/isa/insts/general_purpose/string/compare_strings.py
+++ b/src/arch/x86/isa/insts/general_purpose/string/compare_strings.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2007 The Hewlett-Packard Development Company
+# Copyright (c) 2007-2008 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
@@ -75,12 +75,16 @@ def macroop CMPS_M_M {
#
def macroop CMPS_E_M_M {
+ and t0, rcx, rcx, flags=(EZF,), dataSize=asz
+ br label("end"), flags=(CEZF,)
+
# Find the constant we need to either add or subtract from rdi
ruflag t0, 10
movi t3, t3, dsz, flags=(CEZF,), dataSize=asz
subi t4, t0, dsz, dataSize=asz
mov t3, t3, t4, flags=(nCEZF,), dataSize=asz
+topOfLoop:
ld t1, seg, [1, t0, rsi]
ld t2, es, [1, t0, rdi]
sub t0, t1, t2, flags=(OF, SF, ZF, AF, PF, CF)
@@ -88,17 +92,22 @@ def macroop CMPS_E_M_M {
subi rcx, rcx, 1, flags=(EZF,), dataSize=asz
add rdi, rdi, t3, dataSize=asz
add rsi, rsi, t3, dataSize=asz
- bri t0, 4, flags=(CSTRZnEZF,)
+ br label("topOfLoop"), flags=(CSTRZnEZF,)
+end:
fault "NoFault"
};
def macroop CMPS_N_M_M {
+ and t0, rcx, rcx, flags=(EZF,), dataSize=asz
+ br label("end"), flags=(CEZF,)
+
# Find the constant we need to either add or subtract from rdi
ruflag t0, 10
movi t3, t3, dsz, flags=(CEZF,), dataSize=asz
subi t4, t0, dsz, dataSize=asz
mov t3, t3, t4, flags=(nCEZF,), dataSize=asz
+topOfLoop:
ld t1, seg, [1, t0, rsi]
ld t2, es, [1, t0, rdi]
sub t0, t1, t2, flags=(OF, SF, ZF, AF, PF, CF)
@@ -106,7 +115,8 @@ def macroop CMPS_N_M_M {
subi rcx, rcx, 1, flags=(EZF,), dataSize=asz
add rdi, rdi, t3, dataSize=asz
add rsi, rsi, t3, dataSize=asz
- bri t0, 4, flags=(CSTRnZnEZF,)
+ br label("topOfLoop"), flags=(CSTRnZnEZF,)
+end:
fault "NoFault"
};
'''
diff --git a/src/arch/x86/isa/insts/general_purpose/string/load_string.py b/src/arch/x86/isa/insts/general_purpose/string/load_string.py
index 61525c2f2..14198701a 100644
--- a/src/arch/x86/isa/insts/general_purpose/string/load_string.py
+++ b/src/arch/x86/isa/insts/general_purpose/string/load_string.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2007 The Hewlett-Packard Development Company
+# Copyright (c) 2007-2008 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
@@ -61,12 +61,14 @@ def macroop LODS_M {
subi t4, t0, dsz, dataSize=asz
mov t3, t3, t4, flags=(nCEZF,), dataSize=asz
- ld rax, seg, [1, t0, rdi]
+ ld rax, seg, [1, t0, rsi]
- add rdi, rdi, t3, dataSize=asz
+ add rsi, rsi, t3, dataSize=asz
};
def macroop LODS_E_M {
+ and t0, rcx, rcx, flags=(EZF,), dataSize=asz
+ br label("end"), flags=(CEZF,)
# Find the constant we need to either add or subtract from rdi
ruflag t0, 10
movi t3, t3, dsz, flags=(CEZF,), dataSize=asz
@@ -74,11 +76,12 @@ def macroop LODS_E_M {
mov t3, t3, t4, flags=(nCEZF,), dataSize=asz
topOfLoop:
- ld rax, seg, [1, t0, rdi]
+ ld rax, seg, [1, t0, rsi]
subi rcx, rcx, 1, flags=(EZF,), dataSize=asz
- add rdi, rdi, t3, dataSize=asz
- bri t0, label("topOfLoop"), flags=(nCEZF,)
+ add rsi, rsi, t3, dataSize=asz
+ br label("topOfLoop"), flags=(nCEZF,)
+end:
fault "NoFault"
};
'''
diff --git a/src/arch/x86/isa/insts/general_purpose/string/move_string.py b/src/arch/x86/isa/insts/general_purpose/string/move_string.py
index b64acfdc2..18faa38e2 100644
--- a/src/arch/x86/isa/insts/general_purpose/string/move_string.py
+++ b/src/arch/x86/isa/insts/general_purpose/string/move_string.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2007 The Hewlett-Packard Development Company
+# Copyright (c) 2007-2008 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
@@ -69,6 +69,8 @@ def macroop MOVS_M_M {
};
def macroop MOVS_E_M_M {
+ and t0, rcx, rcx, flags=(EZF,), dataSize=asz
+ br label("end"), flags=(CEZF,)
# Find the constant we need to either add or subtract from rdi
ruflag t0, 10
movi t3, t3, dsz, flags=(CEZF,), dataSize=asz
@@ -82,7 +84,8 @@ topOfLoop:
subi rcx, rcx, 1, flags=(EZF,), dataSize=asz
add rdi, rdi, t3, dataSize=asz
add rsi, rsi, t3, dataSize=asz
- bri t0, label("topOfLoop"), flags=(nCEZF,)
+ br label("topOfLoop"), flags=(nCEZF,)
+end:
fault "NoFault"
};
'''
diff --git a/src/arch/x86/isa/insts/general_purpose/string/scan_string.py b/src/arch/x86/isa/insts/general_purpose/string/scan_string.py
index b038cc00a..5b0e74aad 100644
--- a/src/arch/x86/isa/insts/general_purpose/string/scan_string.py
+++ b/src/arch/x86/isa/insts/general_purpose/string/scan_string.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2007 The Hewlett-Packard Development Company
+# Copyright (c) 2007-2008 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
@@ -73,34 +73,44 @@ def macroop SCAS_M {
#
def macroop SCAS_E_M {
+ and t0, rcx, rcx, flags=(EZF,), dataSize=asz
+ br label("end"), flags=(CEZF,)
+
# Find the constant we need to either add or subtract from rdi
ruflag t0, 10
movi t2, t2, dsz, flags=(CEZF,), dataSize=asz
subi t3, t0, dsz, dataSize=asz
mov t2, t2, t3, flags=(nCEZF,), dataSize=asz
+topOfLoop:
ld t1, es, [1, t0, rdi]
sub t0, t1, rax, flags=(OF, SF, ZF, AF, PF, CF)
subi rcx, rcx, 1, flags=(EZF,), dataSize=asz
add rdi, rdi, t2, dataSize=asz
- bri t0, 4, flags=(CSTRZnEZF,)
+ br label("topOfLoop"), flags=(CSTRZnEZF,)
+end:
fault "NoFault"
};
def macroop SCAS_N_M {
+ and t0, rcx, rcx, flags=(EZF,), dataSize=asz
+ br label("end"), flags=(CEZF,)
+
# Find the constant we need to either add or subtract from rdi
ruflag t0, 10
movi t2, t2, dsz, flags=(CEZF,), dataSize=asz
subi t3, t0, dsz, dataSize=asz
mov t2, t2, t3, flags=(nCEZF,), dataSize=asz
+topOfLoop:
ld t1, es, [1, t0, rdi]
sub t0, t1, rax, flags=(OF, SF, ZF, AF, PF, CF)
subi rcx, rcx, 1, flags=(EZF,), dataSize=asz
add rdi, rdi, t2, dataSize=asz
- bri t0, 4, flags=(CSTRnZnEZF,)
+ br label("topOfLoop"), flags=(CSTRnZnEZF,)
+end:
fault "NoFault"
};
diff --git a/src/arch/x86/isa/insts/general_purpose/string/store_string.py b/src/arch/x86/isa/insts/general_purpose/string/store_string.py
index a8d558929..fe9917ce6 100644
--- a/src/arch/x86/isa/insts/general_purpose/string/store_string.py
+++ b/src/arch/x86/isa/insts/general_purpose/string/store_string.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2007 The Hewlett-Packard Development Company
+# Copyright (c) 2007-2008 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
@@ -67,6 +67,8 @@ def macroop STOS_M {
};
def macroop STOS_E_M {
+ and t0, rcx, rcx, flags=(EZF,), dataSize=asz
+ br label("end"), flags=(CEZF,)
# Find the constant we need to either add or subtract from rdi
ruflag t0, 10
movi t3, t3, dsz, flags=(CEZF,), dataSize=asz
@@ -78,7 +80,8 @@ topOfLoop:
subi rcx, rcx, 1, flags=(EZF,), dataSize=asz
add rdi, rdi, t3, dataSize=asz
- bri t0, label("topOfLoop"), flags=(nCEZF,)
+ br label("topOfLoop"), flags=(nCEZF,)
+end:
fault "NoFault"
};
'''
diff --git a/src/arch/x86/isa/insts/general_purpose/system_calls.py b/src/arch/x86/isa/insts/general_purpose/system_calls.py
index e056bea84..67607d5f8 100644
--- a/src/arch/x86/isa/insts/general_purpose/system_calls.py
+++ b/src/arch/x86/isa/insts/general_purpose/system_calls.py
@@ -53,14 +53,183 @@
#
# Authors: Gabe Black
-microcode = ""
+microcode = '''
+def macroop SYSCALL_64
+{
+ # All 1s.
+ limm t1, "(uint64_t)(-1)"
+
+ # Save the next RIP.
+ rdip rcx
+
+ # Stick rflags with RF masked into r11.
+ rflags t2
+ limm t3, "~RFBit"
+ andi r11, t2, t3, dataSize=8
+
+ rdval t3, star
+ srli t3, t3, 32, dataSize=8
+ andi t3, t3, 0xFC, dataSize=1
+
+ # Set up CS.
+ wrsel cs, t3
+ wrbase cs, t0, dataSize=8
+ wrlimit cs, t1, dataSize=4
+ # Not writable, read/execute-able, not expandDown,
+ # dpl=0, defaultSize=0, long mode
+ limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \
+ (0 << 3) | (0 << 5) | (1 << 6))
+ wrattr cs, t4
+
+ # Set up SS.
+ addi t3, t3, 8
+ wrsel ss, t3
+ wrbase ss, t0, dataSize=8
+ wrlimit ss, t1, dataSize=4
+ # Writable, readable, not expandDown,
+ # dpl=0, defaultSize=0, not long mode
+ limm t4, ((1 << 0) | (1 << 1) | (0 << 2) | \
+ (0 << 3) | (0 << 5) | (0 << 6))
+ wrattr ss, t4
+
+ # Set the new rip.
+ rdval t7, lstar
+ wrip t0, t7
+
+ # Mask the flags against sf_mask and leave RF turned off.
+ rdval t3, sf_mask, dataSize=8
+ xor t3, t3, t1, dataSize=8
+ and t3, t3, r11, dataSize=8
+ wrflags t3, t0
+};
+
+def macroop SYSCALL_COMPAT
+{
+ # All 1s.
+ limm t1, "(uint64_t)(-1)"
+
+ # Save the next RIP.
+ rdip rcx
+
+ # Stick rflags with RF masked into r11.
+ rflags t2
+ limm t3, "~RFBit"
+ andi r11, t2, t3, dataSize=8
+
+ rdval t3, star
+ srli t3, t3, 32, dataSize=8
+ andi t3, t3, 0xFC, dataSize=1
+
+ # Set up CS.
+ wrsel cs, t3
+ wrbase cs, t0, dataSize=8
+ wrlimit cs, t1, dataSize=4
+ # Not writable, read/execute-able, not expandDown,
+ # dpl=0, defaultSize=0, long mode
+ limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \
+ (0 << 3) | (0 << 5) | (1 << 6))
+ wrattr cs, t4
+
+ # Set up SS.
+ addi t3, t3, 8
+ wrsel ss, t3
+ wrbase ss, t0, dataSize=8
+ wrlimit ss, t1, dataSize=4
+ # Writable, readable, not expandDown,
+ # dpl=0, defaultSize=0, not long mode
+ limm t4, ((1 << 0) | (1 << 1) | (0 << 2) | \
+ (0 << 3) | (0 << 5) | (0 << 6))
+ wrattr ss, t4
+
+ # Set the new rip.
+ rdval t7, cstar
+ wrip t0, t7
+
+ # Mask the flags against sf_mask and leave RF turned off.
+ rdval t3, sf_mask, dataSize=8
+ xor t3, t3, t1, dataSize=8
+ and t3, t3, r11, dataSize=8
+ wrflags t3, t0
+};
+
+def macroop SYSCALL_LEGACY
+{
+ panic "The syscall instruction isn't implemented in legacy mode."
+};
+
+def macroop SYSRET_TO_64
+{
+ # All 1s.
+ limm t1, "(uint64_t)(-1)"
+
+ rdval t3, star
+ srli t3, t3, 48, dataSize=8
+ ori t3, t3, 3, dataSize=1
+
+ # Set rflags to r11 with RF and VM cleared.
+ limm t4, "~(RFBit | VMBit)"
+ and t4, t4, r11, dataSize=8
+ wrflags t4, t0
+
+ # Set up CS.
+ addi t4, t3, 16, dataSize=8
+ wrsel cs, t4
+ wrbase cs, t0, dataSize=8
+ wrlimit cs, t1, dataSize=4
+ # Not writable, read/execute-able, not expandDown,
+ # dpl=3, defaultSize=0, long mode
+ limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \
+ (3 << 3) | (0 << 5) | (1 << 6))
+ wrattr cs, t4
+
+ # Only the selector is changed for SS.
+ addi t4, t3, 8, dataSize=8
+ wrsel ss, t4
+
+ # Set the RIP back.
+ wrip rcx, t0, dataSize=8
+};
+
+def macroop SYSRET_TO_COMPAT
+{
+ # All 1s.
+ limm t1, "(uint64_t)(-1)"
+
+ rdval t3, star
+ srli t3, t3, 48, dataSize=8
+ ori t3, t3, 3, dataSize=1
+
+ # Set rflags to r11 with RF and VM cleared.
+ limm t4, "~(RFBit | VMBit)"
+ and t4, t4, r11, dataSize=8
+ wrflags t4, t0
+
+ # Set up CS.
+ wrsel cs, t3
+ wrbase cs, t0, dataSize=8
+ wrlimit cs, t1, dataSize=4
+ # Not writable, read/execute-able, not expandDown,
+ # dpl=3, defaultSize=1, not long mode
+ limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \
+ (3 << 3) | (1 << 5) | (0 << 6))
+ wrattr cs, t4
+
+ # Only the selector is changed for SS.
+ addi t4, t3, 8, dataSize=8
+ wrsel ss, t4
+
+ # Set the RIP back.
+ wrip rcx, t0, dataSize=8
+};
+
+def macroop SYSRET_NON_64
+{
+ panic "The sysret instruction isn't implemented in legacy mode."
+};
+'''
#let {{
# class SYSENTER(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
# class SYSEXIT(Inst):
-# "GenFault ${new UnimpInstFault}"
-# class SYSCALL(Inst):
-# "GenFault ${new UnimpInstFault}"
-# class SYSRET(Inst):
-# "GenFault ${new UnimpInstFault}"
+# "GenFault ${new UnimpInstFault}"
#}};
diff --git a/src/arch/x86/isa/insts/romutil.py b/src/arch/x86/isa/insts/romutil.py
new file mode 100644
index 000000000..e47259eb3
--- /dev/null
+++ b/src/arch/x86/isa/insts/romutil.py
@@ -0,0 +1,212 @@
+# Copyright (c) 2008 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+intCodeTemplate = '''
+def rom
+{
+ # This vectors the CPU into an interrupt handler in long mode.
+ # On entry, t1 is set to the vector of the interrupt and t7 is the current
+ # ip. We need that because rdip returns the next ip.
+ extern %(startLabel)s:
+
+ #
+ # Get the 64 bit interrupt or trap gate descriptor from the IDT
+ #
+
+ # Load the gate descriptor from the IDT
+ slli t4, t1, 4, dataSize=8
+ ld t2, idtr, [1, t0, t4], 8, dataSize=8, addressSize=8, atCPL0=True
+ ld t4, idtr, [1, t0, t4], dataSize=8, addressSize=8, atCPL0=True
+
+ # Make sure the descriptor is a legal gate.
+ chks t1, t4, %(gateCheckType)s
+
+ #
+ # Get the target CS descriptor using the selector in the gate
+ # descriptor.
+ #
+ srli t10, t4, 16, dataSize=8
+ andi t5, t10, 0xF8, dataSize=8
+ andi t0, t10, 0x4, flags=(EZF,), dataSize=2
+ br rom_local_label("%(startLabel)s_globalDescriptor"), flags=(CEZF,)
+ ld t3, tsl, [1, t0, t5], dataSize=8, addressSize=8, atCPL0=True
+ br rom_local_label("%(startLabel)s_processDescriptor")
+%(startLabel)s_globalDescriptor:
+ ld t3, tsg, [1, t0, t5], dataSize=8, addressSize=8, atCPL0=True
+%(startLabel)s_processDescriptor:
+ chks t10, t3, IntCSCheck, dataSize=8
+ wrdl hs, t3, t10, dataSize=8
+
+ # Stick the target offset in t9.
+ wrdh t9, t4, t2, dataSize=8
+
+
+ #
+ # Figure out where the stack should be
+ #
+
+ # Record what we might set the stack selector to.
+ rdsel t11, ss
+
+ # Check if we're changing privelege level. At this point we can assume
+ # we're going to a DPL that's less than or equal to the CPL.
+ rdattr t10, hs, dataSize=8
+ srli t10, t10, 3, dataSize=8
+ andi t10, t10, 3, dataSize=8
+ rdattr t5, cs, dataSize=8
+ srli t5, t5, 3, dataSize=8
+ andi t5, t5, 0x3, dataSize=8
+ sub t0, t5, t10, flags=(EZF,), dataSize=8
+ # We're going to change priviledge, so zero out the stack selector. We
+ # need to let the IST have priority so we don't branch yet.
+ wrsel t11, t0, flags=(nCEZF,)
+
+ # Check the IST field of the gate descriptor
+ srli t12, t4, 32, dataSize=8
+ andi t12, t12, 0x7, dataSize=8
+ subi t0, t12, 1, flags=(ECF,), dataSize=8
+ br rom_local_label("%(startLabel)s_istStackSwitch"), flags=(nCECF,)
+ br rom_local_label("%(startLabel)s_cplStackSwitch"), flags=(nCEZF,)
+
+ # If we're here, it's because the stack isn't being switched.
+ # Set t6 to the new aligned rsp.
+ mov t6, t6, rsp, dataSize=8
+ br rom_local_label("%(startLabel)s_stackSwitched")
+
+%(startLabel)s_istStackSwitch:
+ ld t6, tr, [8, t12, t0], 0x1c, dataSize=8, addressSize=8, atCPL0=True
+ br rom_local_label("%(startLabel)s_stackSwitched")
+
+%(startLabel)s_cplStackSwitch:
+ # Get the new rsp from the TSS
+ ld t6, tr, [8, t10, t0], 4, dataSize=8, addressSize=8, atCPL0=True
+
+%(startLabel)s_stackSwitched:
+
+ andi t6, t6, 0xF0, dataSize=1
+ subi t6, t6, 40 + %(errorCodeSize)d, dataSize=8
+
+ ##
+ ## Point of no return.
+ ## We're now going to irrevocably modify visible state.
+ ## Anything bad that's going to happen should have happened by now or will
+ ## happen right now.
+ ##
+ wrip t0, t9, dataSize=8
+
+ #
+ # Set up the target code segment. Do this now so we have the right
+ # permissions when setting up the stack frame.
+ #
+ srli t5, t4, 16, dataSize=8
+ andi t5, t5, 0xFF, dataSize=8
+ wrdl cs, t3, t5, dataSize=8
+ # Tuck away the old CS for use below
+ limm t10, 0, dataSize=8
+ rdsel t10, cs, dataSize=2
+ wrsel cs, t5, dataSize=2
+
+ # Check that we can access everything we need to on the stack
+ ldst t0, hs, [1, t0, t6], dataSize=8, addressSize=8
+ ldst t0, hs, [1, t0, t6], \
+ 32 + %(errorCodeSize)d, dataSize=8, addressSize=8
+
+
+ #
+ # Build up the interrupt stack frame
+ #
+
+
+ # Write out the contents of memory
+ %(errorCodeCode)s
+ st t7, hs, [1, t0, t6], %(errorCodeSize)d, dataSize=8, addressSize=8
+ st t10, hs, [1, t0, t6], 8 + %(errorCodeSize)d, dataSize=8, addressSize=8
+ rflags t10, dataSize=8
+ st t10, hs, [1, t0, t6], 16 + %(errorCodeSize)d, dataSize=8, addressSize=8
+ st rsp, hs, [1, t0, t6], 24 + %(errorCodeSize)d, dataSize=8, addressSize=8
+ rdsel t5, ss, dataSize=2
+ st t5, hs, [1, t0, t6], 32 + %(errorCodeSize)d, dataSize=8, addressSize=8
+
+ # Set the stack segment
+ mov rsp, rsp, t6, dataSize=8
+ wrsel ss, t11, dataSize=2
+
+ #
+ # Adjust rflags which is still in t10 from above
+ #
+
+ # Set IF to the lowest bit of the original gate type.
+ # The type field of the original gate starts at bit 40.
+
+ # Set the TF, NT, and RF bits. We'll flip them at the end.
+ limm t6, (1 << 8) | (1 << 14) | (1 << 16)
+ or t10, t10, t6
+ srli t5, t4, 40, dataSize=8
+ srli t7, t10, 9, dataSize=8
+ xor t5, t7, t5, dataSize=8
+ andi t5, t5, 1, dataSize=8
+ slli t5, t5, 9, dataSize=8
+ or t6, t5, t6, dataSize=8
+
+ # Put the results into rflags
+ wrflags t6, t10
+
+ eret
+};
+'''
+
+microcode = \
+intCodeTemplate % {\
+ "startLabel" : "longModeInterrupt",
+ "gateCheckType" : "IntGateCheck",
+ "errorCodeSize" : 0,
+ "errorCodeCode" : ""
+} + \
+intCodeTemplate % {\
+ "startLabel" : "longModeSoftInterrupt",
+ "gateCheckType" : "SoftIntGateCheck",
+ "errorCodeSize" : 0,
+ "errorCodeCode" : ""
+} + \
+intCodeTemplate % {\
+ "startLabel" : "longModeInterruptWithError",
+ "gateCheckType" : "IntGateCheck",
+ "errorCodeSize" : 8,
+ "errorCodeCode" : '''
+ st t15, hs, [1, t0, t6], dataSize=8, addressSize=8
+ '''
+} + \
+'''
+def rom
+{
+ # This vectors the CPU into an interrupt handler in legacy mode.
+ extern legacyModeInterrupt:
+ panic "Legacy mode interrupts not implemented (in microcode)"
+ eret
+};
+'''
diff --git a/src/arch/x86/isa/insts/system/__init__.py b/src/arch/x86/isa/insts/system/__init__.py
index 409a929f5..0dec9ebda 100644
--- a/src/arch/x86/isa/insts/system/__init__.py
+++ b/src/arch/x86/isa/insts/system/__init__.py
@@ -81,7 +81,8 @@
#
# Authors: Gabe Black
-categories = ["halt",
+categories = ["control_registers",
+ "halt",
"invlpg",
"undefined_operation",
"msrs",
diff --git a/src/arch/x86/isa/insts/system/control_registers.py b/src/arch/x86/isa/insts/system/control_registers.py
new file mode 100644
index 000000000..902c01abb
--- /dev/null
+++ b/src/arch/x86/isa/insts/system/control_registers.py
@@ -0,0 +1,35 @@
+# Copyright (c) 2009 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+microcode = '''
+def macroop CLTS {
+ rdcr t1, 0, dataSize=8
+ andi t1, t1, 0xF7, dataSize=1
+ wrcr 0, t1, dataSize=8
+};
+'''
diff --git a/src/arch/x86/isa/insts/system/msrs.py b/src/arch/x86/isa/insts/system/msrs.py
index 1acb4c792..7f283c8c1 100644
--- a/src/arch/x86/isa/insts/system/msrs.py
+++ b/src/arch/x86/isa/insts/system/msrs.py
@@ -84,8 +84,8 @@
microcode = '''
def macroop RDMSR
{
- limm t1, "IntAddrPrefixMSR >> 3"
- ld t2, intseg, [8, t1, rcx], dataSize=8, addressSize=4
+ ld t2, intseg, [8, rcx, t0], "IntAddrPrefixMSR << 3", \
+ dataSize=8, addressSize=8
mov rax, rax, t2, dataSize=4
srli t2, t2, 32, dataSize=8
mov rdx, rdx, t2, dataSize=4
@@ -93,10 +93,18 @@ def macroop RDMSR
def macroop WRMSR
{
- limm t1, "IntAddrPrefixMSR >> 3"
mov t2, t2, rax, dataSize=4
slli t3, rdx, 32, dataSize=8
or t2, t2, t3, dataSize=8
- st t2, intseg, [8, t1, rcx], dataSize=8, addressSize=4
+ st t2, intseg, [8, rcx, t0], "IntAddrPrefixMSR << 3", \
+ dataSize=8, addressSize=8
+};
+
+def macroop RDTSC
+{
+ rdtsc t1
+ mov rax, rax, t1, dataSize=4
+ srli t1, t1, 32, dataSize=8
+ mov rdx, rdx, t1, dataSize=4
};
'''
diff --git a/src/arch/x86/isa/insts/system/segmentation.py b/src/arch/x86/isa/insts/system/segmentation.py
index 97846f79c..acbca9f6e 100644
--- a/src/arch/x86/isa/insts/system/segmentation.py
+++ b/src/arch/x86/isa/insts/system/segmentation.py
@@ -56,7 +56,7 @@
microcode = '''
def macroop LGDT_M
{
- .adjust_env oszForPseudoDesc
+ .adjust_env maxOsz
# Get the limit
ld t1, seg, sib, disp, dataSize=2
@@ -68,7 +68,7 @@ def macroop LGDT_M
def macroop LGDT_P
{
- .adjust_env oszForPseudoDesc
+ .adjust_env maxOsz
rdip t7
# Get the limit
@@ -86,34 +86,34 @@ def macroop LGDT_P
def macroop LGDT_16_M
{
- .adjust_env oszForPseudoDesc
+ .adjust_env maxOsz
# Get the limit
ld t1, seg, sib, disp, dataSize=2
# Get the base
ld t2, seg, sib, 'adjustedDisp + 2', dataSize=4
- zexti t2, t2, 23
+ zexti t2, t2, 23, dataSize=8
wrbase tsg, t2
wrlimit tsg, t1
};
def macroop LGDT_16_P
{
- .adjust_env oszForPseudoDesc
+ .adjust_env maxOsz
rdip t7
# Get the limit
ld t1, seg, riprel, disp, dataSize=2
# Get the base
ld t2, seg, riprel, 'adjustedDisp + 2', dataSize=4
- zexti t2, t2, 23
+ zexti t2, t2, 23, dataSize=8
wrbase tsg, t2
wrlimit tsg, t1
};
def macroop LIDT_M
{
- .adjust_env oszForPseudoDesc
+ .adjust_env maxOsz
# Get the limit
ld t1, seg, sib, disp, dataSize=2
@@ -125,7 +125,7 @@ def macroop LIDT_M
def macroop LIDT_P
{
- .adjust_env oszForPseudoDesc
+ .adjust_env maxOsz
rdip t7
# Get the limit
@@ -143,28 +143,135 @@ def macroop LIDT_P
def macroop LIDT_16_M
{
- .adjust_env oszForPseudoDesc
+ .adjust_env maxOsz
# Get the limit
ld t1, seg, sib, disp, dataSize=2
# Get the base
ld t2, seg, sib, 'adjustedDisp + 2', dataSize=4
- zexti t2, t2, 23
+ zexti t2, t2, 23, dataSize=8
wrbase idtr, t2
wrlimit idtr, t1
};
def macroop LIDT_16_P
{
- .adjust_env oszForPseudoDesc
+ .adjust_env maxOsz
rdip t7
# Get the limit
ld t1, seg, riprel, disp, dataSize=2
# Get the base
ld t2, seg, riprel, 'adjustedDisp + 2', dataSize=4
- zexti t2, t2, 23
+ zexti t2, t2, 23, dataSize=8
wrbase idtr, t2
wrlimit idtr, t1
};
+
+def macroop LTR_R
+{
+ chks reg, t0, TRCheck
+ limm t4, 0
+ srli t4, reg, 3, dataSize=2
+ ldst t1, tsg, [8, t4, t0], dataSize=8
+ ld t2, tsg, [8, t4, t0], 8, dataSize=8
+ chks reg, t1, TSSCheck
+ wrdh t3, t1, t2
+ wrdl tr, t1, reg
+ wrbase tr, t3, dataSize=8
+ ori t1, t1, (1 << 9)
+ st t1, tsg, [8, t4, t0], dataSize=8
+};
+
+def macroop LTR_M
+{
+ ld t5, seg, sib, disp, dataSize=2
+ chks t5, t0, TRCheck
+ limm t4, 0
+ srli t4, t5, 3, dataSize=2
+ ldst t1, tsg, [8, t4, t0], dataSize=8
+ ld t2, tsg, [8, t4, t0], 8, dataSize=8
+ chks t5, t1, TSSCheck
+ wrdh t3, t1, t2
+ wrdl tr, t1, t5
+ wrbase tr, t3, dataSize=8
+ ori t1, t1, (1 << 9)
+ st t1, tsg, [8, t4, t0], dataSize=8
+};
+
+def macroop LTR_P
+{
+ rdip t7
+ ld t5, seg, riprel, disp, dataSize=2
+ chks t5, t0, TRCheck
+ limm t4, 0
+ srli t4, t5, 3, dataSize=2
+ ldst t1, tsg, [8, t4, t0], dataSize=8
+ ld t2, tsg, [8, t4, t0], 8, dataSize=8
+ chks t5, t1, TSSCheck
+ wrdh t3, t1, t2
+ wrdl tr, t1, t5
+ wrbase tr, t3, dataSize=8
+ ori t1, t1, (1 << 9)
+ st t1, tsg, [8, t4, t0], dataSize=8
+};
+
+def macroop LLDT_R
+{
+ chks reg, t0, InGDTCheck, flags=(EZF,)
+ br label("end"), flags=(CEZF,)
+ limm t4, 0
+ srli t4, reg, 3, dataSize=2
+ ldst t1, tsg, [8, t4, t0], dataSize=8
+ ld t2, tsg, [8, t4, t0], 8, dataSize=8
+ chks reg, t1, LDTCheck
+ wrdh t3, t1, t2
+ wrdl tr, t1, reg
+ wrbase tr, t3, dataSize=8
+end:
+ fault "NoFault"
+};
+
+def macroop LLDT_M
+{
+ ld t5, seg, sib, disp, dataSize=2
+ chks t5, t0, InGDTCheck, flags=(EZF,)
+ br label("end"), flags=(CEZF,)
+ limm t4, 0
+ srli t4, t5, 3, dataSize=2
+ ldst t1, tsg, [8, t4, t0], dataSize=8
+ ld t2, tsg, [8, t4, t0], 8, dataSize=8
+ chks t5, t1, LDTCheck
+ wrdh t3, t1, t2
+ wrdl tr, t1, t5
+ wrbase tr, t3, dataSize=8
+end:
+ fault "NoFault"
+};
+
+def macroop LLDT_P
+{
+ rdip t7
+ ld t5, seg, riprel, disp, dataSize=2
+ chks t5, t0, InGDTCheck, flags=(EZF,)
+ br label("end"), flags=(CEZF,)
+ limm t4, 0
+ srli t4, t5, 3, dataSize=2
+ ldst t1, tsg, [8, t4, t0], dataSize=8
+ ld t2, tsg, [8, t4, t0], 8, dataSize=8
+ chks t5, t1, LDTCheck
+ wrdh t3, t1, t2
+ wrdl tr, t1, t5
+ wrbase tr, t3, dataSize=8
+end:
+ fault "NoFault"
+};
+
+def macroop SWAPGS
+{
+ rdval t1, kernel_gs_base, dataSize=8
+ rdbase t2, gs, dataSize=8
+ wrbase gs, t1, dataSize=8
+ wrval kernel_gs_base, t2, dataSize=8
+};
'''
diff --git a/src/arch/x86/isa/macroop.isa b/src/arch/x86/isa/macroop.isa
index 4818b926c..3a836ff68 100644
--- a/src/arch/x86/isa/macroop.isa
+++ b/src/arch/x86/isa/macroop.isa
@@ -72,41 +72,13 @@ def template MacroExecPanic {{
output header {{
// Base class for combinationally generated macroops
- class Macroop : public StaticInst
+ class Macroop : public X86ISA::MacroopBase
{
- protected:
- const uint32_t numMicroops;
-
- //Constructor.
+ public:
Macroop(const char *mnem, ExtMachInst _machInst,
- uint32_t _numMicroops)
- : StaticInst(mnem, _machInst, No_OpClass),
- numMicroops(_numMicroops)
- {
- assert(numMicroops);
- microops = new StaticInstPtr[numMicroops];
- flags[IsMacroop] = true;
- }
-
- ~Macroop()
- {
- delete [] microops;
- }
-
- StaticInstPtr * microops;
-
- StaticInstPtr fetchMicroop(MicroPC microPC)
- {
- assert(microPC < numMicroops);
- return microops[microPC];
- }
-
- std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const
- {
- return mnemonic;
- }
-
+ uint32_t _numMicroops, X86ISA::EmulEnv _env)
+ : MacroopBase(mnem, _machInst, _numMicroops, _env)
+ {}
%(MacroExecPanic)s
};
}};
@@ -130,22 +102,42 @@ def template MacroDeclare {{
%(declareLabels)s
public:
// Constructor.
- %(class_name)s(ExtMachInst machInst, X86ISA::EmulEnv env);
+ %(class_name)s(ExtMachInst machInst, X86ISA::EmulEnv _env);
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
};
}};
+def template MacroDisassembly {{
+ std::string
+ X86Macroop::%(class_name)s::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream out;
+ out << mnemonic << "\t";
+
+ int regSize = %(regSize)s;
+ %(disassembly)s
+ // Shut up gcc.
+ regSize = regSize;
+ return out.str();
+ }
+}};
+
// Basic instruction class constructor template.
def template MacroConstructor {{
inline X86Macroop::%(class_name)s::%(class_name)s(
- ExtMachInst machInst, EmulEnv env)
- : %(base_class)s("%(mnemonic)s", machInst, %(num_microops)s)
+ ExtMachInst machInst, EmulEnv _env)
+ : %(base_class)s("%(mnemonic)s", machInst, %(num_microops)s, _env)
{
%(adjust_env)s;
%(adjust_imm)s;
%(adjust_disp)s;
- %(do_modrm)s;
+ %(init_env)s;
%(constructor)s;
+ const char *macrocodeBlock = "%(class_name)s";
//alloc_microops is the code that sets up the microops
//array in the parent class.
%(alloc_microops)s;
@@ -174,7 +166,7 @@ let {{
}
self.declared = False
self.adjust_env = ""
- self.doModRM = ""
+ self.init_env = ""
self.adjust_imm = '''
uint64_t adjustedImm = IMMEDIATE;
//This is to pacify gcc in case the immediate isn't used.
@@ -186,7 +178,12 @@ let {{
adjustedDisp = adjustedDisp;
'''
def getAllocator(self, env):
- return "new X86Macroop::%s(machInst, %s)" % (self.name, env.getAllocator())
+ return "new X86Macroop::%s(machInst, %s)" % \
+ (self.name, env.getAllocator())
+ def getMnemonic(self):
+ mnemonic = self.name.lower()
+ mnemonic = re.match(r'[^_]*', mnemonic).group(0)
+ return mnemonic
def getDeclaration(self):
#FIXME This first parameter should be the mnemonic. I need to
#write some code which pulls that out
@@ -194,32 +191,46 @@ let {{
for (label, microop) in self.labels.items():
declareLabels += "const static uint64_t label_%s = %d;\n" \
% (label, microop.micropc)
- iop = InstObjParams(self.name, self.name, "Macroop",
+ iop = InstObjParams(self.getMnemonic(), self.name, "Macroop",
{"code" : "",
"declareLabels" : declareLabels
})
return MacroDeclare.subst(iop);
- def getDefinition(self):
+ def getDefinition(self, env):
#FIXME This first parameter should be the mnemonic. I need to
#write some code which pulls that out
numMicroops = len(self.microops)
allocMicroops = ''
micropc = 0
for op in self.microops:
+ isLast = (micropc == numMicroops - 1)
allocMicroops += \
"microops[%d] = %s;\n" % \
- (micropc, op.getAllocator(True, False,
- micropc == 0,
- micropc == numMicroops - 1))
+ (micropc, op.getAllocator(True, not isLast,
+ micropc == 0, isLast))
micropc += 1
- iop = InstObjParams(self.name, self.name, "Macroop",
+ if env.useStackSize:
+ useStackSize = "true"
+ else:
+ useStackSize = "false"
+ if env.memoryInst:
+ memoryInst = "true"
+ else:
+ memoryInst = "false"
+ regSize = '''(%s || (env.base == INTREG_RSP && %s) ?
+ env.stackSize :
+ env.dataSize)''' % (useStackSize, memoryInst)
+ iop = InstObjParams(self.getMnemonic(), self.name, "Macroop",
{"code" : "", "num_microops" : numMicroops,
"alloc_microops" : allocMicroops,
"adjust_env" : self.adjust_env,
"adjust_imm" : self.adjust_imm,
"adjust_disp" : self.adjust_disp,
- "do_modrm" : self.doModRM})
- return MacroConstructor.subst(iop);
+ "disassembly" : env.disassembly,
+ "regSize" : regSize,
+ "init_env" : self.initEnv})
+ return MacroConstructor.subst(iop) + \
+ MacroDisassembly.subst(iop);
}};
let {{
@@ -235,6 +246,16 @@ let {{
self.dataSize = "OPSIZE"
self.stackSize = "STACKSIZE"
self.doModRM = False
+ self.disassembly = ""
+ self.firstArgument = True
+ self.useStackSize = False
+ self.memoryInst = False
+
+ def addToDisassembly(self, code):
+ if not self.firstArgument:
+ self.disassembly += "out << \", \";\n"
+ self.firstArgument = False
+ self.disassembly += code
def getAllocator(self):
if self.size == 'b':
@@ -283,6 +304,7 @@ let {{
let {{
doModRMString = "env.doModRM(machInst);\n"
+ noModRMString = "env.setSeg(machInst);\n"
def genMacroop(Name, env):
blocks = OutputBlocks()
if not macroopDict.has_key(Name):
@@ -290,9 +312,11 @@ let {{
macroop = macroopDict[Name]
if not macroop.declared:
if env.doModRM:
- macroop.doModRM = doModRMString
+ macroop.initEnv = doModRMString
+ else:
+ macroop.initEnv = noModRMString
blocks.header_output = macroop.getDeclaration()
- blocks.decoder_output = macroop.getDefinition()
+ blocks.decoder_output = macroop.getDefinition(env)
macroop.declared = True
blocks.decode_block = "return %s;\n" % macroop.getAllocator(env)
return blocks
diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa
index 78ae34f52..c7c6dae2e 100644
--- a/src/arch/x86/isa/microasm.isa
+++ b/src/arch/x86/isa/microasm.isa
@@ -1,6 +1,6 @@
// -*- mode:c++ -*-
-// Copyright (c) 2007 The Hewlett-Packard Development Company
+// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@@ -64,23 +64,32 @@
//Include code to build macroops in both C++ and python.
##include "macroop.isa"
+//Include code to fill out the microcode ROM in both C++ and python.
+##include "rom.isa"
+
let {{
import sys
sys.path[0:0] = ["src/arch/x86/isa/"]
from insts import microcode
# print microcode
- from micro_asm import MicroAssembler, Rom_Macroop, Rom
- mainRom = Rom('main ROM')
+ from micro_asm import MicroAssembler, Rom_Macroop
+ mainRom = X86MicrocodeRom('main ROM')
assembler = MicroAssembler(X86Macroop, microopClasses, mainRom, Rom_Macroop)
# Add in symbols for the microcode registers
- for num in range(15):
+ for num in range(16):
assembler.symbols["t%d" % num] = "NUM_INTREGS+%d" % num
- for num in range(7):
+ for num in range(8):
assembler.symbols["ufp%d" % num] = "FLOATREG_MICROFP(%d)" % num
# Add in symbols for the segment descriptor registers
- for letter in ("C", "D", "E", "F", "G", "S"):
+ for letter in ("C", "D", "E", "F", "G", "H", "S"):
assembler.symbols["%ss" % letter.lower()] = "SEGMENT_REG_%sS" % letter
+ # Add in symbols for the various checks of segment selectors.
+ for check in ("NoCheck", "CSCheck", "CallGateCheck", "IntGateCheck",
+ "SoftIntGateCheck", "SSCheck", "IretCheck", "IntCSCheck",
+ "TRCheck", "TSSCheck", "InGDTCheck", "LDTCheck"):
+ assembler.symbols[check] = "Seg%s" % check
+
for reg in ("TR", "IDTR"):
assembler.symbols[reg.lower()] = "SYS_SEGMENT_REG_%s" % reg
@@ -129,13 +138,15 @@ let {{
# like the internal segment above
assembler.symbols["flatseg"] = "SEGMENT_REG_LS"
- for reg in ('ax', 'bx', 'cx', 'dx', 'sp', 'bp', 'si', 'di'):
+ for reg in ('ax', 'bx', 'cx', 'dx', 'sp', 'bp', 'si', 'di', \
+ '8', '9', '10', '11', '12', '13', '14', '15'):
assembler.symbols["r%s" % reg] = "INTREG_R%s" % reg.upper()
- for reg in range(15):
+ for reg in range(16):
assembler.symbols["cr%d" % reg] = "MISCREG_CR%d" % reg
- for flag in ('CF', 'PF', 'ECF', 'AF', 'EZF', 'ZF', 'SF', 'OF'):
+ for flag in ('CF', 'PF', 'ECF', 'AF', 'EZF', 'ZF', 'SF', 'OF', \
+ 'TF', 'IF', 'NT', 'RF', 'VM', 'AC', 'VIF', 'VIP', 'ID'):
assembler.symbols[flag] = flag + "Bit"
for cond in ('True', 'False', 'ECF', 'EZF', 'SZnZF',
@@ -150,6 +161,11 @@ let {{
assembler.symbols["CTrue"] = "ConditionTests::True"
assembler.symbols["CFalse"] = "ConditionTests::False"
+ for reg in ('sysenter_cs', 'sysenter_esp', 'sysenter_eip',
+ 'star', 'lstar', 'cstar', 'sf_mask',
+ 'kernel_gs_base'):
+ assembler.symbols[reg] = "MISCREG_%s" % reg.upper()
+
# Code literal which forces a default 64 bit operand size in 64 bit mode.
assembler.symbols["oszIn64Override"] = '''
if (machInst.mode.submode == SixtyFourBitMode &&
@@ -157,7 +173,7 @@ let {{
env.dataSize = 8;
'''
- assembler.symbols["oszForPseudoDesc"] = '''
+ assembler.symbols["maxOsz"] = '''
if (machInst.mode.submode == SixtyFourBitMode)
env.dataSize = 8;
else
@@ -174,10 +190,23 @@ let {{
assembler.symbols["label"] = labeler
+ def rom_labeler(labelStr):
+ return "romMicroPC(RomLabels::extern_label_%s)" % labelStr
+
+ assembler.symbols["rom_label"] = rom_labeler
+
+ def rom_local_labeler(labelStr):
+ return "romMicroPC(RomLabels::label_%s)" % labelStr
+
+ assembler.symbols["rom_local_label"] = rom_local_labeler
+
def stack_index(index):
return "(NUM_FLOATREGS + (((%s) + 8) %% 8))" % index
assembler.symbols["st"] = stack_index
macroopDict = assembler.assemble(microcode)
+
+ decoder_output += mainRom.getDefinition()
+ header_output += mainRom.getDeclaration()
}};
diff --git a/src/arch/x86/isa/microops/base.isa b/src/arch/x86/isa/microops/base.isa
index 75658a26c..f1007bf71 100644
--- a/src/arch/x86/isa/microops/base.isa
+++ b/src/arch/x86/isa/microops/base.isa
@@ -69,6 +69,29 @@ let {{
let {{
class X86Microop(object):
+
+ generatorNameTemplate = "generate_%s_%d"
+
+ generatorTemplate = '''
+ StaticInstPtr
+ ''' + generatorNameTemplate + '''(StaticInstPtr curMacroop)
+ {
+ static const char *macrocodeBlock = romMnemonic;
+ static const ExtMachInst dummyExtMachInst;
+ static const EmulEnv dummyEmulEnv(0, 0, 1, 1, 1);
+
+ Macroop * macroop = dynamic_cast<Macroop *>(curMacroop.get());
+ const ExtMachInst &machInst =
+ macroop ? macroop->getExtMachInst() : dummyExtMachInst;
+ const EmulEnv &env =
+ macroop ? macroop->getEmulEnv() : dummyEmulEnv;
+ // env may not be used in the microop's constructor.
+ RegIndex reg = env.reg;
+ reg = reg;
+ using namespace RomLabels;
+ return %s;
+ }
+ '''
def __init__(self, name):
self.name = name
@@ -91,4 +114,12 @@ let {{
def getAllocator(self, mnemonic, *microFlags):
return 'new %s(machInst, %s)' % \
(self.className, mnemonic, self.microFlagsText(microFlags))
+
+ def getGeneratorDef(self, micropc):
+ return self.generatorTemplate % \
+ (self.className, micropc, \
+ self.getAllocator(True, True, False, False))
+
+ def getGenerator(self, micropc):
+ return self.generatorNameTemplate % (self.className, micropc)
}};
diff --git a/src/arch/x86/isa/microops/debug.isa b/src/arch/x86/isa/microops/debug.isa
new file mode 100644
index 000000000..38fee59bb
--- /dev/null
+++ b/src/arch/x86/isa/microops/debug.isa
@@ -0,0 +1,229 @@
+// Copyright (c) 2008 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer. Redistributions
+// in binary form must reproduce the above copyright notice, this list of
+// conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution. Neither the name of
+// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Gabe Black
+
+//////////////////////////////////////////////////////////////////////////
+//
+// Debug Microops
+//
+//////////////////////////////////////////////////////////////////////////
+
+output header {{
+ class MicroDebugBase : public X86ISA::X86MicroopBase
+ {
+ protected:
+ std::string message;
+ uint8_t cc;
+
+ public:
+ MicroDebugBase(ExtMachInst _machInst, const char * mnem,
+ const char * instMnem,
+ bool isMicro, bool isDelayed, bool isFirst, bool isLast,
+ std::string _message, uint8_t _cc);
+
+ MicroDebugBase(ExtMachInst _machInst, const char * mnem,
+ const char * instMnem, std::string _message, uint8_t _cc);
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+ };
+}};
+
+def template MicroDebugDeclare {{
+ class %(class_name)s : public %(base_class)s
+ {
+ private:
+ void buildMe();
+ public:
+ %(class_name)s(ExtMachInst _machInst, const char * instMnem,
+ bool isMicro, bool isDelayed, bool isFirst, bool isLast,
+ std::string _message, uint8_t _cc);
+
+ %(class_name)s(ExtMachInst _machInst, const char * instMnem,
+ std::string _message, uint8_t _cc);
+
+ %(BasicExecDeclare)s
+ };
+}};
+
+def template MicroDebugExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ %(op_decl)s
+ %(op_rd)s
+ if (%(cond_test)s) {
+ %(func)s("%s\n", message);
+ }
+ return NoFault;
+ }
+}};
+
+output decoder {{
+ inline MicroDebugBase::MicroDebugBase(
+ ExtMachInst machInst, const char * mnem, const char * instMnem,
+ std::string _message, uint8_t _cc) :
+ X86MicroopBase(machInst, mnem, instMnem,
+ false, false, false, false, No_OpClass),
+ message(_message), cc(_cc)
+ {
+ }
+
+ inline MicroDebugBase::MicroDebugBase(
+ ExtMachInst machInst, const char * mnem, const char * instMnem,
+ bool isMicro, bool isDelayed, bool isFirst, bool isLast,
+ std::string _message, uint8_t _cc) :
+ X86MicroopBase(machInst, mnem, instMnem,
+ isMicro, isDelayed, isFirst, isLast, No_OpClass),
+ message(_message), cc(_cc)
+ {
+ }
+}};
+
+def template MicroDebugConstructor {{
+
+ inline void %(class_name)s::buildMe()
+ {
+ %(constructor)s;
+ }
+
+ inline %(class_name)s::%(class_name)s(
+ ExtMachInst machInst, const char * instMnem,
+ std::string _message, uint8_t _cc) :
+ %(base_class)s(machInst, "%(func)s", instMnem, _message, _cc)
+ {
+ buildMe();
+ }
+
+ inline %(class_name)s::%(class_name)s(
+ ExtMachInst machInst, const char * instMnem,
+ bool isMicro, bool isDelayed, bool isFirst, bool isLast,
+ std::string _message, uint8_t _cc) :
+ %(base_class)s(machInst, "%(func)s", instMnem,
+ isMicro, isDelayed, isFirst, isLast, _message, _cc)
+ {
+ buildMe();
+ }
+}};
+
+output decoder {{
+ std::string MicroDebugBase::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+
+ printMnemonic(response, instMnem, mnemonic);
+ response << "\"" << message << "\"";
+
+ return response.str();
+ }
+}};
+
+let {{
+ class MicroDebug(X86Microop):
+ def __init__(self, message, flags=None):
+ self.message = message
+ if flags:
+ if not isinstance(flags, (list, tuple)):
+ raise Exception, "flags must be a list or tuple of flags"
+ self.cond = " | ".join(flags)
+ self.className += "Flags"
+ else:
+ self.cond = "0"
+
+ def getAllocator(self, *microFlags):
+ allocator = '''new %(class_name)s(machInst, macrocodeBlock
+ %(flags)s, "%(message)s", %(cc)s)''' % {
+ "class_name" : self.className,
+ "flags" : self.microFlagsText(microFlags),
+ "message" : self.message,
+ "cc" : self.cond}
+ return allocator
+
+ exec_output = ""
+ header_output = ""
+ decoder_output = ""
+
+ def buildDebugMicro(func):
+ global exec_output, header_output, decoder_output
+
+ iop = InstObjParams(func, "Micro%sFlags" % func.capitalize(),
+ "MicroDebugBase",
+ {"code": "",
+ "func": func,
+ "cond_test": "checkCondition(ccFlagBits, cc)"})
+ exec_output += MicroDebugExecute.subst(iop)
+ header_output += MicroDebugDeclare.subst(iop)
+ decoder_output += MicroDebugConstructor.subst(iop)
+
+ iop = InstObjParams(func, "Micro%s" % func.capitalize(),
+ "MicroDebugBase",
+ {"code": "",
+ "func": func,
+ "cond_test": "true"})
+ exec_output += MicroDebugExecute.subst(iop)
+ header_output += MicroDebugDeclare.subst(iop)
+ decoder_output += MicroDebugConstructor.subst(iop)
+
+ class MicroDebugChild(MicroDebug):
+ className = "Micro%s" % func.capitalize()
+
+ global microopClasses
+ microopClasses[func] = MicroDebugChild
+
+ buildDebugMicro("panic")
+ buildDebugMicro("fatal")
+ buildDebugMicro("warn")
+ buildDebugMicro("warn_once")
+}};
diff --git a/src/arch/x86/isa/microops/fpop.isa b/src/arch/x86/isa/microops/fpop.isa
index 2919aa277..d4acfdbf4 100644
--- a/src/arch/x86/isa/microops/fpop.isa
+++ b/src/arch/x86/isa/microops/fpop.isa
@@ -245,7 +245,7 @@ let {{
self.className += "Top"
def getAllocator(self, *microFlags):
- return '''new %(class_name)s(machInst, mnemonic
+ return '''new %(class_name)s(machInst, macrocodeBlock
%(flags)s, %(src1)s, %(src2)s, %(dest)s,
%(dataSize)s, %(spm)d)''' % {
"class_name" : self.className,
diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa
index cb63e7cd9..af94cf31e 100644
--- a/src/arch/x86/isa/microops/ldstop.isa
+++ b/src/arch/x86/isa/microops/ldstop.isa
@@ -124,14 +124,16 @@ def template MicroLeaDeclare {{
uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment,
RegIndex _data,
- uint8_t _dataSize, uint8_t _addressSize);
+ uint8_t _dataSize, uint8_t _addressSize,
+ Request::FlagsType _memFlags);
%(class_name)s(ExtMachInst _machInst,
const char * instMnem,
uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment,
RegIndex _data,
- uint8_t _dataSize, uint8_t _addressSize);
+ uint8_t _dataSize, uint8_t _addressSize,
+ Request::FlagsType _memFlags);
%(BasicExecDeclare)s
};
@@ -151,11 +153,13 @@ def template MicroLoadExecute {{
%(ea_code)s;
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
- fault = read(xc, EA, Mem, (%(mem_flags)s) | segment);
+ fault = read(xc, EA, Mem, memFlags);
- if(fault == NoFault)
- {
+ if (fault == NoFault) {
%(code)s;
+ } else if (memFlags & Request::PF_EXCLUSIVE) {
+ // For prefetches, ignore any faults/exceptions.
+ return NoFault;
}
if(fault == NoFault)
{
@@ -178,7 +182,7 @@ def template MicroLoadInitiateAcc {{
%(ea_code)s;
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
- fault = read(xc, EA, Mem, (%(mem_flags)s) | segment);
+ fault = read(xc, EA, Mem, memFlags);
return fault;
}
@@ -194,7 +198,7 @@ def template MicroLoadCompleteAcc {{
%(op_decl)s;
%(op_rd)s;
- Mem = pkt->get<typeof(Mem)>();
+ Mem = get(pkt);
%(code)s;
@@ -225,9 +229,10 @@ def template MicroStoreExecute {{
if(fault == NoFault)
{
- fault = write(xc, Mem, EA, (%(mem_flags)s) | segment);
+ fault = write(xc, Mem, EA, memFlags);
if(fault == NoFault)
{
+ %(post_code)s;
%(op_wb)s;
}
}
@@ -252,20 +257,20 @@ def template MicroStoreInitiateAcc {{
if(fault == NoFault)
{
- fault = write(xc, Mem, EA, (%(mem_flags)s) | segment);
- if(fault == NoFault)
- {
- %(op_wb)s;
- }
+ write(xc, Mem, EA, memFlags);
}
return fault;
}
}};
def template MicroStoreCompleteAcc {{
- Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
- Trace::InstRecord * traceData) const
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
+ %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const
{
+ %(op_decl)s;
+ %(op_rd)s;
+ %(complete_code)s;
+ %(op_wb)s;
return NoFault;
}
}};
@@ -295,14 +300,16 @@ def template MicroLdStOpDeclare {{
uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment,
RegIndex _data,
- uint8_t _dataSize, uint8_t _addressSize);
+ uint8_t _dataSize, uint8_t _addressSize,
+ Request::FlagsType _memFlags);
%(class_name)s(ExtMachInst _machInst,
const char * instMnem,
uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment,
RegIndex _data,
- uint8_t _dataSize, uint8_t _addressSize);
+ uint8_t _dataSize, uint8_t _addressSize,
+ Request::FlagsType _memFlags);
%(BasicExecDeclare)s
@@ -324,12 +331,13 @@ def template MicroLdStOpConstructor {{
uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment,
RegIndex _data,
- uint8_t _dataSize, uint8_t _addressSize) :
+ uint8_t _dataSize, uint8_t _addressSize,
+ Request::FlagsType _memFlags) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
false, false, false, false,
_scale, _index, _base,
_disp, _segment, _data,
- _dataSize, _addressSize, %(op_class)s)
+ _dataSize, _addressSize, _memFlags, %(op_class)s)
{
buildMe();
}
@@ -340,12 +348,13 @@ def template MicroLdStOpConstructor {{
uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment,
RegIndex _data,
- uint8_t _dataSize, uint8_t _addressSize) :
+ uint8_t _dataSize, uint8_t _addressSize,
+ Request::FlagsType _memFlags) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
isMicro, isDelayed, isFirst, isLast,
_scale, _index, _base,
_disp, _segment, _data,
- _dataSize, _addressSize, %(op_class)s)
+ _dataSize, _addressSize, _memFlags, %(op_class)s)
{
buildMe();
}
@@ -353,26 +362,35 @@ def template MicroLdStOpConstructor {{
let {{
class LdStOp(X86Microop):
- def __init__(self, data, segment, addr, disp, dataSize, addressSize):
+ def __init__(self, data, segment, addr, disp,
+ dataSize, addressSize, baseFlags, atCPL0, prefetch):
self.data = data
[self.scale, self.index, self.base] = addr
self.disp = disp
self.segment = segment
self.dataSize = dataSize
self.addressSize = addressSize
+ self.memFlags = baseFlags
+ if atCPL0:
+ self.memFlags += " | (CPL0FlagBit << FlagShift)"
+ if prefetch:
+ self.memFlags += " | Request::PF_EXCLUSIVE"
+ self.memFlags += " | (machInst.legacy.addr ? " + \
+ "(AddrSizeFlagBit << FlagShift) : 0)"
def getAllocator(self, *microFlags):
- allocator = '''new %(class_name)s(machInst, mnemonic
+ allocator = '''new %(class_name)s(machInst, macrocodeBlock
%(flags)s, %(scale)s, %(index)s, %(base)s,
%(disp)s, %(segment)s, %(data)s,
- %(dataSize)s, %(addressSize)s)''' % {
+ %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % {
"class_name" : self.className,
"flags" : self.microFlagsText(microFlags),
"scale" : self.scale, "index" : self.index,
"base" : self.base,
"disp" : self.disp,
"segment" : self.segment, "data" : self.data,
- "dataSize" : self.dataSize, "addressSize" : self.addressSize}
+ "dataSize" : self.dataSize, "addressSize" : self.addressSize,
+ "memFlags" : self.memFlags}
return allocator
}};
@@ -384,9 +402,11 @@ let {{
decoder_output = ""
exec_output = ""
- calculateEA = "EA = SegBase + scale * Index + Base + disp;"
+ calculateEA = '''
+ EA = bits(SegBase + scale * Index + Base + disp, addressSize * 8 - 1, 0);
+ '''
- def defineMicroLoadOp(mnemonic, code, mem_flags=0):
+ def defineMicroLoadOp(mnemonic, code, mem_flags="0"):
global header_output
global decoder_output
global exec_output
@@ -397,8 +417,7 @@ let {{
# Build up the all register version of this micro op
iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
{"code": code,
- "ea_code": calculateEA,
- "mem_flags": mem_flags})
+ "ea_code": calculateEA})
header_output += MicroLdStOpDeclare.subst(iop)
decoder_output += MicroLdStOpConstructor.subst(iop)
exec_output += MicroLoadExecute.subst(iop)
@@ -407,19 +426,24 @@ let {{
class LoadOp(LdStOp):
def __init__(self, data, segment, addr, disp = 0,
- dataSize="env.dataSize", addressSize="env.addressSize"):
- super(LoadOp, self).__init__(data, segment,
- addr, disp, dataSize, addressSize)
+ dataSize="env.dataSize",
+ addressSize="env.addressSize",
+ atCPL0=False, prefetch=False):
+ super(LoadOp, self).__init__(data, segment, addr,
+ disp, dataSize, addressSize, mem_flags,
+ atCPL0, prefetch)
self.className = Name
self.mnemonic = name
microopClasses[name] = LoadOp
defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);')
- defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);', 'StoreCheck')
+ defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);',
+ 'X86ISA::StoreCheck')
defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;')
- def defineMicroStoreOp(mnemonic, code, mem_flags=0):
+ def defineMicroStoreOp(mnemonic, code, \
+ postCode="", completeCode="", mem_flags="0"):
global header_output
global decoder_output
global exec_output
@@ -430,8 +454,9 @@ let {{
# Build up the all register version of this micro op
iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
{"code": code,
- "ea_code": calculateEA,
- "mem_flags": mem_flags})
+ "post_code": postCode,
+ "complete_code": completeCode,
+ "ea_code": calculateEA})
header_output += MicroLdStOpDeclare.subst(iop)
decoder_output += MicroLdStOpConstructor.subst(iop)
exec_output += MicroStoreExecute.subst(iop)
@@ -440,26 +465,26 @@ let {{
class StoreOp(LdStOp):
def __init__(self, data, segment, addr, disp = 0,
- dataSize="env.dataSize", addressSize="env.addressSize"):
- super(StoreOp, self).__init__(data, segment,
- addr, disp, dataSize, addressSize)
+ dataSize="env.dataSize",
+ addressSize="env.addressSize",
+ atCPL0=False):
+ super(StoreOp, self).__init__(data, segment, addr,
+ disp, dataSize, addressSize, mem_flags, atCPL0, False)
self.className = Name
self.mnemonic = name
microopClasses[name] = StoreOp
- defineMicroStoreOp('St', 'Mem = Data;')
+ defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);')
defineMicroStoreOp('Stfp', 'Mem = FpData.uqw;')
- defineMicroStoreOp('Stupd', '''
- Mem = Data;
- Base = merge(Base, EA - SegBase, addressSize);
- ''');
-
+ defineMicroStoreOp('Stupd', 'Mem = pick(Data, 2, dataSize);',
+ 'Base = merge(Base, EA - SegBase, addressSize);',
+ 'Base = merge(Base, pkt->req->getVaddr() - SegBase, addressSize);');
+ defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS")
iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
{"code": "Data = merge(Data, EA, dataSize);",
- "ea_code": calculateEA,
- "mem_flags": 0})
+ "ea_code": calculateEA})
header_output += MicroLeaDeclare.subst(iop)
decoder_output += MicroLdStOpConstructor.subst(iop)
exec_output += MicroLeaExecute.subst(iop)
@@ -468,7 +493,7 @@ let {{
def __init__(self, data, segment, addr, disp = 0,
dataSize="env.dataSize", addressSize="env.addressSize"):
super(LeaOp, self).__init__(data, segment,
- addr, disp, dataSize, addressSize)
+ addr, disp, dataSize, addressSize, "0", False, False)
self.className = "Lea"
self.mnemonic = "lea"
@@ -477,38 +502,28 @@ let {{
iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp',
{"code": "xc->demapPage(EA, 0);",
- "ea_code": calculateEA,
- "mem_flags": 0})
+ "ea_code": calculateEA})
header_output += MicroLeaDeclare.subst(iop)
decoder_output += MicroLdStOpConstructor.subst(iop)
exec_output += MicroLeaExecute.subst(iop)
class TiaOp(LdStOp):
def __init__(self, segment, addr, disp = 0,
- dataSize="env.dataSize", addressSize="env.addressSize"):
+ dataSize="env.dataSize",
+ addressSize="env.addressSize"):
super(TiaOp, self).__init__("NUM_INTREGS", segment,
- addr, disp, dataSize, addressSize)
+ addr, disp, dataSize, addressSize, "0", False, False)
self.className = "Tia"
self.mnemonic = "tia"
microopClasses["tia"] = TiaOp
- iop = InstObjParams("cda", "Cda", 'X86ISA::LdStOp',
- {"code": '''
- Addr paddr;
- fault = xc->translateDataWriteAddr(EA, paddr,
- dataSize, (1 << segment));
- ''',
- "ea_code": calculateEA})
- header_output += MicroLeaDeclare.subst(iop)
- decoder_output += MicroLdStOpConstructor.subst(iop)
- exec_output += MicroLeaExecute.subst(iop)
-
class CdaOp(LdStOp):
def __init__(self, segment, addr, disp = 0,
- dataSize="env.dataSize", addressSize="env.addressSize"):
+ dataSize="env.dataSize",
+ addressSize="env.addressSize", atCPL0=False):
super(CdaOp, self).__init__("NUM_INTREGS", segment,
- addr, disp, dataSize, addressSize)
+ addr, disp, dataSize, addressSize, "0", atCPL0, False)
self.className = "Cda"
self.mnemonic = "cda"
diff --git a/src/arch/x86/isa/microops/limmop.isa b/src/arch/x86/isa/microops/limmop.isa
index 6686444fd..4e75ab8b0 100644
--- a/src/arch/x86/isa/microops/limmop.isa
+++ b/src/arch/x86/isa/microops/limmop.isa
@@ -154,7 +154,7 @@ let {{
self.dataSize = dataSize
def getAllocator(self, *microFlags):
- allocator = '''new %(class_name)s(machInst, mnemonic
+ allocator = '''new %(class_name)s(machInst, macrocodeBlock
%(flags)s, %(dest)s, %(imm)s, %(dataSize)s)''' % {
"class_name" : self.className,
"mnemonic" : self.mnemonic,
diff --git a/src/arch/x86/isa/microops/microops.isa b/src/arch/x86/isa/microops/microops.isa
index 53f34d3f2..19266f6d6 100644
--- a/src/arch/x86/isa/microops/microops.isa
+++ b/src/arch/x86/isa/microops/microops.isa
@@ -1,4 +1,4 @@
-// Copyright (c) 2007 The Hewlett-Packard Development Company
+// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@@ -68,5 +68,11 @@
//Load/store microop definitions
##include "ldstop.isa"
+//Control flow microop definitions
+##include "seqop.isa"
+
//Miscellaneous microop definitions
##include "specop.isa"
+
+//Microops for printing out debug messages through M5
+##include "debug.isa"
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa
index e761f0034..f9bc82119 100644
--- a/src/arch/x86/isa/microops/regop.isa
+++ b/src/arch/x86/isa/microops/regop.isa
@@ -1,4 +1,4 @@
-// Copyright (c) 2007 The Hewlett-Packard Development Company
+// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@@ -231,6 +231,21 @@ output header {{
void
divide(uint64_t dividend, uint64_t divisor,
uint64_t &quotient, uint64_t &remainder);
+
+ enum SegmentSelectorCheck {
+ SegNoCheck, SegCSCheck, SegCallGateCheck, SegIntGateCheck,
+ SegSoftIntGateCheck, SegSSCheck, SegIretCheck, SegIntCSCheck,
+ SegTRCheck, SegTSSCheck, SegInGDTCheck, SegLDTCheck
+ };
+
+ enum LongModeDescriptorType {
+ LDT64 = 2,
+ AvailableTSS64 = 9,
+ BusyTSS64 = 0xb,
+ CallGate64 = 0xc,
+ IntGate64 = 0xe,
+ TrapGate64 = 0xf
+ };
}};
output decoder {{
@@ -424,7 +439,7 @@ let {{
className = self.className
if self.mnemonic == self.base_mnemonic + 'i':
className += "Imm"
- allocator = '''new %(class_name)s(machInst, mnemonic
+ allocator = '''new %(class_name)s(machInst, macrocodeBlock
%(flags)s, %(src1)s, %(op2)s, %(dest)s,
%(dataSize)s, %(ext)s)''' % {
"class_name" : className,
@@ -838,19 +853,28 @@ let {{
code = 'RIP = psrc1 + sop2 + CSBase'
else_code="RIP = RIP;"
- class Br(WrRegOp, CondRegOp):
- code = 'nuIP = psrc1 + op2;'
- else_code='nuIP = nuIP;'
-
class Wruflags(WrRegOp):
code = 'ccFlagBits = psrc1 ^ op2'
+ class Wrflags(WrRegOp):
+ code = '''
+ MiscReg newFlags = psrc1 ^ op2;
+ MiscReg userFlagMask = 0xDD5;
+ // Get only the user flags
+ ccFlagBits = newFlags & userFlagMask;
+ // Get everything else
+ nccFlagBits = newFlags & ~userFlagMask;
+ '''
+
class Rdip(RdRegOp):
code = 'DestReg = RIP - CSBase'
class Ruflags(RdRegOp):
code = 'DestReg = ccFlagBits'
+ class Rflags(RdRegOp):
+ code = 'DestReg = ccFlagBits | nccFlagBits'
+
class Ruflag(RegOp):
code = '''
int flag = bits(ccFlagBits, imm8);
@@ -863,6 +887,20 @@ let {{
super(Ruflag, self).__init__(dest, \
"NUM_INTREGS", imm, flags, dataSize)
+ class Rflag(RegOp):
+ code = '''
+ MiscReg flagMask = 0x3F7FDD5;
+ MiscReg flags = (nccFlagBits | ccFlagBits) & flagMask;
+ int flag = bits(flags, imm8);
+ DestReg = merge(DestReg, flag, dataSize);
+ ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) :
+ (ccFlagBits & ~EZFBit);
+ '''
+ def __init__(self, dest, imm, flags=None, \
+ dataSize="env.dataSize"):
+ super(Rflag, self).__init__(dest, \
+ "NUM_INTREGS", imm, flags, dataSize)
+
class Sext(RegOp):
code = '''
IntReg val = psrc1;
@@ -883,17 +921,53 @@ let {{
'''
class Zext(RegOp):
- code = 'DestReg = bits(psrc1, op2, 0);'
+ code = 'DestReg = merge(DestReg, bits(psrc1, op2, 0), dataSize);'
+
+ class Rddr(RegOp):
+ def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"):
+ super(Rddr, self).__init__(dest, \
+ src1, "NUM_INTREGS", flags, dataSize)
+ code = '''
+ CR4 cr4 = CR4Op;
+ DR7 dr7 = DR7Op;
+ if ((cr4.de == 1 && (src1 == 4 || src1 == 5)) || src1 >= 8) {
+ fault = new InvalidOpcode();
+ } else if (dr7.gd) {
+ fault = new DebugException();
+ } else {
+ DestReg = merge(DestReg, DebugSrc1, dataSize);
+ }
+ '''
+
+ class Wrdr(RegOp):
+ def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"):
+ super(Wrdr, self).__init__(dest, \
+ src1, "NUM_INTREGS", flags, dataSize)
+ code = '''
+ CR4 cr4 = CR4Op;
+ DR7 dr7 = DR7Op;
+ if ((cr4.de == 1 && (dest == 4 || dest == 5)) || dest >= 8) {
+ fault = new InvalidOpcode();
+ } else if ((dest == 6 || dest == 7) &&
+ bits(psrc1, 63, 32) &&
+ machInst.mode.mode == LongMode) {
+ fault = new GeneralProtection(0);
+ } else if (dr7.gd) {
+ fault = new DebugException();
+ } else {
+ DebugDest = psrc1;
+ }
+ '''
class Rdcr(RegOp):
def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"):
super(Rdcr, self).__init__(dest, \
src1, "NUM_INTREGS", flags, dataSize)
code = '''
- if (dest == 1 || (dest > 4 && dest < 8) || (dest > 8)) {
+ if (src1 == 1 || (src1 > 4 && src1 < 8) || (src1 > 8)) {
fault = new InvalidOpcode();
} else {
- DestReg = ControlSrc1;
+ DestReg = merge(DestReg, ControlSrc1, dataSize);
}
'''
@@ -950,7 +1024,7 @@ let {{
'''
# Microops for manipulating segmentation registers
- class SegOp(RegOp):
+ class SegOp(CondRegOp):
abstract = True
def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"):
super(SegOp, self).__init__(dest, \
@@ -971,74 +1045,223 @@ let {{
SegSelDest = psrc1;
'''
+ class WrAttr(SegOp):
+ code = '''
+ SegAttrDest = psrc1;
+ '''
+
class Rdbase(SegOp):
code = '''
- DestReg = SegBaseDest;
+ DestReg = merge(DestReg, SegBaseSrc1, dataSize);
'''
class Rdlimit(SegOp):
code = '''
- DestReg = SegLimitSrc1;
+ DestReg = merge(DestReg, SegLimitSrc1, dataSize);
+ '''
+
+ class RdAttr(SegOp):
+ code = '''
+ DestReg = merge(DestReg, SegAttrSrc1, dataSize);
'''
class Rdsel(SegOp):
code = '''
- DestReg = SegSelSrc1;
+ DestReg = merge(DestReg, SegSelSrc1, dataSize);
'''
- class Chks(SegOp):
+ class Rdval(RegOp):
+ def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"):
+ super(Rdval, self).__init__(dest, \
+ src1, "NUM_INTREGS", flags, dataSize)
code = '''
- // The selector is in source 1.
- SegSelector selector = psrc1;
-
- // Compute the address of the descriptor and set DestReg to it.
- if (selector.ti) {
- // A descriptor in the LDT
- Addr target = (selector.esi << 3) + LDTRBase;
- if (!LDTRSel || (selector.esi << 3) + dataSize > LDTRLimit)
- fault = new GeneralProtection(selector & mask(16));
- DestReg = target;
- } else {
- // A descriptor in the GDT
- Addr target = (selector.esi << 3) + GDTRBase;
- if ((selector.esi << 3) + dataSize > GDTRLimit)
- fault = new GeneralProtection(selector & mask(16));
- DestReg = target;
+ DestReg = MiscRegSrc1;
+ '''
+
+ class Wrval(RegOp):
+ def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"):
+ super(Wrval, self).__init__(dest, \
+ src1, "NUM_INTREGS", flags, dataSize)
+ code = '''
+ MiscRegDest = SrcReg1;
+ '''
+
+ class Chks(RegOp):
+ def __init__(self, dest, src1, src2=0,
+ flags=None, dataSize="env.dataSize"):
+ super(Chks, self).__init__(dest,
+ src1, src2, flags, dataSize)
+ code = '''
+ // The selector is in source 1 and can be at most 16 bits.
+ SegSelector selector = DestReg;
+ SegDescriptor desc = SrcReg1;
+ HandyM5Reg m5reg = M5Reg;
+
+ switch (imm8)
+ {
+ case SegNoCheck:
+ break;
+ case SegCSCheck:
+ panic("CS checks for far calls/jumps not implemented.\\n");
+ break;
+ case SegCallGateCheck:
+ panic("CS checks for far calls/jumps through call gates"
+ "not implemented.\\n");
+ break;
+ case SegSoftIntGateCheck:
+ // Check permissions.
+ if (desc.dpl < m5reg.cpl) {
+ fault = new GeneralProtection(selector);
+ }
+ // Fall through on purpose
+ case SegIntGateCheck:
+ // Make sure the gate's the right type.
+ if ((m5reg.mode == LongMode && (desc.type & 0xe) != 0xe) ||
+ ((desc.type & 0x6) != 0x6)) {
+ fault = new GeneralProtection(0);
+ }
+ break;
+ case SegSSCheck:
+ if (selector.si || selector.ti) {
+ if (!desc.p) {
+ fault = new StackFault(selector);
+ }
+ } else {
+ if ((m5reg.submode != SixtyFourBitMode ||
+ m5reg.cpl == 3) ||
+ !(desc.s == 1 &&
+ desc.type.codeOrData == 0 && desc.type.w) ||
+ (desc.dpl != m5reg.cpl) ||
+ (selector.rpl != m5reg.cpl)) {
+ fault = new GeneralProtection(selector);
+ }
+ }
+ break;
+ case SegIretCheck:
+ {
+ if ((!selector.si && !selector.ti) ||
+ (selector.rpl < m5reg.cpl) ||
+ !(desc.s == 1 && desc.type.codeOrData == 1) ||
+ (!desc.type.c && desc.dpl != selector.rpl) ||
+ (desc.type.c && desc.dpl > selector.rpl)) {
+ fault = new GeneralProtection(selector);
+ } else if (!desc.p) {
+ fault = new SegmentNotPresent(selector);
+ }
+ break;
+ }
+ case SegIntCSCheck:
+ if (m5reg.mode == LongMode) {
+ if (desc.l != 1 || desc.d != 0) {
+ fault = new GeneralProtection(selector);
+ }
+ } else {
+ panic("Interrupt CS checks not implemented "
+ "in legacy mode.\\n");
+ }
+ break;
+ case SegTRCheck:
+ if (!selector.si || selector.ti) {
+ fault = new GeneralProtection(selector);
+ }
+ break;
+ case SegTSSCheck:
+ if (!desc.p) {
+ fault = new SegmentNotPresent(selector);
+ } else if (!(desc.type == 0x9 ||
+ (desc.type == 1 &&
+ m5reg.mode != LongMode))) {
+ fault = new GeneralProtection(selector);
+ }
+ break;
+ case SegInGDTCheck:
+ if (selector.ti) {
+ fault = new GeneralProtection(selector);
+ }
+ break;
+ case SegLDTCheck:
+ if (!desc.p) {
+ fault = new SegmentNotPresent(selector);
+ } else if (desc.type != 0x2) {
+ fault = new GeneralProtection(selector);
+ }
+ break;
+ default:
+ panic("Undefined segment check type.\\n");
}
'''
flag_code = '''
// Check for a NULL selector and set ZF,EZF appropriately.
ccFlagBits = ccFlagBits & ~(ext & (ZFBit | EZFBit));
- if (!selector.esi && !selector.ti)
+ if (!selector.si && !selector.ti)
ccFlagBits = ccFlagBits | (ext & (ZFBit | EZFBit));
'''
class Wrdh(RegOp):
code = '''
+ SegDescriptor desc = SrcReg1;
+
+ uint64_t target = bits(SrcReg2, 31, 0) << 32;
+ switch(desc.type) {
+ case LDT64:
+ case AvailableTSS64:
+ case BusyTSS64:
+ replaceBits(target, 23, 0, desc.baseLow);
+ replaceBits(target, 31, 24, desc.baseHigh);
+ break;
+ case CallGate64:
+ case IntGate64:
+ case TrapGate64:
+ replaceBits(target, 15, 0, bits(desc, 15, 0));
+ replaceBits(target, 31, 16, bits(desc, 63, 48));
+ break;
+ default:
+ panic("Wrdh used with wrong descriptor type!\\n");
+ }
+ DestReg = target;
+ '''
+
+ class Wrtsc(WrRegOp):
+ code = '''
+ TscOp = psrc1;
+ '''
+
+ class Rdtsc(RdRegOp):
+ code = '''
+ DestReg = TscOp;
+ '''
+ class Rdm5reg(RdRegOp):
+ code = '''
+ DestReg = M5Reg;
'''
class Wrdl(RegOp):
code = '''
SegDescriptor desc = SrcReg1;
- SegAttr attr = 0;
- attr.dpl = desc.dpl;
- attr.defaultSize = desc.d;
- if (!desc.s) {
- SegBaseDest = SegBaseDest;
- SegLimitDest = SegLimitDest;
- SegAttrDest = SegAttrDest;
- panic("System segment encountered.\\n");
- } else {
- if (!desc.p)
- panic("Segment not present.\\n");
- if (desc.type.codeOrData) {
- attr.readable = desc.type.r;
- attr.longMode = desc.l;
- } else {
- attr.expandDown = desc.type.e;
+ SegSelector selector = SrcReg2;
+ if (selector.si || selector.ti) {
+ SegAttr attr = 0;
+ attr.dpl = desc.dpl;
+ attr.defaultSize = desc.d;
+ if (!desc.s) {
+ // The expand down bit happens to be set for gates.
+ if (desc.type.e) {
+ panic("Gate descriptor encountered.\\n");
+ }
attr.readable = 1;
- attr.writable = desc.type.w;
+ attr.writable = 1;
+ } else {
+ if (!desc.p)
+ panic("Segment not present.\\n");
+ if (desc.type.codeOrData) {
+ attr.readable = desc.type.r;
+ attr.longMode = desc.l;
+ } else {
+ attr.expandDown = desc.type.e;
+ attr.readable = 1;
+ attr.writable = desc.type.w;
+ }
}
Addr base = desc.baseLow | (desc.baseHigh << 24);
Addr limit = desc.limitLow | (desc.limitHigh << 16);
@@ -1047,6 +1270,10 @@ let {{
SegBaseDest = base;
SegLimitDest = limit;
SegAttrDest = attr;
+ } else {
+ SegBaseDest = SegBaseDest;
+ SegLimitDest = SegLimitDest;
+ SegAttrDest = SegAttrDest;
}
'''
}};
diff --git a/src/arch/x86/isa/microops/seqop.isa b/src/arch/x86/isa/microops/seqop.isa
new file mode 100644
index 000000000..332519b87
--- /dev/null
+++ b/src/arch/x86/isa/microops/seqop.isa
@@ -0,0 +1,251 @@
+// Copyright (c) 2008 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer. Redistributions
+// in binary form must reproduce the above copyright notice, this list of
+// conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution. Neither the name of
+// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Gabe Black
+
+output header {{
+ class SeqOpBase : public X86ISA::X86MicroopBase
+ {
+ protected:
+ uint16_t target;
+ uint8_t cc;
+
+ public:
+ SeqOpBase(ExtMachInst _machInst, const char * instMnem,
+ const char * mnemonic,
+ bool isMicro, bool isDelayed, bool isFirst, bool isLast,
+ uint16_t _target, uint8_t _cc);
+
+ SeqOpBase(ExtMachInst _machInst, const char * instMnem,
+ const char * mnemonic,
+ uint16_t _target, uint8_t _cc);
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+ };
+}};
+
+def template SeqOpDeclare {{
+ class %(class_name)s : public %(base_class)s
+ {
+ private:
+ void buildMe();
+ public:
+ %(class_name)s(ExtMachInst _machInst, const char * instMnem,
+ bool isMicro, bool isDelayed, bool isFirst, bool isLast,
+ uint16_t _target, uint8_t _cc);
+
+ %(class_name)s(ExtMachInst _machInst, const char * instMnem,
+ uint16_t _target, uint8_t _cc);
+
+ %(BasicExecDeclare)s
+ };
+}};
+
+def template SeqOpExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ %(op_decl)s;
+ %(op_rd)s;
+ if (%(cond_test)s) {
+ %(code)s;
+ } else {
+ %(else_code)s;
+ }
+ %(op_wb)s;
+ return NoFault;
+ }
+}};
+
+output decoder {{
+ inline SeqOpBase::SeqOpBase(
+ ExtMachInst machInst, const char * mnemonic, const char * instMnem,
+ uint16_t _target, uint8_t _cc) :
+ X86MicroopBase(machInst, mnemonic, instMnem,
+ false, false, false, false, No_OpClass),
+ target(_target), cc(_cc)
+ {
+ }
+
+ inline SeqOpBase::SeqOpBase(
+ ExtMachInst machInst, const char * mnemonic, const char * instMnem,
+ bool isMicro, bool isDelayed, bool isFirst, bool isLast,
+ uint16_t _target, uint8_t _cc) :
+ X86MicroopBase(machInst, mnemonic, instMnem,
+ isMicro, isDelayed, isFirst, isLast, No_OpClass),
+ target(_target), cc(_cc)
+ {
+ }
+}};
+
+def template SeqOpConstructor {{
+
+ inline void %(class_name)s::buildMe()
+ {
+ %(constructor)s;
+ }
+
+ inline %(class_name)s::%(class_name)s(
+ ExtMachInst machInst, const char * instMnem,
+ uint16_t _target, uint8_t _cc) :
+ %(base_class)s(machInst, "%(mnemonic)s", instMnem, _target, _cc)
+ {
+ buildMe();
+ }
+
+ inline %(class_name)s::%(class_name)s(
+ ExtMachInst machInst, const char * instMnem,
+ bool isMicro, bool isDelayed, bool isFirst, bool isLast,
+ uint16_t _target, uint8_t _cc) :
+ %(base_class)s(machInst, "%(mnemonic)s", instMnem,
+ isMicro, isDelayed, isFirst, isLast, _target, _cc)
+ {
+ buildMe();
+ }
+}};
+
+output decoder {{
+ std::string SeqOpBase::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+
+ printMnemonic(response, instMnem, mnemonic);
+ ccprintf(response, "%#x", target);
+
+ return response.str();
+ }
+}};
+
+let {{
+ class SeqOp(X86Microop):
+ def __init__(self, target, flags=None):
+ self.target = target
+ if flags:
+ if not isinstance(flags, (list, tuple)):
+ raise Exception, "flags must be a list or tuple of flags"
+ self.cond = " | ".join(flags)
+ self.className += "Flags"
+ else:
+ self.cond = "0"
+
+ def getAllocator(self, *microFlags):
+ allocator = '''new %(class_name)s(machInst, macrocodeBlock
+ %(flags)s, %(target)s, %(cc)s)''' % {
+ "class_name" : self.className,
+ "flags" : self.microFlagsText(microFlags),
+ "target" : self.target,
+ "cc" : self.cond}
+ return allocator
+
+ class Br(SeqOp):
+ className = "MicroBranch"
+
+ def getAllocator(self, *microFlags):
+ (is_micro, is_delayed, is_first, is_last) = microFlags
+ is_last = False
+ is_delayed = True
+ microFlags = (is_micro, is_delayed, is_first, is_last)
+ return super(Br, self).getAllocator(*microFlags)
+
+ class Eret(SeqOp):
+ target = "normalMicroPC(0)"
+ className = "Eret"
+
+ def __init__(self, flags=None):
+ if flags:
+ if not isinstance(flags, (list, tuple)):
+ raise Exception, "flags must be a list or tuple of flags"
+ self.cond = " | ".join(flags)
+ self.className += "Flags"
+ else:
+ self.cond = "0"
+
+ def getAllocator(self, *microFlags):
+ (is_micro, is_delayed, is_first, is_last) = microFlags
+ is_last = True
+ is_delayed = False
+ microFlags = (is_micro, is_delayed, is_first, is_last)
+ return super(Eret, self).getAllocator(*microFlags)
+
+ iop = InstObjParams("br", "MicroBranchFlags", "SeqOpBase",
+ {"code": "nuIP = target",
+ "else_code": "nuIP = nuIP",
+ "cond_test": "checkCondition(ccFlagBits, cc)"})
+ exec_output += SeqOpExecute.subst(iop)
+ header_output += SeqOpDeclare.subst(iop)
+ decoder_output += SeqOpConstructor.subst(iop)
+ iop = InstObjParams("br", "MicroBranch", "SeqOpBase",
+ {"code": "nuIP = target",
+ "else_code": "nuIP = nuIP",
+ "cond_test": "true"})
+ exec_output += SeqOpExecute.subst(iop)
+ header_output += SeqOpDeclare.subst(iop)
+ decoder_output += SeqOpConstructor.subst(iop)
+ microopClasses["br"] = Br
+
+ iop = InstObjParams("eret", "EretFlags", "SeqOpBase",
+ {"code": "", "else_code": "",
+ "cond_test": "checkCondition(ccFlagBits, cc)"})
+ exec_output += SeqOpExecute.subst(iop)
+ header_output += SeqOpDeclare.subst(iop)
+ decoder_output += SeqOpConstructor.subst(iop)
+ iop = InstObjParams("eret", "Eret", "SeqOpBase",
+ {"code": "", "else_code": "",
+ "cond_test": "true"})
+ exec_output += SeqOpExecute.subst(iop)
+ header_output += SeqOpDeclare.subst(iop)
+ decoder_output += SeqOpConstructor.subst(iop)
+ microopClasses["eret"] = Eret
+}};
diff --git a/src/arch/x86/isa/microops/specop.isa b/src/arch/x86/isa/microops/specop.isa
index 6bcc7ff91..c6e172ef1 100644
--- a/src/arch/x86/isa/microops/specop.isa
+++ b/src/arch/x86/isa/microops/specop.isa
@@ -1,4 +1,4 @@
-// Copyright (c) 2007 The Hewlett-Packard Development Company
+// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@@ -95,6 +95,9 @@ output header {{
}
%(BasicExecDeclare)s
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
};
}};
@@ -201,6 +204,16 @@ output decoder {{
return response.str();
}
+
+ std::string MicroHalt::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+
+ printMnemonic(response, instMnem, mnemonic);
+
+ return response.str();
+ }
}};
let {{
@@ -217,7 +230,7 @@ let {{
self.cond = "0"
def getAllocator(self, *microFlags):
- allocator = '''new %(class_name)s(machInst, mnemonic
+ allocator = '''new %(class_name)s(machInst, macrocodeBlock
%(flags)s, %(fault)s, %(cc)s)''' % {
"class_name" : self.className,
"flags" : self.microFlagsText(microFlags),
@@ -244,7 +257,7 @@ let {{
pass
def getAllocator(self, *microFlags):
- return "new MicroHalt(machInst, mnemonic %s)" % \
+ return "new MicroHalt(machInst, macrocodeBlock %s)" % \
self.microFlagsText(microFlags)
microopClasses["halt"] = Halt
diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa
index 9345158e9..ab1e9a851 100644
--- a/src/arch/x86/isa/operands.isa
+++ b/src/arch/x86/isa/operands.isa
@@ -26,7 +26,7 @@
//
// Authors: Gabe Black
-// Copyright (c) 2007 The Hewlett-Packard Development Company
+// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@@ -109,7 +109,14 @@ def operands {{
'Quotient': ('IntReg', 'uqw', 'INTREG_IMPLICIT(2)', 'IsInteger', 9),
'Remainder': ('IntReg', 'uqw', 'INTREG_IMPLICIT(3)', 'IsInteger', 10),
'Divisor': ('IntReg', 'uqw', 'INTREG_IMPLICIT(4)', 'IsInteger', 11),
- 'rax': ('IntReg', 'uqw', '(INTREG_RAX)', 'IsInteger', 12),
+ 'Rax': ('IntReg', 'uqw', '(INTREG_RAX)', 'IsInteger', 12),
+ 'Rbx': ('IntReg', 'uqw', '(INTREG_RBX)', 'IsInteger', 13),
+ 'Rcx': ('IntReg', 'uqw', '(INTREG_RCX)', 'IsInteger', 14),
+ 'Rdx': ('IntReg', 'uqw', '(INTREG_RDX)', 'IsInteger', 15),
+ 'Rsp': ('IntReg', 'uqw', '(INTREG_RSP)', 'IsInteger', 16),
+ 'Rbp': ('IntReg', 'uqw', '(INTREG_RBP)', 'IsInteger', 17),
+ 'Rsi': ('IntReg', 'uqw', '(INTREG_RSI)', 'IsInteger', 18),
+ 'Rdi': ('IntReg', 'uqw', '(INTREG_RDI)', 'IsInteger', 19),
'FpSrcReg1': ('FloatReg', 'df', 'src1', 'IsFloating', 20),
'FpSrcReg2': ('FloatReg', 'df', 'src2', 'IsFloating', 21),
'FpDestReg': ('FloatReg', 'df', 'dest', 'IsFloating', 22),
@@ -117,10 +124,13 @@ def operands {{
'RIP': ('NPC', 'uqw', None, (None, None, 'IsControl'), 50),
'uIP': ('UPC', 'uqw', None, (None, None, 'IsControl'), 51),
'nuIP': ('NUPC', 'uqw', None, (None, None, 'IsControl'), 52),
+ # This holds the condition code portion of the flag register. The
+ # nccFlagBits version holds the rest.
'ccFlagBits': ('IntReg', 'uqw', 'INTREG_PSEUDO(0)', None, 60),
- # The TOP register should needs to be more protected so that later
+ # These register should needs to be more protected so that later
# instructions don't map their indexes with an old value.
- 'TOP': ('ControlReg', 'ub', 'MISCREG_X87_TOP', None, 61),
+ 'nccFlagBits': ('ControlReg', 'uqw', 'MISCREG_RFLAGS', None, 61),
+ 'TOP': ('ControlReg', 'ub', 'MISCREG_X87_TOP', None, 62),
# The segment base as used by memory instructions.
'SegBase': ('ControlReg', 'uqw', 'MISCREG_SEG_EFF_BASE(segment)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 70),
@@ -128,23 +138,31 @@ def operands {{
# original instruction.
'ControlDest': ('ControlReg', 'uqw', 'MISCREG_CR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 100),
'ControlSrc1': ('ControlReg', 'uqw', 'MISCREG_CR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 101),
- 'SegBaseDest': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 102),
- 'SegBaseSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 103),
- 'SegLimitDest': ('ControlReg', 'uqw', 'MISCREG_SEG_LIMIT(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 104),
- 'SegLimitSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_LIMIT(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 105),
- 'SegSelDest': ('ControlReg', 'uqw', 'MISCREG_SEG_SEL(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 106),
- 'SegSelSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_SEL(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 107),
- 'SegAttrDest': ('ControlReg', 'uqw', 'MISCREG_SEG_ATTR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 108),
- 'SegAttrSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_ATTR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 109),
+ 'DebugDest': ('ControlReg', 'uqw', 'MISCREG_DR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 102),
+ 'DebugSrc1': ('ControlReg', 'uqw', 'MISCREG_DR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 103),
+ 'SegBaseDest': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 104),
+ 'SegBaseSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 105),
+ 'SegLimitDest': ('ControlReg', 'uqw', 'MISCREG_SEG_LIMIT(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 106),
+ 'SegLimitSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_LIMIT(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 107),
+ 'SegSelDest': ('ControlReg', 'uqw', 'MISCREG_SEG_SEL(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 108),
+ 'SegSelSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_SEL(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 109),
+ 'SegAttrDest': ('ControlReg', 'uqw', 'MISCREG_SEG_ATTR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 110),
+ 'SegAttrSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_ATTR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 111),
# Operands to access specific control registers directly.
'EferOp': ('ControlReg', 'uqw', 'MISCREG_EFER', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 200),
'CR4Op': ('ControlReg', 'uqw', 'MISCREG_CR4', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 201),
- 'LDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSL_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 202),
- 'LDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSL_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 203),
- 'LDTRSel': ('ControlReg', 'uqw', 'MISCREG_TSL', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 204),
- 'GDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSG_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 205),
- 'GDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSG_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 206),
- 'CSBase': ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 207),
+ 'DR7Op': ('ControlReg', 'uqw', 'MISCREG_DR7', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 202),
+ 'LDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSL_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 203),
+ 'LDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSL_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 204),
+ 'LDTRSel': ('ControlReg', 'uqw', 'MISCREG_TSL', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 205),
+ 'GDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSG_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 206),
+ 'GDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSG_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 207),
+ 'CSBase': ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 208),
+ 'CSAttr': ('ControlReg', 'udw', 'MISCREG_CS_ATTR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 209),
+ 'MiscRegDest': ('ControlReg', 'uqw', 'dest', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 210),
+ 'MiscRegSrc1': ('ControlReg', 'uqw', 'src1', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 211),
+ 'TscOp': ('ControlReg', 'uqw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 212),
+ 'M5Reg': ('ControlReg', 'uqw', 'MISCREG_M5_REG', (None, None, None), 213),
'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 300)
}};
diff --git a/src/arch/x86/isa/rom.isa b/src/arch/x86/isa/rom.isa
new file mode 100644
index 000000000..7d3eb8670
--- /dev/null
+++ b/src/arch/x86/isa/rom.isa
@@ -0,0 +1,90 @@
+// Copyright (c) 2008 The Regents of The University of Michigan
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Gabe Black
+
+def template MicroRomConstructor {{
+
+ %(define_generators)s
+ const MicroPC X86ISA::MicrocodeRom::numMicroops = %(num_microops)s;
+
+ X86ISA::MicrocodeRom::MicrocodeRom()
+ {
+ using namespace RomLabels;
+ genFuncs = new GenFunc[numMicroops];
+ %(alloc_generators)s;
+ }
+}};
+
+let {{
+ from micro_asm import Rom
+
+ class X86MicrocodeRom(Rom):
+ def __init__(self, name):
+ super(X86MicrocodeRom, self).__init__(name)
+ self.directives = {}
+
+ def add_microop(self, mnemonic, microop):
+ microop.mnemonic = mnemonic
+ microop.micropc = len(self.microops)
+ self.microops.append(microop)
+
+
+ def getDeclaration(self):
+ declareLabels = "namespace RomLabels {\n"
+ for (label, microop) in self.labels.items():
+ declareLabels += "const static uint64_t label_%s = %d;\n" \
+ % (label, microop.micropc)
+ for (label, microop) in self.externs.items():
+ declareLabels += \
+ "const static MicroPC extern_label_%s = %d;\n" \
+ % (label, microop.micropc)
+ declareLabels += "}\n"
+ return declareLabels;
+
+ def getDefinition(self):
+ numMicroops = len(self.microops)
+ allocGenerators = ''
+ micropc = 0
+ define_generators = '''
+ namespace
+ {
+ static const char romMnemonic[] = "Microcode_ROM";
+ '''
+ for op in self.microops:
+ define_generators += op.getGeneratorDef(micropc)
+ allocGenerators += "genFuncs[%d] = %s;\n" % \
+ (micropc, op.getGenerator(micropc))
+ micropc += 1
+ define_generators += "}\n"
+ iop = InstObjParams(self.name, self.name, "MicrocodeRom",
+ {"code" : "",
+ "define_generators" : define_generators,
+ "num_microops" : numMicroops,
+ "alloc_generators" : allocGenerators
+ })
+ return MicroRomConstructor.subst(iop);
+}};
diff --git a/src/arch/x86/isa/specialize.isa b/src/arch/x86/isa/specialize.isa
index abf734307..b74363470 100644
--- a/src/arch/x86/isa/specialize.isa
+++ b/src/arch/x86/isa/specialize.isa
@@ -86,8 +86,17 @@ let {{
let {{
def doRipRelativeDecode(Name, opTypes, env):
# print "RIPing %s with opTypes %s" % (Name, opTypes)
- normBlocks = specializeInst(Name + "_M", copy.copy(opTypes), copy.copy(env))
- ripBlocks = specializeInst(Name + "_P", copy.copy(opTypes), copy.copy(env))
+ env.memoryInst = True
+ normEnv = copy.copy(env)
+ normEnv.addToDisassembly(
+ '''printMem(out, env.seg, env.scale, env.index, env.base,
+ machInst.displacement, env.addressSize, false);''')
+ normBlocks = specializeInst(Name + "_M", copy.copy(opTypes), normEnv)
+ ripEnv = copy.copy(env)
+ ripEnv.addToDisassembly(
+ '''printMem(out, env.seg, 1, 0, 0,
+ machInst.displacement, env.addressSize, true);''')
+ ripBlocks = specializeInst(Name + "_P", copy.copy(opTypes), ripEnv)
blocks = OutputBlocks()
blocks.append(normBlocks)
@@ -138,12 +147,17 @@ let {{
#Figure out what to do with fixed register operands
#This is the index to use, so we should stick it some place.
if opType.reg in ("A", "B", "C", "D"):
- env.addReg("INTREG_R%sX" % opType.reg)
+ regString = "INTREG_R%sX" % opType.reg
else:
- env.addReg("INTREG_R%s" % opType.reg)
+ regString = "INTREG_R%s" % opType.reg
+ env.addReg(regString)
+ env.addToDisassembly(
+ "printReg(out, %s, regSize);\n" % regString)
Name += "_R"
elif opType.tag == "B":
# This refers to registers whose index is encoded as part of the opcode
+ env.addToDisassembly(
+ "printReg(out, %s, regSize);\n" % InstRegIndex)
Name += "_R"
env.addReg(InstRegIndex)
elif opType.tag == "M":
@@ -156,24 +170,34 @@ let {{
elif opType.tag == "C":
# A control register indexed by the "reg" field
env.addReg(ModRMRegIndex)
+ env.addToDisassembly(
+ "ccprintf(out, \"CR%%d\", %s);\n" % ModRMRegIndex)
Name += "_C"
elif opType.tag == "D":
# A debug register indexed by the "reg" field
env.addReg(ModRMRegIndex)
+ env.addToDisassembly(
+ "ccprintf(out, \"DR%%d\", %s);\n" % ModRMRegIndex)
Name += "_D"
elif opType.tag == "S":
# A segment selector register indexed by the "reg" field
env.addReg(ModRMRegIndex)
+ env.addToDisassembly(
+ "printSegment(out, %s);\n" % ModRMRegIndex)
Name += "_S"
elif opType.tag in ("G", "P", "T", "V"):
# Use the "reg" field of the ModRM byte to select the register
env.addReg(ModRMRegIndex)
+ env.addToDisassembly(
+ "printReg(out, %s, regSize);\n" % ModRMRegIndex)
Name += "_R"
elif opType.tag in ("E", "Q", "W"):
# This might refer to memory or to a register. We need to
# divide it up farther.
regEnv = copy.copy(env)
regEnv.addReg(ModRMRMIndex)
+ regEnv.addToDisassembly(
+ "printReg(out, %s, regSize);\n" % ModRMRMIndex)
# This refers to memory. The macroop constructor should set up
# modrm addressing.
memEnv = copy.copy(env)
@@ -183,6 +207,8 @@ let {{
(doRipRelativeDecode, Name, copy.copy(opTypes), memEnv))
elif opType.tag in ("I", "J"):
# Immediates
+ env.addToDisassembly(
+ "ccprintf(out, \"%#x\", machInst.immediate);\n")
Name += "_I"
elif opType.tag == "O":
# Immediate containing a memory offset
@@ -190,10 +216,22 @@ let {{
elif opType.tag in ("PR", "R", "VR"):
# Non register modrm settings should cause an error
env.addReg(ModRMRMIndex)
+ env.addToDisassembly(
+ "printReg(out, %s, regSize);\n" % ModRMRMIndex)
Name += "_R"
elif opType.tag in ("X", "Y"):
# This type of memory addressing is for string instructions.
# They'll use the right index and segment internally.
+ if opType.tag == "X":
+ env.addToDisassembly(
+ '''printMem(out, env.seg,
+ 1, X86ISA::ZeroReg, X86ISA::INTREG_RSI, 0,
+ env.addressSize, false);''')
+ else:
+ env.addToDisassembly(
+ '''printMem(out, SEGMENT_REG_ES,
+ 1, X86ISA::ZeroReg, X86ISA::INTREG_RDI, 0,
+ env.addressSize, false);''')
Name += "_M"
else:
raise Exception, "Unrecognized tag %s." % opType.tag
diff --git a/src/arch/x86/isa_traits.hh b/src/arch/x86/isa_traits.hh
index abb7694ed..d25e0eb70 100644
--- a/src/arch/x86/isa_traits.hh
+++ b/src/arch/x86/isa_traits.hh
@@ -106,19 +106,7 @@ namespace X86ISA
const int StackPointerReg = INTREG_RSP;
//X86 doesn't seem to have a link register
const int ReturnAddressReg = 0;
- const int ReturnValueReg = INTREG_RAX;
const int FramePointerReg = INTREG_RBP;
- const int ArgumentReg[] = {
- INTREG_RDI,
- INTREG_RSI,
- INTREG_RDX,
- //This argument register is r10 for syscalls and rcx for C.
- INTREG_R10W,
- //INTREG_RCX,
- INTREG_R8W,
- INTREG_R9W
- };
- const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int);
// Some OS syscalls use a second register (rdx) to return a second
// value
diff --git a/src/arch/x86/linux/linux.cc b/src/arch/x86/linux/linux.cc
index 5e8d2de16..41855da59 100644
--- a/src/arch/x86/linux/linux.cc
+++ b/src/arch/x86/linux/linux.cc
@@ -97,3 +97,42 @@ const int X86Linux64::NUM_OPEN_FLAGS =
sizeof(X86Linux64::openFlagTable) /
sizeof(X86Linux64::openFlagTable[0]);
+// open(2) flags translation table
+OpenFlagTransTable X86Linux32::openFlagTable[] = {
+#ifdef _MSC_VER
+ { TGT_O_RDONLY, _O_RDONLY },
+ { TGT_O_WRONLY, _O_WRONLY },
+ { TGT_O_RDWR, _O_RDWR },
+ { TGT_O_APPEND, _O_APPEND },
+ { TGT_O_CREAT, _O_CREAT },
+ { TGT_O_TRUNC, _O_TRUNC },
+ { TGT_O_EXCL, _O_EXCL },
+#ifdef _O_NONBLOCK
+ { TGT_O_NONBLOCK, _O_NONBLOCK },
+#endif
+#ifdef _O_NOCTTY
+ { TGT_O_NOCTTY, _O_NOCTTY },
+#endif
+#ifdef _O_SYNC
+ { TGT_O_SYNC, _O_SYNC },
+#endif
+#else /* !_MSC_VER */
+ { TGT_O_RDONLY, O_RDONLY },
+ { TGT_O_WRONLY, O_WRONLY },
+ { TGT_O_RDWR, O_RDWR },
+ { TGT_O_APPEND, O_APPEND },
+ { TGT_O_CREAT, O_CREAT },
+ { TGT_O_TRUNC, O_TRUNC },
+ { TGT_O_EXCL, O_EXCL },
+ { TGT_O_NONBLOCK, O_NONBLOCK },
+ { TGT_O_NOCTTY, O_NOCTTY },
+#ifdef O_SYNC
+ { TGT_O_SYNC, O_SYNC },
+#endif
+#endif /* _MSC_VER */
+};
+
+const int X86Linux32::NUM_OPEN_FLAGS =
+ sizeof(X86Linux32::openFlagTable) /
+ sizeof(X86Linux32::openFlagTable[0]);
+
diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh
index 8a78d5320..c2941c769 100644
--- a/src/arch/x86/linux/linux.hh
+++ b/src/arch/x86/linux/linux.hh
@@ -82,26 +82,26 @@ class X86Linux64 : public Linux
uint64_t st_mtime_nsec;
uint64_t st_ctimeX;
uint64_t st_ctime_nsec;
- int64_t __unused[3];
+ int64_t unused0[3];
} tgt_stat64;
static OpenFlagTransTable openFlagTable[];
- 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 = 00004000; //!< O_NONBLOCK
- static const int TGT_O_APPEND = 00002000; //!< O_APPEND
- static const int TGT_O_CREAT = 00000100; //!< O_CREAT
- static const int TGT_O_TRUNC = 00001000; //!< O_TRUNC
- static const int TGT_O_EXCL = 00000200; //!< O_EXCL
- static const int TGT_O_NOCTTY = 00000400; //!< O_NOCTTY
- static const int TGT_O_SYNC = 00010000; //!< O_SYNC
-// static const int TGT_O_DRD = 0x00010000; //!< O_DRD
-// static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO
-// static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE
-// static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC
-// static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC
+ static const int 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 = 00004000; //!< O_NONBLOCK
+ static const int TGT_O_APPEND = 00002000; //!< O_APPEND
+ static const int TGT_O_CREAT = 00000100; //!< O_CREAT
+ static const int TGT_O_TRUNC = 00001000; //!< O_TRUNC
+ static const int TGT_O_EXCL = 00000200; //!< O_EXCL
+ static const int TGT_O_NOCTTY = 00000400; //!< O_NOCTTY
+ static const int TGT_O_SYNC = 00010000; //!< O_SYNC
+// static const int TGT_O_DRD = 0x00010000; //!< O_DRD
+// static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO
+// static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE
+// static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC
+// static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC
static const int NUM_OPEN_FLAGS;
@@ -113,4 +113,53 @@ class X86Linux64 : public Linux
} tgt_iovec;
};
+class X86Linux32 : public Linux
+{
+ public:
+
+ typedef struct {
+ uint64_t st_dev;
+ uint8_t __pad0[4];
+ uint32_t __st_ino;
+ uint32_t st_mode;
+ uint32_t st_nlink;
+ uint32_t st_uid;
+ uint32_t st_gid;
+ uint64_t st_rdev;
+ int64_t st_size;
+ uint8_t __pad3[4];
+ uint32_t st_blksize;
+ uint64_t st_blocks;
+ uint32_t st_atimeX;
+ uint32_t st_atime_nsec;
+ uint32_t st_mtimeX;
+ uint32_t st_mtime_nsec;
+ uint32_t st_ctimeX;
+ uint32_t st_ctime_nsec;
+ uint64_t st_ino;
+ } tgt_stat64;
+
+ static OpenFlagTransTable openFlagTable[];
+
+ 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 = 00004000; //!< O_NONBLOCK
+ static const int TGT_O_APPEND = 00002000; //!< O_APPEND
+ static const int TGT_O_CREAT = 00000100; //!< O_CREAT
+ static const int TGT_O_TRUNC = 00001000; //!< O_TRUNC
+ static const int TGT_O_EXCL = 00000200; //!< O_EXCL
+ static const int TGT_O_NOCTTY = 00000400; //!< O_NOCTTY
+ static const int TGT_O_SYNC = 00010000; //!< O_SYNC
+// static const int TGT_O_DRD = 0x00010000; //!< O_DRD
+// static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO
+// static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE
+// static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC
+// static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC
+
+ static const int NUM_OPEN_FLAGS;
+
+ static const unsigned TGT_MAP_ANONYMOUS = 0x20;
+};
+
#endif
diff --git a/src/arch/x86/linux/process.cc b/src/arch/x86/linux/process.cc
index 8beaf150b..da22d9851 100644
--- a/src/arch/x86/linux/process.cc
+++ b/src/arch/x86/linux/process.cc
@@ -64,34 +64,16 @@
#include "kern/linux/linux.hh"
#include "sim/process.hh"
-#include "sim/syscall_emul.hh"
using namespace std;
using namespace X86ISA;
-SyscallDesc*
-X86LinuxProcess::getDesc(int callnum)
-{
- if (callnum < 0 || callnum > Num_Syscall_Descs)
- return NULL;
- return &syscallDescs[callnum];
-}
-
-X86LinuxProcess::X86LinuxProcess(LiveProcessParams * params,
+X86_64LinuxProcess::X86_64LinuxProcess(LiveProcessParams * params,
ObjectFile *objFile)
- : X86LiveProcess(params, objFile),
- Num_Syscall_Descs(273)
+ : X86_64LiveProcess(params, objFile, syscallDescs, 273)
{}
-void X86LinuxProcess::handleTrap(int trapNum, ThreadContext *tc)
-{
- switch(trapNum)
- {
- //This implementation is from SPARC
- case 0x10: //Linux 32 bit syscall trap
- tc->syscall(tc->readIntReg(1));
- break;
- default:
- X86LiveProcess::handleTrap(trapNum, tc);
- }
-}
+I386LinuxProcess::I386LinuxProcess(LiveProcessParams * params,
+ ObjectFile *objFile)
+ : I386LiveProcess(params, objFile, syscallDescs, 324)
+{}
diff --git a/src/arch/x86/linux/process.hh b/src/arch/x86/linux/process.hh
index e224374d4..ca3606ef0 100644
--- a/src/arch/x86/linux/process.hh
+++ b/src/arch/x86/linux/process.hh
@@ -60,26 +60,30 @@
#include "sim/process.hh"
#include "arch/x86/linux/linux.hh"
-#include "arch/x86/syscallreturn.hh"
#include "arch/x86/process.hh"
namespace X86ISA {
-/// A process with emulated x86/Linux syscalls.
-class X86LinuxProcess : public X86LiveProcess
+class X86_64LinuxProcess : public X86_64LiveProcess
{
+ protected:
+ /// Array of syscall descriptors, indexed by call number.
+ static SyscallDesc syscallDescs[];
+
public:
/// Constructor.
- X86LinuxProcess(LiveProcessParams * params, ObjectFile *objFile);
+ X86_64LinuxProcess(LiveProcessParams * params, ObjectFile *objFile);
+};
+class I386LinuxProcess : public I386LiveProcess
+{
+ protected:
/// Array of syscall descriptors, indexed by call number.
static SyscallDesc syscallDescs[];
- SyscallDesc* getDesc(int callnum);
-
- const int Num_Syscall_Descs;
-
- void handleTrap(int trapNum, ThreadContext *tc);
+ public:
+ /// Constructor.
+ I386LinuxProcess(LiveProcessParams * params, ObjectFile *objFile);
};
} // namespace X86ISA
diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc
index ae2ac243b..09235ec94 100644
--- a/src/arch/x86/linux/syscalls.cc
+++ b/src/arch/x86/linux/syscalls.cc
@@ -68,7 +68,7 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
+ TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
@@ -94,8 +94,8 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
};
//First argument is the code, second is the address
- int code = tc->getSyscallArg(0);
- uint64_t addr = tc->getSyscallArg(1);
+ int code = process->getSyscallArg(tc, 0);
+ uint64_t addr = process->getSyscallArg(tc, 1);
uint64_t fsBase, gsBase;
TranslatingPort *p = tc->getMemPort();
switch(code)
@@ -122,7 +122,112 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
}
}
-SyscallDesc X86LinuxProcess::syscallDescs[] = {
+BitUnion32(UserDescFlags)
+ Bitfield<0> seg_32bit;
+ Bitfield<2, 1> contents;
+ Bitfield<3> read_exec_only;
+ Bitfield<4> limit_in_pages;
+ Bitfield<5> seg_not_present;
+ Bitfield<6> useable;
+EndBitUnion(UserDescFlags)
+
+struct UserDesc32 {
+ uint32_t entry_number;
+ uint32_t base_addr;
+ uint32_t limit;
+ uint32_t flags;
+};
+
+struct UserDesc64 {
+ uint32_t entry_number;
+ uint32_t __padding1;
+ uint64_t base_addr;
+ uint32_t limit;
+ uint32_t flags;
+};
+
+static SyscallReturn
+setThreadArea32Func(SyscallDesc *desc, int callnum,
+ LiveProcess *process, ThreadContext *tc)
+{
+ const int minTLSEntry = 6;
+ const int numTLSEntries = 3;
+ const int maxTLSEntry = minTLSEntry + numTLSEntries - 1;
+
+ X86LiveProcess *x86lp = dynamic_cast<X86LiveProcess *>(process);
+ assert(x86lp);
+
+ assert((maxTLSEntry + 1) * sizeof(uint64_t) <= x86lp->gdtSize());
+
+ TypedBufferArg<UserDesc32> userDesc(process->getSyscallArg(tc, 0));
+ TypedBufferArg<uint64_t>
+ gdt(x86lp->gdtStart() + minTLSEntry * sizeof(uint64_t),
+ numTLSEntries * sizeof(uint64_t));
+
+ if (!userDesc.copyIn(tc->getMemPort()))
+ return -EFAULT;
+
+ if (!gdt.copyIn(tc->getMemPort()))
+ panic("Failed to copy in GDT for %s.\n", desc->name);
+
+ if (userDesc->entry_number == (uint32_t)(-1)) {
+ // Find a free TLS entry.
+ for (int i = 0; i < numTLSEntries; i++) {
+ if (gdt[i] == 0) {
+ userDesc->entry_number = i + minTLSEntry;
+ break;
+ }
+ }
+ // We failed to find one.
+ if (userDesc->entry_number == (uint32_t)(-1))
+ return -ESRCH;
+ }
+
+ int index = userDesc->entry_number;
+
+ if (index < minTLSEntry || index > maxTLSEntry)
+ return -EINVAL;
+
+ index -= minTLSEntry;
+
+ // Build the entry we're going to add.
+ SegDescriptor segDesc = 0;
+ UserDescFlags flags = userDesc->flags;
+
+ segDesc.limitLow = bits(userDesc->limit, 15, 0);
+ segDesc.baseLow = bits(userDesc->base_addr, 23, 0);
+ segDesc.type.a = 1;
+ if (!flags.read_exec_only)
+ segDesc.type.w = 1;
+ if (bits((uint8_t)flags.contents, 0))
+ segDesc.type.e = 1;
+ if (bits((uint8_t)flags.contents, 1))
+ segDesc.type.codeOrData = 1;
+ segDesc.s = 1;
+ segDesc.dpl = 3;
+ if (!flags.seg_not_present)
+ segDesc.p = 1;
+ segDesc.limitHigh = bits(userDesc->limit, 19, 16);
+ if (flags.useable)
+ segDesc.avl = 1;
+ segDesc.l = 0;
+ if (flags.seg_32bit)
+ segDesc.d = 1;
+ if (flags.limit_in_pages)
+ segDesc.g = 1;
+ segDesc.baseHigh = bits(userDesc->base_addr, 31, 24);
+
+ gdt[index] = (uint64_t)segDesc;
+
+ if (!userDesc.copyOut(tc->getMemPort()))
+ return -EFAULT;
+ if (!gdt.copyOut(tc->getMemPort()))
+ panic("Failed to copy out GDT for %s.\n", desc->name);
+
+ return 0;
+}
+
+SyscallDesc X86_64LinuxProcess::syscallDescs[] = {
/* 0 */ SyscallDesc("read", readFunc),
/* 1 */ SyscallDesc("write", writeFunc),
/* 2 */ SyscallDesc("open", openFunc<X86Linux64>),
@@ -135,7 +240,7 @@ SyscallDesc X86LinuxProcess::syscallDescs[] = {
/* 9 */ SyscallDesc("mmap", mmapFunc<X86Linux64>),
/* 10 */ SyscallDesc("mprotect", unimplementedFunc),
/* 11 */ SyscallDesc("munmap", munmapFunc),
- /* 12 */ SyscallDesc("brk", obreakFunc),
+ /* 12 */ SyscallDesc("brk", brkFunc),
/* 13 */ SyscallDesc("rt_sigaction", unimplementedFunc),
/* 14 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
/* 15 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
@@ -148,7 +253,7 @@ SyscallDesc X86LinuxProcess::syscallDescs[] = {
/* 22 */ SyscallDesc("pipe", unimplementedFunc),
/* 23 */ SyscallDesc("select", unimplementedFunc),
/* 24 */ SyscallDesc("sched_yield", unimplementedFunc),
- /* 25 */ SyscallDesc("mremap", unimplementedFunc),
+ /* 25 */ SyscallDesc("mremap", mremapFunc<X86Linux64>),
/* 26 */ SyscallDesc("msync", unimplementedFunc),
/* 27 */ SyscallDesc("mincore", unimplementedFunc),
/* 28 */ SyscallDesc("madvise", unimplementedFunc),
@@ -397,3 +502,330 @@ SyscallDesc X86LinuxProcess::syscallDescs[] = {
/* 271 */ SyscallDesc("ppoll", unimplementedFunc),
/* 272 */ SyscallDesc("unshare", unimplementedFunc)
};
+
+SyscallDesc I386LinuxProcess::syscallDescs[] = {
+ /* 0 */ SyscallDesc("restart_syscall", unimplementedFunc),
+ /* 1 */ SyscallDesc("exit", unimplementedFunc),
+ /* 2 */ SyscallDesc("fork", unimplementedFunc),
+ /* 3 */ SyscallDesc("read", unimplementedFunc),
+ /* 4 */ SyscallDesc("write", writeFunc),
+ /* 5 */ SyscallDesc("open", openFunc<X86Linux64>),
+ /* 6 */ SyscallDesc("close", unimplementedFunc),
+ /* 7 */ SyscallDesc("waitpid", unimplementedFunc),
+ /* 8 */ SyscallDesc("creat", unimplementedFunc),
+ /* 9 */ SyscallDesc("link", unimplementedFunc),
+ /* 10 */ SyscallDesc("unlink", unimplementedFunc),
+ /* 11 */ SyscallDesc("execve", unimplementedFunc),
+ /* 12 */ SyscallDesc("chdir", unimplementedFunc),
+ /* 13 */ SyscallDesc("time", unimplementedFunc),
+ /* 14 */ SyscallDesc("mknod", unimplementedFunc),
+ /* 15 */ SyscallDesc("chmod", unimplementedFunc),
+ /* 16 */ SyscallDesc("lchown", unimplementedFunc),
+ /* 17 */ SyscallDesc("break", unimplementedFunc),
+ /* 18 */ SyscallDesc("oldstat", unimplementedFunc),
+ /* 19 */ SyscallDesc("lseek", unimplementedFunc),
+ /* 20 */ SyscallDesc("getpid", unimplementedFunc),
+ /* 21 */ SyscallDesc("mount", unimplementedFunc),
+ /* 22 */ SyscallDesc("umount", unimplementedFunc),
+ /* 23 */ SyscallDesc("setuid", unimplementedFunc),
+ /* 24 */ SyscallDesc("getuid", unimplementedFunc),
+ /* 25 */ SyscallDesc("stime", unimplementedFunc),
+ /* 26 */ SyscallDesc("ptrace", unimplementedFunc),
+ /* 27 */ SyscallDesc("alarm", unimplementedFunc),
+ /* 28 */ SyscallDesc("oldfstat", 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", unimplementedFunc),
+ /* 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", brkFunc),
+ /* 46 */ SyscallDesc("setgid", unimplementedFunc),
+ /* 47 */ SyscallDesc("getgid", unimplementedFunc),
+ /* 48 */ SyscallDesc("signal", unimplementedFunc),
+ /* 49 */ SyscallDesc("geteuid", unimplementedFunc),
+ /* 50 */ SyscallDesc("getegid", unimplementedFunc),
+ /* 51 */ SyscallDesc("acct", unimplementedFunc),
+ /* 52 */ SyscallDesc("umount2", unimplementedFunc),
+ /* 53 */ SyscallDesc("lock", unimplementedFunc),
+ /* 54 */ SyscallDesc("ioctl", unimplementedFunc),
+ /* 55 */ SyscallDesc("fcntl", unimplementedFunc),
+ /* 56 */ SyscallDesc("mpx", unimplementedFunc),
+ /* 57 */ SyscallDesc("setpgid", unimplementedFunc),
+ /* 58 */ SyscallDesc("ulimit", unimplementedFunc),
+ /* 59 */ SyscallDesc("oldolduname", unimplementedFunc),
+ /* 60 */ SyscallDesc("umask", unimplementedFunc),
+ /* 61 */ SyscallDesc("chroot", unimplementedFunc),
+ /* 62 */ SyscallDesc("ustat", unimplementedFunc),
+ /* 63 */ SyscallDesc("dup2", unimplementedFunc),
+ /* 64 */ SyscallDesc("getppid", unimplementedFunc),
+ /* 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", unimplementedFunc),
+ /* 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("select", unimplementedFunc),
+ /* 83 */ SyscallDesc("symlink", unimplementedFunc),
+ /* 84 */ SyscallDesc("oldlstat", unimplementedFunc),
+ /* 85 */ SyscallDesc("readlink", unimplementedFunc),
+ /* 86 */ SyscallDesc("uselib", unimplementedFunc),
+ /* 87 */ SyscallDesc("swapon", unimplementedFunc),
+ /* 88 */ SyscallDesc("reboot", unimplementedFunc),
+ /* 89 */ SyscallDesc("readdir", unimplementedFunc),
+ /* 90 */ SyscallDesc("mmap", unimplementedFunc),
+ /* 91 */ SyscallDesc("munmap", unimplementedFunc),
+ /* 92 */ SyscallDesc("truncate", unimplementedFunc),
+ /* 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", unimplementedFunc),
+ /* 107 */ SyscallDesc("lstat", unimplementedFunc),
+ /* 108 */ SyscallDesc("fstat", unimplementedFunc),
+ /* 109 */ SyscallDesc("olduname", unimplementedFunc),
+ /* 110 */ SyscallDesc("iopl", unimplementedFunc),
+ /* 111 */ SyscallDesc("vhangup", unimplementedFunc),
+ /* 112 */ SyscallDesc("idle", unimplementedFunc),
+ /* 113 */ SyscallDesc("vm86old", 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", unimplementedFunc),
+ /* 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),
+ /* 145 */ SyscallDesc("readv", unimplementedFunc),
+ /* 146 */ SyscallDesc("writev", writevFunc<X86Linux32>),
+ /* 147 */ SyscallDesc("getsid", unimplementedFunc),
+ /* 148 */ SyscallDesc("fdatasync", unimplementedFunc),
+ /* 149 */ SyscallDesc("_sysctl", unimplementedFunc),
+ /* 150 */ SyscallDesc("mlock", unimplementedFunc),
+ /* 151 */ SyscallDesc("munlock", unimplementedFunc),
+ /* 152 */ SyscallDesc("mlockall", unimplementedFunc),
+ /* 153 */ SyscallDesc("munlockall", unimplementedFunc),
+ /* 154 */ SyscallDesc("sched_setparam", unimplementedFunc),
+ /* 155 */ SyscallDesc("sched_getparam", unimplementedFunc),
+ /* 156 */ SyscallDesc("sched_setscheduler", unimplementedFunc),
+ /* 157 */ SyscallDesc("sched_getscheduler", unimplementedFunc),
+ /* 158 */ SyscallDesc("sched_yield", unimplementedFunc),
+ /* 159 */ SyscallDesc("sched_get_priority_max", unimplementedFunc),
+ /* 160 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
+ /* 161 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
+ /* 162 */ SyscallDesc("nanosleep", unimplementedFunc),
+ /* 163 */ SyscallDesc("mremap", unimplementedFunc),
+ /* 164 */ SyscallDesc("setresuid", unimplementedFunc),
+ /* 165 */ SyscallDesc("getresuid", unimplementedFunc),
+ /* 166 */ SyscallDesc("vm86", unimplementedFunc),
+ /* 167 */ SyscallDesc("query_module", unimplementedFunc),
+ /* 168 */ SyscallDesc("poll", unimplementedFunc),
+ /* 169 */ SyscallDesc("nfsservctl", unimplementedFunc),
+ /* 170 */ SyscallDesc("setresgid", unimplementedFunc),
+ /* 171 */ SyscallDesc("getresgid", unimplementedFunc),
+ /* 172 */ SyscallDesc("prctl", unimplementedFunc),
+ /* 173 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
+ /* 174 */ SyscallDesc("rt_sigaction", unimplementedFunc),
+ /* 175 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
+ /* 176 */ SyscallDesc("rt_sigpending", unimplementedFunc),
+ /* 177 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
+ /* 178 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc),
+ /* 179 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
+ /* 180 */ SyscallDesc("pread64", unimplementedFunc),
+ /* 181 */ SyscallDesc("pwrite64", unimplementedFunc),
+ /* 182 */ SyscallDesc("chown", unimplementedFunc),
+ /* 183 */ SyscallDesc("getcwd", unimplementedFunc),
+ /* 184 */ SyscallDesc("capget", unimplementedFunc),
+ /* 185 */ SyscallDesc("capset", unimplementedFunc),
+ /* 186 */ SyscallDesc("sigaltstack", unimplementedFunc),
+ /* 187 */ SyscallDesc("sendfile", unimplementedFunc),
+ /* 188 */ SyscallDesc("getpmsg", unimplementedFunc),
+ /* 189 */ SyscallDesc("putpmsg", unimplementedFunc),
+ /* 190 */ SyscallDesc("vfork", unimplementedFunc),
+ /* 191 */ SyscallDesc("ugetrlimit", unimplementedFunc),
+ /* 192 */ SyscallDesc("mmap2", mmapFunc<X86Linux32>),
+ /* 193 */ SyscallDesc("truncate64", unimplementedFunc),
+ /* 194 */ SyscallDesc("ftruncate64", unimplementedFunc),
+ /* 195 */ SyscallDesc("stat64", unimplementedFunc),
+ /* 196 */ SyscallDesc("lstat64", unimplementedFunc),
+ /* 197 */ SyscallDesc("fstat64", fstat64Func<X86Linux32>),
+ /* 198 */ SyscallDesc("lchown32", unimplementedFunc),
+ /* 199 */ SyscallDesc("getuid32", unimplementedFunc),
+ /* 200 */ SyscallDesc("getgid32", unimplementedFunc),
+ /* 201 */ SyscallDesc("geteuid32", unimplementedFunc),
+ /* 202 */ SyscallDesc("getegid32", unimplementedFunc),
+ /* 203 */ SyscallDesc("setreuid32", unimplementedFunc),
+ /* 204 */ SyscallDesc("setregid32", unimplementedFunc),
+ /* 205 */ SyscallDesc("getgroups32", unimplementedFunc),
+ /* 206 */ SyscallDesc("setgroups32", unimplementedFunc),
+ /* 207 */ SyscallDesc("fchown32", unimplementedFunc),
+ /* 208 */ SyscallDesc("setresuid32", unimplementedFunc),
+ /* 209 */ SyscallDesc("getresuid32", unimplementedFunc),
+ /* 210 */ SyscallDesc("setresgid32", unimplementedFunc),
+ /* 211 */ SyscallDesc("getresgid32", unimplementedFunc),
+ /* 212 */ SyscallDesc("chown32", unimplementedFunc),
+ /* 213 */ SyscallDesc("setuid32", unimplementedFunc),
+ /* 214 */ SyscallDesc("setgid32", unimplementedFunc),
+ /* 215 */ SyscallDesc("setfsuid32", unimplementedFunc),
+ /* 216 */ SyscallDesc("setfsgid32", unimplementedFunc),
+ /* 217 */ SyscallDesc("pivot_root", unimplementedFunc),
+ /* 218 */ SyscallDesc("mincore", unimplementedFunc),
+ /* 219 */ SyscallDesc("madvise", unimplementedFunc),
+ /* 220 */ SyscallDesc("madvise1", unimplementedFunc),
+ /* 221 */ SyscallDesc("getdents64", unimplementedFunc),
+ /* 222 */ SyscallDesc("fcntl64", unimplementedFunc),
+ /* 223 */ SyscallDesc("unused", unimplementedFunc),
+ /* 224 */ SyscallDesc("gettid", unimplementedFunc),
+ /* 225 */ SyscallDesc("readahead", unimplementedFunc),
+ /* 226 */ SyscallDesc("setxattr", unimplementedFunc),
+ /* 227 */ SyscallDesc("lsetxattr", unimplementedFunc),
+ /* 228 */ SyscallDesc("fsetxattr", unimplementedFunc),
+ /* 229 */ SyscallDesc("getxattr", unimplementedFunc),
+ /* 230 */ SyscallDesc("lgetxattr", unimplementedFunc),
+ /* 231 */ SyscallDesc("fgetxattr", unimplementedFunc),
+ /* 232 */ SyscallDesc("listxattr", unimplementedFunc),
+ /* 233 */ SyscallDesc("llistxattr", unimplementedFunc),
+ /* 234 */ SyscallDesc("flistxattr", unimplementedFunc),
+ /* 235 */ SyscallDesc("removexattr", unimplementedFunc),
+ /* 236 */ SyscallDesc("lremovexattr", unimplementedFunc),
+ /* 237 */ SyscallDesc("fremovexattr", unimplementedFunc),
+ /* 238 */ SyscallDesc("tkill", unimplementedFunc),
+ /* 239 */ SyscallDesc("sendfile64", unimplementedFunc),
+ /* 240 */ SyscallDesc("futex", unimplementedFunc),
+ /* 241 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
+ /* 242 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
+ /* 243 */ SyscallDesc("set_thread_area", setThreadArea32Func),
+ /* 244 */ SyscallDesc("get_thread_area", unimplementedFunc),
+ /* 245 */ SyscallDesc("io_setup", unimplementedFunc),
+ /* 246 */ SyscallDesc("io_destroy", unimplementedFunc),
+ /* 247 */ SyscallDesc("io_getevents", unimplementedFunc),
+ /* 248 */ SyscallDesc("io_submit", unimplementedFunc),
+ /* 249 */ SyscallDesc("io_cancel", unimplementedFunc),
+ /* 250 */ SyscallDesc("fadvise64", unimplementedFunc),
+ /* 251 */ SyscallDesc("unused", unimplementedFunc),
+ /* 252 */ SyscallDesc("exit_group", exitFunc),
+ /* 253 */ SyscallDesc("lookup_dcookie", unimplementedFunc),
+ /* 254 */ SyscallDesc("epoll_create", unimplementedFunc),
+ /* 255 */ SyscallDesc("epoll_ctl", unimplementedFunc),
+ /* 256 */ SyscallDesc("epoll_wait", unimplementedFunc),
+ /* 257 */ SyscallDesc("remap_file_pages", unimplementedFunc),
+ /* 258 */ SyscallDesc("set_tid_address", unimplementedFunc),
+ /* 259 */ SyscallDesc("timer_create", unimplementedFunc),
+ /* 260 */ SyscallDesc("timer_settime", unimplementedFunc),
+ /* 261 */ SyscallDesc("timer_gettime", unimplementedFunc),
+ /* 262 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
+ /* 263 */ SyscallDesc("timer_delete", unimplementedFunc),
+ /* 264 */ SyscallDesc("clock_settime", unimplementedFunc),
+ /* 265 */ SyscallDesc("clock_gettime", unimplementedFunc),
+ /* 266 */ SyscallDesc("clock_getres", unimplementedFunc),
+ /* 267 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
+ /* 268 */ SyscallDesc("statfs64", unimplementedFunc),
+ /* 269 */ SyscallDesc("fstatfs64", unimplementedFunc),
+ /* 270 */ SyscallDesc("tgkill", unimplementedFunc),
+ /* 271 */ SyscallDesc("utimes", unimplementedFunc),
+ /* 272 */ SyscallDesc("fadvise64_64", unimplementedFunc),
+ /* 273 */ SyscallDesc("vserver", unimplementedFunc),
+ /* 274 */ SyscallDesc("mbind", unimplementedFunc),
+ /* 275 */ SyscallDesc("get_mempolicy", unimplementedFunc),
+ /* 276 */ SyscallDesc("set_mempolicy", unimplementedFunc),
+ /* 277 */ SyscallDesc("mq_open", unimplementedFunc),
+ /* 278 */ SyscallDesc("mq_unlink", unimplementedFunc),
+ /* 279 */ SyscallDesc("mq_timedsend", unimplementedFunc),
+ /* 280 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
+ /* 281 */ SyscallDesc("mq_notify", unimplementedFunc),
+ /* 282 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
+ /* 283 */ SyscallDesc("kexec_load", unimplementedFunc),
+ /* 284 */ SyscallDesc("waitid", unimplementedFunc),
+ /* 285 */ SyscallDesc("sys_setaltroot", unimplementedFunc),
+ /* 286 */ SyscallDesc("add_key", unimplementedFunc),
+ /* 287 */ SyscallDesc("request_key", unimplementedFunc),
+ /* 288 */ SyscallDesc("keyctl", unimplementedFunc),
+ /* 289 */ SyscallDesc("ioprio_set", unimplementedFunc),
+ /* 290 */ SyscallDesc("ioprio_get", unimplementedFunc),
+ /* 291 */ SyscallDesc("inotify_init", unimplementedFunc),
+ /* 292 */ SyscallDesc("inotify_add_watch", unimplementedFunc),
+ /* 293 */ SyscallDesc("inotify_rm_watch", unimplementedFunc),
+ /* 294 */ SyscallDesc("migrate_pages", unimplementedFunc),
+ /* 295 */ SyscallDesc("openat", unimplementedFunc),
+ /* 296 */ SyscallDesc("mkdirat", unimplementedFunc),
+ /* 297 */ SyscallDesc("mknodat", unimplementedFunc),
+ /* 298 */ SyscallDesc("fchownat", unimplementedFunc),
+ /* 299 */ SyscallDesc("futimesat", unimplementedFunc),
+ /* 300 */ SyscallDesc("fstatat64", unimplementedFunc),
+ /* 301 */ SyscallDesc("unlinkat", unimplementedFunc),
+ /* 302 */ SyscallDesc("renameat", unimplementedFunc),
+ /* 303 */ SyscallDesc("linkat", unimplementedFunc),
+ /* 304 */ SyscallDesc("symlinkat", unimplementedFunc),
+ /* 305 */ SyscallDesc("readlinkat", unimplementedFunc),
+ /* 306 */ SyscallDesc("fchmodat", unimplementedFunc),
+ /* 307 */ SyscallDesc("faccessat", unimplementedFunc),
+ /* 308 */ SyscallDesc("pselect6", unimplementedFunc),
+ /* 309 */ SyscallDesc("ppoll", unimplementedFunc),
+ /* 310 */ SyscallDesc("unshare", unimplementedFunc),
+ /* 311 */ SyscallDesc("set_robust_list", unimplementedFunc),
+ /* 312 */ SyscallDesc("get_robust_list", unimplementedFunc),
+ /* 313 */ SyscallDesc("splice", unimplementedFunc),
+ /* 314 */ SyscallDesc("sync_file_range", unimplementedFunc),
+ /* 315 */ SyscallDesc("tee", unimplementedFunc),
+ /* 316 */ SyscallDesc("vmsplice", unimplementedFunc),
+ /* 317 */ SyscallDesc("move_pages", unimplementedFunc),
+ /* 318 */ SyscallDesc("getcpu", unimplementedFunc),
+ /* 319 */ SyscallDesc("epoll_pwait", unimplementedFunc),
+ /* 320 */ SyscallDesc("utimensat", unimplementedFunc),
+ /* 321 */ SyscallDesc("signalfd", unimplementedFunc),
+ /* 322 */ SyscallDesc("timerfd", unimplementedFunc),
+ /* 323 */ SyscallDesc("eventfd", unimplementedFunc)
+};
diff --git a/src/arch/x86/linux/system.cc b/src/arch/x86/linux/system.cc
index 944bb2930..c2d9cb35c 100644
--- a/src/arch/x86/linux/system.cc
+++ b/src/arch/x86/linux/system.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * Copyright (c) 2007-2008 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
@@ -68,7 +68,7 @@ using namespace LittleEndianGuest;
using namespace X86ISA;
LinuxX86System::LinuxX86System(Params *p)
- : X86System(p), commandLine(p->boot_osflags)
+ : X86System(p), commandLine(p->boot_osflags), e820Table(p->e820_table)
{
}
@@ -144,62 +144,7 @@ LinuxX86System::startup()
// A pointer to the buffer for E820 entries.
const Addr e820MapPointer = realModeData + 0x2d0;
- struct e820Entry
- {
- Addr addr;
- Addr size;
- uint32_t type;
- };
-
- // The size is computed this way to ensure no padding sneaks in.
- int e820EntrySize =
- sizeof(e820Entry().addr) +
- sizeof(e820Entry().size) +
- sizeof(e820Entry().type);
-
- // I'm not sure what these should actually be. On a real machine they
- // would be generated by the BIOS, and they need to reflect the regions
- // which are actually available/reserved. These values are copied from
- // my development machine.
- e820Entry e820Map[] = {
- {ULL(0x0), ULL(0x9d400), 1},
- {ULL(0x9d400), ULL(0xa0000) - ULL(0x9d400), 2},
- {ULL(0xe8000), ULL(0x100000) - ULL(0xe8000), 2},
- {ULL(0x100000), ULL(0xcfff9300) - ULL(0x100000), 1},
- {ULL(0xcfff9300), ULL(0xd0000000) - ULL(0xcfff9300), 2},
- {ULL(0xfec00000), ULL(0x100000000) - ULL(0xfec00000), 2}
- };
-
- uint8_t e820Nr = sizeof(e820Map) / sizeof(e820Entry);
-
- // Make sure the number of entries isn't bigger than what the kernel
- // would be capable of providing.
- assert(e820Nr <= 128);
-
- uint8_t guestE820Nr = X86ISA::htog(e820Nr);
- physPort->writeBlob(e820MapNrPointer,
- (uint8_t *)&guestE820Nr, sizeof(guestE820Nr));
-
- for (int i = 0; i < e820Nr; i++) {
- e820Entry guestE820Entry;
- guestE820Entry.addr = X86ISA::htog(e820Map[i].addr);
- guestE820Entry.size = X86ISA::htog(e820Map[i].size);
- guestE820Entry.type = X86ISA::htog(e820Map[i].type);
- physPort->writeBlob(e820MapPointer + e820EntrySize * i,
- (uint8_t *)&guestE820Entry.addr,
- sizeof(guestE820Entry.addr));
- physPort->writeBlob(
- e820MapPointer + e820EntrySize * i +
- sizeof(guestE820Entry.addr),
- (uint8_t *)&guestE820Entry.size,
- sizeof(guestE820Entry.size));
- physPort->writeBlob(
- e820MapPointer + e820EntrySize * i +
- sizeof(guestE820Entry.addr) +
- sizeof(guestE820Entry.size),
- (uint8_t *)&guestE820Entry.type,
- sizeof(guestE820Entry.type));
- }
+ e820Table->writeTo(physPort, e820MapNrPointer, e820MapPointer);
/*
* Pass the location of the real mode data structure to the kernel
diff --git a/src/arch/x86/linux/system.hh b/src/arch/x86/linux/system.hh
index fc725ad45..a9c5f4ca9 100644
--- a/src/arch/x86/linux/system.hh
+++ b/src/arch/x86/linux/system.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * Copyright (c) 2007-2008 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
@@ -62,12 +62,14 @@
#include <vector>
#include "params/LinuxX86System.hh"
+#include "arch/x86/bios/e820.hh"
#include "arch/x86/system.hh"
class LinuxX86System : public X86System
{
protected:
std::string commandLine;
+ X86ISA::E820Table * e820Table;
public:
typedef LinuxX86SystemParams Params;
diff --git a/src/arch/x86/microcode_rom.hh b/src/arch/x86/microcode_rom.hh
new file mode 100644
index 000000000..f8ad410ce
--- /dev/null
+++ b/src/arch/x86/microcode_rom.hh
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2008 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_X86_MICROCODE_ROM_HH__
+#define __ARCH_X86_MICROCODE_ROM_HH__
+
+#include "arch/x86/emulenv.hh"
+#include "cpu/static_inst.hh"
+
+namespace X86ISAInst
+{
+ class MicrocodeRom
+ {
+ protected:
+
+ typedef StaticInstPtr (*GenFunc)(StaticInstPtr);
+
+ static const MicroPC numMicroops;
+
+ GenFunc * genFuncs;
+
+ public:
+ //Constructor.
+ MicrocodeRom();
+
+ //Destructor.
+ ~MicrocodeRom()
+ {
+ delete [] genFuncs;
+ }
+
+ StaticInstPtr
+ fetchMicroop(MicroPC microPC, StaticInstPtr curMacroop)
+ {
+ microPC = normalMicroPC(microPC);
+ assert(microPC < numMicroops);
+ return genFuncs[microPC](curMacroop);
+ }
+ };
+}
+
+namespace X86ISA
+{
+ using X86ISAInst::MicrocodeRom;
+}
+
+#endif // __ARCH_X86_MICROCODE_ROM_HH__
diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc
index 3b4dc3407..0316603e5 100644
--- a/src/arch/x86/miscregfile.cc
+++ b/src/arch/x86/miscregfile.cc
@@ -87,6 +87,7 @@
#include "arch/x86/miscregfile.hh"
#include "arch/x86/tlb.hh"
+#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "sim/serialize.hh"
@@ -95,19 +96,16 @@ using namespace std;
class Checkpoint;
-//These functions map register indices to names
-string X86ISA::getMiscRegName(RegIndex index)
-{
- panic("No misc registers in x86 yet!\n");
-}
-
void MiscRegFile::clear()
{
- // Blank everything. 0 might not be an appropriate value for some things.
+ // Blank everything. 0 might not be an appropriate value for some things,
+ // but it is for most.
memset(regVal, 0, NumMiscRegs * sizeof(MiscReg));
+ regVal[MISCREG_DR6] = (mask(8) << 4) | (mask(16) << 16);
+ regVal[MISCREG_DR7] = 1 << 10;
}
-MiscReg MiscRegFile::readRegNoEffect(int miscReg)
+MiscReg MiscRegFile::readRegNoEffect(MiscRegIndex miscReg)
{
// Make sure we're not dealing with an illegal control register.
// Instructions should filter out these indexes, and nothing else should
@@ -121,90 +119,15 @@ MiscReg MiscRegFile::readRegNoEffect(int miscReg)
return regVal[miscReg];
}
-MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc)
+MiscReg MiscRegFile::readReg(MiscRegIndex miscReg, ThreadContext * tc)
{
- if (miscReg >= MISCREG_APIC_START && miscReg <= MISCREG_APIC_END) {
- if (miscReg >= MISCREG_APIC_IN_SERVICE(0) &&
- miscReg <= MISCREG_APIC_IN_SERVICE(15)) {
- panic("Local APIC In-Service registers are unimplemented.\n");
- }
- if (miscReg >= MISCREG_APIC_TRIGGER_MODE(0) &&
- miscReg <= MISCREG_APIC_TRIGGER_MODE(15)) {
- panic("Local APIC Trigger Mode registers are unimplemented.\n");
- }
- if (miscReg >= MISCREG_APIC_INTERRUPT_REQUEST(0) &&
- miscReg <= MISCREG_APIC_INTERRUPT_REQUEST(15)) {
- panic("Local APIC Interrupt Request registers "
- "are unimplemented.\n");
- }
- switch (miscReg) {
- case MISCREG_APIC_TASK_PRIORITY:
- panic("Local APIC Task Priority register unimplemented.\n");
- break;
- case MISCREG_APIC_ARBITRATION_PRIORITY:
- panic("Local APIC Arbitration Priority register unimplemented.\n");
- break;
- case MISCREG_APIC_PROCESSOR_PRIORITY:
- panic("Local APIC Processor Priority register unimplemented.\n");
- break;
- case MISCREG_APIC_EOI:
- panic("Local APIC EOI register unimplemented.\n");
- break;
- case MISCREG_APIC_LOGICAL_DESTINATION:
- panic("Local APIC Logical Destination register unimplemented.\n");
- break;
- case MISCREG_APIC_DESTINATION_FORMAT:
- panic("Local APIC Destination Format register unimplemented.\n");
- break;
- case MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR:
- panic("Local APIC Spurious Interrupt Vector"
- " register unimplemented.\n");
- break;
- case MISCREG_APIC_ERROR_STATUS:
- panic("Local APIC Error Status register unimplemented.\n");
- break;
- case MISCREG_APIC_INTERRUPT_COMMAND_LOW:
- panic("Local APIC Interrupt Command low"
- " register unimplemented.\n");
- break;
- case MISCREG_APIC_INTERRUPT_COMMAND_HIGH:
- panic("Local APIC Interrupt Command high"
- " register unimplemented.\n");
- break;
- case MISCREG_APIC_LVT_TIMER:
- panic("Local APIC LVT Timer register unimplemented.\n");
- break;
- case MISCREG_APIC_LVT_THERMAL_SENSOR:
- panic("Local APIC LVT Thermal Sensor register unimplemented.\n");
- break;
- case MISCREG_APIC_LVT_PERFORMANCE_MONITORING_COUNTERS:
- panic("Local APIC LVT Performance Monitoring Counters"
- " register unimplemented.\n");
- break;
- case MISCREG_APIC_LVT_LINT0:
- panic("Local APIC LVT LINT0 register unimplemented.\n");
- break;
- case MISCREG_APIC_LVT_LINT1:
- panic("Local APIC LVT LINT1 register unimplemented.\n");
- break;
- case MISCREG_APIC_LVT_ERROR:
- panic("Local APIC LVT Error register unimplemented.\n");
- break;
- case MISCREG_APIC_INITIAL_COUNT:
- panic("Local APIC Initial Count register unimplemented.\n");
- break;
- case MISCREG_APIC_CURRENT_COUNT:
- panic("Local APIC Current Count register unimplemented.\n");
- break;
- case MISCREG_APIC_DIVIDE_COUNT:
- panic("Local APIC Divide Count register unimplemented.\n");
- break;
- }
+ if (miscReg == MISCREG_TSC) {
+ return regVal[MISCREG_TSC] + tc->getCpuPtr()->curCycle();
}
return readRegNoEffect(miscReg);
}
-void MiscRegFile::setRegNoEffect(int miscReg, const MiscReg &val)
+void MiscRegFile::setRegNoEffect(MiscRegIndex miscReg, const MiscReg &val)
{
// Make sure we're not dealing with an illegal control register.
// Instructions should filter out these indexes, and nothing else should
@@ -217,96 +140,10 @@ void MiscRegFile::setRegNoEffect(int miscReg, const MiscReg &val)
regVal[miscReg] = val;
}
-void MiscRegFile::setReg(int miscReg,
+void MiscRegFile::setReg(MiscRegIndex miscReg,
const MiscReg &val, ThreadContext * tc)
{
MiscReg newVal = val;
- if (miscReg >= MISCREG_APIC_START && miscReg <= MISCREG_APIC_END) {
- if (miscReg >= MISCREG_APIC_IN_SERVICE(0) &&
- miscReg <= MISCREG_APIC_IN_SERVICE(15)) {
- panic("Local APIC In-Service registers are unimplemented.\n");
- }
- if (miscReg >= MISCREG_APIC_TRIGGER_MODE(0) &&
- miscReg <= MISCREG_APIC_TRIGGER_MODE(15)) {
- panic("Local APIC Trigger Mode registers are unimplemented.\n");
- }
- if (miscReg >= MISCREG_APIC_INTERRUPT_REQUEST(0) &&
- miscReg <= MISCREG_APIC_INTERRUPT_REQUEST(15)) {
- panic("Local APIC Interrupt Request registers "
- "are unimplemented.\n");
- }
- switch (miscReg) {
- case MISCREG_APIC_ID:
- panic("Local APIC ID register unimplemented.\n");
- break;
- case MISCREG_APIC_VERSION:
- panic("Local APIC Version register is read only.\n");
- break;
- case MISCREG_APIC_TASK_PRIORITY:
- panic("Local APIC Task Priority register unimplemented.\n");
- break;
- case MISCREG_APIC_ARBITRATION_PRIORITY:
- panic("Local APIC Arbitration Priority register unimplemented.\n");
- break;
- case MISCREG_APIC_PROCESSOR_PRIORITY:
- panic("Local APIC Processor Priority register unimplemented.\n");
- break;
- case MISCREG_APIC_EOI:
- panic("Local APIC EOI register unimplemented.\n");
- break;
- case MISCREG_APIC_LOGICAL_DESTINATION:
- panic("Local APIC Logical Destination register unimplemented.\n");
- break;
- case MISCREG_APIC_DESTINATION_FORMAT:
- panic("Local APIC Destination Format register unimplemented.\n");
- break;
- case MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR:
- panic("Local APIC Spurious Interrupt Vector"
- " register unimplemented.\n");
- break;
- case MISCREG_APIC_ERROR_STATUS:
- panic("Local APIC Error Status register unimplemented.\n");
- break;
- case MISCREG_APIC_INTERRUPT_COMMAND_LOW:
- panic("Local APIC Interrupt Command low"
- " register unimplemented.\n");
- break;
- case MISCREG_APIC_INTERRUPT_COMMAND_HIGH:
- panic("Local APIC Interrupt Command high"
- " register unimplemented.\n");
- break;
- case MISCREG_APIC_LVT_TIMER:
- panic("Local APIC LVT Timer register unimplemented.\n");
- break;
- case MISCREG_APIC_LVT_THERMAL_SENSOR:
- panic("Local APIC LVT Thermal Sensor register unimplemented.\n");
- break;
- case MISCREG_APIC_LVT_PERFORMANCE_MONITORING_COUNTERS:
- panic("Local APIC LVT Performance Monitoring Counters"
- " register unimplemented.\n");
- break;
- case MISCREG_APIC_LVT_LINT0:
- panic("Local APIC LVT LINT0 register unimplemented.\n");
- break;
- case MISCREG_APIC_LVT_LINT1:
- panic("Local APIC LVT LINT1 register unimplemented.\n");
- break;
- case MISCREG_APIC_LVT_ERROR:
- panic("Local APIC LVT Error register unimplemented.\n");
- break;
- case MISCREG_APIC_INITIAL_COUNT:
- panic("Local APIC Initial Count register unimplemented.\n");
- break;
- case MISCREG_APIC_CURRENT_COUNT:
- panic("Local APIC Current Count register unimplemented.\n");
- break;
- case MISCREG_APIC_DIVIDE_COUNT:
- panic("Local APIC Divide Count register unimplemented.\n");
- break;
- }
- setRegNoEffect(miscReg, newVal);
- return;
- }
switch(miscReg)
{
case MISCREG_CR0:
@@ -314,17 +151,39 @@ void MiscRegFile::setReg(int miscReg,
CR0 toggled = regVal[miscReg] ^ val;
CR0 newCR0 = val;
Efer efer = regVal[MISCREG_EFER];
+ HandyM5Reg m5reg = regVal[MISCREG_M5_REG];
if (toggled.pg && efer.lme) {
if (newCR0.pg) {
//Turning on long mode
efer.lma = 1;
+ m5reg.mode = LongMode;
regVal[MISCREG_EFER] = efer;
} else {
//Turning off long mode
efer.lma = 0;
+ m5reg.mode = LegacyMode;
regVal[MISCREG_EFER] = efer;
}
}
+ // Figure out what submode we're in.
+ if (m5reg.mode == LongMode) {
+ SegAttr csAttr = regVal[MISCREG_CS_ATTR];
+ if (csAttr.longMode)
+ m5reg.submode = SixtyFourBitMode;
+ else
+ m5reg.submode = CompatabilityMode;
+ } else {
+ if (newCR0.pe) {
+ RFLAGS rflags = regVal[MISCREG_RFLAGS];
+ if (rflags.vm)
+ m5reg.submode = Virtual8086Mode;
+ else
+ m5reg.submode = ProtectedMode;
+ } else {
+ m5reg.submode = RealMode;
+ }
+ }
+ regVal[MISCREG_M5_REG] = m5reg;
if (toggled.pg) {
tc->getITBPtr()->invalidateAll();
tc->getDTBPtr()->invalidateAll();
@@ -355,20 +214,26 @@ void MiscRegFile::setReg(int miscReg,
{
SegAttr toggled = regVal[miscReg] ^ val;
SegAttr newCSAttr = val;
+ HandyM5Reg m5reg = regVal[MISCREG_M5_REG];
if (toggled.longMode) {
- SegAttr newCSAttr = val;
if (newCSAttr.longMode) {
+ if (m5reg.mode == LongMode)
+ m5reg.submode = SixtyFourBitMode;
regVal[MISCREG_ES_EFF_BASE] = 0;
regVal[MISCREG_CS_EFF_BASE] = 0;
regVal[MISCREG_SS_EFF_BASE] = 0;
regVal[MISCREG_DS_EFF_BASE] = 0;
} else {
+ if (m5reg.mode == LongMode)
+ m5reg.submode = CompatabilityMode;
regVal[MISCREG_ES_EFF_BASE] = regVal[MISCREG_ES_BASE];
regVal[MISCREG_CS_EFF_BASE] = regVal[MISCREG_CS_BASE];
regVal[MISCREG_SS_EFF_BASE] = regVal[MISCREG_SS_BASE];
regVal[MISCREG_DS_EFF_BASE] = regVal[MISCREG_DS_BASE];
}
}
+ m5reg.cpl = newCSAttr.dpl;
+ regVal[MISCREG_M5_REG] = m5reg;
}
break;
// These segments always actually use their bases, or in other words
@@ -396,6 +261,80 @@ void MiscRegFile::setReg(int miscReg,
MISCREG_SEG_BASE_BASE)] = val;
}
break;
+ case MISCREG_TSC:
+ regVal[MISCREG_TSC] = val - tc->getCpuPtr()->curCycle();
+ return;
+ case MISCREG_DR0:
+ case MISCREG_DR1:
+ case MISCREG_DR2:
+ case MISCREG_DR3:
+ /* These should eventually set up breakpoints. */
+ break;
+ case MISCREG_DR4:
+ miscReg = MISCREG_DR6;
+ /* Fall through to have the same effects as DR6. */
+ case MISCREG_DR6:
+ {
+ DR6 dr6 = regVal[MISCREG_DR6];
+ DR6 newDR6 = val;
+ dr6.b0 = newDR6.b0;
+ dr6.b1 = newDR6.b1;
+ dr6.b2 = newDR6.b2;
+ dr6.b3 = newDR6.b3;
+ dr6.bd = newDR6.bd;
+ dr6.bs = newDR6.bs;
+ dr6.bt = newDR6.bt;
+ newVal = dr6;
+ }
+ break;
+ case MISCREG_DR5:
+ miscReg = MISCREG_DR7;
+ /* Fall through to have the same effects as DR7. */
+ case MISCREG_DR7:
+ {
+ DR7 dr7 = regVal[MISCREG_DR7];
+ DR7 newDR7 = val;
+ dr7.l0 = newDR7.l0;
+ dr7.g0 = newDR7.g0;
+ if (dr7.l0 || dr7.g0) {
+ panic("Debug register breakpoints not implemented.\n");
+ } else {
+ /* Disable breakpoint 0. */
+ }
+ dr7.l1 = newDR7.l1;
+ dr7.g1 = newDR7.g1;
+ if (dr7.l1 || dr7.g1) {
+ panic("Debug register breakpoints not implemented.\n");
+ } else {
+ /* Disable breakpoint 1. */
+ }
+ dr7.l2 = newDR7.l2;
+ dr7.g2 = newDR7.g2;
+ if (dr7.l2 || dr7.g2) {
+ panic("Debug register breakpoints not implemented.\n");
+ } else {
+ /* Disable breakpoint 2. */
+ }
+ dr7.l3 = newDR7.l3;
+ dr7.g3 = newDR7.g3;
+ if (dr7.l3 || dr7.g3) {
+ panic("Debug register breakpoints not implemented.\n");
+ } else {
+ /* Disable breakpoint 3. */
+ }
+ dr7.gd = newDR7.gd;
+ dr7.rw0 = newDR7.rw0;
+ dr7.len0 = newDR7.len0;
+ dr7.rw1 = newDR7.rw1;
+ dr7.len1 = newDR7.len1;
+ dr7.rw2 = newDR7.rw2;
+ dr7.len2 = newDR7.len2;
+ dr7.rw3 = newDR7.rw3;
+ dr7.len3 = newDR7.len3;
+ }
+ break;
+ default:
+ break;
}
setRegNoEffect(miscReg, newVal);
}
diff --git a/src/arch/x86/miscregfile.hh b/src/arch/x86/miscregfile.hh
index e095e06e9..6d3ae4e92 100644
--- a/src/arch/x86/miscregfile.hh
+++ b/src/arch/x86/miscregfile.hh
@@ -29,7 +29,7 @@
*/
/*
- * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * Copyright (c) 2007-2008 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
@@ -91,6 +91,7 @@
#include "arch/x86/faults.hh"
#include "arch/x86/miscregs.hh"
#include "arch/x86/types.hh"
+#include "sim/host.hh"
#include <string>
@@ -98,8 +99,6 @@ class Checkpoint;
namespace X86ISA
{
- std::string getMiscRegName(RegIndex);
-
//These will have to be updated in the future.
const int NumMiscArchRegs = NUM_MISCREGS;
const int NumMiscRegs = NUM_MISCREGS;
@@ -117,13 +116,13 @@ namespace X86ISA
clear();
}
- MiscReg readRegNoEffect(int miscReg);
+ MiscReg readRegNoEffect(MiscRegIndex miscReg);
- MiscReg readReg(int miscReg, ThreadContext *tc);
+ MiscReg readReg(MiscRegIndex miscReg, ThreadContext *tc);
- void setRegNoEffect(int miscReg, const MiscReg &val);
+ void setRegNoEffect(MiscRegIndex miscReg, const MiscReg &val);
- void setReg(int miscReg,
+ void setReg(MiscRegIndex miscReg,
const MiscReg &val, ThreadContext *tc);
void serialize(std::ostream & os);
diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh
index d1016d2a9..af02e9422 100644
--- a/src/arch/x86/miscregs.hh
+++ b/src/arch/x86/miscregs.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * Copyright (c) 2007-2008 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
@@ -82,6 +82,18 @@ namespace X86ISA
OFBit = 1 << 11
};
+ enum RFLAGBit {
+ TFBit = 1 << 8,
+ IFBit = 1 << 9,
+ NTBit = 1 << 14,
+ RFBit = 1 << 16,
+ VMBit = 1 << 17,
+ ACBit = 1 << 18,
+ VIFBit = 1 << 19,
+ VIPBit = 1 << 20,
+ IDBit = 1 << 21
+ };
+
enum MiscRegIndex
{
// Control registers
@@ -118,6 +130,9 @@ namespace X86ISA
// Flags register
MISCREG_RFLAGS = MISCREG_DR_BASE + NumDRegs,
+ //Register to keep handy values like the CPU mode in.
+ MISCREG_M5_REG,
+
/*
* Model Specific Registers
*/
@@ -183,6 +198,9 @@ namespace X86ISA
MISCREG_MC2_CTL,
MISCREG_MC3_CTL,
MISCREG_MC4_CTL,
+ MISCREG_MC5_CTL,
+ MISCREG_MC6_CTL,
+ MISCREG_MC7_CTL,
MISCREG_MC_STATUS_BASE,
MISCREG_MC0_STATUS = MISCREG_MC_STATUS_BASE,
@@ -190,6 +208,9 @@ namespace X86ISA
MISCREG_MC2_STATUS,
MISCREG_MC3_STATUS,
MISCREG_MC4_STATUS,
+ MISCREG_MC5_STATUS,
+ MISCREG_MC6_STATUS,
+ MISCREG_MC7_STATUS,
MISCREG_MC_ADDR_BASE,
MISCREG_MC0_ADDR = MISCREG_MC_ADDR_BASE,
@@ -197,6 +218,9 @@ namespace X86ISA
MISCREG_MC2_ADDR,
MISCREG_MC3_ADDR,
MISCREG_MC4_ADDR,
+ MISCREG_MC5_ADDR,
+ MISCREG_MC6_ADDR,
+ MISCREG_MC7_ADDR,
MISCREG_MC_MISC_BASE,
MISCREG_MC0_MISC = MISCREG_MC_MISC_BASE,
@@ -204,6 +228,9 @@ namespace X86ISA
MISCREG_MC2_MISC,
MISCREG_MC3_MISC,
MISCREG_MC4_MISC,
+ MISCREG_MC5_MISC,
+ MISCREG_MC6_MISC,
+ MISCREG_MC7_MISC,
// Extended feature enable register
MISCREG_EFER,
@@ -341,38 +368,6 @@ namespace X86ISA
MISCREG_APIC_BASE,
- MISCREG_APIC_START,
- MISCREG_APIC_ID = MISCREG_APIC_START,
- MISCREG_APIC_VERSION,
- MISCREG_APIC_TASK_PRIORITY,
- MISCREG_APIC_ARBITRATION_PRIORITY,
- MISCREG_APIC_PROCESSOR_PRIORITY,
- MISCREG_APIC_EOI,
- MISCREG_APIC_LOGICAL_DESTINATION,
- MISCREG_APIC_DESTINATION_FORMAT,
- MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR,
-
- MISCREG_APIC_IN_SERVICE_BASE,
-
- MISCREG_APIC_TRIGGER_MODE_BASE = MISCREG_APIC_IN_SERVICE_BASE + 16,
-
- MISCREG_APIC_INTERRUPT_REQUEST_BASE =
- MISCREG_APIC_TRIGGER_MODE_BASE + 16,
-
- MISCREG_APIC_ERROR_STATUS = MISCREG_APIC_INTERRUPT_REQUEST_BASE + 16,
- MISCREG_APIC_INTERRUPT_COMMAND_LOW,
- MISCREG_APIC_INTERRUPT_COMMAND_HIGH,
- MISCREG_APIC_LVT_TIMER,
- MISCREG_APIC_LVT_THERMAL_SENSOR,
- MISCREG_APIC_LVT_PERFORMANCE_MONITORING_COUNTERS,
- MISCREG_APIC_LVT_LINT0,
- MISCREG_APIC_LVT_LINT1,
- MISCREG_APIC_LVT_ERROR,
- MISCREG_APIC_INITIAL_COUNT,
- MISCREG_APIC_CURRENT_COUNT,
- MISCREG_APIC_DIVIDE_COUNT,
- MISCREG_APIC_END = MISCREG_APIC_DIVIDE_COUNT,
-
// "Fake" MSRs for internally implemented devices
MISCREG_PCI_CONFIG_ADDRESS,
@@ -481,24 +476,6 @@ namespace X86ISA
return (MiscRegIndex)(MISCREG_SEG_ATTR_BASE + index);
}
- static inline MiscRegIndex
- MISCREG_APIC_IN_SERVICE(int index)
- {
- return (MiscRegIndex)(MISCREG_APIC_IN_SERVICE_BASE + index);
- }
-
- static inline MiscRegIndex
- MISCREG_APIC_TRIGGER_MODE(int index)
- {
- return (MiscRegIndex)(MISCREG_APIC_TRIGGER_MODE_BASE + index);
- }
-
- static inline MiscRegIndex
- MISCREG_APIC_INTERRUPT_REQUEST(int index)
- {
- return (MiscRegIndex)(MISCREG_APIC_INTERRUPT_REQUEST_BASE + index);
- }
-
/**
* A type to describe the condition code bits of the RFLAGS register,
* plus two flags, EZF and ECF, which are only visible to microcode.
@@ -537,6 +514,12 @@ namespace X86ISA
Bitfield<0> cf; // Carry Flag
EndBitUnion(RFLAGS)
+ BitUnion64(HandyM5Reg)
+ Bitfield<0> mode;
+ Bitfield<3, 1> submode;
+ Bitfield<5, 4> cpl;
+ EndBitUnion(HandyM5Reg)
+
/**
* Control registers
*/
@@ -589,6 +572,38 @@ namespace X86ISA
Bitfield<3, 0> tpr; // Task Priority Register
EndBitUnion(CR8)
+ BitUnion64(DR6)
+ Bitfield<0> b0;
+ Bitfield<1> b1;
+ Bitfield<2> b2;
+ Bitfield<3> b3;
+ Bitfield<13> bd;
+ Bitfield<14> bs;
+ Bitfield<15> bt;
+ EndBitUnion(DR6)
+
+ BitUnion64(DR7)
+ Bitfield<0> l0;
+ Bitfield<1> g0;
+ Bitfield<2> l1;
+ Bitfield<3> g1;
+ Bitfield<4> l2;
+ Bitfield<5> g2;
+ Bitfield<6> l3;
+ Bitfield<7> g3;
+ Bitfield<8> le;
+ Bitfield<9> ge;
+ Bitfield<13> gd;
+ Bitfield<17, 16> rw0;
+ Bitfield<19, 18> len0;
+ Bitfield<21, 20> rw1;
+ Bitfield<23, 22> len1;
+ Bitfield<25, 24> rw2;
+ Bitfield<27, 26> len2;
+ Bitfield<29, 28> rw3;
+ Bitfield<31, 30> len3;
+ EndBitUnion(DR7)
+
// MTRR capabilities
BitUnion64(MTRRcap)
Bitfield<7, 0> vcnt; // Variable-Range Register Count
diff --git a/src/arch/x86/mmaped_ipr.hh b/src/arch/x86/mmaped_ipr.hh
index eda85c084..7056c0902 100644
--- a/src/arch/x86/mmaped_ipr.hh
+++ b/src/arch/x86/mmaped_ipr.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * Copyright (c) 2007-2008 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
@@ -78,15 +78,12 @@ namespace X86ISA
#if !FULL_SYSTEM
panic("Shouldn't have a memory mapped register in SE\n");
#else
+ Addr offset = pkt->getAddr() & mask(3);
MiscRegIndex index = (MiscRegIndex)(pkt->getAddr() / sizeof(MiscReg));
- if (index == MISCREG_PCI_CONFIG_ADDRESS ||
- (index >= MISCREG_APIC_START &&
- index <= MISCREG_APIC_END)) {
- pkt->set((uint32_t)(xc->readMiscReg(pkt->getAddr() /
- sizeof(MiscReg))));
- } else {
- pkt->set(xc->readMiscReg(pkt->getAddr() / sizeof(MiscReg)));
- }
+ MiscReg data = htog(xc->readMiscReg(index));
+ // Make sure we don't trot off the end of data.
+ assert(offset + pkt->getSize() <= sizeof(MiscReg));
+ pkt->setData(((uint8_t *)&data) + offset);
#endif
return xc->getCpuPtr()->ticks(1);
}
@@ -97,15 +94,14 @@ namespace X86ISA
#if !FULL_SYSTEM
panic("Shouldn't have a memory mapped register in SE\n");
#else
+ Addr offset = pkt->getAddr() & mask(3);
MiscRegIndex index = (MiscRegIndex)(pkt->getAddr() / sizeof(MiscReg));
- if (index == MISCREG_PCI_CONFIG_ADDRESS ||
- (index >= MISCREG_APIC_START &&
- index <= MISCREG_APIC_END)) {
- xc->setMiscReg(index, gtoh(pkt->get<uint32_t>()));
- } else {
- xc->setMiscReg(pkt->getAddr() / sizeof(MiscReg),
- gtoh(pkt->get<uint64_t>()));
- }
+ MiscReg data;
+ data = htog(xc->readMiscRegNoEffect(index));
+ // Make sure we don't trot off the end of data.
+ assert(offset + pkt->getSize() <= sizeof(MiscReg));
+ pkt->writeData(((uint8_t *)&data) + offset);
+ xc->setMiscReg(index, gtoh(data));
#endif
return xc->getCpuPtr()->ticks(1);
}
diff --git a/src/arch/x86/pagetable.hh b/src/arch/x86/pagetable.hh
index e42693c03..1a7a945e4 100644
--- a/src/arch/x86/pagetable.hh
+++ b/src/arch/x86/pagetable.hh
@@ -113,6 +113,12 @@ namespace X86ISA
TlbEntry(Addr asn, Addr _vaddr, Addr _paddr);
TlbEntry() {}
+ void
+ updateVaddr(Addr new_vaddr)
+ {
+ vaddr = new_vaddr;
+ }
+
Addr pageStart()
{
return paddr;
diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc
index e70c16b1d..f625cf4bd 100644
--- a/src/arch/x86/pagetable_walker.cc
+++ b/src/arch/x86/pagetable_walker.cc
@@ -84,8 +84,8 @@ BitUnion64(PageTableEntry)
Bitfield<0> p;
EndBitUnion(PageTableEntry)
-void
-Walker::doNext(PacketPtr &read, PacketPtr &write)
+Fault
+Walker::doNext(PacketPtr &write)
{
assert(state != Ready && state != Waiting);
write = NULL;
@@ -101,39 +101,45 @@ Walker::doNext(PacketPtr &read, PacketPtr &write)
bool badNX = pte.nx && (!tlb->allowNX() || !enableNX);
switch(state) {
case LongPML4:
+ DPRINTF(PageTableWalker,
+ "Got long mode PML4 entry %#016x.\n", (uint64_t)pte);
nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl3 * size;
doWrite = !pte.a;
pte.a = 1;
entry.writable = pte.w;
entry.user = pte.u;
- if (badNX)
- panic("NX violation!\n");
+ if (badNX || !pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
entry.noExec = pte.nx;
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
nextState = LongPDP;
break;
case LongPDP:
+ DPRINTF(PageTableWalker,
+ "Got long mode PDP entry %#016x.\n", (uint64_t)pte);
nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl2 * size;
doWrite = !pte.a;
pte.a = 1;
entry.writable = entry.writable && pte.w;
entry.user = entry.user && pte.u;
- if (badNX)
- panic("NX violation!\n");
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
+ if (badNX || !pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
nextState = LongPD;
break;
case LongPD:
+ DPRINTF(PageTableWalker,
+ "Got long mode PD entry %#016x.\n", (uint64_t)pte);
doWrite = !pte.a;
pte.a = 1;
entry.writable = entry.writable && pte.w;
entry.user = entry.user && pte.u;
- if (badNX)
- panic("NX violation!\n");
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
+ if (badNX || !pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
if (!pte.ps) {
// 4 KB page
entry.size = 4 * (1 << 10);
@@ -150,47 +156,49 @@ Walker::doNext(PacketPtr &read, PacketPtr &write)
entry.patBit = bits(pte, 12);
entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
tlb->insert(entry.vaddr, entry);
- nextState = Ready;
- delete read->req;
- delete read;
- read = NULL;
- return;
+ stop();
+ return NoFault;
}
case LongPTE:
+ DPRINTF(PageTableWalker,
+ "Got long mode PTE entry %#016x.\n", (uint64_t)pte);
doWrite = !pte.a;
pte.a = 1;
entry.writable = entry.writable && pte.w;
entry.user = entry.user && pte.u;
- if (badNX)
- panic("NX violation!\n");
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
+ if (badNX || !pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
entry.paddr = (uint64_t)pte & (mask(40) << 12);
entry.uncacheable = uncacheable;
entry.global = pte.g;
entry.patBit = bits(pte, 12);
entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
tlb->insert(entry.vaddr, entry);
- nextState = Ready;
- delete read->req;
- delete read;
- read = NULL;
- return;
+ stop();
+ return NoFault;
case PAEPDP:
+ DPRINTF(PageTableWalker,
+ "Got legacy mode PAE PDP entry %#08x.\n", (uint32_t)pte);
nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.pael2 * size;
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
+ if (!pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
nextState = PAEPD;
break;
case PAEPD:
+ DPRINTF(PageTableWalker,
+ "Got legacy mode PAE PD entry %#08x.\n", (uint32_t)pte);
doWrite = !pte.a;
pte.a = 1;
entry.writable = pte.w;
entry.user = pte.u;
- if (badNX)
- panic("NX violation!\n");
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
+ if (badNX || !pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
if (!pte.ps) {
// 4 KB page
entry.size = 4 * (1 << 10);
@@ -206,39 +214,39 @@ Walker::doNext(PacketPtr &read, PacketPtr &write)
entry.patBit = bits(pte, 12);
entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
tlb->insert(entry.vaddr, entry);
- nextState = Ready;
- delete read->req;
- delete read;
- read = NULL;
- return;
+ stop();
+ return NoFault;
}
case PAEPTE:
+ DPRINTF(PageTableWalker,
+ "Got legacy mode PAE PTE entry %#08x.\n", (uint32_t)pte);
doWrite = !pte.a;
pte.a = 1;
entry.writable = entry.writable && pte.w;
entry.user = entry.user && pte.u;
- if (badNX)
- panic("NX violation!\n");
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
+ if (badNX || !pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
entry.paddr = (uint64_t)pte & (mask(40) << 12);
entry.uncacheable = uncacheable;
entry.global = pte.g;
entry.patBit = bits(pte, 7);
entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
tlb->insert(entry.vaddr, entry);
- nextState = Ready;
- delete read->req;
- delete read;
- read = NULL;
- return;
+ stop();
+ return NoFault;
case PSEPD:
+ DPRINTF(PageTableWalker,
+ "Got legacy mode PSE PD entry %#08x.\n", (uint32_t)pte);
doWrite = !pte.a;
pte.a = 1;
entry.writable = pte.w;
entry.user = pte.u;
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
+ if (!pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
if (!pte.ps) {
// 4 KB page
entry.size = 4 * (1 << 10);
@@ -255,54 +263,51 @@ Walker::doNext(PacketPtr &read, PacketPtr &write)
entry.patBit = bits(pte, 12);
entry.vaddr = entry.vaddr & ~((4 * (1 << 20)) - 1);
tlb->insert(entry.vaddr, entry);
- nextState = Ready;
- delete read->req;
- delete read;
- read = NULL;
- return;
+ stop();
+ return NoFault;
}
case PD:
+ DPRINTF(PageTableWalker,
+ "Got legacy mode PD entry %#08x.\n", (uint32_t)pte);
doWrite = !pte.a;
pte.a = 1;
entry.writable = pte.w;
entry.user = pte.u;
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
+ if (!pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
// 4 KB page
entry.size = 4 * (1 << 10);
nextRead = ((uint64_t)pte & (mask(20) << 12)) + vaddr.norml2 * size;
nextState = PTE;
break;
- nextState = PTE;
- break;
case PTE:
+ DPRINTF(PageTableWalker,
+ "Got legacy mode PTE entry %#08x.\n", (uint32_t)pte);
doWrite = !pte.a;
pte.a = 1;
entry.writable = pte.w;
entry.user = pte.u;
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
+ if (!pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
entry.paddr = (uint64_t)pte & (mask(20) << 12);
entry.uncacheable = uncacheable;
entry.global = pte.g;
entry.patBit = bits(pte, 7);
entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
tlb->insert(entry.vaddr, entry);
- nextState = Ready;
- delete read->req;
- delete read;
- read = NULL;
- return;
+ stop();
+ return NoFault;
default:
panic("Unknown page table walker state %d!\n");
}
PacketPtr oldRead = read;
//If we didn't return, we're setting up another read.
- uint32_t flags = oldRead->req->getFlags();
- if (uncacheable)
- flags |= UNCACHEABLE;
- else
- flags &= ~UNCACHEABLE;
+ Request::Flags flags = oldRead->req->getFlags();
+ flags.set(Request::UNCACHEABLE, uncacheable);
RequestPtr request =
new Request(nextRead, oldRead->getSize(), flags);
read = new Packet(request, MemCmd::ReadExReq, Packet::Broadcast);
@@ -319,14 +324,20 @@ Walker::doNext(PacketPtr &read, PacketPtr &write)
delete oldRead->req;
delete oldRead;
}
+ return NoFault;
}
-void
-Walker::start(ThreadContext * _tc, Addr vaddr)
+Fault
+Walker::start(ThreadContext * _tc, BaseTLB::Translation *_translation,
+ RequestPtr _req, bool _write, bool _execute)
{
assert(state == Ready);
- assert(!tc);
tc = _tc;
+ req = _req;
+ Addr vaddr = req->getVaddr();
+ execute = _execute;
+ write = _write;
+ translation = _translation;
VAddr addr = vaddr;
@@ -340,6 +351,7 @@ Walker::start(ThreadContext * _tc, Addr vaddr)
// Do long mode.
state = LongPML4;
top = (cr3.longPdtb << 12) + addr.longl4 * size;
+ enableNX = efer.nxe;
} else {
// We're in some flavor of legacy mode.
CR4 cr4 = tc->readMiscRegNoEffect(MISCREG_CR4);
@@ -347,6 +359,7 @@ Walker::start(ThreadContext * _tc, Addr vaddr)
// Do legacy PAE.
state = PAEPDP;
top = (cr3.paePdtb << 5) + addr.pael3 * size;
+ enableNX = efer.nxe;
} else {
size = 4;
top = (cr3.pdtb << 12) + addr.norml2 * size;
@@ -357,38 +370,44 @@ Walker::start(ThreadContext * _tc, Addr vaddr)
// Do legacy non PSE.
state = PD;
}
+ enableNX = false;
}
}
nextState = Ready;
entry.vaddr = vaddr;
- enableNX = efer.nxe;
-
- RequestPtr request =
- new Request(top, size, PHYSICAL | cr3.pcd ? UNCACHEABLE : 0);
+ Request::Flags flags = Request::PHYSICAL;
+ if (cr3.pcd)
+ flags.set(Request::UNCACHEABLE);
+ RequestPtr request = new Request(top, size, flags);
read = new Packet(request, MemCmd::ReadExReq, Packet::Broadcast);
read->allocate();
Enums::MemoryMode memMode = sys->getMemoryMode();
if (memMode == Enums::timing) {
- tc->suspend();
- port.sendTiming(read);
+ nextState = state;
+ state = Waiting;
+ timingFault = NoFault;
+ sendPackets();
} else if (memMode == Enums::atomic) {
+ Fault fault;
do {
port.sendAtomic(read);
PacketPtr write = NULL;
- doNext(read, write);
+ fault = doNext(write);
+ assert(fault == NoFault || read == NULL);
state = nextState;
nextState = Ready;
if (write)
port.sendAtomic(write);
} while(read);
- tc = NULL;
state = Ready;
nextState = Waiting;
+ return fault;
} else {
panic("Unrecognized memory system mode.\n");
}
+ return NoFault;
}
bool
@@ -400,18 +419,19 @@ Walker::WalkerPort::recvTiming(PacketPtr pkt)
bool
Walker::recvTiming(PacketPtr pkt)
{
- inflight--;
if (pkt->isResponse() && !pkt->wasNacked()) {
+ assert(inflight);
+ assert(state == Waiting);
+ assert(!read);
+ inflight--;
if (pkt->isRead()) {
- assert(inflight);
- assert(state == Waiting);
- assert(!read);
state = nextState;
nextState = Ready;
PacketPtr write = NULL;
- doNext(pkt, write);
- state = Waiting;
read = pkt;
+ timingFault = doNext(write);
+ state = Waiting;
+ assert(timingFault == NoFault || read == NULL);
if (write) {
writes.push_back(write);
}
@@ -420,14 +440,31 @@ Walker::recvTiming(PacketPtr pkt)
sendPackets();
}
if (inflight == 0 && read == NULL && writes.size() == 0) {
- tc->activate(0);
- tc = NULL;
state = Ready;
nextState = Waiting;
+ if (timingFault == NoFault) {
+ /*
+ * Finish the translation. Now that we now the right entry is
+ * in the TLB, this should work with no memory accesses.
+ * There could be new faults unrelated to the table walk like
+ * permissions violations, so we'll need the return value as
+ * well.
+ */
+ bool delayedResponse;
+ Fault fault = tlb->translate(req, tc, NULL, write, execute,
+ delayedResponse, true);
+ assert(!delayedResponse);
+ // Let the CPU continue.
+ translation->finish(fault, req, tc, write);
+ } else {
+ // There was a fault during the walk. Let the CPU know.
+ translation->finish(timingFault, req, tc, write);
+ }
}
} else if (pkt->wasNacked()) {
pkt->reinitNacked();
if (!port.sendTiming(pkt)) {
+ inflight--;
retrying = true;
if (pkt->isWrite()) {
writes.push_back(pkt);
@@ -435,8 +472,6 @@ Walker::recvTiming(PacketPtr pkt)
assert(!read);
read = pkt;
}
- } else {
- inflight++;
}
}
return true;
@@ -490,27 +525,26 @@ Walker::sendPackets()
//Reads always have priority
if (read) {
- if (!port.sendTiming(read)) {
+ PacketPtr pkt = read;
+ read = NULL;
+ inflight++;
+ if (!port.sendTiming(pkt)) {
retrying = true;
+ read = pkt;
+ inflight--;
return;
- } else {
- inflight++;
- delete read->req;
- delete read;
- read = NULL;
}
}
//Send off as many of the writes as we can.
while (writes.size()) {
PacketPtr write = writes.back();
+ writes.pop_back();
+ inflight++;
if (!port.sendTiming(write)) {
retrying = true;
+ writes.push_back(write);
+ inflight--;
return;
- } else {
- inflight++;
- delete write->req;
- delete write;
- writes.pop_back();
}
}
}
@@ -524,6 +558,15 @@ Walker::getPort(const std::string &if_name, int idx)
panic("No page table walker port named %s!\n", if_name);
}
+Fault
+Walker::pageFault(bool present)
+{
+ DPRINTF(PageTableWalker, "Raising page fault.\n");
+ HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
+ return new PageFault(entry.vaddr, present, write,
+ m5reg.cpl == 3, false, execute && enableNX);
+}
+
}
X86ISA::Walker *
diff --git a/src/arch/x86/pagetable_walker.hh b/src/arch/x86/pagetable_walker.hh
index 324f16f3c..f73774a45 100644
--- a/src/arch/x86/pagetable_walker.hh
+++ b/src/arch/x86/pagetable_walker.hh
@@ -85,17 +85,28 @@ namespace X86ISA
PSEPD, PD, PTE
};
- // Act on the current state and determine what to do next. read
- // should be the packet that just came back from a read and write
+ // Act on the current state and determine what to do next. The global
+ // read should be the packet that just came back from a read and write
// should be NULL. When the function returns, read is either NULL
// if the machine is finished, or points to a packet to initiate
// the next read. If any write is required to update an "accessed"
// bit, write will point to a packet to do the write. Otherwise it
- // will be NULL.
- void doNext(PacketPtr &read, PacketPtr &write);
+ // will be NULL. The return value is whatever fault was incurred
+ // during this stage of the lookup.
+ Fault doNext(PacketPtr &write);
// Kick off the state machine.
- void start(ThreadContext * _tc, Addr vaddr);
+ Fault start(ThreadContext * _tc, BaseTLB::Translation *translation,
+ RequestPtr req, bool write, bool execute);
+ // Clean up after the state machine.
+ void
+ stop()
+ {
+ nextState = Ready;
+ delete read->req;
+ delete read;
+ read = NULL;
+ }
protected:
@@ -111,6 +122,11 @@ namespace X86ISA
bool retrying;
/*
+ * The fault, if any, that's waiting to be delivered in timing mode.
+ */
+ Fault timingFault;
+
+ /*
* Functions for dealing with packets.
*/
bool recvTiming(PacketPtr pkt);
@@ -156,16 +172,21 @@ namespace X86ISA
// The TLB we're supposed to load.
TLB * tlb;
System * sys;
+ BaseTLB::Translation * translation;
/*
* State machine state.
*/
ThreadContext * tc;
+ RequestPtr req;
State state;
State nextState;
int size;
bool enableNX;
+ bool write, execute, user;
TlbEntry entry;
+
+ Fault pageFault(bool present);
public:
diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc
index 407a09ec0..620ab89ea 100644
--- a/src/arch/x86/predecoder.cc
+++ b/src/arch/x86/predecoder.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * Copyright (c) 2007-2008 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
@@ -55,9 +55,11 @@
* Authors: Gabe Black
*/
+#include "arch/x86/miscregs.hh"
#include "arch/x86/predecoder.hh"
#include "base/misc.hh"
#include "base/trace.hh"
+#include "cpu/thread_context.hh"
#include "sim/host.hh"
namespace X86ISA
@@ -78,7 +80,9 @@ namespace X86ISA
emi.modRM = 0;
emi.sib = 0;
- emi.mode = 0;
+ HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
+ emi.mode.mode = m5reg.mode;
+ emi.mode.submode = m5reg.submode;
}
void Predecoder::process()
@@ -132,7 +136,10 @@ namespace X86ISA
{
uint8_t prefix = Prefixes[nextByte];
State nextState = PrefixState;
- if(prefix)
+ // REX prefixes are only recognized in 64 bit mode.
+ if (prefix == RexPrefix && emi.mode.submode != SixtyFourBitMode)
+ prefix = 0;
+ if (prefix)
consumeByte();
switch(prefix)
{
@@ -209,10 +216,12 @@ namespace X86ISA
DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte);
emi.opcode.op = nextByte;
+ SegAttr csAttr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR);
+
//Figure out the effective operand size. This can be overriden to
//a fixed value at the decoder level.
int logOpSize;
- if(/*FIXME long mode*/1)
+ if (emi.mode.submode == SixtyFourBitMode)
{
if(emi.rex.w)
logOpSize = 3; // 64 bit operand size
@@ -221,7 +230,7 @@ namespace X86ISA
else
logOpSize = 2; // 32 bit operand size
}
- else if(/*FIXME default 32*/1)
+ else if(csAttr.defaultSize)
{
if(emi.legacy.op)
logOpSize = 1; // 16 bit operand size
@@ -242,14 +251,14 @@ namespace X86ISA
//Figure out the effective address size. This can be overriden to
//a fixed value at the decoder level.
int logAddrSize;
- if(/*FIXME 64-bit mode*/1)
+ if(emi.mode.submode == SixtyFourBitMode)
{
if(emi.legacy.addr)
logAddrSize = 2; // 32 bit address size
else
logAddrSize = 3; // 64 bit address size
}
- else if(/*FIXME default 32*/1)
+ else if(csAttr.defaultSize)
{
if(emi.legacy.addr)
logAddrSize = 1; // 16 bit address size
@@ -264,6 +273,16 @@ namespace X86ISA
logAddrSize = 1; // 16 bit address size
}
+ SegAttr ssAttr = tc->readMiscRegNoEffect(MISCREG_SS_ATTR);
+ //Figure out the effective stack width. This can be overriden to
+ //a fixed value at the decoder level.
+ if(emi.mode.submode == SixtyFourBitMode)
+ emi.stackSize = 8; // 64 bit stack width
+ else if(ssAttr.defaultSize)
+ emi.stackSize = 4; // 32 bit stack width
+ else
+ emi.stackSize = 2; // 16 bit stack width
+
//Set the actual address size
emi.addrSize = 1 << logAddrSize;
@@ -299,19 +318,21 @@ namespace X86ISA
ModRM modRM;
modRM = nextByte;
DPRINTF(Predecoder, "Found modrm byte %#x.\n", nextByte);
- if (0) {//FIXME in 16 bit mode
+ SegAttr csAttr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR);
+ if (emi.mode.submode != SixtyFourBitMode &&
+ !csAttr.defaultSize) {
//figure out 16 bit displacement size
- if(modRM.mod == 0 && modRM.rm == 6 || modRM.mod == 2)
+ if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2)
displacementSize = 2;
- else if(modRM.mod == 1)
+ else if (modRM.mod == 1)
displacementSize = 1;
else
displacementSize = 0;
} else {
//figure out 32/64 bit displacement size
- if(modRM.mod == 0 && modRM.rm == 5 || modRM.mod == 2)
+ if ((modRM.mod == 0 && modRM.rm == 5) || modRM.mod == 2)
displacementSize = 4;
- else if(modRM.mod == 1)
+ else if (modRM.mod == 1)
displacementSize = 1;
else
displacementSize = 0;
diff --git a/src/arch/x86/predecoder.hh b/src/arch/x86/predecoder.hh
index 6e41e8134..a16ce6fb8 100644
--- a/src/arch/x86/predecoder.hh
+++ b/src/arch/x86/predecoder.hh
@@ -58,6 +58,8 @@
#ifndef __ARCH_X86_PREDECODER_HH__
#define __ARCH_X86_PREDECODER_HH__
+#include <cassert>
+
#include "arch/x86/types.hh"
#include "base/bitfield.hh"
#include "base/misc.hh"
diff --git a/src/arch/x86/predecoder_tables.cc b/src/arch/x86/predecoder_tables.cc
index a8c719054..5f2b5c421 100644
--- a/src/arch/x86/predecoder_tables.cc
+++ b/src/arch/x86/predecoder_tables.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * Copyright (c) 2007-2008 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
@@ -123,7 +123,7 @@ namespace X86ISA
{ //LSB
// MSB 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
/* 0 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1,
-/* 1 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 1 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
/* 2 */ 1 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
/* 3 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
/* 4 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
@@ -201,7 +201,7 @@ namespace X86ISA
//For two byte instructions
{ //LSB
// MSB 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
-/* 0 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 0 */ 0 , 0 , 0 , 0 , WO, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , BY ,
/* 0 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
/* 2 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
/* 3 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
index 76f0b5d04..4a61ed168 100644
--- a/src/arch/x86/process.cc
+++ b/src/arch/x86/process.cc
@@ -98,56 +98,115 @@
#include "mem/page_table.hh"
#include "mem/translating_port.hh"
#include "sim/process_impl.hh"
+#include "sim/syscall_emul.hh"
#include "sim/system.hh"
using namespace std;
using namespace X86ISA;
-M5_64_auxv_t::M5_64_auxv_t(int64_t type, int64_t val)
-{
- a_type = TheISA::htog(type);
- a_val = TheISA::htog(val);
-}
-
-X86LiveProcess::X86LiveProcess(LiveProcessParams * params,
- ObjectFile *objFile)
- : LiveProcess(params, objFile)
+static const int ReturnValueReg = INTREG_RAX;
+static const int ArgumentReg[] = {
+ INTREG_RDI,
+ INTREG_RSI,
+ INTREG_RDX,
+ //This argument register is r10 for syscalls and rcx for C.
+ INTREG_R10W,
+ //INTREG_RCX,
+ INTREG_R8W,
+ INTREG_R9W
+};
+static const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int);
+static const int ArgumentReg32[] = {
+ INTREG_EBX,
+ INTREG_ECX,
+ INTREG_EDX,
+ INTREG_ESI,
+ INTREG_EDI,
+};
+static const int NumArgumentRegs32 = sizeof(ArgumentReg) / sizeof(const int);
+
+X86LiveProcess::X86LiveProcess(LiveProcessParams * params, ObjectFile *objFile,
+ SyscallDesc *_syscallDescs, int _numSyscallDescs) :
+ LiveProcess(params, objFile), syscallDescs(_syscallDescs),
+ numSyscallDescs(_numSyscallDescs)
{
brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
brk_point = roundUp(brk_point, VMPageSize);
+}
- // Set pointer for next thread stack. Reserve 8M for main stack.
- next_thread_stack_base = stack_base - (8 * 1024 * 1024);
-
+X86_64LiveProcess::X86_64LiveProcess(LiveProcessParams *params,
+ ObjectFile *objFile, SyscallDesc *_syscallDescs,
+ int _numSyscallDescs) :
+ X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs)
+{
// Set up stack. On X86_64 Linux, stack goes from the top of memory
// downward, less the hole for the kernel address space plus one page
// for undertermined purposes.
stack_base = (Addr)0x7FFFFFFFF000ULL;
+ // Set pointer for next thread stack. Reserve 8M for main stack.
+ next_thread_stack_base = stack_base - (8 * 1024 * 1024);
+
// Set up region for mmaps. This was determined empirically and may not
// always be correct.
mmap_start = mmap_end = (Addr)0x2aaaaaaab000ULL;
}
-void X86LiveProcess::handleTrap(int trapNum, ThreadContext *tc)
+void
+I386LiveProcess::syscall(int64_t callnum, ThreadContext *tc)
{
- switch(trapNum)
- {
- default:
- panic("Unimplemented trap to operating system: trap number %#x.\n", trapNum);
+ Addr eip = tc->readPC();
+ if (eip >= vsyscallPage.base &&
+ eip < vsyscallPage.base + vsyscallPage.size) {
+ tc->setNextPC(vsyscallPage.base + vsyscallPage.vsysexitOffset);
}
+ X86LiveProcess::syscall(callnum, tc);
+}
+
+
+I386LiveProcess::I386LiveProcess(LiveProcessParams *params,
+ ObjectFile *objFile, SyscallDesc *_syscallDescs,
+ int _numSyscallDescs) :
+ X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs)
+{
+ _gdtStart = 0x100000000;
+ _gdtSize = VMPageSize;
+
+ vsyscallPage.base = 0xffffe000ULL;
+ vsyscallPage.size = VMPageSize;
+ vsyscallPage.vsyscallOffset = 0x400;
+ vsyscallPage.vsysexitOffset = 0x410;
+
+ stack_base = vsyscallPage.base;
+
+ // Set pointer for next thread stack. Reserve 8M for main stack.
+ next_thread_stack_base = stack_base - (8 * 1024 * 1024);
+
+ // Set up region for mmaps. This was determined empirically and may not
+ // always be correct.
+ mmap_start = mmap_end = (Addr)0xf7ffd000ULL;
+}
+
+SyscallDesc*
+X86LiveProcess::getDesc(int callnum)
+{
+ if (callnum < 0 || callnum >= numSyscallDescs)
+ return NULL;
+ return &syscallDescs[callnum];
}
void
-X86LiveProcess::startup()
+X86_64LiveProcess::startup()
{
+ LiveProcess::startup();
+
if (checkpointRestored)
return;
- argsInit(sizeof(IntReg), VMPageSize);
+ argsInit(sizeof(uint64_t), VMPageSize);
- for (int i = 0; i < threadContexts.size(); i++) {
- ThreadContext * tc = threadContexts[i];
+ for (int i = 0; i < contextIds.size(); i++) {
+ ThreadContext * tc = system->getThreadContext(contextIds[i]);
SegAttr dataAttr = 0;
dataAttr.writable = 1;
@@ -203,10 +262,122 @@ X86LiveProcess::startup()
}
void
-X86LiveProcess::argsInit(int intSize, int pageSize)
+I386LiveProcess::startup()
+{
+ LiveProcess::startup();
+
+ if (checkpointRestored)
+ return;
+
+ argsInit(sizeof(uint32_t), VMPageSize);
+
+ /*
+ * Set up a GDT for this process. The whole GDT wouldn't really be for
+ * this process, but the only parts we care about are.
+ */
+ pTable->allocate(_gdtStart, _gdtSize);
+ uint64_t zero = 0;
+ assert(_gdtSize % sizeof(zero) == 0);
+ for (Addr gdtCurrent = _gdtStart;
+ gdtCurrent < _gdtStart + _gdtSize; gdtCurrent += sizeof(zero)) {
+ initVirtMem->write(gdtCurrent, zero);
+ }
+
+ // Set up the vsyscall page for this process.
+ pTable->allocate(vsyscallPage.base, vsyscallPage.size);
+ uint8_t vsyscallBlob[] = {
+ 0x51, // push %ecx
+ 0x52, // push %edp
+ 0x55, // push %ebp
+ 0x89, 0xe5, // mov %esp, %ebp
+ 0x0f, 0x34 // sysenter
+ };
+ initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vsyscallOffset,
+ vsyscallBlob, sizeof(vsyscallBlob));
+
+ uint8_t vsysexitBlob[] = {
+ 0x5d, // pop %ebp
+ 0x5a, // pop %edx
+ 0x59, // pop %ecx
+ 0xc3 // ret
+ };
+ initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vsysexitOffset,
+ vsysexitBlob, sizeof(vsysexitBlob));
+
+ for (int i = 0; i < contextIds.size(); i++) {
+ ThreadContext * tc = system->getThreadContext(contextIds[i]);
+
+ SegAttr dataAttr = 0;
+ dataAttr.writable = 1;
+ dataAttr.readable = 1;
+ dataAttr.expandDown = 0;
+ dataAttr.dpl = 3;
+ dataAttr.defaultSize = 1;
+ dataAttr.longMode = 0;
+
+ //Initialize the segment registers.
+ for(int seg = 0; seg < NUM_SEGMENTREGS; seg++) {
+ tc->setMiscRegNoEffect(MISCREG_SEG_BASE(seg), 0);
+ tc->setMiscRegNoEffect(MISCREG_SEG_EFF_BASE(seg), 0);
+ tc->setMiscRegNoEffect(MISCREG_SEG_ATTR(seg), dataAttr);
+ tc->setMiscRegNoEffect(MISCREG_SEG_SEL(seg), 0xB);
+ tc->setMiscRegNoEffect(MISCREG_SEG_LIMIT(seg), (uint32_t)(-1));
+ }
+
+ SegAttr csAttr = 0;
+ csAttr.writable = 0;
+ csAttr.readable = 1;
+ csAttr.expandDown = 0;
+ csAttr.dpl = 3;
+ csAttr.defaultSize = 1;
+ csAttr.longMode = 0;
+
+ tc->setMiscRegNoEffect(MISCREG_CS_ATTR, csAttr);
+
+ tc->setMiscRegNoEffect(MISCREG_TSG_BASE, _gdtStart);
+ tc->setMiscRegNoEffect(MISCREG_TSG_EFF_BASE, _gdtStart);
+ tc->setMiscRegNoEffect(MISCREG_TSG_LIMIT, _gdtStart + _gdtSize - 1);
+
+ // Set the LDT selector to 0 to deactivate it.
+ tc->setMiscRegNoEffect(MISCREG_TSL, 0);
+
+ //Set up the registers that describe the operating mode.
+ CR0 cr0 = 0;
+ cr0.pg = 1; // Turn on paging.
+ cr0.cd = 0; // Don't disable caching.
+ cr0.nw = 0; // This is bit is defined to be ignored.
+ cr0.am = 0; // No alignment checking
+ cr0.wp = 0; // Supervisor mode can write read only pages
+ cr0.ne = 1;
+ cr0.et = 1; // This should always be 1
+ cr0.ts = 0; // We don't do task switching, so causing fp exceptions
+ // would be pointless.
+ cr0.em = 0; // Allow x87 instructions to execute natively.
+ cr0.mp = 1; // This doesn't really matter, but the manual suggests
+ // setting it to one.
+ cr0.pe = 1; // We're definitely in protected mode.
+ tc->setMiscReg(MISCREG_CR0, cr0);
+
+ Efer efer = 0;
+ efer.sce = 1; // Enable system call extensions.
+ efer.lme = 1; // Enable long mode.
+ efer.lma = 0; // Deactivate long mode.
+ efer.nxe = 1; // Enable nx support.
+ efer.svme = 0; // Disable svm support for now. It isn't implemented.
+ efer.ffxsr = 1; // Turn on fast fxsave and fxrstor.
+ tc->setMiscReg(MISCREG_EFER, efer);
+ }
+}
+
+template<class IntType>
+void
+X86LiveProcess::argsInit(int pageSize,
+ std::vector<AuxVector<IntType> > extraAuxvs)
{
- typedef M5_64_auxv_t auxv_t;
- Process::startup();
+ int intSize = sizeof(IntType);
+
+ typedef AuxVector<IntType> auxv_t;
+ std::vector<auxv_t> auxv = extraAuxvs;
string filename;
if(argv.size() < 1)
@@ -399,35 +570,35 @@ X86LiveProcess::argsInit(int intSize, int pageSize)
roundUp(stack_size, pageSize));
// map out initial stack contents
- Addr sentry_base = stack_base - sentry_size;
- Addr file_name_base = sentry_base - file_name_size;
- Addr env_data_base = file_name_base - env_data_size;
- Addr arg_data_base = env_data_base - arg_data_size;
- Addr aux_data_base = arg_data_base - info_block_padding - aux_data_size;
- Addr auxv_array_base = aux_data_base - aux_array_size - aux_padding;
- Addr envp_array_base = auxv_array_base - envp_array_size;
- Addr argv_array_base = envp_array_base - argv_array_size;
- Addr argc_base = argv_array_base - argc_size;
-
- DPRINTF(X86, "The addresses of items on the initial stack:\n");
- DPRINTF(X86, "0x%x - file name\n", file_name_base);
- DPRINTF(X86, "0x%x - env data\n", env_data_base);
- DPRINTF(X86, "0x%x - arg data\n", arg_data_base);
- DPRINTF(X86, "0x%x - aux data\n", aux_data_base);
- DPRINTF(X86, "0x%x - auxv array\n", auxv_array_base);
- DPRINTF(X86, "0x%x - envp array\n", envp_array_base);
- DPRINTF(X86, "0x%x - argv array\n", argv_array_base);
- DPRINTF(X86, "0x%x - argc \n", argc_base);
- DPRINTF(X86, "0x%x - stack min\n", stack_min);
+ IntType sentry_base = stack_base - sentry_size;
+ IntType file_name_base = sentry_base - file_name_size;
+ IntType env_data_base = file_name_base - env_data_size;
+ IntType arg_data_base = env_data_base - arg_data_size;
+ IntType aux_data_base = arg_data_base - info_block_padding - aux_data_size;
+ IntType auxv_array_base = aux_data_base - aux_array_size - aux_padding;
+ IntType envp_array_base = auxv_array_base - envp_array_size;
+ IntType argv_array_base = envp_array_base - argv_array_size;
+ IntType argc_base = argv_array_base - argc_size;
+
+ DPRINTF(Stack, "The addresses of items on the initial stack:\n");
+ DPRINTF(Stack, "0x%x - file name\n", file_name_base);
+ DPRINTF(Stack, "0x%x - env data\n", env_data_base);
+ DPRINTF(Stack, "0x%x - arg data\n", arg_data_base);
+ DPRINTF(Stack, "0x%x - aux data\n", aux_data_base);
+ DPRINTF(Stack, "0x%x - auxv array\n", auxv_array_base);
+ DPRINTF(Stack, "0x%x - envp array\n", envp_array_base);
+ DPRINTF(Stack, "0x%x - argv array\n", argv_array_base);
+ DPRINTF(Stack, "0x%x - argc \n", argc_base);
+ DPRINTF(Stack, "0x%x - stack min\n", stack_min);
// write contents to stack
// figure out argc
- uint64_t argc = argv.size();
- uint64_t guestArgc = TheISA::htog(argc);
+ IntType argc = argv.size();
+ IntType guestArgc = X86ISA::htog(argc);
//Write out the sentry void *
- uint64_t sentry_NULL = 0;
+ IntType sentry_NULL = 0;
initVirtMem->writeBlob(sentry_base,
(uint8_t*)&sentry_NULL, sentry_size);
@@ -458,17 +629,70 @@ X86LiveProcess::argsInit(int intSize, int pageSize)
initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
//Set the stack pointer register
- threadContexts[0]->setIntReg(StackPointerReg, stack_min);
+ tc->setIntReg(StackPointerReg, stack_min);
Addr prog_entry = objFile->entryPoint();
// There doesn't need to be any segment base added in since we're dealing
// with the flat segmentation model.
- threadContexts[0]->setPC(prog_entry);
- threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
+ tc->setPC(prog_entry);
+ tc->setNextPC(prog_entry + sizeof(MachInst));
//Align the "stack_min" to a page boundary.
stack_min = roundDown(stack_min, pageSize);
// num_processes++;
}
+
+void
+X86_64LiveProcess::argsInit(int intSize, int pageSize)
+{
+ std::vector<AuxVector<uint64_t> > extraAuxvs;
+ X86LiveProcess::argsInit<uint64_t>(pageSize, extraAuxvs);
+}
+
+void
+I386LiveProcess::argsInit(int intSize, int pageSize)
+{
+ std::vector<AuxVector<uint32_t> > extraAuxvs;
+ //Tell the binary where the vsyscall part of the vsyscall page is.
+ extraAuxvs.push_back(AuxVector<uint32_t>(0x20,
+ vsyscallPage.base + vsyscallPage.vsyscallOffset));
+ extraAuxvs.push_back(AuxVector<uint32_t>(0x21, vsyscallPage.base));
+ X86LiveProcess::argsInit<uint32_t>(pageSize, extraAuxvs);
+}
+
+void
+X86LiveProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn return_value)
+{
+ tc->setIntReg(INTREG_RAX, return_value.value());
+}
+
+X86ISA::IntReg
+X86_64LiveProcess::getSyscallArg(ThreadContext *tc, int i)
+{
+ assert(i < NumArgumentRegs);
+ return tc->readIntReg(ArgumentReg[i]);
+}
+
+void
+X86_64LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
+{
+ assert(i < NumArgumentRegs);
+ return tc->setIntReg(ArgumentReg[i], val);
+}
+
+X86ISA::IntReg
+I386LiveProcess::getSyscallArg(ThreadContext *tc, int i)
+{
+ assert(i < NumArgumentRegs32);
+ return tc->readIntReg(ArgumentReg32[i]);
+}
+
+void
+I386LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
+{
+ assert(i < NumArgumentRegs);
+ return tc->setIntReg(ArgumentReg[i], val);
+}
diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh
index 5def9e13d..cd6d99e66 100644
--- a/src/arch/x86/process.hh
+++ b/src/arch/x86/process.hh
@@ -62,38 +62,76 @@
#include <vector>
#include "sim/process.hh"
+class SyscallDesc;
+
namespace X86ISA
{
- struct M5_64_auxv_t
+
+ class X86LiveProcess : public LiveProcess
{
- int64_t a_type;
- union {
- int64_t a_val;
- int64_t a_ptr;
- int64_t a_fcn;
- };
+ protected:
+ Addr _gdtStart;
+ Addr _gdtSize;
+
+ SyscallDesc *syscallDescs;
+ const int numSyscallDescs;
- M5_64_auxv_t()
- {}
+ X86LiveProcess(LiveProcessParams * params, ObjectFile *objFile,
+ SyscallDesc *_syscallDescs, int _numSyscallDescs);
- M5_64_auxv_t(int64_t type, int64_t val);
+ template<class IntType>
+ void argsInit(int pageSize,
+ std::vector<AuxVector<IntType> > extraAuxvs);
+
+ public:
+ Addr gdtStart()
+ { return _gdtStart; }
+
+ Addr gdtSize()
+ { return _gdtSize; }
+
+ SyscallDesc* getDesc(int callnum);
+
+ void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
};
- class X86LiveProcess : public LiveProcess
+ class X86_64LiveProcess : public X86LiveProcess
{
protected:
- std::vector<M5_64_auxv_t> auxv;
-
- X86LiveProcess(LiveProcessParams * params, ObjectFile *objFile);
+ X86_64LiveProcess(LiveProcessParams *params, ObjectFile *objFile,
+ SyscallDesc *_syscallDescs, int _numSyscallDescs);
+ public:
+ void argsInit(int intSize, int pageSize);
void startup();
- public:
+ X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val);
+ };
- //Handles traps which request services from the operating system
- virtual void handleTrap(int trapNum, ThreadContext *tc);
+ class I386LiveProcess : public X86LiveProcess
+ {
+ protected:
+ I386LiveProcess(LiveProcessParams *params, ObjectFile *objFile,
+ SyscallDesc *_syscallDescs, int _numSyscallDescs);
+ class VSyscallPage
+ {
+ public:
+ Addr base;
+ Addr size;
+ Addr vsyscallOffset;
+ Addr vsysexitOffset;
+ };
+ VSyscallPage vsyscallPage;
+
+ public:
void argsInit(int intSize, int pageSize);
+ void startup();
+
+ void syscall(int64_t callnum, ThreadContext *tc);
+ X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val);
};
}
diff --git a/src/arch/x86/regfile.cc b/src/arch/x86/regfile.cc
index c27ab08ba..7d01c4bb4 100644
--- a/src/arch/x86/regfile.cc
+++ b/src/arch/x86/regfile.cc
@@ -135,23 +135,23 @@ void RegFile::clear()
MiscReg RegFile::readMiscRegNoEffect(int miscReg)
{
- return miscRegFile.readRegNoEffect(miscReg);
+ return miscRegFile.readRegNoEffect((MiscRegIndex)miscReg);
}
MiscReg RegFile::readMiscReg(int miscReg, ThreadContext *tc)
{
- return miscRegFile.readReg(miscReg, tc);
+ return miscRegFile.readReg((MiscRegIndex)miscReg, tc);
}
void RegFile::setMiscRegNoEffect(int miscReg, const MiscReg &val)
{
- miscRegFile.setRegNoEffect(miscReg, val);
+ miscRegFile.setRegNoEffect((MiscRegIndex)miscReg, val);
}
void RegFile::setMiscReg(int miscReg, const MiscReg &val,
ThreadContext * tc)
{
- miscRegFile.setReg(miscReg, val, tc);
+ miscRegFile.setReg((MiscRegIndex)miscReg, val, tc);
}
FloatReg RegFile::readFloatReg(int floatReg, int width)
@@ -214,7 +214,7 @@ int X86ISA::flattenIntIndex(ThreadContext * tc, int reg)
//If we need to fold over the index to match byte semantics, do that.
//Otherwise, just strip off any extra bits and pass it through.
if (reg & (1 << 6))
- return (reg & ~(1 << 6) - 0x4);
+ return (reg & (~(1 << 6) - 0x4));
else
return (reg & ~(1 << 6));
}
@@ -228,7 +228,8 @@ int X86ISA::flattenFloatIndex(ThreadContext * tc, int reg)
return reg;
}
-void RegFile::serialize(std::ostream &os)
+void
+RegFile::serialize(EventManager *em, std::ostream &os)
{
intRegFile.serialize(os);
floatRegFile.serialize(os);
@@ -237,7 +238,8 @@ void RegFile::serialize(std::ostream &os)
SERIALIZE_SCALAR(nextRip);
}
-void RegFile::unserialize(Checkpoint *cp, const std::string &section)
+void
+RegFile::unserialize(EventManager *em, Checkpoint *cp, const string &section)
{
intRegFile.unserialize(cp, section);
floatRegFile.unserialize(cp, section);
@@ -246,11 +248,6 @@ void RegFile::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(nextRip);
}
-void RegFile::changeContext(RegContextParam param, RegContextVal val)
-{
- panic("changeContext not implemented for x86!\n");
-}
-
void X86ISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
{
panic("copyMiscRegs not implemented for x86!\n");
diff --git a/src/arch/x86/regfile.hh b/src/arch/x86/regfile.hh
index 650181aca..8938ab0bc 100644
--- a/src/arch/x86/regfile.hh
+++ b/src/arch/x86/regfile.hh
@@ -68,6 +68,7 @@
#include <string>
class Checkpoint;
+class EventManager;
namespace X86ISA
{
@@ -96,8 +97,6 @@ namespace X86ISA
void clear();
- int FlattenIntIndex(int reg);
-
MiscReg readMiscRegNoEffect(int miscReg);
MiscReg readMiscReg(int miscReg, ThreadContext *tc);
@@ -139,12 +138,11 @@ namespace X86ISA
void setIntReg(int intReg, const IntReg &val);
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
+ void serialize(EventManager *em, std::ostream &os);
+ void unserialize(EventManager *em, Checkpoint *cp,
+ const std::string &section);
public:
-
- void changeContext(RegContextParam param, RegContextVal val);
};
int flattenIntIndex(ThreadContext * tc, int reg);
diff --git a/src/arch/x86/remote_gdb.cc b/src/arch/x86/remote_gdb.cc
index 5ab0ec3fb..c416042c8 100644
--- a/src/arch/x86/remote_gdb.cc
+++ b/src/arch/x86/remote_gdb.cc
@@ -57,7 +57,7 @@
/*
* Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
@@ -65,8 +65,8 @@
*
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratories.
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratories.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -78,8 +78,8 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -96,7 +96,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
+ * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
*/
/*-
@@ -116,8 +116,8 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
@@ -157,7 +157,7 @@
#include "cpu/thread_context.hh"
using namespace std;
-using namespace TheISA;
+using namespace X86ISA;
RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
: BaseRemoteGDB(_system, c, NumGDBRegs)
diff --git a/src/arch/x86/stacktrace.cc b/src/arch/x86/stacktrace.cc
index 300e8dcd0..87767583b 100644
--- a/src/arch/x86/stacktrace.cc
+++ b/src/arch/x86/stacktrace.cc
@@ -70,8 +70,6 @@ namespace X86ISA
if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
panic("thread info not compiled into kernel\n");
name_off = vp->readGtoH<int32_t>(addr);
-
- tc->delVirtPort(vp);
}
Addr
@@ -87,7 +85,6 @@ namespace X86ISA
vp = tc->getVirtPort();
tsk = vp->readGtoH<Addr>(base + task_off);
- tc->delVirtPort(vp);
return tsk;
}
@@ -105,7 +102,6 @@ namespace X86ISA
vp = tc->getVirtPort();
pd = vp->readGtoH<uint16_t>(task + pid_off);
- tc->delVirtPort(vp);
return pd;
}
diff --git a/src/arch/x86/system.cc b/src/arch/x86/system.cc
index 947a7793e..ed3dae4e6 100644
--- a/src/arch/x86/system.cc
+++ b/src/arch/x86/system.cc
@@ -55,13 +55,15 @@
* Authors: Gabe Black
*/
+#include "arch/x86/bios/smbios.hh"
+#include "arch/x86/bios/intelmp.hh"
#include "arch/x86/miscregs.hh"
#include "arch/x86/system.hh"
-#include "arch/x86/smbios.hh"
#include "arch/vtophys.hh"
-#include "base/remote_gdb.hh"
+#include "base/intmath.hh"
#include "base/loader/object_file.hh"
#include "base/loader/symtab.hh"
+#include "base/remote_gdb.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "mem/physical.hh"
@@ -72,14 +74,12 @@
using namespace LittleEndianGuest;
using namespace X86ISA;
-X86System::X86System(Params *p)
- : System(p)
-{
- smbiosTable = new X86ISA::SMBios::SMBiosTable;
- smbiosTable->smbiosHeader.majorVersion = 2;
- smbiosTable->smbiosHeader.minorVersion = 5;
- smbiosTable->smbiosHeader.intermediateHeader.smbiosBCDRevision = 0x25;
-}
+X86System::X86System(Params *p) :
+ System(p), smbiosTable(p->smbios_table),
+ mpFloatingPointer(p->intel_mp_pointer),
+ mpConfigTable(p->intel_mp_table),
+ rsdp(p->acpi_description_table_pointer)
+{}
void
X86System::startup()
@@ -236,27 +236,67 @@ X86System::startup()
// We should now be in long mode. Yay!
+ Addr ebdaPos = 0xF0000;
+ Addr fixed, table;
+
//Write out the SMBios/DMI table
- writeOutSMBiosTable(0xF0000);
+ writeOutSMBiosTable(ebdaPos, fixed, table);
+ ebdaPos += (fixed + table);
+ ebdaPos = roundUp(ebdaPos, 16);
+
+ //Write out the Intel MP Specification configuration table
+ writeOutMPTable(ebdaPos, fixed, table);
+ ebdaPos += (fixed + table);
}
void
-X86System::writeOutSMBiosTable(Addr header, Addr table)
+X86System::writeOutSMBiosTable(Addr header,
+ Addr &headerSize, Addr &structSize, Addr table)
{
// Get a port to write the table and header to memory.
FunctionalPort * physPort = threadContexts[0]->getPhysPort();
// If the table location isn't specified, just put it after the header.
// The header size as of the 2.5 SMBios specification is 0x1F bytes
- if (!table) {
- if (!smbiosTable->smbiosHeader.intermediateHeader.tableAddr)
- smbiosTable->smbiosHeader.
- intermediateHeader.tableAddr = header + 0x1F;
- } else {
- smbiosTable->smbiosHeader.intermediateHeader.tableAddr = table;
+ if (!table)
+ table = header + 0x1F;
+ smbiosTable->setTableAddr(table);
+
+ smbiosTable->writeOut(physPort, header, headerSize, structSize);
+
+ // Do some bounds checking to make sure we at least didn't step on
+ // ourselves.
+ assert(header > table || header + headerSize <= table);
+ assert(table > header || table + structSize <= header);
+}
+
+void
+X86System::writeOutMPTable(Addr fp,
+ Addr &fpSize, Addr &tableSize, Addr table)
+{
+ // Get a port to write the table and header to memory.
+ FunctionalPort * physPort = threadContexts[0]->getPhysPort();
+
+ // If the table location isn't specified and it exists, just put
+ // it after the floating pointer. The fp size as of the 1.4 Intel MP
+ // specification is 0x10 bytes.
+ if (mpConfigTable) {
+ if (!table)
+ table = fp + 0x10;
+ mpFloatingPointer->setTableAddr(table);
}
- smbiosTable->writeOut(physPort, header);
+ fpSize = mpFloatingPointer->writeOut(physPort, fp);
+ if (mpConfigTable)
+ tableSize = mpConfigTable->writeOut(physPort, table);
+ else
+ tableSize = 0;
+
+ // Do some bounds checking to make sure we at least didn't step on
+ // ourselves and the fp structure was the size we thought it was.
+ assert(fp > table || fp + fpSize <= table);
+ assert(table > fp || table + tableSize <= fp);
+ assert(fpSize == 0x10);
}
diff --git a/src/arch/x86/system.hh b/src/arch/x86/system.hh
index 8a5483ebf..12a471f6f 100644
--- a/src/arch/x86/system.hh
+++ b/src/arch/x86/system.hh
@@ -74,6 +74,11 @@ namespace X86ISA
{
class SMBiosTable;
}
+ namespace IntelMP
+ {
+ class FloatingPointer;
+ class ConfigTable;
+ }
}
class X86System : public System
@@ -95,8 +100,15 @@ class X86System : public System
protected:
X86ISA::SMBios::SMBiosTable * smbiosTable;
+ X86ISA::IntelMP::FloatingPointer * mpFloatingPointer;
+ X86ISA::IntelMP::ConfigTable * mpConfigTable;
+ X86ISA::ACPI::RSDP * rsdp;
+
+ void writeOutSMBiosTable(Addr header,
+ Addr &headerSize, Addr &tableSize, Addr table = 0);
- void writeOutSMBiosTable(Addr header, Addr table = 0);
+ void writeOutMPTable(Addr fp,
+ Addr &fpSize, Addr &tableSize, Addr table = 0);
const Params *params() const { return (const Params *)_params; }
diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc
index a87abf212..3fec4c7da 100644
--- a/src/arch/x86/tlb.cc
+++ b/src/arch/x86/tlb.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * Copyright (c) 2007-2008 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
@@ -59,6 +59,7 @@
#include "config/full_system.hh"
+#include "arch/x86/insts/microldstop.hh"
#include "arch/x86/pagetable.hh"
#include "arch/x86/tlb.hh"
#include "arch/x86/x86_traits.hh"
@@ -72,6 +73,9 @@
#if FULL_SYSTEM
#include "arch/x86/pagetable_walker.hh"
+#else
+#include "mem/page_table.hh"
+#include "sim/process.hh"
#endif
namespace X86ISA {
@@ -90,7 +94,7 @@ TLB::TLB(const Params *p) : BaseTLB(p), configAddress(0), size(p->size)
#endif
}
-void
+TlbEntry *
TLB::insert(Addr vpn, TlbEntry &entry)
{
//TODO Deal with conflicting entries
@@ -106,6 +110,7 @@ TLB::insert(Addr vpn, TlbEntry &entry)
*newEntry = entry;
newEntry->vaddr = vpn;
entryList.push_front(newEntry);
+ return newEntry;
}
TLB::EntryList::iterator
@@ -138,14 +143,6 @@ TLB::lookup(Addr va, bool update_lru)
return *entry;
}
-#if FULL_SYSTEM
-void
-TLB::walk(ThreadContext * _tc, Addr vaddr)
-{
- walker->start(_tc, vaddr);
-}
-#endif
-
void
TLB::invalidateAll()
{
@@ -188,16 +185,18 @@ TLB::demapPage(Addr va, uint64_t asn)
}
}
-template<class TlbFault>
Fault
-TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
+TLB::translate(RequestPtr req, ThreadContext *tc,
+ Translation *translation, bool write, bool execute,
+ bool &delayedResponse, bool timing)
{
+ delayedResponse = false;
Addr vaddr = req->getVaddr();
DPRINTF(TLB, "Translating vaddr %#x.\n", vaddr);
uint32_t flags = req->getFlags();
bool storeCheck = flags & StoreCheck;
- int seg = flags & mask(4);
+ int seg = flags & SegmentFlagMask;
//XXX Junk code to surpress the warning
if (storeCheck);
@@ -206,10 +205,11 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
// value.
if (seg == SEGMENT_REG_MS) {
DPRINTF(TLB, "Addresses references internal memory.\n");
- Addr prefix = vaddr & IntAddrPrefixMask;
+ Addr prefix = (vaddr >> 3) & IntAddrPrefixMask;
if (prefix == IntAddrPrefixCPUID) {
panic("CPUID memory space not yet implemented!\n");
} else if (prefix == IntAddrPrefixMSR) {
+ vaddr = vaddr >> 3;
req->setMmapedIpr(true);
Addr regNum = 0;
switch (vaddr & ~IntAddrPrefixMask) {
@@ -357,6 +357,15 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
case 0x410:
regNum = MISCREG_MC4_CTL;
break;
+ case 0x414:
+ regNum = MISCREG_MC5_CTL;
+ break;
+ case 0x418:
+ regNum = MISCREG_MC6_CTL;
+ break;
+ case 0x41C:
+ regNum = MISCREG_MC7_CTL;
+ break;
case 0x401:
regNum = MISCREG_MC0_STATUS;
break;
@@ -372,6 +381,15 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
case 0x411:
regNum = MISCREG_MC4_STATUS;
break;
+ case 0x415:
+ regNum = MISCREG_MC5_STATUS;
+ break;
+ case 0x419:
+ regNum = MISCREG_MC6_STATUS;
+ break;
+ case 0x41D:
+ regNum = MISCREG_MC7_STATUS;
+ break;
case 0x402:
regNum = MISCREG_MC0_ADDR;
break;
@@ -387,6 +405,15 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
case 0x412:
regNum = MISCREG_MC4_ADDR;
break;
+ case 0x416:
+ regNum = MISCREG_MC5_ADDR;
+ break;
+ case 0x41A:
+ regNum = MISCREG_MC6_ADDR;
+ break;
+ case 0x41E:
+ regNum = MISCREG_MC7_ADDR;
+ break;
case 0x403:
regNum = MISCREG_MC0_MISC;
break;
@@ -402,6 +429,15 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
case 0x413:
regNum = MISCREG_MC4_MISC;
break;
+ case 0x417:
+ regNum = MISCREG_MC5_MISC;
+ break;
+ case 0x41B:
+ regNum = MISCREG_MC6_MISC;
+ break;
+ case 0x41F:
+ regNum = MISCREG_MC7_MISC;
+ break;
case 0xC0000080:
regNum = MISCREG_EFER;
break;
@@ -510,7 +546,8 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
tc->readMiscRegNoEffect(MISCREG_PCI_CONFIG_ADDRESS);
if (bits(configAddress, 31, 31)) {
req->setPaddr(PhysAddrPrefixPciConfig |
- bits(configAddress, 30, 0));
+ mbits(configAddress, 30, 2) |
+ (IOPort & mask(2)));
}
} else {
req->setPaddr(PhysAddrPrefixIO | IOPort);
@@ -534,35 +571,38 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
// If we're not in 64-bit mode, do protection/limit checks
if (!efer.lma || !csAttr.longMode) {
DPRINTF(TLB, "Not in long mode. Checking segment protection.\n");
- SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg));
- if (!attr.writable && write)
- return new GeneralProtection(0);
- if (!attr.readable && !write && !execute)
+ // Check for a NULL segment selector.
+ if (!tc->readMiscRegNoEffect(MISCREG_SEG_SEL(seg)))
return new GeneralProtection(0);
+ bool expandDown = false;
+ SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg));
+ if (seg >= SEGMENT_REG_ES && seg <= SEGMENT_REG_HS) {
+ if (!attr.writable && write)
+ return new GeneralProtection(0);
+ if (!attr.readable && !write && !execute)
+ return new GeneralProtection(0);
+ expandDown = attr.expandDown;
+
+ }
Addr base = tc->readMiscRegNoEffect(MISCREG_SEG_BASE(seg));
Addr limit = tc->readMiscRegNoEffect(MISCREG_SEG_LIMIT(seg));
- if (!attr.expandDown) {
+ // This assumes we're not in 64 bit mode. If we were, the default
+ // address size is 64 bits, overridable to 32.
+ int size = 32;
+ bool sizeOverride = (flags & (AddrSizeFlagBit << FlagShift));
+ if ((csAttr.defaultSize && sizeOverride) ||
+ (!csAttr.defaultSize && !sizeOverride))
+ size = 16;
+ Addr offset = bits(vaddr - base, size-1, 0);
+ Addr endOffset = offset + req->getSize() - 1;
+ if (expandDown) {
DPRINTF(TLB, "Checking an expand down segment.\n");
- // We don't have to worry about the access going around the
- // end of memory because accesses will be broken up into
- // pieces at boundaries aligned on sizes smaller than an
- // entire address space. We do have to worry about the limit
- // being less than the base.
- if (limit < base) {
- if (limit < vaddr + req->getSize() && vaddr < base)
- return new GeneralProtection(0);
- } else {
- if (limit < vaddr + req->getSize())
- return new GeneralProtection(0);
- }
+ warn_once("Expand down segments are untested.\n");
+ if (offset <= limit || endOffset <= limit)
+ return new GeneralProtection(0);
} else {
- if (limit < base) {
- if (vaddr <= limit || vaddr + req->getSize() >= base)
- return new GeneralProtection(0);
- } else {
- if (vaddr <= limit && vaddr + req->getSize() >= base)
- return new GeneralProtection(0);
- }
+ if (offset > limit || endOffset > limit)
+ return new GeneralProtection(0);
}
}
// If paging is enabled, do the translation.
@@ -571,14 +611,57 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
// The vaddr already has the segment base applied.
TlbEntry *entry = lookup(vaddr);
if (!entry) {
- return new TlbFault(vaddr);
- } else {
- // Do paging protection checks.
- DPRINTF(TLB, "Entry found with paddr %#x, doing protection checks.\n", entry->paddr);
- Addr paddr = entry->paddr | (vaddr & (entry->size-1));
- DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, paddr);
- req->setPaddr(paddr);
+#if FULL_SYSTEM
+ Fault fault = walker->start(tc, translation, req,
+ write, execute);
+ if (timing || fault != NoFault) {
+ // This gets ignored in atomic mode.
+ delayedResponse = true;
+ return fault;
+ }
+ entry = lookup(vaddr);
+ assert(entry);
+#else
+ DPRINTF(TLB, "Handling a TLB miss for "
+ "address %#x at pc %#x.\n",
+ vaddr, tc->readPC());
+
+ Process *p = tc->getProcessPtr();
+ TlbEntry newEntry;
+ bool success = p->pTable->lookup(vaddr, newEntry);
+ if(!success && !execute) {
+ p->checkAndAllocNextPage(vaddr);
+ success = p->pTable->lookup(vaddr, newEntry);
+ }
+ if(!success) {
+ panic("Tried to execute unmapped address %#x.\n", vaddr);
+ } else {
+ Addr alignedVaddr = p->pTable->pageAlign(vaddr);
+ DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr,
+ newEntry.pageStart());
+ entry = insert(alignedVaddr, newEntry);
+ }
+ DPRINTF(TLB, "Miss was serviced.\n");
+#endif
}
+ // Do paging protection checks.
+ bool inUser = (csAttr.dpl == 3 &&
+ !(flags & (CPL0FlagBit << FlagShift)));
+ if ((inUser && !entry->user) ||
+ (write && !entry->writable)) {
+ // The page must have been present to get into the TLB in
+ // the first place. We'll assume the reserved bits are
+ // fine even though we're not checking them.
+ return new PageFault(vaddr, true, write,
+ inUser, false, execute);
+ }
+
+
+ DPRINTF(TLB, "Entry found with paddr %#x, "
+ "doing protection checks.\n", entry->paddr);
+ Addr paddr = entry->paddr | (vaddr & (entry->size-1));
+ DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, paddr);
+ req->setPaddr(paddr);
} else {
//Use the address which already has segmentation applied.
DPRINTF(TLB, "Paging disabled.\n");
@@ -592,160 +675,68 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
req->setPaddr(vaddr);
}
// Check for an access to the local APIC
+#if FULL_SYSTEM
LocalApicBase localApicBase = tc->readMiscRegNoEffect(MISCREG_APIC_BASE);
- Addr baseAddr = localApicBase.base << 12;
+ Addr baseAddr = localApicBase.base * PageBytes;
Addr paddr = req->getPaddr();
- if (baseAddr <= paddr && baseAddr + (1 << 12) > paddr) {
- req->setMmapedIpr(true);
+ if (baseAddr <= paddr && baseAddr + PageBytes > paddr) {
+ // The Intel developer's manuals say the below restrictions apply,
+ // but the linux kernel, because of a compiler optimization, breaks
+ // them.
+ /*
// Check alignment
if (paddr & ((32/8) - 1))
return new GeneralProtection(0);
// Check access size
if (req->getSize() != (32/8))
return new GeneralProtection(0);
- MiscReg regNum;
- switch (paddr - baseAddr)
- {
- case 0x20:
- regNum = MISCREG_APIC_ID;
- break;
- case 0x30:
- regNum = MISCREG_APIC_VERSION;
- break;
- case 0x80:
- regNum = MISCREG_APIC_TASK_PRIORITY;
- break;
- case 0x90:
- regNum = MISCREG_APIC_ARBITRATION_PRIORITY;
- break;
- case 0xA0:
- regNum = MISCREG_APIC_PROCESSOR_PRIORITY;
- break;
- case 0xB0:
- regNum = MISCREG_APIC_EOI;
- break;
- case 0xD0:
- regNum = MISCREG_APIC_LOGICAL_DESTINATION;
- break;
- case 0xE0:
- regNum = MISCREG_APIC_DESTINATION_FORMAT;
- break;
- case 0xF0:
- regNum = MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR;
- break;
- case 0x100:
- case 0x108:
- case 0x110:
- case 0x118:
- case 0x120:
- case 0x128:
- case 0x130:
- case 0x138:
- case 0x140:
- case 0x148:
- case 0x150:
- case 0x158:
- case 0x160:
- case 0x168:
- case 0x170:
- case 0x178:
- regNum = MISCREG_APIC_IN_SERVICE(
- (paddr - baseAddr - 0x100) / 0x8);
- break;
- case 0x180:
- case 0x188:
- case 0x190:
- case 0x198:
- case 0x1A0:
- case 0x1A8:
- case 0x1B0:
- case 0x1B8:
- case 0x1C0:
- case 0x1C8:
- case 0x1D0:
- case 0x1D8:
- case 0x1E0:
- case 0x1E8:
- case 0x1F0:
- case 0x1F8:
- regNum = MISCREG_APIC_TRIGGER_MODE(
- (paddr - baseAddr - 0x180) / 0x8);
- break;
- case 0x200:
- case 0x208:
- case 0x210:
- case 0x218:
- case 0x220:
- case 0x228:
- case 0x230:
- case 0x238:
- case 0x240:
- case 0x248:
- case 0x250:
- case 0x258:
- case 0x260:
- case 0x268:
- case 0x270:
- case 0x278:
- regNum = MISCREG_APIC_INTERRUPT_REQUEST(
- (paddr - baseAddr - 0x200) / 0x8);
- break;
- case 0x280:
- regNum = MISCREG_APIC_ERROR_STATUS;
- break;
- case 0x300:
- regNum = MISCREG_APIC_INTERRUPT_COMMAND_LOW;
- break;
- case 0x310:
- regNum = MISCREG_APIC_INTERRUPT_COMMAND_HIGH;
- break;
- case 0x320:
- regNum = MISCREG_APIC_LVT_TIMER;
- break;
- case 0x330:
- regNum = MISCREG_APIC_LVT_THERMAL_SENSOR;
- break;
- case 0x340:
- regNum = MISCREG_APIC_LVT_PERFORMANCE_MONITORING_COUNTERS;
- break;
- case 0x350:
- regNum = MISCREG_APIC_LVT_LINT0;
- break;
- case 0x360:
- regNum = MISCREG_APIC_LVT_LINT1;
- break;
- case 0x370:
- regNum = MISCREG_APIC_LVT_ERROR;
- break;
- case 0x380:
- regNum = MISCREG_APIC_INITIAL_COUNT;
- break;
- case 0x390:
- regNum = MISCREG_APIC_CURRENT_COUNT;
- break;
- case 0x3E0:
- regNum = MISCREG_APIC_DIVIDE_COUNT;
- break;
- default:
- // A reserved register field.
- return new GeneralProtection(0);
- break;
- }
- req->setPaddr(regNum * sizeof(MiscReg));
+ */
+ // Force the access to be uncacheable.
+ req->setFlags(Request::UNCACHEABLE);
+ req->setPaddr(x86LocalAPICAddress(tc->contextId(), paddr - baseAddr));
}
+#endif
return NoFault;
};
Fault
-DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
+DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write)
+{
+ bool delayedResponse;
+ return TLB::translate(req, tc, NULL, write,
+ false, delayedResponse, false);
+}
+
+void
+DTB::translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation, bool write)
{
- return TLB::translate<FakeDTLBFault>(req, tc, write, false);
+ bool delayedResponse;
+ assert(translation);
+ Fault fault = TLB::translate(req, tc, translation,
+ write, false, delayedResponse, true);
+ if (!delayedResponse)
+ translation->finish(fault, req, tc, write);
}
Fault
-ITB::translate(RequestPtr &req, ThreadContext *tc)
+ITB::translateAtomic(RequestPtr req, ThreadContext *tc)
+{
+ bool delayedResponse;
+ return TLB::translate(req, tc, NULL, false,
+ true, delayedResponse, false);
+}
+
+void
+ITB::translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation)
{
- return TLB::translate<FakeITLBFault>(req, tc, false, true);
+ bool delayedResponse;
+ assert(translation);
+ Fault fault = TLB::translate(req, tc, translation,
+ false, true, delayedResponse, true);
+ if (!delayedResponse)
+ translation->finish(fault, req, tc, false);
}
#if FULL_SYSTEM
diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh
index 89b965e97..2467bc472 100644
--- a/src/arch/x86/tlb.hh
+++ b/src/arch/x86/tlb.hh
@@ -87,8 +87,7 @@ namespace X86ISA
class TLB : public BaseTLB
{
protected:
- friend class FakeITLBFault;
- friend class FakeDTLBFault;
+ friend class Walker;
typedef std::list<TlbEntry *> EntryList;
@@ -118,8 +117,6 @@ namespace X86ISA
protected:
Walker * walker;
-
- void walk(ThreadContext * _tc, Addr vaddr);
#endif
public:
@@ -137,13 +134,13 @@ namespace X86ISA
EntryList freeList;
EntryList entryList;
- template<class TlbFault>
- Fault translate(RequestPtr &req, ThreadContext *tc,
- bool write, bool execute);
+ Fault translate(RequestPtr req, ThreadContext *tc,
+ Translation *translation, bool write, bool execute,
+ bool &delayedResponse, bool timing);
public:
- void insert(Addr vpn, TlbEntry &entry);
+ TlbEntry * insert(Addr vpn, TlbEntry &entry);
// Checkpointing
virtual void serialize(std::ostream &os);
@@ -159,7 +156,9 @@ namespace X86ISA
_allowNX = false;
}
- Fault translate(RequestPtr &req, ThreadContext *tc);
+ Fault translateAtomic(RequestPtr req, ThreadContext *tc);
+ void translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation);
friend class DTB;
};
@@ -172,7 +171,9 @@ namespace X86ISA
{
_allowNX = true;
}
- Fault translate(RequestPtr &req, ThreadContext *tc, bool write);
+ Fault translateAtomic(RequestPtr req, ThreadContext *tc, bool write);
+ void translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation, bool write);
#if FULL_SYSTEM
Tick doMmuRegRead(ThreadContext *tc, Packet *pkt);
Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt);
diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh
index 90df38d13..29420352b 100644
--- a/src/arch/x86/types.hh
+++ b/src/arch/x86/types.hh
@@ -246,17 +246,6 @@ namespace X86ISA
MiscReg ctrlReg;
} AnyReg;
- //XXX This is very hypothetical. X87 instructions would need to
- //change their "context" constantly. It's also not clear how
- //this would be handled as far as out of order execution.
- //Maybe x87 instructions are in order?
- enum RegContextParam
- {
- CONTEXT_X87_TOP
- };
-
- typedef int RegContextVal;
-
typedef uint16_t RegIndex;
struct CoreSpecific {
diff --git a/src/arch/x86/utility.cc b/src/arch/x86/utility.cc
index 5fe5bf8c3..43a5ca1a9 100644
--- a/src/arch/x86/utility.cc
+++ b/src/arch/x86/utility.cc
@@ -55,11 +55,17 @@
* Authors: Gabe Black
*/
+#include "config/full_system.hh"
+
+#if FULL_SYSTEM
+#include "arch/x86/interrupts.hh"
+#endif
#include "arch/x86/intregs.hh"
#include "arch/x86/miscregs.hh"
#include "arch/x86/segmentregs.hh"
#include "arch/x86/utility.hh"
#include "arch/x86/x86_traits.hh"
+#include "cpu/base.hh"
#include "sim/system.hh"
namespace X86ISA {
@@ -254,9 +260,15 @@ void initCPU(ThreadContext *tc, int cpuId)
lApicBase.bsp = (cpuId == 0);
tc->setMiscReg(MISCREG_APIC_BASE, lApicBase);
- tc->setMiscRegNoEffect(MISCREG_APIC_ID, cpuId << 24);
+ Interrupts * interrupts = dynamic_cast<Interrupts *>(
+ tc->getCpuPtr()->getInterruptController());
+ assert(interrupts);
+
+ interrupts->setRegNoEffect(APIC_ID, cpuId << 24);
- tc->setMiscRegNoEffect(MISCREG_APIC_VERSION, (5 << 16) | 0x14);
+ interrupts->setRegNoEffect(APIC_VERSION, (5 << 16) | 0x14);
+
+ interrupts->setClock(tc->getCpuPtr()->ticks(16));
// TODO Set the SMRAM base address (SMBASE) to 0x00030000
diff --git a/src/arch/x86/utility.hh b/src/arch/x86/utility.hh
index 477a76e0b..6f0812a6a 100644
--- a/src/arch/x86/utility.hh
+++ b/src/arch/x86/utility.hh
@@ -93,7 +93,12 @@ namespace X86ISA
static inline bool
inUserMode(ThreadContext *tc)
{
- return false;
+#if FULL_SYSTEM
+ HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
+ return m5reg.cpl == 3;
+#else
+ return true;
+#endif
}
inline bool isCallerSaveIntegerRegister(unsigned int reg) {
diff --git a/src/arch/x86/x86_traits.hh b/src/arch/x86/x86_traits.hh
index d605ce218..0347a7099 100644
--- a/src/arch/x86/x86_traits.hh
+++ b/src/arch/x86/x86_traits.hh
@@ -55,11 +55,13 @@
* Authors: Gabe Black
*/
-#include "sim/host.hh"
-
#ifndef __ARCH_X86_X86TRAITS_HH__
#define __ARCH_X86_X86TRAITS_HH__
+#include <assert.h>
+
+#include "sim/host.hh"
+
namespace X86ISA
{
const int NumMicroIntRegs = 16;
@@ -90,6 +92,37 @@ namespace X86ISA
const Addr PhysAddrPrefixIO = ULL(0x8000000000000000);
const Addr PhysAddrPrefixPciConfig = ULL(0xC000000000000000);
+ const Addr PhysAddrPrefixLocalAPIC = ULL(0x2000000000000000);
+ const Addr PhysAddrPrefixInterrupts = ULL(0xA000000000000000);
+ // Each APIC gets two pages. One page is used for local apics to field
+ // accesses from the CPU, and the other is for all APICs to communicate.
+ const Addr PhysAddrAPICRangeSize = 1 << 12;
+
+ static inline Addr
+ x86IOAddress(const uint32_t port)
+ {
+ return PhysAddrPrefixIO | port;
+ }
+
+ static inline Addr
+ x86PciConfigAddress(const uint32_t addr)
+ {
+ return PhysAddrPrefixPciConfig | addr;
+ }
+
+ static inline Addr
+ x86LocalAPICAddress(const uint8_t id, const uint16_t addr)
+ {
+ assert(addr < (1 << 12));
+ return PhysAddrPrefixLocalAPIC | (id * (1 << 12)) | addr;
+ }
+
+ static inline Addr
+ x86InterruptAddress(const uint8_t id, const uint16_t addr)
+ {
+ assert(addr < PhysAddrAPICRangeSize);
+ return PhysAddrPrefixInterrupts | (id * PhysAddrAPICRangeSize) | addr;
+ }
}
#endif //__ARCH_X86_X86TRAITS_HH__