Merge ARM into the head. ARM will compile but may not actually work.

This commit is contained in:
Gabe Black 2009-04-06 10:19:36 -07:00
commit d080581db1
1238 changed files with 77272 additions and 36447 deletions

View file

@ -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
View file

@ -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.

View file

@ -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
--------------------

File diff suppressed because it is too large Load diff

View file

@ -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')],

View file

@ -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

View file

@ -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")

View file

@ -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])

View file

@ -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)

View file

@ -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)

View file

@ -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
View 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
View 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
View file

@ -0,0 +1 @@
1.5 (08 Jan 2003)

165
ext/gzstream/gzstream.cc Normal file
View 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
View 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 //

View file

@ -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'])

File diff suppressed because it is too large Load diff

View file

@ -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' ])

View 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'

View file

@ -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

View file

@ -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')

View file

@ -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))

View file

@ -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__*/

View file

@ -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.

View file

@ -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__

View file

@ -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);

View file

@ -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__

View file

@ -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 &section)
{
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 &section)
{
UNSERIALIZE_ARRAY(q, NumFloatRegs);
}
} // namespace AlphaISA

View file

@ -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 &section);
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 &section);
};
} // namespace AlphaISA
#endif // __ARCH_ALPHA_FLOATREGFILE_HH__

View file

@ -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)
{

View file

@ -57,7 +57,6 @@ class FreebsdAlphaSystem : public AlphaSystem
~FreebsdAlphaSystem();
void doCalibrateClocks(ThreadContext *tc);
};
#endif // __ARCH_ALPHA_FREEBSD_SYSTEM_HH__

View file

@ -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();
}

View 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);
}

View file

@ -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 &section)
{
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 &section)
{
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__

View file

@ -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 &section)
{
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 &section)
{
UNSERIALIZE_ARRAY(regs, NumIntRegs);
}
} // namespace AlphaISA

View file

@ -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 &section);
};
void setReg(int intReg, const IntReg &val)
{
regs[intReg] = val;
}
} // namespace AlphaISA
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
void clear()
{ std::memset(regs, 0, sizeof(regs)); }
};
}
#endif
#endif // __ARCH_ALPHA_INTREGFILE_HH__

View file

@ -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

View file

@ -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__

View file

@ -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
}

View file

@ -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);
}

View file

@ -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),

View file

@ -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

View file

@ -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

View file

@ -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__

View file

@ -152,7 +152,7 @@ Statistics::changeMode(cpu_mode newmode, ThreadContext *tc)
void
Statistics::mode(cpu_mode newmode, ThreadContext *tc)
{
Addr pcbb = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23);
Addr pcbb = tc->readMiscRegNoEffect(IPR_PALtemp23);
if (newmode == kernel && pcbb == idleProcess)
newmode = idle;
@ -213,5 +213,5 @@ Statistics::unserialize(Checkpoint *cp, const string &section)
themode = (cpu_mode)exemode;
}
} /* end namespace AlphaISA::Kernel */
} /* end namespace AlphaISA */
} // namespace Kernel
} // namespace AlphaISA

View file

@ -62,15 +62,15 @@ class Statistics : public ::Kernel::Statistics
void changeMode(cpu_mode newmode, ThreadContext *tc);
private:
Stats::Vector<> _callpal;
// Stats::Vector<> _faults;
Stats::Vector _callpal;
// Stats::Vector _faults;
Stats::Vector<> _mode;
Stats::Vector<> _modeGood;
Stats::Vector _mode;
Stats::Vector _modeGood;
Stats::Formula _modeFraction;
Stats::Vector<> _modeTicks;
Stats::Vector _modeTicks;
Stats::Scalar<> _swap_context;
Stats::Scalar _swap_context;
public:
Statistics(System *system);
@ -90,7 +90,7 @@ class Statistics : public ::Kernel::Statistics
void unserialize(Checkpoint *cp, const std::string &section);
};
} /* end namespace AlphaISA::Kernel */
} /* end namespace AlphaISA */
} // namespace Kernel
} // namespace AlphaISA
#endif // __ARCH_ALPHA_KERNEL_STATS_HH__

