Merge with the main repo.

--HG--
rename : src/mem/vport.hh => src/mem/fs_translating_port_proxy.hh
rename : src/mem/translating_port.cc => src/mem/se_translating_port_proxy.cc
rename : src/mem/translating_port.hh => src/mem/se_translating_port_proxy.hh
This commit is contained in:
Gabe Black 2012-01-28 07:24:01 -08:00
commit c3d41a2def
717 changed files with 16788 additions and 13793 deletions

View file

@ -32,11 +32,17 @@
import m5 import m5
from m5.objects import * from m5.objects import *
from Caches import * from Caches import *
from O3_ARM_v7a import *
def config_cache(options, system): def config_cache(options, system):
if options.l2cache: if options.l2cache:
system.l2 = L2Cache(size = options.l2_size, assoc = options.l2_assoc, if options.cpu_type == "arm_detailed":
block_size=options.cacheline_size) system.l2 = O3_ARM_v7aL2(size = options.l2_size, assoc = options.l2_assoc,
block_size=options.cacheline_size)
else:
system.l2 = L2Cache(size = options.l2_size, assoc = options.l2_assoc,
block_size=options.cacheline_size)
system.tol2bus = Bus() system.tol2bus = Bus()
system.l2.cpu_side = system.tol2bus.port system.l2.cpu_side = system.tol2bus.port
system.l2.mem_side = system.membus.port system.l2.mem_side = system.membus.port
@ -44,10 +50,21 @@ def config_cache(options, system):
for i in xrange(options.num_cpus): for i in xrange(options.num_cpus):
if options.caches: if options.caches:
icache = L1Cache(size = options.l1i_size, assoc = options.l1i_assoc, if options.cpu_type == "arm_detailed":
block_size=options.cacheline_size) icache = O3_ARM_v7a_ICache(size = options.l1i_size,
dcache = L1Cache(size = options.l1d_size, assoc = options.l1d_assoc, assoc = options.l1i_assoc,
block_size=options.cacheline_size) block_size=options.cacheline_size)
dcache = O3_ARM_v7a_DCache(size = options.l1d_size,
assoc = options.l1d_assoc,
block_size=options.cacheline_size)
else:
icache = L1Cache(size = options.l1i_size,
assoc = options.l1i_assoc,
block_size=options.cacheline_size)
dcache = L1Cache(size = options.l1d_size,
assoc = options.l1d_assoc,
block_size=options.cacheline_size)
if buildEnv['TARGET_ISA'] == 'x86': if buildEnv['TARGET_ISA'] == 'x86':
system.cpu[i].addPrivateSplitL1Caches(icache, dcache, system.cpu[i].addPrivateSplitL1Caches(icache, dcache,
PageTableWalkerCache(), PageTableWalkerCache(),

View file

@ -1,4 +1,4 @@
# Copyright (c) 2010 ARM Limited # Copyright (c) 2010-2012 ARM Limited
# All rights reserved. # All rights reserved.
# #
# The license below extends only to copyright in the software and shall # The license below extends only to copyright in the software and shall
@ -56,6 +56,7 @@ class MemBus(Bus):
def makeLinuxAlphaSystem(mem_mode, mdesc = None): def makeLinuxAlphaSystem(mem_mode, mdesc = None):
IO_address_space_base = 0x80000000000
class BaseTsunami(Tsunami): class BaseTsunami(Tsunami):
ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0) ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0)
ide = IdeController(disks=[Parent.disk0, Parent.disk2], ide = IdeController(disks=[Parent.disk0, Parent.disk2],
@ -68,10 +69,13 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
self.readfile = mdesc.script() self.readfile = mdesc.script()
self.iobus = Bus(bus_id=0) self.iobus = Bus(bus_id=0)
self.membus = MemBus(bus_id=1) self.membus = MemBus(bus_id=1)
self.bridge = Bridge(delay='50ns', nack_delay='4ns') # By default the bridge responds to all addresses above the I/O
# base address (including the PCI config space)
self.bridge = Bridge(delay='50ns', nack_delay='4ns',
ranges = [AddrRange(IO_address_space_base, Addr.max)])
self.physmem = PhysicalMemory(range = AddrRange(mdesc.mem())) self.physmem = PhysicalMemory(range = AddrRange(mdesc.mem()))
self.bridge.side_a = self.iobus.port self.bridge.master = self.iobus.port
self.bridge.side_b = self.membus.port self.bridge.slave = self.membus.port
self.physmem.port = self.membus.port self.physmem.port = self.membus.port
self.disk0 = CowIdeDisk(driveID='master') self.disk0 = CowIdeDisk(driveID='master')
self.disk2 = CowIdeDisk(driveID='master') self.disk2 = CowIdeDisk(driveID='master')
@ -80,7 +84,11 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
self.tsunami = BaseTsunami() self.tsunami = BaseTsunami()
self.tsunami.attachIO(self.iobus) self.tsunami.attachIO(self.iobus)
self.tsunami.ide.pio = self.iobus.port self.tsunami.ide.pio = self.iobus.port
self.tsunami.ide.config = self.iobus.port
self.tsunami.ide.dma = self.iobus.port
self.tsunami.ethernet.pio = self.iobus.port self.tsunami.ethernet.pio = self.iobus.port
self.tsunami.ethernet.config = self.iobus.port
self.tsunami.ethernet.dma = self.iobus.port
self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(), self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(),
read_only = True)) read_only = True))
self.intrctrl = IntrControl() self.intrctrl = IntrControl()
@ -91,6 +99,8 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
self.console = binary('console') self.console = binary('console')
self.boot_osflags = 'root=/dev/hda1 console=ttyS0' self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
self.system_port = self.membus.port
return self return self
def makeLinuxAlphaRubySystem(mem_mode, mdesc = None): def makeLinuxAlphaRubySystem(mem_mode, mdesc = None):
@ -123,7 +133,11 @@ def makeLinuxAlphaRubySystem(mem_mode, mdesc = None):
self.tsunami = BaseTsunami() self.tsunami = BaseTsunami()
self.tsunami.attachIO(self.piobus) self.tsunami.attachIO(self.piobus)
self.tsunami.ide.pio = self.piobus.port self.tsunami.ide.pio = self.piobus.port
self.tsunami.ide.config = self.piobus.port
self.tsunami.ide.dma = self.piobus.port
self.tsunami.ethernet.pio = self.piobus.port self.tsunami.ethernet.pio = self.piobus.port
self.tsunami.ethernet.config = self.piobus.port
self.tsunami.ethernet.dma = self.piobus.port
# #
# Store the dma devices for later connection to dma ruby ports. # Store the dma devices for later connection to dma ruby ports.
@ -144,6 +158,10 @@ def makeLinuxAlphaRubySystem(mem_mode, mdesc = None):
return self return self
def makeSparcSystem(mem_mode, mdesc = None): def makeSparcSystem(mem_mode, mdesc = None):
# Constants from iob.cc and uart8250.cc
iob_man_addr = 0x9800000000
uart_pio_size = 8
class CowMmDisk(MmDisk): class CowMmDisk(MmDisk):
image = CowDiskImage(child=RawDiskImage(read_only=True), image = CowDiskImage(child=RawDiskImage(read_only=True),
read_only=False) read_only=False)
@ -164,8 +182,8 @@ def makeSparcSystem(mem_mode, mdesc = None):
self.t1000.attachIO(self.iobus) self.t1000.attachIO(self.iobus)
self.physmem = PhysicalMemory(range = AddrRange(Addr('1MB'), size = '64MB'), zero = True) self.physmem = PhysicalMemory(range = AddrRange(Addr('1MB'), size = '64MB'), zero = True)
self.physmem2 = PhysicalMemory(range = AddrRange(Addr('2GB'), size ='256MB'), zero = True) self.physmem2 = PhysicalMemory(range = AddrRange(Addr('2GB'), size ='256MB'), zero = True)
self.bridge.side_a = self.iobus.port self.bridge.master = self.iobus.port
self.bridge.side_b = self.membus.port self.bridge.slave = self.membus.port
self.physmem.port = self.membus.port self.physmem.port = self.membus.port
self.physmem2.port = self.membus.port self.physmem2.port = self.membus.port
self.rom.port = self.membus.port self.rom.port = self.membus.port
@ -176,6 +194,25 @@ def makeSparcSystem(mem_mode, mdesc = None):
self.disk0 = CowMmDisk() self.disk0 = CowMmDisk()
self.disk0.childImage(disk('disk.s10hw2')) self.disk0.childImage(disk('disk.s10hw2'))
self.disk0.pio = self.iobus.port self.disk0.pio = self.iobus.port
# The puart0 and hvuart are placed on the IO bus, so create ranges
# for them. The remaining IO range is rather fragmented, so poke
# holes for the iob and partition descriptors etc.
self.bridge.ranges = \
[
AddrRange(self.t1000.puart0.pio_addr,
self.t1000.puart0.pio_addr + uart_pio_size - 1),
AddrRange(self.disk0.pio_addr,
self.t1000.fake_jbi.pio_addr +
self.t1000.fake_jbi.pio_size - 1),
AddrRange(self.t1000.fake_clk.pio_addr,
iob_man_addr - 1),
AddrRange(self.t1000.fake_l2_1.pio_addr,
self.t1000.fake_ssi.pio_addr +
self.t1000.fake_ssi.pio_size - 1),
AddrRange(self.t1000.hvuart.pio_addr,
self.t1000.hvuart.pio_addr + uart_pio_size - 1)
]
self.reset_bin = binary('reset_new.bin') self.reset_bin = binary('reset_new.bin')
self.hypervisor_bin = binary('q_new.bin') self.hypervisor_bin = binary('q_new.bin')
self.openboot_bin = binary('openboot_new.bin') self.openboot_bin = binary('openboot_new.bin')
@ -183,6 +220,8 @@ def makeSparcSystem(mem_mode, mdesc = None):
self.hypervisor_desc_bin = binary('1up-hv.bin') self.hypervisor_desc_bin = binary('1up-hv.bin')
self.partition_desc_bin = binary('1up-md.bin') self.partition_desc_bin = binary('1up-md.bin')
self.system_port = self.membus.port
return self return self
def makeArmSystem(mem_mode, machine_type, mdesc = None, bare_metal=False): def makeArmSystem(mem_mode, machine_type, mdesc = None, bare_metal=False):
@ -202,8 +241,8 @@ def makeArmSystem(mem_mode, machine_type, mdesc = None, bare_metal=False):
self.membus = MemBus(bus_id=1) self.membus = MemBus(bus_id=1)
self.membus.badaddr_responder.warn_access = "warn" self.membus.badaddr_responder.warn_access = "warn"
self.bridge = Bridge(delay='50ns', nack_delay='4ns') self.bridge = Bridge(delay='50ns', nack_delay='4ns')
self.bridge.side_a = self.iobus.port self.bridge.master = self.iobus.port
self.bridge.side_b = self.membus.port self.bridge.slave = self.membus.port
self.mem_mode = mem_mode self.mem_mode = mem_mode
@ -257,12 +296,14 @@ def makeArmSystem(mem_mode, machine_type, mdesc = None, bare_metal=False):
self.boot_osflags = boot_flags self.boot_osflags = boot_flags
self.physmem.port = self.membus.port self.physmem.port = self.membus.port
self.realview.attachOnChipIO(self.membus) self.realview.attachOnChipIO(self.membus, self.bridge)
self.realview.attachIO(self.iobus) self.realview.attachIO(self.iobus)
self.intrctrl = IntrControl() self.intrctrl = IntrControl()
self.terminal = Terminal() self.terminal = Terminal()
self.vncserver = VncServer() self.vncserver = VncServer()
self.system_port = self.membus.port
return self return self
@ -281,8 +322,8 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None):
self.membus = MemBus(bus_id=1) self.membus = MemBus(bus_id=1)
self.bridge = Bridge(delay='50ns', nack_delay='4ns') self.bridge = Bridge(delay='50ns', nack_delay='4ns')
self.physmem = PhysicalMemory(range = AddrRange('1GB')) self.physmem = PhysicalMemory(range = AddrRange('1GB'))
self.bridge.side_a = self.iobus.port self.bridge.master = self.iobus.port
self.bridge.side_b = self.membus.port self.bridge.slave = self.membus.port
self.physmem.port = self.membus.port self.physmem.port = self.membus.port
self.disk0 = CowIdeDisk(driveID='master') self.disk0 = CowIdeDisk(driveID='master')
self.disk2 = CowIdeDisk(driveID='master') self.disk2 = CowIdeDisk(driveID='master')
@ -291,7 +332,11 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None):
self.malta = BaseMalta() self.malta = BaseMalta()
self.malta.attachIO(self.iobus) self.malta.attachIO(self.iobus)
self.malta.ide.pio = self.iobus.port self.malta.ide.pio = self.iobus.port
self.malta.ide.config = self.iobus.port
self.malta.ide.dma = self.iobus.port
self.malta.ethernet.pio = self.iobus.port self.malta.ethernet.pio = self.iobus.port
self.malta.ethernet.config = self.iobus.port
self.malta.ethernet.dma = self.iobus.port
self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(), self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(),
read_only = True)) read_only = True))
self.intrctrl = IntrControl() self.intrctrl = IntrControl()
@ -301,6 +346,8 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None):
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'
self.system_port = self.membus.port
return self return self
def x86IOAddress(port): def x86IOAddress(port):
@ -308,18 +355,48 @@ def x86IOAddress(port):
return IO_address_space_base + port return IO_address_space_base + port
def connectX86ClassicSystem(x86_sys): def connectX86ClassicSystem(x86_sys):
# Constants similar to x86_traits.hh
IO_address_space_base = 0x8000000000000000
pci_config_address_space_base = 0xc000000000000000
interrupts_address_space_base = 0xa000000000000000
APIC_range_size = 1 << 12;
x86_sys.membus = MemBus(bus_id=1) x86_sys.membus = MemBus(bus_id=1)
x86_sys.physmem.port = x86_sys.membus.port x86_sys.physmem.port = x86_sys.membus.port
# North Bridge # North Bridge
x86_sys.iobus = Bus(bus_id=0) x86_sys.iobus = Bus(bus_id=0)
x86_sys.bridge = Bridge(delay='50ns', nack_delay='4ns') x86_sys.bridge = Bridge(delay='50ns', nack_delay='4ns')
x86_sys.bridge.side_a = x86_sys.iobus.port x86_sys.bridge.master = x86_sys.iobus.port
x86_sys.bridge.side_b = x86_sys.membus.port x86_sys.bridge.slave = x86_sys.membus.port
# Allow the bridge to pass through the IO APIC (two pages),
# everything in the IO address range up to the local APIC, and
# then the entire PCI address space and beyond
x86_sys.bridge.ranges = \
[
AddrRange(x86_sys.pc.south_bridge.io_apic.pio_addr,
x86_sys.pc.south_bridge.io_apic.pio_addr +
APIC_range_size - 1),
AddrRange(IO_address_space_base,
interrupts_address_space_base - 1),
AddrRange(pci_config_address_space_base,
Addr.max)
]
# Create a bridge from the IO bus to the memory bus to allow access to
# the local APIC (two pages)
x86_sys.iobridge = Bridge(delay='50ns', nack_delay='4ns')
x86_sys.iobridge.slave = x86_sys.iobus.port
x86_sys.iobridge.master = x86_sys.membus.port
x86_sys.iobridge.ranges = [AddrRange(interrupts_address_space_base,
interrupts_address_space_base +
APIC_range_size - 1)]
# connect the io bus # connect the io bus
x86_sys.pc.attachIO(x86_sys.iobus) x86_sys.pc.attachIO(x86_sys.iobus)
x86_sys.system_port = x86_sys.membus.port
def connectX86RubySystem(x86_sys): def connectX86RubySystem(x86_sys):
# North Bridge # North Bridge
x86_sys.piobus = Bus(bus_id=0) x86_sys.piobus = Bus(bus_id=0)

View file

@ -0,0 +1,199 @@
# Copyright (c) 2012 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: Ron Dreslinski
from m5.objects import *
# Simple ALU Instructions have a latency of 1
class O3_ARM_v7a_Simple_Int(FUDesc):
opList = [ OpDesc(opClass='IntAlu', opLat=1) ]
count = 2
# Complex ALU instructions have a variable latencies
class O3_ARM_v7a_Complex_Int(FUDesc):
opList = [ OpDesc(opClass='IntMult', opLat=3, issueLat=1),
OpDesc(opClass='IntDiv', opLat=12, issueLat=12),
OpDesc(opClass='IprAccess', opLat=3, issueLat=1) ]
count = 1
# Floating point and SIMD instructions
class O3_ARM_v7a_FP(FUDesc):
opList = [ OpDesc(opClass='SimdAdd', opLat=4),
OpDesc(opClass='SimdAddAcc', opLat=4),
OpDesc(opClass='SimdAlu', opLat=4),
OpDesc(opClass='SimdCmp', opLat=4),
OpDesc(opClass='SimdCvt', opLat=3),
OpDesc(opClass='SimdMisc', opLat=3),
OpDesc(opClass='SimdMult',opLat=5),
OpDesc(opClass='SimdMultAcc',opLat=5),
OpDesc(opClass='SimdShift',opLat=3),
OpDesc(opClass='SimdShiftAcc', opLat=3),
OpDesc(opClass='SimdSqrt', opLat=9),
OpDesc(opClass='SimdFloatAdd',opLat=5),
OpDesc(opClass='SimdFloatAlu',opLat=5),
OpDesc(opClass='SimdFloatCmp', opLat=3),
OpDesc(opClass='SimdFloatCvt', opLat=3),
OpDesc(opClass='SimdFloatDiv', opLat=3),
OpDesc(opClass='SimdFloatMisc', opLat=3),
OpDesc(opClass='SimdFloatMult', opLat=3),
OpDesc(opClass='SimdFloatMultAcc',opLat=1),
OpDesc(opClass='SimdFloatSqrt', opLat=9),
OpDesc(opClass='FloatAdd', opLat=5),
OpDesc(opClass='FloatCmp', opLat=5),
OpDesc(opClass='FloatCvt', opLat=5),
OpDesc(opClass='FloatDiv', opLat=9, issueLat=9),
OpDesc(opClass='FloatSqrt', opLat=33, issueLat=33),
OpDesc(opClass='FloatMult', opLat=4) ]
count = 2
# Load/Store Units
class O3_ARM_v7a_Load(FUDesc):
opList = [ OpDesc(opClass='MemRead',opLat=2) ]
count = 1
class O3_ARM_v7a_Store(FUDesc):
opList = [OpDesc(opClass='MemWrite',opLat=2) ]
count = 1
# Functional Units for this CPU
class O3_ARM_v7a_FUP(FUPool):
FUList = [O3_ARM_v7a_Simple_Int(), O3_ARM_v7a_Complex_Int(),
O3_ARM_v7a_Load(), O3_ARM_v7a_Store(), O3_ARM_v7a_FP()]
class O3_ARM_v7a_3(DerivO3CPU):
predType = "tournament"
localPredictorSize = 64
localCtrBits = 2
localHistoryTableSize = 64
localHistoryBits = 6
globalPredictorSize = 8192
globalCtrBits = 2
globalHistoryBits = 13
choicePredictorSize = 8192
choiceCtrBits = 2
BTBEntries = 2048
BTBTagSize = 18
RASSize = 16
instShiftAmt = 2
LQEntries = 16
SQEntries = 16
LSQDepCheckShift = 0
LFSTSize = 1024
SSITSize = 1024
decodeToFetchDelay = 1
renameToFetchDelay = 1
iewToFetchDelay = 1
commitToFetchDelay = 1
renameToDecodeDelay = 1
iewToDecodeDelay = 1
commitToDecodeDelay = 1
iewToRenameDelay = 1
commitToRenameDelay = 1
commitToIEWDelay = 1
fetchWidth = 3
fetchToDecodeDelay = 3
decodeWidth = 3
decodeToRenameDelay = 2
renameWidth = 3
renameToIEWDelay = 1
issueToExecuteDelay = 1
dispatchWidth = 6
issueWidth = 8
wbWidth = 8
wbDepth = 1
fuPool = O3_ARM_v7a_FUP()
iewToCommitDelay = 1
renameToROBDelay = 1
commitWidth = 8
squashWidth = 8
trapLatency = 13
backComSize = 5
forwardComSize = 5
numPhysIntRegs = 128
numPhysFloatRegs = 128
numIQEntries = 32
numROBEntries = 40
defer_registration= False
# Instruction Cache
# All latencys assume a 1GHz clock rate, with a faster clock they would be faster
class O3_ARM_v7a_ICache(BaseCache):
latency = '1ns'
block_size = 64
mshrs = 2
tgts_per_mshr = 8
size = '32kB'
assoc = 2
is_top_level = 'true'
# Data Cache
# All latencys assume a 1GHz clock rate, with a faster clock they would be faster
class O3_ARM_v7a_DCache(BaseCache):
latency = '2ns'
block_size = 64
mshrs = 6
tgts_per_mshr = 8
size = '32kB'
assoc = 2
write_buffers = 16
is_top_level = 'true'
# TLB Cache
# Use a cache as a L2 TLB
class O3_ARM_v7aWalkCache(BaseCache):
latency = '4ns'
block_size = 64
mshrs = 6
tgts_per_mshr = 8
size = '1kB'
assoc = 8
write_buffers = 16
is_top_level = 'true'
# L2 Cache
# All latencys assume a 1GHz clock rate, with a faster clock they would be faster
class O3_ARM_v7aL2(BaseCache):
latency = '12ns'
block_size = 64
mshrs = 16
tgts_per_mshr = 8
size = '1MB'
assoc = 16
write_buffers = 8
# Simple stride prefetcher
prefetch_policy = 'stride'
prefetch_on_access = 'true'
prefetch_latency = '1.0ns'
prefetch_degree = 8

View file

@ -28,7 +28,8 @@
# system options # system options
parser.add_option("--cpu-type", type="choice", default="atomic", parser.add_option("--cpu-type", type="choice", default="atomic",
choices = ["atomic", "timing", "detailed", "inorder"], choices = ["atomic", "timing", "detailed", "inorder",
"arm_detailed"],
help = "type of cpu to run with") help = "type of cpu to run with")
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")

View file

@ -34,6 +34,7 @@ import m5
from m5.defines import buildEnv from m5.defines import buildEnv
from m5.objects import * from m5.objects import *
from m5.util import * from m5.util import *
from O3_ARM_v7a import *
addToPath('../common') addToPath('../common')
@ -42,11 +43,14 @@ def setCPUClass(options):
atomic = False atomic = False
if options.cpu_type == "timing": if options.cpu_type == "timing":
class TmpClass(TimingSimpleCPU): pass class TmpClass(TimingSimpleCPU): pass
elif options.cpu_type == "detailed": elif options.cpu_type == "detailed" or options.cpu_type == "arm_detailed":
if not options.caches: if not options.caches and not options.ruby:
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 if options.cpu_type == "arm_detailed":
class TmpClass(O3_ARM_v7a_3): pass
else:
class TmpClass(DerivO3CPU): pass
elif options.cpu_type == "inorder": elif options.cpu_type == "inorder":
if not options.caches: if not options.caches:
print "InOrder CPU must be used with caches" print "InOrder CPU must be used with caches"

View file

