1/* 2 * Copyright (c) 2012-2013 ARM Limited 3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 32 unchanged lines hidden (view full) --- 41 42#include "cpu/testers/rubytest/RubyTester.hh" 43#include "debug/Config.hh" 44#include "debug/Drain.hh" 45#include "debug/Ruby.hh" 46#include "mem/protocol/AccessPermission.hh" 47#include "mem/ruby/slicc_interface/AbstractController.hh" 48#include "mem/ruby/system/RubyPort.hh" |
49#include "mem/simple_mem.hh" |
50#include "sim/full_system.hh" 51#include "sim/system.hh" 52 53RubyPort::RubyPort(const Params *p) 54 : MemObject(p), m_version(p->version), m_controller(NULL), 55 m_mandatory_q_ptr(NULL), m_usingRubyTester(p->using_ruby_tester), 56 system(p->system), 57 pioMasterPort(csprintf("%s.pio-master-port", name()), this), 58 pioSlavePort(csprintf("%s.pio-slave-port", name()), this), 59 memMasterPort(csprintf("%s.mem-master-port", name()), this), 60 memSlavePort(csprintf("%s-mem-slave-port", name()), this, |
61 p->ruby_system, p->access_backing_store, -1), 62 gotAddrRanges(p->port_master_connection_count), drainManager(NULL) |
63{ 64 assert(m_version != -1); 65 66 // create the slave ports based on the number of connected ports 67 for (size_t i = 0; i < p->port_slave_connection_count; ++i) { 68 slave_ports.push_back(new MemSlavePort(csprintf("%s.slave%d", name(), |
69 i), this, p->ruby_system, p->access_backing_store, i)); |
70 } 71 72 // create the master ports based on the number of connected ports 73 for (size_t i = 0; i < p->port_master_connection_count; ++i) { 74 master_ports.push_back(new PioMasterPort(csprintf("%s.master%d", 75 name(), i), this)); 76 } 77} --- 72 unchanged lines hidden (view full) --- 150RubyPort::MemMasterPort::MemMasterPort(const std::string &_name, 151 RubyPort *_port) 152 : QueuedMasterPort(_name, _port, queue), queue(*_port, *this) 153{ 154 DPRINTF(RubyPort, "Created master memport on ruby sequencer %s\n", _name); 155} 156 157RubyPort::MemSlavePort::MemSlavePort(const std::string &_name, RubyPort *_port, |
158 RubySystem *_system, 159 bool _access_backing_store, PortID id) |
160 : QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this), |
161 ruby_system(_system), access_backing_store(_access_backing_store) |
162{ 163 DPRINTF(RubyPort, "Created slave memport on ruby sequencer %s\n", _name); 164} 165 166bool 167RubyPort::PioMasterPort::recvTimingResp(PacketPtr pkt) 168{ 169 RubyPort *ruby_port = static_cast<RubyPort *>(&owner); --- 107 unchanged lines hidden (view full) --- 277 278 return false; 279} 280 281void 282RubyPort::MemSlavePort::recvFunctional(PacketPtr pkt) 283{ 284 DPRINTF(RubyPort, "Functional access for address: %#x\n", pkt->getAddr()); |
285 286 // Check for pio requests and directly send them to the dedicated 287 // pio port. 288 if (!isPhysMemAddress(pkt->getAddr())) { |
289 RubyPort *ruby_port M5_VAR_USED = static_cast<RubyPort *>(&owner); |
290 assert(ruby_port->memMasterPort.isConnected()); 291 DPRINTF(RubyPort, "Pio Request for address: 0x%#x\n", pkt->getAddr()); 292 panic("RubyPort::PioMasterPort::recvFunctional() not implemented!\n"); 293 } 294 295 assert(pkt->getAddr() + pkt->getSize() <= 296 line_address(Address(pkt->getAddr())).getAddress() + 297 RubySystem::getBlockSizeBytes()); --- 12 unchanged lines hidden (view full) --- 310 311 // Unless the requester explicitly said otherwise, generate an error if 312 // the functional request failed 313 if (!accessSucceeded && !pkt->suppressFuncError()) { 314 fatal("Ruby functional %s failed for address %#x\n", 315 pkt->isWrite() ? "write" : "read", pkt->getAddr()); 316 } 317 |
318 if (access_backing_store) { |
319 // The attached physmem contains the official version of data. 320 // The following command performs the real functional access. 321 // This line should be removed once Ruby supplies the official version 322 // of data. |
323 ruby_system->getPhysMem()->functionalAccess(pkt); |
324 } 325 326 // turn packet around to go back to requester if response expected 327 if (needsResponse) { 328 pkt->setFunctionalResponseStatus(accessSucceeded); |
329 } |
330 |
331 DPRINTF(RubyPort, "Functional access %s!\n", 332 accessSucceeded ? "successful":"failed"); 333} 334 335void 336RubyPort::ruby_hit_callback(PacketPtr pkt) 337{ 338 DPRINTF(RubyPort, "Hit callback for %s 0x%x\n", pkt->cmdString(), --- 112 unchanged lines hidden (view full) --- 451 return child_drain_count; 452} 453 454void 455RubyPort::MemSlavePort::hitCallback(PacketPtr pkt) 456{ 457 bool needsResponse = pkt->needsResponse(); 458 |
459 // Unless specified at configuraiton, all responses except failed SC 460 // and Flush operations access M5 physical memory. |
461 bool accessPhysMem = access_backing_store; |
462 463 if (pkt->isLLSC()) { 464 if (pkt->isWrite()) { 465 if (pkt->req->getExtraData() != 0) { 466 // 467 // Successful SC packets convert to normal writes 468 // 469 pkt->convertScToWrite(); --- 8 unchanged lines hidden (view full) --- 478 // 479 // All LL packets convert to normal loads so that M5 PhysMem does 480 // not lock the blocks. 481 // 482 pkt->convertLlToRead(); 483 } 484 } 485 |
486 // Flush requests don't access physical memory |
487 if (pkt->isFlush()) { 488 accessPhysMem = false; 489 } 490 491 DPRINTF(RubyPort, "Hit callback needs response %d\n", needsResponse); 492 493 if (accessPhysMem) { |
494 ruby_system->getPhysMem()->functionalAccess(pkt); |
495 } else if (needsResponse) { 496 pkt->makeResponse(); 497 } 498 499 // turn packet around to go back to requester if response expected 500 if (needsResponse) { 501 DPRINTF(RubyPort, "Sending packet back over port\n"); 502 // send next cycle 503 schedTimingResp(pkt, curTick() + g_system_ptr->clockPeriod()); 504 } else { 505 delete pkt; 506 } |
507 |
508 DPRINTF(RubyPort, "Hit callback done!\n"); 509} 510 511AddrRangeList 512RubyPort::PioSlavePort::getAddrRanges() const 513{ 514 // at the moment the assumption is that the master does not care 515 AddrRangeList ranges; --- 48 unchanged lines hidden --- |