Merge ARM into the head. ARM will compile but may not actually work.
This commit is contained in:
commit
d080581db1
1238 changed files with 77272 additions and 36447 deletions
2
.hgtags
2
.hgtags
|
@ -16,3 +16,5 @@ b174ae14f007ba0c341f8df77d36f57f48369cc8 m5_2.0_beta2
|
||||||
91a9ac67662aa3a79315ade29b17a85961fecd88 m5_2.0_beta3
|
91a9ac67662aa3a79315ade29b17a85961fecd88 m5_2.0_beta3
|
||||||
dce5a8655829b7d2e24ce40cafc9c8873a71671f m5_2.0_beta5
|
dce5a8655829b7d2e24ce40cafc9c8873a71671f m5_2.0_beta5
|
||||||
1ac44b6c87ec71a8410c9a9c219269eca71f8077 m5_2.0_beta4
|
1ac44b6c87ec71a8410c9a9c219269eca71f8077 m5_2.0_beta4
|
||||||
|
60a931b03fb165807f02bcccc4f7d0fd705a67a9 copyright_update
|
||||||
|
d8b246a665c160a31751b4091f097022cde16dd7 m5_2.0_beta6
|
||||||
|
|
2
README
2
README
|
@ -1,4 +1,4 @@
|
||||||
This is release 2.0_beta5 of the M5 simulator.
|
This is release 2.0_beta6 of the M5 simulator.
|
||||||
|
|
||||||
For detailed information about building the simulator and getting
|
For detailed information about building the simulator and getting
|
||||||
started please refer to http://www.m5sim.org.
|
started please refer to http://www.m5sim.org.
|
||||||
|
|
|
@ -1,13 +1,26 @@
|
||||||
|
October 6, 2008: m5_2.0_beta6
|
||||||
|
--------------------
|
||||||
|
New Features
|
||||||
|
1. Support for gcc 4.3
|
||||||
|
2. Core m5 code in libm5 for integration with other simulators
|
||||||
|
3. Preliminary support for X86 SE mode
|
||||||
|
4. Additional system calls emulated
|
||||||
|
5. m5term updated to work on OS X
|
||||||
|
6. Ability to disable listen sockets
|
||||||
|
7. Event queue performance improvements and rewrite
|
||||||
|
8. Better errors for unconnected memory ports
|
||||||
|
|
||||||
|
Bug fixes
|
||||||
|
1. ALPHA_SE O3 perlbmk benchmark
|
||||||
|
2. Translation bug where O3 could fetch from uncachable memory
|
||||||
|
3. Many minor bugs
|
||||||
|
|
||||||
Outstanding issues for 2.0 release:
|
Outstanding issues for 2.0 release:
|
||||||
--------------------
|
--------------------
|
||||||
1. Fix O3 CPU bug in SE 40.perlbmk fails
|
1. Statistics cleanup
|
||||||
2. Fix O3 processing nacks/coherence messages
|
2. Improve regression system
|
||||||
3. Better statistics for the caches.
|
3. Testing
|
||||||
4. FS mode doesn't work under Cygwin
|
4. Validation
|
||||||
5. memtest regression crashes under Cygwin
|
|
||||||
6. Make repository public
|
|
||||||
7. Testing
|
|
||||||
8. Validation
|
|
||||||
|
|
||||||
March 1, 2008: m5_2.0_beta5
|
March 1, 2008: m5_2.0_beta5
|
||||||
--------------------
|
--------------------
|
||||||
|
|
689
SConstruct
689
SConstruct
File diff suppressed because it is too large
Load diff
|
@ -59,46 +59,46 @@ Benchmarks = {
|
||||||
'PovrayBench': [SysConfig('povray-bench.rcS', '512MB', 'povray.img')],
|
'PovrayBench': [SysConfig('povray-bench.rcS', '512MB', 'povray.img')],
|
||||||
'PovrayAutumn': [SysConfig('povray-autumn.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')],
|
SysConfig('netperf-server.rcS')],
|
||||||
'NetperfStreamUdp': [SysConfig('netperf-stream-udp-client.rcS'),
|
'NetperfStreamUdp': [SysConfig('netperf-stream-udp-client.rcS'),
|
||||||
SysConfig('netperf-server.rcS')],
|
SysConfig('netperf-server.rcS')],
|
||||||
'NetperfUdpLocal': [SysConfig('netperf-stream-udp-local.rcS')],
|
'NetperfUdpLocal': [SysConfig('netperf-stream-udp-local.rcS')],
|
||||||
'NetperfStreamNT': [SysConfig('netperf-stream-nt-client.rcS'),
|
'NetperfStreamNT': [SysConfig('netperf-stream-nt-client.rcS'),
|
||||||
SysConfig('netperf-server.rcS')],
|
SysConfig('netperf-server.rcS')],
|
||||||
'NetperfMaerts': [SysConfig('netperf-maerts-client.rcS'),
|
'NetperfMaerts': [SysConfig('netperf-maerts-client.rcS'),
|
||||||
SysConfig('netperf-server.rcS')],
|
SysConfig('netperf-server.rcS')],
|
||||||
'SurgeStandard': [SysConfig('surge-server.rcS', '512MB'),
|
'SurgeStandard': [SysConfig('surge-server.rcS', '512MB'),
|
||||||
SysConfig('surge-client.rcS', '256MB')],
|
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')],
|
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')],
|
SysConfig('nfs-client-nhfsstone.rcS')],
|
||||||
'Nfs': [SysConfig('nfs-server.rcS', '900MB'),
|
'Nfs': [SysConfig('nfs-server.rcS', '900MB'),
|
||||||
SysConfig('nfs-client-dbench.rcS')],
|
SysConfig('nfs-client-dbench.rcS')],
|
||||||
'NfsTcp': [SysConfig('nfs-server.rcS', '900MB'),
|
'NfsTcp': [SysConfig('nfs-server.rcS', '900MB'),
|
||||||
SysConfig('nfs-client-tcp.rcS')],
|
SysConfig('nfs-client-tcp.rcS')],
|
||||||
'IScsiInitiator': [SysConfig('iscsi-client.rcS', '512MB'),
|
'IScsiInitiator': [SysConfig('iscsi-client.rcS', '512MB'),
|
||||||
SysConfig('iscsi-server.rcS', '512MB')],
|
SysConfig('iscsi-server.rcS', '512MB')],
|
||||||
'IScsiTarget': [SysConfig('iscsi-server.rcS', '512MB'),
|
'IScsiTarget': [SysConfig('iscsi-server.rcS', '512MB'),
|
||||||
SysConfig('iscsi-client.rcS', '512MB')],
|
SysConfig('iscsi-client.rcS', '512MB')],
|
||||||
'Validation': [SysConfig('iscsi-server.rcS', '512MB'),
|
'Validation': [SysConfig('iscsi-server.rcS', '512MB'),
|
||||||
SysConfig('iscsi-client.rcS', '512MB')],
|
SysConfig('iscsi-client.rcS', '512MB')],
|
||||||
'Ping': [SysConfig('ping-server.rcS',),
|
'Ping': [SysConfig('ping-server.rcS',),
|
||||||
SysConfig('ping-client.rcS')],
|
SysConfig('ping-client.rcS')],
|
||||||
|
|
||||||
'ValAccDelay': [SysConfig('devtime.rcS', '512MB')],
|
'ValAccDelay': [SysConfig('devtime.rcS', '512MB')],
|
||||||
'ValAccDelay2': [SysConfig('devtimewmr.rcS', '512MB')],
|
'ValAccDelay2': [SysConfig('devtimewmr.rcS', '512MB')],
|
||||||
'ValMemLat': [SysConfig('micro_memlat.rcS', '512MB')],
|
'ValMemLat': [SysConfig('micro_memlat.rcS', '512MB')],
|
||||||
'ValMemLat2MB': [SysConfig('micro_memlat2mb.rcS', '512MB')],
|
'ValMemLat2MB': [SysConfig('micro_memlat2mb.rcS', '512MB')],
|
||||||
'ValMemLat8MB': [SysConfig('micro_memlat8mb.rcS', '512MB')],
|
'ValMemLat8MB': [SysConfig('micro_memlat8mb.rcS', '512MB')],
|
||||||
'ValMemLat': [SysConfig('micro_memlat8.rcS', '512MB')],
|
'ValMemLat': [SysConfig('micro_memlat8.rcS', '512MB')],
|
||||||
'ValTlbLat': [SysConfig('micro_tlblat.rcS', '512MB')],
|
'ValTlbLat': [SysConfig('micro_tlblat.rcS', '512MB')],
|
||||||
'ValSysLat': [SysConfig('micro_syscall.rcS', '512MB')],
|
'ValSysLat': [SysConfig('micro_syscall.rcS', '512MB')],
|
||||||
'ValCtxLat': [SysConfig('micro_ctx.rcS', '512MB')],
|
'ValCtxLat': [SysConfig('micro_ctx.rcS', '512MB')],
|
||||||
'ValStream': [SysConfig('micro_stream.rcS', '512MB')],
|
'ValStream': [SysConfig('micro_stream.rcS', '512MB')],
|
||||||
'ValStreamScale': [SysConfig('micro_streamscale.rcS', '512MB')],
|
'ValStreamScale': [SysConfig('micro_streamscale.rcS', '512MB')],
|
||||||
'ValStreamCopy': [SysConfig('micro_streamcopy.rcS', '512MB')],
|
'ValStreamCopy': [SysConfig('micro_streamcopy.rcS', '512MB')],
|
||||||
|
|
||||||
'MutexTest': [SysConfig('mutex-test.rcS', '128MB')],
|
'MutexTest': [SysConfig('mutex-test.rcS', '128MB')],
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
||||||
read_only = True))
|
read_only = True))
|
||||||
self.intrctrl = IntrControl()
|
self.intrctrl = IntrControl()
|
||||||
self.mem_mode = mem_mode
|
self.mem_mode = mem_mode
|
||||||
self.sim_console = SimConsole()
|
self.terminal = Terminal()
|
||||||
self.kernel = binary('vmlinux')
|
self.kernel = binary('vmlinux')
|
||||||
self.pal = binary('ts_osfpal')
|
self.pal = binary('ts_osfpal')
|
||||||
self.console = binary('console')
|
self.console = binary('console')
|
||||||
|
@ -148,7 +148,7 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None):
|
||||||
read_only = True))
|
read_only = True))
|
||||||
self.intrctrl = IntrControl()
|
self.intrctrl = IntrControl()
|
||||||
self.mem_mode = mem_mode
|
self.mem_mode = mem_mode
|
||||||
self.sim_console = SimConsole()
|
self.terminal = Terminal()
|
||||||
self.kernel = binary('mips/vmlinux')
|
self.kernel = binary('mips/vmlinux')
|
||||||
self.console = binary('mips/console')
|
self.console = binary('mips/console')
|
||||||
self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
|
self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
|
||||||
|
@ -159,11 +159,14 @@ def x86IOAddress(port):
|
||||||
IO_address_space_base = 0x8000000000000000
|
IO_address_space_base = 0x8000000000000000
|
||||||
return IO_address_space_base + port;
|
return IO_address_space_base + port;
|
||||||
|
|
||||||
def makeLinuxX86System(mem_mode, mdesc = None):
|
def makeX86System(mem_mode, mdesc = None, self = None):
|
||||||
self = LinuxX86System()
|
if self == None:
|
||||||
|
self = X86System()
|
||||||
|
|
||||||
if not mdesc:
|
if not mdesc:
|
||||||
# generic system
|
# generic system
|
||||||
mdesc = SysConfig()
|
mdesc = SysConfig()
|
||||||
|
mdesc.diskname = 'x86root.img'
|
||||||
self.readfile = mdesc.script()
|
self.readfile = mdesc.script()
|
||||||
|
|
||||||
# Physical memory
|
# Physical memory
|
||||||
|
@ -177,22 +180,168 @@ def makeLinuxX86System(mem_mode, mdesc = None):
|
||||||
self.bridge.side_a = self.iobus.port
|
self.bridge.side_a = self.iobus.port
|
||||||
self.bridge.side_b = self.membus.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
|
# Platform
|
||||||
self.opteron = Opteron()
|
self.pc = Pc()
|
||||||
self.opteron.attachIO(self.iobus)
|
self.pc.attachIO(self.iobus)
|
||||||
|
|
||||||
self.intrctrl = IntrControl()
|
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
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
# system options
|
# system options
|
||||||
parser.add_option("-d", "--detailed", action="store_true")
|
parser.add_option("-d", "--detailed", action="store_true")
|
||||||
parser.add_option("-t", "--timing", 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("-n", "--num-cpus", type="int", default=1)
|
||||||
parser.add_option("--caches", action="store_true")
|
parser.add_option("--caches", action="store_true")
|
||||||
parser.add_option("--l2cache", action="store_true")
|
parser.add_option("--l2cache", action="store_true")
|
||||||
|
|
|
@ -43,6 +43,11 @@ def setCPUClass(options):
|
||||||
print "O3 CPU must be used with caches"
|
print "O3 CPU must be used with caches"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
class TmpClass(DerivO3CPU): pass
|
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:
|
else:
|
||||||
class TmpClass(AtomicSimpleCPU): pass
|
class TmpClass(AtomicSimpleCPU): pass
|
||||||
atomic = True
|
atomic = True
|
||||||
|
@ -78,10 +83,10 @@ def run(options, root, testsys, cpu_class):
|
||||||
cptdir = getcwd()
|
cptdir = getcwd()
|
||||||
|
|
||||||
if options.fast_forward and options.checkpoint_restore != None:
|
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:
|
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
|
np = options.num_cpus
|
||||||
max_checkpoints = options.max_checkpoints
|
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)
|
testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
|
||||||
# Fast forward to a simpoint (warning: time consuming)
|
# Fast forward to a simpoint (warning: time consuming)
|
||||||
elif options.simpoint:
|
elif options.simpoint:
|
||||||
if testsys.cpu[i].workload[0].simpoint == None:
|
if testsys.cpu[i].workload[0].simpoint == 0:
|
||||||
m5.panic('simpoint not found')
|
m5.fatal('simpoint not found')
|
||||||
testsys.cpu[i].max_insts_any_thread = \
|
testsys.cpu[i].max_insts_any_thread = \
|
||||||
testsys.cpu[i].workload[0].simpoint
|
testsys.cpu[i].workload[0].simpoint
|
||||||
# No distance specified, just switch
|
# No distance specified, just switch
|
||||||
|
@ -162,8 +167,8 @@ def run(options, root, testsys, cpu_class):
|
||||||
# Set an instruction break point
|
# Set an instruction break point
|
||||||
if options.simpoint:
|
if options.simpoint:
|
||||||
for i in xrange(np):
|
for i in xrange(np):
|
||||||
if testsys.cpu[i].workload[0].simpoint == None:
|
if testsys.cpu[i].workload[0].simpoint == 0:
|
||||||
m5.panic('no simpoint for testsys.cpu[%d].workload[0]' % i)
|
m5.fatal('no simpoint for testsys.cpu[%d].workload[0]', i)
|
||||||
checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset
|
checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset
|
||||||
testsys.cpu[i].max_insts_any_thread = checkpoint_inst
|
testsys.cpu[i].max_insts_any_thread = checkpoint_inst
|
||||||
# used for output below
|
# used for output below
|
||||||
|
@ -183,13 +188,13 @@ def run(options, root, testsys, cpu_class):
|
||||||
import re
|
import re
|
||||||
|
|
||||||
if not isdir(cptdir):
|
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:
|
if options.at_instruction:
|
||||||
checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % \
|
checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % \
|
||||||
(options.bench, options.checkpoint_restore))
|
(options.bench, options.checkpoint_restore))
|
||||||
if not exists(checkpoint_dir):
|
if not exists(checkpoint_dir):
|
||||||
m5.panic("Unable to find checkpoint directory %s" % \
|
m5.fatal("Unable to find checkpoint directory %s",
|
||||||
checkpoint_dir)
|
checkpoint_dir)
|
||||||
|
|
||||||
print "Restoring checkpoint ..."
|
print "Restoring checkpoint ..."
|
||||||
|
@ -197,8 +202,8 @@ def run(options, root, testsys, cpu_class):
|
||||||
print "Done."
|
print "Done."
|
||||||
elif options.simpoint:
|
elif options.simpoint:
|
||||||
# assume workload 0 has the simpoint
|
# assume workload 0 has the simpoint
|
||||||
if testsys.cpu[0].workload[0].simpoint == None:
|
if testsys.cpu[0].workload[0].simpoint == 0:
|
||||||
m5.panic('Unable to find simpoint')
|
m5.fatal('Unable to find simpoint')
|
||||||
|
|
||||||
options.checkpoint_restore += \
|
options.checkpoint_restore += \
|
||||||
int(testsys.cpu[0].workload[0].simpoint)
|
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" % \
|
checkpoint_dir = joinpath(cptdir, "cpt.%s.%d" % \
|
||||||
(options.bench, options.checkpoint_restore))
|
(options.bench, options.checkpoint_restore))
|
||||||
if not exists(checkpoint_dir):
|
if not exists(checkpoint_dir):
|
||||||
m5.panic("Unable to find checkpoint directory %s.%s" % \
|
m5.fatal("Unable to find checkpoint directory %s.%s",
|
||||||
(options.bench, options.checkpoint_restore))
|
options.bench, options.checkpoint_restore)
|
||||||
|
|
||||||
print "Restoring checkpoint ..."
|
print "Restoring checkpoint ..."
|
||||||
m5.restoreCheckpoint(root,checkpoint_dir)
|
m5.restoreCheckpoint(root,checkpoint_dir)
|
||||||
|
@ -226,7 +231,7 @@ def run(options, root, testsys, cpu_class):
|
||||||
cpt_num = options.checkpoint_restore
|
cpt_num = options.checkpoint_restore
|
||||||
|
|
||||||
if cpt_num > len(cpts):
|
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
|
## Adjust max tick based on our starting tick
|
||||||
maxtick = maxtick - int(cpts[cpt_num - 1])
|
maxtick = maxtick - int(cpts[cpt_num - 1])
|
||||||
|
|
|
@ -140,7 +140,8 @@ class Benchmark(object):
|
||||||
process_args['input'] = self.stdin
|
process_args['input'] = self.stdin
|
||||||
if self.stdout:
|
if self.stdout:
|
||||||
process_args['output'] = self.stdout
|
process_args['output'] = self.stdout
|
||||||
process_args['simpoint'] = self.simpoint
|
if self.simpoint:
|
||||||
|
process_args['simpoint'] = self.simpoint
|
||||||
# explicit keywords override defaults
|
# explicit keywords override defaults
|
||||||
process_args.update(kwargs)
|
process_args.update(kwargs)
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,10 @@
|
||||||
import optparse, os, sys
|
import optparse, os, sys
|
||||||
|
|
||||||
import m5
|
import m5
|
||||||
|
|
||||||
|
if not m5.build_env['FULL_SYSTEM']:
|
||||||
|
m5.fatal("This script requires full-system mode (*_FS).")
|
||||||
|
|
||||||
from m5.objects import *
|
from m5.objects import *
|
||||||
m5.AddToPath('../common')
|
m5.AddToPath('../common')
|
||||||
from FSConfig import *
|
from FSConfig import *
|
||||||
|
@ -37,9 +41,6 @@ from Benchmarks import *
|
||||||
import Simulation
|
import Simulation
|
||||||
from Caches import *
|
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.
|
# 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_path = os.path.dirname(os.path.abspath(__file__))
|
||||||
config_root = os.path.dirname(config_path)
|
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":
|
elif m5.build_env['TARGET_ISA'] == "x86":
|
||||||
test_sys = makeLinuxX86System(test_mem_mode, bm[0])
|
test_sys = makeLinuxX86System(test_mem_mode, bm[0])
|
||||||
else:
|
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:
|
if options.kernel is not None:
|
||||||
test_sys.kernel = binary(options.kernel)
|
test_sys.kernel = binary(options.kernel)
|
||||||
|
|
|
@ -31,8 +31,13 @@
|
||||||
# "m5 test.py"
|
# "m5 test.py"
|
||||||
|
|
||||||
import m5
|
import m5
|
||||||
|
|
||||||
|
if m5.build_env['FULL_SYSTEM']:
|
||||||
|
m5.fatal("This script requires syscall emulation mode (*_SE).")
|
||||||
|
|
||||||
from m5.objects import *
|
from m5.objects import *
|
||||||
import os, optparse, sys
|
import os, optparse, sys
|
||||||
|
from os.path import join as joinpath
|
||||||
m5.AddToPath('../common')
|
m5.AddToPath('../common')
|
||||||
import Simulation
|
import Simulation
|
||||||
from Caches import *
|
from Caches import *
|
||||||
|
@ -47,13 +52,13 @@ parser = optparse.OptionParser()
|
||||||
|
|
||||||
# Benchmark options
|
# Benchmark options
|
||||||
parser.add_option("-c", "--cmd",
|
parser.add_option("-c", "--cmd",
|
||||||
default=os.path.join(m5_root, "tests/test-progs/hello/bin/alpha/linux/hello"),
|
default=joinpath(m5_root, "tests/test-progs/hello/bin/alpha/linux/hello"),
|
||||||
help="The binary to run in syscall emulation mode.")
|
help="The binary to run in syscall emulation mode.")
|
||||||
parser.add_option("-o", "--options", default="",
|
parser.add_option("-o", "--options", default="",
|
||||||
help="The options to pass to the binary, use \" \" around the entire\
|
help='The options to pass to the binary, use " " around the entire string')
|
||||||
string.")
|
parser.add_option("-i", "--input", default="", help="Read stdin from a file.")
|
||||||
parser.add_option("-i", "--input", default="",
|
parser.add_option("--output", default="", help="Redirect stdout to a file.")
|
||||||
help="A file of input to give to the binary.")
|
parser.add_option("--errout", default="", help="Redirect stderr to a file.")
|
||||||
|
|
||||||
execfile(os.path.join(config_root, "common", "Options.py"))
|
execfile(os.path.join(config_root, "common", "Options.py"))
|
||||||
|
|
||||||
|
@ -81,6 +86,10 @@ else:
|
||||||
|
|
||||||
if options.input != "":
|
if options.input != "":
|
||||||
process.input = options.input
|
process.input = options.input
|
||||||
|
if options.output != "":
|
||||||
|
process.output = options.output
|
||||||
|
if options.errout != "":
|
||||||
|
process.errout = options.errout
|
||||||
|
|
||||||
if options.detailed:
|
if options.detailed:
|
||||||
#check for SMT workload
|
#check for SMT workload
|
||||||
|
@ -89,9 +98,15 @@ if options.detailed:
|
||||||
process = []
|
process = []
|
||||||
smt_idx = 0
|
smt_idx = 0
|
||||||
inputs = []
|
inputs = []
|
||||||
|
outputs = []
|
||||||
|
errouts = []
|
||||||
|
|
||||||
if options.input != "":
|
if options.input != "":
|
||||||
inputs = options.input.split(';')
|
inputs = options.input.split(';')
|
||||||
|
if options.output != "":
|
||||||
|
outputs = options.output.split(';')
|
||||||
|
if options.errout != "":
|
||||||
|
errouts = options.errout.split(';')
|
||||||
|
|
||||||
for wrkld in workloads:
|
for wrkld in workloads:
|
||||||
smt_process = LiveProcess()
|
smt_process = LiveProcess()
|
||||||
|
@ -99,6 +114,10 @@ if options.detailed:
|
||||||
smt_process.cmd = wrkld + " " + options.options
|
smt_process.cmd = wrkld + " " + options.options
|
||||||
if inputs and inputs[smt_idx]:
|
if inputs and inputs[smt_idx]:
|
||||||
smt_process.input = 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, ]
|
process += [smt_process, ]
|
||||||
smt_idx += 1
|
smt_idx += 1
|
||||||
|
|
||||||
|
|
504
ext/gzstream/LICENSE
Normal file
504
ext/gzstream/LICENSE
Normal file
|
@ -0,0 +1,504 @@
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts
|
||||||
|
as the successor of the GNU Library Public License, version 2, hence
|
||||||
|
the version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
Licenses are intended to guarantee your freedom to share and change
|
||||||
|
free software--to make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some
|
||||||
|
specially designated software packages--typically libraries--of the
|
||||||
|
Free Software Foundation and other authors who decide to use it. You
|
||||||
|
can use it too, but we suggest you first think carefully about whether
|
||||||
|
this license or the ordinary General Public License is the better
|
||||||
|
strategy to use in any particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use,
|
||||||
|
not price. Our General Public Licenses are designed to make sure that
|
||||||
|
you have the freedom to distribute copies of free software (and charge
|
||||||
|
for this service if you wish); that you receive source code or can get
|
||||||
|
it if you want it; that you can change the software and use pieces of
|
||||||
|
it in new free programs; and that you are informed that you can do
|
||||||
|
these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for
|
||||||
|
you if you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis
|
||||||
|
or for a fee, you must give the recipients all the rights that we gave
|
||||||
|
you. You must make sure that they, too, receive or can get the source
|
||||||
|
code. If you link other code with the library, you must provide
|
||||||
|
complete object files to the recipients, so that they can relink them
|
||||||
|
with the library after making changes to the library and recompiling
|
||||||
|
it. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that
|
||||||
|
there is no warranty for the free library. Also, if the library is
|
||||||
|
modified by someone else and passed on, the recipients should know
|
||||||
|
that what they have is not the original version, so that the original
|
||||||
|
author's reputation will not be affected by problems that might be
|
||||||
|
introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of
|
||||||
|
any free program. We wish to make sure that a company cannot
|
||||||
|
effectively restrict the users of a free program by obtaining a
|
||||||
|
restrictive license from a patent holder. Therefore, we insist that
|
||||||
|
any patent license obtained for a version of the library must be
|
||||||
|
consistent with the full freedom of use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the
|
||||||
|
ordinary GNU General Public License. This license, the GNU Lesser
|
||||||
|
General Public License, applies to certain designated libraries, and
|
||||||
|
is quite different from the ordinary General Public License. We use
|
||||||
|
this license for certain libraries in order to permit linking those
|
||||||
|
libraries into non-free programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using
|
||||||
|
a shared library, the combination of the two is legally speaking a
|
||||||
|
combined work, a derivative of the original library. The ordinary
|
||||||
|
General Public License therefore permits such linking only if the
|
||||||
|
entire combination fits its criteria of freedom. The Lesser General
|
||||||
|
Public License permits more lax criteria for linking other code with
|
||||||
|
the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it
|
||||||
|
does Less to protect the user's freedom than the ordinary General
|
||||||
|
Public License. It also provides other free software developers Less
|
||||||
|
of an advantage over competing non-free programs. These disadvantages
|
||||||
|
are the reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to
|
||||||
|
encourage the widest possible use of a certain library, so that it becomes
|
||||||
|
a de-facto standard. To achieve this, non-free programs must be
|
||||||
|
allowed to use the library. A more frequent case is that a free
|
||||||
|
library does the same job as widely used non-free libraries. In this
|
||||||
|
case, there is little to gain by limiting the free library to free
|
||||||
|
software only, so we use the Lesser General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free
|
||||||
|
programs enables a greater number of people to use a large body of
|
||||||
|
free software. For example, permission to use the GNU C Library in
|
||||||
|
non-free programs enables many more people to use the whole GNU
|
||||||
|
operating system, as well as its variant, the GNU/Linux operating
|
||||||
|
system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the
|
||||||
|
users' freedom, it does ensure that the user of a program that is
|
||||||
|
linked with the Library has the freedom and the wherewithal to run
|
||||||
|
that program using a modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow. Pay close attention to the difference between a
|
||||||
|
"work based on the library" and a "work that uses the library". The
|
||||||
|
former contains code derived from the library, whereas the latter must
|
||||||
|
be combined with the library in order to run.
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other
|
||||||
|
program which contains a notice placed by the copyright holder or
|
||||||
|
other authorized party saying it may be distributed under the terms of
|
||||||
|
this Lesser General Public License (also called "this License").
|
||||||
|
Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work
|
||||||
|
which has been distributed under these terms. A "work based on the
|
||||||
|
Library" means either the Library or any derivative work under
|
||||||
|
copyright law: that is to say, a work containing the Library or a
|
||||||
|
portion of it, either verbatim or with modifications and/or translated
|
||||||
|
straightforwardly into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For a library, complete source code means
|
||||||
|
all the source code for all modules it contains, plus any associated
|
||||||
|
interface definition files, plus the scripts used to control compilation
|
||||||
|
and installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running a program using the Library is not restricted, and output from
|
||||||
|
such a program is covered only if its contents constitute a work based
|
||||||
|
on the Library (independent of the use of the Library in a tool for
|
||||||
|
writing it). Whether that is true depends on what the Library does
|
||||||
|
and what the program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's
|
||||||
|
complete source code as you receive it, in any medium, provided that
|
||||||
|
you conspicuously and appropriately publish on each copy an
|
||||||
|
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||||
|
all the notices that refer to this License and to the absence of any
|
||||||
|
warranty; and distribute a copy of this License along with the
|
||||||
|
Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
|
and you may at your option offer warranty protection in exchange for a
|
||||||
|
fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion
|
||||||
|
of it, thus forming a work based on the Library, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no
|
||||||
|
charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a
|
||||||
|
table of data to be supplied by an application program that uses
|
||||||
|
the facility, other than as an argument passed when the facility
|
||||||
|
is invoked, then you must make a good faith effort to ensure that,
|
||||||
|
in the event an application does not supply such function or
|
||||||
|
table, the facility still operates, and performs whatever part of
|
||||||
|
its purpose remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has
|
||||||
|
a purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must
|
||||||
|
be optional: if the application does not supply it, the square
|
||||||
|
root function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Library, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote
|
||||||
|
it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so
|
||||||
|
that they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in
|
||||||
|
these notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for
|
||||||
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of
|
||||||
|
the Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or
|
||||||
|
derivative of it, under Section 2) in object code or executable form
|
||||||
|
under the terms of Sections 1 and 2 above provided that you accompany
|
||||||
|
it with the complete corresponding machine-readable source code, which
|
||||||
|
must be distributed under the terms of Sections 1 and 2 above on a
|
||||||
|
medium customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy
|
||||||
|
from a designated place, then offering equivalent access to copy the
|
||||||
|
source code from the same place satisfies the requirement to
|
||||||
|
distribute the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the
|
||||||
|
Library, but is designed to work with the Library by being compiled or
|
||||||
|
linked with it, is called a "work that uses the Library". Such a
|
||||||
|
work, in isolation, is not a derivative work of the Library, and
|
||||||
|
therefore falls outside the scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library
|
||||||
|
creates an executable that is a derivative of the Library (because it
|
||||||
|
contains portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License.
|
||||||
|
Section 6 states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is not.
|
||||||
|
Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data
|
||||||
|
structure layouts and accessors, and small macros and small inline
|
||||||
|
functions (ten lines or less in length), then the use of the object
|
||||||
|
file is unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section 6.
|
||||||
|
Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or
|
||||||
|
link a "work that uses the Library" with the Library to produce a
|
||||||
|
work containing portions of the Library, and distribute that work
|
||||||
|
under terms of your choice, provided that the terms permit
|
||||||
|
modification of the work for the customer's own use and reverse
|
||||||
|
engineering for debugging such modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work
|
||||||
|
during execution displays copyright notices, you must include the
|
||||||
|
copyright notice for the Library among them, as well as a reference
|
||||||
|
directing the user to the copy of this License. Also, you must do one
|
||||||
|
of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding
|
||||||
|
machine-readable source code for the Library including whatever
|
||||||
|
changes were used in the work (which must be distributed under
|
||||||
|
Sections 1 and 2 above); and, if the work is an executable linked
|
||||||
|
with the Library, with the complete machine-readable "work that
|
||||||
|
uses the Library", as object code and/or source code, so that the
|
||||||
|
user can modify the Library and then relink to produce a modified
|
||||||
|
executable containing the modified Library. (It is understood
|
||||||
|
that the user who changes the contents of definitions files in the
|
||||||
|
Library will not necessarily be able to recompile the application
|
||||||
|
to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a
|
||||||
|
copy of the library already present on the user's computer system,
|
||||||
|
rather than copying library functions into the executable, and (2)
|
||||||
|
will operate properly with a modified version of the library, if
|
||||||
|
the user installs one, as long as the modified version is
|
||||||
|
interface-compatible with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at
|
||||||
|
least three years, to give the same user the materials
|
||||||
|
specified in Subsection 6a, above, for a charge no more
|
||||||
|
than the cost of performing this distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy
|
||||||
|
from a designated place, offer equivalent access to copy the above
|
||||||
|
specified materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these
|
||||||
|
materials or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the
|
||||||
|
Library" must include any data and utility programs needed for
|
||||||
|
reproducing the executable from it. However, as a special exception,
|
||||||
|
the materials to be distributed need not include anything that is
|
||||||
|
normally distributed (in either source or binary form) with the major
|
||||||
|
components (compiler, kernel, and so on) of the operating system on
|
||||||
|
which the executable runs, unless that component itself accompanies
|
||||||
|
the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license
|
||||||
|
restrictions of other proprietary libraries that do not normally
|
||||||
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
|
use both them and the Library together in an executable that you
|
||||||
|
distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the
|
||||||
|
Library side-by-side in a single library together with other library
|
||||||
|
facilities not covered by this License, and distribute such a combined
|
||||||
|
library, provided that the separate distribution of the work based on
|
||||||
|
the Library and of the other library facilities is otherwise
|
||||||
|
permitted, and provided that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work
|
||||||
|
based on the Library, uncombined with any other library
|
||||||
|
facilities. This must be distributed under the terms of the
|
||||||
|
Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact
|
||||||
|
that part of it is a work based on the Library, and explaining
|
||||||
|
where to find the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute
|
||||||
|
the Library except as expressly provided under this License. Any
|
||||||
|
attempt otherwise to copy, modify, sublicense, link with, or
|
||||||
|
distribute the Library is void, and will automatically terminate your
|
||||||
|
rights under this License. However, parties who have received copies,
|
||||||
|
or rights, from you under this License will not have their licenses
|
||||||
|
terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Library or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Library (or any work based on the
|
||||||
|
Library), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Library or works based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties with
|
||||||
|
this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Library by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any
|
||||||
|
particular circumstance, the balance of the section is intended to apply,
|
||||||
|
and the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Library under this License may add
|
||||||
|
an explicit geographical distribution limitation excluding those countries,
|
||||||
|
so that distribution is permitted only in or among countries not thus
|
||||||
|
excluded. In such case, this License incorporates the limitation as if
|
||||||
|
written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the Lesser General Public License from time to time.
|
||||||
|
Such new versions will be similar in spirit to the present version,
|
||||||
|
but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and
|
||||||
|
"any later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a
|
||||||
|
license version number, you may choose any version ever published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free
|
||||||
|
Software Foundation; we sometimes make exceptions for this. Our
|
||||||
|
decision will be guided by the two goals of preserving the free status
|
||||||
|
of all derivatives of our free software and of promoting the sharing
|
||||||
|
and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||||
|
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||||
|
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||||
|
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||||
|
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||||
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||||
|
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||||
|
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||||
|
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||||
|
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||||
|
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||||
|
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||||
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the library's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||||
|
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
That's all there is to it!
|
||||||
|
|
||||||
|
|
38
ext/gzstream/SConscript
Normal file
38
ext/gzstream/SConscript
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
# -*- mode:python -*-
|
||||||
|
|
||||||
|
# Copyright (c) 2004-2005 The Regents of The University of Michigan
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met: redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer;
|
||||||
|
# redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution;
|
||||||
|
# neither the name of the copyright holders nor the names of its
|
||||||
|
# contributors may be used to endorse or promote products derived from
|
||||||
|
# this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
# Authors: Nathan Binkert
|
||||||
|
|
||||||
|
Import('env')
|
||||||
|
|
||||||
|
env.Library('gzstream', [File('gzstream.cc')])
|
||||||
|
|
||||||
|
env.Append(CPPPATH=Dir('.'))
|
||||||
|
env.Append(LIBS=['gzstream'])
|
||||||
|
env.Append(LIBPATH=[Dir('.')])
|
||||||
|
|
1
ext/gzstream/VERSION
Normal file
1
ext/gzstream/VERSION
Normal file
|
@ -0,0 +1 @@
|
||||||
|
1.5 (08 Jan 2003)
|
165
ext/gzstream/gzstream.cc
Normal file
165
ext/gzstream/gzstream.cc
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
// ============================================================================
|
||||||
|
// gzstream, C++ iostream classes wrapping the zlib compression library.
|
||||||
|
// Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2.1 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
// ============================================================================
|
||||||
|
//
|
||||||
|
// File : gzstream.C
|
||||||
|
// Revision : $Revision: 1.7 $
|
||||||
|
// Revision_date : $Date: 2003/01/08 14:41:27 $
|
||||||
|
// Author(s) : Deepak Bandyopadhyay, Lutz Kettner
|
||||||
|
//
|
||||||
|
// Standard streambuf implementation following Nicolai Josuttis, "The
|
||||||
|
// Standard C++ Library".
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
#include <gzstream.hh>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string.h> // for memcpy
|
||||||
|
|
||||||
|
#ifdef GZSTREAM_NAMESPACE
|
||||||
|
namespace GZSTREAM_NAMESPACE {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Internal classes to implement gzstream. See header file for user classes.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// class gzstreambuf:
|
||||||
|
// --------------------------------------
|
||||||
|
|
||||||
|
gzstreambuf* gzstreambuf::open( const char* name, int open_mode) {
|
||||||
|
if ( is_open())
|
||||||
|
return (gzstreambuf*)0;
|
||||||
|
mode = open_mode;
|
||||||
|
// no append nor read/write mode
|
||||||
|
if ((mode & std::ios::ate) || (mode & std::ios::app)
|
||||||
|
|| ((mode & std::ios::in) && (mode & std::ios::out)))
|
||||||
|
return (gzstreambuf*)0;
|
||||||
|
char fmode[10];
|
||||||
|
char* fmodeptr = fmode;
|
||||||
|
if ( mode & std::ios::in)
|
||||||
|
*fmodeptr++ = 'r';
|
||||||
|
else if ( mode & std::ios::out)
|
||||||
|
*fmodeptr++ = 'w';
|
||||||
|
*fmodeptr++ = 'b';
|
||||||
|
*fmodeptr = '\0';
|
||||||
|
file = gzopen( name, fmode);
|
||||||
|
if (file == 0)
|
||||||
|
return (gzstreambuf*)0;
|
||||||
|
opened = 1;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
gzstreambuf * gzstreambuf::close() {
|
||||||
|
if ( is_open()) {
|
||||||
|
sync();
|
||||||
|
opened = 0;
|
||||||
|
if ( gzclose( file) == Z_OK)
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
return (gzstreambuf*)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gzstreambuf::underflow() { // used for input buffer only
|
||||||
|
if ( gptr() && ( gptr() < egptr()))
|
||||||
|
return * reinterpret_cast<unsigned char *>( gptr());
|
||||||
|
|
||||||
|
if ( ! (mode & std::ios::in) || ! opened)
|
||||||
|
return EOF;
|
||||||
|
// Josuttis' implementation of inbuf
|
||||||
|
int n_putback = gptr() - eback();
|
||||||
|
if ( n_putback > 4)
|
||||||
|
n_putback = 4;
|
||||||
|
memcpy( buffer + (4 - n_putback), gptr() - n_putback, n_putback);
|
||||||
|
|
||||||
|
int num = gzread( file, buffer+4, bufferSize-4);
|
||||||
|
if (num <= 0) // ERROR or EOF
|
||||||
|
return EOF;
|
||||||
|
|
||||||
|
// reset buffer pointers
|
||||||
|
setg( buffer + (4 - n_putback), // beginning of putback area
|
||||||
|
buffer + 4, // read position
|
||||||
|
buffer + 4 + num); // end of buffer
|
||||||
|
|
||||||
|
// return next character
|
||||||
|
return *reinterpret_cast<unsigned char *>(gptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
int gzstreambuf::flush_buffer() {
|
||||||
|
// Separate the writing of the buffer from overflow() and
|
||||||
|
// sync() operation.
|
||||||
|
int w = pptr() - pbase();
|
||||||
|
if ( gzwrite( file, pbase(), w) != w)
|
||||||
|
return EOF;
|
||||||
|
pbump( -w);
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gzstreambuf::overflow( int c) { // used for output buffer only
|
||||||
|
if ( ! ( mode & std::ios::out) || ! opened)
|
||||||
|
return EOF;
|
||||||
|
if (c != EOF) {
|
||||||
|
*pptr() = c;
|
||||||
|
pbump(1);
|
||||||
|
}
|
||||||
|
if ( flush_buffer() == EOF)
|
||||||
|
return EOF;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gzstreambuf::sync() {
|
||||||
|
// Changed to use flush_buffer() instead of overflow( EOF)
|
||||||
|
// which caused improper behavior with std::endl and flush(),
|
||||||
|
// bug reported by Vincent Ricard.
|
||||||
|
if ( pptr() && pptr() > pbase()) {
|
||||||
|
if ( flush_buffer() == EOF)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// class gzstreambase:
|
||||||
|
// --------------------------------------
|
||||||
|
|
||||||
|
gzstreambase::gzstreambase( const char* name, int mode) {
|
||||||
|
init( &buf);
|
||||||
|
open( name, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
gzstreambase::~gzstreambase() {
|
||||||
|
buf.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void gzstreambase::open( const char* name, int open_mode) {
|
||||||
|
if ( ! buf.open( name, open_mode))
|
||||||
|
clear( rdstate() | std::ios::badbit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gzstreambase::close() {
|
||||||
|
if ( buf.is_open())
|
||||||
|
if ( ! buf.close())
|
||||||
|
clear( rdstate() | std::ios::badbit);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef GZSTREAM_NAMESPACE
|
||||||
|
} // namespace GZSTREAM_NAMESPACE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// EOF //
|
122
ext/gzstream/gzstream.hh
Normal file
122
ext/gzstream/gzstream.hh
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
// ============================================================================
|
||||||
|
// gzstream, C++ iostream classes wrapping the zlib compression library.
|
||||||
|
// Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2.1 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
// ============================================================================
|
||||||
|
//
|
||||||
|
// File : gzstream.h
|
||||||
|
// Revision : $Revision: 1.5 $
|
||||||
|
// Revision_date : $Date: 2002/04/26 23:30:15 $
|
||||||
|
// Author(s) : Deepak Bandyopadhyay, Lutz Kettner
|
||||||
|
//
|
||||||
|
// Standard streambuf implementation following Nicolai Josuttis, "The
|
||||||
|
// Standard C++ Library".
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
#ifndef GZSTREAM_H
|
||||||
|
#define GZSTREAM_H 1
|
||||||
|
|
||||||
|
// standard C++ with new header file names and std:: namespace
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
#ifdef GZSTREAM_NAMESPACE
|
||||||
|
namespace GZSTREAM_NAMESPACE {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Internal classes to implement gzstream. See below for user classes.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class gzstreambuf : public std::streambuf {
|
||||||
|
private:
|
||||||
|
static const int bufferSize = 47+256; // size of data buff
|
||||||
|
// totals 512 bytes under g++ for igzstream at the end.
|
||||||
|
|
||||||
|
gzFile file; // file handle for compressed file
|
||||||
|
char buffer[bufferSize]; // data buffer
|
||||||
|
char opened; // open/close state of stream
|
||||||
|
int mode; // I/O mode
|
||||||
|
|
||||||
|
int flush_buffer();
|
||||||
|
public:
|
||||||
|
gzstreambuf() : opened(0) {
|
||||||
|
setp( buffer, buffer + (bufferSize-1));
|
||||||
|
setg( buffer + 4, // beginning of putback area
|
||||||
|
buffer + 4, // read position
|
||||||
|
buffer + 4); // end position
|
||||||
|
// ASSERT: both input & output capabilities will not be used together
|
||||||
|
}
|
||||||
|
int is_open() { return opened; }
|
||||||
|
gzstreambuf* open( const char* name, int open_mode);
|
||||||
|
gzstreambuf* close();
|
||||||
|
~gzstreambuf() { close(); }
|
||||||
|
|
||||||
|
virtual int overflow( int c = EOF);
|
||||||
|
virtual int underflow();
|
||||||
|
virtual int sync();
|
||||||
|
};
|
||||||
|
|
||||||
|
class gzstreambase : virtual public std::ios {
|
||||||
|
protected:
|
||||||
|
gzstreambuf buf;
|
||||||
|
public:
|
||||||
|
gzstreambase() { init(&buf); }
|
||||||
|
gzstreambase( const char* name, int open_mode);
|
||||||
|
~gzstreambase();
|
||||||
|
int is_open() { return buf.is_open(); }
|
||||||
|
void open( const char* name, int open_mode);
|
||||||
|
void close();
|
||||||
|
gzstreambuf* rdbuf() { return &buf; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// User classes. Use igzstream and ogzstream analogously to ifstream and
|
||||||
|
// ofstream respectively. They read and write files based on the gz*
|
||||||
|
// function interface of the zlib. Files are compatible with gzip compression.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class igzstream : public gzstreambase, public std::istream {
|
||||||
|
public:
|
||||||
|
igzstream() : std::istream( &buf) {}
|
||||||
|
igzstream( const char* name, int open_mode = std::ios::in)
|
||||||
|
: gzstreambase( name, open_mode | std::ios::in), std::istream( &buf) {}
|
||||||
|
gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }
|
||||||
|
void open( const char* name, int open_mode = std::ios::in) {
|
||||||
|
gzstreambase::open( name, open_mode);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ogzstream : public gzstreambase, public std::ostream {
|
||||||
|
public:
|
||||||
|
ogzstream() : std::ostream( &buf) {}
|
||||||
|
ogzstream( const char* name, int mode = std::ios::out)
|
||||||
|
: gzstreambase( name, mode | std::ios::out), std::ostream( &buf) {}
|
||||||
|
gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }
|
||||||
|
void open( const char* name, int open_mode = std::ios::out) {
|
||||||
|
gzstreambase::open( name, open_mode);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef GZSTREAM_NAMESPACE
|
||||||
|
} // namespace GZSTREAM_NAMESPACE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // GZSTREAM_H
|
||||||
|
// ============================================================================
|
||||||
|
// EOF //
|
||||||
|
|
|
@ -87,16 +87,13 @@ ElfFile('libelf_convert.c')
|
||||||
ElfFile('libelf_fsize.c')
|
ElfFile('libelf_fsize.c')
|
||||||
ElfFile('libelf_msize.c')
|
ElfFile('libelf_msize.c')
|
||||||
|
|
||||||
m4env = Environment(ENV=os.environ)
|
m4env = env.Clone()
|
||||||
|
if env['GCC']:
|
||||||
if env.get('CC'):
|
major,minor,dot = [ int(x) for x in env['CXXVERSION'].split('.')]
|
||||||
m4env['CC'] = env['CC']
|
if major >= 4:
|
||||||
if env.get('CXX'):
|
m4env.Append(CCFLAGS=['-Wno-pointer-sign'])
|
||||||
m4env['CXX'] = env['CXX']
|
m4env.Append(CCFLAGS=['-Wno-implicit'])
|
||||||
|
del m4env['CPPPATH']
|
||||||
if env.get('OSX64bit'):
|
|
||||||
m4env.Append(CFLAGS='-arch x86_64')
|
|
||||||
m4env.Append(LINKFLAGS='-arch x86_64')
|
|
||||||
|
|
||||||
# If we have gm4 use it
|
# If we have gm4 use it
|
||||||
if m4env.Detect('gm4'):
|
if m4env.Detect('gm4'):
|
||||||
|
@ -117,7 +114,10 @@ m4env.M4(target=File('libelf_fsize.c'),
|
||||||
source=[File('elf_types.m4'), File('libelf_fsize.m4')])
|
source=[File('elf_types.m4'), File('libelf_fsize.m4')])
|
||||||
m4env.M4(target=File('libelf_msize.c'),
|
m4env.M4(target=File('libelf_msize.c'),
|
||||||
source=[File('elf_types.m4'), File('libelf_msize.m4')])
|
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(CPPPATH=Dir('.'))
|
||||||
env.Append(LIBS=['elf'])
|
env.Append(LIBS=['elf'])
|
||||||
|
|
805
src/SConscript
805
src/SConscript
File diff suppressed because it is too large
Load diff
|
@ -49,13 +49,13 @@ isa_switch_hdrs = Split('''
|
||||||
isa_traits.hh
|
isa_traits.hh
|
||||||
kernel_stats.hh
|
kernel_stats.hh
|
||||||
locked_mem.hh
|
locked_mem.hh
|
||||||
|
microcode_rom.hh
|
||||||
mmaped_ipr.hh
|
mmaped_ipr.hh
|
||||||
process.hh
|
process.hh
|
||||||
predecoder.hh
|
predecoder.hh
|
||||||
regfile.hh
|
regfile.hh
|
||||||
remote_gdb.hh
|
remote_gdb.hh
|
||||||
stacktrace.hh
|
stacktrace.hh
|
||||||
syscallreturn.hh
|
|
||||||
tlb.hh
|
tlb.hh
|
||||||
types.hh
|
types.hh
|
||||||
utility.hh
|
utility.hh
|
||||||
|
@ -125,3 +125,8 @@ else:
|
||||||
emitter = isa_desc_emitter)
|
emitter = isa_desc_emitter)
|
||||||
|
|
||||||
env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder })
|
env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder })
|
||||||
|
|
||||||
|
TraceFlag('IntRegs')
|
||||||
|
TraceFlag('FloatRegs')
|
||||||
|
TraceFlag('MiscRegs')
|
||||||
|
CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'MiscRegs' ])
|
||||||
|
|
33
src/arch/alpha/AlphaInterrupts.py
Normal file
33
src/arch/alpha/AlphaInterrupts.py
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# Copyright (c) 2008 The Regents of The University of Michigan
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met: redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer;
|
||||||
|
# redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution;
|
||||||
|
# neither the name of the copyright holders nor the names of its
|
||||||
|
# contributors may be used to endorse or promote products derived from
|
||||||
|
# this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
# Authors: Gabe Black
|
||||||
|
|
||||||
|
from m5.SimObject import SimObject
|
||||||
|
|
||||||
|
class AlphaInterrupts(SimObject):
|
||||||
|
type = 'AlphaInterrupts'
|
||||||
|
cxx_class = 'AlphaISA::Interrupts'
|
|
@ -28,21 +28,20 @@
|
||||||
|
|
||||||
from m5.SimObject import SimObject
|
from m5.SimObject import SimObject
|
||||||
from m5.params import *
|
from m5.params import *
|
||||||
class AlphaTLB(SimObject):
|
|
||||||
|
from BaseTLB import BaseTLB
|
||||||
|
|
||||||
|
class AlphaTLB(BaseTLB):
|
||||||
type = 'AlphaTLB'
|
type = 'AlphaTLB'
|
||||||
abstract = True
|
abstract = True
|
||||||
size = Param.Int("TLB size")
|
size = Param.Int("TLB size")
|
||||||
|
|
||||||
class AlphaDTB(AlphaTLB):
|
class AlphaDTB(AlphaTLB):
|
||||||
type = 'AlphaDTB'
|
type = 'AlphaDTB'
|
||||||
cxx_namespace = 'AlphaISA'
|
cxx_class = 'AlphaISA::DTB'
|
||||||
cxx_class = 'DTB'
|
|
||||||
|
|
||||||
size = 64
|
size = 64
|
||||||
|
|
||||||
class AlphaITB(AlphaTLB):
|
class AlphaITB(AlphaTLB):
|
||||||
type = 'AlphaITB'
|
type = 'AlphaITB'
|
||||||
cxx_namespace = 'AlphaISA'
|
cxx_class = 'AlphaISA::ITB'
|
||||||
cxx_class = 'ITB'
|
|
||||||
|
|
||||||
size = 48
|
size = 48
|
||||||
|
|
|
@ -47,9 +47,11 @@ if env['TARGET_ISA'] == 'alpha':
|
||||||
SimObject('AlphaTLB.py')
|
SimObject('AlphaTLB.py')
|
||||||
|
|
||||||
if env['FULL_SYSTEM']:
|
if env['FULL_SYSTEM']:
|
||||||
|
SimObject('AlphaInterrupts.py')
|
||||||
SimObject('AlphaSystem.py')
|
SimObject('AlphaSystem.py')
|
||||||
|
|
||||||
Source('idle_event.cc')
|
Source('idle_event.cc')
|
||||||
|
Source('interrupts.cc')
|
||||||
Source('kernel_stats.cc')
|
Source('kernel_stats.cc')
|
||||||
Source('osfpal.cc')
|
Source('osfpal.cc')
|
||||||
Source('stacktrace.cc')
|
Source('stacktrace.cc')
|
||||||
|
|
|
@ -33,5 +33,5 @@ Import('*')
|
||||||
all_isa_list.append('alpha')
|
all_isa_list.append('alpha')
|
||||||
|
|
||||||
# Alpha can be compiled with Turbolaser support instead of Tsunami
|
# 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))
|
'Model Alpha TurboLaser platform (vs. Tsunami)', False))
|
||||||
|
|
|
@ -36,35 +36,35 @@
|
||||||
/// Funky Alpha 64-bit a.out header used for PAL code.
|
/// Funky Alpha 64-bit a.out header used for PAL code.
|
||||||
///
|
///
|
||||||
struct aout_exechdr {
|
struct aout_exechdr {
|
||||||
uint16_t magic; ///< magic number
|
uint16_t magic; ///< magic number
|
||||||
uint16_t vstamp; ///< version stamp?
|
uint16_t vstamp; ///< version stamp?
|
||||||
uint16_t bldrev; ///< ???
|
uint16_t bldrev; ///< ???
|
||||||
uint16_t padcell; ///< padding
|
uint16_t padcell; ///< padding
|
||||||
uint64_t tsize; ///< text segment size
|
uint64_t tsize; ///< text segment size
|
||||||
uint64_t dsize; ///< data segment size
|
uint64_t dsize; ///< data segment size
|
||||||
uint64_t bsize; ///< bss segment size
|
uint64_t bsize; ///< bss segment size
|
||||||
uint64_t entry; ///< entry point
|
uint64_t entry; ///< entry point
|
||||||
uint64_t text_start; ///< text base address
|
uint64_t text_start; ///< text base address
|
||||||
uint64_t data_start; ///< data base address
|
uint64_t data_start; ///< data base address
|
||||||
uint64_t bss_start; ///< bss base address
|
uint64_t bss_start; ///< bss base address
|
||||||
uint32_t gprmask; ///< GPR mask (unused, AFAIK)
|
uint32_t gprmask; ///< GPR mask (unused, AFAIK)
|
||||||
uint32_t fprmask; ///< FPR mask (unused, AFAIK)
|
uint32_t fprmask; ///< FPR mask (unused, AFAIK)
|
||||||
uint64_t gp_value; ///< global pointer reg value
|
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_BADMAX
|
||||||
|
|
||||||
#define N_TXTADDR(ex) ((ex).text_start)
|
#define N_TXTADDR(ex) ((ex).text_start)
|
||||||
#define N_DATADDR(ex) ((ex).data_start)
|
#define N_DATADDR(ex) ((ex).data_start)
|
||||||
#define N_BSSADDR(ex) ((ex).bss_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))
|
(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__*/
|
#endif /* !__AOUT_MACHDEP_H__*/
|
||||||
|
|
|
@ -35,32 +35,33 @@
|
||||||
#include "arch/alpha/osfpal.hh"
|
#include "arch/alpha/osfpal.hh"
|
||||||
#include "arch/alpha/tlb.hh"
|
#include "arch/alpha/tlb.hh"
|
||||||
#include "arch/alpha/kgdb.h"
|
#include "arch/alpha/kgdb.h"
|
||||||
|
#include "base/cp_annotate.hh"
|
||||||
|
#include "base/debug.hh"
|
||||||
#include "base/remote_gdb.hh"
|
#include "base/remote_gdb.hh"
|
||||||
#include "base/stats/events.hh"
|
#include "base/stats/events.hh"
|
||||||
#include "config/full_system.hh"
|
#include "config/full_system.hh"
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "cpu/simple_thread.hh"
|
#include "cpu/simple_thread.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "sim/debug.hh"
|
|
||||||
#include "sim/sim_exit.hh"
|
#include "sim/sim_exit.hh"
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
namespace AlphaISA {
|
||||||
|
|
||||||
using namespace EV5;
|
#if FULL_SYSTEM
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Machine dependent functions
|
// Machine dependent functions
|
||||||
//
|
//
|
||||||
void
|
void
|
||||||
AlphaISA::initCPU(ThreadContext *tc, int cpuId)
|
initCPU(ThreadContext *tc, int cpuId)
|
||||||
{
|
{
|
||||||
initIPRs(tc, cpuId);
|
initIPRs(tc, cpuId);
|
||||||
|
|
||||||
tc->setIntReg(16, cpuId);
|
tc->setIntReg(16, cpuId);
|
||||||
tc->setIntReg(0, 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->setPC(tc->readMiscRegNoEffect(IPR_PAL_BASE) + reset->vect());
|
||||||
tc->setNextPC(tc->readPC() + sizeof(MachInst));
|
tc->setNextPC(tc->readPC() + sizeof(MachInst));
|
||||||
|
@ -71,7 +72,7 @@ AlphaISA::initCPU(ThreadContext *tc, int cpuId)
|
||||||
|
|
||||||
template <class CPU>
|
template <class CPU>
|
||||||
void
|
void
|
||||||
AlphaISA::processInterrupts(CPU *cpu)
|
processInterrupts(CPU *cpu)
|
||||||
{
|
{
|
||||||
//Check if there are any outstanding interrupts
|
//Check if there are any outstanding interrupts
|
||||||
//Handle the interrupts
|
//Handle the interrupts
|
||||||
|
@ -117,7 +118,7 @@ AlphaISA::processInterrupts(CPU *cpu)
|
||||||
|
|
||||||
template <class CPU>
|
template <class CPU>
|
||||||
void
|
void
|
||||||
AlphaISA::zeroRegisters(CPU *cpu)
|
zeroRegisters(CPU *cpu)
|
||||||
{
|
{
|
||||||
// Insure ISA semantics
|
// Insure ISA semantics
|
||||||
// (no longer very clean due to the change in setIntReg() in the
|
// (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);
|
cpu->thread->setFloatReg(ZeroReg, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Fault
|
int
|
||||||
SimpleThread::hwrei()
|
MiscRegFile::getInstAsid()
|
||||||
{
|
{
|
||||||
if (!(readPC() & 0x3))
|
return ITB_ASN_ASN(ipr[IPR_ITB_ASN]);
|
||||||
return new UnimplementedOpcodeFault;
|
|
||||||
|
|
||||||
setNextPC(readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR));
|
|
||||||
|
|
||||||
if (!misspeculating()) {
|
|
||||||
if (kernelStats)
|
|
||||||
kernelStats->hwrei();
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: XXX check for interrupts? XXX
|
|
||||||
return NoFault;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
AlphaISA::MiscRegFile::getInstAsid()
|
MiscRegFile::getDataAsid()
|
||||||
{
|
{
|
||||||
return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]);
|
return DTB_ASN_ASN(ipr[IPR_DTB_ASN]);
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
AlphaISA::MiscRegFile::getDataAsid()
|
|
||||||
{
|
|
||||||
return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -162,90 +146,90 @@ AlphaISA::MiscRegFile::getDataAsid()
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
void
|
void
|
||||||
AlphaISA::initIPRs(ThreadContext *tc, int cpuId)
|
initIPRs(ThreadContext *tc, int cpuId)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NumInternalProcRegs; ++i) {
|
for (int i = 0; i < NumInternalProcRegs; ++i) {
|
||||||
tc->setMiscRegNoEffect(i, 0);
|
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_MCSR, 0x6);
|
||||||
tc->setMiscRegNoEffect(IPR_PALtemp16, cpuId);
|
tc->setMiscRegNoEffect(IPR_PALtemp16, cpuId);
|
||||||
}
|
}
|
||||||
|
|
||||||
AlphaISA::MiscReg
|
MiscReg
|
||||||
AlphaISA::MiscRegFile::readIpr(int idx, ThreadContext *tc)
|
MiscRegFile::readIpr(int idx, ThreadContext *tc)
|
||||||
{
|
{
|
||||||
uint64_t retval = 0; // return value, default 0
|
uint64_t retval = 0; // return value, default 0
|
||||||
|
|
||||||
switch (idx) {
|
switch (idx) {
|
||||||
case AlphaISA::IPR_PALtemp0:
|
case IPR_PALtemp0:
|
||||||
case AlphaISA::IPR_PALtemp1:
|
case IPR_PALtemp1:
|
||||||
case AlphaISA::IPR_PALtemp2:
|
case IPR_PALtemp2:
|
||||||
case AlphaISA::IPR_PALtemp3:
|
case IPR_PALtemp3:
|
||||||
case AlphaISA::IPR_PALtemp4:
|
case IPR_PALtemp4:
|
||||||
case AlphaISA::IPR_PALtemp5:
|
case IPR_PALtemp5:
|
||||||
case AlphaISA::IPR_PALtemp6:
|
case IPR_PALtemp6:
|
||||||
case AlphaISA::IPR_PALtemp7:
|
case IPR_PALtemp7:
|
||||||
case AlphaISA::IPR_PALtemp8:
|
case IPR_PALtemp8:
|
||||||
case AlphaISA::IPR_PALtemp9:
|
case IPR_PALtemp9:
|
||||||
case AlphaISA::IPR_PALtemp10:
|
case IPR_PALtemp10:
|
||||||
case AlphaISA::IPR_PALtemp11:
|
case IPR_PALtemp11:
|
||||||
case AlphaISA::IPR_PALtemp12:
|
case IPR_PALtemp12:
|
||||||
case AlphaISA::IPR_PALtemp13:
|
case IPR_PALtemp13:
|
||||||
case AlphaISA::IPR_PALtemp14:
|
case IPR_PALtemp14:
|
||||||
case AlphaISA::IPR_PALtemp15:
|
case IPR_PALtemp15:
|
||||||
case AlphaISA::IPR_PALtemp16:
|
case IPR_PALtemp16:
|
||||||
case AlphaISA::IPR_PALtemp17:
|
case IPR_PALtemp17:
|
||||||
case AlphaISA::IPR_PALtemp18:
|
case IPR_PALtemp18:
|
||||||
case AlphaISA::IPR_PALtemp19:
|
case IPR_PALtemp19:
|
||||||
case AlphaISA::IPR_PALtemp20:
|
case IPR_PALtemp20:
|
||||||
case AlphaISA::IPR_PALtemp21:
|
case IPR_PALtemp21:
|
||||||
case AlphaISA::IPR_PALtemp22:
|
case IPR_PALtemp22:
|
||||||
case AlphaISA::IPR_PALtemp23:
|
case IPR_PALtemp23:
|
||||||
case AlphaISA::IPR_PAL_BASE:
|
case IPR_PAL_BASE:
|
||||||
|
|
||||||
case AlphaISA::IPR_IVPTBR:
|
case IPR_IVPTBR:
|
||||||
case AlphaISA::IPR_DC_MODE:
|
case IPR_DC_MODE:
|
||||||
case AlphaISA::IPR_MAF_MODE:
|
case IPR_MAF_MODE:
|
||||||
case AlphaISA::IPR_ISR:
|
case IPR_ISR:
|
||||||
case AlphaISA::IPR_EXC_ADDR:
|
case IPR_EXC_ADDR:
|
||||||
case AlphaISA::IPR_IC_PERR_STAT:
|
case IPR_IC_PERR_STAT:
|
||||||
case AlphaISA::IPR_DC_PERR_STAT:
|
case IPR_DC_PERR_STAT:
|
||||||
case AlphaISA::IPR_MCSR:
|
case IPR_MCSR:
|
||||||
case AlphaISA::IPR_ASTRR:
|
case IPR_ASTRR:
|
||||||
case AlphaISA::IPR_ASTER:
|
case IPR_ASTER:
|
||||||
case AlphaISA::IPR_SIRR:
|
case IPR_SIRR:
|
||||||
case AlphaISA::IPR_ICSR:
|
case IPR_ICSR:
|
||||||
case AlphaISA::IPR_ICM:
|
case IPR_ICM:
|
||||||
case AlphaISA::IPR_DTB_CM:
|
case IPR_DTB_CM:
|
||||||
case AlphaISA::IPR_IPLR:
|
case IPR_IPLR:
|
||||||
case AlphaISA::IPR_INTID:
|
case IPR_INTID:
|
||||||
case AlphaISA::IPR_PMCTR:
|
case IPR_PMCTR:
|
||||||
// no side-effect
|
// no side-effect
|
||||||
retval = ipr[idx];
|
retval = ipr[idx];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_CC:
|
case IPR_CC:
|
||||||
retval |= ipr[idx] & ULL(0xffffffff00000000);
|
retval |= ipr[idx] & ULL(0xffffffff00000000);
|
||||||
retval |= tc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff);
|
retval |= tc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_VA:
|
case IPR_VA:
|
||||||
retval = ipr[idx];
|
retval = ipr[idx];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_VA_FORM:
|
case IPR_VA_FORM:
|
||||||
case AlphaISA::IPR_MM_STAT:
|
case IPR_MM_STAT:
|
||||||
case AlphaISA::IPR_IFAULT_VA_FORM:
|
case IPR_IFAULT_VA_FORM:
|
||||||
case AlphaISA::IPR_EXC_MASK:
|
case IPR_EXC_MASK:
|
||||||
case AlphaISA::IPR_EXC_SUM:
|
case IPR_EXC_SUM:
|
||||||
retval = ipr[idx];
|
retval = ipr[idx];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_DTB_PTE:
|
case IPR_DTB_PTE:
|
||||||
{
|
{
|
||||||
AlphaISA::TlbEntry &entry
|
TlbEntry &entry
|
||||||
= tc->getDTBPtr()->index(!tc->misspeculating());
|
= tc->getDTBPtr()->index(!tc->misspeculating());
|
||||||
|
|
||||||
retval |= ((uint64_t)entry.ppn & ULL(0x7ffffff)) << 32;
|
retval |= ((uint64_t)entry.ppn & ULL(0x7ffffff)) << 32;
|
||||||
|
@ -259,15 +243,15 @@ AlphaISA::MiscRegFile::readIpr(int idx, ThreadContext *tc)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// write only registers
|
// write only registers
|
||||||
case AlphaISA::IPR_HWINT_CLR:
|
case IPR_HWINT_CLR:
|
||||||
case AlphaISA::IPR_SL_XMIT:
|
case IPR_SL_XMIT:
|
||||||
case AlphaISA::IPR_DC_FLUSH:
|
case IPR_DC_FLUSH:
|
||||||
case AlphaISA::IPR_IC_FLUSH:
|
case IPR_IC_FLUSH:
|
||||||
case AlphaISA::IPR_ALT_MODE:
|
case IPR_ALT_MODE:
|
||||||
case AlphaISA::IPR_DTB_IA:
|
case IPR_DTB_IA:
|
||||||
case AlphaISA::IPR_DTB_IAP:
|
case IPR_DTB_IAP:
|
||||||
case AlphaISA::IPR_ITB_IA:
|
case IPR_ITB_IA:
|
||||||
case AlphaISA::IPR_ITB_IAP:
|
case IPR_ITB_IAP:
|
||||||
panic("Tried to read write only register %d\n", idx);
|
panic("Tried to read write only register %d\n", idx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -286,7 +270,7 @@ int break_ipl = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
|
MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
|
||||||
{
|
{
|
||||||
uint64_t old;
|
uint64_t old;
|
||||||
|
|
||||||
|
@ -294,52 +278,52 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (idx) {
|
switch (idx) {
|
||||||
case AlphaISA::IPR_PALtemp0:
|
case IPR_PALtemp0:
|
||||||
case AlphaISA::IPR_PALtemp1:
|
case IPR_PALtemp1:
|
||||||
case AlphaISA::IPR_PALtemp2:
|
case IPR_PALtemp2:
|
||||||
case AlphaISA::IPR_PALtemp3:
|
case IPR_PALtemp3:
|
||||||
case AlphaISA::IPR_PALtemp4:
|
case IPR_PALtemp4:
|
||||||
case AlphaISA::IPR_PALtemp5:
|
case IPR_PALtemp5:
|
||||||
case AlphaISA::IPR_PALtemp6:
|
case IPR_PALtemp6:
|
||||||
case AlphaISA::IPR_PALtemp7:
|
case IPR_PALtemp7:
|
||||||
case AlphaISA::IPR_PALtemp8:
|
case IPR_PALtemp8:
|
||||||
case AlphaISA::IPR_PALtemp9:
|
case IPR_PALtemp9:
|
||||||
case AlphaISA::IPR_PALtemp10:
|
case IPR_PALtemp10:
|
||||||
case AlphaISA::IPR_PALtemp11:
|
case IPR_PALtemp11:
|
||||||
case AlphaISA::IPR_PALtemp12:
|
case IPR_PALtemp12:
|
||||||
case AlphaISA::IPR_PALtemp13:
|
case IPR_PALtemp13:
|
||||||
case AlphaISA::IPR_PALtemp14:
|
case IPR_PALtemp14:
|
||||||
case AlphaISA::IPR_PALtemp15:
|
case IPR_PALtemp15:
|
||||||
case AlphaISA::IPR_PALtemp16:
|
case IPR_PALtemp16:
|
||||||
case AlphaISA::IPR_PALtemp17:
|
case IPR_PALtemp17:
|
||||||
case AlphaISA::IPR_PALtemp18:
|
case IPR_PALtemp18:
|
||||||
case AlphaISA::IPR_PALtemp19:
|
case IPR_PALtemp19:
|
||||||
case AlphaISA::IPR_PALtemp20:
|
case IPR_PALtemp20:
|
||||||
case AlphaISA::IPR_PALtemp21:
|
case IPR_PALtemp21:
|
||||||
case AlphaISA::IPR_PALtemp22:
|
case IPR_PALtemp22:
|
||||||
case AlphaISA::IPR_PAL_BASE:
|
case IPR_PAL_BASE:
|
||||||
case AlphaISA::IPR_IC_PERR_STAT:
|
case IPR_IC_PERR_STAT:
|
||||||
case AlphaISA::IPR_DC_PERR_STAT:
|
case IPR_DC_PERR_STAT:
|
||||||
case AlphaISA::IPR_PMCTR:
|
case IPR_PMCTR:
|
||||||
// write entire quad w/ no side-effect
|
// write entire quad w/ no side-effect
|
||||||
ipr[idx] = val;
|
ipr[idx] = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_CC_CTL:
|
case IPR_CC_CTL:
|
||||||
// This IPR resets the cycle counter. We assume this only
|
// This IPR resets the cycle counter. We assume this only
|
||||||
// happens once... let's verify that.
|
// happens once... let's verify that.
|
||||||
assert(ipr[idx] == 0);
|
assert(ipr[idx] == 0);
|
||||||
ipr[idx] = 1;
|
ipr[idx] = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_CC:
|
case IPR_CC:
|
||||||
// This IPR only writes the upper 64 bits. It's ok to write
|
// 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
|
// all 64 here since we mask out the lower 32 in rpcc (see
|
||||||
// isa_desc).
|
// isa_desc).
|
||||||
ipr[idx] = val;
|
ipr[idx] = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_PALtemp23:
|
case IPR_PALtemp23:
|
||||||
// write entire quad w/ no side-effect
|
// write entire quad w/ no side-effect
|
||||||
old = ipr[idx];
|
old = ipr[idx];
|
||||||
ipr[idx] = val;
|
ipr[idx] = val;
|
||||||
|
@ -349,23 +333,23 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_DTB_PTE:
|
case IPR_DTB_PTE:
|
||||||
// write entire quad w/ no side-effect, tag is forthcoming
|
// write entire quad w/ no side-effect, tag is forthcoming
|
||||||
ipr[idx] = val;
|
ipr[idx] = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_EXC_ADDR:
|
case IPR_EXC_ADDR:
|
||||||
// second least significant bit in PC is always zero
|
// second least significant bit in PC is always zero
|
||||||
ipr[idx] = val & ~2;
|
ipr[idx] = val & ~2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_ASTRR:
|
case IPR_ASTRR:
|
||||||
case AlphaISA::IPR_ASTER:
|
case IPR_ASTER:
|
||||||
// only write least significant four bits - privilege mask
|
// only write least significant four bits - privilege mask
|
||||||
ipr[idx] = val & 0xf;
|
ipr[idx] = val & 0xf;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_IPLR:
|
case IPR_IPLR:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (break_ipl != -1 && break_ipl == (val & 0x1f))
|
if (break_ipl != -1 && break_ipl == (val & 0x1f))
|
||||||
debug_break();
|
debug_break();
|
||||||
|
@ -379,175 +363,173 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_DTB_CM:
|
case IPR_DTB_CM:
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
if (val & 0x18) {
|
if (val & 0x18) {
|
||||||
if (tc->getKernelStats())
|
if (tc->getKernelStats())
|
||||||
tc->getKernelStats()->mode(TheISA::Kernel::user, tc);
|
tc->getKernelStats()->mode(Kernel::user, tc);
|
||||||
} else {
|
} else {
|
||||||
if (tc->getKernelStats())
|
if (tc->getKernelStats())
|
||||||
tc->getKernelStats()->mode(TheISA::Kernel::kernel, tc);
|
tc->getKernelStats()->mode(Kernel::kernel, tc);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case AlphaISA::IPR_ICM:
|
case IPR_ICM:
|
||||||
// only write two mode bits - processor mode
|
// only write two mode bits - processor mode
|
||||||
ipr[idx] = val & 0x18;
|
ipr[idx] = val & 0x18;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_ALT_MODE:
|
case IPR_ALT_MODE:
|
||||||
// only write two mode bits - processor mode
|
// only write two mode bits - processor mode
|
||||||
ipr[idx] = val & 0x18;
|
ipr[idx] = val & 0x18;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_MCSR:
|
case IPR_MCSR:
|
||||||
// more here after optimization...
|
// more here after optimization...
|
||||||
ipr[idx] = val;
|
ipr[idx] = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_SIRR:
|
case IPR_SIRR:
|
||||||
// only write software interrupt mask
|
// only write software interrupt mask
|
||||||
ipr[idx] = val & 0x7fff0;
|
ipr[idx] = val & 0x7fff0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_ICSR:
|
case IPR_ICSR:
|
||||||
ipr[idx] = val & ULL(0xffffff0300);
|
ipr[idx] = val & ULL(0xffffff0300);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_IVPTBR:
|
case IPR_IVPTBR:
|
||||||
case AlphaISA::IPR_MVPTBR:
|
case IPR_MVPTBR:
|
||||||
ipr[idx] = val & ULL(0xffffffffc0000000);
|
ipr[idx] = val & ULL(0xffffffffc0000000);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_DC_TEST_CTL:
|
case IPR_DC_TEST_CTL:
|
||||||
ipr[idx] = val & 0x1ffb;
|
ipr[idx] = val & 0x1ffb;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_DC_MODE:
|
case IPR_DC_MODE:
|
||||||
case AlphaISA::IPR_MAF_MODE:
|
case IPR_MAF_MODE:
|
||||||
ipr[idx] = val & 0x3f;
|
ipr[idx] = val & 0x3f;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_ITB_ASN:
|
case IPR_ITB_ASN:
|
||||||
ipr[idx] = val & 0x7f0;
|
ipr[idx] = val & 0x7f0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_DTB_ASN:
|
case IPR_DTB_ASN:
|
||||||
ipr[idx] = val & ULL(0xfe00000000000000);
|
ipr[idx] = val & ULL(0xfe00000000000000);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_EXC_SUM:
|
case IPR_EXC_SUM:
|
||||||
case AlphaISA::IPR_EXC_MASK:
|
case IPR_EXC_MASK:
|
||||||
// any write to this register clears it
|
// any write to this register clears it
|
||||||
ipr[idx] = 0;
|
ipr[idx] = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_INTID:
|
case IPR_INTID:
|
||||||
case AlphaISA::IPR_SL_RCV:
|
case IPR_SL_RCV:
|
||||||
case AlphaISA::IPR_MM_STAT:
|
case IPR_MM_STAT:
|
||||||
case AlphaISA::IPR_ITB_PTE_TEMP:
|
case IPR_ITB_PTE_TEMP:
|
||||||
case AlphaISA::IPR_DTB_PTE_TEMP:
|
case IPR_DTB_PTE_TEMP:
|
||||||
// read-only registers
|
// read-only registers
|
||||||
panic("Tried to write read only ipr %d\n", idx);
|
panic("Tried to write read only ipr %d\n", idx);
|
||||||
|
|
||||||
case AlphaISA::IPR_HWINT_CLR:
|
case IPR_HWINT_CLR:
|
||||||
case AlphaISA::IPR_SL_XMIT:
|
case IPR_SL_XMIT:
|
||||||
case AlphaISA::IPR_DC_FLUSH:
|
case IPR_DC_FLUSH:
|
||||||
case AlphaISA::IPR_IC_FLUSH:
|
case IPR_IC_FLUSH:
|
||||||
// the following are write only
|
// the following are write only
|
||||||
ipr[idx] = val;
|
ipr[idx] = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_DTB_IA:
|
case IPR_DTB_IA:
|
||||||
// really a control write
|
// really a control write
|
||||||
ipr[idx] = 0;
|
ipr[idx] = 0;
|
||||||
|
|
||||||
tc->getDTBPtr()->flushAll();
|
tc->getDTBPtr()->flushAll();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_DTB_IAP:
|
case IPR_DTB_IAP:
|
||||||
// really a control write
|
// really a control write
|
||||||
ipr[idx] = 0;
|
ipr[idx] = 0;
|
||||||
|
|
||||||
tc->getDTBPtr()->flushProcesses();
|
tc->getDTBPtr()->flushProcesses();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_DTB_IS:
|
case IPR_DTB_IS:
|
||||||
// really a control write
|
// really a control write
|
||||||
ipr[idx] = val;
|
ipr[idx] = val;
|
||||||
|
|
||||||
tc->getDTBPtr()->flushAddr(val,
|
tc->getDTBPtr()->flushAddr(val, DTB_ASN_ASN(ipr[IPR_DTB_ASN]));
|
||||||
EV5::DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_DTB_TAG: {
|
case IPR_DTB_TAG: {
|
||||||
struct AlphaISA::TlbEntry entry;
|
struct TlbEntry entry;
|
||||||
|
|
||||||
// FIXME: granularity hints NYI...
|
// 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");
|
panic("PTE GH field != 0");
|
||||||
|
|
||||||
// write entire quad
|
// write entire quad
|
||||||
ipr[idx] = val;
|
ipr[idx] = val;
|
||||||
|
|
||||||
// construct PTE for new entry
|
// construct PTE for new entry
|
||||||
entry.ppn = EV5::DTB_PTE_PPN(ipr[AlphaISA::IPR_DTB_PTE]);
|
entry.ppn = DTB_PTE_PPN(ipr[IPR_DTB_PTE]);
|
||||||
entry.xre = EV5::DTB_PTE_XRE(ipr[AlphaISA::IPR_DTB_PTE]);
|
entry.xre = DTB_PTE_XRE(ipr[IPR_DTB_PTE]);
|
||||||
entry.xwe = EV5::DTB_PTE_XWE(ipr[AlphaISA::IPR_DTB_PTE]);
|
entry.xwe = DTB_PTE_XWE(ipr[IPR_DTB_PTE]);
|
||||||
entry.fonr = EV5::DTB_PTE_FONR(ipr[AlphaISA::IPR_DTB_PTE]);
|
entry.fonr = DTB_PTE_FONR(ipr[IPR_DTB_PTE]);
|
||||||
entry.fonw = EV5::DTB_PTE_FONW(ipr[AlphaISA::IPR_DTB_PTE]);
|
entry.fonw = DTB_PTE_FONW(ipr[IPR_DTB_PTE]);
|
||||||
entry.asma = EV5::DTB_PTE_ASMA(ipr[AlphaISA::IPR_DTB_PTE]);
|
entry.asma = DTB_PTE_ASMA(ipr[IPR_DTB_PTE]);
|
||||||
entry.asn = EV5::DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]);
|
entry.asn = DTB_ASN_ASN(ipr[IPR_DTB_ASN]);
|
||||||
|
|
||||||
// insert new TAG/PTE value into data TLB
|
// insert new TAG/PTE value into data TLB
|
||||||
tc->getDTBPtr()->insert(val, entry);
|
tc->getDTBPtr()->insert(val, entry);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_ITB_PTE: {
|
case IPR_ITB_PTE: {
|
||||||
struct AlphaISA::TlbEntry entry;
|
struct TlbEntry entry;
|
||||||
|
|
||||||
// FIXME: granularity hints NYI...
|
// FIXME: granularity hints NYI...
|
||||||
if (EV5::ITB_PTE_GH(val) != 0)
|
if (ITB_PTE_GH(val) != 0)
|
||||||
panic("PTE GH field != 0");
|
panic("PTE GH field != 0");
|
||||||
|
|
||||||
// write entire quad
|
// write entire quad
|
||||||
ipr[idx] = val;
|
ipr[idx] = val;
|
||||||
|
|
||||||
// construct PTE for new entry
|
// construct PTE for new entry
|
||||||
entry.ppn = EV5::ITB_PTE_PPN(val);
|
entry.ppn = ITB_PTE_PPN(val);
|
||||||
entry.xre = EV5::ITB_PTE_XRE(val);
|
entry.xre = ITB_PTE_XRE(val);
|
||||||
entry.xwe = 0;
|
entry.xwe = 0;
|
||||||
entry.fonr = EV5::ITB_PTE_FONR(val);
|
entry.fonr = ITB_PTE_FONR(val);
|
||||||
entry.fonw = EV5::ITB_PTE_FONW(val);
|
entry.fonw = ITB_PTE_FONW(val);
|
||||||
entry.asma = EV5::ITB_PTE_ASMA(val);
|
entry.asma = ITB_PTE_ASMA(val);
|
||||||
entry.asn = EV5::ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]);
|
entry.asn = ITB_ASN_ASN(ipr[IPR_ITB_ASN]);
|
||||||
|
|
||||||
// insert new TAG/PTE value into data TLB
|
// 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;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_ITB_IA:
|
case IPR_ITB_IA:
|
||||||
// really a control write
|
// really a control write
|
||||||
ipr[idx] = 0;
|
ipr[idx] = 0;
|
||||||
|
|
||||||
tc->getITBPtr()->flushAll();
|
tc->getITBPtr()->flushAll();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_ITB_IAP:
|
case IPR_ITB_IAP:
|
||||||
// really a control write
|
// really a control write
|
||||||
ipr[idx] = 0;
|
ipr[idx] = 0;
|
||||||
|
|
||||||
tc->getITBPtr()->flushProcesses();
|
tc->getITBPtr()->flushProcesses();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlphaISA::IPR_ITB_IS:
|
case IPR_ITB_IS:
|
||||||
// really a control write
|
// really a control write
|
||||||
ipr[idx] = val;
|
ipr[idx] = val;
|
||||||
|
|
||||||
tc->getITBPtr()->flushAddr(val,
|
tc->getITBPtr()->flushAddr(val, ITB_ASN_ASN(ipr[IPR_ITB_ASN]));
|
||||||
EV5::ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -558,17 +540,38 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
|
||||||
// no error...
|
// no error...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
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));
|
dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace AlphaISA
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#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.
|
* Check for special simulator handling of specific PAL calls.
|
||||||
* If return value is false, actual PAL call will be suppressed.
|
* If return value is false, actual PAL call will be suppressed.
|
||||||
|
|
|
@ -36,10 +36,7 @@
|
||||||
#include "config/alpha_tlaser.hh"
|
#include "config/alpha_tlaser.hh"
|
||||||
#include "arch/alpha/isa_traits.hh"
|
#include "arch/alpha/isa_traits.hh"
|
||||||
|
|
||||||
namespace EV5 {
|
namespace AlphaISA {
|
||||||
|
|
||||||
//It seems like a safe assumption EV5 only applies to alpha
|
|
||||||
using namespace AlphaISA;
|
|
||||||
|
|
||||||
#if ALPHA_TLASER
|
#if ALPHA_TLASER
|
||||||
const uint64_t AsnMask = ULL(0x7f);
|
const uint64_t AsnMask = ULL(0x7f);
|
||||||
|
@ -51,8 +48,8 @@ const int VAddrImplBits = 43;
|
||||||
const Addr VAddrImplMask = (ULL(1) << VAddrImplBits) - 1;
|
const Addr VAddrImplMask = (ULL(1) << VAddrImplBits) - 1;
|
||||||
const Addr VAddrUnImplMask = ~VAddrImplMask;
|
const Addr VAddrUnImplMask = ~VAddrImplMask;
|
||||||
inline Addr VAddrImpl(Addr a) { return a & VAddrImplMask; }
|
inline Addr VAddrImpl(Addr a) { return a & VAddrImplMask; }
|
||||||
inline Addr VAddrVPN(Addr a) { return a >> AlphaISA::PageShift; }
|
inline Addr VAddrVPN(Addr a) { return a >> PageShift; }
|
||||||
inline Addr VAddrOffset(Addr a) { return a & AlphaISA::PageOffset; }
|
inline Addr VAddrOffset(Addr a) { return a & PageOffset; }
|
||||||
inline Addr VAddrSpaceEV5(Addr a) { return a >> 41 & 0x3; }
|
inline Addr VAddrSpaceEV5(Addr a) { return a >> 41 & 0x3; }
|
||||||
inline Addr VAddrSpaceEV6(Addr a) { return a >> 41 & 0x7f; }
|
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 PAddrUncachedBit40 = ULL(0x10000000000);
|
||||||
const Addr PAddrUncachedBit43 = ULL(0x80000000000);
|
const Addr PAddrUncachedBit43 = ULL(0x80000000000);
|
||||||
const Addr PAddrUncachedMask = ULL(0x807ffffffff); // Clear PA<42:35>
|
const Addr PAddrUncachedMask = ULL(0x807ffffffff); // Clear PA<42:35>
|
||||||
inline Addr Phys2K0Seg(Addr addr)
|
|
||||||
|
inline Addr
|
||||||
|
Phys2K0Seg(Addr addr)
|
||||||
{
|
{
|
||||||
#if !ALPHA_TLASER
|
#if !ALPHA_TLASER
|
||||||
if (addr & PAddrUncachedBit43) {
|
if (addr & PAddrUncachedBit43) {
|
||||||
|
@ -76,12 +75,12 @@ inline Addr Phys2K0Seg(Addr addr)
|
||||||
addr |= PAddrUncachedBit40;
|
addr |= PAddrUncachedBit40;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return addr | AlphaISA::K0SegBase;
|
return addr | K0SegBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int DTB_ASN_ASN(uint64_t reg) { return reg >> 57 & AsnMask; }
|
inline int DTB_ASN_ASN(uint64_t reg) { return reg >> 57 & AsnMask; }
|
||||||
inline Addr DTB_PTE_PPN(uint64_t reg)
|
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_XRE(uint64_t reg) { return reg >> 8 & 0xf; }
|
||||||
inline int DTB_PTE_XWE(uint64_t reg) { return reg >> 12 & 0xf; }
|
inline int DTB_PTE_XWE(uint64_t reg) { return reg >> 12 & 0xf; }
|
||||||
inline int DTB_PTE_FONR(uint64_t reg) { return reg >> 1 & 0x1; }
|
inline int DTB_PTE_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 int ITB_ASN_ASN(uint64_t reg) { return reg >> 4 & AsnMask; }
|
||||||
inline Addr ITB_PTE_PPN(uint64_t reg)
|
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 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_FONR(uint64_t reg) { return reg >> 1 & 0x1; }
|
||||||
inline bool ITB_PTE_FONW(uint64_t reg) { return reg >> 2 & 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_FONR_MASK = ULL(0x0004);
|
||||||
const uint64_t MM_STAT_ACV_MASK = ULL(0x0002);
|
const uint64_t MM_STAT_ACV_MASK = ULL(0x0002);
|
||||||
const uint64_t MM_STAT_WR_MASK = ULL(0x0001);
|
const uint64_t MM_STAT_WR_MASK = ULL(0x0001);
|
||||||
inline int Opcode(AlphaISA::MachInst inst) { return inst >> 26 & 0x3f; }
|
inline int Opcode(MachInst inst) { return inst >> 26 & 0x3f; }
|
||||||
inline int Ra(AlphaISA::MachInst inst) { return inst >> 21 & 0x1f; }
|
inline int Ra(MachInst inst) { return inst >> 21 & 0x1f; }
|
||||||
|
|
||||||
const Addr PalBase = 0x4000;
|
const Addr PalBase = 0x4000;
|
||||||
const Addr PalMax = 0x10000;
|
const Addr PalMax = 0x10000;
|
||||||
|
|
||||||
/* namespace EV5 */ }
|
} // namespace AlphaISA
|
||||||
|
|
||||||
#endif // __ARCH_ALPHA_EV5_HH__
|
#endif // __ARCH_ALPHA_EV5_HH__
|
||||||
|
|
|
@ -40,8 +40,7 @@
|
||||||
#include "mem/page_table.hh"
|
#include "mem/page_table.hh"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace AlphaISA
|
namespace AlphaISA {
|
||||||
{
|
|
||||||
|
|
||||||
FaultName MachineCheckFault::_name = "mchk";
|
FaultName MachineCheckFault::_name = "mchk";
|
||||||
FaultVect MachineCheckFault::_vect = 0x0401;
|
FaultVect MachineCheckFault::_vect = 0x0401;
|
||||||
|
@ -109,64 +108,67 @@ FaultStat IntegerOverflowFault::_count;
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
|
|
||||||
void AlphaFault::invoke(ThreadContext * tc)
|
void
|
||||||
|
AlphaFault::invoke(ThreadContext *tc)
|
||||||
{
|
{
|
||||||
FaultBase::invoke(tc);
|
FaultBase::invoke(tc);
|
||||||
countStat()++;
|
countStat()++;
|
||||||
|
|
||||||
// exception restart address
|
// exception restart address
|
||||||
if (setRestartAddress() || !(tc->readPC() & 0x3))
|
if (setRestartAddress() || !(tc->readPC() & 0x3))
|
||||||
tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR, tc->readPC());
|
tc->setMiscRegNoEffect(IPR_EXC_ADDR, tc->readPC());
|
||||||
|
|
||||||
if (skipFaultingInstruction()) {
|
if (skipFaultingInstruction()) {
|
||||||
// traps... skip faulting instruction.
|
// traps... skip faulting instruction.
|
||||||
tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR,
|
tc->setMiscRegNoEffect(IPR_EXC_ADDR,
|
||||||
tc->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR) + 4);
|
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));
|
tc->setNextPC(tc->readPC() + sizeof(MachInst));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArithmeticFault::invoke(ThreadContext * tc)
|
void
|
||||||
|
ArithmeticFault::invoke(ThreadContext *tc)
|
||||||
{
|
{
|
||||||
FaultBase::invoke(tc);
|
FaultBase::invoke(tc);
|
||||||
panic("Arithmetic traps are unimplemented!");
|
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
|
// Set fault address and flags. Even though we're modeling an
|
||||||
// EV5, we use the EV6 technique of not latching fault registers
|
// EV5, we use the EV6 technique of not latching fault registers
|
||||||
// on VPTE loads (instead of locking the registers until IPR_VA is
|
// on VPTE loads (instead of locking the registers until IPR_VA is
|
||||||
// read, like the EV5). The EV6 approach is cleaner and seems to
|
// read, like the EV5). The EV6 approach is cleaner and seems to
|
||||||
// work with EV5 PAL code, but not the other way around.
|
// work with EV5 PAL code, but not the other way around.
|
||||||
if (!tc->misspeculating()
|
if (!tc->misspeculating() &&
|
||||||
&& !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) {
|
reqFlags.noneSet(Request::VPTE|Request::NO_FAULT)) {
|
||||||
// set VA register with faulting address
|
// set VA register with faulting address
|
||||||
tc->setMiscRegNoEffect(AlphaISA::IPR_VA, vaddr);
|
tc->setMiscRegNoEffect(IPR_VA, vaddr);
|
||||||
|
|
||||||
// set MM_STAT register flags
|
// set MM_STAT register flags
|
||||||
tc->setMiscRegNoEffect(AlphaISA::IPR_MM_STAT,
|
tc->setMiscRegNoEffect(IPR_MM_STAT,
|
||||||
(((EV5::Opcode(tc->getInst()) & 0x3f) << 11)
|
(((Opcode(tc->getInst()) & 0x3f) << 11) |
|
||||||
| ((EV5::Ra(tc->getInst()) & 0x1f) << 6)
|
((Ra(tc->getInst()) & 0x1f) << 6) |
|
||||||
| (flags & 0x3f)));
|
(flags & 0x3f)));
|
||||||
|
|
||||||
// set VA_FORM register with faulting formatted address
|
// set VA_FORM register with faulting formatted address
|
||||||
tc->setMiscRegNoEffect(AlphaISA::IPR_VA_FORM,
|
tc->setMiscRegNoEffect(IPR_VA_FORM,
|
||||||
tc->readMiscRegNoEffect(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3));
|
tc->readMiscRegNoEffect(IPR_MVPTBR) | (vaddr.vpn() << 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
AlphaFault::invoke(tc);
|
AlphaFault::invoke(tc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItbFault::invoke(ThreadContext * tc)
|
void
|
||||||
|
ItbFault::invoke(ThreadContext *tc)
|
||||||
{
|
{
|
||||||
if (!tc->misspeculating()) {
|
if (!tc->misspeculating()) {
|
||||||
tc->setMiscRegNoEffect(AlphaISA::IPR_ITB_TAG, pc);
|
tc->setMiscRegNoEffect(IPR_ITB_TAG, pc);
|
||||||
tc->setMiscRegNoEffect(AlphaISA::IPR_IFAULT_VA_FORM,
|
tc->setMiscRegNoEffect(IPR_IFAULT_VA_FORM,
|
||||||
tc->readMiscRegNoEffect(AlphaISA::IPR_IVPTBR) |
|
tc->readMiscRegNoEffect(IPR_IVPTBR) | (VAddr(pc).vpn() << 3));
|
||||||
(AlphaISA::VAddr(pc).vpn() << 3));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AlphaFault::invoke(tc);
|
AlphaFault::invoke(tc);
|
||||||
|
@ -174,12 +176,13 @@ void ItbFault::invoke(ThreadContext * tc)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
void ItbPageFault::invoke(ThreadContext * tc)
|
void
|
||||||
|
ItbPageFault::invoke(ThreadContext *tc)
|
||||||
{
|
{
|
||||||
Process *p = tc->getProcessPtr();
|
Process *p = tc->getProcessPtr();
|
||||||
TlbEntry entry;
|
TlbEntry entry;
|
||||||
bool success = p->pTable->lookup(pc, entry);
|
bool success = p->pTable->lookup(pc, entry);
|
||||||
if(!success) {
|
if (!success) {
|
||||||
panic("Tried to execute unmapped address %#x.\n", pc);
|
panic("Tried to execute unmapped address %#x.\n", pc);
|
||||||
} else {
|
} else {
|
||||||
VAddr vaddr(pc);
|
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();
|
Process *p = tc->getProcessPtr();
|
||||||
TlbEntry entry;
|
TlbEntry entry;
|
||||||
bool success = p->pTable->lookup(vaddr, entry);
|
bool success = p->pTable->lookup(vaddr, entry);
|
||||||
if(!success) {
|
if (!success) {
|
||||||
p->checkAndAllocNextPage(vaddr);
|
p->checkAndAllocNextPage(vaddr);
|
||||||
success = p->pTable->lookup(vaddr, entry);
|
success = p->pTable->lookup(vaddr, entry);
|
||||||
}
|
}
|
||||||
if(!success) {
|
if (!success) {
|
||||||
panic("Tried to access unmapped address %#x.\n", (Addr)vaddr);
|
panic("Tried to access unmapped address %#x.\n", (Addr)vaddr);
|
||||||
} else {
|
} else {
|
||||||
tc->getDTBPtr()->insert(vaddr.page(), entry);
|
tc->getDTBPtr()->insert(vaddr.page(), entry);
|
||||||
|
|
|
@ -29,18 +29,16 @@
|
||||||
* Kevin Lim
|
* Kevin Lim
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __ALPHA_FAULTS_HH__
|
#ifndef __ARCH_ALPHA_FAULTS_HH__
|
||||||
#define __ALPHA_FAULTS_HH__
|
#define __ARCH_ALPHA_FAULTS_HH__
|
||||||
|
|
||||||
|
#include "arch/alpha/pagetable.hh"
|
||||||
#include "config/full_system.hh"
|
#include "config/full_system.hh"
|
||||||
#include "sim/faults.hh"
|
#include "sim/faults.hh"
|
||||||
|
|
||||||
#include "arch/alpha/pagetable.hh"
|
|
||||||
|
|
||||||
// The design of the "name" and "vect" functions is in sim/faults.hh
|
// The design of the "name" and "vect" functions is in sim/faults.hh
|
||||||
|
|
||||||
namespace AlphaISA
|
namespace AlphaISA {
|
||||||
{
|
|
||||||
|
|
||||||
typedef const Addr FaultVect;
|
typedef const Addr FaultVect;
|
||||||
|
|
||||||
|
@ -63,6 +61,7 @@ class MachineCheckFault : public AlphaFault
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FaultName name() const {return _name;}
|
FaultName name() const {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
|
@ -76,6 +75,7 @@ class AlignmentFault : public AlphaFault
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FaultName name() const {return _name;}
|
FaultName name() const {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
|
@ -94,6 +94,7 @@ class ResetFault : public AlphaFault
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FaultName name() const {return _name;}
|
FaultName name() const {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
|
@ -102,12 +103,14 @@ class ResetFault : public AlphaFault
|
||||||
|
|
||||||
class ArithmeticFault : public AlphaFault
|
class ArithmeticFault : public AlphaFault
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
bool skipFaultingInstruction() {return true;}
|
|
||||||
private:
|
private:
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool skipFaultingInstruction() {return true;}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FaultName name() const {return _name;}
|
FaultName name() const {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
|
@ -119,12 +122,14 @@ class ArithmeticFault : public AlphaFault
|
||||||
|
|
||||||
class InterruptFault : public AlphaFault
|
class InterruptFault : public AlphaFault
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
bool setRestartAddress() {return false;}
|
|
||||||
private:
|
private:
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool setRestartAddress() {return false;}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FaultName name() const {return _name;}
|
FaultName name() const {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
|
@ -134,11 +139,12 @@ class InterruptFault : public AlphaFault
|
||||||
class DtbFault : public AlphaFault
|
class DtbFault : public AlphaFault
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
AlphaISA::VAddr vaddr;
|
VAddr vaddr;
|
||||||
uint32_t reqFlags;
|
Request::Flags reqFlags;
|
||||||
uint64_t flags;
|
uint64_t flags;
|
||||||
|
|
||||||
public:
|
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)
|
: vaddr(_vaddr), reqFlags(_reqFlags), flags(_flags)
|
||||||
{ }
|
{ }
|
||||||
FaultName name() const = 0;
|
FaultName name() const = 0;
|
||||||
|
@ -155,8 +161,9 @@ class NDtbMissFault : public DtbFault
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NDtbMissFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
NDtbMissFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags)
|
||||||
: DtbFault(vaddr, reqFlags, flags)
|
: DtbFault(vaddr, reqFlags, flags)
|
||||||
{ }
|
{ }
|
||||||
FaultName name() const {return _name;}
|
FaultName name() const {return _name;}
|
||||||
|
@ -173,8 +180,9 @@ class PDtbMissFault : public DtbFault
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PDtbMissFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
PDtbMissFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags)
|
||||||
: DtbFault(vaddr, reqFlags, flags)
|
: DtbFault(vaddr, reqFlags, flags)
|
||||||
{ }
|
{ }
|
||||||
FaultName name() const {return _name;}
|
FaultName name() const {return _name;}
|
||||||
|
@ -188,8 +196,9 @@ class DtbPageFault : public DtbFault
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DtbPageFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
DtbPageFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags)
|
||||||
: DtbFault(vaddr, reqFlags, flags)
|
: DtbFault(vaddr, reqFlags, flags)
|
||||||
{ }
|
{ }
|
||||||
FaultName name() const {return _name;}
|
FaultName name() const {return _name;}
|
||||||
|
@ -203,8 +212,9 @@ class DtbAcvFault : public DtbFault
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DtbAcvFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
DtbAcvFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags)
|
||||||
: DtbFault(vaddr, reqFlags, flags)
|
: DtbFault(vaddr, reqFlags, flags)
|
||||||
{ }
|
{ }
|
||||||
FaultName name() const {return _name;}
|
FaultName name() const {return _name;}
|
||||||
|
@ -218,8 +228,9 @@ class DtbAlignmentFault : public DtbFault
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DtbAlignmentFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
DtbAlignmentFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags)
|
||||||
: DtbFault(vaddr, reqFlags, flags)
|
: DtbFault(vaddr, reqFlags, flags)
|
||||||
{ }
|
{ }
|
||||||
FaultName name() const {return _name;}
|
FaultName name() const {return _name;}
|
||||||
|
@ -231,10 +242,9 @@ class ItbFault : public AlphaFault
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Addr pc;
|
Addr pc;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ItbFault(Addr _pc)
|
ItbFault(Addr _pc) : pc(_pc) { }
|
||||||
: pc(_pc)
|
|
||||||
{ }
|
|
||||||
FaultName name() const = 0;
|
FaultName name() const = 0;
|
||||||
FaultVect vect() = 0;
|
FaultVect vect() = 0;
|
||||||
FaultStat & countStat() = 0;
|
FaultStat & countStat() = 0;
|
||||||
|
@ -249,10 +259,9 @@ class ItbPageFault : public ItbFault
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ItbPageFault(Addr pc)
|
ItbPageFault(Addr pc) : ItbFault(pc) { }
|
||||||
: ItbFault(pc)
|
|
||||||
{ }
|
|
||||||
FaultName name() const {return _name;}
|
FaultName name() const {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
FaultStat & countStat() {return _count;}
|
FaultStat & countStat() {return _count;}
|
||||||
|
@ -267,10 +276,9 @@ class ItbAcvFault : public ItbFault
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ItbAcvFault(Addr pc)
|
ItbAcvFault(Addr pc) : ItbFault(pc) { }
|
||||||
: ItbFault(pc)
|
|
||||||
{ }
|
|
||||||
FaultName name() const {return _name;}
|
FaultName name() const {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
FaultStat & countStat() {return _count;}
|
FaultStat & countStat() {return _count;}
|
||||||
|
@ -282,6 +290,7 @@ class UnimplementedOpcodeFault : public AlphaFault
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FaultName name() const {return _name;}
|
FaultName name() const {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
|
@ -294,6 +303,7 @@ class FloatEnableFault : public AlphaFault
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FaultName name() const {return _name;}
|
FaultName name() const {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
|
@ -302,12 +312,14 @@ class FloatEnableFault : public AlphaFault
|
||||||
|
|
||||||
class PalFault : public AlphaFault
|
class PalFault : public AlphaFault
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
bool skipFaultingInstruction() {return true;}
|
|
||||||
private:
|
private:
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool skipFaultingInstruction() {return true;}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FaultName name() const {return _name;}
|
FaultName name() const {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
|
@ -320,12 +332,13 @@ class IntegerOverflowFault : public AlphaFault
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FaultName name() const {return _name;}
|
FaultName name() const {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
FaultStat & countStat() {return _count;}
|
FaultStat & countStat() {return _count;}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // AlphaISA namespace
|
} // namespace AlphaISA
|
||||||
|
|
||||||
#endif // __FAULTS_HH__
|
#endif // __ARCH_ALPHA_FAULTS_HH__
|
||||||
|
|
|
@ -30,20 +30,28 @@
|
||||||
* Kevin Lim
|
* Kevin Lim
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "arch/alpha/floatregfile.hh"
|
#include "arch/alpha/floatregfile.hh"
|
||||||
#include "sim/serialize.hh"
|
#include "sim/serialize.hh"
|
||||||
|
|
||||||
namespace AlphaISA
|
namespace AlphaISA {
|
||||||
|
void
|
||||||
|
FloatRegFile::clear()
|
||||||
{
|
{
|
||||||
void
|
std::memset(d, 0, sizeof(d));
|
||||||
FloatRegFile::serialize(std::ostream &os)
|
|
||||||
{
|
|
||||||
SERIALIZE_ARRAY(q, NumFloatRegs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
FloatRegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
|
||||||
{
|
|
||||||
UNSERIALIZE_ARRAY(q, NumFloatRegs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FloatRegFile::serialize(std::ostream &os)
|
||||||
|
{
|
||||||
|
SERIALIZE_ARRAY(q, NumFloatRegs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FloatRegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
|
{
|
||||||
|
UNSERIALIZE_ARRAY(q, NumFloatRegs);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace AlphaISA
|
||||||
|
|
|
@ -32,37 +32,30 @@
|
||||||
#ifndef __ARCH_ALPHA_FLOATREGFILE_HH__
|
#ifndef __ARCH_ALPHA_FLOATREGFILE_HH__
|
||||||
#define __ARCH_ALPHA_FLOATREGFILE_HH__
|
#define __ARCH_ALPHA_FLOATREGFILE_HH__
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "arch/alpha/isa_traits.hh"
|
#include "arch/alpha/isa_traits.hh"
|
||||||
#include "arch/alpha/types.hh"
|
#include "arch/alpha/types.hh"
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
class Checkpoint;
|
class Checkpoint;
|
||||||
|
|
||||||
namespace AlphaISA
|
namespace AlphaISA {
|
||||||
|
|
||||||
|
class FloatRegFile
|
||||||
{
|
{
|
||||||
static inline std::string getFloatRegName(RegIndex)
|
public:
|
||||||
{
|
union {
|
||||||
return "";
|
uint64_t q[NumFloatRegs]; // integer qword view
|
||||||
}
|
double d[NumFloatRegs]; // double-precision floating point view
|
||||||
|
|
||||||
class FloatRegFile
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
union {
|
|
||||||
uint64_t q[NumFloatRegs]; // integer qword view
|
|
||||||
double d[NumFloatRegs]; // double-precision floating point view
|
|
||||||
};
|
|
||||||
|
|
||||||
void serialize(std::ostream &os);
|
|
||||||
|
|
||||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{ std::memset(d, 0, sizeof(d)); }
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
void clear();
|
||||||
|
|
||||||
|
void serialize(std::ostream &os);
|
||||||
|
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace AlphaISA
|
||||||
|
|
||||||
|
#endif // __ARCH_ALPHA_FLOATREGFILE_HH__
|
||||||
|
|
|
@ -62,29 +62,25 @@ FreebsdAlphaSystem::FreebsdAlphaSystem(Params *p)
|
||||||
addKernelFuncEvent<SkipCalibrateClocksEvent>("calibrate_clocks");
|
addKernelFuncEvent<SkipCalibrateClocksEvent>("calibrate_clocks");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FreebsdAlphaSystem::~FreebsdAlphaSystem()
|
FreebsdAlphaSystem::~FreebsdAlphaSystem()
|
||||||
{
|
{
|
||||||
delete skipDelayEvent;
|
delete skipDelayEvent;
|
||||||
delete skipCalibrateClocks;
|
delete skipCalibrateClocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc)
|
FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc)
|
||||||
{
|
{
|
||||||
Addr ppc_vaddr = 0;
|
Addr ppc_vaddr = 0;
|
||||||
Addr timer_vaddr = 0;
|
Addr timer_vaddr = 0;
|
||||||
|
|
||||||
assert(NumArgumentRegs >= 3);
|
ppc_vaddr = (Addr)tc->readIntReg(17);
|
||||||
ppc_vaddr = (Addr)tc->readIntReg(ArgumentReg[1]);
|
timer_vaddr = (Addr)tc->readIntReg(18);
|
||||||
timer_vaddr = (Addr)tc->readIntReg(ArgumentReg[2]);
|
|
||||||
|
|
||||||
virtPort.write(ppc_vaddr, (uint32_t)Clock::Frequency);
|
virtPort.write(ppc_vaddr, (uint32_t)Clock::Frequency);
|
||||||
virtPort.write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
|
virtPort.write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ThreadContext *tc)
|
FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ThreadContext *tc)
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,7 +57,6 @@ class FreebsdAlphaSystem : public AlphaSystem
|
||||||
~FreebsdAlphaSystem();
|
~FreebsdAlphaSystem();
|
||||||
|
|
||||||
void doCalibrateClocks(ThreadContext *tc);
|
void doCalibrateClocks(ThreadContext *tc);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ARCH_ALPHA_FREEBSD_SYSTEM_HH__
|
#endif // __ARCH_ALPHA_FREEBSD_SYSTEM_HH__
|
||||||
|
|
|
@ -33,13 +33,14 @@
|
||||||
#include "arch/alpha/kernel_stats.hh"
|
#include "arch/alpha/kernel_stats.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
|
|
||||||
using namespace TheISA;
|
using namespace AlphaISA;
|
||||||
|
|
||||||
void
|
void
|
||||||
IdleStartEvent::process(ThreadContext *tc)
|
IdleStartEvent::process(ThreadContext *tc)
|
||||||
{
|
{
|
||||||
if (tc->getKernelStats())
|
if (tc->getKernelStats()) {
|
||||||
tc->getKernelStats()->setIdleProcess(
|
MiscReg val = tc->readMiscRegNoEffect(IPR_PALtemp23);
|
||||||
tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23), tc);
|
tc->getKernelStats()->setIdleProcess(val, tc);
|
||||||
|
}
|
||||||
remove();
|
remove();
|
||||||
}
|
}
|
||||||
|
|
12
src/cpu/o3/sparc/thread_context.cc → src/arch/alpha/interrupts.cc
Executable file → Normal file
12
src/cpu/o3/sparc/thread_context.cc → src/arch/alpha/interrupts.cc
Executable file → Normal file
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2004-2006 The Regents of The University of Michigan
|
* Copyright (c) 2008 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -28,8 +28,10 @@
|
||||||
* Authors: Gabe Black
|
* Authors: Gabe Black
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cpu/o3/thread_context.hh"
|
#include "arch/alpha/interrupts.hh"
|
||||||
#include "cpu/o3/thread_context_impl.hh"
|
|
||||||
|
|
||||||
template class O3ThreadContext<SparcSimpleImpl>;
|
|
||||||
|
|
||||||
|
AlphaISA::Interrupts *
|
||||||
|
AlphaInterruptsParams::create()
|
||||||
|
{
|
||||||
|
return new AlphaISA::Interrupts(this);
|
||||||
|
}
|
|
@ -35,142 +35,163 @@
|
||||||
#include "arch/alpha/faults.hh"
|
#include "arch/alpha/faults.hh"
|
||||||
#include "arch/alpha/isa_traits.hh"
|
#include "arch/alpha/isa_traits.hh"
|
||||||
#include "base/compiler.hh"
|
#include "base/compiler.hh"
|
||||||
|
#include "base/trace.hh"
|
||||||
#include "cpu/thread_context.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:
|
return dynamic_cast<const Params *>(_params);
|
||||||
uint64_t interrupts[NumInterruptLevels];
|
}
|
||||||
uint64_t intstatus;
|
|
||||||
|
|
||||||
public:
|
Interrupts(Params * p) : SimObject(p), cpu(NULL)
|
||||||
Interrupts()
|
{
|
||||||
{
|
memset(interrupts, 0, sizeof(interrupts));
|
||||||
memset(interrupts, 0, sizeof(interrupts));
|
intstatus = 0;
|
||||||
intstatus = 0;
|
newInfoSet = false;
|
||||||
newInfoSet = false;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void post(int int_num, int index)
|
void
|
||||||
{
|
setCPU(BaseCPU * _cpu)
|
||||||
DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
|
{
|
||||||
|
cpu = _cpu;
|
||||||
|
}
|
||||||
|
|
||||||
if (int_num < 0 || int_num >= NumInterruptLevels)
|
void
|
||||||
panic("int_num out of bounds\n");
|
post(int int_num, int index)
|
||||||
|
{
|
||||||
|
DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
|
||||||
|
|
||||||
if (index < 0 || index >= sizeof(uint64_t) * 8)
|
if (int_num < 0 || int_num >= NumInterruptLevels)
|
||||||
panic("int_num out of bounds\n");
|
panic("int_num out of bounds\n");
|
||||||
|
|
||||||
interrupts[int_num] |= 1 << index;
|
if (index < 0 || index >= (int)sizeof(uint64_t) * 8)
|
||||||
intstatus |= (ULL(1) << int_num);
|
panic("int_num out of bounds\n");
|
||||||
}
|
|
||||||
|
|
||||||
void clear(int int_num, int index)
|
interrupts[int_num] |= 1 << index;
|
||||||
{
|
intstatus |= (ULL(1) << int_num);
|
||||||
DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
|
}
|
||||||
|
|
||||||
if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
|
void
|
||||||
panic("int_num out of bounds\n");
|
clear(int int_num, int index)
|
||||||
|
{
|
||||||
|
DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
|
||||||
|
|
||||||
if (index < 0 || index >= sizeof(uint64_t) * 8)
|
if (int_num < 0 || int_num >= NumInterruptLevels)
|
||||||
panic("int_num out of bounds\n");
|
panic("int_num out of bounds\n");
|
||||||
|
|
||||||
interrupts[int_num] &= ~(1 << index);
|
if (index < 0 || index >= (int)sizeof(uint64_t) * 8)
|
||||||
if (interrupts[int_num] == 0)
|
panic("int_num out of bounds\n");
|
||||||
intstatus &= ~(ULL(1) << int_num);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_all()
|
interrupts[int_num] &= ~(1 << index);
|
||||||
{
|
if (interrupts[int_num] == 0)
|
||||||
DPRINTF(Interrupt, "Interrupts all cleared\n");
|
intstatus &= ~(ULL(1) << int_num);
|
||||||
|
}
|
||||||
|
|
||||||
memset(interrupts, 0, sizeof(interrupts));
|
void
|
||||||
intstatus = 0;
|
clearAll()
|
||||||
}
|
{
|
||||||
|
DPRINTF(Interrupt, "Interrupts all cleared\n");
|
||||||
|
|
||||||
void serialize(std::ostream &os)
|
memset(interrupts, 0, sizeof(interrupts));
|
||||||
{
|
intstatus = 0;
|
||||||
SERIALIZE_ARRAY(interrupts, NumInterruptLevels);
|
}
|
||||||
SERIALIZE_SCALAR(intstatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
void unserialize(Checkpoint *cp, const std::string §ion)
|
void
|
||||||
{
|
serialize(std::ostream &os)
|
||||||
UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels);
|
{
|
||||||
UNSERIALIZE_SCALAR(intstatus);
|
SERIALIZE_ARRAY(interrupts, NumInterruptLevels);
|
||||||
}
|
SERIALIZE_SCALAR(intstatus);
|
||||||
|
}
|
||||||
|
|
||||||
bool check_interrupts(ThreadContext * tc) const
|
void
|
||||||
{
|
unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
return (intstatus != 0) && !(tc->readPC() & 0x3);
|
{
|
||||||
}
|
UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels);
|
||||||
|
UNSERIALIZE_SCALAR(intstatus);
|
||||||
|
}
|
||||||
|
|
||||||
Fault getInterrupt(ThreadContext * tc)
|
bool
|
||||||
{
|
checkInterrupts(ThreadContext *tc) const
|
||||||
int ipl = 0;
|
{
|
||||||
int summary = 0;
|
return (intstatus != 0) && !(tc->readPC() & 0x3);
|
||||||
|
}
|
||||||
|
|
||||||
if (tc->readMiscRegNoEffect(IPR_ASTRR))
|
Fault
|
||||||
panic("asynchronous traps not implemented\n");
|
getInterrupt(ThreadContext *tc)
|
||||||
|
{
|
||||||
|
int ipl = 0;
|
||||||
|
int summary = 0;
|
||||||
|
|
||||||
if (tc->readMiscRegNoEffect(IPR_SIRR)) {
|
if (tc->readMiscRegNoEffect(IPR_ASTRR))
|
||||||
for (int i = INTLEVEL_SOFTWARE_MIN;
|
panic("asynchronous traps not implemented\n");
|
||||||
i < INTLEVEL_SOFTWARE_MAX; i++) {
|
|
||||||
if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) {
|
if (tc->readMiscRegNoEffect(IPR_SIRR)) {
|
||||||
// See table 4-19 of 21164 hardware reference
|
for (int i = INTLEVEL_SOFTWARE_MIN;
|
||||||
ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
|
i < INTLEVEL_SOFTWARE_MAX; i++) {
|
||||||
summary |= (ULL(1) << i);
|
if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) {
|
||||||
}
|
// See table 4-19 of 21164 hardware reference
|
||||||
|
ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
|
||||||
|
summary |= (ULL(1) << i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t interrupts = intstatus;
|
uint64_t interrupts = intstatus;
|
||||||
if (interrupts) {
|
if (interrupts) {
|
||||||
for (int i = INTLEVEL_EXTERNAL_MIN;
|
for (int i = INTLEVEL_EXTERNAL_MIN;
|
||||||
i < INTLEVEL_EXTERNAL_MAX; i++) {
|
i < INTLEVEL_EXTERNAL_MAX; i++) {
|
||||||
if (interrupts & (ULL(1) << i)) {
|
if (interrupts & (ULL(1) << i)) {
|
||||||
// See table 4-19 of 21164 hardware reference
|
// See table 4-19 of 21164 hardware reference
|
||||||
ipl = i;
|
ipl = i;
|
||||||
summary |= (ULL(1) << 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)
|
if (ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR)) {
|
||||||
{
|
newIpl = ipl;
|
||||||
assert(newInfoSet);
|
newSummary = summary;
|
||||||
tc->setMiscRegNoEffect(IPR_ISR, newSummary);
|
newInfoSet = true;
|
||||||
tc->setMiscRegNoEffect(IPR_INTID, newIpl);
|
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
|
||||||
newInfoSet = false;
|
tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary);
|
||||||
|
|
||||||
|
return new InterruptFault;
|
||||||
|
} else {
|
||||||
|
return NoFault;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t get_vec(int int_num)
|
void
|
||||||
{
|
updateIntrInfo(ThreadContext *tc)
|
||||||
panic("Shouldn't be called for Alpha\n");
|
{
|
||||||
M5_DUMMY_RETURN
|
assert(newInfoSet);
|
||||||
}
|
tc->setMiscRegNoEffect(IPR_ISR, newSummary);
|
||||||
|
tc->setMiscRegNoEffect(IPR_INTID, newIpl);
|
||||||
|
newInfoSet = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
} // namespace AlphaISA
|
||||||
bool newInfoSet;
|
|
||||||
int newIpl;
|
|
||||||
int newSummary;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif // __ARCH_ALPHA_INTERRUPT_HH__
|
||||||
|
|
||||||
|
|
|
@ -30,36 +30,45 @@
|
||||||
* Kevin Lim
|
* Kevin Lim
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "arch/alpha/isa_traits.hh"
|
#include "arch/alpha/isa_traits.hh"
|
||||||
#include "arch/alpha/intregfile.hh"
|
#include "arch/alpha/intregfile.hh"
|
||||||
#include "sim/serialize.hh"
|
#include "sim/serialize.hh"
|
||||||
|
|
||||||
namespace AlphaISA
|
namespace AlphaISA {
|
||||||
{
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
const int reg_redir[AlphaISA::NumIntRegs] = {
|
const int reg_redir[NumIntRegs] = {
|
||||||
/* 0 */ 0, 1, 2, 3, 4, 5, 6, 7,
|
/* 0 */ 0, 1, 2, 3, 4, 5, 6, 7,
|
||||||
/* 8 */ 32, 33, 34, 35, 36, 37, 38, 15,
|
/* 8 */ 32, 33, 34, 35, 36, 37, 38, 15,
|
||||||
/* 16 */ 16, 17, 18, 19, 20, 21, 22, 23,
|
/* 16 */ 16, 17, 18, 19, 20, 21, 22, 23,
|
||||||
/* 24 */ 24, 39, 26, 27, 28, 29, 30, 31 };
|
/* 24 */ 24, 39, 26, 27, 28, 29, 30, 31 };
|
||||||
#else
|
#else
|
||||||
const int reg_redir[AlphaISA::NumIntRegs] = {
|
const int reg_redir[NumIntRegs] = {
|
||||||
/* 0 */ 0, 1, 2, 3, 4, 5, 6, 7,
|
/* 0 */ 0, 1, 2, 3, 4, 5, 6, 7,
|
||||||
/* 8 */ 8, 9, 10, 11, 12, 13, 14, 15,
|
/* 8 */ 8, 9, 10, 11, 12, 13, 14, 15,
|
||||||
/* 16 */ 16, 17, 18, 19, 20, 21, 22, 23,
|
/* 16 */ 16, 17, 18, 19, 20, 21, 22, 23,
|
||||||
/* 24 */ 24, 25, 26, 27, 28, 29, 30, 31 };
|
/* 24 */ 24, 25, 26, 27, 28, 29, 30, 31 };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
IntRegFile::serialize(std::ostream &os)
|
IntRegFile::clear()
|
||||||
{
|
{
|
||||||
SERIALIZE_ARRAY(regs, NumIntRegs);
|
std::memset(regs, 0, sizeof(regs));
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
IntRegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
|
||||||
{
|
|
||||||
UNSERIALIZE_ARRAY(regs, NumIntRegs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IntRegFile::serialize(std::ostream &os)
|
||||||
|
{
|
||||||
|
SERIALIZE_ARRAY(regs, NumIntRegs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IntRegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
|
{
|
||||||
|
UNSERIALIZE_ARRAY(regs, NumIntRegs);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace AlphaISA
|
||||||
|
|
||||||
|
|
|
@ -32,47 +32,42 @@
|
||||||
#ifndef __ARCH_ALPHA_INTREGFILE_HH__
|
#ifndef __ARCH_ALPHA_INTREGFILE_HH__
|
||||||
#define __ARCH_ALPHA_INTREGFILE_HH__
|
#define __ARCH_ALPHA_INTREGFILE_HH__
|
||||||
|
|
||||||
#include "arch/alpha/types.hh"
|
#include <iosfwd>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <iostream>
|
#include "arch/alpha/types.hh"
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
class Checkpoint;
|
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.
|
void
|
||||||
extern const int reg_redir[NumIntRegs];
|
setReg(int intReg, const IntReg &val)
|
||||||
|
|
||||||
class IntRegFile
|
|
||||||
{
|
{
|
||||||
protected:
|
regs[intReg] = val;
|
||||||
IntReg regs[NumIntRegs];
|
}
|
||||||
|
|
||||||
public:
|
void clear();
|
||||||
|
|
||||||
IntReg readReg(int intReg)
|
void serialize(std::ostream &os);
|
||||||
{
|
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
return regs[intReg];
|
};
|
||||||
}
|
|
||||||
|
|
||||||
void setReg(int intReg, const IntReg &val)
|
} // namespace AlphaISA
|
||||||
{
|
|
||||||
regs[intReg] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void serialize(std::ostream &os);
|
#endif // __ARCH_ALPHA_INTREGFILE_HH__
|
||||||
|
|
||||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{ std::memset(regs, 0, sizeof(regs)); }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -28,113 +28,115 @@
|
||||||
* Authors: Gabe Black
|
* Authors: Gabe Black
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <cassert>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
|
|
||||||
#include "arch/alpha/ipr.hh"
|
#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] =
|
static bool initialized = false;
|
||||||
{
|
if (initialized)
|
||||||
//Write only
|
return;
|
||||||
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
|
memset(IprToMiscRegIndex, -1, MaxInternalProcRegs * sizeof(int));
|
||||||
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
|
for (int x = 0; x < NumInternalProcRegs; x++)
|
||||||
RAW_IPR_ITB_TAG, // ITLB tag register
|
IprToMiscRegIndex[MiscRegIndexToIpr[x]] = x;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace AlphaISA
|
||||||
|
|
||||||
|
|
|
@ -32,206 +32,208 @@
|
||||||
#ifndef __ARCH_ALPHA_IPR_HH__
|
#ifndef __ARCH_ALPHA_IPR_HH__
|
||||||
#define __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
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////////////////
|
//Write only
|
||||||
//
|
MinWriteOnlyIpr,
|
||||||
// Internal Processor Reigsters
|
IPR_HWINT_CLR = MinWriteOnlyIpr,
|
||||||
//
|
IPR_SL_XMIT,
|
||||||
enum md_ipr_names
|
IPR_DC_FLUSH,
|
||||||
{
|
IPR_IC_FLUSH,
|
||||||
RAW_IPR_ISR = 0x100, // interrupt summary register
|
IPR_ALT_MODE,
|
||||||
RAW_IPR_ITB_TAG = 0x101, // ITLB tag register
|
IPR_DTB_IA,
|
||||||
RAW_IPR_ITB_PTE = 0x102, // ITLB page table entry register
|
IPR_DTB_IAP,
|
||||||
RAW_IPR_ITB_ASN = 0x103, // ITLB address space register
|
IPR_ITB_IA,
|
||||||
RAW_IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp register
|
MaxWriteOnlyIpr,
|
||||||
RAW_IPR_ITB_IA = 0x105, // ITLB invalidate all register
|
IPR_ITB_IAP = MaxWriteOnlyIpr,
|
||||||
RAW_IPR_ITB_IAP = 0x106, // ITLB invalidate all process register
|
|
||||||
RAW_IPR_ITB_IS = 0x107, // ITLB invalidate select register
|
|
||||||
RAW_IPR_SIRR = 0x108, // software interrupt request register
|
|
||||||
RAW_IPR_ASTRR = 0x109, // asynchronous system trap request register
|
|
||||||
RAW_IPR_ASTER = 0x10a, // asynchronous system trap enable register
|
|
||||||
RAW_IPR_EXC_ADDR = 0x10b, // exception address register
|
|
||||||
RAW_IPR_EXC_SUM = 0x10c, // exception summary register
|
|
||||||
RAW_IPR_EXC_MASK = 0x10d, // exception mask register
|
|
||||||
RAW_IPR_PAL_BASE = 0x10e, // PAL base address register
|
|
||||||
RAW_IPR_ICM = 0x10f, // instruction current mode
|
|
||||||
RAW_IPR_IPLR = 0x110, // interrupt priority level register
|
|
||||||
RAW_IPR_INTID = 0x111, // interrupt ID register
|
|
||||||
RAW_IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr register
|
|
||||||
RAW_IPR_IVPTBR = 0x113, // virtual page table base register
|
|
||||||
RAW_IPR_HWINT_CLR = 0x115, // H/W interrupt clear register
|
|
||||||
RAW_IPR_SL_XMIT = 0x116, // serial line transmit register
|
|
||||||
RAW_IPR_SL_RCV = 0x117, // serial line receive register
|
|
||||||
RAW_IPR_ICSR = 0x118, // instruction control and status register
|
|
||||||
RAW_IPR_IC_FLUSH = 0x119, // instruction cache flush control
|
|
||||||
RAW_IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status register
|
|
||||||
RAW_IPR_PMCTR = 0x11c, // performance counter register
|
|
||||||
|
|
||||||
// PAL temporary registers...
|
//Read only
|
||||||
// register meanings gleaned from osfpal.s source code
|
MinReadOnlyIpr,
|
||||||
RAW_IPR_PALtemp0 = 0x140, // local scratch
|
IPR_INTID = MinReadOnlyIpr,
|
||||||
RAW_IPR_PALtemp1 = 0x141, // local scratch
|
IPR_SL_RCV,
|
||||||
RAW_IPR_PALtemp2 = 0x142, // entUna
|
IPR_MM_STAT,
|
||||||
RAW_IPR_PALtemp3 = 0x143, // CPU specific impure area pointer
|
IPR_ITB_PTE_TEMP,
|
||||||
RAW_IPR_PALtemp4 = 0x144, // memory management temp
|
MaxReadOnlyIpr,
|
||||||
RAW_IPR_PALtemp5 = 0x145, // memory management temp
|
IPR_DTB_PTE_TEMP = MaxReadOnlyIpr,
|
||||||
RAW_IPR_PALtemp6 = 0x146, // memory management temp
|
|
||||||
RAW_IPR_PALtemp7 = 0x147, // entIF
|
|
||||||
RAW_IPR_PALtemp8 = 0x148, // intmask
|
|
||||||
RAW_IPR_PALtemp9 = 0x149, // entSys
|
|
||||||
RAW_IPR_PALtemp10 = 0x14a, // ??
|
|
||||||
RAW_IPR_PALtemp11 = 0x14b, // entInt
|
|
||||||
RAW_IPR_PALtemp12 = 0x14c, // entArith
|
|
||||||
RAW_IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL
|
|
||||||
RAW_IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL
|
|
||||||
RAW_IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL
|
|
||||||
RAW_IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0>
|
|
||||||
RAW_IPR_PALtemp17 = 0x151, // sysval
|
|
||||||
RAW_IPR_PALtemp18 = 0x152, // usp
|
|
||||||
RAW_IPR_PALtemp19 = 0x153, // ksp
|
|
||||||
RAW_IPR_PALtemp20 = 0x154, // PTBR
|
|
||||||
RAW_IPR_PALtemp21 = 0x155, // entMM
|
|
||||||
RAW_IPR_PALtemp22 = 0x156, // kgp
|
|
||||||
RAW_IPR_PALtemp23 = 0x157, // PCBB
|
|
||||||
|
|
||||||
RAW_IPR_DTB_ASN = 0x200, // DTLB address space number register
|
IPR_ISR,
|
||||||
RAW_IPR_DTB_CM = 0x201, // DTLB current mode register
|
IPR_ITB_TAG,
|
||||||
RAW_IPR_DTB_TAG = 0x202, // DTLB tag register
|
IPR_ITB_PTE,
|
||||||
RAW_IPR_DTB_PTE = 0x203, // DTLB page table entry register
|
IPR_ITB_ASN,
|
||||||
RAW_IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary register
|
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
|
// PAL temporary registers...
|
||||||
RAW_IPR_VA = 0x206, // fault virtual address register
|
// register meanings gleaned from osfpal.s source code
|
||||||
RAW_IPR_VA_FORM = 0x207, // formatted virtual address register
|
IPR_PALtemp0,
|
||||||
RAW_IPR_MVPTBR = 0x208, // MTU virtual page table base register
|
IPR_PALtemp1,
|
||||||
RAW_IPR_DTB_IAP = 0x209, // DTLB invalidate all process register
|
IPR_PALtemp2,
|
||||||
RAW_IPR_DTB_IA = 0x20a, // DTLB invalidate all register
|
IPR_PALtemp3,
|
||||||
RAW_IPR_DTB_IS = 0x20b, // DTLB invalidate single register
|
IPR_PALtemp4,
|
||||||
RAW_IPR_ALT_MODE = 0x20c, // alternate mode register
|
IPR_PALtemp5,
|
||||||
RAW_IPR_CC = 0x20d, // cycle counter register
|
IPR_PALtemp6,
|
||||||
RAW_IPR_CC_CTL = 0x20e, // cycle counter control register
|
IPR_PALtemp7,
|
||||||
RAW_IPR_MCSR = 0x20f, // MTU control register
|
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,
|
IPR_DTB_ASN,
|
||||||
RAW_IPR_DC_PERR_STAT = 0x212, // Dcache parity error status register
|
IPR_DTB_CM,
|
||||||
RAW_IPR_DC_TEST_CTL = 0x213, // Dcache test tag control register
|
IPR_DTB_TAG,
|
||||||
RAW_IPR_DC_TEST_TAG = 0x214, // Dcache test tag register
|
IPR_DTB_PTE,
|
||||||
RAW_IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary register
|
|
||||||
RAW_IPR_DC_MODE = 0x216, // Dcache mode register
|
|
||||||
RAW_IPR_MAF_MODE = 0x217, // miss address file mode register
|
|
||||||
|
|
||||||
MaxInternalProcRegs // number of IPR registers
|
IPR_VA,
|
||||||
};
|
IPR_VA_FORM,
|
||||||
|
IPR_MVPTBR,
|
||||||
|
IPR_DTB_IS,
|
||||||
|
IPR_CC,
|
||||||
|
IPR_CC_CTL,
|
||||||
|
IPR_MCSR,
|
||||||
|
|
||||||
enum MiscRegIpr
|
IPR_DC_PERR_STAT,
|
||||||
{
|
IPR_DC_TEST_CTL,
|
||||||
//Write only
|
IPR_DC_TEST_TAG,
|
||||||
MinWriteOnlyIpr,
|
IPR_DC_TEST_TAG_TEMP,
|
||||||
IPR_HWINT_CLR = MinWriteOnlyIpr,
|
IPR_DC_MODE,
|
||||||
IPR_SL_XMIT,
|
IPR_MAF_MODE,
|
||||||
IPR_DC_FLUSH,
|
|
||||||
IPR_IC_FLUSH,
|
|
||||||
IPR_ALT_MODE,
|
|
||||||
IPR_DTB_IA,
|
|
||||||
IPR_DTB_IAP,
|
|
||||||
IPR_ITB_IA,
|
|
||||||
MaxWriteOnlyIpr,
|
|
||||||
IPR_ITB_IAP = MaxWriteOnlyIpr,
|
|
||||||
|
|
||||||
//Read only
|
NumInternalProcRegs // number of IPR registers
|
||||||
MinReadOnlyIpr,
|
};
|
||||||
IPR_INTID = MinReadOnlyIpr,
|
|
||||||
IPR_SL_RCV,
|
|
||||||
IPR_MM_STAT,
|
|
||||||
IPR_ITB_PTE_TEMP,
|
|
||||||
MaxReadOnlyIpr,
|
|
||||||
IPR_DTB_PTE_TEMP = MaxReadOnlyIpr,
|
|
||||||
|
|
||||||
IPR_ISR,
|
inline bool
|
||||||
IPR_ITB_TAG,
|
IprIsWritable(int index)
|
||||||
IPR_ITB_PTE,
|
{
|
||||||
IPR_ITB_ASN,
|
return index < MinReadOnlyIpr || index > MaxReadOnlyIpr;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
inline bool
|
||||||
|
IprIsReadable(int index)
|
||||||
|
{
|
||||||
|
return index < MinWriteOnlyIpr || index > MaxWriteOnlyIpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs];
|
||||||
|
extern int IprToMiscRegIndex[MaxInternalProcRegs];
|
||||||
|
|
||||||
|
void initializeIprTable();
|
||||||
|
|
||||||
|
} // namespace AlphaISA
|
||||||
|
|
||||||
|
#endif // __ARCH_ALPHA_IPR_HH__
|
||||||
|
|
|
@ -638,7 +638,7 @@ decode OPCODE default Unknown::unknown() {
|
||||||
/* Rb is a fake dependency so here is a fun way to get
|
/* Rb is a fake dependency so here is a fun way to get
|
||||||
* the parser to understand that.
|
* the parser to understand that.
|
||||||
*/
|
*/
|
||||||
Ra = xc->readMiscReg(AlphaISA::IPR_CC) + (Rb & 0);
|
Ra = xc->readMiscReg(IPR_CC) + (Rb & 0);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
Ra = curTick;
|
Ra = curTick;
|
||||||
|
@ -690,7 +690,7 @@ decode OPCODE default Unknown::unknown() {
|
||||||
0x00: CallPal::call_pal({{
|
0x00: CallPal::call_pal({{
|
||||||
if (!palValid ||
|
if (!palValid ||
|
||||||
(palPriv
|
(palPriv
|
||||||
&& xc->readMiscReg(AlphaISA::IPR_ICM) != AlphaISA::mode_kernel)) {
|
&& xc->readMiscReg(IPR_ICM) != mode_kernel)) {
|
||||||
// invalid pal function code, or attempt to do privileged
|
// invalid pal function code, or attempt to do privileged
|
||||||
// PAL call in non-kernel mode
|
// PAL call in non-kernel mode
|
||||||
fault = new UnimplementedOpcodeFault;
|
fault = new UnimplementedOpcodeFault;
|
||||||
|
@ -701,8 +701,8 @@ decode OPCODE default Unknown::unknown() {
|
||||||
bool dopal = xc->simPalCheck(palFunc);
|
bool dopal = xc->simPalCheck(palFunc);
|
||||||
|
|
||||||
if (dopal) {
|
if (dopal) {
|
||||||
xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, NPC);
|
xc->setMiscReg(IPR_EXC_ADDR, NPC);
|
||||||
NPC = xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + palOffset;
|
NPC = xc->readMiscReg(IPR_PAL_BASE) + palOffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}, IsNonSpeculative);
|
}}, IsNonSpeculative);
|
||||||
|
@ -783,14 +783,19 @@ decode OPCODE default Unknown::unknown() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
format BasicOperate {
|
0x1e: decode PALMODE {
|
||||||
0x1e: decode PALMODE {
|
0: OpcdecFault::hw_rei();
|
||||||
0: OpcdecFault::hw_rei();
|
format BasicOperate {
|
||||||
1:hw_rei({{ xc->hwrei(); }}, IsSerializing, IsSerializeBefore);
|
1: hw_rei({{ xc->hwrei(); }}, IsSerializing, IsSerializeBefore);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
format BasicOperate {
|
||||||
// M5 special opcodes use the reserved 0x01 opcode space
|
// M5 special opcodes use the reserved 0x01 opcode space
|
||||||
0x01: decode M5FUNC {
|
0x01: decode M5FUNC {
|
||||||
|
#if FULL_SYSTEM
|
||||||
0x00: arm({{
|
0x00: arm({{
|
||||||
PseudoInst::arm(xc->tcBase());
|
PseudoInst::arm(xc->tcBase());
|
||||||
}}, IsNonSpeculative);
|
}}, IsNonSpeculative);
|
||||||
|
@ -806,22 +811,34 @@ decode OPCODE default Unknown::unknown() {
|
||||||
0x04: quiesceTime({{
|
0x04: quiesceTime({{
|
||||||
R0 = PseudoInst::quiesceTime(xc->tcBase());
|
R0 = PseudoInst::quiesceTime(xc->tcBase());
|
||||||
}}, IsNonSpeculative, IsUnverifiable);
|
}}, IsNonSpeculative, IsUnverifiable);
|
||||||
0x10: ivlb({{
|
#endif
|
||||||
warn_once("Obsolete M5 instruction ivlb encountered.\n");
|
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({{
|
0x11: deprecated_ivle({{
|
||||||
warn_once("Obsolete M5 instruction ivlb encountered.\n");
|
warn_once("Obsolete M5 ivlb instruction encountered.\n");
|
||||||
}});
|
}});
|
||||||
0x20: m5exit_old({{
|
0x20: deprecated_exit ({{
|
||||||
PseudoInst::m5exit_old(xc->tcBase());
|
warn_once("deprecated M5 exit instruction encountered.\n");
|
||||||
|
PseudoInst::m5exit(xc->tcBase(), 0);
|
||||||
}}, No_OpClass, IsNonSpeculative);
|
}}, No_OpClass, IsNonSpeculative);
|
||||||
0x21: m5exit({{
|
0x21: m5exit({{
|
||||||
PseudoInst::m5exit(xc->tcBase(), R16);
|
PseudoInst::m5exit(xc->tcBase(), R16);
|
||||||
}}, No_OpClass, IsNonSpeculative);
|
}}, No_OpClass, IsNonSpeculative);
|
||||||
|
#if FULL_SYSTEM
|
||||||
0x31: loadsymbol({{
|
0x31: loadsymbol({{
|
||||||
PseudoInst::loadsymbol(xc->tcBase());
|
PseudoInst::loadsymbol(xc->tcBase());
|
||||||
}}, No_OpClass, IsNonSpeculative);
|
}}, No_OpClass, IsNonSpeculative);
|
||||||
0x30: initparam({{ Ra = xc->tcBase()->getCpuPtr()->system->init_param; }});
|
0x30: initparam({{
|
||||||
|
Ra = xc->tcBase()->getCpuPtr()->system->init_param;
|
||||||
|
}});
|
||||||
|
#endif
|
||||||
0x40: resetstats({{
|
0x40: resetstats({{
|
||||||
PseudoInst::resetstats(xc->tcBase(), R16, R17);
|
PseudoInst::resetstats(xc->tcBase(), R16, R17);
|
||||||
}}, IsNonSpeculative);
|
}}, IsNonSpeculative);
|
||||||
|
@ -834,28 +851,93 @@ decode OPCODE default Unknown::unknown() {
|
||||||
0x43: m5checkpoint({{
|
0x43: m5checkpoint({{
|
||||||
PseudoInst::m5checkpoint(xc->tcBase(), R16, R17);
|
PseudoInst::m5checkpoint(xc->tcBase(), R16, R17);
|
||||||
}}, IsNonSpeculative);
|
}}, IsNonSpeculative);
|
||||||
|
#if FULL_SYSTEM
|
||||||
0x50: m5readfile({{
|
0x50: m5readfile({{
|
||||||
R0 = PseudoInst::readfile(xc->tcBase(), R16, R17, R18);
|
R0 = PseudoInst::readfile(xc->tcBase(), R16, R17, R18);
|
||||||
}}, IsNonSpeculative);
|
}}, IsNonSpeculative);
|
||||||
|
#endif
|
||||||
0x51: m5break({{
|
0x51: m5break({{
|
||||||
PseudoInst::debugbreak(xc->tcBase());
|
PseudoInst::debugbreak(xc->tcBase());
|
||||||
}}, IsNonSpeculative);
|
}}, IsNonSpeculative);
|
||||||
0x52: m5switchcpu({{
|
0x52: m5switchcpu({{
|
||||||
PseudoInst::switchcpu(xc->tcBase());
|
PseudoInst::switchcpu(xc->tcBase());
|
||||||
}}, IsNonSpeculative);
|
}}, IsNonSpeculative);
|
||||||
|
#if FULL_SYSTEM
|
||||||
0x53: m5addsymbol({{
|
0x53: m5addsymbol({{
|
||||||
PseudoInst::addsymbol(xc->tcBase(), R16, R17);
|
PseudoInst::addsymbol(xc->tcBase(), R16, R17);
|
||||||
}}, IsNonSpeculative);
|
}}, IsNonSpeculative);
|
||||||
|
#endif
|
||||||
0x54: m5panic({{
|
0x54: m5panic({{
|
||||||
panic("M5 panic instruction called at pc=%#x.", xc->readPC());
|
panic("M5 panic instruction called at pc=%#x.", xc->readPC());
|
||||||
}}, IsNonSpeculative);
|
}}, IsNonSpeculative);
|
||||||
0x55: m5anBegin({{
|
#define CPANN(lbl) CPA::cpa()->lbl(xc->tcBase())
|
||||||
PseudoInst::anBegin(xc->tcBase(), R16);
|
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);
|
}}, IsNonSpeculative);
|
||||||
0x56: m5anWait({{
|
0x57: m5reserved3({{
|
||||||
PseudoInst::anWait(xc->tcBase(), R16, R17);
|
warn("M5 reserved opcode ignored");
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x58: m5reserved4({{
|
||||||
|
warn("M5 reserved opcode ignored");
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x59: m5reserved5({{
|
||||||
|
warn("M5 reserved opcode ignored");
|
||||||
}}, IsNonSpeculative);
|
}}, IsNonSpeculative);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ output exec {{
|
||||||
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
|
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
|
||||||
{
|
{
|
||||||
Fault fault = NoFault; // dummy... this ipr access should not fault
|
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;
|
fault = new FloatEnableFault;
|
||||||
}
|
}
|
||||||
return fault;
|
return fault;
|
||||||
|
@ -229,7 +229,7 @@ def template FloatingPointExecute {{
|
||||||
%(code)s;
|
%(code)s;
|
||||||
} else {
|
} else {
|
||||||
m5_fesetround(getC99RoundingMode(
|
m5_fesetround(getC99RoundingMode(
|
||||||
xc->readMiscRegNoEffect(AlphaISA::MISCREG_FPCR)));
|
xc->readMiscRegNoEffect(MISCREG_FPCR)));
|
||||||
%(code)s;
|
%(code)s;
|
||||||
m5_fesetround(M5_FE_TONEAREST);
|
m5_fesetround(M5_FE_TONEAREST);
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,9 +68,8 @@ using namespace AlphaISA;
|
||||||
output exec {{
|
output exec {{
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#include "base/cp_annotate.hh"
|
||||||
#include "sim/pseudo_inst.hh"
|
#include "sim/pseudo_inst.hh"
|
||||||
#endif
|
|
||||||
#include "arch/alpha/ipr.hh"
|
#include "arch/alpha/ipr.hh"
|
||||||
#include "base/fenv.hh"
|
#include "base/fenv.hh"
|
||||||
#include "config/ss_compatible_fp.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.
|
# Int regs default to unsigned, but code should not count on this.
|
||||||
# For clarity, descriptions that depend on unsigned behavior should
|
# For clarity, descriptions that depend on unsigned behavior should
|
||||||
# explicitly specify '.uq'.
|
# explicitly specify '.uq'.
|
||||||
'Ra': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RA] : RA',
|
'Ra': ('IntReg', 'uq', 'PALMODE ? reg_redir[RA] : RA',
|
||||||
'IsInteger', 1),
|
'IsInteger', 1),
|
||||||
'Rb': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RB] : RB',
|
'Rb': ('IntReg', 'uq', 'PALMODE ? reg_redir[RB] : RB',
|
||||||
'IsInteger', 2),
|
'IsInteger', 2),
|
||||||
'Rc': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RC] : RC',
|
'Rc': ('IntReg', 'uq', 'PALMODE ? reg_redir[RC] : RC',
|
||||||
'IsInteger', 3),
|
'IsInteger', 3),
|
||||||
'Fa': ('FloatReg', 'df', 'FA', 'IsFloating', 1),
|
'Fa': ('FloatReg', 'df', 'FA', 'IsFloating', 1),
|
||||||
'Fb': ('FloatReg', 'df', 'FB', 'IsFloating', 2),
|
'Fb': ('FloatReg', 'df', 'FB', 'IsFloating', 2),
|
||||||
|
|
|
@ -43,7 +43,7 @@ output header {{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/// Memory request flags. See mem_req_base.hh.
|
/// Memory request flags. See mem_req_base.hh.
|
||||||
unsigned memAccessFlags;
|
Request::Flags memAccessFlags;
|
||||||
/// Pointer to EAComp object.
|
/// Pointer to EAComp object.
|
||||||
const StaticInstPtr eaCompPtr;
|
const StaticInstPtr eaCompPtr;
|
||||||
/// Pointer to MemAcc object.
|
/// Pointer to MemAcc object.
|
||||||
|
@ -54,7 +54,7 @@ output header {{
|
||||||
StaticInstPtr _eaCompPtr = nullStaticInstPtr,
|
StaticInstPtr _eaCompPtr = nullStaticInstPtr,
|
||||||
StaticInstPtr _memAccPtr = nullStaticInstPtr)
|
StaticInstPtr _memAccPtr = nullStaticInstPtr)
|
||||||
: AlphaStaticInst(mnem, _machInst, __opClass),
|
: 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)
|
inst_flags)
|
||||||
|
|
||||||
if mem_flags:
|
if mem_flags:
|
||||||
|
mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
|
||||||
s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
|
s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
|
||||||
iop.constructor += s
|
iop.constructor += s
|
||||||
memacc_iop.constructor += s
|
memacc_iop.constructor += s
|
||||||
|
|
|
@ -174,11 +174,11 @@ output decoder {{
|
||||||
: Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
|
: Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
|
||||||
disp(HW_LDST_DISP)
|
disp(HW_LDST_DISP)
|
||||||
{
|
{
|
||||||
memAccessFlags = 0;
|
memAccessFlags.clear();
|
||||||
if (HW_LDST_PHYS) memAccessFlags |= PHYSICAL;
|
if (HW_LDST_PHYS) memAccessFlags.set(Request::PHYSICAL);
|
||||||
if (HW_LDST_ALT) memAccessFlags |= ALTMODE;
|
if (HW_LDST_ALT) memAccessFlags.set(Request::ALTMODE);
|
||||||
if (HW_LDST_VPTE) memAccessFlags |= VPTE;
|
if (HW_LDST_VPTE) memAccessFlags.set(Request::VPTE);
|
||||||
if (HW_LDST_LOCK) memAccessFlags |= LOCKED;
|
if (HW_LDST_LOCK) memAccessFlags.set(Request::LOCKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
|
|
|
@ -42,142 +42,134 @@ namespace LittleEndianGuest {}
|
||||||
|
|
||||||
class StaticInstPtr;
|
class StaticInstPtr;
|
||||||
|
|
||||||
namespace AlphaISA
|
namespace AlphaISA {
|
||||||
{
|
|
||||||
using namespace LittleEndianGuest;
|
|
||||||
using AlphaISAInst::MaxInstSrcRegs;
|
|
||||||
using AlphaISAInst::MaxInstDestRegs;
|
|
||||||
|
|
||||||
// These enumerate all the registers for dependence tracking.
|
using namespace LittleEndianGuest;
|
||||||
enum DependenceTags {
|
using AlphaISAInst::MaxInstSrcRegs;
|
||||||
// 0..31 are the integer regs 0..31
|
using AlphaISAInst::MaxInstDestRegs;
|
||||||
// 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;
|
|
||||||
|
|
||||||
|
// 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__
|
#endif // __ARCH_ALPHA_ISA_TRAITS_HH__
|
||||||
|
|
|
@ -152,7 +152,7 @@ Statistics::changeMode(cpu_mode newmode, ThreadContext *tc)
|
||||||
void
|
void
|
||||||
Statistics::mode(cpu_mode newmode, ThreadContext *tc)
|
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)
|
if (newmode == kernel && pcbb == idleProcess)
|
||||||
newmode = idle;
|
newmode = idle;
|
||||||
|
@ -213,5 +213,5 @@ Statistics::unserialize(Checkpoint *cp, const string §ion)
|
||||||
themode = (cpu_mode)exemode;
|
themode = (cpu_mode)exemode;
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* end namespace AlphaISA::Kernel */
|
} // namespace Kernel
|
||||||
} /* end namespace AlphaISA */
|
} // namespace AlphaISA
|
||||||
|
|
|
@ -62,15 +62,15 @@ class Statistics : public ::Kernel::Statistics
|
||||||
void changeMode(cpu_mode newmode, ThreadContext *tc);
|
void changeMode(cpu_mode newmode, ThreadContext *tc);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Stats::Vector<> _callpal;
|
Stats::Vector _callpal;
|
||||||
// Stats::Vector<> _faults;
|
// Stats::Vector _faults;
|
||||||
|
|
||||||
Stats::Vector<> _mode;
|
Stats::Vector _mode;
|
||||||
Stats::Vector<> _modeGood;
|
Stats::Vector _modeGood;
|
||||||
Stats::Formula _modeFraction;
|
Stats::Formula _modeFraction;
|
||||||
Stats::Vector<> _modeTicks;
|
Stats::Vector _modeTicks;
|
||||||
|
|
||||||
Stats::Scalar<> _swap_context;
|
Stats::Scalar _swap_context;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Statistics(System *system);
|
Statistics(System *system);
|
||||||
|
@ -90,7 +90,7 @@ class Statistics : public ::Kernel::Statistics
|
||||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* end namespace AlphaISA::Kernel */
|
} // namespace Kernel
|
||||||
} /* end namespace AlphaISA */
|
} // namespace AlphaISA
|
||||||
|
|
||||||
#endif // __ARCH_ALPHA_KERNEL_STATS_HH__
|
#endif // __ARCH_ALPHA_KERNEL_STATS_HH__
|
||||||
|
|
|
@ -28,47 +28,44 @@
|
||||||
* Authors: Korey Sewell
|
* Authors: Korey Sewell
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "arch/alpha/linux/linux.hh"
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "arch/alpha/linux/linux.hh"
|
||||||
|
|
||||||
// open(2) flags translation table
|
// open(2) flags translation table
|
||||||
OpenFlagTransTable AlphaLinux::openFlagTable[] = {
|
OpenFlagTransTable AlphaLinux::openFlagTable[] = {
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
{ AlphaLinux::TGT_O_RDONLY, _O_RDONLY },
|
{ AlphaLinux::TGT_O_RDONLY, _O_RDONLY },
|
||||||
{ AlphaLinux::TGT_O_WRONLY, _O_WRONLY },
|
{ AlphaLinux::TGT_O_WRONLY, _O_WRONLY },
|
||||||
{ AlphaLinux::TGT_O_RDWR, _O_RDWR },
|
{ AlphaLinux::TGT_O_RDWR, _O_RDWR },
|
||||||
{ AlphaLinux::TGT_O_APPEND, _O_APPEND },
|
{ AlphaLinux::TGT_O_APPEND, _O_APPEND },
|
||||||
{ AlphaLinux::TGT_O_CREAT, _O_CREAT },
|
{ AlphaLinux::TGT_O_CREAT, _O_CREAT },
|
||||||
{ AlphaLinux::TGT_O_TRUNC, _O_TRUNC },
|
{ AlphaLinux::TGT_O_TRUNC, _O_TRUNC },
|
||||||
{ AlphaLinux::TGT_O_EXCL, _O_EXCL },
|
{ AlphaLinux::TGT_O_EXCL, _O_EXCL },
|
||||||
#ifdef _O_NONBLOCK
|
#ifdef _O_NONBLOCK
|
||||||
{ AlphaLinux::TGT_O_NONBLOCK, _O_NONBLOCK },
|
{ AlphaLinux::TGT_O_NONBLOCK, _O_NONBLOCK },
|
||||||
#endif
|
#endif
|
||||||
#ifdef _O_NOCTTY
|
#ifdef _O_NOCTTY
|
||||||
{ AlphaLinux::TGT_O_NOCTTY, _O_NOCTTY },
|
{ AlphaLinux::TGT_O_NOCTTY, _O_NOCTTY },
|
||||||
#endif
|
#endif
|
||||||
#ifdef _O_SYNC
|
#ifdef _O_SYNC
|
||||||
{ AlphaLinux::TGT_O_SYNC, _O_SYNC },
|
{ AlphaLinux::TGT_O_SYNC, _O_SYNC },
|
||||||
#endif
|
#endif
|
||||||
#else /* !_MSC_VER */
|
#else /* !_MSC_VER */
|
||||||
{ AlphaLinux::TGT_O_RDONLY, O_RDONLY },
|
{ AlphaLinux::TGT_O_RDONLY, O_RDONLY },
|
||||||
{ AlphaLinux::TGT_O_WRONLY, O_WRONLY },
|
{ AlphaLinux::TGT_O_WRONLY, O_WRONLY },
|
||||||
{ AlphaLinux::TGT_O_RDWR, O_RDWR },
|
{ AlphaLinux::TGT_O_RDWR, O_RDWR },
|
||||||
{ AlphaLinux::TGT_O_APPEND, O_APPEND },
|
{ AlphaLinux::TGT_O_APPEND, O_APPEND },
|
||||||
{ AlphaLinux::TGT_O_CREAT, O_CREAT },
|
{ AlphaLinux::TGT_O_CREAT, O_CREAT },
|
||||||
{ AlphaLinux::TGT_O_TRUNC, O_TRUNC },
|
{ AlphaLinux::TGT_O_TRUNC, O_TRUNC },
|
||||||
{ AlphaLinux::TGT_O_EXCL, O_EXCL },
|
{ AlphaLinux::TGT_O_EXCL, O_EXCL },
|
||||||
{ AlphaLinux::TGT_O_NONBLOCK, O_NONBLOCK },
|
{ AlphaLinux::TGT_O_NONBLOCK, O_NONBLOCK },
|
||||||
{ AlphaLinux::TGT_O_NOCTTY, O_NOCTTY },
|
{ AlphaLinux::TGT_O_NOCTTY, O_NOCTTY },
|
||||||
#ifdef O_SYNC
|
#ifdef O_SYNC
|
||||||
{ AlphaLinux::TGT_O_SYNC, O_SYNC },
|
{ AlphaLinux::TGT_O_SYNC, O_SYNC },
|
||||||
#endif
|
#endif
|
||||||
#endif /* _MSC_VER */
|
#endif /* _MSC_VER */
|
||||||
};
|
};
|
||||||
|
|
||||||
const int AlphaLinux::NUM_OPEN_FLAGS =
|
const int AlphaLinux::NUM_OPEN_FLAGS =
|
||||||
(sizeof(AlphaLinux::openFlagTable)/sizeof(AlphaLinux::openFlagTable[0]));
|
(sizeof(AlphaLinux::openFlagTable)/sizeof(AlphaLinux::openFlagTable[0]));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
* Authors: Korey Sewell
|
* Authors: Korey Sewell
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __ALPHA_ALPHA_LINUX_HH
|
#ifndef __ALPHA_ALPHA_LINUX_LINUX_HH__
|
||||||
#define __ALPHA_ALPHA_LINUX_HH
|
#define __ALPHA_ALPHA_LINUX_LINUX_HH__
|
||||||
|
|
||||||
#include "kern/linux/linux.hh"
|
#include "kern/linux/linux.hh"
|
||||||
|
|
||||||
|
@ -50,21 +50,21 @@ class AlphaLinux : public Linux
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
/// open(2) flag values.
|
/// open(2) flag values.
|
||||||
static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY
|
static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY
|
||||||
static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY
|
static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY
|
||||||
static const int TGT_O_RDWR = 00000002; //!< O_RDWR
|
static const int TGT_O_RDWR = 00000002; //!< O_RDWR
|
||||||
static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK
|
static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK
|
||||||
static const int TGT_O_APPEND = 00000010; //!< O_APPEND
|
static const int TGT_O_APPEND = 00000010; //!< O_APPEND
|
||||||
static const int TGT_O_CREAT = 00001000; //!< O_CREAT
|
static const int TGT_O_CREAT = 00001000; //!< O_CREAT
|
||||||
static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC
|
static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC
|
||||||
static const int TGT_O_EXCL = 00004000; //!< O_EXCL
|
static const int TGT_O_EXCL = 00004000; //!< O_EXCL
|
||||||
static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY
|
static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY
|
||||||
static const int TGT_O_SYNC = 00040000; //!< O_SYNC
|
static const int TGT_O_SYNC = 00040000; //!< O_SYNC
|
||||||
static const int TGT_O_DRD = 00100000; //!< O_DRD
|
static const int TGT_O_DRD = 00100000; //!< O_DRD
|
||||||
static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO
|
static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO
|
||||||
static const int TGT_O_CACHE = 00400000; //!< O_CACHE
|
static const int TGT_O_CACHE = 00400000; //!< O_CACHE
|
||||||
static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC
|
static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC
|
||||||
static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC
|
static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/// For mmap().
|
/// For mmap().
|
||||||
|
@ -72,13 +72,13 @@ class AlphaLinux : public Linux
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
/// For getsysinfo().
|
/// For getsysinfo().
|
||||||
static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
|
static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
|
||||||
static const unsigned GSI_CPU_INFO = 59; //!< CPU information
|
static const unsigned GSI_CPU_INFO = 59; //!< CPU information
|
||||||
static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
|
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_MAX_CPU = 30; //!< max # CPUs on machine
|
||||||
static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
|
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_PHYSMEM = 19; //!< Physical memory in KB
|
||||||
static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
|
static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
|
||||||
static const unsigned GSI_IEEE_FP_CONTROL = 45;
|
static const unsigned GSI_IEEE_FP_CONTROL = 45;
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
@ -127,4 +127,4 @@ class AlphaLinux : public Linux
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif // __ALPHA_ALPHA_LINUX_LINUX_HH__
|
||||||
|
|
|
@ -43,18 +43,16 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace AlphaISA;
|
using namespace AlphaISA;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Target uname() handler.
|
/// Target uname() handler.
|
||||||
static SyscallReturn
|
static SyscallReturn
|
||||||
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
|
TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
|
||||||
|
|
||||||
strcpy(name->sysname, "Linux");
|
strcpy(name->sysname, "Linux");
|
||||||
strcpy(name->nodename, "m5.eecs.umich.edu");
|
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->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
||||||
strcpy(name->machine, "alpha");
|
strcpy(name->machine, "alpha");
|
||||||
|
|
||||||
|
@ -69,13 +67,13 @@ static SyscallReturn
|
||||||
osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
unsigned op = tc->getSyscallArg(0);
|
unsigned op = process->getSyscallArg(tc, 0);
|
||||||
// unsigned nbytes = tc->getSyscallArg(2);
|
// unsigned nbytes = process->getSyscallArg(tc, 2);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
|
||||||
case 45: { // GSI_IEEE_FP_CONTROL
|
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
|
// I don't think this exactly matches the HW FPCR
|
||||||
*fpcr = 0;
|
*fpcr = 0;
|
||||||
fpcr.copyOut(tc->getMemPort());
|
fpcr.copyOut(tc->getMemPort());
|
||||||
|
@ -96,13 +94,13 @@ static SyscallReturn
|
||||||
osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
unsigned op = tc->getSyscallArg(0);
|
unsigned op = process->getSyscallArg(tc, 0);
|
||||||
// unsigned nbytes = tc->getSyscallArg(2);
|
// unsigned nbytes = process->getSyscallArg(tc, 2);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
|
||||||
case 14: { // SSI_IEEE_FP_CONTROL
|
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
|
// I don't think this exactly matches the HW FPCR
|
||||||
fpcr.copyIn(tc->getMemPort());
|
fpcr.copyIn(tc->getMemPort());
|
||||||
DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
|
DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
|
||||||
|
@ -138,7 +136,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
|
||||||
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
|
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
|
||||||
/* 15 */ SyscallDesc("chmod", chmodFunc<AlphaLinux>),
|
/* 15 */ SyscallDesc("chmod", chmodFunc<AlphaLinux>),
|
||||||
/* 16 */ SyscallDesc("chown", chownFunc),
|
/* 16 */ SyscallDesc("chown", chownFunc),
|
||||||
/* 17 */ SyscallDesc("brk", obreakFunc),
|
/* 17 */ SyscallDesc("brk", brkFunc),
|
||||||
/* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc),
|
/* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc),
|
||||||
/* 19 */ SyscallDesc("lseek", lseekFunc),
|
/* 19 */ SyscallDesc("lseek", lseekFunc),
|
||||||
/* 20 */ SyscallDesc("getxpid", getpidPseudoFunc),
|
/* 20 */ SyscallDesc("getxpid", getpidPseudoFunc),
|
||||||
|
@ -179,9 +177,9 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
|
||||||
/* 55 */ SyscallDesc("osf_reboot", unimplementedFunc),
|
/* 55 */ SyscallDesc("osf_reboot", unimplementedFunc),
|
||||||
/* 56 */ SyscallDesc("osf_revoke", unimplementedFunc),
|
/* 56 */ SyscallDesc("osf_revoke", unimplementedFunc),
|
||||||
/* 57 */ SyscallDesc("symlink", unimplementedFunc),
|
/* 57 */ SyscallDesc("symlink", unimplementedFunc),
|
||||||
/* 58 */ SyscallDesc("readlink", unimplementedFunc),
|
/* 58 */ SyscallDesc("readlink", readlinkFunc),
|
||||||
/* 59 */ SyscallDesc("execve", unimplementedFunc),
|
/* 59 */ SyscallDesc("execve", unimplementedFunc),
|
||||||
/* 60 */ SyscallDesc("umask", unimplementedFunc),
|
/* 60 */ SyscallDesc("umask", umaskFunc),
|
||||||
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
|
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
|
||||||
/* 62 */ SyscallDesc("osf_old_fstat", unimplementedFunc),
|
/* 62 */ SyscallDesc("osf_old_fstat", unimplementedFunc),
|
||||||
/* 63 */ SyscallDesc("getpgrp", unimplementedFunc),
|
/* 63 */ SyscallDesc("getpgrp", unimplementedFunc),
|
||||||
|
@ -250,14 +248,14 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
|
||||||
/* 126 */ SyscallDesc("setreuid", unimplementedFunc),
|
/* 126 */ SyscallDesc("setreuid", unimplementedFunc),
|
||||||
/* 127 */ SyscallDesc("setregid", unimplementedFunc),
|
/* 127 */ SyscallDesc("setregid", unimplementedFunc),
|
||||||
/* 128 */ SyscallDesc("rename", renameFunc),
|
/* 128 */ SyscallDesc("rename", renameFunc),
|
||||||
/* 129 */ SyscallDesc("truncate", unimplementedFunc),
|
/* 129 */ SyscallDesc("truncate", truncateFunc),
|
||||||
/* 130 */ SyscallDesc("ftruncate", unimplementedFunc),
|
/* 130 */ SyscallDesc("ftruncate", ftruncateFunc),
|
||||||
/* 131 */ SyscallDesc("flock", unimplementedFunc),
|
/* 131 */ SyscallDesc("flock", unimplementedFunc),
|
||||||
/* 132 */ SyscallDesc("setgid", unimplementedFunc),
|
/* 132 */ SyscallDesc("setgid", unimplementedFunc),
|
||||||
/* 133 */ SyscallDesc("sendto", unimplementedFunc),
|
/* 133 */ SyscallDesc("sendto", unimplementedFunc),
|
||||||
/* 134 */ SyscallDesc("shutdown", unimplementedFunc),
|
/* 134 */ SyscallDesc("shutdown", unimplementedFunc),
|
||||||
/* 135 */ SyscallDesc("socketpair", unimplementedFunc),
|
/* 135 */ SyscallDesc("socketpair", unimplementedFunc),
|
||||||
/* 136 */ SyscallDesc("mkdir", unimplementedFunc),
|
/* 136 */ SyscallDesc("mkdir", mkdirFunc),
|
||||||
/* 137 */ SyscallDesc("rmdir", unimplementedFunc),
|
/* 137 */ SyscallDesc("rmdir", unimplementedFunc),
|
||||||
/* 138 */ SyscallDesc("osf_utimes", unimplementedFunc),
|
/* 138 */ SyscallDesc("osf_utimes", unimplementedFunc),
|
||||||
/* 139 */ SyscallDesc("osf_old_sigreturn", unimplementedFunc),
|
/* 139 */ SyscallDesc("osf_old_sigreturn", unimplementedFunc),
|
||||||
|
@ -465,7 +463,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
|
||||||
/* 338 */ SyscallDesc("afs_syscall", unimplementedFunc),
|
/* 338 */ SyscallDesc("afs_syscall", unimplementedFunc),
|
||||||
/* 339 */ SyscallDesc("uname", unameFunc),
|
/* 339 */ SyscallDesc("uname", unameFunc),
|
||||||
/* 340 */ SyscallDesc("nanosleep", unimplementedFunc),
|
/* 340 */ SyscallDesc("nanosleep", unimplementedFunc),
|
||||||
/* 341 */ SyscallDesc("mremap", unimplementedFunc),
|
/* 341 */ SyscallDesc("mremap", mremapFunc<AlphaLinux>),
|
||||||
/* 342 */ SyscallDesc("nfsservctl", unimplementedFunc),
|
/* 342 */ SyscallDesc("nfsservctl", unimplementedFunc),
|
||||||
/* 343 */ SyscallDesc("setresuid", unimplementedFunc),
|
/* 343 */ SyscallDesc("setresuid", unimplementedFunc),
|
||||||
/* 344 */ SyscallDesc("getresuid", unimplementedFunc),
|
/* 344 */ SyscallDesc("getresuid", unimplementedFunc),
|
||||||
|
@ -491,7 +489,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
|
||||||
/* 364 */ SyscallDesc("getrusage", getrusageFunc<AlphaLinux>),
|
/* 364 */ SyscallDesc("getrusage", getrusageFunc<AlphaLinux>),
|
||||||
/* 365 */ SyscallDesc("wait4", unimplementedFunc),
|
/* 365 */ SyscallDesc("wait4", unimplementedFunc),
|
||||||
/* 366 */ SyscallDesc("adjtimex", unimplementedFunc),
|
/* 366 */ SyscallDesc("adjtimex", unimplementedFunc),
|
||||||
/* 367 */ SyscallDesc("getcwd", unimplementedFunc),
|
/* 367 */ SyscallDesc("getcwd", getcwdFunc),
|
||||||
/* 368 */ SyscallDesc("capget", unimplementedFunc),
|
/* 368 */ SyscallDesc("capget", unimplementedFunc),
|
||||||
/* 369 */ SyscallDesc("capset", unimplementedFunc),
|
/* 369 */ SyscallDesc("capset", unimplementedFunc),
|
||||||
/* 370 */ SyscallDesc("sendfile", unimplementedFunc),
|
/* 370 */ SyscallDesc("sendfile", unimplementedFunc),
|
||||||
|
@ -581,7 +579,7 @@ AlphaLinuxProcess::AlphaLinuxProcess(LiveProcessParams * params,
|
||||||
SyscallDesc*
|
SyscallDesc*
|
||||||
AlphaLinuxProcess::getDesc(int callnum)
|
AlphaLinuxProcess::getDesc(int callnum)
|
||||||
{
|
{
|
||||||
if (callnum < 0 || callnum > Num_Syscall_Descs)
|
if (callnum < 0 || callnum >= Num_Syscall_Descs)
|
||||||
return NULL;
|
return NULL;
|
||||||
return &syscallDescs[callnum];
|
return &syscallDescs[callnum];
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,4 +51,5 @@ class AlphaLinuxProcess : public AlphaLiveProcess
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AlphaISA
|
} // namespace AlphaISA
|
||||||
|
|
||||||
#endif // __ALPHA_LINUX_PROCESS_HH__
|
#endif // __ALPHA_LINUX_PROCESS_HH__
|
||||||
|
|
|
@ -157,7 +157,6 @@ LinuxAlphaSystem::~LinuxAlphaSystem()
|
||||||
delete printThreadEvent;
|
delete printThreadEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LinuxAlphaSystem::setDelayLoop(ThreadContext *tc)
|
LinuxAlphaSystem::setDelayLoop(ThreadContext *tc)
|
||||||
{
|
{
|
||||||
|
@ -169,11 +168,9 @@ LinuxAlphaSystem::setDelayLoop(ThreadContext *tc)
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtPort();
|
||||||
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
|
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
|
||||||
tc->delVirtPort(vp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LinuxAlphaSystem::SkipDelayLoopEvent::process(ThreadContext *tc)
|
LinuxAlphaSystem::SkipDelayLoopEvent::process(ThreadContext *tc)
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,9 +43,6 @@ class IdleStartEvent;
|
||||||
#include "kern/linux/events.hh"
|
#include "kern/linux/events.hh"
|
||||||
#include "params/LinuxAlphaSystem.hh"
|
#include "params/LinuxAlphaSystem.hh"
|
||||||
|
|
||||||
using namespace AlphaISA;
|
|
||||||
using namespace Linux;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class contains linux specific system code (Loading, Events).
|
* This class contains linux specific system code (Loading, Events).
|
||||||
* It points to objects that are the system binaries to load and patches them
|
* 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
|
class LinuxAlphaSystem : public AlphaSystem
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
class SkipDelayLoopEvent : public SkipFuncEvent
|
struct SkipDelayLoopEvent : public SkipFuncEvent
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
SkipDelayLoopEvent(PCEventQueue *q, const std::string &desc, Addr addr)
|
SkipDelayLoopEvent(PCEventQueue *q, const std::string &desc, Addr addr)
|
||||||
: SkipFuncEvent(q, desc, addr) {}
|
: SkipFuncEvent(q, desc, addr) {}
|
||||||
virtual void process(ThreadContext *tc);
|
virtual void process(ThreadContext *tc);
|
||||||
};
|
};
|
||||||
|
|
||||||
class PrintThreadInfo : public PCEvent
|
struct PrintThreadInfo : public PCEvent
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
PrintThreadInfo(PCEventQueue *q, const std::string &desc, Addr addr)
|
PrintThreadInfo(PCEventQueue *q, const std::string &desc, Addr addr)
|
||||||
: PCEvent(q, desc, addr) {}
|
: PCEvent(q, desc, addr) {}
|
||||||
virtual void process(ThreadContext *tc);
|
virtual void process(ThreadContext *tc);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Addresses defining where the kernel bootloader places various
|
* Addresses defining where the kernel bootloader places various
|
||||||
* elements. Details found in include/asm-alpha/system.h
|
* 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
|
* PC based event to skip the dprink() call and emulate its
|
||||||
* functionality
|
* functionality
|
||||||
*/
|
*/
|
||||||
DebugPrintkEvent *debugPrintkEvent;
|
Linux::DebugPrintkEvent *debugPrintkEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skip calculate_delay_loop() rather than waiting for this to be
|
* Skip calculate_delay_loop() rather than waiting for this to be
|
||||||
|
|
|
@ -55,7 +55,7 @@ class ThreadInfo
|
||||||
|
|
||||||
CopyOut(tc, &data, addr, sizeof(T));
|
CopyOut(tc, &data, addr, sizeof(T));
|
||||||
|
|
||||||
data = TheISA::gtoh(data);
|
data = AlphaISA::gtoh(data);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ class ThreadInfo
|
||||||
Addr sp;
|
Addr sp;
|
||||||
|
|
||||||
if (!addr)
|
if (!addr)
|
||||||
addr = tc->readMiscRegNoEffect(TheISA::IPR_PALtemp23);
|
addr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23);
|
||||||
|
|
||||||
FunctionalPort *p = tc->getPhysPort();
|
FunctionalPort *p = tc->getPhysPort();
|
||||||
p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
|
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__
|
#endif // __ARCH_ALPHA_LINUX_LINUX_THREADINFO_HH__
|
||||||
|
|
|
@ -49,9 +49,8 @@
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
#include "mem/request.hh"
|
#include "mem/request.hh"
|
||||||
|
|
||||||
|
namespace AlphaISA {
|
||||||
|
|
||||||
namespace AlphaISA
|
|
||||||
{
|
|
||||||
template <class XC>
|
template <class XC>
|
||||||
inline void
|
inline void
|
||||||
handleLockedRead(XC *xc, Request *req)
|
handleLockedRead(XC *xc, Request *req)
|
||||||
|
@ -86,9 +85,9 @@ handleLockedWrite(XC *xc, Request *req)
|
||||||
stCondFailures++;
|
stCondFailures++;
|
||||||
xc->setStCondFailures(stCondFailures);
|
xc->setStCondFailures(stCondFailures);
|
||||||
if (stCondFailures % 100000 == 0) {
|
if (stCondFailures % 100000 == 0) {
|
||||||
warn("cpu %d: %d consecutive "
|
warn("context %d: %d consecutive "
|
||||||
"store conditional failures\n",
|
"store conditional failures\n",
|
||||||
xc->readCpuId(), stCondFailures);
|
xc->contextId(), stCondFailures);
|
||||||
}
|
}
|
||||||
|
|
||||||
// store conditional failed already, so don't issue it to mem
|
// store conditional failed already, so don't issue it to mem
|
||||||
|
@ -99,7 +98,6 @@ handleLockedWrite(XC *xc, Request *req)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace AlphaISA
|
} // namespace AlphaISA
|
||||||
|
|
||||||
#endif
|
#endif // __ARCH_ALPHA_LOCKED_MEM_HH__
|
||||||
|
|
41
src/arch/alpha/microcode_rom.hh
Normal file
41
src/arch/alpha/microcode_rom.hh
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008 The Regents of The University of Michigan
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met: redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer;
|
||||||
|
* redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution;
|
||||||
|
* neither the name of the copyright holders nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Authors: Gabe Black
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ARCH_ALPHA_MICROCODE_ROM_HH__
|
||||||
|
#define __ARCH_ALPHA_MICROCODE_ROM_HH__
|
||||||
|
|
||||||
|
#include "sim/microcode_rom.hh"
|
||||||
|
|
||||||
|
namespace AlphaISA
|
||||||
|
{
|
||||||
|
using ::MicrocodeRom;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __ARCH_ALPHA_MICROCODE_ROM_HH__
|
|
@ -30,121 +30,121 @@
|
||||||
* Kevin Lim
|
* Kevin Lim
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#include "arch/alpha/miscregfile.hh"
|
#include "arch/alpha/miscregfile.hh"
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
|
|
||||||
namespace AlphaISA
|
namespace AlphaISA {
|
||||||
|
|
||||||
|
void
|
||||||
|
MiscRegFile::serialize(std::ostream &os)
|
||||||
{
|
{
|
||||||
|
SERIALIZE_SCALAR(fpcr);
|
||||||
void
|
SERIALIZE_SCALAR(uniq);
|
||||||
MiscRegFile::serialize(std::ostream &os)
|
SERIALIZE_SCALAR(lock_flag);
|
||||||
{
|
SERIALIZE_SCALAR(lock_addr);
|
||||||
SERIALIZE_SCALAR(fpcr);
|
SERIALIZE_ARRAY(ipr, NumInternalProcRegs);
|
||||||
SERIALIZE_SCALAR(uniq);
|
|
||||||
SERIALIZE_SCALAR(lock_flag);
|
|
||||||
SERIALIZE_SCALAR(lock_addr);
|
|
||||||
SERIALIZE_ARRAY(ipr, NumInternalProcRegs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
MiscRegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
|
||||||
{
|
|
||||||
UNSERIALIZE_SCALAR(fpcr);
|
|
||||||
UNSERIALIZE_SCALAR(uniq);
|
|
||||||
UNSERIALIZE_SCALAR(lock_flag);
|
|
||||||
UNSERIALIZE_SCALAR(lock_addr);
|
|
||||||
UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs);
|
|
||||||
}
|
|
||||||
|
|
||||||
MiscReg
|
|
||||||
MiscRegFile::readRegNoEffect(int misc_reg)
|
|
||||||
{
|
|
||||||
switch(misc_reg) {
|
|
||||||
case MISCREG_FPCR:
|
|
||||||
return fpcr;
|
|
||||||
case MISCREG_UNIQ:
|
|
||||||
return uniq;
|
|
||||||
case MISCREG_LOCKFLAG:
|
|
||||||
return lock_flag;
|
|
||||||
case MISCREG_LOCKADDR:
|
|
||||||
return lock_addr;
|
|
||||||
case MISCREG_INTR:
|
|
||||||
return intr_flag;
|
|
||||||
default:
|
|
||||||
assert(misc_reg < NumInternalProcRegs);
|
|
||||||
return ipr[misc_reg];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MiscReg
|
|
||||||
MiscRegFile::readReg(int misc_reg, ThreadContext *tc)
|
|
||||||
{
|
|
||||||
switch(misc_reg) {
|
|
||||||
case MISCREG_FPCR:
|
|
||||||
return fpcr;
|
|
||||||
case MISCREG_UNIQ:
|
|
||||||
return uniq;
|
|
||||||
case MISCREG_LOCKFLAG:
|
|
||||||
return lock_flag;
|
|
||||||
case MISCREG_LOCKADDR:
|
|
||||||
return lock_addr;
|
|
||||||
case MISCREG_INTR:
|
|
||||||
return intr_flag;
|
|
||||||
default:
|
|
||||||
return readIpr(misc_reg, tc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val)
|
|
||||||
{
|
|
||||||
switch(misc_reg) {
|
|
||||||
case MISCREG_FPCR:
|
|
||||||
fpcr = val;
|
|
||||||
return;
|
|
||||||
case MISCREG_UNIQ:
|
|
||||||
uniq = val;
|
|
||||||
return;
|
|
||||||
case MISCREG_LOCKFLAG:
|
|
||||||
lock_flag = val;
|
|
||||||
return;
|
|
||||||
case MISCREG_LOCKADDR:
|
|
||||||
lock_addr = val;
|
|
||||||
return;
|
|
||||||
case MISCREG_INTR:
|
|
||||||
intr_flag = val;
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
assert(misc_reg < NumInternalProcRegs);
|
|
||||||
ipr[misc_reg] = val;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
MiscRegFile::setReg(int misc_reg, const MiscReg &val,
|
|
||||||
ThreadContext *tc)
|
|
||||||
{
|
|
||||||
switch(misc_reg) {
|
|
||||||
case MISCREG_FPCR:
|
|
||||||
fpcr = val;
|
|
||||||
return;
|
|
||||||
case MISCREG_UNIQ:
|
|
||||||
uniq = val;
|
|
||||||
return;
|
|
||||||
case MISCREG_LOCKFLAG:
|
|
||||||
lock_flag = val;
|
|
||||||
return;
|
|
||||||
case MISCREG_LOCKADDR:
|
|
||||||
lock_addr = val;
|
|
||||||
return;
|
|
||||||
case MISCREG_INTR:
|
|
||||||
intr_flag = val;
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
setIpr(misc_reg, val, tc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MiscRegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
|
{
|
||||||
|
UNSERIALIZE_SCALAR(fpcr);
|
||||||
|
UNSERIALIZE_SCALAR(uniq);
|
||||||
|
UNSERIALIZE_SCALAR(lock_flag);
|
||||||
|
UNSERIALIZE_SCALAR(lock_addr);
|
||||||
|
UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs);
|
||||||
|
}
|
||||||
|
|
||||||
|
MiscReg
|
||||||
|
MiscRegFile::readRegNoEffect(int misc_reg)
|
||||||
|
{
|
||||||
|
switch (misc_reg) {
|
||||||
|
case MISCREG_FPCR:
|
||||||
|
return fpcr;
|
||||||
|
case MISCREG_UNIQ:
|
||||||
|
return uniq;
|
||||||
|
case MISCREG_LOCKFLAG:
|
||||||
|
return lock_flag;
|
||||||
|
case MISCREG_LOCKADDR:
|
||||||
|
return lock_addr;
|
||||||
|
case MISCREG_INTR:
|
||||||
|
return intr_flag;
|
||||||
|
default:
|
||||||
|
assert(misc_reg < NumInternalProcRegs);
|
||||||
|
return ipr[misc_reg];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MiscReg
|
||||||
|
MiscRegFile::readReg(int misc_reg, ThreadContext *tc)
|
||||||
|
{
|
||||||
|
switch (misc_reg) {
|
||||||
|
case MISCREG_FPCR:
|
||||||
|
return fpcr;
|
||||||
|
case MISCREG_UNIQ:
|
||||||
|
return uniq;
|
||||||
|
case MISCREG_LOCKFLAG:
|
||||||
|
return lock_flag;
|
||||||
|
case MISCREG_LOCKADDR:
|
||||||
|
return lock_addr;
|
||||||
|
case MISCREG_INTR:
|
||||||
|
return intr_flag;
|
||||||
|
default:
|
||||||
|
return readIpr(misc_reg, tc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val)
|
||||||
|
{
|
||||||
|
switch (misc_reg) {
|
||||||
|
case MISCREG_FPCR:
|
||||||
|
fpcr = val;
|
||||||
|
return;
|
||||||
|
case MISCREG_UNIQ:
|
||||||
|
uniq = val;
|
||||||
|
return;
|
||||||
|
case MISCREG_LOCKFLAG:
|
||||||
|
lock_flag = val;
|
||||||
|
return;
|
||||||
|
case MISCREG_LOCKADDR:
|
||||||
|
lock_addr = val;
|
||||||
|
return;
|
||||||
|
case MISCREG_INTR:
|
||||||
|
intr_flag = val;
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
assert(misc_reg < NumInternalProcRegs);
|
||||||
|
ipr[misc_reg] = val;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MiscRegFile::setReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
|
||||||
|
{
|
||||||
|
switch (misc_reg) {
|
||||||
|
case MISCREG_FPCR:
|
||||||
|
fpcr = val;
|
||||||
|
return;
|
||||||
|
case MISCREG_UNIQ:
|
||||||
|
uniq = val;
|
||||||
|
return;
|
||||||
|
case MISCREG_LOCKFLAG:
|
||||||
|
lock_flag = val;
|
||||||
|
return;
|
||||||
|
case MISCREG_LOCKADDR:
|
||||||
|
lock_addr = val;
|
||||||
|
return;
|
||||||
|
case MISCREG_INTR:
|
||||||
|
intr_flag = val;
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
setIpr(misc_reg, val, tc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace AlphaISA
|
||||||
|
|
|
@ -32,85 +32,79 @@
|
||||||
#ifndef __ARCH_ALPHA_MISCREGFILE_HH__
|
#ifndef __ARCH_ALPHA_MISCREGFILE_HH__
|
||||||
#define __ARCH_ALPHA_MISCREGFILE_HH__
|
#define __ARCH_ALPHA_MISCREGFILE_HH__
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
|
|
||||||
#include "arch/alpha/ipr.hh"
|
#include "arch/alpha/ipr.hh"
|
||||||
#include "arch/alpha/types.hh"
|
#include "arch/alpha/types.hh"
|
||||||
#include "sim/host.hh"
|
#include "sim/host.hh"
|
||||||
#include "sim/serialize.hh"
|
#include "sim/serialize.hh"
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
class Checkpoint;
|
class Checkpoint;
|
||||||
class ThreadContext;
|
class ThreadContext;
|
||||||
|
|
||||||
namespace AlphaISA
|
namespace AlphaISA {
|
||||||
{
|
|
||||||
enum MiscRegIndex
|
|
||||||
{
|
|
||||||
MISCREG_FPCR = NumInternalProcRegs,
|
|
||||||
MISCREG_UNIQ,
|
|
||||||
MISCREG_LOCKFLAG,
|
|
||||||
MISCREG_LOCKADDR,
|
|
||||||
MISCREG_INTR
|
|
||||||
};
|
|
||||||
|
|
||||||
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 {
|
// These functions should be removed once the simplescalar cpu
|
||||||
protected:
|
// model has been replaced.
|
||||||
uint64_t fpcr; // floating point condition codes
|
int getInstAsid();
|
||||||
uint64_t uniq; // process-unique register
|
int getDataAsid();
|
||||||
bool lock_flag; // lock flag for LL/SC
|
|
||||||
Addr lock_addr; // lock address for LL/SC
|
|
||||||
int intr_flag;
|
|
||||||
|
|
||||||
public:
|
MiscReg readRegNoEffect(int misc_reg);
|
||||||
MiscRegFile()
|
MiscReg readReg(int misc_reg, ThreadContext *tc);
|
||||||
{
|
|
||||||
initializeIprTable();
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
void serialize(std::ostream &os);
|
||||||
//has been replaced.
|
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
int getInstAsid();
|
};
|
||||||
int getDataAsid();
|
|
||||||
|
|
||||||
void setRegNoEffect(int misc_reg, const MiscReg &val);
|
void copyIprs(ThreadContext *src, ThreadContext *dest);
|
||||||
|
|
||||||
void setReg(int misc_reg, const MiscReg &val,
|
} // namespace AlphaISA
|
||||||
ThreadContext *tc);
|
|
||||||
|
|
||||||
void clear()
|
#endif // __ARCH_ALPHA_MISCREGFILE_HH__
|
||||||
{
|
|
||||||
fpcr = uniq = 0;
|
|
||||||
lock_flag = 0;
|
|
||||||
lock_addr = 0;
|
|
||||||
intr_flag = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void serialize(std::ostream &os);
|
|
||||||
|
|
||||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
|
||||||
protected:
|
|
||||||
typedef uint64_t InternalProcReg;
|
|
||||||
|
|
||||||
InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
|
|
||||||
|
|
||||||
private:
|
|
||||||
InternalProcReg readIpr(int idx, ThreadContext *tc);
|
|
||||||
|
|
||||||
void setIpr(int idx, InternalProcReg val, ThreadContext *tc);
|
|
||||||
friend class RegFile;
|
|
||||||
};
|
|
||||||
|
|
||||||
void copyIprs(ThreadContext *src, ThreadContext *dest);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -39,9 +39,8 @@
|
||||||
|
|
||||||
#include "mem/packet.hh"
|
#include "mem/packet.hh"
|
||||||
|
|
||||||
|
namespace AlphaISA {
|
||||||
|
|
||||||
namespace AlphaISA
|
|
||||||
{
|
|
||||||
inline Tick
|
inline Tick
|
||||||
handleIprRead(ThreadContext *xc, Packet *pkt)
|
handleIprRead(ThreadContext *xc, Packet *pkt)
|
||||||
{
|
{
|
||||||
|
@ -58,4 +57,4 @@ handleIprWrite(ThreadContext *xc, Packet *pkt)
|
||||||
|
|
||||||
} // namespace AlphaISA
|
} // namespace AlphaISA
|
||||||
|
|
||||||
#endif
|
#endif // __ARCH_ALPHA_MMAPED_IPR_HH__
|
||||||
|
|
|
@ -30,275 +30,273 @@
|
||||||
|
|
||||||
#include "arch/alpha/osfpal.hh"
|
#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 *
|
const char *
|
||||||
PAL::name(int index)
|
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)
|
if (index > NumCodes || index < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
* Authors: Nathan Binkert
|
* Authors: Nathan Binkert
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __OSFPAL_HH__
|
#ifndef __ARCH_ALPHA_OSFPAL_HH__
|
||||||
#define __OSFPAL_HH__
|
#define __ARCH_ALPHA_OSFPAL_HH__
|
||||||
|
|
||||||
struct PAL
|
struct PAL
|
||||||
{
|
{
|
||||||
|
@ -79,4 +79,4 @@ struct PAL
|
||||||
static const char *name(int index);
|
static const char *name(int index);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __OSFPAL_HH__
|
#endif // __ARCH_ALPHA_OSFPAL_HH__
|
||||||
|
|
|
@ -31,33 +31,34 @@
|
||||||
#include "arch/alpha/pagetable.hh"
|
#include "arch/alpha/pagetable.hh"
|
||||||
#include "sim/serialize.hh"
|
#include "sim/serialize.hh"
|
||||||
|
|
||||||
namespace AlphaISA
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TlbEntry::unserialize(Checkpoint *cp, const std::string §ion)
|
TlbEntry::serialize(std::ostream &os)
|
||||||
{
|
{
|
||||||
UNSERIALIZE_SCALAR(tag);
|
SERIALIZE_SCALAR(tag);
|
||||||
UNSERIALIZE_SCALAR(ppn);
|
SERIALIZE_SCALAR(ppn);
|
||||||
UNSERIALIZE_SCALAR(xre);
|
SERIALIZE_SCALAR(xre);
|
||||||
UNSERIALIZE_SCALAR(xwe);
|
SERIALIZE_SCALAR(xwe);
|
||||||
UNSERIALIZE_SCALAR(asn);
|
SERIALIZE_SCALAR(asn);
|
||||||
UNSERIALIZE_SCALAR(asma);
|
SERIALIZE_SCALAR(asma);
|
||||||
UNSERIALIZE_SCALAR(fonr);
|
SERIALIZE_SCALAR(fonr);
|
||||||
UNSERIALIZE_SCALAR(fonw);
|
SERIALIZE_SCALAR(fonw);
|
||||||
UNSERIALIZE_SCALAR(valid);
|
SERIALIZE_SCALAR(valid);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TlbEntry::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
|
{
|
||||||
|
UNSERIALIZE_SCALAR(tag);
|
||||||
|
UNSERIALIZE_SCALAR(ppn);
|
||||||
|
UNSERIALIZE_SCALAR(xre);
|
||||||
|
UNSERIALIZE_SCALAR(xwe);
|
||||||
|
UNSERIALIZE_SCALAR(asn);
|
||||||
|
UNSERIALIZE_SCALAR(asma);
|
||||||
|
UNSERIALIZE_SCALAR(fonr);
|
||||||
|
UNSERIALIZE_SCALAR(fonw);
|
||||||
|
UNSERIALIZE_SCALAR(valid);
|
||||||
|
}
|
||||||
|
|
||||||
|
} //namespace AlphaISA
|
||||||
|
|
|
@ -38,97 +38,109 @@
|
||||||
|
|
||||||
namespace AlphaISA {
|
namespace AlphaISA {
|
||||||
|
|
||||||
struct VAddr
|
struct VAddr
|
||||||
{
|
{
|
||||||
static const int ImplBits = 43;
|
static const int ImplBits = 43;
|
||||||
static const Addr ImplMask = (ULL(1) << ImplBits) - 1;
|
static const Addr ImplMask = (ULL(1) << ImplBits) - 1;
|
||||||
static const Addr UnImplMask = ~ImplMask;
|
static const Addr UnImplMask = ~ImplMask;
|
||||||
|
|
||||||
VAddr(Addr a) : addr(a) {}
|
Addr addr;
|
||||||
Addr addr;
|
|
||||||
operator Addr() const { return addr; }
|
|
||||||
const VAddr &operator=(Addr a) { addr = a; return *this; }
|
|
||||||
|
|
||||||
Addr vpn() const { return (addr & ImplMask) >> PageShift; }
|
VAddr(Addr a) : addr(a) {}
|
||||||
Addr page() const { return addr & PageMask; }
|
operator Addr() const { return addr; }
|
||||||
Addr offset() const { return addr & PageOffset; }
|
const VAddr &operator=(Addr a) { addr = a; return *this; }
|
||||||
|
|
||||||
Addr level3() const
|
Addr vpn() const { return (addr & ImplMask) >> PageShift; }
|
||||||
{ return AlphaISA::PteAddr(addr >> PageShift); }
|
Addr page() const { return addr & PageMask; }
|
||||||
Addr level2() const
|
Addr offset() const { return addr & PageOffset; }
|
||||||
{ return AlphaISA::PteAddr(addr >> NPtePageShift + PageShift); }
|
|
||||||
Addr level1() const
|
|
||||||
{ return AlphaISA::PteAddr(addr >> 2 * NPtePageShift + PageShift); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PageTableEntry
|
|
||||||
{
|
|
||||||
PageTableEntry(uint64_t e) : entry(e) {}
|
|
||||||
uint64_t entry;
|
|
||||||
operator uint64_t() const { return entry; }
|
|
||||||
const PageTableEntry &operator=(uint64_t e) { entry = e; return *this; }
|
|
||||||
const PageTableEntry &operator=(const PageTableEntry &e)
|
|
||||||
{ entry = e.entry; return *this; }
|
|
||||||
|
|
||||||
Addr _pfn() const { return (entry >> 32) & 0xffffffff; }
|
|
||||||
Addr _sw() const { return (entry >> 16) & 0xffff; }
|
|
||||||
int _rsv0() const { return (entry >> 14) & 0x3; }
|
|
||||||
bool _uwe() const { return (entry >> 13) & 0x1; }
|
|
||||||
bool _kwe() const { return (entry >> 12) & 0x1; }
|
|
||||||
int _rsv1() const { return (entry >> 10) & 0x3; }
|
|
||||||
bool _ure() const { return (entry >> 9) & 0x1; }
|
|
||||||
bool _kre() const { return (entry >> 8) & 0x1; }
|
|
||||||
bool _nomb() const { return (entry >> 7) & 0x1; }
|
|
||||||
int _gh() const { return (entry >> 5) & 0x3; }
|
|
||||||
bool _asm_() const { return (entry >> 4) & 0x1; }
|
|
||||||
bool _foe() const { return (entry >> 3) & 0x1; }
|
|
||||||
bool _fow() const { return (entry >> 2) & 0x1; }
|
|
||||||
bool _for() const { return (entry >> 1) & 0x1; }
|
|
||||||
bool valid() const { return (entry >> 0) & 0x1; }
|
|
||||||
|
|
||||||
Addr paddr() const { return _pfn() << PageShift; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// ITB/DTB table entry
|
|
||||||
struct TlbEntry
|
|
||||||
{
|
|
||||||
//Construct an entry that maps to physical address addr.
|
|
||||||
TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr)
|
|
||||||
{
|
|
||||||
VAddr vaddr(_vaddr);
|
|
||||||
VAddr paddr(_paddr);
|
|
||||||
tag = vaddr.vpn();
|
|
||||||
ppn = paddr.vpn();
|
|
||||||
xre = 15;
|
|
||||||
xwe = 15;
|
|
||||||
asn = _asn;
|
|
||||||
asma = false;
|
|
||||||
fonr = false;
|
|
||||||
fonw = false;
|
|
||||||
valid = true;
|
|
||||||
}
|
|
||||||
TlbEntry()
|
|
||||||
{}
|
|
||||||
|
|
||||||
Addr tag; // virtual page number tag
|
|
||||||
Addr ppn; // physical page number
|
|
||||||
uint8_t xre; // read permissions - VMEM_PERM_* mask
|
|
||||||
uint8_t xwe; // write permissions - VMEM_PERM_* mask
|
|
||||||
uint8_t asn; // address space number
|
|
||||||
bool asma; // address space match
|
|
||||||
bool fonr; // fault on read
|
|
||||||
bool fonw; // fault on write
|
|
||||||
bool valid; // valid page table entry
|
|
||||||
|
|
||||||
Addr pageStart()
|
|
||||||
{
|
|
||||||
return ppn << PageShift;
|
|
||||||
}
|
|
||||||
|
|
||||||
void serialize(std::ostream &os);
|
|
||||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
Addr level3() const
|
||||||
|
{ return PteAddr(addr >> PageShift); }
|
||||||
|
Addr level2() const
|
||||||
|
{ return PteAddr(addr >> (NPtePageShift + PageShift)); }
|
||||||
|
Addr level1() const
|
||||||
|
{ return PteAddr(addr >> (2 * NPtePageShift + PageShift)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PageTableEntry
|
||||||
|
{
|
||||||
|
PageTableEntry(uint64_t e) : entry(e) {}
|
||||||
|
uint64_t entry;
|
||||||
|
operator uint64_t() const { return entry; }
|
||||||
|
const PageTableEntry &operator=(uint64_t e) { entry = e; return *this; }
|
||||||
|
const PageTableEntry &operator=(const PageTableEntry &e)
|
||||||
|
{ entry = e.entry; return *this; }
|
||||||
|
|
||||||
|
Addr _pfn() const { return (entry >> 32) & 0xffffffff; }
|
||||||
|
Addr _sw() const { return (entry >> 16) & 0xffff; }
|
||||||
|
int _rsv0() const { return (entry >> 14) & 0x3; }
|
||||||
|
bool _uwe() const { return (entry >> 13) & 0x1; }
|
||||||
|
bool _kwe() const { return (entry >> 12) & 0x1; }
|
||||||
|
int _rsv1() const { return (entry >> 10) & 0x3; }
|
||||||
|
bool _ure() const { return (entry >> 9) & 0x1; }
|
||||||
|
bool _kre() const { return (entry >> 8) & 0x1; }
|
||||||
|
bool _nomb() const { return (entry >> 7) & 0x1; }
|
||||||
|
int _gh() const { return (entry >> 5) & 0x3; }
|
||||||
|
bool _asm_() const { return (entry >> 4) & 0x1; }
|
||||||
|
bool _foe() const { return (entry >> 3) & 0x1; }
|
||||||
|
bool _fow() const { return (entry >> 2) & 0x1; }
|
||||||
|
bool _for() const { return (entry >> 1) & 0x1; }
|
||||||
|
bool valid() const { return (entry >> 0) & 0x1; }
|
||||||
|
|
||||||
|
Addr paddr() const { return _pfn() << PageShift; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ITB/DTB table entry
|
||||||
|
struct TlbEntry
|
||||||
|
{
|
||||||
|
Addr tag; // virtual page number tag
|
||||||
|
Addr ppn; // physical page number
|
||||||
|
uint8_t xre; // read permissions - VMEM_PERM_* mask
|
||||||
|
uint8_t xwe; // write permissions - VMEM_PERM_* mask
|
||||||
|
uint8_t asn; // address space number
|
||||||
|
bool asma; // address space match
|
||||||
|
bool fonr; // fault on read
|
||||||
|
bool fonw; // fault on write
|
||||||
|
bool valid; // valid page table entry
|
||||||
|
|
||||||
|
|
||||||
|
//Construct an entry that maps to physical address addr.
|
||||||
|
TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr)
|
||||||
|
{
|
||||||
|
VAddr vaddr(_vaddr);
|
||||||
|
VAddr paddr(_paddr);
|
||||||
|
tag = vaddr.vpn();
|
||||||
|
ppn = paddr.vpn();
|
||||||
|
xre = 15;
|
||||||
|
xwe = 15;
|
||||||
|
asn = _asn;
|
||||||
|
asma = false;
|
||||||
|
fonr = false;
|
||||||
|
fonw = false;
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TlbEntry()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void
|
||||||
|
updateVaddr(Addr new_vaddr)
|
||||||
|
{
|
||||||
|
VAddr vaddr(new_vaddr);
|
||||||
|
tag = vaddr.vpn();
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr
|
||||||
|
pageStart()
|
||||||
|
{
|
||||||
|
return ppn << PageShift;
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialize(std::ostream &os);
|
||||||
|
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace AlphaISA
|
||||||
|
|
||||||
#endif // __ARCH_ALPHA_PAGETABLE_H__
|
#endif // __ARCH_ALPHA_PAGETABLE_H__
|
||||||
|
|
||||||
|
|
|
@ -38,62 +38,72 @@
|
||||||
|
|
||||||
class ThreadContext;
|
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:
|
return tc;
|
||||||
ThreadContext * tc;
|
}
|
||||||
//The extended machine instruction being generated
|
|
||||||
ExtMachInst ext_inst;
|
|
||||||
|
|
||||||
public:
|
void
|
||||||
Predecoder(ThreadContext * _tc) : tc(_tc)
|
setTC(ThreadContext * _tc)
|
||||||
{}
|
{
|
||||||
|
tc = _tc;
|
||||||
|
}
|
||||||
|
|
||||||
ThreadContext * getTC()
|
void
|
||||||
{
|
process()
|
||||||
return tc;
|
{ }
|
||||||
}
|
|
||||||
|
|
||||||
void setTC(ThreadContext * _tc)
|
void
|
||||||
{
|
reset()
|
||||||
tc = _tc;
|
{ }
|
||||||
}
|
|
||||||
|
|
||||||
void process()
|
// Use this to give data to the predecoder. This should be used
|
||||||
{
|
// when there is control flow.
|
||||||
}
|
void
|
||||||
|
moreBytes(Addr pc, Addr fetchPC, MachInst inst)
|
||||||
void reset()
|
{
|
||||||
{}
|
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
|
#if FULL_SYSTEM
|
||||||
ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
|
ext_inst |= (static_cast<ExtMachInst>(pc & 0x1) << 32);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool needMoreBytes()
|
bool
|
||||||
{
|
needMoreBytes()
|
||||||
return true;
|
{
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool extMachInstReady()
|
bool
|
||||||
{
|
extMachInstReady()
|
||||||
return true;
|
{
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//This returns a constant reference to the ExtMachInst to avoid a copy
|
// This returns a constant reference to the ExtMachInst to avoid a copy
|
||||||
const ExtMachInst & getExtMachInst()
|
const ExtMachInst &
|
||||||
{
|
getExtMachInst()
|
||||||
return ext_inst;
|
{
|
||||||
}
|
return ext_inst;
|
||||||
};
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace AlphaISA
|
||||||
|
|
||||||
#endif // __ARCH_ALPHA_PREDECODER_HH__
|
#endif // __ARCH_ALPHA_PREDECODER_HH__
|
||||||
|
|
|
@ -32,16 +32,20 @@
|
||||||
#include "arch/alpha/isa_traits.hh"
|
#include "arch/alpha/isa_traits.hh"
|
||||||
#include "arch/alpha/process.hh"
|
#include "arch/alpha/process.hh"
|
||||||
#include "base/loader/object_file.hh"
|
#include "base/loader/object_file.hh"
|
||||||
|
#include "base/loader/elf_object.hh"
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
|
#include "mem/page_table.hh"
|
||||||
|
#include "sim/process_impl.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
|
|
||||||
using namespace AlphaISA;
|
using namespace AlphaISA;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams * params,
|
static const int SyscallSuccessReg = 19;
|
||||||
ObjectFile *objFile)
|
|
||||||
|
AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams *params,
|
||||||
|
ObjectFile *objFile)
|
||||||
: LiveProcess(params, objFile)
|
: LiveProcess(params, objFile)
|
||||||
{
|
{
|
||||||
brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
|
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.
|
// Set pointer for next thread stack. Reserve 8M for main stack.
|
||||||
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
|
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
|
void
|
||||||
|
@ -66,15 +181,49 @@ AlphaLiveProcess::startup()
|
||||||
if (checkpointRestored)
|
if (checkpointRestored)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Process::startup();
|
||||||
|
|
||||||
argsInit(MachineBytes, VMPageSize);
|
argsInit(MachineBytes, VMPageSize);
|
||||||
|
|
||||||
threadContexts[0]->setIntReg(GlobalPointerReg, objFile->globalPointer());
|
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||||
//Opperate in user mode
|
tc->setIntReg(GlobalPointerReg, objFile->globalPointer());
|
||||||
threadContexts[0]->setMiscRegNoEffect(IPR_ICM, 0x18);
|
//Operate in user mode
|
||||||
|
tc->setMiscRegNoEffect(IPR_ICM, 0x18);
|
||||||
//No super page mapping
|
//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
|
//Set this to 0 for now, but it should be unique for each process
|
||||||
threadContexts[0]->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57);
|
tc->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AlphaISA::IntReg
|
||||||
|
AlphaLiveProcess::getSyscallArg(ThreadContext *tc, int i)
|
||||||
|
{
|
||||||
|
assert(i < 6);
|
||||||
|
return tc->readIntReg(FirstArgumentReg + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AlphaLiveProcess::setSyscallArg(ThreadContext *tc,
|
||||||
|
int i, AlphaISA::IntReg val)
|
||||||
|
{
|
||||||
|
assert(i < 6);
|
||||||
|
tc->setIntReg(FirstArgumentReg + i, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AlphaLiveProcess::setSyscallReturn(ThreadContext *tc,
|
||||||
|
SyscallReturn return_value)
|
||||||
|
{
|
||||||
|
// check for error condition. Alpha syscall convention is to
|
||||||
|
// indicate success/failure in reg a3 (r19) and put the
|
||||||
|
// return value itself in the standard return value reg (v0).
|
||||||
|
if (return_value.successful()) {
|
||||||
|
// no error
|
||||||
|
tc->setIntReg(SyscallSuccessReg, 0);
|
||||||
|
tc->setIntReg(ReturnValueReg, return_value.value());
|
||||||
|
} else {
|
||||||
|
// got an error, return details
|
||||||
|
tc->setIntReg(SyscallSuccessReg, (IntReg)-1);
|
||||||
|
tc->setIntReg(ReturnValueReg, -return_value.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -29,24 +29,24 @@
|
||||||
* Ali Saidi
|
* Ali Saidi
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __ALPHA_PROCESS_HH__
|
#ifndef __ARCH_ALPHA_PROCESS_HH__
|
||||||
#define __ALPHA_PROCESS_HH__
|
#define __ARCH_ALPHA_PROCESS_HH__
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include "sim/process.hh"
|
#include "sim/process.hh"
|
||||||
|
|
||||||
class ObjectFile;
|
|
||||||
class System;
|
|
||||||
|
|
||||||
|
|
||||||
class AlphaLiveProcess : public LiveProcess
|
class AlphaLiveProcess : public LiveProcess
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
AlphaLiveProcess(LiveProcessParams * params, ObjectFile *objFile);
|
AlphaLiveProcess(LiveProcessParams *params, ObjectFile *objFile);
|
||||||
|
|
||||||
void startup();
|
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 // __ARCH_ALPHA_PROCESS_HH__
|
||||||
#endif // __ALPHA_PROCESS_HH__
|
|
||||||
|
|
|
@ -33,67 +33,68 @@
|
||||||
#include "arch/alpha/regfile.hh"
|
#include "arch/alpha/regfile.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
|
|
||||||
namespace AlphaISA
|
using namespace std;
|
||||||
|
|
||||||
|
namespace AlphaISA {
|
||||||
|
|
||||||
|
void
|
||||||
|
RegFile::serialize(EventManager *em, ostream &os)
|
||||||
{
|
{
|
||||||
void
|
intRegFile.serialize(os);
|
||||||
RegFile::serialize(std::ostream &os)
|
floatRegFile.serialize(os);
|
||||||
{
|
miscRegFile.serialize(os);
|
||||||
intRegFile.serialize(os);
|
SERIALIZE_SCALAR(pc);
|
||||||
floatRegFile.serialize(os);
|
SERIALIZE_SCALAR(npc);
|
||||||
miscRegFile.serialize(os);
|
|
||||||
SERIALIZE_SCALAR(pc);
|
|
||||||
SERIALIZE_SCALAR(npc);
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
SERIALIZE_SCALAR(intrflag);
|
SERIALIZE_SCALAR(intrflag);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
|
||||||
{
|
|
||||||
intRegFile.unserialize(cp, section);
|
|
||||||
floatRegFile.unserialize(cp, section);
|
|
||||||
miscRegFile.unserialize(cp, section);
|
|
||||||
UNSERIALIZE_SCALAR(pc);
|
|
||||||
UNSERIALIZE_SCALAR(npc);
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
UNSERIALIZE_SCALAR(intrflag);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
copyRegs(ThreadContext *src, ThreadContext *dest)
|
|
||||||
{
|
|
||||||
// First loop through the integer registers.
|
|
||||||
for (int i = 0; i < NumIntRegs; ++i) {
|
|
||||||
dest->setIntReg(i, src->readIntReg(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then loop through the floating point registers.
|
|
||||||
for (int i = 0; i < TheISA::NumFloatRegs; ++i) {
|
|
||||||
dest->setFloatRegBits(i, src->readFloatRegBits(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy misc. registers
|
|
||||||
copyMiscRegs(src, dest);
|
|
||||||
|
|
||||||
// Lastly copy PC/NPC
|
|
||||||
dest->setPC(src->readPC());
|
|
||||||
dest->setNextPC(src->readNextPC());
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
copyMiscRegs(ThreadContext *src, ThreadContext *dest)
|
|
||||||
{
|
|
||||||
dest->setMiscRegNoEffect(AlphaISA::MISCREG_FPCR,
|
|
||||||
src->readMiscRegNoEffect(AlphaISA::MISCREG_FPCR));
|
|
||||||
dest->setMiscRegNoEffect(AlphaISA::MISCREG_UNIQ,
|
|
||||||
src->readMiscRegNoEffect(AlphaISA::MISCREG_UNIQ));
|
|
||||||
dest->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG,
|
|
||||||
src->readMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG));
|
|
||||||
dest->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKADDR,
|
|
||||||
src->readMiscRegNoEffect(AlphaISA::MISCREG_LOCKADDR));
|
|
||||||
|
|
||||||
copyIprs(src, dest);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RegFile::unserialize(EventManager *em, Checkpoint *cp, const string §ion)
|
||||||
|
{
|
||||||
|
intRegFile.unserialize(cp, section);
|
||||||
|
floatRegFile.unserialize(cp, section);
|
||||||
|
miscRegFile.unserialize(cp, section);
|
||||||
|
UNSERIALIZE_SCALAR(pc);
|
||||||
|
UNSERIALIZE_SCALAR(npc);
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
UNSERIALIZE_SCALAR(intrflag);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
copyRegs(ThreadContext *src, ThreadContext *dest)
|
||||||
|
{
|
||||||
|
// First loop through the integer registers.
|
||||||
|
for (int i = 0; i < NumIntRegs; ++i)
|
||||||
|
dest->setIntReg(i, src->readIntReg(i));
|
||||||
|
|
||||||
|
// Then loop through the floating point registers.
|
||||||
|
for (int i = 0; i < NumFloatRegs; ++i)
|
||||||
|
dest->setFloatRegBits(i, src->readFloatRegBits(i));
|
||||||
|
|
||||||
|
// Copy misc. registers
|
||||||
|
copyMiscRegs(src, dest);
|
||||||
|
|
||||||
|
// Lastly copy PC/NPC
|
||||||
|
dest->setPC(src->readPC());
|
||||||
|
dest->setNextPC(src->readNextPC());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
copyMiscRegs(ThreadContext *src, ThreadContext *dest)
|
||||||
|
{
|
||||||
|
dest->setMiscRegNoEffect(MISCREG_FPCR,
|
||||||
|
src->readMiscRegNoEffect(MISCREG_FPCR));
|
||||||
|
dest->setMiscRegNoEffect(MISCREG_UNIQ,
|
||||||
|
src->readMiscRegNoEffect(MISCREG_UNIQ));
|
||||||
|
dest->setMiscRegNoEffect(MISCREG_LOCKFLAG,
|
||||||
|
src->readMiscRegNoEffect(MISCREG_LOCKFLAG));
|
||||||
|
dest->setMiscRegNoEffect(MISCREG_LOCKADDR,
|
||||||
|
src->readMiscRegNoEffect(MISCREG_LOCKADDR));
|
||||||
|
|
||||||
|
copyIprs(src, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace AlphaISA
|
||||||
|
|
|
@ -43,163 +43,187 @@
|
||||||
//XXX These should be implemented by someone who knows the alpha stuff better
|
//XXX These should be implemented by someone who knows the alpha stuff better
|
||||||
|
|
||||||
class Checkpoint;
|
class Checkpoint;
|
||||||
|
class EventManager;
|
||||||
class ThreadContext;
|
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:
|
public:
|
||||||
Addr pc; // program counter
|
Addr
|
||||||
Addr npc; // next-cycle program counter
|
readPC()
|
||||||
Addr nnpc;
|
{
|
||||||
|
return pc;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
void
|
||||||
Addr readPC()
|
setPC(Addr val)
|
||||||
{
|
{
|
||||||
return pc;
|
pc = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPC(Addr val)
|
Addr
|
||||||
{
|
readNextPC()
|
||||||
pc = val;
|
{
|
||||||
}
|
return npc;
|
||||||
|
}
|
||||||
|
|
||||||
Addr readNextPC()
|
void
|
||||||
{
|
setNextPC(Addr val)
|
||||||
return npc;
|
{
|
||||||
}
|
npc = val;
|
||||||
|
}
|
||||||
|
|
||||||
void setNextPC(Addr val)
|
Addr
|
||||||
{
|
readNextNPC()
|
||||||
npc = val;
|
{
|
||||||
}
|
return npc + sizeof(MachInst);
|
||||||
|
}
|
||||||
|
|
||||||
Addr readNextNPC()
|
void
|
||||||
{
|
setNextNPC(Addr val)
|
||||||
return npc + sizeof(MachInst);
|
{ }
|
||||||
}
|
|
||||||
|
|
||||||
void setNextNPC(Addr val)
|
protected:
|
||||||
{ }
|
IntRegFile intRegFile; // (signed) integer register file
|
||||||
|
FloatRegFile floatRegFile; // floating point register file
|
||||||
protected:
|
MiscRegFile miscRegFile; // control register file
|
||||||
IntRegFile intRegFile; // (signed) integer register file
|
|
||||||
FloatRegFile floatRegFile; // floating point register file
|
|
||||||
MiscRegFile miscRegFile; // control register file
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
|
public:
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
int intrflag; // interrupt flag
|
int intrflag; // interrupt flag
|
||||||
inline int instAsid()
|
|
||||||
{ return miscRegFile.getInstAsid(); }
|
int
|
||||||
inline int dataAsid()
|
instAsid()
|
||||||
{ return miscRegFile.getDataAsid(); }
|
{
|
||||||
|
return miscRegFile.getInstAsid();
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dataAsid()
|
||||||
|
{
|
||||||
|
return miscRegFile.getDataAsid();
|
||||||
|
}
|
||||||
#endif // FULL_SYSTEM
|
#endif // FULL_SYSTEM
|
||||||
|
|
||||||
void clear()
|
void
|
||||||
{
|
clear()
|
||||||
intRegFile.clear();
|
|
||||||
floatRegFile.clear();
|
|
||||||
miscRegFile.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
MiscReg readMiscRegNoEffect(int miscReg)
|
|
||||||
{
|
|
||||||
return miscRegFile.readRegNoEffect(miscReg);
|
|
||||||
}
|
|
||||||
|
|
||||||
MiscReg readMiscReg(int miscReg, ThreadContext *tc)
|
|
||||||
{
|
|
||||||
return miscRegFile.readReg(miscReg, tc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setMiscRegNoEffect(int miscReg, const MiscReg &val)
|
|
||||||
{
|
|
||||||
miscRegFile.setRegNoEffect(miscReg, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setMiscReg(int miscReg, const MiscReg &val,
|
|
||||||
ThreadContext * tc)
|
|
||||||
{
|
|
||||||
miscRegFile.setReg(miscReg, val, tc);
|
|
||||||
}
|
|
||||||
|
|
||||||
FloatReg readFloatReg(int floatReg)
|
|
||||||
{
|
|
||||||
return floatRegFile.d[floatReg];
|
|
||||||
}
|
|
||||||
|
|
||||||
FloatReg readFloatReg(int floatReg, int width)
|
|
||||||
{
|
|
||||||
return readFloatReg(floatReg);
|
|
||||||
}
|
|
||||||
|
|
||||||
FloatRegBits readFloatRegBits(int floatReg)
|
|
||||||
{
|
|
||||||
return floatRegFile.q[floatReg];
|
|
||||||
}
|
|
||||||
|
|
||||||
FloatRegBits readFloatRegBits(int floatReg, int width)
|
|
||||||
{
|
|
||||||
return readFloatRegBits(floatReg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFloatReg(int floatReg, const FloatReg &val)
|
|
||||||
{
|
|
||||||
floatRegFile.d[floatReg] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFloatReg(int floatReg, const FloatReg &val, int width)
|
|
||||||
{
|
|
||||||
setFloatReg(floatReg, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFloatRegBits(int floatReg, const FloatRegBits &val)
|
|
||||||
{
|
|
||||||
floatRegFile.q[floatReg] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
|
|
||||||
{
|
|
||||||
setFloatRegBits(floatReg, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
IntReg readIntReg(int intReg)
|
|
||||||
{
|
|
||||||
return intRegFile.readReg(intReg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setIntReg(int intReg, const IntReg &val)
|
|
||||||
{
|
|
||||||
intRegFile.setReg(intReg, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void serialize(std::ostream &os);
|
|
||||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
|
||||||
|
|
||||||
void changeContext(RegContextParam param, RegContextVal val)
|
|
||||||
{
|
|
||||||
//This would be an alternative place to call/implement
|
|
||||||
//the swapPALShadow function
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline int flattenIntIndex(ThreadContext * tc, int reg)
|
|
||||||
{
|
{
|
||||||
return reg;
|
intRegFile.clear();
|
||||||
|
floatRegFile.clear();
|
||||||
|
miscRegFile.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int flattenFloatIndex(ThreadContext * tc, int reg)
|
MiscReg
|
||||||
|
readMiscRegNoEffect(int miscReg)
|
||||||
{
|
{
|
||||||
return reg;
|
return miscRegFile.readRegNoEffect(miscReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
MiscReg
|
||||||
|
readMiscReg(int miscReg, ThreadContext *tc)
|
||||||
|
{
|
||||||
|
return miscRegFile.readReg(miscReg, tc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setMiscRegNoEffect(int miscReg, const MiscReg &val)
|
||||||
|
{
|
||||||
|
miscRegFile.setRegNoEffect(miscReg, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setMiscReg(int miscReg, const MiscReg &val, ThreadContext *tc)
|
||||||
|
{
|
||||||
|
miscRegFile.setReg(miscReg, val, tc);
|
||||||
|
}
|
||||||
|
|
||||||
|
FloatReg
|
||||||
|
readFloatReg(int floatReg)
|
||||||
|
{
|
||||||
|
return floatRegFile.d[floatReg];
|
||||||
|
}
|
||||||
|
|
||||||
|
FloatReg
|
||||||
|
readFloatReg(int floatReg, int width)
|
||||||
|
{
|
||||||
|
return readFloatReg(floatReg);
|
||||||
|
}
|
||||||
|
|
||||||
|
FloatRegBits
|
||||||
|
readFloatRegBits(int floatReg)
|
||||||
|
{
|
||||||
|
return floatRegFile.q[floatReg];
|
||||||
|
}
|
||||||
|
|
||||||
|
FloatRegBits
|
||||||
|
readFloatRegBits(int floatReg, int width)
|
||||||
|
{
|
||||||
|
return readFloatRegBits(floatReg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setFloatReg(int floatReg, const FloatReg &val)
|
||||||
|
{
|
||||||
|
floatRegFile.d[floatReg] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setFloatReg(int floatReg, const FloatReg &val, int width)
|
||||||
|
{
|
||||||
|
setFloatReg(floatReg, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setFloatRegBits(int floatReg, const FloatRegBits &val)
|
||||||
|
{
|
||||||
|
floatRegFile.q[floatReg] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
|
||||||
|
{
|
||||||
|
setFloatRegBits(floatReg, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
IntReg
|
||||||
|
readIntReg(int intReg)
|
||||||
|
{
|
||||||
|
return intRegFile.readReg(intReg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setIntReg(int intReg, const IntReg &val)
|
||||||
|
{
|
||||||
|
intRegFile.setReg(intReg, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialize(EventManager *em, std::ostream &os);
|
||||||
|
void unserialize(EventManager *em, Checkpoint *cp,
|
||||||
|
const std::string §ion);
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
flattenIntIndex(ThreadContext * tc, int reg)
|
||||||
|
{
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
flattenFloatIndex(ThreadContext * tc, int reg)
|
||||||
|
{
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
||||||
|
|
||||||
|
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
|
||||||
|
|
||||||
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
|
|
||||||
} // namespace AlphaISA
|
} // namespace AlphaISA
|
||||||
|
|
||||||
#endif
|
#endif // __ARCH_ALPHA_REGFILE_HH__
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1990, 1993
|
* 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
|
* This software was developed by the Computer Systems Engineering group
|
||||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
* 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
|
* All advertising materials mentioning features or use of this software
|
||||||
* must display the following acknowledgement:
|
* must display the following acknowledgement:
|
||||||
* This product includes software developed by the University of
|
* This product includes software developed by the University of
|
||||||
* California, Lawrence Berkeley Laboratories.
|
* California, Lawrence Berkeley Laboratories.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
@ -51,8 +51,8 @@
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
* must display the following acknowledgement:
|
* must display the following acknowledgement:
|
||||||
* This product includes software developed by the University of
|
* This product includes software developed by the University of
|
||||||
* California, Berkeley and its contributors.
|
* California, Berkeley and its contributors.
|
||||||
* 4. Neither the name of the University nor the names of 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
|
@ -69,7 +69,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* 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.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
* must display the following acknowledgement:
|
* must display the following acknowledgement:
|
||||||
* This product includes software developed by the NetBSD
|
* This product includes software developed by the NetBSD
|
||||||
* Foundation, Inc. and its contributors.
|
* Foundation, Inc. and its contributors.
|
||||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||||
* contributors may be used to endorse or promote products derived
|
* contributors may be used to endorse or promote products derived
|
||||||
* from this software without specific prior written permission.
|
* from this software without specific prior written permission.
|
||||||
|
@ -117,9 +117,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/signal.h>
|
#include <sys/signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "config/full_system.hh"
|
#include "config/full_system.hh"
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
|
@ -140,19 +140,17 @@
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace TheISA;
|
using namespace AlphaISA;
|
||||||
|
|
||||||
RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
|
RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc)
|
||||||
: BaseRemoteGDB(_system, c, KGDB_NUMREGS)
|
: BaseRemoteGDB(_system, tc, KGDB_NUMREGS)
|
||||||
{
|
{
|
||||||
memset(gdbregs.regs, 0, gdbregs.bytes());
|
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
|
bool
|
||||||
RemoteGDB::acc(Addr va, size_t len)
|
RemoteGDB::acc(Addr va, size_t len)
|
||||||
{
|
{
|
||||||
|
@ -161,12 +159,12 @@ RemoteGDB::acc(Addr va, size_t len)
|
||||||
#else
|
#else
|
||||||
Addr last_va;
|
Addr last_va;
|
||||||
|
|
||||||
va = TheISA::TruncPage(va);
|
va = TruncPage(va);
|
||||||
last_va = TheISA::RoundPage(va + len);
|
last_va = RoundPage(va + len);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (TheISA::IsK0Seg(va)) {
|
if (IsK0Seg(va)) {
|
||||||
if (va < (TheISA::K0SegBase + pmem->size())) {
|
if (va < (K0SegBase + pmem->size())) {
|
||||||
DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= "
|
DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= "
|
||||||
"%#x < K0SEG + size\n", va);
|
"%#x < K0SEG + size\n", va);
|
||||||
return true;
|
return true;
|
||||||
|
@ -177,23 +175,25 @@ RemoteGDB::acc(Addr va, size_t len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This code says that all accesses to palcode (instruction and data)
|
* This code says that all accesses to palcode (instruction
|
||||||
* are valid since there isn't a va->pa mapping because palcode is
|
* and data) are valid since there isn't a va->pa mapping
|
||||||
* accessed physically. At some point this should probably be cleaned up
|
* because palcode is accessed physically. At some point this
|
||||||
* but there is no easy way to do it.
|
* 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;
|
return true;
|
||||||
|
|
||||||
Addr ptbr = context->readMiscRegNoEffect(AlphaISA::IPR_PALtemp20);
|
Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20);
|
||||||
TheISA::PageTableEntry pte = TheISA::kernel_pte_lookup(context->getPhysPort(), ptbr, va);
|
PageTableEntry pte =
|
||||||
|
kernel_pte_lookup(context->getPhysPort(), ptbr, va);
|
||||||
if (!pte.valid()) {
|
if (!pte.valid()) {
|
||||||
DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
|
DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
va += TheISA::PageBytes;
|
va += PageBytes;
|
||||||
} while (va < last_va);
|
} while (va < last_va);
|
||||||
|
|
||||||
DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va);
|
DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va);
|
||||||
|
@ -201,11 +201,10 @@ RemoteGDB::acc(Addr va, size_t len)
|
||||||
#endif
|
#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
|
void
|
||||||
RemoteGDB::getregs()
|
RemoteGDB::getregs()
|
||||||
{
|
{
|
||||||
|
@ -214,45 +213,43 @@ RemoteGDB::getregs()
|
||||||
gdbregs.regs[KGDB_REG_PC] = context->readPC();
|
gdbregs.regs[KGDB_REG_PC] = context->readPC();
|
||||||
|
|
||||||
// @todo: Currently this is very Alpha specific.
|
// @todo: Currently this is very Alpha specific.
|
||||||
if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) {
|
if (PcPAL(gdbregs.regs[KGDB_REG_PC])) {
|
||||||
for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
|
for (int i = 0; i < NumIntArchRegs; ++i) {
|
||||||
gdbregs.regs[i] = context->readIntReg(AlphaISA::reg_redir[i]);
|
gdbregs.regs[i] = context->readIntReg(reg_redir[i]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
|
for (int i = 0; i < NumIntArchRegs; ++i) {
|
||||||
gdbregs.regs[i] = context->readIntReg(i);
|
gdbregs.regs[i] = context->readIntReg(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef KGDB_FP_REGS
|
#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);
|
gdbregs.regs[i + KGDB_REG_F0] = context->readFloatRegBits(i);
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
void
|
||||||
RemoteGDB::setregs()
|
RemoteGDB::setregs()
|
||||||
{
|
{
|
||||||
// @todo: Currently this is very Alpha specific.
|
// @todo: Currently this is very Alpha specific.
|
||||||
if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) {
|
if (PcPAL(gdbregs.regs[KGDB_REG_PC])) {
|
||||||
for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
|
for (int i = 0; i < NumIntArchRegs; ++i) {
|
||||||
context->setIntReg(AlphaISA::reg_redir[i], gdbregs.regs[i]);
|
context->setIntReg(reg_redir[i], gdbregs.regs[i]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
|
for (int i = 0; i < NumIntArchRegs; ++i) {
|
||||||
context->setIntReg(i, gdbregs.regs[i]);
|
context->setIntReg(i, gdbregs.regs[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef KGDB_FP_REGS
|
#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]);
|
context->setFloatRegBits(i, gdbregs.regs[i + KGDB_REG_F0]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -44,31 +44,29 @@ class System;
|
||||||
class ThreadContext;
|
class ThreadContext;
|
||||||
class PhysicalMemory;
|
class PhysicalMemory;
|
||||||
|
|
||||||
namespace AlphaISA
|
namespace AlphaISA {
|
||||||
|
|
||||||
|
class RemoteGDB : public BaseRemoteGDB
|
||||||
{
|
{
|
||||||
class RemoteGDB : public BaseRemoteGDB
|
protected:
|
||||||
{
|
Addr notTakenBkpt;
|
||||||
protected:
|
Addr takenBkpt;
|
||||||
// Machine memory
|
|
||||||
bool write(Addr addr, size_t size, const char *data);
|
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
RemoteGDB(System *system, ThreadContext *context);
|
void getregs();
|
||||||
|
void setregs();
|
||||||
|
|
||||||
bool acc(Addr addr, size_t len);
|
void clearSingleStep();
|
||||||
|
void setSingleStep();
|
||||||
|
|
||||||
protected:
|
// Machine memory
|
||||||
void getregs();
|
bool acc(Addr addr, size_t len);
|
||||||
void setregs();
|
bool write(Addr addr, size_t size, const char *data);
|
||||||
|
|
||||||
void clearSingleStep();
|
public:
|
||||||
void setSingleStep();
|
RemoteGDB(System *system, ThreadContext *context);
|
||||||
|
};
|
||||||
|
|
||||||
protected:
|
} // namespace AlphaISA
|
||||||
|
|
||||||
Addr notTakenBkpt;
|
#endif // __ARCH_ALPHA_REMOTE_GDB_HH__
|
||||||
Addr takenBkpt;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __ARCH_ALPHA_REMOTE_GDB_H__ */
|
|
||||||
|
|
|
@ -41,330 +41,326 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace AlphaISA
|
namespace AlphaISA {
|
||||||
|
|
||||||
|
ProcessInfo::ProcessInfo(ThreadContext *_tc)
|
||||||
|
: tc(_tc)
|
||||||
{
|
{
|
||||||
ProcessInfo::ProcessInfo(ThreadContext *_tc)
|
Addr addr = 0;
|
||||||
: tc(_tc)
|
VirtualPort *vp = tc->getVirtPort();
|
||||||
{
|
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
|
||||||
Addr addr = 0;
|
|
||||||
|
|
||||||
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))
|
if (!symtab->findAddress("thread_info_task", addr))
|
||||||
panic("thread info not compiled into kernel\n");
|
panic("thread info not compiled into kernel\n");
|
||||||
thread_info_size = vp->readGtoH<int32_t>(addr);
|
task_off = vp->readGtoH<int32_t>(addr);
|
||||||
|
|
||||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
|
if (!symtab->findAddress("task_struct_pid", addr))
|
||||||
panic("thread info not compiled into kernel\n");
|
panic("thread info not compiled into kernel\n");
|
||||||
task_struct_size = vp->readGtoH<int32_t>(addr);
|
pid_off = vp->readGtoH<int32_t>(addr);
|
||||||
|
|
||||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
|
if (!symtab->findAddress("task_struct_comm", addr))
|
||||||
panic("thread info not compiled into kernel\n");
|
panic("thread info not compiled into kernel\n");
|
||||||
task_off = vp->readGtoH<int32_t>(addr);
|
name_off = vp->readGtoH<int32_t>(addr);
|
||||||
|
}
|
||||||
|
|
||||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
|
Addr
|
||||||
panic("thread info not compiled into kernel\n");
|
ProcessInfo::task(Addr ksp) const
|
||||||
pid_off = vp->readGtoH<int32_t>(addr);
|
{
|
||||||
|
Addr base = ksp & ~0x3fff;
|
||||||
|
if (base == ULL(0xfffffc0000000000))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
|
Addr tsk;
|
||||||
panic("thread info not compiled into kernel\n");
|
|
||||||
name_off = vp->readGtoH<int32_t>(addr);
|
|
||||||
|
|
||||||
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
|
if (!kernel) {
|
||||||
ProcessInfo::task(Addr ksp) const
|
stack.push_back(console);
|
||||||
{
|
return;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
SymbolTable *symtab = sys->kernelSymtab;
|
||||||
ProcessInfo::pid(Addr ksp) const
|
Addr ksp = tc->readIntReg(StackPointerReg);
|
||||||
{
|
Addr bottom = ksp & ~0x3fff;
|
||||||
Addr task = this->task(ksp);
|
|
||||||
if (!task)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
uint16_t pd;
|
if (is_call) {
|
||||||
|
|
||||||
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;
|
|
||||||
Addr addr;
|
Addr addr;
|
||||||
|
if (!symtab->findNearestAddr(pc, addr))
|
||||||
|
panic("could not find address %#x", pc);
|
||||||
|
|
||||||
if (is_call) {
|
stack.push_back(addr);
|
||||||
if (!symtab->findNearestAddr(pc, addr))
|
pc = tc->readPC();
|
||||||
panic("could not find address %#x", pc);
|
}
|
||||||
|
|
||||||
stack.push_back(addr);
|
while (ksp > bottom) {
|
||||||
pc = tc->readPC();
|
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;
|
Addr ra;
|
||||||
int size;
|
int size;
|
||||||
|
if (decodePrologue(ksp, pc, addr, size, ra)) {
|
||||||
while (ksp > bottom) {
|
if (!ra)
|
||||||
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;
|
return;
|
||||||
|
|
||||||
if (decodePrologue(ksp, pc, addr, size, ra)) {
|
if (size <= 0) {
|
||||||
if (!ra)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (size <= 0) {
|
|
||||||
stack.push_back(unknown);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pc = ra;
|
|
||||||
ksp += size;
|
|
||||||
} else {
|
|
||||||
stack.push_back(unknown);
|
stack.push_back(unknown);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
|
pc = ra;
|
||||||
pc <= tc->getSystemPtr()->kernelEnd;
|
ksp += size;
|
||||||
if (!kernel)
|
} else {
|
||||||
return;
|
stack.push_back(unknown);
|
||||||
|
return;
|
||||||
if (stack.size() >= 1000)
|
|
||||||
panic("unwinding too far");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
panic("unwinding too far");
|
bool kernel = sys->kernelStart <= pc && pc <= sys->kernelEnd;
|
||||||
|
if (!kernel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (stack.size() >= 1000)
|
||||||
|
panic("unwinding too far");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
panic("unwinding too far");
|
||||||
StackTrace::isEntry(Addr addr)
|
}
|
||||||
{
|
|
||||||
if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp12))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp7))
|
bool
|
||||||
return true;
|
StackTrace::isEntry(Addr addr)
|
||||||
|
{
|
||||||
|
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp12))
|
||||||
|
return true;
|
||||||
|
|
||||||
if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp11))
|
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp7))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp21))
|
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp11))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp9))
|
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp21))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp2))
|
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp9))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp2))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
StackTrace::decodeStack(MachInst inst, int &disp)
|
||||||
|
{
|
||||||
|
// lda $sp, -disp($sp)
|
||||||
|
//
|
||||||
|
// Opcode<31:26> == 0x08
|
||||||
|
// RA<25:21> == 30
|
||||||
|
// RB<20:16> == 30
|
||||||
|
// Disp<15:0>
|
||||||
|
const MachInst mem_mask = 0xffff0000;
|
||||||
|
const MachInst lda_pattern = 0x23de0000;
|
||||||
|
const MachInst lda_disp_mask = 0x0000ffff;
|
||||||
|
|
||||||
|
// subq $sp, disp, $sp
|
||||||
|
// addq $sp, disp, $sp
|
||||||
|
//
|
||||||
|
// Opcode<31:26> == 0x10
|
||||||
|
// RA<25:21> == 30
|
||||||
|
// Lit<20:13>
|
||||||
|
// One<12> = 1
|
||||||
|
// Func<11:5> == 0x20 (addq)
|
||||||
|
// Func<11:5> == 0x29 (subq)
|
||||||
|
// RC<4:0> == 30
|
||||||
|
const MachInst intop_mask = 0xffe01fff;
|
||||||
|
const MachInst addq_pattern = 0x43c0141e;
|
||||||
|
const MachInst subq_pattern = 0x43c0153e;
|
||||||
|
const MachInst intop_disp_mask = 0x001fe000;
|
||||||
|
const int intop_disp_shift = 13;
|
||||||
|
|
||||||
|
if ((inst & mem_mask) == lda_pattern)
|
||||||
|
disp = -sext<16>(inst & lda_disp_mask);
|
||||||
|
else if ((inst & intop_mask) == addq_pattern)
|
||||||
|
disp = -int((inst & intop_disp_mask) >> intop_disp_shift);
|
||||||
|
else if ((inst & intop_mask) == subq_pattern)
|
||||||
|
disp = int((inst & intop_disp_mask) >> intop_disp_shift);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
StackTrace::decodeSave(MachInst inst, int ®, int &disp)
|
||||||
|
{
|
||||||
|
// lda $stq, disp($sp)
|
||||||
|
//
|
||||||
|
// Opcode<31:26> == 0x08
|
||||||
|
// RA<25:21> == ?
|
||||||
|
// RB<20:16> == 30
|
||||||
|
// Disp<15:0>
|
||||||
|
const MachInst stq_mask = 0xfc1f0000;
|
||||||
|
const MachInst stq_pattern = 0xb41e0000;
|
||||||
|
const MachInst stq_disp_mask = 0x0000ffff;
|
||||||
|
const MachInst reg_mask = 0x03e00000;
|
||||||
|
const int reg_shift = 21;
|
||||||
|
|
||||||
|
if ((inst & stq_mask) == stq_pattern) {
|
||||||
|
reg = (inst & reg_mask) >> reg_shift;
|
||||||
|
disp = sext<16>(inst & stq_disp_mask);
|
||||||
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
return true;
|
||||||
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
|
* Decode the function prologue for the function we're in, and note
|
||||||
//
|
* which registers are stored where, and how large the stack frame is.
|
||||||
// Opcode<31:26> == 0x10
|
*/
|
||||||
// RA<25:21> == 30
|
bool
|
||||||
// Lit<20:13>
|
StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, int &size,
|
||||||
// One<12> = 1
|
Addr &ra)
|
||||||
// Func<11:5> == 0x20 (addq)
|
{
|
||||||
// Func<11:5> == 0x29 (subq)
|
size = 0;
|
||||||
// RC<4:0> == 30
|
ra = 0;
|
||||||
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)
|
for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
|
||||||
disp = -sext<16>(inst & lda_disp_mask);
|
MachInst inst;
|
||||||
else if ((inst & intop_mask) == addq_pattern)
|
CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst));
|
||||||
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;
|
int reg, disp;
|
||||||
}
|
if (decodeStack(inst, disp)) {
|
||||||
|
if (size) {
|
||||||
bool
|
// panic("decoding frame size again");
|
||||||
StackTrace::decodeSave(MachInst inst, int ®, int &disp)
|
return true;
|
||||||
{
|
}
|
||||||
// lda $stq, disp($sp)
|
size += disp;
|
||||||
//
|
} else if (decodeSave(inst, reg, disp)) {
|
||||||
// Opcode<31:26> == 0x08
|
if (!ra && reg == ReturnAddressReg) {
|
||||||
// RA<25:21> == ?
|
CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr));
|
||||||
// RB<20:16> == 30
|
if (!ra) {
|
||||||
// Disp<15:0>
|
// panic("no return address value pc=%#x\n", pc);
|
||||||
const MachInst stq_mask = 0xfc1f0000;
|
return false;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#if TRACING_ON
|
#if TRACING_ON
|
||||||
void
|
void
|
||||||
StackTrace::dump()
|
StackTrace::dump()
|
||||||
{
|
{
|
||||||
StringWrap name(tc->getCpuPtr()->name());
|
StringWrap name(tc->getCpuPtr()->name());
|
||||||
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
|
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
|
||||||
|
|
||||||
DPRINTFN("------ Stack ------\n");
|
DPRINTFN("------ Stack ------\n");
|
||||||
|
|
||||||
string symbol;
|
string symbol;
|
||||||
for (int i = 0, size = stack.size(); i < size; ++i) {
|
for (int i = 0, size = stack.size(); i < size; ++i) {
|
||||||
Addr addr = stack[size - i - 1];
|
Addr addr = stack[size - i - 1];
|
||||||
if (addr == user)
|
if (addr == user)
|
||||||
symbol = "user";
|
symbol = "user";
|
||||||
else if (addr == console)
|
else if (addr == console)
|
||||||
symbol = "console";
|
symbol = "console";
|
||||||
else if (addr == unknown)
|
else if (addr == unknown)
|
||||||
symbol = "unknown";
|
symbol = "unknown";
|
||||||
else
|
else
|
||||||
symtab->findSymbol(addr, symbol);
|
symtab->findSymbol(addr, symbol);
|
||||||
|
|
||||||
DPRINTFN("%#x: %s\n", addr, symbol);
|
DPRINTFN("%#x: %s\n", addr, symbol);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace AlphaISA
|
||||||
|
|
|
@ -36,90 +36,90 @@
|
||||||
|
|
||||||
class ThreadContext;
|
class ThreadContext;
|
||||||
|
|
||||||
namespace AlphaISA
|
namespace AlphaISA {
|
||||||
|
|
||||||
|
class StackTrace;
|
||||||
|
|
||||||
|
class ProcessInfo
|
||||||
{
|
{
|
||||||
class StackTrace;
|
private:
|
||||||
|
ThreadContext *tc;
|
||||||
|
|
||||||
class ProcessInfo
|
int thread_info_size;
|
||||||
|
int task_struct_size;
|
||||||
|
int task_off;
|
||||||
|
int pid_off;
|
||||||
|
int name_off;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ProcessInfo(ThreadContext *_tc);
|
||||||
|
|
||||||
|
Addr task(Addr ksp) const;
|
||||||
|
int pid(Addr ksp) const;
|
||||||
|
std::string name(Addr ksp) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StackTrace
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
ThreadContext *tc;
|
||||||
|
std::vector<Addr> stack;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isEntry(Addr addr);
|
||||||
|
bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
|
||||||
|
bool decodeSave(MachInst inst, int ®, int &disp);
|
||||||
|
bool decodeStack(MachInst inst, int &disp);
|
||||||
|
|
||||||
|
void trace(ThreadContext *tc, bool is_call);
|
||||||
|
|
||||||
|
public:
|
||||||
|
StackTrace();
|
||||||
|
StackTrace(ThreadContext *tc, StaticInstPtr inst);
|
||||||
|
~StackTrace();
|
||||||
|
|
||||||
|
void
|
||||||
|
clear()
|
||||||
{
|
{
|
||||||
private:
|
tc = 0;
|
||||||
ThreadContext *tc;
|
stack.clear();
|
||||||
|
}
|
||||||
|
|
||||||
int thread_info_size;
|
bool valid() const { return tc != NULL; }
|
||||||
int task_struct_size;
|
bool trace(ThreadContext *tc, StaticInstPtr inst);
|
||||||
int task_off;
|
|
||||||
int pid_off;
|
|
||||||
int name_off;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ProcessInfo(ThreadContext *_tc);
|
const std::vector<Addr> &getstack() const { return stack; }
|
||||||
|
|
||||||
Addr task(Addr ksp) const;
|
static const int user = 1;
|
||||||
int pid(Addr ksp) const;
|
static const int console = 2;
|
||||||
std::string name(Addr ksp) const;
|
static const int unknown = 3;
|
||||||
};
|
|
||||||
|
|
||||||
class StackTrace
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
typedef TheISA::MachInst MachInst;
|
|
||||||
private:
|
|
||||||
ThreadContext *tc;
|
|
||||||
std::vector<Addr> stack;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool isEntry(Addr addr);
|
|
||||||
bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
|
|
||||||
bool decodeSave(MachInst inst, int ®, int &disp);
|
|
||||||
bool decodeStack(MachInst inst, int &disp);
|
|
||||||
|
|
||||||
void trace(ThreadContext *tc, bool is_call);
|
|
||||||
|
|
||||||
public:
|
|
||||||
StackTrace();
|
|
||||||
StackTrace(ThreadContext *tc, StaticInstPtr inst);
|
|
||||||
~StackTrace();
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
tc = 0;
|
|
||||||
stack.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool valid() const { return tc != NULL; }
|
|
||||||
bool trace(ThreadContext *tc, StaticInstPtr inst);
|
|
||||||
|
|
||||||
public:
|
|
||||||
const std::vector<Addr> &getstack() const { return stack; }
|
|
||||||
|
|
||||||
static const int user = 1;
|
|
||||||
static const int console = 2;
|
|
||||||
static const int unknown = 3;
|
|
||||||
|
|
||||||
#if TRACING_ON
|
#if TRACING_ON
|
||||||
private:
|
private:
|
||||||
void dump();
|
void dump();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void dprintf() { if (DTRACE(Stack)) dump(); }
|
void dprintf() { if (DTRACE(Stack)) dump(); }
|
||||||
#else
|
#else
|
||||||
public:
|
public:
|
||||||
void dprintf() {}
|
void dprintf() {}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
|
StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
|
||||||
{
|
{
|
||||||
if (!inst->isCall() && !inst->isReturn())
|
if (!inst->isCall() && !inst->isReturn())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (valid())
|
if (valid())
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
trace(tc, !inst->isReturn());
|
trace(tc, !inst->isReturn());
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace AlphaISA
|
||||||
|
|
||||||
#endif // __ARCH_ALPHA_STACKTRACE_HH__
|
#endif // __ARCH_ALPHA_STACKTRACE_HH__
|
||||||
|
|
|
@ -42,8 +42,7 @@
|
||||||
#include "params/AlphaSystem.hh"
|
#include "params/AlphaSystem.hh"
|
||||||
#include "sim/byteswap.hh"
|
#include "sim/byteswap.hh"
|
||||||
|
|
||||||
|
using namespace AlphaISA;
|
||||||
using namespace LittleEndianGuest;
|
|
||||||
|
|
||||||
AlphaSystem::AlphaSystem(Params *p)
|
AlphaSystem::AlphaSystem(Params *p)
|
||||||
: System(p)
|
: System(p)
|
||||||
|
@ -67,8 +66,8 @@ AlphaSystem::AlphaSystem(Params *p)
|
||||||
|
|
||||||
|
|
||||||
// Load program sections into memory
|
// Load program sections into memory
|
||||||
pal->loadSections(&functionalPort, AlphaISA::LoadAddrMask);
|
pal->loadSections(&functionalPort, LoadAddrMask);
|
||||||
console->loadSections(&functionalPort, AlphaISA::LoadAddrMask);
|
console->loadSections(&functionalPort, LoadAddrMask);
|
||||||
|
|
||||||
// load symbols
|
// load symbols
|
||||||
if (!console->loadGlobalSymbols(consoleSymtab))
|
if (!console->loadGlobalSymbols(consoleSymtab))
|
||||||
|
@ -117,7 +116,6 @@ AlphaSystem::AlphaSystem(Params *p)
|
||||||
virtPort.write(addr+0x58, data);
|
virtPort.write(addr+0x58, data);
|
||||||
} else
|
} else
|
||||||
panic("could not find hwrpb\n");
|
panic("could not find hwrpb\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AlphaSystem::~AlphaSystem()
|
AlphaSystem::~AlphaSystem()
|
||||||
|
@ -142,9 +140,9 @@ AlphaSystem::~AlphaSystem()
|
||||||
* in the procedure value register (pv aka t12 == r27). This sequence
|
* in the procedure value register (pv aka t12 == r27). This sequence
|
||||||
* looks like the following:
|
* looks like the following:
|
||||||
*
|
*
|
||||||
* opcode Ra Rb offset
|
* opcode Ra Rb offset
|
||||||
* ldah gp,X(pv) 09 29 27 X
|
* ldah gp,X(pv) 09 29 27 X
|
||||||
* lda gp,Y(gp) 08 29 29 Y
|
* lda gp,Y(gp) 08 29 29 Y
|
||||||
*
|
*
|
||||||
* for some constant offsets X and Y. The catch is that the linker
|
* 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
|
* (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);
|
const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16);
|
||||||
|
|
||||||
uint32_t i1 = virtPort.read<uint32_t>(addr);
|
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 &&
|
if ((i1 & inst_mask) == gp_ldah_pattern &&
|
||||||
(i2 & inst_mask) == gp_lda_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);
|
DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr);
|
||||||
return new_addr;
|
return new_addr;
|
||||||
} else {
|
} else {
|
||||||
|
@ -184,15 +182,15 @@ AlphaSystem::fixFuncEventAddr(Addr addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AlphaSystem::setAlphaAccess(Addr access)
|
AlphaSystem::setAlphaAccess(Addr access)
|
||||||
{
|
{
|
||||||
Addr addr = 0;
|
Addr addr = 0;
|
||||||
if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
|
if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
|
||||||
virtPort.write(addr, htog(EV5::Phys2K0Seg(access)));
|
virtPort.write(addr, htog(Phys2K0Seg(access)));
|
||||||
} else
|
} else {
|
||||||
panic("could not find m5AlphaAccess\n");
|
panic("could not find m5AlphaAccess\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -203,7 +201,6 @@ AlphaSystem::serialize(std::ostream &os)
|
||||||
palSymtab->serialize("pal_symtab", os);
|
palSymtab->serialize("pal_symtab", os);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AlphaSystem::unserialize(Checkpoint *cp, const std::string §ion)
|
AlphaSystem::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,10 +49,10 @@ class AlphaSystem : public System
|
||||||
AlphaSystem(Params *p);
|
AlphaSystem(Params *p);
|
||||||
~AlphaSystem();
|
~AlphaSystem();
|
||||||
|
|
||||||
/**
|
|
||||||
* Serialization stuff
|
|
||||||
*/
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Serialization stuff
|
||||||
|
*/
|
||||||
virtual void serialize(std::ostream &os);
|
virtual void serialize(std::ostream &os);
|
||||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
||||||
|
@ -77,26 +77,28 @@ class AlphaSystem : public System
|
||||||
/** Event to halt the simulator if the console calls panic() */
|
/** Event to halt the simulator if the console calls panic() */
|
||||||
BreakPCEvent *consolePanicEvent;
|
BreakPCEvent *consolePanicEvent;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const Params *params() const { return (const Params *)_params; }
|
const Params *params() const { return (const Params *)_params; }
|
||||||
|
|
||||||
/** Add a function-based event to PALcode. */
|
/** Add a function-based event to PALcode. */
|
||||||
template <class T>
|
template <class T>
|
||||||
T *addPalFuncEvent(const char *lbl)
|
T *
|
||||||
|
addPalFuncEvent(const char *lbl)
|
||||||
{
|
{
|
||||||
return addFuncEvent<T>(palSymtab, lbl);
|
return addFuncEvent<T>(palSymtab, lbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add a function-based event to the console code. */
|
/** Add a function-based event to the console code. */
|
||||||
template <class T>
|
template <class T>
|
||||||
T *addConsoleFuncEvent(const char *lbl)
|
T *
|
||||||
|
addConsoleFuncEvent(const char *lbl)
|
||||||
{
|
{
|
||||||
return addFuncEvent<T>(consoleSymtab, lbl);
|
return addFuncEvent<T>(consoleSymtab, lbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Addr fixFuncEventAddr(Addr addr);
|
virtual Addr fixFuncEventAddr(Addr addr);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif // __ARCH_ALPHA_SYSTEM_HH__
|
||||||
|
|
||||||
|
|
|
@ -43,19 +43,20 @@
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace EV5;
|
|
||||||
|
|
||||||
namespace AlphaISA {
|
namespace AlphaISA {
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Alpha TLB
|
// Alpha TLB
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bool uncacheBit39 = false;
|
bool uncacheBit39 = false;
|
||||||
bool uncacheBit40 = false;
|
bool uncacheBit40 = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MODE2MASK(X) (1 << (X))
|
#define MODE2MASK(X) (1 << (X))
|
||||||
|
|
||||||
TLB::TLB(const Params *p)
|
TLB::TLB(const Params *p)
|
||||||
: BaseTLB(p), size(p->size), nlu(0)
|
: BaseTLB(p), size(p->size), nlu(0)
|
||||||
|
@ -114,20 +115,20 @@ TLB::lookup(Addr vpn, uint8_t asn)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Fault
|
Fault
|
||||||
TLB::checkCacheability(RequestPtr &req)
|
TLB::checkCacheability(RequestPtr &req, bool itb)
|
||||||
{
|
{
|
||||||
// in Alpha, cacheability is controlled by upper-level bits of the
|
// in Alpha, cacheability is controlled by upper-level bits of the
|
||||||
// physical address
|
// physical address
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We support having the uncacheable bit in either bit 39 or bit 40.
|
* We support having the uncacheable bit in either bit 39 or bit
|
||||||
* The Turbolaser platform (and EV5) support having the bit in 39, but
|
* 40. The Turbolaser platform (and EV5) support having the bit
|
||||||
* Tsunami (which Linux assumes uses an EV6) generates accesses with
|
* in 39, but Tsunami (which Linux assumes uses an EV6) generates
|
||||||
* the bit in 40. So we must check for both, but we have debug flags
|
* accesses with the bit in 40. So we must check for both, but we
|
||||||
* to catch a weird case where both are used, which shouldn't happen.
|
* have debug flags to catch a weird case where both are used,
|
||||||
*/
|
* which shouldn't happen.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#if ALPHA_TLASER
|
#if ALPHA_TLASER
|
||||||
|
@ -141,13 +142,20 @@ TLB::checkCacheability(RequestPtr &req)
|
||||||
return new UnimpFault("IPR memory space not implemented!");
|
return new UnimpFault("IPR memory space not implemented!");
|
||||||
} else {
|
} else {
|
||||||
// mark request as uncacheable
|
// mark request as uncacheable
|
||||||
req->setFlags(req->getFlags() | UNCACHEABLE);
|
req->setFlags(Request::UNCACHEABLE);
|
||||||
|
|
||||||
#if !ALPHA_TLASER
|
#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);
|
req->setPaddr(req->getPaddr() & PAddrUncachedMask);
|
||||||
#endif
|
#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;
|
return NoFault;
|
||||||
}
|
}
|
||||||
|
@ -216,7 +224,8 @@ TLB::flushProcesses()
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
if (!entry->asma) {
|
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;
|
entry->valid = false;
|
||||||
lookupTable.erase(cur);
|
lookupTable.erase(cur);
|
||||||
}
|
}
|
||||||
|
@ -279,7 +288,6 @@ TLB::unserialize(Checkpoint *cp, const string §ion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Alpha ITB
|
// Alpha ITB
|
||||||
|
@ -308,13 +316,12 @@ ITB::regStats()
|
||||||
accesses = hits + misses;
|
accesses = hits + misses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Fault
|
Fault
|
||||||
ITB::translate(RequestPtr &req, ThreadContext *tc)
|
ITB::translateAtomic(RequestPtr req, ThreadContext *tc)
|
||||||
{
|
{
|
||||||
//If this is a pal pc, then set PHYSICAL
|
//If this is a pal pc, then set PHYSICAL
|
||||||
if(FULL_SYSTEM && PcPAL(req->getPC()))
|
if (FULL_SYSTEM && PcPAL(req->getPC()))
|
||||||
req->setFlags(req->getFlags() | PHYSICAL);
|
req->setFlags(Request::PHYSICAL);
|
||||||
|
|
||||||
if (PcPAL(req->getPC())) {
|
if (PcPAL(req->getPC())) {
|
||||||
// strip off PAL PC marker (lsb is 1)
|
// strip off PAL PC marker (lsb is 1)
|
||||||
|
@ -323,7 +330,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
|
||||||
return NoFault;
|
return NoFault;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->getFlags() & PHYSICAL) {
|
if (req->getFlags() & Request::PHYSICAL) {
|
||||||
req->setPaddr(req->getVaddr());
|
req->setPaddr(req->getVaddr());
|
||||||
} else {
|
} else {
|
||||||
// verify that this is a good virtual address
|
// verify that this is a good virtual address
|
||||||
|
@ -390,15 +397,23 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
|
||||||
if (req->getPaddr() & ~PAddrImplMask)
|
if (req->getPaddr() & ~PAddrImplMask)
|
||||||
return genMachineCheckFault();
|
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
|
// Alpha DTB
|
||||||
//
|
//
|
||||||
DTB::DTB(const Params *p)
|
DTB::DTB(const Params *p)
|
||||||
: TLB(p)
|
: TLB(p)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -472,14 +487,13 @@ DTB::regStats()
|
||||||
}
|
}
|
||||||
|
|
||||||
Fault
|
Fault
|
||||||
DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write)
|
||||||
{
|
{
|
||||||
Addr pc = tc->readPC();
|
Addr pc = tc->readPC();
|
||||||
|
|
||||||
mode_type mode =
|
mode_type mode =
|
||||||
(mode_type)DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM));
|
(mode_type)DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM));
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for alignment faults
|
* Check for alignment faults
|
||||||
*/
|
*/
|
||||||
|
@ -491,13 +505,13 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PcPAL(pc)) {
|
if (PcPAL(pc)) {
|
||||||
mode = (req->getFlags() & ALTMODE) ?
|
mode = (req->getFlags() & Request::ALTMODE) ?
|
||||||
(mode_type)ALT_MODE_AM(
|
(mode_type)ALT_MODE_AM(
|
||||||
tc->readMiscRegNoEffect(IPR_ALT_MODE))
|
tc->readMiscRegNoEffect(IPR_ALT_MODE))
|
||||||
: mode_kernel;
|
: mode_kernel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->getFlags() & PHYSICAL) {
|
if (req->getFlags() & Request::PHYSICAL) {
|
||||||
req->setPaddr(req->getVaddr());
|
req->setPaddr(req->getVaddr());
|
||||||
} else {
|
} else {
|
||||||
// verify that this is a good virtual address
|
// 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)
|
if (VAddrSpaceEV6(req->getVaddr()) == 0x7e)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
|
||||||
// only valid in kernel mode
|
// only valid in kernel mode
|
||||||
if (DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)) !=
|
if (DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)) !=
|
||||||
mode_kernel) {
|
mode_kernel) {
|
||||||
if (write) { write_acv++; } else { read_acv++; }
|
if (write) { write_acv++; } else { read_acv++; }
|
||||||
uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) |
|
uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) |
|
||||||
MM_STAT_ACV_MASK);
|
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);
|
req->setPaddr(req->getVaddr() & PAddrImplMask);
|
||||||
|
@ -553,7 +568,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
||||||
if (write) { write_misses++; } else { read_misses++; }
|
if (write) { write_misses++; } else { read_misses++; }
|
||||||
uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
|
uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
|
||||||
MM_STAT_DTB_MISS_MASK;
|
MM_STAT_DTB_MISS_MASK;
|
||||||
return (req->getFlags() & VPTE) ?
|
return (req->getFlags() & Request::VPTE) ?
|
||||||
(Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(),
|
(Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(),
|
||||||
flags)) :
|
flags)) :
|
||||||
(Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(),
|
(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 |
|
uint64_t flags = MM_STAT_WR_MASK |
|
||||||
MM_STAT_ACV_MASK |
|
MM_STAT_ACV_MASK |
|
||||||
(entry->fonw ? MM_STAT_FONW_MASK : 0);
|
(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) {
|
if (entry->fonw) {
|
||||||
write_acv++;
|
write_acv++;
|
||||||
uint64_t flags = MM_STAT_WR_MASK |
|
uint64_t flags = MM_STAT_WR_MASK | MM_STAT_FONW_MASK;
|
||||||
MM_STAT_FONW_MASK;
|
return new DtbPageFault(req->getVaddr(), req->getFlags(),
|
||||||
return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
|
flags);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!(entry->xre & MODE2MASK(mode))) {
|
if (!(entry->xre & MODE2MASK(mode))) {
|
||||||
read_acv++;
|
read_acv++;
|
||||||
uint64_t flags = MM_STAT_ACV_MASK |
|
uint64_t flags = MM_STAT_ACV_MASK |
|
||||||
(entry->fonr ? MM_STAT_FONR_MASK : 0);
|
(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) {
|
if (entry->fonr) {
|
||||||
read_acv++;
|
read_acv++;
|
||||||
uint64_t flags = MM_STAT_FONR_MASK;
|
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);
|
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 &
|
TlbEntry &
|
||||||
TLB::index(bool advance)
|
TLB::index(bool advance)
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
* Steve Reinhardt
|
* Steve Reinhardt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __ALPHA_MEMORY_HH__
|
#ifndef __ARCH_ALPHA_TLB_HH__
|
||||||
#define __ALPHA_MEMORY_HH__
|
#define __ARCH_ALPHA_TLB_HH__
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
@ -48,110 +48,120 @@
|
||||||
|
|
||||||
class ThreadContext;
|
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:
|
assert(asn < (1 << 8));
|
||||||
typedef std::multimap<Addr, int> PageTable;
|
flushAddr(vaddr, asn);
|
||||||
PageTable lookupTable; // Quick lookup into page table
|
}
|
||||||
|
|
||||||
TlbEntry *table; // the Page Table
|
// static helper functions... really EV5 VM traits
|
||||||
int size; // TLB Size
|
static bool
|
||||||
int nlu; // not last used entry (for replacement)
|
validVirtualAddress(Addr vaddr)
|
||||||
|
|
||||||
void nextnlu() { if (++nlu >= size) nlu = 0; }
|
|
||||||
TlbEntry *lookup(Addr vpn, uint8_t asn);
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef AlphaTLBParams Params;
|
|
||||||
TLB(const Params *p);
|
|
||||||
virtual ~TLB();
|
|
||||||
|
|
||||||
int getsize() const { return size; }
|
|
||||||
|
|
||||||
TlbEntry &index(bool advance = true);
|
|
||||||
void insert(Addr vaddr, TlbEntry &entry);
|
|
||||||
|
|
||||||
void flushAll();
|
|
||||||
void flushProcesses();
|
|
||||||
void flushAddr(Addr addr, uint8_t asn);
|
|
||||||
|
|
||||||
void demapPage(Addr vaddr, uint64_t asn)
|
|
||||||
{
|
|
||||||
assert(asn < (1 << 8));
|
|
||||||
flushAddr(vaddr, asn);
|
|
||||||
}
|
|
||||||
|
|
||||||
// static helper functions... really EV5 VM traits
|
|
||||||
static bool validVirtualAddress(Addr vaddr) {
|
|
||||||
// unimplemented bits must be all 0 or all 1
|
|
||||||
Addr unimplBits = vaddr & EV5::VAddrUnImplMask;
|
|
||||||
return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Fault checkCacheability(RequestPtr &req);
|
|
||||||
|
|
||||||
// Checkpointing
|
|
||||||
virtual void serialize(std::ostream &os);
|
|
||||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
|
||||||
|
|
||||||
// Most recently used page table entries
|
|
||||||
TlbEntry *EntryCache[3];
|
|
||||||
inline void flushCache()
|
|
||||||
{
|
|
||||||
memset(EntryCache, 0, 3 * sizeof(TlbEntry*));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline TlbEntry* updateCache(TlbEntry *entry) {
|
|
||||||
EntryCache[2] = EntryCache[1];
|
|
||||||
EntryCache[1] = EntryCache[0];
|
|
||||||
EntryCache[0] = entry;
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ITB : public TLB
|
|
||||||
{
|
{
|
||||||
protected:
|
// unimplemented bits must be all 0 or all 1
|
||||||
mutable Stats::Scalar<> hits;
|
Addr unimplBits = vaddr & VAddrUnImplMask;
|
||||||
mutable Stats::Scalar<> misses;
|
return unimplBits == 0 || unimplBits == VAddrUnImplMask;
|
||||||
mutable Stats::Scalar<> acv;
|
}
|
||||||
mutable Stats::Formula accesses;
|
|
||||||
|
|
||||||
public:
|
static Fault checkCacheability(RequestPtr &req, bool itb = false);
|
||||||
typedef AlphaITBParams Params;
|
|
||||||
ITB(const Params *p);
|
|
||||||
virtual void regStats();
|
|
||||||
|
|
||||||
Fault translate(RequestPtr &req, ThreadContext *tc);
|
// Checkpointing
|
||||||
};
|
virtual void serialize(std::ostream &os);
|
||||||
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
||||||
class DTB : public TLB
|
// Most recently used page table entries
|
||||||
|
TlbEntry *EntryCache[3];
|
||||||
|
inline void
|
||||||
|
flushCache()
|
||||||
{
|
{
|
||||||
protected:
|
memset(EntryCache, 0, 3 * sizeof(TlbEntry*));
|
||||||
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:
|
inline TlbEntry *
|
||||||
typedef AlphaDTBParams Params;
|
updateCache(TlbEntry *entry) {
|
||||||
DTB(const Params *p);
|
EntryCache[2] = EntryCache[1];
|
||||||
virtual void regStats();
|
EntryCache[1] = EntryCache[0];
|
||||||
|
EntryCache[0] = entry;
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Fault translate(RequestPtr &req, ThreadContext *tc, bool write);
|
class ITB : public TLB
|
||||||
};
|
{
|
||||||
}
|
protected:
|
||||||
|
mutable Stats::Scalar hits;
|
||||||
|
mutable Stats::Scalar misses;
|
||||||
|
mutable Stats::Scalar acv;
|
||||||
|
mutable Stats::Formula accesses;
|
||||||
|
|
||||||
#endif // __ALPHA_MEMORY_HH__
|
public:
|
||||||
|
typedef AlphaITBParams Params;
|
||||||
|
ITB(const Params *p);
|
||||||
|
virtual void regStats();
|
||||||
|
|
||||||
|
Fault translateAtomic(RequestPtr req, ThreadContext *tc);
|
||||||
|
void translateTiming(RequestPtr req, ThreadContext *tc,
|
||||||
|
Translation *translation);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DTB : public TLB
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
mutable Stats::Scalar read_hits;
|
||||||
|
mutable Stats::Scalar read_misses;
|
||||||
|
mutable Stats::Scalar read_acv;
|
||||||
|
mutable Stats::Scalar read_accesses;
|
||||||
|
mutable Stats::Scalar write_hits;
|
||||||
|
mutable Stats::Scalar write_misses;
|
||||||
|
mutable Stats::Scalar write_acv;
|
||||||
|
mutable Stats::Scalar write_accesses;
|
||||||
|
Stats::Formula hits;
|
||||||
|
Stats::Formula misses;
|
||||||
|
Stats::Formula acv;
|
||||||
|
Stats::Formula accesses;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef AlphaDTBParams Params;
|
||||||
|
DTB(const Params *p);
|
||||||
|
virtual void regStats();
|
||||||
|
|
||||||
|
Fault translateAtomic(RequestPtr req, ThreadContext *tc, bool write);
|
||||||
|
void translateTiming(RequestPtr req, ThreadContext *tc,
|
||||||
|
Translation *translation, bool write);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace AlphaISA
|
||||||
|
|
||||||
|
#endif // __ARCH_ALPHA_TLB_HH__
|
||||||
|
|
|
@ -32,10 +32,8 @@
|
||||||
#include "arch/alpha/tru64/tru64.hh"
|
#include "arch/alpha/tru64/tru64.hh"
|
||||||
#include "arch/alpha/isa_traits.hh"
|
#include "arch/alpha/isa_traits.hh"
|
||||||
#include "arch/alpha/tru64/process.hh"
|
#include "arch/alpha/tru64/process.hh"
|
||||||
|
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "kern/tru64/tru64.hh"
|
#include "kern/tru64/tru64.hh"
|
||||||
|
|
||||||
#include "sim/process.hh"
|
#include "sim/process.hh"
|
||||||
#include "sim/syscall_emul.hh"
|
#include "sim/syscall_emul.hh"
|
||||||
|
|
||||||
|
@ -47,7 +45,7 @@ static SyscallReturn
|
||||||
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
TypedBufferArg<AlphaTru64::utsname> name(tc->getSyscallArg(0));
|
TypedBufferArg<AlphaTru64::utsname> name(process->getSyscallArg(tc, 0));
|
||||||
|
|
||||||
strcpy(name->sysname, "OSF1");
|
strcpy(name->sysname, "OSF1");
|
||||||
strcpy(name->nodename, "m5.eecs.umich.edu");
|
strcpy(name->nodename, "m5.eecs.umich.edu");
|
||||||
|
@ -64,34 +62,35 @@ static SyscallReturn
|
||||||
getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
unsigned op = tc->getSyscallArg(0);
|
unsigned op = process->getSyscallArg(tc, 0);
|
||||||
unsigned nbytes = tc->getSyscallArg(2);
|
unsigned nbytes = process->getSyscallArg(tc, 2);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
|
||||||
case AlphaTru64::GSI_MAX_CPU: {
|
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 = htog((uint32_t)process->numCpus());
|
||||||
max_cpu.copyOut(tc->getMemPort());
|
max_cpu.copyOut(tc->getMemPort());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_CPUS_IN_BOX: {
|
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 = htog((uint32_t)process->numCpus());
|
||||||
cpus_in_box.copyOut(tc->getMemPort());
|
cpus_in_box.copyOut(tc->getMemPort());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_PHYSMEM: {
|
case AlphaTru64::GSI_PHYSMEM: {
|
||||||
TypedBufferArg<uint64_t> physmem(tc->getSyscallArg(1));
|
TypedBufferArg<uint64_t> physmem(process->getSyscallArg(tc, 1));
|
||||||
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
|
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
|
||||||
physmem.copyOut(tc->getMemPort());
|
physmem.copyOut(tc->getMemPort());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_CPU_INFO: {
|
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->current_cpu = htog(0);
|
||||||
infop->cpus_in_box = htog(process->numCpus());
|
infop->cpus_in_box = htog(process->numCpus());
|
||||||
|
@ -108,14 +107,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_PROC_TYPE: {
|
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 = htog((uint64_t)11);
|
||||||
proc_type.copyOut(tc->getMemPort());
|
proc_type.copyOut(tc->getMemPort());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_PLATFORM_NAME: {
|
case AlphaTru64::GSI_PLATFORM_NAME: {
|
||||||
BufferArg bufArg(tc->getSyscallArg(1), nbytes);
|
BufferArg bufArg(process->getSyscallArg(tc, 1), nbytes);
|
||||||
strncpy((char *)bufArg.bufferPtr(),
|
strncpy((char *)bufArg.bufferPtr(),
|
||||||
"COMPAQ Professional Workstation XP1000",
|
"COMPAQ Professional Workstation XP1000",
|
||||||
nbytes);
|
nbytes);
|
||||||
|
@ -124,7 +123,7 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_CLK_TCK: {
|
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 = htog((uint64_t)1024);
|
||||||
clk_hz.copyOut(tc->getMemPort());
|
clk_hz.copyOut(tc->getMemPort());
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -143,12 +142,12 @@ static SyscallReturn
|
||||||
setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
unsigned op = tc->getSyscallArg(0);
|
unsigned op = process->getSyscallArg(tc, 0);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case AlphaTru64::SSI_IEEE_FP_CONTROL:
|
case AlphaTru64::SSI_IEEE_FP_CONTROL:
|
||||||
warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n",
|
warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n",
|
||||||
tc->getSyscallArg(1));
|
process->getSyscallArg(tc, 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -159,26 +158,24 @@ setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Target table() handler.
|
/// Target table() handler.
|
||||||
static
|
static SyscallReturn
|
||||||
SyscallReturn tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace TheISA;
|
|
||||||
|
|
||||||
int id = tc->getSyscallArg(0); // table ID
|
int id = process->getSyscallArg(tc, 0); // table ID
|
||||||
int index = tc->getSyscallArg(1); // index into table
|
int index = process->getSyscallArg(tc, 1); // index into table
|
||||||
// arg 2 is buffer pointer; type depends on table ID
|
// arg 2 is buffer pointer; type depends on table ID
|
||||||
int nel = tc->getSyscallArg(3); // number of elements
|
int nel = process->getSyscallArg(tc, 3); // number of elements
|
||||||
int lel = tc->getSyscallArg(4); // expected element size
|
int lel = process->getSyscallArg(tc, 4); // expected element size
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case AlphaTru64::TBL_SYSINFO: {
|
case AlphaTru64::TBL_SYSINFO: {
|
||||||
if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo))
|
if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo))
|
||||||
return -EINVAL;
|
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;
|
const int clk_hz = one_million;
|
||||||
elp->si_user = htog(curTick / (Clock::Frequency / clk_hz));
|
elp->si_user = htog(curTick / (Clock::Frequency / clk_hz));
|
||||||
|
@ -219,7 +216,7 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = {
|
||||||
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
|
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
|
||||||
/* 15 */ SyscallDesc("chmod", unimplementedFunc),
|
/* 15 */ SyscallDesc("chmod", unimplementedFunc),
|
||||||
/* 16 */ SyscallDesc("chown", unimplementedFunc),
|
/* 16 */ SyscallDesc("chown", unimplementedFunc),
|
||||||
/* 17 */ SyscallDesc("obreak", obreakFunc),
|
/* 17 */ SyscallDesc("obreak", brkFunc),
|
||||||
/* 18 */ SyscallDesc("pre_F64_getfsstat", unimplementedFunc),
|
/* 18 */ SyscallDesc("pre_F64_getfsstat", unimplementedFunc),
|
||||||
/* 19 */ SyscallDesc("lseek", lseekFunc),
|
/* 19 */ SyscallDesc("lseek", lseekFunc),
|
||||||
/* 20 */ SyscallDesc("getpid", getpidPseudoFunc),
|
/* 20 */ SyscallDesc("getpid", getpidPseudoFunc),
|
||||||
|
@ -260,9 +257,9 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = {
|
||||||
/* 55 */ SyscallDesc("reboot", unimplementedFunc),
|
/* 55 */ SyscallDesc("reboot", unimplementedFunc),
|
||||||
/* 56 */ SyscallDesc("revoke", unimplementedFunc),
|
/* 56 */ SyscallDesc("revoke", unimplementedFunc),
|
||||||
/* 57 */ SyscallDesc("symlink", unimplementedFunc),
|
/* 57 */ SyscallDesc("symlink", unimplementedFunc),
|
||||||
/* 58 */ SyscallDesc("readlink", unimplementedFunc),
|
/* 58 */ SyscallDesc("readlink", readlinkFunc),
|
||||||
/* 59 */ SyscallDesc("execve", unimplementedFunc),
|
/* 59 */ SyscallDesc("execve", unimplementedFunc),
|
||||||
/* 60 */ SyscallDesc("umask", unimplementedFunc),
|
/* 60 */ SyscallDesc("umask", umaskFunc),
|
||||||
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
|
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
|
||||||
/* 62 */ SyscallDesc("old_fstat", unimplementedFunc),
|
/* 62 */ SyscallDesc("old_fstat", unimplementedFunc),
|
||||||
/* 63 */ SyscallDesc("getpgrp", unimplementedFunc),
|
/* 63 */ SyscallDesc("getpgrp", unimplementedFunc),
|
||||||
|
@ -339,7 +336,7 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = {
|
||||||
/* 133 */ SyscallDesc("sendto", unimplementedFunc),
|
/* 133 */ SyscallDesc("sendto", unimplementedFunc),
|
||||||
/* 134 */ SyscallDesc("shutdown", unimplementedFunc),
|
/* 134 */ SyscallDesc("shutdown", unimplementedFunc),
|
||||||
/* 135 */ SyscallDesc("socketpair", unimplementedFunc),
|
/* 135 */ SyscallDesc("socketpair", unimplementedFunc),
|
||||||
/* 136 */ SyscallDesc("mkdir", unimplementedFunc),
|
/* 136 */ SyscallDesc("mkdir", mkdirFunc),
|
||||||
/* 137 */ SyscallDesc("rmdir", unimplementedFunc),
|
/* 137 */ SyscallDesc("rmdir", unimplementedFunc),
|
||||||
/* 138 */ SyscallDesc("utimes", unimplementedFunc),
|
/* 138 */ SyscallDesc("utimes", unimplementedFunc),
|
||||||
/* 139 */ SyscallDesc("obsolete 4.2 sigreturn", unimplementedFunc),
|
/* 139 */ SyscallDesc("obsolete 4.2 sigreturn", unimplementedFunc),
|
||||||
|
@ -472,15 +469,14 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = {
|
||||||
/* 266 */ SyscallDesc("sendfile", unimplementedFunc),
|
/* 266 */ SyscallDesc("sendfile", unimplementedFunc),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SyscallDesc AlphaTru64Process::machSyscallDescs[] = {
|
SyscallDesc AlphaTru64Process::machSyscallDescs[] = {
|
||||||
/* 0 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
/* 0 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||||
/* 1 */ SyscallDesc("m5_mutex_lock", AlphaTru64::m5_mutex_lockFunc),
|
/* 1 */ SyscallDesc("m5_mutex_lock", AlphaTru64::m5_mutex_lockFunc),
|
||||||
/* 2 */ SyscallDesc("m5_mutex_trylock", AlphaTru64::m5_mutex_trylockFunc),
|
/* 2 */ SyscallDesc("m5_mutex_trylock", AlphaTru64::m5_mutex_trylockFunc),
|
||||||
/* 3 */ SyscallDesc("m5_mutex_unlock", AlphaTru64::m5_mutex_unlockFunc),
|
/* 3 */ SyscallDesc("m5_mutex_unlock", AlphaTru64::m5_mutex_unlockFunc),
|
||||||
/* 4 */ SyscallDesc("m5_cond_signal", AlphaTru64::m5_cond_signalFunc),
|
/* 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),
|
/* 6 */ SyscallDesc("m5_cond_wait", AlphaTru64::m5_cond_waitFunc),
|
||||||
/* 7 */ SyscallDesc("m5_thread_exit", AlphaTru64::m5_thread_exitFunc),
|
/* 7 */ SyscallDesc("m5_thread_exit", AlphaTru64::m5_thread_exitFunc),
|
||||||
/* 8 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
/* 8 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||||
|
@ -507,7 +503,8 @@ SyscallDesc AlphaTru64Process::machSyscallDescs[] = {
|
||||||
/* 29 */ SyscallDesc("nxm_thread_destroy", unimplementedFunc),
|
/* 29 */ SyscallDesc("nxm_thread_destroy", unimplementedFunc),
|
||||||
/* 30 */ SyscallDesc("lw_wire", unimplementedFunc),
|
/* 30 */ SyscallDesc("lw_wire", unimplementedFunc),
|
||||||
/* 31 */ SyscallDesc("lw_unwire", 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),
|
/* 33 */ SyscallDesc("nxm_task_init", AlphaTru64::nxm_task_initFunc),
|
||||||
/* 34 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
/* 34 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||||
/* 35 */ SyscallDesc("nxm_idle", AlphaTru64::nxm_idleFunc),
|
/* 35 */ SyscallDesc("nxm_idle", AlphaTru64::nxm_idleFunc),
|
||||||
|
@ -572,9 +569,8 @@ AlphaTru64Process::getDesc(int callnum)
|
||||||
return &syscallDescs[callnum];
|
return &syscallDescs[callnum];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AlphaTru64Process::AlphaTru64Process(LiveProcessParams *params,
|
||||||
AlphaTru64Process::AlphaTru64Process(LiveProcessParams * params,
|
ObjectFile *objFile)
|
||||||
ObjectFile *objFile)
|
|
||||||
: AlphaLiveProcess(params, objFile),
|
: AlphaLiveProcess(params, objFile),
|
||||||
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)),
|
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)),
|
||||||
Num_Mach_Syscall_Descs(sizeof(machSyscallDescs) / sizeof(SyscallDesc))
|
Num_Mach_Syscall_Descs(sizeof(machSyscallDescs) / sizeof(SyscallDesc))
|
||||||
|
|
|
@ -28,12 +28,13 @@
|
||||||
* Authors: Steve Reinhardt
|
* Authors: Steve Reinhardt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __ALPHA_TRU64_PROCESS_HH__
|
#ifndef __ARCH_ALPHA_TRU64_PROCESS_HH__
|
||||||
#define __ALPHA_TRU64_PROCESS_HH__
|
#define __ARCH_ALPHA_TRU64_PROCESS_HH__
|
||||||
|
|
||||||
#include "arch/alpha/process.hh"
|
#include "arch/alpha/process.hh"
|
||||||
|
|
||||||
namespace AlphaISA {
|
namespace AlphaISA {
|
||||||
|
|
||||||
/// A process with emulated Alpha Tru64 syscalls.
|
/// A process with emulated Alpha Tru64 syscalls.
|
||||||
class AlphaTru64Process : public AlphaLiveProcess
|
class AlphaTru64Process : public AlphaLiveProcess
|
||||||
{
|
{
|
||||||
|
@ -51,9 +52,9 @@ class AlphaTru64Process : public AlphaLiveProcess
|
||||||
const int Num_Syscall_Descs;
|
const int Num_Syscall_Descs;
|
||||||
const int Num_Mach_Syscall_Descs;
|
const int Num_Mach_Syscall_Descs;
|
||||||
|
|
||||||
virtual SyscallDesc* getDesc(int callnum);
|
virtual SyscallDesc *getDesc(int callnum);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AlphaISA
|
} // namespace AlphaISA
|
||||||
|
|
||||||
#endif // __ALPHA_TRU64_PROCESS_HH__
|
#endif // __ARCH_ALPHA_TRU64_PROCESS_HH__
|
||||||
|
|
|
@ -33,34 +33,34 @@
|
||||||
// open(2) flags translation table
|
// open(2) flags translation table
|
||||||
OpenFlagTransTable AlphaTru64::openFlagTable[] = {
|
OpenFlagTransTable AlphaTru64::openFlagTable[] = {
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
{ AlphaTru64::TGT_O_RDONLY, _O_RDONLY },
|
{ AlphaTru64::TGT_O_RDONLY, _O_RDONLY },
|
||||||
{ AlphaTru64::TGT_O_WRONLY, _O_WRONLY },
|
{ AlphaTru64::TGT_O_WRONLY, _O_WRONLY },
|
||||||
{ AlphaTru64::TGT_O_RDWR, _O_RDWR },
|
{ AlphaTru64::TGT_O_RDWR, _O_RDWR },
|
||||||
{ AlphaTru64::TGT_O_APPEND, _O_APPEND },
|
{ AlphaTru64::TGT_O_APPEND, _O_APPEND },
|
||||||
{ AlphaTru64::TGT_O_CREAT, _O_CREAT },
|
{ AlphaTru64::TGT_O_CREAT, _O_CREAT },
|
||||||
{ AlphaTru64::TGT_O_TRUNC, _O_TRUNC },
|
{ AlphaTru64::TGT_O_TRUNC, _O_TRUNC },
|
||||||
{ AlphaTru64::TGT_O_EXCL, _O_EXCL },
|
{ AlphaTru64::TGT_O_EXCL, _O_EXCL },
|
||||||
#ifdef _O_NONBLOCK
|
#ifdef _O_NONBLOCK
|
||||||
{ AlphaTru64::TGT_O_NONBLOCK, _O_NONBLOCK },
|
{ AlphaTru64::TGT_O_NONBLOCK, _O_NONBLOCK },
|
||||||
#endif
|
#endif
|
||||||
#ifdef _O_NOCTTY
|
#ifdef _O_NOCTTY
|
||||||
{ AlphaTru64::TGT_O_NOCTTY, _O_NOCTTY },
|
{ AlphaTru64::TGT_O_NOCTTY, _O_NOCTTY },
|
||||||
#endif
|
#endif
|
||||||
#ifdef _O_SYNC
|
#ifdef _O_SYNC
|
||||||
{ AlphaTru64::TGT_O_SYNC, _O_SYNC },
|
{ AlphaTru64::TGT_O_SYNC, _O_SYNC },
|
||||||
#endif
|
#endif
|
||||||
#else /* !_MSC_VER */
|
#else /* !_MSC_VER */
|
||||||
{ AlphaTru64::TGT_O_RDONLY, O_RDONLY },
|
{ AlphaTru64::TGT_O_RDONLY, O_RDONLY },
|
||||||
{ AlphaTru64::TGT_O_WRONLY, O_WRONLY },
|
{ AlphaTru64::TGT_O_WRONLY, O_WRONLY },
|
||||||
{ AlphaTru64::TGT_O_RDWR, O_RDWR },
|
{ AlphaTru64::TGT_O_RDWR, O_RDWR },
|
||||||
{ AlphaTru64::TGT_O_APPEND, O_APPEND },
|
{ AlphaTru64::TGT_O_APPEND, O_APPEND },
|
||||||
{ AlphaTru64::TGT_O_CREAT, O_CREAT },
|
{ AlphaTru64::TGT_O_CREAT, O_CREAT },
|
||||||
{ AlphaTru64::TGT_O_TRUNC, O_TRUNC },
|
{ AlphaTru64::TGT_O_TRUNC, O_TRUNC },
|
||||||
{ AlphaTru64::TGT_O_EXCL, O_EXCL },
|
{ AlphaTru64::TGT_O_EXCL, O_EXCL },
|
||||||
{ AlphaTru64::TGT_O_NONBLOCK, O_NONBLOCK },
|
{ AlphaTru64::TGT_O_NONBLOCK, O_NONBLOCK },
|
||||||
{ AlphaTru64::TGT_O_NOCTTY, O_NOCTTY },
|
{ AlphaTru64::TGT_O_NOCTTY, O_NOCTTY },
|
||||||
#ifdef O_SYNC
|
#ifdef O_SYNC
|
||||||
{ AlphaTru64::TGT_O_SYNC, O_SYNC },
|
{ AlphaTru64::TGT_O_SYNC, O_SYNC },
|
||||||
#endif
|
#endif
|
||||||
#endif /* _MSC_VER */
|
#endif /* _MSC_VER */
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,14 +28,13 @@
|
||||||
* Authors: Korey Sewell
|
* Authors: Korey Sewell
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __ALPHA_ALPHA_TRU64_HH
|
#ifndef __ALPHA_ALPHA_TRU64_TRU64_HH__
|
||||||
#define __ALPHA_ALPHA_TRU64_HH
|
#define __ALPHA_ALPHA_TRU64_TRU64_HH__
|
||||||
|
|
||||||
#include "kern/tru64/tru64.hh"
|
#include "kern/tru64/tru64.hh"
|
||||||
|
|
||||||
class AlphaTru64 : public Tru64
|
class AlphaTru64 : public Tru64
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// This table maps the target open() flags to the corresponding
|
/// This table maps the target open() flags to the corresponding
|
||||||
/// host open() flags.
|
/// host open() flags.
|
||||||
|
@ -46,21 +45,21 @@ class AlphaTru64 : public Tru64
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
/// open(2) flag values.
|
/// open(2) flag values.
|
||||||
static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY
|
static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY
|
||||||
static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY
|
static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY
|
||||||
static const int TGT_O_RDWR = 00000002; //!< O_RDWR
|
static const int TGT_O_RDWR = 00000002; //!< O_RDWR
|
||||||
static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK
|
static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK
|
||||||
static const int TGT_O_APPEND = 00000010; //!< O_APPEND
|
static const int TGT_O_APPEND = 00000010; //!< O_APPEND
|
||||||
static const int TGT_O_CREAT = 00001000; //!< O_CREAT
|
static const int TGT_O_CREAT = 00001000; //!< O_CREAT
|
||||||
static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC
|
static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC
|
||||||
static const int TGT_O_EXCL = 00004000; //!< O_EXCL
|
static const int TGT_O_EXCL = 00004000; //!< O_EXCL
|
||||||
static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY
|
static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY
|
||||||
static const int TGT_O_SYNC = 00040000; //!< O_SYNC
|
static const int TGT_O_SYNC = 00040000; //!< O_SYNC
|
||||||
static const int TGT_O_DRD = 00100000; //!< O_DRD
|
static const int TGT_O_DRD = 00100000; //!< O_DRD
|
||||||
static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO
|
static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO
|
||||||
static const int TGT_O_CACHE = 00400000; //!< O_CACHE
|
static const int TGT_O_CACHE = 00400000; //!< O_CACHE
|
||||||
static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC
|
static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC
|
||||||
static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC
|
static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/// For mmap().
|
/// For mmap().
|
||||||
|
@ -68,13 +67,13 @@ class AlphaTru64 : public Tru64
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
/// For getsysinfo().
|
/// For getsysinfo().
|
||||||
static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
|
static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name string
|
||||||
static const unsigned GSI_CPU_INFO = 59; //!< CPU information
|
static const unsigned GSI_CPU_INFO = 59; //!< CPU information
|
||||||
static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
|
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_MAX_CPU = 30; //!< max # CPUs on machine
|
||||||
static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
|
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_PHYSMEM = 19; //!< Physical memory in KB
|
||||||
static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
|
static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
|
@ -124,6 +123,4 @@ class AlphaTru64 : public Tru64
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // __ALPHA_ALPHA_TRU64_TRU64_HH__
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -32,47 +32,43 @@
|
||||||
#ifndef __ARCH_ALPHA_TYPES_HH__
|
#ifndef __ARCH_ALPHA_TYPES_HH__
|
||||||
#define __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;
|
enum annotes
|
||||||
typedef uint64_t ExtMachInst;
|
{
|
||||||
typedef uint8_t RegIndex;
|
ANNOTE_NONE = 0,
|
||||||
|
// An impossible number for instruction annotations
|
||||||
|
ITOUCH_ANNOTE = 0xffffffff,
|
||||||
|
};
|
||||||
|
|
||||||
typedef uint64_t IntReg;
|
struct CoreSpecific
|
||||||
typedef uint64_t LargestRead;
|
{
|
||||||
|
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
|
} // namespace AlphaISA
|
||||||
|
|
||||||
#endif
|
#endif // __ARCH_ALPHA_TYPES_HH__
|
||||||
|
|
|
@ -36,28 +36,28 @@
|
||||||
#include "mem/vport.hh"
|
#include "mem/vport.hh"
|
||||||
#endif
|
#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
|
#if FULL_SYSTEM
|
||||||
|
const int NumArgumentRegs = 6;
|
||||||
if (number < NumArgumentRegs) {
|
if (number < NumArgumentRegs) {
|
||||||
if (fp)
|
if (fp)
|
||||||
return tc->readFloatRegBits(ArgumentReg[number]);
|
return tc->readFloatRegBits(16 + number);
|
||||||
else
|
else
|
||||||
return tc->readIntReg(ArgumentReg[number]);
|
return tc->readIntReg(16 + number);
|
||||||
} else {
|
} else {
|
||||||
Addr sp = tc->readIntReg(StackPointerReg);
|
Addr sp = tc->readIntReg(StackPointerReg);
|
||||||
VirtualPort *vp = tc->getVirtPort(tc);
|
VirtualPort *vp = tc->getVirtPort();
|
||||||
uint64_t arg = vp->read<uint64_t>(sp +
|
uint64_t arg = vp->read<uint64_t>(sp +
|
||||||
(number-NumArgumentRegs) * sizeof(uint64_t));
|
(number-NumArgumentRegs) * sizeof(uint64_t));
|
||||||
tc->delVirtPort(vp);
|
|
||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
panic("getArgument() is Full system only\n");
|
panic("getArgument() is Full system only\n");
|
||||||
M5_DUMMY_RETURN
|
M5_DUMMY_RETURN;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,127 +32,137 @@
|
||||||
#ifndef __ARCH_ALPHA_UTILITY_HH__
|
#ifndef __ARCH_ALPHA_UTILITY_HH__
|
||||||
#define __ARCH_ALPHA_UTILITY_HH__
|
#define __ARCH_ALPHA_UTILITY_HH__
|
||||||
|
|
||||||
#include "config/full_system.hh"
|
|
||||||
#include "arch/alpha/types.hh"
|
#include "arch/alpha/types.hh"
|
||||||
#include "arch/alpha/isa_traits.hh"
|
#include "arch/alpha/isa_traits.hh"
|
||||||
#include "arch/alpha/regfile.hh"
|
#include "arch/alpha/regfile.hh"
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
|
#include "config/full_system.hh"
|
||||||
#include "cpu/thread_context.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
|
inline bool
|
||||||
inUserMode(ThreadContext *tc)
|
isCalleeSaveIntegerRegister(unsigned int reg)
|
||||||
{
|
{
|
||||||
return (tc->readMiscRegNoEffect(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
|
panic("register classification not implemented");
|
||||||
}
|
return reg >= 9 && reg <= 15;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool isCallerSaveIntegerRegister(unsigned int reg) {
|
inline bool
|
||||||
panic("register classification not implemented");
|
isCallerSaveFloatRegister(unsigned int reg)
|
||||||
return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27);
|
{
|
||||||
}
|
panic("register classification not implemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool isCalleeSaveIntegerRegister(unsigned int reg) {
|
inline bool
|
||||||
panic("register classification not implemented");
|
isCalleeSaveFloatRegister(unsigned int reg)
|
||||||
return (reg >= 9 && reg <= 15);
|
{
|
||||||
}
|
panic("register classification not implemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool isCallerSaveFloatRegister(unsigned int reg) {
|
inline Addr
|
||||||
panic("register classification not implemented");
|
alignAddress(const Addr &addr, unsigned int nbytes)
|
||||||
return false;
|
{
|
||||||
}
|
return (addr & ~(nbytes - 1));
|
||||||
|
}
|
||||||
|
|
||||||
inline bool isCalleeSaveFloatRegister(unsigned int reg) {
|
// Instruction address compression hooks
|
||||||
panic("register classification not implemented");
|
inline Addr
|
||||||
return false;
|
realPCToFetchPC(const Addr &addr)
|
||||||
}
|
{
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
inline Addr alignAddress(const Addr &addr,
|
inline Addr
|
||||||
unsigned int nbytes) {
|
fetchPCToRealPC(const Addr &addr)
|
||||||
return (addr & ~(nbytes - 1));
|
{
|
||||||
}
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
// Instruction address compression hooks
|
// the size of "fetched" instructions (not necessarily the size
|
||||||
inline Addr realPCToFetchPC(const Addr &addr) {
|
// of real instructions for PISA)
|
||||||
return addr;
|
inline size_t
|
||||||
}
|
fetchInstSize()
|
||||||
|
{
|
||||||
|
return sizeof(MachInst);
|
||||||
|
}
|
||||||
|
|
||||||
inline Addr fetchPCToRealPC(const Addr &addr) {
|
inline MachInst
|
||||||
return addr;
|
makeRegisterCopy(int dest, int src)
|
||||||
}
|
{
|
||||||
|
panic("makeRegisterCopy not implemented");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// the size of "fetched" instructions (not necessarily the size
|
// Machine operations
|
||||||
// of real instructions for PISA)
|
void saveMachineReg(AnyReg &savereg, const RegFile ®_file, int regnum);
|
||||||
inline size_t fetchInstSize() {
|
void restoreMachineReg(RegFile ®s, const AnyReg ®, int regnum);
|
||||||
return sizeof(MachInst);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline MachInst makeRegisterCopy(int dest, int src) {
|
/**
|
||||||
panic("makeRegisterCopy not implemented");
|
* Function to insure ISA semantics about 0 registers.
|
||||||
return 0;
|
* @param tc The thread context.
|
||||||
}
|
*/
|
||||||
|
template <class TC>
|
||||||
|
void zeroRegisters(TC *tc);
|
||||||
|
|
||||||
// Machine operations
|
// Alpha IPR register accessors
|
||||||
|
inline bool PcPAL(Addr addr) { return addr & 0x3; }
|
||||||
|
inline void startupCPU(ThreadContext *tc, int cpuId) { tc->activate(0); }
|
||||||
|
|
||||||
void saveMachineReg(AnyReg &savereg, const RegFile ®_file,
|
////////////////////////////////////////////////////////////////////////
|
||||||
int regnum);
|
//
|
||||||
|
// Translation stuff
|
||||||
|
//
|
||||||
|
|
||||||
void restoreMachineReg(RegFile ®s, const AnyReg ®,
|
inline Addr PteAddr(Addr a) { return (a & PteMask) << PteShift; }
|
||||||
int regnum);
|
|
||||||
|
|
||||||
/**
|
// User Virtual
|
||||||
* Function to insure ISA semantics about 0 registers.
|
inline bool IsUSeg(Addr a) { return USegBase <= a && a <= USegEnd; }
|
||||||
* @param tc The thread context.
|
|
||||||
*/
|
|
||||||
template <class TC>
|
|
||||||
void zeroRegisters(TC *tc);
|
|
||||||
|
|
||||||
// Alpha IPR register accessors
|
// Kernel Direct Mapped
|
||||||
inline bool PcPAL(Addr addr) { return addr & 0x3; }
|
inline bool IsK0Seg(Addr a) { return K0SegBase <= a && a <= K0SegEnd; }
|
||||||
inline void startupCPU(ThreadContext *tc, int cpuId) {
|
inline Addr K0Seg2Phys(Addr addr) { return addr & ~K0SegBase; }
|
||||||
tc->activate(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
// Kernel Virtual
|
||||||
//
|
inline bool IsK1Seg(Addr a) { return K1SegBase <= a && a <= K1SegEnd; }
|
||||||
// Translation stuff
|
|
||||||
//
|
|
||||||
|
|
||||||
inline Addr PteAddr(Addr a) { return (a & PteMask) << PteShift; }
|
inline Addr
|
||||||
|
TruncPage(Addr addr)
|
||||||
|
{ return addr & ~(PageBytes - 1); }
|
||||||
|
|
||||||
// User Virtual
|
inline Addr
|
||||||
inline bool IsUSeg(Addr a) { return USegBase <= a && a <= USegEnd; }
|
RoundPage(Addr addr)
|
||||||
|
{ return (addr + PageBytes - 1) & ~(PageBytes - 1); }
|
||||||
|
|
||||||
// Kernel Direct Mapped
|
void initIPRs(ThreadContext *tc, int cpuId);
|
||||||
inline bool IsK0Seg(Addr a) { return K0SegBase <= a && a <= K0SegEnd; }
|
|
||||||
inline Addr K0Seg2Phys(Addr addr) { return addr & ~K0SegBase; }
|
|
||||||
|
|
||||||
// Kernel Virtual
|
|
||||||
inline bool IsK1Seg(Addr a) { return K1SegBase <= a && a <= K1SegEnd; }
|
|
||||||
|
|
||||||
inline Addr
|
|
||||||
TruncPage(Addr addr)
|
|
||||||
{ return addr & ~(PageBytes - 1); }
|
|
||||||
|
|
||||||
inline Addr
|
|
||||||
RoundPage(Addr addr)
|
|
||||||
{ return (addr + PageBytes - 1) & ~(PageBytes - 1); }
|
|
||||||
|
|
||||||
void initIPRs(ThreadContext *tc, int cpuId);
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
void initCPU(ThreadContext *tc, int cpuId);
|
void initCPU(ThreadContext *tc, int cpuId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to check for and process any interrupts.
|
* Function to check for and process any interrupts.
|
||||||
* @param tc The thread context.
|
* @param tc The thread context.
|
||||||
*/
|
*/
|
||||||
template <class TC>
|
template <class TC>
|
||||||
void processInterrupts(TC *tc);
|
void processInterrupts(TC *tc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace AlphaISA
|
} // namespace AlphaISA
|
||||||
|
|
||||||
#endif
|
#endif // __ARCH_ALPHA_UTILITY_HH__
|
||||||
|
|
|
@ -40,27 +40,28 @@
|
||||||
#include "mem/vport.hh"
|
#include "mem/vport.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace AlphaISA;
|
|
||||||
|
|
||||||
AlphaISA::PageTableEntry
|
namespace AlphaISA {
|
||||||
AlphaISA::kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr)
|
|
||||||
|
PageTableEntry
|
||||||
|
kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, VAddr vaddr)
|
||||||
{
|
{
|
||||||
Addr level1_pte = ptbr + vaddr.level1();
|
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()) {
|
if (!level1.valid()) {
|
||||||
DPRINTF(VtoPhys, "level 1 PTE not valid, va = %#\n", vaddr);
|
DPRINTF(VtoPhys, "level 1 PTE not valid, va = %#\n", vaddr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr level2_pte = level1.paddr() + vaddr.level2();
|
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()) {
|
if (!level2.valid()) {
|
||||||
DPRINTF(VtoPhys, "level 2 PTE not valid, va = %#x\n", vaddr);
|
DPRINTF(VtoPhys, "level 2 PTE not valid, va = %#x\n", vaddr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr level3_pte = level2.paddr() + vaddr.level3();
|
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()) {
|
if (!level3.valid()) {
|
||||||
DPRINTF(VtoPhys, "level 3 PTE not valid, va = %#x\n", vaddr);
|
DPRINTF(VtoPhys, "level 3 PTE not valid, va = %#x\n", vaddr);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -69,13 +70,13 @@ AlphaISA::kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vadd
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
AlphaISA::vtophys(Addr vaddr)
|
vtophys(Addr vaddr)
|
||||||
{
|
{
|
||||||
Addr paddr = 0;
|
Addr paddr = 0;
|
||||||
if (AlphaISA::IsUSeg(vaddr))
|
if (IsUSeg(vaddr))
|
||||||
DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr);
|
DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr);
|
||||||
else if (AlphaISA::IsK0Seg(vaddr))
|
else if (IsK0Seg(vaddr))
|
||||||
paddr = AlphaISA::K0Seg2Phys(vaddr);
|
paddr = K0Seg2Phys(vaddr);
|
||||||
else
|
else
|
||||||
panic("vtophys: ptbr is not set on virtual lookup");
|
panic("vtophys: ptbr is not set on virtual lookup");
|
||||||
|
|
||||||
|
@ -85,22 +86,22 @@ AlphaISA::vtophys(Addr vaddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
AlphaISA::vtophys(ThreadContext *tc, Addr addr)
|
vtophys(ThreadContext *tc, Addr addr)
|
||||||
{
|
{
|
||||||
AlphaISA::VAddr vaddr = addr;
|
VAddr vaddr = addr;
|
||||||
Addr ptbr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp20);
|
Addr ptbr = tc->readMiscRegNoEffect(IPR_PALtemp20);
|
||||||
Addr paddr = 0;
|
Addr paddr = 0;
|
||||||
//@todo Andrew couldn't remember why he commented some of this code
|
//@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?
|
//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);
|
paddr = vaddr & ~ULL(1);
|
||||||
} else {
|
} else {
|
||||||
if (AlphaISA::IsK0Seg(vaddr)) {
|
if (IsK0Seg(vaddr)) {
|
||||||
paddr = AlphaISA::K0Seg2Phys(vaddr);
|
paddr = K0Seg2Phys(vaddr);
|
||||||
} else if (!ptbr) {
|
} else if (!ptbr) {
|
||||||
paddr = vaddr;
|
paddr = vaddr;
|
||||||
} else {
|
} else {
|
||||||
AlphaISA::PageTableEntry pte =
|
PageTableEntry pte =
|
||||||
kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr);
|
kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr);
|
||||||
if (pte.valid())
|
if (pte.valid())
|
||||||
paddr = pte.paddr() | vaddr.offset();
|
paddr = pte.paddr() | vaddr.offset();
|
||||||
|
@ -113,3 +114,4 @@ AlphaISA::vtophys(ThreadContext *tc, Addr addr)
|
||||||
return paddr;
|
return paddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace AlphaISA
|
||||||
|
|
|
@ -41,12 +41,13 @@ class FunctionalPort;
|
||||||
|
|
||||||
namespace AlphaISA {
|
namespace AlphaISA {
|
||||||
|
|
||||||
PageTableEntry
|
PageTableEntry kernel_pte_lookup(FunctionalPort *mem, Addr ptbr,
|
||||||
kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr);
|
VAddr vaddr);
|
||||||
|
|
||||||
Addr vtophys(Addr vaddr);
|
Addr vtophys(Addr vaddr);
|
||||||
Addr vtophys(ThreadContext *tc, Addr vaddr);
|
Addr vtophys(ThreadContext *tc, Addr vaddr);
|
||||||
|
|
||||||
|
} // namespace AlphaISA
|
||||||
|
|
||||||
};
|
|
||||||
#endif // __ARCH_ALPHA_VTOPHYS_H__
|
#endif // __ARCH_ALPHA_VTOPHYS_H__
|
||||||
|
|
||||||
|
|
|
@ -34,25 +34,21 @@ from m5.params import *
|
||||||
class ArmTLB(SimObject):
|
class ArmTLB(SimObject):
|
||||||
abstract = True
|
abstract = True
|
||||||
type = 'ArmTLB'
|
type = 'ArmTLB'
|
||||||
cxx_namespace = 'ArmISA'
|
cxx_class = 'ArmISA::TLB'
|
||||||
cxx_class = 'TLB'
|
|
||||||
size = Param.Int("TLB size")
|
size = Param.Int("TLB size")
|
||||||
|
|
||||||
class ArmDTB(ArmTLB):
|
class ArmDTB(ArmTLB):
|
||||||
type = 'ArmDTB'
|
type = 'ArmDTB'
|
||||||
cxx_namespace = 'ArmISA'
|
cxx_class = 'ArmISA::DTB'
|
||||||
cxx_class = 'DTB'
|
|
||||||
size = 64
|
size = 64
|
||||||
|
|
||||||
class ArmITB(ArmTLB):
|
class ArmITB(ArmTLB):
|
||||||
type = 'ArmITB'
|
type = 'ArmITB'
|
||||||
cxx_namespace = 'ArmISA'
|
cxx_class = 'ArmISA::ITB'
|
||||||
cxx_class = 'ITB'
|
|
||||||
size = 64
|
size = 64
|
||||||
|
|
||||||
class ArmUTB(ArmTLB):
|
class ArmUTB(ArmTLB):
|
||||||
type = 'ArmUTB'
|
type = 'ArmUTB'
|
||||||
cxx_namespace = 'ArmISA'
|
cxx_class = 'ArmISA::UTB'
|
||||||
cxx_class = 'UTB'
|
|
||||||
size = 64
|
size = 64
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue