[gem5-dev] Change in gem5/gem5[develop]: cpu: HTM Implementation for TimingCPU

2020-09-08 Thread Giacomo Travaglini (Gerrit) via gem5-dev
Giacomo Travaglini has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/30327 )


Change subject: cpu: HTM Implementation for TimingCPU
..

cpu: HTM Implementation for TimingCPU

JIRA: https://gem5.atlassian.net/browse/GEM5-587

Change-Id: I3e1de639560ea5492e914470e31bacb321425f0a
Signed-off-by: Giacomo Travaglini 
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/30327
Reviewed-by: Jason Lowe-Power 
Maintainer: Jason Lowe-Power 
Tested-by: kokoro 
---
M src/cpu/simple/base.cc
M src/cpu/simple/exec_context.hh
M src/cpu/simple/timing.cc
M src/cpu/simple_thread.cc
M src/cpu/simple_thread.hh
5 files changed, 272 insertions(+), 20 deletions(-)

Approvals:
  Jason Lowe-Power: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index a597f06..bf940ba 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -63,6 +63,7 @@
 #include "debug/Decode.hh"
 #include "debug/ExecFaulting.hh"
 #include "debug/Fetch.hh"
+#include "debug/HtmCpu.hh"
 #include "debug/Quiesce.hh"
 #include "mem/packet.hh"
 #include "mem/request.hh"