@ -1,4 +1,4 @@
# Copyright (c) 2010 ARM Limited # Copyright (c) 2010-2011 ARM Limited
# All rights reserved. # All rights reserved.
# #
# The license below extends only to copyright in the software and shall # The license below extends only to copyright in the software and shall
@ -157,23 +157,19 @@ test_sys.cpu = [TestCPUClass(cpu_id=i) for i in xrange(np)]
CacheConfig.config_cache(options, test_sys) CacheConfig.config_cache(options, test_sys)
if bm[0]:
mem_size = bm[0].mem()
else:
mem_size = SysConfig().mem()
if options.caches or options.l2cache: if options.caches or options.l2cache:
if bm[0]:
mem_size = bm[0].mem()
else:
mem_size = SysConfig().mem()
# For x86, we need to poke a hole for interrupt messages to get back to the
# CPU. These use a portion of the physical address space which has a
# non-zero prefix in the top nibble. Normal memory accesses have a 0
# prefix.
if buildEnv['TARGET_ISA'] == 'x86':
test_sys.bridge.filter_ranges_a=[AddrRange(0, Addr.max >> 4)]
else:
test_sys.bridge.filter_ranges_a=[AddrRange(0, Addr.max)]
test_sys.bridge.filter_ranges_b=[AddrRange(mem_size)]
test_sys.iocache = IOCache(addr_range=mem_size) test_sys.iocache = IOCache(addr_range=mem_size)
test_sys.iocache.cpu_side = test_sys.iobus.port test_sys.iocache.cpu_side = test_sys.iobus.port
test_sys.iocache.mem_side = test_sys.membus.port test_sys.iocache.mem_side = test_sys.membus.port
else:
test_sys.iobridge = Bridge(delay='50ns', nack_delay='4ns',
ranges = [AddrRange(mem_size)])
test_sys.iobridge.slave = test_sys.iobus.port
test_sys.iobridge.master = test_sys.membus.port
for i in xrange(np): for i in xrange(np):
if options.fastmem: if options.fastmem:

View file

@ -1,3 +1,15 @@
# Copyright (c) 2012 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder. You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Copyright (c) 2006-2008 The Regents of The University of Michigan # Copyright (c) 2006-2008 The Regents of The University of Michigan
# All rights reserved. # All rights reserved.
# #
@ -152,20 +164,13 @@ if options.cpu_type == "detailed" or options.cpu_type == "inorder":
process += [smt_process, ] process += [smt_process, ]
smt_idx += 1 smt_idx += 1
numThreads = len(workloads) numThreads = len(workloads)
if options.ruby: if options.ruby:
if options.cpu_type == "detailed": if not (options.cpu_type == "detailed" or options.cpu_type == "timing"):
print >> sys.stderr, "Ruby only works with TimingSimpleCPU!!" print >> sys.stderr, "Ruby requires TimingSimpleCPU or O3CPU!!"
sys.exit(1) sys.exit(1)
elif not options.cpu_type == "timing":
print >> sys.stderr, "****WARN: using Timing CPU since it's needed by Ruby"
class CPUClass(TimingSimpleCPU): pass
test_mem_mode = 'timing'
FutureClass = None
else:
(CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options)
(CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options)
CPUClass.clock = '2GHz' CPUClass.clock = '2GHz'
CPUClass.numThreads = numThreads; CPUClass.numThreads = numThreads;
@ -179,7 +184,9 @@ if options.ruby:
options.use_map = True options.use_map = True
Ruby.create_system(options, system) Ruby.create_system(options, system)
assert(options.num_cpus == len(system.ruby._cpu_ruby_ports)) assert(options.num_cpus == len(system.ruby._cpu_ruby_ports))
system.system_port = system.ruby._sys_port_proxy.port
else: else:
system.system_port = system.membus.port
system.physmem.port = system.membus.port system.physmem.port = system.membus.port
CacheConfig.config_cache(options, system) CacheConfig.config_cache(options, system)

View file

@ -89,6 +89,8 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
L1IcacheMemory = l1i_cache, L1IcacheMemory = l1i_cache,
L1DcacheMemory = l1d_cache, L1DcacheMemory = l1d_cache,
l2_select_num_bits = l2_bits, l2_select_num_bits = l2_bits,
send_evictions = (
options.cpu_type == "detailed"),
ruby_system = ruby_system) ruby_system = ruby_system)
cpu_seq = RubySequencer(version = i, cpu_seq = RubySequencer(version = i,
@ -151,7 +153,9 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
cntrl_id = cntrl_count, cntrl_id = cntrl_count,
directory = \ directory = \
RubyDirectoryMemory(version = i, RubyDirectoryMemory(version = i,
size = dir_size), size = dir_size,
use_map =
options.use_map),
memBuffer = mem_cntrl, memBuffer = mem_cntrl,
ruby_system = ruby_system) ruby_system = ruby_system)

View file

@ -81,6 +81,8 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
l1_cntrl = L1Cache_Controller(version = i, l1_cntrl = L1Cache_Controller(version = i,
cntrl_id = cntrl_count, cntrl_id = cntrl_count,
cacheMemory = cache, cacheMemory = cache,
send_evictions = (
options.cpu_type == "detailed"),
ruby_system = ruby_system) ruby_system = ruby_system)
cpu_seq = RubySequencer(version = i, cpu_seq = RubySequencer(version = i,

View file

@ -89,6 +89,8 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
L1IcacheMemory = l1i_cache, L1IcacheMemory = l1i_cache,
L1DcacheMemory = l1d_cache, L1DcacheMemory = l1d_cache,
l2_select_num_bits = l2_bits, l2_select_num_bits = l2_bits,
send_evictions = (
options.cpu_type == "detailed"),
ruby_system = ruby_system) ruby_system = ruby_system)
cpu_seq = RubySequencer(version = i, cpu_seq = RubySequencer(version = i,

View file

@ -111,6 +111,8 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
not options.disable_dyn_timeouts, not options.disable_dyn_timeouts,
no_mig_atomic = not \ no_mig_atomic = not \
options.allow_atomic_migration, options.allow_atomic_migration,
send_evictions = (
options.cpu_type == "detailed"),
ruby_system = ruby_system) ruby_system = ruby_system)
cpu_seq = RubySequencer(version = i, cpu_seq = RubySequencer(version = i,

View file

@ -104,6 +104,8 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
L2cacheMemory = l2_cache, L2cacheMemory = l2_cache,
no_mig_atomic = not \ no_mig_atomic = not \
options.allow_atomic_migration, options.allow_atomic_migration,
send_evictions = (
options.cpu_type == "detailed"),
ruby_system = ruby_system) ruby_system = ruby_system)
cpu_seq = RubySequencer(version = i, cpu_seq = RubySequencer(version = i,

View file

@ -1,3 +1,15 @@
# Copyright (c) 2012 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder. You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Copyright (c) 2006-2007 The Regents of The University of Michigan # Copyright (c) 2006-2007 The Regents of The University of Michigan
# Copyright (c) 2009 Advanced Micro Devices, Inc. # Copyright (c) 2009 Advanced Micro Devices, Inc.
# All rights reserved. # All rights reserved.
@ -82,6 +94,17 @@ def create_system(options, system, piobus = None, dma_devices = []):
print "Error: could not create sytem for ruby protocol %s" % protocol print "Error: could not create sytem for ruby protocol %s" % protocol
raise raise
# Create a port proxy for connecting the system port. This is
# independent of the protocol and kept in the protocol-agnostic
# part (i.e. here).
sys_port_proxy = RubyPortProxy(version = 0,
physMemPort = system.physmem.port,
physmem = system.physmem,
ruby_system = ruby)
# Give the system port proxy a SimObject parent without creating a
# full-fledged controller
system.sys_port_proxy = sys_port_proxy
# #
# Set the network classes based on the command line options # Set the network classes based on the command line options
# #
@ -159,4 +182,5 @@ def create_system(options, system, piobus = None, dma_devices = []):
ruby.profiler = ruby_profiler ruby.profiler = ruby_profiler
ruby.mem_size = total_mem_size ruby.mem_size = total_mem_size
ruby._cpu_ruby_ports = cpu_sequencers ruby._cpu_ruby_ports = cpu_sequencers
ruby._sys_port_proxy = sys_port_proxy
ruby.random_seed = options.random_seed ruby.random_seed = options.random_seed

View file

@ -41,9 +41,7 @@
#include "arch/vtophys.hh" #include "arch/vtophys.hh"
#include "base/loader/symtab.hh" #include "base/loader/symtab.hh"
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "mem/physical.hh" #include "mem/fs_translating_port_proxy.hh"
#include "mem/port.hh"
#include "mem/vport.hh"
#include "sim/byteswap.hh" #include "sim/byteswap.hh"
#define TIMER_FREQUENCY 1193180 #define TIMER_FREQUENCY 1193180
@ -78,8 +76,8 @@ FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc)
ppc_vaddr = (Addr)tc->readIntReg(17); ppc_vaddr = (Addr)tc->readIntReg(17);
timer_vaddr = (Addr)tc->readIntReg(18); timer_vaddr = (Addr)tc->readIntReg(18);
virtPort->write(ppc_vaddr, (uint32_t)SimClock::Frequency); virtProxy->write(ppc_vaddr, (uint32_t)SimClock::Frequency);
virtPort->write(timer_vaddr, (uint32_t)TIMER_FREQUENCY); virtProxy->write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
} }
void void

View file

@ -56,7 +56,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
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");
name.copyOut(tc->getMemPort()); name.copyOut(tc->getMemProxy());
return 0; return 0;
} }
@ -78,7 +78,7 @@ osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
TypedBufferArg<uint64_t> fpcr(bufPtr); TypedBufferArg<uint64_t> fpcr(bufPtr);
// 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->getMemProxy());
return 0; return 0;
} }
@ -106,7 +106,7 @@ osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
case 14: { // SSI_IEEE_FP_CONTROL case 14: { // SSI_IEEE_FP_CONTROL
TypedBufferArg<uint64_t> fpcr(bufPtr); TypedBufferArg<uint64_t> fpcr(bufPtr);
// 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->getMemProxy());
DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr)); " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
return 0; return 0;

View file

@ -63,6 +63,17 @@ using namespace Linux;
LinuxAlphaSystem::LinuxAlphaSystem(Params *p) LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
: AlphaSystem(p) : AlphaSystem(p)
{ {
}
void
LinuxAlphaSystem::initState()
{
// Moved from the constructor to here since it relies on the
// address map being resolved in the interconnect
// Call the initialisation of the super class
AlphaSystem::initState();
Addr addr = 0; Addr addr = 0;
/** /**
@ -77,8 +88,9 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
* Since we aren't using a bootloader, we have to copy the * Since we aren't using a bootloader, we have to copy the
* kernel arguments directly into the kernel's memory. * kernel arguments directly into the kernel's memory.
*/ */
virtPort->writeBlob(CommandLine(), (uint8_t*)params()->boot_osflags.c_str(), virtProxy->writeBlob(CommandLine(),
params()->boot_osflags.length()+1); (uint8_t*)params()->boot_osflags.c_str(),
params()->boot_osflags.length()+1);
/** /**
* find the address of the est_cycle_freq variable and insert it * find the address of the est_cycle_freq variable and insert it
@ -86,8 +98,8 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
* calculated it by using the PIT, RTC, etc. * calculated it by using the PIT, RTC, etc.
*/ */
if (kernelSymtab->findAddress("est_cycle_freq", addr)) if (kernelSymtab->findAddress("est_cycle_freq", addr))
virtPort->write(addr, (uint64_t)(SimClock::Frequency / virtProxy->write(addr, (uint64_t)(SimClock::Frequency /
p->boot_cpu_frequency)); params()->boot_cpu_frequency));
/** /**
@ -97,7 +109,7 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
* 255 ASNs. * 255 ASNs.
*/ */
if (kernelSymtab->findAddress("dp264_mv", addr)) if (kernelSymtab->findAddress("dp264_mv", addr))
virtPort->write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127)); virtProxy->write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127));
else else
panic("could not find dp264_mv\n"); panic("could not find dp264_mv\n");
@ -164,9 +176,9 @@ LinuxAlphaSystem::setDelayLoop(ThreadContext *tc)
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) { if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
Tick cpuFreq = tc->getCpuPtr()->frequency(); Tick cpuFreq = tc->getCpuPtr()->frequency();
assert(intrFreq); assert(intrFreq);
VirtualPort *vp; FSTranslatingPortProxy* vp;
vp = tc->getVirtPort(); vp = tc->getVirtProxy();
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988)); vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
} }
} }

View file

@ -128,7 +128,14 @@ class LinuxAlphaSystem : public AlphaSystem
LinuxAlphaSystem(Params *p); LinuxAlphaSystem(Params *p);
~LinuxAlphaSystem(); ~LinuxAlphaSystem();
/**
* Initialise the system
*/
virtual void initState();
void setDelayLoop(ThreadContext *tc); void setDelayLoop(ThreadContext *tc);
const Params *params() const { return (const Params *)_params; }
}; };
#endif // __ARCH_ALPHA_LINUX_SYSTEM_HH__ #endif // __ARCH_ALPHA_LINUX_SYSTEM_HH__

View file

@ -78,7 +78,7 @@ class ThreadInfo
if (!addr) if (!addr)
addr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23); addr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23);
FunctionalPort *p = tc->getPhysPort(); PortProxy* p = tc->getPhysProxy();
p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr)); p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
return sp & ~ULL(0x3fff); return sp & ~ULL(0x3fff);

View file

@ -188,7 +188,7 @@ RemoteGDB::acc(Addr va, size_t len)
Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20); Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20);
PageTableEntry pte = PageTableEntry pte =
kernel_pte_lookup(context->getPhysPort(), ptbr, va); kernel_pte_lookup(context->getPhysProxy(), 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;
@ -312,3 +312,11 @@ RemoteGDB::write(Addr vaddr, size_t size, const char *data)
} }
} }
bool
RemoteGDB::insertHardBreak(Addr addr, size_t len)
{
warn_once("Breakpoints do not work in Alpha PAL mode.\n"
" See PCEventQueue::doService() in cpu/pc_event.cc.\n");
return BaseRemoteGDB::insertHardBreak(addr, len);
}

View file

@ -63,6 +63,8 @@ class RemoteGDB : public BaseRemoteGDB
bool acc(Addr addr, size_t len); bool acc(Addr addr, size_t len);
bool write(Addr addr, size_t size, const char *data); bool write(Addr addr, size_t size, const char *data);
virtual bool insertHardBreak(Addr addr, size_t len);
public: public:
RemoteGDB(System *system, ThreadContext *context); RemoteGDB(System *system, ThreadContext *context);
}; };

View file

@ -37,7 +37,7 @@
#include "base/trace.hh" #include "base/trace.hh"
#include "cpu/base.hh" #include "cpu/base.hh"
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "mem/vport.hh" #include "mem/fs_translating_port_proxy.hh"
#include "sim/system.hh" #include "sim/system.hh"
using namespace std; using namespace std;
@ -48,7 +48,7 @@ ProcessInfo::ProcessInfo(ThreadContext *_tc)
: tc(_tc) : tc(_tc)
{ {
Addr addr = 0; Addr addr = 0;
VirtualPort *vp = tc->getVirtPort(); FSTranslatingPortProxy* vp = tc->getVirtProxy();
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
if (!symtab->findAddress("thread_info_size", addr)) if (!symtab->findAddress("thread_info_size", addr))
@ -81,9 +81,9 @@ ProcessInfo::task(Addr ksp) const
Addr tsk; Addr tsk;
VirtualPort *vp; FSTranslatingPortProxy* vp;
vp = tc->getVirtPort(); vp = tc->getVirtProxy();
tsk = vp->readGtoH<Addr>(base + task_off); tsk = vp->readGtoH<Addr>(base + task_off);
return tsk; return tsk;
@ -98,9 +98,9 @@ ProcessInfo::pid(Addr ksp) const
uint16_t pd; uint16_t pd;
VirtualPort *vp; FSTranslatingPortProxy* vp;
vp = tc->getVirtPort(); vp = tc->getVirtProxy();
pd = vp->readGtoH<uint16_t>(task + pid_off); pd = vp->readGtoH<uint16_t>(task + pid_off);
return pd; return pd;

View file

@ -38,8 +38,7 @@
#include "base/loader/symtab.hh" #include "base/loader/symtab.hh"
#include "base/trace.hh" #include "base/trace.hh"
#include "debug/Loader.hh" #include "debug/Loader.hh"
#include "mem/physical.hh" #include "mem/fs_translating_port_proxy.hh"
#include "mem/vport.hh"
#include "params/AlphaSystem.hh" #include "params/AlphaSystem.hh"
#include "sim/byteswap.hh" #include "sim/byteswap.hh"
@ -64,11 +63,30 @@ AlphaSystem::AlphaSystem(Params *p)
pal = createObjectFile(params()->pal); pal = createObjectFile(params()->pal);
if (pal == NULL) if (pal == NULL)
fatal("Could not load PALcode file %s", params()->pal); fatal("Could not load PALcode file %s", params()->pal);
}
AlphaSystem::~AlphaSystem()
{
delete consoleSymtab;
delete console;
delete pal;
#ifdef DEBUG
delete consolePanicEvent;
#endif
}
void
AlphaSystem::initState()
{
// Moved from the constructor to here since it relies on the
// address map being resolved in the interconnect
// Call the initialisation of the super class
System::initState();
// Load program sections into memory // Load program sections into memory
pal->loadSections(functionalPort, loadAddrMask); pal->loadSections(physProxy, loadAddrMask);
console->loadSections(functionalPort, loadAddrMask); console->loadSections(physProxy, loadAddrMask);
// load symbols // load symbols
if (!console->loadGlobalSymbols(consoleSymtab)) if (!console->loadGlobalSymbols(consoleSymtab))
@ -101,8 +119,8 @@ AlphaSystem::AlphaSystem(Params *p)
* others do.) * others do.)
*/ */
if (consoleSymtab->findAddress("env_booted_osflags", addr)) { if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
virtPort->writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(), virtProxy->writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
strlen(params()->boot_osflags.c_str())); strlen(params()->boot_osflags.c_str()));
} }
/** /**
@ -112,23 +130,13 @@ AlphaSystem::AlphaSystem(Params *p)
if (consoleSymtab->findAddress("m5_rpb", addr)) { if (consoleSymtab->findAddress("m5_rpb", addr)) {
uint64_t data; uint64_t data;
data = htog(params()->system_type); data = htog(params()->system_type);
virtPort->write(addr+0x50, data); virtProxy->write(addr+0x50, data);
data = htog(params()->system_rev); data = htog(params()->system_rev);
virtPort->write(addr+0x58, data); virtProxy->write(addr+0x58, data);
} else } else
panic("could not find hwrpb\n"); panic("could not find hwrpb\n");
} }
AlphaSystem::~AlphaSystem()
{
delete consoleSymtab;
delete console;
delete pal;
#ifdef DEBUG
delete consolePanicEvent;
#endif
}
/** /**
* This function fixes up addresses that are used to match PCs for * This function fixes up addresses that are used to match PCs for
* hooking simulator events on to target function executions. * hooking simulator events on to target function executions.
@ -170,8 +178,8 @@ AlphaSystem::fixFuncEventAddr(Addr addr)
// lda gp,Y(gp): opcode 8, Ra = 29, rb = 29 // lda gp,Y(gp): opcode 8, Ra = 29, rb = 29
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 = virtProxy->read<uint32_t>(addr);
uint32_t i2 = virtPort->read<uint32_t>(addr + sizeof(MachInst)); uint32_t i2 = virtProxy->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) {
@ -188,7 +196,7 @@ AlphaSystem::setAlphaAccess(Addr access)
{ {
Addr addr = 0; Addr addr = 0;
if (consoleSymtab->findAddress("m5AlphaAccess", addr)) { if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
virtPort->write(addr, htog(Phys2K0Seg(access))); virtProxy->write(addr, htog(Phys2K0Seg(access)));
} else { } else {
panic("could not find m5AlphaAccess\n"); panic("could not find m5AlphaAccess\n");
} }

View file

@ -50,6 +50,12 @@ class AlphaSystem : public System
~AlphaSystem(); ~AlphaSystem();
public: public:
/**
* Initialise the state of the system.
*/
virtual void initState();
/** /**
* Serialization stuff * Serialization stuff
*/ */

View file

@ -55,7 +55,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
strcpy(name->version, "732"); strcpy(name->version, "732");
strcpy(name->machine, "alpha"); strcpy(name->machine, "alpha");
name.copyOut(tc->getMemPort()); name.copyOut(tc->getMemProxy());
return 0; return 0;
} }
@ -74,21 +74,21 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
case AlphaTru64::GSI_MAX_CPU: { case AlphaTru64::GSI_MAX_CPU: {
TypedBufferArg<uint32_t> max_cpu(bufPtr); TypedBufferArg<uint32_t> max_cpu(bufPtr);
*max_cpu = htog((uint32_t)process->numCpus()); *max_cpu = htog((uint32_t)process->numCpus());
max_cpu.copyOut(tc->getMemPort()); max_cpu.copyOut(tc->getMemProxy());
return 1; return 1;
} }
case AlphaTru64::GSI_CPUS_IN_BOX: { case AlphaTru64::GSI_CPUS_IN_BOX: {
TypedBufferArg<uint32_t> cpus_in_box(bufPtr); TypedBufferArg<uint32_t> cpus_in_box(bufPtr);
*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->getMemProxy());
return 1; return 1;
} }
case AlphaTru64::GSI_PHYSMEM: { case AlphaTru64::GSI_PHYSMEM: {
TypedBufferArg<uint64_t> physmem(bufPtr); TypedBufferArg<uint64_t> physmem(bufPtr);
*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->getMemProxy());
return 1; return 1;
} }
@ -105,14 +105,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
infop->cpu_ex_binding = htog(0); infop->cpu_ex_binding = htog(0);
infop->mhz = htog(667); infop->mhz = htog(667);
infop.copyOut(tc->getMemPort()); infop.copyOut(tc->getMemProxy());
return 1; return 1;
} }
case AlphaTru64::GSI_PROC_TYPE: { case AlphaTru64::GSI_PROC_TYPE: {
TypedBufferArg<uint64_t> proc_type(bufPtr); TypedBufferArg<uint64_t> proc_type(bufPtr);
*proc_type = htog((uint64_t)11); *proc_type = htog((uint64_t)11);
proc_type.copyOut(tc->getMemPort()); proc_type.copyOut(tc->getMemProxy());
return 1; return 1;
} }
@ -121,14 +121,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
strncpy((char *)bufArg.bufferPtr(), strncpy((char *)bufArg.bufferPtr(),
"COMPAQ Professional Workstation XP1000", "COMPAQ Professional Workstation XP1000",
nbytes); nbytes);
bufArg.copyOut(tc->getMemPort()); bufArg.copyOut(tc->getMemProxy());
return 1; return 1;
} }
case AlphaTru64::GSI_CLK_TCK: { case AlphaTru64::GSI_CLK_TCK: {
TypedBufferArg<uint64_t> clk_hz(bufPtr); TypedBufferArg<uint64_t> clk_hz(bufPtr);
*clk_hz = htog((uint64_t)1024); *clk_hz = htog((uint64_t)1024);
clk_hz.copyOut(tc->getMemPort()); clk_hz.copyOut(tc->getMemProxy());
return 1; return 1;
} }
@ -193,7 +193,7 @@ tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
elp->si_phz = htog(clk_hz); elp->si_phz = htog(clk_hz);
elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch? elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch?
elp->si_max_procs = htog(process->numCpus()); elp->si_max_procs = htog(process->numCpus());
elp.copyOut(tc->getMemPort()); elp.copyOut(tc->getMemProxy());
return 0; return 0;
} }

