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

Reply via email to