Revision 5a25cc2b target-sh4/helper.c
b/target-sh4/helper.c | ||
---|---|---|
272 | 272 |
return match; |
273 | 273 |
} |
274 | 274 |
|
275 |
static int same_tlb_entry_exists(const tlb_t * haystack, uint8_t nbtlb, |
|
276 |
const tlb_t * needle) |
|
277 |
{ |
|
278 |
int i; |
|
279 |
for (i = 0; i < nbtlb; i++) |
|
280 |
if (!memcmp(&haystack[i], needle, sizeof(tlb_t))) |
|
281 |
return 1; |
|
282 |
return 0; |
|
283 |
} |
|
284 |
|
|
285 | 275 |
static void increment_urc(CPUState * env) |
286 | 276 |
{ |
287 | 277 |
uint8_t urb, urc; |
... | ... | |
314 | 304 |
n = itlb_replacement(env); |
315 | 305 |
ientry = &env->itlb[n]; |
316 | 306 |
if (ientry->v) { |
317 |
if (!same_tlb_entry_exists(env->utlb, UTLB_SIZE, ientry)) |
|
318 |
tlb_flush_page(env, ientry->vpn << 10); |
|
307 |
tlb_flush_page(env, ientry->vpn << 10); |
|
319 | 308 |
} |
320 | 309 |
*ientry = env->utlb[e]; |
321 | 310 |
e = n; |
... | ... | |
362 | 351 |
if (!(env->sr & SR_MD) && !(matching->pr & 2)) |
363 | 352 |
n = MMU_ITLB_VIOLATION; |
364 | 353 |
else |
365 |
*prot = PAGE_READ;
|
|
354 |
*prot = PAGE_EXEC;
|
|
366 | 355 |
} |
367 | 356 |
} else { |
368 | 357 |
n = find_utlb_entry(env, address, use_asid); |
... | ... | |
418 | 407 |
} else { |
419 | 408 |
*physical = address; |
420 | 409 |
} |
421 |
*prot = PAGE_READ | PAGE_WRITE; |
|
410 |
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
|
422 | 411 |
return MMU_OK; |
423 | 412 |
} |
424 | 413 |
|
425 | 414 |
/* If MMU is disabled, return the corresponding physical page */ |
426 | 415 |
if (!env->mmucr & MMUCR_AT) { |
427 | 416 |
*physical = address & 0x1FFFFFFF; |
428 |
*prot = PAGE_READ | PAGE_WRITE; |
|
417 |
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
|
429 | 418 |
return MMU_OK; |
430 | 419 |
} |
431 | 420 |
|
... | ... | |
506 | 495 |
if (entry->v) { |
507 | 496 |
/* Overwriting valid entry in utlb. */ |
508 | 497 |
target_ulong address = entry->vpn << 10; |
509 |
if (!same_tlb_entry_exists(env->itlb, ITLB_SIZE, entry)) { |
|
510 |
tlb_flush_page(env, address); |
|
511 |
} |
|
498 |
tlb_flush_page(env, address); |
|
512 | 499 |
} |
513 | 500 |
|
514 | 501 |
/* Take values into cpu status from registers. */ |
... | ... | |
623 | 610 |
if (entry->v) { |
624 | 611 |
/* Overwriting valid entry in utlb. */ |
625 | 612 |
target_ulong address = entry->vpn << 10; |
626 |
if (!same_tlb_entry_exists(s->itlb, ITLB_SIZE, entry)) { |
|
627 |
tlb_flush_page(s, address); |
|
628 |
} |
|
613 |
tlb_flush_page(s, address); |
|
629 | 614 |
} |
630 | 615 |
entry->asid = asid; |
631 | 616 |
entry->vpn = vpn; |
Also available in: Unified diff