View file

@ -38,9 +38,7 @@
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "kern/tru64/tru64_events.hh" #include "kern/tru64/tru64_events.hh"
#include "kern/system_events.hh" #include "kern/system_events.hh"
#include "mem/physical.hh" #include "mem/fs_translating_port_proxy.hh"
#include "mem/port.hh"
#include "mem/vport.hh"
using namespace std; using namespace std;
@ -49,7 +47,7 @@ Tru64AlphaSystem::Tru64AlphaSystem(Tru64AlphaSystem::Params *p)
{ {
Addr addr = 0; Addr addr = 0;
if (kernelSymtab->findAddress("enable_async_printf", addr)) { if (kernelSymtab->findAddress("enable_async_printf", addr)) {
virtPort->write(addr, (uint32_t)0); virtProxy->write(addr, (uint32_t)0);
} }
#ifdef DEBUG #ifdef DEBUG

View file

@ -31,7 +31,7 @@
#include "arch/alpha/utility.hh" #include "arch/alpha/utility.hh"
#include "arch/alpha/vtophys.hh" #include "arch/alpha/vtophys.hh"
#include "mem/vport.hh" #include "mem/fs_translating_port_proxy.hh"
#include "sim/full_system.hh" #include "sim/full_system.hh"
namespace AlphaISA { namespace AlphaISA {
@ -48,7 +48,7 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
return tc->readIntReg(16 + number); return tc->readIntReg(16 + number);
} else { } else {
Addr sp = tc->readIntReg(StackPointerReg); Addr sp = tc->readIntReg(StackPointerReg);
VirtualPort *vp = tc->getVirtPort(); FSTranslatingPortProxy* vp = tc->getVirtProxy();
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));
return arg; return arg;

View file

@ -38,14 +38,14 @@
#include "base/trace.hh" #include "base/trace.hh"
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "debug/VtoPhys.hh" #include "debug/VtoPhys.hh"
#include "mem/vport.hh" #include "mem/port_proxy.hh"
using namespace std; using namespace std;
namespace AlphaISA { namespace AlphaISA {
PageTableEntry PageTableEntry
kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, VAddr vaddr) kernel_pte_lookup(PortProxy* mem, Addr ptbr, VAddr vaddr)
{ {
Addr level1_pte = ptbr + vaddr.level1(); Addr level1_pte = ptbr + vaddr.level1();
PageTableEntry level1 = mem->read<uint64_t>(level1_pte); PageTableEntry level1 = mem->read<uint64_t>(level1_pte);
@ -103,7 +103,7 @@ vtophys(ThreadContext *tc, Addr addr)
paddr = vaddr; paddr = vaddr;
} else { } else {
PageTableEntry pte = PageTableEntry pte =
kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr); kernel_pte_lookup(tc->getPhysProxy(), ptbr, vaddr);
if (pte.valid()) if (pte.valid())
paddr = pte.paddr() | vaddr.offset(); paddr = pte.paddr() | vaddr.offset();
} }

View file

@ -37,11 +37,11 @@
#include "arch/alpha/utility.hh" #include "arch/alpha/utility.hh"
class ThreadContext; class ThreadContext;
class FunctionalPort; class PortProxy;
namespace AlphaISA { namespace AlphaISA {
PageTableEntry kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, PageTableEntry kernel_pte_lookup(PortProxy* mem, Addr ptbr,
VAddr vaddr); VAddr vaddr);
Addr vtophys(Addr vaddr); Addr vtophys(Addr vaddr);

View file

@ -70,7 +70,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
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, "armv7l"); strcpy(name->machine, "armv7l");
name.copyOut(tc->getMemPort()); name.copyOut(tc->getMemProxy());
return 0; return 0;
} }
@ -452,7 +452,7 @@ setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
int index = 0; int index = 0;
uint32_t tlsPtr = process->getSyscallArg(tc, index); uint32_t tlsPtr = process->getSyscallArg(tc, index);
tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0, tc->getMemProxy()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
(uint8_t *)&tlsPtr, sizeof(tlsPtr)); (uint8_t *)&tlsPtr, sizeof(tlsPtr));
tc->setMiscReg(MISCREG_TPIDRURO,tlsPtr); tc->setMiscReg(MISCREG_TPIDRURO,tlsPtr);
return 0; return 0;
@ -512,7 +512,7 @@ ArmLinuxProcess::initState()
// Fill this page with swi -1 so we'll no if we land in it somewhere. // Fill this page with swi -1 so we'll no if we land in it somewhere.
for (Addr addr = 0; addr < PageBytes; addr += sizeof(swiNeg1)) { for (Addr addr = 0; addr < PageBytes; addr += sizeof(swiNeg1)) {
tc->getMemPort()->writeBlob(commPage + addr, tc->getMemProxy()->writeBlob(commPage + addr,
swiNeg1, sizeof(swiNeg1)); swiNeg1, sizeof(swiNeg1));
} }
@ -521,7 +521,7 @@ ArmLinuxProcess::initState()
0x5f, 0xf0, 0x7f, 0xf5, // dmb 0x5f, 0xf0, 0x7f, 0xf5, // dmb
0x0e, 0xf0, 0xa0, 0xe1 // return 0x0e, 0xf0, 0xa0, 0xe1 // return
}; };
tc->getMemPort()->writeBlob(commPage + 0x0fa0, memory_barrier, tc->getMemProxy()->writeBlob(commPage + 0x0fa0, memory_barrier,
sizeof(memory_barrier)); sizeof(memory_barrier));
uint8_t cmpxchg[] = uint8_t cmpxchg[] =
@ -535,7 +535,7 @@ ArmLinuxProcess::initState()
0x5f, 0xf0, 0x7f, 0xf5, // dmb 0x5f, 0xf0, 0x7f, 0xf5, // dmb
0x0e, 0xf0, 0xa0, 0xe1 // return 0x0e, 0xf0, 0xa0, 0xe1 // return
}; };
tc->getMemPort()->writeBlob(commPage + 0x0fc0, cmpxchg, sizeof(cmpxchg)); tc->getMemProxy()->writeBlob(commPage + 0x0fc0, cmpxchg, sizeof(cmpxchg));
uint8_t get_tls[] = uint8_t get_tls[] =
{ {
@ -543,7 +543,7 @@ ArmLinuxProcess::initState()
0x70, 0x0f, 0x1d, 0xee, // mrc p15, 0, r0, c13, c0, 3 0x70, 0x0f, 0x1d, 0xee, // mrc p15, 0, r0, c13, c0, 3
0x0e, 0xf0, 0xa0, 0xe1 // return 0x0e, 0xf0, 0xa0, 0xe1 // return
}; };
tc->getMemPort()->writeBlob(commPage + 0x0fe0, get_tls, sizeof(get_tls)); tc->getMemProxy()->writeBlob(commPage + 0x0fe0, get_tls, sizeof(get_tls));
} }
ArmISA::IntReg ArmISA::IntReg

View file

@ -49,6 +49,7 @@
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "debug/Loader.hh" #include "debug/Loader.hh"
#include "kern/linux/events.hh" #include "kern/linux/events.hh"
#include "mem/fs_translating_port_proxy.hh"
#include "mem/physical.hh" #include "mem/physical.hh"
using namespace ArmISA; using namespace ArmISA;
@ -57,6 +58,27 @@ using namespace Linux;
LinuxArmSystem::LinuxArmSystem(Params *p) LinuxArmSystem::LinuxArmSystem(Params *p)
: ArmSystem(p) : ArmSystem(p)
{ {
}
bool
LinuxArmSystem::adderBootUncacheable(Addr a)
{
Addr block = a & ~ULL(0x7F);
if (block == secDataPtrAddr || block == secDataAddr ||
block == penReleaseAddr)
return true;
return false;
}
void
LinuxArmSystem::initState()
{
// Moved from the constructor to here since it relies on the
// address map being resolved in the interconnect
// Call the initialisation of the super class
ArmSystem::initState();
// Load symbols at physical address, we might not want // Load symbols at physical address, we might not want
// to do this perminately, for but early bootup work // to do this perminately, for but early bootup work
// it is helpfulp. // it is helpfulp.
@ -92,7 +114,7 @@ LinuxArmSystem::LinuxArmSystem(Params *p)
DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2); DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2);
DDUMP(Loader, boot_data, size << 2); DDUMP(Loader, boot_data, size << 2);
functionalPort->writeBlob(ParamsList, boot_data, size << 2); physProxy->writeBlob(ParamsList, boot_data, size << 2);
#ifndef NDEBUG #ifndef NDEBUG
kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic"); kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
@ -128,22 +150,6 @@ LinuxArmSystem::LinuxArmSystem(Params *p)
secDataPtrAddr &= ~ULL(0x7F); secDataPtrAddr &= ~ULL(0x7F);
secDataAddr &= ~ULL(0x7F); secDataAddr &= ~ULL(0x7F);
penReleaseAddr &= ~ULL(0x7F); penReleaseAddr &= ~ULL(0x7F);
}
bool
LinuxArmSystem::adderBootUncacheable(Addr a)
{
Addr block = a & ~ULL(0x7F);
if (block == secDataPtrAddr || block == secDataAddr ||
block == penReleaseAddr)
return true;
return false;
}
void
LinuxArmSystem::initState()
{
ArmSystem::initState();
for (int i = 0; i < threadContexts.size(); i++) { for (int i = 0; i < threadContexts.size(); i++) {
threadContexts[i]->setIntReg(0, 0); threadContexts[i]->setIntReg(0, 0);

View file

@ -50,7 +50,6 @@
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "debug/Stack.hh" #include "debug/Stack.hh"
#include "mem/page_table.hh" #include "mem/page_table.hh"
#include "mem/translating_port.hh"
#include "sim/byteswap.hh" #include "sim/byteswap.hh"
#include "sim/process_impl.hh" #include "sim/process_impl.hh"
#include "sim/system.hh" #include "sim/system.hh"

View file

@ -37,7 +37,7 @@
#include "base/trace.hh" #include "base/trace.hh"
#include "cpu/base.hh" #include "cpu/base.hh"
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "mem/vport.hh" #include "mem/fs_translating_port_proxy.hh"
#include "sim/system.hh" #include "sim/system.hh"
using namespace std; using namespace std;
@ -48,9 +48,9 @@ namespace ArmISA
{ {
Addr addr = 0; Addr addr = 0;
VirtualPort *vp; FSTranslatingPortProxy* vp;
vp = tc->getVirtPort(); vp = tc->getVirtProxy();
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr)) if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
panic("thread info not compiled into kernel\n"); panic("thread info not compiled into kernel\n");

View file

@ -47,6 +47,7 @@
#include "base/loader/symtab.hh" #include "base/loader/symtab.hh"
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "mem/physical.hh" #include "mem/physical.hh"
#include "mem/fs_translating_port_proxy.hh"
using namespace std; using namespace std;
using namespace Linux; using namespace Linux;
@ -55,6 +56,18 @@ ArmSystem::ArmSystem(Params *p)
: System(p), bootldr(NULL) : System(p), bootldr(NULL)
{ {
debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk"); debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
}
void
ArmSystem::initState()
{
// Moved from the constructor to here since it relies on the
// address map being resolved in the interconnect
// Call the initialisation of the super class
System::initState();
const Params* p = params();
if ((p->boot_loader == "") != (p->boot_loader_mem == NULL)) if ((p->boot_loader == "") != (p->boot_loader_mem == NULL))
fatal("If boot_loader is specifed, memory to load it must be also.\n"); fatal("If boot_loader is specifed, memory to load it must be also.\n");
@ -65,29 +78,18 @@ ArmSystem::ArmSystem(Params *p)
if (!bootldr) if (!bootldr)
fatal("Could not read bootloader: %s\n", p->boot_loader); fatal("Could not read bootloader: %s\n", p->boot_loader);
Port *mem_port; bootldr->loadSections(physProxy);
FunctionalPort fp(name() + "-fport");
mem_port = p->boot_loader_mem->getPort("functional");
fp.setPeer(mem_port);
mem_port->setPeer(&fp);
bootldr->loadSections(&fp);
bootldr->loadGlobalSymbols(debugSymbolTable); bootldr->loadGlobalSymbols(debugSymbolTable);
uint8_t jump_to_bl[] = uint8_t jump_to_bl[] =
{ {
0x07, 0xf0, 0xa0, 0xe1 // branch to r7 0x07, 0xf0, 0xa0, 0xe1 // branch to r7
}; };
functionalPort->writeBlob(0x0, jump_to_bl, sizeof(jump_to_bl)); physProxy->writeBlob(0x0, jump_to_bl, sizeof(jump_to_bl));
inform("Using bootloader at address %#x\n", bootldr->entryPoint()); inform("Using bootloader at address %#x\n", bootldr->entryPoint());
} }
}
void
ArmSystem::initState()
{
System::initState();
if (bootldr) { if (bootldr) {
// Put the address of the boot loader into r7 so we know // Put the address of the boot loader into r7 so we know
// where to branch to after the reset fault // where to branch to after the reset fault
@ -98,16 +100,16 @@ ArmSystem::initState()
threadContexts[i]->setIntReg(5, params()->flags_addr); threadContexts[i]->setIntReg(5, params()->flags_addr);
threadContexts[i]->setIntReg(7, bootldr->entryPoint()); threadContexts[i]->setIntReg(7, bootldr->entryPoint());
} }
if (!params()->gic_cpu_addr || !params()->flags_addr) if (!p->gic_cpu_addr || !p->flags_addr)
fatal("gic_cpu_addr && flags_addr must be set with bootloader\n"); fatal("gic_cpu_addr && flags_addr must be set with bootloader\n");
} else { } else {
// Set the initial PC to be at start of the kernel code // Set the initial PC to be at start of the kernel code
threadContexts[0]->pcState(kernelEntry & loadAddrMask); threadContexts[0]->pcState(kernelEntry & loadAddrMask);
} }
for (int i = 0; i < threadContexts.size(); i++) { for (int i = 0; i < threadContexts.size(); i++) {
if (params()->midr_regval) { if (p->midr_regval) {
threadContexts[i]->setMiscReg(ArmISA::MISCREG_MIDR, threadContexts[i]->setMiscReg(ArmISA::MISCREG_MIDR,
params()->midr_regval); p->midr_regval);
} }
} }

View file

@ -76,7 +76,10 @@ class ArmSystem : public System
ArmSystem(Params *p); ArmSystem(Params *p);
~ArmSystem(); ~ArmSystem();
void initState(); /**
* Initialise the system
*/
virtual void initState();
/** Check if an address should be uncacheable until all caches are enabled. /** Check if an address should be uncacheable until all caches are enabled.
* This exits because coherence on some addresses at boot is maintained via * This exits because coherence on some addresses at boot is maintained via

View file

@ -44,7 +44,7 @@
#include "arch/arm/utility.hh" #include "arch/arm/utility.hh"
#include "arch/arm/vtophys.hh" #include "arch/arm/vtophys.hh"
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "mem/vport.hh" #include "mem/fs_translating_port_proxy.hh"
#include "sim/full_system.hh" #include "sim/full_system.hh"
namespace ArmISA { namespace ArmISA {
@ -86,7 +86,7 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
} }
} else { } else {
Addr sp = tc->readIntReg(StackPointerReg); Addr sp = tc->readIntReg(StackPointerReg);
VirtualPort *vp = tc->getVirtPort(); FSTranslatingPortProxy* vp = tc->getVirtProxy();
uint64_t arg; uint64_t arg;
if (size == sizeof(uint64_t)) { if (size == sizeof(uint64_t)) {
// If the argument is even it must be aligned // If the argument is even it must be aligned

View file

@ -51,7 +51,7 @@
#include "base/chunk_generator.hh" #include "base/chunk_generator.hh"
#include "base/trace.hh" #include "base/trace.hh"
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "mem/vport.hh" #include "mem/fs_translating_port_proxy.hh"
using namespace std; using namespace std;
using namespace ArmISA; using namespace ArmISA;
@ -101,7 +101,7 @@ ArmISA::vtophys(ThreadContext *tc, Addr addr)
N = 0; N = 0;
} }
FunctionalPort *port = tc->getPhysPort(); PortProxy* port = tc->getPhysProxy();
Addr l1desc_addr = mbits(ttbr, 31, 14-N) | (bits(addr,31-N,20) << 2); Addr l1desc_addr = mbits(ttbr, 31, 14-N) | (bits(addr,31-N,20) << 2);
TableWalker::L1Descriptor l1desc; TableWalker::L1Descriptor l1desc;

View file

@ -59,7 +59,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
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, "mips"); strcpy(name->machine, "mips");
name.copyOut(tc->getMemPort()); name.copyOut(tc->getMemProxy());
return 0; return 0;
} }
@ -82,7 +82,7 @@ sys_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
TypedBufferArg<uint64_t> fpcr(bufPtr); TypedBufferArg<uint64_t> fpcr(bufPtr);
// 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->getMemProxy());
return 0; return 0;
} }
default: default:
@ -111,7 +111,7 @@ sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
// SSI_IEEE_FP_CONTROL // SSI_IEEE_FP_CONTROL
TypedBufferArg<uint64_t> fpcr(bufPtr); TypedBufferArg<uint64_t> fpcr(bufPtr);
// 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->getMemProxy());
DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): " DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): "
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr)); " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
return 0; return 0;

View file

@ -63,91 +63,10 @@ using namespace Linux;
LinuxMipsSystem::LinuxMipsSystem(Params *p) LinuxMipsSystem::LinuxMipsSystem(Params *p)
: MipsSystem(p) : MipsSystem(p)
{ {
Addr addr = 0;
/**
* The symbol swapper_pg_dir marks the beginning of the kernel and
* the location of bootloader passed arguments
*/
if (!kernelSymtab->findAddress("swapper_pg_dir", KernelStart)) {
panic("Could not determine start location of kernel");
}
/**
* Since we aren't using a bootloader, we have to copy the
* kernel arguments directly into the kernel's memory.
*/
virtPort->writeBlob(CommandLine(), (uint8_t*)params()->boot_osflags.c_str(),
params()->boot_osflags.length()+1);
/**
* find the address of the est_cycle_freq variable and insert it
* so we don't through the lengthly process of trying to
* calculated it by using the PIT, RTC, etc.
*/
if (kernelSymtab->findAddress("est_cycle_freq", addr))
virtPort->write(addr, (uint64_t)(SimClock::Frequency /
p->boot_cpu_frequency));
/**
* EV5 only supports 127 ASNs so we are going to tell the kernel that the
* paritiuclar EV6 we have only supports 127 asns.
* @todo At some point we should change ev5.hh and the palcode to support
* 255 ASNs.
*/
if (kernelSymtab->findAddress("dp264_mv", addr))
virtPort->write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127));
else
panic("could not find dp264_mv\n");
#ifndef NDEBUG
kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
if (!kernelPanicEvent)
panic("could not find kernel symbol \'panic\'");
#endif
/**
* Any time ide_delay_50ms, calibarte_delay or
* determine_cpu_caches is called just skip the
* function. Currently determine_cpu_caches only is used put
* information in proc, however if that changes in the future we
* will have to fill in the cache size variables appropriately.
*/
skipIdeDelay50msEvent =
addKernelFuncEvent<SkipFuncEvent>("ide_delay_50ms");
skipDelayLoopEvent =
addKernelFuncEvent<SkipDelayLoopEvent>("calibrate_delay");
skipCacheProbeEvent =
addKernelFuncEvent<SkipFuncEvent>("determine_cpu_caches");
debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
idleStartEvent = addKernelFuncEvent<IdleStartEvent>("cpu_idle");
// Disable for now as it runs into panic() calls in VPTr methods
// (see sim/vptr.hh). Once those bugs are fixed, we can
// re-enable, but we should find a better way to turn it on than
// using DTRACE(Thread), since looking at a trace flag at tick 0
// leads to non-intuitive behavior with --trace-start.
if (false && kernelSymtab->findAddress("mips_switch_to", addr)) {
printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo",
addr + sizeof(MachInst) * 6);
} else {
printThreadEvent = NULL;
}
} }
LinuxMipsSystem::~LinuxMipsSystem() LinuxMipsSystem::~LinuxMipsSystem()
{ {
#ifndef NDEBUG
delete kernelPanicEvent;
#endif
delete skipIdeDelay50msEvent;
delete skipDelayLoopEvent;
delete skipCacheProbeEvent;
delete debugPrintkEvent;
delete idleStartEvent;
delete printThreadEvent;
} }

View file

@ -79,7 +79,7 @@ class ThreadInfo
if (!addr) if (!addr)
addr = tc->readMiscRegNoEffect(0/*MipsISA::IPR_PALtemp23*/); addr = tc->readMiscRegNoEffect(0/*MipsISA::IPR_PALtemp23*/);
FunctionalPort *p = tc->getPhysPort(); PortProxy* p = tc->getPhysProxy();
p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr)); p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
return sp & ~ULL(0x3fff); return sp & ~ULL(0x3fff);

View file

@ -37,7 +37,7 @@
#include "base/trace.hh" #include "base/trace.hh"
#include "cpu/base.hh" #include "cpu/base.hh"
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "mem/vport.hh" #include "mem/fs_translating_port_proxy.hh"
#include "sim/system.hh" #include "sim/system.hh"
using namespace std; using namespace std;
@ -55,9 +55,9 @@ ProcessInfo::task(Addr ksp) const
Addr tsk; Addr tsk;
VirtualPort *vp; FSTranslatingPortProxy* vp;
vp = tc->getVirtPort(); vp = tc->getVirtProxy();
tsk = vp->readGtoH<Addr>(base + task_off); tsk = vp->readGtoH<Addr>(base + task_off);
return tsk; return tsk;
@ -72,9 +72,9 @@ ProcessInfo::pid(Addr ksp) const
uint16_t pd; uint16_t pd;
VirtualPort *vp; FSTranslatingPortProxy* vp;
vp = tc->getVirtPort(); vp = tc->getVirtProxy();
pd = vp->readGtoH<uint16_t>(task + pid_off); pd = vp->readGtoH<uint16_t>(task + pid_off);
return pd; return pd;

View file

