You've moved a lot of #if 0 code here. Is this code useful? What is needed to make it work?
Nate On Sat, Dec 12, 2009 at 2:37 PM, Brad Beckmann <[email protected]> wrote: > # HG changeset patch > # User Brad Beckmann <[email protected]> > # Date 1260657435 28800 > # Node ID f164db9baf4ad51cf790ea3b134fed28f4e3d026 > # Parent 5d3a90f0ef4c0f69f61fd262028a32fa5e632f8e > ruby: Copy M5 Port code from RubyMemory to RubyPort. > > diff -r 5d3a90f0ef4c -r f164db9baf4a src/mem/ruby/system/RubyPort.cc > --- a/src/mem/ruby/system/RubyPort.cc Sat Dec 12 14:37:14 2009 -0800 > +++ b/src/mem/ruby/system/RubyPort.cc Sat Dec 12 14:37:15 2009 -0800 > @@ -5,8 +5,11 @@ > //void (*RubyPort::m_hit_callback)(int64_t) = NULL; > uint16_t RubyPort::m_num_ports = 0; > > +RubyPort::RequestMap RubyPort::pending_requests; > + > RubyPort::RubyPort(const Params *p) > - : MemObject(p) > + : MemObject(p), > + funcMemPort(csprintf("%s-funcmem_port", name()), this) > { > m_version = p->version; > assert(m_version != -1); > @@ -24,5 +27,196 @@ > Port * > RubyPort::getPort(const std::string &if_name, int idx) > { > + if (if_name == "port") { > + return new M5Port(csprintf("%s-port%d", name(), idx), this); > + } else if (if_name == "funcmem_port") { > + return &funcMemPort; > + } > return NULL; > } > + > +RubyPort::M5Port::M5Port(const std::string &_name, > + RubyPort *_port) > + : SimpleTimingPort(_name, _port) > +{ > + DPRINTF(Ruby, "creating port to ruby memory %s\n", _name); > + ruby_port = _port; > +} > + > +Tick > +RubyPort::M5Port::recvAtomic(PacketPtr pkt) > +{ > + panic("RubyPort::M5Port::recvAtomic() not implemented!\n"); > + return 0; > +} > + > + > +bool > +RubyPort::M5Port::recvTiming(PacketPtr pkt) > +{ > + DPRINTF(MemoryAccess, > + "Timing access caught for address %#x\n", > + pkt->getAddr()); > + > + //dsm: based on SimpleTimingPort::recvTiming(pkt); > + > + // > + // In FS mode, ruby memory will receive pio responses from devices and > + // it must forward these responses back to the particular CPU. > + // > +#if 0 > + if (pkt->isResponse() != false && isPioAddress(pkt->getAddr()) != false) { > + DPRINTF(MemoryAccess, > + "Pio Response callback %#x\n", > + pkt->getAddr()); > + SenderState *senderState = safe_cast<SenderState > *>(pkt->senderState); > + M5Port *port = senderState->port; > + > + // pop the sender state from the packet > + pkt->senderState = senderState->saved; > + delete senderState; > + > + port->sendTiming(pkt); > + > + return true; > + } > +#endif > + > + // > + // After checking for pio responses, the remainder of packets > + // received by ruby should only be M5 requests, which should never > + // get nacked. There used to be code to hanldle nacks here, but > + // I'm pretty sure it didn't work correctly with the drain code, > + // so that would need to be fixed if we ever added it back. > + // > + assert(pkt->isRequest()); > + > + if (pkt->memInhibitAsserted()) { > + warn("memInhibitAsserted???"); > + // snooper will supply based on copy of packet > + // still target's responsibility to delete packet > + delete pkt; > + return true; > + } > + > + // > + // Check for pio requests and directly send them to the dedicated > + // pio_port. > + // > +#if 0 > + if (isPioAddress(pkt->getAddr()) != false) { > + return ruby_mem->pio_port->sendTiming(pkt); > + } > +#endif > + > + // > + // For DMA and CPU requests, translate them to ruby requests before > + // sending them to our assigned ruby port. > + // > + RubyRequestType type = RubyRequestType_NULL; > + Addr pc = 0; > + if (pkt->isRead()) { > + if (pkt->req->isInstFetch()) { > + type = RubyRequestType_IFETCH; > + pc = pkt->req->getPC(); > + } else { > + type = RubyRequestType_LD; > + } > + } else if (pkt->isWrite()) { > + type = RubyRequestType_ST; > + } else if (pkt->isReadWrite()) { > + // type = RubyRequestType_RMW; > + } > + > + RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(), > + pkt->getSize(), pc, type, > + RubyAccessMode_Supervisor); > + > + // Submit the ruby request > + int64_t req_id = ruby_port->makeRequest(ruby_request); > + if (req_id == -1) { > + return false; > + } > + > + // Save the request for the callback > + RubyPort::pending_requests[req_id] = new RequestCookie(pkt, this); > + > + return true; > +} > + > +void > +RubyPort::ruby_hit_callback(int64_t req_id) > +{ > + // > + // Note: This single fuction can be called by cpu and dma ports, > + // as well as the functional port. The functional port prevents > + // us from replacing this single function with separate port > + // functions. > + // > + RequestMap::iterator i = pending_requests.find(req_id); > + if (i == pending_requests.end()) > + panic("could not find pending request %d\n", req_id); > + > + RequestCookie *cookie = i->second; > + pending_requests.erase(i); > + > + Packet *pkt = cookie->pkt; > + M5Port *port = cookie->m5Port; > + delete cookie; > + > + port->hitCallback(pkt); > +} > + > +void > +RubyPort::M5Port::hitCallback(PacketPtr pkt) > +{ > + > + bool needsResponse = pkt->needsResponse(); > + > + DPRINTF(MemoryAccess, "Hit callback needs response %d\n", > + needsResponse); > + > + ruby_port->funcMemPort.sendFunctional(pkt); > + > + // turn packet around to go back to requester if response expected > + if (needsResponse) { > + // recvAtomic() should already have turned packet into > + // atomic response > + assert(pkt->isResponse()); > + DPRINTF(MemoryAccess, "Sending packet back over port\n"); > + sendTiming(pkt); > + } else { > + delete pkt; > + } > + DPRINTF(MemoryAccess, "Hit callback done!\n"); > +} > + > +bool > +RubyPort::M5Port::sendTiming(PacketPtr pkt) > +{ > + schedSendTiming(pkt, curTick + 1); //minimum latency, must be > 0 > + return true; > +} > + > +bool > +RubyPort::M5Port::isPioAddress(Addr addr) > +{ > +#if 0 > + AddrRangeList pioAddrList; > + bool snoop = false; > + if (ruby_mem->pio_port == NULL) { > + return false; > + } > + > + ruby_mem->pio_port->getPeerAddressRanges(pioAddrList, snoop); > + for(AddrRangeIter iter = pioAddrList.begin(); iter != pioAddrList.end(); > iter++) { > + if (addr >= iter->start && addr <= iter->end) { > + DPRINTF(MemoryAccess, "Pio request found in %#llx - %#llx > range\n", > + iter->start, iter->end); > + return true; > + } > + } > +#endif > + return false; > +} > + > diff -r 5d3a90f0ef4c -r f164db9baf4a src/mem/ruby/system/RubyPort.hh > --- a/src/mem/ruby/system/RubyPort.hh Sat Dec 12 14:37:14 2009 -0800 > +++ b/src/mem/ruby/system/RubyPort.hh Sat Dec 12 14:37:15 2009 -0800 > @@ -17,6 +17,28 @@ > > class RubyPort : public MemObject { > public: > + > + class M5Port : public SimpleTimingPort > + { > + > + RubyPort *ruby_port; > + > + public: > + M5Port(const std::string &_name, > + RubyPort *_port); > + bool sendTiming(PacketPtr pkt); > + void hitCallback(PacketPtr pkt); > + > + protected: > + virtual bool recvTiming(PacketPtr pkt); > + virtual Tick recvAtomic(PacketPtr pkt); > + > + private: > + bool isPioAddress(Addr addr); > + }; > + > + friend class M5Port; > + > typedef RubyPortParams Params; > RubyPort(const Params *p); > virtual ~RubyPort() {} > @@ -63,6 +85,20 @@ > static uint16_t m_num_ports; > uint16_t m_port_id; > uint64_t m_request_cnt; > + > + struct RequestCookie { > + Packet *pkt; > + M5Port *m5Port; > + RequestCookie(Packet *p, M5Port *m5p) > + : pkt(p), m5Port(m5p) > + {} > + }; > + > + typedef std::map<int64_t, RequestCookie*> RequestMap; > + static RequestMap pending_requests; > + static void ruby_hit_callback(int64_t req_id); > + > + FunctionalPort funcMemPort; > }; > > #endif > > _______________________________________________ > m5-dev mailing list > [email protected] > http://m5sim.org/mailman/listinfo/m5-dev > > _______________________________________________ m5-dev mailing list [email protected] http://m5sim.org/mailman/listinfo/m5-dev