View file

@ -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]));

View file

@ -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__

View file

@ -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];
}

View file

@ -51,4 +51,5 @@ class AlphaLinuxProcess : public AlphaLiveProcess
};
} // namespace AlphaISA
#endif // __ALPHA_LINUX_PROCESS_HH__

View file

@ -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)
{

View file

@ -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

View file

@ -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__

View file

@ -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__

View 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__

View file

@ -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 &section)
{
UNSERIALIZE_SCALAR(fpcr);
UNSERIALIZE_SCALAR(uniq);
UNSERIALIZE_SCALAR(lock_flag);
UNSERIALIZE_SCALAR(lock_addr);
UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs);
}
MiscReg
MiscRegFile::readRegNoEffect(int misc_reg)
{
switch(misc_reg) {
case MISCREG_FPCR:
return fpcr;
case MISCREG_UNIQ:
return uniq;
case MISCREG_LOCKFLAG:
return lock_flag;
case MISCREG_LOCKADDR:
return lock_addr;
case MISCREG_INTR:
return intr_flag;
default:
assert(misc_reg < NumInternalProcRegs);
return ipr[misc_reg];
}
}
MiscReg
MiscRegFile::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 &section)
{
UNSERIALIZE_SCALAR(fpcr);
UNSERIALIZE_SCALAR(uniq);
UNSERIALIZE_SCALAR(lock_flag);
UNSERIALIZE_SCALAR(lock_addr);
UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs);
}
MiscReg
MiscRegFile::readRegNoEffect(int misc_reg)
{
switch (misc_reg) {
case MISCREG_FPCR:
return fpcr;
case MISCREG_UNIQ:
return uniq;
case MISCREG_LOCKFLAG:
return lock_flag;
case MISCREG_LOCKADDR:
return lock_addr;
case MISCREG_INTR:
return intr_flag;
default:
assert(misc_reg < NumInternalProcRegs);
return ipr[misc_reg];
}
}
MiscReg
MiscRegFile::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

View file

@ -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 &section);
};
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 &section);
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__

View file

@ -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__

View file

@ -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;

View file

@ -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__

View file

@ -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 &section)
{
UNSERIALIZE_SCALAR(tag);
UNSERIALIZE_SCALAR(ppn);
UNSERIALIZE_SCALAR(xre);
UNSERIALIZE_SCALAR(xwe);
UNSERIALIZE_SCALAR(asn);
UNSERIALIZE_SCALAR(asma);
UNSERIALIZE_SCALAR(fonr);
UNSERIALIZE_SCALAR(fonw);
UNSERIALIZE_SCALAR(valid);
}
void
TlbEntry::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 &section)
{
UNSERIALIZE_SCALAR(tag);
UNSERIALIZE_SCALAR(ppn);
UNSERIALIZE_SCALAR(xre);
UNSERIALIZE_SCALAR(xwe);
UNSERIALIZE_SCALAR(asn);
UNSERIALIZE_SCALAR(asma);
UNSERIALIZE_SCALAR(fonr);
UNSERIALIZE_SCALAR(fonw);
UNSERIALIZE_SCALAR(valid);
}
} //namespace AlphaISA

View file

@ -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 &section);
};
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 &section);
};
} // namespace AlphaISA
#endif // __ARCH_ALPHA_PAGETABLE_H__

View file

@ -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__

View file

@ -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());
}
}

View file

@ -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__

View file

@ -33,67 +33,68 @@
#include "arch/alpha/regfile.hh"
#include "cpu/thread_context.hh"
namespace AlphaISA
using namespace std;
namespace AlphaISA {
void
RegFile::serialize(EventManager *em, ostream &os)
{
void
RegFile::serialize(std::ostream &os)
{
intRegFile.serialize(os);
floatRegFile.serialize(os);
miscRegFile.serialize(os);
SERIALIZE_SCALAR(pc);
SERIALIZE_SCALAR(npc);
intRegFile.serialize(os);
floatRegFile.serialize(os);
miscRegFile.serialize(os);
SERIALIZE_SCALAR(pc);
SERIALIZE_SCALAR(npc);
#if FULL_SYSTEM
SERIALIZE_SCALAR(intrflag);
SERIALIZE_SCALAR(intrflag);
#endif
}
void
RegFile::unserialize(Checkpoint *cp, const std::string &section)
{
intRegFile.unserialize(cp, section);
floatRegFile.unserialize(cp, section);
miscRegFile.unserialize(cp, section);
UNSERIALIZE_SCALAR(pc);
UNSERIALIZE_SCALAR(npc);
#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 &section)
{
intRegFile.unserialize(cp, section);
floatRegFile.unserialize(cp, section);
miscRegFile.unserialize(cp, section);
UNSERIALIZE_SCALAR(pc);
UNSERIALIZE_SCALAR(npc);
#if FULL_SYSTEM
UNSERIALIZE_SCALAR(intrflag);
#endif
}
void
copyRegs(ThreadContext *src, ThreadContext *dest)
{
// First loop through the integer registers.
for (int i = 0; i < NumIntRegs; ++i)
dest->setIntReg(i, src->readIntReg(i));
// Then loop through the floating point registers.
for (int i = 0; i < 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

View file

@ -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 &section);
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 &section);
};
static inline int
flattenIntIndex(ThreadContext * tc, int reg)
{
return reg;
}
static inline int
flattenFloatIndex(ThreadContext * tc, int reg)
{
return reg;
}
void copyRegs(ThreadContext *src, ThreadContext *dest);
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
} // namespace AlphaISA
#endif
#endif // __ARCH_ALPHA_REGFILE_HH__

View file

@ -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

View file

@ -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__

View file

@ -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 &reg, int &disp)
{
// lda $stq, disp($sp)
//
// Opcode<31:26> == 0x08
// RA<25:21> == ?
// RB<20:16> == 30
// Disp<15:0>
const MachInst stq_mask = 0xfc1f0000;
const MachInst stq_pattern = 0xb41e0000;
const MachInst stq_disp_mask = 0x0000ffff;
const MachInst reg_mask = 0x03e00000;
const int reg_shift = 21;
if ((inst & stq_mask) == stq_pattern) {
reg = (inst & reg_mask) >> reg_shift;
disp = sext<16>(inst & stq_disp_mask);
} else {
return false;
}
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 &reg, int &disp)
{
// lda $stq, disp($sp)
//
// Opcode<31:26> == 0x08
// RA<25:21> == ?
// RB<20:16> == 30
// Disp<15:0>
const MachInst stq_mask = 0xfc1f0000;
const MachInst stq_pattern = 0xb41e0000;
const MachInst stq_disp_mask = 0x0000ffff;
const MachInst reg_mask = 0x03e00000;
const int reg_shift = 21;
if ((inst & stq_mask) == stq_pattern) {
reg = (inst & reg_mask) >> reg_shift;
disp = sext<16>(inst & stq_disp_mask);
} else {
return false;
}
return true;
}
/*
* Decode the function prologue for the function we're in, and note
* which registers are stored where, and how large the stack frame is.
*/
bool
StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
int &size, Addr &ra)
{
size = 0;
ra = 0;
for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
MachInst inst;
CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst));
int reg, disp;
if (decodeStack(inst, disp)) {
if (size) {
// panic("decoding frame size again");
return true;
}
size += disp;
} else if (decodeSave(inst, reg, disp)) {
if (!ra && reg == ReturnAddressReg) {
CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr));
if (!ra) {
// panic("no return address value pc=%#x\n", pc);
return false;
}
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

View file

