Commit e83ce550688af60cd5f5f78db4071eaa4858065f
1 parent
4487fd34
Implement no-fault loads
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5148 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
36 additions
and
8 deletions
target-sparc/op_helper.c
| ... | ... | @@ -1402,10 +1402,17 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) |
| 1402 | 1402 | address_mask(env, &addr); |
| 1403 | 1403 | |
| 1404 | 1404 | switch (asi) { |
| 1405 | - case 0x80: // Primary | |
| 1406 | 1405 | case 0x82: // Primary no-fault |
| 1407 | - case 0x88: // Primary LE | |
| 1408 | 1406 | case 0x8a: // Primary no-fault LE |
| 1407 | + if (page_check_range(addr, size, PAGE_READ) == -1) { | |
| 1408 | +#ifdef DEBUG_ASI | |
| 1409 | + dump_asi("read ", last_addr, asi, size, ret); | |
| 1410 | +#endif | |
| 1411 | + return 0; | |
| 1412 | + } | |
| 1413 | + // Fall through | |
| 1414 | + case 0x80: // Primary | |
| 1415 | + case 0x88: // Primary LE | |
| 1409 | 1416 | { |
| 1410 | 1417 | switch(size) { |
| 1411 | 1418 | case 1: |
| ... | ... | @@ -1424,10 +1431,17 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) |
| 1424 | 1431 | } |
| 1425 | 1432 | } |
| 1426 | 1433 | break; |
| 1427 | - case 0x81: // Secondary | |
| 1428 | 1434 | case 0x83: // Secondary no-fault |
| 1429 | - case 0x89: // Secondary LE | |
| 1430 | 1435 | case 0x8b: // Secondary no-fault LE |
| 1436 | + if (page_check_range(addr, size, PAGE_READ) == -1) { | |
| 1437 | +#ifdef DEBUG_ASI | |
| 1438 | + dump_asi("read ", last_addr, asi, size, ret); | |
| 1439 | +#endif | |
| 1440 | + return 0; | |
| 1441 | + } | |
| 1442 | + // Fall through | |
| 1443 | + case 0x81: // Secondary | |
| 1444 | + case 0x89: // Secondary LE | |
| 1431 | 1445 | // XXX |
| 1432 | 1446 | break; |
| 1433 | 1447 | default: |
| ... | ... | @@ -1564,12 +1578,19 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) |
| 1564 | 1578 | |
| 1565 | 1579 | helper_check_align(addr, size - 1); |
| 1566 | 1580 | switch (asi) { |
| 1581 | + case 0x82: // Primary no-fault | |
| 1582 | + case 0x8a: // Primary no-fault LE | |
| 1583 | + if (cpu_get_phys_page_debug(env, addr) == -1ULL) { | |
| 1584 | +#ifdef DEBUG_ASI | |
| 1585 | + dump_asi("read ", last_addr, asi, size, ret); | |
| 1586 | +#endif | |
| 1587 | + return 0; | |
| 1588 | + } | |
| 1589 | + // Fall through | |
| 1567 | 1590 | case 0x10: // As if user primary |
| 1568 | 1591 | case 0x18: // As if user primary LE |
| 1569 | 1592 | case 0x80: // Primary |
| 1570 | - case 0x82: // Primary no-fault | |
| 1571 | 1593 | case 0x88: // Primary LE |
| 1572 | - case 0x8a: // Primary no-fault LE | |
| 1573 | 1594 | if ((asi & 0x80) && (env->pstate & PS_PRIV)) { |
| 1574 | 1595 | if ((env->def->features & CPU_FEATURE_HYPV) |
| 1575 | 1596 | && env->hpstate & HS_PRIV) { |
| ... | ... | @@ -1650,15 +1671,22 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) |
| 1650 | 1671 | // Only ldda allowed |
| 1651 | 1672 | raise_exception(TT_ILL_INSN); |
| 1652 | 1673 | return 0; |
| 1674 | + case 0x83: // Secondary no-fault | |
| 1675 | + case 0x8b: // Secondary no-fault LE | |
| 1676 | + if (cpu_get_phys_page_debug(env, addr) == -1ULL) { | |
| 1677 | +#ifdef DEBUG_ASI | |
| 1678 | + dump_asi("read ", last_addr, asi, size, ret); | |
| 1679 | +#endif | |
| 1680 | + return 0; | |
| 1681 | + } | |
| 1682 | + // Fall through | |
| 1653 | 1683 | case 0x04: // Nucleus |
| 1654 | 1684 | case 0x0c: // Nucleus Little Endian (LE) |
| 1655 | 1685 | case 0x11: // As if user secondary |
| 1656 | 1686 | case 0x19: // As if user secondary LE |
| 1657 | 1687 | case 0x4a: // UPA config |
| 1658 | 1688 | case 0x81: // Secondary |
| 1659 | - case 0x83: // Secondary no-fault | |
| 1660 | 1689 | case 0x89: // Secondary LE |
| 1661 | - case 0x8b: // Secondary no-fault LE | |
| 1662 | 1690 | // XXX |
| 1663 | 1691 | break; |
| 1664 | 1692 | case 0x45: // LSU | ... | ... |