1/* 2 * Copyright (c) 2002-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 22 unchanged lines hidden (view full) --- 31#include "arch/locked_mem.hh" 32#include "arch/mmaped_ipr.hh" 33#include "arch/utility.hh" 34#include "base/bigint.hh" 35#include "cpu/exetrace.hh" 36#include "cpu/simple/atomic.hh" 37#include "mem/packet.hh" 38#include "mem/packet_access.hh" |
39#include "sim/builder.hh" |
40#include "sim/system.hh" 41 42using namespace std; 43using namespace TheISA; 44 45AtomicSimpleCPU::TickEvent::TickEvent(AtomicSimpleCPU *c) 46 : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c) 47{ --- 95 unchanged lines hidden (view full) --- 143 width(p->width), simulate_stalls(p->simulate_stalls), 144 icachePort(name() + "-iport", this), dcachePort(name() + "-iport", this) 145{ 146 _status = Idle; 147 148 icachePort.snoopRangeSent = false; 149 dcachePort.snoopRangeSent = false; 150 |
151 ifetch_req.setThreadContext(p->cpu_id, 0); // Add thread ID if we add MT 152 data_read_req.setThreadContext(p->cpu_id, 0); // Add thread ID here too 153 data_write_req.setThreadContext(p->cpu_id, 0); // Add thread ID here too |
154} 155 156 157AtomicSimpleCPU::~AtomicSimpleCPU() 158{ 159} 160 161void --- 17 unchanged lines hidden (view full) --- 179 BaseSimpleCPU::unserialize(cp, section); 180 tickEvent.unserialize(cp, csprintf("%s.tickEvent", section)); 181} 182 183void 184AtomicSimpleCPU::resume() 185{ 186 if (_status != SwitchedOut && _status != Idle) { |
187 assert(system->getMemoryMode() == System::Atomic); |
188 189 changeState(SimObject::Running); 190 if (thread->status() == ThreadContext::Active) { 191 if (!tickEvent.scheduled()) { 192 tickEvent.schedule(nextCycle()); 193 } 194 } 195 } --- 67 unchanged lines hidden (view full) --- 263} 264 265 266template <class T> 267Fault 268AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags) 269{ 270 // use the CPU's statically allocated read request and packet objects |
271 Request *req = &data_read_req; |
272 req->setVirt(0, addr, sizeof(T), flags, thread->readPC()); 273 274 if (traceData) { 275 traceData->setAddr(addr); 276 } 277 278 // translate to physical address 279 Fault fault = thread->translateDataReadReq(req); 280 281 // Now do the access. 282 if (fault == NoFault) { |
283 Packet pkt = Packet(req, MemCmd::ReadReq, Packet::Broadcast); 284 pkt.dataStatic(&data); |
285 286 if (req->isMmapedIpr()) |
287 dcache_latency = TheISA::handleIprRead(thread->getTC(), &pkt); |
288 else |
289 dcache_latency = dcachePort.sendAtomic(&pkt); |
290 dcache_access = true; |
291 assert(!pkt.isError()); |
292 293 if (req->isLocked()) { 294 TheISA::handleLockedRead(thread, req); 295 } 296 } 297 298 // This will need a new way to tell if it has a dcache attached. 299 if (req->isUncacheable()) --- 53 unchanged lines hidden (view full) --- 353} 354 355 356template <class T> 357Fault 358AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) 359{ 360 // use the CPU's statically allocated write request and packet objects |
361 Request *req = &data_write_req; |
362 req->setVirt(0, addr, sizeof(T), flags, thread->readPC()); 363 |
364 if (traceData) { 365 traceData->setAddr(addr); 366 } 367 368 // translate to physical address 369 Fault fault = thread->translateDataWriteReq(req); 370 371 // Now do the access. 372 if (fault == NoFault) { |
373 Packet pkt = 374 Packet(req, req->isSwap() ? MemCmd::SwapReq : MemCmd::WriteReq, 375 Packet::Broadcast); 376 pkt.dataStatic(&data); 377 |
378 bool do_access = true; // flag to suppress cache access 379 380 if (req->isLocked()) { 381 do_access = TheISA::handleLockedWrite(thread, req); 382 } 383 if (req->isCondSwap()) { 384 assert(res); 385 req->setExtraData(*res); 386 } 387 388 389 if (do_access) { |
390 if (req->isMmapedIpr()) { |
391 dcache_latency = TheISA::handleIprWrite(thread->getTC(), &pkt); |
392 } else { 393 data = htog(data); |
394 dcache_latency = dcachePort.sendAtomic(&pkt); |
395 } 396 dcache_access = true; |
397 assert(!pkt.isError()); |
398 } 399 400 if (req->isSwap()) { 401 assert(res); |
402 *res = pkt.get<T>(); |
403 } else if (res) { 404 *res = req->getExtraData(); 405 } 406 } 407 408 // This will need a new way to tell if it's hooked up to a cache or not. 409 if (req->isUncacheable()) 410 recordEvent("Uncached Write"); --- 67 unchanged lines hidden (view full) --- 478 Tick latency = cycles(1); // instruction takes one cycle by default 479 480 for (int i = 0; i < width; ++i) { 481 numCycles++; 482 483 if (!curStaticInst || !curStaticInst->isDelayedCommit()) 484 checkForInterrupts(); 485 |
486 Fault fault = setupFetchRequest(&ifetch_req); |
487 488 if (fault == NoFault) { 489 Tick icache_latency = 0; 490 bool icache_access = false; 491 dcache_access = false; // assume no dcache access 492 493 //Fetch more instruction memory if necessary 494 //if(predecoder.needMoreBytes()) 495 //{ 496 icache_access = true; |
497 Packet ifetch_pkt = Packet(&ifetch_req, MemCmd::ReadReq, 498 Packet::Broadcast); 499 ifetch_pkt.dataStatic(&inst); |
500 |
501 icache_latency = icachePort.sendAtomic(&ifetch_pkt); |
502 // ifetch_req is initialized to read the instruction directly 503 // into the CPU object's inst field. 504 //} 505 506 preExecute(); 507 508 if(curStaticInst) 509 { --- 27 unchanged lines hidden (view full) --- 537 tickEvent.schedule(curTick + latency); 538} 539 540 541//////////////////////////////////////////////////////////////////////// 542// 543// AtomicSimpleCPU Simulation Object 544// |
545BEGIN_DECLARE_SIM_OBJECT_PARAMS(AtomicSimpleCPU) 546 547 Param<Counter> max_insts_any_thread; 548 Param<Counter> max_insts_all_threads; 549 Param<Counter> max_loads_any_thread; 550 Param<Counter> max_loads_all_threads; 551 Param<Tick> progress_interval; 552 SimObjectParam<System *> system; 553 Param<int> cpu_id; 554 555#if FULL_SYSTEM 556 SimObjectParam<TheISA::ITB *> itb; 557 SimObjectParam<TheISA::DTB *> dtb; 558 Param<Tick> profile; 559 560 Param<bool> do_quiesce; 561 Param<bool> do_checkpoint_insts; 562 Param<bool> do_statistics_insts; 563#else 564 SimObjectParam<Process *> workload; 565#endif // FULL_SYSTEM 566 567 Param<int> clock; 568 Param<int> phase; 569 570 Param<bool> defer_registration; 571 Param<int> width; 572 Param<bool> function_trace; 573 Param<Tick> function_trace_start; 574 Param<bool> simulate_stalls; 575 576END_DECLARE_SIM_OBJECT_PARAMS(AtomicSimpleCPU) 577 578BEGIN_INIT_SIM_OBJECT_PARAMS(AtomicSimpleCPU) 579 580 INIT_PARAM(max_insts_any_thread, 581 "terminate when any thread reaches this inst count"), 582 INIT_PARAM(max_insts_all_threads, 583 "terminate when all threads have reached this inst count"), 584 INIT_PARAM(max_loads_any_thread, 585 "terminate when any thread reaches this load count"), 586 INIT_PARAM(max_loads_all_threads, 587 "terminate when all threads have reached this load count"), 588 INIT_PARAM(progress_interval, "Progress interval"), 589 INIT_PARAM(system, "system object"), 590 INIT_PARAM(cpu_id, "processor ID"), 591 592#if FULL_SYSTEM 593 INIT_PARAM(itb, "Instruction TLB"), 594 INIT_PARAM(dtb, "Data TLB"), 595 INIT_PARAM(profile, ""), 596 INIT_PARAM(do_quiesce, ""), 597 INIT_PARAM(do_checkpoint_insts, ""), 598 INIT_PARAM(do_statistics_insts, ""), 599#else 600 INIT_PARAM(workload, "processes to run"), 601#endif // FULL_SYSTEM 602 603 INIT_PARAM(clock, "clock speed"), 604 INIT_PARAM_DFLT(phase, "clock phase", 0), 605 INIT_PARAM(defer_registration, "defer system registration (for sampling)"), 606 INIT_PARAM(width, "cpu width"), 607 INIT_PARAM(function_trace, "Enable function trace"), 608 INIT_PARAM(function_trace_start, "Cycle to start function trace"), 609 INIT_PARAM(simulate_stalls, "Simulate cache stall cycles") 610 611END_INIT_SIM_OBJECT_PARAMS(AtomicSimpleCPU) 612 613 614CREATE_SIM_OBJECT(AtomicSimpleCPU) |
615{ 616 AtomicSimpleCPU::Params *params = new AtomicSimpleCPU::Params(); |
617 params->name = getInstanceName(); |
618 params->numberOfThreads = 1; 619 params->max_insts_any_thread = max_insts_any_thread; 620 params->max_insts_all_threads = max_insts_all_threads; 621 params->max_loads_any_thread = max_loads_any_thread; 622 params->max_loads_all_threads = max_loads_all_threads; 623 params->progress_interval = progress_interval; 624 params->deferRegistration = defer_registration; 625 params->phase = phase; 626 params->clock = clock; 627 params->functionTrace = function_trace; 628 params->functionTraceStart = function_trace_start; 629 params->width = width; 630 params->simulate_stalls = simulate_stalls; 631 params->system = system; 632 params->cpu_id = cpu_id; |
633 634#if FULL_SYSTEM 635 params->itb = itb; 636 params->dtb = dtb; 637 params->profile = profile; 638 params->do_quiesce = do_quiesce; 639 params->do_checkpoint_insts = do_checkpoint_insts; 640 params->do_statistics_insts = do_statistics_insts; 641#else |
642 params->process = workload; |
643#endif 644 645 AtomicSimpleCPU *cpu = new AtomicSimpleCPU(params); 646 return cpu; 647} |
648 649REGISTER_SIM_OBJECT("AtomicSimpleCPU", AtomicSimpleCPU) 650 |