@ -38,7 +38,6 @@
#include "base/loader/symtab.hh" #include "base/loader/symtab.hh"
#include "base/trace.hh" #include "base/trace.hh"
#include "mem/physical.hh" #include "mem/physical.hh"
#include "mem/vport.hh"
#include "params/MipsSystem.hh" #include "params/MipsSystem.hh"
#include "sim/byteswap.hh" #include "sim/byteswap.hh"
@ -46,67 +45,6 @@ using namespace LittleEndianGuest;
MipsSystem::MipsSystem(Params *p) : System(p) MipsSystem::MipsSystem(Params *p) : System(p)
{ {
if (p->bare_iron == true) {
hexFile = new HexFile(params()->hex_file_name);
if (!hexFile->loadSections(functionalPort))
panic("Could not load hex file\n");
}
Addr addr = 0;
consoleSymtab = new SymbolTable;
/**
* Load the console code into memory
*/
// Load Console Code
console = createObjectFile(params()->console);
warn("console code is located at: %s\n", params()->console);
if (console == NULL)
fatal("Could not load console file %s", params()->console);
//Load program sections into memory
console->loadSections(functionalPort, loadAddrMask);
//load symbols
if (!console->loadGlobalSymbols(consoleSymtab))
panic("could not load console symbols\n");
if (!console->loadGlobalSymbols(debugSymbolTable))
panic("could not load console symbols\n");
#ifndef NDEBUG
consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic");
#endif
/**
* Copy the osflags (kernel arguments) into the consoles
* memory. (Presently Linux does not use the console service
* routine to get these command line arguments, but Tru64 and
* others do.)
*/
if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
warn("writing addr starting from %#x", addr);
virtPort->writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
strlen(params()->boot_osflags.c_str()));
}
/**
* Set the hardware reset parameter block system type and revision
* information to Tsunami.
*/
if (consoleSymtab->findAddress("m5_rpb", addr)) {
uint64_t data;
data = htog(params()->system_type);
virtPort->write(addr + 0x50, data);
data = htog(params()->system_rev);
virtPort->write(addr + 0x58, data);
} else {
panic("could not find hwrpb\n");
}
} }
MipsSystem::~MipsSystem() MipsSystem::~MipsSystem()

View file

@ -31,17 +31,16 @@
#include <cmath> #include <cmath>
#include "arch/mips/isa_traits.hh" #include "arch/mips/isa_traits.hh"
#include "arch/mips/registers.hh"
#include "arch/mips/utility.hh" #include "arch/mips/utility.hh"
#include "arch/mips/vtophys.hh"
#include "base/bitfield.hh" #include "base/bitfield.hh"
#include "base/misc.hh" #include "base/misc.hh"
#include "cpu/static_inst.hh" #include "cpu/static_inst.hh"
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "mem/fs_translating_port_proxy.hh"
#include "sim/serialize.hh" #include "sim/serialize.hh"
#include "arch/mips/registers.hh"
#include "arch/mips/vtophys.hh"
#include "mem/vport.hh"
using namespace MipsISA; using namespace MipsISA;
using namespace std; using namespace std;

View file

@ -38,7 +38,6 @@
#include "base/trace.hh" #include "base/trace.hh"
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "debug/VtoPhys.hh" #include "debug/VtoPhys.hh"
#include "mem/vport.hh"
using namespace std; using namespace std;
using namespace MipsISA; using namespace MipsISA;

View file

@ -59,7 +59,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
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, "power"); strcpy(name->machine, "power");
name.copyOut(tc->getMemPort()); name.copyOut(tc->getMemProxy());
return 0; return 0;
} }

View file

@ -39,7 +39,6 @@
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "debug/Stack.hh" #include "debug/Stack.hh"
#include "mem/page_table.hh" #include "mem/page_table.hh"
#include "mem/translating_port.hh"
#include "sim/process_impl.hh" #include "sim/process_impl.hh"
#include "sim/system.hh" #include "sim/system.hh"

View file

@ -50,7 +50,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
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, "sparc"); strcpy(name->machine, "sparc");
name.copyOut(tc->getMemPort()); name.copyOut(tc->getMemProxy());
return 0; return 0;
} }
@ -69,19 +69,19 @@ getresuidFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
if (ruid) { if (ruid) {
BufferArg ruidBuff(ruid, sizeof(IntReg)); BufferArg ruidBuff(ruid, sizeof(IntReg));
memcpy(ruidBuff.bufferPtr(), &id, sizeof(IntReg)); memcpy(ruidBuff.bufferPtr(), &id, sizeof(IntReg));
ruidBuff.copyOut(tc->getMemPort()); ruidBuff.copyOut(tc->getMemProxy());
} }
// Set the euid // Set the euid
if (euid) { if (euid) {
BufferArg euidBuff(euid, sizeof(IntReg)); BufferArg euidBuff(euid, sizeof(IntReg));
memcpy(euidBuff.bufferPtr(), &id, sizeof(IntReg)); memcpy(euidBuff.bufferPtr(), &id, sizeof(IntReg));
euidBuff.copyOut(tc->getMemPort()); euidBuff.copyOut(tc->getMemProxy());
} }
// Set the suid // Set the suid
if (suid) { if (suid) {
BufferArg suidBuff(suid, sizeof(IntReg)); BufferArg suidBuff(suid, sizeof(IntReg));
memcpy(suidBuff.bufferPtr(), &id, sizeof(IntReg)); memcpy(suidBuff.bufferPtr(), &id, sizeof(IntReg));
suidBuff.copyOut(tc->getMemPort()); suidBuff.copyOut(tc->getMemProxy());
} }
return 0; return 0;
} }

View file

@ -41,7 +41,6 @@
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "debug/Stack.hh" #include "debug/Stack.hh"
#include "mem/page_table.hh" #include "mem/page_table.hh"
#include "mem/translating_port.hh"
#include "sim/process_impl.hh" #include "sim/process_impl.hh"
#include "sim/system.hh" #include "sim/system.hh"
@ -448,7 +447,7 @@ void Sparc32LiveProcess::flushWindows(ThreadContext *tc)
for (int index = 16; index < 32; index++) { for (int index = 16; index < 32; index++) {
uint32_t regVal = tc->readIntReg(index); uint32_t regVal = tc->readIntReg(index);
regVal = htog(regVal); regVal = htog(regVal);
if (!tc->getMemPort()->tryWriteBlob( if (!tc->getMemProxy()->tryWriteBlob(
sp + (index - 16) * 4, (uint8_t *)&regVal, 4)) { sp + (index - 16) * 4, (uint8_t *)&regVal, 4)) {
warn("Failed to save register to the stack when " warn("Failed to save register to the stack when "
"flushing windows.\n"); "flushing windows.\n");
@ -483,7 +482,7 @@ Sparc64LiveProcess::flushWindows(ThreadContext *tc)
for (int index = 16; index < 32; index++) { for (int index = 16; index < 32; index++) {
IntReg regVal = tc->readIntReg(index); IntReg regVal = tc->readIntReg(index);
regVal = htog(regVal); regVal = htog(regVal);
if (!tc->getMemPort()->tryWriteBlob( if (!tc->getMemProxy()->tryWriteBlob(
sp + 2047 + (index - 16) * 8, (uint8_t *)&regVal, 8)) { sp + 2047 + (index - 16) * 8, (uint8_t *)&regVal, 8)) {
warn("Failed to save register to the stack when " warn("Failed to save register to the stack when "
"flushing windows.\n"); "flushing windows.\n");

View file

@ -55,7 +55,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
strcpy(name->version, "Generic_118558-21"); strcpy(name->version, "Generic_118558-21");
strcpy(name->machine, "sun4u"); strcpy(name->machine, "sun4u");
name.copyOut(tc->getMemPort()); name.copyOut(tc->getMemProxy());
return 0; return 0;
} }

View file

@ -40,10 +40,7 @@
using namespace BigEndianGuest; using namespace BigEndianGuest;
SparcSystem::SparcSystem(Params *p) SparcSystem::SparcSystem(Params *p)
: System(p), sysTick(0),funcRomPort(p->name + "-fromport"), : System(p), sysTick(0)
funcNvramPort(p->name + "-fnvramport"),
funcHypDescPort(p->name + "-fhypdescport"),
funcPartDescPort(p->name + "-fpartdescport")
{ {
resetSymtab = new SymbolTable; resetSymtab = new SymbolTable;
hypervisorSymtab = new SymbolTable; hypervisorSymtab = new SymbolTable;
@ -51,23 +48,13 @@ SparcSystem::SparcSystem(Params *p)
nvramSymtab = new SymbolTable; nvramSymtab = new SymbolTable;
hypervisorDescSymtab = new SymbolTable; hypervisorDescSymtab = new SymbolTable;
partitionDescSymtab = new SymbolTable; partitionDescSymtab = new SymbolTable;
}
Port *rom_port; void
rom_port = params()->rom->getPort("functional"); SparcSystem::initState()
funcRomPort.setPeer(rom_port); {
rom_port->setPeer(&funcRomPort); // Call the initialisation of the super class
System::initState();
rom_port = params()->nvram->getPort("functional");
funcNvramPort.setPeer(rom_port);
rom_port->setPeer(&funcNvramPort);
rom_port = params()->hypervisor_desc->getPort("functional");
funcHypDescPort.setPeer(rom_port);
rom_port->setPeer(&funcHypDescPort);
rom_port = params()->partition_desc->getPort("functional");
funcPartDescPort.setPeer(rom_port);
rom_port->setPeer(&funcPartDescPort);
/** /**
* Load the boot code, and hypervisor into memory. * Load the boot code, and hypervisor into memory.
@ -107,22 +94,22 @@ SparcSystem::SparcSystem(Params *p)
// Load reset binary into memory // Load reset binary into memory
reset->setTextBase(params()->reset_addr); reset->setTextBase(params()->reset_addr);
reset->loadSections(&funcRomPort); reset->loadSections(physProxy);
// Load the openboot binary // Load the openboot binary
openboot->setTextBase(params()->openboot_addr); openboot->setTextBase(params()->openboot_addr);
openboot->loadSections(&funcRomPort); openboot->loadSections(physProxy);
// Load the hypervisor binary // Load the hypervisor binary
hypervisor->setTextBase(params()->hypervisor_addr); hypervisor->setTextBase(params()->hypervisor_addr);
hypervisor->loadSections(&funcRomPort); hypervisor->loadSections(physProxy);
// Load the nvram image // Load the nvram image
nvram->setTextBase(params()->nvram_addr); nvram->setTextBase(params()->nvram_addr);
nvram->loadSections(&funcNvramPort); nvram->loadSections(physProxy);
// Load the hypervisor description image // Load the hypervisor description image
hypervisor_desc->setTextBase(params()->hypervisor_desc_addr); hypervisor_desc->setTextBase(params()->hypervisor_desc_addr);
hypervisor_desc->loadSections(&funcHypDescPort); hypervisor_desc->loadSections(physProxy);
// Load the partition description image // Load the partition description image
partition_desc->setTextBase(params()->partition_desc_addr); partition_desc->setTextBase(params()->partition_desc_addr);
partition_desc->loadSections(&funcPartDescPort); partition_desc->loadSections(physProxy);
// load symbols // load symbols
if (!reset->loadGlobalSymbols(resetSymtab)) if (!reset->loadGlobalSymbols(resetSymtab))

View file

@ -48,6 +48,8 @@ class SparcSystem : public System
SparcSystem(Params *p); SparcSystem(Params *p);
~SparcSystem(); ~SparcSystem();
virtual void initState();
/** /**
* Serialization stuff * Serialization stuff
*/ */
@ -94,18 +96,6 @@ class SparcSystem : public System
/** System Tick for syncronized tick across all cpus. */ /** System Tick for syncronized tick across all cpus. */
Tick sysTick; Tick sysTick;
/** functional port to ROM */
FunctionalPort funcRomPort;
/** functional port to nvram */
FunctionalPort funcNvramPort;
/** functional port to hypervisor description */
FunctionalPort funcHypDescPort;
/** functional port to partition description */
FunctionalPort funcPartDescPort;
protected: protected:
const Params *params() const { return (const Params *)_params; } const Params *params() const { return (const Params *)_params; }

View file

@ -32,7 +32,7 @@
#include "arch/sparc/faults.hh" #include "arch/sparc/faults.hh"
#include "arch/sparc/utility.hh" #include "arch/sparc/utility.hh"
#include "arch/sparc/vtophys.hh" #include "arch/sparc/vtophys.hh"
#include "mem/vport.hh" #include "mem/fs_translating_port_proxy.hh"
namespace SparcISA { namespace SparcISA {
@ -52,7 +52,7 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
return tc->readIntReg(8 + number); return tc->readIntReg(8 + number);
} else { } else {
Addr sp = tc->readIntReg(StackPointerReg); Addr sp = tc->readIntReg(StackPointerReg);
VirtualPort *vp = tc->getVirtPort(); FSTranslatingPortProxy* vp = tc->getVirtProxy();
uint64_t arg = vp->read<uint64_t>(sp + 92 + uint64_t arg = vp->read<uint64_t>(sp + 92 +
(number-NumArgumentRegs) * sizeof(uint64_t)); (number-NumArgumentRegs) * sizeof(uint64_t));
return arg; return arg;

View file

@ -37,7 +37,7 @@
#include "base/trace.hh" #include "base/trace.hh"
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "debug/VtoPhys.hh" #include "debug/VtoPhys.hh"
#include "mem/vport.hh" #include "mem/port_proxy.hh"
using namespace std; using namespace std;
@ -81,7 +81,7 @@ vtophys(ThreadContext *tc, Addr addr)
int pri_context = bits(tlbdata,47,32); int pri_context = bits(tlbdata,47,32);
// int sec_context = bits(tlbdata,63,48); // int sec_context = bits(tlbdata,63,48);
FunctionalPort *mem = tc->getPhysPort(); PortProxy* mem = tc->getPhysProxy();
TLB* itb = tc->getITBPtr(); TLB* itb = tc->getITBPtr();
TLB* dtb = tc->getDTBPtr(); TLB* dtb = tc->getDTBPtr();
TlbEntry* tbe; TlbEntry* tbe;

View file

@ -41,7 +41,7 @@
#include "arch/x86/isa_traits.hh" #include "arch/x86/isa_traits.hh"
#include "base/misc.hh" #include "base/misc.hh"
#include "base/types.hh" #include "base/types.hh"
#include "mem/port.hh" #include "mem/port_proxy.hh"
#include "sim/byteswap.hh" #include "sim/byteswap.hh"
// Config entry types // Config entry types
@ -70,10 +70,10 @@ const char X86ISA::IntelMP::FloatingPointer::signature[] = "_MP_";
template<class T> template<class T>
uint8_t uint8_t
writeOutField(FunctionalPort * port, Addr addr, T val) writeOutField(PortProxy* proxy, Addr addr, T val)
{ {
T guestVal = X86ISA::htog(val); T guestVal = X86ISA::htog(val);
port->writeBlob(addr, (uint8_t *)(&guestVal), sizeof(T)); proxy->writeBlob(addr, (uint8_t *)(&guestVal), sizeof(T));
uint8_t checkSum = 0; uint8_t checkSum = 0;
while(guestVal) { while(guestVal) {
@ -84,7 +84,7 @@ writeOutField(FunctionalPort * port, Addr addr, T val)
} }
uint8_t uint8_t
writeOutString(FunctionalPort * port, Addr addr, string str, int length) writeOutString(PortProxy* proxy, Addr addr, string str, int length)
{ {
char cleanedString[length + 1]; char cleanedString[length + 1];
cleanedString[length] = 0; cleanedString[length] = 0;
@ -97,7 +97,7 @@ writeOutString(FunctionalPort * port, Addr addr, string str, int length)
memcpy(cleanedString, str.c_str(), str.length()); memcpy(cleanedString, str.c_str(), str.length());
memset(cleanedString + str.length(), 0, length - str.length()); memset(cleanedString + str.length(), 0, length - str.length());
} }
port->writeBlob(addr, (uint8_t *)(&cleanedString), length); proxy->writeBlob(addr, (uint8_t *)(&cleanedString), length);
uint8_t checkSum = 0; uint8_t checkSum = 0;
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)
@ -107,7 +107,7 @@ writeOutString(FunctionalPort * port, Addr addr, string str, int length)
} }
Addr Addr
X86ISA::IntelMP::FloatingPointer::writeOut(FunctionalPort * port, Addr addr) X86ISA::IntelMP::FloatingPointer::writeOut(PortProxy* proxy, Addr addr)
{ {
// Make sure that either a config table is present or a default // Make sure that either a config table is present or a default
// configuration was found but not both. // configuration was found but not both.
@ -120,28 +120,28 @@ X86ISA::IntelMP::FloatingPointer::writeOut(FunctionalPort * port, Addr addr)
uint8_t checkSum = 0; uint8_t checkSum = 0;
port->writeBlob(addr, (uint8_t *)signature, 4); proxy->writeBlob(addr, (uint8_t *)signature, 4);
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
checkSum += signature[i]; checkSum += signature[i];
checkSum += writeOutField(port, addr + 4, tableAddr); checkSum += writeOutField(proxy, addr + 4, tableAddr);
// The length of the structure in paragraphs, aka 16 byte chunks. // The length of the structure in paragraphs, aka 16 byte chunks.
uint8_t length = 1; uint8_t length = 1;
port->writeBlob(addr + 8, &length, 1); proxy->writeBlob(addr + 8, &length, 1);
checkSum += length; checkSum += length;
port->writeBlob(addr + 9, &specRev, 1); proxy->writeBlob(addr + 9, &specRev, 1);
checkSum += specRev; checkSum += specRev;
port->writeBlob(addr + 11, &defaultConfig, 1); proxy->writeBlob(addr + 11, &defaultConfig, 1);
checkSum += defaultConfig; checkSum += defaultConfig;
uint32_t features2_5 = imcrPresent ? (1 << 7) : 0; uint32_t features2_5 = imcrPresent ? (1 << 7) : 0;
checkSum += writeOutField(port, addr + 12, features2_5); checkSum += writeOutField(proxy, addr + 12, features2_5);
checkSum = -checkSum; checkSum = -checkSum;
port->writeBlob(addr + 10, &checkSum, 1); proxy->writeBlob(addr + 10, &checkSum, 1);
return 16; return 16;
} }
@ -158,10 +158,10 @@ X86IntelMPFloatingPointerParams::create()
} }
Addr Addr
X86ISA::IntelMP::BaseConfigEntry::writeOut(FunctionalPort * port, X86ISA::IntelMP::BaseConfigEntry::writeOut(PortProxy* proxy,
Addr addr, uint8_t &checkSum) Addr addr, uint8_t &checkSum)
{ {
port->writeBlob(addr, &type, 1); proxy->writeBlob(addr, &type, 1);
checkSum += type; checkSum += type;
return 1; return 1;
} }
@ -171,12 +171,12 @@ X86ISA::IntelMP::BaseConfigEntry::BaseConfigEntry(Params * p, uint8_t _type) :
{} {}
Addr Addr
X86ISA::IntelMP::ExtConfigEntry::writeOut(FunctionalPort * port, X86ISA::IntelMP::ExtConfigEntry::writeOut(PortProxy* proxy,
Addr addr, uint8_t &checkSum) Addr addr, uint8_t &checkSum)
{ {
port->writeBlob(addr, &type, 1); proxy->writeBlob(addr, &type, 1);
checkSum += type; checkSum += type;
port->writeBlob(addr + 1, &length, 1); proxy->writeBlob(addr + 1, &length, 1);
checkSum += length; checkSum += length;
return 1; return 1;
} }
@ -189,59 +189,59 @@ X86ISA::IntelMP::ExtConfigEntry::ExtConfigEntry(Params * p,
const char X86ISA::IntelMP::ConfigTable::signature[] = "PCMP"; const char X86ISA::IntelMP::ConfigTable::signature[] = "PCMP";
Addr Addr
X86ISA::IntelMP::ConfigTable::writeOut(FunctionalPort * port, Addr addr) X86ISA::IntelMP::ConfigTable::writeOut(PortProxy* proxy, Addr addr)
{ {
uint8_t checkSum = 0; uint8_t checkSum = 0;
port->writeBlob(addr, (uint8_t *)signature, 4); proxy->writeBlob(addr, (uint8_t *)signature, 4);
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
checkSum += signature[i]; checkSum += signature[i];
// Base table length goes here but will be calculated later. // Base table length goes here but will be calculated later.
port->writeBlob(addr + 6, (uint8_t *)(&specRev), 1); proxy->writeBlob(addr + 6, (uint8_t *)(&specRev), 1);
checkSum += specRev; checkSum += specRev;
// The checksum goes here but is still being calculated. // The checksum goes here but is still being calculated.
checkSum += writeOutString(port, addr + 8, oemID, 8); checkSum += writeOutString(proxy, addr + 8, oemID, 8);
checkSum += writeOutString(port, addr + 16, productID, 12); checkSum += writeOutString(proxy, addr + 16, productID, 12);
checkSum += writeOutField(port, addr + 28, oemTableAddr); checkSum += writeOutField(proxy, addr + 28, oemTableAddr);
checkSum += writeOutField(port, addr + 32, oemTableSize); checkSum += writeOutField(proxy, addr + 32, oemTableSize);
checkSum += writeOutField(port, addr + 34, (uint16_t)baseEntries.size()); checkSum += writeOutField(proxy, addr + 34, (uint16_t)baseEntries.size());
checkSum += writeOutField(port, addr + 36, localApic); checkSum += writeOutField(proxy, addr + 36, localApic);
uint8_t reserved = 0; uint8_t reserved = 0;
port->writeBlob(addr + 43, &reserved, 1); proxy->writeBlob(addr + 43, &reserved, 1);
checkSum += reserved; checkSum += reserved;
vector<BaseConfigEntry *>::iterator baseEnt; vector<BaseConfigEntry *>::iterator baseEnt;
uint16_t offset = 44; uint16_t offset = 44;
for (baseEnt = baseEntries.begin(); for (baseEnt = baseEntries.begin();
baseEnt != baseEntries.end(); baseEnt++) { baseEnt != baseEntries.end(); baseEnt++) {
offset += (*baseEnt)->writeOut(port, addr + offset, checkSum); offset += (*baseEnt)->writeOut(proxy, addr + offset, checkSum);
} }
// We've found the end of the base table this point. // We've found the end of the base table this point.
checkSum += writeOutField(port, addr + 4, offset); checkSum += writeOutField(proxy, addr + 4, offset);
vector<ExtConfigEntry *>::iterator extEnt; vector<ExtConfigEntry *>::iterator extEnt;
uint16_t extOffset = 0; uint16_t extOffset = 0;
uint8_t extCheckSum = 0; uint8_t extCheckSum = 0;
for (extEnt = extEntries.begin(); for (extEnt = extEntries.begin();
extEnt != extEntries.end(); extEnt++) { extEnt != extEntries.end(); extEnt++) {
extOffset += (*extEnt)->writeOut(port, extOffset += (*extEnt)->writeOut(proxy,
addr + offset + extOffset, extCheckSum); addr + offset + extOffset, extCheckSum);
} }
checkSum += writeOutField(port, addr + 40, extOffset); checkSum += writeOutField(proxy, addr + 40, extOffset);
extCheckSum = -extCheckSum; extCheckSum = -extCheckSum;
checkSum += writeOutField(port, addr + 42, extCheckSum); checkSum += writeOutField(proxy, addr + 42, extCheckSum);
// And now, we finally have the whole check sum completed. // And now, we finally have the whole check sum completed.
checkSum = -checkSum; checkSum = -checkSum;
writeOutField(port, addr + 7, checkSum); writeOutField(proxy, addr + 7, checkSum);
return offset + extOffset; return offset + extOffset;
}; };
@ -261,18 +261,18 @@ X86IntelMPConfigTableParams::create()
Addr Addr
X86ISA::IntelMP::Processor::writeOut( X86ISA::IntelMP::Processor::writeOut(
FunctionalPort * port, Addr addr, uint8_t &checkSum) PortProxy* proxy, Addr addr, uint8_t &checkSum)
{ {
BaseConfigEntry::writeOut(port, addr, checkSum); BaseConfigEntry::writeOut(proxy, addr, checkSum);
checkSum += writeOutField(port, addr + 1, localApicID); checkSum += writeOutField(proxy, addr + 1, localApicID);
checkSum += writeOutField(port, addr + 2, localApicVersion); checkSum += writeOutField(proxy, addr + 2, localApicVersion);
checkSum += writeOutField(port, addr + 3, cpuFlags); checkSum += writeOutField(proxy, addr + 3, cpuFlags);
checkSum += writeOutField(port, addr + 4, cpuSignature); checkSum += writeOutField(proxy, addr + 4, cpuSignature);
checkSum += writeOutField(port, addr + 8, featureFlags); checkSum += writeOutField(proxy, addr + 8, featureFlags);
uint32_t reserved = 0; uint32_t reserved = 0;
port->writeBlob(addr + 12, (uint8_t *)(&reserved), 4); proxy->writeBlob(addr + 12, (uint8_t *)(&reserved), 4);
port->writeBlob(addr + 16, (uint8_t *)(&reserved), 4); proxy->writeBlob(addr + 16, (uint8_t *)(&reserved), 4);
return 20; return 20;
} }
@ -298,11 +298,11 @@ X86IntelMPProcessorParams::create()
Addr Addr
X86ISA::IntelMP::Bus::writeOut( X86ISA::IntelMP::Bus::writeOut(
FunctionalPort * port, Addr addr, uint8_t &checkSum) PortProxy* proxy, Addr addr, uint8_t &checkSum)
{ {
BaseConfigEntry::writeOut(port, addr, checkSum); BaseConfigEntry::writeOut(proxy, addr, checkSum);
checkSum += writeOutField(port, addr + 1, busID); checkSum += writeOutField(proxy, addr + 1, busID);
checkSum += writeOutString(port, addr + 2, busType, 6); checkSum += writeOutString(proxy, addr + 2, busType, 6);
return 8; return 8;
} }
@ -318,13 +318,13 @@ X86IntelMPBusParams::create()
Addr Addr
X86ISA::IntelMP::IOAPIC::writeOut( X86ISA::IntelMP::IOAPIC::writeOut(
FunctionalPort * port, Addr addr, uint8_t &checkSum) PortProxy* proxy, Addr addr, uint8_t &checkSum)
{ {
BaseConfigEntry::writeOut(port, addr, checkSum); BaseConfigEntry::writeOut(proxy, addr, checkSum);
checkSum += writeOutField(port, addr + 1, id); checkSum += writeOutField(proxy, addr + 1, id);
checkSum += writeOutField(port, addr + 2, version); checkSum += writeOutField(proxy, addr + 2, version);
checkSum += writeOutField(port, addr + 3, flags); checkSum += writeOutField(proxy, addr + 3, flags);
checkSum += writeOutField(port, addr + 4, address); checkSum += writeOutField(proxy, addr + 4, address);
return 8; return 8;
} }
@ -343,15 +343,15 @@ X86IntelMPIOAPICParams::create()
Addr Addr
X86ISA::IntelMP::IntAssignment::writeOut( X86ISA::IntelMP::IntAssignment::writeOut(
FunctionalPort * port, Addr addr, uint8_t &checkSum) PortProxy* proxy, Addr addr, uint8_t &checkSum)
{ {
BaseConfigEntry::writeOut(port, addr, checkSum); BaseConfigEntry::writeOut(proxy, addr, checkSum);
checkSum += writeOutField(port, addr + 1, interruptType); checkSum += writeOutField(proxy, addr + 1, interruptType);
checkSum += writeOutField(port, addr + 2, flags); checkSum += writeOutField(proxy, addr + 2, flags);
checkSum += writeOutField(port, addr + 4, sourceBusID); checkSum += writeOutField(proxy, addr + 4, sourceBusID);
checkSum += writeOutField(port, addr + 5, sourceBusIRQ); checkSum += writeOutField(proxy, addr + 5, sourceBusIRQ);
checkSum += writeOutField(port, addr + 6, destApicID); checkSum += writeOutField(proxy, addr + 6, destApicID);
checkSum += writeOutField(port, addr + 7, destApicIntIn); checkSum += writeOutField(proxy, addr + 7, destApicIntIn);
return 8; return 8;
} }
@ -381,13 +381,13 @@ X86IntelMPLocalIntAssignmentParams::create()
Addr Addr
X86ISA::IntelMP::AddrSpaceMapping::writeOut( X86ISA::IntelMP::AddrSpaceMapping::writeOut(
FunctionalPort * port, Addr addr, uint8_t &checkSum) PortProxy* proxy, Addr addr, uint8_t &checkSum)
{ {
ExtConfigEntry::writeOut(port, addr, checkSum); ExtConfigEntry::writeOut(proxy, addr, checkSum);
checkSum += writeOutField(port, addr + 2, busID); checkSum += writeOutField(proxy, addr + 2, busID);
checkSum += writeOutField(port, addr + 3, addrType); checkSum += writeOutField(proxy, addr + 3, addrType);
checkSum += writeOutField(port, addr + 4, addr); checkSum += writeOutField(proxy, addr + 4, addr);
checkSum += writeOutField(port, addr + 12, addrLength); checkSum += writeOutField(proxy, addr + 12, addrLength);
return length; return length;
} }
@ -405,15 +405,15 @@ X86IntelMPAddrSpaceMappingParams::create()
Addr Addr
X86ISA::IntelMP::BusHierarchy::writeOut( X86ISA::IntelMP::BusHierarchy::writeOut(
FunctionalPort * port, Addr addr, uint8_t &checkSum) PortProxy* proxy, Addr addr, uint8_t &checkSum)
{ {
ExtConfigEntry::writeOut(port, addr, checkSum); ExtConfigEntry::writeOut(proxy, addr, checkSum);
checkSum += writeOutField(port, addr + 2, busID); checkSum += writeOutField(proxy, addr + 2, busID);
checkSum += writeOutField(port, addr + 3, info); checkSum += writeOutField(proxy, addr + 3, info);
checkSum += writeOutField(port, addr + 4, parentBus); checkSum += writeOutField(proxy, addr + 4, parentBus);
uint32_t reserved = 0; uint32_t reserved = 0;
port->writeBlob(addr + 5, (uint8_t *)(&reserved), 3); proxy->writeBlob(addr + 5, (uint8_t *)(&reserved), 3);
return length; return length;
} }
@ -434,12 +434,12 @@ X86IntelMPBusHierarchyParams::create()
Addr Addr
X86ISA::IntelMP::CompatAddrSpaceMod::writeOut( X86ISA::IntelMP::CompatAddrSpaceMod::writeOut(
FunctionalPort * port, Addr addr, uint8_t &checkSum) PortProxy* proxy, Addr addr, uint8_t &checkSum)
{ {
ExtConfigEntry::writeOut(port, addr, checkSum); ExtConfigEntry::writeOut(proxy, addr, checkSum);
checkSum += writeOutField(port, addr + 2, busID); checkSum += writeOutField(proxy, addr + 2, busID);
checkSum += writeOutField(port, addr + 3, mod); checkSum += writeOutField(proxy, addr + 3, mod);
checkSum += writeOutField(port, addr + 4, rangeList); checkSum += writeOutField(proxy, addr + 4, rangeList);
return length; return length;
} }

View file

@ -51,7 +51,7 @@
#include "enums/X86IntelMPTriggerMode.hh" #include "enums/X86IntelMPTriggerMode.hh"
#include "sim/sim_object.hh" #include "sim/sim_object.hh"
class FunctionalPort; class PortProxy;
// Config entry types // Config entry types
class X86IntelMPBaseConfigEntryParams; class X86IntelMPBaseConfigEntryParams;
@ -93,7 +93,7 @@ class FloatingPointer : public SimObject
public: public:
Addr writeOut(FunctionalPort * port, Addr addr); Addr writeOut(PortProxy* proxy, Addr addr);
Addr getTableAddr() Addr getTableAddr()
{ {
@ -117,7 +117,7 @@ class BaseConfigEntry : public SimObject
public: public:
virtual Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); virtual Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
BaseConfigEntry(Params * p, uint8_t _type); BaseConfigEntry(Params * p, uint8_t _type);
}; };
@ -132,7 +132,7 @@ class ExtConfigEntry : public SimObject
public: public:
virtual Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); virtual Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
ExtConfigEntry(Params * p, uint8_t _type, uint8_t _length); ExtConfigEntry(Params * p, uint8_t _type, uint8_t _length);
}; };
@ -155,7 +155,7 @@ class ConfigTable : public SimObject
std::vector<ExtConfigEntry *> extEntries; std::vector<ExtConfigEntry *> extEntries;
public: public:
Addr writeOut(FunctionalPort * port, Addr addr); Addr writeOut(PortProxy* proxy, Addr addr);
ConfigTable(Params * p); ConfigTable(Params * p);
}; };
@ -172,7 +172,7 @@ class Processor : public BaseConfigEntry
uint32_t featureFlags; uint32_t featureFlags;
public: public:
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
Processor(Params * p); Processor(Params * p);
}; };
@ -186,7 +186,7 @@ class Bus : public BaseConfigEntry
std::string busType; std::string busType;
public: public:
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
Bus(Params * p); Bus(Params * p);
}; };
@ -202,7 +202,7 @@ class IOAPIC : public BaseConfigEntry
uint32_t address; uint32_t address;
public: public:
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
IOAPIC(Params * p); IOAPIC(Params * p);
}; };
@ -221,7 +221,7 @@ class IntAssignment : public BaseConfigEntry
uint8_t destApicIntIn; uint8_t destApicIntIn;
public: public:
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
IntAssignment(X86IntelMPBaseConfigEntryParams * p, IntAssignment(X86IntelMPBaseConfigEntryParams * p,
Enums::X86IntelMPInterruptType _interruptType, Enums::X86IntelMPInterruptType _interruptType,
@ -269,7 +269,7 @@ class AddrSpaceMapping : public ExtConfigEntry
uint64_t addrLength; uint64_t addrLength;
public: public:
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
AddrSpaceMapping(Params * p); AddrSpaceMapping(Params * p);
}; };
@ -284,7 +284,7 @@ class BusHierarchy : public ExtConfigEntry
uint8_t parentBus; uint8_t parentBus;
public: public:
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
BusHierarchy(Params * p); BusHierarchy(Params * p);
}; };
@ -299,7 +299,7 @@ class CompatAddrSpaceMod : public ExtConfigEntry
uint32_t rangeList; uint32_t rangeList;
public: public:
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
CompatAddrSpaceMod(Params * p); CompatAddrSpaceMod(Params * p);
}; };

