aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm/tlb_nohash.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-26 01:59:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-26 01:59:39 -0400
commit184475029a724b6b900d88fc3a5f462a6107d5af (patch)
tree408320b46df221a2424bf94282b1b8e5b7aff7a1 /arch/powerpc/mm/tlb_nohash.c
parent3b76eefe0f970c2e19f165d4a1650abc523d10bc (diff)
parentf1f4ee01c0d3dce0e3aa7d04e4332677db7af478 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (99 commits) drivers/virt: add missing linux/interrupt.h to fsl_hypervisor.c powerpc/85xx: fix mpic configuration in CAMP mode powerpc: Copy back TIF flags on return from softirq stack powerpc/64: Make server perfmon only built on ppc64 server devices powerpc/pseries: Fix hvc_vio.c build due to recent changes powerpc: Exporting boot_cpuid_phys powerpc: Add CFAR to oops output hvc_console: Add kdb support powerpc/pseries: Fix hvterm_raw_get_chars to accept < 16 chars, fixing xmon powerpc/irq: Quieten irq mapping printks powerpc: Enable lockup and hung task detectors in pseries and ppc64 defeconfigs powerpc: Add mpt2sas driver to pseries and ppc64 defconfig powerpc: Disable IRQs off tracer in ppc64 defconfig powerpc: Sync pseries and ppc64 defconfigs powerpc/pseries/hvconsole: Fix dropped console output hvc_console: Improve tty/console put_chars handling powerpc/kdump: Fix timeout in crash_kexec_wait_realmode powerpc/mm: Fix output of total_ram. powerpc/cpufreq: Add cpufreq driver for Momentum Maple boards powerpc: Correct annotations of pmu registration functions ... Fix up trivial Kconfig/Makefile conflicts in arch/powerpc, drivers, and drivers/cpufreq
Diffstat (limited to 'arch/powerpc/mm/tlb_nohash.c')
-rw-r--r--arch/powerpc/mm/tlb_nohash.c64
1 files changed, 49 insertions, 15 deletions
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index 0bdad3aecc67..d32ec643c231 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -35,6 +35,7 @@
35#include <linux/preempt.h> 35#include <linux/preempt.h>
36#include <linux/spinlock.h> 36#include <linux/spinlock.h>
37#include <linux/memblock.h> 37#include <linux/memblock.h>
38#include <linux/of_fdt.h>
38 39
39#include <asm/tlbflush.h> 40#include <asm/tlbflush.h>
40#include <asm/tlb.h> 41#include <asm/tlb.h>
@@ -102,6 +103,12 @@ unsigned long linear_map_top; /* Top of linear mapping */
102 103
103#endif /* CONFIG_PPC64 */ 104#endif /* CONFIG_PPC64 */
104 105
106#ifdef CONFIG_PPC_FSL_BOOK3E
107/* next_tlbcam_idx is used to round-robin tlbcam entry assignment */
108DEFINE_PER_CPU(int, next_tlbcam_idx);
109EXPORT_PER_CPU_SYMBOL(next_tlbcam_idx);
110#endif
111
105/* 112/*
106 * Base TLB flushing operations: 113 * Base TLB flushing operations:
107 * 114 *
@@ -266,6 +273,17 @@ EXPORT_SYMBOL(flush_tlb_page);
266 273
267#endif /* CONFIG_SMP */ 274#endif /* CONFIG_SMP */
268 275
276#ifdef CONFIG_PPC_47x
277void __init early_init_mmu_47x(void)
278{
279#ifdef CONFIG_SMP
280 unsigned long root = of_get_flat_dt_root();
281 if (of_get_flat_dt_prop(root, "cooperative-partition", NULL))
282 mmu_clear_feature(MMU_FTR_USE_TLBIVAX_BCAST);
283#endif /* CONFIG_SMP */
284}
285#endif /* CONFIG_PPC_47x */
286
269/* 287/*
270 * Flush kernel TLB entries in the given range 288 * Flush kernel TLB entries in the given range
271 */ 289 */
@@ -443,14 +461,27 @@ static void setup_page_sizes(void)
443 } 461 }
444} 462}
445 463
446static void setup_mmu_htw(void) 464static void __patch_exception(int exc, unsigned long addr)
447{ 465{
448 extern unsigned int interrupt_base_book3e; 466 extern unsigned int interrupt_base_book3e;
449 extern unsigned int exc_data_tlb_miss_htw_book3e; 467 unsigned int *ibase = &interrupt_base_book3e;
450 extern unsigned int exc_instruction_tlb_miss_htw_book3e; 468
469 /* Our exceptions vectors start with a NOP and -then- a branch
470 * to deal with single stepping from userspace which stops on
471 * the second instruction. Thus we need to patch the second
472 * instruction of the exception, not the first one
473 */
451 474
452 unsigned int *ibase = &interrupt_base_book3e; 475 patch_branch(ibase + (exc / 4) + 1, addr, 0);
476}
477
478#define patch_exception(exc, name) do { \
479 extern unsigned int name; \
480 __patch_exception((exc), (unsigned long)&name); \
481} while (0)
453 482
483static void setup_mmu_htw(void)
484{
454 /* Check if HW tablewalk is present, and if yes, enable it by: 485 /* Check if HW tablewalk is present, and if yes, enable it by:
455 * 486 *
456 * - patching the TLB miss handlers to branch to the 487 * - patching the TLB miss handlers to branch to the
@@ -462,19 +493,12 @@ static void setup_mmu_htw(void)
462 493
463 if ((tlb0cfg & TLBnCFG_IND) && 494 if ((tlb0cfg & TLBnCFG_IND) &&
464 (tlb0cfg & TLBnCFG_PT)) { 495 (tlb0cfg & TLBnCFG_PT)) {
465 /* Our exceptions vectors start with a NOP and -then- a branch 496 patch_exception(0x1c0, exc_data_tlb_miss_htw_book3e);
466 * to deal with single stepping from userspace which stops on 497 patch_exception(0x1e0, exc_instruction_tlb_miss_htw_book3e);
467 * the second instruction. Thus we need to patch the second
468 * instruction of the exception, not the first one
469 */
470 patch_branch(ibase + (0x1c0 / 4) + 1,
471 (unsigned long)&exc_data_tlb_miss_htw_book3e, 0);
472 patch_branch(ibase + (0x1e0 / 4) + 1,
473 (unsigned long)&exc_instruction_tlb_miss_htw_book3e, 0);
474 book3e_htw_enabled = 1; 498 book3e_htw_enabled = 1;
475 } 499 }
476 pr_info("MMU: Book3E Page Tables %s\n", 500 pr_info("MMU: Book3E HW tablewalk %s\n",
477 book3e_htw_enabled ? "Enabled" : "Disabled"); 501 book3e_htw_enabled ? "enabled" : "not supported");
478} 502}
479 503
480/* 504/*
@@ -549,6 +573,9 @@ static void __early_init_mmu(int boot_cpu)
549 /* limit memory so we dont have linear faults */ 573 /* limit memory so we dont have linear faults */
550 memblock_enforce_memory_limit(linear_map_top); 574 memblock_enforce_memory_limit(linear_map_top);
551 memblock_analyze(); 575 memblock_analyze();
576
577 patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e);
578 patch_exception(0x1e0, exc_instruction_tlb_miss_bolted_book3e);
552 } 579 }
553#endif 580#endif
554 581
@@ -584,4 +611,11 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
584 /* Finally limit subsequent allocations */ 611 /* Finally limit subsequent allocations */
585 memblock_set_current_limit(first_memblock_base + ppc64_rma_size); 612 memblock_set_current_limit(first_memblock_base + ppc64_rma_size);
586} 613}
614#else /* ! CONFIG_PPC64 */
615void __init early_init_mmu(void)
616{
617#ifdef CONFIG_PPC_47x
618 early_init_mmu_47x();
619#endif
620}
587#endif /* CONFIG_PPC64 */ 621#endif /* CONFIG_PPC64 */