timing.cc (9442:36967173340c) timing.cc (9448:569d1e8f74e4)
1/*
2 * Copyright (c) 2010-2012 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

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

104
105TimingSimpleCPU::~TimingSimpleCPU()
106{
107}
108
109unsigned int
110TimingSimpleCPU::drain(DrainManager *drain_manager)
111{
1/*
2 * Copyright (c) 2010-2012 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

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

104
105TimingSimpleCPU::~TimingSimpleCPU()
106{
107}
108
109unsigned int
110TimingSimpleCPU::drain(DrainManager *drain_manager)
111{
112 assert(!drainManager);
113 if (switchedOut())
114 return 0;
115
112 if (_status == Idle ||
116 if (_status == Idle ||
113 (_status == BaseSimpleCPU::Running && isDrained()) ||
114 _status == SwitchedOut) {
117 (_status == BaseSimpleCPU::Running && isDrained())) {
115 assert(!fetchEvent.scheduled());
116 DPRINTF(Drain, "No need to drain.\n");
117 return 0;
118 } else {
119 drainManager = drain_manager;
120 DPRINTF(Drain, "Requesting drain: %s\n", pcState());
121
122 // The fetch event can become descheduled if a drain didn't
123 // succeed on the first attempt. We need to reschedule it if
124 // the CPU is waiting for a microcode routine to complete.
118 assert(!fetchEvent.scheduled());
119 DPRINTF(Drain, "No need to drain.\n");
120 return 0;
121 } else {
122 drainManager = drain_manager;
123 DPRINTF(Drain, "Requesting drain: %s\n", pcState());
124
125 // The fetch event can become descheduled if a drain didn't
126 // succeed on the first attempt. We need to reschedule it if
127 // the CPU is waiting for a microcode routine to complete.
125 if (_status == BaseSimpleCPU::Running && !isDrained() &&
126 !fetchEvent.scheduled()) {
128 if (_status == BaseSimpleCPU::Running && !fetchEvent.scheduled())
127 schedule(fetchEvent, nextCycle());
129 schedule(fetchEvent, nextCycle());
128 }
129
130 return 1;
131 }
132}
133
134void
135TimingSimpleCPU::drainResume()
136{
137 assert(!fetchEvent.scheduled());
130
131 return 1;
132 }
133}
134
135void
136TimingSimpleCPU::drainResume()
137{
138 assert(!fetchEvent.scheduled());
139 assert(!drainManager);
140 if (switchedOut())
141 return;
138
139 DPRINTF(SimpleCPU, "Resume\n");
142
143 DPRINTF(SimpleCPU, "Resume\n");
140 if (_status != SwitchedOut && _status != Idle) {
141 if (system->getMemoryMode() != Enums::timing) {
142 fatal("The timing CPU requires the memory system to be in "
143 "'timing' mode.\n");
144 }
144 if (system->getMemoryMode() != Enums::timing) {
145 fatal("The timing CPU requires the memory system to be in "
146 "'timing' mode.\n");
147 }
145
148
149 assert(!threadContexts.empty());
150 if (threadContexts.size() > 1)
151 fatal("The timing CPU only supports one thread.\n");
152
153 if (thread->status() == ThreadContext::Active) {
146 schedule(fetchEvent, nextCycle());
154 schedule(fetchEvent, nextCycle());
155 _status = BaseSimpleCPU::Running;
156 } else {
157 _status = BaseSimpleCPU::Idle;
147 }
148}
149
150bool
151TimingSimpleCPU::tryCompleteDrain()
152{
153 if (!drainManager)
154 return false;

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

169{
170 BaseSimpleCPU::switchOut();
171
172 assert(!fetchEvent.scheduled());
173 assert(_status == BaseSimpleCPU::Running || _status == Idle);
174 assert(!stayAtPC);
175 assert(microPC() == 0);
176
158 }
159}
160
161bool
162TimingSimpleCPU::tryCompleteDrain()
163{
164 if (!drainManager)
165 return false;

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

180{
181 BaseSimpleCPU::switchOut();
182
183 assert(!fetchEvent.scheduled());
184 assert(_status == BaseSimpleCPU::Running || _status == Idle);
185 assert(!stayAtPC);
186 assert(microPC() == 0);
187
177 _status = SwitchedOut;
178 numCycles += curCycle() - previousCycle;
179}
180
181
182void
183TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
184{
185 BaseSimpleCPU::takeOverFrom(oldCPU);
186
188 numCycles += curCycle() - previousCycle;
189}
190
191
192void
193TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
194{
195 BaseSimpleCPU::takeOverFrom(oldCPU);
196
187 // if any of this CPU's ThreadContexts are active, mark the CPU as
188 // running and schedule its tick event.
189 for (int i = 0; i < threadContexts.size(); ++i) {
190 ThreadContext *tc = threadContexts[i];
191 if (tc->status() == ThreadContext::Active &&
192 _status != BaseSimpleCPU::Running) {
193 _status = BaseSimpleCPU::Running;
194 break;
195 }
196 }
197
198 if (_status != BaseSimpleCPU::Running) {
199 _status = Idle;
200 }
201 assert(threadContexts.size() == 1);
202 previousCycle = curCycle();
203}
204
205
206void
207TimingSimpleCPU::activateContext(ThreadID thread_num, Cycles delay)
208{
209 DPRINTF(SimpleCPU, "ActivateContext %d (%d cycles)\n", thread_num, delay);

--- 715 unchanged lines hidden ---
197 previousCycle = curCycle();
198}
199
200
201void
202TimingSimpleCPU::activateContext(ThreadID thread_num, Cycles delay)
203{
204 DPRINTF(SimpleCPU, "ActivateContext %d (%d cycles)\n", thread_num, delay);

--- 715 unchanged lines hidden ---