aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/mm
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-08-05 03:53:57 -0400
committerDavid S. Miller <davem@davemloft.net>2011-08-05 03:53:57 -0400
commit9076d0e7e02b98f7a65df10d1956326c8d8ba61a (patch)
treeef7d3b694a7365ad8be871c2e892c7454c4b31c2 /arch/sparc/mm
parenta61b582954183e93a3dc3a5cf6bfd2e2c3b40aba (diff)
sparc: Access kernel TSB using physical addressing when possible.
On sun4v this is basically required since we point the hypervisor and the TSB walking hardware at these tables using physical addressing too. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/mm')
-rw-r--r--arch/sparc/mm/init_64.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 3fd8e18bed80..adfac23d976a 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -1597,6 +1597,42 @@ static void __init tsb_phys_patch(void)
1597static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR]; 1597static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR];
1598extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; 1598extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES];
1599 1599
1600static void patch_one_ktsb_phys(unsigned int *start, unsigned int *end, unsigned long pa)
1601{
1602 pa >>= KTSB_PHYS_SHIFT;
1603
1604 while (start < end) {
1605 unsigned int *ia = (unsigned int *)(unsigned long)*start;
1606
1607 ia[0] = (ia[0] & ~0x3fffff) | (pa >> 10);
1608 __asm__ __volatile__("flush %0" : : "r" (ia));
1609
1610 ia[1] = (ia[1] & ~0x3ff) | (pa & 0x3ff);
1611 __asm__ __volatile__("flush %0" : : "r" (ia + 1));
1612
1613 start++;
1614 }
1615}
1616
1617static void ktsb_phys_patch(void)
1618{
1619 extern unsigned int __swapper_tsb_phys_patch;
1620 extern unsigned int __swapper_tsb_phys_patch_end;
1621 extern unsigned int __swapper_4m_tsb_phys_patch;
1622 extern unsigned int __swapper_4m_tsb_phys_patch_end;
1623 unsigned long ktsb_pa;
1624
1625 ktsb_pa = kern_base + ((unsigned long)&swapper_tsb[0] - KERNBASE);
1626 patch_one_ktsb_phys(&__swapper_tsb_phys_patch,
1627 &__swapper_tsb_phys_patch_end, ktsb_pa);
1628#ifndef CONFIG_DEBUG_PAGEALLOC
1629 ktsb_pa = (kern_base +
1630 ((unsigned long)&swapper_4m_tsb[0] - KERNBASE));
1631 patch_one_ktsb_phys(&__swapper_4m_tsb_phys_patch,
1632 &__swapper_4m_tsb_phys_patch_end, ktsb_pa);
1633#endif
1634}
1635
1600static void __init sun4v_ktsb_init(void) 1636static void __init sun4v_ktsb_init(void)
1601{ 1637{
1602 unsigned long ktsb_pa; 1638 unsigned long ktsb_pa;
@@ -1716,8 +1752,10 @@ void __init paging_init(void)
1716 sun4u_pgprot_init(); 1752 sun4u_pgprot_init();
1717 1753
1718 if (tlb_type == cheetah_plus || 1754 if (tlb_type == cheetah_plus ||
1719 tlb_type == hypervisor) 1755 tlb_type == hypervisor) {
1720 tsb_phys_patch(); 1756 tsb_phys_patch();
1757 ktsb_phys_patch();
1758 }
1721 1759
1722 if (tlb_type == hypervisor) { 1760 if (tlb_type == hypervisor) {
1723 sun4v_patch_tlb_handlers(); 1761 sun4v_patch_tlb_handlers();