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 --- |