diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2007-05-25 19:29:32 -0700 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2007-05-25 19:29:32 -0700 |
commit | a3ae9486d543f23cd4203381e7bcf2ce86c51389 (patch) | |
tree | d66d3b9851f3002d0746c7af830062480f83773d /src | |
parent | ad02a59f89139a75dfcfaa7a79498e54f7ce7e5d (diff) | |
parent | 44ebb8d3e27329e9f0b501897585359b4ab696f2 (diff) | |
download | gem5-a3ae9486d543f23cd4203381e7bcf2ce86c51389.tar.xz |
Merge zizzer.eecs.umich.edu:/bk/newmem
into doughnut.mwconnections.com:/home/gblack/m5/newmem-x86
--HG--
extra : convert_revision : 276d00a73b1834d5262129c3f7e0f7fae18e23bc
Diffstat (limited to 'src')
-rwxr-xr-x | src/arch/isa_parser.py | 4 | ||||
-rw-r--r-- | src/cpu/base.cc | 7 | ||||
-rw-r--r-- | src/cpu/memtest/memtest.hh | 4 | ||||
-rw-r--r-- | src/cpu/o3/fetch.hh | 4 | ||||
-rw-r--r-- | src/cpu/o3/lsq.hh | 4 | ||||
-rw-r--r-- | src/cpu/ozone/front_end.hh | 4 | ||||
-rw-r--r-- | src/cpu/ozone/lw_lsq.hh | 4 | ||||
-rw-r--r-- | src/cpu/simple/atomic.hh | 4 | ||||
-rw-r--r-- | src/cpu/simple/timing.cc | 8 | ||||
-rw-r--r-- | src/cpu/simple/timing.hh | 11 | ||||
-rw-r--r-- | src/dev/io_device.cc | 4 | ||||
-rw-r--r-- | src/dev/io_device.hh | 6 | ||||
-rw-r--r-- | src/dev/ns_gige.cc | 6 | ||||
-rw-r--r-- | src/dev/pcidev.cc | 4 | ||||
-rw-r--r-- | src/dev/pcidev.hh | 2 | ||||
-rw-r--r-- | src/dev/sinic.cc | 6 | ||||
-rw-r--r-- | src/kern/tru64/tru64_events.cc | 2 | ||||
-rw-r--r-- | src/mem/bridge.cc | 2 | ||||
-rw-r--r-- | src/mem/bridge.hh | 2 | ||||
-rw-r--r-- | src/mem/bus.cc | 182 | ||||
-rw-r--r-- | src/mem/bus.hh | 167 | ||||
-rw-r--r-- | src/mem/cache/base_cache.cc | 3 | ||||
-rw-r--r-- | src/mem/cache/base_cache.hh | 9 | ||||
-rw-r--r-- | src/mem/physical.cc | 60 | ||||
-rw-r--r-- | src/mem/physical.hh | 7 | ||||
-rw-r--r-- | src/mem/port.hh | 4 | ||||
-rw-r--r-- | src/python/m5/objects/PhysicalMemory.py | 3 | ||||
-rw-r--r-- | src/python/swig/pyobject.cc | 1 | ||||
-rw-r--r-- | src/sim/eventq.hh | 14 |
29 files changed, 258 insertions, 280 deletions
diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index 57d58cc9d..7edb9f3d7 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -40,8 +40,8 @@ from types import * # of 'build' in the current tree. sys.path[0:0] = [os.environ['M5_PLY']] -import lex -import yacc +from ply import lex +from ply import yacc ##################################################################### # diff --git a/src/cpu/base.cc b/src/cpu/base.cc index 4dccee0d3..078ae1283 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -179,10 +179,9 @@ BaseCPU::BaseCPU(Params *p) if (p->functionTraceStart == 0) { functionTracingEnabled = true; } else { - Event *e = - new EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace>(this, - true); - e->schedule(p->functionTraceStart); + new EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace>(this, + p->functionTraceStart, + true); } } #if FULL_SYSTEM diff --git a/src/cpu/memtest/memtest.hh b/src/cpu/memtest/memtest.hh index 264309fd7..123ee2a6c 100644 --- a/src/cpu/memtest/memtest.hh +++ b/src/cpu/memtest/memtest.hh @@ -115,8 +115,8 @@ class MemTest : public MemObject virtual void recvRetry(); virtual void getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop) - { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); } + bool &snoop) + { resp.clear(); snoop = true; } }; CpuPort cachePort; diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh index 241935416..d9b0a47bd 100644 --- a/src/cpu/o3/fetch.hh +++ b/src/cpu/o3/fetch.hh @@ -100,8 +100,8 @@ class DefaultFetch /** Returns the address ranges of this device. */ virtual void getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop) - { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); } + bool &snoop) + { resp.clear(); snoop = true; } /** Timing version of receive. Handles setting fetch to the * proper status to start fetching. */ diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh index fd8f878a7..06de608e0 100644 --- a/src/cpu/o3/lsq.hh +++ b/src/cpu/o3/lsq.hh @@ -316,8 +316,8 @@ class LSQ { /** Returns the address ranges of this device. */ virtual void getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop) - { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); } + bool &snoop) + { resp.clear(); snoop = true; } /** Timing version of receive. Handles writing back and * completing the load or store that has returned from diff --git a/src/cpu/ozone/front_end.hh b/src/cpu/ozone/front_end.hh index 0acf99ead..667392c06 100644 --- a/src/cpu/ozone/front_end.hh +++ b/src/cpu/ozone/front_end.hh @@ -91,8 +91,8 @@ class FrontEnd /** Returns the address ranges of this device. */ virtual void getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop) - { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); } + bool &snoop) + { resp.clear(); snoop = true; } /** Timing version of receive. Handles setting fetch to the * proper status to start fetching. */ diff --git a/src/cpu/ozone/lw_lsq.hh b/src/cpu/ozone/lw_lsq.hh index c981b8e63..2048ad6bb 100644 --- a/src/cpu/ozone/lw_lsq.hh +++ b/src/cpu/ozone/lw_lsq.hh @@ -257,8 +257,8 @@ class OzoneLWLSQ { virtual void recvStatusChange(Status status); virtual void getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop) - { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); } + bool &snoop) + { resp.clear(); snoop = true; } virtual bool recvTiming(PacketPtr pkt); diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh index ad4aa4708..b127e3791 100644 --- a/src/cpu/simple/atomic.hh +++ b/src/cpu/simple/atomic.hh @@ -104,8 +104,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU virtual void recvRetry(); virtual void getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop) - { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); } + bool &snoop) + { resp.clear(); snoop = true; } }; CpuPort icachePort; diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index fa7bb4f86..1c79fcf6b 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -168,9 +168,7 @@ TimingSimpleCPU::resume() delete fetchEvent; } - fetchEvent = - new EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch>(this, false); - fetchEvent->schedule(nextCycle()); + fetchEvent = new FetchEvent(this, nextCycle()); } changeState(SimObject::Running); @@ -224,9 +222,7 @@ TimingSimpleCPU::activateContext(int thread_num, int delay) _status = Running; // kick things off by initiating the fetch of the next instruction - fetchEvent = - new EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch>(this, false); - fetchEvent->schedule(nextCycle(curTick + cycles(delay))); + fetchEvent = new FetchEvent(this, nextCycle(curTick + cycles(delay))); } diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh index ef062d24a..39958bfb6 100644 --- a/src/cpu/simple/timing.hh +++ b/src/cpu/simple/timing.hh @@ -66,8 +66,6 @@ class TimingSimpleCPU : public BaseSimpleCPU Event *drainEvent; - Event *fetchEvent; - private: class CpuPort : public Port @@ -93,8 +91,8 @@ class TimingSimpleCPU : public BaseSimpleCPU virtual void recvStatusChange(Status status); virtual void getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop) - { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); } + bool &snoop) + { resp.clear(); snoop = false; } struct TickEvent : public Event { @@ -199,7 +197,12 @@ class TimingSimpleCPU : public BaseSimpleCPU void completeIfetch(PacketPtr ); void completeDataAccess(PacketPtr ); void advanceInst(Fault fault); + private: + + typedef EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch> FetchEvent; + FetchEvent *fetchEvent; + void completeDrain(); }; diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc index 6528bd81c..ecbb391ef 100644 --- a/src/dev/io_device.cc +++ b/src/dev/io_device.cc @@ -48,9 +48,9 @@ PioPort::recvAtomic(PacketPtr pkt) } void -PioPort::getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) +PioPort::getDeviceAddressRanges(AddrRangeList &resp, bool &snoop) { - snoop.clear(); + snoop = false; device->addressRanges(resp); } diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh index bd150bfe4..25bd2de8d 100644 --- a/src/dev/io_device.hh +++ b/src/dev/io_device.hh @@ -59,7 +59,7 @@ class PioPort : public SimpleTimingPort virtual Tick recvAtomic(PacketPtr pkt); virtual void getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop); + bool &snoop); public: @@ -127,8 +127,8 @@ class DmaPort : public Port virtual void recvRetry() ; virtual void getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop) - { resp.clear(); snoop.clear(); } + bool &snoop) + { resp.clear(); snoop = false; } void queueDma(PacketPtr pkt, bool front = false); void sendDma(); diff --git a/src/dev/ns_gige.cc b/src/dev/ns_gige.cc index d9985f808..e9d9c419d 100644 --- a/src/dev/ns_gige.cc +++ b/src/dev/ns_gige.cc @@ -1270,8 +1270,7 @@ NSGigE::cpuIntrPost(Tick when) if (intrEvent) intrEvent->squash(); - intrEvent = new IntrEvent(this, true); - intrEvent->schedule(intrTick); + intrEvent = new IntrEvent(this, intrTick, true); } void @@ -2770,8 +2769,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) Tick intrEventTick; UNSERIALIZE_SCALAR(intrEventTick); if (intrEventTick) { - intrEvent = new IntrEvent(this, true); - intrEvent->schedule(intrEventTick); + intrEvent = new IntrEvent(this, intrEventTick, true); } } diff --git a/src/dev/pcidev.cc b/src/dev/pcidev.cc index f906e69cf..c2a2bc02d 100644 --- a/src/dev/pcidev.cc +++ b/src/dev/pcidev.cc @@ -76,9 +76,9 @@ PciDev::PciConfigPort::recvAtomic(PacketPtr pkt) void PciDev::PciConfigPort::getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop) + bool &snoop) { - snoop.clear(); + snoop = false;; resp.push_back(RangeSize(configAddr, PCI_CONFIG_SIZE+1)); } diff --git a/src/dev/pcidev.hh b/src/dev/pcidev.hh index 5044e2932..5ddbe84a0 100644 --- a/src/dev/pcidev.hh +++ b/src/dev/pcidev.hh @@ -89,7 +89,7 @@ class PciDev : public DmaDevice virtual Tick recvAtomic(PacketPtr pkt); virtual void getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop); + bool &snoop); Platform *platform; diff --git a/src/dev/sinic.cc b/src/dev/sinic.cc index 420761620..e13fdb0bc 100644 --- a/src/dev/sinic.cc +++ b/src/dev/sinic.cc @@ -630,8 +630,7 @@ Base::cpuIntrPost(Tick when) if (intrEvent) intrEvent->squash(); - intrEvent = new IntrEvent(this, true); - intrEvent->schedule(intrTick); + intrEvent = new IntrEvent(this, intrTick, true); } void @@ -1339,8 +1338,7 @@ Base::unserialize(Checkpoint *cp, const std::string §ion) Tick intrEventTick; UNSERIALIZE_SCALAR(intrEventTick); if (intrEventTick) { - intrEvent = new IntrEvent(this, true); - intrEvent->schedule(intrEventTick); + intrEvent = new IntrEvent(this, intrEventTick, true); } } diff --git a/src/kern/tru64/tru64_events.cc b/src/kern/tru64/tru64_events.cc index 0ad89f8bd..4db5df067 100644 --- a/src/kern/tru64/tru64_events.cc +++ b/src/kern/tru64/tru64_events.cc @@ -54,7 +54,7 @@ BadAddrEvent::process(ThreadContext *tc) uint64_t a0 = tc->readIntReg(ArgumentReg0); AddrRangeList resp; - AddrRangeList snoop; + bool snoop; AddrRangeIter iter; bool found = false; diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc index 9509aea38..04b0308e1 100644 --- a/src/mem/bridge.cc +++ b/src/mem/bridge.cc @@ -367,7 +367,7 @@ Bridge::BridgePort::recvStatusChange(Port::Status status) void Bridge::BridgePort::getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop) + bool &snoop) { otherPort->getPeerAddressRanges(resp, snoop); } diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh index a47fe3c1e..89d626611 100644 --- a/src/mem/bridge.hh +++ b/src/mem/bridge.hh @@ -182,7 +182,7 @@ class Bridge : public MemObject /** When receiving a address range request the peer port, pass it to the bridge. */ virtual void getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop); + bool &snoop); }; BridgePort portA, portB; diff --git a/src/mem/bus.cc b/src/mem/bus.cc index 95d4e2873..1f96115b8 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -296,16 +296,15 @@ Bus::findPort(Addr addr, int id) { /* An interval tree would be a better way to do this. --ali. */ int dest_id = -1; - AddrRangeIter iter; - range_map<Addr,int>::iterator i; - i = portMap.find(RangeSize(addr,1)); + PortIter i = portMap.find(RangeSize(addr,1)); if (i != portMap.end()) dest_id = i->second; // Check if this matches the default range if (dest_id == -1) { - for (iter = defaultRange.begin(); iter != defaultRange.end(); iter++) { + for (AddrRangeIter iter = defaultRange.begin(); + iter != defaultRange.end(); iter++) { if (*iter == addr) { DPRINTF(Bus, " found addr %#llx on default\n", addr); return defaultPort; @@ -333,88 +332,63 @@ Bus::findPort(Addr addr, int id) return interfaces[dest_id]; } -std::vector<int> -Bus::findSnoopPorts(Addr addr, int id) -{ - int i = 0; - AddrRangeIter iter; - std::vector<int> ports; - - while (i < portSnoopList.size()) - { - if (portSnoopList[i].range == addr && portSnoopList[i].portId != id) { - //Careful to not overlap ranges - //or snoop will be called more than once on the port - - //@todo Fix this hack because ranges are overlapping - //need to make sure we dont't create overlapping ranges - bool hack_overlap = false; - int size = ports.size(); - for (int j=0; j < size; j++) { - if (ports[j] == portSnoopList[i].portId) - hack_overlap = true; - } - - if (!hack_overlap) - ports.push_back(portSnoopList[i].portId); -// DPRINTF(Bus, " found snoop addr %#llx on device%d\n", addr, -// portSnoopList[i].portId); - } - i++; - } - return ports; -} - Tick Bus::atomicSnoop(PacketPtr pkt, Port *responder) { - std::vector<int> ports = findSnoopPorts(pkt->getAddr(), pkt->getSrc()); Tick response_time = 0; - while (!ports.empty()) - { - if (interfaces[ports.back()] != responder) { - Tick response = interfaces[ports.back()]->sendAtomic(pkt); + for (SnoopIter s_iter = snoopPorts.begin(); + s_iter != snoopPorts.end(); + s_iter++) { + BusPort *p = *s_iter; + if (p != responder && p->getId() != pkt->getSrc()) { + Tick response = p->sendAtomic(pkt); if (response) { assert(!response_time); //Multiple responders response_time = response; } } - ports.pop_back(); } + return response_time; } void Bus::functionalSnoop(PacketPtr pkt, Port *responder) { - std::vector<int> ports = findSnoopPorts(pkt->getAddr(), pkt->getSrc()); - - //The packet may be changed by another bus on snoops, restore the id after each - int id = pkt->getSrc(); - while (!ports.empty() && pkt->result != Packet::Success) - { - if (interfaces[ports.back()] != responder) - interfaces[ports.back()]->sendFunctional(pkt); - ports.pop_back(); - pkt->setSrc(id); + // The packet may be changed by another bus on snoops, restore the + // id after each + int src_id = pkt->getSrc(); + + for (SnoopIter s_iter = snoopPorts.begin(); + s_iter != snoopPorts.end(); + s_iter++) { + BusPort *p = *s_iter; + if (p != responder && p->getId() != src_id) { + p->sendFunctional(pkt); + } + if (pkt->result == Packet::Success) { + break; + } + pkt->setSrc(src_id); } } bool Bus::timingSnoop(PacketPtr pkt, Port* responder) { - std::vector<int> ports = findSnoopPorts(pkt->getAddr(), pkt->getSrc()); - bool success = true; - - while (!ports.empty() && success) - { - if (interfaces[ports.back()] != responder) //Don't call if responder also, once will do - success = interfaces[ports.back()]->sendTiming(pkt); - ports.pop_back(); + for (SnoopIter s_iter = snoopPorts.begin(); + s_iter != snoopPorts.end(); + s_iter++) { + BusPort *p = *s_iter; + if (p != responder && p->getId() != pkt->getSrc()) { + bool success = p->sendTiming(pkt); + if (!success) + return false; + } } - return success; + return true; } @@ -467,7 +441,7 @@ void Bus::recvStatusChange(Port::Status status, int id) { AddrRangeList ranges; - AddrRangeList snoops; + bool snoops; AddrRangeIter iter; assert(status == Port::RangeChange && @@ -480,7 +454,7 @@ Bus::recvStatusChange(Port::Status status, int id) // Only try to update these ranges if the user set a default responder. if (responderSet) { defaultPort->getPeerAddressRanges(ranges, snoops); - assert(snoops.size() == 0); + assert(snoops == false); for(iter = ranges.begin(); iter != ranges.end(); iter++) { defaultRange.push_back(*iter); DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for default range\n", @@ -490,39 +464,33 @@ Bus::recvStatusChange(Port::Status status, int id) } else { assert((id < maxId && id >= 0) || id == defaultId); - Port *port = interfaces[id]; - range_map<Addr,int>::iterator portIter; - std::vector<DevMap>::iterator snoopIter; + BusPort *port = interfaces[id]; // Clean out any previously existent ids - for (portIter = portMap.begin(); portIter != portMap.end(); ) { + for (PortIter portIter = portMap.begin(); + portIter != portMap.end(); ) { if (portIter->second == id) portMap.erase(portIter++); else portIter++; } - for (snoopIter = portSnoopList.begin(); snoopIter != portSnoopList.end(); ) { - if (snoopIter->portId == id) - snoopIter = portSnoopList.erase(snoopIter); + for (SnoopIter s_iter = snoopPorts.begin(); + s_iter != snoopPorts.end(); ) { + if ((*s_iter)->getId() == id) + s_iter = snoopPorts.erase(s_iter); else - snoopIter++; + s_iter++; } port->getPeerAddressRanges(ranges, snoops); - for(iter = snoops.begin(); iter != snoops.end(); iter++) { - DevMap dm; - dm.portId = id; - dm.range = *iter; - - //@todo, make sure we don't overlap ranges - DPRINTF(BusAddrRanges, "Adding snoop range %#llx - %#llx for id %d\n", - dm.range.start, dm.range.end, id); - portSnoopList.push_back(dm); + if (snoops) { + DPRINTF(BusAddrRanges, "Adding id %d to snoop list\n", id); + snoopPorts.push_back(port); } - for(iter = ranges.begin(); iter != ranges.end(); iter++) { + for (iter = ranges.begin(); iter != ranges.end(); iter++) { DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for id %d\n", iter->start, iter->end, id); if (portMap.insert(*iter, id) == portMap.end()) @@ -545,28 +513,24 @@ Bus::recvStatusChange(Port::Status status, int id) } void -Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id) +Bus::addressRanges(AddrRangeList &resp, bool &snoop, int id) { - std::vector<DevMap>::iterator snoopIter; - range_map<Addr,int>::iterator portIter; - AddrRangeIter dflt_iter; - bool subset; - resp.clear(); - snoop.clear(); + snoop = false; DPRINTF(BusAddrRanges, "received address range request, returning:\n"); - for (dflt_iter = defaultRange.begin(); dflt_iter != defaultRange.end(); - dflt_iter++) { + for (AddrRangeIter dflt_iter = defaultRange.begin(); + dflt_iter != defaultRange.end(); dflt_iter++) { resp.push_back(*dflt_iter); DPRINTF(BusAddrRanges, " -- Dflt: %#llx : %#llx\n",dflt_iter->start, dflt_iter->end); } - for (portIter = portMap.begin(); portIter != portMap.end(); portIter++) { - subset = false; - for (dflt_iter = defaultRange.begin(); dflt_iter != defaultRange.end(); - dflt_iter++) { + for (PortIter portIter = portMap.begin(); + portIter != portMap.end(); portIter++) { + bool subset = false; + for (AddrRangeIter dflt_iter = defaultRange.begin(); + dflt_iter != defaultRange.end(); dflt_iter++) { if ((portIter->first.start < dflt_iter->start && portIter->first.end >= dflt_iter->start) || (portIter->first.start < dflt_iter->end && @@ -587,15 +551,11 @@ Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id) } } - for (snoopIter = portSnoopList.begin(); - snoopIter != portSnoopList.end(); snoopIter++) - { - if (snoopIter->portId != id) { - snoop.push_back(snoopIter->range); - DPRINTF(BusAddrRanges, " -- Snoop: %#llx : %#llx\n", - snoopIter->range.start, snoopIter->range.end); - //@todo We need to properly insert snoop ranges - //not overlapping the ranges (multiple) + for (SnoopIter s_iter = snoopPorts.begin(); s_iter != snoopPorts.end(); + s_iter++) { + if ((*s_iter)->getId() != id) { + snoop = true; + break; } } } @@ -606,17 +566,17 @@ Bus::findBlockSize(int id) if (cachedBlockSizeValid) return cachedBlockSize; - int max_bs = -1, tmp_bs; - range_map<Addr,int>::iterator portIter; - std::vector<DevMap>::iterator snoopIter; - for (portIter = portMap.begin(); portIter != portMap.end(); portIter++) { - tmp_bs = interfaces[portIter->second]->peerBlockSize(); + int max_bs = -1; + + for (PortIter portIter = portMap.begin(); + portIter != portMap.end(); portIter++) { + int tmp_bs = interfaces[portIter->second]->peerBlockSize(); if (tmp_bs > max_bs) max_bs = tmp_bs; } - for (snoopIter = portSnoopList.begin(); - snoopIter != portSnoopList.end(); snoopIter++) { - tmp_bs = interfaces[snoopIter->portId]->peerBlockSize(); + for (SnoopIter s_iter = snoopPorts.begin(); + s_iter != snoopPorts.end(); s_iter++) { + int tmp_bs = (*s_iter)->peerBlockSize(); if (tmp_bs > max_bs) max_bs = tmp_bs; } diff --git a/src/mem/bus.hh b/src/mem/bus.hh index f0dc67b12..5dd98c07e 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -52,93 +52,6 @@ class Bus : public MemObject { - /** a globally unique id for this bus. */ - int busId; - /** the clock speed for the bus */ - int clock; - /** the width of the bus in bytes */ - int width; - /** the next tick at which the bus will be idle */ - Tick tickNextIdle; - - Event * drainEvent; - - - static const int defaultId = -3; //Make it unique from Broadcast - - struct DevMap { - int portId; - Range<Addr> range; - }; - range_map<Addr, int> portMap; - AddrRangeList defaultRange; - std::vector<DevMap> portSnoopList; - - /** Function called by the port when the bus is recieving a Timing - transaction.*/ - bool recvTiming(PacketPtr pkt); - - /** Function called by the port when the bus is recieving a Atomic - transaction.*/ - Tick recvAtomic(PacketPtr pkt); - - /** Function called by the port when the bus is recieving a Functional - transaction.*/ - void recvFunctional(PacketPtr pkt); - - /** Timing function called by port when it is once again able to process - * requests. */ - void recvRetry(int id); - - /** Function called by the port when the bus is recieving a status change.*/ - void recvStatusChange(Port::Status status, int id); - - /** Find which port connected to this bus (if any) should be given a packet - * with this address. - * @param addr Address to find port for. - * @param id Id of the port this packet was received from (to prevent - * loops) - * @return pointer to port that the packet should be sent out of. - */ - Port *findPort(Addr addr, int id); - - /** Find all ports with a matching snoop range, except src port. Keep in mind - * that the ranges shouldn't overlap or you will get a double snoop to the same - * interface.and the cache will assert out. - * @param addr Address to find snoop prts for. - * @param id Id of the src port of the request to avoid calling snoop on src - * @return vector of IDs to snoop on - */ - std::vector<int> findSnoopPorts(Addr addr, int id); - - /** Snoop all relevant ports atomicly. */ - Tick atomicSnoop(PacketPtr pkt, Port* responder); - - /** Snoop all relevant ports functionally. */ - void functionalSnoop(PacketPtr pkt, Port *responder); - - /** Call snoop on caches, be sure to set SNOOP_COMMIT bit if you want - * the snoop to happen - * @return True if succeds. - */ - bool timingSnoop(PacketPtr pkt, Port *responder); - - /** Process address range request. - * @param resp addresses that we can respond to - * @param snoop addresses that we would like to snoop - * @param id ide of the busport that made the request. - */ - void addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id); - - /** Occupy the bus with transmitting the packet pkt */ - void occupyBus(PacketPtr pkt); - - /** Ask everyone on the bus what their size is - * @param id id of the busport that made the request - * @return the max of all the sizes - */ - int findBlockSize(int id); - /** Declaration of the buses port type, one will be instantiated for each of the interfaces connecting to the bus. */ class BusPort : public Port @@ -198,7 +111,7 @@ class Bus : public MemObject // the 'owned' address ranges of all the other interfaces on // this bus... virtual void getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop) + bool &snoop) { bus->addressRanges(resp, snoop, id); } // Ask the bus to ask everyone on the bus what their block size is and @@ -219,6 +132,84 @@ class Bus : public MemObject const char *description(); }; + /** a globally unique id for this bus. */ + int busId; + /** the clock speed for the bus */ + int clock; + /** the width of the bus in bytes */ + int width; + /** the next tick at which the bus will be idle */ + Tick tickNextIdle; + + Event * drainEvent; + + + static const int defaultId = -3; //Make it unique from Broadcast + + typedef range_map<Addr,int>::iterator PortIter; + range_map<Addr, int> portMap; + + AddrRangeList defaultRange; + + typedef std::vector<BusPort*>::iterator SnoopIter; + std::vector<BusPort*> snoopPorts; + + /** Function called by the port when the bus is recieving a Timing + transaction.*/ + bool recvTiming(PacketPtr pkt); + + /** Function called by the port when the bus is recieving a Atomic + transaction.*/ + Tick recvAtomic(PacketPtr pkt); + + /** Function called by the port when the bus is recieving a Functional + transaction.*/ + void recvFunctional(PacketPtr pkt); + + /** Timing function called by port when it is once again able to process + * requests. */ + void recvRetry(int id); + + /** Function called by the port when the bus is recieving a status change.*/ + void recvStatusChange(Port::Status status, int id); + + /** Find which port connected to this bus (if any) should be given a packet + * with this address. + * @param addr Address to find port for. + * @param id Id of the port this packet was received from (to prevent + * loops) + * @return pointer to port that the packet should be sent out of. + */ + Port *findPort(Addr addr, int id); + + /** Snoop all relevant ports atomicly. */ + Tick atomicSnoop(PacketPtr pkt, Port* responder); + + /** Snoop all relevant ports functionally. */ + void functionalSnoop(PacketPtr pkt, Port *responder); + + /** Call snoop on caches, be sure to set SNOOP_COMMIT bit if you want + * the snoop to happen + * @return True if succeds. + */ + bool timingSnoop(PacketPtr pkt, Port *responder); + + /** Process address range request. + * @param resp addresses that we can respond to + * @param snoop addresses that we would like to snoop + * @param id ide of the busport that made the request. + */ + void addressRanges(AddrRangeList &resp, bool &snoop, int id); + + /** Occupy the bus with transmitting the packet pkt */ + void occupyBus(PacketPtr pkt); + + /** Ask everyone on the bus what their size is + * @param id id of the busport that made the request + * @return the max of all the sizes + */ + int findBlockSize(int id); + BusFreeEvent busIdle; bool inRetry; diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index 3ed4b84d1..8aac02460 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -59,8 +59,7 @@ BaseCache::CachePort::recvStatusChange(Port::Status status) } void -BaseCache::CachePort::getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop) +BaseCache::CachePort::getDeviceAddressRanges(AddrRangeList &resp, bool &snoop) { cache->getAddressRanges(resp, snoop, isCpuSide); } diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh index e45e36fa0..f06a79dc0 100644 --- a/src/mem/cache/base_cache.hh +++ b/src/mem/cache/base_cache.hh @@ -87,7 +87,7 @@ class BaseCache : public MemObject virtual void recvStatusChange(Status status); virtual void getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop); + bool &snoop); virtual int deviceBlockSize(); @@ -656,19 +656,18 @@ class BaseCache : public MemObject */ void rangeChange() {} - void getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop, bool isCpuSide) + void getAddressRanges(AddrRangeList &resp, bool &snoop, bool isCpuSide) { if (isCpuSide) { - AddrRangeList dummy; + bool dummy; memSidePort->getPeerAddressRanges(resp, dummy); } else { //This is where snoops get updated AddrRangeList dummy; - cpuSidePort->getPeerAddressRanges(dummy, snoop); - return; + snoop = true; } } diff --git a/src/mem/physical.cc b/src/mem/physical.cc index 5d7d7382a..6621c36cf 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -52,7 +52,7 @@ using namespace std; using namespace TheISA; PhysicalMemory::PhysicalMemory(Params *p) - : MemObject(p->name), pmemAddr(NULL), port(NULL), lat(p->latency), _params(p) + : MemObject(p->name), pmemAddr(NULL), lat(p->latency), _params(p) { if (params()->addrRange.size() % TheISA::PageBytes != 0) panic("Memory Size not divisible by page size\n"); @@ -76,9 +76,14 @@ PhysicalMemory::PhysicalMemory(Params *p) void PhysicalMemory::init() { - if (!port) - panic("PhysicalMemory not connected to anything!"); - port->sendStatusChange(Port::RangeChange); + if (ports.size() == 0) { + fatal("PhysicalMemory object %s is unconnected!", name()); + } + + for (PortIterator pi = ports.begin(); pi != ports.end(); ++pi) { + if (*pi) + (*pi)->sendStatusChange(Port::RangeChange); + } } PhysicalMemory::~PhysicalMemory() @@ -335,19 +340,33 @@ PhysicalMemory::doFunctionalAccess(PacketPtr pkt) Port * PhysicalMemory::getPort(const std::string &if_name, int idx) { - if (if_name == "port" && idx == -1) { - if (port != NULL) - panic("PhysicalMemory::getPort: additional port requested to memory!"); - port = new MemoryPort(name() + "-port", this); - return port; - } else if (if_name == "functional") { - /* special port for functional writes at startup. And for memtester */ - return new MemoryPort(name() + "-funcport", this); - } else { + // Accept request for "functional" port for backwards compatibility + // with places where this function is called from C++. I'd prefer + // to move all these into Python someday. + if (if_name == "functional") { + return new MemoryPort(csprintf("%s-functional", name()), this); + } + + if (if_name != "port") { panic("PhysicalMemory::getPort: unknown port %s requested", if_name); } + + if (idx >= ports.size()) { + ports.resize(idx+1); + } + + if (ports[idx] != NULL) { + panic("PhysicalMemory::getPort: port %d already assigned", idx); + } + + MemoryPort *port = + new MemoryPort(csprintf("%s-port%d", name(), idx), this); + + ports[idx] = port; + return port; } + void PhysicalMemory::recvStatusChange(Port::Status status) { @@ -366,18 +385,17 @@ PhysicalMemory::MemoryPort::recvStatusChange(Port::Status status) void PhysicalMemory::MemoryPort::getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop) + bool &snoop) { memory->getAddressRanges(resp, snoop); } void -PhysicalMemory::getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) +PhysicalMemory::getAddressRanges(AddrRangeList &resp, bool &snoop) { - snoop.clear(); + snoop = false; resp.clear(); - resp.push_back(RangeSize(start(), - params()->addrRange.size())); + resp.push_back(RangeSize(start(), params()->addrRange.size())); } int @@ -420,7 +438,11 @@ PhysicalMemory::MemoryPort::recvFunctional(PacketPtr pkt) unsigned int PhysicalMemory::drain(Event *de) { - int count = port->drain(de); + int count = 0; + for (PortIterator pi = ports.begin(); pi != ports.end(); ++pi) { + count += (*pi)->drain(de); + } + if (count) changeState(Draining); else diff --git a/src/mem/physical.hh b/src/mem/physical.hh index f7200b502..b9af5d334 100644 --- a/src/mem/physical.hh +++ b/src/mem/physical.hh @@ -64,7 +64,7 @@ class PhysicalMemory : public MemObject virtual void recvStatusChange(Status status); virtual void getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop); + bool &snoop); virtual int deviceBlockSize(); }; @@ -141,9 +141,10 @@ class PhysicalMemory : public MemObject } uint8_t *pmemAddr; - MemoryPort *port; int pagePtr; Tick lat; + std::vector<MemoryPort*> ports; + typedef std::vector<MemoryPort*>::iterator PortIterator; public: Addr new_page(); @@ -168,7 +169,7 @@ class PhysicalMemory : public MemObject public: int deviceBlockSize(); - void getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop); + void getAddressRanges(AddrRangeList &resp, bool &snoop); virtual Port *getPort(const std::string &if_name, int idx = -1); void virtual init(); unsigned int drain(Event *de); diff --git a/src/mem/port.hh b/src/mem/port.hh index 877e00293..b23de6050 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -172,7 +172,7 @@ class Port @param snoop is a list of ranges snooped */ virtual void getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop) + bool &snoop) { panic("??"); } public: @@ -222,7 +222,7 @@ class Port /** Called by the associated device if it wishes to find out the address ranges connected to the peer ports devices. */ - void getPeerAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) + void getPeerAddressRanges(AddrRangeList &resp, bool &snoop) { peer->getDeviceAddressRanges(resp, snoop); } /** This function is a wrapper around sendFunctional() diff --git a/src/python/m5/objects/PhysicalMemory.py b/src/python/m5/objects/PhysicalMemory.py index c389e4a7f..83dbc7710 100644 --- a/src/python/m5/objects/PhysicalMemory.py +++ b/src/python/m5/objects/PhysicalMemory.py @@ -4,8 +4,7 @@ from MemObject import * class PhysicalMemory(MemObject): type = 'PhysicalMemory' - port = Port("the access port") - functional = Port("Functional Access Port") + port = VectorPort("the access port") range = Param.AddrRange(AddrRange('128MB'), "Device Address") file = Param.String('', "memory mapped file") latency = Param.Latency('1t', "latency of an access") diff --git a/src/python/swig/pyobject.cc b/src/python/swig/pyobject.cc index 11141fa84..2a5f2b9fb 100644 --- a/src/python/swig/pyobject.cc +++ b/src/python/swig/pyobject.cc @@ -62,6 +62,7 @@ lookupPort(SimObject *so, const std::string &name, int i) /** * Connect the described MemObject ports. Called from Python via SWIG. + * The indices i1 & i2 will be -1 for regular ports, >= 0 for vector ports. */ int connectPorts(SimObject *o1, const std::string &name1, int i1, diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index 974313968..6fbba46d5 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -293,13 +293,25 @@ class EventWrapper : public Event T *object; public: - EventWrapper(T *obj, bool del = false, EventQueue *q = &mainEventQueue, + EventWrapper(T *obj, bool del = false, + EventQueue *q = &mainEventQueue, Priority p = Default_Pri) : Event(q, p), object(obj) { if (del) setFlags(AutoDelete); } + + EventWrapper(T *obj, Tick t, bool del = false, + EventQueue *q = &mainEventQueue, + Priority p = Default_Pri) + : Event(q, p), object(obj) + { + if (del) + setFlags(AutoDelete); + schedule(t); + } + void process() { (object->*F)(); } }; |