RubyPort.cc (10917:c38f28fad4c3) | RubyPort.cc (10919:80069a602c83) |
---|---|
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 --- 37 unchanged lines hidden (view full) --- 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" 50#include "sim/full_system.hh" 51#include "sim/system.hh" 52 53RubyPort::RubyPort(const Params *p) | 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 --- 37 unchanged lines hidden (view full) --- 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" 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), | 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, | 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, p->ruby_system->getAccessBackingStore(), -1), | 61 p->ruby_system->getAccessBackingStore(), -1), |
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(), | 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(), |
69 i), this, p->ruby_system, 70 p->ruby_system->getAccessBackingStore(), i)); | 69 i), this, p->ruby_system->getAccessBackingStore(), i)); |
71 } 72 73 // create the master ports based on the number of connected ports 74 for (size_t i = 0; i < p->port_master_connection_count; ++i) { 75 master_ports.push_back(new PioMasterPort(csprintf("%s.master%d", 76 name(), i), this)); 77 } 78} --- 74 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, | 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} --- 74 unchanged lines hidden (view full) --- 152 RubyPort *_port) 153 : QueuedMasterPort(_name, _port, reqQueue, snoopRespQueue), 154 reqQueue(*_port, *this), snoopRespQueue(*_port, *this) 155{ 156 DPRINTF(RubyPort, "Created master memport on ruby sequencer %s\n", _name); 157} 158 159RubyPort::MemSlavePort::MemSlavePort(const std::string &_name, RubyPort *_port, |
161 RubySystem *_system, | |
162 bool _access_backing_store, PortID id) 163 : QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this), | 160 bool _access_backing_store, PortID id) 161 : QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this), |
164 ruby_system(_system), access_backing_store(_access_backing_store) | 162 access_backing_store(_access_backing_store) |
165{ 166 DPRINTF(RubyPort, "Created slave memport on ruby sequencer %s\n", _name); 167} 168 169bool 170RubyPort::PioMasterPort::recvTimingResp(PacketPtr pkt) 171{ | 163{ 164 DPRINTF(RubyPort, "Created slave memport on ruby sequencer %s\n", _name); 165} 166 167bool 168RubyPort::PioMasterPort::recvTimingResp(PacketPtr pkt) 169{ |
172 RubyPort *ruby_port = static_cast<RubyPort *>(&owner); | 170 RubyPort *rp = static_cast<RubyPort *>(&owner); |
173 DPRINTF(RubyPort, "Response for address: 0x%#x\n", pkt->getAddr()); 174 175 // send next cycle | 171 DPRINTF(RubyPort, "Response for address: 0x%#x\n", pkt->getAddr()); 172 173 // send next cycle |
176 ruby_port->pioSlavePort.schedTimingResp( 177 pkt, curTick() + g_system_ptr->clockPeriod()); | 174 rp->pioSlavePort.schedTimingResp( 175 pkt, curTick() + rp->m_ruby_system->clockPeriod()); |
178 return true; 179} 180 181bool RubyPort::MemMasterPort::recvTimingResp(PacketPtr pkt) 182{ 183 // got a response from a device 184 assert(pkt->isResponse()); 185 --- 5 unchanged lines hidden (view full) --- 191 delete senderState; 192 193 // In FS mode, ruby memory will receive pio responses from devices 194 // and it must forward these responses back to the particular CPU. 195 DPRINTF(RubyPort, "Pio response for address %#x, going to %s\n", 196 pkt->getAddr(), port->name()); 197 198 // attempt to send the response in the next cycle | 176 return true; 177} 178 179bool RubyPort::MemMasterPort::recvTimingResp(PacketPtr pkt) 180{ 181 // got a response from a device 182 assert(pkt->isResponse()); 183 --- 5 unchanged lines hidden (view full) --- 189 delete senderState; 190 191 // In FS mode, ruby memory will receive pio responses from devices 192 // and it must forward these responses back to the particular CPU. 193 DPRINTF(RubyPort, "Pio response for address %#x, going to %s\n", 194 pkt->getAddr(), port->name()); 195 196 // attempt to send the response in the next cycle |
199 port->schedTimingResp(pkt, curTick() + g_system_ptr->clockPeriod()); | 197 RubyPort *rp = static_cast<RubyPort *>(&owner); 198 port->schedTimingResp(pkt, curTick() + rp->m_ruby_system->clockPeriod()); |
200 201 return true; 202} 203 204bool 205RubyPort::PioSlavePort::recvTimingReq(PacketPtr pkt) 206{ 207 RubyPort *ruby_port = static_cast<RubyPort *>(&owner); --- 31 unchanged lines hidden (view full) --- 239 DPRINTF(RubyPort, "Request address %#x assumed to be a pio address\n", 240 pkt->getAddr()); 241 242 // Save the port in the sender state object to be used later to 243 // route the response 244 pkt->pushSenderState(new SenderState(this)); 245 246 // send next cycle | 199 200 return true; 201} 202 203bool 204RubyPort::PioSlavePort::recvTimingReq(PacketPtr pkt) 205{ 206 RubyPort *ruby_port = static_cast<RubyPort *>(&owner); --- 31 unchanged lines hidden (view full) --- 238 DPRINTF(RubyPort, "Request address %#x assumed to be a pio address\n", 239 pkt->getAddr()); 240 241 // Save the port in the sender state object to be used later to 242 // route the response 243 pkt->pushSenderState(new SenderState(this)); 244 245 // send next cycle |
246 RubySystem *rs = ruby_port->m_ruby_system; |
|
247 ruby_port->memMasterPort.schedTimingReq(pkt, | 247 ruby_port->memMasterPort.schedTimingReq(pkt, |
248 curTick() + g_system_ptr->clockPeriod()); | 248 curTick() + rs->clockPeriod()); |
249 return true; 250 } 251 252 assert(Address(pkt->getAddr()).getOffset() + pkt->getSize() <= 253 RubySystem::getBlockSizeBytes()); 254 255 // Submit the ruby request 256 RequestStatus requestStatus = ruby_port->makeRequest(pkt); --- 7 unchanged lines hidden (view full) --- 264 pkt->pushSenderState(new SenderState(this)); 265 266 DPRINTF(RubyPort, "Request %s 0x%x issued\n", pkt->cmdString(), 267 pkt->getAddr()); 268 return true; 269 } 270 271 // | 249 return true; 250 } 251 252 assert(Address(pkt->getAddr()).getOffset() + pkt->getSize() <= 253 RubySystem::getBlockSizeBytes()); 254 255 // Submit the ruby request 256 RequestStatus requestStatus = ruby_port->makeRequest(pkt); --- 7 unchanged lines hidden (view full) --- 264 pkt->pushSenderState(new SenderState(this)); 265 266 DPRINTF(RubyPort, "Request %s 0x%x issued\n", pkt->cmdString(), 267 pkt->getAddr()); 268 return true; 269 } 270 271 // |
272 // Unless one is using the ruby tester, record the stalled M5 port for | 272 // Unless one is using the ruby tester, record the stalled M5 port for |
273 // later retry when the sequencer becomes free. 274 // 275 if (!ruby_port->m_usingRubyTester) { 276 ruby_port->addToRetryList(this); 277 } 278 279 DPRINTF(RubyPort, "Request for address %#x did not issued because %s\n", 280 pkt->getAddr(), RequestStatus_to_string(requestStatus)); 281 282 return false; 283} 284 285void 286RubyPort::MemSlavePort::recvFunctional(PacketPtr pkt) 287{ 288 DPRINTF(RubyPort, "Functional access for address: %#x\n", pkt->getAddr()); 289 | 273 // later retry when the sequencer becomes free. 274 // 275 if (!ruby_port->m_usingRubyTester) { 276 ruby_port->addToRetryList(this); 277 } 278 279 DPRINTF(RubyPort, "Request for address %#x did not issued because %s\n", 280 pkt->getAddr(), RequestStatus_to_string(requestStatus)); 281 282 return false; 283} 284 285void 286RubyPort::MemSlavePort::recvFunctional(PacketPtr pkt) 287{ 288 DPRINTF(RubyPort, "Functional access for address: %#x\n", pkt->getAddr()); 289 |
290 RubyPort *rp M5_VAR_USED = static_cast<RubyPort *>(&owner); 291 RubySystem *rs = rp->m_ruby_system; 292 |
|
290 // Check for pio requests and directly send them to the dedicated 291 // pio port. 292 if (!isPhysMemAddress(pkt->getAddr())) { | 293 // Check for pio requests and directly send them to the dedicated 294 // pio port. 295 if (!isPhysMemAddress(pkt->getAddr())) { |
293 RubyPort *ruby_port M5_VAR_USED = static_cast<RubyPort *>(&owner); 294 assert(ruby_port->memMasterPort.isConnected()); | 296 assert(rp->memMasterPort.isConnected()); |
295 DPRINTF(RubyPort, "Pio Request for address: 0x%#x\n", pkt->getAddr()); 296 panic("RubyPort::PioMasterPort::recvFunctional() not implemented!\n"); 297 } 298 299 assert(pkt->getAddr() + pkt->getSize() <= 300 line_address(Address(pkt->getAddr())).getAddress() + 301 RubySystem::getBlockSizeBytes()); 302 303 if (access_backing_store) { 304 // The attached physmem contains the official version of data. 305 // The following command performs the real functional access. 306 // This line should be removed once Ruby supplies the official version 307 // of data. | 297 DPRINTF(RubyPort, "Pio Request for address: 0x%#x\n", pkt->getAddr()); 298 panic("RubyPort::PioMasterPort::recvFunctional() not implemented!\n"); 299 } 300 301 assert(pkt->getAddr() + pkt->getSize() <= 302 line_address(Address(pkt->getAddr())).getAddress() + 303 RubySystem::getBlockSizeBytes()); 304 305 if (access_backing_store) { 306 // The attached physmem contains the official version of data. 307 // The following command performs the real functional access. 308 // This line should be removed once Ruby supplies the official version 309 // of data. |
308 ruby_system->getPhysMem()->functionalAccess(pkt); | 310 rs->getPhysMem()->functionalAccess(pkt); |
309 } else { 310 bool accessSucceeded = false; 311 bool needsResponse = pkt->needsResponse(); 312 313 // Do the functional access on ruby memory 314 if (pkt->isRead()) { | 311 } else { 312 bool accessSucceeded = false; 313 bool needsResponse = pkt->needsResponse(); 314 315 // Do the functional access on ruby memory 316 if (pkt->isRead()) { |
315 accessSucceeded = ruby_system->functionalRead(pkt); | 317 accessSucceeded = rs->functionalRead(pkt); |
316 } else if (pkt->isWrite()) { | 318 } else if (pkt->isWrite()) { |
317 accessSucceeded = ruby_system->functionalWrite(pkt); | 319 accessSucceeded = rs->functionalWrite(pkt); |
318 } else { 319 panic("Unsupported functional command %s\n", pkt->cmdString()); 320 } 321 322 // Unless the requester explicitly said otherwise, generate an error if 323 // the functional request failed 324 if (!accessSucceeded && !pkt->suppressFuncError()) { 325 fatal("Ruby functional %s failed for address %#x\n", --- 125 unchanged lines hidden (view full) --- 451 452 // Flush requests don't access physical memory 453 if (pkt->isFlush()) { 454 accessPhysMem = false; 455 } 456 457 DPRINTF(RubyPort, "Hit callback needs response %d\n", needsResponse); 458 | 320 } else { 321 panic("Unsupported functional command %s\n", pkt->cmdString()); 322 } 323 324 // Unless the requester explicitly said otherwise, generate an error if 325 // the functional request failed 326 if (!accessSucceeded && !pkt->suppressFuncError()) { 327 fatal("Ruby functional %s failed for address %#x\n", --- 125 unchanged lines hidden (view full) --- 453 454 // Flush requests don't access physical memory 455 if (pkt->isFlush()) { 456 accessPhysMem = false; 457 } 458 459 DPRINTF(RubyPort, "Hit callback needs response %d\n", needsResponse); 460 |
461 RubyPort *ruby_port = static_cast<RubyPort *>(&owner); 462 RubySystem *rs = ruby_port->m_ruby_system; |
|
459 if (accessPhysMem) { | 463 if (accessPhysMem) { |
460 ruby_system->getPhysMem()->access(pkt); | 464 rs->getPhysMem()->access(pkt); |
461 } else if (needsResponse) { 462 pkt->makeResponse(); 463 } 464 465 // turn packet around to go back to requester if response expected 466 if (needsResponse) { 467 DPRINTF(RubyPort, "Sending packet back over port\n"); 468 // send next cycle | 465 } else if (needsResponse) { 466 pkt->makeResponse(); 467 } 468 469 // turn packet around to go back to requester if response expected 470 if (needsResponse) { 471 DPRINTF(RubyPort, "Sending packet back over port\n"); 472 // send next cycle |
469 schedTimingResp(pkt, curTick() + g_system_ptr->clockPeriod()); | 473 schedTimingResp(pkt, curTick() + rs->clockPeriod()); |
470 } else { 471 delete pkt; 472 } 473 474 DPRINTF(RubyPort, "Hit callback done!\n"); 475} 476 477AddrRangeList --- 52 unchanged lines hidden --- | 474 } else { 475 delete pkt; 476 } 477 478 DPRINTF(RubyPort, "Hit callback done!\n"); 479} 480 481AddrRangeList --- 52 unchanged lines hidden --- |