cpu: Create a virtual BaseCPU::htmSendAbortSignal method.

This virtual method can trivially be shared among different CPUs, making
it unnecessary to cast from a BaseCPU pointer to some more specific CPU
class. The existing similar functions which implement this functionality
are only trivially different, and can be merged into overloads of this
common method.

Noteably this method is not implemented for the MinorCPU which uses the
SimpleThread class, typedef-ed to be MinorThread. If the previous
version of this method had been called on that CPU, it would have
crashed the simulator since a dynamic_cast would have failed. This
doesn't provide an implementation for the MinorCPU, but it also doesn't
make the problem worse, and provides a way to actually implement it some
day.

Change-Id: I23399ea6bbbbabd87e6c8bf7a66d48902745d2cf
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/52084
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Gabe Black
2021-10-26 00:09:30 -07:00
parent 2ecd88f0da
commit 0feb0a34db
7 changed files with 27 additions and 20 deletions

View File

@@ -47,12 +47,14 @@
// Before we do anything else, check if this build is the NULL ISA,
// and if so stop here
#include "config/the_isa.hh"
#if IS_NULL_ISA
#error Including BaseCPU in a system without CPU support
#else
#include "arch/generic/interrupts.hh"
#include "base/statistics.hh"
#include "debug/Mwait.hh"
#include "mem/htm.hh"
#include "mem/port_proxy.hh"
#include "sim/clocked_object.hh"
#include "sim/eventq.hh"
@@ -622,6 +624,21 @@ class BaseCPU : public ClockedObject
Cycles syscallRetryLatency;
/** This function is used to instruct the memory subsystem that a
* transaction should be aborted and the speculative state should be
* thrown away. This is called in the transaction's very last breath in
* the core. Afterwards, the core throws away its speculative state and
* resumes execution at the point the transaction started, i.e. reverses
* time. When instruction execution resumes, the core expects the
* memory subsystem to be in a stable, i.e. pre-speculative, state as
* well. */
virtual void
htmSendAbortSignal(ThreadID tid, uint64_t htm_uid,
HtmFailureFaultCause cause)
{
panic("htmSendAbortSignal not implemented");
}
// Enables CPU to enter power gating on a configurable cycle count
protected:
void enterPwrGating();

View File

@@ -708,7 +708,7 @@ class CPU : public BaseCPU
public:
// hardware transactional memory
void htmSendAbortSignal(ThreadID tid, uint64_t htm_uid,
HtmFailureFaultCause cause);
HtmFailureFaultCause cause) override;
};
} // namespace o3

View File

@@ -231,10 +231,11 @@ class AtomicSimpleCPU : public BaseSimpleCPU
}
void
htmSendAbortSignal(HtmFailureFaultCause cause) override
htmSendAbortSignal(ThreadID tid, uint64_t htm_uid,
HtmFailureFaultCause cause) override
{
panic("htmSendAbortSignal() is for timing accesses, and should "
"never be called on AtomicSimpleCPU.\n");
"never be called on AtomicSimpleCPU.");
}
Fault writeMem(uint8_t *data, unsigned size,

View File

@@ -190,16 +190,6 @@ class BaseSimpleCPU : public BaseCPU
* neither really (true) loads nor stores. For this reason the interface
* is extended and initiateHtmCmd() is used to instigate the command. */
virtual Fault initiateHtmCmd(Request::Flags flags) = 0;
/** This function is used to instruct the memory subsystem that a
* transaction should be aborted and the speculative state should be
* thrown away. This is called in the transaction's very last breath in
* the core. Afterwards, the core throws away its speculative state and
* resumes execution at the point the transaction started, i.e. reverses
* time. When instruction execution resumes, the core expects the
* memory subsystem to be in a stable, i.e. pre-speculative, state as
* well. */
virtual void htmSendAbortSignal(HtmFailureFaultCause cause) = 0;
};
} // namespace gem5

View File

@@ -1259,9 +1259,10 @@ TimingSimpleCPU::initiateHtmCmd(Request::Flags flags)
}
void
TimingSimpleCPU::htmSendAbortSignal(HtmFailureFaultCause cause)
TimingSimpleCPU::htmSendAbortSignal(ThreadID tid, uint64_t htm_uid,
HtmFailureFaultCause cause)
{
SimpleExecContext& t_info = *threadInfo[curThread];
SimpleExecContext& t_info = *threadInfo[tid];
SimpleThread* thread = t_info.thread;
const Addr addr = 0x0ul;

View File

@@ -327,7 +327,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
/** hardware transactional memory **/
Fault initiateHtmCmd(Request::Flags flags) override;
void htmSendAbortSignal(HtmFailureFaultCause) override;
void htmSendAbortSignal(ThreadID tid, uint64_t htm_uid,
HtmFailureFaultCause) override;
private:

View File

@@ -171,10 +171,7 @@ SimpleThread::copyArchRegs(ThreadContext *src_tc)
void
SimpleThread::htmAbortTransaction(uint64_t htm_uid, HtmFailureFaultCause cause)
{
BaseSimpleCPU *baseSimpleCpu = dynamic_cast<BaseSimpleCPU*>(baseCpu);
assert(baseSimpleCpu);
baseSimpleCpu->htmSendAbortSignal(cause);
baseCpu->htmSendAbortSignal(threadId(), htm_uid, cause);
// these must be reset after the abort signal has been sent
htmTransactionStarts = 0;