RubyPort.cc (8839:eeb293859255) RubyPort.cc (8851:7e966326ef5b)
1/*
2 * Copyright (c) 2009 Advanced Micro Devices, Inc.
3 * Copyright (c) 2011 Mark D. Hill and David A. Wood
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright

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

30#include "cpu/testers/rubytest/RubyTester.hh"
31#include "debug/Config.hh"
32#include "debug/Ruby.hh"
33#include "mem/protocol/AccessPermission.hh"
34#include "mem/ruby/slicc_interface/AbstractController.hh"
35#include "mem/ruby/system/RubyPort.hh"
36
37RubyPort::RubyPort(const Params *p)
1/*
2 * Copyright (c) 2009 Advanced Micro Devices, Inc.
3 * Copyright (c) 2011 Mark D. Hill and David A. Wood
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright

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

30#include "cpu/testers/rubytest/RubyTester.hh"
31#include "debug/Config.hh"
32#include "debug/Ruby.hh"
33#include "mem/protocol/AccessPermission.hh"
34#include "mem/ruby/slicc_interface/AbstractController.hh"
35#include "mem/ruby/system/RubyPort.hh"
36
37RubyPort::RubyPort(const Params *p)
38 : MemObject(p)
38 : MemObject(p), pio_port(csprintf("%s-pio-port", name()), this),
39 physMemPort(csprintf("%s-physMemPort", name()), this)
39{
40 m_version = p->version;
41 assert(m_version != -1);
42
43 physmem = p->physmem;
44
45 m_controller = NULL;
46 m_mandatory_q_ptr = NULL;
47
48 m_request_cnt = 0;
40{
41 m_version = p->version;
42 assert(m_version != -1);
43
44 physmem = p->physmem;
45
46 m_controller = NULL;
47 m_mandatory_q_ptr = NULL;
48
49 m_request_cnt = 0;
49 pio_port = NULL;
50 physMemPort = NULL;
51
52 m_usingRubyTester = p->using_ruby_tester;
53 access_phys_mem = p->access_phys_mem;
54
55 drainEvent = NULL;
56
57 ruby_system = p->ruby_system;
58 waitingOnSequencer = false;

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

82 if (if_name == "master") {
83 PioPort* masterPort = new PioPort(csprintf("%s-master%d", name(), idx),
84 this);
85
86 return masterPort;
87 }
88
89 if (if_name == "pio_port") {
50
51 m_usingRubyTester = p->using_ruby_tester;
52 access_phys_mem = p->access_phys_mem;
53
54 drainEvent = NULL;
55
56 ruby_system = p->ruby_system;
57 waitingOnSequencer = false;

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

81 if (if_name == "master") {
82 PioPort* masterPort = new PioPort(csprintf("%s-master%d", name(), idx),
83 this);
84
85 return masterPort;
86 }
87
88 if (if_name == "pio_port") {
90 // ensure there is only one pio port
91 assert(pio_port == NULL);
92
93 pio_port = new PioPort(csprintf("%s-pio-port%d", name(), idx), this);
94
95 return pio_port;
89 return &pio_port;
96 }
97
98 if (if_name == "physMemPort") {
90 }
91
92 if (if_name == "physMemPort") {
99 // RubyPort should only have one port to physical memory
100 assert (physMemPort == NULL);
101
102 physMemPort = new PioPort(csprintf("%s-physMemPort", name()), this);
103
104 return physMemPort;
93 return &physMemPort;
105 }
106
107 return NULL;
108}
109
110RubyPort::PioPort::PioPort(const std::string &_name,
111 RubyPort *_port)
112 : SimpleTimingPort(_name, _port)

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

189
190 // Save the port in the sender state object to be used later to
191 // route the response
192 pkt->senderState = new SenderState(this, pkt->senderState);
193
194 // Check for pio requests and directly send them to the dedicated
195 // pio port.
196 if (!isPhysMemAddress(pkt->getAddr())) {
94 }
95
96 return NULL;
97}
98
99RubyPort::PioPort::PioPort(const std::string &_name,
100 RubyPort *_port)
101 : SimpleTimingPort(_name, _port)

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

178
179 // Save the port in the sender state object to be used later to
180 // route the response
181 pkt->senderState = new SenderState(this, pkt->senderState);
182
183 // Check for pio requests and directly send them to the dedicated
184 // pio port.
185 if (!isPhysMemAddress(pkt->getAddr())) {
197 assert(ruby_port->pio_port != NULL);
186 assert(ruby_port->pio_port.isConnected());
198 DPRINTF(RubyPort,
199 "Request for address 0x%#x is assumed to be a pio request\n",
200 pkt->getAddr());
201
187 DPRINTF(RubyPort,
188 "Request for address 0x%#x is assumed to be a pio request\n",
189 pkt->getAddr());
190
202 return ruby_port->pio_port->sendTiming(pkt);
191 return ruby_port->pio_port.sendTiming(pkt);
203 }
204
205 assert(Address(pkt->getAddr()).getOffset() + pkt->getSize() <=
206 RubySystem::getBlockSizeBytes());
207
208 // Submit the ruby request
209 RequestStatus requestStatus = ruby_port->makeRequest(pkt);
210

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

421RubyPort::M5Port::recvFunctional(PacketPtr pkt)
422{
423 DPRINTF(RubyPort, "Functional access caught for address %#x\n",
424 pkt->getAddr());
425
426 // Check for pio requests and directly send them to the dedicated
427 // pio port.
428 if (!isPhysMemAddress(pkt->getAddr())) {
192 }
193
194 assert(Address(pkt->getAddr()).getOffset() + pkt->getSize() <=
195 RubySystem::getBlockSizeBytes());
196
197 // Submit the ruby request
198 RequestStatus requestStatus = ruby_port->makeRequest(pkt);
199

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

410RubyPort::M5Port::recvFunctional(PacketPtr pkt)
411{
412 DPRINTF(RubyPort, "Functional access caught for address %#x\n",
413 pkt->getAddr());
414
415 // Check for pio requests and directly send them to the dedicated
416 // pio port.
417 if (!isPhysMemAddress(pkt->getAddr())) {
429 assert(ruby_port->pio_port != NULL);
418 assert(ruby_port->pio_port.isConnected());
430 DPRINTF(RubyPort, "Request for address 0x%#x is a pio request\n",
431 pkt->getAddr());
432 panic("RubyPort::PioPort::recvFunctional() not implemented!\n");
433 }
434
435 assert(pkt->getAddr() + pkt->getSize() <=
436 line_address(Address(pkt->getAddr())).getAddress() +
437 RubySystem::getBlockSizeBytes());

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

456 pkt->isWrite() ? "write" : "read", pkt->getAddr());
457 }
458
459 if (access_phys_mem) {
460 // The attached physmem contains the official version of data.
461 // The following command performs the real functional access.
462 // This line should be removed once Ruby supplies the official version
463 // of data.
419 DPRINTF(RubyPort, "Request for address 0x%#x is a pio request\n",
420 pkt->getAddr());
421 panic("RubyPort::PioPort::recvFunctional() not implemented!\n");
422 }
423
424 assert(pkt->getAddr() + pkt->getSize() <=
425 line_address(Address(pkt->getAddr())).getAddress() +
426 RubySystem::getBlockSizeBytes());

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

445 pkt->isWrite() ? "write" : "read", pkt->getAddr());
446 }
447
448 if (access_phys_mem) {
449 // The attached physmem contains the official version of data.
450 // The following command performs the real functional access.
451 // This line should be removed once Ruby supplies the official version
452 // of data.
464 ruby_port->physMemPort->sendFunctional(pkt);
453 ruby_port->physMemPort.sendFunctional(pkt);
465 }
466
467 // turn packet around to go back to requester if response expected
468 if (needsResponse) {
469 pkt->setFunctionalResponseStatus(accessSucceeded);
470
471 // @todo There should not be a reverse call since the response is
472 // communicated through the packet pointer

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

549 count += outstandingCount();
550
551 DPRINTF(Config, "outstanding count %d\n", outstandingCount());
552
553 // To simplify the draining process, the sequencer's deadlock detection
554 // event should have been descheduled.
555 assert(isDeadlockEventScheduled() == false);
556
454 }
455
456 // turn packet around to go back to requester if response expected
457 if (needsResponse) {
458 pkt->setFunctionalResponseStatus(accessSucceeded);
459
460 // @todo There should not be a reverse call since the response is
461 // communicated through the packet pointer

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

538 count += outstandingCount();
539
540 DPRINTF(Config, "outstanding count %d\n", outstandingCount());
541
542 // To simplify the draining process, the sequencer's deadlock detection
543 // event should have been descheduled.
544 assert(isDeadlockEventScheduled() == false);
545
557 if (pio_port != NULL) {
558 count += pio_port->drain(de);
546 if (pio_port.isConnected()) {
547 count += pio_port.drain(de);
559 DPRINTF(Config, "count after pio check %d\n", count);
560 }
548 DPRINTF(Config, "count after pio check %d\n", count);
549 }
561 if (physMemPort != NULL) {
562 count += physMemPort->drain(de);
550 if (physMemPort.isConnected()) {
551 count += physMemPort.drain(de);
563 DPRINTF(Config, "count after physmem check %d\n", count);
564 }
565
566 for (CpuPortIter p_iter = cpu_ports.begin(); p_iter != cpu_ports.end();
567 p_iter++) {
568 M5Port* cpu_port = *p_iter;
569 count += cpu_port->drain(de);
570 DPRINTF(Config, "count after cpu port check %d\n", count);

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

635 //
636 if (pkt->isFlush()) {
637 accessPhysMem = false;
638 }
639
640 DPRINTF(RubyPort, "Hit callback needs response %d\n", needsResponse);
641
642 if (accessPhysMem) {
552 DPRINTF(Config, "count after physmem check %d\n", count);
553 }
554
555 for (CpuPortIter p_iter = cpu_ports.begin(); p_iter != cpu_ports.end();
556 p_iter++) {
557 M5Port* cpu_port = *p_iter;
558 count += cpu_port->drain(de);
559 DPRINTF(Config, "count after cpu port check %d\n", count);

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

624 //
625 if (pkt->isFlush()) {
626 accessPhysMem = false;
627 }
628
629 DPRINTF(RubyPort, "Hit callback needs response %d\n", needsResponse);
630
631 if (accessPhysMem) {
643 ruby_port->physMemPort->sendAtomic(pkt);
632 ruby_port->physMemPort.sendAtomic(pkt);
644 } else if (needsResponse) {
645 pkt->makeResponse();
646 }
647
648 // turn packet around to go back to requester if response expected
649 if (needsResponse) {
650 DPRINTF(RubyPort, "Sending packet back over port\n");
651 sendTiming(pkt);

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

670 schedSendTiming(pkt, curTick() + (1 * g_eventQueue_ptr->getClock()));
671 return true;
672}
673
674bool
675RubyPort::M5Port::isPhysMemAddress(Addr addr)
676{
677 AddrRangeList physMemAddrList =
633 } else if (needsResponse) {
634 pkt->makeResponse();
635 }
636
637 // turn packet around to go back to requester if response expected
638 if (needsResponse) {
639 DPRINTF(RubyPort, "Sending packet back over port\n");
640 sendTiming(pkt);

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

659 schedSendTiming(pkt, curTick() + (1 * g_eventQueue_ptr->getClock()));
660 return true;
661}
662
663bool
664RubyPort::M5Port::isPhysMemAddress(Addr addr)
665{
666 AddrRangeList physMemAddrList =
678 ruby_port->physMemPort->getPeer()->getAddrRanges();
667 ruby_port->physMemPort.getPeer()->getAddrRanges();
679 for (AddrRangeIter iter = physMemAddrList.begin();
680 iter != physMemAddrList.end();
681 iter++) {
682 if (addr >= iter->start && addr <= iter->end) {
683 DPRINTF(RubyPort, "Request found in %#llx - %#llx range\n",
684 iter->start, iter->end);
685 return true;
686 }

--- 20 unchanged lines hidden ---
668 for (AddrRangeIter iter = physMemAddrList.begin();
669 iter != physMemAddrList.end();
670 iter++) {
671 if (addr >= iter->start && addr <= iter->end) {
672 DPRINTF(RubyPort, "Request found in %#llx - %#llx range\n",
673 iter->start, iter->end);
674 return true;
675 }

--- 20 unchanged lines hidden ---