summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2012-02-13 06:43:09 -0500
committerAndreas Hansson <andreas.hansson@arm.com>2012-02-13 06:43:09 -0500
commit5a9a743cfc4517f93e5c94533efa767b92272c59 (patch)
treef3dbc078a51e5759b26b1a5f16263ddb1cf55a7b /src
parent8cb4a2208d568eb86ad3f6c6bb250bcbe2952302 (diff)
downloadgem5-5a9a743cfc4517f93e5c94533efa767b92272c59.tar.xz
MEM: Introduce the master/slave port roles in the Python classes
This patch classifies all ports in Python as either Master or Slave and enforces a binding of master to slave. Conceptually, a master (such as a CPU or DMA port) issues requests, and receives responses, and conversely, a slave (such as a memory or a PIO device) receives requests and sends back responses. Currently there is no differentiation between coherent and non-coherent masters and slaves. The classification as master/slave also involves splitting the dual role port of the bus into a master and slave port and updating all the system assembly scripts to use the appropriate port. Similarly, the interrupt devices have to have their int_port split into a master and slave port. The intdev and its children have minimal changes to facilitate the extra port. Note that this patch does not enforce any port typing in the C++ world, it merely ensures that the Python objects have a notion of the port roles and are connected in an appropriate manner. This check is carried when two ports are connected, e.g. bus.master = memory.port. The following patches will make use of the classifications and specialise the C++ ports into masters and slaves.
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm/ArmTLB.py2
-rw-r--r--src/arch/x86/X86LocalApic.py15
-rw-r--r--src/arch/x86/X86TLB.py2
-rw-r--r--src/arch/x86/interrupts.hh22
-rw-r--r--src/cpu/BaseCPU.py33
-rw-r--r--src/cpu/simple/AtomicSimpleCPU.py2
-rw-r--r--src/cpu/testers/directedtest/RubyDirectedTester.py2
-rw-r--r--src/cpu/testers/memtest/MemTest.py5
-rw-r--r--src/cpu/testers/networktest/NetworkTest.py2
-rw-r--r--src/cpu/testers/rubytest/RubyTester.py2
-rw-r--r--src/dev/Device.py4
-rw-r--r--src/dev/Ethernet.py6
-rw-r--r--src/dev/Pci.py2
-rw-r--r--src/dev/alpha/Tsunami.py50
-rw-r--r--src/dev/arm/RealView.py194
-rw-r--r--src/dev/x86/I82094AA.py2
-rw-r--r--src/dev/x86/Pc.py14
-rw-r--r--src/dev/x86/SouthBridge.py24
-rw-r--r--src/dev/x86/i82094aa.hh2
-rw-r--r--src/dev/x86/intdev.hh2
-rw-r--r--src/mem/Bridge.py4
-rw-r--r--src/mem/Bus.py7
-rw-r--r--src/mem/PhysicalMemory.py2
-rw-r--r--src/mem/cache/BaseCache.py4
-rw-r--r--src/mem/ruby/system/RubyPort.cc15
-rw-r--r--src/mem/ruby/system/Sequencer.py7
-rw-r--r--src/python/m5/SimObject.py2
-rw-r--r--src/python/m5/params.py92
-rw-r--r--src/sim/System.py2
29 files changed, 321 insertions, 201 deletions
diff --git a/src/arch/arm/ArmTLB.py b/src/arch/arm/ArmTLB.py
index fc6f51d84..8599fa75f 100644
--- a/src/arch/arm/ArmTLB.py
+++ b/src/arch/arm/ArmTLB.py
@@ -45,7 +45,7 @@ from MemObject import MemObject
class ArmTableWalker(MemObject):
type = 'ArmTableWalker'
cxx_class = 'ArmISA::TableWalker'
- port = Port("Port for TableWalker to do walk the translation with")
+ port = MasterPort("Port for TableWalker to do walk the translation with")
sys = Param.System(Parent.any, "system object parameter")
min_backoff = Param.Tick(0, "Minimum backoff delay after failed send")
max_backoff = Param.Tick(100000, "Minimum backoff delay after failed send")
diff --git a/src/arch/x86/X86LocalApic.py b/src/arch/x86/X86LocalApic.py
index 2f53c4e24..283d94ba7 100644
--- a/src/arch/x86/X86LocalApic.py
+++ b/src/arch/x86/X86LocalApic.py
@@ -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) 2008 The Regents of The University of Michigan
# All rights reserved.
#
@@ -35,6 +47,7 @@ class X86LocalApic(BasicPioDevice):
type = 'X86LocalApic'
cxx_class = 'X86ISA::Interrupts'
pio_latency = Param.Latency('1ns', 'Programmed IO latency in simticks')
- int_port = Port("Port for sending and receiving interrupt messages")
+ int_master = MasterPort("Port for sending interrupt messages")
+ int_slave = SlavePort("Port for receiving interrupt messages")
int_latency = Param.Latency('1ns', \
"Latency for an interrupt to propagate through this device.")
diff --git a/src/arch/x86/X86TLB.py b/src/arch/x86/X86TLB.py
index 7f2fcd358..334d2a0cf 100644
--- a/src/arch/x86/X86TLB.py
+++ b/src/arch/x86/X86TLB.py
@@ -44,7 +44,7 @@ from MemObject import MemObject
class X86PagetableWalker(MemObject):
type = 'X86PagetableWalker'
cxx_class = 'X86ISA::Walker'
- port = Port("Port for the hardware table walker")
+ port = MasterPort("Port for the hardware table walker")
system = Param.System(Parent.any, "system object")
class X86TLB(BaseTLB):
diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh
index 8567b30f0..13ad2069b 100644
--- a/src/arch/x86/interrupts.hh
+++ b/src/arch/x86/interrupts.hh
@@ -1,4 +1,16 @@
/*
+ * 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) 2007 The Hewlett-Packard Development Company
* All rights reserved.
*
@@ -35,6 +47,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
+ * Andreas Hansson
*/
#ifndef __ARCH_X86_INTERRUPTS_HH__
@@ -225,8 +238,15 @@ class Interrupts : public BasicPioDevice, IntDev
Port *getPort(const std::string &if_name, int idx = -1)
{
- if (if_name == "int_port")
+ // a bit of an odd one since there is now two ports in the
+ // Python class we also need two ports even if they are
+ // identical
+ if (if_name == "int_master") {
return intPort;
+ } else if (if_name == "int_slave") {
+ // memory leak...but will be removed in the next patch
+ return new IntPort(name() + ".int_slave", this, this, latency);
+ }
return BasicPioDevice::getPort(if_name, idx);
}
diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py
index fda0a3bc8..0bb2090ad 100644
--- a/src/cpu/BaseCPU.py
+++ b/src/cpu/BaseCPU.py
@@ -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) 2005-2008 The Regents of The University of Michigan
# Copyright (c) 2011 Regents of the University of California
# All rights reserved.
@@ -27,6 +39,7 @@
#
# Authors: Nathan Binkert
# Rick Strong
+# Andreas Hansson
import sys
@@ -138,24 +151,28 @@ class BaseCPU(MemObject):
tracer = Param.InstTracer(default_tracer, "Instruction tracer")
- icache_port = Port("Instruction Port")
- dcache_port = Port("Data Port")
+ icache_port = MasterPort("Instruction Port")
+ dcache_port = MasterPort("Data Port")
_cached_ports = ['icache_port', 'dcache_port']
if buildEnv['TARGET_ISA'] in ['x86', 'arm']:
_cached_ports += ["itb.walker.port", "dtb.walker.port"]
- _uncached_ports = []
+ _uncached_slave_ports = []
+ _uncached_master_ports = []
if buildEnv['TARGET_ISA'] == 'x86':
- _uncached_ports = ["interrupts.pio", "interrupts.int_port"]
+ _uncached_slave_ports += ["interrupts.pio", "interrupts.int_slave"]
+ _uncached_master_ports += ["interrupts.int_master"]
def connectCachedPorts(self, bus):
for p in self._cached_ports:
- exec('self.%s = bus.port' % p)
+ exec('self.%s = bus.slave' % p)
def connectUncachedPorts(self, bus):
- for p in self._uncached_ports:
- exec('self.%s = bus.port' % p)
+ for p in self._uncached_slave_ports:
+ exec('self.%s = bus.master' % p)
+ for p in self._uncached_master_ports:
+ exec('self.%s = bus.slave' % p)
def connectAllPorts(self, cached_bus, uncached_bus = None):
self.connectCachedPorts(cached_bus)
@@ -190,5 +207,5 @@ class BaseCPU(MemObject):
self.toL2Bus = Bus()
self.connectCachedPorts(self.toL2Bus)
self.l2cache = l2c
- self.l2cache.cpu_side = self.toL2Bus.port
+ self.toL2Bus.master = self.l2cache.cpu_side
self._cached_ports = ['l2cache.mem_side']
diff --git a/src/cpu/simple/AtomicSimpleCPU.py b/src/cpu/simple/AtomicSimpleCPU.py
index 93cd02ba7..1199f35e1 100644
--- a/src/cpu/simple/AtomicSimpleCPU.py
+++ b/src/cpu/simple/AtomicSimpleCPU.py
@@ -34,4 +34,4 @@ class AtomicSimpleCPU(BaseSimpleCPU):
width = Param.Int(1, "CPU width")
simulate_data_stalls = Param.Bool(False, "Simulate dcache stall cycles")
simulate_inst_stalls = Param.Bool(False, "Simulate icache stall cycles")
- physmem_port = Port("Physical Memory Port")
+ physmem_port = MasterPort("Physical Memory Port")
diff --git a/src/cpu/testers/directedtest/RubyDirectedTester.py b/src/cpu/testers/directedtest/RubyDirectedTester.py
index ccadc5b36..bf3eace08 100644
--- a/src/cpu/testers/directedtest/RubyDirectedTester.py
+++ b/src/cpu/testers/directedtest/RubyDirectedTester.py
@@ -48,6 +48,6 @@ class InvalidateGenerator(DirectedGenerator):
class RubyDirectedTester(MemObject):
type = 'RubyDirectedTester'
- cpuPort = VectorPort("the cpu ports")
+ cpuPort = VectorMasterPort("the cpu ports")
requests_to_complete = Param.Int("checks to complete")
generator = Param.DirectedGenerator("the request generator")
diff --git a/src/cpu/testers/memtest/MemTest.py b/src/cpu/testers/memtest/MemTest.py
index 6a3568379..1b4d6767c 100644
--- a/src/cpu/testers/memtest/MemTest.py
+++ b/src/cpu/testers/memtest/MemTest.py
@@ -48,8 +48,9 @@ class MemTest(MemObject):
"progress report interval (in accesses)")
trace_addr = Param.Addr(0, "address to trace")
- test = Port("Port to the memory system to test")
- functional = Port("Port to the functional memory used for verification")
+ test = MasterPort("Port to the memory system to test")
+ functional = MasterPort("Port to the functional memory " \
+ "used for verification")
suppress_func_warnings = Param.Bool(False,
"suppress warnings when functional accesses fail.\n")
sys = Param.System(Parent.any, "System Parameter")
diff --git a/src/cpu/testers/networktest/NetworkTest.py b/src/cpu/testers/networktest/NetworkTest.py
index b2eda9aa2..7d6ed576b 100644
--- a/src/cpu/testers/networktest/NetworkTest.py
+++ b/src/cpu/testers/networktest/NetworkTest.py
@@ -41,5 +41,5 @@ class NetworkTest(MemObject):
traffic_type = Param.Counter(0, "Traffic type: uniform random, tornado, bit complement")
inj_rate = Param.Float(0.1, "Packet injection rate")
precision = Param.Int(3, "Number of digits of precision after decimal point")
- test = Port("Port to the memory system to test")
+ test = MasterPort("Port to the memory system to test")
system = Param.System(Parent.any, "System we belong to")
diff --git a/src/cpu/testers/rubytest/RubyTester.py b/src/cpu/testers/rubytest/RubyTester.py
index fc0a60e11..6518862e9 100644
--- a/src/cpu/testers/rubytest/RubyTester.py
+++ b/src/cpu/testers/rubytest/RubyTester.py
@@ -32,7 +32,7 @@ from m5.proxy import *
class RubyTester(MemObject):
type = 'RubyTester'
- cpuPort = VectorPort("the cpu ports")
+ cpuPort = VectorMasterPort("the cpu ports")
checks_to_complete = Param.Int(100, "checks to complete")
deadlock_threshold = Param.Int(50000, "how often to check for deadlock")
wakeup_frequency = Param.Int(10, "number of cycles between wakeups")
diff --git a/src/dev/Device.py b/src/dev/Device.py
index c32946277..96c95ebc9 100644
--- a/src/dev/Device.py
+++ b/src/dev/Device.py
@@ -33,7 +33,7 @@ from MemObject import MemObject
class PioDevice(MemObject):
type = 'PioDevice'
abstract = True
- pio = Port("Programmed I/O port")
+ pio = SlavePort("Programmed I/O port")
system = Param.System(Parent.any, "System this device is part of")
class BasicPioDevice(PioDevice):
@@ -45,7 +45,7 @@ class BasicPioDevice(PioDevice):
class DmaDevice(PioDevice):
type = 'DmaDevice'
abstract = True
- dma = Port("DMA port")
+ dma = MasterPort("DMA port")
min_backoff_delay = Param.Latency('4ns',
"min time between a nack packet being received and the next request made by the device")
max_backoff_delay = Param.Latency('10us',
diff --git a/src/dev/Ethernet.py b/src/dev/Ethernet.py
index 539e4ea9b..91d4e230e 100644
--- a/src/dev/Ethernet.py
+++ b/src/dev/Ethernet.py
@@ -37,8 +37,8 @@ class EtherObject(SimObject):
class EtherLink(EtherObject):
type = 'EtherLink'
- int0 = Port("interface 0")
- int1 = Port("interface 1")
+ int0 = SlavePort("interface 0")
+ int1 = SlavePort("interface 1")
delay = Param.Latency('0us', "packet transmit delay")
delay_var = Param.Latency('0ns', "packet transmit delay variability")
speed = Param.NetworkBandwidth('1Gbps', "link speed")
@@ -64,7 +64,7 @@ class EtherDump(SimObject):
class EtherDevice(PciDevice):
type = 'EtherDevice'
abstract = True
- interface = Port("Ethernet Interface")
+ interface = MasterPort("Ethernet Interface")
class IGbE(EtherDevice):
# Base class for two IGbE adapters listed above
diff --git a/src/dev/Pci.py b/src/dev/Pci.py
index 95cb3916f..c866f9386 100644
--- a/src/dev/Pci.py
+++ b/src/dev/Pci.py
@@ -43,7 +43,7 @@ class PciDevice(DmaDevice):
type = 'PciDevice'
abstract = True
platform = Param.Platform(Parent.any, "Platform this device is part of.")
- config = Port("PCI configuration space port")
+ config = SlavePort("PCI configuration space port")
pci_bus = Param.Int("PCI bus")
pci_dev = Param.Int("PCI device number")
pci_func = Param.Int("PCI function code")
diff --git a/src/dev/alpha/Tsunami.py b/src/dev/alpha/Tsunami.py
index e6a899604..9a3ec0593 100644
--- a/src/dev/alpha/Tsunami.py
+++ b/src/dev/alpha/Tsunami.py
@@ -93,30 +93,30 @@ class Tsunami(Platform):
# earlier, since the bus object itself is typically defined at the
# System level.
def attachIO(self, bus):
- self.cchip.pio = bus.port
- self.pchip.pio = bus.port
+ self.cchip.pio = bus.master
+ self.pchip.pio = bus.master
self.pciconfig.pio = bus.default
bus.use_default_range = True
- self.fake_sm_chip.pio = bus.port
- self.fake_uart1.pio = bus.port
- self.fake_uart2.pio = bus.port
- self.fake_uart3.pio = bus.port
- self.fake_uart4.pio = bus.port
- self.fake_ppc.pio = bus.port
- self.fake_OROM.pio = bus.port
- self.fake_pnp_addr.pio = bus.port
- self.fake_pnp_write.pio = bus.port
- self.fake_pnp_read0.pio = bus.port
- self.fake_pnp_read1.pio = bus.port
- self.fake_pnp_read2.pio = bus.port
- self.fake_pnp_read3.pio = bus.port
- self.fake_pnp_read4.pio = bus.port
- self.fake_pnp_read5.pio = bus.port
- self.fake_pnp_read6.pio = bus.port
- self.fake_pnp_read7.pio = bus.port
- self.fake_ata0.pio = bus.port
- self.fake_ata1.pio = bus.port
- self.fb.pio = bus.port
- self.io.pio = bus.port
- self.uart.pio = bus.port
- self.backdoor.pio = bus.port
+ self.fake_sm_chip.pio = bus.master
+ self.fake_uart1.pio = bus.master
+ self.fake_uart2.pio = bus.master
+ self.fake_uart3.pio = bus.master
+ self.fake_uart4.pio = bus.master
+ self.fake_ppc.pio = bus.master
+ self.fake_OROM.pio = bus.master
+ self.fake_pnp_addr.pio = bus.master
+ self.fake_pnp_write.pio = bus.master
+ self.fake_pnp_read0.pio = bus.master
+ self.fake_pnp_read1.pio = bus.master
+ self.fake_pnp_read2.pio = bus.master
+ self.fake_pnp_read3.pio = bus.master
+ self.fake_pnp_read4.pio = bus.master
+ self.fake_pnp_read5.pio = bus.master
+ self.fake_pnp_read6.pio = bus.master
+ self.fake_pnp_read7.pio = bus.master
+ self.fake_ata0.pio = bus.master
+ self.fake_ata1.pio = bus.master
+ self.fb.pio = bus.master
+ self.io.pio = bus.master
+ self.uart.pio = bus.master
+ self.backdoor.pio = bus.master
diff --git a/src/dev/arm/RealView.py b/src/dev/arm/RealView.py
index 3da47399e..e42bc4b94 100644
--- a/src/dev/arm/RealView.py
+++ b/src/dev/arm/RealView.py
@@ -181,10 +181,10 @@ class RealViewPBX(RealView):
# Attach I/O devices that are on chip and also set the appropriate
# ranges for the bridge
def attachOnChipIO(self, bus, bridge):
- self.gic.pio = bus.port
- self.l2x0_fake.pio = bus.port
- self.a9scu.pio = bus.port
- self.local_cpu_timer.pio = bus.port
+ self.gic.pio = bus.master
+ self.l2x0_fake.pio = bus.master
+ self.a9scu.pio = bus.master
+ self.local_cpu_timer.pio = bus.master
# Bridge ranges based on excluding what is part of on-chip I/O
# (gic, l2x0, a9scu, local_cpu_timer)
bridge.ranges = [AddrRange(self.realview_io.pio_addr,
@@ -195,33 +195,33 @@ class RealViewPBX(RealView):
# earlier, since the bus object itself is typically defined at the
# System level.
def attachIO(self, bus):
- self.uart.pio = bus.port
- self.realview_io.pio = bus.port
- self.timer0.pio = bus.port
- self.timer1.pio = bus.port
- self.clcd.pio = bus.port
- self.clcd.dma = bus.port
- self.kmi0.pio = bus.port
- self.kmi1.pio = bus.port
- self.cf_ctrl.pio = bus.port
- self.cf_ctrl.config = bus.port
- self.cf_ctrl.dma = bus.port
- self.dmac_fake.pio = bus.port
- self.uart1_fake.pio = bus.port
- self.uart2_fake.pio = bus.port
- self.uart3_fake.pio = bus.port
- self.smc_fake.pio = bus.port
- self.sp810_fake.pio = bus.port
- self.watchdog_fake.pio = bus.port
- self.gpio0_fake.pio = bus.port
- self.gpio1_fake.pio = bus.port
- self.gpio2_fake.pio = bus.port
- self.ssp_fake.pio = bus.port
- self.sci_fake.pio = bus.port
- self.aaci_fake.pio = bus.port
- self.mmc_fake.pio = bus.port
- self.rtc_fake.pio = bus.port
- self.flash_fake.pio = bus.port
+ self.uart.pio = bus.master
+ self.realview_io.pio = bus.master
+ self.timer0.pio = bus.master
+ self.timer1.pio = bus.master
+ self.clcd.pio = bus.master
+ self.clcd.dma = bus.slave
+ self.kmi0.pio = bus.master
+ self.kmi1.pio = bus.master
+ self.cf_ctrl.pio = bus.master
+ self.cf_ctrl.config = bus.master
+ self.cf_ctrl.dma = bus.slave
+ self.dmac_fake.pio = bus.master
+ self.uart1_fake.pio = bus.master
+ self.uart2_fake.pio = bus.master
+ self.uart3_fake.pio = bus.master
+ self.smc_fake.pio = bus.master
+ self.sp810_fake.pio = bus.master
+ self.watchdog_fake.pio = bus.master
+ self.gpio0_fake.pio = bus.master
+ self.gpio1_fake.pio = bus.master
+ self.gpio2_fake.pio = bus.master
+ self.ssp_fake.pio = bus.master
+ self.sci_fake.pio = bus.master
+ self.aaci_fake.pio = bus.master
+ self.mmc_fake.pio = bus.master
+ self.rtc_fake.pio = bus.master
+ self.flash_fake.pio = bus.master
# Reference for memory map and interrupt number
# RealView Emulation Baseboard User Guide (ARM DUI 0143B)
@@ -261,8 +261,8 @@ class RealViewEB(RealView):
# Attach I/O devices that are on chip and also set the appropriate
# ranges for the bridge
def attachOnChipIO(self, bus, bridge):
- self.gic.pio = bus.port
- self.l2x0_fake.pio = bus.port
+ self.gic.pio = bus.master
+ self.l2x0_fake.pio = bus.master
# Bridge ranges based on excluding what is part of on-chip I/O
# (gic, l2x0)
bridge.ranges = [AddrRange(self.realview_io.pio_addr,
@@ -273,31 +273,31 @@ class RealViewEB(RealView):
# earlier, since the bus object itself is typically defined at the
# System level.
def attachIO(self, bus):
- self.uart.pio = bus.port
- self.realview_io.pio = bus.port
- self.timer0.pio = bus.port
- self.timer1.pio = bus.port
- self.clcd.pio = bus.port
- self.clcd.dma = bus.port
- self.kmi0.pio = bus.port
- self.kmi1.pio = bus.port
- self.dmac_fake.pio = bus.port
- self.uart1_fake.pio = bus.port
- self.uart2_fake.pio = bus.port
- self.uart3_fake.pio = bus.port
- self.smc_fake.pio = bus.port
- self.sp810_fake.pio = bus.port
- self.watchdog_fake.pio = bus.port
- self.gpio0_fake.pio = bus.port
- self.gpio1_fake.pio = bus.port
- self.gpio2_fake.pio = bus.port
- self.ssp_fake.pio = bus.port
- self.sci_fake.pio = bus.port
- self.aaci_fake.pio = bus.port
- self.mmc_fake.pio = bus.port
- self.rtc_fake.pio = bus.port
- self.flash_fake.pio = bus.port
- self.smcreg_fake.pio = bus.port
+ self.uart.pio = bus.master
+ self.realview_io.pio = bus.master
+ self.timer0.pio = bus.master
+ self.timer1.pio = bus.master
+ self.clcd.pio = bus.master
+ self.clcd.dma = bus.slave
+ self.kmi0.pio = bus.master
+ self.kmi1.pio = bus.master
+ self.dmac_fake.pio = bus.master
+ self.uart1_fake.pio = bus.master
+ self.uart2_fake.pio = bus.master
+ self.uart3_fake.pio = bus.master
+ self.smc_fake.pio = bus.master
+ self.sp810_fake.pio = bus.master
+ self.watchdog_fake.pio = bus.master
+ self.gpio0_fake.pio = bus.master
+ self.gpio1_fake.pio = bus.master
+ self.gpio2_fake.pio = bus.master
+ self.ssp_fake.pio = bus.master
+ self.sci_fake.pio = bus.master
+ self.aaci_fake.pio = bus.master
+ self.mmc_fake.pio = bus.master
+ self.rtc_fake.pio = bus.master
+ self.flash_fake.pio = bus.master
+ self.smcreg_fake.pio = bus.master
class VExpress_ELT(RealView):
pci_cfg_base = 0xD0000000
@@ -349,9 +349,9 @@ class VExpress_ELT(RealView):
# Attach I/O devices that are on chip and also set the appropriate
# ranges for the bridge
def attachOnChipIO(self, bus, bridge):
- self.gic.pio = bus.port
- self.a9scu.pio = bus.port
- self.local_cpu_timer.pio = bus.port
+ self.gic.pio = bus.master
+ self.a9scu.pio = bus.master
+ self.local_cpu_timer.pio = bus.master
# Bridge ranges based on excluding what is part of on-chip I/O
# (gic, a9scu)
bridge.ranges = [AddrRange(self.pci_cfg_base, self.a9scu.pio_addr - 1),
@@ -361,44 +361,44 @@ class VExpress_ELT(RealView):
# earlier, since the bus object itself is typically defined at the
# System level.
def attachIO(self, bus):
- self.elba_uart.pio = bus.port
- self.uart.pio = bus.port
- self.realview_io.pio = bus.port
- self.v2m_timer0.pio = bus.port
- self.v2m_timer1.pio = bus.port
- self.elba_timer0.pio = bus.port
- self.elba_timer1.pio = bus.port
- self.clcd.pio = bus.port
- self.clcd.dma = bus.port
- self.kmi0.pio = bus.port
- self.kmi1.pio = bus.port
- self.elba_kmi0.pio = bus.port
- self.elba_kmi1.pio = bus.port
- self.cf_ctrl.pio = bus.port
- self.cf_ctrl.config = bus.port
+ self.elba_uart.pio = bus.master
+ self.uart.pio = bus.master
+ self.realview_io.pio = bus.master
+ self.v2m_timer0.pio = bus.master
+ self.v2m_timer1.pio = bus.master
+ self.elba_timer0.pio = bus.master
+ self.elba_timer1.pio = bus.master
+ self.clcd.pio = bus.master
+ self.clcd.dma = bus.slave
+ self.kmi0.pio = bus.master
+ self.kmi1.pio = bus.master
+ self.elba_kmi0.pio = bus.master
+ self.elba_kmi1.pio = bus.master
+ self.cf_ctrl.pio = bus.master
+ self.cf_ctrl.config = bus.master
self.cf_ctrl.dma = bus.port
- self.ide.pio = bus.port
- self.ide.config = bus.port
- self.ide.dma = bus.port
- self.ethernet.pio = bus.port
- self.ethernet.config = bus.port
- self.ethernet.dma = bus.port
+ self.ide.pio = bus.master
+ self.ide.config = bus.master
+ self.ide.dma = bus.slave
+ self.ethernet.pio = bus.master
+ self.ethernet.config = bus.master
+ self.ethernet.dma = bus.slave
self.pciconfig.pio = bus.default
bus.use_default_range = True
- self.l2x0_fake.pio = bus.port
- self.dmac_fake.pio = bus.port
- self.uart1_fake.pio = bus.port
- self.uart2_fake.pio = bus.port
- self.uart3_fake.pio = bus.port
- self.smc_fake.pio = bus.port
- self.sp810_fake.pio = bus.port
- self.watchdog_fake.pio = bus.port
- self.aaci_fake.pio = bus.port
- self.elba_aaci_fake.pio = bus.port
- self.mmc_fake.pio = bus.port
- self.rtc_fake.pio = bus.port
- self.spsc_fake.pio = bus.port
- self.lan_fake.pio = bus.port
- self.usb_fake.pio = bus.port
+ self.l2x0_fake.pio = bus.master
+ self.dmac_fake.pio = bus.master
+ self.uart1_fake.pio = bus.master
+ self.uart2_fake.pio = bus.master
+ self.uart3_fake.pio = bus.master
+ self.smc_fake.pio = bus.master
+ self.sp810_fake.pio = bus.master
+ self.watchdog_fake.pio = bus.master
+ self.aaci_fake.pio = bus.master
+ self.elba_aaci_fake.pio = bus.master
+ self.mmc_fake.pio = bus.master
+ self.rtc_fake.pio = bus.master
+ self.spsc_fake.pio = bus.master
+ self.lan_fake.pio = bus.master
+ self.usb_fake.pio = bus.master
diff --git a/src/dev/x86/I82094AA.py b/src/dev/x86/I82094AA.py
index d4ab2cb17..09923f6c2 100644
--- a/src/dev/x86/I82094AA.py
+++ b/src/dev/x86/I82094AA.py
@@ -37,7 +37,7 @@ class I82094AA(BasicPioDevice):
apic_id = Param.Int(1, 'APIC id for this IO APIC')
pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
pio_addr = Param.Addr("Device address")
- int_port = Port("Port for sending and receiving interrupt messages")
+ int_master = MasterPort("Port for sending interrupt messages")
int_latency = Param.Latency('1ns', \
"Latency for an interrupt to propagate through this device.")
external_int_pic = Param.I8259(NULL, "External PIC, if any")
diff --git a/src/dev/x86/Pc.py b/src/dev/x86/Pc.py
index bb8c91ac6..5b7d0864e 100644
--- a/src/dev/x86/Pc.py
+++ b/src/dev/x86/Pc.py
@@ -71,12 +71,12 @@ class Pc(Platform):
def attachIO(self, bus):
self.south_bridge.attachIO(bus)
- self.i_dont_exist.pio = bus.port
- self.behind_pci.pio = bus.port
- self.com_1.pio = bus.port
- self.fake_com_2.pio = bus.port
- self.fake_com_3.pio = bus.port
- self.fake_com_4.pio = bus.port
- self.fake_floppy.pio = bus.port
+ self.i_dont_exist.pio = bus.master
+ self.behind_pci.pio = bus.master
+ self.com_1.pio = bus.master
+ self.fake_com_2.pio = bus.master
+ self.fake_com_3.pio = bus.master
+ self.fake_com_4.pio = bus.master
+ self.fake_floppy.pio = bus.master
self.pciconfig.pio = bus.default
bus.use_default_range = True
diff --git a/src/dev/x86/SouthBridge.py b/src/dev/x86/SouthBridge.py
index baff35e0b..9f7070e96 100644
--- a/src/dev/x86/SouthBridge.py
+++ b/src/dev/x86/SouthBridge.py
@@ -102,15 +102,15 @@ class SouthBridge(SimObject):
self.speaker.i8254 = self.pit
self.io_apic.external_int_pic = self.pic1
# Connect to the bus
- self.cmos.pio = bus.port
- self.dma1.pio = bus.port
- self.ide.pio = bus.port
- self.ide.config = bus.port
- self.ide.dma = bus.port
- self.keyboard.pio = bus.port
- self.pic1.pio = bus.port
- self.pic2.pio = bus.port
- self.pit.pio = bus.port
- self.speaker.pio = bus.port
- self.io_apic.pio = bus.port
- self.io_apic.int_port = bus.port
+ self.cmos.pio = bus.master
+ self.dma1.pio = bus.master
+ self.ide.pio = bus.master
+ self.ide.config = bus.master
+ self.ide.dma = bus.slave
+ self.keyboard.pio = bus.master
+ self.pic1.pio = bus.master
+ self.pic2.pio = bus.master
+ self.pit.pio = bus.master
+ self.speaker.pio = bus.master
+ self.io_apic.pio = bus.master
+ self.io_apic.int_master = bus.slave
diff --git a/src/dev/x86/i82094aa.hh b/src/dev/x86/i82094aa.hh
index dfef059c3..60ef27012 100644
--- a/src/dev/x86/i82094aa.hh
+++ b/src/dev/x86/i82094aa.hh
@@ -123,7 +123,7 @@ class I82094AA : public PioDevice, public IntDev
Port *getPort(const std::string &if_name, int idx = -1)
{
- if (if_name == "int_port")
+ if (if_name == "int_master")
return intPort;
return PioDevice::getPort(if_name, idx);
}
diff --git a/src/dev/x86/intdev.hh b/src/dev/x86/intdev.hh
index 9713d042b..05b4d12a1 100644
--- a/src/dev/x86/intdev.hh
+++ b/src/dev/x86/intdev.hh
@@ -90,7 +90,7 @@ class IntDev
IntDev(MemObject * parent, Tick latency = 0)
{
if (parent != NULL) {
- intPort = new IntPort(parent->name() + ".int_port",
+ intPort = new IntPort(parent->name() + ".int_master",
parent, this, latency);
} else {
intPort = NULL;
diff --git a/src/mem/Bridge.py b/src/mem/Bridge.py
index 38b344613..ea8684e1b 100644
--- a/src/mem/Bridge.py
+++ b/src/mem/Bridge.py
@@ -31,8 +31,8 @@ from MemObject import MemObject
class Bridge(MemObject):
type = 'Bridge'
- slave = Port('Slave port')
- master = Port('Master port')
+ slave = SlavePort('Slave port')
+ master = MasterPort('Master port')
req_size = Param.Int(16, "The number of requests to buffer")
resp_size = Param.Int(16, "The number of requests to buffer")
delay = Param.Latency('0ns', "The latency of this bridge")
diff --git a/src/mem/Bus.py b/src/mem/Bus.py
index fda91742f..91043da80 100644
--- a/src/mem/Bus.py
+++ b/src/mem/Bus.py
@@ -33,13 +33,14 @@ from MemObject import MemObject
class Bus(MemObject):
type = 'Bus'
- port = VectorPort("vector port for connecting devices")
+ slave = VectorSlavePort("vector port for connecting masters")
+ master = VectorMasterPort("vector port for connecting slaves")
bus_id = Param.Int(0, "blah")
clock = Param.Clock("1GHz", "bus clock speed")
header_cycles = Param.Int(1, "cycles of overhead per transaction")
width = Param.Int(64, "bus width (bytes)")
block_size = Param.Int(64, "The default block size if one isn't set by a device attached to the bus.")
- default = \
- Port("Default port for requests that aren't handled by a device.")
+ default = MasterPort("Default port for requests that aren't handled " \
+ "by a device.")
use_default_range = \
Param.Bool(False, "Query default port device for legal range.")
diff --git a/src/mem/PhysicalMemory.py b/src/mem/PhysicalMemory.py
index 95cc73daa..c5f80b4c9 100644
--- a/src/mem/PhysicalMemory.py
+++ b/src/mem/PhysicalMemory.py
@@ -32,7 +32,7 @@ from MemObject import *
class PhysicalMemory(MemObject):
type = 'PhysicalMemory'
- port = VectorPort("the access port")
+ port = VectorSlavePort("the access port")
range = Param.AddrRange(AddrRange('128MB'), "Device Address")
file = Param.String('', "memory mapped file")
latency = Param.Latency('30ns', "latency of an access")
diff --git a/src/mem/cache/BaseCache.py b/src/mem/cache/BaseCache.py
index 4389eb356..adc48a461 100644
--- a/src/mem/cache/BaseCache.py
+++ b/src/mem/cache/BaseCache.py
@@ -58,7 +58,7 @@ class BaseCache(MemObject):
prefetch_on_access = Param.Bool(False,
"notify the hardware prefetcher on every access (not just misses)")
prefetcher = Param.BasePrefetcher(NULL,"Prefetcher attached to cache")
- cpu_side = Port("Port on side closer to CPU")
- mem_side = Port("Port on side closer to MEM")
+ cpu_side = SlavePort("Port on side closer to CPU")
+ mem_side = MasterPort("Port on side closer to MEM")
addr_range = Param.AddrRange(AllMemory, "The address range for the CPU-side port")
system = Param.System(Parent.any, "System we belong to")
diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc
index ab3e6e3b7..2ef65a13a 100644
--- a/src/mem/ruby/system/RubyPort.cc
+++ b/src/mem/ruby/system/RubyPort.cc
@@ -68,13 +68,24 @@ RubyPort::init()
Port *
RubyPort::getPort(const std::string &if_name, int idx)
{
- if (if_name == "port") {
- M5Port* cpuPort = new M5Port(csprintf("%s-port%d", name(), idx),
+ // used by the CPUs to connect the caches to the interconnect, and
+ // for the x86 case also the interrupt master
+ if (if_name == "slave") {
+ M5Port* cpuPort = new M5Port(csprintf("%s-slave%d", name(), idx),
this, ruby_system, access_phys_mem);
cpu_ports.push_back(cpuPort);
return cpuPort;
}
+ // used by the x86 CPUs to connect the interrupt PIO and interrupt slave
+ // port
+ if (if_name == "master") {
+ PioPort* masterPort = new PioPort(csprintf("%s-master%d", name(), idx),
+ this);
+
+ return masterPort;
+ }
+
if (if_name == "pio_port") {
// ensure there is only one pio port
assert(pio_port == NULL);
diff --git a/src/mem/ruby/system/Sequencer.py b/src/mem/ruby/system/Sequencer.py
index ddf760f7b..b1e17e052 100644
--- a/src/mem/ruby/system/Sequencer.py
+++ b/src/mem/ruby/system/Sequencer.py
@@ -34,11 +34,12 @@ from MemObject import MemObject
class RubyPort(MemObject):
type = 'RubyPort'
abstract = True
- port = VectorPort("M5 port")
+ slave = VectorSlavePort("CPU slave port")
+ master = VectorMasterPort("CPU master port")
version = Param.Int(0, "")
- pio_port = Port("Ruby_pio_port")
+ pio_port = MasterPort("Ruby_pio_port")
physmem = Param.PhysicalMemory("")
- physMemPort = Port("port to physical memory")
+ physMemPort = MasterPort("port to physical memory")
using_ruby_tester = Param.Bool(False, "")
using_network_tester = Param.Bool(False, "")
access_phys_mem = Param.Bool(True,
diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py
index c45867c85..afdd84fe3 100644
--- a/src/python/m5/SimObject.py
+++ b/src/python/m5/SimObject.py
@@ -46,7 +46,7 @@ from m5.params import *
# There are a few things we need that aren't in params.__all__ since
# normal users don't need them
from m5.params import ParamDesc, VectorParamDesc, \
- isNullPointer, SimObjectVector
+ isNullPointer, SimObjectVector, Port
from m5.proxy import *
from m5.proxy import isproxy
diff --git a/src/python/m5/params.py b/src/python/m5/params.py
index dfc703a40..95958e3e6 100644
--- a/src/python/m5/params.py
+++ b/src/python/m5/params.py
@@ -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) 2004-2006 The Regents of The University of Michigan
# Copyright (c) 2010-2011 Advanced Micro Devices, Inc.
# All rights reserved.
@@ -28,6 +40,7 @@
# Authors: Steve Reinhardt
# Nathan Binkert
# Gabe Black
+# Andreas Hansson
#####################################################################
#
@@ -1324,10 +1337,11 @@ AllMemory = AddrRange(0, MaxAddr)
# Port reference: encapsulates a reference to a particular port on a
# particular SimObject.
class PortRef(object):
- def __init__(self, simobj, name):
+ def __init__(self, simobj, name, role):
assert(isSimObject(simobj) or isSimObjectClass(simobj))
self.simobj = simobj
self.name = name
+ self.role = role
self.peer = None # not associated with another port yet
self.ccConnected = False # C++ port connection done?
self.index = -1 # always -1 for non-vector ports
@@ -1397,12 +1411,24 @@ class PortRef(object):
def ccConnect(self):
from m5.internal.pyobject import connectPorts
+ if self.role == 'SLAVE':
+ # do nothing and let the master take care of it
+ return
+
if self.ccConnected: # already done this
return
peer = self.peer
if not self.peer: # nothing to connect to
return
+
+ # check that we connect a master to a slave
+ if self.role == peer.role:
+ raise TypeError, \
+ "cannot connect '%s' and '%s' due to identical role '%s'" \
+ % (peer, self, self.role)
+
try:
+ # self is always the master and peer the slave
connectPorts(self.simobj.getCCObject(), self.name, self.index,
peer.simobj.getCCObject(), peer.name, peer.index)
except:
@@ -1416,8 +1442,8 @@ class PortRef(object):
# A reference to an individual element of a VectorPort... much like a
# PortRef, but has an index.
class VectorPortElementRef(PortRef):
- def __init__(self, simobj, name, index):
- PortRef.__init__(self, simobj, name)
+ def __init__(self, simobj, name, role, index):
+ PortRef.__init__(self, simobj, name, role)
self.index = index
def __str__(self):
@@ -1426,10 +1452,11 @@ class VectorPortElementRef(PortRef):
# A reference to a complete vector-valued port (not just a single element).
# Can be indexed to retrieve individual VectorPortElementRef instances.
class VectorPortRef(object):
- def __init__(self, simobj, name):
+ def __init__(self, simobj, name, role):
assert(isSimObject(simobj) or isSimObjectClass(simobj))
self.simobj = simobj
self.name = name
+ self.role = role
self.elements = []
def __str__(self):
@@ -1444,7 +1471,7 @@ class VectorPortRef(object):
raise TypeError, "VectorPort index must be integer"
if key >= len(self.elements):
# need to extend list
- ext = [VectorPortElementRef(self.simobj, self.name, i)
+ ext = [VectorPortElementRef(self.simobj, self.name, self.role, i)
for i in range(len(self.elements), key+1)]
self.elements.extend(ext)
return self.elements[key]
@@ -1488,34 +1515,62 @@ class VectorPortRef(object):
# logical port in the SimObject class, not a particular port on a
# SimObject instance. The latter are represented by PortRef objects.
class Port(object):
- # Port("description")
- def __init__(self, *args):
- if len(args) == 1:
- self.desc = args[0]
- else:
- raise TypeError, 'wrong number of arguments'
- # self.name is set by SimObject class on assignment
- # e.g., pio_port = Port("blah") sets self.name to 'pio_port'
-
# Generate a PortRef for this port on the given SimObject with the
# given name
def makeRef(self, simobj):
- return PortRef(simobj, self.name)
+ return PortRef(simobj, self.name, self.role)
# Connect an instance of this port (on the given SimObject with
# the given name) with the port described by the supplied PortRef
def connect(self, simobj, ref):
self.makeRef(simobj).connect(ref)
+class MasterPort(Port):
+ # MasterPort("description")
+ def __init__(self, *args):
+ if len(args) == 1:
+ self.desc = args[0]
+ self.role = 'MASTER'
+ else:
+ raise TypeError, 'wrong number of arguments'
+
+class SlavePort(Port):
+ # SlavePort("description")
+ def __init__(self, *args):
+ if len(args) == 1:
+ self.desc = args[0]
+ self.role = 'SLAVE'
+ else:
+ raise TypeError, 'wrong number of arguments'
+
# VectorPort description object. Like Port, but represents a vector
# of connections (e.g., as on a Bus).
class VectorPort(Port):
def __init__(self, *args):
- Port.__init__(self, *args)
self.isVec = True
def makeRef(self, simobj):
- return VectorPortRef(simobj, self.name)
+ return VectorPortRef(simobj, self.name, self.role)
+
+class VectorMasterPort(VectorPort):
+ # VectorMasterPort("description")
+ def __init__(self, *args):
+ if len(args) == 1:
+ self.desc = args[0]
+ self.role = 'MASTER'
+ VectorPort.__init__(self, *args)
+ else:
+ raise TypeError, 'wrong number of arguments'
+
+class VectorSlavePort(VectorPort):
+ # VectorSlavePort("description")
+ def __init__(self, *args):
+ if len(args) == 1:
+ self.desc = args[0]
+ self.role = 'SLAVE'
+ VectorPort.__init__(self, *args)
+ else:
+ raise TypeError, 'wrong number of arguments'
# 'Fake' ParamDesc for Port references to assign to the _pdesc slot of
# proxy objects (via set_param_desc()) so that proxy error messages
@@ -1549,6 +1604,7 @@ __all__ = ['Param', 'VectorParam',
'MaxAddr', 'MaxTick', 'AllMemory',
'Time',
'NextEthernetAddr', 'NULL',
- 'Port', 'VectorPort']
+ 'MasterPort', 'SlavePort',
+ 'VectorMasterPort', 'VectorSlavePort']
import SimObject
diff --git a/src/sim/System.py b/src/sim/System.py
index 73124ecb9..88485fcf8 100644
--- a/src/sim/System.py
+++ b/src/sim/System.py
@@ -39,7 +39,7 @@ class MemoryMode(Enum): vals = ['invalid', 'atomic', 'timing']
class System(MemObject):
type = 'System'
- system_port = Port("System port")
+ system_port = MasterPort("System port")
@classmethod
def export_method_cxx_predecls(cls, code):