From f85286b3debf4a4a94d3b959e5bb880be81bd692 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Tue, 17 Jan 2012 12:55:08 -0600 Subject: MEM: Add port proxies instead of non-structural ports Port proxies are used to replace non-structural ports, and thus enable all ports in the system to correspond to a structural entity. This has the advantage of accessing memory through the normal memory subsystem and thus allowing any constellation of distributed memories, address maps, etc. Most accesses are done through the "system port" that is used for loading binaries, debugging etc. For the entities that belong to the CPU, e.g. threads and thread contexts, they wrap the CPU data port in a port proxy. The following replacements are made: FunctionalPort > PortProxy TranslatingPort > SETranslatingPortProxy VirtualPort > FSTranslatingPortProxy --HG-- rename : src/mem/vport.cc => src/mem/fs_translating_port_proxy.cc 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 --- src/cpu/simple/atomic.cc | 15 +++------------ src/cpu/simple/atomic.hh | 11 +---------- src/cpu/simple/timing.cc | 15 +++------------ src/cpu/simple/timing.hh | 2 -- 4 files changed, 7 insertions(+), 36 deletions(-) (limited to 'src/cpu/simple') diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 5376519d4..b40109ec1 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -91,6 +91,9 @@ AtomicSimpleCPU::init() // initialize CPU, including PC TheISA::initCPU(tc, tc->contextId()); } + + // Initialise the ThreadContext's memory proxies + tcBase()->initMemProxies(tcBase()); #endif if (hasPhysMemPort) { bool snoop = false; @@ -145,18 +148,6 @@ AtomicSimpleCPU::CpuPort::recvRetry() panic("AtomicSimpleCPU doesn't expect recvRetry callback!"); } -void -AtomicSimpleCPU::DcachePort::setPeer(Port *port) -{ - Port::setPeer(port); - -#if FULL_SYSTEM - // Update the ThreadContext's memory ports (Functional/Virtual - // Ports) - cpu->tcBase()->connectMemPorts(cpu->tcBase()); -#endif -} - AtomicSimpleCPU::AtomicSimpleCPU(AtomicSimpleCPUParams *p) : BaseSimpleCPU(p), tickEvent(this), width(p->width), locked(false), simulate_data_stalls(p->simulate_data_stalls), diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh index 246afa0b2..c3d78a381 100644 --- a/src/cpu/simple/atomic.hh +++ b/src/cpu/simple/atomic.hh @@ -95,16 +95,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU }; CpuPort icachePort; - class DcachePort : public CpuPort - { - public: - DcachePort(const std::string &_name, AtomicSimpleCPU *_cpu) - : CpuPort(_name, _cpu) - { } - - virtual void setPeer(Port *port); - }; - DcachePort dcachePort; + CpuPort dcachePort; CpuPort physmemPort; bool hasPhysMemPort; diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index e2151d974..4375d2549 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -81,6 +81,9 @@ TimingSimpleCPU::init() // initialize CPU, including PC TheISA::initCPU(tc, _cpuId); } + + // Initialise the ThreadContext's memory proxies + tcBase()->initMemProxies(tcBase()); #endif } @@ -874,18 +877,6 @@ TimingSimpleCPU::completeDrain() drainEvent->process(); } -void -TimingSimpleCPU::DcachePort::setPeer(Port *port) -{ - Port::setPeer(port); - -#if FULL_SYSTEM - // Update the ThreadContext's memory ports (Functional/Virtual - // Ports) - cpu->tcBase()->connectMemPorts(cpu->tcBase()); -#endif -} - bool TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt) { diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh index 4301dfca7..6e95ddd9d 100644 --- a/src/cpu/simple/timing.hh +++ b/src/cpu/simple/timing.hh @@ -212,8 +212,6 @@ class TimingSimpleCPU : public BaseSimpleCPU : CpuPort(_cpu->name() + "-dport", _cpu, _lat), tickEvent(_cpu) { } - virtual void setPeer(Port *port); - protected: virtual bool recvTiming(PacketPtr pkt); -- cgit v1.2.3 From b3f930c884ef23e4d784553fdccc91a772334fd7 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Tue, 17 Jan 2012 12:55:08 -0600 Subject: CPU: Moving towards a more general port across CPU models This patch performs minimal changes to move the instruction and data ports from specialised subclasses to the base CPU (to the largest degree possible). Ultimately it servers to make the CPU(s) have a well-defined interface to the memory sub-system. --- src/cpu/simple/AtomicSimpleCPU.py | 4 ---- src/cpu/simple/TimingSimpleCPU.py | 3 --- src/cpu/simple/atomic.cc | 45 --------------------------------------- src/cpu/simple/atomic.hh | 37 +++++++++++++------------------- src/cpu/simple/timing.cc | 38 +++------------------------------ src/cpu/simple/timing.hh | 43 ++++++++++++++++--------------------- 6 files changed, 36 insertions(+), 134 deletions(-) (limited to 'src/cpu/simple') diff --git a/src/cpu/simple/AtomicSimpleCPU.py b/src/cpu/simple/AtomicSimpleCPU.py index a4d807f86..93cd02ba7 100644 --- a/src/cpu/simple/AtomicSimpleCPU.py +++ b/src/cpu/simple/AtomicSimpleCPU.py @@ -34,8 +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") - icache_port = Port("Instruction Port") - dcache_port = Port("Data Port") physmem_port = Port("Physical Memory Port") - _cached_ports = BaseSimpleCPU._cached_ports + \ - ['icache_port', 'dcache_port'] diff --git a/src/cpu/simple/TimingSimpleCPU.py b/src/cpu/simple/TimingSimpleCPU.py index 8d6888f72..61491b087 100644 --- a/src/cpu/simple/TimingSimpleCPU.py +++ b/src/cpu/simple/TimingSimpleCPU.py @@ -31,6 +31,3 @@ from BaseSimpleCPU import BaseSimpleCPU class TimingSimpleCPU(BaseSimpleCPU): type = 'TimingSimpleCPU' - icache_port = Port("Instruction Port") - dcache_port = Port("Data Port") - _cached_ports = BaseSimpleCPU._cached_ports + ['icache_port', 'dcache_port'] diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index b40109ec1..84f42da08 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -107,47 +107,6 @@ AtomicSimpleCPU::init() data_write_req.setThreadContext(_cpuId, 0); // Add thread ID here too } -bool -AtomicSimpleCPU::CpuPort::recvTiming(PacketPtr pkt) -{ - panic("AtomicSimpleCPU doesn't expect recvTiming callback!"); - return true; -} - -Tick -AtomicSimpleCPU::CpuPort::recvAtomic(PacketPtr pkt) -{ - //Snooping a coherence request, just return - return 0; -} - -void -AtomicSimpleCPU::CpuPort::recvFunctional(PacketPtr pkt) -{ - //No internal storage to update, just return - return; -} - -void -AtomicSimpleCPU::CpuPort::recvStatusChange(Status status) -{ - if (status == RangeChange) { - if (!snoopRangeSent) { - snoopRangeSent = true; - sendStatusChange(Port::RangeChange); - } - return; - } - - panic("AtomicSimpleCPU doesn't expect recvStatusChange callback!"); -} - -void -AtomicSimpleCPU::CpuPort::recvRetry() -{ - panic("AtomicSimpleCPU doesn't expect recvRetry callback!"); -} - AtomicSimpleCPU::AtomicSimpleCPU(AtomicSimpleCPUParams *p) : BaseSimpleCPU(p), tickEvent(this), width(p->width), locked(false), simulate_data_stalls(p->simulate_data_stalls), @@ -156,10 +115,6 @@ AtomicSimpleCPU::AtomicSimpleCPU(AtomicSimpleCPUParams *p) physmemPort(name() + "-iport", this), hasPhysMemPort(false) { _status = Idle; - - icachePort.snoopRangeSent = false; - dcachePort.snoopRangeSent = false; - } diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh index c3d78a381..77a9d6b0d 100644 --- a/src/cpu/simple/atomic.hh +++ b/src/cpu/simple/atomic.hh @@ -64,38 +64,31 @@ class AtomicSimpleCPU : public BaseSimpleCPU // main simulation loop (one cycle) void tick(); - class CpuPort : public Port + /** + * An AtomicCPUPort overrides the default behaviour of the + * recvAtomic and ignores the packet instead of panicking. + */ + class AtomicCPUPort : public CpuPort { + public: - CpuPort(const std::string &_name, AtomicSimpleCPU *_cpu) - : Port(_name, _cpu), cpu(_cpu) + AtomicCPUPort(const std::string &_name, BaseCPU* _cpu) + : CpuPort(_name, _cpu) { } - bool snoopRangeSent; - protected: - AtomicSimpleCPU *cpu; - - virtual bool recvTiming(PacketPtr pkt); - - virtual Tick recvAtomic(PacketPtr pkt); - - virtual void recvFunctional(PacketPtr pkt); - - virtual void recvStatusChange(Status status); - - virtual void recvRetry(); - - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop) - { resp.clear(); snoop = true; } + virtual Tick recvAtomic(PacketPtr pkt) + { + // Snooping a coherence request, just return + return 0; + } }; - CpuPort icachePort; - CpuPort dcachePort; + AtomicCPUPort icachePort; + AtomicCPUPort dcachePort; CpuPort physmemPort; bool hasPhysMemPort; diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 4375d2549..70583cae9 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -87,51 +87,19 @@ TimingSimpleCPU::init() #endif } -Tick -TimingSimpleCPU::CpuPort::recvAtomic(PacketPtr pkt) -{ - panic("TimingSimpleCPU doesn't expect recvAtomic callback!"); - return curTick(); -} - void -TimingSimpleCPU::CpuPort::recvFunctional(PacketPtr pkt) -{ - //No internal storage to update, jusst return - return; -} - -void -TimingSimpleCPU::CpuPort::recvStatusChange(Status status) -{ - if (status == RangeChange) { - if (!snoopRangeSent) { - snoopRangeSent = true; - sendStatusChange(Port::RangeChange); - } - return; - } - - panic("TimingSimpleCPU doesn't expect recvStatusChange callback!"); -} - - -void -TimingSimpleCPU::CpuPort::TickEvent::schedule(PacketPtr _pkt, Tick t) +TimingSimpleCPU::TimingCPUPort::TickEvent::schedule(PacketPtr _pkt, Tick t) { pkt = _pkt; cpu->schedule(this, t); } TimingSimpleCPU::TimingSimpleCPU(TimingSimpleCPUParams *p) - : BaseSimpleCPU(p), fetchTranslation(this), icachePort(this, p->clock), - dcachePort(this, p->clock), fetchEvent(this) + : BaseSimpleCPU(p), fetchTranslation(this), icachePort(this), + dcachePort(this), fetchEvent(this) { _status = Idle; - icachePort.snoopRangeSent = false; - dcachePort.snoopRangeSent = false; - ifetch_pkt = dcache_pkt = NULL; drainEvent = NULL; previousTick = 0; diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh index 6e95ddd9d..dce3c58ff 100644 --- a/src/cpu/simple/timing.hh +++ b/src/cpu/simple/timing.hh @@ -137,31 +137,23 @@ class TimingSimpleCPU : public BaseSimpleCPU // This function always implicitly uses dcache_pkt. bool handleWritePacket(); - class CpuPort : public Port + /** + * A TimingCPUPort overrides the default behaviour of the + * recvTiming and recvRetry and implements events for the + * scheduling of handling of incoming packets in the following + * cycle. + */ + class TimingCPUPort : public CpuPort { - protected: - TimingSimpleCPU *cpu; - Tick lat; - public: - CpuPort(const std::string &_name, TimingSimpleCPU *_cpu, Tick _lat) - : Port(_name, _cpu), cpu(_cpu), lat(_lat), retryEvent(this) + TimingCPUPort(const std::string& _name, TimingSimpleCPU* _cpu) + : CpuPort(_name, _cpu), cpu(_cpu), retryEvent(this) { } - bool snoopRangeSent; - protected: - virtual Tick recvAtomic(PacketPtr pkt); - - virtual void recvFunctional(PacketPtr pkt); - - virtual void recvStatusChange(Status status); - - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop) - { resp.clear(); snoop = false; } + TimingSimpleCPU* cpu; struct TickEvent : public Event { @@ -169,7 +161,7 @@ class TimingSimpleCPU : public BaseSimpleCPU TimingSimpleCPU *cpu; CpuPort *port; - TickEvent(TimingSimpleCPU *_cpu) : cpu(_cpu) {} + TickEvent(TimingSimpleCPU *_cpu) : pkt(NULL), cpu(_cpu) {} const char *description() const { return "Timing CPU tick"; } void schedule(PacketPtr _pkt, Tick t); }; @@ -177,12 +169,13 @@ class TimingSimpleCPU : public BaseSimpleCPU EventWrapper retryEvent; }; - class IcachePort : public CpuPort + class IcachePort : public TimingCPUPort { public: - IcachePort(TimingSimpleCPU *_cpu, Tick _lat) - : CpuPort(_cpu->name() + "-iport", _cpu, _lat), tickEvent(_cpu) + IcachePort(TimingSimpleCPU *_cpu) + : TimingCPUPort(_cpu->name() + "-iport", _cpu), + tickEvent(_cpu) { } protected: @@ -204,12 +197,12 @@ class TimingSimpleCPU : public BaseSimpleCPU }; - class DcachePort : public CpuPort + class DcachePort : public TimingCPUPort { public: - DcachePort(TimingSimpleCPU *_cpu, Tick _lat) - : CpuPort(_cpu->name() + "-dport", _cpu, _lat), tickEvent(_cpu) + DcachePort(TimingSimpleCPU *_cpu) + : TimingCPUPort(_cpu->name() + "-dport", _cpu), tickEvent(_cpu) { } protected: -- cgit v1.2.3 From de34e49d15b95cc8be51dbed2e98c469e7486959 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Tue, 17 Jan 2012 12:55:09 -0600 Subject: MEM: Simplify ports by removing EventManager This patch removes the inheritance of EventManager from the ports and moves all responsibility for event queues to the owner. Eventually the event manager should be the interface block, which could either be the structural owner or a subblock like a LSQ in the O3 CPU for example. --- src/cpu/simple/timing.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/cpu/simple') diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 70583cae9..f8d13efd9 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -862,7 +862,7 @@ TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt) // faster than a CPU we could get two responses before // next_tick expires if (!retryEvent.scheduled()) - schedule(retryEvent, next_tick); + cpu->schedule(retryEvent, next_tick); return false; } } -- cgit v1.2.3 From 07cf9d914b292008ead7021182ec2ef8fc4671f1 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Tue, 17 Jan 2012 12:55:09 -0600 Subject: MEM: Separate queries for snooping and address ranges This patch simplifies the address-range determination mechanism and also unifies the naming across ports and devices. It further splits the queries for determining if a port is snooping and what address ranges it responds to (aiming towards a separation of cache-maintenance ports and pure memory-mapped ports). Default behaviours are such that most ports do not have to define isSnooping, and master ports need not implement getAddrRanges. --- src/cpu/simple/atomic.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/cpu/simple') diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 84f42da08..425c8b1f1 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -96,9 +96,7 @@ AtomicSimpleCPU::init() tcBase()->initMemProxies(tcBase()); #endif if (hasPhysMemPort) { - bool snoop = false; - AddrRangeList pmAddrList; - physmemPort.getPeerAddressRanges(pmAddrList, snoop); + AddrRangeList pmAddrList = physmemPort.getPeer()->getAddrRanges(); physMemAddr = *pmAddrList.begin(); } // Atomic doesn't do MT right now, so contextId == threadId -- cgit v1.2.3