/*
- * Copyright (c) 2011-2012,2016-2017 ARM Limited
+ * Copyright (c) 2011-2012,2016-2017, 2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Authors: Steve Reinhardt
- * Nathan Binkert
- * Rick Strong
*/
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "debug/Mwait.hh"
#include "debug/SyscallVerbose.hh"
+#include "debug/Thread.hh"
#include "mem/page_table.hh"
#include "params/BaseCPU.hh"
#include "sim/clocked_object.hh"
if (numThreads > maxThreadsPerCPU)
maxThreadsPerCPU = numThreads;
- // allocate per-thread instruction-based event queues
- comInstEventQueue = new EventQueue *[numThreads];
- for (ThreadID tid = 0; tid < numThreads; ++tid)
- comInstEventQueue[tid] =
- new EventQueue("instruction-based event queue");
-
- //
- // set up instruction-count-based termination events, if any
- //
- if (p->max_insts_any_thread != 0) {
- const char *cause = "a thread reached the max instruction count";
- for (ThreadID tid = 0; tid < numThreads; ++tid)
- scheduleInstStop(tid, p->max_insts_any_thread, cause);
- }
-
- // Set up instruction-count-based termination events for SimPoints
- // Typically, there are more than one action points.
- // Simulation.py is responsible to take the necessary actions upon
- // exitting the simulation loop.
- if (!p->simpoint_start_insts.empty()) {
- const char *cause = "simpoint starting point found";
- for (size_t i = 0; i < p->simpoint_start_insts.size(); ++i)
- scheduleInstStop(0, p->simpoint_start_insts[i], cause);
- }
-
- if (p->max_insts_all_threads != 0) {
- const char *cause = "all threads reached the max instruction count";
-
- // allocate & initialize shared downcounter: each event will
- // decrement this when triggered; simulation will terminate
- // when counter reaches 0
- int *counter = new int;
- *counter = numThreads;
- for (ThreadID tid = 0; tid < numThreads; ++tid) {
- Event *event = new CountedExitEvent(cause, *counter);
- scheduleInstCountEvent(tid, event, p->max_insts_all_threads);
- }
- }
-
- //
- // set up instruction-count-based termination events, if any
- //
-
functionTracingEnabled = false;
if (p->function_trace) {
const string fname = csprintf("ftrace.%s", name());
BaseCPU::~BaseCPU()
{
delete profileEvent;
- delete[] comInstEventQueue;
}
void
if (secondAddr > addr)
size = secondAddr - addr;
- req->setVirt(0, addr, size, 0x0, dataMasterId(), tc->instAddr());
+ req->setVirt(addr, size, 0x0, dataMasterId(), tc->instAddr());
// translate to physical address
Fault fault = dtb->translateAtomic(req, tc, BaseTLB::Read);
void
BaseCPU::init()
{
+ // Set up instruction-count-based termination events, if any. This needs
+ // to happen after threadContexts has been constructed.
+ if (params()->max_insts_any_thread != 0) {
+ const char *cause = "a thread reached the max instruction count";
+ for (ThreadID tid = 0; tid < numThreads; ++tid)
+ scheduleInstStop(tid, params()->max_insts_any_thread, cause);
+ }
+
+ // Set up instruction-count-based termination events for SimPoints
+ // Typically, there are more than one action points.
+ // Simulation.py is responsible to take the necessary actions upon
+ // exitting the simulation loop.
+ if (!params()->simpoint_start_insts.empty()) {
+ const char *cause = "simpoint starting point found";
+ for (size_t i = 0; i < params()->simpoint_start_insts.size(); ++i)
+ scheduleInstStop(0, params()->simpoint_start_insts[i], cause);
+ }
+
+ if (params()->max_insts_all_threads != 0) {
+ const char *cause = "all threads reached the max instruction count";
+
+ // allocate & initialize shared downcounter: each event will
+ // decrement this when triggered; simulation will terminate
+ // when counter reaches 0
+ int *counter = new int;
+ *counter = numThreads;
+ for (ThreadID tid = 0; tid < numThreads; ++tid) {
+ Event *event = new CountedExitEvent(cause, *counter);
+ threadContexts[tid]->scheduleInstCountEvent(
+ event, params()->max_insts_all_threads);
+ }
+ }
+
if (!params()->switched_out) {
registerThreadContexts();
void
BaseCPU::activateContext(ThreadID thread_num)
{
+ DPRINTF(Thread, "activate contextId %d\n",
+ threadContexts[thread_num]->contextId());
// Squash enter power gating event while cpu gets activated
if (enterPwrGatingEvent.scheduled())
deschedule(enterPwrGatingEvent);
void
BaseCPU::suspendContext(ThreadID thread_num)
{
+ DPRINTF(Thread, "suspend contextId %d\n",
+ threadContexts[thread_num]->contextId());
// Check if all threads are suspended
for (auto t : threadContexts) {
if (t->status() != ThreadContext::Suspended) {
const Tick now(getCurrentInstCount(tid));
Event *event(new LocalSimLoopExitEvent(cause, 0));
- scheduleInstCountEvent(tid, event, now + insts);
+ threadContexts[tid]->scheduleInstCountEvent(event, now + insts);
}
Tick
BaseCPU::getCurrentInstCount(ThreadID tid)
{
- return comInstEventQueue[tid]->getCurTick();
+ return threadContexts[tid]->getCurrentInstCount();
}
AddressMonitor::AddressMonitor() {