View file

@ -43,7 +43,7 @@
#include "arch/x86/bios/smbios.hh" #include "arch/x86/bios/smbios.hh"
#include "arch/x86/isa_traits.hh" #include "arch/x86/isa_traits.hh"
#include "base/types.hh" #include "base/types.hh"
#include "mem/port.hh" #include "mem/port_proxy.hh"
#include "params/X86SMBiosBiosInformation.hh" #include "params/X86SMBiosBiosInformation.hh"
#include "params/X86SMBiosSMBiosStructure.hh" #include "params/X86SMBiosSMBiosStructure.hh"
#include "params/X86SMBiosSMBiosTable.hh" #include "params/X86SMBiosSMBiosTable.hh"
@ -74,15 +74,15 @@ composeBitVector(T vec)
} }
uint16_t uint16_t
X86ISA::SMBios::SMBiosStructure::writeOut(FunctionalPort * port, Addr addr) X86ISA::SMBios::SMBiosStructure::writeOut(PortProxy* proxy, Addr addr)
{ {
port->writeBlob(addr, (uint8_t *)(&type), 1); proxy->writeBlob(addr, (uint8_t *)(&type), 1);
uint8_t length = getLength(); uint8_t length = getLength();
port->writeBlob(addr + 1, (uint8_t *)(&length), 1); proxy->writeBlob(addr + 1, (uint8_t *)(&length), 1);
uint16_t handleGuest = X86ISA::htog(handle); uint16_t handleGuest = X86ISA::htog(handle);
port->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2); proxy->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2);
return length + getStringLength(); return length + getStringLength();
} }
@ -93,7 +93,7 @@ X86ISA::SMBios::SMBiosStructure::SMBiosStructure(Params * p, uint8_t _type) :
void void
X86ISA::SMBios::SMBiosStructure::writeOutStrings( X86ISA::SMBios::SMBiosStructure::writeOutStrings(
FunctionalPort * port, Addr addr) PortProxy* proxy, Addr addr)
{ {
std::vector<std::string>::iterator it; std::vector<std::string>::iterator it;
Addr offset = 0; Addr offset = 0;
@ -103,16 +103,16 @@ X86ISA::SMBios::SMBiosStructure::writeOutStrings(
// If there are string fields but none of them are used, that's a // If there are string fields but none of them are used, that's a
// special case which is handled by this if. // special case which is handled by this if.
if (strings.size() == 0 && stringFields) { if (strings.size() == 0 && stringFields) {
port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1); proxy->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
offset++; offset++;
} else { } else {
for (it = strings.begin(); it != strings.end(); it++) { for (it = strings.begin(); it != strings.end(); it++) {
port->writeBlob(addr + offset, proxy->writeBlob(addr + offset,
(uint8_t *)it->c_str(), it->length() + 1); (uint8_t *)it->c_str(), it->length() + 1);
offset += it->length() + 1; offset += it->length() + 1;
} }
} }
port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1); proxy->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
} }
int int
@ -172,32 +172,32 @@ X86ISA::SMBios::BiosInformation::BiosInformation(Params * p) :
} }
uint16_t uint16_t
X86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr) X86ISA::SMBios::BiosInformation::writeOut(PortProxy* proxy, Addr addr)
{ {
uint8_t size = SMBiosStructure::writeOut(port, addr); uint8_t size = SMBiosStructure::writeOut(proxy, addr);
port->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1); proxy->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1);
port->writeBlob(addr + 0x5, (uint8_t *)(&version), 1); proxy->writeBlob(addr + 0x5, (uint8_t *)(&version), 1);
uint16_t startingAddrSegmentGuest = X86ISA::htog(startingAddrSegment); uint16_t startingAddrSegmentGuest = X86ISA::htog(startingAddrSegment);
port->writeBlob(addr + 0x6, (uint8_t *)(&startingAddrSegmentGuest), 2); proxy->writeBlob(addr + 0x6, (uint8_t *)(&startingAddrSegmentGuest), 2);
port->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1); proxy->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1);
port->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1); proxy->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1);
uint64_t characteristicsGuest = X86ISA::htog(characteristics); uint64_t characteristicsGuest = X86ISA::htog(characteristics);
port->writeBlob(addr + 0xA, (uint8_t *)(&characteristicsGuest), 8); proxy->writeBlob(addr + 0xA, (uint8_t *)(&characteristicsGuest), 8);
uint16_t characteristicExtBytesGuest = uint16_t characteristicExtBytesGuest =
X86ISA::htog(characteristicExtBytes); X86ISA::htog(characteristicExtBytes);
port->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2); proxy->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2);
port->writeBlob(addr + 0x14, (uint8_t *)(&majorVer), 1); proxy->writeBlob(addr + 0x14, (uint8_t *)(&majorVer), 1);
port->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1); proxy->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1);
port->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1); proxy->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1);
port->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1); proxy->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1);
writeOutStrings(port, addr + getLength()); writeOutStrings(proxy, addr + getLength());
return size; return size;
} }
@ -214,7 +214,7 @@ X86ISA::SMBios::SMBiosTable::SMBiosTable(Params * p) :
} }
void void
X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr, X86ISA::SMBios::SMBiosTable::writeOut(PortProxy* proxy, Addr addr,
Addr &headerSize, Addr &structSize) Addr &headerSize, Addr &structSize)
{ {
headerSize = 0x1F; headerSize = 0x1F;
@ -224,26 +224,26 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
*/ */
uint8_t mainChecksum = 0; uint8_t mainChecksum = 0;
port->writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4); proxy->writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4);
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
mainChecksum += smbiosHeader.anchorString[i]; mainChecksum += smbiosHeader.anchorString[i];
// The checksum goes here, but we're figuring it out as we go. // The checksum goes here, but we're figuring it out as we go.
port->writeBlob(addr + 0x5, proxy->writeBlob(addr + 0x5,
(uint8_t *)(&smbiosHeader.entryPointLength), 1); (uint8_t *)(&smbiosHeader.entryPointLength), 1);
mainChecksum += smbiosHeader.entryPointLength; mainChecksum += smbiosHeader.entryPointLength;
port->writeBlob(addr + 0x6, proxy->writeBlob(addr + 0x6,
(uint8_t *)(&smbiosHeader.majorVersion), 1); (uint8_t *)(&smbiosHeader.majorVersion), 1);
mainChecksum += smbiosHeader.majorVersion; mainChecksum += smbiosHeader.majorVersion;
port->writeBlob(addr + 0x7, proxy->writeBlob(addr + 0x7,
(uint8_t *)(&smbiosHeader.minorVersion), 1); (uint8_t *)(&smbiosHeader.minorVersion), 1);
mainChecksum += smbiosHeader.minorVersion; mainChecksum += smbiosHeader.minorVersion;
// Maximum structure size goes here, but we'll figure it out later. // Maximum structure size goes here, but we'll figure it out later.
port->writeBlob(addr + 0xA, proxy->writeBlob(addr + 0xA,
(uint8_t *)(&smbiosHeader.entryPointRevision), 1); (uint8_t *)(&smbiosHeader.entryPointRevision), 1);
mainChecksum += smbiosHeader.entryPointRevision; mainChecksum += smbiosHeader.entryPointRevision;
port->writeBlob(addr + 0xB, proxy->writeBlob(addr + 0xB,
(uint8_t *)(&smbiosHeader.formattedArea), 5); (uint8_t *)(&smbiosHeader.formattedArea), 5);
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
mainChecksum += smbiosHeader.formattedArea[i]; mainChecksum += smbiosHeader.formattedArea[i];
@ -253,7 +253,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
*/ */
uint8_t intChecksum = 0; uint8_t intChecksum = 0;
port->writeBlob(addr + 0x10, proxy->writeBlob(addr + 0x10,
(uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5); (uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5);
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
intChecksum += smbiosHeader.intermediateHeader.anchorString[i]; intChecksum += smbiosHeader.intermediateHeader.anchorString[i];
@ -263,20 +263,20 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
uint32_t tableAddrGuest = uint32_t tableAddrGuest =
X86ISA::htog(smbiosHeader.intermediateHeader.tableAddr); X86ISA::htog(smbiosHeader.intermediateHeader.tableAddr);
port->writeBlob(addr + 0x18, (uint8_t *)(&tableAddrGuest), 4); proxy->writeBlob(addr + 0x18, (uint8_t *)(&tableAddrGuest), 4);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
intChecksum += tableAddrGuest; intChecksum += tableAddrGuest;
tableAddrGuest >>= 8; tableAddrGuest >>= 8;
} }
uint16_t numStructs = X86ISA::gtoh(structures.size()); uint16_t numStructs = X86ISA::gtoh(structures.size());
port->writeBlob(addr + 0x1C, (uint8_t *)(&numStructs), 2); proxy->writeBlob(addr + 0x1C, (uint8_t *)(&numStructs), 2);
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
intChecksum += numStructs; intChecksum += numStructs;
numStructs >>= 8; numStructs >>= 8;
} }
port->writeBlob(addr + 0x1E, proxy->writeBlob(addr + 0x1E,
(uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision), (uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision),
1); 1);
intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision; intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision;
@ -290,7 +290,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
uint16_t maxSize = 0; uint16_t maxSize = 0;
std::vector<SMBiosStructure *>::iterator it; std::vector<SMBiosStructure *>::iterator it;
for (it = structures.begin(); it != structures.end(); it++) { for (it = structures.begin(); it != structures.end(); it++) {
uint16_t size = (*it)->writeOut(port, base + offset); uint16_t size = (*it)->writeOut(proxy, base + offset);
if (size > maxSize) if (size > maxSize)
maxSize = size; maxSize = size;
offset += size; offset += size;
@ -303,7 +303,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
*/ */
maxSize = X86ISA::htog(maxSize); maxSize = X86ISA::htog(maxSize);
port->writeBlob(addr + 0x8, (uint8_t *)(&maxSize), 2); proxy->writeBlob(addr + 0x8, (uint8_t *)(&maxSize), 2);
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
mainChecksum += maxSize; mainChecksum += maxSize;
maxSize >>= 8; maxSize >>= 8;
@ -311,7 +311,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
// Set the checksum // Set the checksum
mainChecksum = -mainChecksum; mainChecksum = -mainChecksum;
port->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1); proxy->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1);
/* /*
* Intermediate header * Intermediate header
@ -319,14 +319,14 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
uint16_t tableSize = offset; uint16_t tableSize = offset;
tableSize = X86ISA::htog(tableSize); tableSize = X86ISA::htog(tableSize);
port->writeBlob(addr + 0x16, (uint8_t *)(&tableSize), 2); proxy->writeBlob(addr + 0x16, (uint8_t *)(&tableSize), 2);
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
intChecksum += tableSize; intChecksum += tableSize;
tableSize >>= 8; tableSize >>= 8;
} }
intChecksum = -intChecksum; intChecksum = -intChecksum;
port->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1); proxy->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1);
} }
X86ISA::SMBios::BiosInformation * X86ISA::SMBios::BiosInformation *

View file

@ -51,7 +51,7 @@
#include "enums/ExtCharacteristic.hh" #include "enums/ExtCharacteristic.hh"
#include "sim/sim_object.hh" #include "sim/sim_object.hh"
class FunctionalPort; class PortProxy;
class X86SMBiosBiosInformationParams; class X86SMBiosBiosInformationParams;
class X86SMBiosSMBiosStructureParams; class X86SMBiosSMBiosStructureParams;
class X86SMBiosSMBiosTableParams; class X86SMBiosSMBiosTableParams;
@ -89,7 +89,7 @@ class SMBiosStructure : public SimObject
return 4; return 4;
} }
virtual uint16_t writeOut(FunctionalPort * port, Addr addr); virtual uint16_t writeOut(PortProxy* proxy, Addr addr);
protected: protected:
bool stringFields; bool stringFields;
@ -98,7 +98,7 @@ class SMBiosStructure : public SimObject
std::vector<std::string> strings; std::vector<std::string> strings;
void writeOutStrings(FunctionalPort * port, Addr addr); void writeOutStrings(PortProxy* proxy, Addr addr);
int getStringLength(); int getStringLength();
@ -145,7 +145,7 @@ class BiosInformation : public SMBiosStructure
BiosInformation(Params * p); BiosInformation(Params * p);
uint8_t getLength() { return 0x18; } uint8_t getLength() { return 0x18; }
uint16_t writeOut(FunctionalPort * port, Addr addr); uint16_t writeOut(PortProxy* proxy, Addr addr);
}; };
class SMBiosTable : public SimObject class SMBiosTable : public SimObject
@ -223,7 +223,7 @@ class SMBiosTable : public SimObject
smbiosHeader.intermediateHeader.tableAddr = addr; smbiosHeader.intermediateHeader.tableAddr = addr;
} }
void writeOut(FunctionalPort * port, Addr addr, void writeOut(PortProxy* proxy, Addr addr,
Addr &headerSize, Addr &structSize); Addr &headerSize, Addr &structSize);
}; };

View file

@ -351,25 +351,27 @@ X86ISA::Interrupts::recvResponse(PacketPtr pkt)
} }
void AddrRangeList
X86ISA::Interrupts::addressRanges(AddrRangeList &range_list) X86ISA::Interrupts::getAddrRanges()
{ {
range_list.clear(); AddrRangeList ranges;
Range<Addr> range = RangeEx(x86LocalAPICAddress(initialApicId, 0), Range<Addr> range = RangeEx(x86LocalAPICAddress(initialApicId, 0),
x86LocalAPICAddress(initialApicId, 0) + x86LocalAPICAddress(initialApicId, 0) +
PageBytes); PageBytes);
range_list.push_back(range); ranges.push_back(range);
pioAddr = range.start; pioAddr = range.start;
return ranges;
} }
void AddrRangeList
X86ISA::Interrupts::getIntAddrRange(AddrRangeList &range_list) X86ISA::Interrupts::getIntAddrRange()
{ {
range_list.clear(); AddrRangeList ranges;
range_list.push_back(RangeEx(x86InterruptAddress(initialApicId, 0), ranges.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
x86InterruptAddress(initialApicId, 0) + x86InterruptAddress(initialApicId, 0) +
PhysAddrAPICRangeSize)); PhysAddrAPICRangeSize));
return ranges;
} }

View file

@ -220,8 +220,8 @@ class Interrupts : public BasicPioDevice, IntDev
return entry.periodic; return entry.periodic;
} }
void addressRanges(AddrRangeList &range_list); AddrRangeList getAddrRanges();
void getIntAddrRange(AddrRangeList &range_list); AddrRangeList getIntAddrRange();
Port *getPort(const std::string &if_name, int idx = -1) Port *getPort(const std::string &if_name, int idx = -1)
{ {

View file

@ -59,7 +59,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
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, "x86_64"); strcpy(name->machine, "x86_64");
name.copyOut(tc->getMemPort()); name.copyOut(tc->getMemProxy());
return 0; return 0;
} }
@ -81,7 +81,7 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
int code = process->getSyscallArg(tc, index); int code = process->getSyscallArg(tc, index);
uint64_t addr = process->getSyscallArg(tc, index); uint64_t addr = process->getSyscallArg(tc, index);
uint64_t fsBase, gsBase; uint64_t fsBase, gsBase;
TranslatingPort *p = tc->getMemPort(); SETranslatingPortProxy* p = tc->getMemProxy();
switch(code) switch(code)
{ {
//Each of these valid options should actually check addr. //Each of these valid options should actually check addr.
@ -149,10 +149,10 @@ setThreadArea32Func(SyscallDesc *desc, int callnum,
gdt(x86lp->gdtStart() + minTLSEntry * sizeof(uint64_t), gdt(x86lp->gdtStart() + minTLSEntry * sizeof(uint64_t),
numTLSEntries * sizeof(uint64_t)); numTLSEntries * sizeof(uint64_t));
if (!userDesc.copyIn(tc->getMemPort())) if (!userDesc.copyIn(tc->getMemProxy()))
return -EFAULT; return -EFAULT;
if (!gdt.copyIn(tc->getMemPort())) if (!gdt.copyIn(tc->getMemProxy()))
panic("Failed to copy in GDT for %s.\n", desc->name); panic("Failed to copy in GDT for %s.\n", desc->name);
if (userDesc->entry_number == (uint32_t)(-1)) { if (userDesc->entry_number == (uint32_t)(-1)) {
@ -204,9 +204,9 @@ setThreadArea32Func(SyscallDesc *desc, int callnum,
gdt[index] = (uint64_t)segDesc; gdt[index] = (uint64_t)segDesc;
if (!userDesc.copyOut(tc->getMemPort())) if (!userDesc.copyOut(tc->getMemProxy()))
return -EFAULT; return -EFAULT;
if (!gdt.copyOut(tc->getMemPort())) if (!gdt.copyOut(tc->getMemProxy()))
panic("Failed to copy out GDT for %s.\n", desc->name); panic("Failed to copy out GDT for %s.\n", desc->name);
return 0; return 0;

View file

@ -43,7 +43,7 @@
#include "arch/vtophys.hh" #include "arch/vtophys.hh"
#include "base/trace.hh" #include "base/trace.hh"
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "mem/physical.hh" #include "mem/port_proxy.hh"
#include "params/LinuxX86System.hh" #include "params/LinuxX86System.hh"
#include "sim/byteswap.hh" #include "sim/byteswap.hh"
@ -67,8 +67,8 @@ LinuxX86System::initState()
// The location of the real mode data structure. // The location of the real mode data structure.
const Addr realModeData = 0x90200; const Addr realModeData = 0x90200;
// A port to write to memory. // A port proxy to write to memory.
FunctionalPort * physPort = threadContexts[0]->getPhysPort(); PortProxy* physProxy = threadContexts[0]->getPhysProxy();
/* /*
* Deal with the command line stuff. * Deal with the command line stuff.
@ -82,14 +82,14 @@ LinuxX86System::initState()
if (commandLine.length() + 1 > realModeData - commandLineBuff) if (commandLine.length() + 1 > realModeData - commandLineBuff)
panic("Command line \"%s\" is longer than %d characters.\n", panic("Command line \"%s\" is longer than %d characters.\n",
commandLine, realModeData - commandLineBuff - 1); commandLine, realModeData - commandLineBuff - 1);
physPort->writeBlob(commandLineBuff, physProxy->writeBlob(commandLineBuff,
(uint8_t *)commandLine.c_str(), commandLine.length() + 1); (uint8_t *)commandLine.c_str(), commandLine.length() + 1);
// Generate a pointer of the right size and endianness to put into // Generate a pointer of the right size and endianness to put into
// commandLinePointer. // commandLinePointer.
uint32_t guestCommandLineBuff = uint32_t guestCommandLineBuff =
X86ISA::htog((uint32_t)commandLineBuff); X86ISA::htog((uint32_t)commandLineBuff);
physPort->writeBlob(commandLinePointer, physProxy->writeBlob(commandLinePointer,
(uint8_t *)&guestCommandLineBuff, sizeof(guestCommandLineBuff)); (uint8_t *)&guestCommandLineBuff, sizeof(guestCommandLineBuff));
/* /*
@ -127,7 +127,7 @@ LinuxX86System::initState()
// A pointer to the buffer for E820 entries. // A pointer to the buffer for E820 entries.
const Addr e820MapPointer = realModeData + 0x2d0; const Addr e820MapPointer = realModeData + 0x2d0;
e820Table->writeTo(physPort, e820MapNrPointer, e820MapPointer); e820Table->writeTo(getSystemPort(), e820MapNrPointer, e820MapPointer);
/* /*
* Pass the location of the real mode data structure to the kernel * Pass the location of the real mode data structure to the kernel

View file

@ -154,17 +154,8 @@ Walker::WalkerPort::recvFunctional(PacketPtr pkt)
} }
void void
Walker::WalkerPort::recvStatusChange(Status status) Walker::WalkerPort::recvRangeChange()
{ {
if (status == RangeChange) {
if (!snoopRangeSent) {
snoopRangeSent = true;
sendStatusChange(Port::RangeChange);
}
return;
}
panic("Unexpected recvStatusChange.\n");
} }
void void

View file

@ -63,26 +63,18 @@ namespace X86ISA
{ {
public: public:
WalkerPort(const std::string &_name, Walker * _walker) : WalkerPort(const std::string &_name, Walker * _walker) :
Port(_name, _walker), walker(_walker), Port(_name, _walker), walker(_walker)
snoopRangeSent(false)
{} {}
protected: protected:
Walker * walker; Walker * walker;
bool snoopRangeSent;
bool recvTiming(PacketPtr pkt); bool recvTiming(PacketPtr pkt);
Tick recvAtomic(PacketPtr pkt); Tick recvAtomic(PacketPtr pkt);
void recvFunctional(PacketPtr pkt); void recvFunctional(PacketPtr pkt);
void recvStatusChange(Status status); void recvRangeChange();
void recvRetry(); void recvRetry();
void getDeviceAddressRanges(AddrRangeList &resp, bool isSnooping() { return true; }
bool &snoop)
{
resp.clear();
snoop = true;
}
}; };
friend class WalkerPort; friend class WalkerPort;

View file

@ -53,7 +53,6 @@
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "debug/Stack.hh" #include "debug/Stack.hh"
#include "mem/page_table.hh" #include "mem/page_table.hh"
#include "mem/translating_port.hh"
#include "sim/process_impl.hh" #include "sim/process_impl.hh"
#include "sim/syscall_emul.hh" #include "sim/syscall_emul.hh"
#include "sim/system.hh" #include "sim/system.hh"

View file

@ -37,7 +37,7 @@
#include "base/trace.hh" #include "base/trace.hh"
#include "cpu/base.hh" #include "cpu/base.hh"
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "mem/vport.hh" #include "mem/fs_translating_port_proxy.hh"
#include "sim/system.hh" #include "sim/system.hh"
using namespace std; using namespace std;
@ -48,9 +48,9 @@ namespace X86ISA
{ {
Addr addr = 0; Addr addr = 0;
VirtualPort *vp; FSTranslatingPortProxy* vp;
vp = tc->getVirtPort(); vp = tc->getVirtProxy();
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr)) if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
panic("thread info not compiled into kernel\n"); panic("thread info not compiled into kernel\n");
@ -82,9 +82,9 @@ namespace X86ISA
Addr tsk; Addr tsk;
VirtualPort *vp; FSTranslatingPortProxy* vp;
vp = tc->getVirtPort(); vp = tc->getVirtProxy();
tsk = vp->readGtoH<Addr>(base + task_off); tsk = vp->readGtoH<Addr>(base + task_off);
return tsk; return tsk;
@ -99,9 +99,9 @@ namespace X86ISA
uint16_t pd; uint16_t pd;
VirtualPort *vp; FSTranslatingPortProxy* vp;
vp = tc->getVirtPort(); vp = tc->getVirtProxy();
pd = vp->readGtoH<uint16_t>(task + pid_off); pd = vp->readGtoH<uint16_t>(task + pid_off);
return pd; return pd;

View file

@ -48,7 +48,7 @@
#include "base/intmath.hh" #include "base/intmath.hh"
#include "base/trace.hh" #include "base/trace.hh"
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "mem/physical.hh" #include "mem/port_proxy.hh"
#include "params/X86System.hh" #include "params/X86System.hh"
#include "sim/byteswap.hh" #include "sim/byteswap.hh"
@ -61,8 +61,6 @@ X86System::X86System(Params *p) :
mpConfigTable(p->intel_mp_table), mpConfigTable(p->intel_mp_table),
rsdp(p->acpi_description_table_pointer) rsdp(p->acpi_description_table_pointer)
{ {
if (kernel->getArch() == ObjectFile::I386)
fatal("Loading a 32 bit x86 kernel is not supported.\n");
} }
static void static void
@ -116,6 +114,9 @@ X86System::initState()
{ {
System::initState(); System::initState();
if (kernel->getArch() == ObjectFile::I386)
fatal("Loading a 32 bit x86 kernel is not supported.\n");
ThreadContext *tc = threadContexts[0]; ThreadContext *tc = threadContexts[0];
// This is the boot strap processor (BSP). Initialize it to look like // This is the boot strap processor (BSP). Initialize it to look like
// the boot loader has just turned control over to the 64 bit OS. We // the boot loader has just turned control over to the 64 bit OS. We
@ -137,8 +138,8 @@ X86System::initState()
const int PDPTBits = 9; const int PDPTBits = 9;
const int PDTBits = 9; const int PDTBits = 9;
// Get a port to write the page tables and descriptor tables. // Get a port proxy to write the page tables and descriptor tables.
FunctionalPort * physPort = tc->getPhysPort(); PortProxy* physProxy = tc->getPhysProxy();
/* /*
* Set up the gdt. * Set up the gdt.
@ -146,7 +147,7 @@ X86System::initState()
uint8_t numGDTEntries = 0; uint8_t numGDTEntries = 0;
// Place holder at selector 0 // Place holder at selector 0
uint64_t nullDescriptor = 0; uint64_t nullDescriptor = 0;
physPort->writeBlob(GDTBase + numGDTEntries * 8, physProxy->writeBlob(GDTBase + numGDTEntries * 8,
(uint8_t *)(&nullDescriptor), 8); (uint8_t *)(&nullDescriptor), 8);
numGDTEntries++; numGDTEntries++;
@ -168,7 +169,7 @@ X86System::initState()
//it's beginning in memory and it's actual data, we'll use an //it's beginning in memory and it's actual data, we'll use an
//intermediary. //intermediary.
uint64_t csDescVal = csDesc; uint64_t csDescVal = csDesc;
physPort->writeBlob(GDTBase + numGDTEntries * 8, physProxy->writeBlob(GDTBase + numGDTEntries * 8,
(uint8_t *)(&csDescVal), 8); (uint8_t *)(&csDescVal), 8);
numGDTEntries++; numGDTEntries++;
@ -191,7 +192,7 @@ X86System::initState()
dsDesc.limitHigh = 0xF; dsDesc.limitHigh = 0xF;
dsDesc.limitLow = 0xFF; dsDesc.limitLow = 0xFF;
uint64_t dsDescVal = dsDesc; uint64_t dsDescVal = dsDesc;
physPort->writeBlob(GDTBase + numGDTEntries * 8, physProxy->writeBlob(GDTBase + numGDTEntries * 8,
(uint8_t *)(&dsDescVal), 8); (uint8_t *)(&dsDescVal), 8);
numGDTEntries++; numGDTEntries++;
@ -219,7 +220,7 @@ X86System::initState()
tssDesc.limitHigh = 0xF; tssDesc.limitHigh = 0xF;
tssDesc.limitLow = 0xFF; tssDesc.limitLow = 0xFF;
uint64_t tssDescVal = tssDesc; uint64_t tssDescVal = tssDesc;
physPort->writeBlob(GDTBase + numGDTEntries * 8, physProxy->writeBlob(GDTBase + numGDTEntries * 8,
(uint8_t *)(&tssDescVal), 8); (uint8_t *)(&tssDescVal), 8);
numGDTEntries++; numGDTEntries++;
@ -249,24 +250,24 @@ X86System::initState()
// read/write, user, not present // read/write, user, not present
uint64_t pml4e = X86ISA::htog(0x6); uint64_t pml4e = X86ISA::htog(0x6);
for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) { for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) {
physPort->writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8); physProxy->writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8);
} }
// Point to the only PDPT // Point to the only PDPT
pml4e = X86ISA::htog(0x7 | PageDirPtrTable); pml4e = X86ISA::htog(0x7 | PageDirPtrTable);
physPort->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8); physProxy->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8);
// Page Directory Pointer Table // Page Directory Pointer Table
// read/write, user, not present // read/write, user, not present
uint64_t pdpe = X86ISA::htog(0x6); uint64_t pdpe = X86ISA::htog(0x6);
for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) { for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) {
physPort->writeBlob(PageDirPtrTable + offset, physProxy->writeBlob(PageDirPtrTable + offset,
(uint8_t *)(&pdpe), 8); (uint8_t *)(&pdpe), 8);
} }
// Point to the PDTs // Point to the PDTs
for (int table = 0; table < NumPDTs; table++) { for (int table = 0; table < NumPDTs; table++) {
pdpe = X86ISA::htog(0x7 | PageDirTable[table]); pdpe = X86ISA::htog(0x7 | PageDirTable[table]);
physPort->writeBlob(PageDirPtrTable + table * 8, physProxy->writeBlob(PageDirPtrTable + table * 8,
(uint8_t *)(&pdpe), 8); (uint8_t *)(&pdpe), 8);
} }
@ -278,7 +279,7 @@ X86System::initState()
for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) { for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) {
// read/write, user, present, 4MB // read/write, user, present, 4MB
uint64_t pdte = X86ISA::htog(0x87 | base); uint64_t pdte = X86ISA::htog(0x87 | base);
physPort->writeBlob(PageDirTable[table] + offset, physProxy->writeBlob(PageDirTable[table] + offset,
(uint8_t *)(&pdte), 8); (uint8_t *)(&pdte), 8);
base += pageSize; base += pageSize;
} }
@ -341,8 +342,8 @@ void
X86System::writeOutSMBiosTable(Addr header, X86System::writeOutSMBiosTable(Addr header,
Addr &headerSize, Addr &structSize, Addr table) Addr &headerSize, Addr &structSize, Addr table)
{ {
// Get a port to write the table and header to memory. // Get a port proxy to write the table and header to memory.
FunctionalPort * physPort = threadContexts[0]->getPhysPort(); PortProxy* physProxy = threadContexts[0]->getPhysProxy();
// If the table location isn't specified, just put it after the header. // If the table location isn't specified, just put it after the header.
// The header size as of the 2.5 SMBios specification is 0x1F bytes // The header size as of the 2.5 SMBios specification is 0x1F bytes
@ -350,7 +351,7 @@ X86System::writeOutSMBiosTable(Addr header,
table = header + 0x1F; table = header + 0x1F;
smbiosTable->setTableAddr(table); smbiosTable->setTableAddr(table);
smbiosTable->writeOut(physPort, header, headerSize, structSize); smbiosTable->writeOut(physProxy, header, headerSize, structSize);
// Do some bounds checking to make sure we at least didn't step on // Do some bounds checking to make sure we at least didn't step on
// ourselves. // ourselves.
@ -362,8 +363,8 @@ void
X86System::writeOutMPTable(Addr fp, X86System::writeOutMPTable(Addr fp,
Addr &fpSize, Addr &tableSize, Addr table) Addr &fpSize, Addr &tableSize, Addr table)
{ {
// Get a port to write the table and header to memory. // Get a port proxy to write the table and header to memory.
FunctionalPort * physPort = threadContexts[0]->getPhysPort(); PortProxy* physProxy = threadContexts[0]->getPhysProxy();
// If the table location isn't specified and it exists, just put // If the table location isn't specified and it exists, just put
// it after the floating pointer. The fp size as of the 1.4 Intel MP // it after the floating pointer. The fp size as of the 1.4 Intel MP
@ -374,9 +375,9 @@ X86System::writeOutMPTable(Addr fp,
mpFloatingPointer->setTableAddr(table); mpFloatingPointer->setTableAddr(table);
} }
fpSize = mpFloatingPointer->writeOut(physPort, fp); fpSize = mpFloatingPointer->writeOut(physProxy, fp);
if (mpConfigTable) if (mpConfigTable)
tableSize = mpConfigTable->writeOut(physPort, table); tableSize = mpConfigTable->writeOut(physProxy, table);
else else
tableSize = 0; tableSize = 0;

View file

@ -134,7 +134,7 @@ struct AllFlags : public Flag
FlagsMap::iterator end = allFlags().end(); FlagsMap::iterator end = allFlags().end();
for (; i != end; ++i) for (; i != end; ++i)
if (i->second != this) if (i->second != this)
i->second->enable(); i->second->disable();
} }
}; };

View file

@ -414,15 +414,15 @@ ElfObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask)
} }
bool bool
ElfObject::loadSections(Port *memPort, Addr addrMask) ElfObject::loadSections(PortProxy* memProxy, Addr addrMask)
{ {
if (!ObjectFile::loadSections(memPort, addrMask)) if (!ObjectFile::loadSections(memProxy, addrMask))
return false; return false;
vector<Segment>::iterator extraIt; vector<Segment>::iterator extraIt;
for (extraIt = extraSegments.begin(); for (extraIt = extraSegments.begin();
extraIt != extraSegments.end(); extraIt++) { extraIt != extraSegments.end(); extraIt++) {
if (!loadSection(&(*extraIt), memPort, addrMask)) { if (!loadSection(&(*extraIt), memProxy, addrMask)) {
return false; return false;
} }
} }

View file

@ -65,7 +65,7 @@ class ElfObject : public ObjectFile
public: public:
virtual ~ElfObject() {} virtual ~ElfObject() {}
bool loadSections(Port *memPort, bool loadSections(PortProxy *memProxy,
Addr addrMask = std::numeric_limits<Addr>::max()); Addr addrMask = std::numeric_limits<Addr>::max());
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask = virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
std::numeric_limits<Addr>::max()); std::numeric_limits<Addr>::max());

View file

@ -36,7 +36,7 @@
#include "base/loader/hex_file.hh" #include "base/loader/hex_file.hh"
#include "base/loader/symtab.hh" #include "base/loader/symtab.hh"
#include "base/cprintf.hh" #include "base/cprintf.hh"
#include "mem/translating_port.hh" #include "mem/port_proxy.hh"
using namespace std; using namespace std;
/* /*
@ -59,7 +59,7 @@ HexFile::~HexFile()
} }
bool bool
HexFile::loadSections(Port *memPort) HexFile::loadSections(PortProxy* memProxy)
{ {
char Line[64]; char Line[64];
Addr MemAddr; Addr MemAddr;
@ -71,7 +71,7 @@ HexFile::loadSections(Port *memPort)
parseLine(Line, &MemAddr, &Data); parseLine(Line, &MemAddr, &Data);
if (MemAddr != 0) { if (MemAddr != 0) {
// Now, write to memory // Now, write to memory
memPort->writeBlob(MemAddr << 2, (uint8_t *)&Data, sizeof(Data)); memProxy->writeBlob(MemAddr << 2, (uint8_t *)&Data, sizeof(Data));
} }
} }
return true; return true;

View file

@ -37,7 +37,7 @@
#include "base/types.hh" #include "base/types.hh"
class Port; class PortProxy;
class HexFile class HexFile
{ {
@ -52,7 +52,7 @@ class HexFile
virtual ~HexFile(); virtual ~HexFile();
void close(); void close();
bool loadSections(Port *memPort); bool loadSections(PortProxy* memProxy);
}; };
#endif // __BASE_LOADER_HEX_FILE_HH__ #endif // __BASE_LOADER_HEX_FILE_HH__

View file

@ -45,7 +45,7 @@
#include "base/loader/raw_object.hh" #include "base/loader/raw_object.hh"
#include "base/loader/symtab.hh" #include "base/loader/symtab.hh"
#include "base/cprintf.hh" #include "base/cprintf.hh"
#include "mem/translating_port.hh" #include "mem/port_proxy.hh"
using namespace std; using namespace std;
@ -65,16 +65,16 @@ ObjectFile::~ObjectFile()
bool bool
ObjectFile::loadSection(Section *sec, Port *memPort, Addr addrMask) ObjectFile::loadSection(Section *sec, PortProxy* memProxy, Addr addrMask)
{ {
if (sec->size != 0) { if (sec->size != 0) {
Addr addr = sec->baseAddr & addrMask; Addr addr = sec->baseAddr & addrMask;
if (sec->fileImage) { if (sec->fileImage) {
memPort->writeBlob(addr, sec->fileImage, sec->size); memProxy->writeBlob(addr, sec->fileImage, sec->size);
} }
else { else {
// no image: must be bss // no image: must be bss
memPort->memsetBlob(addr, 0, sec->size); memProxy->memsetBlob(addr, 0, sec->size);
} }
} }
return true; return true;
@ -82,11 +82,11 @@ ObjectFile::loadSection(Section *sec, Port *memPort, Addr addrMask)
bool bool
ObjectFile::loadSections(Port *memPort, Addr addrMask) ObjectFile::loadSections(PortProxy* memProxy, Addr addrMask)
{ {
return (loadSection(&text, memPort, addrMask) return (loadSection(&text, memProxy, addrMask)
&& loadSection(&data, memPort, addrMask) && loadSection(&data, memProxy, addrMask)
&& loadSection(&bss, memPort, addrMask)); && loadSection(&bss, memProxy, addrMask));
} }

View file

@ -37,7 +37,7 @@
#include "base/types.hh" #include "base/types.hh"
class Port; class PortProxy;
class SymbolTable; class SymbolTable;
class ObjectFile class ObjectFile
@ -83,7 +83,7 @@ class ObjectFile
void close(); void close();
virtual bool loadSections(Port *memPort, Addr addrMask = virtual bool loadSections(PortProxy *memProxy, Addr addrMask =
std::numeric_limits<Addr>::max()); std::numeric_limits<Addr>::max());
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask = virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
std::numeric_limits<Addr>::max()) = 0; std::numeric_limits<Addr>::max()) = 0;
@ -111,7 +111,7 @@ class ObjectFile
Section data; Section data;
Section bss; Section bss;
bool loadSection(Section *sec, Port *memPort, Addr addrMask); bool loadSection(Section *sec, PortProxy* memProxy, Addr addrMask);
void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; } void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; }
public: public:

View file

@ -132,8 +132,8 @@
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "debug/GDBAll.hh" #include "debug/GDBAll.hh"
#include "mem/port.hh" #include "mem/port.hh"
#include "mem/translating_port.hh" #include "mem/fs_translating_port_proxy.hh"
#include "mem/vport.hh" #include "mem/se_translating_port_proxy.hh"
#include "sim/full_system.hh" #include "sim/full_system.hh"
#include "sim/system.hh" #include "sim/system.hh"
@ -461,10 +461,10 @@ BaseRemoteGDB::read(Addr vaddr, size_t size, char *data)
DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size); DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
if (FullSystem) { if (FullSystem) {
VirtualPort *port = context->getVirtPort(); FSTranslatingPortProxy *port = context->getVirtProxy();
port->readBlob(vaddr, (uint8_t*)data, size); port->readBlob(vaddr, (uint8_t*)data, size);
} else { } else {
TranslatingPort *port = context->getMemPort(); SETranslatingPortProxy *port = context->getMemProxy();
port->readBlob(vaddr, (uint8_t*)data, size); port->readBlob(vaddr, (uint8_t*)data, size);
} }
@ -504,10 +504,10 @@ BaseRemoteGDB::write(Addr vaddr, size_t size, const char *data)
DPRINTFNR("\n"); DPRINTFNR("\n");
} }
if (FullSystem) { if (FullSystem) {
VirtualPort *port = context->getVirtPort(); FSTranslatingPortProxy *port = context->getVirtProxy();
port->writeBlob(vaddr, (uint8_t*)data, size); port->writeBlob(vaddr, (uint8_t*)data, size);
} else { } else {
TranslatingPort *port = context->getMemPort(); SETranslatingPortProxy *port = context->getMemProxy();
port->writeBlob(vaddr, (uint8_t*)data, size); port->writeBlob(vaddr, (uint8_t*)data, size);
delete port; delete port;
} }

View file

@ -216,7 +216,7 @@ class BaseRemoteGDB
bool insertSoftBreak(Addr addr, size_t len); bool insertSoftBreak(Addr addr, size_t len);
bool removeSoftBreak(Addr addr, size_t len); bool removeSoftBreak(Addr addr, size_t len);
bool insertHardBreak(Addr addr, size_t len); virtual bool insertHardBreak(Addr addr, size_t len);
bool removeHardBreak(Addr addr, size_t len); bool removeHardBreak(Addr addr, size_t len);
protected: protected:

View file

@ -138,9 +138,12 @@ class BaseCPU(MemObject):
tracer = Param.InstTracer(default_tracer, "Instruction tracer") tracer = Param.InstTracer(default_tracer, "Instruction tracer")
_cached_ports = [] icache_port = Port("Instruction Port")
dcache_port = Port("Data Port")
_cached_ports = ['icache_port', 'dcache_port']
if buildEnv['TARGET_ISA'] in ['x86', 'arm']: if buildEnv['TARGET_ISA'] in ['x86', 'arm']:
_cached_ports = ["itb.walker.port", "dtb.walker.port"] _cached_ports += ["itb.walker.port", "dtb.walker.port"]
_uncached_ports = [] _uncached_ports = []
if buildEnv['TARGET_ISA'] == 'x86': if buildEnv['TARGET_ISA'] == 'x86':

View file

@ -1,4 +1,16 @@
/* /*
* Copyright (c) 2011 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2002-2005 The Regents of The University of Michigan * Copyright (c) 2002-2005 The Regents of The University of Michigan
* Copyright (c) 2011 Regents of the University of California * Copyright (c) 2011 Regents of the University of California
* All rights reserved. * All rights reserved.
@ -470,3 +482,36 @@ BaseCPU::traceFunctionsInternal(Addr pc)
functionEntryTick = curTick(); functionEntryTick = curTick();
} }
} }
bool
BaseCPU::CpuPort::recvTiming(PacketPtr pkt)
{
panic("BaseCPU doesn't expect recvTiming callback!");
return true;
}
void
BaseCPU::CpuPort::recvRetry()
{
panic("BaseCPU doesn't expect recvRetry callback!");
}
Tick
BaseCPU::CpuPort::recvAtomic(PacketPtr pkt)
{
panic("BaseCPU doesn't expect recvAtomic callback!");
return curTick();
}
void
BaseCPU::CpuPort::recvFunctional(PacketPtr pkt)
{
// No internal storage to update (in the general case). In the
// long term this should never be called, but that assumed a split
// into master/slave and request/response.
}
void
BaseCPU::CpuPort::recvRangeChange()
{
}

View file

@ -1,4 +1,16 @@
/* /*
* Copyright (c) 2011 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2002-2005 The Regents of The University of Michigan * Copyright (c) 2002-2005 The Regents of The University of Michigan
* Copyright (c) 2011 Regents of the University of California * Copyright (c) 2011 Regents of the University of California
* All rights reserved. * All rights reserved.
@ -92,6 +104,42 @@ class BaseCPU : public MemObject
// therefore no setCpuId() method is provided // therefore no setCpuId() method is provided
int _cpuId; int _cpuId;
/**
* Define a base class for the CPU ports (instruction and data)
* that is refined in the subclasses. This class handles the
* common cases, i.e. the functional accesses and the status
* changes and address range queries. The default behaviour for
* both atomic and timing access is to panic and the corresponding
* subclasses have to override these methods.
*/
class CpuPort : public Port
{
public:
/**
* Create a CPU port with a name and a structural owner.
*
* @param _name port name including the owner
* @param _name structural owner of this port
*/
CpuPort(const std::string& _name, MemObject* _owner) :
Port(_name, _owner)
{ }
protected:
virtual bool recvTiming(PacketPtr pkt);
virtual Tick recvAtomic(PacketPtr pkt);
virtual void recvRetry();
void recvFunctional(PacketPtr pkt);
void recvRangeChange();
};
public: public:
/** Reads this CPU's ID. */ /** Reads this CPU's ID. */
int cpuId() { return _cpuId; } int cpuId() { return _cpuId; }