@ -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 &reg, int &disp);
bool decodeStack(MachInst inst, int &disp);
void trace(ThreadContext *tc, bool is_call);
public:
StackTrace();
StackTrace(ThreadContext *tc, StaticInstPtr inst);
~StackTrace();
void
clear()
{
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 &reg, int &disp);
bool decodeStack(MachInst inst, int &disp);
void trace(ThreadContext *tc, bool is_call);
public:
StackTrace();
StackTrace(ThreadContext *tc, StaticInstPtr inst);
~StackTrace();
void clear()
{
tc = 0;
stack.clear();
}
bool valid() const { return tc != NULL; }
bool trace(ThreadContext *tc, StaticInstPtr inst);
public:
const std::vector<Addr> &getstack() const { return stack; }
static const int user = 1;
static const int console = 2;
static const int unknown = 3;
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__

View file

@ -42,8 +42,7 @@
#include "params/AlphaSystem.hh"
#include "sim/byteswap.hh"
using namespace LittleEndianGuest;
using namespace AlphaISA;
AlphaSystem::AlphaSystem(Params *p)
: System(p)
@ -67,8 +66,8 @@ AlphaSystem::AlphaSystem(Params *p)
// Load program sections into memory
pal->loadSections(&functionalPort, AlphaISA::LoadAddrMask);
console->loadSections(&functionalPort, AlphaISA::LoadAddrMask);
pal->loadSections(&functionalPort, LoadAddrMask);
console->loadSections(&functionalPort, LoadAddrMask);
// load symbols
if (!console->loadGlobalSymbols(consoleSymtab))
@ -117,7 +116,6 @@ AlphaSystem::AlphaSystem(Params *p)
virtPort.write(addr+0x58, data);
} else
panic("could not find hwrpb\n");
}
AlphaSystem::~AlphaSystem()
@ -142,9 +140,9 @@ AlphaSystem::~AlphaSystem()
* in the procedure value register (pv aka t12 == r27). This sequence
* looks like the following:
*
* opcode Ra Rb offset
* ldah gp,X(pv) 09 29 27 X
* lda gp,Y(gp) 08 29 29 Y
* opcode Ra Rb offset
* ldah gp,X(pv) 09 29 27 X
* lda gp,Y(gp) 08 29 29 Y
*
* for some constant offsets X and Y. The catch is that the linker
* (or maybe even the compiler, I'm not sure) may recognize that the
@ -172,11 +170,11 @@ AlphaSystem::fixFuncEventAddr(Addr addr)
const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16);
uint32_t i1 = virtPort.read<uint32_t>(addr);
uint32_t i2 = virtPort.read<uint32_t>(addr + sizeof(AlphaISA::MachInst));
uint32_t i2 = virtPort.read<uint32_t>(addr + sizeof(MachInst));
if ((i1 & inst_mask) == gp_ldah_pattern &&
(i2 & inst_mask) == gp_lda_pattern) {
Addr new_addr = addr + 2* sizeof(AlphaISA::MachInst);
Addr new_addr = addr + 2 * sizeof(MachInst);
DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr);
return new_addr;
} else {
@ -184,15 +182,15 @@ AlphaSystem::fixFuncEventAddr(Addr addr)
}
}
void
AlphaSystem::setAlphaAccess(Addr access)
{
Addr addr = 0;
if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
virtPort.write(addr, htog(EV5::Phys2K0Seg(access)));
} else
virtPort.write(addr, htog(Phys2K0Seg(access)));
} else {
panic("could not find m5AlphaAccess\n");
}
}
void
@ -203,7 +201,6 @@ AlphaSystem::serialize(std::ostream &os)
palSymtab->serialize("pal_symtab", os);
}
void
AlphaSystem::unserialize(Checkpoint *cp, const std::string &section)
{

View file

@ -49,10 +49,10 @@ class AlphaSystem : public System
AlphaSystem(Params *p);
~AlphaSystem();
/**
* Serialization stuff
*/
public:
/**
* Serialization stuff
*/
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
@ -77,26 +77,28 @@ class AlphaSystem : public System
/** Event to halt the simulator if the console calls panic() */
BreakPCEvent *consolePanicEvent;
#endif
protected:
const Params *params() const { return (const Params *)_params; }
/** Add a function-based event to PALcode. */
template <class T>
T *addPalFuncEvent(const char *lbl)
T *
addPalFuncEvent(const char *lbl)
{
return addFuncEvent<T>(palSymtab, lbl);
}
/** Add a function-based event to the console code. */
template <class T>
T *addConsoleFuncEvent(const char *lbl)
T *
addConsoleFuncEvent(const char *lbl)
{
return addFuncEvent<T>(consoleSymtab, lbl);
}
virtual Addr fixFuncEventAddr(Addr addr);
};
#endif
#endif // __ARCH_ALPHA_SYSTEM_HH__

