RubyPort.cc revision 7023
16285Snate@binkert.org 26876Ssteve.reinhardt@amd.com/* 36876Ssteve.reinhardt@amd.com * Copyright (c) 2009 Advanced Micro Devices, Inc. 46876Ssteve.reinhardt@amd.com * All rights reserved. 56876Ssteve.reinhardt@amd.com * 66876Ssteve.reinhardt@amd.com * Redistribution and use in source and binary forms, with or without 76876Ssteve.reinhardt@amd.com * modification, are permitted provided that the following conditions are 86876Ssteve.reinhardt@amd.com * met: redistributions of source code must retain the above copyright 96876Ssteve.reinhardt@amd.com * notice, this list of conditions and the following disclaimer; 106876Ssteve.reinhardt@amd.com * redistributions in binary form must reproduce the above copyright 116876Ssteve.reinhardt@amd.com * notice, this list of conditions and the following disclaimer in the 126876Ssteve.reinhardt@amd.com * documentation and/or other materials provided with the distribution; 136876Ssteve.reinhardt@amd.com * neither the name of the copyright holders nor the names of its 146876Ssteve.reinhardt@amd.com * contributors may be used to endorse or promote products derived from 156876Ssteve.reinhardt@amd.com * this software without specific prior written permission. 166876Ssteve.reinhardt@amd.com * 176876Ssteve.reinhardt@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 186876Ssteve.reinhardt@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 196876Ssteve.reinhardt@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 206876Ssteve.reinhardt@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 216876Ssteve.reinhardt@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 226876Ssteve.reinhardt@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 236876Ssteve.reinhardt@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 246876Ssteve.reinhardt@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 256876Ssteve.reinhardt@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 266876Ssteve.reinhardt@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 276876Ssteve.reinhardt@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 286876Ssteve.reinhardt@amd.com */ 296876Ssteve.reinhardt@amd.com 306876Ssteve.reinhardt@amd.com#include "mem/physical.hh" 316285Snate@binkert.org#include "mem/ruby/system/RubyPort.hh" 326876Ssteve.reinhardt@amd.com#include "mem/ruby/slicc_interface/AbstractController.hh" 336899SBrad.Beckmann@amd.com#include "cpu/rubytest/RubyTester.hh" 346285Snate@binkert.org 356876Ssteve.reinhardt@amd.comRubyPort::RubyPort(const Params *p) 366893SBrad.Beckmann@amd.com : MemObject(p) 376876Ssteve.reinhardt@amd.com{ 386876Ssteve.reinhardt@amd.com m_version = p->version; 396876Ssteve.reinhardt@amd.com assert(m_version != -1); 406876Ssteve.reinhardt@amd.com 416893SBrad.Beckmann@amd.com physmem = p->physmem; 426893SBrad.Beckmann@amd.com 436882SBrad.Beckmann@amd.com m_controller = NULL; 446882SBrad.Beckmann@amd.com m_mandatory_q_ptr = NULL; 456876Ssteve.reinhardt@amd.com 466876Ssteve.reinhardt@amd.com m_request_cnt = 0; 476882SBrad.Beckmann@amd.com pio_port = NULL; 486893SBrad.Beckmann@amd.com physMemPort = NULL; 496876Ssteve.reinhardt@amd.com} 506876Ssteve.reinhardt@amd.com 516882SBrad.Beckmann@amd.comvoid RubyPort::init() 526882SBrad.Beckmann@amd.com{ 536882SBrad.Beckmann@amd.com assert(m_controller != NULL); 546882SBrad.Beckmann@amd.com m_mandatory_q_ptr = m_controller->getMandatoryQueue(); 556882SBrad.Beckmann@amd.com} 566882SBrad.Beckmann@amd.com 576876Ssteve.reinhardt@amd.comPort * 586876Ssteve.reinhardt@amd.comRubyPort::getPort(const std::string &if_name, int idx) 596876Ssteve.reinhardt@amd.com{ 606882SBrad.Beckmann@amd.com if (if_name == "port") { 616882SBrad.Beckmann@amd.com return new M5Port(csprintf("%s-port%d", name(), idx), this); 626882SBrad.Beckmann@amd.com } else if (if_name == "pio_port") { 636882SBrad.Beckmann@amd.com // 646882SBrad.Beckmann@amd.com // ensure there is only one pio port 656882SBrad.Beckmann@amd.com // 666882SBrad.Beckmann@amd.com assert(pio_port == NULL); 676882SBrad.Beckmann@amd.com 686882SBrad.Beckmann@amd.com pio_port = new PioPort(csprintf("%s-pio-port%d", name(), idx), 696882SBrad.Beckmann@amd.com this); 706882SBrad.Beckmann@amd.com 716882SBrad.Beckmann@amd.com return pio_port; 726893SBrad.Beckmann@amd.com } else if (if_name == "physMemPort") { 736893SBrad.Beckmann@amd.com // 746893SBrad.Beckmann@amd.com // RubyPort should only have one port to physical memory 756893SBrad.Beckmann@amd.com // 766893SBrad.Beckmann@amd.com assert (physMemPort == NULL); 776893SBrad.Beckmann@amd.com 786893SBrad.Beckmann@amd.com physMemPort = new M5Port(csprintf("%s-physMemPort", name()), 796893SBrad.Beckmann@amd.com this); 806893SBrad.Beckmann@amd.com 816893SBrad.Beckmann@amd.com return physMemPort; 826893SBrad.Beckmann@amd.com } else if (if_name == "functional") { 836893SBrad.Beckmann@amd.com // 846893SBrad.Beckmann@amd.com // Calls for the functional port only want to access functional memory. 856893SBrad.Beckmann@amd.com // Therefore, directly pass these calls ports to physmem. 866893SBrad.Beckmann@amd.com // 876893SBrad.Beckmann@amd.com assert(physmem != NULL); 886893SBrad.Beckmann@amd.com return physmem->getPort(if_name, idx); 896882SBrad.Beckmann@amd.com } 906876Ssteve.reinhardt@amd.com return NULL; 916876Ssteve.reinhardt@amd.com} 926882SBrad.Beckmann@amd.com 936882SBrad.Beckmann@amd.comRubyPort::PioPort::PioPort(const std::string &_name, 946882SBrad.Beckmann@amd.com RubyPort *_port) 956882SBrad.Beckmann@amd.com : SimpleTimingPort(_name, _port) 966882SBrad.Beckmann@amd.com{ 976882SBrad.Beckmann@amd.com DPRINTF(Ruby, "creating port to ruby sequencer to cpu %s\n", _name); 986882SBrad.Beckmann@amd.com ruby_port = _port; 996882SBrad.Beckmann@amd.com} 1006882SBrad.Beckmann@amd.com 1016882SBrad.Beckmann@amd.comRubyPort::M5Port::M5Port(const std::string &_name, 1026882SBrad.Beckmann@amd.com RubyPort *_port) 1036882SBrad.Beckmann@amd.com : SimpleTimingPort(_name, _port) 1046882SBrad.Beckmann@amd.com{ 1056882SBrad.Beckmann@amd.com DPRINTF(Ruby, "creating port from ruby sequcner to cpu %s\n", _name); 1066882SBrad.Beckmann@amd.com ruby_port = _port; 1076882SBrad.Beckmann@amd.com} 1086882SBrad.Beckmann@amd.com 1096882SBrad.Beckmann@amd.comTick 1106882SBrad.Beckmann@amd.comRubyPort::PioPort::recvAtomic(PacketPtr pkt) 1116882SBrad.Beckmann@amd.com{ 1126882SBrad.Beckmann@amd.com panic("RubyPort::PioPort::recvAtomic() not implemented!\n"); 1136882SBrad.Beckmann@amd.com return 0; 1146882SBrad.Beckmann@amd.com} 1156882SBrad.Beckmann@amd.com 1166882SBrad.Beckmann@amd.com 1176882SBrad.Beckmann@amd.comTick 1186882SBrad.Beckmann@amd.comRubyPort::M5Port::recvAtomic(PacketPtr pkt) 1196882SBrad.Beckmann@amd.com{ 1206882SBrad.Beckmann@amd.com panic("RubyPort::M5Port::recvAtomic() not implemented!\n"); 1216882SBrad.Beckmann@amd.com return 0; 1226882SBrad.Beckmann@amd.com} 1236882SBrad.Beckmann@amd.com 1246882SBrad.Beckmann@amd.com 1256882SBrad.Beckmann@amd.combool 1266882SBrad.Beckmann@amd.comRubyPort::PioPort::recvTiming(PacketPtr pkt) 1276882SBrad.Beckmann@amd.com{ 1286882SBrad.Beckmann@amd.com // 1296882SBrad.Beckmann@amd.com // In FS mode, ruby memory will receive pio responses from devices and 1306882SBrad.Beckmann@amd.com // it must forward these responses back to the particular CPU. 1316882SBrad.Beckmann@amd.com // 1326882SBrad.Beckmann@amd.com DPRINTF(MemoryAccess, 1336882SBrad.Beckmann@amd.com "Pio response for address %#x\n", 1346882SBrad.Beckmann@amd.com pkt->getAddr()); 1356882SBrad.Beckmann@amd.com 1366882SBrad.Beckmann@amd.com assert(pkt->isResponse()); 1376882SBrad.Beckmann@amd.com 1386882SBrad.Beckmann@amd.com // 1396882SBrad.Beckmann@amd.com // First we must retrieve the request port from the sender State 1406882SBrad.Beckmann@amd.com // 1416882SBrad.Beckmann@amd.com RubyPort::SenderState *senderState = 1426882SBrad.Beckmann@amd.com safe_cast<RubyPort::SenderState *>(pkt->senderState); 1436882SBrad.Beckmann@amd.com M5Port *port = senderState->port; 1446882SBrad.Beckmann@amd.com assert(port != NULL); 1456882SBrad.Beckmann@amd.com 1466882SBrad.Beckmann@amd.com // pop the sender state from the packet 1476882SBrad.Beckmann@amd.com pkt->senderState = senderState->saved; 1486882SBrad.Beckmann@amd.com delete senderState; 1496882SBrad.Beckmann@amd.com 1506882SBrad.Beckmann@amd.com port->sendTiming(pkt); 1516882SBrad.Beckmann@amd.com 1526882SBrad.Beckmann@amd.com return true; 1536882SBrad.Beckmann@amd.com} 1546882SBrad.Beckmann@amd.com 1556882SBrad.Beckmann@amd.combool 1566882SBrad.Beckmann@amd.comRubyPort::M5Port::recvTiming(PacketPtr pkt) 1576882SBrad.Beckmann@amd.com{ 1586882SBrad.Beckmann@amd.com DPRINTF(MemoryAccess, 1596882SBrad.Beckmann@amd.com "Timing access caught for address %#x\n", 1606882SBrad.Beckmann@amd.com pkt->getAddr()); 1616882SBrad.Beckmann@amd.com 1626882SBrad.Beckmann@amd.com //dsm: based on SimpleTimingPort::recvTiming(pkt); 1636882SBrad.Beckmann@amd.com 1646882SBrad.Beckmann@amd.com // 1656922SBrad.Beckmann@amd.com // The received packets should only be M5 requests, which should never 1666882SBrad.Beckmann@amd.com // get nacked. There used to be code to hanldle nacks here, but 1676882SBrad.Beckmann@amd.com // I'm pretty sure it didn't work correctly with the drain code, 1686882SBrad.Beckmann@amd.com // so that would need to be fixed if we ever added it back. 1696882SBrad.Beckmann@amd.com // 1706882SBrad.Beckmann@amd.com assert(pkt->isRequest()); 1716882SBrad.Beckmann@amd.com 1726882SBrad.Beckmann@amd.com if (pkt->memInhibitAsserted()) { 1736882SBrad.Beckmann@amd.com warn("memInhibitAsserted???"); 1746882SBrad.Beckmann@amd.com // snooper will supply based on copy of packet 1756882SBrad.Beckmann@amd.com // still target's responsibility to delete packet 1766882SBrad.Beckmann@amd.com delete pkt; 1776882SBrad.Beckmann@amd.com return true; 1786882SBrad.Beckmann@amd.com } 1796882SBrad.Beckmann@amd.com 1806882SBrad.Beckmann@amd.com // 1816922SBrad.Beckmann@amd.com // Save the port in the sender state object to be used later to 1826922SBrad.Beckmann@amd.com // route the response 1836922SBrad.Beckmann@amd.com // 1846922SBrad.Beckmann@amd.com pkt->senderState = new SenderState(this, pkt->senderState); 1856922SBrad.Beckmann@amd.com 1866922SBrad.Beckmann@amd.com // 1876882SBrad.Beckmann@amd.com // Check for pio requests and directly send them to the dedicated 1886882SBrad.Beckmann@amd.com // pio port. 1896882SBrad.Beckmann@amd.com // 1906882SBrad.Beckmann@amd.com if (!isPhysMemAddress(pkt->getAddr())) { 1916882SBrad.Beckmann@amd.com assert(ruby_port->pio_port != NULL); 1926922SBrad.Beckmann@amd.com DPRINTF(MemoryAccess, 1936922SBrad.Beckmann@amd.com "Request for address 0x%#x is assumed to be a pio request\n", 1946922SBrad.Beckmann@amd.com pkt->getAddr()); 1956882SBrad.Beckmann@amd.com 1966882SBrad.Beckmann@amd.com return ruby_port->pio_port->sendTiming(pkt); 1976882SBrad.Beckmann@amd.com } 1986882SBrad.Beckmann@amd.com 1996882SBrad.Beckmann@amd.com // 2006882SBrad.Beckmann@amd.com // For DMA and CPU requests, translate them to ruby requests before 2016882SBrad.Beckmann@amd.com // sending them to our assigned ruby port. 2026882SBrad.Beckmann@amd.com // 2036882SBrad.Beckmann@amd.com RubyRequestType type = RubyRequestType_NULL; 2046899SBrad.Beckmann@amd.com 2056899SBrad.Beckmann@amd.com // 2066899SBrad.Beckmann@amd.com // If valid, copy the pc to the ruby request 2076899SBrad.Beckmann@amd.com // 2086882SBrad.Beckmann@amd.com Addr pc = 0; 2096899SBrad.Beckmann@amd.com if (pkt->req->hasPC()) { 2106899SBrad.Beckmann@amd.com pc = pkt->req->getPC(); 2116899SBrad.Beckmann@amd.com } 2126899SBrad.Beckmann@amd.com 2137023SBrad.Beckmann@amd.com if (pkt->isLLSC()) { 2147023SBrad.Beckmann@amd.com if (pkt->isWrite()) { 2157023SBrad.Beckmann@amd.com DPRINTF(MemoryAccess, "Issuing SC\n"); 2167023SBrad.Beckmann@amd.com type = RubyRequestType_Locked_Write; 2176882SBrad.Beckmann@amd.com } else { 2187023SBrad.Beckmann@amd.com DPRINTF(MemoryAccess, "Issuing LL\n"); 2197023SBrad.Beckmann@amd.com assert(pkt->isRead()); 2207023SBrad.Beckmann@amd.com type = RubyRequestType_Locked_Read; 2216882SBrad.Beckmann@amd.com } 2226922SBrad.Beckmann@amd.com } else { 2237023SBrad.Beckmann@amd.com if (pkt->isRead()) { 2247023SBrad.Beckmann@amd.com if (pkt->req->isInstFetch()) { 2257023SBrad.Beckmann@amd.com type = RubyRequestType_IFETCH; 2267023SBrad.Beckmann@amd.com } else { 2277023SBrad.Beckmann@amd.com type = RubyRequestType_LD; 2287023SBrad.Beckmann@amd.com } 2297023SBrad.Beckmann@amd.com } else if (pkt->isWrite()) { 2307023SBrad.Beckmann@amd.com type = RubyRequestType_ST; 2317023SBrad.Beckmann@amd.com } else if (pkt->isReadWrite()) { 2327023SBrad.Beckmann@amd.com // 2337023SBrad.Beckmann@amd.com // Fix me. Just because the packet is a read/write request does not 2347023SBrad.Beckmann@amd.com // necessary mean it is a read-modify-write atomic operation. 2357023SBrad.Beckmann@amd.com // 2367023SBrad.Beckmann@amd.com type = RubyRequestType_RMW_Write; 2377023SBrad.Beckmann@amd.com } else { 2387023SBrad.Beckmann@amd.com panic("Unsupported ruby packet type\n"); 2397023SBrad.Beckmann@amd.com } 2406882SBrad.Beckmann@amd.com } 2416882SBrad.Beckmann@amd.com 2426922SBrad.Beckmann@amd.com RubyRequest ruby_request(pkt->getAddr(), 2436922SBrad.Beckmann@amd.com pkt->getPtr<uint8_t>(), 2446922SBrad.Beckmann@amd.com pkt->getSize(), 2456922SBrad.Beckmann@amd.com pc, 2466922SBrad.Beckmann@amd.com type, 2476922SBrad.Beckmann@amd.com RubyAccessMode_Supervisor, 2486922SBrad.Beckmann@amd.com pkt); 2496882SBrad.Beckmann@amd.com 2506882SBrad.Beckmann@amd.com // Submit the ruby request 2516922SBrad.Beckmann@amd.com RequestStatus requestStatus = ruby_port->makeRequest(ruby_request); 2527023SBrad.Beckmann@amd.com 2537023SBrad.Beckmann@amd.com // 2547023SBrad.Beckmann@amd.com // If the request successfully issued or the SC request completed because 2557023SBrad.Beckmann@amd.com // exclusive permission was lost, then we should return true. 2567023SBrad.Beckmann@amd.com // Otherwise, we need to delete the senderStatus we just created and return 2577023SBrad.Beckmann@amd.com // false. 2587023SBrad.Beckmann@amd.com // 2597023SBrad.Beckmann@amd.com if ((requestStatus == RequestStatus_Issued) || 2607023SBrad.Beckmann@amd.com (requestStatus == RequestStatus_LlscFailed)) { 2617023SBrad.Beckmann@amd.com 2627023SBrad.Beckmann@amd.com // 2637023SBrad.Beckmann@amd.com // The communicate to M5 whether the SC command succeeded by seting the 2647023SBrad.Beckmann@amd.com // packet's extra data. 2657023SBrad.Beckmann@amd.com // 2667023SBrad.Beckmann@amd.com if (pkt->isLLSC() && pkt->isWrite()) { 2677023SBrad.Beckmann@amd.com if (requestStatus == RequestStatus_LlscFailed) { 2687023SBrad.Beckmann@amd.com DPRINTF(MemoryAccess, "SC failed and request completed\n"); 2697023SBrad.Beckmann@amd.com pkt->req->setExtraData(0); 2707023SBrad.Beckmann@amd.com } else { 2717023SBrad.Beckmann@amd.com pkt->req->setExtraData(1); 2727023SBrad.Beckmann@amd.com } 2737023SBrad.Beckmann@amd.com } 2746922SBrad.Beckmann@amd.com return true; 2756882SBrad.Beckmann@amd.com } 2767023SBrad.Beckmann@amd.com 2776922SBrad.Beckmann@amd.com DPRINTF(MemoryAccess, 2786922SBrad.Beckmann@amd.com "Request for address #x did not issue because %s\n", 2796922SBrad.Beckmann@amd.com pkt->getAddr(), 2806922SBrad.Beckmann@amd.com RequestStatus_to_string(requestStatus)); 2816922SBrad.Beckmann@amd.com 2826922SBrad.Beckmann@amd.com SenderState* senderState = safe_cast<SenderState*>(pkt->senderState); 2836922SBrad.Beckmann@amd.com pkt->senderState = senderState->saved; 2846922SBrad.Beckmann@amd.com delete senderState; 2856922SBrad.Beckmann@amd.com return false; 2866882SBrad.Beckmann@amd.com} 2876882SBrad.Beckmann@amd.com 2886882SBrad.Beckmann@amd.comvoid 2896922SBrad.Beckmann@amd.comRubyPort::ruby_hit_callback(PacketPtr pkt) 2906882SBrad.Beckmann@amd.com{ 2916882SBrad.Beckmann@amd.com // 2926922SBrad.Beckmann@amd.com // Retrieve the request port from the sender State 2936882SBrad.Beckmann@amd.com // 2946922SBrad.Beckmann@amd.com RubyPort::SenderState *senderState = 2956922SBrad.Beckmann@amd.com safe_cast<RubyPort::SenderState *>(pkt->senderState); 2966922SBrad.Beckmann@amd.com M5Port *port = senderState->port; 2976922SBrad.Beckmann@amd.com assert(port != NULL); 2986922SBrad.Beckmann@amd.com 2996922SBrad.Beckmann@amd.com // pop the sender state from the packet 3006922SBrad.Beckmann@amd.com pkt->senderState = senderState->saved; 3016922SBrad.Beckmann@amd.com delete senderState; 3026882SBrad.Beckmann@amd.com 3036882SBrad.Beckmann@amd.com port->hitCallback(pkt); 3046882SBrad.Beckmann@amd.com} 3056882SBrad.Beckmann@amd.com 3066882SBrad.Beckmann@amd.comvoid 3076882SBrad.Beckmann@amd.comRubyPort::M5Port::hitCallback(PacketPtr pkt) 3086882SBrad.Beckmann@amd.com{ 3096882SBrad.Beckmann@amd.com 3106882SBrad.Beckmann@amd.com bool needsResponse = pkt->needsResponse(); 3116882SBrad.Beckmann@amd.com 3126882SBrad.Beckmann@amd.com DPRINTF(MemoryAccess, "Hit callback needs response %d\n", 3136882SBrad.Beckmann@amd.com needsResponse); 3146882SBrad.Beckmann@amd.com 3156893SBrad.Beckmann@amd.com ruby_port->physMemPort->sendAtomic(pkt); 3166882SBrad.Beckmann@amd.com 3176882SBrad.Beckmann@amd.com // turn packet around to go back to requester if response expected 3186882SBrad.Beckmann@amd.com if (needsResponse) { 3196893SBrad.Beckmann@amd.com // sendAtomic() should already have turned packet into 3206882SBrad.Beckmann@amd.com // atomic response 3216882SBrad.Beckmann@amd.com assert(pkt->isResponse()); 3226882SBrad.Beckmann@amd.com DPRINTF(MemoryAccess, "Sending packet back over port\n"); 3236882SBrad.Beckmann@amd.com sendTiming(pkt); 3246882SBrad.Beckmann@amd.com } else { 3256882SBrad.Beckmann@amd.com delete pkt; 3266882SBrad.Beckmann@amd.com } 3276882SBrad.Beckmann@amd.com DPRINTF(MemoryAccess, "Hit callback done!\n"); 3286882SBrad.Beckmann@amd.com} 3296882SBrad.Beckmann@amd.com 3306882SBrad.Beckmann@amd.combool 3316882SBrad.Beckmann@amd.comRubyPort::M5Port::sendTiming(PacketPtr pkt) 3326882SBrad.Beckmann@amd.com{ 3336882SBrad.Beckmann@amd.com schedSendTiming(pkt, curTick + 1); //minimum latency, must be > 0 3346882SBrad.Beckmann@amd.com return true; 3356882SBrad.Beckmann@amd.com} 3366882SBrad.Beckmann@amd.com 3376882SBrad.Beckmann@amd.combool 3386882SBrad.Beckmann@amd.comRubyPort::PioPort::sendTiming(PacketPtr pkt) 3396882SBrad.Beckmann@amd.com{ 3406882SBrad.Beckmann@amd.com schedSendTiming(pkt, curTick + 1); //minimum latency, must be > 0 3416882SBrad.Beckmann@amd.com return true; 3426882SBrad.Beckmann@amd.com} 3436882SBrad.Beckmann@amd.com 3446882SBrad.Beckmann@amd.combool 3456882SBrad.Beckmann@amd.comRubyPort::M5Port::isPhysMemAddress(Addr addr) 3466882SBrad.Beckmann@amd.com{ 3476882SBrad.Beckmann@amd.com AddrRangeList physMemAddrList; 3486882SBrad.Beckmann@amd.com bool snoop = false; 3496893SBrad.Beckmann@amd.com ruby_port->physMemPort->getPeerAddressRanges(physMemAddrList, snoop); 3506882SBrad.Beckmann@amd.com for(AddrRangeIter iter = physMemAddrList.begin(); 3516882SBrad.Beckmann@amd.com iter != physMemAddrList.end(); 3526882SBrad.Beckmann@amd.com iter++) { 3536882SBrad.Beckmann@amd.com if (addr >= iter->start && addr <= iter->end) { 3546882SBrad.Beckmann@amd.com DPRINTF(MemoryAccess, "Request found in %#llx - %#llx range\n", 3556882SBrad.Beckmann@amd.com iter->start, iter->end); 3566882SBrad.Beckmann@amd.com return true; 3576882SBrad.Beckmann@amd.com } 3586882SBrad.Beckmann@amd.com } 3596882SBrad.Beckmann@amd.com return false; 3606882SBrad.Beckmann@amd.com} 361