atomic.cc (4776:8c8407243a2c) | atomic.cc (4870:fcc39d001154) |
---|---|
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" | 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 "params/AtomicSimpleCPU.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 | 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 = new Request(); 152 ifetch_req->setThreadContext(p->cpu_id, 0); // Add thread ID if we add MT 153 ifetch_pkt = new Packet(ifetch_req, MemCmd::ReadReq, Packet::Broadcast); 154 ifetch_pkt->dataStatic(&inst); 155 156 data_read_req = new Request(); 157 data_read_req->setThreadContext(p->cpu_id, 0); // Add thread ID here too 158 data_read_pkt = new Packet(data_read_req, MemCmd::ReadReq, 159 Packet::Broadcast); 160 data_read_pkt->dataStatic(&dataReg); 161 162 data_write_req = new Request(); 163 data_write_req->setThreadContext(p->cpu_id, 0); // Add thread ID here too 164 data_write_pkt = new Packet(data_write_req, MemCmd::WriteReq, 165 Packet::Broadcast); 166 data_swap_pkt = new Packet(data_write_req, MemCmd::SwapReq, 167 Packet::Broadcast); | 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 |
168} 169 170 171AtomicSimpleCPU::~AtomicSimpleCPU() 172{ 173} 174 175void --- 17 unchanged lines hidden (view full) --- 193 BaseSimpleCPU::unserialize(cp, section); 194 tickEvent.unserialize(cp, csprintf("%s.tickEvent", section)); 195} 196 197void 198AtomicSimpleCPU::resume() 199{ 200 if (_status != SwitchedOut && _status != Idle) { | 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) { |
201 assert(system->getMemoryMode() == Enums::atomic); | 187 assert(system->getMemoryMode() == System::Atomic); |
202 203 changeState(SimObject::Running); 204 if (thread->status() == ThreadContext::Active) { 205 if (!tickEvent.scheduled()) { 206 tickEvent.schedule(nextCycle()); 207 } 208 } 209 } --- 67 unchanged lines hidden (view full) --- 277} 278 279 280template <class T> 281Fault 282AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags) 283{ 284 // use the CPU's statically allocated read request and packet objects | 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 |
285 Request *req = data_read_req; 286 PacketPtr pkt = data_read_pkt; 287 | 271 Request *req = &data_read_req; |
288 req->setVirt(0, addr, sizeof(T), flags, thread->readPC()); 289 290 if (traceData) { 291 traceData->setAddr(addr); 292 } 293 294 // translate to physical address 295 Fault fault = thread->translateDataReadReq(req); 296 297 // Now do the access. 298 if (fault == NoFault) { | 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) { |
299 pkt->reinitFromRequest(); | 283 Packet pkt = Packet(req, MemCmd::ReadReq, Packet::Broadcast); 284 pkt.dataStatic(&data); |
300 301 if (req->isMmapedIpr()) | 285 286 if (req->isMmapedIpr()) |
302 dcache_latency = TheISA::handleIprRead(thread->getTC(),pkt); | 287 dcache_latency = TheISA::handleIprRead(thread->getTC(), &pkt); |
303 else | 288 else |
304 dcache_latency = dcachePort.sendAtomic(pkt); | 289 dcache_latency = dcachePort.sendAtomic(&pkt); |
305 dcache_access = true; | 290 dcache_access = true; |
306#if !defined(NDEBUG) 307 if (pkt->result != Packet::Success) 308 panic("Unable to find responder for address pa = %#X va = %#X\n", 309 pkt->req->getPaddr(), pkt->req->getVaddr()); 310#endif 311 data = pkt->get<T>(); | 291 assert(!pkt.isError()); |
312 313 if (req->isLocked()) { 314 TheISA::handleLockedRead(thread, req); 315 } 316 } 317 318 // This will need a new way to tell if it has a dcache attached. 319 if (req->isUncacheable()) --- 53 unchanged lines hidden (view full) --- 373} 374 375 376template <class T> 377Fault 378AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) 379{ 380 // use the CPU's statically allocated write request and packet objects | 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 |
381 Request *req = data_write_req; 382 PacketPtr pkt; 383 | 361 Request *req = &data_write_req; |
384 req->setVirt(0, addr, sizeof(T), flags, thread->readPC()); 385 | 362 req->setVirt(0, addr, sizeof(T), flags, thread->readPC()); 363 |
386 if (req->isSwap()) 387 pkt = data_swap_pkt; 388 else 389 pkt = data_write_pkt; 390 | |
391 if (traceData) { 392 traceData->setAddr(addr); 393 } 394 395 // translate to physical address 396 Fault fault = thread->translateDataWriteReq(req); 397 398 // Now do the access. 399 if (fault == NoFault) { | 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 |
|
400 bool do_access = true; // flag to suppress cache access 401 402 if (req->isLocked()) { 403 do_access = TheISA::handleLockedWrite(thread, req); 404 } 405 if (req->isCondSwap()) { 406 assert(res); 407 req->setExtraData(*res); 408 } 409 410 411 if (do_access) { | 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) { |
412 pkt->reinitFromRequest(); 413 pkt->dataStatic(&data); 414 | |
415 if (req->isMmapedIpr()) { | 390 if (req->isMmapedIpr()) { |
416 dcache_latency = TheISA::handleIprWrite(thread->getTC(), pkt); | 391 dcache_latency = TheISA::handleIprWrite(thread->getTC(), &pkt); |
417 } else { 418 data = htog(data); | 392 } else { 393 data = htog(data); |
419 dcache_latency = dcachePort.sendAtomic(pkt); | 394 dcache_latency = dcachePort.sendAtomic(&pkt); |
420 } 421 dcache_access = true; | 395 } 396 dcache_access = true; |
422 423#if !defined(NDEBUG) 424 if (pkt->result != Packet::Success) 425 panic("Unable to find responder for address pa = %#X va = %#X\n", 426 pkt->req->getPaddr(), pkt->req->getVaddr()); 427#endif | 397 assert(!pkt.isError()); |
428 } 429 430 if (req->isSwap()) { 431 assert(res); | 398 } 399 400 if (req->isSwap()) { 401 assert(res); |
432 *res = pkt->get<T>(); | 402 *res = pkt.get<T>(); |
433 } else if (res) { 434 *res = req->getExtraData(); 435 } 436 } 437 438 // This will need a new way to tell if it's hooked up to a cache or not. 439 if (req->isUncacheable()) 440 recordEvent("Uncached Write"); --- 67 unchanged lines hidden (view full) --- 508 Tick latency = cycles(1); // instruction takes one cycle by default 509 510 for (int i = 0; i < width; ++i) { 511 numCycles++; 512 513 if (!curStaticInst || !curStaticInst->isDelayedCommit()) 514 checkForInterrupts(); 515 | 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 |
516 Fault fault = setupFetchRequest(ifetch_req); | 486 Fault fault = setupFetchRequest(&ifetch_req); |
517 518 if (fault == NoFault) { 519 Tick icache_latency = 0; 520 bool icache_access = false; 521 dcache_access = false; // assume no dcache access 522 523 //Fetch more instruction memory if necessary 524 //if(predecoder.needMoreBytes()) 525 //{ 526 icache_access = true; | 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; |
527 ifetch_pkt->reinitFromRequest(); | 497 Packet ifetch_pkt = Packet(&ifetch_req, MemCmd::ReadReq, 498 Packet::Broadcast); 499 ifetch_pkt.dataStatic(&inst); |
528 | 500 |
529 icache_latency = icachePort.sendAtomic(ifetch_pkt); | 501 icache_latency = icachePort.sendAtomic(&ifetch_pkt); |
530 // ifetch_req is initialized to read the instruction directly 531 // into the CPU object's inst field. 532 //} 533 534 preExecute(); 535 536 if(curStaticInst) 537 { --- 27 unchanged lines hidden (view full) --- 565 tickEvent.schedule(curTick + latency); 566} 567 568 569//////////////////////////////////////////////////////////////////////// 570// 571// AtomicSimpleCPU Simulation Object 572// | 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// |
573AtomicSimpleCPU * 574AtomicSimpleCPUParams::create() | 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) |
575{ 576 AtomicSimpleCPU::Params *params = new AtomicSimpleCPU::Params(); | 615{ 616 AtomicSimpleCPU::Params *params = new AtomicSimpleCPU::Params(); |
577 params->name = name; | 617 params->name = getInstanceName(); |
578 params->numberOfThreads = 1; 579 params->max_insts_any_thread = max_insts_any_thread; 580 params->max_insts_all_threads = max_insts_all_threads; 581 params->max_loads_any_thread = max_loads_any_thread; 582 params->max_loads_all_threads = max_loads_all_threads; 583 params->progress_interval = progress_interval; 584 params->deferRegistration = defer_registration; 585 params->phase = phase; 586 params->clock = clock; 587 params->functionTrace = function_trace; 588 params->functionTraceStart = function_trace_start; 589 params->width = width; 590 params->simulate_stalls = simulate_stalls; 591 params->system = system; 592 params->cpu_id = cpu_id; | 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; |
593 params->tracer = tracer; | |
594 595#if FULL_SYSTEM 596 params->itb = itb; 597 params->dtb = dtb; 598 params->profile = profile; 599 params->do_quiesce = do_quiesce; 600 params->do_checkpoint_insts = do_checkpoint_insts; 601 params->do_statistics_insts = do_statistics_insts; 602#else | 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 |
603 if (workload.size() != 1) 604 panic("only one workload allowed"); 605 params->process = workload[0]; | 642 params->process = workload; |
606#endif 607 608 AtomicSimpleCPU *cpu = new AtomicSimpleCPU(params); 609 return cpu; 610} | 643#endif 644 645 AtomicSimpleCPU *cpu = new AtomicSimpleCPU(params); 646 return cpu; 647} |
648 649REGISTER_SIM_OBJECT("AtomicSimpleCPU", AtomicSimpleCPU) 650 |
|