View file

@ -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 &section)
}
}
///////////////////////////////////////////////////////////////////////
//
// Alpha ITB
@ -308,13 +316,12 @@ ITB::regStats()
accesses = hits + misses;
}
Fault
ITB::translate(RequestPtr &req, ThreadContext *tc)
ITB::translateAtomic(RequestPtr req, ThreadContext *tc)
{
//If this is a pal pc, then set PHYSICAL
if(FULL_SYSTEM && PcPAL(req->getPC()))
req->setFlags(req->getFlags() | PHYSICAL);
if (FULL_SYSTEM && PcPAL(req->getPC()))
req->setFlags(Request::PHYSICAL);
if (PcPAL(req->getPC())) {
// strip off PAL PC marker (lsb is 1)
@ -323,7 +330,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
return NoFault;
}
if (req->getFlags() & PHYSICAL) {
if (req->getFlags() & Request::PHYSICAL) {
req->setPaddr(req->getVaddr());
} else {
// verify that this is a good virtual address
@ -390,15 +397,23 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
if (req->getPaddr() & ~PAddrImplMask)
return genMachineCheckFault();
return checkCacheability(req);
return checkCacheability(req, true);
}
void
ITB::translateTiming(RequestPtr req, ThreadContext *tc,
Translation *translation)
{
assert(translation);
translation->finish(translateAtomic(req, tc), req, tc, false);
}
///////////////////////////////////////////////////////////////////////
//
// Alpha DTB
//
DTB::DTB(const Params *p)
DTB::DTB(const Params *p)
: TLB(p)
{}
@ -472,14 +487,13 @@ DTB::regStats()
}
Fault
DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write)
{
Addr pc = tc->readPC();
mode_type mode =
(mode_type)DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM));
/**
* Check for alignment faults
*/
@ -491,13 +505,13 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
}
if (PcPAL(pc)) {
mode = (req->getFlags() & ALTMODE) ?
mode = (req->getFlags() & Request::ALTMODE) ?
(mode_type)ALT_MODE_AM(
tc->readMiscRegNoEffect(IPR_ALT_MODE))
: mode_kernel;
}
if (req->getFlags() & PHYSICAL) {
if (req->getFlags() & Request::PHYSICAL) {
req->setPaddr(req->getVaddr());
} else {
// verify that this is a good virtual address
@ -517,14 +531,15 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
if (VAddrSpaceEV6(req->getVaddr()) == 0x7e)
#endif
{
// only valid in kernel mode
if (DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)) !=
mode_kernel) {
if (write) { write_acv++; } else { read_acv++; }
uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) |
MM_STAT_ACV_MASK);
return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
return new DtbAcvFault(req->getVaddr(), req->getFlags(),
flags);
}
req->setPaddr(req->getVaddr() & PAddrImplMask);
@ -553,7 +568,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
if (write) { write_misses++; } else { read_misses++; }
uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
MM_STAT_DTB_MISS_MASK;
return (req->getFlags() & VPTE) ?
return (req->getFlags() & Request::VPTE) ?
(Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(),
flags)) :
(Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(),
@ -570,25 +585,28 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
uint64_t flags = MM_STAT_WR_MASK |
MM_STAT_ACV_MASK |
(entry->fonw ? MM_STAT_FONW_MASK : 0);
return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
return new DtbPageFault(req->getVaddr(), req->getFlags(),
flags);
}
if (entry->fonw) {
write_acv++;
uint64_t flags = MM_STAT_WR_MASK |
MM_STAT_FONW_MASK;
return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
uint64_t flags = MM_STAT_WR_MASK | MM_STAT_FONW_MASK;
return new DtbPageFault(req->getVaddr(), req->getFlags(),
flags);
}
} else {
if (!(entry->xre & MODE2MASK(mode))) {
read_acv++;
uint64_t flags = MM_STAT_ACV_MASK |
(entry->fonr ? MM_STAT_FONR_MASK : 0);
return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
return new DtbAcvFault(req->getVaddr(), req->getFlags(),
flags);
}
if (entry->fonr) {
read_acv++;
uint64_t flags = MM_STAT_FONR_MASK;
return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
return new DtbPageFault(req->getVaddr(), req->getFlags(),
flags);
}
}
}
@ -606,6 +624,14 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
return checkCacheability(req);
}
void
DTB::translateTiming(RequestPtr req, ThreadContext *tc,
Translation *translation, bool write)
{
assert(translation);
translation->finish(translateAtomic(req, tc, write), req, tc, write);
}
TlbEntry &
TLB::index(bool advance)
{

View file

@ -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 &section);
// Most recently used page table entries
TlbEntry *EntryCache[3];
inline void flushCache()
{
memset(EntryCache, 0, 3 * sizeof(TlbEntry*));
}
inline TlbEntry* updateCache(TlbEntry *entry) {
EntryCache[2] = EntryCache[1];
EntryCache[1] = EntryCache[0];
EntryCache[0] = entry;
return entry;
}
};
class ITB : public TLB
// static helper functions... really EV5 VM traits
static bool
validVirtualAddress(Addr vaddr)
{
protected:
mutable Stats::Scalar<> hits;
mutable Stats::Scalar<> misses;
mutable Stats::Scalar<> acv;
mutable Stats::Formula accesses;
// unimplemented bits must be all 0 or all 1
Addr unimplBits = vaddr & VAddrUnImplMask;
return unimplBits == 0 || unimplBits == VAddrUnImplMask;
}
public:
typedef AlphaITBParams Params;
ITB(const Params *p);
virtual void regStats();
static Fault checkCacheability(RequestPtr &req, bool itb = false);
Fault translate(RequestPtr &req, ThreadContext *tc);
};
// Checkpointing
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
class DTB : public TLB
// Most recently used page table entries
TlbEntry *EntryCache[3];
inline void
flushCache()
{
protected:
mutable Stats::Scalar<> read_hits;
mutable Stats::Scalar<> read_misses;
mutable Stats::Scalar<> read_acv;
mutable Stats::Scalar<> read_accesses;
mutable Stats::Scalar<> write_hits;
mutable Stats::Scalar<> write_misses;
mutable Stats::Scalar<> write_acv;
mutable Stats::Scalar<> write_accesses;
Stats::Formula hits;
Stats::Formula misses;
Stats::Formula acv;
Stats::Formula accesses;
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__

View file

@ -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))

View file

@ -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__

View file

@ -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 */
};

View file

@ -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__

View file

@ -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__

View file

@ -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
}

View file

@ -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 &reg_file, int regnum);
void restoreMachineReg(RegFile &regs, const AnyReg &reg, 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 &reg_file,
int regnum);
////////////////////////////////////////////////////////////////////////
//
// Translation stuff
//
void restoreMachineReg(RegFile &regs, const AnyReg &reg,
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__

View file

@ -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

View file

@ -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__

View file

@ -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