base.cc (8737:770ccf3af571) | base.cc (8745:575cab0db076) |
---|---|
1/* | 1/* |
2 * Copyright (c) 2011 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * | |
14 * Copyright (c) 2002-2005 The Regents of The University of Michigan 15 * Copyright (c) 2011 Regents of the University of California 16 * All rights reserved. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions are 20 * met: redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer; --- 26 unchanged lines hidden (view full) --- 48#include <string> 49 50#include "arch/tlb.hh" 51#include "base/loader/symtab.hh" 52#include "base/cprintf.hh" 53#include "base/misc.hh" 54#include "base/output.hh" 55#include "base/trace.hh" | 2 * Copyright (c) 2002-2005 The Regents of The University of Michigan 3 * Copyright (c) 2011 Regents of the University of California 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer; --- 26 unchanged lines hidden (view full) --- 36#include <string> 37 38#include "arch/tlb.hh" 39#include "base/loader/symtab.hh" 40#include "base/cprintf.hh" 41#include "base/misc.hh" 42#include "base/output.hh" 43#include "base/trace.hh" |
56#include "config/use_checker.hh" | |
57#include "cpu/base.hh" 58#include "cpu/cpuevent.hh" 59#include "cpu/profile.hh" 60#include "cpu/thread_context.hh" 61#include "debug/SyscallVerbose.hh" 62#include "params/BaseCPU.hh" 63#include "sim/process.hh" 64#include "sim/sim_events.hh" 65#include "sim/sim_exit.hh" 66#include "sim/system.hh" 67 | 44#include "cpu/base.hh" 45#include "cpu/cpuevent.hh" 46#include "cpu/profile.hh" 47#include "cpu/thread_context.hh" 48#include "debug/SyscallVerbose.hh" 49#include "params/BaseCPU.hh" 50#include "sim/process.hh" 51#include "sim/sim_events.hh" 52#include "sim/sim_exit.hh" 53#include "sim/system.hh" 54 |
68#if USE_CHECKER 69#include "cpu/checker/cpu.hh" 70#endif 71 | |
72// Hack 73#include "sim/stat_control.hh" 74 75using namespace std; 76 77vector<BaseCPU *> BaseCPU::cpuList; 78 79// This variable reflects the max number of threads in any CPU. Be --- 32 unchanged lines hidden (view full) --- 112} 113 114const char * 115CPUProgressEvent::description() const 116{ 117 return "CPU Progress"; 118} 119 | 55// Hack 56#include "sim/stat_control.hh" 57 58using namespace std; 59 60vector<BaseCPU *> BaseCPU::cpuList; 61 62// This variable reflects the max number of threads in any CPU. Be --- 32 unchanged lines hidden (view full) --- 95} 96 97const char * 98CPUProgressEvent::description() const 99{ 100 return "CPU Progress"; 101} 102 |
120#if FULL_SYSTEM | |
121BaseCPU::BaseCPU(Params *p) 122 : MemObject(p), clock(p->clock), instCnt(0), _cpuId(p->cpu_id), 123 interrupts(p->interrupts), 124 numThreads(p->numThreads), system(p->system), 125 phase(p->phase) | 103BaseCPU::BaseCPU(Params *p) 104 : MemObject(p), clock(p->clock), instCnt(0), _cpuId(p->cpu_id), 105 interrupts(p->interrupts), 106 numThreads(p->numThreads), system(p->system), 107 phase(p->phase) |
126#else 127BaseCPU::BaseCPU(Params *p) 128 : MemObject(p), clock(p->clock), _cpuId(p->cpu_id), 129 numThreads(p->numThreads), system(p->system), 130 phase(p->phase) 131#endif | |
132{ 133// currentTick = curTick(); 134 135 // if Python did not provide a valid ID, do it here 136 if (_cpuId == -1 ) { 137 _cpuId = cpuList.size(); 138 } 139 --- 62 unchanged lines hidden (view full) --- 202 for (ThreadID tid = 0; tid < numThreads; ++tid) { 203 Event *event = new CountedExitEvent(cause, *counter); 204 comLoadEventQueue[tid]->schedule(event, p->max_loads_all_threads); 205 } 206 } 207 208 functionTracingEnabled = false; 209 if (p->function_trace) { | 108{ 109// currentTick = curTick(); 110 111 // if Python did not provide a valid ID, do it here 112 if (_cpuId == -1 ) { 113 _cpuId = cpuList.size(); 114 } 115 --- 62 unchanged lines hidden (view full) --- 178 for (ThreadID tid = 0; tid < numThreads; ++tid) { 179 Event *event = new CountedExitEvent(cause, *counter); 180 comLoadEventQueue[tid]->schedule(event, p->max_loads_all_threads); 181 } 182 } 183 184 functionTracingEnabled = false; 185 if (p->function_trace) { |
210 const string fname = csprintf("ftrace.%s", name()); 211 functionTraceStream = simout.find(fname); 212 if (!functionTraceStream) 213 functionTraceStream = simout.create(fname); 214 | 186 functionTraceStream = simout.find(csprintf("ftrace.%s", name())); |
215 currentFunctionStart = currentFunctionEnd = 0; 216 functionEntryTick = p->function_trace_start; 217 218 if (p->function_trace_start == 0) { 219 functionTracingEnabled = true; 220 } else { 221 typedef EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace> wrap; 222 Event *event = new wrap(this, true); 223 schedule(event, p->function_trace_start); 224 } 225 } | 187 currentFunctionStart = currentFunctionEnd = 0; 188 functionEntryTick = p->function_trace_start; 189 190 if (p->function_trace_start == 0) { 191 functionTracingEnabled = true; 192 } else { 193 typedef EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace> wrap; 194 Event *event = new wrap(this, true); 195 schedule(event, p->function_trace_start); 196 } 197 } |
226#if FULL_SYSTEM 227 // Check if CPU model has interrupts connected. The CheckerCPU 228 // cannot take interrupts directly for example. 229 if (interrupts) 230 interrupts->setCPU(this); | 198 interrupts->setCPU(this); |
231 | 199 |
200#if FULL_SYSTEM |
|
232 profileEvent = NULL; 233 if (params()->profile) 234 profileEvent = new ProfileEvent(this, params()->profile); 235#endif 236 tracer = params()->tracer; 237} 238 239void --- 19 unchanged lines hidden (view full) --- 259#if FULL_SYSTEM 260 if (!params()->defer_registration && profileEvent) 261 schedule(profileEvent, curTick()); 262#endif 263 264 if (params()->progress_interval) { 265 Tick num_ticks = ticks(params()->progress_interval); 266 | 201 profileEvent = NULL; 202 if (params()->profile) 203 profileEvent = new ProfileEvent(this, params()->profile); 204#endif 205 tracer = params()->tracer; 206} 207 208void --- 19 unchanged lines hidden (view full) --- 228#if FULL_SYSTEM 229 if (!params()->defer_registration && profileEvent) 230 schedule(profileEvent, curTick()); 231#endif 232 233 if (params()->progress_interval) { 234 Tick num_ticks = ticks(params()->progress_interval); 235 |
267 new CPUProgressEvent(this, num_ticks); | 236 Event *event; 237 event = new CPUProgressEvent(this, num_ticks); |
268 } 269} 270 271 272void 273BaseCPU::regStats() 274{ 275 using namespace Stats; --- 90 unchanged lines hidden (view full) --- 366// panic("This CPU doesn't support sampling!"); 367#if FULL_SYSTEM 368 if (profileEvent && profileEvent->scheduled()) 369 deschedule(profileEvent); 370#endif 371} 372 373void | 238 } 239} 240 241 242void 243BaseCPU::regStats() 244{ 245 using namespace Stats; --- 90 unchanged lines hidden (view full) --- 336// panic("This CPU doesn't support sampling!"); 337#if FULL_SYSTEM 338 if (profileEvent && profileEvent->scheduled()) 339 deschedule(profileEvent); 340#endif 341} 342 343void |
374BaseCPU::takeOverFrom(BaseCPU *oldCPU) | 344BaseCPU::takeOverFrom(BaseCPU *oldCPU, Port *ic, Port *dc) |
375{ | 345{ |
376 Port *ic = getPort("icache_port"); 377 Port *dc = getPort("dcache_port"); | |
378 assert(threadContexts.size() == oldCPU->threadContexts.size()); 379 380 _cpuId = oldCPU->cpuId(); 381 382 ThreadID size = threadContexts.size(); 383 for (ThreadID i = 0; i < size; ++i) { 384 ThreadContext *newTC = threadContexts[i]; 385 ThreadContext *oldTC = oldCPU->threadContexts[i]; --- 27 unchanged lines hidden (view full) --- 413 peer->setPeer(new_itb_port); 414 } 415 if (new_dtb_port && !new_dtb_port->isConnected()) { 416 assert(old_dtb_port); 417 Port *peer = old_dtb_port->getPeer();; 418 new_dtb_port->setPeer(peer); 419 peer->setPeer(new_dtb_port); 420 } | 346 assert(threadContexts.size() == oldCPU->threadContexts.size()); 347 348 _cpuId = oldCPU->cpuId(); 349 350 ThreadID size = threadContexts.size(); 351 for (ThreadID i = 0; i < size; ++i) { 352 ThreadContext *newTC = threadContexts[i]; 353 ThreadContext *oldTC = oldCPU->threadContexts[i]; --- 27 unchanged lines hidden (view full) --- 381 peer->setPeer(new_itb_port); 382 } 383 if (new_dtb_port && !new_dtb_port->isConnected()) { 384 assert(old_dtb_port); 385 Port *peer = old_dtb_port->getPeer();; 386 new_dtb_port->setPeer(peer); 387 peer->setPeer(new_dtb_port); 388 } |
421 422#if USE_CHECKER 423 Port *old_checker_itb_port, *old_checker_dtb_port; 424 Port *new_checker_itb_port, *new_checker_dtb_port; 425 426 CheckerCPU *oldChecker = 427 dynamic_cast<CheckerCPU*>(oldTC->getCheckerCpuPtr()); 428 CheckerCPU *newChecker = 429 dynamic_cast<CheckerCPU*>(newTC->getCheckerCpuPtr()); 430 old_checker_itb_port = oldChecker->getITBPtr()->getPort(); 431 old_checker_dtb_port = oldChecker->getDTBPtr()->getPort(); 432 new_checker_itb_port = newChecker->getITBPtr()->getPort(); 433 new_checker_dtb_port = newChecker->getDTBPtr()->getPort(); 434 435 // Move over any table walker ports if they exist for checker 436 if (new_checker_itb_port && !new_checker_itb_port->isConnected()) { 437 assert(old_checker_itb_port); 438 Port *peer = old_checker_itb_port->getPeer();; 439 new_checker_itb_port->setPeer(peer); 440 peer->setPeer(new_checker_itb_port); 441 } 442 if (new_checker_dtb_port && !new_checker_dtb_port->isConnected()) { 443 assert(old_checker_dtb_port); 444 Port *peer = old_checker_dtb_port->getPeer();; 445 new_checker_dtb_port->setPeer(peer); 446 peer->setPeer(new_checker_dtb_port); 447 } 448#endif 449 | |
450 } 451 | 389 } 390 |
452#if FULL_SYSTEM | |
453 interrupts = oldCPU->interrupts; 454 interrupts->setCPU(this); 455 | 391 interrupts = oldCPU->interrupts; 392 interrupts->setCPU(this); 393 |
394#if FULL_SYSTEM |
|
456 for (ThreadID i = 0; i < size; ++i) 457 threadContexts[i]->profileClear(); 458 459 if (profileEvent) 460 schedule(profileEvent, curTick()); 461#endif 462 463 // Connect new CPU to old CPU's memory only if new CPU isn't --- 25 unchanged lines hidden (view full) --- 489 for (ThreadID i = 0; i < size; ++i) { 490 ThreadContext *tc = cpu->threadContexts[i]; 491 tc->profileSample(); 492 } 493 494 cpu->schedule(this, curTick() + interval); 495} 496 | 395 for (ThreadID i = 0; i < size; ++i) 396 threadContexts[i]->profileClear(); 397 398 if (profileEvent) 399 schedule(profileEvent, curTick()); 400#endif 401 402 // Connect new CPU to old CPU's memory only if new CPU isn't --- 25 unchanged lines hidden (view full) --- 428 for (ThreadID i = 0; i < size; ++i) { 429 ThreadContext *tc = cpu->threadContexts[i]; 430 tc->profileSample(); 431 } 432 433 cpu->schedule(this, curTick() + interval); 434} 435 |
436#endif // FULL_SYSTEM 437 |
|
497void 498BaseCPU::serialize(std::ostream &os) 499{ 500 SERIALIZE_SCALAR(instCnt); 501 interrupts->serialize(os); 502} 503 504void 505BaseCPU::unserialize(Checkpoint *cp, const std::string §ion) 506{ 507 UNSERIALIZE_SCALAR(instCnt); 508 interrupts->unserialize(cp, section); 509} 510 | 438void 439BaseCPU::serialize(std::ostream &os) 440{ 441 SERIALIZE_SCALAR(instCnt); 442 interrupts->serialize(os); 443} 444 445void 446BaseCPU::unserialize(Checkpoint *cp, const std::string §ion) 447{ 448 UNSERIALIZE_SCALAR(instCnt); 449 interrupts->unserialize(cp, section); 450} 451 |
511#endif // FULL_SYSTEM 512 | |
513void 514BaseCPU::traceFunctionsInternal(Addr pc) 515{ 516 if (!debugSymbolTable) 517 return; 518 519 // if pc enters different function, print new function symbol and 520 // update saved range. Otherwise do nothing. --- 10 unchanged lines hidden (view full) --- 531 currentFunctionEnd = pc + 1; 532 } 533 534 ccprintf(*functionTraceStream, " (%d)\n%d: %s", 535 curTick() - functionEntryTick, curTick(), sym_str); 536 functionEntryTick = curTick(); 537 } 538} | 452void 453BaseCPU::traceFunctionsInternal(Addr pc) 454{ 455 if (!debugSymbolTable) 456 return; 457 458 // if pc enters different function, print new function symbol and 459 // update saved range. Otherwise do nothing. --- 10 unchanged lines hidden (view full) --- 470 currentFunctionEnd = pc + 1; 471 } 472 473 ccprintf(*functionTraceStream, " (%d)\n%d: %s", 474 curTick() - functionEntryTick, curTick(), sym_str); 475 functionEntryTick = curTick(); 476 } 477} |
539 540bool 541BaseCPU::CpuPort::recvTiming(PacketPtr pkt) 542{ 543 panic("BaseCPU doesn't expect recvTiming callback!"); 544 return true; 545} 546 547void 548BaseCPU::CpuPort::recvRetry() 549{ 550 panic("BaseCPU doesn't expect recvRetry callback!"); 551} 552 553Tick 554BaseCPU::CpuPort::recvAtomic(PacketPtr pkt) 555{ 556 panic("BaseCPU doesn't expect recvAtomic callback!"); 557 return curTick(); 558} 559 560void 561BaseCPU::CpuPort::recvFunctional(PacketPtr pkt) 562{ 563 // No internal storage to update (in the general case). In the 564 // long term this should never be called, but that assumed a split 565 // into master/slave and request/response. 566} 567 568void 569BaseCPU::CpuPort::recvRangeChange() 570{ 571} | |