Merge ARM into the head. ARM will compile but may not actually work.
This commit is contained in:
commit
d080581db1
1238 changed files with 77272 additions and 36447 deletions
2
.hgtags
2
.hgtags
|
@ -16,3 +16,5 @@ b174ae14f007ba0c341f8df77d36f57f48369cc8 m5_2.0_beta2
|
|||
91a9ac67662aa3a79315ade29b17a85961fecd88 m5_2.0_beta3
|
||||
dce5a8655829b7d2e24ce40cafc9c8873a71671f m5_2.0_beta5
|
||||
1ac44b6c87ec71a8410c9a9c219269eca71f8077 m5_2.0_beta4
|
||||
60a931b03fb165807f02bcccc4f7d0fd705a67a9 copyright_update
|
||||
d8b246a665c160a31751b4091f097022cde16dd7 m5_2.0_beta6
|
||||
|
|
2
README
2
README
|
@ -1,4 +1,4 @@
|
|||
This is release 2.0_beta5 of the M5 simulator.
|
||||
This is release 2.0_beta6 of the M5 simulator.
|
||||
|
||||
For detailed information about building the simulator and getting
|
||||
started please refer to http://www.m5sim.org.
|
||||
|
|
|
@ -1,13 +1,26 @@
|
|||
October 6, 2008: m5_2.0_beta6
|
||||
--------------------
|
||||
New Features
|
||||
1. Support for gcc 4.3
|
||||
2. Core m5 code in libm5 for integration with other simulators
|
||||
3. Preliminary support for X86 SE mode
|
||||
4. Additional system calls emulated
|
||||
5. m5term updated to work on OS X
|
||||
6. Ability to disable listen sockets
|
||||
7. Event queue performance improvements and rewrite
|
||||
8. Better errors for unconnected memory ports
|
||||
|
||||
Bug fixes
|
||||
1. ALPHA_SE O3 perlbmk benchmark
|
||||
2. Translation bug where O3 could fetch from uncachable memory
|
||||
3. Many minor bugs
|
||||
|
||||
Outstanding issues for 2.0 release:
|
||||
--------------------
|
||||
1. Fix O3 CPU bug in SE 40.perlbmk fails
|
||||
2. Fix O3 processing nacks/coherence messages
|
||||
3. Better statistics for the caches.
|
||||
4. FS mode doesn't work under Cygwin
|
||||
5. memtest regression crashes under Cygwin
|
||||
6. Make repository public
|
||||
7. Testing
|
||||
8. Validation
|
||||
1. Statistics cleanup
|
||||
2. Improve regression system
|
||||
3. Testing
|
||||
4. Validation
|
||||
|
||||
March 1, 2008: m5_2.0_beta5
|
||||
--------------------
|
||||
|
|
689
SConstruct
689
SConstruct
File diff suppressed because it is too large
Load diff
|
@ -59,46 +59,46 @@ Benchmarks = {
|
|||
'PovrayBench': [SysConfig('povray-bench.rcS', '512MB', 'povray.img')],
|
||||
'PovrayAutumn': [SysConfig('povray-autumn.rcS', '512MB', 'povray.img')],
|
||||
|
||||
'NetperfStream': [SysConfig('netperf-stream-client.rcS'),
|
||||
'NetperfStream': [SysConfig('netperf-stream-client.rcS'),
|
||||
SysConfig('netperf-server.rcS')],
|
||||
'NetperfStreamUdp': [SysConfig('netperf-stream-udp-client.rcS'),
|
||||
'NetperfStreamUdp': [SysConfig('netperf-stream-udp-client.rcS'),
|
||||
SysConfig('netperf-server.rcS')],
|
||||
'NetperfUdpLocal': [SysConfig('netperf-stream-udp-local.rcS')],
|
||||
'NetperfStreamNT': [SysConfig('netperf-stream-nt-client.rcS'),
|
||||
'NetperfUdpLocal': [SysConfig('netperf-stream-udp-local.rcS')],
|
||||
'NetperfStreamNT': [SysConfig('netperf-stream-nt-client.rcS'),
|
||||
SysConfig('netperf-server.rcS')],
|
||||
'NetperfMaerts': [SysConfig('netperf-maerts-client.rcS'),
|
||||
'NetperfMaerts': [SysConfig('netperf-maerts-client.rcS'),
|
||||
SysConfig('netperf-server.rcS')],
|
||||
'SurgeStandard': [SysConfig('surge-server.rcS', '512MB'),
|
||||
'SurgeStandard': [SysConfig('surge-server.rcS', '512MB'),
|
||||
SysConfig('surge-client.rcS', '256MB')],
|
||||
'SurgeSpecweb': [SysConfig('spec-surge-server.rcS', '512MB'),
|
||||
'SurgeSpecweb': [SysConfig('spec-surge-server.rcS', '512MB'),
|
||||
SysConfig('spec-surge-client.rcS', '256MB')],
|
||||
'Nhfsstone': [SysConfig('nfs-server-nhfsstone.rcS', '512MB'),
|
||||
'Nhfsstone': [SysConfig('nfs-server-nhfsstone.rcS', '512MB'),
|
||||
SysConfig('nfs-client-nhfsstone.rcS')],
|
||||
'Nfs': [SysConfig('nfs-server.rcS', '900MB'),
|
||||
'Nfs': [SysConfig('nfs-server.rcS', '900MB'),
|
||||
SysConfig('nfs-client-dbench.rcS')],
|
||||
'NfsTcp': [SysConfig('nfs-server.rcS', '900MB'),
|
||||
'NfsTcp': [SysConfig('nfs-server.rcS', '900MB'),
|
||||
SysConfig('nfs-client-tcp.rcS')],
|
||||
'IScsiInitiator': [SysConfig('iscsi-client.rcS', '512MB'),
|
||||
'IScsiInitiator': [SysConfig('iscsi-client.rcS', '512MB'),
|
||||
SysConfig('iscsi-server.rcS', '512MB')],
|
||||
'IScsiTarget': [SysConfig('iscsi-server.rcS', '512MB'),
|
||||
'IScsiTarget': [SysConfig('iscsi-server.rcS', '512MB'),
|
||||
SysConfig('iscsi-client.rcS', '512MB')],
|
||||
'Validation': [SysConfig('iscsi-server.rcS', '512MB'),
|
||||
'Validation': [SysConfig('iscsi-server.rcS', '512MB'),
|
||||
SysConfig('iscsi-client.rcS', '512MB')],
|
||||
'Ping': [SysConfig('ping-server.rcS',),
|
||||
'Ping': [SysConfig('ping-server.rcS',),
|
||||
SysConfig('ping-client.rcS')],
|
||||
|
||||
'ValAccDelay': [SysConfig('devtime.rcS', '512MB')],
|
||||
'ValAccDelay2': [SysConfig('devtimewmr.rcS', '512MB')],
|
||||
'ValMemLat': [SysConfig('micro_memlat.rcS', '512MB')],
|
||||
'ValMemLat2MB': [SysConfig('micro_memlat2mb.rcS', '512MB')],
|
||||
'ValMemLat8MB': [SysConfig('micro_memlat8mb.rcS', '512MB')],
|
||||
'ValMemLat': [SysConfig('micro_memlat8.rcS', '512MB')],
|
||||
'ValTlbLat': [SysConfig('micro_tlblat.rcS', '512MB')],
|
||||
'ValSysLat': [SysConfig('micro_syscall.rcS', '512MB')],
|
||||
'ValCtxLat': [SysConfig('micro_ctx.rcS', '512MB')],
|
||||
'ValStream': [SysConfig('micro_stream.rcS', '512MB')],
|
||||
'ValStreamScale': [SysConfig('micro_streamscale.rcS', '512MB')],
|
||||
'ValStreamCopy': [SysConfig('micro_streamcopy.rcS', '512MB')],
|
||||
'ValAccDelay': [SysConfig('devtime.rcS', '512MB')],
|
||||
'ValAccDelay2': [SysConfig('devtimewmr.rcS', '512MB')],
|
||||
'ValMemLat': [SysConfig('micro_memlat.rcS', '512MB')],
|
||||
'ValMemLat2MB': [SysConfig('micro_memlat2mb.rcS', '512MB')],
|
||||
'ValMemLat8MB': [SysConfig('micro_memlat8mb.rcS', '512MB')],
|
||||
'ValMemLat': [SysConfig('micro_memlat8.rcS', '512MB')],
|
||||
'ValTlbLat': [SysConfig('micro_tlblat.rcS', '512MB')],
|
||||
'ValSysLat': [SysConfig('micro_syscall.rcS', '512MB')],
|
||||
'ValCtxLat': [SysConfig('micro_ctx.rcS', '512MB')],
|
||||
'ValStream': [SysConfig('micro_stream.rcS', '512MB')],
|
||||
'ValStreamScale': [SysConfig('micro_streamscale.rcS', '512MB')],
|
||||
'ValStreamCopy': [SysConfig('micro_streamcopy.rcS', '512MB')],
|
||||
|
||||
'MutexTest': [SysConfig('mutex-test.rcS', '128MB')],
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
|||
read_only = True))
|
||||
self.intrctrl = IntrControl()
|
||||
self.mem_mode = mem_mode
|
||||
self.sim_console = SimConsole()
|
||||
self.terminal = Terminal()
|
||||
self.kernel = binary('vmlinux')
|
||||
self.pal = binary('ts_osfpal')
|
||||
self.console = binary('console')
|
||||
|
@ -148,7 +148,7 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None):
|
|||
read_only = True))
|
||||
self.intrctrl = IntrControl()
|
||||
self.mem_mode = mem_mode
|
||||
self.sim_console = SimConsole()
|
||||
self.terminal = Terminal()
|
||||
self.kernel = binary('mips/vmlinux')
|
||||
self.console = binary('mips/console')
|
||||
self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
|
||||
|
@ -159,11 +159,14 @@ def x86IOAddress(port):
|
|||
IO_address_space_base = 0x8000000000000000
|
||||
return IO_address_space_base + port;
|
||||
|
||||
def makeLinuxX86System(mem_mode, mdesc = None):
|
||||
self = LinuxX86System()
|
||||
def makeX86System(mem_mode, mdesc = None, self = None):
|
||||
if self == None:
|
||||
self = X86System()
|
||||
|
||||
if not mdesc:
|
||||
# generic system
|
||||
mdesc = SysConfig()
|
||||
mdesc.diskname = 'x86root.img'
|
||||
self.readfile = mdesc.script()
|
||||
|
||||
# Physical memory
|
||||
|
@ -177,22 +180,168 @@ def makeLinuxX86System(mem_mode, mdesc = None):
|
|||
self.bridge.side_a = self.iobus.port
|
||||
self.bridge.side_b = self.membus.port
|
||||
|
||||
# Serial port and console
|
||||
self.console = SimConsole()
|
||||
self.com_1 = Uart8250()
|
||||
self.com_1.pio_addr = x86IOAddress(0x3f8)
|
||||
self.com_1.pio = self.iobus.port
|
||||
self.com_1.sim_console = self.console
|
||||
|
||||
# Command line
|
||||
self.boot_osflags = 'earlyprintk=ttyS0'
|
||||
|
||||
# Platform
|
||||
self.opteron = Opteron()
|
||||
self.opteron.attachIO(self.iobus)
|
||||
self.pc = Pc()
|
||||
self.pc.attachIO(self.iobus)
|
||||
|
||||
self.intrctrl = IntrControl()
|
||||
|
||||
# Disks
|
||||
disk0 = CowIdeDisk(driveID='master')
|
||||
disk2 = CowIdeDisk(driveID='master')
|
||||
disk0.childImage(mdesc.disk())
|
||||
disk2.childImage(disk('linux-bigswap2.img'))
|
||||
self.pc.south_bridge.ide.disks = [disk0, disk2]
|
||||
|
||||
# Add in a Bios information structure.
|
||||
structures = [X86SMBiosBiosInformation()]
|
||||
self.smbios_table.structures = structures
|
||||
|
||||
# Set up the Intel MP table
|
||||
bp = X86IntelMPProcessor(
|
||||
local_apic_id = 0,
|
||||
local_apic_version = 0x14,
|
||||
enable = True,
|
||||
bootstrap = True)
|
||||
self.intel_mp_table.add_entry(bp)
|
||||
io_apic = X86IntelMPIOAPIC(
|
||||
id = 1,
|
||||
version = 0x11,
|
||||
enable = True,
|
||||
address = 0xfec00000)
|
||||
self.intel_mp_table.add_entry(io_apic)
|
||||
isa_bus = X86IntelMPBus(bus_id = 0, bus_type='ISA')
|
||||
self.intel_mp_table.add_entry(isa_bus)
|
||||
pci_bus = X86IntelMPBus(bus_id = 1, bus_type='PCI')
|
||||
self.intel_mp_table.add_entry(pci_bus)
|
||||
connect_busses = X86IntelMPBusHierarchy(bus_id=0,
|
||||
subtractive_decode=True, parent_bus=1)
|
||||
self.intel_mp_table.add_entry(connect_busses)
|
||||
pci_dev4_inta = X86IntelMPIOIntAssignment(
|
||||
interrupt_type = 'INT',
|
||||
polarity = 'ConformPolarity',
|
||||
trigger = 'ConformTrigger',
|
||||
source_bus_id = 1,
|
||||
source_bus_irq = 0 + (4 << 2),
|
||||
dest_io_apic_id = 1,
|
||||
dest_io_apic_intin = 16)
|
||||
assign_8259_0_to_apic = X86IntelMPIOIntAssignment(
|
||||
interrupt_type = 'ExtInt',
|
||||
polarity = 'ConformPolarity',
|
||||
trigger = 'ConformTrigger',
|
||||
source_bus_id = 0,
|
||||
source_bus_irq = 0,
|
||||
dest_io_apic_id = 1,
|
||||
dest_io_apic_intin = 0)
|
||||
self.intel_mp_table.add_entry(assign_8259_0_to_apic)
|
||||
assign_0_to_apic = X86IntelMPIOIntAssignment(
|
||||
interrupt_type = 'INT',
|
||||
polarity = 'ConformPolarity',
|
||||
trigger = 'ConformTrigger',
|
||||
source_bus_id = 0,
|
||||
source_bus_irq = 0,
|
||||
dest_io_apic_id = 1,
|
||||
dest_io_apic_intin = 2)
|
||||
self.intel_mp_table.add_entry(assign_0_to_apic)
|
||||
assign_8259_1_to_apic = X86IntelMPIOIntAssignment(
|
||||
interrupt_type = 'ExtInt',
|
||||
polarity = 'ConformPolarity',
|
||||
trigger = 'ConformTrigger',
|
||||
source_bus_id = 0,
|
||||
source_bus_irq = 1,
|
||||
dest_io_apic_id = 1,
|
||||
dest_io_apic_intin = 0)
|
||||
self.intel_mp_table.add_entry(assign_8259_1_to_apic)
|
||||
assign_1_to_apic = X86IntelMPIOIntAssignment(
|
||||
interrupt_type = 'INT',
|
||||
polarity = 'ConformPolarity',
|
||||
trigger = 'ConformTrigger',
|
||||
source_bus_id = 0,
|
||||
source_bus_irq = 1,
|
||||
dest_io_apic_id = 1,
|
||||
dest_io_apic_intin = 1)
|
||||
self.intel_mp_table.add_entry(assign_1_to_apic)
|
||||
assign_8259_4_to_apic = X86IntelMPIOIntAssignment(
|
||||
interrupt_type = 'ExtInt',
|
||||
polarity = 'ConformPolarity',
|
||||
trigger = 'ConformTrigger',
|
||||
source_bus_id = 0,
|
||||
source_bus_irq = 4,
|
||||
dest_io_apic_id = 1,
|
||||
dest_io_apic_intin = 0)
|
||||
self.intel_mp_table.add_entry(assign_8259_4_to_apic)
|
||||
assign_4_to_apic = X86IntelMPIOIntAssignment(
|
||||
interrupt_type = 'INT',
|
||||
polarity = 'ConformPolarity',
|
||||
trigger = 'ConformTrigger',
|
||||
source_bus_id = 0,
|
||||
source_bus_irq = 4,
|
||||
dest_io_apic_id = 1,
|
||||
dest_io_apic_intin = 4)
|
||||
self.intel_mp_table.add_entry(assign_4_to_apic)
|
||||
assign_8259_12_to_apic = X86IntelMPIOIntAssignment(
|
||||
interrupt_type = 'ExtInt',
|
||||
polarity = 'ConformPolarity',
|
||||
trigger = 'ConformTrigger',
|
||||
source_bus_id = 0,
|
||||
source_bus_irq = 12,
|
||||
dest_io_apic_id = 1,
|
||||
dest_io_apic_intin = 0)
|
||||
self.intel_mp_table.add_entry(assign_8259_12_to_apic)
|
||||
assign_12_to_apic = X86IntelMPIOIntAssignment(
|
||||
interrupt_type = 'INT',
|
||||
polarity = 'ConformPolarity',
|
||||
trigger = 'ConformTrigger',
|
||||
source_bus_id = 0,
|
||||
source_bus_irq = 12,
|
||||
dest_io_apic_id = 1,
|
||||
dest_io_apic_intin = 12)
|
||||
self.intel_mp_table.add_entry(assign_12_to_apic)
|
||||
assign_8259_14_to_apic = X86IntelMPIOIntAssignment(
|
||||
interrupt_type = 'ExtInt',
|
||||
polarity = 'ConformPolarity',
|
||||
trigger = 'ConformTrigger',
|
||||
source_bus_id = 0,
|
||||
source_bus_irq = 14,
|
||||
dest_io_apic_id = 1,
|
||||
dest_io_apic_intin = 0)
|
||||
self.intel_mp_table.add_entry(assign_8259_14_to_apic)
|
||||
assign_14_to_apic = X86IntelMPIOIntAssignment(
|
||||
interrupt_type = 'INT',
|
||||
polarity = 'ConformPolarity',
|
||||
trigger = 'ConformTrigger',
|
||||
source_bus_id = 0,
|
||||
source_bus_irq = 14,
|
||||
dest_io_apic_id = 1,
|
||||
dest_io_apic_intin = 14)
|
||||
self.intel_mp_table.add_entry(assign_14_to_apic)
|
||||
|
||||
|
||||
def makeLinuxX86System(mem_mode, mdesc = None):
|
||||
self = LinuxX86System()
|
||||
|
||||
# Build up a generic x86 system and then specialize it for Linux
|
||||
makeX86System(mem_mode, mdesc, self)
|
||||
|
||||
# We assume below that there's at least 1MB of memory. We'll require 2
|
||||
# just to avoid corner cases.
|
||||
assert(self.physmem.range.second >= 0x200000)
|
||||
|
||||
# Mark the first megabyte of memory as reserved
|
||||
self.e820_table.entries.append(X86E820Entry(
|
||||
addr = 0,
|
||||
size = '1MB',
|
||||
range_type = 2))
|
||||
|
||||
# Mark the rest as available
|
||||
self.e820_table.entries.append(X86E820Entry(
|
||||
addr = 0x100000,
|
||||
size = '%dB' % (self.physmem.range.second - 0x100000 - 1),
|
||||
range_type = 1))
|
||||
|
||||
# Command line
|
||||
self.boot_osflags = 'earlyprintk=ttyS0 console=ttyS0 lpj=7999923 ' + \
|
||||
'root=/dev/hda1'
|
||||
return self
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
# system options
|
||||
parser.add_option("-d", "--detailed", action="store_true")
|
||||
parser.add_option("-t", "--timing", action="store_true")
|
||||
parser.add_option("--inorder", action="store_true")
|
||||
parser.add_option("-n", "--num-cpus", type="int", default=1)
|
||||
parser.add_option("--caches", action="store_true")
|
||||
parser.add_option("--l2cache", action="store_true")
|
||||
|
|
|
@ -43,6 +43,11 @@ def setCPUClass(options):
|
|||
print "O3 CPU must be used with caches"
|
||||
sys.exit(1)
|
||||
class TmpClass(DerivO3CPU): pass
|
||||
elif options.inorder:
|
||||
if not options.caches:
|
||||
print "InOrder CPU must be used with caches"
|
||||
sys.exit(1)
|
||||
class TmpClass(InOrderCPU): pass
|
||||
else:
|
||||
class TmpClass(AtomicSimpleCPU): pass
|
||||
atomic = True
|
||||
|
@ -78,10 +83,10 @@ def run(options, root, testsys, cpu_class):
|
|||
cptdir = getcwd()
|
||||
|
||||
if options.fast_forward and options.checkpoint_restore != None:
|
||||
m5.panic("Error: Can't specify both --fast-forward and --checkpoint-restore")
|
||||
m5.fatal("Error: Can't specify both --fast-forward and --checkpoint-restore")
|
||||
|
||||
if options.standard_switch and not options.caches:
|
||||
m5.panic("Error: Must specify --caches when using --standard-switch")
|
||||
m5.fatal("Error: Must specify --caches when using --standard-switch")
|
||||
|
||||
np = options.num_cpus
|
||||
max_checkpoints = options.max_checkpoints
|
||||
|
@ -128,8 +133,8 @@ def run(options, root, testsys, cpu_class):
|
|||
testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
|
||||
# Fast forward to a simpoint (warning: time consuming)
|
||||
elif options.simpoint:
|
||||
if testsys.cpu[i].workload[0].simpoint == None:
|
||||
m5.panic('simpoint not found')
|
||||
if testsys.cpu[i].workload[0].simpoint == 0:
|
||||
m5.fatal('simpoint not found')
|
||||
testsys.cpu[i].max_insts_any_thread = \
|
||||
testsys.cpu[i].workload[0].simpoint
|
||||
# No distance specified, just switch
|
||||
|
@ -162,8 +167,8 @@ def run(options, root, testsys, cpu_class):
|
|||
# Set an instruction break point
|
||||
if options.simpoint:
|
||||
for i in xrange(np):
|
||||
if testsys.cpu[i].workload[0].simpoint == None:
|
||||
m5.panic('no simpoint for testsys.cpu[%d].workload[0]' % i)
|
||||
if testsys.cpu[i].workload[0].simpoint == 0:
|
||||
m5.fatal('no simpoint for testsys.cpu[%d].workload[0]', i)
|
||||
checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset
|
||||
testsys.cpu[i].max_insts_any_thread = checkpoint_inst
|
||||
# used for output below
|
||||
|
@ -183,13 +188,13 @@ def run(options, root, testsys, cpu_class):
|
|||
import re
|
||||
|
||||
if not isdir(cptdir):
|
||||
m5.panic("checkpoint dir %s does not exist!" % cptdir)
|
||||
m5.fatal("checkpoint dir %s does not exist!", cptdir)
|
||||
|
||||
if options.at_instruction:
|
||||
checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % \
|
||||
(options.bench, options.checkpoint_restore))
|
||||
if not exists(checkpoint_dir):
|
||||
m5.panic("Unable to find checkpoint directory %s" % \
|
||||
m5.fatal("Unable to find checkpoint directory %s",
|
||||
checkpoint_dir)
|
||||
|
||||
print "Restoring checkpoint ..."
|
||||
|
@ -197,8 +202,8 @@ def run(options, root, testsys, cpu_class):
|
|||
print "Done."
|
||||
elif options.simpoint:
|
||||
# assume workload 0 has the simpoint
|
||||
if testsys.cpu[0].workload[0].simpoint == None:
|
||||
m5.panic('Unable to find simpoint')
|
||||
if testsys.cpu[0].workload[0].simpoint == 0:
|
||||
m5.fatal('Unable to find simpoint')
|
||||
|
||||
options.checkpoint_restore += \
|
||||
int(testsys.cpu[0].workload[0].simpoint)
|
||||
|
@ -206,8 +211,8 @@ def run(options, root, testsys, cpu_class):
|
|||
checkpoint_dir = joinpath(cptdir, "cpt.%s.%d" % \
|
||||
(options.bench, options.checkpoint_restore))
|
||||
if not exists(checkpoint_dir):
|
||||
m5.panic("Unable to find checkpoint directory %s.%s" % \
|
||||
(options.bench, options.checkpoint_restore))
|
||||
m5.fatal("Unable to find checkpoint directory %s.%s",
|
||||
options.bench, options.checkpoint_restore)
|
||||
|
||||
print "Restoring checkpoint ..."
|
||||
m5.restoreCheckpoint(root,checkpoint_dir)
|
||||
|
@ -226,7 +231,7 @@ def run(options, root, testsys, cpu_class):
|
|||
cpt_num = options.checkpoint_restore
|
||||
|
||||
if cpt_num > len(cpts):
|
||||
m5.panic('Checkpoint %d not found' % cpt_num)
|
||||
m5.fatal('Checkpoint %d not found', cpt_num)
|
||||
|
||||
## Adjust max tick based on our starting tick
|
||||
maxtick = maxtick - int(cpts[cpt_num - 1])
|
||||
|
|
|
@ -140,7 +140,8 @@ class Benchmark(object):
|
|||
process_args['input'] = self.stdin
|
||||
if self.stdout:
|
||||
process_args['output'] = self.stdout
|
||||
process_args['simpoint'] = self.simpoint
|
||||
if self.simpoint:
|
||||
process_args['simpoint'] = self.simpoint
|
||||
# explicit keywords override defaults
|
||||
process_args.update(kwargs)
|
||||
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
import optparse, os, sys
|
||||
|
||||
import m5
|
||||
|
||||
if not m5.build_env['FULL_SYSTEM']:
|
||||
m5.fatal("This script requires full-system mode (*_FS).")
|
||||
|
||||
from m5.objects import *
|
||||
m5.AddToPath('../common')
|
||||
from FSConfig import *
|
||||
|
@ -37,9 +41,6 @@ from Benchmarks import *
|
|||
import Simulation
|
||||
from Caches import *
|
||||
|
||||
if not m5.build_env['FULL_SYSTEM']:
|
||||
m5.panic("This script requires full-system mode (ALPHA_FS).")
|
||||
|
||||
# Get paths we might need. It's expected this file is in m5/configs/example.
|
||||
config_path = os.path.dirname(os.path.abspath(__file__))
|
||||
config_root = os.path.dirname(config_path)
|
||||
|
@ -104,7 +105,7 @@ elif m5.build_env['TARGET_ISA'] == "sparc":
|
|||
elif m5.build_env['TARGET_ISA'] == "x86":
|
||||
test_sys = makeLinuxX86System(test_mem_mode, bm[0])
|
||||
else:
|
||||
m5.panic("incapable of building non-alpha or non-sparc full system!")
|
||||
m5.fatal("incapable of building non-alpha or non-sparc full system!")
|
||||
|
||||
if options.kernel is not None:
|
||||
test_sys.kernel = binary(options.kernel)
|
||||
|
|
|
@ -31,8 +31,13 @@
|
|||
# "m5 test.py"
|
||||
|
||||
import m5
|
||||
|
||||
if m5.build_env['FULL_SYSTEM']:
|
||||
m5.fatal("This script requires syscall emulation mode (*_SE).")
|
||||
|
||||
from m5.objects import *
|
||||
import os, optparse, sys
|
||||
from os.path import join as joinpath
|
||||
m5.AddToPath('../common')
|
||||
import Simulation
|
||||
from Caches import *
|
||||
|
@ -47,13 +52,13 @@ parser = optparse.OptionParser()
|
|||
|
||||
# Benchmark options
|
||||
parser.add_option("-c", "--cmd",
|
||||
default=os.path.join(m5_root, "tests/test-progs/hello/bin/alpha/linux/hello"),
|
||||
help="The binary to run in syscall emulation mode.")
|
||||
default=joinpath(m5_root, "tests/test-progs/hello/bin/alpha/linux/hello"),
|
||||
help="The binary to run in syscall emulation mode.")
|
||||
parser.add_option("-o", "--options", default="",
|
||||
help="The options to pass to the binary, use \" \" around the entire\
|
||||
string.")
|
||||
parser.add_option("-i", "--input", default="",
|
||||
help="A file of input to give to the binary.")
|
||||
help='The options to pass to the binary, use " " around the entire string')
|
||||
parser.add_option("-i", "--input", default="", help="Read stdin from a file.")
|
||||
parser.add_option("--output", default="", help="Redirect stdout to a file.")
|
||||
parser.add_option("--errout", default="", help="Redirect stderr to a file.")
|
||||
|
||||
execfile(os.path.join(config_root, "common", "Options.py"))
|
||||
|
||||
|
@ -81,6 +86,10 @@ else:
|
|||
|
||||
if options.input != "":
|
||||
process.input = options.input
|
||||
if options.output != "":
|
||||
process.output = options.output
|
||||
if options.errout != "":
|
||||
process.errout = options.errout
|
||||
|
||||
if options.detailed:
|
||||
#check for SMT workload
|
||||
|
@ -89,9 +98,15 @@ if options.detailed:
|
|||
process = []
|
||||
smt_idx = 0
|
||||
inputs = []
|
||||
outputs = []
|
||||
errouts = []
|
||||
|
||||
if options.input != "":
|
||||
inputs = options.input.split(';')
|
||||
if options.output != "":
|
||||
outputs = options.output.split(';')
|
||||
if options.errout != "":
|
||||
errouts = options.errout.split(';')
|
||||
|
||||
for wrkld in workloads:
|
||||
smt_process = LiveProcess()
|
||||
|
@ -99,6 +114,10 @@ if options.detailed:
|
|||
smt_process.cmd = wrkld + " " + options.options
|
||||
if inputs and inputs[smt_idx]:
|
||||
smt_process.input = inputs[smt_idx]
|
||||
if outputs and outputs[smt_idx]:
|
||||
smt_process.output = outputs[smt_idx]
|
||||
if errouts and errouts[smt_idx]:
|
||||
smt_process.errout = errouts[smt_idx]
|
||||
process += [smt_process, ]
|
||||
smt_idx += 1
|
||||
|
||||
|
|
504
ext/gzstream/LICENSE
Normal file
504
ext/gzstream/LICENSE
Normal file
|
@ -0,0 +1,504 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
38
ext/gzstream/SConscript
Normal file
38
ext/gzstream/SConscript
Normal file
|
@ -0,0 +1,38 @@
|
|||
# -*- mode:python -*-
|
||||
|
||||
# Copyright (c) 2004-2005 The Regents of The University of Michigan
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met: redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer;
|
||||
# redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution;
|
||||
# neither the name of the copyright holders nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Authors: Nathan Binkert
|
||||
|
||||
Import('env')
|
||||
|
||||
env.Library('gzstream', [File('gzstream.cc')])
|
||||
|
||||
env.Append(CPPPATH=Dir('.'))
|
||||
env.Append(LIBS=['gzstream'])
|
||||
env.Append(LIBPATH=[Dir('.')])
|
||||
|
1
ext/gzstream/VERSION
Normal file
1
ext/gzstream/VERSION
Normal file
|
@ -0,0 +1 @@
|
|||
1.5 (08 Jan 2003)
|
165
ext/gzstream/gzstream.cc
Normal file
165
ext/gzstream/gzstream.cc
Normal file
|
@ -0,0 +1,165 @@
|
|||
// ============================================================================
|
||||
// gzstream, C++ iostream classes wrapping the zlib compression library.
|
||||
// Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
// ============================================================================
|
||||
//
|
||||
// File : gzstream.C
|
||||
// Revision : $Revision: 1.7 $
|
||||
// Revision_date : $Date: 2003/01/08 14:41:27 $
|
||||
// Author(s) : Deepak Bandyopadhyay, Lutz Kettner
|
||||
//
|
||||
// Standard streambuf implementation following Nicolai Josuttis, "The
|
||||
// Standard C++ Library".
|
||||
// ============================================================================
|
||||
|
||||
#include <gzstream.hh>
|
||||
#include <iostream>
|
||||
#include <string.h> // for memcpy
|
||||
|
||||
#ifdef GZSTREAM_NAMESPACE
|
||||
namespace GZSTREAM_NAMESPACE {
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Internal classes to implement gzstream. See header file for user classes.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// --------------------------------------
|
||||
// class gzstreambuf:
|
||||
// --------------------------------------
|
||||
|
||||
gzstreambuf* gzstreambuf::open( const char* name, int open_mode) {
|
||||
if ( is_open())
|
||||
return (gzstreambuf*)0;
|
||||
mode = open_mode;
|
||||
// no append nor read/write mode
|
||||
if ((mode & std::ios::ate) || (mode & std::ios::app)
|
||||
|| ((mode & std::ios::in) && (mode & std::ios::out)))
|
||||
return (gzstreambuf*)0;
|
||||
char fmode[10];
|
||||
char* fmodeptr = fmode;
|
||||
if ( mode & std::ios::in)
|
||||
*fmodeptr++ = 'r';
|
||||
else if ( mode & std::ios::out)
|
||||
*fmodeptr++ = 'w';
|
||||
*fmodeptr++ = 'b';
|
||||
*fmodeptr = '\0';
|
||||
file = gzopen( name, fmode);
|
||||
if (file == 0)
|
||||
return (gzstreambuf*)0;
|
||||
opened = 1;
|
||||
return this;
|
||||
}
|
||||
|
||||
gzstreambuf * gzstreambuf::close() {
|
||||
if ( is_open()) {
|
||||
sync();
|
||||
opened = 0;
|
||||
if ( gzclose( file) == Z_OK)
|
||||
return this;
|
||||
}
|
||||
return (gzstreambuf*)0;
|
||||
}
|
||||
|
||||
int gzstreambuf::underflow() { // used for input buffer only
|
||||
if ( gptr() && ( gptr() < egptr()))
|
||||
return * reinterpret_cast<unsigned char *>( gptr());
|
||||
|
||||
if ( ! (mode & std::ios::in) || ! opened)
|
||||
return EOF;
|
||||
// Josuttis' implementation of inbuf
|
||||
int n_putback = gptr() - eback();
|
||||
if ( n_putback > 4)
|
||||
n_putback = 4;
|
||||
memcpy( buffer + (4 - n_putback), gptr() - n_putback, n_putback);
|
||||
|
||||
int num = gzread( file, buffer+4, bufferSize-4);
|
||||
if (num <= 0) // ERROR or EOF
|
||||
return EOF;
|
||||
|
||||
// reset buffer pointers
|
||||
setg( buffer + (4 - n_putback), // beginning of putback area
|
||||
buffer + 4, // read position
|
||||
buffer + 4 + num); // end of buffer
|
||||
|
||||
// return next character
|
||||
return *reinterpret_cast<unsigned char *>(gptr());
|
||||
}
|
||||
|
||||
int gzstreambuf::flush_buffer() {
|
||||
// Separate the writing of the buffer from overflow() and
|
||||
// sync() operation.
|
||||
int w = pptr() - pbase();
|
||||
if ( gzwrite( file, pbase(), w) != w)
|
||||
return EOF;
|
||||
pbump( -w);
|
||||
return w;
|
||||
}
|
||||
|
||||
int gzstreambuf::overflow( int c) { // used for output buffer only
|
||||
if ( ! ( mode & std::ios::out) || ! opened)
|
||||
return EOF;
|
||||
if (c != EOF) {
|
||||
*pptr() = c;
|
||||
pbump(1);
|
||||
}
|
||||
if ( flush_buffer() == EOF)
|
||||
return EOF;
|
||||
return c;
|
||||
}
|
||||
|
||||
int gzstreambuf::sync() {
|
||||
// Changed to use flush_buffer() instead of overflow( EOF)
|
||||
// which caused improper behavior with std::endl and flush(),
|
||||
// bug reported by Vincent Ricard.
|
||||
if ( pptr() && pptr() > pbase()) {
|
||||
if ( flush_buffer() == EOF)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --------------------------------------
|
||||
// class gzstreambase:
|
||||
// --------------------------------------
|
||||
|
||||
gzstreambase::gzstreambase( const char* name, int mode) {
|
||||
init( &buf);
|
||||
open( name, mode);
|
||||
}
|
||||
|
||||
gzstreambase::~gzstreambase() {
|
||||
buf.close();
|
||||
}
|
||||
|
||||
void gzstreambase::open( const char* name, int open_mode) {
|
||||
if ( ! buf.open( name, open_mode))
|
||||
clear( rdstate() | std::ios::badbit);
|
||||
}
|
||||
|
||||
void gzstreambase::close() {
|
||||
if ( buf.is_open())
|
||||
if ( ! buf.close())
|
||||
clear( rdstate() | std::ios::badbit);
|
||||
}
|
||||
|
||||
#ifdef GZSTREAM_NAMESPACE
|
||||
} // namespace GZSTREAM_NAMESPACE
|
||||
#endif
|
||||
|
||||
// ============================================================================
|
||||
// EOF //
|
122
ext/gzstream/gzstream.hh
Normal file
122
ext/gzstream/gzstream.hh
Normal file
|
@ -0,0 +1,122 @@
|
|||
// ============================================================================
|
||||
// gzstream, C++ iostream classes wrapping the zlib compression library.
|
||||
// Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
// ============================================================================
|
||||
//
|
||||
// File : gzstream.h
|
||||
// Revision : $Revision: 1.5 $
|
||||
// Revision_date : $Date: 2002/04/26 23:30:15 $
|
||||
// Author(s) : Deepak Bandyopadhyay, Lutz Kettner
|
||||
//
|
||||
// Standard streambuf implementation following Nicolai Josuttis, "The
|
||||
// Standard C++ Library".
|
||||
// ============================================================================
|
||||
|
||||
#ifndef GZSTREAM_H
|
||||
#define GZSTREAM_H 1
|
||||
|
||||
// standard C++ with new header file names and std:: namespace
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <zlib.h>
|
||||
|
||||
#ifdef GZSTREAM_NAMESPACE
|
||||
namespace GZSTREAM_NAMESPACE {
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Internal classes to implement gzstream. See below for user classes.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class gzstreambuf : public std::streambuf {
|
||||
private:
|
||||
static const int bufferSize = 47+256; // size of data buff
|
||||
// totals 512 bytes under g++ for igzstream at the end.
|
||||
|
||||
gzFile file; // file handle for compressed file
|
||||
char buffer[bufferSize]; // data buffer
|
||||
char opened; // open/close state of stream
|
||||
int mode; // I/O mode
|
||||
|
||||
int flush_buffer();
|
||||
public:
|
||||
gzstreambuf() : opened(0) {
|
||||
setp( buffer, buffer + (bufferSize-1));
|
||||
setg( buffer + 4, // beginning of putback area
|
||||
buffer + 4, // read position
|
||||
buffer + 4); // end position
|
||||
// ASSERT: both input & output capabilities will not be used together
|
||||
}
|
||||
int is_open() { return opened; }
|
||||
gzstreambuf* open( const char* name, int open_mode);
|
||||
gzstreambuf* close();
|
||||
~gzstreambuf() { close(); }
|
||||
|
||||
virtual int overflow( int c = EOF);
|
||||
virtual int underflow();
|
||||
virtual int sync();
|
||||
};
|
||||
|
||||
class gzstreambase : virtual public std::ios {
|
||||
protected:
|
||||
gzstreambuf buf;
|
||||
public:
|
||||
gzstreambase() { init(&buf); }
|
||||
gzstreambase( const char* name, int open_mode);
|
||||
~gzstreambase();
|
||||
int is_open() { return buf.is_open(); }
|
||||
void open( const char* name, int open_mode);
|
||||
void close();
|
||||
gzstreambuf* rdbuf() { return &buf; }
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// User classes. Use igzstream and ogzstream analogously to ifstream and
|
||||
// ofstream respectively. They read and write files based on the gz*
|
||||
// function interface of the zlib. Files are compatible with gzip compression.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class igzstream : public gzstreambase, public std::istream {
|
||||
public:
|
||||
igzstream() : std::istream( &buf) {}
|
||||
igzstream( const char* name, int open_mode = std::ios::in)
|
||||
: gzstreambase( name, open_mode | std::ios::in), std::istream( &buf) {}
|
||||
gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }
|
||||
void open( const char* name, int open_mode = std::ios::in) {
|
||||
gzstreambase::open( name, open_mode);
|
||||
}
|
||||
};
|
||||
|
||||
class ogzstream : public gzstreambase, public std::ostream {
|
||||
public:
|
||||
ogzstream() : std::ostream( &buf) {}
|
||||
ogzstream( const char* name, int mode = std::ios::out)
|
||||
: gzstreambase( name, mode | std::ios::out), std::ostream( &buf) {}
|
||||
gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }
|
||||
void open( const char* name, int open_mode = std::ios::out) {
|
||||
gzstreambase::open( name, open_mode);
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef GZSTREAM_NAMESPACE
|
||||
} // namespace GZSTREAM_NAMESPACE
|
||||
#endif
|
||||
|
||||
#endif // GZSTREAM_H
|
||||
// ============================================================================
|
||||
// EOF //
|
||||
|
|
@ -87,16 +87,13 @@ ElfFile('libelf_convert.c')
|
|||
ElfFile('libelf_fsize.c')
|
||||
ElfFile('libelf_msize.c')
|
||||
|
||||
m4env = Environment(ENV=os.environ)
|
||||
|
||||
if env.get('CC'):
|
||||
m4env['CC'] = env['CC']
|
||||
if env.get('CXX'):
|
||||
m4env['CXX'] = env['CXX']
|
||||
|
||||
if env.get('OSX64bit'):
|
||||
m4env.Append(CFLAGS='-arch x86_64')
|
||||
m4env.Append(LINKFLAGS='-arch x86_64')
|
||||
m4env = env.Clone()
|
||||
if env['GCC']:
|
||||
major,minor,dot = [ int(x) for x in env['CXXVERSION'].split('.')]
|
||||
if major >= 4:
|
||||
m4env.Append(CCFLAGS=['-Wno-pointer-sign'])
|
||||
m4env.Append(CCFLAGS=['-Wno-implicit'])
|
||||
del m4env['CPPPATH']
|
||||
|
||||
# If we have gm4 use it
|
||||
if m4env.Detect('gm4'):
|
||||
|
@ -117,7 +114,10 @@ m4env.M4(target=File('libelf_fsize.c'),
|
|||
source=[File('elf_types.m4'), File('libelf_fsize.m4')])
|
||||
m4env.M4(target=File('libelf_msize.c'),
|
||||
source=[File('elf_types.m4'), File('libelf_msize.m4')])
|
||||
m4env.Library('elf', elf_files)
|
||||
|
||||
# Build libelf as a static library with PIC code so it can be linked
|
||||
# into either m5 or the library
|
||||
m4env.Library('elf', [m4env.SharedObject(f) for f in elf_files])
|
||||
|
||||
env.Append(CPPPATH=Dir('.'))
|
||||
env.Append(LIBS=['elf'])
|
||||
|
|
805
src/SConscript
805
src/SConscript
File diff suppressed because it is too large
Load diff
|
@ -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' ])
|
||||
|
|
33
src/arch/alpha/AlphaInterrupts.py
Normal file
33
src/arch/alpha/AlphaInterrupts.py
Normal file
|
@ -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'
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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__*/
|
||||
|
|
|
@ -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()
|
||||
int
|
||||
MiscRegFile::getInstAsid()
|
||||
{
|
||||
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;
|
||||
return ITB_ASN_ASN(ipr[IPR_ITB_ASN]);
|
||||
}
|
||||
|
||||
int
|
||||
AlphaISA::MiscRegFile::getInstAsid()
|
||||
MiscRegFile::getDataAsid()
|
||||
{
|
||||
return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]);
|
||||
}
|
||||
|
||||
int
|
||||
AlphaISA::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 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 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_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.
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
void
|
||||
FloatRegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_ARRAY(q, NumFloatRegs);
|
||||
}
|
||||
std::memset(d, 0, sizeof(d));
|
||||
}
|
||||
|
||||
void
|
||||
FloatRegFile::serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_ARRAY(q, NumFloatRegs);
|
||||
}
|
||||
|
||||
void
|
||||
FloatRegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_ARRAY(q, NumFloatRegs);
|
||||
}
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
|
|
@ -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
|
||||
namespace AlphaISA {
|
||||
|
||||
class FloatRegFile
|
||||
{
|
||||
static inline std::string getFloatRegName(RegIndex)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
class FloatRegFile
|
||||
{
|
||||
public:
|
||||
|
||||
union {
|
||||
uint64_t q[NumFloatRegs]; // integer qword view
|
||||
double d[NumFloatRegs]; // double-precision floating point view
|
||||
};
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
void clear()
|
||||
{ std::memset(d, 0, sizeof(d)); }
|
||||
public:
|
||||
union {
|
||||
uint64_t q[NumFloatRegs]; // integer qword view
|
||||
double d[NumFloatRegs]; // double-precision floating point view
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
void clear();
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ARCH_ALPHA_FLOATREGFILE_HH__
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -57,7 +57,6 @@ class FreebsdAlphaSystem : public AlphaSystem
|
|||
~FreebsdAlphaSystem();
|
||||
|
||||
void doCalibrateClocks(ThreadContext *tc);
|
||||
|
||||
};
|
||||
|
||||
#endif // __ARCH_ALPHA_FREEBSD_SYSTEM_HH__
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
12
src/cpu/o3/sparc/thread_context.cc → src/arch/alpha/interrupts.cc
Executable file → Normal file
12
src/cpu/o3/sparc/thread_context.cc → src/arch/alpha/interrupts.cc
Executable file → Normal file
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2006 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,8 +28,10 @@
|
|||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#include "cpu/o3/thread_context.hh"
|
||||
#include "cpu/o3/thread_context_impl.hh"
|
||||
|
||||
template class O3ThreadContext<SparcSimpleImpl>;
|
||||
#include "arch/alpha/interrupts.hh"
|
||||
|
||||
AlphaISA::Interrupts *
|
||||
AlphaInterruptsParams::create()
|
||||
{
|
||||
return new AlphaISA::Interrupts(this);
|
||||
}
|
|
@ -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;
|
||||
return dynamic_cast<const Params *>(_params);
|
||||
}
|
||||
|
||||
public:
|
||||
Interrupts()
|
||||
{
|
||||
memset(interrupts, 0, sizeof(interrupts));
|
||||
intstatus = 0;
|
||||
newInfoSet = false;
|
||||
}
|
||||
Interrupts(Params * p) : SimObject(p), cpu(NULL)
|
||||
{
|
||||
memset(interrupts, 0, sizeof(interrupts));
|
||||
intstatus = 0;
|
||||
newInfoSet = false;
|
||||
}
|
||||
|
||||
void post(int int_num, int index)
|
||||
{
|
||||
DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
|
||||
void
|
||||
setCPU(BaseCPU * _cpu)
|
||||
{
|
||||
cpu = _cpu;
|
||||
}
|
||||
|
||||
if (int_num < 0 || int_num >= NumInterruptLevels)
|
||||
panic("int_num out of bounds\n");
|
||||
void
|
||||
post(int int_num, int index)
|
||||
{
|
||||
DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
|
||||
|
||||
if (index < 0 || index >= sizeof(uint64_t) * 8)
|
||||
panic("int_num out of bounds\n");
|
||||
if (int_num < 0 || int_num >= NumInterruptLevels)
|
||||
panic("int_num out of bounds\n");
|
||||
|
||||
interrupts[int_num] |= 1 << index;
|
||||
intstatus |= (ULL(1) << int_num);
|
||||
}
|
||||
if (index < 0 || index >= (int)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;
|
||||
intstatus |= (ULL(1) << int_num);
|
||||
}
|
||||
|
||||
if (int_num < 0 || int_num >= TheISA::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 >= sizeof(uint64_t) * 8)
|
||||
panic("int_num out of bounds\n");
|
||||
if (int_num < 0 || int_num >= NumInterruptLevels)
|
||||
panic("int_num out of bounds\n");
|
||||
|
||||
interrupts[int_num] &= ~(1 << index);
|
||||
if (interrupts[int_num] == 0)
|
||||
intstatus &= ~(ULL(1) << int_num);
|
||||
}
|
||||
if (index < 0 || index >= (int)sizeof(uint64_t) * 8)
|
||||
panic("int_num out of bounds\n");
|
||||
|
||||
void clear_all()
|
||||
{
|
||||
DPRINTF(Interrupt, "Interrupts all cleared\n");
|
||||
interrupts[int_num] &= ~(1 << index);
|
||||
if (interrupts[int_num] == 0)
|
||||
intstatus &= ~(ULL(1) << int_num);
|
||||
}
|
||||
|
||||
memset(interrupts, 0, sizeof(interrupts));
|
||||
intstatus = 0;
|
||||
}
|
||||
void
|
||||
clearAll()
|
||||
{
|
||||
DPRINTF(Interrupt, "Interrupts all cleared\n");
|
||||
|
||||
void serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_ARRAY(interrupts, NumInterruptLevels);
|
||||
SERIALIZE_SCALAR(intstatus);
|
||||
}
|
||||
memset(interrupts, 0, sizeof(interrupts));
|
||||
intstatus = 0;
|
||||
}
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels);
|
||||
UNSERIALIZE_SCALAR(intstatus);
|
||||
}
|
||||
void
|
||||
serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_ARRAY(interrupts, NumInterruptLevels);
|
||||
SERIALIZE_SCALAR(intstatus);
|
||||
}
|
||||
|
||||
bool check_interrupts(ThreadContext * tc) const
|
||||
{
|
||||
return (intstatus != 0) && !(tc->readPC() & 0x3);
|
||||
}
|
||||
void
|
||||
unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels);
|
||||
UNSERIALIZE_SCALAR(intstatus);
|
||||
}
|
||||
|
||||
Fault getInterrupt(ThreadContext * tc)
|
||||
{
|
||||
int ipl = 0;
|
||||
int summary = 0;
|
||||
bool
|
||||
checkInterrupts(ThreadContext *tc) const
|
||||
{
|
||||
return (intstatus != 0) && !(tc->readPC() & 0x3);
|
||||
}
|
||||
|
||||
if (tc->readMiscRegNoEffect(IPR_ASTRR))
|
||||
panic("asynchronous traps not implemented\n");
|
||||
Fault
|
||||
getInterrupt(ThreadContext *tc)
|
||||
{
|
||||
int ipl = 0;
|
||||
int summary = 0;
|
||||
|
||||
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 (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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
uint64_t interrupts = intstatus;
|
||||
if (interrupts) {
|
||||
for (int i = INTLEVEL_EXTERNAL_MIN;
|
||||
i < INTLEVEL_EXTERNAL_MAX; i++) {
|
||||
if (interrupts & (ULL(1) << i)) {
|
||||
// See table 4-19 of 21164 hardware reference
|
||||
ipl = i;
|
||||
summary |= (ULL(1) << i);
|
||||
}
|
||||
}
|
||||
|
||||
if (ipl && ipl > tc->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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return new InterruptFault;
|
||||
} else {
|
||||
return NoFault;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t get_vec(int int_num)
|
||||
{
|
||||
panic("Shouldn't be called for Alpha\n");
|
||||
M5_DUMMY_RETURN
|
||||
}
|
||||
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__
|
||||
|
||||
|
|
|
@ -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::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_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 §ion)
|
||||
{
|
||||
UNSERIALIZE_ARRAY(regs, NumIntRegs);
|
||||
}
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
|
|
|
@ -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];
|
||||
regs[intReg] = val;
|
||||
}
|
||||
|
||||
public:
|
||||
void clear();
|
||||
|
||||
IntReg readReg(int intReg)
|
||||
{
|
||||
return regs[intReg];
|
||||
}
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
void setReg(int intReg, const IntReg &val)
|
||||
{
|
||||
regs[intReg] = val;
|
||||
}
|
||||
} // namespace AlphaISA
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
void clear()
|
||||
{ std::memset(regs, 0, sizeof(regs)); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // __ARCH_ALPHA_INTREGFILE_HH__
|
||||
|
|
|
@ -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
|
||||
static bool initialized = false;
|
||||
if (initialized)
|
||||
return;
|
||||
|
||||
//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
|
||||
memset(IprToMiscRegIndex, -1, MaxInternalProcRegs * sizeof(int));
|
||||
|
||||
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;
|
||||
}
|
||||
for (int x = 0; x < NumInternalProcRegs; x++)
|
||||
IprToMiscRegIndex[MiscRegIndexToIpr[x]] = x;
|
||||
}
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
|
|
|
@ -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
|
||||
//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,
|
||||
|
||||
// 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
|
||||
//Read only
|
||||
MinReadOnlyIpr,
|
||||
IPR_INTID = MinReadOnlyIpr,
|
||||
IPR_SL_RCV,
|
||||
IPR_MM_STAT,
|
||||
IPR_ITB_PTE_TEMP,
|
||||
MaxReadOnlyIpr,
|
||||
IPR_DTB_PTE_TEMP = MaxReadOnlyIpr,
|
||||
|
||||
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
|
||||
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,
|
||||
|
||||
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
|
||||
// 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,
|
||||
|
||||
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
|
||||
IPR_DTB_ASN,
|
||||
IPR_DTB_CM,
|
||||
IPR_DTB_TAG,
|
||||
IPR_DTB_PTE,
|
||||
|
||||
MaxInternalProcRegs // number of IPR registers
|
||||
};
|
||||
IPR_VA,
|
||||
IPR_VA_FORM,
|
||||
IPR_MVPTBR,
|
||||
IPR_DTB_IS,
|
||||
IPR_CC,
|
||||
IPR_CC_CTL,
|
||||
IPR_MCSR,
|
||||
|
||||
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,
|
||||
IPR_DC_PERR_STAT,
|
||||
IPR_DC_TEST_CTL,
|
||||
IPR_DC_TEST_TAG,
|
||||
IPR_DC_TEST_TAG_TEMP,
|
||||
IPR_DC_MODE,
|
||||
IPR_MAF_MODE,
|
||||
|
||||
//Read only
|
||||
MinReadOnlyIpr,
|
||||
IPR_INTID = MinReadOnlyIpr,
|
||||
IPR_SL_RCV,
|
||||
IPR_MM_STAT,
|
||||
IPR_ITB_PTE_TEMP,
|
||||
MaxReadOnlyIpr,
|
||||
IPR_DTB_PTE_TEMP = MaxReadOnlyIpr,
|
||||
NumInternalProcRegs // number of IPR registers
|
||||
};
|
||||
|
||||
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();
|
||||
inline bool
|
||||
IprIsWritable(int index)
|
||||
{
|
||||
return index < MinReadOnlyIpr || index > MaxReadOnlyIpr;
|
||||
}
|
||||
|
||||
#endif
|
||||
inline bool
|
||||
IprIsReadable(int index)
|
||||
{
|
||||
return index < MinWriteOnlyIpr || index > MaxWriteOnlyIpr;
|
||||
}
|
||||
|
||||
extern md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs];
|
||||
extern int IprToMiscRegIndex[MaxInternalProcRegs];
|
||||
|
||||
void initializeIprTable();
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ARCH_ALPHA_IPR_HH__
|
||||
|
|
|
@ -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);
|
||||
0x56: m5anWait({{
|
||||
PseudoInst::anWait(xc->tcBase(), R16, R17);
|
||||
0x57: m5reserved3({{
|
||||
warn("M5 reserved opcode ignored");
|
||||
}}, IsNonSpeculative);
|
||||
0x58: m5reserved4({{
|
||||
warn("M5 reserved opcode ignored");
|
||||
}}, IsNonSpeculative);
|
||||
0x59: m5reserved5({{
|
||||
warn("M5 reserved opcode ignored");
|
||||
}}, IsNonSpeculative);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -42,142 +42,134 @@ namespace LittleEndianGuest {}
|
|||
|
||||
class StaticInstPtr;
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
using namespace LittleEndianGuest;
|
||||
using AlphaISAInst::MaxInstSrcRegs;
|
||||
using AlphaISAInst::MaxInstDestRegs;
|
||||
namespace AlphaISA {
|
||||
|
||||
// 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;
|
||||
|
||||
const int ArgumentReg[] = {16, 17, 18, 19, 20, 21};
|
||||
const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int);
|
||||
|
||||
const int SyscallNumReg = ReturnValueReg;
|
||||
const int SyscallPseudoReturnReg = ArgumentReg[4];
|
||||
const int SyscallSuccessReg = 19;
|
||||
|
||||
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;
|
||||
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
|
||||
{
|
||||
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
|
||||
};
|
||||
|
||||
// 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__
|
||||
|
|
|
@ -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 §ion)
|
|||
themode = (cpu_mode)exemode;
|
||||
}
|
||||
|
||||
} /* end namespace AlphaISA::Kernel */
|
||||
} /* end namespace AlphaISA */
|
||||
} // namespace Kernel
|
||||
} // namespace AlphaISA
|
||||
|
|
|
@ -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 §ion);
|
||||
};
|
||||
|
||||
} /* end namespace AlphaISA::Kernel */
|
||||
} /* end namespace AlphaISA */
|
||||
} // namespace Kernel
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ARCH_ALPHA_KERNEL_STATS_HH__
|
||||
|
|
|
@ -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]));
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -51,4 +51,5 @@ class AlphaLinuxProcess : public AlphaLiveProcess
|
|||
};
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ALPHA_LINUX_PROCESS_HH__
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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__
|
||||
|
|
41
src/arch/alpha/microcode_rom.hh
Normal file
41
src/arch/alpha/microcode_rom.hh
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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_ALPHA_MICROCODE_ROM_HH__
|
||||
#define __ARCH_ALPHA_MICROCODE_ROM_HH__
|
||||
|
||||
#include "sim/microcode_rom.hh"
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
using ::MicrocodeRom;
|
||||
}
|
||||
|
||||
#endif // __ARCH_ALPHA_MICROCODE_ROM_HH__
|
|
@ -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)
|
||||
{
|
||||
|
||||
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 §ion)
|
||||
{
|
||||
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::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::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;
|
||||
}
|
||||
}
|
||||
|
||||
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 §ion)
|
||||
{
|
||||
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::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::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
|
||||
|
|
|
@ -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
|
||||
};
|
||||
namespace AlphaISA {
|
||||
|
||||
static inline std::string getMiscRegName(RegIndex)
|
||||
enum MiscRegIndex
|
||||
{
|
||||
MISCREG_FPCR = NumInternalProcRegs,
|
||||
MISCREG_UNIQ,
|
||||
MISCREG_LOCKFLAG,
|
||||
MISCREG_LOCKADDR,
|
||||
MISCREG_INTR
|
||||
};
|
||||
|
||||
class MiscRegFile
|
||||
{
|
||||
public:
|
||||
friend class RegFile;
|
||||
typedef uint64_t InternalProcReg;
|
||||
|
||||
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;
|
||||
|
||||
InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
|
||||
|
||||
protected:
|
||||
InternalProcReg readIpr(int idx, ThreadContext *tc);
|
||||
void setIpr(int idx, InternalProcReg val, ThreadContext *tc);
|
||||
|
||||
public:
|
||||
MiscRegFile()
|
||||
{
|
||||
return "";
|
||||
initializeIprTable();
|
||||
}
|
||||
|
||||
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;
|
||||
// These functions should be removed once the simplescalar cpu
|
||||
// model has been replaced.
|
||||
int getInstAsid();
|
||||
int getDataAsid();
|
||||
|
||||
public:
|
||||
MiscRegFile()
|
||||
{
|
||||
initializeIprTable();
|
||||
}
|
||||
MiscReg readRegNoEffect(int misc_reg);
|
||||
MiscReg readReg(int misc_reg, ThreadContext *tc);
|
||||
|
||||
MiscReg readRegNoEffect(int misc_reg);
|
||||
void setRegNoEffect(int misc_reg, const MiscReg &val);
|
||||
void setReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
|
||||
|
||||
MiscReg readReg(int misc_reg, ThreadContext *tc);
|
||||
void
|
||||
clear()
|
||||
{
|
||||
fpcr = 0;
|
||||
uniq = 0;
|
||||
lock_flag = 0;
|
||||
lock_addr = 0;
|
||||
intr_flag = 0;
|
||||
}
|
||||
|
||||
//These functions should be removed once the simplescalar cpu model
|
||||
//has been replaced.
|
||||
int getInstAsid();
|
||||
int getDataAsid();
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
void setRegNoEffect(int misc_reg, const MiscReg &val);
|
||||
void copyIprs(ThreadContext *src, ThreadContext *dest);
|
||||
|
||||
void setReg(int misc_reg, const MiscReg &val,
|
||||
ThreadContext *tc);
|
||||
} // namespace AlphaISA
|
||||
|
||||
void clear()
|
||||
{
|
||||
fpcr = uniq = 0;
|
||||
lock_flag = 0;
|
||||
lock_addr = 0;
|
||||
intr_flag = 0;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
protected:
|
||||
typedef uint64_t InternalProcReg;
|
||||
|
||||
InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
|
||||
|
||||
private:
|
||||
InternalProcReg readIpr(int idx, ThreadContext *tc);
|
||||
|
||||
void setIpr(int idx, InternalProcReg val, ThreadContext *tc);
|
||||
friend class RegFile;
|
||||
};
|
||||
|
||||
void copyIprs(ThreadContext *src, ThreadContext *dest);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // __ARCH_ALPHA_MISCREGFILE_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__
|
||||
|
|
|
@ -30,275 +30,273 @@
|
|||
|
||||
#include "arch/alpha/osfpal.hh"
|
||||
|
||||
namespace {
|
||||
const char *strings[PAL::NumCodes] = {
|
||||
// Priviledged PAL instructions
|
||||
"halt", // 0x00
|
||||
"cflush", // 0x01
|
||||
"draina", // 0x02
|
||||
0, // 0x03
|
||||
0, // 0x04
|
||||
0, // 0x05
|
||||
0, // 0x06
|
||||
0, // 0x07
|
||||
0, // 0x08
|
||||
"cserve", // 0x09
|
||||
"swppal", // 0x0a
|
||||
0, // 0x0b
|
||||
0, // 0x0c
|
||||
"wripir", // 0x0d
|
||||
0, // 0x0e
|
||||
0, // 0x0f
|
||||
"rdmces", // 0x10
|
||||
"wrmces", // 0x11
|
||||
0, // 0x12
|
||||
0, // 0x13
|
||||
0, // 0x14
|
||||
0, // 0x15
|
||||
0, // 0x16
|
||||
0, // 0x17
|
||||
0, // 0x18
|
||||
0, // 0x19
|
||||
0, // 0x1a
|
||||
0, // 0x1b
|
||||
0, // 0x1c
|
||||
0, // 0x1d
|
||||
0, // 0x1e
|
||||
0, // 0x1f
|
||||
0, // 0x20
|
||||
0, // 0x21
|
||||
0, // 0x22
|
||||
0, // 0x23
|
||||
0, // 0x24
|
||||
0, // 0x25
|
||||
0, // 0x26
|
||||
0, // 0x27
|
||||
0, // 0x28
|
||||
0, // 0x29
|
||||
0, // 0x2a
|
||||
"wrfen", // 0x2b
|
||||
0, // 0x2c
|
||||
"wrvptptr", // 0x2d
|
||||
0, // 0x2e
|
||||
0, // 0x2f
|
||||
"swpctx", // 0x30
|
||||
"wrval", // 0x31
|
||||
"rdval", // 0x32
|
||||
"tbi", // 0x33
|
||||
"wrent", // 0x34
|
||||
"swpipl", // 0x35
|
||||
"rdps", // 0x36
|
||||
"wrkgp", // 0x37
|
||||
"wrusp", // 0x38
|
||||
"wrperfmon", // 0x39
|
||||
"rdusp", // 0x3a
|
||||
0, // 0x3b
|
||||
"whami", // 0x3c
|
||||
"retsys", // 0x3d
|
||||
"wtint", // 0x3e
|
||||
"rti", // 0x3f
|
||||
0, // 0x40
|
||||
0, // 0x41
|
||||
0, // 0x42
|
||||
0, // 0x43
|
||||
0, // 0x44
|
||||
0, // 0x45
|
||||
0, // 0x46
|
||||
0, // 0x47
|
||||
0, // 0x48
|
||||
0, // 0x49
|
||||
0, // 0x4a
|
||||
0, // 0x4b
|
||||
0, // 0x4c
|
||||
0, // 0x4d
|
||||
0, // 0x4e
|
||||
0, // 0x4f
|
||||
0, // 0x50
|
||||
0, // 0x51
|
||||
0, // 0x52
|
||||
0, // 0x53
|
||||
0, // 0x54
|
||||
0, // 0x55
|
||||
0, // 0x56
|
||||
0, // 0x57
|
||||
0, // 0x58
|
||||
0, // 0x59
|
||||
0, // 0x5a
|
||||
0, // 0x5b
|
||||
0, // 0x5c
|
||||
0, // 0x5d
|
||||
0, // 0x5e
|
||||
0, // 0x5f
|
||||
0, // 0x60
|
||||
0, // 0x61
|
||||
0, // 0x62
|
||||
0, // 0x63
|
||||
0, // 0x64
|
||||
0, // 0x65
|
||||
0, // 0x66
|
||||
0, // 0x67
|
||||
0, // 0x68
|
||||
0, // 0x69
|
||||
0, // 0x6a
|
||||
0, // 0x6b
|
||||
0, // 0x6c
|
||||
0, // 0x6d
|
||||
0, // 0x6e
|
||||
0, // 0x6f
|
||||
0, // 0x70
|
||||
0, // 0x71
|
||||
0, // 0x72
|
||||
0, // 0x73
|
||||
0, // 0x74
|
||||
0, // 0x75
|
||||
0, // 0x76
|
||||
0, // 0x77
|
||||
0, // 0x78
|
||||
0, // 0x79
|
||||
0, // 0x7a
|
||||
0, // 0x7b
|
||||
0, // 0x7c
|
||||
0, // 0x7d
|
||||
0, // 0x7e
|
||||
0, // 0x7f
|
||||
|
||||
// Unpriviledged PAL instructions
|
||||
"bpt", // 0x80
|
||||
"bugchk", // 0x81
|
||||
0, // 0x82
|
||||
"callsys", // 0x83
|
||||
0, // 0x84
|
||||
0, // 0x85
|
||||
"imb", // 0x86
|
||||
0, // 0x87
|
||||
0, // 0x88
|
||||
0, // 0x89
|
||||
0, // 0x8a
|
||||
0, // 0x8b
|
||||
0, // 0x8c
|
||||
0, // 0x8d
|
||||
0, // 0x8e
|
||||
0, // 0x8f
|
||||
0, // 0x90
|
||||
0, // 0x91
|
||||
"urti", // 0x92
|
||||
0, // 0x93
|
||||
0, // 0x94
|
||||
0, // 0x95
|
||||
0, // 0x96
|
||||
0, // 0x97
|
||||
0, // 0x98
|
||||
0, // 0x99
|
||||
0, // 0x9a
|
||||
0, // 0x9b
|
||||
0, // 0x9c
|
||||
0, // 0x9d
|
||||
"rdunique", // 0x9e
|
||||
"wrunique", // 0x9f
|
||||
0, // 0xa0
|
||||
0, // 0xa1
|
||||
0, // 0xa2
|
||||
0, // 0xa3
|
||||
0, // 0xa4
|
||||
0, // 0xa5
|
||||
0, // 0xa6
|
||||
0, // 0xa7
|
||||
0, // 0xa8
|
||||
0, // 0xa9
|
||||
"gentrap", // 0xaa
|
||||
0, // 0xab
|
||||
0, // 0xac
|
||||
0, // 0xad
|
||||
"clrfen", // 0xae
|
||||
0, // 0xaf
|
||||
0, // 0xb0
|
||||
0, // 0xb1
|
||||
0, // 0xb2
|
||||
0, // 0xb3
|
||||
0, // 0xb4
|
||||
0, // 0xb5
|
||||
0, // 0xb6
|
||||
0, // 0xb7
|
||||
0, // 0xb8
|
||||
0, // 0xb9
|
||||
0, // 0xba
|
||||
0, // 0xbb
|
||||
0, // 0xbc
|
||||
0, // 0xbd
|
||||
"nphalt", // 0xbe
|
||||
"copypal", // 0xbf
|
||||
#if 0
|
||||
0, // 0xc0
|
||||
0, // 0xc1
|
||||
0, // 0xc2
|
||||
0, // 0xc3
|
||||
0, // 0xc4
|
||||
0, // 0xc5
|
||||
0, // 0xc6
|
||||
0, // 0xc7
|
||||
0, // 0xc8
|
||||
0, // 0xc9
|
||||
0, // 0xca
|
||||
0, // 0xcb
|
||||
0, // 0xcc
|
||||
0, // 0xcd
|
||||
0, // 0xce
|
||||
0, // 0xcf
|
||||
0, // 0xd0
|
||||
0, // 0xd1
|
||||
0, // 0xd2
|
||||
0, // 0xd3
|
||||
0, // 0xd4
|
||||
0, // 0xd5
|
||||
0, // 0xd6
|
||||
0, // 0xd7
|
||||
0, // 0xd8
|
||||
0, // 0xd9
|
||||
0, // 0xda
|
||||
0, // 0xdb
|
||||
0, // 0xdc
|
||||
0, // 0xdd
|
||||
0, // 0xde
|
||||
0, // 0xdf
|
||||
0, // 0xe0
|
||||
0, // 0xe1
|
||||
0, // 0xe2
|
||||
0, // 0xe3
|
||||
0, // 0xe4
|
||||
0, // 0xe5
|
||||
0, // 0xe6
|
||||
0, // 0xe7
|
||||
0, // 0xe8
|
||||
0, // 0xe9
|
||||
0, // 0xea
|
||||
0, // 0xeb
|
||||
0, // 0xec
|
||||
0, // 0xed
|
||||
0, // 0xee
|
||||
0, // 0xef
|
||||
0, // 0xf0
|
||||
0, // 0xf1
|
||||
0, // 0xf2
|
||||
0, // 0xf3
|
||||
0, // 0xf4
|
||||
0, // 0xf5
|
||||
0, // 0xf6
|
||||
0, // 0xf7
|
||||
0, // 0xf8
|
||||
0, // 0xf9
|
||||
0, // 0xfa
|
||||
0, // 0xfb
|
||||
0, // 0xfc
|
||||
0, // 0xfd
|
||||
0, // 0xfe
|
||||
0 // 0xff
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
const char *
|
||||
PAL::name(int index)
|
||||
{
|
||||
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
|
||||
|
||||
// Unpriviledged PAL instructions
|
||||
"bpt", // 0x80
|
||||
"bugchk", // 0x81
|
||||
0, // 0x82
|
||||
"callsys", // 0x83
|
||||
0, // 0x84
|
||||
0, // 0x85
|
||||
"imb", // 0x86
|
||||
0, // 0x87
|
||||
0, // 0x88
|
||||
0, // 0x89
|
||||
0, // 0x8a
|
||||
0, // 0x8b
|
||||
0, // 0x8c
|
||||
0, // 0x8d
|
||||
0, // 0x8e
|
||||
0, // 0x8f
|
||||
0, // 0x90
|
||||
0, // 0x91
|
||||
"urti", // 0x92
|
||||
0, // 0x93
|
||||
0, // 0x94
|
||||
0, // 0x95
|
||||
0, // 0x96
|
||||
0, // 0x97
|
||||
0, // 0x98
|
||||
0, // 0x99
|
||||
0, // 0x9a
|
||||
0, // 0x9b
|
||||
0, // 0x9c
|
||||
0, // 0x9d
|
||||
"rdunique", // 0x9e
|
||||
"wrunique", // 0x9f
|
||||
0, // 0xa0
|
||||
0, // 0xa1
|
||||
0, // 0xa2
|
||||
0, // 0xa3
|
||||
0, // 0xa4
|
||||
0, // 0xa5
|
||||
0, // 0xa6
|
||||
0, // 0xa7
|
||||
0, // 0xa8
|
||||
0, // 0xa9
|
||||
"gentrap", // 0xaa
|
||||
0, // 0xab
|
||||
0, // 0xac
|
||||
0, // 0xad
|
||||
"clrfen", // 0xae
|
||||
0, // 0xaf
|
||||
0, // 0xb0
|
||||
0, // 0xb1
|
||||
0, // 0xb2
|
||||
0, // 0xb3
|
||||
0, // 0xb4
|
||||
0, // 0xb5
|
||||
0, // 0xb6
|
||||
0, // 0xb7
|
||||
0, // 0xb8
|
||||
0, // 0xb9
|
||||
0, // 0xba
|
||||
0, // 0xbb
|
||||
0, // 0xbc
|
||||
0, // 0xbd
|
||||
"nphalt", // 0xbe
|
||||
"copypal", // 0xbf
|
||||
#if 0
|
||||
0, // 0xc0
|
||||
0, // 0xc1
|
||||
0, // 0xc2
|
||||
0, // 0xc3
|
||||
0, // 0xc4
|
||||
0, // 0xc5
|
||||
0, // 0xc6
|
||||
0, // 0xc7
|
||||
0, // 0xc8
|
||||
0, // 0xc9
|
||||
0, // 0xca
|
||||
0, // 0xcb
|
||||
0, // 0xcc
|
||||
0, // 0xcd
|
||||
0, // 0xce
|
||||
0, // 0xcf
|
||||
0, // 0xd0
|
||||
0, // 0xd1
|
||||
0, // 0xd2
|
||||
0, // 0xd3
|
||||
0, // 0xd4
|
||||
0, // 0xd5
|
||||
0, // 0xd6
|
||||
0, // 0xd7
|
||||
0, // 0xd8
|
||||
0, // 0xd9
|
||||
0, // 0xda
|
||||
0, // 0xdb
|
||||
0, // 0xdc
|
||||
0, // 0xdd
|
||||
0, // 0xde
|
||||
0, // 0xdf
|
||||
0, // 0xe0
|
||||
0, // 0xe1
|
||||
0, // 0xe2
|
||||
0, // 0xe3
|
||||
0, // 0xe4
|
||||
0, // 0xe5
|
||||
0, // 0xe6
|
||||
0, // 0xe7
|
||||
0, // 0xe8
|
||||
0, // 0xe9
|
||||
0, // 0xea
|
||||
0, // 0xeb
|
||||
0, // 0xec
|
||||
0, // 0xed
|
||||
0, // 0xee
|
||||
0, // 0xef
|
||||
0, // 0xf0
|
||||
0, // 0xf1
|
||||
0, // 0xf2
|
||||
0, // 0xf3
|
||||
0, // 0xf4
|
||||
0, // 0xf5
|
||||
0, // 0xf6
|
||||
0, // 0xf7
|
||||
0, // 0xf8
|
||||
0, // 0xf9
|
||||
0, // 0xfa
|
||||
0, // 0xfb
|
||||
0, // 0xfc
|
||||
0, // 0xfd
|
||||
0, // 0xfe
|
||||
0 // 0xff
|
||||
#endif
|
||||
};
|
||||
|
||||
if (index > NumCodes || index < 0)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -31,33 +31,34 @@
|
|||
#include "arch/alpha/pagetable.hh"
|
||||
#include "sim/serialize.hh"
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
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);
|
||||
}
|
||||
namespace AlphaISA {
|
||||
|
||||
void
|
||||
TlbEntry::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_SCALAR(tag);
|
||||
UNSERIALIZE_SCALAR(ppn);
|
||||
UNSERIALIZE_SCALAR(xre);
|
||||
UNSERIALIZE_SCALAR(xwe);
|
||||
UNSERIALIZE_SCALAR(asn);
|
||||
UNSERIALIZE_SCALAR(asma);
|
||||
UNSERIALIZE_SCALAR(fonr);
|
||||
UNSERIALIZE_SCALAR(fonw);
|
||||
UNSERIALIZE_SCALAR(valid);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
TlbEntry::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_SCALAR(tag);
|
||||
UNSERIALIZE_SCALAR(ppn);
|
||||
UNSERIALIZE_SCALAR(xre);
|
||||
UNSERIALIZE_SCALAR(xwe);
|
||||
UNSERIALIZE_SCALAR(asn);
|
||||
UNSERIALIZE_SCALAR(asma);
|
||||
UNSERIALIZE_SCALAR(fonr);
|
||||
UNSERIALIZE_SCALAR(fonw);
|
||||
UNSERIALIZE_SCALAR(valid);
|
||||
}
|
||||
|
||||
} //namespace AlphaISA
|
||||
|
|
|
@ -38,97 +38,109 @@
|
|||
|
||||
namespace AlphaISA {
|
||||
|
||||
struct VAddr
|
||||
{
|
||||
static const int ImplBits = 43;
|
||||
static const Addr ImplMask = (ULL(1) << ImplBits) - 1;
|
||||
static const Addr UnImplMask = ~ImplMask;
|
||||
struct VAddr
|
||||
{
|
||||
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 addr;
|
||||
|
||||
Addr vpn() const { return (addr & ImplMask) >> PageShift; }
|
||||
Addr page() const { return addr & PageMask; }
|
||||
Addr offset() const { return addr & PageOffset; }
|
||||
VAddr(Addr a) : addr(a) {}
|
||||
operator Addr() const { return addr; }
|
||||
const VAddr &operator=(Addr a) { addr = a; return *this; }
|
||||
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
//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 §ion);
|
||||
};
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
VAddr vaddr(new_vaddr);
|
||||
tag = vaddr.vpn();
|
||||
}
|
||||
|
||||
Addr
|
||||
pageStart()
|
||||
{
|
||||
return ppn << PageShift;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ARCH_ALPHA_PAGETABLE_H__
|
||||
|
||||
|
|
|
@ -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;
|
||||
return tc;
|
||||
}
|
||||
|
||||
public:
|
||||
Predecoder(ThreadContext * _tc) : tc(_tc)
|
||||
{}
|
||||
void
|
||||
setTC(ThreadContext * _tc)
|
||||
{
|
||||
tc = _tc;
|
||||
}
|
||||
|
||||
ThreadContext * getTC()
|
||||
{
|
||||
return tc;
|
||||
}
|
||||
void
|
||||
process()
|
||||
{ }
|
||||
|
||||
void setTC(ThreadContext * _tc)
|
||||
{
|
||||
tc = _tc;
|
||||
}
|
||||
void
|
||||
reset()
|
||||
{ }
|
||||
|
||||
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;
|
||||
// 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
|
||||
needMoreBytes()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool extMachInstReady()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool
|
||||
extMachInstReady()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//This returns a constant reference to the ExtMachInst to avoid a copy
|
||||
const ExtMachInst & getExtMachInst()
|
||||
{
|
||||
return ext_inst;
|
||||
}
|
||||
};
|
||||
// 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__
|
||||
|
|
|
@ -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();
|
||||
|
@ -58,6 +62,117 @@ AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams * params,
|
|||
// Set pointer for next thread stack. Reserve 8M for main stack.
|
||||
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -66,15 +181,49 @@ 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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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 §ion)
|
||||
{
|
||||
intRegFile.unserialize(cp, section);
|
||||
floatRegFile.unserialize(cp, section);
|
||||
miscRegFile.unserialize(cp, section);
|
||||
UNSERIALIZE_SCALAR(pc);
|
||||
UNSERIALIZE_SCALAR(npc);
|
||||
#if FULL_SYSTEM
|
||||
UNSERIALIZE_SCALAR(intrflag);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
copyRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
// First loop through the integer registers.
|
||||
for (int i = 0; i < NumIntRegs; ++i) {
|
||||
dest->setIntReg(i, src->readIntReg(i));
|
||||
}
|
||||
|
||||
// Then loop through the floating point registers.
|
||||
for (int i = 0; i < TheISA::NumFloatRegs; ++i) {
|
||||
dest->setFloatRegBits(i, src->readFloatRegBits(i));
|
||||
}
|
||||
|
||||
// Copy misc. registers
|
||||
copyMiscRegs(src, dest);
|
||||
|
||||
// Lastly copy PC/NPC
|
||||
dest->setPC(src->readPC());
|
||||
dest->setNextPC(src->readNextPC());
|
||||
}
|
||||
|
||||
void
|
||||
copyMiscRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
dest->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));
|
||||
|
||||
copyIprs(src, dest);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RegFile::unserialize(EventManager *em, Checkpoint *cp, const string §ion)
|
||||
{
|
||||
intRegFile.unserialize(cp, section);
|
||||
floatRegFile.unserialize(cp, section);
|
||||
miscRegFile.unserialize(cp, section);
|
||||
UNSERIALIZE_SCALAR(pc);
|
||||
UNSERIALIZE_SCALAR(npc);
|
||||
#if FULL_SYSTEM
|
||||
UNSERIALIZE_SCALAR(intrflag);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
copyRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
// First loop through the integer registers.
|
||||
for (int i = 0; i < NumIntRegs; ++i)
|
||||
dest->setIntReg(i, src->readIntReg(i));
|
||||
|
||||
// Then loop through the floating point registers.
|
||||
for (int i = 0; i < NumFloatRegs; ++i)
|
||||
dest->setFloatRegBits(i, src->readFloatRegBits(i));
|
||||
|
||||
// Copy misc. registers
|
||||
copyMiscRegs(src, dest);
|
||||
|
||||
// Lastly copy PC/NPC
|
||||
dest->setPC(src->readPC());
|
||||
dest->setNextPC(src->readNextPC());
|
||||
}
|
||||
|
||||
void
|
||||
copyMiscRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
dest->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);
|
||||
}
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
|
|
@ -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
|
||||
{
|
||||
namespace AlphaISA {
|
||||
|
||||
class RegFile {
|
||||
class RegFile {
|
||||
protected:
|
||||
Addr pc; // program counter
|
||||
Addr npc; // next-cycle program counter
|
||||
Addr nnpc; // next next-cycle program counter
|
||||
|
||||
protected:
|
||||
Addr pc; // program counter
|
||||
Addr npc; // next-cycle program counter
|
||||
Addr nnpc;
|
||||
public:
|
||||
Addr
|
||||
readPC()
|
||||
{
|
||||
return pc;
|
||||
}
|
||||
|
||||
public:
|
||||
Addr readPC()
|
||||
{
|
||||
return pc;
|
||||
}
|
||||
void
|
||||
setPC(Addr val)
|
||||
{
|
||||
pc = val;
|
||||
}
|
||||
|
||||
void setPC(Addr val)
|
||||
{
|
||||
pc = val;
|
||||
}
|
||||
Addr
|
||||
readNextPC()
|
||||
{
|
||||
return npc;
|
||||
}
|
||||
|
||||
Addr readNextPC()
|
||||
{
|
||||
return npc;
|
||||
}
|
||||
void
|
||||
setNextPC(Addr val)
|
||||
{
|
||||
npc = val;
|
||||
}
|
||||
|
||||
void setNextPC(Addr val)
|
||||
{
|
||||
npc = val;
|
||||
}
|
||||
Addr
|
||||
readNextNPC()
|
||||
{
|
||||
return npc + sizeof(MachInst);
|
||||
}
|
||||
|
||||
Addr readNextNPC()
|
||||
{
|
||||
return npc + sizeof(MachInst);
|
||||
}
|
||||
void
|
||||
setNextNPC(Addr val)
|
||||
{ }
|
||||
|
||||
void setNextNPC(Addr val)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
IntRegFile intRegFile; // (signed) integer register file
|
||||
FloatRegFile floatRegFile; // floating point register file
|
||||
MiscRegFile miscRegFile; // control register file
|
||||
|
||||
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(); }
|
||||
int intrflag; // interrupt flag
|
||||
|
||||
int
|
||||
instAsid()
|
||||
{
|
||||
return miscRegFile.getInstAsid();
|
||||
}
|
||||
|
||||
int
|
||||
dataAsid()
|
||||
{
|
||||
return miscRegFile.getDataAsid();
|
||||
}
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void setMiscRegNoEffect(int miscReg, const MiscReg &val)
|
||||
{
|
||||
miscRegFile.setRegNoEffect(miscReg, val);
|
||||
}
|
||||
|
||||
void setMiscReg(int miscReg, const MiscReg &val,
|
||||
ThreadContext * tc)
|
||||
{
|
||||
miscRegFile.setReg(miscReg, val, tc);
|
||||
}
|
||||
|
||||
FloatReg readFloatReg(int floatReg)
|
||||
{
|
||||
return floatRegFile.d[floatReg];
|
||||
}
|
||||
|
||||
FloatReg readFloatReg(int floatReg, int width)
|
||||
{
|
||||
return readFloatReg(floatReg);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegBits(int floatReg)
|
||||
{
|
||||
return floatRegFile.q[floatReg];
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegBits(int floatReg, int width)
|
||||
{
|
||||
return readFloatRegBits(floatReg);
|
||||
}
|
||||
|
||||
void setFloatReg(int floatReg, const FloatReg &val)
|
||||
{
|
||||
floatRegFile.d[floatReg] = val;
|
||||
}
|
||||
|
||||
void setFloatReg(int floatReg, const FloatReg &val, int width)
|
||||
{
|
||||
setFloatReg(floatReg, val);
|
||||
}
|
||||
|
||||
void setFloatRegBits(int floatReg, const FloatRegBits &val)
|
||||
{
|
||||
floatRegFile.q[floatReg] = val;
|
||||
}
|
||||
|
||||
void setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
|
||||
{
|
||||
setFloatRegBits(floatReg, val);
|
||||
}
|
||||
|
||||
IntReg readIntReg(int intReg)
|
||||
{
|
||||
return intRegFile.readReg(intReg);
|
||||
}
|
||||
|
||||
void setIntReg(int intReg, const IntReg &val)
|
||||
{
|
||||
intRegFile.setReg(intReg, val);
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
void changeContext(RegContextParam param, RegContextVal val)
|
||||
{
|
||||
//This would be an alternative place to call/implement
|
||||
//the swapPALShadow function
|
||||
}
|
||||
};
|
||||
|
||||
static inline int flattenIntIndex(ThreadContext * tc, int reg)
|
||||
void
|
||||
clear()
|
||||
{
|
||||
return reg;
|
||||
intRegFile.clear();
|
||||
floatRegFile.clear();
|
||||
miscRegFile.clear();
|
||||
}
|
||||
|
||||
static inline int flattenFloatIndex(ThreadContext * tc, int reg)
|
||||
MiscReg
|
||||
readMiscRegNoEffect(int miscReg)
|
||||
{
|
||||
return reg;
|
||||
return miscRegFile.readRegNoEffect(miscReg);
|
||||
}
|
||||
|
||||
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
||||
MiscReg
|
||||
readMiscReg(int miscReg, ThreadContext *tc)
|
||||
{
|
||||
return miscRegFile.readReg(miscReg, tc);
|
||||
}
|
||||
|
||||
void
|
||||
setMiscRegNoEffect(int miscReg, const MiscReg &val)
|
||||
{
|
||||
miscRegFile.setRegNoEffect(miscReg, val);
|
||||
}
|
||||
|
||||
void
|
||||
setMiscReg(int miscReg, const MiscReg &val, ThreadContext *tc)
|
||||
{
|
||||
miscRegFile.setReg(miscReg, val, tc);
|
||||
}
|
||||
|
||||
FloatReg
|
||||
readFloatReg(int floatReg)
|
||||
{
|
||||
return floatRegFile.d[floatReg];
|
||||
}
|
||||
|
||||
FloatReg
|
||||
readFloatReg(int floatReg, int width)
|
||||
{
|
||||
return readFloatReg(floatReg);
|
||||
}
|
||||
|
||||
FloatRegBits
|
||||
readFloatRegBits(int floatReg)
|
||||
{
|
||||
return floatRegFile.q[floatReg];
|
||||
}
|
||||
|
||||
FloatRegBits
|
||||
readFloatRegBits(int floatReg, int width)
|
||||
{
|
||||
return readFloatRegBits(floatReg);
|
||||
}
|
||||
|
||||
void
|
||||
setFloatReg(int floatReg, const FloatReg &val)
|
||||
{
|
||||
floatRegFile.d[floatReg] = val;
|
||||
}
|
||||
|
||||
void
|
||||
setFloatReg(int floatReg, const FloatReg &val, int width)
|
||||
{
|
||||
setFloatReg(floatReg, val);
|
||||
}
|
||||
|
||||
void
|
||||
setFloatRegBits(int floatReg, const FloatRegBits &val)
|
||||
{
|
||||
floatRegFile.q[floatReg] = val;
|
||||
}
|
||||
|
||||
void
|
||||
setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
|
||||
{
|
||||
setFloatRegBits(floatReg, val);
|
||||
}
|
||||
|
||||
IntReg
|
||||
readIntReg(int intReg)
|
||||
{
|
||||
return intRegFile.readReg(intReg);
|
||||
}
|
||||
|
||||
void
|
||||
setIntReg(int intReg, const IntReg &val)
|
||||
{
|
||||
intRegFile.setReg(intReg, val);
|
||||
}
|
||||
|
||||
void serialize(EventManager *em, std::ostream &os);
|
||||
void unserialize(EventManager *em, Checkpoint *cp,
|
||||
const std::string §ion);
|
||||
};
|
||||
|
||||
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__
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -44,31 +44,29 @@ class System;
|
|||
class ThreadContext;
|
||||
class PhysicalMemory;
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
class RemoteGDB : public BaseRemoteGDB
|
||||
{
|
||||
class RemoteGDB : public BaseRemoteGDB
|
||||
{
|
||||
protected:
|
||||
// Machine memory
|
||||
bool write(Addr addr, size_t size, const char *data);
|
||||
protected:
|
||||
Addr notTakenBkpt;
|
||||
Addr takenBkpt;
|
||||
|
||||
public:
|
||||
RemoteGDB(System *system, ThreadContext *context);
|
||||
protected:
|
||||
void getregs();
|
||||
void setregs();
|
||||
|
||||
bool acc(Addr addr, size_t len);
|
||||
void clearSingleStep();
|
||||
void setSingleStep();
|
||||
|
||||
protected:
|
||||
void getregs();
|
||||
void setregs();
|
||||
// Machine memory
|
||||
bool acc(Addr addr, size_t len);
|
||||
bool write(Addr addr, size_t size, const char *data);
|
||||
|
||||
void clearSingleStep();
|
||||
void setSingleStep();
|
||||
public:
|
||||
RemoteGDB(System *system, ThreadContext *context);
|
||||
};
|
||||
|
||||
protected:
|
||||
} // namespace AlphaISA
|
||||
|
||||
Addr notTakenBkpt;
|
||||
Addr takenBkpt;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* __ARCH_ALPHA_REMOTE_GDB_H__ */
|
||||
#endif // __ARCH_ALPHA_REMOTE_GDB_HH__
|
||||
|
|
|
@ -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;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
tsk = vp->readGtoH<Addr>(base + task_off);
|
||||
|
||||
return tsk;
|
||||
}
|
||||
|
||||
int
|
||||
ProcessInfo::pid(Addr ksp) const
|
||||
{
|
||||
Addr task = this->task(ksp);
|
||||
if (!task)
|
||||
return -1;
|
||||
|
||||
uint16_t pd;
|
||||
|
||||
VirtualPort *vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
||||
|
||||
return pd;
|
||||
}
|
||||
|
||||
string
|
||||
ProcessInfo::name(Addr ksp) const
|
||||
{
|
||||
Addr task = this->task(ksp);
|
||||
if (!task)
|
||||
return "console";
|
||||
|
||||
char comm[256];
|
||||
CopyStringOut(tc, comm, task + name_off, sizeof(comm));
|
||||
if (!comm[0])
|
||||
return "startup";
|
||||
|
||||
return comm;
|
||||
}
|
||||
|
||||
StackTrace::StackTrace()
|
||||
: tc(0), stack(64)
|
||||
{
|
||||
}
|
||||
|
||||
StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst)
|
||||
: tc(0), stack(64)
|
||||
{
|
||||
trace(_tc, inst);
|
||||
}
|
||||
|
||||
StackTrace::~StackTrace()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
StackTrace::trace(ThreadContext *_tc, bool is_call)
|
||||
{
|
||||
tc = _tc;
|
||||
|
||||
System *sys = tc->getSystemPtr();
|
||||
|
||||
bool usermode =
|
||||
(tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0;
|
||||
|
||||
Addr pc = tc->readNextPC();
|
||||
bool kernel = sys->kernelStart <= pc && pc <= sys->kernelEnd;
|
||||
|
||||
if (usermode) {
|
||||
stack.push_back(user);
|
||||
return;
|
||||
}
|
||||
|
||||
Addr
|
||||
ProcessInfo::task(Addr ksp) const
|
||||
{
|
||||
Addr base = ksp & ~0x3fff;
|
||||
if (base == ULL(0xfffffc0000000000))
|
||||
return 0;
|
||||
|
||||
Addr tsk;
|
||||
|
||||
VirtualPort *vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
tsk = vp->readGtoH<Addr>(base + task_off);
|
||||
tc->delVirtPort(vp);
|
||||
|
||||
return tsk;
|
||||
if (!kernel) {
|
||||
stack.push_back(console);
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
ProcessInfo::pid(Addr ksp) const
|
||||
{
|
||||
Addr task = this->task(ksp);
|
||||
if (!task)
|
||||
return -1;
|
||||
SymbolTable *symtab = sys->kernelSymtab;
|
||||
Addr ksp = tc->readIntReg(StackPointerReg);
|
||||
Addr bottom = ksp & ~0x3fff;
|
||||
|
||||
uint16_t pd;
|
||||
|
||||
VirtualPort *vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
||||
tc->delVirtPort(vp);
|
||||
|
||||
return pd;
|
||||
}
|
||||
|
||||
string
|
||||
ProcessInfo::name(Addr ksp) const
|
||||
{
|
||||
Addr task = this->task(ksp);
|
||||
if (!task)
|
||||
return "console";
|
||||
|
||||
char comm[256];
|
||||
CopyStringOut(tc, comm, task + name_off, sizeof(comm));
|
||||
if (!comm[0])
|
||||
return "startup";
|
||||
|
||||
return comm;
|
||||
}
|
||||
|
||||
StackTrace::StackTrace()
|
||||
: tc(0), stack(64)
|
||||
{
|
||||
}
|
||||
|
||||
StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst)
|
||||
: tc(0), stack(64)
|
||||
{
|
||||
trace(_tc, inst);
|
||||
}
|
||||
|
||||
StackTrace::~StackTrace()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
StackTrace::trace(ThreadContext *_tc, bool is_call)
|
||||
{
|
||||
tc = _tc;
|
||||
|
||||
bool usermode = (tc->readMiscRegNoEffect(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
|
||||
|
||||
Addr pc = tc->readNextPC();
|
||||
bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
|
||||
pc <= tc->getSystemPtr()->kernelEnd;
|
||||
|
||||
if (usermode) {
|
||||
stack.push_back(user);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!kernel) {
|
||||
stack.push_back(console);
|
||||
return;
|
||||
}
|
||||
|
||||
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
|
||||
Addr ksp = tc->readIntReg(TheISA::StackPointerReg);
|
||||
Addr bottom = ksp & ~0x3fff;
|
||||
if (is_call) {
|
||||
Addr addr;
|
||||
if (!symtab->findNearestAddr(pc, addr))
|
||||
panic("could not find address %#x", pc);
|
||||
|
||||
if (is_call) {
|
||||
if (!symtab->findNearestAddr(pc, addr))
|
||||
panic("could not find address %#x", pc);
|
||||
stack.push_back(addr);
|
||||
pc = tc->readPC();
|
||||
}
|
||||
|
||||
stack.push_back(addr);
|
||||
pc = tc->readPC();
|
||||
}
|
||||
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");
|
||||
|
||||
stack.push_back(addr);
|
||||
|
||||
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;
|
||||
|
||||
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp2))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
StackTrace::decodeStack(MachInst inst, int &disp)
|
||||
{
|
||||
// lda $sp, -disp($sp)
|
||||
//
|
||||
// Opcode<31:26> == 0x08
|
||||
// RA<25:21> == 30
|
||||
// RB<20:16> == 30
|
||||
// Disp<15:0>
|
||||
const MachInst mem_mask = 0xffff0000;
|
||||
const MachInst lda_pattern = 0x23de0000;
|
||||
const MachInst lda_disp_mask = 0x0000ffff;
|
||||
|
||||
// subq $sp, disp, $sp
|
||||
// addq $sp, disp, $sp
|
||||
//
|
||||
// Opcode<31:26> == 0x10
|
||||
// RA<25:21> == 30
|
||||
// Lit<20:13>
|
||||
// One<12> = 1
|
||||
// Func<11:5> == 0x20 (addq)
|
||||
// Func<11:5> == 0x29 (subq)
|
||||
// RC<4:0> == 30
|
||||
const MachInst intop_mask = 0xffe01fff;
|
||||
const MachInst addq_pattern = 0x43c0141e;
|
||||
const MachInst subq_pattern = 0x43c0153e;
|
||||
const MachInst intop_disp_mask = 0x001fe000;
|
||||
const int intop_disp_shift = 13;
|
||||
|
||||
if ((inst & mem_mask) == lda_pattern)
|
||||
disp = -sext<16>(inst & lda_disp_mask);
|
||||
else if ((inst & intop_mask) == addq_pattern)
|
||||
disp = -int((inst & intop_disp_mask) >> intop_disp_shift);
|
||||
else if ((inst & intop_mask) == subq_pattern)
|
||||
disp = int((inst & intop_disp_mask) >> intop_disp_shift);
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
StackTrace::decodeSave(MachInst inst, int ®, int &disp)
|
||||
{
|
||||
// lda $stq, disp($sp)
|
||||
//
|
||||
// Opcode<31:26> == 0x08
|
||||
// RA<25:21> == ?
|
||||
// RB<20:16> == 30
|
||||
// Disp<15:0>
|
||||
const MachInst stq_mask = 0xfc1f0000;
|
||||
const MachInst stq_pattern = 0xb41e0000;
|
||||
const MachInst stq_disp_mask = 0x0000ffff;
|
||||
const MachInst reg_mask = 0x03e00000;
|
||||
const int reg_shift = 21;
|
||||
|
||||
if ((inst & stq_mask) == stq_pattern) {
|
||||
reg = (inst & reg_mask) >> reg_shift;
|
||||
disp = sext<16>(inst & stq_disp_mask);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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;
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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;
|
||||
for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
|
||||
MachInst inst;
|
||||
CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
StackTrace::decodeSave(MachInst inst, int ®, int &disp)
|
||||
{
|
||||
// lda $stq, disp($sp)
|
||||
//
|
||||
// Opcode<31:26> == 0x08
|
||||
// RA<25:21> == ?
|
||||
// RB<20:16> == 30
|
||||
// Disp<15:0>
|
||||
const MachInst stq_mask = 0xfc1f0000;
|
||||
const MachInst stq_pattern = 0xb41e0000;
|
||||
const MachInst stq_disp_mask = 0x0000ffff;
|
||||
const MachInst reg_mask = 0x03e00000;
|
||||
const int reg_shift = 21;
|
||||
|
||||
if ((inst & stq_mask) == stq_pattern) {
|
||||
reg = (inst & reg_mask) >> reg_shift;
|
||||
disp = sext<16>(inst & stq_disp_mask);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode the function prologue for the function we're in, and note
|
||||
* which registers are stored where, and how large the stack frame is.
|
||||
*/
|
||||
bool
|
||||
StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
|
||||
int &size, Addr &ra)
|
||||
{
|
||||
size = 0;
|
||||
ra = 0;
|
||||
|
||||
for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
|
||||
MachInst inst;
|
||||
CopyOut(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;
|
||||
}
|
||||
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;
|
||||
void
|
||||
StackTrace::dump()
|
||||
{
|
||||
StringWrap name(tc->getCpuPtr()->name());
|
||||
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
|
||||
|
||||
DPRINTFN("------ Stack ------\n");
|
||||
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);
|
||||
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);
|
||||
}
|
||||
DPRINTFN("%#x: %s\n", addr, symbol);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
|
|
@ -36,90 +36,90 @@
|
|||
|
||||
class ThreadContext;
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
class StackTrace;
|
||||
|
||||
class ProcessInfo
|
||||
{
|
||||
class StackTrace;
|
||||
private:
|
||||
ThreadContext *tc;
|
||||
|
||||
class ProcessInfo
|
||||
int thread_info_size;
|
||||
int task_struct_size;
|
||||
int task_off;
|
||||
int pid_off;
|
||||
int name_off;
|
||||
|
||||
public:
|
||||
ProcessInfo(ThreadContext *_tc);
|
||||
|
||||
Addr task(Addr ksp) const;
|
||||
int pid(Addr ksp) const;
|
||||
std::string name(Addr ksp) const;
|
||||
};
|
||||
|
||||
class StackTrace
|
||||
{
|
||||
private:
|
||||
ThreadContext *tc;
|
||||
std::vector<Addr> stack;
|
||||
|
||||
private:
|
||||
bool isEntry(Addr addr);
|
||||
bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
|
||||
bool decodeSave(MachInst inst, int ®, int &disp);
|
||||
bool decodeStack(MachInst inst, int &disp);
|
||||
|
||||
void trace(ThreadContext *tc, bool is_call);
|
||||
|
||||
public:
|
||||
StackTrace();
|
||||
StackTrace(ThreadContext *tc, StaticInstPtr inst);
|
||||
~StackTrace();
|
||||
|
||||
void
|
||||
clear()
|
||||
{
|
||||
private:
|
||||
ThreadContext *tc;
|
||||
tc = 0;
|
||||
stack.clear();
|
||||
}
|
||||
|
||||
int thread_info_size;
|
||||
int task_struct_size;
|
||||
int task_off;
|
||||
int pid_off;
|
||||
int name_off;
|
||||
bool valid() const { return tc != NULL; }
|
||||
bool trace(ThreadContext *tc, StaticInstPtr inst);
|
||||
|
||||
public:
|
||||
ProcessInfo(ThreadContext *_tc);
|
||||
public:
|
||||
const std::vector<Addr> &getstack() const { return stack; }
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
bool isEntry(Addr addr);
|
||||
bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
|
||||
bool decodeSave(MachInst inst, int ®, int &disp);
|
||||
bool decodeStack(MachInst inst, int &disp);
|
||||
|
||||
void trace(ThreadContext *tc, bool is_call);
|
||||
|
||||
public:
|
||||
StackTrace();
|
||||
StackTrace(ThreadContext *tc, StaticInstPtr inst);
|
||||
~StackTrace();
|
||||
|
||||
void clear()
|
||||
{
|
||||
tc = 0;
|
||||
stack.clear();
|
||||
}
|
||||
|
||||
bool valid() const { return tc != NULL; }
|
||||
bool trace(ThreadContext *tc, StaticInstPtr inst);
|
||||
|
||||
public:
|
||||
const std::vector<Addr> &getstack() const { return stack; }
|
||||
|
||||
static const int user = 1;
|
||||
static const int console = 2;
|
||||
static const int unknown = 3;
|
||||
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__
|
||||
|
|
|
@ -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 §ion)
|
||||
{
|
||||
|
|
|
@ -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 §ion);
|
||||
|
||||
|
@ -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__
|
||||
|
||||
|
|
|
@ -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
|
||||
// in Alpha, cacheability is controlled by upper-level bits of the
|
||||
// physical address
|
||||
|
||||
/*
|
||||
* We support having the uncacheable bit in either bit 39 or bit 40.
|
||||
* The Turbolaser platform (and EV5) support having the bit in 39, but
|
||||
* Tsunami (which Linux assumes uses an EV6) generates accesses with
|
||||
* the bit in 40. So we must check for both, but we have debug flags
|
||||
* to catch a weird case where both are used, which shouldn't happen.
|
||||
*/
|
||||
/*
|
||||
* We support having the uncacheable bit in either bit 39 or bit
|
||||
* 40. The Turbolaser platform (and EV5) support having the bit
|
||||
* in 39, but Tsunami (which Linux assumes uses an EV6) generates
|
||||
* accesses with the bit in 40. So we must check for both, but we
|
||||
* have debug flags to catch a weird case where both are used,
|
||||
* which shouldn't happen.
|
||||
*/
|
||||
|
||||
|
||||
#if ALPHA_TLASER
|
||||
|
@ -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 §ion)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
||||
class TLB : public BaseTLB
|
||||
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)
|
||||
{
|
||||
protected:
|
||||
typedef std::multimap<Addr, int> PageTable;
|
||||
PageTable lookupTable; // Quick lookup into page table
|
||||
assert(asn < (1 << 8));
|
||||
flushAddr(vaddr, asn);
|
||||
}
|
||||
|
||||
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 §ion);
|
||||
|
||||
// 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
|
||||
// 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 §ion);
|
||||
|
||||
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;
|
||||
memset(EntryCache, 0, 3 * sizeof(TlbEntry*));
|
||||
}
|
||||
|
||||
public:
|
||||
typedef AlphaDTBParams Params;
|
||||
DTB(const Params *p);
|
||||
virtual void regStats();
|
||||
inline TlbEntry *
|
||||
updateCache(TlbEntry *entry) {
|
||||
EntryCache[2] = EntryCache[1];
|
||||
EntryCache[1] = EntryCache[0];
|
||||
EntryCache[0] = entry;
|
||||
return entry;
|
||||
}
|
||||
};
|
||||
|
||||
Fault translate(RequestPtr &req, ThreadContext *tc, bool write);
|
||||
};
|
||||
}
|
||||
class ITB : public TLB
|
||||
{
|
||||
protected:
|
||||
mutable Stats::Scalar hits;
|
||||
mutable Stats::Scalar misses;
|
||||
mutable Stats::Scalar acv;
|
||||
mutable Stats::Formula accesses;
|
||||
|
||||
#endif // __ALPHA_MEMORY_HH__
|
||||
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__
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -32,47 +32,43 @@
|
|||
#ifndef __ARCH_ALPHA_TYPES_HH__
|
||||
#define __ARCH_ALPHA_TYPES_HH__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "sim/host.hh"
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
typedef uint32_t MachInst;
|
||||
typedef uint64_t ExtMachInst;
|
||||
typedef uint8_t RegIndex;
|
||||
|
||||
typedef uint64_t IntReg;
|
||||
typedef uint64_t LargestRead;
|
||||
|
||||
// floating point register file entry type
|
||||
typedef double FloatReg;
|
||||
typedef uint64_t FloatRegBits;
|
||||
|
||||
// control register file contents
|
||||
typedef uint64_t MiscReg;
|
||||
|
||||
union AnyReg
|
||||
{
|
||||
IntReg intreg;
|
||||
FloatReg fpreg;
|
||||
MiscReg ctrlreg;
|
||||
};
|
||||
|
||||
typedef uint32_t MachInst;
|
||||
typedef uint64_t ExtMachInst;
|
||||
typedef uint8_t RegIndex;
|
||||
enum annotes
|
||||
{
|
||||
ANNOTE_NONE = 0,
|
||||
// An impossible number for instruction annotations
|
||||
ITOUCH_ANNOTE = 0xffffffff,
|
||||
};
|
||||
|
||||
typedef uint64_t IntReg;
|
||||
typedef uint64_t LargestRead;
|
||||
struct CoreSpecific
|
||||
{
|
||||
int core_type;
|
||||
};
|
||||
|
||||
// floating point register file entry type
|
||||
typedef double FloatReg;
|
||||
typedef uint64_t FloatRegBits;
|
||||
|
||||
// control register file contents
|
||||
typedef uint64_t MiscReg;
|
||||
|
||||
typedef union {
|
||||
IntReg intreg;
|
||||
FloatReg fpreg;
|
||||
MiscReg ctrlreg;
|
||||
} AnyReg;
|
||||
|
||||
enum RegContextParam
|
||||
{
|
||||
CONTEXT_PALMODE
|
||||
};
|
||||
|
||||
typedef bool RegContextVal;
|
||||
|
||||
enum annotes {
|
||||
ANNOTE_NONE = 0,
|
||||
// An impossible number for instruction annotations
|
||||
ITOUCH_ANNOTE = 0xffffffff,
|
||||
};
|
||||
|
||||
struct CoreSpecific {
|
||||
int core_type;
|
||||
};
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif
|
||||
#endif // __ARCH_ALPHA_TYPES_HH__
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
uint64_t getArgument(ThreadContext *tc, int number, bool fp);
|
||||
inline bool
|
||||
isCallerSaveIntegerRegister(unsigned int reg)
|
||||
{
|
||||
panic("register classification not implemented");
|
||||
return (reg >= 1 && reg <= 8) || (reg >= 22 && reg <= 25) || reg == 27;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
inUserMode(ThreadContext *tc)
|
||||
{
|
||||
return (tc->readMiscRegNoEffect(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
|
||||
}
|
||||
inline bool
|
||||
isCalleeSaveIntegerRegister(unsigned int reg)
|
||||
{
|
||||
panic("register classification not implemented");
|
||||
return reg >= 9 && reg <= 15;
|
||||
}
|
||||
|
||||
inline bool isCallerSaveIntegerRegister(unsigned int reg) {
|
||||
panic("register classification not implemented");
|
||||
return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27);
|
||||
}
|
||||
inline bool
|
||||
isCallerSaveFloatRegister(unsigned int reg)
|
||||
{
|
||||
panic("register classification not implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool isCalleeSaveIntegerRegister(unsigned int reg) {
|
||||
panic("register classification not implemented");
|
||||
return (reg >= 9 && reg <= 15);
|
||||
}
|
||||
inline bool
|
||||
isCalleeSaveFloatRegister(unsigned int reg)
|
||||
{
|
||||
panic("register classification not implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool isCallerSaveFloatRegister(unsigned int reg) {
|
||||
panic("register classification not implemented");
|
||||
return false;
|
||||
}
|
||||
inline Addr
|
||||
alignAddress(const Addr &addr, unsigned int nbytes)
|
||||
{
|
||||
return (addr & ~(nbytes - 1));
|
||||
}
|
||||
|
||||
inline bool isCalleeSaveFloatRegister(unsigned int reg) {
|
||||
panic("register classification not implemented");
|
||||
return false;
|
||||
}
|
||||
// Instruction address compression hooks
|
||||
inline Addr
|
||||
realPCToFetchPC(const Addr &addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
inline Addr alignAddress(const Addr &addr,
|
||||
unsigned int nbytes) {
|
||||
return (addr & ~(nbytes - 1));
|
||||
}
|
||||
inline Addr
|
||||
fetchPCToRealPC(const Addr &addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
// Instruction address compression hooks
|
||||
inline Addr realPCToFetchPC(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 Addr fetchPCToRealPC(const Addr &addr) {
|
||||
return addr;
|
||||
}
|
||||
inline MachInst
|
||||
makeRegisterCopy(int dest, int src)
|
||||
{
|
||||
panic("makeRegisterCopy not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// the size of "fetched" instructions (not necessarily the size
|
||||
// of real instructions for PISA)
|
||||
inline size_t fetchInstSize() {
|
||||
return sizeof(MachInst);
|
||||
}
|
||||
// Machine operations
|
||||
void saveMachineReg(AnyReg &savereg, const RegFile ®_file, int regnum);
|
||||
void restoreMachineReg(RegFile ®s, const AnyReg ®, int regnum);
|
||||
|
||||
inline MachInst makeRegisterCopy(int dest, int src) {
|
||||
panic("makeRegisterCopy not implemented");
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Function to insure ISA semantics about 0 registers.
|
||||
* @param tc The thread context.
|
||||
*/
|
||||
template <class TC>
|
||||
void zeroRegisters(TC *tc);
|
||||
|
||||
// Machine operations
|
||||
// Alpha IPR register accessors
|
||||
inline bool PcPAL(Addr addr) { return addr & 0x3; }
|
||||
inline void startupCPU(ThreadContext *tc, int cpuId) { tc->activate(0); }
|
||||
|
||||
void saveMachineReg(AnyReg &savereg, const RegFile ®_file,
|
||||
int regnum);
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Translation stuff
|
||||
//
|
||||
|
||||
void restoreMachineReg(RegFile ®s, const AnyReg ®,
|
||||
int regnum);
|
||||
inline Addr PteAddr(Addr a) { return (a & PteMask) << PteShift; }
|
||||
|
||||
/**
|
||||
* Function to insure ISA semantics about 0 registers.
|
||||
* @param tc The thread context.
|
||||
*/
|
||||
template <class TC>
|
||||
void zeroRegisters(TC *tc);
|
||||
// User Virtual
|
||||
inline bool IsUSeg(Addr a) { return USegBase <= a && a <= USegEnd; }
|
||||
|
||||
// Alpha IPR register accessors
|
||||
inline bool PcPAL(Addr addr) { return addr & 0x3; }
|
||||
inline void startupCPU(ThreadContext *tc, int cpuId) {
|
||||
tc->activate(0);
|
||||
}
|
||||
// Kernel Direct Mapped
|
||||
inline bool IsK0Seg(Addr a) { return K0SegBase <= a && a <= K0SegEnd; }
|
||||
inline Addr K0Seg2Phys(Addr addr) { return addr & ~K0SegBase; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Translation stuff
|
||||
//
|
||||
// Kernel Virtual
|
||||
inline bool IsK1Seg(Addr a) { return K1SegBase <= a && a <= K1SegEnd; }
|
||||
|
||||
inline Addr PteAddr(Addr a) { return (a & PteMask) << PteShift; }
|
||||
inline Addr
|
||||
TruncPage(Addr addr)
|
||||
{ return addr & ~(PageBytes - 1); }
|
||||
|
||||
// User Virtual
|
||||
inline bool IsUSeg(Addr a) { return USegBase <= a && a <= USegEnd; }
|
||||
inline Addr
|
||||
RoundPage(Addr addr)
|
||||
{ return (addr + PageBytes - 1) & ~(PageBytes - 1); }
|
||||
|
||||
// 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);
|
||||
void initIPRs(ThreadContext *tc, int cpuId);
|
||||
#if FULL_SYSTEM
|
||||
void initCPU(ThreadContext *tc, int cpuId);
|
||||
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);
|
||||
/**
|
||||
* 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__
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue