diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 01:59:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 01:59:39 -0400 |
commit | 184475029a724b6b900d88fc3a5f462a6107d5af (patch) | |
tree | 408320b46df221a2424bf94282b1b8e5b7aff7a1 /arch/powerpc/mm/tlb_nohash.c | |
parent | 3b76eefe0f970c2e19f165d4a1650abc523d10bc (diff) | |
parent | f1f4ee01c0d3dce0e3aa7d04e4332677db7af478 (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.c | 64 |
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 */ | ||
108 | DEFINE_PER_CPU(int, next_tlbcam_idx); | ||
109 | EXPORT_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 | ||
277 | void __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 | ||
446 | static void setup_mmu_htw(void) | 464 | static 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 | ||
483 | static 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 */ | ||
615 | void __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 */ |