aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/mm
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-09-17 13:14:56 -0400
committerDavid S. Miller <davem@davemloft.net>2014-10-05 19:53:39 -0400
commit8c82dc0e883821c098c8b0b130ffebabf9aab5df (patch)
tree47d5fb85d84918f4857bfa37b0a363d517685ffb /arch/sparc/mm
parent4397bed080598001e88f612deb8b080bb1cc2322 (diff)
sparc64: Adjust KTSB assembler to support larger physical addresses.
As currently coded the KTSB accesses in the kernel only support up to 47 bits of physical addressing. Adjust the instruction and patching sequence in order to support arbitrary 64 bits addresses. Signed-off-by: David S. Miller <davem@davemloft.net> Acked-by: Bob Picco <bob.picco@oracle.com>
Diffstat (limited to 'arch/sparc/mm')
-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}