RubyPort.cc (6899:f8057af86bf7) | RubyPort.cc (6922:1620cffaa3b6) |
---|---|
1 2/* 3 * Copyright (c) 2009 Advanced Micro Devices, Inc. 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 --- 18 unchanged lines hidden (view full) --- 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include "mem/physical.hh" 31#include "mem/ruby/system/RubyPort.hh" 32#include "mem/ruby/slicc_interface/AbstractController.hh" 33#include "cpu/rubytest/RubyTester.hh" 34 | 1 2/* 3 * Copyright (c) 2009 Advanced Micro Devices, Inc. 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 --- 18 unchanged lines hidden (view full) --- 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include "mem/physical.hh" 31#include "mem/ruby/system/RubyPort.hh" 32#include "mem/ruby/slicc_interface/AbstractController.hh" 33#include "cpu/rubytest/RubyTester.hh" 34 |
35uint16_t RubyPort::m_num_ports = 0; 36 37RubyPort::RequestMap RubyPort::pending_cpu_requests; 38 | |
39RubyPort::RubyPort(const Params *p) 40 : MemObject(p) 41{ 42 m_version = p->version; 43 assert(m_version != -1); 44 45 physmem = p->physmem; 46 47 m_controller = NULL; 48 m_mandatory_q_ptr = NULL; 49 | 35RubyPort::RubyPort(const Params *p) 36 : MemObject(p) 37{ 38 m_version = p->version; 39 assert(m_version != -1); 40 41 physmem = p->physmem; 42 43 m_controller = NULL; 44 m_mandatory_q_ptr = NULL; 45 |
50 m_port_id = m_num_ports++; | |
51 m_request_cnt = 0; | 46 m_request_cnt = 0; |
52 m_hit_callback = ruby_hit_callback; | |
53 pio_port = NULL; 54 physMemPort = NULL; | 47 pio_port = NULL; 48 physMemPort = NULL; |
55 assert(m_num_ports <= 2048); // see below for reason | |
56} 57 58void RubyPort::init() 59{ 60 assert(m_controller != NULL); 61 m_mandatory_q_ptr = m_controller->getMandatoryQueue(); 62} 63 --- 100 unchanged lines hidden (view full) --- 164{ 165 DPRINTF(MemoryAccess, 166 "Timing access caught for address %#x\n", 167 pkt->getAddr()); 168 169 //dsm: based on SimpleTimingPort::recvTiming(pkt); 170 171 // | 49} 50 51void RubyPort::init() 52{ 53 assert(m_controller != NULL); 54 m_mandatory_q_ptr = m_controller->getMandatoryQueue(); 55} 56 --- 100 unchanged lines hidden (view full) --- 157{ 158 DPRINTF(MemoryAccess, 159 "Timing access caught for address %#x\n", 160 pkt->getAddr()); 161 162 //dsm: based on SimpleTimingPort::recvTiming(pkt); 163 164 // |
172 // After checking for pio responses, the remainder of packets 173 // received by ruby should only be M5 requests, which should never | 165 // The received packets should only be M5 requests, which should never |
174 // get nacked. There used to be code to hanldle nacks here, but 175 // I'm pretty sure it didn't work correctly with the drain code, 176 // so that would need to be fixed if we ever added it back. 177 // 178 assert(pkt->isRequest()); 179 180 if (pkt->memInhibitAsserted()) { 181 warn("memInhibitAsserted???"); 182 // snooper will supply based on copy of packet 183 // still target's responsibility to delete packet 184 delete pkt; 185 return true; 186 } 187 188 // | 166 // get nacked. There used to be code to hanldle nacks here, but 167 // I'm pretty sure it didn't work correctly with the drain code, 168 // so that would need to be fixed if we ever added it back. 169 // 170 assert(pkt->isRequest()); 171 172 if (pkt->memInhibitAsserted()) { 173 warn("memInhibitAsserted???"); 174 // snooper will supply based on copy of packet 175 // still target's responsibility to delete packet 176 delete pkt; 177 return true; 178 } 179 180 // |
181 // Save the port in the sender state object to be used later to 182 // route the response 183 // 184 pkt->senderState = new SenderState(this, pkt->senderState); 185 186 // |
|
189 // Check for pio requests and directly send them to the dedicated 190 // pio port. 191 // 192 if (!isPhysMemAddress(pkt->getAddr())) { 193 assert(ruby_port->pio_port != NULL); | 187 // Check for pio requests and directly send them to the dedicated 188 // pio port. 189 // 190 if (!isPhysMemAddress(pkt->getAddr())) { 191 assert(ruby_port->pio_port != NULL); |
192 DPRINTF(MemoryAccess, 193 "Request for address 0x%#x is assumed to be a pio request\n", 194 pkt->getAddr()); |
|
194 | 195 |
195 // 196 // Save the port in the sender state object to be used later to 197 // route the response 198 // 199 pkt->senderState = new SenderState(this, pkt->senderState); 200 | |
201 return ruby_port->pio_port->sendTiming(pkt); 202 } 203 204 // 205 // For DMA and CPU requests, translate them to ruby requests before 206 // sending them to our assigned ruby port. 207 // 208 RubyRequestType type = RubyRequestType_NULL; --- 11 unchanged lines hidden (view full) --- 220 type = RubyRequestType_IFETCH; 221 } else { 222 type = RubyRequestType_LD; 223 } 224 } else if (pkt->isWrite()) { 225 type = RubyRequestType_ST; 226 } else if (pkt->isReadWrite()) { 227 type = RubyRequestType_RMW_Write; | 196 return ruby_port->pio_port->sendTiming(pkt); 197 } 198 199 // 200 // For DMA and CPU requests, translate them to ruby requests before 201 // sending them to our assigned ruby port. 202 // 203 RubyRequestType type = RubyRequestType_NULL; --- 11 unchanged lines hidden (view full) --- 215 type = RubyRequestType_IFETCH; 216 } else { 217 type = RubyRequestType_LD; 218 } 219 } else if (pkt->isWrite()) { 220 type = RubyRequestType_ST; 221 } else if (pkt->isReadWrite()) { 222 type = RubyRequestType_RMW_Write; |
223 } else { 224 panic("Unsupported ruby packet type\n"); |
|
228 } 229 | 225 } 226 |
230 RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(), 231 pkt->getSize(), pc, type, 232 RubyAccessMode_Supervisor); | 227 RubyRequest ruby_request(pkt->getAddr(), 228 pkt->getPtr<uint8_t>(), 229 pkt->getSize(), 230 pc, 231 type, 232 RubyAccessMode_Supervisor, 233 pkt); |
233 234 // Submit the ruby request | 234 235 // Submit the ruby request |
235 int64_t req_id = ruby_port->makeRequest(ruby_request); 236 if (req_id == -1) { 237 return false; | 236 RequestStatus requestStatus = ruby_port->makeRequest(ruby_request); 237 if (requestStatus == RequestStatus_Issued) { 238 return true; |
238 } | 239 } |
239 240 // Save the request for the callback 241 RubyPort::pending_cpu_requests[req_id] = new RequestCookie(pkt, this); 242 243 return true; | 240 241 DPRINTF(MemoryAccess, 242 "Request for address #x did not issue because %s\n", 243 pkt->getAddr(), 244 RequestStatus_to_string(requestStatus)); 245 246 SenderState* senderState = safe_cast<SenderState*>(pkt->senderState); 247 pkt->senderState = senderState->saved; 248 delete senderState; 249 return false; |
244} 245 246void | 250} 251 252void |
247RubyPort::ruby_hit_callback(int64_t req_id) | 253RubyPort::ruby_hit_callback(PacketPtr pkt) |
248{ 249 // | 254{ 255 // |
250 // Note: This single fuction can be called by cpu and dma ports, 251 // as well as the functional port. | 256 // Retrieve the request port from the sender State |
252 // | 257 // |
253 RequestMap::iterator i = pending_cpu_requests.find(req_id); 254 if (i == pending_cpu_requests.end()) 255 panic("could not find pending request %d\n", req_id); | 258 RubyPort::SenderState *senderState = 259 safe_cast<RubyPort::SenderState *>(pkt->senderState); 260 M5Port *port = senderState->port; 261 assert(port != NULL); 262 263 // pop the sender state from the packet 264 pkt->senderState = senderState->saved; 265 delete senderState; |
256 | 266 |
257 RequestCookie *cookie = i->second; 258 pending_cpu_requests.erase(i); 259 260 Packet *pkt = cookie->pkt; 261 M5Port *port = cookie->m5Port; 262 delete cookie; 263 | |
264 port->hitCallback(pkt); 265} 266 267void 268RubyPort::M5Port::hitCallback(PacketPtr pkt) 269{ 270 271 bool needsResponse = pkt->needsResponse(); --- 50 unchanged lines hidden --- | 267 port->hitCallback(pkt); 268} 269 270void 271RubyPort::M5Port::hitCallback(PacketPtr pkt) 272{ 273 274 bool needsResponse = pkt->needsResponse(); --- 50 unchanged lines hidden --- |