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 ---