RubyPort.cc (7940:d6294150a32e) | RubyPort.cc (8161:ebb373fcb206) |
---|---|
1/* 2 * Copyright (c) 2009 Advanced Micro Devices, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 89 unchanged lines hidden (view full) --- 98 99 return NULL; 100} 101 102RubyPort::PioPort::PioPort(const std::string &_name, 103 RubyPort *_port) 104 : SimpleTimingPort(_name, _port) 105{ | 1/* 2 * Copyright (c) 2009 Advanced Micro Devices, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 89 unchanged lines hidden (view full) --- 98 99 return NULL; 100} 101 102RubyPort::PioPort::PioPort(const std::string &_name, 103 RubyPort *_port) 104 : SimpleTimingPort(_name, _port) 105{ |
106 DPRINTF(Ruby, "creating port to ruby sequencer to cpu %s\n", _name); | 106 DPRINTF(RubyPort, "creating port to ruby sequencer to cpu %s\n", _name); |
107 ruby_port = _port; 108} 109 110RubyPort::M5Port::M5Port(const std::string &_name, 111 RubyPort *_port, bool _access_phys_mem) 112 : SimpleTimingPort(_name, _port) 113{ | 107 ruby_port = _port; 108} 109 110RubyPort::M5Port::M5Port(const std::string &_name, 111 RubyPort *_port, bool _access_phys_mem) 112 : SimpleTimingPort(_name, _port) 113{ |
114 DPRINTF(Ruby, "creating port from ruby sequcner to cpu %s\n", _name); | 114 DPRINTF(RubyPort, "creating port from ruby sequcner to cpu %s\n", _name); |
115 ruby_port = _port; 116 _onRetryList = false; 117 access_phys_mem = _access_phys_mem; 118} 119 120Tick 121RubyPort::PioPort::recvAtomic(PacketPtr pkt) 122{ --- 9 unchanged lines hidden (view full) --- 132} 133 134 135bool 136RubyPort::PioPort::recvTiming(PacketPtr pkt) 137{ 138 // In FS mode, ruby memory will receive pio responses from devices 139 // and it must forward these responses back to the particular CPU. | 115 ruby_port = _port; 116 _onRetryList = false; 117 access_phys_mem = _access_phys_mem; 118} 119 120Tick 121RubyPort::PioPort::recvAtomic(PacketPtr pkt) 122{ --- 9 unchanged lines hidden (view full) --- 132} 133 134 135bool 136RubyPort::PioPort::recvTiming(PacketPtr pkt) 137{ 138 // In FS mode, ruby memory will receive pio responses from devices 139 // and it must forward these responses back to the particular CPU. |
140 DPRINTF(MemoryAccess, "Pio response for address %#x\n", pkt->getAddr()); | 140 DPRINTF(RubyPort, "Pio response for address %#x\n", pkt->getAddr()); |
141 142 assert(pkt->isResponse()); 143 144 // First we must retrieve the request port from the sender State 145 RubyPort::SenderState *senderState = 146 safe_cast<RubyPort::SenderState *>(pkt->senderState); 147 M5Port *port = senderState->port; 148 assert(port != NULL); --- 5 unchanged lines hidden (view full) --- 154 port->sendTiming(pkt); 155 156 return true; 157} 158 159bool 160RubyPort::M5Port::recvTiming(PacketPtr pkt) 161{ | 141 142 assert(pkt->isResponse()); 143 144 // First we must retrieve the request port from the sender State 145 RubyPort::SenderState *senderState = 146 safe_cast<RubyPort::SenderState *>(pkt->senderState); 147 M5Port *port = senderState->port; 148 assert(port != NULL); --- 5 unchanged lines hidden (view full) --- 154 port->sendTiming(pkt); 155 156 return true; 157} 158 159bool 160RubyPort::M5Port::recvTiming(PacketPtr pkt) 161{ |
162 DPRINTF(MemoryAccess, | 162 DPRINTF(RubyPort, |
163 "Timing access caught for address %#x\n", pkt->getAddr()); 164 165 //dsm: based on SimpleTimingPort::recvTiming(pkt); 166 167 // The received packets should only be M5 requests, which should never 168 // get nacked. There used to be code to hanldle nacks here, but 169 // I'm pretty sure it didn't work correctly with the drain code, 170 // so that would need to be fixed if we ever added it back. --- 10 unchanged lines hidden (view full) --- 181 // Save the port in the sender state object to be used later to 182 // route the response 183 pkt->senderState = new SenderState(this, pkt->senderState); 184 185 // Check for pio requests and directly send them to the dedicated 186 // pio port. 187 if (!isPhysMemAddress(pkt->getAddr())) { 188 assert(ruby_port->pio_port != NULL); | 163 "Timing access caught for address %#x\n", pkt->getAddr()); 164 165 //dsm: based on SimpleTimingPort::recvTiming(pkt); 166 167 // The received packets should only be M5 requests, which should never 168 // get nacked. There used to be code to hanldle nacks here, but 169 // I'm pretty sure it didn't work correctly with the drain code, 170 // so that would need to be fixed if we ever added it back. --- 10 unchanged lines hidden (view full) --- 181 // Save the port in the sender state object to be used later to 182 // route the response 183 pkt->senderState = new SenderState(this, pkt->senderState); 184 185 // Check for pio requests and directly send them to the dedicated 186 // pio port. 187 if (!isPhysMemAddress(pkt->getAddr())) { 188 assert(ruby_port->pio_port != NULL); |
189 DPRINTF(MemoryAccess, | 189 DPRINTF(RubyPort, |
190 "Request for address 0x%#x is assumed to be a pio request\n", 191 pkt->getAddr()); 192 193 return ruby_port->pio_port->sendTiming(pkt); 194 } 195 196 // For DMA and CPU requests, translate them to ruby requests before 197 // sending them to our assigned ruby port. 198 RubyRequestType type = RubyRequestType_NULL; 199 200 // If valid, copy the pc to the ruby request 201 Addr pc = 0; 202 if (pkt->req->hasPC()) { 203 pc = pkt->req->getPC(); 204 } 205 206 if (pkt->isLLSC()) { 207 if (pkt->isWrite()) { | 190 "Request for address 0x%#x is assumed to be a pio request\n", 191 pkt->getAddr()); 192 193 return ruby_port->pio_port->sendTiming(pkt); 194 } 195 196 // For DMA and CPU requests, translate them to ruby requests before 197 // sending them to our assigned ruby port. 198 RubyRequestType type = RubyRequestType_NULL; 199 200 // If valid, copy the pc to the ruby request 201 Addr pc = 0; 202 if (pkt->req->hasPC()) { 203 pc = pkt->req->getPC(); 204 } 205 206 if (pkt->isLLSC()) { 207 if (pkt->isWrite()) { |
208 DPRINTF(MemoryAccess, "Issuing SC\n"); | 208 DPRINTF(RubyPort, "Issuing SC\n"); |
209 type = RubyRequestType_Store_Conditional; 210 } else { | 209 type = RubyRequestType_Store_Conditional; 210 } else { |
211 DPRINTF(MemoryAccess, "Issuing LL\n"); | 211 DPRINTF(RubyPort, "Issuing LL\n"); |
212 assert(pkt->isRead()); 213 type = RubyRequestType_Load_Linked; 214 } 215 } else if (pkt->req->isLocked()) { 216 if (pkt->isWrite()) { | 212 assert(pkt->isRead()); 213 type = RubyRequestType_Load_Linked; 214 } 215 } else if (pkt->req->isLocked()) { 216 if (pkt->isWrite()) { |
217 DPRINTF(MemoryAccess, "Issuing Locked RMW Write\n"); | 217 DPRINTF(RubyPort, "Issuing Locked RMW Write\n"); |
218 type = RubyRequestType_Locked_RMW_Write; 219 } else { | 218 type = RubyRequestType_Locked_RMW_Write; 219 } else { |
220 DPRINTF(MemoryAccess, "Issuing Locked RMW Read\n"); | 220 DPRINTF(RubyPort, "Issuing Locked RMW Read\n"); |
221 assert(pkt->isRead()); 222 type = RubyRequestType_Locked_RMW_Read; 223 } 224 } else { 225 if (pkt->isRead()) { 226 if (pkt->req->isInstFetch()) { 227 type = RubyRequestType_IFETCH; 228 } else { --- 29 unchanged lines hidden (view full) --- 258 259 // Submit the ruby request 260 RequestStatus requestStatus = ruby_port->makeRequest(ruby_request); 261 262 // If the request successfully issued then we should return true. 263 // Otherwise, we need to delete the senderStatus we just created and return 264 // false. 265 if (requestStatus == RequestStatus_Issued) { | 221 assert(pkt->isRead()); 222 type = RubyRequestType_Locked_RMW_Read; 223 } 224 } else { 225 if (pkt->isRead()) { 226 if (pkt->req->isInstFetch()) { 227 type = RubyRequestType_IFETCH; 228 } else { --- 29 unchanged lines hidden (view full) --- 258 259 // Submit the ruby request 260 RequestStatus requestStatus = ruby_port->makeRequest(ruby_request); 261 262 // If the request successfully issued then we should return true. 263 // Otherwise, we need to delete the senderStatus we just created and return 264 // false. 265 if (requestStatus == RequestStatus_Issued) { |
266 DPRINTF(MemoryAccess, "Request %x issued\n", pkt->getAddr()); | 266 DPRINTF(RubyPort, "Request %#x issued\n", pkt->getAddr()); |
267 return true; 268 } 269 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 | 267 return true; 268 } 269 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(MemoryAccess, | 278 DPRINTF(RubyPort, |
279 "Request for address %#x did not issue because %s\n", 280 pkt->getAddr(), RequestStatus_to_string(requestStatus)); 281 282 SenderState* senderState = safe_cast<SenderState*>(pkt->senderState); 283 pkt->senderState = senderState->saved; 284 delete senderState; 285 return false; 286} --- 59 unchanged lines hidden (view full) --- 346 } else { 347 // 348 // All LL packets convert to normal loads so that M5 PhysMem does 349 // not lock the blocks. 350 // 351 pkt->convertLlToRead(); 352 } 353 } | 279 "Request for address %#x did not issue because %s\n", 280 pkt->getAddr(), RequestStatus_to_string(requestStatus)); 281 282 SenderState* senderState = safe_cast<SenderState*>(pkt->senderState); 283 pkt->senderState = senderState->saved; 284 delete senderState; 285 return false; 286} --- 59 unchanged lines hidden (view full) --- 346 } else { 347 // 348 // All LL packets convert to normal loads so that M5 PhysMem does 349 // not lock the blocks. 350 // 351 pkt->convertLlToRead(); 352 } 353 } |
354 DPRINTF(MemoryAccess, "Hit callback needs response %d\n", needsResponse); | 354 DPRINTF(RubyPort, "Hit callback needs response %d\n", needsResponse); |
355 356 if (accessPhysMem) { 357 ruby_port->physMemPort->sendAtomic(pkt); 358 } else { 359 pkt->makeResponse(); 360 } 361 362 // turn packet around to go back to requester if response expected 363 if (needsResponse) { | 355 356 if (accessPhysMem) { 357 ruby_port->physMemPort->sendAtomic(pkt); 358 } else { 359 pkt->makeResponse(); 360 } 361 362 // turn packet around to go back to requester if response expected 363 if (needsResponse) { |
364 DPRINTF(MemoryAccess, "Sending packet back over port\n"); | 364 DPRINTF(RubyPort, "Sending packet back over port\n"); |
365 sendTiming(pkt); 366 } else { 367 delete pkt; 368 } | 365 sendTiming(pkt); 366 } else { 367 delete pkt; 368 } |
369 DPRINTF(MemoryAccess, "Hit callback done!\n"); | 369 DPRINTF(RubyPort, "Hit callback done!\n"); |
370} 371 372bool 373RubyPort::M5Port::sendTiming(PacketPtr pkt) 374{ 375 //minimum latency, must be > 0 376 schedSendTiming(pkt, curTick() + (1 * g_eventQueue_ptr->getClock())); 377 return true; --- 12 unchanged lines hidden (view full) --- 390{ 391 AddrRangeList physMemAddrList; 392 bool snoop = false; 393 ruby_port->physMemPort->getPeerAddressRanges(physMemAddrList, snoop); 394 for (AddrRangeIter iter = physMemAddrList.begin(); 395 iter != physMemAddrList.end(); 396 iter++) { 397 if (addr >= iter->start && addr <= iter->end) { | 370} 371 372bool 373RubyPort::M5Port::sendTiming(PacketPtr pkt) 374{ 375 //minimum latency, must be > 0 376 schedSendTiming(pkt, curTick() + (1 * g_eventQueue_ptr->getClock())); 377 return true; --- 12 unchanged lines hidden (view full) --- 390{ 391 AddrRangeList physMemAddrList; 392 bool snoop = false; 393 ruby_port->physMemPort->getPeerAddressRanges(physMemAddrList, snoop); 394 for (AddrRangeIter iter = physMemAddrList.begin(); 395 iter != physMemAddrList.end(); 396 iter++) { 397 if (addr >= iter->start && addr <= iter->end) { |
398 DPRINTF(MemoryAccess, "Request found in %#llx - %#llx range\n", | 398 DPRINTF(RubyPort, "Request found in %#llx - %#llx range\n", |
399 iter->start, iter->end); 400 return true; 401 } 402 } 403 return false; 404} 405 406unsigned 407RubyPort::M5Port::deviceBlockSize() const 408{ 409 return (unsigned) RubySystem::getBlockSizeBytes(); 410} | 399 iter->start, iter->end); 400 return true; 401 } 402 } 403 return false; 404} 405 406unsigned 407RubyPort::M5Port::deviceBlockSize() const 408{ 409 return (unsigned) RubySystem::getBlockSizeBytes(); 410} |