View file

@ -98,12 +98,12 @@ class CheckerThreadContext : public ThreadContext
Process *getProcessPtr() { return actualTC->getProcessPtr(); } Process *getProcessPtr() { return actualTC->getProcessPtr(); }
TranslatingPort *getMemPort() { return actualTC->getMemPort(); } PortProxy* getPhysProxy() { return actualTC->getPhysProxy(); }
VirtualPort *getVirtPort() FSTranslatingPortProxy* getVirtProxy()
{ return actualTC->getVirtPort(); } { return actualTC->getVirtProxy(); }
FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); } SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); }
Status status() const { return actualTC->status(); } Status status() const { return actualTC->status(); }

View file

@ -44,9 +44,6 @@ class InOrderCPU(BaseCPU):
fetchMemPort = Param.String("icache_port" , "Name of Memory Port to get instructions from") fetchMemPort = Param.String("icache_port" , "Name of Memory Port to get instructions from")
dataMemPort = Param.String("dcache_port" , "Name of Memory Port to get data from") dataMemPort = Param.String("dcache_port" , "Name of Memory Port to get data from")
icache_port = Port("Instruction Port")
dcache_port = Port("Data Port")
_cached_ports = ['icache_port', 'dcache_port']
fetchBuffSize = Param.Unsigned(4, "Fetch Buffer Size (Number of Cache Blocks Stored)") fetchBuffSize = Param.Unsigned(4, "Fetch Buffer Size (Number of Cache Blocks Stored)")
memBlockSize = Param.Unsigned(64, "Memory Block Size") memBlockSize = Param.Unsigned(64, "Memory Block Size")

