diff options
Diffstat (limited to 'arch/sparc/mm/init_64.c')
| -rw-r--r-- | arch/sparc/mm/init_64.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index c241c5723373..35fcc9cb960d 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c | |||
| @@ -1733,19 +1733,41 @@ static void __init tsb_phys_patch(void) | |||
| 1733 | static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR]; | 1733 | static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR]; |
| 1734 | extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; | 1734 | extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; |
| 1735 | 1735 | ||
| 1736 | /* The swapper TSBs are loaded with a base sequence of: | ||
| 1737 | * | ||
| 1738 | * sethi %uhi(SYMBOL), REG1 | ||
| 1739 | * sethi %hi(SYMBOL), REG2 | ||
| 1740 | * or REG1, %ulo(SYMBOL), REG1 | ||
| 1741 | * or REG2, %lo(SYMBOL), REG2 | ||
| 1742 | * sllx REG1, 32, REG1 | ||
| 1743 | * or REG1, REG2, REG1 | ||
| 1744 | * | ||
| 1745 | * When we use physical addressing for the TSB accesses, we patch the | ||
| 1746 | * first four instructions in the above sequence. | ||
| 1747 | */ | ||
| 1748 | |||
| 1736 | static void patch_one_ktsb_phys(unsigned int *start, unsigned int *end, unsigned long pa) | 1749 | static void patch_one_ktsb_phys(unsigned int *start, unsigned int *end, unsigned long pa) |
| 1737 | { | 1750 | { |
| 1738 | pa >>= KTSB_PHYS_SHIFT; | 1751 | unsigned long high_bits, low_bits; |
| 1752 | |||
| 1753 | high_bits = (pa >> 32) & 0xffffffff; | ||
| 1754 | low_bits = (pa >> 0) & 0xffffffff; | ||
| 1739 | 1755 | ||
| 1740 | while (start < end) { | 1756 | while (start < end) { |
| 1741 | unsigned int *ia = (unsigned int *)(unsigned long)*start; | 1757 | unsigned int *ia = (unsigned int *)(unsigned long)*start; |
| 1742 | 1758 | ||
| 1743 | ia[0] = (ia[0] & ~0x3fffff) | (pa >> 10); | 1759 | ia[0] = (ia[0] & ~0x3fffff) | (high_bits >> 10); |
| 1744 | __asm__ __volatile__("flush %0" : : "r" (ia)); | 1760 | __asm__ __volatile__("flush %0" : : "r" (ia)); |
| 1745 | 1761 | ||
| 1746 | ia[1] = (ia[1] & ~0x3ff) | (pa & 0x3ff); | 1762 | ia[1] = (ia[1] & ~0x3fffff) | (low_bits >> 10); |
| 1747 | __asm__ __volatile__("flush %0" : : "r" (ia + 1)); | 1763 | __asm__ __volatile__("flush %0" : : "r" (ia + 1)); |
| 1748 | 1764 | ||
| 1765 | ia[2] = (ia[2] & ~0x1fff) | (high_bits & 0x3ff); | ||
| 1766 | __asm__ __volatile__("flush %0" : : "r" (ia + 2)); | ||
| 1767 | |||
| 1768 | ia[3] = (ia[3] & ~0x1fff) | (low_bits & 0x3ff); | ||
| 1769 | __asm__ __volatile__("flush %0" : : "r" (ia + 3)); | ||
| 1770 | |||
| 1749 | start++; | 1771 | start++; |
| 1750 | } | 1772 | } |
| 1751 | } | 1773 | } |
