RubyPort.cc (10481:59fb5779ec6e) RubyPort.cc (10525:77787650cbbc)
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"
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"
49#include "sim/full_system.hh"
50#include "sim/system.hh"
51
52RubyPort::RubyPort(const Params *p)
53 : MemObject(p), m_version(p->version), m_controller(NULL),
54 m_mandatory_q_ptr(NULL), m_usingRubyTester(p->using_ruby_tester),
55 system(p->system),
56 pioMasterPort(csprintf("%s.pio-master-port", name()), this),
57 pioSlavePort(csprintf("%s.pio-slave-port", name()), this),
58 memMasterPort(csprintf("%s.mem-master-port", name()), this),
59 memSlavePort(csprintf("%s-mem-slave-port", name()), this,
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,
60 p->ruby_system, p->access_phys_mem, -1),
61 gotAddrRanges(p->port_master_connection_count), drainManager(NULL),
62 access_phys_mem(p->access_phys_mem)
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(),
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, access_phys_mem, i));
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,
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, bool _access_phys_mem, PortID id)
158 RubySystem *_system,
159 bool _access_backing_store, PortID id)
159 : QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this),
160 : QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this),
160 ruby_system(_system), access_phys_mem(_access_phys_mem)
161 ruby_system(_system), access_backing_store(_access_backing_store)
161{
162 DPRINTF(RubyPort, "Created slave memport on ruby sequencer %s\n", _name);
163}
164
165bool
166RubyPort::PioMasterPort::recvTimingResp(PacketPtr pkt)
167{
168 RubyPort *ruby_port = static_cast<RubyPort *>(&owner);

--- 107 unchanged lines hidden (view full) ---

276
277 return false;
278}
279
280void
281RubyPort::MemSlavePort::recvFunctional(PacketPtr pkt)
282{
283 DPRINTF(RubyPort, "Functional access for address: %#x\n", pkt->getAddr());
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());
284 RubyPort *ruby_port = static_cast<RubyPort *>(&owner);
285
286 // Check for pio requests and directly send them to the dedicated
287 // pio port.
288 if (!isPhysMemAddress(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);
289 assert(ruby_port->memMasterPort.isConnected());
290 DPRINTF(RubyPort, "Pio Request for address: 0x%#x\n", pkt->getAddr());
291 panic("RubyPort::PioMasterPort::recvFunctional() not implemented!\n");
292 }
293
294 assert(pkt->getAddr() + pkt->getSize() <=
295 line_address(Address(pkt->getAddr())).getAddress() +
296 RubySystem::getBlockSizeBytes());

--- 12 unchanged lines hidden (view full) ---

309
310 // Unless the requester explicitly said otherwise, generate an error if
311 // the functional request failed
312 if (!accessSucceeded && !pkt->suppressFuncError()) {
313 fatal("Ruby functional %s failed for address %#x\n",
314 pkt->isWrite() ? "write" : "read", pkt->getAddr());
315 }
316
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
317 if (access_phys_mem) {
318 if (access_backing_store) {
318 // The attached physmem contains the official version of data.
319 // The following command performs the real functional access.
320 // This line should be removed once Ruby supplies the official version
321 // of data.
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.
322 ruby_port->system->getPhysMem().functionalAccess(pkt);
323 ruby_system->getPhysMem()->functionalAccess(pkt);
323 }
324
325 // turn packet around to go back to requester if response expected
326 if (needsResponse) {
327 pkt->setFunctionalResponseStatus(accessSucceeded);
324 }
325
326 // turn packet around to go back to requester if response expected
327 if (needsResponse) {
328 pkt->setFunctionalResponseStatus(accessSucceeded);
328
329 // @todo There should not be a reverse call since the response is
330 // communicated through the packet pointer
331 // DPRINTF(RubyPort, "Sending packet back over port\n");
332 // sendFunctional(pkt);
333 }
329 }
330
334 DPRINTF(RubyPort, "Functional access %s!\n",
335 accessSucceeded ? "successful":"failed");
336}
337
338void
339RubyPort::ruby_hit_callback(PacketPtr pkt)
340{
341 DPRINTF(RubyPort, "Hit callback for %s 0x%x\n", pkt->cmdString(),

--- 112 unchanged lines hidden (view full) ---

454 return child_drain_count;
455}
456
457void
458RubyPort::MemSlavePort::hitCallback(PacketPtr pkt)
459{
460 bool needsResponse = pkt->needsResponse();
461
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
462 //
463 // Unless specified at configuraiton, all responses except failed SC
464 // and Flush operations access M5 physical memory.
459 // Unless specified at configuraiton, all responses except failed SC
460 // and Flush operations access M5 physical memory.
465 //
466 bool accessPhysMem = access_phys_mem;
461 bool accessPhysMem = access_backing_store;
467
468 if (pkt->isLLSC()) {
469 if (pkt->isWrite()) {
470 if (pkt->req->getExtraData() != 0) {
471 //
472 // Successful SC packets convert to normal writes
473 //
474 pkt->convertScToWrite();

--- 8 unchanged lines hidden (view full) ---

483 //
484 // All LL packets convert to normal loads so that M5 PhysMem does
485 // not lock the blocks.
486 //
487 pkt->convertLlToRead();
488 }
489 }
490
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
491 //
492 // Flush requests don't access physical memory
486 // Flush requests don't access physical memory
493 //
494 if (pkt->isFlush()) {
495 accessPhysMem = false;
496 }
497
498 DPRINTF(RubyPort, "Hit callback needs response %d\n", needsResponse);
499
500 if (accessPhysMem) {
487 if (pkt->isFlush()) {
488 accessPhysMem = false;
489 }
490
491 DPRINTF(RubyPort, "Hit callback needs response %d\n", needsResponse);
492
493 if (accessPhysMem) {
501 RubyPort *ruby_port = static_cast<RubyPort *>(&owner);
502 ruby_port->system->getPhysMem().access(pkt);
494 ruby_system->getPhysMem()->functionalAccess(pkt);
503 } else if (needsResponse) {
504 pkt->makeResponse();
505 }
506
507 // turn packet around to go back to requester if response expected
508 if (needsResponse) {
509 DPRINTF(RubyPort, "Sending packet back over port\n");
510 // send next cycle
511 schedTimingResp(pkt, curTick() + g_system_ptr->clockPeriod());
512 } else {
513 delete pkt;
514 }
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
515 DPRINTF(RubyPort, "Hit callback done!\n");
516}
517
518AddrRangeList
519RubyPort::PioSlavePort::getAddrRanges() const
520{
521 // at the moment the assumption is that the master does not care
522 AddrRangeList ranges;

--- 48 unchanged lines hidden ---
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 ---