View file

@ -54,7 +54,6 @@
#include "debug/RefCount.hh" #include "debug/RefCount.hh"
#include "debug/SkedCache.hh" #include "debug/SkedCache.hh"
#include "debug/Quiesce.hh" #include "debug/Quiesce.hh"
#include "mem/translating_port.hh"
#include "params/InOrderCPU.hh" #include "params/InOrderCPU.hh"
#include "sim/full_system.hh" #include "sim/full_system.hh"
#include "sim/process.hh" #include "sim/process.hh"
@ -758,6 +757,8 @@ InOrderCPU::init()
for (ThreadID tid = 0; tid < numThreads; tid++) { for (ThreadID tid = 0; tid < numThreads; tid++) {
ThreadContext *src_tc = threadContexts[tid]; ThreadContext *src_tc = threadContexts[tid];
TheISA::initCPU(src_tc, src_tc->contextId()); TheISA::initCPU(src_tc, src_tc->contextId());
// Initialise the ThreadContext's memory proxies
thread[tid]->initMemProxies(thread[tid]->getTC());
} }
} }
@ -860,7 +861,6 @@ InOrderCPU::getInterrupts()
return interrupts->getInterrupt(threadContexts[0]); return interrupts->getInterrupt(threadContexts[0]);
} }
void void
InOrderCPU::processInterrupts(Fault interrupt) InOrderCPU::processInterrupts(Fault interrupt)
{ {
@ -879,16 +879,6 @@ InOrderCPU::processInterrupts(Fault interrupt)
trap(interrupt, threadContexts[0]->contextId(), dummyBufferInst); trap(interrupt, threadContexts[0]->contextId(), dummyBufferInst);
} }
void
InOrderCPU::updateMemPorts()
{
// Update all ThreadContext's memory ports (Functional/Virtual
// Ports)
ThreadID size = thread.size();
for (ThreadID i = 0; i < size; ++i)
thread[i]->connectMemPorts(thread[i]->getTC());
}
void void
InOrderCPU::trapContext(Fault fault, ThreadID tid, DynInstPtr inst, int delay) InOrderCPU::trapContext(Fault fault, ThreadID tid, DynInstPtr inst, int delay)
{ {

View file

@ -428,10 +428,6 @@ class InOrderCPU : public BaseCPU
/** Halts the CPU. */ /** Halts the CPU. */
void halt() { panic("Halt not implemented!\n"); } void halt() { panic("Halt not implemented!\n"); }
/** Update the Virt and Phys ports of all ThreadContexts to
* reflect change in memory connections. */
void updateMemPorts();
/** Check if this address is a valid instruction address. */ /** Check if this address is a valid instruction address. */
bool validInstAddr(Addr addr) { return true; } bool validInstAddr(Addr addr) { return true; }

View file

@ -82,17 +82,8 @@ CacheUnit::CachePort::recvFunctional(PacketPtr pkt)
} }
void void
CacheUnit::CachePort::recvStatusChange(Status status) CacheUnit::CachePort::recvRangeChange()
{ {
if (status == RangeChange) {
if (!snoopRangeSent) {
snoopRangeSent = true;
sendStatusChange(Port::RangeChange);
}
return;
}
panic("CacheUnit::CachePort doesn't expect recvStatusChange callback!");
} }
bool bool
@ -145,18 +136,6 @@ CacheUnit::tlb()
} }
void
CacheUnit::CachePort::setPeer(Port *port)
{
Port::setPeer(port);
// Update the ThreadContext's memory ports (Functional/Virtual
// Ports)
if (cachePortUnit->resName == "dcache_port") {
cachePortUnit->cpu->updateMemPorts();
}
}
Port * Port *
CacheUnit::getPort(const string &if_name, int idx) CacheUnit::getPort(const string &if_name, int idx)
{ {

View file

@ -90,13 +90,9 @@ class CacheUnit : public Resource
CachePort(CacheUnit *_cachePortUnit) CachePort(CacheUnit *_cachePortUnit)
: Port(_cachePortUnit->name() + "-cache-port", : Port(_cachePortUnit->name() + "-cache-port",
(MemObject*)_cachePortUnit->cpu), (MemObject*)_cachePortUnit->cpu),
cachePortUnit(_cachePortUnit), snoopRangeSent(false) cachePortUnit(_cachePortUnit)
{ } { }
bool snoopRangeSent;
void setPeer(Port *port);
protected: protected:
/** Atomic version of receive. Panics. */ /** Atomic version of receive. Panics. */
Tick recvAtomic(PacketPtr pkt); Tick recvAtomic(PacketPtr pkt);
@ -104,13 +100,8 @@ class CacheUnit : public Resource
/** Functional version of receive.*/ /** Functional version of receive.*/
void recvFunctional(PacketPtr pkt); void recvFunctional(PacketPtr pkt);
/** Receives status change. Other than range changing, panics. */ /** Receives range changes. */
void recvStatusChange(Status status); void recvRangeChange();
/** Returns the address ranges of this device. */
void getDeviceAddressRanges(AddrRangeList &resp,
bool &snoop)
{ resp.clear(); snoop = true; }
/** Timing version of receive */ /** Timing version of receive */
bool recvTiming(PacketPtr pkt); bool recvTiming(PacketPtr pkt);

View file

@ -38,10 +38,10 @@
using namespace TheISA; using namespace TheISA;
VirtualPort * FSTranslatingPortProxy*
InOrderThreadContext::getVirtPort() InOrderThreadContext::getVirtProxy()
{ {
return thread->getVirtPort(); return thread->getVirtProxy();
} }
void void

View file

@ -117,8 +117,12 @@ class InOrderThreadContext : public ThreadContext
TheISA::Kernel::Statistics *getKernelStats() TheISA::Kernel::Statistics *getKernelStats()
{ return thread->kernelStats; } { return thread->kernelStats; }
void connectMemPorts(ThreadContext *tc) PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
{ thread->connectMemPorts(tc); }
FSTranslatingPortProxy* getVirtProxy();
void initMemProxies(ThreadContext *tc)
{ thread->initMemProxies(tc); }
/** Dumps the function profiling information. /** Dumps the function profiling information.
* @todo: Implement. * @todo: Implement.
@ -142,14 +146,11 @@ class InOrderThreadContext : public ThreadContext
return this->thread->quiesceEvent; return this->thread->quiesceEvent;
} }
SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); }
/** Returns a pointer to this thread's process. */ /** Returns a pointer to this thread's process. */
Process *getProcessPtr() { return thread->getProcessPtr(); } Process *getProcessPtr() { return thread->getProcessPtr(); }
TranslatingPort *getMemPort() { return thread->getMemPort(); }
VirtualPort *getVirtPort();
FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
/** Returns this thread's status. */ /** Returns this thread's status. */
Status status() const { return thread->status(); } Status status() const { return thread->status(); }

View file

@ -49,9 +49,6 @@ class DerivO3CPU(BaseCPU):
checker.dtb = Parent.dtb checker.dtb = Parent.dtb
cachePorts = Param.Unsigned(200, "Cache Ports") cachePorts = Param.Unsigned(200, "Cache Ports")
icache_port = Port("Instruction Port")
dcache_port = Port("Data Port")
_cached_ports = BaseCPU._cached_ports + ['icache_port', 'dcache_port']
decodeToFetchDelay = Param.Unsigned(1, "Decode to fetch delay") decodeToFetchDelay = Param.Unsigned(1, "Decode to fetch delay")
renameToFetchDelay = Param.Unsigned(1 ,"Rename to fetch delay") renameToFetchDelay = Param.Unsigned(1 ,"Rename to fetch delay")

View file

@ -1,4 +1,16 @@
/* /*
* Copyright (c) 2011 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2004-2006 The Regents of The University of Michigan * Copyright (c) 2004-2006 The Regents of The University of Michigan
* Copyright (c) 2011 Regents of the University of California * Copyright (c) 2011 Regents of the University of California
* All rights reserved. * All rights reserved.
@ -76,6 +88,42 @@ BaseO3CPU::regStats()
BaseCPU::regStats(); BaseCPU::regStats();
} }
template<class Impl>
bool
FullO3CPU<Impl>::IcachePort::recvTiming(PacketPtr pkt)
{
DPRINTF(O3CPU, "Fetch unit received timing\n");
if (pkt->isResponse()) {
// We shouldn't ever get a block in ownership state
assert(!(pkt->memInhibitAsserted() && !pkt->sharedAsserted()));
fetch->processCacheCompletion(pkt);
}
//else Snooped a coherence request, just return
return true;
}
template<class Impl>
void
FullO3CPU<Impl>::IcachePort::recvRetry()
{
fetch->recvRetry();
}
template <class Impl>
bool
FullO3CPU<Impl>::DcachePort::recvTiming(PacketPtr pkt)
{
return lsq->recvTiming(pkt);
}
template <class Impl>
void
FullO3CPU<Impl>::DcachePort::recvRetry()
{
lsq->recvRetry();
}
template <class Impl> template <class Impl>
FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c) FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c)
: Event(CPU_Tick_Pri), cpu(c) : Event(CPU_Tick_Pri), cpu(c)
@ -191,6 +239,9 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
TheISA::NumMiscRegs * numThreads, TheISA::NumMiscRegs * numThreads,
TheISA::ZeroReg), TheISA::ZeroReg),
icachePort(&fetch, this),
dcachePort(&iew.ldstQueue, this),
timeBuffer(params->backComSize, params->forwardComSize), timeBuffer(params->backComSize, params->forwardComSize),
fetchQueue(params->backComSize, params->forwardComSize), fetchQueue(params->backComSize, params->forwardComSize),
decodeQueue(params->backComSize, params->forwardComSize), decodeQueue(params->backComSize, params->forwardComSize),
@ -215,6 +266,7 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
if (params->checker) { if (params->checker) {
BaseCPU *temp_checker = params->checker; BaseCPU *temp_checker = params->checker;
checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker); checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
checker->setIcachePort(&icachePort);
checker->setSystem(params->system); checker->setSystem(params->system);
} else { } else {
checker = NULL; checker = NULL;
@ -524,9 +576,9 @@ Port *
FullO3CPU<Impl>::getPort(const std::string &if_name, int idx) FullO3CPU<Impl>::getPort(const std::string &if_name, int idx)
{ {
if (if_name == "dcache_port") if (if_name == "dcache_port")
return iew.getDcachePort(); return &dcachePort;
else if (if_name == "icache_port") else if (if_name == "icache_port")
return fetch.getIcachePort(); return &icachePort;
else else
panic("No Such Port\n"); panic("No Such Port\n");
} }
@ -600,10 +652,19 @@ FullO3CPU<Impl>::init()
for (ThreadID tid = 0; tid < numThreads; ++tid) for (ThreadID tid = 0; tid < numThreads; ++tid)
thread[tid]->inSyscall = true; thread[tid]->inSyscall = true;
// this CPU could still be unconnected if we are restoring from a
// checkpoint and this CPU is to be switched in, thus we can only
// do this here if the instruction port is actually connected, if
// not we have to do it as part of takeOverFrom
if (icachePort.isConnected())
fetch.setIcache();
if (FullSystem) { if (FullSystem) {
for (ThreadID tid = 0; tid < numThreads; tid++) { for (ThreadID tid = 0; tid < numThreads; tid++) {
ThreadContext *src_tc = threadContexts[tid]; ThreadContext *src_tc = threadContexts[tid];
TheISA::initCPU(src_tc, src_tc->contextId()); TheISA::initCPU(src_tc, src_tc->contextId());
// Initialise the ThreadContext's memory proxies
thread[tid]->initMemProxies(thread[tid]->getTC());
} }
} }
@ -967,17 +1028,6 @@ FullO3CPU<Impl>::processInterrupts(Fault interrupt)
this->trap(interrupt, 0, NULL); this->trap(interrupt, 0, NULL);
} }
template <class Impl>
void
FullO3CPU<Impl>::updateMemPorts()
{
// Update all ThreadContext's memory ports (Functional/Virtual
// Ports)
ThreadID size = thread.size();
for (ThreadID i = 0; i < size; ++i)
thread[i]->connectMemPorts(thread[i]->getTC());
}
template <class Impl> template <class Impl>
void void
FullO3CPU<Impl>::trap(Fault fault, ThreadID tid, StaticInstPtr inst) FullO3CPU<Impl>::trap(Fault fault, ThreadID tid, StaticInstPtr inst)
@ -1166,7 +1216,7 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
activityRec.reset(); activityRec.reset();
BaseCPU::takeOverFrom(oldCPU, fetch.getIcachePort(), iew.getDcachePort()); BaseCPU::takeOverFrom(oldCPU, &icachePort, &dcachePort);
fetch.takeOverFrom(); fetch.takeOverFrom();
decode.takeOverFrom(); decode.takeOverFrom();

View file

@ -1,4 +1,16 @@
/* /*
* Copyright (c) 2011 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2004-2005 The Regents of The University of Michigan * Copyright (c) 2004-2005 The Regents of The University of Michigan
* Copyright (c) 2011 Regents of the University of California * Copyright (c) 2011 Regents of the University of California
* All rights reserved. * All rights reserved.
@ -117,6 +129,68 @@ class FullO3CPU : public BaseO3CPU
Status _threadStatus[Impl::MaxThreads]; Status _threadStatus[Impl::MaxThreads];
private: private:
/**
* IcachePort class for instruction fetch.
*/
class IcachePort : public CpuPort
{
protected:
/** Pointer to fetch. */
DefaultFetch<Impl> *fetch;
public:
/** Default constructor. */
IcachePort(DefaultFetch<Impl> *_fetch, FullO3CPU<Impl>* _cpu)
: CpuPort(_fetch->name() + "-iport", _cpu), fetch(_fetch)
{ }
protected:
/** Timing version of receive. Handles setting fetch to the
* proper status to start fetching. */
virtual bool recvTiming(PacketPtr pkt);
/** Handles doing a retry of a failed fetch. */
virtual void recvRetry();
};
/**
* DcachePort class for the load/store queue.
*/
class DcachePort : public CpuPort
{
protected:
/** Pointer to LSQ. */
LSQ<Impl> *lsq;
public:
/** Default constructor. */
DcachePort(LSQ<Impl> *_lsq, FullO3CPU<Impl>* _cpu)
: CpuPort(_lsq->name() + "-dport", _cpu), lsq(_lsq)
{ }
protected:
/** Timing version of receive. Handles writing back and
* completing the load or store that has returned from
* memory. */
virtual bool recvTiming(PacketPtr pkt);
/** Handles doing a retry of the previous send. */
virtual void recvRetry();
/**
* As this CPU requires snooping to maintain the load store queue
* change the behaviour from the base CPU port.
*
* @return true since we have to snoop
*/
virtual bool isSnooping()
{ return true; }
};
class TickEvent : public Event class TickEvent : public Event
{ {
private: private:
@ -391,10 +465,6 @@ class FullO3CPU : public BaseO3CPU
/** Halts the CPU. */ /** Halts the CPU. */
void halt() { panic("Halt not implemented!\n"); } void halt() { panic("Halt not implemented!\n"); }
/** Update the Virt and Phys ports of all ThreadContexts to
* reflect change in memory connections. */
void updateMemPorts();
/** Check if this address is a valid instruction address. */ /** Check if this address is a valid instruction address. */
bool validInstAddr(Addr addr) { return true; } bool validInstAddr(Addr addr) { return true; }
@ -565,6 +635,12 @@ class FullO3CPU : public BaseO3CPU
TheISA::ISA isa[Impl::MaxThreads]; TheISA::ISA isa[Impl::MaxThreads];
/** Instruction port. Note that it has to appear after the fetch stage. */
IcachePort icachePort;
/** Data port. Note that it has to appear after the iew stages */
DcachePort dcachePort;
public: public:
/** Enum to give each stage a specific index, so when calling /** Enum to give each stage a specific index, so when calling
* activateStage() or deactivateStage(), they can specify which stage * activateStage() or deactivateStage(), they can specify which stage
@ -701,8 +777,11 @@ class FullO3CPU : public BaseO3CPU
data, store_idx); data, store_idx);
} }
/** Used by the fetch unit to get a hold of the instruction port. */
Port* getIcachePort() { return &icachePort; }
/** Get the dcache port (used to find block size for translations). */ /** Get the dcache port (used to find block size for translations). */
Port *getDcachePort() { return this->iew.ldstQueue.getDcachePort(); } Port* getDcachePort() { return &dcachePort; }
Addr lockAddr; Addr lockAddr;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010 ARM Limited * Copyright (c) 2010-2011 ARM Limited
* All rights reserved * All rights reserved
* *
* The license below extends only to copyright in the software and shall * The license below extends only to copyright in the software and shall
@ -85,48 +85,6 @@ class DefaultFetch
typedef TheISA::MachInst MachInst; typedef TheISA::MachInst MachInst;
typedef TheISA::ExtMachInst ExtMachInst; typedef TheISA::ExtMachInst ExtMachInst;
/** IcachePort class for DefaultFetch. Handles doing the
* communication with the cache/memory.
*/
class IcachePort : public Port
{
protected:
/** Pointer to fetch. */
DefaultFetch<Impl> *fetch;
public:
/** Default constructor. */
IcachePort(DefaultFetch<Impl> *_fetch)
: Port(_fetch->name() + "-iport", _fetch->cpu), fetch(_fetch)
{ }
bool snoopRangeSent;
virtual void setPeer(Port *port);
protected:
/** Atomic version of receive. Panics. */
virtual Tick recvAtomic(PacketPtr pkt);
/** Functional version of receive. Panics. */
virtual void recvFunctional(PacketPtr pkt);
/** Receives status change. Other than range changing, panics. */
virtual void recvStatusChange(Status status);
/** Returns the address ranges of this device. */
virtual void getDeviceAddressRanges(AddrRangeList &resp,
bool &snoop)
{ resp.clear(); snoop = true; }
/** Timing version of receive. Handles setting fetch to the
* proper status to start fetching. */
virtual bool recvTiming(PacketPtr pkt);
/** Handles doing a retry of a failed fetch. */
virtual void recvRetry();
};
class FetchTranslation : public BaseTLB::Translation class FetchTranslation : public BaseTLB::Translation
{ {
protected: protected:
@ -248,9 +206,6 @@ class DefaultFetch
/** Registers statistics. */ /** Registers statistics. */
void regStats(); void regStats();
/** Returns the icache port. */
Port *getIcachePort() { return icachePort; }
/** Sets the main backwards communication time buffer pointer. */ /** Sets the main backwards communication time buffer pointer. */
void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer); void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer);
@ -266,6 +221,9 @@ class DefaultFetch
/** Tells the fetch stage that the Icache is set. */ /** Tells the fetch stage that the Icache is set. */
void setIcache(); void setIcache();
/** Handles retrying the fetch access. */
void recvRetry();
/** Processes cache completion event. */ /** Processes cache completion event. */
void processCacheCompletion(PacketPtr pkt); void processCacheCompletion(PacketPtr pkt);
@ -389,9 +347,6 @@ class DefaultFetch
StaticInstPtr curMacroop, TheISA::PCState thisPC, StaticInstPtr curMacroop, TheISA::PCState thisPC,
TheISA::PCState nextPC, bool trace); TheISA::PCState nextPC, bool trace);
/** Handles retrying the fetch access. */
void recvRetry();
/** Returns the appropriate thread to fetch, given the fetch policy. */ /** Returns the appropriate thread to fetch, given the fetch policy. */
ThreadID getFetchingThread(FetchPriority &fetch_priority); ThreadID getFetchingThread(FetchPriority &fetch_priority);
@ -440,9 +395,6 @@ class DefaultFetch
/** Wire used to write any information heading to decode. */ /** Wire used to write any information heading to decode. */
typename TimeBuffer<FetchStruct>::wire toDecode; typename TimeBuffer<FetchStruct>::wire toDecode;
/** Icache interface. */
IcachePort *icachePort;
/** BPredUnit. */ /** BPredUnit. */
BPredUnit branchPred; BPredUnit branchPred;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010 ARM Limited * Copyright (c) 2010-2011 ARM Limited
* All rights reserved. * All rights reserved.
* *
* The license below extends only to copyright in the software and shall * The license below extends only to copyright in the software and shall
@ -68,68 +68,6 @@
using namespace std; using namespace std;
template<class Impl>
void
DefaultFetch<Impl>::IcachePort::setPeer(Port *port)
{
Port::setPeer(port);
fetch->setIcache();
}
template<class Impl>
Tick
DefaultFetch<Impl>::IcachePort::recvAtomic(PacketPtr pkt)
{
panic("DefaultFetch doesn't expect recvAtomic callback!");
return curTick();
}
template<class Impl>
void
DefaultFetch<Impl>::IcachePort::recvFunctional(PacketPtr pkt)
{
DPRINTF(Fetch, "DefaultFetch doesn't update its state from a "
"functional call.\n");
}
template<class Impl>
void
DefaultFetch<Impl>::IcachePort::recvStatusChange(Status status)
{
if (status == RangeChange) {
if (!snoopRangeSent) {
snoopRangeSent = true;
sendStatusChange(Port::RangeChange);
}
return;
}
panic("DefaultFetch doesn't expect recvStatusChange callback!");
}
template<class Impl>
bool
DefaultFetch<Impl>::IcachePort::recvTiming(PacketPtr pkt)
{
DPRINTF(Fetch, "Received timing\n");
if (pkt->isResponse()) {
// We shouldn't ever get a block in ownership state
assert(!(pkt->memInhibitAsserted() && !pkt->sharedAsserted()));
fetch->processCacheCompletion(pkt);
}
//else Snooped a coherence request, just return
return true;
}
template<class Impl>
void
DefaultFetch<Impl>::IcachePort::recvRetry()
{
fetch->recvRetry();
}
template<class Impl> template<class Impl>
DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params) DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params)
: cpu(_cpu), : cpu(_cpu),
@ -189,17 +127,6 @@ DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params)
// Get the size of an instruction. // Get the size of an instruction.
instSize = sizeof(TheISA::MachInst); instSize = sizeof(TheISA::MachInst);
// Name is finally available, so create the port.
icachePort = new IcachePort(this);
icachePort->snoopRangeSent = false;
#if USE_CHECKER
if (cpu->checker) {
cpu->checker->setIcachePort(icachePort);
}
#endif
} }
template <class Impl> template <class Impl>
@ -402,8 +329,10 @@ template<class Impl>
void void
DefaultFetch<Impl>::setIcache() DefaultFetch<Impl>::setIcache()
{ {
assert(cpu->getIcachePort()->isConnected());
// Size of cache block. // Size of cache block.
cacheBlkSize = icachePort->peerBlockSize(); cacheBlkSize = cpu->getIcachePort()->peerBlockSize();
// Create mask to get rid of offset bits. // Create mask to get rid of offset bits.
cacheBlkMask = (cacheBlkSize - 1); cacheBlkMask = (cacheBlkSize - 1);
@ -494,6 +423,10 @@ template <class Impl>
void void
DefaultFetch<Impl>::takeOverFrom() DefaultFetch<Impl>::takeOverFrom()
{ {
// the instruction port is now connected so we can get the block
// size
setIcache();
// Reset all state // Reset all state
for (ThreadID i = 0; i < Impl::MaxThreads; ++i) { for (ThreadID i = 0; i < Impl::MaxThreads; ++i) {
stalls[i].decode = 0; stalls[i].decode = 0;
@ -684,7 +617,7 @@ DefaultFetch<Impl>::finishTranslation(Fault fault, RequestPtr mem_req)
fetchedCacheLines++; fetchedCacheLines++;
// Access the cache. // Access the cache.
if (!icachePort->sendTiming(data_pkt)) { if (!cpu->getIcachePort()->sendTiming(data_pkt)) {
assert(retryPkt == NULL); assert(retryPkt == NULL);
assert(retryTid == InvalidThreadID); assert(retryTid == InvalidThreadID);
DPRINTF(Fetch, "[tid:%i] Out of MSHRs!\n", tid); DPRINTF(Fetch, "[tid:%i] Out of MSHRs!\n", tid);
@ -1403,7 +1336,7 @@ DefaultFetch<Impl>::recvRetry()
assert(retryTid != InvalidThreadID); assert(retryTid != InvalidThreadID);
assert(fetchStatus[retryTid] == IcacheWaitRetry); assert(fetchStatus[retryTid] == IcacheWaitRetry);
if (icachePort->sendTiming(retryPkt)) { if (cpu->getIcachePort()->sendTiming(retryPkt)) {
fetchStatus[retryTid] = IcacheWaitResponse; fetchStatus[retryTid] = IcacheWaitResponse;
retryPkt = NULL; retryPkt = NULL;
retryTid = InvalidThreadID; retryTid = InvalidThreadID;

View file

@ -138,9 +138,6 @@ class DefaultIEW
/** Initializes stage; sends back the number of free IQ and LSQ entries. */ /** Initializes stage; sends back the number of free IQ and LSQ entries. */
void initStage(); void initStage();
/** Returns the dcache port. */
Port *getDcachePort() { return ldstQueue.getDcachePort(); }
/** Sets main time buffer used for backwards communication. */ /** Sets main time buffer used for backwards communication. */
void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr); void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);

View file

@ -1,4 +1,16 @@
/* /*
* Copyright (c) 2011 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2004-2006 The Regents of The University of Michigan * Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved. * All rights reserved.
* *
@ -65,13 +77,6 @@ class LSQ {
/** Registers statistics of each LSQ unit. */ /** Registers statistics of each LSQ unit. */
void regStats(); void regStats();
/** Returns dcache port.
* @todo: Dcache port needs to be moved up to this level for SMT
* to work. For now it just returns the port from one of the
* threads.
*/
Port *getDcachePort() { return &dcachePort; }
/** Sets the pointer to the list of active threads. */ /** Sets the pointer to the list of active threads. */
void setActiveThreads(std::list<ThreadID> *at_ptr); void setActiveThreads(std::list<ThreadID> *at_ptr);
/** Switches out the LSQ. */ /** Switches out the LSQ. */
@ -281,61 +286,25 @@ class LSQ {
Fault write(RequestPtr req, RequestPtr sreqLow, RequestPtr sreqHigh, Fault write(RequestPtr req, RequestPtr sreqLow, RequestPtr sreqHigh,
uint8_t *data, int store_idx); uint8_t *data, int store_idx);
/**
* Retry the previous send that failed.
*/
void recvRetry();
/**
* Handles writing back and completing the load or store that has
* returned from memory.
*
* @param pkt Response packet from the memory sub-system
*/
bool recvTiming(PacketPtr pkt);
/** The CPU pointer. */ /** The CPU pointer. */
O3CPU *cpu; O3CPU *cpu;
/** The IEW stage pointer. */ /** The IEW stage pointer. */
IEW *iewStage; IEW *iewStage;
/** DcachePort class for this LSQ. Handles doing the
* communication with the cache/memory.
*/
class DcachePort : public Port
{
protected:
/** Pointer to LSQ. */
LSQ *lsq;
public:
/** Default constructor. */
DcachePort(LSQ *_lsq)
: Port(_lsq->name() + "-dport", _lsq->cpu), lsq(_lsq)
{ }
bool snoopRangeSent;
virtual void setPeer(Port *port);
protected:
/** Atomic version of receive. Panics. */
virtual Tick recvAtomic(PacketPtr pkt);
/** Functional version of receive. Panics. */
virtual void recvFunctional(PacketPtr pkt);
/** Receives status change. Other than range changing, panics. */
virtual void recvStatusChange(Status status);
/** Returns the address ranges of this device. */
virtual void getDeviceAddressRanges(AddrRangeList &resp,
bool &snoop)
{ resp.clear(); snoop = true; }
/** Timing version of receive. Handles writing back and
* completing the load or store that has returned from
* memory. */
virtual bool recvTiming(PacketPtr pkt);
/** Handles doing a retry of the previous send. */
virtual void recvRetry();
};
/** D-cache port. */
DcachePort dcachePort;
/** Tell the CPU to update the Phys and Virt ports. */
void updateMemPorts() { cpu->updateMemPorts(); }
protected: protected:
/** The LSQ policy for SMT mode. */ /** The LSQ policy for SMT mode. */
LSQPolicy lsqPolicy; LSQPolicy lsqPolicy;

View file

@ -1,4 +1,16 @@
/* /*
* Copyright (c) 2011 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2005-2006 The Regents of The University of Michigan * Copyright (c) 2005-2006 The Regents of The University of Michigan
* All rights reserved. * All rights reserved.
* *
@ -40,96 +52,14 @@
using namespace std; using namespace std;
template<class Impl>
void
LSQ<Impl>::DcachePort::setPeer(Port *port)
{
Port::setPeer(port);
// Update the ThreadContext's memory ports (Functional/Virtual
// Ports)
lsq->updateMemPorts();
}
template <class Impl>
Tick
LSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
{
panic("O3CPU model does not work with atomic mode!");
return curTick();
}
template <class Impl>
void
LSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt)
{
DPRINTF(LSQ, "LSQ doesn't update things on a recvFunctional.\n");
}
template <class Impl>
void
LSQ<Impl>::DcachePort::recvStatusChange(Status status)
{
if (status == RangeChange) {
if (!snoopRangeSent) {
snoopRangeSent = true;
sendStatusChange(Port::RangeChange);
}
return;
}
panic("O3CPU doesn't expect recvStatusChange callback!");
}
template <class Impl>
bool
LSQ<Impl>::DcachePort::recvTiming(PacketPtr pkt)
{
if (pkt->isError())
DPRINTF(LSQ, "Got error packet back for address: %#X\n", pkt->getAddr());
if (pkt->isResponse()) {
lsq->thread[pkt->req->threadId()].completeDataAccess(pkt);
} else {
DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(),
pkt->cmdString());
// must be a snoop
if (pkt->isInvalidate()) {
DPRINTF(LSQ, "received invalidation for addr:%#x\n", pkt->getAddr());
for (ThreadID tid = 0; tid < lsq->numThreads; tid++) {
lsq->thread[tid].checkSnoop(pkt);
}
}
// to provide stronger consistency model
}
return true;
}
template <class Impl>
void
LSQ<Impl>::DcachePort::recvRetry()
{
if (lsq->retryTid == -1)
{
//Squashed, so drop it
return;
}
int curr_retry_tid = lsq->retryTid;
// Speculatively clear the retry Tid. This will get set again if
// the LSQUnit was unable to complete its access.
lsq->retryTid = -1;
lsq->thread[curr_retry_tid].recvRetry();
}
template <class Impl> template <class Impl>
LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
: cpu(cpu_ptr), iewStage(iew_ptr), dcachePort(this), : cpu(cpu_ptr), iewStage(iew_ptr),
LQEntries(params->LQEntries), LQEntries(params->LQEntries),
SQEntries(params->SQEntries), SQEntries(params->SQEntries),
numThreads(params->numThreads), numThreads(params->numThreads),
retryTid(-1) retryTid(-1)
{ {
dcachePort.snoopRangeSent = false;
//**********************************************/ //**********************************************/
//************ Handle SMT Parameters ***********/ //************ Handle SMT Parameters ***********/
//**********************************************/ //**********************************************/
@ -181,7 +111,7 @@ LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
for (ThreadID tid = 0; tid < numThreads; tid++) { for (ThreadID tid = 0; tid < numThreads; tid++) {
thread[tid].init(cpu, iew_ptr, params, this, thread[tid].init(cpu, iew_ptr, params, this,
maxLQEntries, maxSQEntries, tid); maxLQEntries, maxSQEntries, tid);
thread[tid].setDcachePort(&dcachePort); thread[tid].setDcachePort(cpu_ptr->getDcachePort());
} }
} }
@ -371,6 +301,48 @@ LSQ<Impl>::violation()
return false; return false;
} }
template <class Impl>
void
LSQ<Impl>::recvRetry()
{
if (retryTid == InvalidThreadID)
{
//Squashed, so drop it
return;
}
int curr_retry_tid = retryTid;
// Speculatively clear the retry Tid. This will get set again if
// the LSQUnit was unable to complete its access.
retryTid = -1;
thread[curr_retry_tid].recvRetry();
}
template <class Impl>
bool
LSQ<Impl>::recvTiming(PacketPtr pkt)
{
if (pkt->isError())
DPRINTF(LSQ, "Got error packet back for address: %#X\n",
pkt->getAddr());
if (pkt->isResponse()) {
thread[pkt->req->threadId()].completeDataAccess(pkt);
} else {
DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(),
pkt->cmdString());
// must be a snoop
if (pkt->isInvalidate()) {
DPRINTF(LSQ, "received invalidation for addr:%#x\n",
pkt->getAddr());
for (ThreadID tid = 0; tid < numThreads; tid++) {
thread[tid].checkSnoop(pkt);
}
}
// to provide stronger consistency model
}
return true;
}
template<class Impl> template<class Impl>
int int
LSQ<Impl>::getCount() LSQ<Impl>::getCount()

View file

@ -96,17 +96,18 @@ class O3ThreadContext : public ThreadContext
virtual TheISA::Kernel::Statistics *getKernelStats() virtual TheISA::Kernel::Statistics *getKernelStats()
{ return thread->kernelStats; } { return thread->kernelStats; }
virtual void connectMemPorts(ThreadContext *tc)
{ thread->connectMemPorts(tc); }
/** Returns a pointer to this thread's process. */ /** Returns a pointer to this thread's process. */
virtual Process *getProcessPtr() { return thread->getProcessPtr(); } virtual Process *getProcessPtr() { return thread->getProcessPtr(); }
virtual TranslatingPort *getMemPort() { return thread->getMemPort(); } virtual PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
virtual VirtualPort *getVirtPort(); virtual FSTranslatingPortProxy* getVirtProxy();
virtual FunctionalPort *getPhysPort() { return thread->getPhysPort(); } virtual void initMemProxies(ThreadContext *tc)
{ thread->initMemProxies(tc); }
virtual SETranslatingPortProxy* getMemProxy()
{ return thread->getMemProxy(); }
/** Returns this thread's status. */ /** Returns this thread's status. */
virtual Status status() const { return thread->status(); } virtual Status status() const { return thread->status(); }

View file

@ -49,10 +49,10 @@
#include "debug/O3CPU.hh" #include "debug/O3CPU.hh"
template <class Impl> template <class Impl>
VirtualPort * FSTranslatingPortProxy*
O3ThreadContext<Impl>::getVirtPort() O3ThreadContext<Impl>::getVirtProxy()
{ {
return thread->getVirtPort(); return thread->getVirtProxy();
} }
template <class Impl> template <class Impl>

View file

@ -114,12 +114,12 @@ class OzoneCPU : public BaseCPU
Process *getProcessPtr() { return thread->getProcessPtr(); } Process *getProcessPtr() { return thread->getProcessPtr(); }
TranslatingPort *getMemPort() { return thread->getMemPort(); } PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
VirtualPort *getVirtPort() FSTranslatingPortProxy* getVirtProxy()
{ return thread->getVirtPort(); } { return thread->getVirtProxy(); }
FunctionalPort *getPhysPort() { return thread->getPhysPort(); } SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); }
Status status() const { return thread->status(); } Status status() const { return thread->status(); }

View file

@ -186,25 +186,7 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
frontEnd->renameTable.copyFrom(thread.renameTable); frontEnd->renameTable.copyFrom(thread.renameTable);
backEnd->renameTable.copyFrom(thread.renameTable); backEnd->renameTable.copyFrom(thread.renameTable);
if (FullSystem) { thread.connectMemPorts(tc);
Port *mem_port;
FunctionalPort *phys_port;
VirtualPort *virt_port;
phys_port = new FunctionalPort(csprintf("%s-%d-funcport",
name(), 0));
mem_port = system->physmem->getPort("functional");
mem_port->setPeer(phys_port);
phys_port->setPeer(mem_port);
virt_port = new VirtualPort(csprintf("%s-%d-vport",
name(), 0));
mem_port = system->physmem->getPort("functional");
mem_port->setPeer(virt_port);
virt_port->setPeer(mem_port);
thread.setPhysPort(phys_port);
thread.setVirtPort(virt_port);
}
DPRINTF(OzoneCPU, "OzoneCPU: Created Ozone cpu object.\n"); DPRINTF(OzoneCPU, "OzoneCPU: Created Ozone cpu object.\n");
} }

