aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/mm/init_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/mm/init_64.c')
-rw-r--r--arch/sparc/mm/init_64.c28
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)
1733static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR]; 1733static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR];
1734extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; 1734extern 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
1736static void patch_one_ktsb_phys(unsigned int *start, unsigned int *end, unsigned long pa) 1749static 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}