Deleted Added
sdiff udiff text old ( 8737:770ccf3af571 ) new ( 8779:2a590c51adb1 )
full compact
1/*
2 * Copyright (c) 2010 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

--- 40 unchanged lines hidden (view full) ---

49#include "cpu/exetrace.hh"
50#include "debug/Config.hh"
51#include "debug/ExecFaulting.hh"
52#include "debug/SimpleCPU.hh"
53#include "mem/packet.hh"
54#include "mem/packet_access.hh"
55#include "params/TimingSimpleCPU.hh"
56#include "sim/faults.hh"
57#include "sim/full_system.hh"
58#include "sim/system.hh"
59
60using namespace std;
61using namespace TheISA;
62
63Port *
64TimingSimpleCPU::getPort(const std::string &if_name, int idx)
65{

--- 4 unchanged lines hidden (view full) ---

70 else
71 panic("No Such Port\n");
72}
73
74void
75TimingSimpleCPU::init()
76{
77 BaseCPU::init();
78 if (FullSystem) {
79 for (int i = 0; i < threadContexts.size(); ++i) {
80#if FULL_SYSTEM
81 ThreadContext *tc = threadContexts[i];
82 // initialize CPU, including PC
83 TheISA::initCPU(tc, _cpuId);
84#endif
85 }
86 }
87}
88
89Tick
90TimingSimpleCPU::CpuPort::recvAtomic(PacketPtr pkt)
91{
92 panic("TimingSimpleCPU doesn't expect recvAtomic callback!");
93 return curTick();
94}
95
96void
97TimingSimpleCPU::CpuPort::recvFunctional(PacketPtr pkt)
98{
99 //No internal storage to update, jusst return
100 return;
101}
102
103void
104TimingSimpleCPU::CpuPort::recvStatusChange(Status status)
105{
106 if (status == RangeChange) {
107 if (!snoopRangeSent) {
108 snoopRangeSent = true;
109 sendStatusChange(Port::RangeChange);
110 }
111 return;
112 }
113
114 panic("TimingSimpleCPU doesn't expect recvStatusChange callback!");
115}
116
117
118void
119TimingSimpleCPU::CpuPort::TickEvent::schedule(PacketPtr _pkt, Tick t)
120{
121 pkt = _pkt;
122 cpu->schedule(this, t);
123}
124
125TimingSimpleCPU::TimingSimpleCPU(TimingSimpleCPUParams *p)
126 : BaseSimpleCPU(p), fetchTranslation(this), icachePort(this, p->clock),
127 dcachePort(this, p->clock), fetchEvent(this)
128{
129 _status = Idle;
130
131 icachePort.snoopRangeSent = false;
132 dcachePort.snoopRangeSent = false;
133
134 ifetch_pkt = dcache_pkt = NULL;
135 drainEvent = NULL;
136 previousTick = 0;
137 changeState(SimObject::Running);
138 system->totalNumInsts = 0;
139}
140
141

--- 60 unchanged lines hidden (view full) ---

202 if (fetchEvent.scheduled())
203 deschedule(fetchEvent);
204}
205
206
207void
208TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
209{
210 BaseCPU::takeOverFrom(oldCPU, &icachePort, &dcachePort);
211
212 // if any of this CPU's ThreadContexts are active, mark the CPU as
213 // running and schedule its tick event.
214 for (int i = 0; i < threadContexts.size(); ++i) {
215 ThreadContext *tc = threadContexts[i];
216 if (tc->status() == ThreadContext::Active && _status != Running) {
217 _status = Running;
218 break;

--- 4 unchanged lines hidden (view full) ---

223 _status = Idle;
224 }
225 assert(threadContexts.size() == 1);
226 previousTick = curTick();
227}
228
229
230void
231TimingSimpleCPU::activateContext(int thread_num, int delay)
232{
233 DPRINTF(SimpleCPU, "ActivateContext %d (%d cycles)\n", thread_num, delay);
234
235 assert(thread_num == 0);
236 assert(thread);
237
238 assert(_status == Idle);
239
240 notIdleFraction++;
241 _status = Running;
242
243 // kick things off by initiating the fetch of the next instruction
244 schedule(fetchEvent, nextCycle(curTick() + ticks(delay)));
245}
246
247
248void
249TimingSimpleCPU::suspendContext(int thread_num)
250{
251 DPRINTF(SimpleCPU, "SuspendContext %d\n", thread_num);
252
253 assert(thread_num == 0);
254 assert(thread);
255
256 if (_status == Idle)
257 return;

--- 613 unchanged lines hidden (view full) ---

871void
872TimingSimpleCPU::completeDrain()
873{
874 DPRINTF(Config, "Done draining\n");
875 changeState(SimObject::Drained);
876 drainEvent->process();
877}
878
879void
880TimingSimpleCPU::DcachePort::setPeer(Port *port)
881{
882 Port::setPeer(port);
883
884 if (FullSystem) {
885 // Update the ThreadContext's memory ports (Functional/Virtual
886 // Ports)
887 cpu->tcBase()->connectMemPorts(cpu->tcBase());
888 }
889}
890
891bool
892TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
893{
894 if (pkt->isResponse() && !pkt->wasNacked()) {
895 // delay processing of returned data until next CPU clock edge
896 Tick next_tick = cpu->nextCycle(curTick());
897
898 if (next_tick == curTick()) {
899 cpu->completeDataAccess(pkt);
900 } else {
901 if (!tickEvent.scheduled()) {
902 tickEvent.schedule(pkt, next_tick);
903 } else {
904 // In the case of a split transaction and a cache that is
905 // faster than a CPU we could get two responses before
906 // next_tick expires
907 if (!retryEvent.scheduled())
908 schedule(retryEvent, next_tick);
909 return false;
910 }
911 }
912
913 return true;
914 }
915 else if (pkt->wasNacked()) {
916 assert(cpu->_status == DcacheWaitResponse);

--- 88 unchanged lines hidden (view full) ---

1005//
1006// TimingSimpleCPU Simulation Object
1007//
1008TimingSimpleCPU *
1009TimingSimpleCPUParams::create()
1010{
1011 numThreads = 1;
1012#if !FULL_SYSTEM
1013 if (!FullSystem && workload.size() != 1)
1014 panic("only one workload allowed");
1015#endif
1016 return new TimingSimpleCPU(this);
1017}