Commit 697a77e6e7357f4ae6c74f06a4fa31701442d79d
Committed by
Blue Swirl
1 parent
ef28c4b0
sparc64 support TSB related MMU registers
Posting updated patch to the list...
>>> On Fri, Apr 24, 2009 at 9:42 PM, Blue Swirl <blauwirbel@gmail.com> wrote:
>>> >
>>> > Nice, though I didn't notice any visible improvement in my tests.
>>>
>>> This early in boot process there is not much to output; and I test
>>> recent kernel which may use different startup sequence.
>>> I modified openbios cif handler to output arguments and I now can see
>>> visible difference.
>>>
>>>
>>> >
>>> > About the patch, there are a few problems:
>>> > - it breaks Sparc32
>>>
>>> You mean it stops working?
>>
>> Does not even build.
Fixed now.
>>> > - commented out code is ugly
>>> > - if and else should be on the same line as '{' or '}'
>>> > - long lines should be wrapped
>>> > - in the line:
>>> > + return (((tag_access_register & 0x1fff)<<48)|(tag_access_register >> 22));
>>> > there should be white space between ) and << and 48.
>>> >
>>>
>>
>> Also the ")|(" in between is crowded.
>>
>> Maybe the coding style does not describe this well enough.
BTW Supplying indent template would be great.
Please see the updated patch qemu-sparc64-tsb-asi-2.patch attached.
--
Kind regards,
Igor V. Kovalenko
Showing
1 changed file
with
93 additions
and
6 deletions
target-sparc/op_helper.c
| @@ -39,6 +39,56 @@ do { printf("ASI: " fmt , ##args); } while (0) | @@ -39,6 +39,56 @@ do { printf("ASI: " fmt , ##args); } while (0) | ||
| 39 | #endif | 39 | #endif |
| 40 | #endif | 40 | #endif |
| 41 | 41 | ||
| 42 | +#ifdef TARGET_SPARC64 | ||
| 43 | +// Calculates TSB pointer value for fault page size 8k or 64k | ||
| 44 | +static uint64_t ultrasparc_tsb_pointer(uint64_t tsb_register, | ||
| 45 | + uint64_t tag_access_register, | ||
| 46 | + int page_size) | ||
| 47 | +{ | ||
| 48 | + uint64_t tsb_base = tsb_register & ~0x1fffULL; | ||
| 49 | + int tsb_split = (env->dmmuregs[5] & 0x1000ULL) ? 1 : 0; | ||
| 50 | + int tsb_size = env->dmmuregs[5] & 0xf; | ||
| 51 | + | ||
| 52 | + // discard lower 13 bits which hold tag access context | ||
| 53 | + uint64_t tag_access_va = tag_access_register & ~0x1fffULL; | ||
| 54 | + | ||
| 55 | + // now reorder bits | ||
| 56 | + uint64_t tsb_base_mask = ~0x1fffULL; | ||
| 57 | + uint64_t va = tag_access_va; | ||
| 58 | + | ||
| 59 | + // move va bits to correct position | ||
| 60 | + if (page_size == 8*1024) { | ||
| 61 | + va >>= 9; | ||
| 62 | + } else if (page_size == 64*1024) { | ||
| 63 | + va >>= 12; | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + if (tsb_size) { | ||
| 67 | + tsb_base_mask <<= tsb_size; | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + // calculate tsb_base mask and adjust va if split is in use | ||
| 71 | + if (tsb_split) { | ||
| 72 | + if (page_size == 8*1024) { | ||
| 73 | + va &= ~(1ULL << (13 + tsb_size)); | ||
| 74 | + } else if (page_size == 64*1024) { | ||
| 75 | + va |= (1ULL << (13 + tsb_size)); | ||
| 76 | + } | ||
| 77 | + tsb_base_mask <<= 1; | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + return ((tsb_base & tsb_base_mask) | (va & ~tsb_base_mask)) & ~0xfULL; | ||
| 81 | +} | ||
| 82 | + | ||
| 83 | +// Calculates tag target register value by reordering bits | ||
| 84 | +// in tag access register | ||
| 85 | +static uint64_t ultrasparc_tag_target(uint64_t tag_access_register) | ||
| 86 | +{ | ||
| 87 | + return ((tag_access_register & 0x1fff) << 48) | (tag_access_register >> 22); | ||
| 88 | +} | ||
| 89 | + | ||
| 90 | +#endif | ||
| 91 | + | ||
| 42 | static inline void address_mask(CPUState *env1, target_ulong *addr) | 92 | static inline void address_mask(CPUState *env1, target_ulong *addr) |
| 43 | { | 93 | { |
| 44 | #ifdef TARGET_SPARC64 | 94 | #ifdef TARGET_SPARC64 |
| @@ -1652,13 +1702,31 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) | @@ -1652,13 +1702,31 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) | ||
| 1652 | { | 1702 | { |
| 1653 | int reg = (addr >> 3) & 0xf; | 1703 | int reg = (addr >> 3) & 0xf; |
| 1654 | 1704 | ||
| 1655 | - ret = env->immuregs[reg]; | 1705 | + if (reg == 0) { |
| 1706 | + // I-TSB Tag Target register | ||
| 1707 | + ret = ultrasparc_tag_target(env->immuregs[6]); | ||
| 1708 | + } else { | ||
| 1709 | + ret = env->immuregs[reg]; | ||
| 1710 | + } | ||
| 1711 | + | ||
| 1656 | break; | 1712 | break; |
| 1657 | } | 1713 | } |
| 1658 | case 0x51: // I-MMU 8k TSB pointer | 1714 | case 0x51: // I-MMU 8k TSB pointer |
| 1715 | + { | ||
| 1716 | + // env->immuregs[5] holds I-MMU TSB register value | ||
| 1717 | + // env->immuregs[6] holds I-MMU Tag Access register value | ||
| 1718 | + ret = ultrasparc_tsb_pointer(env->immuregs[5], env->immuregs[6], | ||
| 1719 | + 8*1024); | ||
| 1720 | + break; | ||
| 1721 | + } | ||
| 1659 | case 0x52: // I-MMU 64k TSB pointer | 1722 | case 0x52: // I-MMU 64k TSB pointer |
| 1660 | - // XXX | ||
| 1661 | - break; | 1723 | + { |
| 1724 | + // env->immuregs[5] holds I-MMU TSB register value | ||
| 1725 | + // env->immuregs[6] holds I-MMU Tag Access register value | ||
| 1726 | + ret = ultrasparc_tsb_pointer(env->immuregs[5], env->immuregs[6], | ||
| 1727 | + 64*1024); | ||
| 1728 | + break; | ||
| 1729 | + } | ||
| 1662 | case 0x55: // I-MMU data access | 1730 | case 0x55: // I-MMU data access |
| 1663 | { | 1731 | { |
| 1664 | int reg = (addr >> 3) & 0x3f; | 1732 | int reg = (addr >> 3) & 0x3f; |
| @@ -1677,7 +1745,28 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) | @@ -1677,7 +1745,28 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) | ||
| 1677 | { | 1745 | { |
| 1678 | int reg = (addr >> 3) & 0xf; | 1746 | int reg = (addr >> 3) & 0xf; |
| 1679 | 1747 | ||
| 1680 | - ret = env->dmmuregs[reg]; | 1748 | + if (reg == 0) { |
| 1749 | + // D-TSB Tag Target register | ||
| 1750 | + ret = ultrasparc_tag_target(env->dmmuregs[6]); | ||
| 1751 | + } else { | ||
| 1752 | + ret = env->dmmuregs[reg]; | ||
| 1753 | + } | ||
| 1754 | + break; | ||
| 1755 | + } | ||
| 1756 | + case 0x59: // D-MMU 8k TSB pointer | ||
| 1757 | + { | ||
| 1758 | + // env->dmmuregs[5] holds D-MMU TSB register value | ||
| 1759 | + // env->dmmuregs[6] holds D-MMU Tag Access register value | ||
| 1760 | + ret = ultrasparc_tsb_pointer(env->dmmuregs[5], env->dmmuregs[6], | ||
| 1761 | + 8*1024); | ||
| 1762 | + break; | ||
| 1763 | + } | ||
| 1764 | + case 0x5a: // D-MMU 64k TSB pointer | ||
| 1765 | + { | ||
| 1766 | + // env->dmmuregs[5] holds D-MMU TSB register value | ||
| 1767 | + // env->dmmuregs[6] holds D-MMU Tag Access register value | ||
| 1768 | + ret = ultrasparc_tsb_pointer(env->dmmuregs[5], env->dmmuregs[6], | ||
| 1769 | + 64*1024); | ||
| 1681 | break; | 1770 | break; |
| 1682 | } | 1771 | } |
| 1683 | case 0x5d: // D-MMU data access | 1772 | case 0x5d: // D-MMU data access |
| @@ -1707,8 +1796,6 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) | @@ -1707,8 +1796,6 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) | ||
| 1707 | case 0x76: // E-cache tag | 1796 | case 0x76: // E-cache tag |
| 1708 | case 0x7e: // E-cache tag | 1797 | case 0x7e: // E-cache tag |
| 1709 | break; | 1798 | break; |
| 1710 | - case 0x59: // D-MMU 8k TSB pointer | ||
| 1711 | - case 0x5a: // D-MMU 64k TSB pointer | ||
| 1712 | case 0x5b: // D-MMU data pointer | 1799 | case 0x5b: // D-MMU data pointer |
| 1713 | case 0x48: // Interrupt dispatch, RO | 1800 | case 0x48: // Interrupt dispatch, RO |
| 1714 | case 0x49: // Interrupt data receive | 1801 | case 0x49: // Interrupt data receive |