146 |
void mips64_idle_break_wait(cpu_mips_t *cpu) |
void mips64_idle_break_wait(cpu_mips_t *cpu) |
147 |
{ |
{ |
148 |
pthread_cond_signal(&cpu->idle_cond); |
pthread_cond_signal(&cpu->idle_cond); |
149 |
|
cpu->idle_count = 0; |
150 |
} |
} |
151 |
|
|
152 |
/* Timer IRQ */ |
/* Timer IRQ */ |
193 |
return NULL; |
return NULL; |
194 |
} |
} |
195 |
|
|
196 |
|
#define IDLE_HASH_SIZE 8192 |
197 |
|
|
198 |
/* Idle PC hash item */ |
/* Idle PC hash item */ |
199 |
struct mips64_idle_pc { |
struct mips64_idle_pc_hash { |
200 |
m_uint64_t pc; |
m_uint64_t pc; |
201 |
u_int count; |
u_int count; |
202 |
struct mips64_idle_pc *next; |
struct mips64_idle_pc_hash *next; |
203 |
}; |
}; |
204 |
|
|
|
#define IDLE_HASH_SIZE 8192 |
|
|
#define IDLE_MAX_RES 10 |
|
|
|
|
205 |
/* Determine an "idling" PC */ |
/* Determine an "idling" PC */ |
206 |
int mips64_get_idling_pc(cpu_mips_t *cpu) |
int mips64_get_idling_pc(cpu_mips_t *cpu) |
207 |
{ |
{ |
208 |
struct mips64_idle_pc *res[IDLE_MAX_RES]; |
struct mips64_idle_pc_hash **pc_hash,*p; |
209 |
struct mips64_idle_pc **pc_hash,*p; |
struct mips64_idle_pc *res; |
210 |
u_int h_index,res_count; |
u_int h_index,res_count; |
211 |
m_uint64_t cur_pc; |
m_uint64_t cur_pc; |
212 |
int i; |
int i; |
213 |
|
|
214 |
|
cpu->idle_pc_prop_count = 0; |
215 |
|
|
216 |
if (cpu->idle_pc != 0) { |
if (cpu->idle_pc != 0) { |
217 |
printf("\nYou already use an idle PC, using the calibration would give " |
printf("\nYou already use an idle PC, using the calibration would give " |
218 |
"incorrect results.\n"); |
"incorrect results.\n"); |
250 |
} |
} |
251 |
|
|
252 |
/* Select PCs */ |
/* Select PCs */ |
|
memset(res,0,sizeof(res)); |
|
|
|
|
253 |
for(i=0,res_count=0;i<IDLE_HASH_SIZE;i++) { |
for(i=0,res_count=0;i<IDLE_HASH_SIZE;i++) { |
254 |
for(p=pc_hash[i];p;p=p->next) |
for(p=pc_hash[i];p;p=p->next) |
255 |
if ((p->count >= 20) && (p->count <= 80)) { |
if ((p->count >= 20) && (p->count <= 80)) { |
256 |
res[res_count++] = p; |
res = &cpu->idle_pc_prop[cpu->idle_pc_prop_count++]; |
257 |
|
|
258 |
if (res_count >= IDLE_MAX_RES) |
res->pc = p->pc; |
259 |
|
res->count = p->count; |
260 |
|
|
261 |
|
if (cpu->idle_pc_prop_count >= MIPS64_IDLE_PC_MAX_RES) |
262 |
goto done; |
goto done; |
263 |
} |
} |
264 |
} |
} |
265 |
|
|
266 |
done: |
done: |
267 |
/* Set idle PC */ |
/* Set idle PC */ |
268 |
if (res_count) { |
if (cpu->idle_pc_prop_count) { |
269 |
printf("Done. Suggested idling PC:\n"); |
printf("Done. Suggested idling PC:\n"); |
270 |
|
|
271 |
for(i=0;i<res_count;i++) |
for(i=0;i<cpu->idle_pc_prop_count;i++) { |
272 |
printf(" 0x%llx (count=%u)\n",res[i]->pc,res[i]->count); |
printf(" 0x%llx (count=%u)\n", |
273 |
|
cpu->idle_pc_prop[i].pc, |
274 |
|
cpu->idle_pc_prop[i].count); |
275 |
|
} |
276 |
|
|
277 |
printf("Restart the emulator with \"--idle-pc=0x%llx\" (for example)\n", |
printf("Restart the emulator with \"--idle-pc=0x%llx\" (for example)\n", |
278 |
res[0]->pc); |
cpu->idle_pc_prop[0].pc); |
279 |
} else { |
} else { |
280 |
printf("Done. No suggestion for idling PC\n"); |
printf("Done. No suggestion for idling PC\n"); |
281 |
} |
} |