gem5_to_tlm.cc (13823:040971e0f728) | gem5_to_tlm.cc (13846:af21c0a800fb) |
---|---|
1/* 2 * Copyright 2019 Google, Inc. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer; 8 * redistributions in binary form must reproduce the above copyright --- 66 unchanged lines hidden (view full) --- 75/** 76 * Instantiate a tlm memory manager that takes care about all the 77 * tlm transactions in the system. 78 */ 79Gem5SystemC::MemoryManager mm; 80 81/** 82 * Convert a gem5 packet to a TLM payload by copying all the relevant | 1/* 2 * Copyright 2019 Google, Inc. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer; 8 * redistributions in binary form must reproduce the above copyright --- 66 unchanged lines hidden (view full) --- 75/** 76 * Instantiate a tlm memory manager that takes care about all the 77 * tlm transactions in the system. 78 */ 79Gem5SystemC::MemoryManager mm; 80 81/** 82 * Convert a gem5 packet to a TLM payload by copying all the relevant |
83 * information to a previously allocated tlm payload | 83 * information to new tlm payload. |
84 */ | 84 */ |
85void 86packet2payload(PacketPtr packet, tlm::tlm_generic_payload &trans) | 85tlm::tlm_generic_payload * 86packet2payload(PacketPtr packet) |
87{ | 87{ |
88 trans.set_address(packet->getAddr()); | 88 tlm::tlm_generic_payload *trans = mm.allocate(); 89 trans->acquire(); |
89 | 90 |
91 trans->set_address(packet->getAddr()); 92 |
|
90 /* Check if this transaction was allocated by mm */ | 93 /* Check if this transaction was allocated by mm */ |
91 sc_assert(trans.has_mm()); | 94 sc_assert(trans->has_mm()); |
92 93 unsigned int size = packet->getSize(); 94 unsigned char *data = packet->getPtr<unsigned char>(); 95 | 95 96 unsigned int size = packet->getSize(); 97 unsigned char *data = packet->getPtr<unsigned char>(); 98 |
96 trans.set_data_length(size); 97 trans.set_streaming_width(size); 98 trans.set_data_ptr(data); | 99 trans->set_data_length(size); 100 trans->set_streaming_width(size); 101 trans->set_data_ptr(data); |
99 | 102 |
100 if (packet->isRead()) { 101 trans.set_command(tlm::TLM_READ_COMMAND); | 103 if ((packet->req->getFlags() & Request::NO_ACCESS) != 0) { 104 /* Do nothing */ 105 trans->set_command(tlm::TLM_IGNORE_COMMAND); 106 } else if (packet->isRead()) { 107 trans->set_command(tlm::TLM_READ_COMMAND); |
102 } else if (packet->isInvalidate()) { 103 /* Do nothing */ | 108 } else if (packet->isInvalidate()) { 109 /* Do nothing */ |
110 trans->set_command(tlm::TLM_IGNORE_COMMAND); |
|
104 } else if (packet->isWrite()) { | 111 } else if (packet->isWrite()) { |
105 trans.set_command(tlm::TLM_WRITE_COMMAND); | 112 trans->set_command(tlm::TLM_WRITE_COMMAND); |
106 } else { 107 SC_REPORT_FATAL("Gem5ToTlmBridge", "No R/W packet"); 108 } | 113 } else { 114 SC_REPORT_FATAL("Gem5ToTlmBridge", "No R/W packet"); 115 } |
116 117 // Attach the packet pointer to the TLM transaction to keep track. 118 auto *extension = new Gem5SystemC::Gem5Extension(packet); 119 trans->set_auto_extension(extension); 120 121 return trans; |
|
109} 110 111template <unsigned int BITWIDTH> 112void 113Gem5ToTlmBridge<BITWIDTH>::pec( 114 Gem5SystemC::PayloadEvent<Gem5ToTlmBridge<BITWIDTH>> *pe, 115 tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase) 116{ --- 44 unchanged lines hidden (view full) --- 161 // Release the transaction with all the extensions. 162 trans.release(); 163 } 164 } 165 } 166 delete pe; 167} 168 | 122} 123 124template <unsigned int BITWIDTH> 125void 126Gem5ToTlmBridge<BITWIDTH>::pec( 127 Gem5SystemC::PayloadEvent<Gem5ToTlmBridge<BITWIDTH>> *pe, 128 tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase) 129{ --- 44 unchanged lines hidden (view full) --- 174 // Release the transaction with all the extensions. 175 trans.release(); 176 } 177 } 178 } 179 delete pe; 180} 181 |
182template <unsigned int BITWIDTH> 183MemBackdoorPtr 184Gem5ToTlmBridge<BITWIDTH>::getBackdoor(tlm::tlm_generic_payload &trans) 185{ 186 sc_dt::uint64 start = trans.get_address(); 187 sc_dt::uint64 end = start + trans.get_data_length(); 188 189 // Check for a back door we already know about. 190 AddrRange r(start, end); 191 auto it = backdoorMap.contains(r); 192 if (it != backdoorMap.end()) 193 return it->second; 194 195 // If not, ask the target for one. 196 tlm::tlm_dmi dmi_data; 197 if (!socket->get_direct_mem_ptr(trans, dmi_data)) 198 return nullptr; 199 200 // If the target gave us one, translate it to a gem5 MemBackdoor and 201 // store it in our cache. 202 AddrRange dmi_r(dmi_data.get_start_address(), dmi_data.get_end_address()); 203 auto backdoor = new MemBackdoor( 204 dmi_r, dmi_data.get_dmi_ptr(), MemBackdoor::NoAccess); 205 backdoor->readable(dmi_data.is_read_allowed()); 206 backdoor->writeable(dmi_data.is_write_allowed()); 207 208 backdoorMap.insert(dmi_r, backdoor); 209 210 return backdoor; 211} 212 |
|
169// Similar to TLM's blocking transport (LT) 170template <unsigned int BITWIDTH> 171Tick 172Gem5ToTlmBridge<BITWIDTH>::recvAtomic(PacketPtr packet) 173{ 174 panic_if(packet->cacheResponding(), 175 "Should not see packets where cache is responding"); 176 | 213// Similar to TLM's blocking transport (LT) 214template <unsigned int BITWIDTH> 215Tick 216Gem5ToTlmBridge<BITWIDTH>::recvAtomic(PacketPtr packet) 217{ 218 panic_if(packet->cacheResponding(), 219 "Should not see packets where cache is responding"); 220 |
177 panic_if(!(packet->isRead() || packet->isWrite()), 178 "Should only see read and writes at TLM memory\n"); | 221 // Prepare the transaction. 222 auto *trans = packet2payload(packet); |
179 180 sc_core::sc_time delay = sc_core::SC_ZERO_TIME; 181 | 223 224 sc_core::sc_time delay = sc_core::SC_ZERO_TIME; 225 |
182 // Prepare the transaction. 183 tlm::tlm_generic_payload *trans = mm.allocate(); 184 trans->acquire(); 185 packet2payload(packet, *trans); | 226 if (trans->get_command() != tlm::TLM_IGNORE_COMMAND) { 227 // Execute b_transport: 228 socket->b_transport(*trans, delay); 229 } |
186 | 230 |
187 // Attach the packet pointer to the TLM transaction to keep track. 188 auto *extension = new Gem5SystemC::Gem5Extension(packet); 189 trans->set_auto_extension(extension); | 231 if (packet->needsResponse()) 232 packet->makeResponse(); |
190 | 233 |
191 // Execute b_transport: 192 if (packet->cmd == MemCmd::SwapReq) { 193 SC_REPORT_FATAL("Gem5ToTlmBridge", "SwapReq not supported"); 194 } else if (packet->isRead()) { | 234 trans->release(); 235 236 return delay.value(); 237} 238 239template <unsigned int BITWIDTH> 240Tick 241Gem5ToTlmBridge<BITWIDTH>::recvAtomicBackdoor( 242 PacketPtr packet, MemBackdoorPtr &backdoor) 243{ 244 panic_if(packet->cacheResponding(), 245 "Should not see packets where cache is responding"); 246 247 sc_core::sc_time delay = sc_core::SC_ZERO_TIME; 248 249 // Prepare the transaction. 250 auto *trans = packet2payload(packet); 251 252 if (trans->get_command() != tlm::TLM_IGNORE_COMMAND) { 253 // Execute b_transport: |
195 socket->b_transport(*trans, delay); | 254 socket->b_transport(*trans, delay); |
196 } else if (packet->isInvalidate()) { 197 // do nothing 198 } else if (packet->isWrite()) { 199 socket->b_transport(*trans, delay); | 255 // If the hint said we could use DMI, set that up. 256 if (trans->is_dmi_allowed()) 257 backdoor = getBackdoor(*trans); |
200 } else { | 258 } else { |
201 SC_REPORT_FATAL("Gem5ToTlmBridge", "Typo of request not supported"); | 259 // There's no transaction to piggy back on, so just request the 260 // backdoor normally. 261 backdoor = getBackdoor(*trans); |
202 } 203 | 262 } 263 |
204 if (packet->needsResponse()) { | 264 if (packet->needsResponse()) |
205 packet->makeResponse(); | 265 packet->makeResponse(); |
206 } | |
207 208 trans->release(); 209 210 return delay.value(); 211} 212 213template <unsigned int BITWIDTH> 214void --- 34 unchanged lines hidden (view full) --- 249 * if (requestInProgress) 250 * { 251 * wait(endRequestEvent); 252 * } 253 * requestInProgress = trans; 254 */ 255 256 // Prepare the transaction. | 266 267 trans->release(); 268 269 return delay.value(); 270} 271 272template <unsigned int BITWIDTH> 273void --- 34 unchanged lines hidden (view full) --- 308 * if (requestInProgress) 309 * { 310 * wait(endRequestEvent); 311 * } 312 * requestInProgress = trans; 313 */ 314 315 // Prepare the transaction. |
257 tlm::tlm_generic_payload *trans = mm.allocate(); 258 trans->acquire(); 259 packet2payload(packet, *trans); | 316 auto *trans = packet2payload(packet); |
260 | 317 |
261 // Attach the packet pointer to the TLM transaction to keep track. 262 auto *extension = new Gem5SystemC::Gem5Extension(packet); 263 trans->set_auto_extension(extension); 264 | |
265 /* 266 * Pay for annotated transport delays. 267 * 268 * The header delay marks the point in time, when the packet first is seen 269 * by the transactor. This is the point in time when the transactor needs 270 * to send the BEGIN_REQ to the SystemC world. 271 * 272 * NOTE: We drop the payload delay here. Normally, the receiver would be --- 84 unchanged lines hidden (view full) --- 357} 358 359// Similar to TLM's debug transport. 360template <unsigned int BITWIDTH> 361void 362Gem5ToTlmBridge<BITWIDTH>::recvFunctional(PacketPtr packet) 363{ 364 // Prepare the transaction. | 318 /* 319 * Pay for annotated transport delays. 320 * 321 * The header delay marks the point in time, when the packet first is seen 322 * by the transactor. This is the point in time when the transactor needs 323 * to send the BEGIN_REQ to the SystemC world. 324 * 325 * NOTE: We drop the payload delay here. Normally, the receiver would be --- 84 unchanged lines hidden (view full) --- 410} 411 412// Similar to TLM's debug transport. 413template <unsigned int BITWIDTH> 414void 415Gem5ToTlmBridge<BITWIDTH>::recvFunctional(PacketPtr packet) 416{ 417 // Prepare the transaction. |
365 tlm::tlm_generic_payload *trans = mm.allocate(); 366 trans->acquire(); 367 packet2payload(packet, *trans); | 418 auto *trans = packet2payload(packet); |
368 | 419 |
369 // Attach the packet pointer to the TLM transaction to keep track. 370 auto *extension = new Gem5SystemC::Gem5Extension(packet); 371 trans->set_auto_extension(extension); 372 | |
373 /* Execute Debug Transport: */ 374 unsigned int bytes = socket->transport_dbg(*trans); 375 if (bytes != trans->get_data_length()) { 376 SC_REPORT_FATAL("Gem5ToTlmBridge", 377 "debug transport was not completed"); 378 } 379 380 trans->release(); --- 8 unchanged lines hidden (view full) --- 389 *this, &Gem5ToTlmBridge::pec, "PE"); 390 Tick nextEventTick = curTick() + delay.value(); 391 system->wakeupEventQueue(nextEventTick); 392 system->schedule(pe, nextEventTick); 393 return tlm::TLM_ACCEPTED; 394} 395 396template <unsigned int BITWIDTH> | 420 /* Execute Debug Transport: */ 421 unsigned int bytes = socket->transport_dbg(*trans); 422 if (bytes != trans->get_data_length()) { 423 SC_REPORT_FATAL("Gem5ToTlmBridge", 424 "debug transport was not completed"); 425 } 426 427 trans->release(); --- 8 unchanged lines hidden (view full) --- 436 *this, &Gem5ToTlmBridge::pec, "PE"); 437 Tick nextEventTick = curTick() + delay.value(); 438 system->wakeupEventQueue(nextEventTick); 439 system->schedule(pe, nextEventTick); 440 return tlm::TLM_ACCEPTED; 441} 442 443template <unsigned int BITWIDTH> |
444void 445Gem5ToTlmBridge<BITWIDTH>::invalidate_direct_mem_ptr( 446 sc_dt::uint64 start_range, sc_dt::uint64 end_range) 447{ 448 AddrRange r(start_range, end_range); 449 450 for (;;) { 451 auto it = backdoorMap.intersects(r); 452 if (it == backdoorMap.end()) 453 break; 454 455 it->second->invalidate(); 456 delete it->second; 457 backdoorMap.erase(it); 458 }; 459} 460 461template <unsigned int BITWIDTH> |
|
397Gem5ToTlmBridge<BITWIDTH>::Gem5ToTlmBridge( 398 Params *params, const sc_core::sc_module_name &mn) : 399 Gem5ToTlmBridgeBase(mn), bsp(std::string(name()) + ".gem5", *this), 400 socket("tlm_socket"), 401 wrapper(socket, std::string(name()) + ".tlm", InvalidPortID), 402 system(params->system), blockingRequest(nullptr), 403 needToSendRequestRetry(false), blockingResponse(nullptr), 404 addrRanges(params->addr_ranges.begin(), params->addr_ranges.end()) --- 14 unchanged lines hidden (view full) --- 419 420template <unsigned int BITWIDTH> 421void 422Gem5ToTlmBridge<BITWIDTH>::before_end_of_elaboration() 423{ 424 bsp.sendRangeChange(); 425 426 socket.register_nb_transport_bw(this, &Gem5ToTlmBridge::nb_transport_bw); | 462Gem5ToTlmBridge<BITWIDTH>::Gem5ToTlmBridge( 463 Params *params, const sc_core::sc_module_name &mn) : 464 Gem5ToTlmBridgeBase(mn), bsp(std::string(name()) + ".gem5", *this), 465 socket("tlm_socket"), 466 wrapper(socket, std::string(name()) + ".tlm", InvalidPortID), 467 system(params->system), blockingRequest(nullptr), 468 needToSendRequestRetry(false), blockingResponse(nullptr), 469 addrRanges(params->addr_ranges.begin(), params->addr_ranges.end()) --- 14 unchanged lines hidden (view full) --- 484 485template <unsigned int BITWIDTH> 486void 487Gem5ToTlmBridge<BITWIDTH>::before_end_of_elaboration() 488{ 489 bsp.sendRangeChange(); 490 491 socket.register_nb_transport_bw(this, &Gem5ToTlmBridge::nb_transport_bw); |
492 socket.register_invalidate_direct_mem_ptr( 493 this, &Gem5ToTlmBridge::invalidate_direct_mem_ptr); |
|
427 sc_core::sc_module::before_end_of_elaboration(); 428} 429 430} // namespace sc_gem5 431 432sc_gem5::Gem5ToTlmBridge<32> * 433Gem5ToTlmBridge32Params::create() 434{ 435 return new sc_gem5::Gem5ToTlmBridge<32>( 436 this, sc_core::sc_module_name(name.c_str())); 437} 438 439sc_gem5::Gem5ToTlmBridge<64> * 440Gem5ToTlmBridge64Params::create() 441{ 442 return new sc_gem5::Gem5ToTlmBridge<64>( 443 this, sc_core::sc_module_name(name.c_str())); 444} | 494 sc_core::sc_module::before_end_of_elaboration(); 495} 496 497} // namespace sc_gem5 498 499sc_gem5::Gem5ToTlmBridge<32> * 500Gem5ToTlmBridge32Params::create() 501{ 502 return new sc_gem5::Gem5ToTlmBridge<32>( 503 this, sc_core::sc_module_name(name.c_str())); 504} 505 506sc_gem5::Gem5ToTlmBridge<64> * 507Gem5ToTlmBridge64Params::create() 508{ 509 return new sc_gem5::Gem5ToTlmBridge<64>( 510 this, sc_core::sc_module_name(name.c_str())); 511} |