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
|
import m5
|
||||||
from m5.objects import *
|
from m5.objects import *
|
||||||
from Caches import *
|
from Caches import *
|
||||||
|
from O3_ARM_v7a import *
|
||||||
|
|
||||||
def config_cache(options, system):
|
def config_cache(options, system):
|
||||||
if options.l2cache:
|
if options.l2cache:
|
||||||
system.l2 = L2Cache(size = options.l2_size, assoc = options.l2_assoc,
|
if options.cpu_type == "arm_detailed":
|
||||||
block_size=options.cacheline_size)
|
system.l2 = O3_ARM_v7aL2(size = options.l2_size, assoc = options.l2_assoc,
|
||||||
|
block_size=options.cacheline_size)
|
||||||
|
else:
|
||||||
|
system.l2 = L2Cache(size = options.l2_size, assoc = options.l2_assoc,
|
||||||
|
block_size=options.cacheline_size)
|
||||||
|
|
||||||
system.tol2bus = Bus()
|
system.tol2bus = Bus()
|
||||||
system.l2.cpu_side = system.tol2bus.port
|
system.l2.cpu_side = system.tol2bus.port
|
||||||
system.l2.mem_side = system.membus.port
|
system.l2.mem_side = system.membus.port
|
||||||
|
@ -44,10 +50,21 @@ def config_cache(options, system):
|
||||||
|
|
||||||
for i in xrange(options.num_cpus):
|
for i in xrange(options.num_cpus):
|
||||||
if options.caches:
|
if options.caches:
|
||||||
icache = L1Cache(size = options.l1i_size, assoc = options.l1i_assoc,
|
if options.cpu_type == "arm_detailed":
|
||||||
block_size=options.cacheline_size)
|
icache = O3_ARM_v7a_ICache(size = options.l1i_size,
|
||||||
dcache = L1Cache(size = options.l1d_size, assoc = options.l1d_assoc,
|
assoc = options.l1i_assoc,
|
||||||
block_size=options.cacheline_size)
|
block_size=options.cacheline_size)
|
||||||
|
dcache = O3_ARM_v7a_DCache(size = options.l1d_size,
|
||||||
|
assoc = options.l1d_assoc,
|
||||||
|
block_size=options.cacheline_size)
|
||||||
|
else:
|
||||||
|
icache = L1Cache(size = options.l1i_size,
|
||||||
|
assoc = options.l1i_assoc,
|
||||||
|
block_size=options.cacheline_size)
|
||||||
|
dcache = L1Cache(size = options.l1d_size,
|
||||||
|
assoc = options.l1d_assoc,
|
||||||
|
block_size=options.cacheline_size)
|
||||||
|
|
||||||
if buildEnv['TARGET_ISA'] == 'x86':
|
if buildEnv['TARGET_ISA'] == 'x86':
|
||||||
system.cpu[i].addPrivateSplitL1Caches(icache, dcache,
|
system.cpu[i].addPrivateSplitL1Caches(icache, dcache,
|
||||||
PageTableWalkerCache(),
|
PageTableWalkerCache(),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2010 ARM Limited
|
# Copyright (c) 2010-2012 ARM Limited
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# The license below extends only to copyright in the software and shall
|
# The license below extends only to copyright in the software and shall
|
||||||
|
@ -56,6 +56,7 @@ class MemBus(Bus):
|
||||||
|
|
||||||
|
|
||||||
def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
||||||
|
IO_address_space_base = 0x80000000000
|
||||||
class BaseTsunami(Tsunami):
|
class BaseTsunami(Tsunami):
|
||||||
ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0)
|
ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0)
|
||||||
ide = IdeController(disks=[Parent.disk0, Parent.disk2],
|
ide = IdeController(disks=[Parent.disk0, Parent.disk2],
|
||||||
|
@ -68,10 +69,13 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
||||||
self.readfile = mdesc.script()
|
self.readfile = mdesc.script()
|
||||||
self.iobus = Bus(bus_id=0)
|
self.iobus = Bus(bus_id=0)
|
||||||
self.membus = MemBus(bus_id=1)
|
self.membus = MemBus(bus_id=1)
|
||||||
self.bridge = Bridge(delay='50ns', nack_delay='4ns')
|
# By default the bridge responds to all addresses above the I/O
|
||||||
|
# base address (including the PCI config space)
|
||||||
|
self.bridge = Bridge(delay='50ns', nack_delay='4ns',
|
||||||
|
ranges = [AddrRange(IO_address_space_base, Addr.max)])
|
||||||
self.physmem = PhysicalMemory(range = AddrRange(mdesc.mem()))
|
self.physmem = PhysicalMemory(range = AddrRange(mdesc.mem()))
|
||||||
self.bridge.side_a = self.iobus.port
|
self.bridge.master = self.iobus.port
|
||||||
self.bridge.side_b = self.membus.port
|
self.bridge.slave = self.membus.port
|
||||||
self.physmem.port = self.membus.port
|
self.physmem.port = self.membus.port
|
||||||
self.disk0 = CowIdeDisk(driveID='master')
|
self.disk0 = CowIdeDisk(driveID='master')
|
||||||
self.disk2 = CowIdeDisk(driveID='master')
|
self.disk2 = CowIdeDisk(driveID='master')
|
||||||
|
@ -80,7 +84,11 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
||||||
self.tsunami = BaseTsunami()
|
self.tsunami = BaseTsunami()
|
||||||
self.tsunami.attachIO(self.iobus)
|
self.tsunami.attachIO(self.iobus)
|
||||||
self.tsunami.ide.pio = self.iobus.port
|
self.tsunami.ide.pio = self.iobus.port
|
||||||
|
self.tsunami.ide.config = self.iobus.port
|
||||||
|
self.tsunami.ide.dma = self.iobus.port
|
||||||
self.tsunami.ethernet.pio = self.iobus.port
|
self.tsunami.ethernet.pio = self.iobus.port
|
||||||
|
self.tsunami.ethernet.config = self.iobus.port
|
||||||
|
self.tsunami.ethernet.dma = self.iobus.port
|
||||||
self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(),
|
self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(),
|
||||||
read_only = True))
|
read_only = True))
|
||||||
self.intrctrl = IntrControl()
|
self.intrctrl = IntrControl()
|
||||||
|
@ -91,6 +99,8 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
||||||
self.console = binary('console')
|
self.console = binary('console')
|
||||||
self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
|
self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
|
||||||
|
|
||||||
|
self.system_port = self.membus.port
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def makeLinuxAlphaRubySystem(mem_mode, mdesc = None):
|
def makeLinuxAlphaRubySystem(mem_mode, mdesc = None):
|
||||||
|
@ -123,7 +133,11 @@ def makeLinuxAlphaRubySystem(mem_mode, mdesc = None):
|
||||||
self.tsunami = BaseTsunami()
|
self.tsunami = BaseTsunami()
|
||||||
self.tsunami.attachIO(self.piobus)
|
self.tsunami.attachIO(self.piobus)
|
||||||
self.tsunami.ide.pio = self.piobus.port
|
self.tsunami.ide.pio = self.piobus.port
|
||||||
|
self.tsunami.ide.config = self.piobus.port
|
||||||
|
self.tsunami.ide.dma = self.piobus.port
|
||||||
self.tsunami.ethernet.pio = self.piobus.port
|
self.tsunami.ethernet.pio = self.piobus.port
|
||||||
|
self.tsunami.ethernet.config = self.piobus.port
|
||||||
|
self.tsunami.ethernet.dma = self.piobus.port
|
||||||
|
|
||||||
#
|
#
|
||||||
# Store the dma devices for later connection to dma ruby ports.
|
# Store the dma devices for later connection to dma ruby ports.
|
||||||
|
@ -144,6 +158,10 @@ def makeLinuxAlphaRubySystem(mem_mode, mdesc = None):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def makeSparcSystem(mem_mode, mdesc = None):
|
def makeSparcSystem(mem_mode, mdesc = None):
|
||||||
|
# Constants from iob.cc and uart8250.cc
|
||||||
|
iob_man_addr = 0x9800000000
|
||||||
|
uart_pio_size = 8
|
||||||
|
|
||||||
class CowMmDisk(MmDisk):
|
class CowMmDisk(MmDisk):
|
||||||
image = CowDiskImage(child=RawDiskImage(read_only=True),
|
image = CowDiskImage(child=RawDiskImage(read_only=True),
|
||||||
read_only=False)
|
read_only=False)
|
||||||
|
@ -164,8 +182,8 @@ def makeSparcSystem(mem_mode, mdesc = None):
|
||||||
self.t1000.attachIO(self.iobus)
|
self.t1000.attachIO(self.iobus)
|
||||||
self.physmem = PhysicalMemory(range = AddrRange(Addr('1MB'), size = '64MB'), zero = True)
|
self.physmem = PhysicalMemory(range = AddrRange(Addr('1MB'), size = '64MB'), zero = True)
|
||||||
self.physmem2 = PhysicalMemory(range = AddrRange(Addr('2GB'), size ='256MB'), zero = True)
|
self.physmem2 = PhysicalMemory(range = AddrRange(Addr('2GB'), size ='256MB'), zero = True)
|
||||||
self.bridge.side_a = self.iobus.port
|
self.bridge.master = self.iobus.port
|
||||||
self.bridge.side_b = self.membus.port
|
self.bridge.slave = self.membus.port
|
||||||
self.physmem.port = self.membus.port
|
self.physmem.port = self.membus.port
|
||||||
self.physmem2.port = self.membus.port
|
self.physmem2.port = self.membus.port
|
||||||
self.rom.port = self.membus.port
|
self.rom.port = self.membus.port
|
||||||
|
@ -176,6 +194,25 @@ def makeSparcSystem(mem_mode, mdesc = None):
|
||||||
self.disk0 = CowMmDisk()
|
self.disk0 = CowMmDisk()
|
||||||
self.disk0.childImage(disk('disk.s10hw2'))
|
self.disk0.childImage(disk('disk.s10hw2'))
|
||||||
self.disk0.pio = self.iobus.port
|
self.disk0.pio = self.iobus.port
|
||||||
|
|
||||||
|
# The puart0 and hvuart are placed on the IO bus, so create ranges
|
||||||
|
# for them. The remaining IO range is rather fragmented, so poke
|
||||||
|
# holes for the iob and partition descriptors etc.
|
||||||
|
self.bridge.ranges = \
|
||||||
|
[
|
||||||
|
AddrRange(self.t1000.puart0.pio_addr,
|
||||||
|
self.t1000.puart0.pio_addr + uart_pio_size - 1),
|
||||||
|
AddrRange(self.disk0.pio_addr,
|
||||||
|
self.t1000.fake_jbi.pio_addr +
|
||||||
|
self.t1000.fake_jbi.pio_size - 1),
|
||||||
|
AddrRange(self.t1000.fake_clk.pio_addr,
|
||||||
|
iob_man_addr - 1),
|
||||||
|
AddrRange(self.t1000.fake_l2_1.pio_addr,
|
||||||
|
self.t1000.fake_ssi.pio_addr +
|
||||||
|
self.t1000.fake_ssi.pio_size - 1),
|
||||||
|
AddrRange(self.t1000.hvuart.pio_addr,
|
||||||
|
self.t1000.hvuart.pio_addr + uart_pio_size - 1)
|
||||||
|
]
|
||||||
self.reset_bin = binary('reset_new.bin')
|
self.reset_bin = binary('reset_new.bin')
|
||||||
self.hypervisor_bin = binary('q_new.bin')
|
self.hypervisor_bin = binary('q_new.bin')
|
||||||
self.openboot_bin = binary('openboot_new.bin')
|
self.openboot_bin = binary('openboot_new.bin')
|
||||||
|
@ -183,6 +220,8 @@ def makeSparcSystem(mem_mode, mdesc = None):
|
||||||
self.hypervisor_desc_bin = binary('1up-hv.bin')
|
self.hypervisor_desc_bin = binary('1up-hv.bin')
|
||||||
self.partition_desc_bin = binary('1up-md.bin')
|
self.partition_desc_bin = binary('1up-md.bin')
|
||||||
|
|
||||||
|
self.system_port = self.membus.port
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def makeArmSystem(mem_mode, machine_type, mdesc = None, bare_metal=False):
|
def makeArmSystem(mem_mode, machine_type, mdesc = None, bare_metal=False):
|
||||||
|
@ -202,8 +241,8 @@ def makeArmSystem(mem_mode, machine_type, mdesc = None, bare_metal=False):
|
||||||
self.membus = MemBus(bus_id=1)
|
self.membus = MemBus(bus_id=1)
|
||||||
self.membus.badaddr_responder.warn_access = "warn"
|
self.membus.badaddr_responder.warn_access = "warn"
|
||||||
self.bridge = Bridge(delay='50ns', nack_delay='4ns')
|
self.bridge = Bridge(delay='50ns', nack_delay='4ns')
|
||||||
self.bridge.side_a = self.iobus.port
|
self.bridge.master = self.iobus.port
|
||||||
self.bridge.side_b = self.membus.port
|
self.bridge.slave = self.membus.port
|
||||||
|
|
||||||
self.mem_mode = mem_mode
|
self.mem_mode = mem_mode
|
||||||
|
|
||||||
|
@ -257,12 +296,14 @@ def makeArmSystem(mem_mode, machine_type, mdesc = None, bare_metal=False):
|
||||||
self.boot_osflags = boot_flags
|
self.boot_osflags = boot_flags
|
||||||
|
|
||||||
self.physmem.port = self.membus.port
|
self.physmem.port = self.membus.port
|
||||||
self.realview.attachOnChipIO(self.membus)
|
self.realview.attachOnChipIO(self.membus, self.bridge)
|
||||||
self.realview.attachIO(self.iobus)
|
self.realview.attachIO(self.iobus)
|
||||||
self.intrctrl = IntrControl()
|
self.intrctrl = IntrControl()
|
||||||
self.terminal = Terminal()
|
self.terminal = Terminal()
|
||||||
self.vncserver = VncServer()
|
self.vncserver = VncServer()
|
||||||
|
|
||||||
|
self.system_port = self.membus.port
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
@ -281,8 +322,8 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None):
|
||||||
self.membus = MemBus(bus_id=1)
|
self.membus = MemBus(bus_id=1)
|
||||||
self.bridge = Bridge(delay='50ns', nack_delay='4ns')
|
self.bridge = Bridge(delay='50ns', nack_delay='4ns')
|
||||||
self.physmem = PhysicalMemory(range = AddrRange('1GB'))
|
self.physmem = PhysicalMemory(range = AddrRange('1GB'))
|
||||||
self.bridge.side_a = self.iobus.port
|
self.bridge.master = self.iobus.port
|
||||||
self.bridge.side_b = self.membus.port
|
self.bridge.slave = self.membus.port
|
||||||
self.physmem.port = self.membus.port
|
self.physmem.port = self.membus.port
|
||||||
self.disk0 = CowIdeDisk(driveID='master')
|
self.disk0 = CowIdeDisk(driveID='master')
|
||||||
self.disk2 = CowIdeDisk(driveID='master')
|
self.disk2 = CowIdeDisk(driveID='master')
|
||||||
|
@ -291,7 +332,11 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None):
|
||||||
self.malta = BaseMalta()
|
self.malta = BaseMalta()
|
||||||
self.malta.attachIO(self.iobus)
|
self.malta.attachIO(self.iobus)
|
||||||
self.malta.ide.pio = self.iobus.port
|
self.malta.ide.pio = self.iobus.port
|
||||||
|
self.malta.ide.config = self.iobus.port
|
||||||
|
self.malta.ide.dma = self.iobus.port
|
||||||
self.malta.ethernet.pio = self.iobus.port
|
self.malta.ethernet.pio = self.iobus.port
|
||||||
|
self.malta.ethernet.config = self.iobus.port
|
||||||
|
self.malta.ethernet.dma = self.iobus.port
|
||||||
self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(),
|
self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(),
|
||||||
read_only = True))
|
read_only = True))
|
||||||
self.intrctrl = IntrControl()
|
self.intrctrl = IntrControl()
|
||||||
|
@ -301,6 +346,8 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None):
|
||||||
self.console = binary('mips/console')
|
self.console = binary('mips/console')
|
||||||
self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
|
self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
|
||||||
|
|
||||||
|
self.system_port = self.membus.port
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def x86IOAddress(port):
|
def x86IOAddress(port):
|
||||||
|
@ -308,18 +355,48 @@ def x86IOAddress(port):
|
||||||
return IO_address_space_base + port
|
return IO_address_space_base + port
|
||||||
|
|
||||||
def connectX86ClassicSystem(x86_sys):
|
def connectX86ClassicSystem(x86_sys):
|
||||||
|
# Constants similar to x86_traits.hh
|
||||||
|
IO_address_space_base = 0x8000000000000000
|
||||||
|
pci_config_address_space_base = 0xc000000000000000
|
||||||
|
interrupts_address_space_base = 0xa000000000000000
|
||||||
|
APIC_range_size = 1 << 12;
|
||||||
|
|
||||||
x86_sys.membus = MemBus(bus_id=1)
|
x86_sys.membus = MemBus(bus_id=1)
|
||||||
x86_sys.physmem.port = x86_sys.membus.port
|
x86_sys.physmem.port = x86_sys.membus.port
|
||||||
|
|
||||||
# North Bridge
|
# North Bridge
|
||||||
x86_sys.iobus = Bus(bus_id=0)
|
x86_sys.iobus = Bus(bus_id=0)
|
||||||
x86_sys.bridge = Bridge(delay='50ns', nack_delay='4ns')
|
x86_sys.bridge = Bridge(delay='50ns', nack_delay='4ns')
|
||||||
x86_sys.bridge.side_a = x86_sys.iobus.port
|
x86_sys.bridge.master = x86_sys.iobus.port
|
||||||
x86_sys.bridge.side_b = x86_sys.membus.port
|
x86_sys.bridge.slave = x86_sys.membus.port
|
||||||
|
# Allow the bridge to pass through the IO APIC (two pages),
|
||||||
|
# everything in the IO address range up to the local APIC, and
|
||||||
|
# then the entire PCI address space and beyond
|
||||||
|
x86_sys.bridge.ranges = \
|
||||||
|
[
|
||||||
|
AddrRange(x86_sys.pc.south_bridge.io_apic.pio_addr,
|
||||||
|
x86_sys.pc.south_bridge.io_apic.pio_addr +
|
||||||
|
APIC_range_size - 1),
|
||||||
|
AddrRange(IO_address_space_base,
|
||||||
|
interrupts_address_space_base - 1),
|
||||||
|
AddrRange(pci_config_address_space_base,
|
||||||
|
Addr.max)
|
||||||
|
]
|
||||||
|
|
||||||
|
# Create a bridge from the IO bus to the memory bus to allow access to
|
||||||
|
# the local APIC (two pages)
|
||||||
|
x86_sys.iobridge = Bridge(delay='50ns', nack_delay='4ns')
|
||||||
|
x86_sys.iobridge.slave = x86_sys.iobus.port
|
||||||
|
x86_sys.iobridge.master = x86_sys.membus.port
|
||||||
|
x86_sys.iobridge.ranges = [AddrRange(interrupts_address_space_base,
|
||||||
|
interrupts_address_space_base +
|
||||||
|
APIC_range_size - 1)]
|
||||||
|
|
||||||
# connect the io bus
|
# connect the io bus
|
||||||
x86_sys.pc.attachIO(x86_sys.iobus)
|
x86_sys.pc.attachIO(x86_sys.iobus)
|
||||||
|
|
||||||
|
x86_sys.system_port = x86_sys.membus.port
|
||||||
|
|
||||||
def connectX86RubySystem(x86_sys):
|
def connectX86RubySystem(x86_sys):
|
||||||
# North Bridge
|
# North Bridge
|
||||||
x86_sys.piobus = Bus(bus_id=0)
|
x86_sys.piobus = Bus(bus_id=0)
|
||||||
|
|
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
|
# system options
|
||||||
parser.add_option("--cpu-type", type="choice", default="atomic",
|
parser.add_option("--cpu-type", type="choice", default="atomic",
|
||||||
choices = ["atomic", "timing", "detailed", "inorder"],
|
choices = ["atomic", "timing", "detailed", "inorder",
|
||||||
|
"arm_detailed"],
|
||||||
help = "type of cpu to run with")
|
help = "type of cpu to run with")
|
||||||
parser.add_option("-n", "--num-cpus", type="int", default=1)
|
parser.add_option("-n", "--num-cpus", type="int", default=1)
|
||||||
parser.add_option("--caches", action="store_true")
|
parser.add_option("--caches", action="store_true")
|
||||||
|
|
|
@ -34,6 +34,7 @@ import m5
|
||||||
from m5.defines import buildEnv
|
from m5.defines import buildEnv
|
||||||
from m5.objects import *
|
from m5.objects import *
|
||||||
from m5.util import *
|
from m5.util import *
|
||||||
|
from O3_ARM_v7a import *
|
||||||
|
|
||||||
addToPath('../common')
|
addToPath('../common')
|
||||||
|
|
||||||
|
@ -42,11 +43,14 @@ def setCPUClass(options):
|
||||||
atomic = False
|
atomic = False
|
||||||
if options.cpu_type == "timing":
|
if options.cpu_type == "timing":
|
||||||
class TmpClass(TimingSimpleCPU): pass
|
class TmpClass(TimingSimpleCPU): pass
|
||||||
elif options.cpu_type == "detailed":
|
elif options.cpu_type == "detailed" or options.cpu_type == "arm_detailed":
|
||||||
if not options.caches:
|
if not options.caches and not options.ruby:
|
||||||
print "O3 CPU must be used with caches"
|
print "O3 CPU must be used with caches"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
class TmpClass(DerivO3CPU): pass
|
if options.cpu_type == "arm_detailed":
|
||||||
|
class TmpClass(O3_ARM_v7a_3): pass
|
||||||
|
else:
|
||||||
|
class TmpClass(DerivO3CPU): pass
|
||||||
elif options.cpu_type == "inorder":
|
elif options.cpu_type == "inorder":
|
||||||
if not options.caches:
|
if not options.caches:
|
||||||
print "InOrder CPU must be used with caches"
|
print "InOrder CPU must be used with caches"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2010 ARM Limited
|
# Copyright (c) 2010-2011 ARM Limited
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# The license below extends only to copyright in the software and shall
|
# The license below extends only to copyright in the software and shall
|
||||||
|
@ -157,23 +157,19 @@ test_sys.cpu = [TestCPUClass(cpu_id=i) for i in xrange(np)]
|
||||||
|
|
||||||
CacheConfig.config_cache(options, test_sys)
|
CacheConfig.config_cache(options, test_sys)
|
||||||
|
|
||||||
|
if bm[0]:
|
||||||
|
mem_size = bm[0].mem()
|
||||||
|
else:
|
||||||
|
mem_size = SysConfig().mem()
|
||||||
if options.caches or options.l2cache:
|
if options.caches or options.l2cache:
|
||||||
if bm[0]:
|
|
||||||
mem_size = bm[0].mem()
|
|
||||||
else:
|
|
||||||
mem_size = SysConfig().mem()
|
|
||||||
# For x86, we need to poke a hole for interrupt messages to get back to the
|
|
||||||
# CPU. These use a portion of the physical address space which has a
|
|
||||||
# non-zero prefix in the top nibble. Normal memory accesses have a 0
|
|
||||||
# prefix.
|
|
||||||
if buildEnv['TARGET_ISA'] == 'x86':
|
|
||||||
test_sys.bridge.filter_ranges_a=[AddrRange(0, Addr.max >> 4)]
|
|
||||||
else:
|
|
||||||
test_sys.bridge.filter_ranges_a=[AddrRange(0, Addr.max)]
|
|
||||||
test_sys.bridge.filter_ranges_b=[AddrRange(mem_size)]
|
|
||||||
test_sys.iocache = IOCache(addr_range=mem_size)
|
test_sys.iocache = IOCache(addr_range=mem_size)
|
||||||
test_sys.iocache.cpu_side = test_sys.iobus.port
|
test_sys.iocache.cpu_side = test_sys.iobus.port
|
||||||
test_sys.iocache.mem_side = test_sys.membus.port
|
test_sys.iocache.mem_side = test_sys.membus.port
|
||||||
|
else:
|
||||||
|
test_sys.iobridge = Bridge(delay='50ns', nack_delay='4ns',
|
||||||
|
ranges = [AddrRange(mem_size)])
|
||||||
|
test_sys.iobridge.slave = test_sys.iobus.port
|
||||||
|
test_sys.iobridge.master = test_sys.membus.port
|
||||||
|
|
||||||
for i in xrange(np):
|
for i in xrange(np):
|
||||||
if options.fastmem:
|
if options.fastmem:
|
||||||
|
|
|
@ -1,3 +1,15 @@
|
||||||
|
# Copyright (c) 2012 ARM Limited
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# The license below extends only to copyright in the software and shall
|
||||||
|
# not be construed as granting a license to any other intellectual
|
||||||
|
# property including but not limited to intellectual property relating
|
||||||
|
# to a hardware implementation of the functionality of the software
|
||||||
|
# licensed hereunder. You may use the software subject to the license
|
||||||
|
# terms below provided that you ensure that this notice is replicated
|
||||||
|
# unmodified and in its entirety in all distributions of the software,
|
||||||
|
# modified or unmodified, in source code or in binary form.
|
||||||
|
#
|
||||||
# Copyright (c) 2006-2008 The Regents of The University of Michigan
|
# Copyright (c) 2006-2008 The Regents of The University of Michigan
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
|
@ -152,20 +164,13 @@ if options.cpu_type == "detailed" or options.cpu_type == "inorder":
|
||||||
process += [smt_process, ]
|
process += [smt_process, ]
|
||||||
smt_idx += 1
|
smt_idx += 1
|
||||||
numThreads = len(workloads)
|
numThreads = len(workloads)
|
||||||
|
|
||||||
if options.ruby:
|
if options.ruby:
|
||||||
if options.cpu_type == "detailed":
|
if not (options.cpu_type == "detailed" or options.cpu_type == "timing"):
|
||||||
print >> sys.stderr, "Ruby only works with TimingSimpleCPU!!"
|
print >> sys.stderr, "Ruby requires TimingSimpleCPU or O3CPU!!"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
elif not options.cpu_type == "timing":
|
|
||||||
print >> sys.stderr, "****WARN: using Timing CPU since it's needed by Ruby"
|
|
||||||
|
|
||||||
class CPUClass(TimingSimpleCPU): pass
|
|
||||||
test_mem_mode = 'timing'
|
|
||||||
FutureClass = None
|
|
||||||
else:
|
|
||||||
(CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options)
|
|
||||||
|
|
||||||
|
(CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options)
|
||||||
CPUClass.clock = '2GHz'
|
CPUClass.clock = '2GHz'
|
||||||
CPUClass.numThreads = numThreads;
|
CPUClass.numThreads = numThreads;
|
||||||
|
|
||||||
|
@ -179,7 +184,9 @@ if options.ruby:
|
||||||
options.use_map = True
|
options.use_map = True
|
||||||
Ruby.create_system(options, system)
|
Ruby.create_system(options, system)
|
||||||
assert(options.num_cpus == len(system.ruby._cpu_ruby_ports))
|
assert(options.num_cpus == len(system.ruby._cpu_ruby_ports))
|
||||||
|
system.system_port = system.ruby._sys_port_proxy.port
|
||||||
else:
|
else:
|
||||||
|
system.system_port = system.membus.port
|
||||||
system.physmem.port = system.membus.port
|
system.physmem.port = system.membus.port
|
||||||
CacheConfig.config_cache(options, system)
|
CacheConfig.config_cache(options, system)
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,8 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
|
||||||
L1IcacheMemory = l1i_cache,
|
L1IcacheMemory = l1i_cache,
|
||||||
L1DcacheMemory = l1d_cache,
|
L1DcacheMemory = l1d_cache,
|
||||||
l2_select_num_bits = l2_bits,
|
l2_select_num_bits = l2_bits,
|
||||||
|
send_evictions = (
|
||||||
|
options.cpu_type == "detailed"),
|
||||||
ruby_system = ruby_system)
|
ruby_system = ruby_system)
|
||||||
|
|
||||||
cpu_seq = RubySequencer(version = i,
|
cpu_seq = RubySequencer(version = i,
|
||||||
|
@ -151,7 +153,9 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
|
||||||
cntrl_id = cntrl_count,
|
cntrl_id = cntrl_count,
|
||||||
directory = \
|
directory = \
|
||||||
RubyDirectoryMemory(version = i,
|
RubyDirectoryMemory(version = i,
|
||||||
size = dir_size),
|
size = dir_size,
|
||||||
|
use_map =
|
||||||
|
options.use_map),
|
||||||
memBuffer = mem_cntrl,
|
memBuffer = mem_cntrl,
|
||||||
ruby_system = ruby_system)
|
ruby_system = ruby_system)
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,8 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
|
||||||
l1_cntrl = L1Cache_Controller(version = i,
|
l1_cntrl = L1Cache_Controller(version = i,
|
||||||
cntrl_id = cntrl_count,
|
cntrl_id = cntrl_count,
|
||||||
cacheMemory = cache,
|
cacheMemory = cache,
|
||||||
|
send_evictions = (
|
||||||
|
options.cpu_type == "detailed"),
|
||||||
ruby_system = ruby_system)
|
ruby_system = ruby_system)
|
||||||
|
|
||||||
cpu_seq = RubySequencer(version = i,
|
cpu_seq = RubySequencer(version = i,
|
||||||
|
|
|
@ -89,6 +89,8 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
|
||||||
L1IcacheMemory = l1i_cache,
|
L1IcacheMemory = l1i_cache,
|
||||||
L1DcacheMemory = l1d_cache,
|
L1DcacheMemory = l1d_cache,
|
||||||
l2_select_num_bits = l2_bits,
|
l2_select_num_bits = l2_bits,
|
||||||
|
send_evictions = (
|
||||||
|
options.cpu_type == "detailed"),
|
||||||
ruby_system = ruby_system)
|
ruby_system = ruby_system)
|
||||||
|
|
||||||
cpu_seq = RubySequencer(version = i,
|
cpu_seq = RubySequencer(version = i,
|
||||||
|
|
|
@ -111,6 +111,8 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
|
||||||
not options.disable_dyn_timeouts,
|
not options.disable_dyn_timeouts,
|
||||||
no_mig_atomic = not \
|
no_mig_atomic = not \
|
||||||
options.allow_atomic_migration,
|
options.allow_atomic_migration,
|
||||||
|
send_evictions = (
|
||||||
|
options.cpu_type == "detailed"),
|
||||||
ruby_system = ruby_system)
|
ruby_system = ruby_system)
|
||||||
|
|
||||||
cpu_seq = RubySequencer(version = i,
|
cpu_seq = RubySequencer(version = i,
|
||||||
|
|
|
@ -104,6 +104,8 @@ def create_system(options, system, piobus, dma_devices, ruby_system):
|
||||||
L2cacheMemory = l2_cache,
|
L2cacheMemory = l2_cache,
|
||||||
no_mig_atomic = not \
|
no_mig_atomic = not \
|
||||||
options.allow_atomic_migration,
|
options.allow_atomic_migration,
|
||||||
|
send_evictions = (
|
||||||
|
options.cpu_type == "detailed"),
|
||||||
ruby_system = ruby_system)
|
ruby_system = ruby_system)
|
||||||
|
|
||||||
cpu_seq = RubySequencer(version = i,
|
cpu_seq = RubySequencer(version = i,
|
||||||
|
|
|
@ -1,3 +1,15 @@
|
||||||
|
# Copyright (c) 2012 ARM Limited
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# The license below extends only to copyright in the software and shall
|
||||||
|
# not be construed as granting a license to any other intellectual
|
||||||
|
# property including but not limited to intellectual property relating
|
||||||
|
# to a hardware implementation of the functionality of the software
|
||||||
|
# licensed hereunder. You may use the software subject to the license
|
||||||
|
# terms below provided that you ensure that this notice is replicated
|
||||||
|
# unmodified and in its entirety in all distributions of the software,
|
||||||
|
# modified or unmodified, in source code or in binary form.
|
||||||
|
#
|
||||||
# Copyright (c) 2006-2007 The Regents of The University of Michigan
|
# Copyright (c) 2006-2007 The Regents of The University of Michigan
|
||||||
# Copyright (c) 2009 Advanced Micro Devices, Inc.
|
# Copyright (c) 2009 Advanced Micro Devices, Inc.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
@ -82,6 +94,17 @@ def create_system(options, system, piobus = None, dma_devices = []):
|
||||||
print "Error: could not create sytem for ruby protocol %s" % protocol
|
print "Error: could not create sytem for ruby protocol %s" % protocol
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
# Create a port proxy for connecting the system port. This is
|
||||||
|
# independent of the protocol and kept in the protocol-agnostic
|
||||||
|
# part (i.e. here).
|
||||||
|
sys_port_proxy = RubyPortProxy(version = 0,
|
||||||
|
physMemPort = system.physmem.port,
|
||||||
|
physmem = system.physmem,
|
||||||
|
ruby_system = ruby)
|
||||||
|
# Give the system port proxy a SimObject parent without creating a
|
||||||
|
# full-fledged controller
|
||||||
|
system.sys_port_proxy = sys_port_proxy
|
||||||
|
|
||||||
#
|
#
|
||||||
# Set the network classes based on the command line options
|
# Set the network classes based on the command line options
|
||||||
#
|
#
|
||||||
|
@ -159,4 +182,5 @@ def create_system(options, system, piobus = None, dma_devices = []):
|
||||||
ruby.profiler = ruby_profiler
|
ruby.profiler = ruby_profiler
|
||||||
ruby.mem_size = total_mem_size
|
ruby.mem_size = total_mem_size
|
||||||
ruby._cpu_ruby_ports = cpu_sequencers
|
ruby._cpu_ruby_ports = cpu_sequencers
|
||||||
|
ruby._sys_port_proxy = sys_port_proxy
|
||||||
ruby.random_seed = options.random_seed
|
ruby.random_seed = options.random_seed
|
||||||
|
|
|
@ -41,9 +41,7 @@
|
||||||
#include "arch/vtophys.hh"
|
#include "arch/vtophys.hh"
|
||||||
#include "base/loader/symtab.hh"
|
#include "base/loader/symtab.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/physical.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "mem/port.hh"
|
|
||||||
#include "mem/vport.hh"
|
|
||||||
#include "sim/byteswap.hh"
|
#include "sim/byteswap.hh"
|
||||||
|
|
||||||
#define TIMER_FREQUENCY 1193180
|
#define TIMER_FREQUENCY 1193180
|
||||||
|
@ -78,8 +76,8 @@ FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc)
|
||||||
ppc_vaddr = (Addr)tc->readIntReg(17);
|
ppc_vaddr = (Addr)tc->readIntReg(17);
|
||||||
timer_vaddr = (Addr)tc->readIntReg(18);
|
timer_vaddr = (Addr)tc->readIntReg(18);
|
||||||
|
|
||||||
virtPort->write(ppc_vaddr, (uint32_t)SimClock::Frequency);
|
virtProxy->write(ppc_vaddr, (uint32_t)SimClock::Frequency);
|
||||||
virtPort->write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
|
virtProxy->write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -56,7 +56,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
||||||
strcpy(name->machine, "alpha");
|
strcpy(name->machine, "alpha");
|
||||||
|
|
||||||
name.copyOut(tc->getMemPort());
|
name.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
||||||
// I don't think this exactly matches the HW FPCR
|
// I don't think this exactly matches the HW FPCR
|
||||||
*fpcr = 0;
|
*fpcr = 0;
|
||||||
fpcr.copyOut(tc->getMemPort());
|
fpcr.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
case 14: { // SSI_IEEE_FP_CONTROL
|
case 14: { // SSI_IEEE_FP_CONTROL
|
||||||
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
||||||
// I don't think this exactly matches the HW FPCR
|
// I don't think this exactly matches the HW FPCR
|
||||||
fpcr.copyIn(tc->getMemPort());
|
fpcr.copyIn(tc->getMemProxy());
|
||||||
DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
|
DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
|
||||||
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
|
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -63,6 +63,17 @@ using namespace Linux;
|
||||||
LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
|
LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
|
||||||
: AlphaSystem(p)
|
: AlphaSystem(p)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LinuxAlphaSystem::initState()
|
||||||
|
{
|
||||||
|
// Moved from the constructor to here since it relies on the
|
||||||
|
// address map being resolved in the interconnect
|
||||||
|
|
||||||
|
// Call the initialisation of the super class
|
||||||
|
AlphaSystem::initState();
|
||||||
|
|
||||||
Addr addr = 0;
|
Addr addr = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -77,8 +88,9 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
|
||||||
* Since we aren't using a bootloader, we have to copy the
|
* Since we aren't using a bootloader, we have to copy the
|
||||||
* kernel arguments directly into the kernel's memory.
|
* kernel arguments directly into the kernel's memory.
|
||||||
*/
|
*/
|
||||||
virtPort->writeBlob(CommandLine(), (uint8_t*)params()->boot_osflags.c_str(),
|
virtProxy->writeBlob(CommandLine(),
|
||||||
params()->boot_osflags.length()+1);
|
(uint8_t*)params()->boot_osflags.c_str(),
|
||||||
|
params()->boot_osflags.length()+1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find the address of the est_cycle_freq variable and insert it
|
* find the address of the est_cycle_freq variable and insert it
|
||||||
|
@ -86,8 +98,8 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
|
||||||
* calculated it by using the PIT, RTC, etc.
|
* calculated it by using the PIT, RTC, etc.
|
||||||
*/
|
*/
|
||||||
if (kernelSymtab->findAddress("est_cycle_freq", addr))
|
if (kernelSymtab->findAddress("est_cycle_freq", addr))
|
||||||
virtPort->write(addr, (uint64_t)(SimClock::Frequency /
|
virtProxy->write(addr, (uint64_t)(SimClock::Frequency /
|
||||||
p->boot_cpu_frequency));
|
params()->boot_cpu_frequency));
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,7 +109,7 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
|
||||||
* 255 ASNs.
|
* 255 ASNs.
|
||||||
*/
|
*/
|
||||||
if (kernelSymtab->findAddress("dp264_mv", addr))
|
if (kernelSymtab->findAddress("dp264_mv", addr))
|
||||||
virtPort->write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127));
|
virtProxy->write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127));
|
||||||
else
|
else
|
||||||
panic("could not find dp264_mv\n");
|
panic("could not find dp264_mv\n");
|
||||||
|
|
||||||
|
@ -164,9 +176,9 @@ LinuxAlphaSystem::setDelayLoop(ThreadContext *tc)
|
||||||
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
|
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
|
||||||
Tick cpuFreq = tc->getCpuPtr()->frequency();
|
Tick cpuFreq = tc->getCpuPtr()->frequency();
|
||||||
assert(intrFreq);
|
assert(intrFreq);
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
|
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,14 @@ class LinuxAlphaSystem : public AlphaSystem
|
||||||
LinuxAlphaSystem(Params *p);
|
LinuxAlphaSystem(Params *p);
|
||||||
~LinuxAlphaSystem();
|
~LinuxAlphaSystem();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the system
|
||||||
|
*/
|
||||||
|
virtual void initState();
|
||||||
|
|
||||||
void setDelayLoop(ThreadContext *tc);
|
void setDelayLoop(ThreadContext *tc);
|
||||||
|
|
||||||
|
const Params *params() const { return (const Params *)_params; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ARCH_ALPHA_LINUX_SYSTEM_HH__
|
#endif // __ARCH_ALPHA_LINUX_SYSTEM_HH__
|
||||||
|
|
|
@ -78,7 +78,7 @@ class ThreadInfo
|
||||||
if (!addr)
|
if (!addr)
|
||||||
addr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23);
|
addr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23);
|
||||||
|
|
||||||
FunctionalPort *p = tc->getPhysPort();
|
PortProxy* p = tc->getPhysProxy();
|
||||||
p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
|
p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
|
||||||
|
|
||||||
return sp & ~ULL(0x3fff);
|
return sp & ~ULL(0x3fff);
|
||||||
|
|
|
@ -188,7 +188,7 @@ RemoteGDB::acc(Addr va, size_t len)
|
||||||
|
|
||||||
Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20);
|
Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20);
|
||||||
PageTableEntry pte =
|
PageTableEntry pte =
|
||||||
kernel_pte_lookup(context->getPhysPort(), ptbr, va);
|
kernel_pte_lookup(context->getPhysProxy(), ptbr, va);
|
||||||
if (!pte.valid()) {
|
if (!pte.valid()) {
|
||||||
DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
|
DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
|
||||||
return false;
|
return false;
|
||||||
|
@ -312,3 +312,11 @@ RemoteGDB::write(Addr vaddr, size_t size, const char *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
RemoteGDB::insertHardBreak(Addr addr, size_t len)
|
||||||
|
{
|
||||||
|
warn_once("Breakpoints do not work in Alpha PAL mode.\n"
|
||||||
|
" See PCEventQueue::doService() in cpu/pc_event.cc.\n");
|
||||||
|
return BaseRemoteGDB::insertHardBreak(addr, len);
|
||||||
|
}
|
||||||
|
|
|
@ -63,6 +63,8 @@ class RemoteGDB : public BaseRemoteGDB
|
||||||
bool acc(Addr addr, size_t len);
|
bool acc(Addr addr, size_t len);
|
||||||
bool write(Addr addr, size_t size, const char *data);
|
bool write(Addr addr, size_t size, const char *data);
|
||||||
|
|
||||||
|
virtual bool insertHardBreak(Addr addr, size_t len);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RemoteGDB(System *system, ThreadContext *context);
|
RemoteGDB(System *system, ThreadContext *context);
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -48,7 +48,7 @@ ProcessInfo::ProcessInfo(ThreadContext *_tc)
|
||||||
: tc(_tc)
|
: tc(_tc)
|
||||||
{
|
{
|
||||||
Addr addr = 0;
|
Addr addr = 0;
|
||||||
VirtualPort *vp = tc->getVirtPort();
|
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||||
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
|
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
|
||||||
|
|
||||||
if (!symtab->findAddress("thread_info_size", addr))
|
if (!symtab->findAddress("thread_info_size", addr))
|
||||||
|
@ -81,9 +81,9 @@ ProcessInfo::task(Addr ksp) const
|
||||||
|
|
||||||
Addr tsk;
|
Addr tsk;
|
||||||
|
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
tsk = vp->readGtoH<Addr>(base + task_off);
|
tsk = vp->readGtoH<Addr>(base + task_off);
|
||||||
|
|
||||||
return tsk;
|
return tsk;
|
||||||
|
@ -98,9 +98,9 @@ ProcessInfo::pid(Addr ksp) const
|
||||||
|
|
||||||
uint16_t pd;
|
uint16_t pd;
|
||||||
|
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
||||||
|
|
||||||
return pd;
|
return pd;
|
||||||
|
|
|
@ -38,8 +38,7 @@
|
||||||
#include "base/loader/symtab.hh"
|
#include "base/loader/symtab.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "debug/Loader.hh"
|
#include "debug/Loader.hh"
|
||||||
#include "mem/physical.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "mem/vport.hh"
|
|
||||||
#include "params/AlphaSystem.hh"
|
#include "params/AlphaSystem.hh"
|
||||||
#include "sim/byteswap.hh"
|
#include "sim/byteswap.hh"
|
||||||
|
|
||||||
|
@ -64,11 +63,30 @@ AlphaSystem::AlphaSystem(Params *p)
|
||||||
pal = createObjectFile(params()->pal);
|
pal = createObjectFile(params()->pal);
|
||||||
if (pal == NULL)
|
if (pal == NULL)
|
||||||
fatal("Could not load PALcode file %s", params()->pal);
|
fatal("Could not load PALcode file %s", params()->pal);
|
||||||
|
}
|
||||||
|
|
||||||
|
AlphaSystem::~AlphaSystem()
|
||||||
|
{
|
||||||
|
delete consoleSymtab;
|
||||||
|
delete console;
|
||||||
|
delete pal;
|
||||||
|
#ifdef DEBUG
|
||||||
|
delete consolePanicEvent;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AlphaSystem::initState()
|
||||||
|
{
|
||||||
|
// Moved from the constructor to here since it relies on the
|
||||||
|
// address map being resolved in the interconnect
|
||||||
|
|
||||||
|
// Call the initialisation of the super class
|
||||||
|
System::initState();
|
||||||
|
|
||||||
// Load program sections into memory
|
// Load program sections into memory
|
||||||
pal->loadSections(functionalPort, loadAddrMask);
|
pal->loadSections(physProxy, loadAddrMask);
|
||||||
console->loadSections(functionalPort, loadAddrMask);
|
console->loadSections(physProxy, loadAddrMask);
|
||||||
|
|
||||||
// load symbols
|
// load symbols
|
||||||
if (!console->loadGlobalSymbols(consoleSymtab))
|
if (!console->loadGlobalSymbols(consoleSymtab))
|
||||||
|
@ -101,8 +119,8 @@ AlphaSystem::AlphaSystem(Params *p)
|
||||||
* others do.)
|
* others do.)
|
||||||
*/
|
*/
|
||||||
if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
|
if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
|
||||||
virtPort->writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
|
virtProxy->writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
|
||||||
strlen(params()->boot_osflags.c_str()));
|
strlen(params()->boot_osflags.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -112,23 +130,13 @@ AlphaSystem::AlphaSystem(Params *p)
|
||||||
if (consoleSymtab->findAddress("m5_rpb", addr)) {
|
if (consoleSymtab->findAddress("m5_rpb", addr)) {
|
||||||
uint64_t data;
|
uint64_t data;
|
||||||
data = htog(params()->system_type);
|
data = htog(params()->system_type);
|
||||||
virtPort->write(addr+0x50, data);
|
virtProxy->write(addr+0x50, data);
|
||||||
data = htog(params()->system_rev);
|
data = htog(params()->system_rev);
|
||||||
virtPort->write(addr+0x58, data);
|
virtProxy->write(addr+0x58, data);
|
||||||
} else
|
} else
|
||||||
panic("could not find hwrpb\n");
|
panic("could not find hwrpb\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
AlphaSystem::~AlphaSystem()
|
|
||||||
{
|
|
||||||
delete consoleSymtab;
|
|
||||||
delete console;
|
|
||||||
delete pal;
|
|
||||||
#ifdef DEBUG
|
|
||||||
delete consolePanicEvent;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function fixes up addresses that are used to match PCs for
|
* This function fixes up addresses that are used to match PCs for
|
||||||
* hooking simulator events on to target function executions.
|
* hooking simulator events on to target function executions.
|
||||||
|
@ -170,8 +178,8 @@ AlphaSystem::fixFuncEventAddr(Addr addr)
|
||||||
// lda gp,Y(gp): opcode 8, Ra = 29, rb = 29
|
// lda gp,Y(gp): opcode 8, Ra = 29, rb = 29
|
||||||
const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16);
|
const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16);
|
||||||
|
|
||||||
uint32_t i1 = virtPort->read<uint32_t>(addr);
|
uint32_t i1 = virtProxy->read<uint32_t>(addr);
|
||||||
uint32_t i2 = virtPort->read<uint32_t>(addr + sizeof(MachInst));
|
uint32_t i2 = virtProxy->read<uint32_t>(addr + sizeof(MachInst));
|
||||||
|
|
||||||
if ((i1 & inst_mask) == gp_ldah_pattern &&
|
if ((i1 & inst_mask) == gp_ldah_pattern &&
|
||||||
(i2 & inst_mask) == gp_lda_pattern) {
|
(i2 & inst_mask) == gp_lda_pattern) {
|
||||||
|
@ -188,7 +196,7 @@ AlphaSystem::setAlphaAccess(Addr access)
|
||||||
{
|
{
|
||||||
Addr addr = 0;
|
Addr addr = 0;
|
||||||
if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
|
if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
|
||||||
virtPort->write(addr, htog(Phys2K0Seg(access)));
|
virtProxy->write(addr, htog(Phys2K0Seg(access)));
|
||||||
} else {
|
} else {
|
||||||
panic("could not find m5AlphaAccess\n");
|
panic("could not find m5AlphaAccess\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,12 @@ class AlphaSystem : public System
|
||||||
~AlphaSystem();
|
~AlphaSystem();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the state of the system.
|
||||||
|
*/
|
||||||
|
virtual void initState();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialization stuff
|
* Serialization stuff
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -55,7 +55,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strcpy(name->version, "732");
|
strcpy(name->version, "732");
|
||||||
strcpy(name->machine, "alpha");
|
strcpy(name->machine, "alpha");
|
||||||
|
|
||||||
name.copyOut(tc->getMemPort());
|
name.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,21 +74,21 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
case AlphaTru64::GSI_MAX_CPU: {
|
case AlphaTru64::GSI_MAX_CPU: {
|
||||||
TypedBufferArg<uint32_t> max_cpu(bufPtr);
|
TypedBufferArg<uint32_t> max_cpu(bufPtr);
|
||||||
*max_cpu = htog((uint32_t)process->numCpus());
|
*max_cpu = htog((uint32_t)process->numCpus());
|
||||||
max_cpu.copyOut(tc->getMemPort());
|
max_cpu.copyOut(tc->getMemProxy());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_CPUS_IN_BOX: {
|
case AlphaTru64::GSI_CPUS_IN_BOX: {
|
||||||
TypedBufferArg<uint32_t> cpus_in_box(bufPtr);
|
TypedBufferArg<uint32_t> cpus_in_box(bufPtr);
|
||||||
*cpus_in_box = htog((uint32_t)process->numCpus());
|
*cpus_in_box = htog((uint32_t)process->numCpus());
|
||||||
cpus_in_box.copyOut(tc->getMemPort());
|
cpus_in_box.copyOut(tc->getMemProxy());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_PHYSMEM: {
|
case AlphaTru64::GSI_PHYSMEM: {
|
||||||
TypedBufferArg<uint64_t> physmem(bufPtr);
|
TypedBufferArg<uint64_t> physmem(bufPtr);
|
||||||
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
|
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
|
||||||
physmem.copyOut(tc->getMemPort());
|
physmem.copyOut(tc->getMemProxy());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,14 +105,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
infop->cpu_ex_binding = htog(0);
|
infop->cpu_ex_binding = htog(0);
|
||||||
infop->mhz = htog(667);
|
infop->mhz = htog(667);
|
||||||
|
|
||||||
infop.copyOut(tc->getMemPort());
|
infop.copyOut(tc->getMemProxy());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_PROC_TYPE: {
|
case AlphaTru64::GSI_PROC_TYPE: {
|
||||||
TypedBufferArg<uint64_t> proc_type(bufPtr);
|
TypedBufferArg<uint64_t> proc_type(bufPtr);
|
||||||
*proc_type = htog((uint64_t)11);
|
*proc_type = htog((uint64_t)11);
|
||||||
proc_type.copyOut(tc->getMemPort());
|
proc_type.copyOut(tc->getMemProxy());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,14 +121,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strncpy((char *)bufArg.bufferPtr(),
|
strncpy((char *)bufArg.bufferPtr(),
|
||||||
"COMPAQ Professional Workstation XP1000",
|
"COMPAQ Professional Workstation XP1000",
|
||||||
nbytes);
|
nbytes);
|
||||||
bufArg.copyOut(tc->getMemPort());
|
bufArg.copyOut(tc->getMemProxy());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_CLK_TCK: {
|
case AlphaTru64::GSI_CLK_TCK: {
|
||||||
TypedBufferArg<uint64_t> clk_hz(bufPtr);
|
TypedBufferArg<uint64_t> clk_hz(bufPtr);
|
||||||
*clk_hz = htog((uint64_t)1024);
|
*clk_hz = htog((uint64_t)1024);
|
||||||
clk_hz.copyOut(tc->getMemPort());
|
clk_hz.copyOut(tc->getMemProxy());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
elp->si_phz = htog(clk_hz);
|
elp->si_phz = htog(clk_hz);
|
||||||
elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch?
|
elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch?
|
||||||
elp->si_max_procs = htog(process->numCpus());
|
elp->si_max_procs = htog(process->numCpus());
|
||||||
elp.copyOut(tc->getMemPort());
|
elp.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,7 @@
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "kern/tru64/tru64_events.hh"
|
#include "kern/tru64/tru64_events.hh"
|
||||||
#include "kern/system_events.hh"
|
#include "kern/system_events.hh"
|
||||||
#include "mem/physical.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "mem/port.hh"
|
|
||||||
#include "mem/vport.hh"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -49,7 +47,7 @@ Tru64AlphaSystem::Tru64AlphaSystem(Tru64AlphaSystem::Params *p)
|
||||||
{
|
{
|
||||||
Addr addr = 0;
|
Addr addr = 0;
|
||||||
if (kernelSymtab->findAddress("enable_async_printf", addr)) {
|
if (kernelSymtab->findAddress("enable_async_printf", addr)) {
|
||||||
virtPort->write(addr, (uint32_t)0);
|
virtProxy->write(addr, (uint32_t)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
#include "arch/alpha/utility.hh"
|
#include "arch/alpha/utility.hh"
|
||||||
#include "arch/alpha/vtophys.hh"
|
#include "arch/alpha/vtophys.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "sim/full_system.hh"
|
#include "sim/full_system.hh"
|
||||||
|
|
||||||
namespace AlphaISA {
|
namespace AlphaISA {
|
||||||
|
@ -48,7 +48,7 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
|
||||||
return tc->readIntReg(16 + number);
|
return tc->readIntReg(16 + number);
|
||||||
} else {
|
} else {
|
||||||
Addr sp = tc->readIntReg(StackPointerReg);
|
Addr sp = tc->readIntReg(StackPointerReg);
|
||||||
VirtualPort *vp = tc->getVirtPort();
|
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||||
uint64_t arg = vp->read<uint64_t>(sp +
|
uint64_t arg = vp->read<uint64_t>(sp +
|
||||||
(number-NumArgumentRegs) * sizeof(uint64_t));
|
(number-NumArgumentRegs) * sizeof(uint64_t));
|
||||||
return arg;
|
return arg;
|
||||||
|
|
|
@ -38,14 +38,14 @@
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/VtoPhys.hh"
|
#include "debug/VtoPhys.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/port_proxy.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace AlphaISA {
|
namespace AlphaISA {
|
||||||
|
|
||||||
PageTableEntry
|
PageTableEntry
|
||||||
kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, VAddr vaddr)
|
kernel_pte_lookup(PortProxy* mem, Addr ptbr, VAddr vaddr)
|
||||||
{
|
{
|
||||||
Addr level1_pte = ptbr + vaddr.level1();
|
Addr level1_pte = ptbr + vaddr.level1();
|
||||||
PageTableEntry level1 = mem->read<uint64_t>(level1_pte);
|
PageTableEntry level1 = mem->read<uint64_t>(level1_pte);
|
||||||
|
@ -103,7 +103,7 @@ vtophys(ThreadContext *tc, Addr addr)
|
||||||
paddr = vaddr;
|
paddr = vaddr;
|
||||||
} else {
|
} else {
|
||||||
PageTableEntry pte =
|
PageTableEntry pte =
|
||||||
kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr);
|
kernel_pte_lookup(tc->getPhysProxy(), ptbr, vaddr);
|
||||||
if (pte.valid())
|
if (pte.valid())
|
||||||
paddr = pte.paddr() | vaddr.offset();
|
paddr = pte.paddr() | vaddr.offset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,11 +37,11 @@
|
||||||
#include "arch/alpha/utility.hh"
|
#include "arch/alpha/utility.hh"
|
||||||
|
|
||||||
class ThreadContext;
|
class ThreadContext;
|
||||||
class FunctionalPort;
|
class PortProxy;
|
||||||
|
|
||||||
namespace AlphaISA {
|
namespace AlphaISA {
|
||||||
|
|
||||||
PageTableEntry kernel_pte_lookup(FunctionalPort *mem, Addr ptbr,
|
PageTableEntry kernel_pte_lookup(PortProxy* mem, Addr ptbr,
|
||||||
VAddr vaddr);
|
VAddr vaddr);
|
||||||
|
|
||||||
Addr vtophys(Addr vaddr);
|
Addr vtophys(Addr vaddr);
|
||||||
|
|
|
@ -70,7 +70,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
||||||
strcpy(name->machine, "armv7l");
|
strcpy(name->machine, "armv7l");
|
||||||
|
|
||||||
name.copyOut(tc->getMemPort());
|
name.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +452,7 @@ setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
int index = 0;
|
int index = 0;
|
||||||
uint32_t tlsPtr = process->getSyscallArg(tc, index);
|
uint32_t tlsPtr = process->getSyscallArg(tc, index);
|
||||||
|
|
||||||
tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
|
tc->getMemProxy()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
|
||||||
(uint8_t *)&tlsPtr, sizeof(tlsPtr));
|
(uint8_t *)&tlsPtr, sizeof(tlsPtr));
|
||||||
tc->setMiscReg(MISCREG_TPIDRURO,tlsPtr);
|
tc->setMiscReg(MISCREG_TPIDRURO,tlsPtr);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -512,7 +512,7 @@ ArmLinuxProcess::initState()
|
||||||
|
|
||||||
// Fill this page with swi -1 so we'll no if we land in it somewhere.
|
// Fill this page with swi -1 so we'll no if we land in it somewhere.
|
||||||
for (Addr addr = 0; addr < PageBytes; addr += sizeof(swiNeg1)) {
|
for (Addr addr = 0; addr < PageBytes; addr += sizeof(swiNeg1)) {
|
||||||
tc->getMemPort()->writeBlob(commPage + addr,
|
tc->getMemProxy()->writeBlob(commPage + addr,
|
||||||
swiNeg1, sizeof(swiNeg1));
|
swiNeg1, sizeof(swiNeg1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,7 +521,7 @@ ArmLinuxProcess::initState()
|
||||||
0x5f, 0xf0, 0x7f, 0xf5, // dmb
|
0x5f, 0xf0, 0x7f, 0xf5, // dmb
|
||||||
0x0e, 0xf0, 0xa0, 0xe1 // return
|
0x0e, 0xf0, 0xa0, 0xe1 // return
|
||||||
};
|
};
|
||||||
tc->getMemPort()->writeBlob(commPage + 0x0fa0, memory_barrier,
|
tc->getMemProxy()->writeBlob(commPage + 0x0fa0, memory_barrier,
|
||||||
sizeof(memory_barrier));
|
sizeof(memory_barrier));
|
||||||
|
|
||||||
uint8_t cmpxchg[] =
|
uint8_t cmpxchg[] =
|
||||||
|
@ -535,7 +535,7 @@ ArmLinuxProcess::initState()
|
||||||
0x5f, 0xf0, 0x7f, 0xf5, // dmb
|
0x5f, 0xf0, 0x7f, 0xf5, // dmb
|
||||||
0x0e, 0xf0, 0xa0, 0xe1 // return
|
0x0e, 0xf0, 0xa0, 0xe1 // return
|
||||||
};
|
};
|
||||||
tc->getMemPort()->writeBlob(commPage + 0x0fc0, cmpxchg, sizeof(cmpxchg));
|
tc->getMemProxy()->writeBlob(commPage + 0x0fc0, cmpxchg, sizeof(cmpxchg));
|
||||||
|
|
||||||
uint8_t get_tls[] =
|
uint8_t get_tls[] =
|
||||||
{
|
{
|
||||||
|
@ -543,7 +543,7 @@ ArmLinuxProcess::initState()
|
||||||
0x70, 0x0f, 0x1d, 0xee, // mrc p15, 0, r0, c13, c0, 3
|
0x70, 0x0f, 0x1d, 0xee, // mrc p15, 0, r0, c13, c0, 3
|
||||||
0x0e, 0xf0, 0xa0, 0xe1 // return
|
0x0e, 0xf0, 0xa0, 0xe1 // return
|
||||||
};
|
};
|
||||||
tc->getMemPort()->writeBlob(commPage + 0x0fe0, get_tls, sizeof(get_tls));
|
tc->getMemProxy()->writeBlob(commPage + 0x0fe0, get_tls, sizeof(get_tls));
|
||||||
}
|
}
|
||||||
|
|
||||||
ArmISA::IntReg
|
ArmISA::IntReg
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/Loader.hh"
|
#include "debug/Loader.hh"
|
||||||
#include "kern/linux/events.hh"
|
#include "kern/linux/events.hh"
|
||||||
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "mem/physical.hh"
|
#include "mem/physical.hh"
|
||||||
|
|
||||||
using namespace ArmISA;
|
using namespace ArmISA;
|
||||||
|
@ -57,6 +58,27 @@ using namespace Linux;
|
||||||
LinuxArmSystem::LinuxArmSystem(Params *p)
|
LinuxArmSystem::LinuxArmSystem(Params *p)
|
||||||
: ArmSystem(p)
|
: ArmSystem(p)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
LinuxArmSystem::adderBootUncacheable(Addr a)
|
||||||
|
{
|
||||||
|
Addr block = a & ~ULL(0x7F);
|
||||||
|
if (block == secDataPtrAddr || block == secDataAddr ||
|
||||||
|
block == penReleaseAddr)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LinuxArmSystem::initState()
|
||||||
|
{
|
||||||
|
// Moved from the constructor to here since it relies on the
|
||||||
|
// address map being resolved in the interconnect
|
||||||
|
|
||||||
|
// Call the initialisation of the super class
|
||||||
|
ArmSystem::initState();
|
||||||
|
|
||||||
// Load symbols at physical address, we might not want
|
// Load symbols at physical address, we might not want
|
||||||
// to do this perminately, for but early bootup work
|
// to do this perminately, for but early bootup work
|
||||||
// it is helpfulp.
|
// it is helpfulp.
|
||||||
|
@ -92,7 +114,7 @@ LinuxArmSystem::LinuxArmSystem(Params *p)
|
||||||
DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2);
|
DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2);
|
||||||
DDUMP(Loader, boot_data, size << 2);
|
DDUMP(Loader, boot_data, size << 2);
|
||||||
|
|
||||||
functionalPort->writeBlob(ParamsList, boot_data, size << 2);
|
physProxy->writeBlob(ParamsList, boot_data, size << 2);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
|
kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
|
||||||
|
@ -128,22 +150,6 @@ LinuxArmSystem::LinuxArmSystem(Params *p)
|
||||||
secDataPtrAddr &= ~ULL(0x7F);
|
secDataPtrAddr &= ~ULL(0x7F);
|
||||||
secDataAddr &= ~ULL(0x7F);
|
secDataAddr &= ~ULL(0x7F);
|
||||||
penReleaseAddr &= ~ULL(0x7F);
|
penReleaseAddr &= ~ULL(0x7F);
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
LinuxArmSystem::adderBootUncacheable(Addr a)
|
|
||||||
{
|
|
||||||
Addr block = a & ~ULL(0x7F);
|
|
||||||
if (block == secDataPtrAddr || block == secDataAddr ||
|
|
||||||
block == penReleaseAddr)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LinuxArmSystem::initState()
|
|
||||||
{
|
|
||||||
ArmSystem::initState();
|
|
||||||
|
|
||||||
for (int i = 0; i < threadContexts.size(); i++) {
|
for (int i = 0; i < threadContexts.size(); i++) {
|
||||||
threadContexts[i]->setIntReg(0, 0);
|
threadContexts[i]->setIntReg(0, 0);
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/Stack.hh"
|
#include "debug/Stack.hh"
|
||||||
#include "mem/page_table.hh"
|
#include "mem/page_table.hh"
|
||||||
#include "mem/translating_port.hh"
|
|
||||||
#include "sim/byteswap.hh"
|
#include "sim/byteswap.hh"
|
||||||
#include "sim/process_impl.hh"
|
#include "sim/process_impl.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -48,9 +48,9 @@ namespace ArmISA
|
||||||
{
|
{
|
||||||
Addr addr = 0;
|
Addr addr = 0;
|
||||||
|
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
|
|
||||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
|
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
|
||||||
panic("thread info not compiled into kernel\n");
|
panic("thread info not compiled into kernel\n");
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include "base/loader/symtab.hh"
|
#include "base/loader/symtab.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/physical.hh"
|
#include "mem/physical.hh"
|
||||||
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Linux;
|
using namespace Linux;
|
||||||
|
@ -55,6 +56,18 @@ ArmSystem::ArmSystem(Params *p)
|
||||||
: System(p), bootldr(NULL)
|
: System(p), bootldr(NULL)
|
||||||
{
|
{
|
||||||
debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
|
debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ArmSystem::initState()
|
||||||
|
{
|
||||||
|
// Moved from the constructor to here since it relies on the
|
||||||
|
// address map being resolved in the interconnect
|
||||||
|
|
||||||
|
// Call the initialisation of the super class
|
||||||
|
System::initState();
|
||||||
|
|
||||||
|
const Params* p = params();
|
||||||
|
|
||||||
if ((p->boot_loader == "") != (p->boot_loader_mem == NULL))
|
if ((p->boot_loader == "") != (p->boot_loader_mem == NULL))
|
||||||
fatal("If boot_loader is specifed, memory to load it must be also.\n");
|
fatal("If boot_loader is specifed, memory to load it must be also.\n");
|
||||||
|
@ -65,29 +78,18 @@ ArmSystem::ArmSystem(Params *p)
|
||||||
if (!bootldr)
|
if (!bootldr)
|
||||||
fatal("Could not read bootloader: %s\n", p->boot_loader);
|
fatal("Could not read bootloader: %s\n", p->boot_loader);
|
||||||
|
|
||||||
Port *mem_port;
|
bootldr->loadSections(physProxy);
|
||||||
FunctionalPort fp(name() + "-fport");
|
|
||||||
mem_port = p->boot_loader_mem->getPort("functional");
|
|
||||||
fp.setPeer(mem_port);
|
|
||||||
mem_port->setPeer(&fp);
|
|
||||||
|
|
||||||
bootldr->loadSections(&fp);
|
|
||||||
bootldr->loadGlobalSymbols(debugSymbolTable);
|
bootldr->loadGlobalSymbols(debugSymbolTable);
|
||||||
|
|
||||||
uint8_t jump_to_bl[] =
|
uint8_t jump_to_bl[] =
|
||||||
{
|
{
|
||||||
0x07, 0xf0, 0xa0, 0xe1 // branch to r7
|
0x07, 0xf0, 0xa0, 0xe1 // branch to r7
|
||||||
};
|
};
|
||||||
functionalPort->writeBlob(0x0, jump_to_bl, sizeof(jump_to_bl));
|
physProxy->writeBlob(0x0, jump_to_bl, sizeof(jump_to_bl));
|
||||||
|
|
||||||
inform("Using bootloader at address %#x\n", bootldr->entryPoint());
|
inform("Using bootloader at address %#x\n", bootldr->entryPoint());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ArmSystem::initState()
|
|
||||||
{
|
|
||||||
System::initState();
|
|
||||||
if (bootldr) {
|
if (bootldr) {
|
||||||
// Put the address of the boot loader into r7 so we know
|
// Put the address of the boot loader into r7 so we know
|
||||||
// where to branch to after the reset fault
|
// where to branch to after the reset fault
|
||||||
|
@ -98,16 +100,16 @@ ArmSystem::initState()
|
||||||
threadContexts[i]->setIntReg(5, params()->flags_addr);
|
threadContexts[i]->setIntReg(5, params()->flags_addr);
|
||||||
threadContexts[i]->setIntReg(7, bootldr->entryPoint());
|
threadContexts[i]->setIntReg(7, bootldr->entryPoint());
|
||||||
}
|
}
|
||||||
if (!params()->gic_cpu_addr || !params()->flags_addr)
|
if (!p->gic_cpu_addr || !p->flags_addr)
|
||||||
fatal("gic_cpu_addr && flags_addr must be set with bootloader\n");
|
fatal("gic_cpu_addr && flags_addr must be set with bootloader\n");
|
||||||
} else {
|
} else {
|
||||||
// Set the initial PC to be at start of the kernel code
|
// Set the initial PC to be at start of the kernel code
|
||||||
threadContexts[0]->pcState(kernelEntry & loadAddrMask);
|
threadContexts[0]->pcState(kernelEntry & loadAddrMask);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < threadContexts.size(); i++) {
|
for (int i = 0; i < threadContexts.size(); i++) {
|
||||||
if (params()->midr_regval) {
|
if (p->midr_regval) {
|
||||||
threadContexts[i]->setMiscReg(ArmISA::MISCREG_MIDR,
|
threadContexts[i]->setMiscReg(ArmISA::MISCREG_MIDR,
|
||||||
params()->midr_regval);
|
p->midr_regval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,10 @@ class ArmSystem : public System
|
||||||
ArmSystem(Params *p);
|
ArmSystem(Params *p);
|
||||||
~ArmSystem();
|
~ArmSystem();
|
||||||
|
|
||||||
void initState();
|
/**
|
||||||
|
* Initialise the system
|
||||||
|
*/
|
||||||
|
virtual void initState();
|
||||||
|
|
||||||
/** Check if an address should be uncacheable until all caches are enabled.
|
/** Check if an address should be uncacheable until all caches are enabled.
|
||||||
* This exits because coherence on some addresses at boot is maintained via
|
* This exits because coherence on some addresses at boot is maintained via
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
#include "arch/arm/utility.hh"
|
#include "arch/arm/utility.hh"
|
||||||
#include "arch/arm/vtophys.hh"
|
#include "arch/arm/vtophys.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "sim/full_system.hh"
|
#include "sim/full_system.hh"
|
||||||
|
|
||||||
namespace ArmISA {
|
namespace ArmISA {
|
||||||
|
@ -86,7 +86,7 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Addr sp = tc->readIntReg(StackPointerReg);
|
Addr sp = tc->readIntReg(StackPointerReg);
|
||||||
VirtualPort *vp = tc->getVirtPort();
|
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||||
uint64_t arg;
|
uint64_t arg;
|
||||||
if (size == sizeof(uint64_t)) {
|
if (size == sizeof(uint64_t)) {
|
||||||
// If the argument is even it must be aligned
|
// If the argument is even it must be aligned
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
#include "base/chunk_generator.hh"
|
#include "base/chunk_generator.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace ArmISA;
|
using namespace ArmISA;
|
||||||
|
@ -101,7 +101,7 @@ ArmISA::vtophys(ThreadContext *tc, Addr addr)
|
||||||
N = 0;
|
N = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionalPort *port = tc->getPhysPort();
|
PortProxy* port = tc->getPhysProxy();
|
||||||
Addr l1desc_addr = mbits(ttbr, 31, 14-N) | (bits(addr,31-N,20) << 2);
|
Addr l1desc_addr = mbits(ttbr, 31, 14-N) | (bits(addr,31-N,20) << 2);
|
||||||
|
|
||||||
TableWalker::L1Descriptor l1desc;
|
TableWalker::L1Descriptor l1desc;
|
||||||
|
|
|
@ -59,7 +59,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
||||||
strcpy(name->machine, "mips");
|
strcpy(name->machine, "mips");
|
||||||
|
|
||||||
name.copyOut(tc->getMemPort());
|
name.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ sys_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
||||||
// I don't think this exactly matches the HW FPCR
|
// I don't think this exactly matches the HW FPCR
|
||||||
*fpcr = 0;
|
*fpcr = 0;
|
||||||
fpcr.copyOut(tc->getMemPort());
|
fpcr.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -111,7 +111,7 @@ sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
// SSI_IEEE_FP_CONTROL
|
// SSI_IEEE_FP_CONTROL
|
||||||
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
||||||
// I don't think this exactly matches the HW FPCR
|
// I don't think this exactly matches the HW FPCR
|
||||||
fpcr.copyIn(tc->getMemPort());
|
fpcr.copyIn(tc->getMemProxy());
|
||||||
DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): "
|
DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): "
|
||||||
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
|
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -63,91 +63,10 @@ using namespace Linux;
|
||||||
LinuxMipsSystem::LinuxMipsSystem(Params *p)
|
LinuxMipsSystem::LinuxMipsSystem(Params *p)
|
||||||
: MipsSystem(p)
|
: MipsSystem(p)
|
||||||
{
|
{
|
||||||
Addr addr = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The symbol swapper_pg_dir marks the beginning of the kernel and
|
|
||||||
* the location of bootloader passed arguments
|
|
||||||
*/
|
|
||||||
if (!kernelSymtab->findAddress("swapper_pg_dir", KernelStart)) {
|
|
||||||
panic("Could not determine start location of kernel");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Since we aren't using a bootloader, we have to copy the
|
|
||||||
* kernel arguments directly into the kernel's memory.
|
|
||||||
*/
|
|
||||||
virtPort->writeBlob(CommandLine(), (uint8_t*)params()->boot_osflags.c_str(),
|
|
||||||
params()->boot_osflags.length()+1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* find the address of the est_cycle_freq variable and insert it
|
|
||||||
* so we don't through the lengthly process of trying to
|
|
||||||
* calculated it by using the PIT, RTC, etc.
|
|
||||||
*/
|
|
||||||
if (kernelSymtab->findAddress("est_cycle_freq", addr))
|
|
||||||
virtPort->write(addr, (uint64_t)(SimClock::Frequency /
|
|
||||||
p->boot_cpu_frequency));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* EV5 only supports 127 ASNs so we are going to tell the kernel that the
|
|
||||||
* paritiuclar EV6 we have only supports 127 asns.
|
|
||||||
* @todo At some point we should change ev5.hh and the palcode to support
|
|
||||||
* 255 ASNs.
|
|
||||||
*/
|
|
||||||
if (kernelSymtab->findAddress("dp264_mv", addr))
|
|
||||||
virtPort->write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127));
|
|
||||||
else
|
|
||||||
panic("could not find dp264_mv\n");
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
|
|
||||||
if (!kernelPanicEvent)
|
|
||||||
panic("could not find kernel symbol \'panic\'");
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Any time ide_delay_50ms, calibarte_delay or
|
|
||||||
* determine_cpu_caches is called just skip the
|
|
||||||
* function. Currently determine_cpu_caches only is used put
|
|
||||||
* information in proc, however if that changes in the future we
|
|
||||||
* will have to fill in the cache size variables appropriately.
|
|
||||||
*/
|
|
||||||
|
|
||||||
skipIdeDelay50msEvent =
|
|
||||||
addKernelFuncEvent<SkipFuncEvent>("ide_delay_50ms");
|
|
||||||
skipDelayLoopEvent =
|
|
||||||
addKernelFuncEvent<SkipDelayLoopEvent>("calibrate_delay");
|
|
||||||
skipCacheProbeEvent =
|
|
||||||
addKernelFuncEvent<SkipFuncEvent>("determine_cpu_caches");
|
|
||||||
debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
|
|
||||||
idleStartEvent = addKernelFuncEvent<IdleStartEvent>("cpu_idle");
|
|
||||||
|
|
||||||
// Disable for now as it runs into panic() calls in VPTr methods
|
|
||||||
// (see sim/vptr.hh). Once those bugs are fixed, we can
|
|
||||||
// re-enable, but we should find a better way to turn it on than
|
|
||||||
// using DTRACE(Thread), since looking at a trace flag at tick 0
|
|
||||||
// leads to non-intuitive behavior with --trace-start.
|
|
||||||
if (false && kernelSymtab->findAddress("mips_switch_to", addr)) {
|
|
||||||
printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo",
|
|
||||||
addr + sizeof(MachInst) * 6);
|
|
||||||
} else {
|
|
||||||
printThreadEvent = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LinuxMipsSystem::~LinuxMipsSystem()
|
LinuxMipsSystem::~LinuxMipsSystem()
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
|
||||||
delete kernelPanicEvent;
|
|
||||||
#endif
|
|
||||||
delete skipIdeDelay50msEvent;
|
|
||||||
delete skipDelayLoopEvent;
|
|
||||||
delete skipCacheProbeEvent;
|
|
||||||
delete debugPrintkEvent;
|
|
||||||
delete idleStartEvent;
|
|
||||||
delete printThreadEvent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ class ThreadInfo
|
||||||
if (!addr)
|
if (!addr)
|
||||||
addr = tc->readMiscRegNoEffect(0/*MipsISA::IPR_PALtemp23*/);
|
addr = tc->readMiscRegNoEffect(0/*MipsISA::IPR_PALtemp23*/);
|
||||||
|
|
||||||
FunctionalPort *p = tc->getPhysPort();
|
PortProxy* p = tc->getPhysProxy();
|
||||||
p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
|
p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
|
||||||
|
|
||||||
return sp & ~ULL(0x3fff);
|
return sp & ~ULL(0x3fff);
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -55,9 +55,9 @@ ProcessInfo::task(Addr ksp) const
|
||||||
|
|
||||||
Addr tsk;
|
Addr tsk;
|
||||||
|
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
tsk = vp->readGtoH<Addr>(base + task_off);
|
tsk = vp->readGtoH<Addr>(base + task_off);
|
||||||
|
|
||||||
return tsk;
|
return tsk;
|
||||||
|
@ -72,9 +72,9 @@ ProcessInfo::pid(Addr ksp) const
|
||||||
|
|
||||||
uint16_t pd;
|
uint16_t pd;
|
||||||
|
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
||||||
|
|
||||||
return pd;
|
return pd;
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#include "base/loader/symtab.hh"
|
#include "base/loader/symtab.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "mem/physical.hh"
|
#include "mem/physical.hh"
|
||||||
#include "mem/vport.hh"
|
|
||||||
#include "params/MipsSystem.hh"
|
#include "params/MipsSystem.hh"
|
||||||
#include "sim/byteswap.hh"
|
#include "sim/byteswap.hh"
|
||||||
|
|
||||||
|
@ -46,67 +45,6 @@ using namespace LittleEndianGuest;
|
||||||
|
|
||||||
MipsSystem::MipsSystem(Params *p) : System(p)
|
MipsSystem::MipsSystem(Params *p) : System(p)
|
||||||
{
|
{
|
||||||
if (p->bare_iron == true) {
|
|
||||||
hexFile = new HexFile(params()->hex_file_name);
|
|
||||||
if (!hexFile->loadSections(functionalPort))
|
|
||||||
panic("Could not load hex file\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
Addr addr = 0;
|
|
||||||
|
|
||||||
consoleSymtab = new SymbolTable;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the console code into memory
|
|
||||||
*/
|
|
||||||
// Load Console Code
|
|
||||||
console = createObjectFile(params()->console);
|
|
||||||
|
|
||||||
warn("console code is located at: %s\n", params()->console);
|
|
||||||
|
|
||||||
if (console == NULL)
|
|
||||||
fatal("Could not load console file %s", params()->console);
|
|
||||||
//Load program sections into memory
|
|
||||||
console->loadSections(functionalPort, loadAddrMask);
|
|
||||||
|
|
||||||
//load symbols
|
|
||||||
if (!console->loadGlobalSymbols(consoleSymtab))
|
|
||||||
panic("could not load console symbols\n");
|
|
||||||
|
|
||||||
if (!console->loadGlobalSymbols(debugSymbolTable))
|
|
||||||
panic("could not load console symbols\n");
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy the osflags (kernel arguments) into the consoles
|
|
||||||
* memory. (Presently Linux does not use the console service
|
|
||||||
* routine to get these command line arguments, but Tru64 and
|
|
||||||
* others do.)
|
|
||||||
*/
|
|
||||||
if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
|
|
||||||
warn("writing addr starting from %#x", addr);
|
|
||||||
virtPort->writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
|
|
||||||
strlen(params()->boot_osflags.c_str()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the hardware reset parameter block system type and revision
|
|
||||||
* information to Tsunami.
|
|
||||||
*/
|
|
||||||
if (consoleSymtab->findAddress("m5_rpb", addr)) {
|
|
||||||
uint64_t data;
|
|
||||||
data = htog(params()->system_type);
|
|
||||||
virtPort->write(addr + 0x50, data);
|
|
||||||
data = htog(params()->system_rev);
|
|
||||||
virtPort->write(addr + 0x58, data);
|
|
||||||
} else {
|
|
||||||
panic("could not find hwrpb\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MipsSystem::~MipsSystem()
|
MipsSystem::~MipsSystem()
|
||||||
|
|
|
@ -31,17 +31,16 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "arch/mips/isa_traits.hh"
|
#include "arch/mips/isa_traits.hh"
|
||||||
|
#include "arch/mips/registers.hh"
|
||||||
#include "arch/mips/utility.hh"
|
#include "arch/mips/utility.hh"
|
||||||
|
#include "arch/mips/vtophys.hh"
|
||||||
#include "base/bitfield.hh"
|
#include "base/bitfield.hh"
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
#include "cpu/static_inst.hh"
|
#include "cpu/static_inst.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "sim/serialize.hh"
|
#include "sim/serialize.hh"
|
||||||
|
|
||||||
#include "arch/mips/registers.hh"
|
|
||||||
#include "arch/mips/vtophys.hh"
|
|
||||||
#include "mem/vport.hh"
|
|
||||||
|
|
||||||
|
|
||||||
using namespace MipsISA;
|
using namespace MipsISA;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/VtoPhys.hh"
|
#include "debug/VtoPhys.hh"
|
||||||
#include "mem/vport.hh"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace MipsISA;
|
using namespace MipsISA;
|
||||||
|
|
|
@ -59,7 +59,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
||||||
strcpy(name->machine, "power");
|
strcpy(name->machine, "power");
|
||||||
|
|
||||||
name.copyOut(tc->getMemPort());
|
name.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/Stack.hh"
|
#include "debug/Stack.hh"
|
||||||
#include "mem/page_table.hh"
|
#include "mem/page_table.hh"
|
||||||
#include "mem/translating_port.hh"
|
|
||||||
#include "sim/process_impl.hh"
|
#include "sim/process_impl.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
||||||
strcpy(name->machine, "sparc");
|
strcpy(name->machine, "sparc");
|
||||||
|
|
||||||
name.copyOut(tc->getMemPort());
|
name.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -69,19 +69,19 @@ getresuidFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||||
if (ruid) {
|
if (ruid) {
|
||||||
BufferArg ruidBuff(ruid, sizeof(IntReg));
|
BufferArg ruidBuff(ruid, sizeof(IntReg));
|
||||||
memcpy(ruidBuff.bufferPtr(), &id, sizeof(IntReg));
|
memcpy(ruidBuff.bufferPtr(), &id, sizeof(IntReg));
|
||||||
ruidBuff.copyOut(tc->getMemPort());
|
ruidBuff.copyOut(tc->getMemProxy());
|
||||||
}
|
}
|
||||||
// Set the euid
|
// Set the euid
|
||||||
if (euid) {
|
if (euid) {
|
||||||
BufferArg euidBuff(euid, sizeof(IntReg));
|
BufferArg euidBuff(euid, sizeof(IntReg));
|
||||||
memcpy(euidBuff.bufferPtr(), &id, sizeof(IntReg));
|
memcpy(euidBuff.bufferPtr(), &id, sizeof(IntReg));
|
||||||
euidBuff.copyOut(tc->getMemPort());
|
euidBuff.copyOut(tc->getMemProxy());
|
||||||
}
|
}
|
||||||
// Set the suid
|
// Set the suid
|
||||||
if (suid) {
|
if (suid) {
|
||||||
BufferArg suidBuff(suid, sizeof(IntReg));
|
BufferArg suidBuff(suid, sizeof(IntReg));
|
||||||
memcpy(suidBuff.bufferPtr(), &id, sizeof(IntReg));
|
memcpy(suidBuff.bufferPtr(), &id, sizeof(IntReg));
|
||||||
suidBuff.copyOut(tc->getMemPort());
|
suidBuff.copyOut(tc->getMemProxy());
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/Stack.hh"
|
#include "debug/Stack.hh"
|
||||||
#include "mem/page_table.hh"
|
#include "mem/page_table.hh"
|
||||||
#include "mem/translating_port.hh"
|
|
||||||
#include "sim/process_impl.hh"
|
#include "sim/process_impl.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
|
@ -448,7 +447,7 @@ void Sparc32LiveProcess::flushWindows(ThreadContext *tc)
|
||||||
for (int index = 16; index < 32; index++) {
|
for (int index = 16; index < 32; index++) {
|
||||||
uint32_t regVal = tc->readIntReg(index);
|
uint32_t regVal = tc->readIntReg(index);
|
||||||
regVal = htog(regVal);
|
regVal = htog(regVal);
|
||||||
if (!tc->getMemPort()->tryWriteBlob(
|
if (!tc->getMemProxy()->tryWriteBlob(
|
||||||
sp + (index - 16) * 4, (uint8_t *)®Val, 4)) {
|
sp + (index - 16) * 4, (uint8_t *)®Val, 4)) {
|
||||||
warn("Failed to save register to the stack when "
|
warn("Failed to save register to the stack when "
|
||||||
"flushing windows.\n");
|
"flushing windows.\n");
|
||||||
|
@ -483,7 +482,7 @@ Sparc64LiveProcess::flushWindows(ThreadContext *tc)
|
||||||
for (int index = 16; index < 32; index++) {
|
for (int index = 16; index < 32; index++) {
|
||||||
IntReg regVal = tc->readIntReg(index);
|
IntReg regVal = tc->readIntReg(index);
|
||||||
regVal = htog(regVal);
|
regVal = htog(regVal);
|
||||||
if (!tc->getMemPort()->tryWriteBlob(
|
if (!tc->getMemProxy()->tryWriteBlob(
|
||||||
sp + 2047 + (index - 16) * 8, (uint8_t *)®Val, 8)) {
|
sp + 2047 + (index - 16) * 8, (uint8_t *)®Val, 8)) {
|
||||||
warn("Failed to save register to the stack when "
|
warn("Failed to save register to the stack when "
|
||||||
"flushing windows.\n");
|
"flushing windows.\n");
|
||||||
|
|
|
@ -55,7 +55,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strcpy(name->version, "Generic_118558-21");
|
strcpy(name->version, "Generic_118558-21");
|
||||||
strcpy(name->machine, "sun4u");
|
strcpy(name->machine, "sun4u");
|
||||||
|
|
||||||
name.copyOut(tc->getMemPort());
|
name.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,10 +40,7 @@
|
||||||
using namespace BigEndianGuest;
|
using namespace BigEndianGuest;
|
||||||
|
|
||||||
SparcSystem::SparcSystem(Params *p)
|
SparcSystem::SparcSystem(Params *p)
|
||||||
: System(p), sysTick(0),funcRomPort(p->name + "-fromport"),
|
: System(p), sysTick(0)
|
||||||
funcNvramPort(p->name + "-fnvramport"),
|
|
||||||
funcHypDescPort(p->name + "-fhypdescport"),
|
|
||||||
funcPartDescPort(p->name + "-fpartdescport")
|
|
||||||
{
|
{
|
||||||
resetSymtab = new SymbolTable;
|
resetSymtab = new SymbolTable;
|
||||||
hypervisorSymtab = new SymbolTable;
|
hypervisorSymtab = new SymbolTable;
|
||||||
|
@ -51,23 +48,13 @@ SparcSystem::SparcSystem(Params *p)
|
||||||
nvramSymtab = new SymbolTable;
|
nvramSymtab = new SymbolTable;
|
||||||
hypervisorDescSymtab = new SymbolTable;
|
hypervisorDescSymtab = new SymbolTable;
|
||||||
partitionDescSymtab = new SymbolTable;
|
partitionDescSymtab = new SymbolTable;
|
||||||
|
}
|
||||||
|
|
||||||
Port *rom_port;
|
void
|
||||||
rom_port = params()->rom->getPort("functional");
|
SparcSystem::initState()
|
||||||
funcRomPort.setPeer(rom_port);
|
{
|
||||||
rom_port->setPeer(&funcRomPort);
|
// Call the initialisation of the super class
|
||||||
|
System::initState();
|
||||||
rom_port = params()->nvram->getPort("functional");
|
|
||||||
funcNvramPort.setPeer(rom_port);
|
|
||||||
rom_port->setPeer(&funcNvramPort);
|
|
||||||
|
|
||||||
rom_port = params()->hypervisor_desc->getPort("functional");
|
|
||||||
funcHypDescPort.setPeer(rom_port);
|
|
||||||
rom_port->setPeer(&funcHypDescPort);
|
|
||||||
|
|
||||||
rom_port = params()->partition_desc->getPort("functional");
|
|
||||||
funcPartDescPort.setPeer(rom_port);
|
|
||||||
rom_port->setPeer(&funcPartDescPort);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the boot code, and hypervisor into memory.
|
* Load the boot code, and hypervisor into memory.
|
||||||
|
@ -107,22 +94,22 @@ SparcSystem::SparcSystem(Params *p)
|
||||||
|
|
||||||
// Load reset binary into memory
|
// Load reset binary into memory
|
||||||
reset->setTextBase(params()->reset_addr);
|
reset->setTextBase(params()->reset_addr);
|
||||||
reset->loadSections(&funcRomPort);
|
reset->loadSections(physProxy);
|
||||||
// Load the openboot binary
|
// Load the openboot binary
|
||||||
openboot->setTextBase(params()->openboot_addr);
|
openboot->setTextBase(params()->openboot_addr);
|
||||||
openboot->loadSections(&funcRomPort);
|
openboot->loadSections(physProxy);
|
||||||
// Load the hypervisor binary
|
// Load the hypervisor binary
|
||||||
hypervisor->setTextBase(params()->hypervisor_addr);
|
hypervisor->setTextBase(params()->hypervisor_addr);
|
||||||
hypervisor->loadSections(&funcRomPort);
|
hypervisor->loadSections(physProxy);
|
||||||
// Load the nvram image
|
// Load the nvram image
|
||||||
nvram->setTextBase(params()->nvram_addr);
|
nvram->setTextBase(params()->nvram_addr);
|
||||||
nvram->loadSections(&funcNvramPort);
|
nvram->loadSections(physProxy);
|
||||||
// Load the hypervisor description image
|
// Load the hypervisor description image
|
||||||
hypervisor_desc->setTextBase(params()->hypervisor_desc_addr);
|
hypervisor_desc->setTextBase(params()->hypervisor_desc_addr);
|
||||||
hypervisor_desc->loadSections(&funcHypDescPort);
|
hypervisor_desc->loadSections(physProxy);
|
||||||
// Load the partition description image
|
// Load the partition description image
|
||||||
partition_desc->setTextBase(params()->partition_desc_addr);
|
partition_desc->setTextBase(params()->partition_desc_addr);
|
||||||
partition_desc->loadSections(&funcPartDescPort);
|
partition_desc->loadSections(physProxy);
|
||||||
|
|
||||||
// load symbols
|
// load symbols
|
||||||
if (!reset->loadGlobalSymbols(resetSymtab))
|
if (!reset->loadGlobalSymbols(resetSymtab))
|
||||||
|
|
|
@ -48,6 +48,8 @@ class SparcSystem : public System
|
||||||
SparcSystem(Params *p);
|
SparcSystem(Params *p);
|
||||||
~SparcSystem();
|
~SparcSystem();
|
||||||
|
|
||||||
|
virtual void initState();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialization stuff
|
* Serialization stuff
|
||||||
*/
|
*/
|
||||||
|
@ -94,18 +96,6 @@ class SparcSystem : public System
|
||||||
/** System Tick for syncronized tick across all cpus. */
|
/** System Tick for syncronized tick across all cpus. */
|
||||||
Tick sysTick;
|
Tick sysTick;
|
||||||
|
|
||||||
/** functional port to ROM */
|
|
||||||
FunctionalPort funcRomPort;
|
|
||||||
|
|
||||||
/** functional port to nvram */
|
|
||||||
FunctionalPort funcNvramPort;
|
|
||||||
|
|
||||||
/** functional port to hypervisor description */
|
|
||||||
FunctionalPort funcHypDescPort;
|
|
||||||
|
|
||||||
/** functional port to partition description */
|
|
||||||
FunctionalPort funcPartDescPort;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const Params *params() const { return (const Params *)_params; }
|
const Params *params() const { return (const Params *)_params; }
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include "arch/sparc/faults.hh"
|
#include "arch/sparc/faults.hh"
|
||||||
#include "arch/sparc/utility.hh"
|
#include "arch/sparc/utility.hh"
|
||||||
#include "arch/sparc/vtophys.hh"
|
#include "arch/sparc/vtophys.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
|
|
||||||
namespace SparcISA {
|
namespace SparcISA {
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
|
||||||
return tc->readIntReg(8 + number);
|
return tc->readIntReg(8 + number);
|
||||||
} else {
|
} else {
|
||||||
Addr sp = tc->readIntReg(StackPointerReg);
|
Addr sp = tc->readIntReg(StackPointerReg);
|
||||||
VirtualPort *vp = tc->getVirtPort();
|
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||||
uint64_t arg = vp->read<uint64_t>(sp + 92 +
|
uint64_t arg = vp->read<uint64_t>(sp + 92 +
|
||||||
(number-NumArgumentRegs) * sizeof(uint64_t));
|
(number-NumArgumentRegs) * sizeof(uint64_t));
|
||||||
return arg;
|
return arg;
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/VtoPhys.hh"
|
#include "debug/VtoPhys.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/port_proxy.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ vtophys(ThreadContext *tc, Addr addr)
|
||||||
int pri_context = bits(tlbdata,47,32);
|
int pri_context = bits(tlbdata,47,32);
|
||||||
// int sec_context = bits(tlbdata,63,48);
|
// int sec_context = bits(tlbdata,63,48);
|
||||||
|
|
||||||
FunctionalPort *mem = tc->getPhysPort();
|
PortProxy* mem = tc->getPhysProxy();
|
||||||
TLB* itb = tc->getITBPtr();
|
TLB* itb = tc->getITBPtr();
|
||||||
TLB* dtb = tc->getDTBPtr();
|
TLB* dtb = tc->getDTBPtr();
|
||||||
TlbEntry* tbe;
|
TlbEntry* tbe;
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
#include "arch/x86/isa_traits.hh"
|
#include "arch/x86/isa_traits.hh"
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
#include "base/types.hh"
|
#include "base/types.hh"
|
||||||
#include "mem/port.hh"
|
#include "mem/port_proxy.hh"
|
||||||
#include "sim/byteswap.hh"
|
#include "sim/byteswap.hh"
|
||||||
|
|
||||||
// Config entry types
|
// Config entry types
|
||||||
|
@ -70,10 +70,10 @@ const char X86ISA::IntelMP::FloatingPointer::signature[] = "_MP_";
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
uint8_t
|
uint8_t
|
||||||
writeOutField(FunctionalPort * port, Addr addr, T val)
|
writeOutField(PortProxy* proxy, Addr addr, T val)
|
||||||
{
|
{
|
||||||
T guestVal = X86ISA::htog(val);
|
T guestVal = X86ISA::htog(val);
|
||||||
port->writeBlob(addr, (uint8_t *)(&guestVal), sizeof(T));
|
proxy->writeBlob(addr, (uint8_t *)(&guestVal), sizeof(T));
|
||||||
|
|
||||||
uint8_t checkSum = 0;
|
uint8_t checkSum = 0;
|
||||||
while(guestVal) {
|
while(guestVal) {
|
||||||
|
@ -84,7 +84,7 @@ writeOutField(FunctionalPort * port, Addr addr, T val)
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
writeOutString(FunctionalPort * port, Addr addr, string str, int length)
|
writeOutString(PortProxy* proxy, Addr addr, string str, int length)
|
||||||
{
|
{
|
||||||
char cleanedString[length + 1];
|
char cleanedString[length + 1];
|
||||||
cleanedString[length] = 0;
|
cleanedString[length] = 0;
|
||||||
|
@ -97,7 +97,7 @@ writeOutString(FunctionalPort * port, Addr addr, string str, int length)
|
||||||
memcpy(cleanedString, str.c_str(), str.length());
|
memcpy(cleanedString, str.c_str(), str.length());
|
||||||
memset(cleanedString + str.length(), 0, length - str.length());
|
memset(cleanedString + str.length(), 0, length - str.length());
|
||||||
}
|
}
|
||||||
port->writeBlob(addr, (uint8_t *)(&cleanedString), length);
|
proxy->writeBlob(addr, (uint8_t *)(&cleanedString), length);
|
||||||
|
|
||||||
uint8_t checkSum = 0;
|
uint8_t checkSum = 0;
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
|
@ -107,7 +107,7 @@ writeOutString(FunctionalPort * port, Addr addr, string str, int length)
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::FloatingPointer::writeOut(FunctionalPort * port, Addr addr)
|
X86ISA::IntelMP::FloatingPointer::writeOut(PortProxy* proxy, Addr addr)
|
||||||
{
|
{
|
||||||
// Make sure that either a config table is present or a default
|
// Make sure that either a config table is present or a default
|
||||||
// configuration was found but not both.
|
// configuration was found but not both.
|
||||||
|
@ -120,28 +120,28 @@ X86ISA::IntelMP::FloatingPointer::writeOut(FunctionalPort * port, Addr addr)
|
||||||
|
|
||||||
uint8_t checkSum = 0;
|
uint8_t checkSum = 0;
|
||||||
|
|
||||||
port->writeBlob(addr, (uint8_t *)signature, 4);
|
proxy->writeBlob(addr, (uint8_t *)signature, 4);
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
checkSum += signature[i];
|
checkSum += signature[i];
|
||||||
|
|
||||||
checkSum += writeOutField(port, addr + 4, tableAddr);
|
checkSum += writeOutField(proxy, addr + 4, tableAddr);
|
||||||
|
|
||||||
// The length of the structure in paragraphs, aka 16 byte chunks.
|
// The length of the structure in paragraphs, aka 16 byte chunks.
|
||||||
uint8_t length = 1;
|
uint8_t length = 1;
|
||||||
port->writeBlob(addr + 8, &length, 1);
|
proxy->writeBlob(addr + 8, &length, 1);
|
||||||
checkSum += length;
|
checkSum += length;
|
||||||
|
|
||||||
port->writeBlob(addr + 9, &specRev, 1);
|
proxy->writeBlob(addr + 9, &specRev, 1);
|
||||||
checkSum += specRev;
|
checkSum += specRev;
|
||||||
|
|
||||||
port->writeBlob(addr + 11, &defaultConfig, 1);
|
proxy->writeBlob(addr + 11, &defaultConfig, 1);
|
||||||
checkSum += defaultConfig;
|
checkSum += defaultConfig;
|
||||||
|
|
||||||
uint32_t features2_5 = imcrPresent ? (1 << 7) : 0;
|
uint32_t features2_5 = imcrPresent ? (1 << 7) : 0;
|
||||||
checkSum += writeOutField(port, addr + 12, features2_5);
|
checkSum += writeOutField(proxy, addr + 12, features2_5);
|
||||||
|
|
||||||
checkSum = -checkSum;
|
checkSum = -checkSum;
|
||||||
port->writeBlob(addr + 10, &checkSum, 1);
|
proxy->writeBlob(addr + 10, &checkSum, 1);
|
||||||
|
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
@ -158,10 +158,10 @@ X86IntelMPFloatingPointerParams::create()
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::BaseConfigEntry::writeOut(FunctionalPort * port,
|
X86ISA::IntelMP::BaseConfigEntry::writeOut(PortProxy* proxy,
|
||||||
Addr addr, uint8_t &checkSum)
|
Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
port->writeBlob(addr, &type, 1);
|
proxy->writeBlob(addr, &type, 1);
|
||||||
checkSum += type;
|
checkSum += type;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -171,12 +171,12 @@ X86ISA::IntelMP::BaseConfigEntry::BaseConfigEntry(Params * p, uint8_t _type) :
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::ExtConfigEntry::writeOut(FunctionalPort * port,
|
X86ISA::IntelMP::ExtConfigEntry::writeOut(PortProxy* proxy,
|
||||||
Addr addr, uint8_t &checkSum)
|
Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
port->writeBlob(addr, &type, 1);
|
proxy->writeBlob(addr, &type, 1);
|
||||||
checkSum += type;
|
checkSum += type;
|
||||||
port->writeBlob(addr + 1, &length, 1);
|
proxy->writeBlob(addr + 1, &length, 1);
|
||||||
checkSum += length;
|
checkSum += length;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -189,59 +189,59 @@ X86ISA::IntelMP::ExtConfigEntry::ExtConfigEntry(Params * p,
|
||||||
const char X86ISA::IntelMP::ConfigTable::signature[] = "PCMP";
|
const char X86ISA::IntelMP::ConfigTable::signature[] = "PCMP";
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::ConfigTable::writeOut(FunctionalPort * port, Addr addr)
|
X86ISA::IntelMP::ConfigTable::writeOut(PortProxy* proxy, Addr addr)
|
||||||
{
|
{
|
||||||
uint8_t checkSum = 0;
|
uint8_t checkSum = 0;
|
||||||
|
|
||||||
port->writeBlob(addr, (uint8_t *)signature, 4);
|
proxy->writeBlob(addr, (uint8_t *)signature, 4);
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
checkSum += signature[i];
|
checkSum += signature[i];
|
||||||
|
|
||||||
// Base table length goes here but will be calculated later.
|
// Base table length goes here but will be calculated later.
|
||||||
|
|
||||||
port->writeBlob(addr + 6, (uint8_t *)(&specRev), 1);
|
proxy->writeBlob(addr + 6, (uint8_t *)(&specRev), 1);
|
||||||
checkSum += specRev;
|
checkSum += specRev;
|
||||||
|
|
||||||
// The checksum goes here but is still being calculated.
|
// The checksum goes here but is still being calculated.
|
||||||
|
|
||||||
checkSum += writeOutString(port, addr + 8, oemID, 8);
|
checkSum += writeOutString(proxy, addr + 8, oemID, 8);
|
||||||
checkSum += writeOutString(port, addr + 16, productID, 12);
|
checkSum += writeOutString(proxy, addr + 16, productID, 12);
|
||||||
|
|
||||||
checkSum += writeOutField(port, addr + 28, oemTableAddr);
|
checkSum += writeOutField(proxy, addr + 28, oemTableAddr);
|
||||||
checkSum += writeOutField(port, addr + 32, oemTableSize);
|
checkSum += writeOutField(proxy, addr + 32, oemTableSize);
|
||||||
checkSum += writeOutField(port, addr + 34, (uint16_t)baseEntries.size());
|
checkSum += writeOutField(proxy, addr + 34, (uint16_t)baseEntries.size());
|
||||||
checkSum += writeOutField(port, addr + 36, localApic);
|
checkSum += writeOutField(proxy, addr + 36, localApic);
|
||||||
|
|
||||||
uint8_t reserved = 0;
|
uint8_t reserved = 0;
|
||||||
port->writeBlob(addr + 43, &reserved, 1);
|
proxy->writeBlob(addr + 43, &reserved, 1);
|
||||||
checkSum += reserved;
|
checkSum += reserved;
|
||||||
|
|
||||||
vector<BaseConfigEntry *>::iterator baseEnt;
|
vector<BaseConfigEntry *>::iterator baseEnt;
|
||||||
uint16_t offset = 44;
|
uint16_t offset = 44;
|
||||||
for (baseEnt = baseEntries.begin();
|
for (baseEnt = baseEntries.begin();
|
||||||
baseEnt != baseEntries.end(); baseEnt++) {
|
baseEnt != baseEntries.end(); baseEnt++) {
|
||||||
offset += (*baseEnt)->writeOut(port, addr + offset, checkSum);
|
offset += (*baseEnt)->writeOut(proxy, addr + offset, checkSum);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We've found the end of the base table this point.
|
// We've found the end of the base table this point.
|
||||||
checkSum += writeOutField(port, addr + 4, offset);
|
checkSum += writeOutField(proxy, addr + 4, offset);
|
||||||
|
|
||||||
vector<ExtConfigEntry *>::iterator extEnt;
|
vector<ExtConfigEntry *>::iterator extEnt;
|
||||||
uint16_t extOffset = 0;
|
uint16_t extOffset = 0;
|
||||||
uint8_t extCheckSum = 0;
|
uint8_t extCheckSum = 0;
|
||||||
for (extEnt = extEntries.begin();
|
for (extEnt = extEntries.begin();
|
||||||
extEnt != extEntries.end(); extEnt++) {
|
extEnt != extEntries.end(); extEnt++) {
|
||||||
extOffset += (*extEnt)->writeOut(port,
|
extOffset += (*extEnt)->writeOut(proxy,
|
||||||
addr + offset + extOffset, extCheckSum);
|
addr + offset + extOffset, extCheckSum);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkSum += writeOutField(port, addr + 40, extOffset);
|
checkSum += writeOutField(proxy, addr + 40, extOffset);
|
||||||
extCheckSum = -extCheckSum;
|
extCheckSum = -extCheckSum;
|
||||||
checkSum += writeOutField(port, addr + 42, extCheckSum);
|
checkSum += writeOutField(proxy, addr + 42, extCheckSum);
|
||||||
|
|
||||||
// And now, we finally have the whole check sum completed.
|
// And now, we finally have the whole check sum completed.
|
||||||
checkSum = -checkSum;
|
checkSum = -checkSum;
|
||||||
writeOutField(port, addr + 7, checkSum);
|
writeOutField(proxy, addr + 7, checkSum);
|
||||||
|
|
||||||
return offset + extOffset;
|
return offset + extOffset;
|
||||||
};
|
};
|
||||||
|
@ -261,18 +261,18 @@ X86IntelMPConfigTableParams::create()
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::Processor::writeOut(
|
X86ISA::IntelMP::Processor::writeOut(
|
||||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
BaseConfigEntry::writeOut(port, addr, checkSum);
|
BaseConfigEntry::writeOut(proxy, addr, checkSum);
|
||||||
checkSum += writeOutField(port, addr + 1, localApicID);
|
checkSum += writeOutField(proxy, addr + 1, localApicID);
|
||||||
checkSum += writeOutField(port, addr + 2, localApicVersion);
|
checkSum += writeOutField(proxy, addr + 2, localApicVersion);
|
||||||
checkSum += writeOutField(port, addr + 3, cpuFlags);
|
checkSum += writeOutField(proxy, addr + 3, cpuFlags);
|
||||||
checkSum += writeOutField(port, addr + 4, cpuSignature);
|
checkSum += writeOutField(proxy, addr + 4, cpuSignature);
|
||||||
checkSum += writeOutField(port, addr + 8, featureFlags);
|
checkSum += writeOutField(proxy, addr + 8, featureFlags);
|
||||||
|
|
||||||
uint32_t reserved = 0;
|
uint32_t reserved = 0;
|
||||||
port->writeBlob(addr + 12, (uint8_t *)(&reserved), 4);
|
proxy->writeBlob(addr + 12, (uint8_t *)(&reserved), 4);
|
||||||
port->writeBlob(addr + 16, (uint8_t *)(&reserved), 4);
|
proxy->writeBlob(addr + 16, (uint8_t *)(&reserved), 4);
|
||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,11 +298,11 @@ X86IntelMPProcessorParams::create()
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::Bus::writeOut(
|
X86ISA::IntelMP::Bus::writeOut(
|
||||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
BaseConfigEntry::writeOut(port, addr, checkSum);
|
BaseConfigEntry::writeOut(proxy, addr, checkSum);
|
||||||
checkSum += writeOutField(port, addr + 1, busID);
|
checkSum += writeOutField(proxy, addr + 1, busID);
|
||||||
checkSum += writeOutString(port, addr + 2, busType, 6);
|
checkSum += writeOutString(proxy, addr + 2, busType, 6);
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,13 +318,13 @@ X86IntelMPBusParams::create()
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::IOAPIC::writeOut(
|
X86ISA::IntelMP::IOAPIC::writeOut(
|
||||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
BaseConfigEntry::writeOut(port, addr, checkSum);
|
BaseConfigEntry::writeOut(proxy, addr, checkSum);
|
||||||
checkSum += writeOutField(port, addr + 1, id);
|
checkSum += writeOutField(proxy, addr + 1, id);
|
||||||
checkSum += writeOutField(port, addr + 2, version);
|
checkSum += writeOutField(proxy, addr + 2, version);
|
||||||
checkSum += writeOutField(port, addr + 3, flags);
|
checkSum += writeOutField(proxy, addr + 3, flags);
|
||||||
checkSum += writeOutField(port, addr + 4, address);
|
checkSum += writeOutField(proxy, addr + 4, address);
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,15 +343,15 @@ X86IntelMPIOAPICParams::create()
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::IntAssignment::writeOut(
|
X86ISA::IntelMP::IntAssignment::writeOut(
|
||||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
BaseConfigEntry::writeOut(port, addr, checkSum);
|
BaseConfigEntry::writeOut(proxy, addr, checkSum);
|
||||||
checkSum += writeOutField(port, addr + 1, interruptType);
|
checkSum += writeOutField(proxy, addr + 1, interruptType);
|
||||||
checkSum += writeOutField(port, addr + 2, flags);
|
checkSum += writeOutField(proxy, addr + 2, flags);
|
||||||
checkSum += writeOutField(port, addr + 4, sourceBusID);
|
checkSum += writeOutField(proxy, addr + 4, sourceBusID);
|
||||||
checkSum += writeOutField(port, addr + 5, sourceBusIRQ);
|
checkSum += writeOutField(proxy, addr + 5, sourceBusIRQ);
|
||||||
checkSum += writeOutField(port, addr + 6, destApicID);
|
checkSum += writeOutField(proxy, addr + 6, destApicID);
|
||||||
checkSum += writeOutField(port, addr + 7, destApicIntIn);
|
checkSum += writeOutField(proxy, addr + 7, destApicIntIn);
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,13 +381,13 @@ X86IntelMPLocalIntAssignmentParams::create()
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::AddrSpaceMapping::writeOut(
|
X86ISA::IntelMP::AddrSpaceMapping::writeOut(
|
||||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
ExtConfigEntry::writeOut(port, addr, checkSum);
|
ExtConfigEntry::writeOut(proxy, addr, checkSum);
|
||||||
checkSum += writeOutField(port, addr + 2, busID);
|
checkSum += writeOutField(proxy, addr + 2, busID);
|
||||||
checkSum += writeOutField(port, addr + 3, addrType);
|
checkSum += writeOutField(proxy, addr + 3, addrType);
|
||||||
checkSum += writeOutField(port, addr + 4, addr);
|
checkSum += writeOutField(proxy, addr + 4, addr);
|
||||||
checkSum += writeOutField(port, addr + 12, addrLength);
|
checkSum += writeOutField(proxy, addr + 12, addrLength);
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,15 +405,15 @@ X86IntelMPAddrSpaceMappingParams::create()
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::BusHierarchy::writeOut(
|
X86ISA::IntelMP::BusHierarchy::writeOut(
|
||||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
ExtConfigEntry::writeOut(port, addr, checkSum);
|
ExtConfigEntry::writeOut(proxy, addr, checkSum);
|
||||||
checkSum += writeOutField(port, addr + 2, busID);
|
checkSum += writeOutField(proxy, addr + 2, busID);
|
||||||
checkSum += writeOutField(port, addr + 3, info);
|
checkSum += writeOutField(proxy, addr + 3, info);
|
||||||
checkSum += writeOutField(port, addr + 4, parentBus);
|
checkSum += writeOutField(proxy, addr + 4, parentBus);
|
||||||
|
|
||||||
uint32_t reserved = 0;
|
uint32_t reserved = 0;
|
||||||
port->writeBlob(addr + 5, (uint8_t *)(&reserved), 3);
|
proxy->writeBlob(addr + 5, (uint8_t *)(&reserved), 3);
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
@ -434,12 +434,12 @@ X86IntelMPBusHierarchyParams::create()
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::CompatAddrSpaceMod::writeOut(
|
X86ISA::IntelMP::CompatAddrSpaceMod::writeOut(
|
||||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
ExtConfigEntry::writeOut(port, addr, checkSum);
|
ExtConfigEntry::writeOut(proxy, addr, checkSum);
|
||||||
checkSum += writeOutField(port, addr + 2, busID);
|
checkSum += writeOutField(proxy, addr + 2, busID);
|
||||||
checkSum += writeOutField(port, addr + 3, mod);
|
checkSum += writeOutField(proxy, addr + 3, mod);
|
||||||
checkSum += writeOutField(port, addr + 4, rangeList);
|
checkSum += writeOutField(proxy, addr + 4, rangeList);
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
#include "enums/X86IntelMPTriggerMode.hh"
|
#include "enums/X86IntelMPTriggerMode.hh"
|
||||||
#include "sim/sim_object.hh"
|
#include "sim/sim_object.hh"
|
||||||
|
|
||||||
class FunctionalPort;
|
class PortProxy;
|
||||||
|
|
||||||
// Config entry types
|
// Config entry types
|
||||||
class X86IntelMPBaseConfigEntryParams;
|
class X86IntelMPBaseConfigEntryParams;
|
||||||
|
@ -93,7 +93,7 @@ class FloatingPointer : public SimObject
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr);
|
Addr writeOut(PortProxy* proxy, Addr addr);
|
||||||
|
|
||||||
Addr getTableAddr()
|
Addr getTableAddr()
|
||||||
{
|
{
|
||||||
|
@ -117,7 +117,7 @@ class BaseConfigEntry : public SimObject
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
virtual Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||||
|
|
||||||
BaseConfigEntry(Params * p, uint8_t _type);
|
BaseConfigEntry(Params * p, uint8_t _type);
|
||||||
};
|
};
|
||||||
|
@ -132,7 +132,7 @@ class ExtConfigEntry : public SimObject
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
virtual Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||||
|
|
||||||
ExtConfigEntry(Params * p, uint8_t _type, uint8_t _length);
|
ExtConfigEntry(Params * p, uint8_t _type, uint8_t _length);
|
||||||
};
|
};
|
||||||
|
@ -155,7 +155,7 @@ class ConfigTable : public SimObject
|
||||||
std::vector<ExtConfigEntry *> extEntries;
|
std::vector<ExtConfigEntry *> extEntries;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr);
|
Addr writeOut(PortProxy* proxy, Addr addr);
|
||||||
|
|
||||||
ConfigTable(Params * p);
|
ConfigTable(Params * p);
|
||||||
};
|
};
|
||||||
|
@ -172,7 +172,7 @@ class Processor : public BaseConfigEntry
|
||||||
uint32_t featureFlags;
|
uint32_t featureFlags;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||||
|
|
||||||
Processor(Params * p);
|
Processor(Params * p);
|
||||||
};
|
};
|
||||||
|
@ -186,7 +186,7 @@ class Bus : public BaseConfigEntry
|
||||||
std::string busType;
|
std::string busType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||||
|
|
||||||
Bus(Params * p);
|
Bus(Params * p);
|
||||||
};
|
};
|
||||||
|
@ -202,7 +202,7 @@ class IOAPIC : public BaseConfigEntry
|
||||||
uint32_t address;
|
uint32_t address;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||||
|
|
||||||
IOAPIC(Params * p);
|
IOAPIC(Params * p);
|
||||||
};
|
};
|
||||||
|
@ -221,7 +221,7 @@ class IntAssignment : public BaseConfigEntry
|
||||||
uint8_t destApicIntIn;
|
uint8_t destApicIntIn;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||||
|
|
||||||
IntAssignment(X86IntelMPBaseConfigEntryParams * p,
|
IntAssignment(X86IntelMPBaseConfigEntryParams * p,
|
||||||
Enums::X86IntelMPInterruptType _interruptType,
|
Enums::X86IntelMPInterruptType _interruptType,
|
||||||
|
@ -269,7 +269,7 @@ class AddrSpaceMapping : public ExtConfigEntry
|
||||||
uint64_t addrLength;
|
uint64_t addrLength;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||||
|
|
||||||
AddrSpaceMapping(Params * p);
|
AddrSpaceMapping(Params * p);
|
||||||
};
|
};
|
||||||
|
@ -284,7 +284,7 @@ class BusHierarchy : public ExtConfigEntry
|
||||||
uint8_t parentBus;
|
uint8_t parentBus;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||||
|
|
||||||
BusHierarchy(Params * p);
|
BusHierarchy(Params * p);
|
||||||
};
|
};
|
||||||
|
@ -299,7 +299,7 @@ class CompatAddrSpaceMod : public ExtConfigEntry
|
||||||
uint32_t rangeList;
|
uint32_t rangeList;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||||
|
|
||||||
CompatAddrSpaceMod(Params * p);
|
CompatAddrSpaceMod(Params * p);
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
#include "arch/x86/bios/smbios.hh"
|
#include "arch/x86/bios/smbios.hh"
|
||||||
#include "arch/x86/isa_traits.hh"
|
#include "arch/x86/isa_traits.hh"
|
||||||
#include "base/types.hh"
|
#include "base/types.hh"
|
||||||
#include "mem/port.hh"
|
#include "mem/port_proxy.hh"
|
||||||
#include "params/X86SMBiosBiosInformation.hh"
|
#include "params/X86SMBiosBiosInformation.hh"
|
||||||
#include "params/X86SMBiosSMBiosStructure.hh"
|
#include "params/X86SMBiosSMBiosStructure.hh"
|
||||||
#include "params/X86SMBiosSMBiosTable.hh"
|
#include "params/X86SMBiosSMBiosTable.hh"
|
||||||
|
@ -74,15 +74,15 @@ composeBitVector(T vec)
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t
|
uint16_t
|
||||||
X86ISA::SMBios::SMBiosStructure::writeOut(FunctionalPort * port, Addr addr)
|
X86ISA::SMBios::SMBiosStructure::writeOut(PortProxy* proxy, Addr addr)
|
||||||
{
|
{
|
||||||
port->writeBlob(addr, (uint8_t *)(&type), 1);
|
proxy->writeBlob(addr, (uint8_t *)(&type), 1);
|
||||||
|
|
||||||
uint8_t length = getLength();
|
uint8_t length = getLength();
|
||||||
port->writeBlob(addr + 1, (uint8_t *)(&length), 1);
|
proxy->writeBlob(addr + 1, (uint8_t *)(&length), 1);
|
||||||
|
|
||||||
uint16_t handleGuest = X86ISA::htog(handle);
|
uint16_t handleGuest = X86ISA::htog(handle);
|
||||||
port->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2);
|
proxy->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2);
|
||||||
|
|
||||||
return length + getStringLength();
|
return length + getStringLength();
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ X86ISA::SMBios::SMBiosStructure::SMBiosStructure(Params * p, uint8_t _type) :
|
||||||
|
|
||||||
void
|
void
|
||||||
X86ISA::SMBios::SMBiosStructure::writeOutStrings(
|
X86ISA::SMBios::SMBiosStructure::writeOutStrings(
|
||||||
FunctionalPort * port, Addr addr)
|
PortProxy* proxy, Addr addr)
|
||||||
{
|
{
|
||||||
std::vector<std::string>::iterator it;
|
std::vector<std::string>::iterator it;
|
||||||
Addr offset = 0;
|
Addr offset = 0;
|
||||||
|
@ -103,16 +103,16 @@ X86ISA::SMBios::SMBiosStructure::writeOutStrings(
|
||||||
// If there are string fields but none of them are used, that's a
|
// If there are string fields but none of them are used, that's a
|
||||||
// special case which is handled by this if.
|
// special case which is handled by this if.
|
||||||
if (strings.size() == 0 && stringFields) {
|
if (strings.size() == 0 && stringFields) {
|
||||||
port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
|
proxy->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
|
||||||
offset++;
|
offset++;
|
||||||
} else {
|
} else {
|
||||||
for (it = strings.begin(); it != strings.end(); it++) {
|
for (it = strings.begin(); it != strings.end(); it++) {
|
||||||
port->writeBlob(addr + offset,
|
proxy->writeBlob(addr + offset,
|
||||||
(uint8_t *)it->c_str(), it->length() + 1);
|
(uint8_t *)it->c_str(), it->length() + 1);
|
||||||
offset += it->length() + 1;
|
offset += it->length() + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
|
proxy->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -172,32 +172,32 @@ X86ISA::SMBios::BiosInformation::BiosInformation(Params * p) :
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t
|
uint16_t
|
||||||
X86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr)
|
X86ISA::SMBios::BiosInformation::writeOut(PortProxy* proxy, Addr addr)
|
||||||
{
|
{
|
||||||
uint8_t size = SMBiosStructure::writeOut(port, addr);
|
uint8_t size = SMBiosStructure::writeOut(proxy, addr);
|
||||||
|
|
||||||
port->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1);
|
proxy->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1);
|
||||||
port->writeBlob(addr + 0x5, (uint8_t *)(&version), 1);
|
proxy->writeBlob(addr + 0x5, (uint8_t *)(&version), 1);
|
||||||
|
|
||||||
uint16_t startingAddrSegmentGuest = X86ISA::htog(startingAddrSegment);
|
uint16_t startingAddrSegmentGuest = X86ISA::htog(startingAddrSegment);
|
||||||
port->writeBlob(addr + 0x6, (uint8_t *)(&startingAddrSegmentGuest), 2);
|
proxy->writeBlob(addr + 0x6, (uint8_t *)(&startingAddrSegmentGuest), 2);
|
||||||
|
|
||||||
port->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1);
|
proxy->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1);
|
||||||
port->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1);
|
proxy->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1);
|
||||||
|
|
||||||
uint64_t characteristicsGuest = X86ISA::htog(characteristics);
|
uint64_t characteristicsGuest = X86ISA::htog(characteristics);
|
||||||
port->writeBlob(addr + 0xA, (uint8_t *)(&characteristicsGuest), 8);
|
proxy->writeBlob(addr + 0xA, (uint8_t *)(&characteristicsGuest), 8);
|
||||||
|
|
||||||
uint16_t characteristicExtBytesGuest =
|
uint16_t characteristicExtBytesGuest =
|
||||||
X86ISA::htog(characteristicExtBytes);
|
X86ISA::htog(characteristicExtBytes);
|
||||||
port->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2);
|
proxy->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2);
|
||||||
|
|
||||||
port->writeBlob(addr + 0x14, (uint8_t *)(&majorVer), 1);
|
proxy->writeBlob(addr + 0x14, (uint8_t *)(&majorVer), 1);
|
||||||
port->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1);
|
proxy->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1);
|
||||||
port->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1);
|
proxy->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1);
|
||||||
port->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1);
|
proxy->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1);
|
||||||
|
|
||||||
writeOutStrings(port, addr + getLength());
|
writeOutStrings(proxy, addr + getLength());
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ X86ISA::SMBios::SMBiosTable::SMBiosTable(Params * p) :
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
X86ISA::SMBios::SMBiosTable::writeOut(PortProxy* proxy, Addr addr,
|
||||||
Addr &headerSize, Addr &structSize)
|
Addr &headerSize, Addr &structSize)
|
||||||
{
|
{
|
||||||
headerSize = 0x1F;
|
headerSize = 0x1F;
|
||||||
|
@ -224,26 +224,26 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
||||||
*/
|
*/
|
||||||
uint8_t mainChecksum = 0;
|
uint8_t mainChecksum = 0;
|
||||||
|
|
||||||
port->writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4);
|
proxy->writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4);
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
mainChecksum += smbiosHeader.anchorString[i];
|
mainChecksum += smbiosHeader.anchorString[i];
|
||||||
|
|
||||||
// The checksum goes here, but we're figuring it out as we go.
|
// The checksum goes here, but we're figuring it out as we go.
|
||||||
|
|
||||||
port->writeBlob(addr + 0x5,
|
proxy->writeBlob(addr + 0x5,
|
||||||
(uint8_t *)(&smbiosHeader.entryPointLength), 1);
|
(uint8_t *)(&smbiosHeader.entryPointLength), 1);
|
||||||
mainChecksum += smbiosHeader.entryPointLength;
|
mainChecksum += smbiosHeader.entryPointLength;
|
||||||
port->writeBlob(addr + 0x6,
|
proxy->writeBlob(addr + 0x6,
|
||||||
(uint8_t *)(&smbiosHeader.majorVersion), 1);
|
(uint8_t *)(&smbiosHeader.majorVersion), 1);
|
||||||
mainChecksum += smbiosHeader.majorVersion;
|
mainChecksum += smbiosHeader.majorVersion;
|
||||||
port->writeBlob(addr + 0x7,
|
proxy->writeBlob(addr + 0x7,
|
||||||
(uint8_t *)(&smbiosHeader.minorVersion), 1);
|
(uint8_t *)(&smbiosHeader.minorVersion), 1);
|
||||||
mainChecksum += smbiosHeader.minorVersion;
|
mainChecksum += smbiosHeader.minorVersion;
|
||||||
// Maximum structure size goes here, but we'll figure it out later.
|
// Maximum structure size goes here, but we'll figure it out later.
|
||||||
port->writeBlob(addr + 0xA,
|
proxy->writeBlob(addr + 0xA,
|
||||||
(uint8_t *)(&smbiosHeader.entryPointRevision), 1);
|
(uint8_t *)(&smbiosHeader.entryPointRevision), 1);
|
||||||
mainChecksum += smbiosHeader.entryPointRevision;
|
mainChecksum += smbiosHeader.entryPointRevision;
|
||||||
port->writeBlob(addr + 0xB,
|
proxy->writeBlob(addr + 0xB,
|
||||||
(uint8_t *)(&smbiosHeader.formattedArea), 5);
|
(uint8_t *)(&smbiosHeader.formattedArea), 5);
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
mainChecksum += smbiosHeader.formattedArea[i];
|
mainChecksum += smbiosHeader.formattedArea[i];
|
||||||
|
@ -253,7 +253,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
||||||
*/
|
*/
|
||||||
uint8_t intChecksum = 0;
|
uint8_t intChecksum = 0;
|
||||||
|
|
||||||
port->writeBlob(addr + 0x10,
|
proxy->writeBlob(addr + 0x10,
|
||||||
(uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5);
|
(uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5);
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
intChecksum += smbiosHeader.intermediateHeader.anchorString[i];
|
intChecksum += smbiosHeader.intermediateHeader.anchorString[i];
|
||||||
|
@ -263,20 +263,20 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
||||||
|
|
||||||
uint32_t tableAddrGuest =
|
uint32_t tableAddrGuest =
|
||||||
X86ISA::htog(smbiosHeader.intermediateHeader.tableAddr);
|
X86ISA::htog(smbiosHeader.intermediateHeader.tableAddr);
|
||||||
port->writeBlob(addr + 0x18, (uint8_t *)(&tableAddrGuest), 4);
|
proxy->writeBlob(addr + 0x18, (uint8_t *)(&tableAddrGuest), 4);
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
intChecksum += tableAddrGuest;
|
intChecksum += tableAddrGuest;
|
||||||
tableAddrGuest >>= 8;
|
tableAddrGuest >>= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t numStructs = X86ISA::gtoh(structures.size());
|
uint16_t numStructs = X86ISA::gtoh(structures.size());
|
||||||
port->writeBlob(addr + 0x1C, (uint8_t *)(&numStructs), 2);
|
proxy->writeBlob(addr + 0x1C, (uint8_t *)(&numStructs), 2);
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
intChecksum += numStructs;
|
intChecksum += numStructs;
|
||||||
numStructs >>= 8;
|
numStructs >>= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
port->writeBlob(addr + 0x1E,
|
proxy->writeBlob(addr + 0x1E,
|
||||||
(uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision),
|
(uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision),
|
||||||
1);
|
1);
|
||||||
intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision;
|
intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision;
|
||||||
|
@ -290,7 +290,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
||||||
uint16_t maxSize = 0;
|
uint16_t maxSize = 0;
|
||||||
std::vector<SMBiosStructure *>::iterator it;
|
std::vector<SMBiosStructure *>::iterator it;
|
||||||
for (it = structures.begin(); it != structures.end(); it++) {
|
for (it = structures.begin(); it != structures.end(); it++) {
|
||||||
uint16_t size = (*it)->writeOut(port, base + offset);
|
uint16_t size = (*it)->writeOut(proxy, base + offset);
|
||||||
if (size > maxSize)
|
if (size > maxSize)
|
||||||
maxSize = size;
|
maxSize = size;
|
||||||
offset += size;
|
offset += size;
|
||||||
|
@ -303,7 +303,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
maxSize = X86ISA::htog(maxSize);
|
maxSize = X86ISA::htog(maxSize);
|
||||||
port->writeBlob(addr + 0x8, (uint8_t *)(&maxSize), 2);
|
proxy->writeBlob(addr + 0x8, (uint8_t *)(&maxSize), 2);
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
mainChecksum += maxSize;
|
mainChecksum += maxSize;
|
||||||
maxSize >>= 8;
|
maxSize >>= 8;
|
||||||
|
@ -311,7 +311,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
||||||
|
|
||||||
// Set the checksum
|
// Set the checksum
|
||||||
mainChecksum = -mainChecksum;
|
mainChecksum = -mainChecksum;
|
||||||
port->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1);
|
proxy->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Intermediate header
|
* Intermediate header
|
||||||
|
@ -319,14 +319,14 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
||||||
|
|
||||||
uint16_t tableSize = offset;
|
uint16_t tableSize = offset;
|
||||||
tableSize = X86ISA::htog(tableSize);
|
tableSize = X86ISA::htog(tableSize);
|
||||||
port->writeBlob(addr + 0x16, (uint8_t *)(&tableSize), 2);
|
proxy->writeBlob(addr + 0x16, (uint8_t *)(&tableSize), 2);
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
intChecksum += tableSize;
|
intChecksum += tableSize;
|
||||||
tableSize >>= 8;
|
tableSize >>= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
intChecksum = -intChecksum;
|
intChecksum = -intChecksum;
|
||||||
port->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1);
|
proxy->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
X86ISA::SMBios::BiosInformation *
|
X86ISA::SMBios::BiosInformation *
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
#include "enums/ExtCharacteristic.hh"
|
#include "enums/ExtCharacteristic.hh"
|
||||||
#include "sim/sim_object.hh"
|
#include "sim/sim_object.hh"
|
||||||
|
|
||||||
class FunctionalPort;
|
class PortProxy;
|
||||||
class X86SMBiosBiosInformationParams;
|
class X86SMBiosBiosInformationParams;
|
||||||
class X86SMBiosSMBiosStructureParams;
|
class X86SMBiosSMBiosStructureParams;
|
||||||
class X86SMBiosSMBiosTableParams;
|
class X86SMBiosSMBiosTableParams;
|
||||||
|
@ -89,7 +89,7 @@ class SMBiosStructure : public SimObject
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual uint16_t writeOut(FunctionalPort * port, Addr addr);
|
virtual uint16_t writeOut(PortProxy* proxy, Addr addr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool stringFields;
|
bool stringFields;
|
||||||
|
@ -98,7 +98,7 @@ class SMBiosStructure : public SimObject
|
||||||
|
|
||||||
std::vector<std::string> strings;
|
std::vector<std::string> strings;
|
||||||
|
|
||||||
void writeOutStrings(FunctionalPort * port, Addr addr);
|
void writeOutStrings(PortProxy* proxy, Addr addr);
|
||||||
|
|
||||||
int getStringLength();
|
int getStringLength();
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ class BiosInformation : public SMBiosStructure
|
||||||
BiosInformation(Params * p);
|
BiosInformation(Params * p);
|
||||||
|
|
||||||
uint8_t getLength() { return 0x18; }
|
uint8_t getLength() { return 0x18; }
|
||||||
uint16_t writeOut(FunctionalPort * port, Addr addr);
|
uint16_t writeOut(PortProxy* proxy, Addr addr);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SMBiosTable : public SimObject
|
class SMBiosTable : public SimObject
|
||||||
|
@ -223,7 +223,7 @@ class SMBiosTable : public SimObject
|
||||||
smbiosHeader.intermediateHeader.tableAddr = addr;
|
smbiosHeader.intermediateHeader.tableAddr = addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeOut(FunctionalPort * port, Addr addr,
|
void writeOut(PortProxy* proxy, Addr addr,
|
||||||
Addr &headerSize, Addr &structSize);
|
Addr &headerSize, Addr &structSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -351,25 +351,27 @@ X86ISA::Interrupts::recvResponse(PacketPtr pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
AddrRangeList
|
||||||
X86ISA::Interrupts::addressRanges(AddrRangeList &range_list)
|
X86ISA::Interrupts::getAddrRanges()
|
||||||
{
|
{
|
||||||
range_list.clear();
|
AddrRangeList ranges;
|
||||||
Range<Addr> range = RangeEx(x86LocalAPICAddress(initialApicId, 0),
|
Range<Addr> range = RangeEx(x86LocalAPICAddress(initialApicId, 0),
|
||||||
x86LocalAPICAddress(initialApicId, 0) +
|
x86LocalAPICAddress(initialApicId, 0) +
|
||||||
PageBytes);
|
PageBytes);
|
||||||
range_list.push_back(range);
|
ranges.push_back(range);
|
||||||
pioAddr = range.start;
|
pioAddr = range.start;
|
||||||
|
return ranges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
AddrRangeList
|
||||||
X86ISA::Interrupts::getIntAddrRange(AddrRangeList &range_list)
|
X86ISA::Interrupts::getIntAddrRange()
|
||||||
{
|
{
|
||||||
range_list.clear();
|
AddrRangeList ranges;
|
||||||
range_list.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
|
ranges.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
|
||||||
x86InterruptAddress(initialApicId, 0) +
|
x86InterruptAddress(initialApicId, 0) +
|
||||||
PhysAddrAPICRangeSize));
|
PhysAddrAPICRangeSize));
|
||||||
|
return ranges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -220,8 +220,8 @@ class Interrupts : public BasicPioDevice, IntDev
|
||||||
return entry.periodic;
|
return entry.periodic;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addressRanges(AddrRangeList &range_list);
|
AddrRangeList getAddrRanges();
|
||||||
void getIntAddrRange(AddrRangeList &range_list);
|
AddrRangeList getIntAddrRange();
|
||||||
|
|
||||||
Port *getPort(const std::string &if_name, int idx = -1)
|
Port *getPort(const std::string &if_name, int idx = -1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,7 +59,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
||||||
strcpy(name->machine, "x86_64");
|
strcpy(name->machine, "x86_64");
|
||||||
|
|
||||||
name.copyOut(tc->getMemPort());
|
name.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
int code = process->getSyscallArg(tc, index);
|
int code = process->getSyscallArg(tc, index);
|
||||||
uint64_t addr = process->getSyscallArg(tc, index);
|
uint64_t addr = process->getSyscallArg(tc, index);
|
||||||
uint64_t fsBase, gsBase;
|
uint64_t fsBase, gsBase;
|
||||||
TranslatingPort *p = tc->getMemPort();
|
SETranslatingPortProxy* p = tc->getMemProxy();
|
||||||
switch(code)
|
switch(code)
|
||||||
{
|
{
|
||||||
//Each of these valid options should actually check addr.
|
//Each of these valid options should actually check addr.
|
||||||
|
@ -149,10 +149,10 @@ setThreadArea32Func(SyscallDesc *desc, int callnum,
|
||||||
gdt(x86lp->gdtStart() + minTLSEntry * sizeof(uint64_t),
|
gdt(x86lp->gdtStart() + minTLSEntry * sizeof(uint64_t),
|
||||||
numTLSEntries * sizeof(uint64_t));
|
numTLSEntries * sizeof(uint64_t));
|
||||||
|
|
||||||
if (!userDesc.copyIn(tc->getMemPort()))
|
if (!userDesc.copyIn(tc->getMemProxy()))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
if (!gdt.copyIn(tc->getMemPort()))
|
if (!gdt.copyIn(tc->getMemProxy()))
|
||||||
panic("Failed to copy in GDT for %s.\n", desc->name);
|
panic("Failed to copy in GDT for %s.\n", desc->name);
|
||||||
|
|
||||||
if (userDesc->entry_number == (uint32_t)(-1)) {
|
if (userDesc->entry_number == (uint32_t)(-1)) {
|
||||||
|
@ -204,9 +204,9 @@ setThreadArea32Func(SyscallDesc *desc, int callnum,
|
||||||
|
|
||||||
gdt[index] = (uint64_t)segDesc;
|
gdt[index] = (uint64_t)segDesc;
|
||||||
|
|
||||||
if (!userDesc.copyOut(tc->getMemPort()))
|
if (!userDesc.copyOut(tc->getMemProxy()))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (!gdt.copyOut(tc->getMemPort()))
|
if (!gdt.copyOut(tc->getMemProxy()))
|
||||||
panic("Failed to copy out GDT for %s.\n", desc->name);
|
panic("Failed to copy out GDT for %s.\n", desc->name);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
#include "arch/vtophys.hh"
|
#include "arch/vtophys.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/physical.hh"
|
#include "mem/port_proxy.hh"
|
||||||
#include "params/LinuxX86System.hh"
|
#include "params/LinuxX86System.hh"
|
||||||
#include "sim/byteswap.hh"
|
#include "sim/byteswap.hh"
|
||||||
|
|
||||||
|
@ -67,8 +67,8 @@ LinuxX86System::initState()
|
||||||
// The location of the real mode data structure.
|
// The location of the real mode data structure.
|
||||||
const Addr realModeData = 0x90200;
|
const Addr realModeData = 0x90200;
|
||||||
|
|
||||||
// A port to write to memory.
|
// A port proxy to write to memory.
|
||||||
FunctionalPort * physPort = threadContexts[0]->getPhysPort();
|
PortProxy* physProxy = threadContexts[0]->getPhysProxy();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Deal with the command line stuff.
|
* Deal with the command line stuff.
|
||||||
|
@ -82,14 +82,14 @@ LinuxX86System::initState()
|
||||||
if (commandLine.length() + 1 > realModeData - commandLineBuff)
|
if (commandLine.length() + 1 > realModeData - commandLineBuff)
|
||||||
panic("Command line \"%s\" is longer than %d characters.\n",
|
panic("Command line \"%s\" is longer than %d characters.\n",
|
||||||
commandLine, realModeData - commandLineBuff - 1);
|
commandLine, realModeData - commandLineBuff - 1);
|
||||||
physPort->writeBlob(commandLineBuff,
|
physProxy->writeBlob(commandLineBuff,
|
||||||
(uint8_t *)commandLine.c_str(), commandLine.length() + 1);
|
(uint8_t *)commandLine.c_str(), commandLine.length() + 1);
|
||||||
|
|
||||||
// Generate a pointer of the right size and endianness to put into
|
// Generate a pointer of the right size and endianness to put into
|
||||||
// commandLinePointer.
|
// commandLinePointer.
|
||||||
uint32_t guestCommandLineBuff =
|
uint32_t guestCommandLineBuff =
|
||||||
X86ISA::htog((uint32_t)commandLineBuff);
|
X86ISA::htog((uint32_t)commandLineBuff);
|
||||||
physPort->writeBlob(commandLinePointer,
|
physProxy->writeBlob(commandLinePointer,
|
||||||
(uint8_t *)&guestCommandLineBuff, sizeof(guestCommandLineBuff));
|
(uint8_t *)&guestCommandLineBuff, sizeof(guestCommandLineBuff));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -127,7 +127,7 @@ LinuxX86System::initState()
|
||||||
// A pointer to the buffer for E820 entries.
|
// A pointer to the buffer for E820 entries.
|
||||||
const Addr e820MapPointer = realModeData + 0x2d0;
|
const Addr e820MapPointer = realModeData + 0x2d0;
|
||||||
|
|
||||||
e820Table->writeTo(physPort, e820MapNrPointer, e820MapPointer);
|
e820Table->writeTo(getSystemPort(), e820MapNrPointer, e820MapPointer);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pass the location of the real mode data structure to the kernel
|
* Pass the location of the real mode data structure to the kernel
|
||||||
|
|
|
@ -154,17 +154,8 @@ Walker::WalkerPort::recvFunctional(PacketPtr pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Walker::WalkerPort::recvStatusChange(Status status)
|
Walker::WalkerPort::recvRangeChange()
|
||||||
{
|
{
|
||||||
if (status == RangeChange) {
|
|
||||||
if (!snoopRangeSent) {
|
|
||||||
snoopRangeSent = true;
|
|
||||||
sendStatusChange(Port::RangeChange);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
panic("Unexpected recvStatusChange.\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -63,26 +63,18 @@ namespace X86ISA
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WalkerPort(const std::string &_name, Walker * _walker) :
|
WalkerPort(const std::string &_name, Walker * _walker) :
|
||||||
Port(_name, _walker), walker(_walker),
|
Port(_name, _walker), walker(_walker)
|
||||||
snoopRangeSent(false)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Walker * walker;
|
Walker * walker;
|
||||||
|
|
||||||
bool snoopRangeSent;
|
|
||||||
|
|
||||||
bool recvTiming(PacketPtr pkt);
|
bool recvTiming(PacketPtr pkt);
|
||||||
Tick recvAtomic(PacketPtr pkt);
|
Tick recvAtomic(PacketPtr pkt);
|
||||||
void recvFunctional(PacketPtr pkt);
|
void recvFunctional(PacketPtr pkt);
|
||||||
void recvStatusChange(Status status);
|
void recvRangeChange();
|
||||||
void recvRetry();
|
void recvRetry();
|
||||||
void getDeviceAddressRanges(AddrRangeList &resp,
|
bool isSnooping() { return true; }
|
||||||
bool &snoop)
|
|
||||||
{
|
|
||||||
resp.clear();
|
|
||||||
snoop = true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
friend class WalkerPort;
|
friend class WalkerPort;
|
||||||
|
|
|
@ -53,7 +53,6 @@
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/Stack.hh"
|
#include "debug/Stack.hh"
|
||||||
#include "mem/page_table.hh"
|
#include "mem/page_table.hh"
|
||||||
#include "mem/translating_port.hh"
|
|
||||||
#include "sim/process_impl.hh"
|
#include "sim/process_impl.hh"
|
||||||
#include "sim/syscall_emul.hh"
|
#include "sim/syscall_emul.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -48,9 +48,9 @@ namespace X86ISA
|
||||||
{
|
{
|
||||||
Addr addr = 0;
|
Addr addr = 0;
|
||||||
|
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
|
|
||||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
|
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
|
||||||
panic("thread info not compiled into kernel\n");
|
panic("thread info not compiled into kernel\n");
|
||||||
|
@ -82,9 +82,9 @@ namespace X86ISA
|
||||||
|
|
||||||
Addr tsk;
|
Addr tsk;
|
||||||
|
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
tsk = vp->readGtoH<Addr>(base + task_off);
|
tsk = vp->readGtoH<Addr>(base + task_off);
|
||||||
|
|
||||||
return tsk;
|
return tsk;
|
||||||
|
@ -99,9 +99,9 @@ namespace X86ISA
|
||||||
|
|
||||||
uint16_t pd;
|
uint16_t pd;
|
||||||
|
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
||||||
|
|
||||||
return pd;
|
return pd;
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
#include "base/intmath.hh"
|
#include "base/intmath.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/physical.hh"
|
#include "mem/port_proxy.hh"
|
||||||
#include "params/X86System.hh"
|
#include "params/X86System.hh"
|
||||||
#include "sim/byteswap.hh"
|
#include "sim/byteswap.hh"
|
||||||
|
|
||||||
|
@ -61,8 +61,6 @@ X86System::X86System(Params *p) :
|
||||||
mpConfigTable(p->intel_mp_table),
|
mpConfigTable(p->intel_mp_table),
|
||||||
rsdp(p->acpi_description_table_pointer)
|
rsdp(p->acpi_description_table_pointer)
|
||||||
{
|
{
|
||||||
if (kernel->getArch() == ObjectFile::I386)
|
|
||||||
fatal("Loading a 32 bit x86 kernel is not supported.\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -116,6 +114,9 @@ X86System::initState()
|
||||||
{
|
{
|
||||||
System::initState();
|
System::initState();
|
||||||
|
|
||||||
|
if (kernel->getArch() == ObjectFile::I386)
|
||||||
|
fatal("Loading a 32 bit x86 kernel is not supported.\n");
|
||||||
|
|
||||||
ThreadContext *tc = threadContexts[0];
|
ThreadContext *tc = threadContexts[0];
|
||||||
// This is the boot strap processor (BSP). Initialize it to look like
|
// This is the boot strap processor (BSP). Initialize it to look like
|
||||||
// the boot loader has just turned control over to the 64 bit OS. We
|
// the boot loader has just turned control over to the 64 bit OS. We
|
||||||
|
@ -137,8 +138,8 @@ X86System::initState()
|
||||||
const int PDPTBits = 9;
|
const int PDPTBits = 9;
|
||||||
const int PDTBits = 9;
|
const int PDTBits = 9;
|
||||||
|
|
||||||
// Get a port to write the page tables and descriptor tables.
|
// Get a port proxy to write the page tables and descriptor tables.
|
||||||
FunctionalPort * physPort = tc->getPhysPort();
|
PortProxy* physProxy = tc->getPhysProxy();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up the gdt.
|
* Set up the gdt.
|
||||||
|
@ -146,7 +147,7 @@ X86System::initState()
|
||||||
uint8_t numGDTEntries = 0;
|
uint8_t numGDTEntries = 0;
|
||||||
// Place holder at selector 0
|
// Place holder at selector 0
|
||||||
uint64_t nullDescriptor = 0;
|
uint64_t nullDescriptor = 0;
|
||||||
physPort->writeBlob(GDTBase + numGDTEntries * 8,
|
physProxy->writeBlob(GDTBase + numGDTEntries * 8,
|
||||||
(uint8_t *)(&nullDescriptor), 8);
|
(uint8_t *)(&nullDescriptor), 8);
|
||||||
numGDTEntries++;
|
numGDTEntries++;
|
||||||
|
|
||||||
|
@ -168,7 +169,7 @@ X86System::initState()
|
||||||
//it's beginning in memory and it's actual data, we'll use an
|
//it's beginning in memory and it's actual data, we'll use an
|
||||||
//intermediary.
|
//intermediary.
|
||||||
uint64_t csDescVal = csDesc;
|
uint64_t csDescVal = csDesc;
|
||||||
physPort->writeBlob(GDTBase + numGDTEntries * 8,
|
physProxy->writeBlob(GDTBase + numGDTEntries * 8,
|
||||||
(uint8_t *)(&csDescVal), 8);
|
(uint8_t *)(&csDescVal), 8);
|
||||||
|
|
||||||
numGDTEntries++;
|
numGDTEntries++;
|
||||||
|
@ -191,7 +192,7 @@ X86System::initState()
|
||||||
dsDesc.limitHigh = 0xF;
|
dsDesc.limitHigh = 0xF;
|
||||||
dsDesc.limitLow = 0xFF;
|
dsDesc.limitLow = 0xFF;
|
||||||
uint64_t dsDescVal = dsDesc;
|
uint64_t dsDescVal = dsDesc;
|
||||||
physPort->writeBlob(GDTBase + numGDTEntries * 8,
|
physProxy->writeBlob(GDTBase + numGDTEntries * 8,
|
||||||
(uint8_t *)(&dsDescVal), 8);
|
(uint8_t *)(&dsDescVal), 8);
|
||||||
|
|
||||||
numGDTEntries++;
|
numGDTEntries++;
|
||||||
|
@ -219,7 +220,7 @@ X86System::initState()
|
||||||
tssDesc.limitHigh = 0xF;
|
tssDesc.limitHigh = 0xF;
|
||||||
tssDesc.limitLow = 0xFF;
|
tssDesc.limitLow = 0xFF;
|
||||||
uint64_t tssDescVal = tssDesc;
|
uint64_t tssDescVal = tssDesc;
|
||||||
physPort->writeBlob(GDTBase + numGDTEntries * 8,
|
physProxy->writeBlob(GDTBase + numGDTEntries * 8,
|
||||||
(uint8_t *)(&tssDescVal), 8);
|
(uint8_t *)(&tssDescVal), 8);
|
||||||
|
|
||||||
numGDTEntries++;
|
numGDTEntries++;
|
||||||
|
@ -249,24 +250,24 @@ X86System::initState()
|
||||||
// read/write, user, not present
|
// read/write, user, not present
|
||||||
uint64_t pml4e = X86ISA::htog(0x6);
|
uint64_t pml4e = X86ISA::htog(0x6);
|
||||||
for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) {
|
for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) {
|
||||||
physPort->writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8);
|
physProxy->writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8);
|
||||||
}
|
}
|
||||||
// Point to the only PDPT
|
// Point to the only PDPT
|
||||||
pml4e = X86ISA::htog(0x7 | PageDirPtrTable);
|
pml4e = X86ISA::htog(0x7 | PageDirPtrTable);
|
||||||
physPort->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8);
|
physProxy->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8);
|
||||||
|
|
||||||
// Page Directory Pointer Table
|
// Page Directory Pointer Table
|
||||||
|
|
||||||
// read/write, user, not present
|
// read/write, user, not present
|
||||||
uint64_t pdpe = X86ISA::htog(0x6);
|
uint64_t pdpe = X86ISA::htog(0x6);
|
||||||
for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) {
|
for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) {
|
||||||
physPort->writeBlob(PageDirPtrTable + offset,
|
physProxy->writeBlob(PageDirPtrTable + offset,
|
||||||
(uint8_t *)(&pdpe), 8);
|
(uint8_t *)(&pdpe), 8);
|
||||||
}
|
}
|
||||||
// Point to the PDTs
|
// Point to the PDTs
|
||||||
for (int table = 0; table < NumPDTs; table++) {
|
for (int table = 0; table < NumPDTs; table++) {
|
||||||
pdpe = X86ISA::htog(0x7 | PageDirTable[table]);
|
pdpe = X86ISA::htog(0x7 | PageDirTable[table]);
|
||||||
physPort->writeBlob(PageDirPtrTable + table * 8,
|
physProxy->writeBlob(PageDirPtrTable + table * 8,
|
||||||
(uint8_t *)(&pdpe), 8);
|
(uint8_t *)(&pdpe), 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +279,7 @@ X86System::initState()
|
||||||
for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) {
|
for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) {
|
||||||
// read/write, user, present, 4MB
|
// read/write, user, present, 4MB
|
||||||
uint64_t pdte = X86ISA::htog(0x87 | base);
|
uint64_t pdte = X86ISA::htog(0x87 | base);
|
||||||
physPort->writeBlob(PageDirTable[table] + offset,
|
physProxy->writeBlob(PageDirTable[table] + offset,
|
||||||
(uint8_t *)(&pdte), 8);
|
(uint8_t *)(&pdte), 8);
|
||||||
base += pageSize;
|
base += pageSize;
|
||||||
}
|
}
|
||||||
|
@ -341,8 +342,8 @@ void
|
||||||
X86System::writeOutSMBiosTable(Addr header,
|
X86System::writeOutSMBiosTable(Addr header,
|
||||||
Addr &headerSize, Addr &structSize, Addr table)
|
Addr &headerSize, Addr &structSize, Addr table)
|
||||||
{
|
{
|
||||||
// Get a port to write the table and header to memory.
|
// Get a port proxy to write the table and header to memory.
|
||||||
FunctionalPort * physPort = threadContexts[0]->getPhysPort();
|
PortProxy* physProxy = threadContexts[0]->getPhysProxy();
|
||||||
|
|
||||||
// If the table location isn't specified, just put it after the header.
|
// If the table location isn't specified, just put it after the header.
|
||||||
// The header size as of the 2.5 SMBios specification is 0x1F bytes
|
// The header size as of the 2.5 SMBios specification is 0x1F bytes
|
||||||
|
@ -350,7 +351,7 @@ X86System::writeOutSMBiosTable(Addr header,
|
||||||
table = header + 0x1F;
|
table = header + 0x1F;
|
||||||
smbiosTable->setTableAddr(table);
|
smbiosTable->setTableAddr(table);
|
||||||
|
|
||||||
smbiosTable->writeOut(physPort, header, headerSize, structSize);
|
smbiosTable->writeOut(physProxy, header, headerSize, structSize);
|
||||||
|
|
||||||
// Do some bounds checking to make sure we at least didn't step on
|
// Do some bounds checking to make sure we at least didn't step on
|
||||||
// ourselves.
|
// ourselves.
|
||||||
|
@ -362,8 +363,8 @@ void
|
||||||
X86System::writeOutMPTable(Addr fp,
|
X86System::writeOutMPTable(Addr fp,
|
||||||
Addr &fpSize, Addr &tableSize, Addr table)
|
Addr &fpSize, Addr &tableSize, Addr table)
|
||||||
{
|
{
|
||||||
// Get a port to write the table and header to memory.
|
// Get a port proxy to write the table and header to memory.
|
||||||
FunctionalPort * physPort = threadContexts[0]->getPhysPort();
|
PortProxy* physProxy = threadContexts[0]->getPhysProxy();
|
||||||
|
|
||||||
// If the table location isn't specified and it exists, just put
|
// If the table location isn't specified and it exists, just put
|
||||||
// it after the floating pointer. The fp size as of the 1.4 Intel MP
|
// it after the floating pointer. The fp size as of the 1.4 Intel MP
|
||||||
|
@ -374,9 +375,9 @@ X86System::writeOutMPTable(Addr fp,
|
||||||
mpFloatingPointer->setTableAddr(table);
|
mpFloatingPointer->setTableAddr(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
fpSize = mpFloatingPointer->writeOut(physPort, fp);
|
fpSize = mpFloatingPointer->writeOut(physProxy, fp);
|
||||||
if (mpConfigTable)
|
if (mpConfigTable)
|
||||||
tableSize = mpConfigTable->writeOut(physPort, table);
|
tableSize = mpConfigTable->writeOut(physProxy, table);
|
||||||
else
|
else
|
||||||
tableSize = 0;
|
tableSize = 0;
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,7 @@ struct AllFlags : public Flag
|
||||||
FlagsMap::iterator end = allFlags().end();
|
FlagsMap::iterator end = allFlags().end();
|
||||||
for (; i != end; ++i)
|
for (; i != end; ++i)
|
||||||
if (i->second != this)
|
if (i->second != this)
|
||||||
i->second->enable();
|
i->second->disable();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -414,15 +414,15 @@ ElfObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ElfObject::loadSections(Port *memPort, Addr addrMask)
|
ElfObject::loadSections(PortProxy* memProxy, Addr addrMask)
|
||||||
{
|
{
|
||||||
if (!ObjectFile::loadSections(memPort, addrMask))
|
if (!ObjectFile::loadSections(memProxy, addrMask))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
vector<Segment>::iterator extraIt;
|
vector<Segment>::iterator extraIt;
|
||||||
for (extraIt = extraSegments.begin();
|
for (extraIt = extraSegments.begin();
|
||||||
extraIt != extraSegments.end(); extraIt++) {
|
extraIt != extraSegments.end(); extraIt++) {
|
||||||
if (!loadSection(&(*extraIt), memPort, addrMask)) {
|
if (!loadSection(&(*extraIt), memProxy, addrMask)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ class ElfObject : public ObjectFile
|
||||||
public:
|
public:
|
||||||
virtual ~ElfObject() {}
|
virtual ~ElfObject() {}
|
||||||
|
|
||||||
bool loadSections(Port *memPort,
|
bool loadSections(PortProxy *memProxy,
|
||||||
Addr addrMask = std::numeric_limits<Addr>::max());
|
Addr addrMask = std::numeric_limits<Addr>::max());
|
||||||
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
|
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
|
||||||
std::numeric_limits<Addr>::max());
|
std::numeric_limits<Addr>::max());
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
#include "base/loader/hex_file.hh"
|
#include "base/loader/hex_file.hh"
|
||||||
#include "base/loader/symtab.hh"
|
#include "base/loader/symtab.hh"
|
||||||
#include "base/cprintf.hh"
|
#include "base/cprintf.hh"
|
||||||
#include "mem/translating_port.hh"
|
#include "mem/port_proxy.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
/*
|
/*
|
||||||
|
@ -59,7 +59,7 @@ HexFile::~HexFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HexFile::loadSections(Port *memPort)
|
HexFile::loadSections(PortProxy* memProxy)
|
||||||
{
|
{
|
||||||
char Line[64];
|
char Line[64];
|
||||||
Addr MemAddr;
|
Addr MemAddr;
|
||||||
|
@ -71,7 +71,7 @@ HexFile::loadSections(Port *memPort)
|
||||||
parseLine(Line, &MemAddr, &Data);
|
parseLine(Line, &MemAddr, &Data);
|
||||||
if (MemAddr != 0) {
|
if (MemAddr != 0) {
|
||||||
// Now, write to memory
|
// Now, write to memory
|
||||||
memPort->writeBlob(MemAddr << 2, (uint8_t *)&Data, sizeof(Data));
|
memProxy->writeBlob(MemAddr << 2, (uint8_t *)&Data, sizeof(Data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
#include "base/types.hh"
|
#include "base/types.hh"
|
||||||
|
|
||||||
class Port;
|
class PortProxy;
|
||||||
|
|
||||||
class HexFile
|
class HexFile
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,7 @@ class HexFile
|
||||||
virtual ~HexFile();
|
virtual ~HexFile();
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
bool loadSections(Port *memPort);
|
bool loadSections(PortProxy* memProxy);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __BASE_LOADER_HEX_FILE_HH__
|
#endif // __BASE_LOADER_HEX_FILE_HH__
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
#include "base/loader/raw_object.hh"
|
#include "base/loader/raw_object.hh"
|
||||||
#include "base/loader/symtab.hh"
|
#include "base/loader/symtab.hh"
|
||||||
#include "base/cprintf.hh"
|
#include "base/cprintf.hh"
|
||||||
#include "mem/translating_port.hh"
|
#include "mem/port_proxy.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -65,16 +65,16 @@ ObjectFile::~ObjectFile()
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ObjectFile::loadSection(Section *sec, Port *memPort, Addr addrMask)
|
ObjectFile::loadSection(Section *sec, PortProxy* memProxy, Addr addrMask)
|
||||||
{
|
{
|
||||||
if (sec->size != 0) {
|
if (sec->size != 0) {
|
||||||
Addr addr = sec->baseAddr & addrMask;
|
Addr addr = sec->baseAddr & addrMask;
|
||||||
if (sec->fileImage) {
|
if (sec->fileImage) {
|
||||||
memPort->writeBlob(addr, sec->fileImage, sec->size);
|
memProxy->writeBlob(addr, sec->fileImage, sec->size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// no image: must be bss
|
// no image: must be bss
|
||||||
memPort->memsetBlob(addr, 0, sec->size);
|
memProxy->memsetBlob(addr, 0, sec->size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -82,11 +82,11 @@ ObjectFile::loadSection(Section *sec, Port *memPort, Addr addrMask)
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ObjectFile::loadSections(Port *memPort, Addr addrMask)
|
ObjectFile::loadSections(PortProxy* memProxy, Addr addrMask)
|
||||||
{
|
{
|
||||||
return (loadSection(&text, memPort, addrMask)
|
return (loadSection(&text, memProxy, addrMask)
|
||||||
&& loadSection(&data, memPort, addrMask)
|
&& loadSection(&data, memProxy, addrMask)
|
||||||
&& loadSection(&bss, memPort, addrMask));
|
&& loadSection(&bss, memProxy, addrMask));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
#include "base/types.hh"
|
#include "base/types.hh"
|
||||||
|
|
||||||
class Port;
|
class PortProxy;
|
||||||
class SymbolTable;
|
class SymbolTable;
|
||||||
|
|
||||||
class ObjectFile
|
class ObjectFile
|
||||||
|
@ -83,7 +83,7 @@ class ObjectFile
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
virtual bool loadSections(Port *memPort, Addr addrMask =
|
virtual bool loadSections(PortProxy *memProxy, Addr addrMask =
|
||||||
std::numeric_limits<Addr>::max());
|
std::numeric_limits<Addr>::max());
|
||||||
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
|
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
|
||||||
std::numeric_limits<Addr>::max()) = 0;
|
std::numeric_limits<Addr>::max()) = 0;
|
||||||
|
@ -111,7 +111,7 @@ class ObjectFile
|
||||||
Section data;
|
Section data;
|
||||||
Section bss;
|
Section bss;
|
||||||
|
|
||||||
bool loadSection(Section *sec, Port *memPort, Addr addrMask);
|
bool loadSection(Section *sec, PortProxy* memProxy, Addr addrMask);
|
||||||
void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; }
|
void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -132,8 +132,8 @@
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/GDBAll.hh"
|
#include "debug/GDBAll.hh"
|
||||||
#include "mem/port.hh"
|
#include "mem/port.hh"
|
||||||
#include "mem/translating_port.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/se_translating_port_proxy.hh"
|
||||||
#include "sim/full_system.hh"
|
#include "sim/full_system.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
|
@ -461,10 +461,10 @@ BaseRemoteGDB::read(Addr vaddr, size_t size, char *data)
|
||||||
DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
|
DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
|
||||||
|
|
||||||
if (FullSystem) {
|
if (FullSystem) {
|
||||||
VirtualPort *port = context->getVirtPort();
|
FSTranslatingPortProxy *port = context->getVirtProxy();
|
||||||
port->readBlob(vaddr, (uint8_t*)data, size);
|
port->readBlob(vaddr, (uint8_t*)data, size);
|
||||||
} else {
|
} else {
|
||||||
TranslatingPort *port = context->getMemPort();
|
SETranslatingPortProxy *port = context->getMemProxy();
|
||||||
port->readBlob(vaddr, (uint8_t*)data, size);
|
port->readBlob(vaddr, (uint8_t*)data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,10 +504,10 @@ BaseRemoteGDB::write(Addr vaddr, size_t size, const char *data)
|
||||||
DPRINTFNR("\n");
|
DPRINTFNR("\n");
|
||||||
}
|
}
|
||||||
if (FullSystem) {
|
if (FullSystem) {
|
||||||
VirtualPort *port = context->getVirtPort();
|
FSTranslatingPortProxy *port = context->getVirtProxy();
|
||||||
port->writeBlob(vaddr, (uint8_t*)data, size);
|
port->writeBlob(vaddr, (uint8_t*)data, size);
|
||||||
} else {
|
} else {
|
||||||
TranslatingPort *port = context->getMemPort();
|
SETranslatingPortProxy *port = context->getMemProxy();
|
||||||
port->writeBlob(vaddr, (uint8_t*)data, size);
|
port->writeBlob(vaddr, (uint8_t*)data, size);
|
||||||
delete port;
|
delete port;
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,7 +216,7 @@ class BaseRemoteGDB
|
||||||
|
|
||||||
bool insertSoftBreak(Addr addr, size_t len);
|
bool insertSoftBreak(Addr addr, size_t len);
|
||||||
bool removeSoftBreak(Addr addr, size_t len);
|
bool removeSoftBreak(Addr addr, size_t len);
|
||||||
bool insertHardBreak(Addr addr, size_t len);
|
virtual bool insertHardBreak(Addr addr, size_t len);
|
||||||
bool removeHardBreak(Addr addr, size_t len);
|
bool removeHardBreak(Addr addr, size_t len);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -138,9 +138,12 @@ class BaseCPU(MemObject):
|
||||||
|
|
||||||
tracer = Param.InstTracer(default_tracer, "Instruction tracer")
|
tracer = Param.InstTracer(default_tracer, "Instruction tracer")
|
||||||
|
|
||||||
_cached_ports = []
|
icache_port = Port("Instruction Port")
|
||||||
|
dcache_port = Port("Data Port")
|
||||||
|
_cached_ports = ['icache_port', 'dcache_port']
|
||||||
|
|
||||||
if buildEnv['TARGET_ISA'] in ['x86', 'arm']:
|
if buildEnv['TARGET_ISA'] in ['x86', 'arm']:
|
||||||
_cached_ports = ["itb.walker.port", "dtb.walker.port"]
|
_cached_ports += ["itb.walker.port", "dtb.walker.port"]
|
||||||
|
|
||||||
_uncached_ports = []
|
_uncached_ports = []
|
||||||
if buildEnv['TARGET_ISA'] == 'x86':
|
if buildEnv['TARGET_ISA'] == 'x86':
|
||||||
|
|
|
@ -1,4 +1,16 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2011 ARM Limited
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* The license below extends only to copyright in the software and shall
|
||||||
|
* not be construed as granting a license to any other intellectual
|
||||||
|
* property including but not limited to intellectual property relating
|
||||||
|
* to a hardware implementation of the functionality of the software
|
||||||
|
* licensed hereunder. You may use the software subject to the license
|
||||||
|
* terms below provided that you ensure that this notice is replicated
|
||||||
|
* unmodified and in its entirety in all distributions of the software,
|
||||||
|
* modified or unmodified, in source code or in binary form.
|
||||||
|
*
|
||||||
* Copyright (c) 2002-2005 The Regents of The University of Michigan
|
* Copyright (c) 2002-2005 The Regents of The University of Michigan
|
||||||
* Copyright (c) 2011 Regents of the University of California
|
* Copyright (c) 2011 Regents of the University of California
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
@ -470,3 +482,36 @@ BaseCPU::traceFunctionsInternal(Addr pc)
|
||||||
functionEntryTick = curTick();
|
functionEntryTick = curTick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BaseCPU::CpuPort::recvTiming(PacketPtr pkt)
|
||||||
|
{
|
||||||
|
panic("BaseCPU doesn't expect recvTiming callback!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BaseCPU::CpuPort::recvRetry()
|
||||||
|
{
|
||||||
|
panic("BaseCPU doesn't expect recvRetry callback!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Tick
|
||||||
|
BaseCPU::CpuPort::recvAtomic(PacketPtr pkt)
|
||||||
|
{
|
||||||
|
panic("BaseCPU doesn't expect recvAtomic callback!");
|
||||||
|
return curTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BaseCPU::CpuPort::recvFunctional(PacketPtr pkt)
|
||||||
|
{
|
||||||
|
// No internal storage to update (in the general case). In the
|
||||||
|
// long term this should never be called, but that assumed a split
|
||||||
|
// into master/slave and request/response.
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BaseCPU::CpuPort::recvRangeChange()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,16 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2011 ARM Limited
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* The license below extends only to copyright in the software and shall
|
||||||
|
* not be construed as granting a license to any other intellectual
|
||||||
|
* property including but not limited to intellectual property relating
|
||||||
|
* to a hardware implementation of the functionality of the software
|
||||||
|
* licensed hereunder. You may use the software subject to the license
|
||||||
|
* terms below provided that you ensure that this notice is replicated
|
||||||
|
* unmodified and in its entirety in all distributions of the software,
|
||||||
|
* modified or unmodified, in source code or in binary form.
|
||||||
|
*
|
||||||
* Copyright (c) 2002-2005 The Regents of The University of Michigan
|
* Copyright (c) 2002-2005 The Regents of The University of Michigan
|
||||||
* Copyright (c) 2011 Regents of the University of California
|
* Copyright (c) 2011 Regents of the University of California
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
@ -92,6 +104,42 @@ class BaseCPU : public MemObject
|
||||||
// therefore no setCpuId() method is provided
|
// therefore no setCpuId() method is provided
|
||||||
int _cpuId;
|
int _cpuId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define a base class for the CPU ports (instruction and data)
|
||||||
|
* that is refined in the subclasses. This class handles the
|
||||||
|
* common cases, i.e. the functional accesses and the status
|
||||||
|
* changes and address range queries. The default behaviour for
|
||||||
|
* both atomic and timing access is to panic and the corresponding
|
||||||
|
* subclasses have to override these methods.
|
||||||
|
*/
|
||||||
|
class CpuPort : public Port
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a CPU port with a name and a structural owner.
|
||||||
|
*
|
||||||
|
* @param _name port name including the owner
|
||||||
|
* @param _name structural owner of this port
|
||||||
|
*/
|
||||||
|
CpuPort(const std::string& _name, MemObject* _owner) :
|
||||||
|
Port(_name, _owner)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual bool recvTiming(PacketPtr pkt);
|
||||||
|
|
||||||
|
virtual Tick recvAtomic(PacketPtr pkt);
|
||||||
|
|
||||||
|
virtual void recvRetry();
|
||||||
|
|
||||||
|
void recvFunctional(PacketPtr pkt);
|
||||||
|
|
||||||
|
void recvRangeChange();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Reads this CPU's ID. */
|
/** Reads this CPU's ID. */
|
||||||
int cpuId() { return _cpuId; }
|
int cpuId() { return _cpuId; }
|
||||||
|
|
|
@ -98,12 +98,12 @@ class CheckerThreadContext : public ThreadContext
|
||||||
|
|
||||||
Process *getProcessPtr() { return actualTC->getProcessPtr(); }
|
Process *getProcessPtr() { return actualTC->getProcessPtr(); }
|
||||||
|
|
||||||
TranslatingPort *getMemPort() { return actualTC->getMemPort(); }
|
PortProxy* getPhysProxy() { return actualTC->getPhysProxy(); }
|
||||||
|
|
||||||
VirtualPort *getVirtPort()
|
FSTranslatingPortProxy* getVirtProxy()
|
||||||
{ return actualTC->getVirtPort(); }
|
{ return actualTC->getVirtProxy(); }
|
||||||
|
|
||||||
FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); }
|
SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); }
|
||||||
|
|
||||||
Status status() const { return actualTC->status(); }
|
Status status() const { return actualTC->status(); }
|
||||||
|
|
||||||
|
|
|
@ -44,9 +44,6 @@ class InOrderCPU(BaseCPU):
|
||||||
|
|
||||||
fetchMemPort = Param.String("icache_port" , "Name of Memory Port to get instructions from")
|
fetchMemPort = Param.String("icache_port" , "Name of Memory Port to get instructions from")
|
||||||
dataMemPort = Param.String("dcache_port" , "Name of Memory Port to get data from")
|
dataMemPort = Param.String("dcache_port" , "Name of Memory Port to get data from")
|
||||||
icache_port = Port("Instruction Port")
|
|
||||||
dcache_port = Port("Data Port")
|
|
||||||
_cached_ports = ['icache_port', 'dcache_port']
|
|
||||||
|
|
||||||
fetchBuffSize = Param.Unsigned(4, "Fetch Buffer Size (Number of Cache Blocks Stored)")
|
fetchBuffSize = Param.Unsigned(4, "Fetch Buffer Size (Number of Cache Blocks Stored)")
|
||||||
memBlockSize = Param.Unsigned(64, "Memory Block Size")
|
memBlockSize = Param.Unsigned(64, "Memory Block Size")
|
||||||
|
|
|
@ -54,7 +54,6 @@
|
||||||
#include "debug/RefCount.hh"
|
#include "debug/RefCount.hh"
|
||||||
#include "debug/SkedCache.hh"
|
#include "debug/SkedCache.hh"
|
||||||
#include "debug/Quiesce.hh"
|
#include "debug/Quiesce.hh"
|
||||||
#include "mem/translating_port.hh"
|
|
||||||
#include "params/InOrderCPU.hh"
|
#include "params/InOrderCPU.hh"
|
||||||
#include "sim/full_system.hh"
|
#include "sim/full_system.hh"
|
||||||
#include "sim/process.hh"
|
#include "sim/process.hh"
|
||||||
|
@ -758,6 +757,8 @@ InOrderCPU::init()
|
||||||
for (ThreadID tid = 0; tid < numThreads; tid++) {
|
for (ThreadID tid = 0; tid < numThreads; tid++) {
|
||||||
ThreadContext *src_tc = threadContexts[tid];
|
ThreadContext *src_tc = threadContexts[tid];
|
||||||
TheISA::initCPU(src_tc, src_tc->contextId());
|
TheISA::initCPU(src_tc, src_tc->contextId());
|
||||||
|
// Initialise the ThreadContext's memory proxies
|
||||||
|
thread[tid]->initMemProxies(thread[tid]->getTC());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -860,7 +861,6 @@ InOrderCPU::getInterrupts()
|
||||||
return interrupts->getInterrupt(threadContexts[0]);
|
return interrupts->getInterrupt(threadContexts[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
InOrderCPU::processInterrupts(Fault interrupt)
|
InOrderCPU::processInterrupts(Fault interrupt)
|
||||||
{
|
{
|
||||||
|
@ -879,16 +879,6 @@ InOrderCPU::processInterrupts(Fault interrupt)
|
||||||
trap(interrupt, threadContexts[0]->contextId(), dummyBufferInst);
|
trap(interrupt, threadContexts[0]->contextId(), dummyBufferInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
InOrderCPU::updateMemPorts()
|
|
||||||
{
|
|
||||||
// Update all ThreadContext's memory ports (Functional/Virtual
|
|
||||||
// Ports)
|
|
||||||
ThreadID size = thread.size();
|
|
||||||
for (ThreadID i = 0; i < size; ++i)
|
|
||||||
thread[i]->connectMemPorts(thread[i]->getTC());
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
InOrderCPU::trapContext(Fault fault, ThreadID tid, DynInstPtr inst, int delay)
|
InOrderCPU::trapContext(Fault fault, ThreadID tid, DynInstPtr inst, int delay)
|
||||||
{
|
{
|
||||||
|
|
|
@ -428,10 +428,6 @@ class InOrderCPU : public BaseCPU
|
||||||
/** Halts the CPU. */
|
/** Halts the CPU. */
|
||||||
void halt() { panic("Halt not implemented!\n"); }
|
void halt() { panic("Halt not implemented!\n"); }
|
||||||
|
|
||||||
/** Update the Virt and Phys ports of all ThreadContexts to
|
|
||||||
* reflect change in memory connections. */
|
|
||||||
void updateMemPorts();
|
|
||||||
|
|
||||||
/** Check if this address is a valid instruction address. */
|
/** Check if this address is a valid instruction address. */
|
||||||
bool validInstAddr(Addr addr) { return true; }
|
bool validInstAddr(Addr addr) { return true; }
|
||||||
|
|
||||||
|
|
|
@ -82,17 +82,8 @@ CacheUnit::CachePort::recvFunctional(PacketPtr pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CacheUnit::CachePort::recvStatusChange(Status status)
|
CacheUnit::CachePort::recvRangeChange()
|
||||||
{
|
{
|
||||||
if (status == RangeChange) {
|
|
||||||
if (!snoopRangeSent) {
|
|
||||||
snoopRangeSent = true;
|
|
||||||
sendStatusChange(Port::RangeChange);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
panic("CacheUnit::CachePort doesn't expect recvStatusChange callback!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -145,18 +136,6 @@ CacheUnit::tlb()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
CacheUnit::CachePort::setPeer(Port *port)
|
|
||||||
{
|
|
||||||
Port::setPeer(port);
|
|
||||||
|
|
||||||
// Update the ThreadContext's memory ports (Functional/Virtual
|
|
||||||
// Ports)
|
|
||||||
if (cachePortUnit->resName == "dcache_port") {
|
|
||||||
cachePortUnit->cpu->updateMemPorts();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Port *
|
Port *
|
||||||
CacheUnit::getPort(const string &if_name, int idx)
|
CacheUnit::getPort(const string &if_name, int idx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -90,13 +90,9 @@ class CacheUnit : public Resource
|
||||||
CachePort(CacheUnit *_cachePortUnit)
|
CachePort(CacheUnit *_cachePortUnit)
|
||||||
: Port(_cachePortUnit->name() + "-cache-port",
|
: Port(_cachePortUnit->name() + "-cache-port",
|
||||||
(MemObject*)_cachePortUnit->cpu),
|
(MemObject*)_cachePortUnit->cpu),
|
||||||
cachePortUnit(_cachePortUnit), snoopRangeSent(false)
|
cachePortUnit(_cachePortUnit)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
bool snoopRangeSent;
|
|
||||||
|
|
||||||
void setPeer(Port *port);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Atomic version of receive. Panics. */
|
/** Atomic version of receive. Panics. */
|
||||||
Tick recvAtomic(PacketPtr pkt);
|
Tick recvAtomic(PacketPtr pkt);
|
||||||
|
@ -104,13 +100,8 @@ class CacheUnit : public Resource
|
||||||
/** Functional version of receive.*/
|
/** Functional version of receive.*/
|
||||||
void recvFunctional(PacketPtr pkt);
|
void recvFunctional(PacketPtr pkt);
|
||||||
|
|
||||||
/** Receives status change. Other than range changing, panics. */
|
/** Receives range changes. */
|
||||||
void recvStatusChange(Status status);
|
void recvRangeChange();
|
||||||
|
|
||||||
/** Returns the address ranges of this device. */
|
|
||||||
void getDeviceAddressRanges(AddrRangeList &resp,
|
|
||||||
bool &snoop)
|
|
||||||
{ resp.clear(); snoop = true; }
|
|
||||||
|
|
||||||
/** Timing version of receive */
|
/** Timing version of receive */
|
||||||
bool recvTiming(PacketPtr pkt);
|
bool recvTiming(PacketPtr pkt);
|
||||||
|
|
|
@ -38,10 +38,10 @@
|
||||||
|
|
||||||
using namespace TheISA;
|
using namespace TheISA;
|
||||||
|
|
||||||
VirtualPort *
|
FSTranslatingPortProxy*
|
||||||
InOrderThreadContext::getVirtPort()
|
InOrderThreadContext::getVirtProxy()
|
||||||
{
|
{
|
||||||
return thread->getVirtPort();
|
return thread->getVirtProxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -117,8 +117,12 @@ class InOrderThreadContext : public ThreadContext
|
||||||
TheISA::Kernel::Statistics *getKernelStats()
|
TheISA::Kernel::Statistics *getKernelStats()
|
||||||
{ return thread->kernelStats; }
|
{ return thread->kernelStats; }
|
||||||
|
|
||||||
void connectMemPorts(ThreadContext *tc)
|
PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
|
||||||
{ thread->connectMemPorts(tc); }
|
|
||||||
|
FSTranslatingPortProxy* getVirtProxy();
|
||||||
|
|
||||||
|
void initMemProxies(ThreadContext *tc)
|
||||||
|
{ thread->initMemProxies(tc); }
|
||||||
|
|
||||||
/** Dumps the function profiling information.
|
/** Dumps the function profiling information.
|
||||||
* @todo: Implement.
|
* @todo: Implement.
|
||||||
|
@ -142,14 +146,11 @@ class InOrderThreadContext : public ThreadContext
|
||||||
return this->thread->quiesceEvent;
|
return this->thread->quiesceEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); }
|
||||||
|
|
||||||
/** Returns a pointer to this thread's process. */
|
/** Returns a pointer to this thread's process. */
|
||||||
Process *getProcessPtr() { return thread->getProcessPtr(); }
|
Process *getProcessPtr() { return thread->getProcessPtr(); }
|
||||||
|
|
||||||
TranslatingPort *getMemPort() { return thread->getMemPort(); }
|
|
||||||
|
|
||||||
VirtualPort *getVirtPort();
|
|
||||||
FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
|
|
||||||
|
|
||||||
/** Returns this thread's status. */
|
/** Returns this thread's status. */
|
||||||
Status status() const { return thread->status(); }
|
Status status() const { return thread->status(); }
|
||||||
|
|
||||||
|
|
|
@ -49,9 +49,6 @@ class DerivO3CPU(BaseCPU):
|
||||||
checker.dtb = Parent.dtb
|
checker.dtb = Parent.dtb
|
||||||
|
|
||||||
cachePorts = Param.Unsigned(200, "Cache Ports")
|
cachePorts = Param.Unsigned(200, "Cache Ports")
|
||||||
icache_port = Port("Instruction Port")
|
|
||||||
dcache_port = Port("Data Port")
|
|
||||||
_cached_ports = BaseCPU._cached_ports + ['icache_port', 'dcache_port']
|
|
||||||
|
|
||||||
decodeToFetchDelay = Param.Unsigned(1, "Decode to fetch delay")
|
decodeToFetchDelay = Param.Unsigned(1, "Decode to fetch delay")
|
||||||
renameToFetchDelay = Param.Unsigned(1 ,"Rename to fetch delay")
|
renameToFetchDelay = Param.Unsigned(1 ,"Rename to fetch delay")
|
||||||
|
|
|
@ -1,4 +1,16 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2011 ARM Limited
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* The license below extends only to copyright in the software and shall
|
||||||
|
* not be construed as granting a license to any other intellectual
|
||||||
|
* property including but not limited to intellectual property relating
|
||||||
|
* to a hardware implementation of the functionality of the software
|
||||||
|
* licensed hereunder. You may use the software subject to the license
|
||||||
|
* terms below provided that you ensure that this notice is replicated
|
||||||
|
* unmodified and in its entirety in all distributions of the software,
|
||||||
|
* modified or unmodified, in source code or in binary form.
|
||||||
|
*
|
||||||
* Copyright (c) 2004-2006 The Regents of The University of Michigan
|
* Copyright (c) 2004-2006 The Regents of The University of Michigan
|
||||||
* Copyright (c) 2011 Regents of the University of California
|
* Copyright (c) 2011 Regents of the University of California
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
@ -76,6 +88,42 @@ BaseO3CPU::regStats()
|
||||||
BaseCPU::regStats();
|
BaseCPU::regStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Impl>
|
||||||
|
bool
|
||||||
|
FullO3CPU<Impl>::IcachePort::recvTiming(PacketPtr pkt)
|
||||||
|
{
|
||||||
|
DPRINTF(O3CPU, "Fetch unit received timing\n");
|
||||||
|
if (pkt->isResponse()) {
|
||||||
|
// We shouldn't ever get a block in ownership state
|
||||||
|
assert(!(pkt->memInhibitAsserted() && !pkt->sharedAsserted()));
|
||||||
|
|
||||||
|
fetch->processCacheCompletion(pkt);
|
||||||
|
}
|
||||||
|
//else Snooped a coherence request, just return
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Impl>
|
||||||
|
void
|
||||||
|
FullO3CPU<Impl>::IcachePort::recvRetry()
|
||||||
|
{
|
||||||
|
fetch->recvRetry();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Impl>
|
||||||
|
bool
|
||||||
|
FullO3CPU<Impl>::DcachePort::recvTiming(PacketPtr pkt)
|
||||||
|
{
|
||||||
|
return lsq->recvTiming(pkt);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Impl>
|
||||||
|
void
|
||||||
|
FullO3CPU<Impl>::DcachePort::recvRetry()
|
||||||
|
{
|
||||||
|
lsq->recvRetry();
|
||||||
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c)
|
FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c)
|
||||||
: Event(CPU_Tick_Pri), cpu(c)
|
: Event(CPU_Tick_Pri), cpu(c)
|
||||||
|
@ -191,6 +239,9 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
|
||||||
TheISA::NumMiscRegs * numThreads,
|
TheISA::NumMiscRegs * numThreads,
|
||||||
TheISA::ZeroReg),
|
TheISA::ZeroReg),
|
||||||
|
|
||||||
|
icachePort(&fetch, this),
|
||||||
|
dcachePort(&iew.ldstQueue, this),
|
||||||
|
|
||||||
timeBuffer(params->backComSize, params->forwardComSize),
|
timeBuffer(params->backComSize, params->forwardComSize),
|
||||||
fetchQueue(params->backComSize, params->forwardComSize),
|
fetchQueue(params->backComSize, params->forwardComSize),
|
||||||
decodeQueue(params->backComSize, params->forwardComSize),
|
decodeQueue(params->backComSize, params->forwardComSize),
|
||||||
|
@ -215,6 +266,7 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
|
||||||
if (params->checker) {
|
if (params->checker) {
|
||||||
BaseCPU *temp_checker = params->checker;
|
BaseCPU *temp_checker = params->checker;
|
||||||
checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
|
checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
|
||||||
|
checker->setIcachePort(&icachePort);
|
||||||
checker->setSystem(params->system);
|
checker->setSystem(params->system);
|
||||||
} else {
|
} else {
|
||||||
checker = NULL;
|
checker = NULL;
|
||||||
|
@ -524,9 +576,9 @@ Port *
|
||||||
FullO3CPU<Impl>::getPort(const std::string &if_name, int idx)
|
FullO3CPU<Impl>::getPort(const std::string &if_name, int idx)
|
||||||
{
|
{
|
||||||
if (if_name == "dcache_port")
|
if (if_name == "dcache_port")
|
||||||
return iew.getDcachePort();
|
return &dcachePort;
|
||||||
else if (if_name == "icache_port")
|
else if (if_name == "icache_port")
|
||||||
return fetch.getIcachePort();
|
return &icachePort;
|
||||||
else
|
else
|
||||||
panic("No Such Port\n");
|
panic("No Such Port\n");
|
||||||
}
|
}
|
||||||
|
@ -600,10 +652,19 @@ FullO3CPU<Impl>::init()
|
||||||
for (ThreadID tid = 0; tid < numThreads; ++tid)
|
for (ThreadID tid = 0; tid < numThreads; ++tid)
|
||||||
thread[tid]->inSyscall = true;
|
thread[tid]->inSyscall = true;
|
||||||
|
|
||||||
|
// this CPU could still be unconnected if we are restoring from a
|
||||||
|
// checkpoint and this CPU is to be switched in, thus we can only
|
||||||
|
// do this here if the instruction port is actually connected, if
|
||||||
|
// not we have to do it as part of takeOverFrom
|
||||||
|
if (icachePort.isConnected())
|
||||||
|
fetch.setIcache();
|
||||||
|
|
||||||
if (FullSystem) {
|
if (FullSystem) {
|
||||||
for (ThreadID tid = 0; tid < numThreads; tid++) {
|
for (ThreadID tid = 0; tid < numThreads; tid++) {
|
||||||
ThreadContext *src_tc = threadContexts[tid];
|
ThreadContext *src_tc = threadContexts[tid];
|
||||||
TheISA::initCPU(src_tc, src_tc->contextId());
|
TheISA::initCPU(src_tc, src_tc->contextId());
|
||||||
|
// Initialise the ThreadContext's memory proxies
|
||||||
|
thread[tid]->initMemProxies(thread[tid]->getTC());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -967,17 +1028,6 @@ FullO3CPU<Impl>::processInterrupts(Fault interrupt)
|
||||||
this->trap(interrupt, 0, NULL);
|
this->trap(interrupt, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
|
||||||
void
|
|
||||||
FullO3CPU<Impl>::updateMemPorts()
|
|
||||||
{
|
|
||||||
// Update all ThreadContext's memory ports (Functional/Virtual
|
|
||||||
// Ports)
|
|
||||||
ThreadID size = thread.size();
|
|
||||||
for (ThreadID i = 0; i < size; ++i)
|
|
||||||
thread[i]->connectMemPorts(thread[i]->getTC());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
FullO3CPU<Impl>::trap(Fault fault, ThreadID tid, StaticInstPtr inst)
|
FullO3CPU<Impl>::trap(Fault fault, ThreadID tid, StaticInstPtr inst)
|
||||||
|
@ -1166,7 +1216,7 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
|
||||||
|
|
||||||
activityRec.reset();
|
activityRec.reset();
|
||||||
|
|
||||||
BaseCPU::takeOverFrom(oldCPU, fetch.getIcachePort(), iew.getDcachePort());
|
BaseCPU::takeOverFrom(oldCPU, &icachePort, &dcachePort);
|
||||||
|
|
||||||
fetch.takeOverFrom();
|
fetch.takeOverFrom();
|
||||||
decode.takeOverFrom();
|
decode.takeOverFrom();
|
||||||
|
|
|
@ -1,4 +1,16 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2011 ARM Limited
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* The license below extends only to copyright in the software and shall
|
||||||
|
* not be construed as granting a license to any other intellectual
|
||||||
|
* property including but not limited to intellectual property relating
|
||||||
|
* to a hardware implementation of the functionality of the software
|
||||||
|
* licensed hereunder. You may use the software subject to the license
|
||||||
|
* terms below provided that you ensure that this notice is replicated
|
||||||
|
* unmodified and in its entirety in all distributions of the software,
|
||||||
|
* modified or unmodified, in source code or in binary form.
|
||||||
|
*
|
||||||
* Copyright (c) 2004-2005 The Regents of The University of Michigan
|
* Copyright (c) 2004-2005 The Regents of The University of Michigan
|
||||||
* Copyright (c) 2011 Regents of the University of California
|
* Copyright (c) 2011 Regents of the University of California
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
@ -117,6 +129,68 @@ class FullO3CPU : public BaseO3CPU
|
||||||
Status _threadStatus[Impl::MaxThreads];
|
Status _threadStatus[Impl::MaxThreads];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IcachePort class for instruction fetch.
|
||||||
|
*/
|
||||||
|
class IcachePort : public CpuPort
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/** Pointer to fetch. */
|
||||||
|
DefaultFetch<Impl> *fetch;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Default constructor. */
|
||||||
|
IcachePort(DefaultFetch<Impl> *_fetch, FullO3CPU<Impl>* _cpu)
|
||||||
|
: CpuPort(_fetch->name() + "-iport", _cpu), fetch(_fetch)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/** Timing version of receive. Handles setting fetch to the
|
||||||
|
* proper status to start fetching. */
|
||||||
|
virtual bool recvTiming(PacketPtr pkt);
|
||||||
|
|
||||||
|
/** Handles doing a retry of a failed fetch. */
|
||||||
|
virtual void recvRetry();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DcachePort class for the load/store queue.
|
||||||
|
*/
|
||||||
|
class DcachePort : public CpuPort
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/** Pointer to LSQ. */
|
||||||
|
LSQ<Impl> *lsq;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Default constructor. */
|
||||||
|
DcachePort(LSQ<Impl> *_lsq, FullO3CPU<Impl>* _cpu)
|
||||||
|
: CpuPort(_lsq->name() + "-dport", _cpu), lsq(_lsq)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/** Timing version of receive. Handles writing back and
|
||||||
|
* completing the load or store that has returned from
|
||||||
|
* memory. */
|
||||||
|
virtual bool recvTiming(PacketPtr pkt);
|
||||||
|
|
||||||
|
/** Handles doing a retry of the previous send. */
|
||||||
|
virtual void recvRetry();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As this CPU requires snooping to maintain the load store queue
|
||||||
|
* change the behaviour from the base CPU port.
|
||||||
|
*
|
||||||
|
* @return true since we have to snoop
|
||||||
|
*/
|
||||||
|
virtual bool isSnooping()
|
||||||
|
{ return true; }
|
||||||
|
};
|
||||||
|
|
||||||
class TickEvent : public Event
|
class TickEvent : public Event
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -391,10 +465,6 @@ class FullO3CPU : public BaseO3CPU
|
||||||
/** Halts the CPU. */
|
/** Halts the CPU. */
|
||||||
void halt() { panic("Halt not implemented!\n"); }
|
void halt() { panic("Halt not implemented!\n"); }
|
||||||
|
|
||||||
/** Update the Virt and Phys ports of all ThreadContexts to
|
|
||||||
* reflect change in memory connections. */
|
|
||||||
void updateMemPorts();
|
|
||||||
|
|
||||||
/** Check if this address is a valid instruction address. */
|
/** Check if this address is a valid instruction address. */
|
||||||
bool validInstAddr(Addr addr) { return true; }
|
bool validInstAddr(Addr addr) { return true; }
|
||||||
|
|
||||||
|
@ -565,6 +635,12 @@ class FullO3CPU : public BaseO3CPU
|
||||||
|
|
||||||
TheISA::ISA isa[Impl::MaxThreads];
|
TheISA::ISA isa[Impl::MaxThreads];
|
||||||
|
|
||||||
|
/** Instruction port. Note that it has to appear after the fetch stage. */
|
||||||
|
IcachePort icachePort;
|
||||||
|
|
||||||
|
/** Data port. Note that it has to appear after the iew stages */
|
||||||
|
DcachePort dcachePort;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Enum to give each stage a specific index, so when calling
|
/** Enum to give each stage a specific index, so when calling
|
||||||
* activateStage() or deactivateStage(), they can specify which stage
|
* activateStage() or deactivateStage(), they can specify which stage
|
||||||
|
@ -701,8 +777,11 @@ class FullO3CPU : public BaseO3CPU
|
||||||
data, store_idx);
|
data, store_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Used by the fetch unit to get a hold of the instruction port. */
|
||||||
|
Port* getIcachePort() { return &icachePort; }
|
||||||
|
|
||||||
/** Get the dcache port (used to find block size for translations). */
|
/** Get the dcache port (used to find block size for translations). */
|
||||||
Port *getDcachePort() { return this->iew.ldstQueue.getDcachePort(); }
|
Port* getDcachePort() { return &dcachePort; }
|
||||||
|
|
||||||
Addr lockAddr;
|
Addr lockAddr;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010 ARM Limited
|
* Copyright (c) 2010-2011 ARM Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
*
|
*
|
||||||
* The license below extends only to copyright in the software and shall
|
* The license below extends only to copyright in the software and shall
|
||||||
|
@ -85,48 +85,6 @@ class DefaultFetch
|
||||||
typedef TheISA::MachInst MachInst;
|
typedef TheISA::MachInst MachInst;
|
||||||
typedef TheISA::ExtMachInst ExtMachInst;
|
typedef TheISA::ExtMachInst ExtMachInst;
|
||||||
|
|
||||||
/** IcachePort class for DefaultFetch. Handles doing the
|
|
||||||
* communication with the cache/memory.
|
|
||||||
*/
|
|
||||||
class IcachePort : public Port
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
/** Pointer to fetch. */
|
|
||||||
DefaultFetch<Impl> *fetch;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/** Default constructor. */
|
|
||||||
IcachePort(DefaultFetch<Impl> *_fetch)
|
|
||||||
: Port(_fetch->name() + "-iport", _fetch->cpu), fetch(_fetch)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
bool snoopRangeSent;
|
|
||||||
|
|
||||||
virtual void setPeer(Port *port);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/** Atomic version of receive. Panics. */
|
|
||||||
virtual Tick recvAtomic(PacketPtr pkt);
|
|
||||||
|
|
||||||
/** Functional version of receive. Panics. */
|
|
||||||
virtual void recvFunctional(PacketPtr pkt);
|
|
||||||
|
|
||||||
/** Receives status change. Other than range changing, panics. */
|
|
||||||
virtual void recvStatusChange(Status status);
|
|
||||||
|
|
||||||
/** Returns the address ranges of this device. */
|
|
||||||
virtual void getDeviceAddressRanges(AddrRangeList &resp,
|
|
||||||
bool &snoop)
|
|
||||||
{ resp.clear(); snoop = true; }
|
|
||||||
|
|
||||||
/** Timing version of receive. Handles setting fetch to the
|
|
||||||
* proper status to start fetching. */
|
|
||||||
virtual bool recvTiming(PacketPtr pkt);
|
|
||||||
|
|
||||||
/** Handles doing a retry of a failed fetch. */
|
|
||||||
virtual void recvRetry();
|
|
||||||
};
|
|
||||||
|
|
||||||
class FetchTranslation : public BaseTLB::Translation
|
class FetchTranslation : public BaseTLB::Translation
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -248,9 +206,6 @@ class DefaultFetch
|
||||||
/** Registers statistics. */
|
/** Registers statistics. */
|
||||||
void regStats();
|
void regStats();
|
||||||
|
|
||||||
/** Returns the icache port. */
|
|
||||||
Port *getIcachePort() { return icachePort; }
|
|
||||||
|
|
||||||
/** Sets the main backwards communication time buffer pointer. */
|
/** Sets the main backwards communication time buffer pointer. */
|
||||||
void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer);
|
void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer);
|
||||||
|
|
||||||
|
@ -266,6 +221,9 @@ class DefaultFetch
|
||||||
/** Tells the fetch stage that the Icache is set. */
|
/** Tells the fetch stage that the Icache is set. */
|
||||||
void setIcache();
|
void setIcache();
|
||||||
|
|
||||||
|
/** Handles retrying the fetch access. */
|
||||||
|
void recvRetry();
|
||||||
|
|
||||||
/** Processes cache completion event. */
|
/** Processes cache completion event. */
|
||||||
void processCacheCompletion(PacketPtr pkt);
|
void processCacheCompletion(PacketPtr pkt);
|
||||||
|
|
||||||
|
@ -389,9 +347,6 @@ class DefaultFetch
|
||||||
StaticInstPtr curMacroop, TheISA::PCState thisPC,
|
StaticInstPtr curMacroop, TheISA::PCState thisPC,
|
||||||
TheISA::PCState nextPC, bool trace);
|
TheISA::PCState nextPC, bool trace);
|
||||||
|
|
||||||
/** Handles retrying the fetch access. */
|
|
||||||
void recvRetry();
|
|
||||||
|
|
||||||
/** Returns the appropriate thread to fetch, given the fetch policy. */
|
/** Returns the appropriate thread to fetch, given the fetch policy. */
|
||||||
ThreadID getFetchingThread(FetchPriority &fetch_priority);
|
ThreadID getFetchingThread(FetchPriority &fetch_priority);
|
||||||
|
|
||||||
|
@ -440,9 +395,6 @@ class DefaultFetch
|
||||||
/** Wire used to write any information heading to decode. */
|
/** Wire used to write any information heading to decode. */
|
||||||
typename TimeBuffer<FetchStruct>::wire toDecode;
|
typename TimeBuffer<FetchStruct>::wire toDecode;
|
||||||
|
|
||||||
/** Icache interface. */
|
|
||||||
IcachePort *icachePort;
|
|
||||||
|
|
||||||
/** BPredUnit. */
|
/** BPredUnit. */
|
||||||
BPredUnit branchPred;
|
BPredUnit branchPred;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010 ARM Limited
|
* Copyright (c) 2010-2011 ARM Limited
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* The license below extends only to copyright in the software and shall
|
* The license below extends only to copyright in the software and shall
|
||||||
|
@ -68,68 +68,6 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void
|
|
||||||
DefaultFetch<Impl>::IcachePort::setPeer(Port *port)
|
|
||||||
{
|
|
||||||
Port::setPeer(port);
|
|
||||||
|
|
||||||
fetch->setIcache();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
Tick
|
|
||||||
DefaultFetch<Impl>::IcachePort::recvAtomic(PacketPtr pkt)
|
|
||||||
{
|
|
||||||
panic("DefaultFetch doesn't expect recvAtomic callback!");
|
|
||||||
return curTick();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void
|
|
||||||
DefaultFetch<Impl>::IcachePort::recvFunctional(PacketPtr pkt)
|
|
||||||
{
|
|
||||||
DPRINTF(Fetch, "DefaultFetch doesn't update its state from a "
|
|
||||||
"functional call.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void
|
|
||||||
DefaultFetch<Impl>::IcachePort::recvStatusChange(Status status)
|
|
||||||
{
|
|
||||||
if (status == RangeChange) {
|
|
||||||
if (!snoopRangeSent) {
|
|
||||||
snoopRangeSent = true;
|
|
||||||
sendStatusChange(Port::RangeChange);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
panic("DefaultFetch doesn't expect recvStatusChange callback!");
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
bool
|
|
||||||
DefaultFetch<Impl>::IcachePort::recvTiming(PacketPtr pkt)
|
|
||||||
{
|
|
||||||
DPRINTF(Fetch, "Received timing\n");
|
|
||||||
if (pkt->isResponse()) {
|
|
||||||
// We shouldn't ever get a block in ownership state
|
|
||||||
assert(!(pkt->memInhibitAsserted() && !pkt->sharedAsserted()));
|
|
||||||
|
|
||||||
fetch->processCacheCompletion(pkt);
|
|
||||||
}
|
|
||||||
//else Snooped a coherence request, just return
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void
|
|
||||||
DefaultFetch<Impl>::IcachePort::recvRetry()
|
|
||||||
{
|
|
||||||
fetch->recvRetry();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params)
|
DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params)
|
||||||
: cpu(_cpu),
|
: cpu(_cpu),
|
||||||
|
@ -189,17 +127,6 @@ DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params)
|
||||||
|
|
||||||
// Get the size of an instruction.
|
// Get the size of an instruction.
|
||||||
instSize = sizeof(TheISA::MachInst);
|
instSize = sizeof(TheISA::MachInst);
|
||||||
|
|
||||||
// Name is finally available, so create the port.
|
|
||||||
icachePort = new IcachePort(this);
|
|
||||||
|
|
||||||
icachePort->snoopRangeSent = false;
|
|
||||||
|
|
||||||
#if USE_CHECKER
|
|
||||||
if (cpu->checker) {
|
|
||||||
cpu->checker->setIcachePort(icachePort);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
|
@ -402,8 +329,10 @@ template<class Impl>
|
||||||
void
|
void
|
||||||
DefaultFetch<Impl>::setIcache()
|
DefaultFetch<Impl>::setIcache()
|
||||||
{
|
{
|
||||||
|
assert(cpu->getIcachePort()->isConnected());
|
||||||
|
|
||||||
// Size of cache block.
|
// Size of cache block.
|
||||||
cacheBlkSize = icachePort->peerBlockSize();
|
cacheBlkSize = cpu->getIcachePort()->peerBlockSize();
|
||||||
|
|
||||||
// Create mask to get rid of offset bits.
|
// Create mask to get rid of offset bits.
|
||||||
cacheBlkMask = (cacheBlkSize - 1);
|
cacheBlkMask = (cacheBlkSize - 1);
|
||||||
|
@ -494,6 +423,10 @@ template <class Impl>
|
||||||
void
|
void
|
||||||
DefaultFetch<Impl>::takeOverFrom()
|
DefaultFetch<Impl>::takeOverFrom()
|
||||||
{
|
{
|
||||||
|
// the instruction port is now connected so we can get the block
|
||||||
|
// size
|
||||||
|
setIcache();
|
||||||
|
|
||||||
// Reset all state
|
// Reset all state
|
||||||
for (ThreadID i = 0; i < Impl::MaxThreads; ++i) {
|
for (ThreadID i = 0; i < Impl::MaxThreads; ++i) {
|
||||||
stalls[i].decode = 0;
|
stalls[i].decode = 0;
|
||||||
|
@ -684,7 +617,7 @@ DefaultFetch<Impl>::finishTranslation(Fault fault, RequestPtr mem_req)
|
||||||
fetchedCacheLines++;
|
fetchedCacheLines++;
|
||||||
|
|
||||||
// Access the cache.
|
// Access the cache.
|
||||||
if (!icachePort->sendTiming(data_pkt)) {
|
if (!cpu->getIcachePort()->sendTiming(data_pkt)) {
|
||||||
assert(retryPkt == NULL);
|
assert(retryPkt == NULL);
|
||||||
assert(retryTid == InvalidThreadID);
|
assert(retryTid == InvalidThreadID);
|
||||||
DPRINTF(Fetch, "[tid:%i] Out of MSHRs!\n", tid);
|
DPRINTF(Fetch, "[tid:%i] Out of MSHRs!\n", tid);
|
||||||
|
@ -1403,7 +1336,7 @@ DefaultFetch<Impl>::recvRetry()
|
||||||
assert(retryTid != InvalidThreadID);
|
assert(retryTid != InvalidThreadID);
|
||||||
assert(fetchStatus[retryTid] == IcacheWaitRetry);
|
assert(fetchStatus[retryTid] == IcacheWaitRetry);
|
||||||
|
|
||||||
if (icachePort->sendTiming(retryPkt)) {
|
if (cpu->getIcachePort()->sendTiming(retryPkt)) {
|
||||||
fetchStatus[retryTid] = IcacheWaitResponse;
|
fetchStatus[retryTid] = IcacheWaitResponse;
|
||||||
retryPkt = NULL;
|
retryPkt = NULL;
|
||||||
retryTid = InvalidThreadID;
|
retryTid = InvalidThreadID;
|
||||||
|
|
|
@ -138,9 +138,6 @@ class DefaultIEW
|
||||||
/** Initializes stage; sends back the number of free IQ and LSQ entries. */
|
/** Initializes stage; sends back the number of free IQ and LSQ entries. */
|
||||||
void initStage();
|
void initStage();
|
||||||
|
|
||||||
/** Returns the dcache port. */
|
|
||||||
Port *getDcachePort() { return ldstQueue.getDcachePort(); }
|
|
||||||
|
|
||||||
/** Sets main time buffer used for backwards communication. */
|
/** Sets main time buffer used for backwards communication. */
|
||||||
void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
|
void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,16 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2011 ARM Limited
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* The license below extends only to copyright in the software and shall
|
||||||
|
* not be construed as granting a license to any other intellectual
|
||||||
|
* property including but not limited to intellectual property relating
|
||||||
|
* to a hardware implementation of the functionality of the software
|
||||||
|
* licensed hereunder. You may use the software subject to the license
|
||||||
|
* terms below provided that you ensure that this notice is replicated
|
||||||
|
* unmodified and in its entirety in all distributions of the software,
|
||||||
|
* modified or unmodified, in source code or in binary form.
|
||||||
|
*
|
||||||
* Copyright (c) 2004-2006 The Regents of The University of Michigan
|
* Copyright (c) 2004-2006 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -65,13 +77,6 @@ class LSQ {
|
||||||
/** Registers statistics of each LSQ unit. */
|
/** Registers statistics of each LSQ unit. */
|
||||||
void regStats();
|
void regStats();
|
||||||
|
|
||||||
/** Returns dcache port.
|
|
||||||
* @todo: Dcache port needs to be moved up to this level for SMT
|
|
||||||
* to work. For now it just returns the port from one of the
|
|
||||||
* threads.
|
|
||||||
*/
|
|
||||||
Port *getDcachePort() { return &dcachePort; }
|
|
||||||
|
|
||||||
/** Sets the pointer to the list of active threads. */
|
/** Sets the pointer to the list of active threads. */
|
||||||
void setActiveThreads(std::list<ThreadID> *at_ptr);
|
void setActiveThreads(std::list<ThreadID> *at_ptr);
|
||||||
/** Switches out the LSQ. */
|
/** Switches out the LSQ. */
|
||||||
|
@ -281,61 +286,25 @@ class LSQ {
|
||||||
Fault write(RequestPtr req, RequestPtr sreqLow, RequestPtr sreqHigh,
|
Fault write(RequestPtr req, RequestPtr sreqLow, RequestPtr sreqHigh,
|
||||||
uint8_t *data, int store_idx);
|
uint8_t *data, int store_idx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retry the previous send that failed.
|
||||||
|
*/
|
||||||
|
void recvRetry();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles writing back and completing the load or store that has
|
||||||
|
* returned from memory.
|
||||||
|
*
|
||||||
|
* @param pkt Response packet from the memory sub-system
|
||||||
|
*/
|
||||||
|
bool recvTiming(PacketPtr pkt);
|
||||||
|
|
||||||
/** The CPU pointer. */
|
/** The CPU pointer. */
|
||||||
O3CPU *cpu;
|
O3CPU *cpu;
|
||||||
|
|
||||||
/** The IEW stage pointer. */
|
/** The IEW stage pointer. */
|
||||||
IEW *iewStage;
|
IEW *iewStage;
|
||||||
|
|
||||||
/** DcachePort class for this LSQ. Handles doing the
|
|
||||||
* communication with the cache/memory.
|
|
||||||
*/
|
|
||||||
class DcachePort : public Port
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
/** Pointer to LSQ. */
|
|
||||||
LSQ *lsq;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/** Default constructor. */
|
|
||||||
DcachePort(LSQ *_lsq)
|
|
||||||
: Port(_lsq->name() + "-dport", _lsq->cpu), lsq(_lsq)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
bool snoopRangeSent;
|
|
||||||
|
|
||||||
virtual void setPeer(Port *port);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/** Atomic version of receive. Panics. */
|
|
||||||
virtual Tick recvAtomic(PacketPtr pkt);
|
|
||||||
|
|
||||||
/** Functional version of receive. Panics. */
|
|
||||||
virtual void recvFunctional(PacketPtr pkt);
|
|
||||||
|
|
||||||
/** Receives status change. Other than range changing, panics. */
|
|
||||||
virtual void recvStatusChange(Status status);
|
|
||||||
|
|
||||||
/** Returns the address ranges of this device. */
|
|
||||||
virtual void getDeviceAddressRanges(AddrRangeList &resp,
|
|
||||||
bool &snoop)
|
|
||||||
{ resp.clear(); snoop = true; }
|
|
||||||
|
|
||||||
/** Timing version of receive. Handles writing back and
|
|
||||||
* completing the load or store that has returned from
|
|
||||||
* memory. */
|
|
||||||
virtual bool recvTiming(PacketPtr pkt);
|
|
||||||
|
|
||||||
/** Handles doing a retry of the previous send. */
|
|
||||||
virtual void recvRetry();
|
|
||||||
};
|
|
||||||
|
|
||||||
/** D-cache port. */
|
|
||||||
DcachePort dcachePort;
|
|
||||||
|
|
||||||
/** Tell the CPU to update the Phys and Virt ports. */
|
|
||||||
void updateMemPorts() { cpu->updateMemPorts(); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** The LSQ policy for SMT mode. */
|
/** The LSQ policy for SMT mode. */
|
||||||
LSQPolicy lsqPolicy;
|
LSQPolicy lsqPolicy;
|
||||||
|
|
|
@ -1,4 +1,16 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2011 ARM Limited
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* The license below extends only to copyright in the software and shall
|
||||||
|
* not be construed as granting a license to any other intellectual
|
||||||
|
* property including but not limited to intellectual property relating
|
||||||
|
* to a hardware implementation of the functionality of the software
|
||||||
|
* licensed hereunder. You may use the software subject to the license
|
||||||
|
* terms below provided that you ensure that this notice is replicated
|
||||||
|
* unmodified and in its entirety in all distributions of the software,
|
||||||
|
* modified or unmodified, in source code or in binary form.
|
||||||
|
*
|
||||||
* Copyright (c) 2005-2006 The Regents of The University of Michigan
|
* Copyright (c) 2005-2006 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -40,96 +52,14 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void
|
|
||||||
LSQ<Impl>::DcachePort::setPeer(Port *port)
|
|
||||||
{
|
|
||||||
Port::setPeer(port);
|
|
||||||
|
|
||||||
// Update the ThreadContext's memory ports (Functional/Virtual
|
|
||||||
// Ports)
|
|
||||||
lsq->updateMemPorts();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Impl>
|
|
||||||
Tick
|
|
||||||
LSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
|
|
||||||
{
|
|
||||||
panic("O3CPU model does not work with atomic mode!");
|
|
||||||
return curTick();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Impl>
|
|
||||||
void
|
|
||||||
LSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt)
|
|
||||||
{
|
|
||||||
DPRINTF(LSQ, "LSQ doesn't update things on a recvFunctional.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Impl>
|
|
||||||
void
|
|
||||||
LSQ<Impl>::DcachePort::recvStatusChange(Status status)
|
|
||||||
{
|
|
||||||
if (status == RangeChange) {
|
|
||||||
if (!snoopRangeSent) {
|
|
||||||
snoopRangeSent = true;
|
|
||||||
sendStatusChange(Port::RangeChange);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
panic("O3CPU doesn't expect recvStatusChange callback!");
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Impl>
|
|
||||||
bool
|
|
||||||
LSQ<Impl>::DcachePort::recvTiming(PacketPtr pkt)
|
|
||||||
{
|
|
||||||
if (pkt->isError())
|
|
||||||
DPRINTF(LSQ, "Got error packet back for address: %#X\n", pkt->getAddr());
|
|
||||||
if (pkt->isResponse()) {
|
|
||||||
lsq->thread[pkt->req->threadId()].completeDataAccess(pkt);
|
|
||||||
} else {
|
|
||||||
DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(),
|
|
||||||
pkt->cmdString());
|
|
||||||
|
|
||||||
// must be a snoop
|
|
||||||
if (pkt->isInvalidate()) {
|
|
||||||
DPRINTF(LSQ, "received invalidation for addr:%#x\n", pkt->getAddr());
|
|
||||||
for (ThreadID tid = 0; tid < lsq->numThreads; tid++) {
|
|
||||||
lsq->thread[tid].checkSnoop(pkt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// to provide stronger consistency model
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Impl>
|
|
||||||
void
|
|
||||||
LSQ<Impl>::DcachePort::recvRetry()
|
|
||||||
{
|
|
||||||
if (lsq->retryTid == -1)
|
|
||||||
{
|
|
||||||
//Squashed, so drop it
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int curr_retry_tid = lsq->retryTid;
|
|
||||||
// Speculatively clear the retry Tid. This will get set again if
|
|
||||||
// the LSQUnit was unable to complete its access.
|
|
||||||
lsq->retryTid = -1;
|
|
||||||
lsq->thread[curr_retry_tid].recvRetry();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
|
LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
|
||||||
: cpu(cpu_ptr), iewStage(iew_ptr), dcachePort(this),
|
: cpu(cpu_ptr), iewStage(iew_ptr),
|
||||||
LQEntries(params->LQEntries),
|
LQEntries(params->LQEntries),
|
||||||
SQEntries(params->SQEntries),
|
SQEntries(params->SQEntries),
|
||||||
numThreads(params->numThreads),
|
numThreads(params->numThreads),
|
||||||
retryTid(-1)
|
retryTid(-1)
|
||||||
{
|
{
|
||||||
dcachePort.snoopRangeSent = false;
|
|
||||||
|
|
||||||
//**********************************************/
|
//**********************************************/
|
||||||
//************ Handle SMT Parameters ***********/
|
//************ Handle SMT Parameters ***********/
|
||||||
//**********************************************/
|
//**********************************************/
|
||||||
|
@ -181,7 +111,7 @@ LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
|
||||||
for (ThreadID tid = 0; tid < numThreads; tid++) {
|
for (ThreadID tid = 0; tid < numThreads; tid++) {
|
||||||
thread[tid].init(cpu, iew_ptr, params, this,
|
thread[tid].init(cpu, iew_ptr, params, this,
|
||||||
maxLQEntries, maxSQEntries, tid);
|
maxLQEntries, maxSQEntries, tid);
|
||||||
thread[tid].setDcachePort(&dcachePort);
|
thread[tid].setDcachePort(cpu_ptr->getDcachePort());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,6 +301,48 @@ LSQ<Impl>::violation()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class Impl>
|
||||||
|
void
|
||||||
|
LSQ<Impl>::recvRetry()
|
||||||
|
{
|
||||||
|
if (retryTid == InvalidThreadID)
|
||||||
|
{
|
||||||
|
//Squashed, so drop it
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int curr_retry_tid = retryTid;
|
||||||
|
// Speculatively clear the retry Tid. This will get set again if
|
||||||
|
// the LSQUnit was unable to complete its access.
|
||||||
|
retryTid = -1;
|
||||||
|
thread[curr_retry_tid].recvRetry();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Impl>
|
||||||
|
bool
|
||||||
|
LSQ<Impl>::recvTiming(PacketPtr pkt)
|
||||||
|
{
|
||||||
|
if (pkt->isError())
|
||||||
|
DPRINTF(LSQ, "Got error packet back for address: %#X\n",
|
||||||
|
pkt->getAddr());
|
||||||
|
if (pkt->isResponse()) {
|
||||||
|
thread[pkt->req->threadId()].completeDataAccess(pkt);
|
||||||
|
} else {
|
||||||
|
DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(),
|
||||||
|
pkt->cmdString());
|
||||||
|
|
||||||
|
// must be a snoop
|
||||||
|
if (pkt->isInvalidate()) {
|
||||||
|
DPRINTF(LSQ, "received invalidation for addr:%#x\n",
|
||||||
|
pkt->getAddr());
|
||||||
|
for (ThreadID tid = 0; tid < numThreads; tid++) {
|
||||||
|
thread[tid].checkSnoop(pkt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// to provide stronger consistency model
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
int
|
int
|
||||||
LSQ<Impl>::getCount()
|
LSQ<Impl>::getCount()
|
||||||
|
|
|
@ -96,17 +96,18 @@ class O3ThreadContext : public ThreadContext
|
||||||
virtual TheISA::Kernel::Statistics *getKernelStats()
|
virtual TheISA::Kernel::Statistics *getKernelStats()
|
||||||
{ return thread->kernelStats; }
|
{ return thread->kernelStats; }
|
||||||
|
|
||||||
virtual void connectMemPorts(ThreadContext *tc)
|
|
||||||
{ thread->connectMemPorts(tc); }
|
|
||||||
|
|
||||||
/** Returns a pointer to this thread's process. */
|
/** Returns a pointer to this thread's process. */
|
||||||
virtual Process *getProcessPtr() { return thread->getProcessPtr(); }
|
virtual Process *getProcessPtr() { return thread->getProcessPtr(); }
|
||||||
|
|
||||||
virtual TranslatingPort *getMemPort() { return thread->getMemPort(); }
|
virtual PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
|
||||||
|
|
||||||
virtual VirtualPort *getVirtPort();
|
virtual FSTranslatingPortProxy* getVirtProxy();
|
||||||
|
|
||||||
virtual FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
|
virtual void initMemProxies(ThreadContext *tc)
|
||||||
|
{ thread->initMemProxies(tc); }
|
||||||
|
|
||||||
|
virtual SETranslatingPortProxy* getMemProxy()
|
||||||
|
{ return thread->getMemProxy(); }
|
||||||
|
|
||||||
/** Returns this thread's status. */
|
/** Returns this thread's status. */
|
||||||
virtual Status status() const { return thread->status(); }
|
virtual Status status() const { return thread->status(); }
|
||||||
|
|
|
@ -49,10 +49,10 @@
|
||||||
#include "debug/O3CPU.hh"
|
#include "debug/O3CPU.hh"
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
VirtualPort *
|
FSTranslatingPortProxy*
|
||||||
O3ThreadContext<Impl>::getVirtPort()
|
O3ThreadContext<Impl>::getVirtProxy()
|
||||||
{
|
{
|
||||||
return thread->getVirtPort();
|
return thread->getVirtProxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
|
|
|
@ -114,12 +114,12 @@ class OzoneCPU : public BaseCPU
|
||||||
|
|
||||||
Process *getProcessPtr() { return thread->getProcessPtr(); }
|
Process *getProcessPtr() { return thread->getProcessPtr(); }
|
||||||
|
|
||||||
TranslatingPort *getMemPort() { return thread->getMemPort(); }
|
PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
|
||||||
|
|
||||||
VirtualPort *getVirtPort()
|
FSTranslatingPortProxy* getVirtProxy()
|
||||||
{ return thread->getVirtPort(); }
|
{ return thread->getVirtProxy(); }
|
||||||
|
|
||||||
FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
|
SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); }
|
||||||
|
|
||||||
Status status() const { return thread->status(); }
|
Status status() const { return thread->status(); }
|
||||||
|
|
||||||
|
|
|
@ -186,25 +186,7 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
|
||||||
frontEnd->renameTable.copyFrom(thread.renameTable);
|
frontEnd->renameTable.copyFrom(thread.renameTable);
|
||||||
backEnd->renameTable.copyFrom(thread.renameTable);
|
backEnd->renameTable.copyFrom(thread.renameTable);
|
||||||
|
|
||||||
if (FullSystem) {
|
thread.connectMemPorts(tc);
|
||||||
Port *mem_port;
|
|
||||||
FunctionalPort *phys_port;
|
|
||||||
VirtualPort *virt_port;
|
|
||||||
phys_port = new FunctionalPort(csprintf("%s-%d-funcport",
|
|
||||||
name(), 0));
|
|
||||||
mem_port = system->physmem->getPort("functional");
|
|
||||||
mem_port->setPeer(phys_port);
|
|
||||||
phys_port->setPeer(mem_port);
|
|
||||||
|
|
||||||
virt_port = new VirtualPort(csprintf("%s-%d-vport",
|
|
||||||
name(), 0));
|
|
||||||
mem_port = system->physmem->getPort("functional");
|
|
||||||
mem_port->setPeer(virt_port);
|
|
||||||
virt_port->setPeer(mem_port);
|
|
||||||
|
|
||||||
thread.setPhysPort(phys_port);
|
|
||||||
thread.setVirtPort(virt_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINTF(OzoneCPU, "OzoneCPU: Created Ozone cpu object.\n");
|
DPRINTF(OzoneCPU, "OzoneCPU: Created Ozone cpu object.\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,13 +87,8 @@ class FrontEnd
|
||||||
/** Functional version of receive. Panics. */
|
/** Functional version of receive. Panics. */
|
||||||
virtual void recvFunctional(PacketPtr pkt);
|
virtual void recvFunctional(PacketPtr pkt);
|
||||||
|
|
||||||
/** Receives status change. Other than range changing, panics. */
|
/** Receives range change. */
|
||||||
virtual void recvStatusChange(Status status);
|
virtual void recvRangeChange();
|
||||||
|
|
||||||
/** Returns the address ranges of this device. */
|
|
||||||
virtual void getDeviceAddressRanges(AddrRangeList &resp,
|
|
||||||
bool &snoop)
|
|
||||||
{ resp.clear(); snoop = true; }
|
|
||||||
|
|
||||||
/** Timing version of receive. Handles setting fetch to the
|
/** Timing version of receive. Handles setting fetch to the
|
||||||
* proper status to start fetching. */
|
* proper status to start fetching. */
|
||||||
|
|
|
@ -64,12 +64,8 @@ FrontEnd<Impl>::IcachePort::recvFunctional(PacketPtr pkt)
|
||||||
|
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
void
|
void
|
||||||
FrontEnd<Impl>::IcachePort::recvStatusChange(Status status)
|
FrontEnd<Impl>::IcachePort::recvRangeChange()
|
||||||
{
|
{
|
||||||
if (status == RangeChange)
|
|
||||||
return;
|
|
||||||
|
|
||||||
panic("FrontEnd doesn't expect recvStatusChange callback!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
|
|
|
@ -255,11 +255,13 @@ class OzoneLWLSQ {
|
||||||
|
|
||||||
virtual void recvFunctional(PacketPtr pkt);
|
virtual void recvFunctional(PacketPtr pkt);
|
||||||
|
|
||||||
virtual void recvStatusChange(Status status);
|
virtual void recvRangeChange();
|
||||||
|
|
||||||
virtual void getDeviceAddressRanges(AddrRangeList &resp,
|
/**
|
||||||
bool &snoop)
|
* Is a snooper due to LSQ maintenance
|
||||||
{ resp.clear(); snoop = true; }
|
*/
|
||||||
|
virtual bool isSnooping()
|
||||||
|
{ return true; }
|
||||||
|
|
||||||
virtual bool recvTiming(PacketPtr pkt);
|
virtual bool recvTiming(PacketPtr pkt);
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue