48 #include "debug/LLSC.hh"
49 #include "debug/MemoryAccess.hh"
50 #include "debug/ProtocolTrace.hh"
51 #include "debug/RubySequencer.hh"
52 #include "debug/RubyStats.hh"
55 #include "mem/ruby/protocol/PrefetchBit.hh"
56 #include "mem/ruby/protocol/RubyAccessMode.hh"
63 :
RubyPort(
p), m_IncompleteTimes(MachineType_NUM),
64 deadlockCheckEvent([this]{
wakeup(); },
"Sequencer deadlock check")
66 m_outstanding_count = 0;
68 m_dataCache_ptr =
p.dcache;
69 m_max_outstanding_requests =
p.max_outstanding_requests;
70 m_deadlock_threshold =
p.deadlock_threshold;
73 assert(m_max_outstanding_requests > 0);
74 assert(m_deadlock_threshold > 0);
76 m_runningGarnetStandalone =
p.garnet_standalone;
82 m_outstandReqHist.init(10);
83 m_latencyHist.init(10);
84 m_hitLatencyHist.init(10);
85 m_missLatencyHist.init(10);
87 for (
int i = 0;
i < RubyRequestType_NUM;
i++) {
89 m_typeLatencyHist[
i]->init(10);
92 m_hitTypeLatencyHist[
i]->init(10);
95 m_missTypeLatencyHist[
i]->init(10);
98 for (
int i = 0;
i < MachineType_NUM;
i++) {
100 m_hitMachLatencyHist[
i]->init(10);
103 m_missMachLatencyHist[
i]->init(10);
106 m_IssueToInitialDelayHist[
i]->init(10);
109 m_InitialToForwardDelayHist[
i]->init(10);
112 m_ForwardToFirstResponseDelayHist[
i]->init(10);
115 m_FirstResponseToCompletionDelayHist[
i]->init(10);
118 for (
int i = 0;
i < RubyRequestType_NUM;
i++) {
122 for (
int j = 0;
j < MachineType_NUM;
j++) {
124 m_hitTypeMachLatencyHist[
i][
j]->init(10);
127 m_missTypeMachLatencyHist[
i][
j]->init(10);
141 "%s must have a dcache object to support LLSC requests.",
name());
145 DPRINTF(LLSC,
"LLSC Monitor - inserting load linked - "
146 "addr=0x%lx - cpu=%u\n", claddr,
m_version);
159 DPRINTF(LLSC,
"LLSC Monitor - clearing due to store - "
160 "addr=0x%lx - cpu=%u\n", claddr,
m_version);
168 "%s must have a dcache object to support LLSC requests.",
name());
173 DPRINTF(LLSC,
"LLSC Monitor - clearing due to "
174 "store conditional - "
175 "addr=0x%lx - cpu=%u\n",
218 int total_outstanding = 0;
221 for (
const auto &seq_req : table_entry.second) {
225 panic(
"Possible Deadlock detected. Aborting!\n version: %d "
226 "request.paddr: 0x%x m_readRequestTable: %d current time: "
227 "%u issue_time: %d difference: %d\n",
m_version,
228 seq_req.pkt->getAddr(), table_entry.second.size(),
233 total_outstanding += table_entry.second.size();
250 for (
const auto& seq_req : table_entry.second) {
251 if (seq_req.functionalWrite(func_pkt))
265 for (
int i = 0;
i < RubyRequestType_NUM;
i++) {
269 for (
int j = 0;
j < MachineType_NUM;
j++) {
275 for (
int i = 0;
i < MachineType_NUM;
i++) {
292 RubyRequestType secondary_type)
304 seq_req_list.emplace_back(pkt, primary_type,
308 if (seq_req_list.size() > 1) {
309 return RequestStatus_Aliased;
314 return RequestStatus_Ready;
325 const MachineType respondingMach,
326 bool isExternalHit,
Cycles initialRequestTime,
327 Cycles forwardRequestTime,
335 Cycles total_lat = completion_time - issued_time;
337 if ((initialRequestTime != 0) && (initialRequestTime < issued_time)) {
346 DPRINTFR(ProtocolTrace,
"%15s %3s %10s%20s %6s>%-6s %s %d cycles\n",
357 if (respondingMach != MachineType_NUM) {
361 if ((issued_time <= initialRequestTime) &&
362 (initialRequestTime <= forwardRequestTime) &&
363 (forwardRequestTime <= firstResponseTime) &&
364 (firstResponseTime <= completion_time)) {
367 initialRequestTime - issued_time);
369 forwardRequestTime - initialRequestTime);
371 firstResponseTime - forwardRequestTime);
373 completion_time - firstResponseTime);
382 if (respondingMach != MachineType_NUM) {
398 const bool externalHit,
const MachineType mach,
399 const Cycles initialRequestTime,
400 const Cycles forwardRequestTime,
401 const Cycles firstResponseTime,
415 bool ruby_request =
true;
416 int aliased_stores = 0;
417 int aliased_loads = 0;
418 while (!seq_req_list.empty()) {
421 if (noCoales && !ruby_request) {
430 assert(seq_req.
m_type != RubyRequestType_LD);
431 assert(seq_req.
m_type != RubyRequestType_Load_Linked);
432 assert(seq_req.
m_type != RubyRequestType_IFETCH);
436 if ((seq_req.
m_type != RubyRequestType_LD) &&
437 (seq_req.
m_type != RubyRequestType_Load_Linked) &&
438 (seq_req.
m_type != RubyRequestType_IFETCH)) {
442 if (seq_req.
m_type != RubyRequestType_Store_Conditional) {
450 seq_req.
pkt->
req->setExtraData(success ? 1 : 0);
456 if (seq_req.
m_type == RubyRequestType_Locked_RMW_Read) {
464 }
else if (seq_req.
m_type == RubyRequestType_Locked_RMW_Write) {
470 initialRequestTime, forwardRequestTime,
477 initialRequestTime, forwardRequestTime,
478 firstResponseTime, !ruby_request);
479 ruby_request =
false;
482 assert(!ruby_request);
486 initialRequestTime, forwardRequestTime,
487 firstResponseTime, !ruby_request);
489 seq_req_list.pop_front();
493 if (seq_req_list.empty()) {
500 bool externalHit,
const MachineType mach,
501 Cycles initialRequestTime,
502 Cycles forwardRequestTime,
516 bool ruby_request =
true;
517 int aliased_loads = 0;
518 while (!seq_req_list.empty()) {
521 assert((seq_req.
m_type == RubyRequestType_LD) ||
522 (seq_req.
m_type == RubyRequestType_Load_Linked) ||
523 (seq_req.
m_type == RubyRequestType_IFETCH));
527 if ((seq_req.
m_type != RubyRequestType_LD) &&
528 (seq_req.
m_type != RubyRequestType_Load_Linked) &&
529 (seq_req.
m_type != RubyRequestType_IFETCH)) {
536 initialRequestTime, forwardRequestTime,
541 initialRequestTime, forwardRequestTime,
542 firstResponseTime, !ruby_request);
543 ruby_request =
false;
544 seq_req_list.pop_front();
548 if (seq_req_list.empty()) {
556 const MachineType mach,
const bool externalHit,
557 const Cycles initialRequestTime,
558 const Cycles forwardRequestTime,
559 const Cycles firstResponseTime,
560 const bool was_coalesced)
562 warn_once(
"Replacement policy updates recently became the responsibility "
563 "of SLICC state machines. Make sure to setMRU() near callbacks "
579 if (
type == RubyRequestType_Load_Linked) {
588 if ((
type == RubyRequestType_LD) ||
589 (
type == RubyRequestType_IFETCH) ||
590 (
type == RubyRequestType_RMW_Read) ||
591 (
type == RubyRequestType_Locked_RMW_Read) ||
592 (
type == RubyRequestType_Load_Linked)) {
596 }
else if (pkt->
req->isSwap()) {
602 data.setData(&overwrite_val[0],
605 }
else if (
type != RubyRequestType_Store_Conditional || llscSuccess) {
617 DPRINTF(RubySequencer,
"hitCallback %s 0x%x using RubyTester\n",
621 assert(testerSenderState);
629 rs->m_cache_recorder->enqueueNextFetchRequest();
632 rs->m_cache_recorder->enqueueNextFlushRequest();
651 !pkt->
req->isHTMAbort()) {
652 return RequestStatus_BufferFull;
655 RubyRequestType primary_type = RubyRequestType_NULL;
656 RubyRequestType secondary_type = RubyRequestType_NULL;
670 DPRINTF(RubySequencer,
"Issuing SC\n");
671 primary_type = RubyRequestType_Store_Conditional;
672 #if defined (PROTOCOL_MESI_Three_Level) || defined (PROTOCOL_MESI_Three_Level_HTM)
673 secondary_type = RubyRequestType_Store_Conditional;
675 secondary_type = RubyRequestType_ST;
678 DPRINTF(RubySequencer,
"Issuing LL\n");
680 primary_type = RubyRequestType_Load_Linked;
681 secondary_type = RubyRequestType_LD;
683 }
else if (pkt->
req->isLockedRMW()) {
691 DPRINTF(RubySequencer,
"Issuing Locked RMW Write\n");
692 primary_type = RubyRequestType_Locked_RMW_Write;
694 DPRINTF(RubySequencer,
"Issuing Locked RMW Read\n");
696 primary_type = RubyRequestType_Locked_RMW_Read;
698 secondary_type = RubyRequestType_ST;
709 primary_type = secondary_type = RubyRequestType_ST;
710 }
else if (pkt->
isRead()) {
712 if (pkt->
req->isHTMCmd()) {
714 }
else if (pkt->
req->isInstFetch()) {
715 primary_type = secondary_type = RubyRequestType_IFETCH;
717 bool storeCheck =
false;
720 uint32_t flags = pkt->
req->getFlags();
725 primary_type = RubyRequestType_RMW_Read;
726 secondary_type = RubyRequestType_ST;
728 primary_type = secondary_type = RubyRequestType_LD;
732 primary_type = secondary_type = RubyRequestType_FLUSH;
734 panic(
"Unsupported ruby packet type\n");
740 (primary_type != RubyRequestType_Locked_RMW_Write)) {
744 return RequestStatus_Aliased;
750 if (
status != RequestStatus_Ready &&
status != RequestStatus_Aliased)
754 if (
status != RequestStatus_Aliased)
758 return RequestStatus_Issued;
772 if (pkt->
req->hasPC()) {
773 pc = pkt->
req->getPC();
778 std::shared_ptr<RubyRequest> msg =
781 RubyAccessMode_Supervisor, pkt,
782 PrefetchBit_No, proc_id, core_id);
784 DPRINTFR(ProtocolTrace,
"%15s %3s %10s%20s %6s>%-6s %#x %s\n",
787 RubyRequestType_to_string(secondary_type));
793 msg->m_htmFromTransaction =
true;
805 template <
class KEY,
class VALUE>
807 operator<<(std::ostream &out,
const std::unordered_map<KEY, VALUE> &map)
809 for (
const auto &table_entry : map) {
810 out <<
"[ " << table_entry.first <<
" =";
811 for (
const auto &seq_req : table_entry.second) {
812 out <<
" " << RubyRequestType_to_string(seq_req.m_second_type);
831 DPRINTF(RubyStats,
"Recorded statistic: %s\n",
832 SequencerRequestType_to_string(requestType));