View file

@ -87,13 +87,8 @@ class FrontEnd
/** Functional version of receive. Panics. */ /** Functional version of receive. Panics. */
virtual void recvFunctional(PacketPtr pkt); virtual void recvFunctional(PacketPtr pkt);
/** Receives status change. Other than range changing, panics. */ /** Receives range change. */
virtual void recvStatusChange(Status status); virtual void recvRangeChange();
/** Returns the address ranges of this device. */
virtual void getDeviceAddressRanges(AddrRangeList &resp,
bool &snoop)
{ resp.clear(); snoop = true; }
/** Timing version of receive. Handles setting fetch to the /** Timing version of receive. Handles setting fetch to the
* proper status to start fetching. */ * proper status to start fetching. */

View file

@ -64,12 +64,8 @@ FrontEnd<Impl>::IcachePort::recvFunctional(PacketPtr pkt)
template<class Impl> template<class Impl>
void void
FrontEnd<Impl>::IcachePort::recvStatusChange(Status status) FrontEnd<Impl>::IcachePort::recvRangeChange()
{ {
if (status == RangeChange)
return;
panic("FrontEnd doesn't expect recvStatusChange callback!");
} }
template<class Impl> template<class Impl>

View file

@ -255,11 +255,13 @@ class OzoneLWLSQ {
virtual void recvFunctional(PacketPtr pkt); virtual void recvFunctional(PacketPtr pkt);
virtual void recvStatusChange(Status status); virtual void recvRangeChange();
virtual void getDeviceAddressRanges(AddrRangeList &resp, /**
bool &snoop) * Is a snooper due to LSQ maintenance
{ resp.clear(); snoop = true; } */
virtual bool isSnooping()
{ return true; }
virtual bool recvTiming(PacketPtr pkt); virtual bool recvTiming(PacketPtr pkt);

Some files were not shown because too many files have changed in this diff Show more