@@ -453,6 +454,17 @@
 Fault interrupt = interrupts[curThread]->getInterrupt();

 if (interrupt != NoFault) {
+// hardware transactional memory
+// Postpone taking interrupts while executing transactions.
+assert(!std::dynamic_pointer_cast(
+interrupt));
+if (t_info.inHtmTransactionalState()) {
+DPRINTF(HtmCpu, "Deferring pending interrupt - %s -"
+"due to transactional state\n",
+interrupt->name());
+return;
+}
+
 t_info.fetchOffset = 0;
 interrupts[curThread]->updateIntrInfo();
 interrupt->invoke(tc);
diff --git a/src/cpu/simple/exec_context.hh b/src/cpu/simple/exec_context.hh
index 41e1d3d..2b2afd2 100644
--- a/src/cpu/simple/exec_context.hh
+++ b/src/cpu/simple/exec_context.hh
@@ -475,8 +475,7 @@

 Fault initiateHtmCmd(Request::Flags flags) override
 {
-panic("Not yet supported\n");
-return NoFault;
+return cpu->initiateHtmCmd(flags);
 }

 /**
@@ -536,29 +535,26 @@
 uint64_t
 getHtmTransactionUid() const override
 {
-panic("Not yet supported\n");
-return 0;
+return tcBase()->getHtmCheckpointPtr()->getHtmUid();
 }

 uint64_t
 newHtmTransactionUid() const override
 {
-panic("Not yet supported\n");
-return 0;
+return tcBase()->getHtmCheckpointPtr()->newHtmUid();
 }

 bool
 inHtmTransactionalState() const override
 {
-panic("Not yet supported\n");
-return false;
+return (getHtmTransactionalDepth() > 0);
 }

 uint64_t
 getHtmTransactionalDepth() const override
 {
-panic("Not yet supported\n");
-return 0;
+assert(thread->htmTransactionStarts >=  
thread->htmTransactionStops);
+return (thread->htmTransactionStarts -  
thread->htmTransactionStops);

 }

 /**
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index d3adbcc..f22c58d 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -48,6 +48,7 @@
 #include "debug/Config.hh"
 #include "debug/Drain.hh"
 #include "debug/ExecFaulting.hh"
+#include "debug/HtmCpu.hh"
 #include "debug/Mwait.hh"
 #include "debug/SimpleCPU.hh"
 #include "mem/packet.hh"
@@ -173,6 +174,10 @@
 SimpleExecContext& t_info = *threadInfo[curThread];
 M5_VAR_USED SimpleThread* thread = t_info.thread;

+// hardware transactional memory
+// Cannot switch out the CPU in the middle of a transaction
+assert(!t_info.inHtmTransactionalState());
+
 BaseSimpleCPU::switchOut();

 assert(!fetchEvent.scheduled());
@@ -234,6 +239,10 @@
 assert(thread_num < numThreads);
 activeThreads.remove(thread_num);

+// hardware transactional memory
+// Cannot suspend context in the middle of a transaction.
+assert(!threadInfo[curThread]->inHtmTransactionalState());
+
 if (_status == Idle)
 return;

@@ -260,6 +269,12 @@

 const RequestPtr  = pkt->req;

+// hardware transactional memory
+// sanity check
+if (req->isHTMCmd()) {
+assert(!req->isLocalAccess());
+}
+
 // We're about the issues a locked load, so tell the monitor
 // to start caring about this address
 if (pkt->isRead() && pkt->req->isLLSC()) {
@@ -291,6 +306,17 @@
 PacketPtr pkt = buildPacket(req, read);
 pkt->dataDynamic(data);

+// hardware transactional memory
+// If the core is in transactional mode or if the request is HtmCMD
+// to abort a transaction, the packet should reflect that it is
+// transactional and also contain a HtmUid for debugging.
+const bool 

[gem5-dev] Change in gem5/gem5[develop]: cpu: HTM Implementation for TimingCPU

2020-06-15 Thread Giacomo Travaglini (Gerrit) via gem5-dev

Hello Timothy Hayes,

I'd like you to do a code review. Please visit

https://gem5-review.googlesource.com/c/public/gem5/+/30327

to review the following change.


Change subject: cpu: HTM Implementation for TimingCPU
..

cpu: HTM Implementation for TimingCPU

JIRA: https://gem5.atlassian.net/browse/GEM5-587

Change-Id: I3e1de639560ea5492e914470e31bacb321425f0a
Signed-off-by: Giacomo Travaglini 
---
M src/cpu/simple/base.cc
M src/cpu/simple/exec_context.hh
M src/cpu/simple/timing.cc
3 files changed, 251 insertions(+), 16 deletions(-)



diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index c6d5761..fb0aa42 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012, 2015, 2017, 2018 ARM Limited
+ * Copyright (c) 2010-2012, 2015, 2017, 2018-2019 ARM Limited
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
@@ -65,6 +65,7 @@
 #include "cpu/thread_context.hh"
 #include "debug/Decode.hh"
 #include "debug/Fetch.hh"
+#include "debug/HtmCpu.hh"
 #include "debug/Quiesce.hh"
 #include "mem/packet.hh"
 #include "mem/request.hh"
@@ -443,6 +444,17 @@
 Fault interrupt = interrupts[curThread]->getInterrupt();

 if (interrupt != NoFault) {
+// hardware transactional memory
+// Postpone taking interrupts while executing transactions.
+assert(!std::dynamic_pointer_cast(
+interrupt));
+if (t_info.inHtmTransactionalState()) {
+DPRINTF(HtmCpu, "Deferring pending interrupt - %s -"
+"due to transactional state\n",
+interrupt->name());
+return;
+}
+
 t_info.fetchOffset = 0;
 interrupts[curThread]->updateIntrInfo();
 interrupt->invoke(tc);
diff --git a/src/cpu/simple/exec_context.hh b/src/cpu/simple/exec_context.hh
index ade9b68..42b5d0e 100644
--- a/src/cpu/simple/exec_context.hh
+++ b/src/cpu/simple/exec_context.hh
@@ -475,8 +475,7 @@

 Fault initiateHtmCmd(Request::Flags flags) override
 {
-panic("Not yet supported\n");
-return NoFault;
+return cpu->initiateHtmCmd(flags);
 }

 /**
@@ -540,29 +539,26 @@
 uint64_t
 getHtmTransactionUid() const override
 {
-panic("Not yet supported\n");
-return 0;
+return tcBase()->getHTMCheckpointPtr()->getHtmUid();
 }

 uint64_t
 newHtmTransactionUid() const override
 {
-panic("Not yet supported\n");
-return 0;
+return tcBase()->getHTMCheckpointPtr()->newHtmUid();
 }

 bool
 inHtmTransactionalState() const override
 {
-panic("Not yet supported\n");
-return false;
+return (getHtmTransactionalDepth() > 0);
 }

 uint64_t
 getHtmTransactionalDepth() const override
 {
-panic("Not yet supported\n");
-return 0;
+assert(thread->htmTransactionStarts >=  
thread->htmTransactionStops);
+return (thread->htmTransactionStarts -  
thread->htmTransactionStops);

 }

 /**
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index a509562..3240792 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -48,6 +48,7 @@
 #include "debug/Config.hh"
 #include "debug/Drain.hh"
 #include "debug/ExecFaulting.hh"
+#include "debug/HtmCpu.hh"
 #include "debug/Mwait.hh"
 #include "debug/SimpleCPU.hh"
 #include "mem/packet.hh"
@@ -173,6 +174,10 @@
 SimpleExecContext& t_info = *threadInfo[curThread];
 M5_VAR_USED SimpleThread* thread = t_info.thread;

+// hardware transactional memory
+// Cannot switch out the CPU in the middle of a transaction
+assert(!t_info.inHtmTransactionalState());
+
 BaseSimpleCPU::switchOut();

 assert(!fetchEvent.scheduled());
@@ -234,6 +239,10 @@
 assert(thread_num < numThreads);
 activeThreads.remove(thread_num);

+// hardware transactional memory
+// Cannot suspend context in the middle of a transaction.
+assert(!threadInfo[curThread]->inHtmTransactionalState());
+
 if (_status == Idle)
 return;

@@ -260,6 +269,12 @@

 const RequestPtr  = pkt->req;

+// hardware transactional memory
+// sanity check
+if (req->isHTMCmd()) {
+assert(!req->isLocalAccess());
+}
+
 // We're about the issues a locked load, so tell the monitor
 // to start caring about this address
 if (pkt->isRead() && pkt->req->isLLSC()) {
@@ -291,6 +306,17 @@
 PacketPtr pkt = buildPacket(req, read);
 pkt->dataDynamic(data);

+// hardware transactional memory
+// If the core is in transactional mode or if the request is HtmCMD
+// to abort a transaction, the packet should reflect that it is
+// transactional and also contain a HtmUid for debugging.
+const bool is_htm_speculative =