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:
commit
c3d41a2def
717 changed files with 16788 additions and 13793 deletions
|
@ -32,11 +32,17 @@
|
|||
import m5
|
||||
from m5.objects import *
|
||||
from Caches import *
|
||||
from O3_ARM_v7a import *
|
||||
|
||||
def config_cache(options, system):
|
||||
if options.l2cache:
|
||||
system.l2 = L2Cache(size = options.l2_size, assoc = options.l2_assoc,
|
||||
block_size=options.cacheline_size)
|
||||
if options.cpu_type == "arm_detailed":
|
||||
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.l2.cpu_side = system.tol2bus.port
|
||||
system.l2.mem_side = system.membus.port
|
||||
|
@ -44,10 +50,21 @@ def config_cache(options, system):
|
|||
|
||||
for i in xrange(options.num_cpus):
|
||||
if options.caches:
|
||||
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 options.cpu_type == "arm_detailed":
|
||||
icache = O3_ARM_v7a_ICache(size = options.l1i_size,
|
||||
assoc = options.l1i_assoc,
|
||||
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':
|
||||
system.cpu[i].addPrivateSplitL1Caches(icache, dcache,
|
||||
PageTableWalkerCache(),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2010 ARM Limited
|
||||
# Copyright (c) 2010-2012 ARM Limited
|
||||
# All rights reserved.
|
||||
#
|
||||
# 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):
|
||||
IO_address_space_base = 0x80000000000
|
||||
class BaseTsunami(Tsunami):
|
||||
ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0)
|
||||
ide = IdeController(disks=[Parent.disk0, Parent.disk2],
|
||||
|
@ -68,10 +69,13 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
|||
self.readfile = mdesc.script()
|
||||
self.iobus = Bus(bus_id=0)
|
||||
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.bridge.side_a = self.iobus.port
|
||||
self.bridge.side_b = self.membus.port
|
||||
self.bridge.master = self.iobus.port
|
||||
self.bridge.slave = self.membus.port
|
||||
self.physmem.port = self.membus.port
|
||||
self.disk0 = CowIdeDisk(driveID='master')
|
||||
self.disk2 = CowIdeDisk(driveID='master')
|
||||
|
@ -80,7 +84,11 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
|||
self.tsunami = BaseTsunami()
|
||||
self.tsunami.attachIO(self.iobus)
|
||||
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.config = self.iobus.port
|
||||
self.tsunami.ethernet.dma = self.iobus.port
|
||||
self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(),
|
||||
read_only = True))
|
||||
self.intrctrl = IntrControl()
|
||||
|
@ -91,6 +99,8 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
|||
self.console = binary('console')
|
||||
self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
|
||||
|
||||
self.system_port = self.membus.port
|
||||
|
||||
return self
|
||||
|
||||
def makeLinuxAlphaRubySystem(mem_mode, mdesc = None):
|
||||
|
@ -123,7 +133,11 @@ def makeLinuxAlphaRubySystem(mem_mode, mdesc = None):
|
|||
self.tsunami = BaseTsunami()
|
||||
self.tsunami.attachIO(self.piobus)
|
||||
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.config = self.piobus.port
|
||||
self.tsunami.ethernet.dma = self.piobus.port
|
||||
|
||||
#
|
||||
# Store the dma devices for later connection to dma ruby ports.
|
||||
|
@ -144,6 +158,10 @@ def makeLinuxAlphaRubySystem(mem_mode, mdesc = None):
|
|||
return self
|
||||
|
||||
def makeSparcSystem(mem_mode, mdesc = None):
|
||||
# Constants from iob.cc and uart8250.cc
|
||||
iob_man_addr = 0x9800000000
|
||||
uart_pio_size = 8
|
||||
|
||||
class CowMmDisk(MmDisk):
|
||||
image = CowDiskImage(child=RawDiskImage(read_only=True),
|
||||
read_only=False)
|
||||
|
@ -164,8 +182,8 @@ def makeSparcSystem(mem_mode, mdesc = None):
|
|||
self.t1000.attachIO(self.iobus)
|
||||
self.physmem = PhysicalMemory(range = AddrRange(Addr('1MB'), size = '64MB'), zero = True)
|
||||
self.physmem2 = PhysicalMemory(range = AddrRange(Addr('2GB'), size ='256MB'), zero = True)
|
||||
self.bridge.side_a = self.iobus.port
|
||||
self.bridge.side_b = self.membus.port
|
||||
self.bridge.master = self.iobus.port
|
||||
self.bridge.slave = self.membus.port
|
||||
self.physmem.port = self.membus.port
|
||||
self.physmem2.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.childImage(disk('disk.s10hw2'))
|
||||
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.hypervisor_bin = binary('q_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.partition_desc_bin = binary('1up-md.bin')
|
||||
|
||||
self.system_port = self.membus.port
|
||||
|
||||
return self
|
||||
|
||||
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.badaddr_responder.warn_access = "warn"
|
||||
self.bridge = Bridge(delay='50ns', nack_delay='4ns')
|
||||
self.bridge.side_a = self.iobus.port
|
||||
self.bridge.side_b = self.membus.port
|
||||
self.bridge.master = self.iobus.port
|
||||
self.bridge.slave = self.membus.port
|
||||
|
||||
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.physmem.port = self.membus.port
|
||||
self.realview.attachOnChipIO(self.membus)
|
||||
self.realview.attachOnChipIO(self.membus, self.bridge)
|
||||
self.realview.attachIO(self.iobus)
|
||||
self.intrctrl = IntrControl()
|
||||
self.terminal = Terminal()
|
||||
self.vncserver = VncServer()
|
||||
|
||||
self.system_port = self.membus.port
|
||||
|
||||
return self
|
||||
|
||||
|
||||
|
@ -281,8 +322,8 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None):
|
|||
self.membus = MemBus(bus_id=1)
|
||||
self.bridge = Bridge(delay='50ns', nack_delay='4ns')
|
||||
self.physmem = PhysicalMemory(range = AddrRange('1GB'))
|
||||
self.bridge.side_a = self.iobus.port
|
||||
self.bridge.side_b = self.membus.port
|
||||
self.bridge.master = self.iobus.port
|
||||
self.bridge.slave = self.membus.port
|
||||
self.physmem.port = self.membus.port
|
||||
self.disk0 = CowIdeDisk(driveID='master')
|
||||
self.disk2 = CowIdeDisk(driveID='master')
|
||||
|
@ -291,7 +332,11 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None):
|
|||
self.malta = BaseMalta()
|
||||
self.malta.attachIO(self.iobus)
|
||||
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.config = self.iobus.port
|
||||
self.malta.ethernet.dma = self.iobus.port
|
||||
self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(),
|
||||
read_only = True))
|
||||
self.intrctrl = IntrControl()
|
||||
|
@ -301,6 +346,8 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None):
|
|||
self.console = binary('mips/console')
|
||||
self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
|
||||
|
||||
self.system_port = self.membus.port
|
||||
|
||||
return self
|
||||
|
||||
def x86IOAddress(port):
|
||||
|
@ -308,18 +355,48 @@ def x86IOAddress(port):
|
|||
return IO_address_space_base + port
|
||||
|
||||
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.physmem.port = x86_sys.membus.port
|
||||
|
||||
# North Bridge
|
||||
x86_sys.iobus = Bus(bus_id=0)
|
||||
x86_sys.bridge = Bridge(delay='50ns', nack_delay='4ns')
|
||||
x86_sys.bridge.side_a = x86_sys.iobus.port
|
||||
x86_sys.bridge.side_b = x86_sys.membus.port
|
||||
x86_sys.bridge.master = x86_sys.iobus.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
|
||||
x86_sys.pc.attachIO(x86_sys.iobus)
|
||||
|
||||
x86_sys.system_port = x86_sys.membus.port
|
||||
|
||||
def connectX86RubySystem(x86_sys):
|
||||
# North Bridge
|
||||
x86_sys.piobus = Bus(bus_id=0)
|
||||
|
|
199
configs/common/O3_ARM_v7a.py
Normal file
199
configs/common/O3_ARM_v7a.py
Normal 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
|
||||
|
||||
|
|
@ -28,7 +28,8 @@
|
|||
|
||||
# system options
|
||||
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")
|
||||
parser.add_option("-n", "--num-cpus", type="int", default=1)
|
||||
parser.add_option("--caches", action="store_true")
|
||||
|
|
|
@ -34,6 +34,7 @@ import m5
|
|||
from m5.defines import buildEnv
|
||||
from m5.objects import *
|
||||
from m5.util import *
|
||||
from O3_ARM_v7a import *
|
||||
|
||||
addToPath('../common')
|
||||
|
||||
|
@ -42,11 +43,14 @@ def setCPUClass(options):
|
|||
atomic = False
|
||||
if options.cpu_type == "timing":
|
||||
class TmpClass(TimingSimpleCPU): pass
|
||||
elif options.cpu_type == "detailed":
|
||||
if not options.caches:
|
||||
elif options.cpu_type == "detailed" or options.cpu_type == "arm_detailed":
|
||||
if not options.caches and not options.ruby:
|
||||
print "O3 CPU must be used with caches"
|
||||
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":
|
||||
if not options.caches:
|
||||
print "InOrder CPU must be used with caches"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2010 ARM Limited
|
||||
# Copyright (c) 2010-2011 ARM Limited
|
||||
# All rights reserved.
|
||||
#
|
||||
# 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)
|
||||
|
||||
if bm[0]:
|
||||
mem_size = bm[0].mem()
|
||||
else:
|
||||
mem_size = SysConfig().mem()
|
||||
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.cpu_side = test_sys.iobus.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):
|
||||
if options.fastmem:
|
||||
|
|
|
@ -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
|
||||
# All rights reserved.
|
||||
#
|
||||
|
@ -152,20 +164,13 @@ if options.cpu_type == "detailed" or options.cpu_type == "inorder":
|
|||
process += [smt_process, ]
|
||||
smt_idx += 1
|
||||
numThreads = len(workloads)
|
||||
|
||||
|
||||
if options.ruby:
|
||||
if options.cpu_type == "detailed":
|
||||
print >> sys.stderr, "Ruby only works with TimingSimpleCPU!!"
|
||||
if not (options.cpu_type == "detailed" or options.cpu_type == "timing"):
|
||||
print >> sys.stderr, "Ruby requires TimingSimpleCPU or O3CPU!!"
|
||||
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.numThreads = numThreads;
|
||||
|
||||
|
@ -179,7 +184,9 @@ if options.ruby:
|
|||
options.use_map = True
|
||||
Ruby.create_system(options, system)
|
||||
assert(options.num_cpus == len(system.ruby._cpu_ruby_ports))
|
||||
system.system_port = system.ruby._sys_port_proxy.port
|
||||
else:
|
||||
system.system_port = system.membus.port
|
||||
system.physmem.port = system.membus.port
|
||||
CacheConfig.config_cache(options, system)
|
||||
|
||||
|
|
|
@ -89,6 +89,8 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
|
|||
L1IcacheMemory = l1i_cache,
|
||||
L1DcacheMemory = l1d_cache,
|
||||
l2_select_num_bits = l2_bits,
|
||||
send_evictions = (
|
||||
options.cpu_type == "detailed"),
|
||||
ruby_system = ruby_system)
|
||||
|
||||
cpu_seq = RubySequencer(version = i,
|
||||
|
@ -151,7 +153,9 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
|
|||
cntrl_id = cntrl_count,
|
||||
directory = \
|
||||
RubyDirectoryMemory(version = i,
|
||||
size = dir_size),
|
||||
size = dir_size,
|
||||
use_map =
|
||||
options.use_map),
|
||||
memBuffer = mem_cntrl,
|
||||
ruby_system = ruby_system)
|
||||
|
||||
|
|
|
@ -81,6 +81,8 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
|
|||
l1_cntrl = L1Cache_Controller(version = i,
|
||||
cntrl_id = cntrl_count,
|
||||
cacheMemory = cache,
|
||||
send_evictions = (
|
||||
options.cpu_type == "detailed"),
|
||||
ruby_system = ruby_system)
|
||||
|
||||
cpu_seq = RubySequencer(version = i,
|
||||
|
|
|
@ -89,6 +89,8 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
|
|||
L1IcacheMemory = l1i_cache,
|
||||
L1DcacheMemory = l1d_cache,
|
||||
l2_select_num_bits = l2_bits,
|
||||
send_evictions = (
|
||||
options.cpu_type == "detailed"),
|
||||
ruby_system = ruby_system)
|
||||
|
||||
cpu_seq = RubySequencer(version = i,
|
||||
|
|
|
@ -111,6 +111,8 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
|
|||
not options.disable_dyn_timeouts,
|
||||
no_mig_atomic = not \
|
||||
options.allow_atomic_migration,
|
||||
send_evictions = (
|
||||
options.cpu_type == "detailed"),
|
||||
ruby_system = ruby_system)
|
||||
|
||||
cpu_seq = RubySequencer(version = i,
|
||||
|
|
|
@ -104,6 +104,8 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
|
|||
L2cacheMemory = l2_cache,
|
||||
no_mig_atomic = not \
|
||||
options.allow_atomic_migration,
|
||||
send_evictions = (
|
||||
options.cpu_type == "detailed"),
|
||||
ruby_system = ruby_system)
|
||||
|
||||
cpu_seq = RubySequencer(version = i,
|
||||
|
|
|
@ -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) 2009 Advanced Micro Devices, Inc.
|
||||
# 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
|
||||
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
|
||||
#
|
||||
|
@ -159,4 +182,5 @@ def create_system(options, system, piobus = None, dma_devices = []):
|
|||
ruby.profiler = ruby_profiler
|
||||
ruby.mem_size = total_mem_size
|
||||
ruby._cpu_ruby_ports = cpu_sequencers
|
||||
ruby._sys_port_proxy = sys_port_proxy
|
||||
ruby.random_seed = options.random_seed
|
||||
|
|
|
@ -41,9 +41,7 @@
|
|||
#include "arch/vtophys.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "mem/physical.hh"
|
||||
#include "mem/port.hh"
|
||||
#include "mem/vport.hh"
|
||||
#include "mem/fs_translating_port_proxy.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
|
||||
#define TIMER_FREQUENCY 1193180
|
||||
|
@ -78,8 +76,8 @@ FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc)
|
|||
ppc_vaddr = (Addr)tc->readIntReg(17);
|
||||
timer_vaddr = (Addr)tc->readIntReg(18);
|
||||
|
||||
virtPort->write(ppc_vaddr, (uint32_t)SimClock::Frequency);
|
||||
virtPort->write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
|
||||
virtProxy->write(ppc_vaddr, (uint32_t)SimClock::Frequency);
|
||||
virtProxy->write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -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->machine, "alpha");
|
||||
|
||||
name.copyOut(tc->getMemPort());
|
||||
name.copyOut(tc->getMemProxy());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
|||
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
||||
// I don't think this exactly matches the HW FPCR
|
||||
*fpcr = 0;
|
||||
fpcr.copyOut(tc->getMemPort());
|
||||
fpcr.copyOut(tc->getMemProxy());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
|||
case 14: { // SSI_IEEE_FP_CONTROL
|
||||
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
||||
// 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): "
|
||||
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
|
||||
return 0;
|
||||
|
|
|
@ -63,6 +63,17 @@ using namespace Linux;
|
|||
LinuxAlphaSystem::LinuxAlphaSystem(Params *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;
|
||||
|
||||
/**
|
||||
|
@ -77,8 +88,9 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
|
|||
* 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);
|
||||
virtProxy->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
|
||||
|
@ -86,8 +98,8 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
|
|||
* 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));
|
||||
virtProxy->write(addr, (uint64_t)(SimClock::Frequency /
|
||||
params()->boot_cpu_frequency));
|
||||
|
||||
|
||||
/**
|
||||
|
@ -97,7 +109,7 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
|
|||
* 255 ASNs.
|
||||
*/
|
||||
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
|
||||
panic("could not find dp264_mv\n");
|
||||
|
||||
|
@ -164,9 +176,9 @@ LinuxAlphaSystem::setDelayLoop(ThreadContext *tc)
|
|||
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
|
||||
Tick cpuFreq = tc->getCpuPtr()->frequency();
|
||||
assert(intrFreq);
|
||||
VirtualPort *vp;
|
||||
FSTranslatingPortProxy* vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
vp = tc->getVirtProxy();
|
||||
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,7 +128,14 @@ class LinuxAlphaSystem : public AlphaSystem
|
|||
LinuxAlphaSystem(Params *p);
|
||||
~LinuxAlphaSystem();
|
||||
|
||||
/**
|
||||
* Initialise the system
|
||||
*/
|
||||
virtual void initState();
|
||||
|
||||
void setDelayLoop(ThreadContext *tc);
|
||||
|
||||
const Params *params() const { return (const Params *)_params; }
|
||||
};
|
||||
|
||||
#endif // __ARCH_ALPHA_LINUX_SYSTEM_HH__
|
||||
|
|
|
@ -78,7 +78,7 @@ class ThreadInfo
|
|||
if (!addr)
|
||||
addr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23);
|
||||
|
||||
FunctionalPort *p = tc->getPhysPort();
|
||||
PortProxy* p = tc->getPhysProxy();
|
||||
p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
|
||||
|
||||
return sp & ~ULL(0x3fff);
|
||||
|
|
|
@ -188,7 +188,7 @@ RemoteGDB::acc(Addr va, size_t len)
|
|||
|
||||
Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20);
|
||||
PageTableEntry pte =
|
||||
kernel_pte_lookup(context->getPhysPort(), ptbr, va);
|
||||
kernel_pte_lookup(context->getPhysProxy(), ptbr, va);
|
||||
if (!pte.valid()) {
|
||||
DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -63,6 +63,8 @@ class RemoteGDB : public BaseRemoteGDB
|
|||
bool acc(Addr addr, size_t len);
|
||||
bool write(Addr addr, size_t size, const char *data);
|
||||
|
||||
virtual bool insertHardBreak(Addr addr, size_t len);
|
||||
|
||||
public:
|
||||
RemoteGDB(System *system, ThreadContext *context);
|
||||
};
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include "base/trace.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "mem/vport.hh"
|
||||
#include "mem/fs_translating_port_proxy.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
using namespace std;
|
||||
|
@ -48,7 +48,7 @@ ProcessInfo::ProcessInfo(ThreadContext *_tc)
|
|||
: tc(_tc)
|
||||
{
|
||||
Addr addr = 0;
|
||||
VirtualPort *vp = tc->getVirtPort();
|
||||
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
|
||||
|
||||
if (!symtab->findAddress("thread_info_size", addr))
|
||||
|
@ -81,9 +81,9 @@ ProcessInfo::task(Addr ksp) const
|
|||
|
||||
Addr tsk;
|
||||
|
||||
VirtualPort *vp;
|
||||
FSTranslatingPortProxy* vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
vp = tc->getVirtProxy();
|
||||
tsk = vp->readGtoH<Addr>(base + task_off);
|
||||
|
||||
return tsk;
|
||||
|
@ -98,9 +98,9 @@ ProcessInfo::pid(Addr ksp) const
|
|||
|
||||
uint16_t pd;
|
||||
|
||||
VirtualPort *vp;
|
||||
FSTranslatingPortProxy* vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
vp = tc->getVirtProxy();
|
||||
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
||||
|
||||
return pd;
|
||||
|
|
|
@ -38,8 +38,7 @@
|
|||
#include "base/loader/symtab.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "debug/Loader.hh"
|
||||
#include "mem/physical.hh"
|
||||
#include "mem/vport.hh"
|
||||
#include "mem/fs_translating_port_proxy.hh"
|
||||
#include "params/AlphaSystem.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
|
||||
|
@ -64,11 +63,30 @@ AlphaSystem::AlphaSystem(Params *p)
|
|||
pal = createObjectFile(params()->pal);
|
||||
if (pal == NULL)
|
||||
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
|
||||
pal->loadSections(functionalPort, loadAddrMask);
|
||||
console->loadSections(functionalPort, loadAddrMask);
|
||||
pal->loadSections(physProxy, loadAddrMask);
|
||||
console->loadSections(physProxy, loadAddrMask);
|
||||
|
||||
// load symbols
|
||||
if (!console->loadGlobalSymbols(consoleSymtab))
|
||||
|
@ -101,8 +119,8 @@ AlphaSystem::AlphaSystem(Params *p)
|
|||
* others do.)
|
||||
*/
|
||||
if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
|
||||
virtPort->writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
|
||||
strlen(params()->boot_osflags.c_str()));
|
||||
virtProxy->writeBlob(addr, (uint8_t*)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)) {
|
||||
uint64_t data;
|
||||
data = htog(params()->system_type);
|
||||
virtPort->write(addr+0x50, data);
|
||||
virtProxy->write(addr+0x50, data);
|
||||
data = htog(params()->system_rev);
|
||||
virtPort->write(addr+0x58, data);
|
||||
virtProxy->write(addr+0x58, data);
|
||||
} else
|
||||
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
|
||||
* 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
|
||||
const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16);
|
||||
|
||||
uint32_t i1 = virtPort->read<uint32_t>(addr);
|
||||
uint32_t i2 = virtPort->read<uint32_t>(addr + sizeof(MachInst));
|
||||
uint32_t i1 = virtProxy->read<uint32_t>(addr);
|
||||
uint32_t i2 = virtProxy->read<uint32_t>(addr + sizeof(MachInst));
|
||||
|
||||
if ((i1 & inst_mask) == gp_ldah_pattern &&
|
||||
(i2 & inst_mask) == gp_lda_pattern) {
|
||||
|
@ -188,7 +196,7 @@ AlphaSystem::setAlphaAccess(Addr access)
|
|||
{
|
||||
Addr addr = 0;
|
||||
if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
|
||||
virtPort->write(addr, htog(Phys2K0Seg(access)));
|
||||
virtProxy->write(addr, htog(Phys2K0Seg(access)));
|
||||
} else {
|
||||
panic("could not find m5AlphaAccess\n");
|
||||
}
|
||||
|
|
|
@ -50,6 +50,12 @@ class AlphaSystem : public System
|
|||
~AlphaSystem();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Initialise the state of the system.
|
||||
*/
|
||||
virtual void initState();
|
||||
|
||||
/**
|
||||
* Serialization stuff
|
||||
*/
|
||||
|
|
|
@ -55,7 +55,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
|||
strcpy(name->version, "732");
|
||||
strcpy(name->machine, "alpha");
|
||||
|
||||
name.copyOut(tc->getMemPort());
|
||||
name.copyOut(tc->getMemProxy());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -74,21 +74,21 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
|||
case AlphaTru64::GSI_MAX_CPU: {
|
||||
TypedBufferArg<uint32_t> max_cpu(bufPtr);
|
||||
*max_cpu = htog((uint32_t)process->numCpus());
|
||||
max_cpu.copyOut(tc->getMemPort());
|
||||
max_cpu.copyOut(tc->getMemProxy());
|
||||
return 1;
|
||||
}
|
||||
|
||||
case AlphaTru64::GSI_CPUS_IN_BOX: {
|
||||
TypedBufferArg<uint32_t> cpus_in_box(bufPtr);
|
||||
*cpus_in_box = htog((uint32_t)process->numCpus());
|
||||
cpus_in_box.copyOut(tc->getMemPort());
|
||||
cpus_in_box.copyOut(tc->getMemProxy());
|
||||
return 1;
|
||||
}
|
||||
|
||||
case AlphaTru64::GSI_PHYSMEM: {
|
||||
TypedBufferArg<uint64_t> physmem(bufPtr);
|
||||
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
|
||||
physmem.copyOut(tc->getMemPort());
|
||||
physmem.copyOut(tc->getMemProxy());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -105,14 +105,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
|||
infop->cpu_ex_binding = htog(0);
|
||||
infop->mhz = htog(667);
|
||||
|
||||
infop.copyOut(tc->getMemPort());
|
||||
infop.copyOut(tc->getMemProxy());
|
||||
return 1;
|
||||
}
|
||||
|
||||
case AlphaTru64::GSI_PROC_TYPE: {
|
||||
TypedBufferArg<uint64_t> proc_type(bufPtr);
|
||||
*proc_type = htog((uint64_t)11);
|
||||
proc_type.copyOut(tc->getMemPort());
|
||||
proc_type.copyOut(tc->getMemProxy());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -121,14 +121,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
|||
strncpy((char *)bufArg.bufferPtr(),
|
||||
"COMPAQ Professional Workstation XP1000",
|
||||
nbytes);
|
||||
bufArg.copyOut(tc->getMemPort());
|
||||
bufArg.copyOut(tc->getMemProxy());
|
||||
return 1;
|
||||
}
|
||||
|
||||
case AlphaTru64::GSI_CLK_TCK: {
|
||||
TypedBufferArg<uint64_t> clk_hz(bufPtr);
|
||||
*clk_hz = htog((uint64_t)1024);
|
||||
clk_hz.copyOut(tc->getMemPort());
|
||||
clk_hz.copyOut(tc->getMemProxy());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -193,7 +193,7 @@ tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
|||
elp->si_phz = htog(clk_hz);
|
||||
elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch?
|
||||
elp->si_max_procs = htog(process->numCpus());
|
||||
elp.copyOut(tc->getMemPort());
|
||||
elp.copyOut(tc->getMemProxy());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,9 +38,7 @@
|
|||
#include "cpu/thread_context.hh"
|
||||
#include "kern/tru64/tru64_events.hh"
|
||||
#include "kern/system_events.hh"
|
||||
#include "mem/physical.hh"
|
||||
#include "mem/port.hh"
|
||||
#include "mem/vport.hh"
|
||||
#include "mem/fs_translating_port_proxy.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -49,7 +47,7 @@ Tru64AlphaSystem::Tru64AlphaSystem(Tru64AlphaSystem::Params *p)
|
|||
{
|
||||
Addr addr = 0;
|
||||
if (kernelSymtab->findAddress("enable_async_printf", addr)) {
|
||||
virtPort->write(addr, (uint32_t)0);
|
||||
virtProxy->write(addr, (uint32_t)0);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include "arch/alpha/utility.hh"
|
||||
#include "arch/alpha/vtophys.hh"
|
||||
#include "mem/vport.hh"
|
||||
#include "mem/fs_translating_port_proxy.hh"
|
||||
#include "sim/full_system.hh"
|
||||
|
||||
namespace AlphaISA {
|
||||
|
@ -48,7 +48,7 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
|
|||
return tc->readIntReg(16 + number);
|
||||
} else {
|
||||
Addr sp = tc->readIntReg(StackPointerReg);
|
||||
VirtualPort *vp = tc->getVirtPort();
|
||||
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||
uint64_t arg = vp->read<uint64_t>(sp +
|
||||
(number-NumArgumentRegs) * sizeof(uint64_t));
|
||||
return arg;
|
||||
|
|
|
@ -38,14 +38,14 @@
|
|||
#include "base/trace.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "debug/VtoPhys.hh"
|
||||
#include "mem/vport.hh"
|
||||
#include "mem/port_proxy.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace AlphaISA {
|
||||
|
||||
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();
|
||||
PageTableEntry level1 = mem->read<uint64_t>(level1_pte);
|
||||
|
@ -103,7 +103,7 @@ vtophys(ThreadContext *tc, Addr addr)
|
|||
paddr = vaddr;
|
||||
} else {
|
||||
PageTableEntry pte =
|
||||
kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr);
|
||||
kernel_pte_lookup(tc->getPhysProxy(), ptbr, vaddr);
|
||||
if (pte.valid())
|
||||
paddr = pte.paddr() | vaddr.offset();
|
||||
}
|
||||
|
|
|
@ -37,11 +37,11 @@
|
|||
#include "arch/alpha/utility.hh"
|
||||
|
||||
class ThreadContext;
|
||||
class FunctionalPort;
|
||||
class PortProxy;
|
||||
|
||||
namespace AlphaISA {
|
||||
|
||||
PageTableEntry kernel_pte_lookup(FunctionalPort *mem, Addr ptbr,
|
||||
PageTableEntry kernel_pte_lookup(PortProxy* mem, Addr ptbr,
|
||||
VAddr vaddr);
|
||||
|
||||
Addr vtophys(Addr vaddr);
|
||||
|
|
|
@ -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->machine, "armv7l");
|
||||
|
||||
name.copyOut(tc->getMemPort());
|
||||
name.copyOut(tc->getMemProxy());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -452,7 +452,7 @@ setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
|||
int index = 0;
|
||||
uint32_t tlsPtr = process->getSyscallArg(tc, index);
|
||||
|
||||
tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
|
||||
tc->getMemProxy()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
|
||||
(uint8_t *)&tlsPtr, sizeof(tlsPtr));
|
||||
tc->setMiscReg(MISCREG_TPIDRURO,tlsPtr);
|
||||
return 0;
|
||||
|
@ -512,7 +512,7 @@ ArmLinuxProcess::initState()
|
|||
|
||||
// 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)) {
|
||||
tc->getMemPort()->writeBlob(commPage + addr,
|
||||
tc->getMemProxy()->writeBlob(commPage + addr,
|
||||
swiNeg1, sizeof(swiNeg1));
|
||||
}
|
||||
|
||||
|
@ -521,7 +521,7 @@ ArmLinuxProcess::initState()
|
|||
0x5f, 0xf0, 0x7f, 0xf5, // dmb
|
||||
0x0e, 0xf0, 0xa0, 0xe1 // return
|
||||
};
|
||||
tc->getMemPort()->writeBlob(commPage + 0x0fa0, memory_barrier,
|
||||
tc->getMemProxy()->writeBlob(commPage + 0x0fa0, memory_barrier,
|
||||
sizeof(memory_barrier));
|
||||
|
||||
uint8_t cmpxchg[] =
|
||||
|
@ -535,7 +535,7 @@ ArmLinuxProcess::initState()
|
|||
0x5f, 0xf0, 0x7f, 0xf5, // dmb
|
||||
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[] =
|
||||
{
|
||||
|
@ -543,7 +543,7 @@ ArmLinuxProcess::initState()
|
|||
0x70, 0x0f, 0x1d, 0xee, // mrc p15, 0, r0, c13, c0, 3
|
||||
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
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "cpu/thread_context.hh"
|
||||
#include "debug/Loader.hh"
|
||||
#include "kern/linux/events.hh"
|
||||
#include "mem/fs_translating_port_proxy.hh"
|
||||
#include "mem/physical.hh"
|
||||
|
||||
using namespace ArmISA;
|
||||
|
@ -57,6 +58,27 @@ using namespace Linux;
|
|||
LinuxArmSystem::LinuxArmSystem(Params *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
|
||||
// to do this perminately, for but early bootup work
|
||||
// it is helpfulp.
|
||||
|
@ -92,7 +114,7 @@ LinuxArmSystem::LinuxArmSystem(Params *p)
|
|||
DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2);
|
||||
DDUMP(Loader, boot_data, size << 2);
|
||||
|
||||
functionalPort->writeBlob(ParamsList, boot_data, size << 2);
|
||||
physProxy->writeBlob(ParamsList, boot_data, size << 2);
|
||||
|
||||
#ifndef NDEBUG
|
||||
kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
|
||||
|
@ -128,22 +150,6 @@ LinuxArmSystem::LinuxArmSystem(Params *p)
|
|||
secDataPtrAddr &= ~ULL(0x7F);
|
||||
secDataAddr &= ~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++) {
|
||||
threadContexts[i]->setIntReg(0, 0);
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
#include "cpu/thread_context.hh"
|
||||
#include "debug/Stack.hh"
|
||||
#include "mem/page_table.hh"
|
||||
#include "mem/translating_port.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
#include "sim/process_impl.hh"
|
||||
#include "sim/system.hh"
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include "base/trace.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "mem/vport.hh"
|
||||
#include "mem/fs_translating_port_proxy.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
using namespace std;
|
||||
|
@ -48,9 +48,9 @@ namespace ArmISA
|
|||
{
|
||||
Addr addr = 0;
|
||||
|
||||
VirtualPort *vp;
|
||||
FSTranslatingPortProxy* vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
vp = tc->getVirtProxy();
|
||||
|
||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "base/loader/symtab.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "mem/physical.hh"
|
||||
#include "mem/fs_translating_port_proxy.hh"
|
||||
|
||||
using namespace std;
|
||||
using namespace Linux;
|
||||
|
@ -55,6 +56,18 @@ ArmSystem::ArmSystem(Params *p)
|
|||
: System(p), bootldr(NULL)
|
||||
{
|
||||
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))
|
||||
fatal("If boot_loader is specifed, memory to load it must be also.\n");
|
||||
|
@ -65,29 +78,18 @@ ArmSystem::ArmSystem(Params *p)
|
|||
if (!bootldr)
|
||||
fatal("Could not read bootloader: %s\n", p->boot_loader);
|
||||
|
||||
Port *mem_port;
|
||||
FunctionalPort fp(name() + "-fport");
|
||||
mem_port = p->boot_loader_mem->getPort("functional");
|
||||
fp.setPeer(mem_port);
|
||||
mem_port->setPeer(&fp);
|
||||
|
||||
bootldr->loadSections(&fp);
|
||||
bootldr->loadSections(physProxy);
|
||||
bootldr->loadGlobalSymbols(debugSymbolTable);
|
||||
|
||||
uint8_t jump_to_bl[] =
|
||||
{
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ArmSystem::initState()
|
||||
{
|
||||
System::initState();
|
||||
if (bootldr) {
|
||||
// Put the address of the boot loader into r7 so we know
|
||||
// where to branch to after the reset fault
|
||||
|
@ -98,16 +100,16 @@ ArmSystem::initState()
|
|||
threadContexts[i]->setIntReg(5, params()->flags_addr);
|
||||
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");
|
||||
} else {
|
||||
// Set the initial PC to be at start of the kernel code
|
||||
threadContexts[0]->pcState(kernelEntry & loadAddrMask);
|
||||
}
|
||||
for (int i = 0; i < threadContexts.size(); i++) {
|
||||
if (params()->midr_regval) {
|
||||
if (p->midr_regval) {
|
||||
threadContexts[i]->setMiscReg(ArmISA::MISCREG_MIDR,
|
||||
params()->midr_regval);
|
||||
p->midr_regval);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,10 @@ class ArmSystem : public System
|
|||
ArmSystem(Params *p);
|
||||
~ArmSystem();
|
||||
|
||||
void initState();
|
||||
/**
|
||||
* Initialise the system
|
||||
*/
|
||||
virtual void initState();
|
||||
|
||||
/** Check if an address should be uncacheable until all caches are enabled.
|
||||
* This exits because coherence on some addresses at boot is maintained via
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#include "arch/arm/utility.hh"
|
||||
#include "arch/arm/vtophys.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "mem/vport.hh"
|
||||
#include "mem/fs_translating_port_proxy.hh"
|
||||
#include "sim/full_system.hh"
|
||||
|
||||
namespace ArmISA {
|
||||
|
@ -86,7 +86,7 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
|
|||
}
|
||||
} else {
|
||||
Addr sp = tc->readIntReg(StackPointerReg);
|
||||
VirtualPort *vp = tc->getVirtPort();
|
||||
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||
uint64_t arg;
|
||||
if (size == sizeof(uint64_t)) {
|
||||
// If the argument is even it must be aligned
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
#include "base/chunk_generator.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "mem/vport.hh"
|
||||
#include "mem/fs_translating_port_proxy.hh"
|
||||
|
||||
using namespace std;
|
||||
using namespace ArmISA;
|
||||
|
@ -101,7 +101,7 @@ ArmISA::vtophys(ThreadContext *tc, Addr addr)
|
|||
N = 0;
|
||||
}
|
||||
|
||||
FunctionalPort *port = tc->getPhysPort();
|
||||
PortProxy* port = tc->getPhysProxy();
|
||||
Addr l1desc_addr = mbits(ttbr, 31, 14-N) | (bits(addr,31-N,20) << 2);
|
||||
|
||||
TableWalker::L1Descriptor l1desc;
|
||||
|
|
|
@ -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->machine, "mips");
|
||||
|
||||
name.copyOut(tc->getMemPort());
|
||||
name.copyOut(tc->getMemProxy());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ sys_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
|||
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
||||
// I don't think this exactly matches the HW FPCR
|
||||
*fpcr = 0;
|
||||
fpcr.copyOut(tc->getMemPort());
|
||||
fpcr.copyOut(tc->getMemProxy());
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
|
@ -111,7 +111,7 @@ sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
|||
// SSI_IEEE_FP_CONTROL
|
||||
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
||||
// 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): "
|
||||
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
|
||||
return 0;
|
||||
|
|
|
@ -63,91 +63,10 @@ using namespace Linux;
|
|||
LinuxMipsSystem::LinuxMipsSystem(Params *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()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
delete kernelPanicEvent;
|
||||
#endif
|
||||
delete skipIdeDelay50msEvent;
|
||||
delete skipDelayLoopEvent;
|
||||
delete skipCacheProbeEvent;
|
||||
delete debugPrintkEvent;
|
||||
delete idleStartEvent;
|
||||
delete printThreadEvent;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ class ThreadInfo
|
|||
if (!addr)
|
||||
addr = tc->readMiscRegNoEffect(0/*MipsISA::IPR_PALtemp23*/);
|
||||
|
||||
FunctionalPort *p = tc->getPhysPort();
|
||||
PortProxy* p = tc->getPhysProxy();
|
||||
p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
|
||||
|
||||
return sp & ~ULL(0x3fff);
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include "base/trace.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "mem/vport.hh"
|
||||
#include "mem/fs_translating_port_proxy.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
using namespace std;
|
||||
|
@ -55,9 +55,9 @@ ProcessInfo::task(Addr ksp) const
|
|||
|
||||
Addr tsk;
|
||||
|
||||
VirtualPort *vp;
|
||||
FSTranslatingPortProxy* vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
vp = tc->getVirtProxy();
|
||||
tsk = vp->readGtoH<Addr>(base + task_off);
|
||||
|
||||
return tsk;
|
||||
|
@ -72,9 +72,9 @@ ProcessInfo::pid(Addr ksp) const
|
|||
|
||||
uint16_t pd;
|
||||
|
||||
VirtualPort *vp;
|
||||
FSTranslatingPortProxy* vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
vp = tc->getVirtProxy();
|
||||
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
||||
|
||||
return pd;
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#include "base/loader/symtab.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "mem/physical.hh"
|
||||
#include "mem/vport.hh"
|
||||
#include "params/MipsSystem.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
|
||||
|
@ -46,67 +45,6 @@ using namespace LittleEndianGuest;
|
|||
|
||||
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()
|
||||
|
|
|
@ -31,17 +31,16 @@
|
|||
#include <cmath>
|
||||
|
||||
#include "arch/mips/isa_traits.hh"
|
||||
#include "arch/mips/registers.hh"
|
||||
#include "arch/mips/utility.hh"
|
||||
#include "arch/mips/vtophys.hh"
|
||||
#include "base/bitfield.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "cpu/static_inst.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "mem/fs_translating_port_proxy.hh"
|
||||
#include "sim/serialize.hh"
|
||||
|
||||
#include "arch/mips/registers.hh"
|
||||
#include "arch/mips/vtophys.hh"
|
||||
#include "mem/vport.hh"
|
||||
|
||||
|
||||
using namespace MipsISA;
|
||||
using namespace std;
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#include "base/trace.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "debug/VtoPhys.hh"
|
||||
#include "mem/vport.hh"
|
||||
|
||||
using namespace std;
|
||||
using namespace MipsISA;
|
||||
|
|
|
@ -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->machine, "power");
|
||||
|
||||
name.copyOut(tc->getMemPort());
|
||||
name.copyOut(tc->getMemProxy());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include "cpu/thread_context.hh"
|
||||
#include "debug/Stack.hh"
|
||||
#include "mem/page_table.hh"
|
||||
#include "mem/translating_port.hh"
|
||||
#include "sim/process_impl.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
|
|
|
@ -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->machine, "sparc");
|
||||
|
||||
name.copyOut(tc->getMemPort());
|
||||
name.copyOut(tc->getMemProxy());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -69,19 +69,19 @@ getresuidFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
|||
if (ruid) {
|
||||
BufferArg ruidBuff(ruid, sizeof(IntReg));
|
||||
memcpy(ruidBuff.bufferPtr(), &id, sizeof(IntReg));
|
||||
ruidBuff.copyOut(tc->getMemPort());
|
||||
ruidBuff.copyOut(tc->getMemProxy());
|
||||
}
|
||||
// Set the euid
|
||||
if (euid) {
|
||||
BufferArg euidBuff(euid, sizeof(IntReg));
|
||||
memcpy(euidBuff.bufferPtr(), &id, sizeof(IntReg));
|
||||
euidBuff.copyOut(tc->getMemPort());
|
||||
euidBuff.copyOut(tc->getMemProxy());
|
||||
}
|
||||
// Set the suid
|
||||
if (suid) {
|
||||
BufferArg suidBuff(suid, sizeof(IntReg));
|
||||
memcpy(suidBuff.bufferPtr(), &id, sizeof(IntReg));
|
||||
suidBuff.copyOut(tc->getMemPort());
|
||||
suidBuff.copyOut(tc->getMemProxy());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
#include "cpu/thread_context.hh"
|
||||
#include "debug/Stack.hh"
|
||||
#include "mem/page_table.hh"
|
||||
#include "mem/translating_port.hh"
|
||||
#include "sim/process_impl.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
|
@ -448,7 +447,7 @@ void Sparc32LiveProcess::flushWindows(ThreadContext *tc)
|
|||
for (int index = 16; index < 32; index++) {
|
||||
uint32_t regVal = tc->readIntReg(index);
|
||||
regVal = htog(regVal);
|
||||
if (!tc->getMemPort()->tryWriteBlob(
|
||||
if (!tc->getMemProxy()->tryWriteBlob(
|
||||
sp + (index - 16) * 4, (uint8_t *)®Val, 4)) {
|
||||
warn("Failed to save register to the stack when "
|
||||
"flushing windows.\n");
|
||||
|
@ -483,7 +482,7 @@ Sparc64LiveProcess::flushWindows(ThreadContext *tc)
|
|||
for (int index = 16; index < 32; index++) {
|
||||
IntReg regVal = tc->readIntReg(index);
|
||||
regVal = htog(regVal);
|
||||
if (!tc->getMemPort()->tryWriteBlob(
|
||||
if (!tc->getMemProxy()->tryWriteBlob(
|
||||
sp + 2047 + (index - 16) * 8, (uint8_t *)®Val, 8)) {
|
||||
warn("Failed to save register to the stack when "
|
||||
"flushing windows.\n");
|
||||
|
|
|
@ -55,7 +55,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
|||
strcpy(name->version, "Generic_118558-21");
|
||||
strcpy(name->machine, "sun4u");
|
||||
|
||||
name.copyOut(tc->getMemPort());
|
||||
name.copyOut(tc->getMemProxy());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -40,10 +40,7 @@
|
|||
using namespace BigEndianGuest;
|
||||
|
||||
SparcSystem::SparcSystem(Params *p)
|
||||
: System(p), sysTick(0),funcRomPort(p->name + "-fromport"),
|
||||
funcNvramPort(p->name + "-fnvramport"),
|
||||
funcHypDescPort(p->name + "-fhypdescport"),
|
||||
funcPartDescPort(p->name + "-fpartdescport")
|
||||
: System(p), sysTick(0)
|
||||
{
|
||||
resetSymtab = new SymbolTable;
|
||||
hypervisorSymtab = new SymbolTable;
|
||||
|
@ -51,23 +48,13 @@ SparcSystem::SparcSystem(Params *p)
|
|||
nvramSymtab = new SymbolTable;
|
||||
hypervisorDescSymtab = new SymbolTable;
|
||||
partitionDescSymtab = new SymbolTable;
|
||||
}
|
||||
|
||||
Port *rom_port;
|
||||
rom_port = params()->rom->getPort("functional");
|
||||
funcRomPort.setPeer(rom_port);
|
||||
rom_port->setPeer(&funcRomPort);
|
||||
|
||||
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);
|
||||
void
|
||||
SparcSystem::initState()
|
||||
{
|
||||
// Call the initialisation of the super class
|
||||
System::initState();
|
||||
|
||||
/**
|
||||
* Load the boot code, and hypervisor into memory.
|
||||
|
@ -107,22 +94,22 @@ SparcSystem::SparcSystem(Params *p)
|
|||
|
||||
// Load reset binary into memory
|
||||
reset->setTextBase(params()->reset_addr);
|
||||
reset->loadSections(&funcRomPort);
|
||||
reset->loadSections(physProxy);
|
||||
// Load the openboot binary
|
||||
openboot->setTextBase(params()->openboot_addr);
|
||||
openboot->loadSections(&funcRomPort);
|
||||
openboot->loadSections(physProxy);
|
||||
// Load the hypervisor binary
|
||||
hypervisor->setTextBase(params()->hypervisor_addr);
|
||||
hypervisor->loadSections(&funcRomPort);
|
||||
hypervisor->loadSections(physProxy);
|
||||
// Load the nvram image
|
||||
nvram->setTextBase(params()->nvram_addr);
|
||||
nvram->loadSections(&funcNvramPort);
|
||||
nvram->loadSections(physProxy);
|
||||
// Load the hypervisor description image
|
||||
hypervisor_desc->setTextBase(params()->hypervisor_desc_addr);
|
||||
hypervisor_desc->loadSections(&funcHypDescPort);
|
||||
hypervisor_desc->loadSections(physProxy);
|
||||
// Load the partition description image
|
||||
partition_desc->setTextBase(params()->partition_desc_addr);
|
||||
partition_desc->loadSections(&funcPartDescPort);
|
||||
partition_desc->loadSections(physProxy);
|
||||
|
||||
// load symbols
|
||||
if (!reset->loadGlobalSymbols(resetSymtab))
|
||||
|
|
|
@ -48,6 +48,8 @@ class SparcSystem : public System
|
|||
SparcSystem(Params *p);
|
||||
~SparcSystem();
|
||||
|
||||
virtual void initState();
|
||||
|
||||
/**
|
||||
* Serialization stuff
|
||||
*/
|
||||
|
@ -94,18 +96,6 @@ class SparcSystem : public System
|
|||
/** System Tick for syncronized tick across all cpus. */
|
||||
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:
|
||||
const Params *params() const { return (const Params *)_params; }
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "arch/sparc/faults.hh"
|
||||
#include "arch/sparc/utility.hh"
|
||||
#include "arch/sparc/vtophys.hh"
|
||||
#include "mem/vport.hh"
|
||||
#include "mem/fs_translating_port_proxy.hh"
|
||||
|
||||
namespace SparcISA {
|
||||
|
||||
|
@ -52,7 +52,7 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
|
|||
return tc->readIntReg(8 + number);
|
||||
} else {
|
||||
Addr sp = tc->readIntReg(StackPointerReg);
|
||||
VirtualPort *vp = tc->getVirtPort();
|
||||
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||
uint64_t arg = vp->read<uint64_t>(sp + 92 +
|
||||
(number-NumArgumentRegs) * sizeof(uint64_t));
|
||||
return arg;
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include "base/trace.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "debug/VtoPhys.hh"
|
||||
#include "mem/vport.hh"
|
||||
#include "mem/port_proxy.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -81,7 +81,7 @@ vtophys(ThreadContext *tc, Addr addr)
|
|||
int pri_context = bits(tlbdata,47,32);
|
||||
// int sec_context = bits(tlbdata,63,48);
|
||||
|
||||
FunctionalPort *mem = tc->getPhysPort();
|
||||
PortProxy* mem = tc->getPhysProxy();
|
||||
TLB* itb = tc->getITBPtr();
|
||||
TLB* dtb = tc->getDTBPtr();
|
||||
TlbEntry* tbe;
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#include "arch/x86/isa_traits.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "base/types.hh"
|
||||
#include "mem/port.hh"
|
||||
#include "mem/port_proxy.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
|
||||
// Config entry types
|
||||
|
@ -70,10 +70,10 @@ const char X86ISA::IntelMP::FloatingPointer::signature[] = "_MP_";
|
|||
|
||||
template<class T>
|
||||
uint8_t
|
||||
writeOutField(FunctionalPort * port, Addr addr, T val)
|
||||
writeOutField(PortProxy* proxy, Addr addr, T 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;
|
||||
while(guestVal) {
|
||||
|
@ -84,7 +84,7 @@ writeOutField(FunctionalPort * port, Addr addr, T val)
|
|||
}
|
||||
|
||||
uint8_t
|
||||
writeOutString(FunctionalPort * port, Addr addr, string str, int length)
|
||||
writeOutString(PortProxy* proxy, Addr addr, string str, int length)
|
||||
{
|
||||
char cleanedString[length + 1];
|
||||
cleanedString[length] = 0;
|
||||
|
@ -97,7 +97,7 @@ writeOutString(FunctionalPort * port, Addr addr, string str, int length)
|
|||
memcpy(cleanedString, str.c_str(), 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;
|
||||
for (int i = 0; i < length; i++)
|
||||
|
@ -107,7 +107,7 @@ writeOutString(FunctionalPort * port, Addr addr, string str, int length)
|
|||
}
|
||||
|
||||
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
|
||||
// configuration was found but not both.
|
||||
|
@ -120,28 +120,28 @@ X86ISA::IntelMP::FloatingPointer::writeOut(FunctionalPort * port, Addr addr)
|
|||
|
||||
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++)
|
||||
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.
|
||||
uint8_t length = 1;
|
||||
port->writeBlob(addr + 8, &length, 1);
|
||||
proxy->writeBlob(addr + 8, &length, 1);
|
||||
checkSum += length;
|
||||
|
||||
port->writeBlob(addr + 9, &specRev, 1);
|
||||
proxy->writeBlob(addr + 9, &specRev, 1);
|
||||
checkSum += specRev;
|
||||
|
||||
port->writeBlob(addr + 11, &defaultConfig, 1);
|
||||
proxy->writeBlob(addr + 11, &defaultConfig, 1);
|
||||
checkSum += defaultConfig;
|
||||
|
||||
uint32_t features2_5 = imcrPresent ? (1 << 7) : 0;
|
||||
checkSum += writeOutField(port, addr + 12, features2_5);
|
||||
checkSum += writeOutField(proxy, addr + 12, features2_5);
|
||||
|
||||
checkSum = -checkSum;
|
||||
port->writeBlob(addr + 10, &checkSum, 1);
|
||||
proxy->writeBlob(addr + 10, &checkSum, 1);
|
||||
|
||||
return 16;
|
||||
}
|
||||
|
@ -158,10 +158,10 @@ X86IntelMPFloatingPointerParams::create()
|
|||
}
|
||||
|
||||
Addr
|
||||
X86ISA::IntelMP::BaseConfigEntry::writeOut(FunctionalPort * port,
|
||||
X86ISA::IntelMP::BaseConfigEntry::writeOut(PortProxy* proxy,
|
||||
Addr addr, uint8_t &checkSum)
|
||||
{
|
||||
port->writeBlob(addr, &type, 1);
|
||||
proxy->writeBlob(addr, &type, 1);
|
||||
checkSum += type;
|
||||
return 1;
|
||||
}
|
||||
|
@ -171,12 +171,12 @@ X86ISA::IntelMP::BaseConfigEntry::BaseConfigEntry(Params * p, uint8_t _type) :
|
|||
{}
|
||||
|
||||
Addr
|
||||
X86ISA::IntelMP::ExtConfigEntry::writeOut(FunctionalPort * port,
|
||||
X86ISA::IntelMP::ExtConfigEntry::writeOut(PortProxy* proxy,
|
||||
Addr addr, uint8_t &checkSum)
|
||||
{
|
||||
port->writeBlob(addr, &type, 1);
|
||||
proxy->writeBlob(addr, &type, 1);
|
||||
checkSum += type;
|
||||
port->writeBlob(addr + 1, &length, 1);
|
||||
proxy->writeBlob(addr + 1, &length, 1);
|
||||
checkSum += length;
|
||||
return 1;
|
||||
}
|
||||
|
@ -189,59 +189,59 @@ X86ISA::IntelMP::ExtConfigEntry::ExtConfigEntry(Params * p,
|
|||
const char X86ISA::IntelMP::ConfigTable::signature[] = "PCMP";
|
||||
|
||||
Addr
|
||||
X86ISA::IntelMP::ConfigTable::writeOut(FunctionalPort * port, Addr addr)
|
||||
X86ISA::IntelMP::ConfigTable::writeOut(PortProxy* proxy, Addr addr)
|
||||
{
|
||||
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++)
|
||||
checkSum += signature[i];
|
||||
|
||||
// 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;
|
||||
|
||||
// The checksum goes here but is still being calculated.
|
||||
|
||||
checkSum += writeOutString(port, addr + 8, oemID, 8);
|
||||
checkSum += writeOutString(port, addr + 16, productID, 12);
|
||||
checkSum += writeOutString(proxy, addr + 8, oemID, 8);
|
||||
checkSum += writeOutString(proxy, addr + 16, productID, 12);
|
||||
|
||||
checkSum += writeOutField(port, addr + 28, oemTableAddr);
|
||||
checkSum += writeOutField(port, addr + 32, oemTableSize);
|
||||
checkSum += writeOutField(port, addr + 34, (uint16_t)baseEntries.size());
|
||||
checkSum += writeOutField(port, addr + 36, localApic);
|
||||
checkSum += writeOutField(proxy, addr + 28, oemTableAddr);
|
||||
checkSum += writeOutField(proxy, addr + 32, oemTableSize);
|
||||
checkSum += writeOutField(proxy, addr + 34, (uint16_t)baseEntries.size());
|
||||
checkSum += writeOutField(proxy, addr + 36, localApic);
|
||||
|
||||
uint8_t reserved = 0;
|
||||
port->writeBlob(addr + 43, &reserved, 1);
|
||||
proxy->writeBlob(addr + 43, &reserved, 1);
|
||||
checkSum += reserved;
|
||||
|
||||
vector<BaseConfigEntry *>::iterator baseEnt;
|
||||
uint16_t offset = 44;
|
||||
for (baseEnt = baseEntries.begin();
|
||||
baseEnt != baseEntries.end(); baseEnt++) {
|
||||
offset += (*baseEnt)->writeOut(port, addr + offset, checkSum);
|
||||
offset += (*baseEnt)->writeOut(proxy, addr + offset, checkSum);
|
||||
}
|
||||
|
||||
// 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;
|
||||
uint16_t extOffset = 0;
|
||||
uint8_t extCheckSum = 0;
|
||||
for (extEnt = extEntries.begin();
|
||||
extEnt != extEntries.end(); extEnt++) {
|
||||
extOffset += (*extEnt)->writeOut(port,
|
||||
extOffset += (*extEnt)->writeOut(proxy,
|
||||
addr + offset + extOffset, extCheckSum);
|
||||
}
|
||||
|
||||
checkSum += writeOutField(port, addr + 40, extOffset);
|
||||
checkSum += writeOutField(proxy, addr + 40, extOffset);
|
||||
extCheckSum = -extCheckSum;
|
||||
checkSum += writeOutField(port, addr + 42, extCheckSum);
|
||||
checkSum += writeOutField(proxy, addr + 42, extCheckSum);
|
||||
|
||||
// And now, we finally have the whole check sum completed.
|
||||
checkSum = -checkSum;
|
||||
writeOutField(port, addr + 7, checkSum);
|
||||
writeOutField(proxy, addr + 7, checkSum);
|
||||
|
||||
return offset + extOffset;
|
||||
};
|
||||
|
@ -261,18 +261,18 @@ X86IntelMPConfigTableParams::create()
|
|||
|
||||
Addr
|
||||
X86ISA::IntelMP::Processor::writeOut(
|
||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
||||
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||
{
|
||||
BaseConfigEntry::writeOut(port, addr, checkSum);
|
||||
checkSum += writeOutField(port, addr + 1, localApicID);
|
||||
checkSum += writeOutField(port, addr + 2, localApicVersion);
|
||||
checkSum += writeOutField(port, addr + 3, cpuFlags);
|
||||
checkSum += writeOutField(port, addr + 4, cpuSignature);
|
||||
checkSum += writeOutField(port, addr + 8, featureFlags);
|
||||
BaseConfigEntry::writeOut(proxy, addr, checkSum);
|
||||
checkSum += writeOutField(proxy, addr + 1, localApicID);
|
||||
checkSum += writeOutField(proxy, addr + 2, localApicVersion);
|
||||
checkSum += writeOutField(proxy, addr + 3, cpuFlags);
|
||||
checkSum += writeOutField(proxy, addr + 4, cpuSignature);
|
||||
checkSum += writeOutField(proxy, addr + 8, featureFlags);
|
||||
|
||||
uint32_t reserved = 0;
|
||||
port->writeBlob(addr + 12, (uint8_t *)(&reserved), 4);
|
||||
port->writeBlob(addr + 16, (uint8_t *)(&reserved), 4);
|
||||
proxy->writeBlob(addr + 12, (uint8_t *)(&reserved), 4);
|
||||
proxy->writeBlob(addr + 16, (uint8_t *)(&reserved), 4);
|
||||
return 20;
|
||||
}
|
||||
|
||||
|
@ -298,11 +298,11 @@ X86IntelMPProcessorParams::create()
|
|||
|
||||
Addr
|
||||
X86ISA::IntelMP::Bus::writeOut(
|
||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
||||
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||
{
|
||||
BaseConfigEntry::writeOut(port, addr, checkSum);
|
||||
checkSum += writeOutField(port, addr + 1, busID);
|
||||
checkSum += writeOutString(port, addr + 2, busType, 6);
|
||||
BaseConfigEntry::writeOut(proxy, addr, checkSum);
|
||||
checkSum += writeOutField(proxy, addr + 1, busID);
|
||||
checkSum += writeOutString(proxy, addr + 2, busType, 6);
|
||||
return 8;
|
||||
}
|
||||
|
||||
|
@ -318,13 +318,13 @@ X86IntelMPBusParams::create()
|
|||
|
||||
Addr
|
||||
X86ISA::IntelMP::IOAPIC::writeOut(
|
||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
||||
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||
{
|
||||
BaseConfigEntry::writeOut(port, addr, checkSum);
|
||||
checkSum += writeOutField(port, addr + 1, id);
|
||||
checkSum += writeOutField(port, addr + 2, version);
|
||||
checkSum += writeOutField(port, addr + 3, flags);
|
||||
checkSum += writeOutField(port, addr + 4, address);
|
||||
BaseConfigEntry::writeOut(proxy, addr, checkSum);
|
||||
checkSum += writeOutField(proxy, addr + 1, id);
|
||||
checkSum += writeOutField(proxy, addr + 2, version);
|
||||
checkSum += writeOutField(proxy, addr + 3, flags);
|
||||
checkSum += writeOutField(proxy, addr + 4, address);
|
||||
return 8;
|
||||
}
|
||||
|
||||
|
@ -343,15 +343,15 @@ X86IntelMPIOAPICParams::create()
|
|||
|
||||
Addr
|
||||
X86ISA::IntelMP::IntAssignment::writeOut(
|
||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
||||
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||
{
|
||||
BaseConfigEntry::writeOut(port, addr, checkSum);
|
||||
checkSum += writeOutField(port, addr + 1, interruptType);
|
||||
checkSum += writeOutField(port, addr + 2, flags);
|
||||
checkSum += writeOutField(port, addr + 4, sourceBusID);
|
||||
checkSum += writeOutField(port, addr + 5, sourceBusIRQ);
|
||||
checkSum += writeOutField(port, addr + 6, destApicID);
|
||||
checkSum += writeOutField(port, addr + 7, destApicIntIn);
|
||||
BaseConfigEntry::writeOut(proxy, addr, checkSum);
|
||||
checkSum += writeOutField(proxy, addr + 1, interruptType);
|
||||
checkSum += writeOutField(proxy, addr + 2, flags);
|
||||
checkSum += writeOutField(proxy, addr + 4, sourceBusID);
|
||||
checkSum += writeOutField(proxy, addr + 5, sourceBusIRQ);
|
||||
checkSum += writeOutField(proxy, addr + 6, destApicID);
|
||||
checkSum += writeOutField(proxy, addr + 7, destApicIntIn);
|
||||
return 8;
|
||||
}
|
||||
|
||||
|
@ -381,13 +381,13 @@ X86IntelMPLocalIntAssignmentParams::create()
|
|||
|
||||
Addr
|
||||
X86ISA::IntelMP::AddrSpaceMapping::writeOut(
|
||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
||||
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||
{
|
||||
ExtConfigEntry::writeOut(port, addr, checkSum);
|
||||
checkSum += writeOutField(port, addr + 2, busID);
|
||||
checkSum += writeOutField(port, addr + 3, addrType);
|
||||
checkSum += writeOutField(port, addr + 4, addr);
|
||||
checkSum += writeOutField(port, addr + 12, addrLength);
|
||||
ExtConfigEntry::writeOut(proxy, addr, checkSum);
|
||||
checkSum += writeOutField(proxy, addr + 2, busID);
|
||||
checkSum += writeOutField(proxy, addr + 3, addrType);
|
||||
checkSum += writeOutField(proxy, addr + 4, addr);
|
||||
checkSum += writeOutField(proxy, addr + 12, addrLength);
|
||||
return length;
|
||||
}
|
||||
|
||||
|
@ -405,15 +405,15 @@ X86IntelMPAddrSpaceMappingParams::create()
|
|||
|
||||
Addr
|
||||
X86ISA::IntelMP::BusHierarchy::writeOut(
|
||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
||||
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||
{
|
||||
ExtConfigEntry::writeOut(port, addr, checkSum);
|
||||
checkSum += writeOutField(port, addr + 2, busID);
|
||||
checkSum += writeOutField(port, addr + 3, info);
|
||||
checkSum += writeOutField(port, addr + 4, parentBus);
|
||||
ExtConfigEntry::writeOut(proxy, addr, checkSum);
|
||||
checkSum += writeOutField(proxy, addr + 2, busID);
|
||||
checkSum += writeOutField(proxy, addr + 3, info);
|
||||
checkSum += writeOutField(proxy, addr + 4, parentBus);
|
||||
|
||||
uint32_t reserved = 0;
|
||||
port->writeBlob(addr + 5, (uint8_t *)(&reserved), 3);
|
||||
proxy->writeBlob(addr + 5, (uint8_t *)(&reserved), 3);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
@ -434,12 +434,12 @@ X86IntelMPBusHierarchyParams::create()
|
|||
|
||||
Addr
|
||||
X86ISA::IntelMP::CompatAddrSpaceMod::writeOut(
|
||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
||||
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||
{
|
||||
ExtConfigEntry::writeOut(port, addr, checkSum);
|
||||
checkSum += writeOutField(port, addr + 2, busID);
|
||||
checkSum += writeOutField(port, addr + 3, mod);
|
||||
checkSum += writeOutField(port, addr + 4, rangeList);
|
||||
ExtConfigEntry::writeOut(proxy, addr, checkSum);
|
||||
checkSum += writeOutField(proxy, addr + 2, busID);
|
||||
checkSum += writeOutField(proxy, addr + 3, mod);
|
||||
checkSum += writeOutField(proxy, addr + 4, rangeList);
|
||||
return length;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
#include "enums/X86IntelMPTriggerMode.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
|
||||
class FunctionalPort;
|
||||
class PortProxy;
|
||||
|
||||
// Config entry types
|
||||
class X86IntelMPBaseConfigEntryParams;
|
||||
|
@ -93,7 +93,7 @@ class FloatingPointer : public SimObject
|
|||
|
||||
public:
|
||||
|
||||
Addr writeOut(FunctionalPort * port, Addr addr);
|
||||
Addr writeOut(PortProxy* proxy, Addr addr);
|
||||
|
||||
Addr getTableAddr()
|
||||
{
|
||||
|
@ -117,7 +117,7 @@ class BaseConfigEntry : public SimObject
|
|||
|
||||
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);
|
||||
};
|
||||
|
@ -132,7 +132,7 @@ class ExtConfigEntry : public SimObject
|
|||
|
||||
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);
|
||||
};
|
||||
|
@ -155,7 +155,7 @@ class ConfigTable : public SimObject
|
|||
std::vector<ExtConfigEntry *> extEntries;
|
||||
|
||||
public:
|
||||
Addr writeOut(FunctionalPort * port, Addr addr);
|
||||
Addr writeOut(PortProxy* proxy, Addr addr);
|
||||
|
||||
ConfigTable(Params * p);
|
||||
};
|
||||
|
@ -172,7 +172,7 @@ class Processor : public BaseConfigEntry
|
|||
uint32_t featureFlags;
|
||||
|
||||
public:
|
||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
||||
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||
|
||||
Processor(Params * p);
|
||||
};
|
||||
|
@ -186,7 +186,7 @@ class Bus : public BaseConfigEntry
|
|||
std::string busType;
|
||||
|
||||
public:
|
||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
||||
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||
|
||||
Bus(Params * p);
|
||||
};
|
||||
|
@ -202,7 +202,7 @@ class IOAPIC : public BaseConfigEntry
|
|||
uint32_t address;
|
||||
|
||||
public:
|
||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
||||
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||
|
||||
IOAPIC(Params * p);
|
||||
};
|
||||
|
@ -221,7 +221,7 @@ class IntAssignment : public BaseConfigEntry
|
|||
uint8_t destApicIntIn;
|
||||
|
||||
public:
|
||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
||||
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||
|
||||
IntAssignment(X86IntelMPBaseConfigEntryParams * p,
|
||||
Enums::X86IntelMPInterruptType _interruptType,
|
||||
|
@ -269,7 +269,7 @@ class AddrSpaceMapping : public ExtConfigEntry
|
|||
uint64_t addrLength;
|
||||
|
||||
public:
|
||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
||||
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||
|
||||
AddrSpaceMapping(Params * p);
|
||||
};
|
||||
|
@ -284,7 +284,7 @@ class BusHierarchy : public ExtConfigEntry
|
|||
uint8_t parentBus;
|
||||
|
||||
public:
|
||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
||||
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||
|
||||
BusHierarchy(Params * p);
|
||||
};
|
||||
|
@ -299,7 +299,7 @@ class CompatAddrSpaceMod : public ExtConfigEntry
|
|||
uint32_t rangeList;
|
||||
|
||||
public:
|
||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
||||
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||
|
||||
CompatAddrSpaceMod(Params * p);
|
||||
};
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "arch/x86/bios/smbios.hh"
|
||||
#include "arch/x86/isa_traits.hh"
|
||||
#include "base/types.hh"
|
||||
#include "mem/port.hh"
|
||||
#include "mem/port_proxy.hh"
|
||||
#include "params/X86SMBiosBiosInformation.hh"
|
||||
#include "params/X86SMBiosSMBiosStructure.hh"
|
||||
#include "params/X86SMBiosSMBiosTable.hh"
|
||||
|
@ -74,15 +74,15 @@ composeBitVector(T vec)
|
|||
}
|
||||
|
||||
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();
|
||||
port->writeBlob(addr + 1, (uint8_t *)(&length), 1);
|
||||
proxy->writeBlob(addr + 1, (uint8_t *)(&length), 1);
|
||||
|
||||
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();
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ X86ISA::SMBios::SMBiosStructure::SMBiosStructure(Params * p, uint8_t _type) :
|
|||
|
||||
void
|
||||
X86ISA::SMBios::SMBiosStructure::writeOutStrings(
|
||||
FunctionalPort * port, Addr addr)
|
||||
PortProxy* proxy, Addr addr)
|
||||
{
|
||||
std::vector<std::string>::iterator it;
|
||||
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
|
||||
// special case which is handled by this if.
|
||||
if (strings.size() == 0 && stringFields) {
|
||||
port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
|
||||
proxy->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
|
||||
offset++;
|
||||
} else {
|
||||
for (it = strings.begin(); it != strings.end(); it++) {
|
||||
port->writeBlob(addr + offset,
|
||||
proxy->writeBlob(addr + offset,
|
||||
(uint8_t *)it->c_str(), it->length() + 1);
|
||||
offset += it->length() + 1;
|
||||
}
|
||||
}
|
||||
port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
|
||||
proxy->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -172,32 +172,32 @@ X86ISA::SMBios::BiosInformation::BiosInformation(Params * p) :
|
|||
}
|
||||
|
||||
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);
|
||||
port->writeBlob(addr + 0x5, (uint8_t *)(&version), 1);
|
||||
proxy->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1);
|
||||
proxy->writeBlob(addr + 0x5, (uint8_t *)(&version), 1);
|
||||
|
||||
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);
|
||||
port->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1);
|
||||
proxy->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1);
|
||||
proxy->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1);
|
||||
|
||||
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 =
|
||||
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);
|
||||
port->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1);
|
||||
port->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1);
|
||||
port->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1);
|
||||
proxy->writeBlob(addr + 0x14, (uint8_t *)(&majorVer), 1);
|
||||
proxy->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1);
|
||||
proxy->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1);
|
||||
proxy->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1);
|
||||
|
||||
writeOutStrings(port, addr + getLength());
|
||||
writeOutStrings(proxy, addr + getLength());
|
||||
|
||||
return size;
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ X86ISA::SMBios::SMBiosTable::SMBiosTable(Params * p) :
|
|||
}
|
||||
|
||||
void
|
||||
X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
||||
X86ISA::SMBios::SMBiosTable::writeOut(PortProxy* proxy, Addr addr,
|
||||
Addr &headerSize, Addr &structSize)
|
||||
{
|
||||
headerSize = 0x1F;
|
||||
|
@ -224,26 +224,26 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
|||
*/
|
||||
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++)
|
||||
mainChecksum += smbiosHeader.anchorString[i];
|
||||
|
||||
// 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);
|
||||
mainChecksum += smbiosHeader.entryPointLength;
|
||||
port->writeBlob(addr + 0x6,
|
||||
proxy->writeBlob(addr + 0x6,
|
||||
(uint8_t *)(&smbiosHeader.majorVersion), 1);
|
||||
mainChecksum += smbiosHeader.majorVersion;
|
||||
port->writeBlob(addr + 0x7,
|
||||
proxy->writeBlob(addr + 0x7,
|
||||
(uint8_t *)(&smbiosHeader.minorVersion), 1);
|
||||
mainChecksum += smbiosHeader.minorVersion;
|
||||
// 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);
|
||||
mainChecksum += smbiosHeader.entryPointRevision;
|
||||
port->writeBlob(addr + 0xB,
|
||||
proxy->writeBlob(addr + 0xB,
|
||||
(uint8_t *)(&smbiosHeader.formattedArea), 5);
|
||||
for (int i = 0; i < 5; i++)
|
||||
mainChecksum += smbiosHeader.formattedArea[i];
|
||||
|
@ -253,7 +253,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
|||
*/
|
||||
uint8_t intChecksum = 0;
|
||||
|
||||
port->writeBlob(addr + 0x10,
|
||||
proxy->writeBlob(addr + 0x10,
|
||||
(uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5);
|
||||
for (int i = 0; i < 5; i++)
|
||||
intChecksum += smbiosHeader.intermediateHeader.anchorString[i];
|
||||
|
@ -263,20 +263,20 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
|||
|
||||
uint32_t tableAddrGuest =
|
||||
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++) {
|
||||
intChecksum += tableAddrGuest;
|
||||
tableAddrGuest >>= 8;
|
||||
}
|
||||
|
||||
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++) {
|
||||
intChecksum += numStructs;
|
||||
numStructs >>= 8;
|
||||
}
|
||||
|
||||
port->writeBlob(addr + 0x1E,
|
||||
proxy->writeBlob(addr + 0x1E,
|
||||
(uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision),
|
||||
1);
|
||||
intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision;
|
||||
|
@ -290,7 +290,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
|||
uint16_t maxSize = 0;
|
||||
std::vector<SMBiosStructure *>::iterator it;
|
||||
for (it = structures.begin(); it != structures.end(); it++) {
|
||||
uint16_t size = (*it)->writeOut(port, base + offset);
|
||||
uint16_t size = (*it)->writeOut(proxy, base + offset);
|
||||
if (size > maxSize)
|
||||
maxSize = size;
|
||||
offset += size;
|
||||
|
@ -303,7 +303,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
|||
*/
|
||||
|
||||
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++) {
|
||||
mainChecksum += maxSize;
|
||||
maxSize >>= 8;
|
||||
|
@ -311,7 +311,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
|||
|
||||
// Set the checksum
|
||||
mainChecksum = -mainChecksum;
|
||||
port->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1);
|
||||
proxy->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1);
|
||||
|
||||
/*
|
||||
* Intermediate header
|
||||
|
@ -319,14 +319,14 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
|||
|
||||
uint16_t tableSize = offset;
|
||||
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++) {
|
||||
intChecksum += tableSize;
|
||||
tableSize >>= 8;
|
||||
}
|
||||
|
||||
intChecksum = -intChecksum;
|
||||
port->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1);
|
||||
proxy->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1);
|
||||
}
|
||||
|
||||
X86ISA::SMBios::BiosInformation *
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
#include "enums/ExtCharacteristic.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
|
||||
class FunctionalPort;
|
||||
class PortProxy;
|
||||
class X86SMBiosBiosInformationParams;
|
||||
class X86SMBiosSMBiosStructureParams;
|
||||
class X86SMBiosSMBiosTableParams;
|
||||
|
@ -89,7 +89,7 @@ class SMBiosStructure : public SimObject
|
|||
return 4;
|
||||
}
|
||||
|
||||
virtual uint16_t writeOut(FunctionalPort * port, Addr addr);
|
||||
virtual uint16_t writeOut(PortProxy* proxy, Addr addr);
|
||||
|
||||
protected:
|
||||
bool stringFields;
|
||||
|
@ -98,7 +98,7 @@ class SMBiosStructure : public SimObject
|
|||
|
||||
std::vector<std::string> strings;
|
||||
|
||||
void writeOutStrings(FunctionalPort * port, Addr addr);
|
||||
void writeOutStrings(PortProxy* proxy, Addr addr);
|
||||
|
||||
int getStringLength();
|
||||
|
||||
|
@ -145,7 +145,7 @@ class BiosInformation : public SMBiosStructure
|
|||
BiosInformation(Params * p);
|
||||
|
||||
uint8_t getLength() { return 0x18; }
|
||||
uint16_t writeOut(FunctionalPort * port, Addr addr);
|
||||
uint16_t writeOut(PortProxy* proxy, Addr addr);
|
||||
};
|
||||
|
||||
class SMBiosTable : public SimObject
|
||||
|
@ -223,7 +223,7 @@ class SMBiosTable : public SimObject
|
|||
smbiosHeader.intermediateHeader.tableAddr = addr;
|
||||
}
|
||||
|
||||
void writeOut(FunctionalPort * port, Addr addr,
|
||||
void writeOut(PortProxy* proxy, Addr addr,
|
||||
Addr &headerSize, Addr &structSize);
|
||||
};
|
||||
|
||||
|
|
|
@ -351,25 +351,27 @@ X86ISA::Interrupts::recvResponse(PacketPtr pkt)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
X86ISA::Interrupts::addressRanges(AddrRangeList &range_list)
|
||||
AddrRangeList
|
||||
X86ISA::Interrupts::getAddrRanges()
|
||||
{
|
||||
range_list.clear();
|
||||
AddrRangeList ranges;
|
||||
Range<Addr> range = RangeEx(x86LocalAPICAddress(initialApicId, 0),
|
||||
x86LocalAPICAddress(initialApicId, 0) +
|
||||
PageBytes);
|
||||
range_list.push_back(range);
|
||||
ranges.push_back(range);
|
||||
pioAddr = range.start;
|
||||
return ranges;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
X86ISA::Interrupts::getIntAddrRange(AddrRangeList &range_list)
|
||||
AddrRangeList
|
||||
X86ISA::Interrupts::getIntAddrRange()
|
||||
{
|
||||
range_list.clear();
|
||||
range_list.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
|
||||
x86InterruptAddress(initialApicId, 0) +
|
||||
PhysAddrAPICRangeSize));
|
||||
AddrRangeList ranges;
|
||||
ranges.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
|
||||
x86InterruptAddress(initialApicId, 0) +
|
||||
PhysAddrAPICRangeSize));
|
||||
return ranges;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -220,8 +220,8 @@ class Interrupts : public BasicPioDevice, IntDev
|
|||
return entry.periodic;
|
||||
}
|
||||
|
||||
void addressRanges(AddrRangeList &range_list);
|
||||
void getIntAddrRange(AddrRangeList &range_list);
|
||||
AddrRangeList getAddrRanges();
|
||||
AddrRangeList getIntAddrRange();
|
||||
|
||||
Port *getPort(const std::string &if_name, int idx = -1)
|
||||
{
|
||||
|
|
|
@ -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->machine, "x86_64");
|
||||
|
||||
name.copyOut(tc->getMemPort());
|
||||
name.copyOut(tc->getMemProxy());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
|||
int code = process->getSyscallArg(tc, index);
|
||||
uint64_t addr = process->getSyscallArg(tc, index);
|
||||
uint64_t fsBase, gsBase;
|
||||
TranslatingPort *p = tc->getMemPort();
|
||||
SETranslatingPortProxy* p = tc->getMemProxy();
|
||||
switch(code)
|
||||
{
|
||||
//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),
|
||||
numTLSEntries * sizeof(uint64_t));
|
||||
|
||||
if (!userDesc.copyIn(tc->getMemPort()))
|
||||
if (!userDesc.copyIn(tc->getMemProxy()))
|
||||
return -EFAULT;
|
||||
|
||||
if (!gdt.copyIn(tc->getMemPort()))
|
||||
if (!gdt.copyIn(tc->getMemProxy()))
|
||||
panic("Failed to copy in GDT for %s.\n", desc->name);
|
||||
|
||||
if (userDesc->entry_number == (uint32_t)(-1)) {
|
||||
|
@ -204,9 +204,9 @@ setThreadArea32Func(SyscallDesc *desc, int callnum,
|
|||
|
||||
gdt[index] = (uint64_t)segDesc;
|
||||
|
||||
if (!userDesc.copyOut(tc->getMemPort()))
|
||||
if (!userDesc.copyOut(tc->getMemProxy()))
|
||||
return -EFAULT;
|
||||
if (!gdt.copyOut(tc->getMemPort()))
|
||||
if (!gdt.copyOut(tc->getMemProxy()))
|
||||
panic("Failed to copy out GDT for %s.\n", desc->name);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "arch/vtophys.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "mem/physical.hh"
|
||||
#include "mem/port_proxy.hh"
|
||||
#include "params/LinuxX86System.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
|
||||
|
@ -67,8 +67,8 @@ LinuxX86System::initState()
|
|||
// The location of the real mode data structure.
|
||||
const Addr realModeData = 0x90200;
|
||||
|
||||
// A port to write to memory.
|
||||
FunctionalPort * physPort = threadContexts[0]->getPhysPort();
|
||||
// A port proxy to write to memory.
|
||||
PortProxy* physProxy = threadContexts[0]->getPhysProxy();
|
||||
|
||||
/*
|
||||
* Deal with the command line stuff.
|
||||
|
@ -82,14 +82,14 @@ LinuxX86System::initState()
|
|||
if (commandLine.length() + 1 > realModeData - commandLineBuff)
|
||||
panic("Command line \"%s\" is longer than %d characters.\n",
|
||||
commandLine, realModeData - commandLineBuff - 1);
|
||||
physPort->writeBlob(commandLineBuff,
|
||||
physProxy->writeBlob(commandLineBuff,
|
||||
(uint8_t *)commandLine.c_str(), commandLine.length() + 1);
|
||||
|
||||
// Generate a pointer of the right size and endianness to put into
|
||||
// commandLinePointer.
|
||||
uint32_t guestCommandLineBuff =
|
||||
X86ISA::htog((uint32_t)commandLineBuff);
|
||||
physPort->writeBlob(commandLinePointer,
|
||||
physProxy->writeBlob(commandLinePointer,
|
||||
(uint8_t *)&guestCommandLineBuff, sizeof(guestCommandLineBuff));
|
||||
|
||||
/*
|
||||
|
@ -127,7 +127,7 @@ LinuxX86System::initState()
|
|||
// A pointer to the buffer for E820 entries.
|
||||
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
|
||||
|
|
|
@ -154,17 +154,8 @@ Walker::WalkerPort::recvFunctional(PacketPtr pkt)
|
|||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -63,26 +63,18 @@ namespace X86ISA
|
|||
{
|
||||
public:
|
||||
WalkerPort(const std::string &_name, Walker * _walker) :
|
||||
Port(_name, _walker), walker(_walker),
|
||||
snoopRangeSent(false)
|
||||
Port(_name, _walker), walker(_walker)
|
||||
{}
|
||||
|
||||
protected:
|
||||
Walker * walker;
|
||||
|
||||
bool snoopRangeSent;
|
||||
|
||||
bool recvTiming(PacketPtr pkt);
|
||||
Tick recvAtomic(PacketPtr pkt);
|
||||
void recvFunctional(PacketPtr pkt);
|
||||
void recvStatusChange(Status status);
|
||||
void recvRangeChange();
|
||||
void recvRetry();
|
||||
void getDeviceAddressRanges(AddrRangeList &resp,
|
||||
bool &snoop)
|
||||
{
|
||||
resp.clear();
|
||||
snoop = true;
|
||||
}
|
||||
bool isSnooping() { return true; }
|
||||
};
|
||||
|
||||
friend class WalkerPort;
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
#include "cpu/thread_context.hh"
|
||||
#include "debug/Stack.hh"
|
||||
#include "mem/page_table.hh"
|
||||
#include "mem/translating_port.hh"
|
||||
#include "sim/process_impl.hh"
|
||||
#include "sim/syscall_emul.hh"
|
||||
#include "sim/system.hh"
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include "base/trace.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "mem/vport.hh"
|
||||
#include "mem/fs_translating_port_proxy.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
using namespace std;
|
||||
|
@ -48,9 +48,9 @@ namespace X86ISA
|
|||
{
|
||||
Addr addr = 0;
|
||||
|
||||
VirtualPort *vp;
|
||||
FSTranslatingPortProxy* vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
vp = tc->getVirtProxy();
|
||||
|
||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
|
@ -82,9 +82,9 @@ namespace X86ISA
|
|||
|
||||
Addr tsk;
|
||||
|
||||
VirtualPort *vp;
|
||||
FSTranslatingPortProxy* vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
vp = tc->getVirtProxy();
|
||||
tsk = vp->readGtoH<Addr>(base + task_off);
|
||||
|
||||
return tsk;
|
||||
|
@ -99,9 +99,9 @@ namespace X86ISA
|
|||
|
||||
uint16_t pd;
|
||||
|
||||
VirtualPort *vp;
|
||||
FSTranslatingPortProxy* vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
vp = tc->getVirtProxy();
|
||||
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
||||
|
||||
return pd;
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#include "base/intmath.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "mem/physical.hh"
|
||||
#include "mem/port_proxy.hh"
|
||||
#include "params/X86System.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
|
||||
|
@ -61,8 +61,6 @@ X86System::X86System(Params *p) :
|
|||
mpConfigTable(p->intel_mp_table),
|
||||
rsdp(p->acpi_description_table_pointer)
|
||||
{
|
||||
if (kernel->getArch() == ObjectFile::I386)
|
||||
fatal("Loading a 32 bit x86 kernel is not supported.\n");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -116,6 +114,9 @@ X86System::initState()
|
|||
{
|
||||
System::initState();
|
||||
|
||||
if (kernel->getArch() == ObjectFile::I386)
|
||||
fatal("Loading a 32 bit x86 kernel is not supported.\n");
|
||||
|
||||
ThreadContext *tc = threadContexts[0];
|
||||
// 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
|
||||
|
@ -137,8 +138,8 @@ X86System::initState()
|
|||
const int PDPTBits = 9;
|
||||
const int PDTBits = 9;
|
||||
|
||||
// Get a port to write the page tables and descriptor tables.
|
||||
FunctionalPort * physPort = tc->getPhysPort();
|
||||
// Get a port proxy to write the page tables and descriptor tables.
|
||||
PortProxy* physProxy = tc->getPhysProxy();
|
||||
|
||||
/*
|
||||
* Set up the gdt.
|
||||
|
@ -146,7 +147,7 @@ X86System::initState()
|
|||
uint8_t numGDTEntries = 0;
|
||||
// Place holder at selector 0
|
||||
uint64_t nullDescriptor = 0;
|
||||
physPort->writeBlob(GDTBase + numGDTEntries * 8,
|
||||
physProxy->writeBlob(GDTBase + numGDTEntries * 8,
|
||||
(uint8_t *)(&nullDescriptor), 8);
|
||||
numGDTEntries++;
|
||||
|
||||
|
@ -168,7 +169,7 @@ X86System::initState()
|
|||
//it's beginning in memory and it's actual data, we'll use an
|
||||
//intermediary.
|
||||
uint64_t csDescVal = csDesc;
|
||||
physPort->writeBlob(GDTBase + numGDTEntries * 8,
|
||||
physProxy->writeBlob(GDTBase + numGDTEntries * 8,
|
||||
(uint8_t *)(&csDescVal), 8);
|
||||
|
||||
numGDTEntries++;
|
||||
|
@ -191,7 +192,7 @@ X86System::initState()
|
|||
dsDesc.limitHigh = 0xF;
|
||||
dsDesc.limitLow = 0xFF;
|
||||
uint64_t dsDescVal = dsDesc;
|
||||
physPort->writeBlob(GDTBase + numGDTEntries * 8,
|
||||
physProxy->writeBlob(GDTBase + numGDTEntries * 8,
|
||||
(uint8_t *)(&dsDescVal), 8);
|
||||
|
||||
numGDTEntries++;
|
||||
|
@ -219,7 +220,7 @@ X86System::initState()
|
|||
tssDesc.limitHigh = 0xF;
|
||||
tssDesc.limitLow = 0xFF;
|
||||
uint64_t tssDescVal = tssDesc;
|
||||
physPort->writeBlob(GDTBase + numGDTEntries * 8,
|
||||
physProxy->writeBlob(GDTBase + numGDTEntries * 8,
|
||||
(uint8_t *)(&tssDescVal), 8);
|
||||
|
||||
numGDTEntries++;
|
||||
|
@ -249,24 +250,24 @@ X86System::initState()
|
|||
// read/write, user, not present
|
||||
uint64_t pml4e = X86ISA::htog(0x6);
|
||||
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
|
||||
pml4e = X86ISA::htog(0x7 | PageDirPtrTable);
|
||||
physPort->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8);
|
||||
physProxy->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8);
|
||||
|
||||
// Page Directory Pointer Table
|
||||
|
||||
// read/write, user, not present
|
||||
uint64_t pdpe = X86ISA::htog(0x6);
|
||||
for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) {
|
||||
physPort->writeBlob(PageDirPtrTable + offset,
|
||||
physProxy->writeBlob(PageDirPtrTable + offset,
|
||||
(uint8_t *)(&pdpe), 8);
|
||||
}
|
||||
// Point to the PDTs
|
||||
for (int table = 0; table < NumPDTs; table++) {
|
||||
pdpe = X86ISA::htog(0x7 | PageDirTable[table]);
|
||||
physPort->writeBlob(PageDirPtrTable + table * 8,
|
||||
physProxy->writeBlob(PageDirPtrTable + table * 8,
|
||||
(uint8_t *)(&pdpe), 8);
|
||||
}
|
||||
|
||||
|
@ -278,7 +279,7 @@ X86System::initState()
|
|||
for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) {
|
||||
// read/write, user, present, 4MB
|
||||
uint64_t pdte = X86ISA::htog(0x87 | base);
|
||||
physPort->writeBlob(PageDirTable[table] + offset,
|
||||
physProxy->writeBlob(PageDirTable[table] + offset,
|
||||
(uint8_t *)(&pdte), 8);
|
||||
base += pageSize;
|
||||
}
|
||||
|
@ -341,8 +342,8 @@ void
|
|||
X86System::writeOutSMBiosTable(Addr header,
|
||||
Addr &headerSize, Addr &structSize, Addr table)
|
||||
{
|
||||
// Get a port to write the table and header to memory.
|
||||
FunctionalPort * physPort = threadContexts[0]->getPhysPort();
|
||||
// Get a port proxy to write the table and header to memory.
|
||||
PortProxy* physProxy = threadContexts[0]->getPhysProxy();
|
||||
|
||||
// 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
|
||||
|
@ -350,7 +351,7 @@ X86System::writeOutSMBiosTable(Addr header,
|
|||
table = header + 0x1F;
|
||||
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
|
||||
// ourselves.
|
||||
|
@ -362,8 +363,8 @@ void
|
|||
X86System::writeOutMPTable(Addr fp,
|
||||
Addr &fpSize, Addr &tableSize, Addr table)
|
||||
{
|
||||
// Get a port to write the table and header to memory.
|
||||
FunctionalPort * physPort = threadContexts[0]->getPhysPort();
|
||||
// Get a port proxy to write the table and header to memory.
|
||||
PortProxy* physProxy = threadContexts[0]->getPhysProxy();
|
||||
|
||||
// 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
|
||||
|
@ -374,9 +375,9 @@ X86System::writeOutMPTable(Addr fp,
|
|||
mpFloatingPointer->setTableAddr(table);
|
||||
}
|
||||
|
||||
fpSize = mpFloatingPointer->writeOut(physPort, fp);
|
||||
fpSize = mpFloatingPointer->writeOut(physProxy, fp);
|
||||
if (mpConfigTable)
|
||||
tableSize = mpConfigTable->writeOut(physPort, table);
|
||||
tableSize = mpConfigTable->writeOut(physProxy, table);
|
||||
else
|
||||
tableSize = 0;
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ struct AllFlags : public Flag
|
|||
FlagsMap::iterator end = allFlags().end();
|
||||
for (; i != end; ++i)
|
||||
if (i->second != this)
|
||||
i->second->enable();
|
||||
i->second->disable();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -414,15 +414,15 @@ ElfObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask)
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
vector<Segment>::iterator extraIt;
|
||||
for (extraIt = extraSegments.begin();
|
||||
extraIt != extraSegments.end(); extraIt++) {
|
||||
if (!loadSection(&(*extraIt), memPort, addrMask)) {
|
||||
if (!loadSection(&(*extraIt), memProxy, addrMask)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ class ElfObject : public ObjectFile
|
|||
public:
|
||||
virtual ~ElfObject() {}
|
||||
|
||||
bool loadSections(Port *memPort,
|
||||
bool loadSections(PortProxy *memProxy,
|
||||
Addr addrMask = std::numeric_limits<Addr>::max());
|
||||
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
|
||||
std::numeric_limits<Addr>::max());
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "base/loader/hex_file.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "base/cprintf.hh"
|
||||
#include "mem/translating_port.hh"
|
||||
#include "mem/port_proxy.hh"
|
||||
|
||||
using namespace std;
|
||||
/*
|
||||
|
@ -59,7 +59,7 @@ HexFile::~HexFile()
|
|||
}
|
||||
|
||||
bool
|
||||
HexFile::loadSections(Port *memPort)
|
||||
HexFile::loadSections(PortProxy* memProxy)
|
||||
{
|
||||
char Line[64];
|
||||
Addr MemAddr;
|
||||
|
@ -71,7 +71,7 @@ HexFile::loadSections(Port *memPort)
|
|||
parseLine(Line, &MemAddr, &Data);
|
||||
if (MemAddr != 0) {
|
||||
// Now, write to memory
|
||||
memPort->writeBlob(MemAddr << 2, (uint8_t *)&Data, sizeof(Data));
|
||||
memProxy->writeBlob(MemAddr << 2, (uint8_t *)&Data, sizeof(Data));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
#include "base/types.hh"
|
||||
|
||||
class Port;
|
||||
class PortProxy;
|
||||
|
||||
class HexFile
|
||||
{
|
||||
|
@ -52,7 +52,7 @@ class HexFile
|
|||
virtual ~HexFile();
|
||||
|
||||
void close();
|
||||
bool loadSections(Port *memPort);
|
||||
bool loadSections(PortProxy* memProxy);
|
||||
};
|
||||
|
||||
#endif // __BASE_LOADER_HEX_FILE_HH__
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#include "base/loader/raw_object.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "base/cprintf.hh"
|
||||
#include "mem/translating_port.hh"
|
||||
#include "mem/port_proxy.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -65,16 +65,16 @@ ObjectFile::~ObjectFile()
|
|||
|
||||
|
||||
bool
|
||||
ObjectFile::loadSection(Section *sec, Port *memPort, Addr addrMask)
|
||||
ObjectFile::loadSection(Section *sec, PortProxy* memProxy, Addr addrMask)
|
||||
{
|
||||
if (sec->size != 0) {
|
||||
Addr addr = sec->baseAddr & addrMask;
|
||||
if (sec->fileImage) {
|
||||
memPort->writeBlob(addr, sec->fileImage, sec->size);
|
||||
memProxy->writeBlob(addr, sec->fileImage, sec->size);
|
||||
}
|
||||
else {
|
||||
// no image: must be bss
|
||||
memPort->memsetBlob(addr, 0, sec->size);
|
||||
memProxy->memsetBlob(addr, 0, sec->size);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -82,11 +82,11 @@ ObjectFile::loadSection(Section *sec, Port *memPort, Addr addrMask)
|
|||
|
||||
|
||||
bool
|
||||
ObjectFile::loadSections(Port *memPort, Addr addrMask)
|
||||
ObjectFile::loadSections(PortProxy* memProxy, Addr addrMask)
|
||||
{
|
||||
return (loadSection(&text, memPort, addrMask)
|
||||
&& loadSection(&data, memPort, addrMask)
|
||||
&& loadSection(&bss, memPort, addrMask));
|
||||
return (loadSection(&text, memProxy, addrMask)
|
||||
&& loadSection(&data, memProxy, addrMask)
|
||||
&& loadSection(&bss, memProxy, addrMask));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
#include "base/types.hh"
|
||||
|
||||
class Port;
|
||||
class PortProxy;
|
||||
class SymbolTable;
|
||||
|
||||
class ObjectFile
|
||||
|
@ -83,7 +83,7 @@ class ObjectFile
|
|||
|
||||
void close();
|
||||
|
||||
virtual bool loadSections(Port *memPort, Addr addrMask =
|
||||
virtual bool loadSections(PortProxy *memProxy, Addr addrMask =
|
||||
std::numeric_limits<Addr>::max());
|
||||
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
|
||||
std::numeric_limits<Addr>::max()) = 0;
|
||||
|
@ -111,7 +111,7 @@ class ObjectFile
|
|||
Section data;
|
||||
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; }
|
||||
|
||||
public:
|
||||
|
|
|
@ -132,8 +132,8 @@
|
|||
#include "cpu/thread_context.hh"
|
||||
#include "debug/GDBAll.hh"
|
||||
#include "mem/port.hh"
|
||||
#include "mem/translating_port.hh"
|
||||
#include "mem/vport.hh"
|
||||
#include "mem/fs_translating_port_proxy.hh"
|
||||
#include "mem/se_translating_port_proxy.hh"
|
||||
#include "sim/full_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);
|
||||
|
||||
if (FullSystem) {
|
||||
VirtualPort *port = context->getVirtPort();
|
||||
FSTranslatingPortProxy *port = context->getVirtProxy();
|
||||
port->readBlob(vaddr, (uint8_t*)data, size);
|
||||
} else {
|
||||
TranslatingPort *port = context->getMemPort();
|
||||
SETranslatingPortProxy *port = context->getMemProxy();
|
||||
port->readBlob(vaddr, (uint8_t*)data, size);
|
||||
}
|
||||
|
||||
|
@ -504,10 +504,10 @@ BaseRemoteGDB::write(Addr vaddr, size_t size, const char *data)
|
|||
DPRINTFNR("\n");
|
||||
}
|
||||
if (FullSystem) {
|
||||
VirtualPort *port = context->getVirtPort();
|
||||
FSTranslatingPortProxy *port = context->getVirtProxy();
|
||||
port->writeBlob(vaddr, (uint8_t*)data, size);
|
||||
} else {
|
||||
TranslatingPort *port = context->getMemPort();
|
||||
SETranslatingPortProxy *port = context->getMemProxy();
|
||||
port->writeBlob(vaddr, (uint8_t*)data, size);
|
||||
delete port;
|
||||
}
|
||||
|
|
|
@ -216,7 +216,7 @@ class BaseRemoteGDB
|
|||
|
||||
bool insertSoftBreak(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);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -138,9 +138,12 @@ class BaseCPU(MemObject):
|
|||
|
||||
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']:
|
||||
_cached_ports = ["itb.walker.port", "dtb.walker.port"]
|
||||
_cached_ports += ["itb.walker.port", "dtb.walker.port"]
|
||||
|
||||
_uncached_ports = []
|
||||
if buildEnv['TARGET_ISA'] == 'x86':
|
||||
|
|
|
@ -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) 2011 Regents of the University of California
|
||||
* All rights reserved.
|
||||
|
@ -470,3 +482,36 @@ BaseCPU::traceFunctionsInternal(Addr pc)
|
|||
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()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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) 2011 Regents of the University of California
|
||||
* All rights reserved.
|
||||
|
@ -92,6 +104,42 @@ class BaseCPU : public MemObject
|
|||
// therefore no setCpuId() method is provided
|
||||
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:
|
||||
/** Reads this CPU's ID. */
|
||||
int cpuId() { return _cpuId; }
|
||||
|
|
|
@ -98,12 +98,12 @@ class CheckerThreadContext : public ThreadContext
|
|||
|
||||
Process *getProcessPtr() { return actualTC->getProcessPtr(); }
|
||||
|
||||
TranslatingPort *getMemPort() { return actualTC->getMemPort(); }
|
||||
PortProxy* getPhysProxy() { return actualTC->getPhysProxy(); }
|
||||
|
||||
VirtualPort *getVirtPort()
|
||||
{ return actualTC->getVirtPort(); }
|
||||
FSTranslatingPortProxy* getVirtProxy()
|
||||
{ return actualTC->getVirtProxy(); }
|
||||
|
||||
FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); }
|
||||
SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); }
|
||||
|
||||
Status status() const { return actualTC->status(); }
|
||||
|
||||
|
|
|
@ -44,9 +44,6 @@ class InOrderCPU(BaseCPU):
|
|||
|
||||
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")
|
||||
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)")
|
||||
memBlockSize = Param.Unsigned(64, "Memory Block Size")
|
||||
|
|
|
@ -54,7 +54,6 @@
|
|||
#include "debug/RefCount.hh"
|
||||
#include "debug/SkedCache.hh"
|
||||
#include "debug/Quiesce.hh"
|
||||
#include "mem/translating_port.hh"
|
||||
#include "params/InOrderCPU.hh"
|
||||
#include "sim/full_system.hh"
|
||||
#include "sim/process.hh"
|
||||
|
@ -758,6 +757,8 @@ InOrderCPU::init()
|
|||
for (ThreadID tid = 0; tid < numThreads; tid++) {
|
||||
ThreadContext *src_tc = threadContexts[tid];
|
||||
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]);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InOrderCPU::processInterrupts(Fault interrupt)
|
||||
{
|
||||
|
@ -879,16 +879,6 @@ InOrderCPU::processInterrupts(Fault interrupt)
|
|||
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
|
||||
InOrderCPU::trapContext(Fault fault, ThreadID tid, DynInstPtr inst, int delay)
|
||||
{
|
||||
|
|
|
@ -428,10 +428,6 @@ class InOrderCPU : public BaseCPU
|
|||
/** Halts the CPU. */
|
||||
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. */
|
||||
bool validInstAddr(Addr addr) { return true; }
|
||||
|
||||
|
|
|
@ -82,17 +82,8 @@ CacheUnit::CachePort::recvFunctional(PacketPtr pkt)
|
|||
}
|
||||
|
||||
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
|
||||
|
@ -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 *
|
||||
CacheUnit::getPort(const string &if_name, int idx)
|
||||
{
|
||||
|
|
|
@ -90,13 +90,9 @@ class CacheUnit : public Resource
|
|||
CachePort(CacheUnit *_cachePortUnit)
|
||||
: Port(_cachePortUnit->name() + "-cache-port",
|
||||
(MemObject*)_cachePortUnit->cpu),
|
||||
cachePortUnit(_cachePortUnit), snoopRangeSent(false)
|
||||
cachePortUnit(_cachePortUnit)
|
||||
{ }
|
||||
|
||||
bool snoopRangeSent;
|
||||
|
||||
void setPeer(Port *port);
|
||||
|
||||
protected:
|
||||
/** Atomic version of receive. Panics. */
|
||||
Tick recvAtomic(PacketPtr pkt);
|
||||
|
@ -104,13 +100,8 @@ class CacheUnit : public Resource
|
|||
/** Functional version of receive.*/
|
||||
void recvFunctional(PacketPtr pkt);
|
||||
|
||||
/** Receives status change. Other than range changing, panics. */
|
||||
void recvStatusChange(Status status);
|
||||
|
||||
/** Returns the address ranges of this device. */
|
||||
void getDeviceAddressRanges(AddrRangeList &resp,
|
||||
bool &snoop)
|
||||
{ resp.clear(); snoop = true; }
|
||||
/** Receives range changes. */
|
||||
void recvRangeChange();
|
||||
|
||||
/** Timing version of receive */
|
||||
bool recvTiming(PacketPtr pkt);
|
||||
|
|
|
@ -38,10 +38,10 @@
|
|||
|
||||
using namespace TheISA;
|
||||
|
||||
VirtualPort *
|
||||
InOrderThreadContext::getVirtPort()
|
||||
FSTranslatingPortProxy*
|
||||
InOrderThreadContext::getVirtProxy()
|
||||
{
|
||||
return thread->getVirtPort();
|
||||
return thread->getVirtProxy();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -117,8 +117,12 @@ class InOrderThreadContext : public ThreadContext
|
|||
TheISA::Kernel::Statistics *getKernelStats()
|
||||
{ return thread->kernelStats; }
|
||||
|
||||
void connectMemPorts(ThreadContext *tc)
|
||||
{ thread->connectMemPorts(tc); }
|
||||
PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
|
||||
|
||||
FSTranslatingPortProxy* getVirtProxy();
|
||||
|
||||
void initMemProxies(ThreadContext *tc)
|
||||
{ thread->initMemProxies(tc); }
|
||||
|
||||
/** Dumps the function profiling information.
|
||||
* @todo: Implement.
|
||||
|
@ -142,14 +146,11 @@ class InOrderThreadContext : public ThreadContext
|
|||
return this->thread->quiesceEvent;
|
||||
}
|
||||
|
||||
SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); }
|
||||
|
||||
/** Returns a pointer to this thread's process. */
|
||||
Process *getProcessPtr() { return thread->getProcessPtr(); }
|
||||
|
||||
TranslatingPort *getMemPort() { return thread->getMemPort(); }
|
||||
|
||||
VirtualPort *getVirtPort();
|
||||
FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
|
||||
|
||||
/** Returns this thread's status. */
|
||||
Status status() const { return thread->status(); }
|
||||
|
||||
|
|
|
@ -49,9 +49,6 @@ class DerivO3CPU(BaseCPU):
|
|||
checker.dtb = Parent.dtb
|
||||
|
||||
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")
|
||||
renameToFetchDelay = Param.Unsigned(1 ,"Rename to fetch delay")
|
||||
|
|
|
@ -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) 2011 Regents of the University of California
|
||||
* All rights reserved.
|
||||
|
@ -76,6 +88,42 @@ BaseO3CPU::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>
|
||||
FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c)
|
||||
: Event(CPU_Tick_Pri), cpu(c)
|
||||
|
@ -191,6 +239,9 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
|
|||
TheISA::NumMiscRegs * numThreads,
|
||||
TheISA::ZeroReg),
|
||||
|
||||
icachePort(&fetch, this),
|
||||
dcachePort(&iew.ldstQueue, this),
|
||||
|
||||
timeBuffer(params->backComSize, params->forwardComSize),
|
||||
fetchQueue(params->backComSize, params->forwardComSize),
|
||||
decodeQueue(params->backComSize, params->forwardComSize),
|
||||
|
@ -215,6 +266,7 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
|
|||
if (params->checker) {
|
||||
BaseCPU *temp_checker = params->checker;
|
||||
checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
|
||||
checker->setIcachePort(&icachePort);
|
||||
checker->setSystem(params->system);
|
||||
} else {
|
||||
checker = NULL;
|
||||
|
@ -524,9 +576,9 @@ Port *
|
|||
FullO3CPU<Impl>::getPort(const std::string &if_name, int idx)
|
||||
{
|
||||
if (if_name == "dcache_port")
|
||||
return iew.getDcachePort();
|
||||
return &dcachePort;
|
||||
else if (if_name == "icache_port")
|
||||
return fetch.getIcachePort();
|
||||
return &icachePort;
|
||||
else
|
||||
panic("No Such Port\n");
|
||||
}
|
||||
|
@ -600,10 +652,19 @@ FullO3CPU<Impl>::init()
|
|||
for (ThreadID tid = 0; tid < numThreads; ++tid)
|
||||
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) {
|
||||
for (ThreadID tid = 0; tid < numThreads; tid++) {
|
||||
ThreadContext *src_tc = threadContexts[tid];
|
||||
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);
|
||||
}
|
||||
|
||||
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>
|
||||
void
|
||||
FullO3CPU<Impl>::trap(Fault fault, ThreadID tid, StaticInstPtr inst)
|
||||
|
@ -1166,7 +1216,7 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
|
|||
|
||||
activityRec.reset();
|
||||
|
||||
BaseCPU::takeOverFrom(oldCPU, fetch.getIcachePort(), iew.getDcachePort());
|
||||
BaseCPU::takeOverFrom(oldCPU, &icachePort, &dcachePort);
|
||||
|
||||
fetch.takeOverFrom();
|
||||
decode.takeOverFrom();
|
||||
|
|
|
@ -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) 2011 Regents of the University of California
|
||||
* All rights reserved.
|
||||
|
@ -117,6 +129,68 @@ class FullO3CPU : public BaseO3CPU
|
|||
Status _threadStatus[Impl::MaxThreads];
|
||||
|
||||
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
|
||||
{
|
||||
private:
|
||||
|
@ -391,10 +465,6 @@ class FullO3CPU : public BaseO3CPU
|
|||
/** Halts the CPU. */
|
||||
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. */
|
||||
bool validInstAddr(Addr addr) { return true; }
|
||||
|
||||
|
@ -565,6 +635,12 @@ class FullO3CPU : public BaseO3CPU
|
|||
|
||||
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:
|
||||
/** Enum to give each stage a specific index, so when calling
|
||||
* activateStage() or deactivateStage(), they can specify which stage
|
||||
|
@ -701,8 +777,11 @@ class FullO3CPU : public BaseO3CPU
|
|||
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). */
|
||||
Port *getDcachePort() { return this->iew.ldstQueue.getDcachePort(); }
|
||||
Port* getDcachePort() { return &dcachePort; }
|
||||
|
||||
Addr lockAddr;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2010 ARM Limited
|
||||
* Copyright (c) 2010-2011 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
|
@ -85,48 +85,6 @@ class DefaultFetch
|
|||
typedef TheISA::MachInst MachInst;
|
||||
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
|
||||
{
|
||||
protected:
|
||||
|
@ -248,9 +206,6 @@ class DefaultFetch
|
|||
/** Registers statistics. */
|
||||
void regStats();
|
||||
|
||||
/** Returns the icache port. */
|
||||
Port *getIcachePort() { return icachePort; }
|
||||
|
||||
/** Sets the main backwards communication time buffer pointer. */
|
||||
void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer);
|
||||
|
||||
|
@ -266,6 +221,9 @@ class DefaultFetch
|
|||
/** Tells the fetch stage that the Icache is set. */
|
||||
void setIcache();
|
||||
|
||||
/** Handles retrying the fetch access. */
|
||||
void recvRetry();
|
||||
|
||||
/** Processes cache completion event. */
|
||||
void processCacheCompletion(PacketPtr pkt);
|
||||
|
||||
|
@ -389,9 +347,6 @@ class DefaultFetch
|
|||
StaticInstPtr curMacroop, TheISA::PCState thisPC,
|
||||
TheISA::PCState nextPC, bool trace);
|
||||
|
||||
/** Handles retrying the fetch access. */
|
||||
void recvRetry();
|
||||
|
||||
/** Returns the appropriate thread to fetch, given the fetch policy. */
|
||||
ThreadID getFetchingThread(FetchPriority &fetch_priority);
|
||||
|
||||
|
@ -440,9 +395,6 @@ class DefaultFetch
|
|||
/** Wire used to write any information heading to decode. */
|
||||
typename TimeBuffer<FetchStruct>::wire toDecode;
|
||||
|
||||
/** Icache interface. */
|
||||
IcachePort *icachePort;
|
||||
|
||||
/** BPredUnit. */
|
||||
BPredUnit branchPred;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2010 ARM Limited
|
||||
* Copyright (c) 2010-2011 ARM Limited
|
||||
* All rights reserved.
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
|
@ -68,68 +68,6 @@
|
|||
|
||||
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>
|
||||
DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params)
|
||||
: cpu(_cpu),
|
||||
|
@ -189,17 +127,6 @@ DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params)
|
|||
|
||||
// Get the size of an instruction.
|
||||
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>
|
||||
|
@ -402,8 +329,10 @@ template<class Impl>
|
|||
void
|
||||
DefaultFetch<Impl>::setIcache()
|
||||
{
|
||||
assert(cpu->getIcachePort()->isConnected());
|
||||
|
||||
// Size of cache block.
|
||||
cacheBlkSize = icachePort->peerBlockSize();
|
||||
cacheBlkSize = cpu->getIcachePort()->peerBlockSize();
|
||||
|
||||
// Create mask to get rid of offset bits.
|
||||
cacheBlkMask = (cacheBlkSize - 1);
|
||||
|
@ -494,6 +423,10 @@ template <class Impl>
|
|||
void
|
||||
DefaultFetch<Impl>::takeOverFrom()
|
||||
{
|
||||
// the instruction port is now connected so we can get the block
|
||||
// size
|
||||
setIcache();
|
||||
|
||||
// Reset all state
|
||||
for (ThreadID i = 0; i < Impl::MaxThreads; ++i) {
|
||||
stalls[i].decode = 0;
|
||||
|
@ -684,7 +617,7 @@ DefaultFetch<Impl>::finishTranslation(Fault fault, RequestPtr mem_req)
|
|||
fetchedCacheLines++;
|
||||
|
||||
// Access the cache.
|
||||
if (!icachePort->sendTiming(data_pkt)) {
|
||||
if (!cpu->getIcachePort()->sendTiming(data_pkt)) {
|
||||
assert(retryPkt == NULL);
|
||||
assert(retryTid == InvalidThreadID);
|
||||
DPRINTF(Fetch, "[tid:%i] Out of MSHRs!\n", tid);
|
||||
|
@ -1403,7 +1336,7 @@ DefaultFetch<Impl>::recvRetry()
|
|||
assert(retryTid != InvalidThreadID);
|
||||
assert(fetchStatus[retryTid] == IcacheWaitRetry);
|
||||
|
||||
if (icachePort->sendTiming(retryPkt)) {
|
||||
if (cpu->getIcachePort()->sendTiming(retryPkt)) {
|
||||
fetchStatus[retryTid] = IcacheWaitResponse;
|
||||
retryPkt = NULL;
|
||||
retryTid = InvalidThreadID;
|
||||
|
|
|
@ -138,9 +138,6 @@ class DefaultIEW
|
|||
/** Initializes stage; sends back the number of free IQ and LSQ entries. */
|
||||
void initStage();
|
||||
|
||||
/** Returns the dcache port. */
|
||||
Port *getDcachePort() { return ldstQueue.getDcachePort(); }
|
||||
|
||||
/** Sets main time buffer used for backwards communication. */
|
||||
void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
|
||||
|
||||
|
|
|
@ -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
|
||||
* All rights reserved.
|
||||
*
|
||||
|
@ -65,13 +77,6 @@ class LSQ {
|
|||
/** Registers statistics of each LSQ unit. */
|
||||
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. */
|
||||
void setActiveThreads(std::list<ThreadID> *at_ptr);
|
||||
/** Switches out the LSQ. */
|
||||
|
@ -281,61 +286,25 @@ class LSQ {
|
|||
Fault write(RequestPtr req, RequestPtr sreqLow, RequestPtr sreqHigh,
|
||||
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. */
|
||||
O3CPU *cpu;
|
||||
|
||||
/** The IEW stage pointer. */
|
||||
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:
|
||||
/** The LSQ policy for SMT mode. */
|
||||
LSQPolicy lsqPolicy;
|
||||
|
|
|
@ -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
|
||||
* All rights reserved.
|
||||
*
|
||||
|
@ -40,96 +52,14 @@
|
|||
|
||||
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>
|
||||
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),
|
||||
SQEntries(params->SQEntries),
|
||||
numThreads(params->numThreads),
|
||||
retryTid(-1)
|
||||
{
|
||||
dcachePort.snoopRangeSent = false;
|
||||
|
||||
//**********************************************/
|
||||
//************ 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++) {
|
||||
thread[tid].init(cpu, iew_ptr, params, this,
|
||||
maxLQEntries, maxSQEntries, tid);
|
||||
thread[tid].setDcachePort(&dcachePort);
|
||||
thread[tid].setDcachePort(cpu_ptr->getDcachePort());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -371,6 +301,48 @@ LSQ<Impl>::violation()
|
|||
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>
|
||||
int
|
||||
LSQ<Impl>::getCount()
|
||||
|
|
|
@ -96,17 +96,18 @@ class O3ThreadContext : public ThreadContext
|
|||
virtual TheISA::Kernel::Statistics *getKernelStats()
|
||||
{ return thread->kernelStats; }
|
||||
|
||||
virtual void connectMemPorts(ThreadContext *tc)
|
||||
{ thread->connectMemPorts(tc); }
|
||||
|
||||
/** Returns a pointer to this thread's process. */
|
||||
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. */
|
||||
virtual Status status() const { return thread->status(); }
|
||||
|
|
|
@ -49,10 +49,10 @@
|
|||
#include "debug/O3CPU.hh"
|
||||
|
||||
template <class Impl>
|
||||
VirtualPort *
|
||||
O3ThreadContext<Impl>::getVirtPort()
|
||||
FSTranslatingPortProxy*
|
||||
O3ThreadContext<Impl>::getVirtProxy()
|
||||
{
|
||||
return thread->getVirtPort();
|
||||
return thread->getVirtProxy();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
|
|
|
@ -114,12 +114,12 @@ class OzoneCPU : public BaseCPU
|
|||
|
||||
Process *getProcessPtr() { return thread->getProcessPtr(); }
|
||||
|
||||
TranslatingPort *getMemPort() { return thread->getMemPort(); }
|
||||
PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
|
||||
|
||||
VirtualPort *getVirtPort()
|
||||
{ return thread->getVirtPort(); }
|
||||
FSTranslatingPortProxy* getVirtProxy()
|
||||
{ return thread->getVirtProxy(); }
|
||||
|
||||
FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
|
||||
SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); }
|
||||
|
||||
Status status() const { return thread->status(); }
|
||||
|
||||
|
|
|
@ -186,25 +186,7 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
|
|||
frontEnd->renameTable.copyFrom(thread.renameTable);
|
||||
backEnd->renameTable.copyFrom(thread.renameTable);
|
||||
|
||||
if (FullSystem) {
|
||||
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);
|
||||
}
|
||||
thread.connectMemPorts(tc);
|
||||
|
||||
DPRINTF(OzoneCPU, "OzoneCPU: Created Ozone cpu object.\n");
|
||||
}
|
||||
|
|
|
@ -87,13 +87,8 @@ class FrontEnd
|
|||
/** 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; }
|
||||
/** Receives range change. */
|
||||
virtual void recvRangeChange();
|
||||
|
||||
/** Timing version of receive. Handles setting fetch to the
|
||||
* proper status to start fetching. */
|
||||
|
|
|
@ -64,12 +64,8 @@ FrontEnd<Impl>::IcachePort::recvFunctional(PacketPtr pkt)
|
|||
|
||||
template<class Impl>
|
||||
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>
|
||||
|
|
|
@ -255,11 +255,13 @@ class OzoneLWLSQ {
|
|||
|
||||
virtual void recvFunctional(PacketPtr pkt);
|
||||
|
||||
virtual void recvStatusChange(Status status);
|
||||
virtual void recvRangeChange();
|
||||
|
||||
virtual void getDeviceAddressRanges(AddrRangeList &resp,
|
||||
bool &snoop)
|
||||
{ resp.clear(); snoop = true; }
|
||||
/**
|
||||
* Is a snooper due to LSQ maintenance
|
||||
*/
|
||||
virtual bool isSnooping()
|
||||
{ return true; }
|
||||
|
||||
virtual bool recvTiming(PacketPtr pkt);
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue