Deleted Added
sdiff udiff text old ( 10481:59fb5779ec6e ) new ( 10525:77787650cbbc )
full compact
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 "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,
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)
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));
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)
159 : QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this),
160 ruby_system(_system), access_phys_mem(_access_phys_mem)
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());
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())) {
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
317 if (access_phys_mem) {
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.
322 ruby_port->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);
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 }
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
462 //
463 // Unless specified at configuraiton, all responses except failed SC
464 // and Flush operations access M5 physical memory.
465 //
466 bool accessPhysMem = access_phys_mem;
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
491 //
492 // 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) {
501 RubyPort *ruby_port = static_cast<RubyPort *>(&owner);
502 ruby_port->system->getPhysMem().access(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 }
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 ---