RubyPort.cc (11143:d2114f5629ff) | RubyPort.cc (11266:452e10b868ea) |
---|---|
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 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * | 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 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * |
14 * Copyright (c) 2009 Advanced Micro Devices, Inc. | 14 * Copyright (c) 2009-2013 Advanced Micro Devices, Inc. |
15 * Copyright (c) 2011 Mark D. Hill and David A. Wood 16 * All rights reserved. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions are 20 * met: redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer; 22 * redistributions in binary form must reproduce the above copyright --- 30 unchanged lines hidden (view full) --- 53RubyPort::RubyPort(const Params *p) 54 : MemObject(p), m_ruby_system(p->ruby_system), m_version(p->version), 55 m_controller(NULL), m_mandatory_q_ptr(NULL), 56 m_usingRubyTester(p->using_ruby_tester), 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, | 15 * Copyright (c) 2011 Mark D. Hill and David A. Wood 16 * All rights reserved. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions are 20 * met: redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer; 22 * redistributions in binary form must reproduce the above copyright --- 30 unchanged lines hidden (view full) --- 53RubyPort::RubyPort(const Params *p) 54 : MemObject(p), m_ruby_system(p->ruby_system), m_version(p->version), 55 m_controller(NULL), m_mandatory_q_ptr(NULL), 56 m_usingRubyTester(p->using_ruby_tester), 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->getAccessBackingStore(), -1), | 61 p->ruby_system->getAccessBackingStore(), -1, 62 p->no_retry_on_stall), |
62 gotAddrRanges(p->port_master_connection_count) 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 gotAddrRanges(p->port_master_connection_count) 64{ 65 assert(m_version != -1); 66 67 // create the slave ports based on the number of connected ports 68 for (size_t i = 0; i < p->port_slave_connection_count; ++i) { 69 slave_ports.push_back(new MemSlavePort(csprintf("%s.slave%d", name(), |
69 i), this, p->ruby_system->getAccessBackingStore(), i)); | 70 i), this, p->ruby_system->getAccessBackingStore(), 71 i, p->no_retry_on_stall)); |
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} --- 73 unchanged lines hidden (view full) --- 151 RubyPort *_port) 152 : QueuedMasterPort(_name, _port, reqQueue, snoopRespQueue), 153 reqQueue(*_port, *this), snoopRespQueue(*_port, *this) 154{ 155 DPRINTF(RubyPort, "Created master memport on ruby sequencer %s\n", _name); 156} 157 158RubyPort::MemSlavePort::MemSlavePort(const std::string &_name, RubyPort *_port, | 72 } 73 74 // create the master ports based on the number of connected ports 75 for (size_t i = 0; i < p->port_master_connection_count; ++i) { 76 master_ports.push_back(new PioMasterPort(csprintf("%s.master%d", 77 name(), i), this)); 78 } 79} --- 73 unchanged lines hidden (view full) --- 153 RubyPort *_port) 154 : QueuedMasterPort(_name, _port, reqQueue, snoopRespQueue), 155 reqQueue(*_port, *this), snoopRespQueue(*_port, *this) 156{ 157 DPRINTF(RubyPort, "Created master memport on ruby sequencer %s\n", _name); 158} 159 160RubyPort::MemSlavePort::MemSlavePort(const std::string &_name, RubyPort *_port, |
159 bool _access_backing_store, PortID id) | 161 bool _access_backing_store, PortID id, 162 bool _no_retry_on_stall) |
160 : QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this), | 163 : QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this), |
161 access_backing_store(_access_backing_store) | 164 access_backing_store(_access_backing_store), 165 no_retry_on_stall(_no_retry_on_stall) |
162{ 163 DPRINTF(RubyPort, "Created slave memport on ruby sequencer %s\n", _name); 164} 165 166bool 167RubyPort::PioMasterPort::recvTimingResp(PacketPtr pkt) 168{ 169 RubyPort *rp = static_cast<RubyPort *>(&owner); --- 92 unchanged lines hidden (view full) --- 262 // route the response 263 pkt->pushSenderState(new SenderState(this)); 264 265 DPRINTF(RubyPort, "Request %s 0x%x issued\n", pkt->cmdString(), 266 pkt->getAddr()); 267 return true; 268 } 269 | 166{ 167 DPRINTF(RubyPort, "Created slave memport on ruby sequencer %s\n", _name); 168} 169 170bool 171RubyPort::PioMasterPort::recvTimingResp(PacketPtr pkt) 172{ 173 RubyPort *rp = static_cast<RubyPort *>(&owner); --- 92 unchanged lines hidden (view full) --- 266 // route the response 267 pkt->pushSenderState(new SenderState(this)); 268 269 DPRINTF(RubyPort, "Request %s 0x%x issued\n", pkt->cmdString(), 270 pkt->getAddr()); 271 return true; 272 } 273 |
270 // 271 // Unless one is using the ruby tester, record the stalled M5 port for 272 // later retry when the sequencer becomes free. 273 // 274 if (!ruby_port->m_usingRubyTester) { 275 ruby_port->addToRetryList(this); 276 } | |
277 278 DPRINTF(RubyPort, "Request for address %#x did not issued because %s\n", 279 pkt->getAddr(), RequestStatus_to_string(requestStatus)); 280 | 274 275 DPRINTF(RubyPort, "Request for address %#x did not issued because %s\n", 276 pkt->getAddr(), RequestStatus_to_string(requestStatus)); 277 |
278 addToRetryList(); 279 |
|
281 return false; 282} 283 284void | 280 return false; 281} 282 283void |
284RubyPort::MemSlavePort::addToRetryList() 285{ 286 RubyPort *ruby_port = static_cast<RubyPort *>(&owner); 287 288 // 289 // Unless the requestor do not want retries (e.g., the Ruby tester), 290 // record the stalled M5 port for later retry when the sequencer 291 // becomes free. 292 // 293 if (!no_retry_on_stall && !ruby_port->onRetryList(this)) { 294 ruby_port->addToRetryList(this); 295 } 296} 297 298void |
|
285RubyPort::MemSlavePort::recvFunctional(PacketPtr pkt) 286{ 287 DPRINTF(RubyPort, "Functional access for address: %#x\n", pkt->getAddr()); 288 289 RubyPort *rp M5_VAR_USED = static_cast<RubyPort *>(&owner); 290 RubySystem *rs = rp->m_ruby_system; 291 292 // Check for pio requests and directly send them to the dedicated --- 58 unchanged lines hidden (view full) --- 351 RubyPort::SenderState *senderState = 352 safe_cast<RubyPort::SenderState *>(pkt->popSenderState()); 353 MemSlavePort *port = senderState->port; 354 assert(port != NULL); 355 delete senderState; 356 357 port->hitCallback(pkt); 358 | 299RubyPort::MemSlavePort::recvFunctional(PacketPtr pkt) 300{ 301 DPRINTF(RubyPort, "Functional access for address: %#x\n", pkt->getAddr()); 302 303 RubyPort *rp M5_VAR_USED = static_cast<RubyPort *>(&owner); 304 RubySystem *rs = rp->m_ruby_system; 305 306 // Check for pio requests and directly send them to the dedicated --- 58 unchanged lines hidden (view full) --- 365 RubyPort::SenderState *senderState = 366 safe_cast<RubyPort::SenderState *>(pkt->popSenderState()); 367 MemSlavePort *port = senderState->port; 368 assert(port != NULL); 369 delete senderState; 370 371 port->hitCallback(pkt); 372 |
373 trySendRetries(); 374} 375 376void 377RubyPort::trySendRetries() 378{ |
|
359 // 360 // If we had to stall the MemSlavePorts, wake them up because the sequencer 361 // likely has free resources now. 362 // 363 if (!retryList.empty()) { | 379 // 380 // If we had to stall the MemSlavePorts, wake them up because the sequencer 381 // likely has free resources now. 382 // 383 if (!retryList.empty()) { |
364 // 365 // Record the current list of ports to retry on a temporary list before 366 // calling sendRetry on those ports. sendRetry will cause an 367 // immediate retry, which may result in the ports being put back on the 368 // list. Therefore we want to clear the retryList before calling 369 // sendRetry. 370 // | 384 // Record the current list of ports to retry on a temporary list 385 // before calling sendRetryReq on those ports. sendRetryReq will cause 386 // an immediate retry, which may result in the ports being put back on 387 // the list. Therefore we want to clear the retryList before calling 388 // sendRetryReq. |
371 std::vector<MemSlavePort *> curRetryList(retryList); 372 373 retryList.clear(); 374 375 for (auto i = curRetryList.begin(); i != curRetryList.end(); ++i) { 376 DPRINTF(RubyPort, | 389 std::vector<MemSlavePort *> curRetryList(retryList); 390 391 retryList.clear(); 392 393 for (auto i = curRetryList.begin(); i != curRetryList.end(); ++i) { 394 DPRINTF(RubyPort, |
377 "Sequencer may now be free. SendRetry to port %s\n", | 395 "Sequencer may now be free. SendRetry to port %s\n", |
378 (*i)->name()); 379 (*i)->sendRetryReq(); 380 } 381 } | 396 (*i)->name()); 397 (*i)->sendRetryReq(); 398 } 399 } |
382 383 testDrainComplete(); | |
384} 385 386void 387RubyPort::testDrainComplete() 388{ 389 //If we weren't able to drain before, we might be able to now. 390 if (drainState() == DrainState::Draining) { 391 unsigned int drainCount = outstandingCount(); --- 142 unchanged lines hidden --- | 400} 401 402void 403RubyPort::testDrainComplete() 404{ 405 //If we weren't able to drain before, we might be able to now. 406 if (drainState() == DrainState::Draining) { 407 unsigned int drainCount = outstandingCount(); --- 142 unchanged lines hidden --- |