aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
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
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')
-rw-r--r--arch/sparc/include/asm/tsb.h30
-rw-r--r--arch/sparc/mm/init_64.c28
2 files changed, 37 insertions, 21 deletions
diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h
index 2e268b646348..a2f541905715 100644
--- a/arch/sparc/include/asm/tsb.h
+++ b/arch/sparc/include/asm/tsb.h
@@ -256,8 +256,6 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
256 (KERNEL_TSB_SIZE_BYTES / 16) 256 (KERNEL_TSB_SIZE_BYTES / 16)
257#define KERNEL_TSB4M_NENTRIES 4096 257#define KERNEL_TSB4M_NENTRIES 4096
258 258
259#define KTSB_PHYS_SHIFT 15
260
261 /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL 259 /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL
262 * on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries 260 * on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries
263 * and the found TTE will be left in REG1. REG3 and REG4 must 261 * and the found TTE will be left in REG1. REG3 and REG4 must
@@ -266,17 +264,15 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
266 * VADDR and TAG will be preserved and not clobbered by this macro. 264 * VADDR and TAG will be preserved and not clobbered by this macro.
267 */ 265 */
268#define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ 266#define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
269661: sethi %hi(swapper_tsb), REG1; \ 267661: sethi %uhi(swapper_tsb), REG1; \
270 or REG1, %lo(swapper_tsb), REG1; \ 268 sethi %hi(swapper_tsb), REG2; \
269 or REG1, %ulo(swapper_tsb), REG1; \
270 or REG2, %lo(swapper_tsb), REG2; \
271 .section .swapper_tsb_phys_patch, "ax"; \ 271 .section .swapper_tsb_phys_patch, "ax"; \
272 .word 661b; \ 272 .word 661b; \
273 .previous; \ 273 .previous; \
274661: nop; \ 274 sllx REG1, 32, REG1; \
275 .section .tsb_ldquad_phys_patch, "ax"; \ 275 or REG1, REG2, REG1; \
276 .word 661b; \
277 sllx REG1, KTSB_PHYS_SHIFT, REG1; \
278 sllx REG1, KTSB_PHYS_SHIFT, REG1; \
279 .previous; \
280 srlx VADDR, PAGE_SHIFT, REG2; \ 276 srlx VADDR, PAGE_SHIFT, REG2; \
281 and REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \ 277 and REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \
282 sllx REG2, 4, REG2; \ 278 sllx REG2, 4, REG2; \
@@ -291,17 +287,15 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
291 * we can make use of that for the index computation. 287 * we can make use of that for the index computation.
292 */ 288 */
293#define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ 289#define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
294661: sethi %hi(swapper_4m_tsb), REG1; \ 290661: sethi %uhi(swapper_4m_tsb), REG1; \
295 or REG1, %lo(swapper_4m_tsb), REG1; \ 291 sethi %hi(swapper_4m_tsb), REG2; \
292 or REG1, %ulo(swapper_4m_tsb), REG1; \
293 or REG2, %lo(swapper_4m_tsb), REG2; \
296 .section .swapper_4m_tsb_phys_patch, "ax"; \ 294 .section .swapper_4m_tsb_phys_patch, "ax"; \
297 .word 661b; \ 295 .word 661b; \
298 .previous; \ 296 .previous; \
299661: nop; \ 297 sllx REG1, 32, REG1; \
300 .section .tsb_ldquad_phys_patch, "ax"; \ 298 or REG1, REG2, REG1; \
301 .word 661b; \
302 sllx REG1, KTSB_PHYS_SHIFT, REG1; \
303 sllx REG1, KTSB_PHYS_SHIFT, REG1; \
304 .previous; \
305 and TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \ 299 and TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \
306 sllx REG2, 4, REG2; \ 300 sllx REG2, 4, REG2; \
307 add REG1, REG2, REG2; \ 301 add REG1, REG2, REG2; \
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}